summaryrefslogtreecommitdiff
path: root/sites/all/modules/wysiwyg/editors/js/tinymce-2.js
blob: 61a60ade44a6533f0afa7d450e9f0c26da857abb (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
(function($) {

/**
 * Initialize editor instances.
 *
 * This function needs to be called before the page is fully loaded, as
 * calling tinyMCE.init() after the page is loaded breaks IE6.
 *
 * @param editorSettings
 *   An object containing editor settings for each input format.
 */
Drupal.wysiwyg.editor.init.tinymce = function(settings) {
  // Initialize editor configurations.
  for (var format in settings) {
    tinyMCE.init(settings[format]);
    if (Drupal.settings.wysiwyg.plugins[format]) {
      // Load native external plugins.
      // Array syntax required; 'native' is a predefined token in JavaScript.
      for (var plugin in Drupal.settings.wysiwyg.plugins[format]['native']) {
        tinyMCE.loadPlugin(plugin, Drupal.settings.wysiwyg.plugins[format]['native'][plugin]);
      }
      // Load Drupal plugins.
      for (var plugin in Drupal.settings.wysiwyg.plugins[format].drupal) {
        Drupal.wysiwyg.editor.instance.tinymce.addPlugin(plugin, Drupal.settings.wysiwyg.plugins[format].drupal[plugin], Drupal.settings.wysiwyg.plugins.drupal[plugin]);
      }
    }
  }
};

/**
 * Attach this editor to a target element.
 *
 * See Drupal.wysiwyg.editor.attach.none() for a full desciption of this hook.
 */
Drupal.wysiwyg.editor.attach.tinymce = function(context, params, settings) {
  // Configure editor settings for this input format.
  for (var setting in settings) {
    tinyMCE.settings[setting] = settings[setting];
  }

  // Remove TinyMCE's internal mceItem class, which was incorrectly added to
  // submitted content by Wysiwyg <2.1. TinyMCE only temporarily adds the class
  // for placeholder elements. If preemptively set, the class prevents (native)
  // editor plugins from gaining an active state, so we have to manually remove
  // it prior to attaching the editor. This is done on the client-side instead
  // of the server-side, as Wysiwyg has no way to figure out where content is
  // stored, and the class only affects editing.
  $field = $('#' + params.field);
  $field.val($field.val().replace(/(<.+?\s+class=['"][\w\s]*?)\bmceItem\b([\w\s]*?['"].*?>)/ig, '$1$2'));

  // Attach editor.
  tinyMCE.execCommand('mceAddControl', true, params.field);
};

/**
 * Detach a single or all editors.
 *
 * See Drupal.wysiwyg.editor.detach.none() for a full desciption of this hook.
 */
Drupal.wysiwyg.editor.detach.tinymce = function (context, params, trigger) {
  if (typeof params != 'undefined') {
    tinyMCE.removeMCEControl(tinyMCE.getEditorId(params.field));
    $('#' + params.field).removeAttr('style');
  }
//  else if (tinyMCE.activeEditor) {
//    tinyMCE.triggerSave();
//    tinyMCE.activeEditor.remove();
//  }
};

Drupal.wysiwyg.editor.instance.tinymce = {
  addPlugin: function(plugin, settings, pluginSettings) {
    if (typeof Drupal.wysiwyg.plugins[plugin] != 'object') {
      return;
    }
    tinyMCE.addPlugin(plugin, {

      // Register an editor command for this plugin, invoked by the plugin's button.
      execCommand: function(editor_id, element, command, user_interface, value) {
        switch (command) {
          case plugin:
            if (typeof Drupal.wysiwyg.plugins[plugin].invoke == 'function') {
              var ed = tinyMCE.getInstanceById(editor_id);
              var data = { format: 'html', node: ed.getFocusElement(), content: ed.getFocusElement() };
              Drupal.wysiwyg.plugins[plugin].invoke(data, pluginSettings, ed.formTargetElementId);
              return true;
            }
        }
        // Pass to next handler in chain.
        return false;
      },

      // Register the plugin button.
      getControlHTML: function(control_name) {
        switch (control_name) {
          case plugin:
            return tinyMCE.getButtonHTML(control_name, settings.iconTitle, settings.icon, plugin);
        }
        return '';
      },

      // Load custom CSS for editor contents on startup.
      initInstance: function(ed) {
        if (settings.css) {
          tinyMCE.importCSS(ed.getDoc(), settings.css);
        }
      },

      cleanup: function(type, content) {
        switch (type) {
          case 'insert_to_editor':
            // Attach: Replace plain text with HTML representations.
            if (typeof Drupal.wysiwyg.plugins[plugin].attach == 'function') {
              content = Drupal.wysiwyg.plugins[plugin].attach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
              content = Drupal.wysiwyg.editor.instance.tinymce.prepareContent(content);
            }
            break;

          case 'get_from_editor':
            // Detach: Replace HTML representations with plain text.
            if (typeof Drupal.wysiwyg.plugins[plugin].detach == 'function') {
              content = Drupal.wysiwyg.plugins[plugin].detach(content, pluginSettings, tinyMCE.selectedInstance.editorId);
            }
            break;
        }
        // Pass through to next handler in chain
        return content;
      },

      // isNode: Return whether the plugin button should be enabled for the
      // current selection.
      handleNodeChange: function(editor_id, node, undo_index, undo_levels, visual_aid, any_selection) {
        if (node === null) {
          return;
        }
        if (typeof Drupal.wysiwyg.plugins[plugin].isNode == 'function') {
          if (Drupal.wysiwyg.plugins[plugin].isNode(node)) {
            tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonSelected');
            return true;
          }
        }
        tinyMCE.switchClass(editor_id + '_' + plugin, 'mceButtonNormal');
        return true;
      },

      /**
       * Return information about the plugin as a name/value array.
       */
      getInfo: function() {
        return {
          longname: settings.title
        };
      }
    });
  },

  openDialog: function(dialog, params) {
    var editor = tinyMCE.getInstanceById(this.field);
    tinyMCE.openWindow({
      file: dialog.url + '/' + this.field,
      width: dialog.width,
      height: dialog.height,
      inline: 1
    }, params);
  },

  closeDialog: function(dialog) {
    var editor = tinyMCE.getInstanceById(this.field);
    tinyMCEPopup.close();
  },

  prepareContent: function(content) {
    // Certain content elements need to have additional DOM properties applied
    // to prevent this editor from highlighting an internal button in addition
    // to the button of a Drupal plugin.
    var specialProperties = {
      img: { 'name': 'mce_drupal' }
    };
    var $content = $('<div>' + content + '</div>'); // No .outerHTML() in jQuery :(
    jQuery.each(specialProperties, function(element, properties) {
      $content.find(element).each(function() {
        for (var property in properties) {
          if (property == 'class') {
            $(this).addClass(properties[property]);
          }
          else {
            $(this).attr(property, properties[property]);
          }
        }
      });
    });
    return $content.html();
  },

  insert: function(content) {
    content = this.prepareContent(content);
    var editor = tinyMCE.getInstanceById(this.field);
    editor.execCommand('mceInsertContent', false, content);
    editor.repaint();
  }
};

})(jQuery);