fckeditor-2.6.js 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198
  1. (function($) {
  2. /**
  3. * Attach this editor to a target element.
  4. */
  5. Drupal.wysiwyg.editor.attach.fckeditor = function(context, params, settings) {
  6. if (!settings.Height) {
  7. settings.Height = $('#' + params.field).height();
  8. }
  9. var FCKinstance = new FCKeditor(params.field, settings.Width, settings.Height, settings.ToolbarSet);
  10. // Keep track of the settings for this instance.
  11. this.editorSettings = settings;
  12. // Temporarily store the private instance for use in the config file.
  13. $('#' + params.field, context).data('wysiwygInstance', this);
  14. // Apply editor instance settings.
  15. FCKinstance.BasePath = settings.EditorPath;
  16. FCKinstance.Config.wysiwygFormat = params.format;
  17. FCKinstance.Config.CustomConfigurationsPath = settings.CustomConfigurationsPath;
  18. // Load Drupal plugins and apply format specific settings.
  19. // @see fckeditor.config.js
  20. // @see Drupal.wysiwyg.editor.instance.fckeditor.init()
  21. // Attach editor.
  22. FCKinstance.ReplaceTextarea();
  23. };
  24. /**
  25. * Detach a single editor instance.
  26. */
  27. Drupal.wysiwyg.editor.detach.fckeditor = function (context, params, trigger) {
  28. var instanceName = params.field;
  29. var instance = FCKeditorAPI.GetInstance(instanceName);
  30. if (!instance) {
  31. return;
  32. }
  33. instance.UpdateLinkedField();
  34. if (trigger == 'serialize') {
  35. // The editor is not being removed from the DOM, so updating the linked
  36. // field is the only action necessary.
  37. return;
  38. }
  39. // Since we already detach the editor and update the textarea, the submit
  40. // event handler needs to be removed to prevent data loss (in IE).
  41. // FCKeditor uses 2 nested iFrames; instance.EditingArea.Window is the
  42. // deepest. Its parent is the iFrame containing the editor.
  43. var instanceScope = instance.EditingArea.Window.parent;
  44. instanceScope.FCKTools.RemoveEventListener(instance.GetParentForm(), 'submit', instance.UpdateLinkedField);
  45. // Run cleanups before forcing an unload of the iFrames or IE crashes.
  46. // This also deletes the instance from the FCKeditorAPI.__Instances array.
  47. instanceScope.FCKTools.RemoveEventListener(instanceScope, 'unload', instanceScope.FCKeditorAPI_Cleanup);
  48. instanceScope.FCKTools.RemoveEventListener(instanceScope, 'beforeunload', instanceScope.FCKeditorAPI_ConfirmCleanup);
  49. if (jQuery.isFunction(instanceScope.FCKIECleanup_Cleanup)) {
  50. instanceScope.FCKIECleanup_Cleanup();
  51. }
  52. instanceScope.FCKeditorAPI_ConfirmCleanup();
  53. instanceScope.FCKeditorAPI_Cleanup();
  54. // Remove the editor elements.
  55. $('#' + instanceName + '___Config').remove();
  56. $('#' + instanceName + '___Frame').remove();
  57. $('#' + instanceName).show();
  58. };
  59. Drupal.wysiwyg.editor.instance.fckeditor = {
  60. init: function(instance) {
  61. var wysiwygInstance = instance.wysiwygInstance;
  62. var pluginInfo = wysiwygInstance.pluginInfo;
  63. var enabledPlugins = pluginInfo.instances.drupal;
  64. // Track which editor instance is active.
  65. instance.FCK.Events.AttachEvent('OnFocus', function(editorInstance) {
  66. Drupal.wysiwyg.activeId = editorInstance.Name;
  67. });
  68. // Create a custom data processor to wrap the default one and allow Drupal
  69. // plugins modify the editor contents.
  70. var wysiwygDataProcessor = function() {};
  71. wysiwygDataProcessor.prototype = new instance.FCKDataProcessor();
  72. // Attach: Convert text into HTML.
  73. wysiwygDataProcessor.prototype.ConvertToHtml = function(data) {
  74. // Called from SetData() with stripped comments/scripts, revert those
  75. // manipulations and attach Drupal plugins.
  76. var data = instance.FCKConfig.ProtectedSource.Revert(data);
  77. for (var plugin in enabledPlugins) {
  78. if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
  79. data = Drupal.wysiwyg.plugins[plugin].attach(data, pluginInfo.global.drupal[plugin], instance.FCK.Name);
  80. data = Drupal.wysiwyg.editor.instance.fckeditor.prepareContent(data);
  81. }
  82. }
  83. // Re-protect the source and use the original data processor to convert it
  84. // into XHTML.
  85. data = instance.FCKConfig.ProtectedSource.Protect(data);
  86. return instance.FCKDataProcessor.prototype.ConvertToHtml.call(this, data);
  87. };
  88. // Detach: Convert HTML into text.
  89. wysiwygDataProcessor.prototype.ConvertToDataFormat = function(rootNode, excludeRoot, ignoreIfEmptyParagraph, format) {
  90. // Called from GetData(), convert the content's DOM into a XHTML string
  91. // using the original data processor and detach Drupal plugins.
  92. var data = instance.FCKDataProcessor.prototype.ConvertToDataFormat.call(this, rootNode, excludeRoot, ignoreIfEmptyParagraph, format);
  93. for (var plugin in enabledPlugins) {
  94. if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
  95. data = Drupal.wysiwyg.plugins[plugin].detach(data, pluginInfo.global.drupal[plugin], instance.FCK.Name);
  96. }
  97. }
  98. return data;
  99. };
  100. instance.FCK.DataProcessor = new wysiwygDataProcessor();
  101. },
  102. addPlugin: function(plugin, pluginSettings, instance) {
  103. if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
  104. return;
  105. }
  106. if (pluginSettings.css) {
  107. instance.FCKConfig.EditorAreaCSS += ',' + pluginSettings.css;
  108. }
  109. // @see fckcommands.js, fck_othercommands.js, fckpastewordcommand.js
  110. instance.FCKCommands.RegisterCommand(plugin, {
  111. // Invoke the plugin's button.
  112. Execute: function () {
  113. if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
  114. var data = { format: 'html', node: instance.FCKSelection.GetParentElement() };
  115. // @todo This is NOT the same as data.node.
  116. data.content = data.node.innerHTML;
  117. Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, instance.FCK.Name);
  118. }
  119. },
  120. // isNode: Return whether the plugin button should be enabled for the
  121. // current selection.
  122. // @see FCKUnlinkCommand.prototype.GetState()
  123. GetState: function () {
  124. // Always disabled if not in WYSIWYG mode.
  125. if (instance.FCK.EditMode != FCK_EDITMODE_WYSIWYG) {
  126. return FCK_TRISTATE_DISABLED;
  127. }
  128. var state = instance.FCK.GetNamedCommandState(this.Name);
  129. // FCKeditor sets the wrong state in WebKit browsers.
  130. if (!$.support.queryCommandEnabled && state == FCK_TRISTATE_DISABLED) {
  131. state = FCK_TRISTATE_OFF;
  132. }
  133. if (state == FCK_TRISTATE_OFF && instance.FCK.EditMode == FCK_EDITMODE_WYSIWYG) {
  134. if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
  135. var node = instance.FCKSelection.GetSelectedElement();
  136. state = Drupal.wysiwyg.plugins[plugin].isNode(node) ? FCK_TRISTATE_ON : FCK_TRISTATE_OFF;
  137. }
  138. }
  139. return state;
  140. },
  141. /**
  142. * Return information about the plugin as a name/value array.
  143. */
  144. Name: plugin
  145. });
  146. // Register the plugin button.
  147. // Arguments: commandName, label, tooltip, style, sourceView, contextSensitive, icon.
  148. instance.FCKToolbarItems.RegisterItem(plugin, new instance.FCKToolbarButton(plugin, pluginSettings.title, pluginSettings.title, null, false, true, pluginSettings.icon));
  149. },
  150. openDialog: function(dialog, params) {
  151. // @todo Implement open dialog.
  152. },
  153. closeDialog: function(dialog) {
  154. // @todo Implement close dialog.
  155. },
  156. prepareContent: function(content) {
  157. // @todo Not needed for FCKeditor?
  158. return content;
  159. },
  160. insert: function(content) {
  161. var instance = FCKeditorAPI.GetInstance(this.field);
  162. // @see FCK.InsertHtml(), FCK.InsertElement()
  163. instance.InsertHtml(content);
  164. },
  165. getContent: function () {
  166. var instance = FCKeditorAPI.GetInstance(this.field);
  167. return instance.GetData();
  168. },
  169. setContent: function (content) {
  170. var instance = FCKeditorAPI.GetInstance(this.field);
  171. instance.SetHTML(content);
  172. },
  173. isFullscreen: function () {
  174. var cmd = FCKeditorAPI.GetInstance(this.field).Commands.LoadedCommands.FitWindow;
  175. return !!(cmd && cmd.IsMaximized);
  176. }
  177. };
  178. })(jQuery);