Our goal:
We need the StackEdit editor to render exactly at the same place where the textbox is (the way TinyMCE and other editors do) instead of rendering it in modal/fullscreen/covering the entire UI on the HTML page.
We are trying to implement https://stackedit.io/ mark down editor in our application. In order to do that we have set a local instance of https://github.com/benweet/stackedit at following local url say https://localhost:4433.
This would act as a local endpoint http://localhost:8080/app to serve the stackedit editor the way https://stackedit.io/app is having. We set up a local instance so that for editor rendering the remote endpoint of StackEdit domain itself should not hit.
In order to use that endpoint and use stackedit editor on a html page we are using https://benweet.github.io/stackedit.js/ and written the following code to render the editor:
var el = document.querySelector('textarea');
var stackedit = new Stackedit({
url: 'https://localhost:4433/app'
});
// Open the iframe
stackedit.openFile({
name: 'Filename', // with an optional filename
content: {
text: el.value // and the Markdown content.
}
});
// Listen to StackEdit events and apply the changes to the textarea.
stackedit.on('fileChange', (file) => {
el.value = file.content.text;
});
We have taken that code from https://benweet.github.io/stackedit.js/
The issue with the above implementation is that the editor is rendered as a modal and hide all the UI which is on the html page. Here is how it is rendered:
That is not what we need. In our application there will be multiple editors on a single page and having that editor as full screen or in modal will not serve. Our expectation with the editor is to make StackEditor render like popular TinyMCE edito i.e it should be rendered exactly at the same position where the textbox is.
TinyMCE editor:
This is how StackExchange editor comes:
So coming back to my original question, is it even possible with StackEdit to implement the editor in place where the textbox is instead of modal or full screen?
EDIT:
I went to following links with similar request and got no success there also:
https://github.com/benweet/stackedit.js/issues/10
https://github.com/benweet/stackedit.js/issues/14
https://github.com/benweet/stackedit.js/issues/26
Related
So, I have this extension, and it should show a custom popup on the page when the icon is clicked, and by "custom popup", I mean, something rendered inside an <iframe> and injected in the page dom itself, not an "traditional extension popup", but the problem is that in some pages i'm not able to inject a content-script, in those cases, I would want to display the content in the "traditional extension popup".
I got it to work, but it's not the most elegant of a solution, here's how I'm doing it
The popup.html has no content in it's <body>, and it imports a script.
This script tries to send a message to the content script running in the page, if the message is successfully, the popup will close itself, and the content script will handle the render on the page
If the message could not be sent then it tries to inject the script on the page, if the injection works, then the message is sent again, if it doesn't, then we are on a page that does not allow injection, in that case, we simply render the content to the popup's body (i'm using Svelte here)
browser.tabs.query({active: true, currentWindow: true}).then(tabs => {
const tab = tabs[0];
browser.tabs.sendMessage(tab.id, {action: "toggle"}).then(() => {
window.close();
}).catch(() => {
injectScript(tab).then(() => {
browser.tabs.sendMessage(tab.id, {action: "toggle"}).then(() => {
window.close();
});
}).catch(() => {
document.body.style.width="400px";
document.documentElement.style.height="580px";
new App({
target: document.body,
});
});
});
});
The thing is, most of the time, this process is basically instantaneous, you just click the icon, and the custom popup shows up, but sometimes, it takes a little longer (maybe 1 sec?), and in that time, you can see the "traditional popup" on it's minimum size (maybe something around 32x32? It's a really small square)
What I would like is to keep the popup hidden until my code "decided" wheter it's possible or not to inject the content in the page.
What I've tried and does not work:
Setting width and/or height of the and/or tags to 0px
Setting display:none and/or visibility: hidden on and/or tags
Is there any way to do what I'm looking for?
EDIT:
Here's an image so you can better understand what I'm talking about, this is the "square":
Sometimes you can't even see it, sometimes it just blinks, and sometimes it takes a bit longer to go away, it depends on the pc I think
I would use a layer in this case. A layer can be done using CSS, can contain all of the proper formatting and text, and can be shown or hidden whenever you want not affecting any of the other text around it due to it being on another layer. I'm unsure if this will solve your problem because I don't really know the context of the program you are creating and what you are trying to accomplish.
Like many others, due to the limitations of TinyMCE's Image Plugin, I've decided to take the route of creating one that ties into my site's own uploading system.
I've gotten this partially working and pulling up a individual page, designed just for the purpose. However, now I want to return content from selecting images on this page. Is that possible or am I hitting a dead end?
tinymce.PluginManager.add('imageLoader', function(editor, url) {
// Adds a menu item to the tools menu
editor.addButton('imageLoader', {
icon: 'mce-ico mce-i-link',
image: 'Photos.png',
onclick: function() {
// Open window
editor.windowManager.open({
title: 'Image Loader',
url: 'load_images',
width: 500,
height: 400,
onsubmit: function(e) {
// Insert content when the window form is submitted
editor.insertContent('Image To Insert');
}
});
}
});
return {
getMetadata: function () {
return {
name: "Image Loader"
};
}
};
});
We made this a lot easier in TinyMCE 5 with a new URL dialog api:
https://www.tiny.cloud/docs/ui-components/urldialog/
In version 4, I believe the usual technique was to (inside the iframe) access the TinyMCE instance that opened the dialog via window.parent.tinymce.activeEditor, and then replicate the onsubmit function there. With the editor instance you can insert whatever content you need to and then editor.windowManager.close() will close the topmost window (i.e. the url dialog).
For more advanced use cases, editor.windowManager.getParams() can be used to pass information between the plugin and dialog, although perhaps not from the dialog to the plugin. editor.plugins is another possible technique, it's a name/value object of active plugin instances (it's a live reference to the return value from the PluginManager.add init function which can be mutated at runtime).
These are all fairly complicated, but likely more reliable than searching for the dialog iframe from your plugin.
I found an answer, although this is likely not the most elegant solution.
The image that I'm selecting is passed into a hidden text input in my custom page. From there, on Submit or Closing the TinyMCE 4 Frame, I use this snippet:
let getVal = $('[role="application"]').find('iframe')[1].contentWindow.document.getElementById("imgHolder").value;
In order:
It first finds the iFrame. Since both external pages and the editor itself use iFrames, this will generally be the 'second' iFrame - unfortunately, it isn't given an ID.
"contentWindow.document.getElementByID" fetches the hidden input, in my case named "imgHolder"
From here, you can get your content as normal with .value, and insert it into the TinyMCE Editor.
I hope this helps point others in the right direction, especially knowing that it gets asked a lot for TinyMCE 4. Further I hope this can be made a bit more elegent as well.
Im looking for solution that can track user activity inside wp_editor, i mean, i want to know if he is idle or not and then save content as concept (autosaving)
I was trying to use this https://css-tricks.com/snippets/jquery/fire-event-when-user-is-idle/ and it's working mostly for all elements on website but i can't use it inside wp_editor because it's iframe.
and i tried also this library:
https://github.com/kidh0/jquery.idle
$('body').idle({
onIdle: function(){
$("#workingState").html('<?=displayInLanguage("<p>Stav: <strong>neaktívny, obsah uložený.</strong></p>", "<p>Status: <strong>inactive, content saved.</strong></p>")?>');
if( $('#show_add_actuality').hasClass('d-block') ){
saveForm('actualityForm_sk', "autoSaveScript");
saveForm('actualityForm_en', "autoSaveScript");
}
},
onActive: function(){
$("#workingState").html('<?=displayInLanguage("<p>Stav: <strong>aktívny</strong></p>", "<p>Status: <strong>active</strong></p>")?>');
},
idle: 2000
});
so as you can see im trying to save form in slovak and english language when user is not active, i will perform ajax request on both forms which includes also wp_editor, but i can't just track activity inside another page (which wp_editor generate another iframe site inside, its blank but still it's not working that way)
So i'm expecting some solution that can help me track user activity inside wordpress editor.
Script is working as expected, the only activity that i can't track is wordpress editor, no typing, no cursor movements nothing it will ignore idle state.
Thanks for any answer.
I have an app that I need to show images in (after clicking on a thumbnail), written in meteor.
I'm able to store the images in gridFS and pull them out fine, but am struggling to work out how to dynamically size a modal dialogue for showing the full size image.
I think I need to trap the bs-show event for the dialogue and set the .css.width property to the size required, but I have no idea how to intercept the bs-show event in meteor.
I have tried putting the following code in the app
Template.projectImageItem.events = {
"click .open-modal" : function(e,t) {
e.preventDefault();
Session.set("selectedImageId", t.data._id);
Session.set("showProjModal", true);
//console.log("Image ID: "+ Session.get("selectedImageId"));
console.log($("projectImageModalID").find('modal-body'));
$("projectImageModalID").find('modal-body').css({
width: '20px'
});
$("#projectImageModalID").modal("show");
}
};
and in the chrome debugger can see the object being returned to the consol log, but the css change has no effect before the show so I guess I'm not in the right place for this.
I am writing intranet site for tracking employees science activities in organization.
There lots of editable information on each personal page (science degree, publications & so on) so I upload editor per request (user clicks "edit" and modal dialog with html editor: set of textboxes/comboboxes/autocomplete features & validation logic appears).
Editor is html layout that is wrapped with jquery dialog plugin + some logic, written as javascript functions that should be invoked from the callee page (onsubmit, validate, afterLoad editor events). There are also attributes (editor preferrable with and height) that are passed to callee page also.
Currently I send these functions & attribute as ... function onsubmit() { }; function validate() { } var width = 640; var height = 800 ... code that is embedded into the request page. Function calls and editor markup wrap with jquery plugin completed in the callee page.
It works, but I have some try { call editor event handler } catch { } stuff in callee page (because not every editor provides these functions) and some attributes (editor width & height for instance) that are loaded as variables declared in javascript.
Please, suggest, is there a better approach to build & use custom editors for my situation.
Thank you in advance!
First off, maybe you can use CKEditor. This editor has a jQuery adapter so that you can instantiate the editor very easy:
$('#editor1').ckeditor({
language : 'en',
toolbar : 'Basic',
width : 640,
height : 800
});
You pass all needed informations at the edit page loading to the callee page and load the editor afterwards:
User click edit link -> Ajax request to get the necessary edit infos -> Editor rendering
Perhaps you can write different editor renderers, one for each use case.