/** * @file * Plugin for inserting links with Linkit. */ (function ($) { CKEDITOR.plugins.add( 'linkit', { requires : [ 'link' ], hidpi: true, icons: 'linkit', init: function( editor ) { // Get the major CKeditor verison. // We do not care about minor versions. var version = parseInt(CKEDITOR.version); // Add Button. editor.ui.addButton( 'linkit', { label: Drupal.t('Link to content'), command: 'linkit' }); // Ckeditor version lower then 4 needs to have a icon path. if (version < 4) { editor.ui._.items.linkit.icon = this.path + 'icons/linkit.png'; editor.ui._.items.linkit.args[0].icon = this.path + 'icons/linkit.png'; } // Add Command. editor.addCommand( 'linkit', { // FOR ACF in ckeditor 4.1+, allow everything. allowedContent: 'a[*]{*}(*)', exec : function () { if (typeof Drupal.settings.linkit === 'undefined') { alert(Drupal.t('Could not find the Linkit profile.')); return ; } // Set the editor object. Drupal.settings.linkit.currentInstance.editor = editor; // Find the current input format of the field we're looking at. var format = ''; if (Drupal.wysiwyg) { // If using the WYSIWYG module with CKEditor as the editor // Note that WYSIWYG prepends "profile" to the profile name, so we use .substring() to remove the "format". format = Drupal.wysiwyg.instances[editor.name].format.substring(6); } else if (Drupal.settings.ckeditor) { // If using the CKEditor module format = Drupal.settings.ckeditor.elements[editor.name]; } else { alert(Drupal.t('Could not find the Linkit profile.')); return; } // Set profile based on the current text format of this field. Drupal.settings.linkit.currentInstance.profile = Drupal.settings.linkit.formats[format].profile; // Set the name of the source field. Drupal.settings.linkit.currentInstance.source = editor.name; // Set the source type. Drupal.settings.linkit.currentInstance.helper = 'ckeditor'; var selection = editor.getSelection(), element = null; // If we have selected a link element, we what to grab its attributes // so we can inserten them into the Linkit form in the dialog. if ((element = CKEDITOR.plugins.link.getSelectedLink(editor)) && element.hasAttribute('href')) { selection.selectElement(element); } else { element = null; } // Save the selection. Drupal.settings.linkit.currentInstance.selection = selection; // Lock the selecton for IE. if (CKEDITOR.env.ie && typeof selection !== 'undefined') { selection.lock(); } // Save the selected element. Drupal.settings.linkit.currentInstance.selectedElement = element; // Create the modal. Drupal.linkit.createModal(); } }); // If the "menu" plugin is loaded, register the menu items. if (editor.addMenuItems) { // Use the default link menu group weight and subtract one. var defaultMenuGroup = editor._.menuGroups.link; editor.addMenuGroup("Linkit", defaultMenuGroup - 1); editor.addMenuItems({ linkit: { label: Drupal.t('Link to content'), command: 'linkit', group: 'Linkit', order: 0 } }); // Remove the default link option. editor.removeMenuItem('link'); } // If the "contextmenu" plugin is loaded, register the listeners. if (editor.contextMenu) { editor.contextMenu.addListener(function(element, selection) { if (!element || element.isReadOnly() || (selection.getSelectedText().length < 1 && !element.is('a'))) { return null; } return {linkit: CKEDITOR.TRISTATE_OFF}; }); } // Add a shortcut. Only CKeditor version 4 has this function. if (version >= 4) { editor.setKeystroke(CKEDITOR.CTRL + 76 /*L*/, 'linkit'); } // Add event listener. editor.on('doubleclick', function(evt) { if (evt.data.dialog !== 'link') { return; } // Delete the default link dialog. delete evt.data.dialog; var element = CKEDITOR.plugins.link.getSelectedLink(editor) || evt.data.element; if (!element.isReadOnly()) { if (element.is( 'a' )) { editor.getSelection().selectElement(element); if (version >= 4) { editor.commands.linkit.exec(); } else if(version == 3) { editor._.commands.linkit.exec(); } } } }); // Register an extra fucntion, this will be used in the modal. editor._.linkitFnNum = CKEDITOR.tools.addFunction(insertLink, editor); } }); /** * Create or update a link element in the editor. */ function insertLink(data, editor) { var selection = editor.getSelection(); data.path = CKEDITOR.tools.trim(data.path); // Browser need the "href" for copy/paste link to work. (CKEDITOR ISSUE #6641) data.attributes['data-cke-saved-href'] = data.path; if (!Drupal.settings.linkit.currentInstance.selectedElement) { // We have not selected any link element so lets create a new one. var range = selection.getRanges(1)[0]; if (range.collapsed) { var content = (Drupal.settings.linkit.currentInstance.linkContent) ? Drupal.settings.linkit.currentInstance.linkContent : data.path; var text = new CKEDITOR.dom.text(content , editor.document); range.insertNode(text); range.selectNodeContents(text); } // Delete all attributes that are empty. data.attributes.href = data.path; for (name in data.attributes) { data.attributes[name] ? null : delete data.attributes[name]; } // Apply style. var style = new CKEDITOR.style({element : 'a', attributes : data.attributes}); style.type = CKEDITOR.STYLE_INLINE; style.applyToRange(range); range.select(); } else { var element = Drupal.settings.linkit.currentInstance.selectedElement; // We are editing an existing link, so just overwrite the attributes. element.setAttribute('href', data.path); element.setAttribute('data-cke-saved-href', data.path); for (name in data.attributes) { data.attributes[name] ? element.setAttribute(name, data.attributes[name]) : element.removeAttribute(name); } selection.selectElement( element ); } // Unlock the selection. if (CKEDITOR.env.ie && typeof selection !== 'undefined') { selection.unlock(); } } })(jQuery);