TinyMCE WordPress Plugin for clickable image - javascript

I'm trying to create a simple WordPress plugin for the TinyMCE editor that adds a button to the editor bar, that when you click on this it inserts an image into the content, and I want this image to be clickable by the person reading the published and run some JavaScript when this occurs (basically just to open a new window with some specific sizing).
The problem I have is that TinyMCE strips the onClick event I add to the image hyperlink, so it doesn't work. I understand one way to fix this is to change the valid_elements section for TinyMCE, but this would involve anyone installing the plugin having to go and make those changes manually. Is there anyway to be able to run some JS when the image is clicked by the reader solely in my plugin?

Should be a matter of extending TinyMCE valid elements inside your own plugin. Here an example adding the image tag with all properties enabled:
add_filter( 'tiny_mce_before_init', function ( $init ) {
$img = 'img[*]';
if ( isset( $init['extended_valid_elements'] ) ) {
$init['extended_valid_elements'] .= ',' . $img;
} else {
$init['extended_valid_elements'] = $img;
}
return $init;
});
I used the following when creating the TinyMCE button to insert a clickable <img> element into the post content:
ed.addButton( 'test_button', {
title : 'Insert clickable image',
image : '../wp-includes/images/smilies/icon_eek.gif',
onclick : function() {
ed.selection.setContent( '<img src="http://example.com/test.gif" onclick="alert()" />' );
}
});

Related

Add attribute to wordpress menu

I'm using a lightweight lightbox script for my wordpress site. I want one of the main navigation buttons to open a Vimeo link in the lightbox. The documentation of the lightbox says to "Add the 'data-lity' attribute to any <a> elements for which you want the links to be opened in a lightbox"...like so:
<a href="//vimeo.com/1084537" data-lity>iFrame Vimeo</a>
That works fine for a normal on page links - but I don't see any way in wordpress menus to add that "data-lity" attribute to the wordpress menu. How can I achieve this?
Thanks
Try this code:
Add this code to your current theme's functions.php file:
add_filter( 'nav_menu_link_attributes', 'wpse44532_add_attr_menu_atts', 10, 3 );
function wpse44532_add_attr_menu_atts( $atts, $item, $args )
{
// The id of the target menu item
$menu_target = 44;
if ($item->ID == $menu_target) {
$atts['data-lity'] = 'test';
}
return $atts;
}

Wordpress Detect Click on Gallery Shortcode Preview in TinyMCE

Working on customizing the wordpress gallery with some different settings for different gallery types.
Short of the long is I'm using multiple wp_editors on page and I'm having a focus problem when jumping between editors.
I'm making use of wp.media.view.Settings.Gallery.extend to switch between gallery types and display different js templates.
The functionality is actually all good and gallery shortcodes are going where they need to and being updated as needed.
For certain gallery types I am extending the attachment details with
an extend that looks something like this slimed down version:
var $gal_media = wp.media;
$gal_media.view.Attachment.Details = $gal_media.view.Attachment.Details.extend({
initialize: function(){
this.model.on('change', this.render, this);
},
render: function(){
var check_active_editor = window.wpActiveEditor;
return this;
}
});
The problem lies here when I'm attempting to detect the current editor during the render part of the function with window.wpActiveEditor;
It's working correctly providing you get focus on the current editor but if you just click the gallery preview or edit gallery pencil window.wpActiveEditor; will return the last focused editor.
Tried several different attempts to change focus on the editor in the wp_editor call using on click events during init like so:
'tinymce' => array(
'init_instance_callback' => 'function(gallery_editor) {
gallery_editor.on("click", function(){
tinyMCE.get(gallery_editor.id).focus();
});
}'
)
but they are not called when clicking on the gallery preview or edit.
Any suggestion on either:
1) Getting the proper id?
Obviously the Gallery knows it as it's returning the shortcode to the proper editor.
or
2) Toggling Focus/Blur on Multiple Editors when Gallery Preview or Edit button is pressed.
Much appreciated!
If anyone finds themselves in a similar situation I was able to resolve this issue with an on click callback on my editors that cycles through all the editors and removes the data-mce-selected attribute from any other gallery nodes that were selected.
Then it sets focus on the editor that was just clicked.
Not the prettiest but it's behaving as expected.
The key for me was using tinyMCE.dom.DomQuery
'tinymce' => array(
'init_instance_callback' => 'function(ed) {
ed.on("click", function(){
for (edId in tinyMCE.editors){
if(edId !== ed.id){
var this_editor = tinyMCE.get(edId);
var $ = tinyMCE.dom.DomQuery;
$("div[data-wpview-type]", this_editor.dom.doc).removeAttr("data-mce-selected");
}
}
tinyMCE.get(ed.id).focus();
});
}'
)

TinyMCE editor content missing after drag and move

I've got a page with multiple TinyMce editors and i have drag and drop feature enabled which allows me to change the order of each items.
But as i drag-drop an editor its content gets removed.
See the screen shots :
Before Drag-Drop
After Drag-Drop
Finally fixed the issue...
The solution is to first shut down the tinymce instance (id needed!)
tinymce.execCommand('mceRemoveControl',true,'editor_id');
then do the DOM action and reinit the tinymce instance
tinymce.execCommand('mceAddControl',true,'editor_id');
Add following code on drag end event:
onDragEnd(event: any) {
var tinymceId = 'tinymceId_' + event.source.data.index; //get selected element id
tinymce.get(tinymceId ).remove(); //remove existing instance
$('#' + tinymceId ).closest('.mce-tinymce.mce-container').show();
tinymce.init({id: tinymceId , selector: '#' + tinymceId , height: 200}; //you can add other properties into init()
}

Magento WYSIWYG editor error: Target element not found for content update

I added editor to widget. I used solution described in this answer. Everything works fine excepting inserting image to editor where widget is inserted.
When I open widget and save it or close it, I can not insert image into original editor because it lost reference. I get error "Target element not found for content update" when I try to insert image.
I checked browser.js and checked value for this.targetElementId inside getTargetElement function. It has value of closed widget editor and not original active editor. I tried to change this value just to see if this would solve the problem:
getTargetElement: function() {
this.targetElementId = 'myeditor_content';
if (typeof(tinyMCE) != 'undefined' && tinyMCE.get(this.targetElementId)) {
if ((opener = this.getMediaBrowserOpener())) {
var targetElementId = tinyMceEditors.get(this.targetElementId).getMediaBrowserTargetElementId();
return opener.document.getElementById(targetElementId);
} else {
return null;
}
} else {
return document.getElementById(this.targetElementId);
}
},
but then other errors shows up in console.
TypeError: tinyMceEditors.get(...).getMediaBrowserOpener(...) is null
Is there any easy way to somehow destroy reference to old editor (editor from widget which was closed)?
Try to add editor handle to layout.
For example:
<default>
<update handle="editor"/>
</default>

How do you dynamically add a button/plugin to TinyMCE?

I have a TinyMCE editor in my page. I would like to add/remove buttons/plugins from the toolbar based on things happening else where in the page. I am looking for a solution that avoids destroying and recreating the editor. Is there a tinyMCE command to do this? Something like
tinyMCE.execCommand("mceInsertPlugin", pluginName);
You cannot load plugins without reinitializing the editor.
But with buttons it is possible:
Create button on the fly:
ed.addButton('example', {
title : 'example.desc',
image : '../jscripts/tiny_mce/plugins/example/img/example.gif',
onclick : function() {
ed.windowManager.alert('Hello world!! Selection: ' + ed.selection.getContent({format : 'text'}));
}
});
Removal:
$('.mce_example').parent('td').remove();

Categories