diff --git a/design/standard/javascript/plugins/breakoutspace/editor_plugin.js b/design/standard/javascript/plugins/breakoutspace/editor_plugin.js new file mode 100755 index 0000000..ed01a0a --- /dev/null +++ b/design/standard/javascript/plugins/breakoutspace/editor_plugin.js @@ -0,0 +1,56 @@ +/** + * Break Out Space TinyMCE plugin. When you press CTRL+Enter in a custom tag you will get an empty paragraph outside the tag + * + * @author Peter Keung + * @copyright Copyright 2014, Mugo Web + */ + +( function() +{ + tinymce.create('tinymce.plugins.breakoutspace', + { + /** + * Initializes the plugin, this will be executed after the plugin has been created. + * This call is done before the editor instance has finished it's initialization so use the onInit event + * of the editor instance to intercept that event. + * + * @param {tinymce.Editor} ed Editor instance that the plugin is initialized in. + * @param {string} url Absolute URL to where the plugin is located. + */ + init: function( ed, url ) + { + ed.onKeyDown.add( function( ed, e ) + { + // Capture CTRL+Enter + if( ( ( e.keyCode == 13 ) || ( e.keyCode == 10 ) ) && ( e.ctrlKey == true ) ) + { + var dom = ed.dom; + + var parents = dom.getParents( ed.selection.getNode() ); + for( var i=0; i < parents.length; i++ ) + { + currentNode = parents[i]; + // Insert empty paragraph at the end of the parent of the closest custom tag + if( currentNode.nodeName == 'DIV' && currentNode.getAttribute( 'type' ) == 'custom' ) + { + // dom.insertAfter doesn't work reliably + var uniqueID = dom.uniqueId(); + jQuery( '


' ).insertAfter( currentNode ); + + // Move to the new node + var newParagraph = dom.select( 'p#' + uniqueID )[0]; + ed.selection.setCursorLocation( newParagraph ); + + // Don't create an extra paragraph + e.preventDefault(); + break; + } + } + } + }); + } + }); + + // Register plugin + tinymce.PluginManager.add( 'breakoutspace', tinymce.plugins.breakoutspace ); +})(); diff --git a/design/standard/templates/ezoe/customattributes/link.tpl b/design/standard/templates/ezoe/customattributes/link.tpl index 423ca45..45c9ad8 100644 --- a/design/standard/templates/ezoe/customattributes/link.tpl +++ b/design/standard/templates/ezoe/customattributes/link.tpl @@ -32,8 +32,10 @@ eZOEPopupUtils.settings.onInitDoneArray.push( function( editorElement ) { var drop = jQuery( 'select.atr_link_source_types'), inp = jQuery( 'input.link_href_input' ), - tagName = drop.attr('data-tag-name'); - + tagName = []; + drop.each(function(){ + tagName[ $(this).attr('id') ] = $(this).attr('data-tag-name'); + }); // init source type selection inp.each(function( i ){ var self = jQuery(this); @@ -44,23 +46,23 @@ eZOEPopupUtils.settings.onInitDoneArray.push( function( editorElement ) { var url = self.val().split('://'), id = eZOEPopupUtils.Int( url[1] ); if ( id !== 0 && ( url[0] === 'eznode' || url[0] === 'ezobject' ) ) - ezoeLinkAttribute.ajaxCheck.call( this, url[0] + '_' + id ); + ezoeLinkAttribute.ajaxCheck.call( this, url[0] + '_' + id, ezoeLinkAttribute.lid( this.id, tagName[this.id + '_types'] ) ); } }); // add event to lookup changes to source type drop.change(function( e ) { - var lid = ezoeLinkAttribute.lid( this.id, tagName ), input = document.getElementById( lid+'_source' ); + var lid = ezoeLinkAttribute.lid( this.id, tagName[this.id] ), input = document.getElementById( lid+'_source' ); if ( this.value === 'ezobject://' ) { - input.value = this.value + ezoeLinkAttribute.node['contentobject_id']; - ezoeLinkAttribute.namePreview( ezoeLinkAttribute.node['name'], lid ); + input.value = this.value + ezoeLinkAttribute.getNode( lid )['contentobject_id']; + ezoeLinkAttribute.namePreview( ezoeLinkAttribute.getNode( lid )['name'], lid ); } else if ( this.value === 'eznode://' ) { - input.value = this.value + ezoeLinkAttribute.node['node_id']; - ezoeLinkAttribute.namePreview( ezoeLinkAttribute.node['name'], lid ); + input.value = this.value + ezoeLinkAttribute.getNode( lid )['node_id']; + ezoeLinkAttribute.namePreview( ezoeLinkAttribute.getNode( lid )['name'], lid ); } else { @@ -73,7 +75,7 @@ eZOEPopupUtils.settings.onInitDoneArray.push( function( editorElement ) inp.keyup( function( e ) { e = e || window.event; - var c = e.keyCode || e.which, lid = ezoeLinkAttribute.lid( this.id, tagName ), dropdown = jQuery( '#'+lid + '_source_types' ); + var c = e.keyCode || e.which, lid = $(this).closest('.custom_attribute_type_link, .attribute_type_link').attr('id'), dropdown = jQuery( '#'+lid + '_source_types' ); clearTimeout( ezoeLinkAttribute.timeOut ); // break if user is pressing arrow keys @@ -90,13 +92,15 @@ eZOEPopupUtils.settings.onInitDoneArray.push( function( editorElement ) ezoeLinkAttribute.timeOut = setTimeout( eZOEPopupUtils.BIND( ezoeLinkAttribute.ajaxCheck, this, url[0] + '_' + id, lid ), 320 ); return true; }); + inp.keyup(); // setup navigation on bookmark / browse / search links to their 'boxes' (panels) jQuery( 'a.atr_link_search_link, a.atr_link_browse_link, a.atr_link_bookmark_link' ).click( function(){ - ezoeLinkAttribute.id = ezoeLinkAttribute.lid( this.id, tagName ); + var tagNameKey = $(this).closest('.custom_attribute_type_link, .attribute_type_link').find('select.atr_link_source_types').attr('id'); + ezoeLinkAttribute.id = ezoeLinkAttribute.lid( this.id, tagName[tagNameKey] ); jQuery('div.panel, div.link-dialog').hide(); - jQuery('#' + ezoeLinkAttribute.box( this.id, tagName ) ).show(); - jQuery('#' + ezoeLinkAttribute.box( this.id, tagName ) + ' input[type=text]:first').focus(); + jQuery('#' + ezoeLinkAttribute.box( this.id, tagName[tagNameKey] ) ).show(); + jQuery('#' + ezoeLinkAttribute.box( this.id, tagName[tagNameKey] ) + ' input[type=text]:first').focus(); }); jQuery( '#embed_search_go_back_link, #embed_browse_go_back_link, #embed_bookmark_go_back_link' ).click( ezoeLinkAttribute.toggleBack ); }); @@ -127,7 +131,7 @@ eZOEPopupUtils.settings.browseLinkGenerator = function( n, mode, ed ) // override so selected element is redirected to link input eZOEPopupUtils.selectByEmbedId = function( object_id, node_id, name ) { - var lid = ezoeLinkAttribute.id, drop = jQuery( '#'+lid+'_source_types'), inp = jQuery( '#'+lid+'_source' ), info = jQuery( '#'+lid+'_source_info' ) + var lid = ezoeLinkAttribute.id, drop = jQuery( '#'+lid+'_source_types'), inp = jQuery( '#'+lid+'_source' ), info = jQuery( '#'+lid+'_source_info' ); if ( drop.val() === 'ezobject://' ) inp.val( 'ezobject://' + object_id ); else @@ -135,7 +139,7 @@ eZOEPopupUtils.selectByEmbedId = function( object_id, node_id, name ) ezoeLinkAttribute.typeSet( inp, drop ); ezoeLinkAttribute.namePreview( name, lid ); ezoeLinkAttribute.toggleBack(); - ezoeLinkAttribute.node = {'contentobject_id': object_id, 'node_id': node_id, 'name': name } + ezoeLinkAttribute.node[lid] = {'contentobject_id': object_id, 'node_id': node_id, 'name': name } }; // misc link related variables and functions @@ -143,7 +147,15 @@ var ezoeLinkAttribute = { timeOut : null, slides : 0, id : null, - node : {'contentobject_id': '', 'node_id': '', 'name': '' }, + node : [], + getNode : function( lid ) + { + if( typeof this.node[lid] === "undefined" ) + { + this.node[lid] = {'contentobject_id': '', 'node_id': '', 'name': '' }; + } + return this.node[lid]; + }, ajaxCheck : function( url, lid ) { var url = tinyMCEPopup.editor.settings.ez_extension_url + '/load/' + url; @@ -154,7 +166,7 @@ var ezoeLinkAttribute = { if ( r ) { ezoeLinkAttribute.namePreview( r.name, lid ); - ezoeLinkAttribute.node = r; + ezoeLinkAttribute.node[lid] = r; } else ezoeLinkAttribute.namePreview( false, lid ); diff --git a/settings/ezoe.ini b/settings/ezoe.ini index 6bd2541..05113aa 100644 --- a/settings/ezoe.ini +++ b/settings/ezoe.ini @@ -30,6 +30,8 @@ Plugins[]=inlinepopups Plugins[]=autolink # list plugin Plugins[]=lists +# Support CTRL+Enter to exit a custom tag +Plugins[]=breakoutspace # Skin for the editor, 'default' and 'o2k7' is included as standard Skin=o2k7