tinymce-2.js 7.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. (function($) {
  2. /**
  3. * Initialize editor instances.
  4. *
  5. * This function needs to be called before the page is fully loaded, as
  6. * calling tinyMCE.init() after the page is loaded breaks IE6.
  7. *
  8. * @param editorSettings
  9. * An object containing editor settings for each input format.
  10. */
  11. Drupal.wysiwyg.editor.init.tinymce = function(settings) {
  12. // If JS compression is enabled, TinyMCE is unable to autodetect its global
  13. // settinge, hence we need to define them manually.
  14. // @todo Move global library settings somewhere else.
  15. tinyMCE.baseURL = settings.global.editorBasePath;
  16. tinyMCE.srcMode = (settings.global.execMode == 'src' ? '_src' : '');
  17. tinyMCE.gzipMode = (settings.global.execMode == 'gzip');
  18. // Initialize editor configurations.
  19. for (var format in settings) {
  20. if (format == 'global') {
  21. continue;
  22. }
  23. tinyMCE.init(settings[format]);
  24. if (Drupal.settings.wysiwyg.plugins[format]) {
  25. // Load native external plugins.
  26. // Array syntax required; 'native' is a predefined token in JavaScript.
  27. for (var plugin in Drupal.settings.wysiwyg.plugins[format]['native']) {
  28. tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwyg.plugins[format]['native'][plugin]);
  29. }
  30. // Load Drupal plugins.
  31. for (var plugin in Drupal.settings.wysiwyg.plugins[format].drupal) {
  32. Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
  33. }
  34. }
  35. }
  36. };
  37. /**
  38. * Attach this editor to a target element.
  39. *
  40. * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
  41. */
  42. Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
  43. // Configure editor settings for this input format.
  44. for (var setting in settings) {
  45. tinyMCE.settings[setting] = settings[setting];
  46. }
  47. // Remove TinyMCE's internal mceItem class, which was incorrectly added to
  48. // submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class
  49. // for placeholder elements. If preemptively set, the class prevents (native)
  50. // editor plugins from gaining an active state, so we have to manually remove
  51. // it prior to attaching the editor. This is done on the client-side instead
  52. // of the server-side, as Wysiwyg has no way to figure out where content is
  53. // stored, and the class only affects editing.
  54. $field = $('#' + params.field);
  55. $field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2'));
  56. // Attach editor.
  57. tinyMCE.execCommand('mceAddControl', true, params.field);
  58. };
  59. /**
  60. * Detach a single or all editors.
  61. *
  62. * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
  63. */
  64. Drupal.wysiwyg.editor.detach.tinymce = function(context, params) {
  65. if (typeof params != 'undefined') {
  66. tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field));
  67. $('#' + params.field).removeAttr('style');
  68. }
  69. // else if (tinyMCE.activeEditor) {
  70. // tinyMCE.triggerSave();
  71. // tinyMCE.activeEditor.remove();
  72. // }
  73. };
  74. Drupal.wysiwyg.editor.instance.tinymce = {
  75. addPlugin: function(plugin, settings, pluginSettings) {
  76. if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
  77. return;
  78. }
  79. tinyMCE.addPlugin(plugin, {
  80. // Register an editor command for this plugin, invoked by the plugin's button.
  81. execCommand: function(editor_id, element, command, user_interface, value) {
  82. switch (command) {
  83. case plugin:
  84. if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
  85. var ed = tinyMCE.getInstanceById(editor_id);
  86. var data = { format: 'html', node: ed.getFocusElement(), content: ed.getFocusElement() };
  87. Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, ed.formTargetElementId);
  88. return true;
  89. }
  90. }
  91. // Pass to next handler in chain.
  92. return false;
  93. },
  94. // Register the plugin button.
  95. getControlHTML: function(control_name) {
  96. switch (control_name) {
  97. case plugin:
  98. return tinyMCE.getButtonHTML(control_name, settings.iconTitle, settings.icon, plugin);
  99. }
  100. return '';
  101. },
  102. // Load custom CSS for editor contents on startup.
  103. initInstance: function(ed) {
  104. if (settings.css) {
  105. tinyMCE.importCSS(ed.getDoc(), settings.css);
  106. }
  107. },
  108. cleanup: function(type, content) {
  109. switch (type) {
  110. case 'insert_to_editor':
  111. // Attach: Replace plain text with HTML representations.
  112. if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
  113. content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
  114. content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(content);
  115. }
  116. break;
  117. case 'get_from_editor':
  118. // Detach: Replace HTML representations with plain text.
  119. if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
  120. content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
  121. }
  122. break;
  123. }
  124. // Pass through to next handler in chain
  125. return content;
  126. },
  127. // isNode: Return whether the plugin button should be enabled for the
  128. // current selection.
  129. handleNodeChange: function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
  130. if (node === null) {
  131. return;
  132. }
  133. if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
  134. if (Drupal.wysiwyg.plugins[plugin].isNode(node)) {
  135. tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonSelected');
  136. return true;
  137. }
  138. }
  139. tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonNormal');
  140. return true;
  141. },
  142. /**
  143. * Return information about the plugin as a name/value array.
  144. */
  145. getInfo: function() {
  146. return {
  147. longname: settings.title
  148. };
  149. }
  150. });
  151. },
  152. openDialog: function(dialog, params) {
  153. var editor = tinyMCE.getInstanceById(this.field);
  154. tinyMCE.openWindow({
  155. file: dialog.url + '/' + this.field,
  156. width: dialog.width,
  157. height: dialog.height,
  158. inline: 1
  159. }, params);
  160. },
  161. closeDialog: function(dialog) {
  162. var editor = tinyMCE.getInstanceById(this.field);
  163. tinyMCEPopup.close();
  164. },
  165. prepareContent: function(content) {
  166. // Certain content elements need to have additional DOM properties applied
  167. // to prevent this editor from highlighting an internal button in addition
  168. // to the button of a Drupal plugin.
  169. var specialProperties = {
  170. img: { 'name': 'mce_drupal' }
  171. };
  172. var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
  173. jQuery.each(specialProperties, function(element, properties) {
  174. $content.find(element).each(function() {
  175. for (var property in properties) {
  176. if (property == 'class') {
  177. $(this).addClass(properties[property]);
  178. }
  179. else {
  180. $(this).attr(property, properties[property]);
  181. }
  182. }
  183. });
  184. });
  185. return $content.html();
  186. },
  187. insert: function(content) {
  188. content = this.prepareContent(content);
  189. var editor = tinyMCE.getInstanceById(this.field);
  190. editor.execCommand('mceInsertContent', false, content);
  191. editor.repaint();
  192. }
  193. };
  194. })(jQuery);