plugin.js 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. /**
  2. * @file
  3. * Plugin for inserting links with Linkit.
  4. */
  5. (function ($) {
  6. CKEDITOR.plugins.add( 'linkit', {
  7. requires : [ 'link' ],
  8. hidpi: true,
  9. icons: 'linkit',
  10. init: function( editor ) {
  11. // Get the major CKeditor verison.
  12. // We do not care about minor versions.
  13. var version = parseInt(CKEDITOR.version);
  14. // Add Button.
  15. editor.ui.addButton( 'linkit', {
  16. label: Drupal.t('Link to content'),
  17. command: 'linkit'
  18. });
  19. // Ckeditor version lower then 4 needs to have a icon path.
  20. if (version < 4) {
  21. editor.ui._.items.linkit.icon = this.path + 'icons/linkit.png';
  22. editor.ui._.items.linkit.args[0].icon = this.path + 'icons/linkit.png';
  23. }
  24. // Add Command.
  25. editor.addCommand( 'linkit', {
  26. // FOR ACF in ckeditor 4.1+, allow everything.
  27. allowedContent: 'a[*]{*}(*)',
  28. exec : function () {
  29. if (typeof Drupal.settings.linkit === 'undefined') {
  30. alert(Drupal.t('Could not find the Linkit profile.'));
  31. return ;
  32. }
  33. // Set the editor object.
  34. Drupal.settings.linkit.currentInstance.editor = editor;
  35. // Find the current input format of the field we're looking at.
  36. var format = '';
  37. if (Drupal.wysiwyg) { // If using the WYSIWYG module with CKEditor as the editor
  38. // Note that WYSIWYG prepends "profile" to the profile name, so we use .substring() to remove the "format".
  39. format = Drupal.wysiwyg.instances[editor.name].format.substring(6);
  40. }
  41. else if (Drupal.settings.ckeditor) { // If using the CKEditor module
  42. format = Drupal.settings.ckeditor.elements[editor.name];
  43. } else {
  44. alert(Drupal.t('Could not find the Linkit profile.'));
  45. return;
  46. }
  47. // Set profile based on the current text format of this field.
  48. Drupal.settings.linkit.currentInstance.profile = Drupal.settings.linkit.formats[format].profile;
  49. // Set the name of the source field.
  50. Drupal.settings.linkit.currentInstance.source = editor.name;
  51. // Set the source type.
  52. Drupal.settings.linkit.currentInstance.helper = 'ckeditor';
  53. var selection = editor.getSelection(),
  54. element = null;
  55. // If we have selected a link element, we what to grab its attributes
  56. // so we can inserten them into the Linkit form in the dialog.
  57. if ((element = CKEDITOR.plugins.link.getSelectedLink(editor)) && element.hasAttribute('href')) {
  58. selection.selectElement(element);
  59. }
  60. else {
  61. element = null;
  62. }
  63. // Save the selection.
  64. Drupal.settings.linkit.currentInstance.selection = selection;
  65. // Lock the selecton for IE.
  66. if (CKEDITOR.env.ie && typeof selection !== 'undefined') {
  67. selection.lock();
  68. }
  69. // Save the selected element.
  70. Drupal.settings.linkit.currentInstance.selectedElement = element;
  71. // Create the modal.
  72. Drupal.linkit.createModal();
  73. }
  74. });
  75. // If the "menu" plugin is loaded, register the menu items.
  76. if (editor.addMenuItems) {
  77. // Use the default link menu group weight and subtract one.
  78. var defaultMenuGroup = editor._.menuGroups.link;
  79. editor.addMenuGroup("Linkit", defaultMenuGroup - 1);
  80. editor.addMenuItems({
  81. linkit: {
  82. label: Drupal.t('Link to content'),
  83. command: 'linkit',
  84. group: 'Linkit',
  85. order: 0
  86. }
  87. });
  88. // Remove the default link option.
  89. editor.removeMenuItem('link');
  90. }
  91. // If the "contextmenu" plugin is loaded, register the listeners.
  92. if (editor.contextMenu) {
  93. editor.contextMenu.addListener(function(element, selection) {
  94. if (!element || element.isReadOnly() || (selection.getSelectedText().length < 1 && !element.is('a'))) {
  95. return null;
  96. }
  97. return {linkit: CKEDITOR.TRISTATE_OFF};
  98. });
  99. }
  100. // Add a shortcut. Only CKeditor version 4 has this function.
  101. if (version >= 4) {
  102. editor.setKeystroke(CKEDITOR.CTRL + 76 /*L*/, 'linkit');
  103. }
  104. // Add event listener.
  105. editor.on('doubleclick', function(evt) {
  106. if (evt.data.dialog !== 'link') {
  107. return;
  108. }
  109. // Delete the default link dialog.
  110. delete evt.data.dialog;
  111. var element = CKEDITOR.plugins.link.getSelectedLink(editor) || evt.data.element;
  112. if (!element.isReadOnly()) {
  113. if (element.is( 'a' )) {
  114. editor.getSelection().selectElement(element);
  115. if (version >= 4) {
  116. editor.commands.linkit.exec();
  117. }
  118. else if(version == 3) {
  119. editor._.commands.linkit.exec();
  120. }
  121. }
  122. }
  123. });
  124. // Register an extra fucntion, this will be used in the modal.
  125. editor._.linkitFnNum = CKEDITOR.tools.addFunction(insertLink, editor);
  126. }
  127. });
  128. /**
  129. * Create or update a link element in the editor.
  130. */
  131. function insertLink(data, editor) {
  132. var selection = editor.getSelection();
  133. data.path = CKEDITOR.tools.trim(data.path);
  134. // Browser need the "href" for copy/paste link to work. (CKEDITOR ISSUE #6641)
  135. data.attributes['data-cke-saved-href'] = data.path;
  136. if (!Drupal.settings.linkit.currentInstance.selectedElement) {
  137. // We have not selected any link element so lets create a new one.
  138. var range = selection.getRanges(1)[0];
  139. if (range.collapsed) {
  140. var content = (Drupal.settings.linkit.currentInstance.linkContent) ? Drupal.settings.linkit.currentInstance.linkContent : data.path;
  141. var text = new CKEDITOR.dom.text(content , editor.document);
  142. range.insertNode(text);
  143. range.selectNodeContents(text);
  144. }
  145. // Delete all attributes that are empty.
  146. data.attributes.href = data.path;
  147. for (name in data.attributes) {
  148. data.attributes[name] ? null : delete data.attributes[name];
  149. }
  150. // Apply style.
  151. var style = new CKEDITOR.style({element : 'a', attributes : data.attributes});
  152. style.type = CKEDITOR.STYLE_INLINE;
  153. style.applyToRange(range);
  154. range.select();
  155. }
  156. else {
  157. var element = Drupal.settings.linkit.currentInstance.selectedElement;
  158. // We are editing an existing link, so just overwrite the attributes.
  159. element.setAttribute('href', data.path);
  160. element.setAttribute('data-cke-saved-href', data.path);
  161. for (name in data.attributes) {
  162. data.attributes[name] ?
  163. element.setAttribute(name, data.attributes[name]) :
  164. element.removeAttribute(name);
  165. }
  166. selection.selectElement( element );
  167. }
  168. // Unlock the selection.
  169. if (CKEDITOR.env.ie && typeof selection !== 'undefined') {
  170. selection.unlock();
  171. }
  172. }
  173. })(jQuery);