Lib_Js_TinyMCE - Version 3.5.11.0

Version Notes

3.5.11.0

Download this release

Release Info

Developer Magento Core Team
Extension Lib_Js_TinyMCE
Version 3.5.11.0
Comparing to
See all releases


Code changes from version 3.4.7.1 to 3.5.11.0

Files changed (143) hide show
  1. js/tiny_mce/classes/AddOnManager.js +7 -7
  2. js/tiny_mce/classes/ControlManager.js +33 -19
  3. js/tiny_mce/classes/Editor.Events.js +932 -0
  4. js/tiny_mce/classes/Editor.js +482 -1798
  5. js/tiny_mce/classes/EditorCommands.js +46 -24
  6. js/tiny_mce/classes/EditorManager.js +62 -34
  7. js/tiny_mce/classes/EnterKey.js +582 -0
  8. js/tiny_mce/classes/ForceBlocks.js +87 -607
  9. js/tiny_mce/classes/Formatter.js +552 -306
  10. js/tiny_mce/classes/LegacyInput.js +22 -22
  11. js/tiny_mce/classes/Popup.js +22 -61
  12. js/tiny_mce/classes/UndoManager.js +119 -9
  13. js/tiny_mce/classes/WindowManager.js +3 -3
  14. js/tiny_mce/classes/adapter/jquery/adapter.js +10 -24
  15. js/tiny_mce/classes/adapter/jquery/jquery.tinymce.js +340 -335
  16. js/tiny_mce/classes/adapter/prototype/adapter.js +4 -4
  17. js/tiny_mce/classes/dom/DOMUtils.js +188 -63
  18. js/tiny_mce/classes/dom/Element.js +14 -14
  19. js/tiny_mce/classes/dom/EventUtils.js +523 -288
  20. js/tiny_mce/classes/dom/Range.js +43 -16
  21. js/tiny_mce/classes/dom/RangeUtils.js +3 -3
  22. js/tiny_mce/classes/dom/ScriptLoader.js +11 -12
  23. js/tiny_mce/classes/dom/Selection.js +516 -245
  24. js/tiny_mce/classes/dom/Serializer.js +31 -11
  25. js/tiny_mce/classes/dom/Sizzle.js +627 -250
  26. js/tiny_mce/classes/dom/TreeWalker.js +3 -3
  27. js/tiny_mce/classes/dom/TridentSelection.js +68 -31
  28. js/tiny_mce/classes/html/DomParser.js +148 -29
  29. js/tiny_mce/classes/html/Entities.js +4 -5
  30. js/tiny_mce/classes/html/Node.js +8 -4
  31. js/tiny_mce/classes/html/SaxParser.js +48 -46
  32. js/tiny_mce/classes/html/Schema.js +375 -159
  33. js/tiny_mce/classes/html/Serializer.js +4 -4
  34. js/tiny_mce/classes/html/Styles.js +31 -24
  35. js/tiny_mce/classes/html/Writer.js +3 -3
  36. js/tiny_mce/classes/tinymce.js +94 -72
  37. js/tiny_mce/classes/ui/Button.js +26 -7
  38. js/tiny_mce/classes/ui/ColorSplitButton.js +37 -23
  39. js/tiny_mce/classes/ui/Container.js +3 -3
  40. js/tiny_mce/classes/ui/Control.js +3 -3
  41. js/tiny_mce/classes/ui/DropMenu.js +12 -8
  42. js/tiny_mce/classes/ui/KeyboardNavigation.js +24 -14
  43. js/tiny_mce/classes/ui/ListBox.js +32 -12
  44. js/tiny_mce/classes/ui/Menu.js +3 -3
  45. js/tiny_mce/classes/ui/MenuButton.js +5 -5
  46. js/tiny_mce/classes/ui/MenuItem.js +3 -3
  47. js/tiny_mce/classes/ui/NativeListBox.js +11 -13
  48. js/tiny_mce/classes/ui/Separator.js +3 -3
  49. js/tiny_mce/classes/ui/SplitButton.js +3 -3
  50. js/tiny_mce/classes/ui/Toolbar.js +3 -3
  51. js/tiny_mce/classes/ui/ToolbarGroup.js +3 -3
  52. js/tiny_mce/classes/util/Cookie.js +11 -10
  53. js/tiny_mce/classes/util/Dispatcher.js +41 -29
  54. js/tiny_mce/classes/util/JSON.js +8 -8
  55. js/tiny_mce/classes/util/JSONP.js +3 -3
  56. js/tiny_mce/classes/util/JSONRequest.js +3 -3
  57. js/tiny_mce/classes/util/Quirks.js +984 -95
  58. js/tiny_mce/classes/util/URI.js +19 -12
  59. js/tiny_mce/classes/util/VK.js +25 -4
  60. js/tiny_mce/classes/util/XHR.js +15 -15
  61. js/tiny_mce/jquery.tinymce.js +1 -1
  62. js/tiny_mce/langs/en.js +1 -1
  63. js/tiny_mce/license.txt +1 -1
  64. js/tiny_mce/plugins/advimage/js/image.js +5 -3
  65. js/tiny_mce/plugins/advlink/js/advlink.js +16 -5
  66. js/tiny_mce/plugins/autolink/editor_plugin.js +1 -1
  67. js/tiny_mce/plugins/autolink/editor_plugin_src.js +24 -12
  68. js/tiny_mce/plugins/autoresize/editor_plugin.js +1 -1
  69. js/tiny_mce/plugins/autoresize/editor_plugin_src.js +20 -38
  70. js/tiny_mce/plugins/autosave/editor_plugin.js +1 -1
  71. js/tiny_mce/plugins/autosave/editor_plugin_src.js +4 -2
  72. js/tiny_mce/plugins/contextmenu/editor_plugin.js +1 -1
  73. js/tiny_mce/plugins/contextmenu/editor_plugin_src.js +10 -7
  74. js/tiny_mce/plugins/directionality/editor_plugin.js +1 -1
  75. js/tiny_mce/plugins/directionality/editor_plugin_src.js +22 -19
  76. js/tiny_mce/plugins/emotions/emotions.htm +1 -1
  77. js/tiny_mce/plugins/example/editor_plugin_src.js +1 -1
  78. js/tiny_mce/plugins/fullscreen/editor_plugin.js +1 -1
  79. js/tiny_mce/plugins/fullscreen/editor_plugin_src.js +107 -32
  80. js/tiny_mce/plugins/fullscreen/fullscreen.htm +16 -9
  81. js/tiny_mce/plugins/inlinepopups/editor_plugin.js +1 -1
  82. js/tiny_mce/plugins/inlinepopups/editor_plugin_src.js +13 -13
  83. js/tiny_mce/plugins/legacyoutput/editor_plugin.js +1 -1
  84. js/tiny_mce/plugins/legacyoutput/editor_plugin_src.js +1 -1
  85. js/tiny_mce/plugins/lists/editor_plugin.js +1 -1
  86. js/tiny_mce/plugins/lists/editor_plugin_src.js +98 -68
  87. js/tiny_mce/plugins/media/editor_plugin.js +1 -1
  88. js/tiny_mce/plugins/media/editor_plugin_src.js +23 -15
  89. js/tiny_mce/plugins/media/js/media.js +75 -26
  90. js/tiny_mce/plugins/noneditable/editor_plugin.js +1 -1
  91. js/tiny_mce/plugins/noneditable/editor_plugin_src.js +499 -57
  92. js/tiny_mce/plugins/paste/editor_plugin.js +1 -1
  93. js/tiny_mce/plugins/paste/editor_plugin_src.js +24 -8
  94. js/tiny_mce/plugins/searchreplace/js/searchreplace.js +10 -0
  95. js/tiny_mce/plugins/searchreplace/searchreplace.htm +1 -1
  96. js/tiny_mce/plugins/spellchecker/editor_plugin.js +1 -1
  97. js/tiny_mce/plugins/spellchecker/editor_plugin_src.js +44 -9
  98. js/tiny_mce/plugins/style/css/props.css +1 -0
  99. js/tiny_mce/plugins/style/editor_plugin.js +1 -1
  100. js/tiny_mce/plugins/style/editor_plugin_src.js +19 -3
  101. js/tiny_mce/plugins/style/js/props.js +77 -3
  102. js/tiny_mce/plugins/style/langs/en_dlg.js +1 -1
  103. js/tiny_mce/plugins/style/props.htm +6 -1
  104. js/tiny_mce/plugins/style/readme.txt +19 -0
  105. js/tiny_mce/plugins/tabfocus/editor_plugin.js +1 -1
  106. js/tiny_mce/plugins/tabfocus/editor_plugin_src.js +1 -1
  107. js/tiny_mce/plugins/table/editor_plugin.js +1 -1
  108. js/tiny_mce/plugins/table/editor_plugin_src.js +90 -42
  109. js/tiny_mce/plugins/table/js/cell.js +2 -2
  110. js/tiny_mce/plugins/table/js/row.js +17 -0
  111. js/tiny_mce/plugins/table/js/table.js +22 -5
  112. js/tiny_mce/plugins/table/row.htm +15 -15
  113. js/tiny_mce/plugins/visualblocks/css/visualblocks.css +21 -0
  114. js/tiny_mce/plugins/visualblocks/editor_plugin.js +1 -0
  115. js/tiny_mce/plugins/visualblocks/editor_plugin_src.js +63 -0
  116. js/tiny_mce/plugins/wordcount/editor_plugin.js +1 -1
  117. js/tiny_mce/plugins/wordcount/editor_plugin_src.js +15 -7
  118. js/tiny_mce/themes/advanced/color_picker.htm +2 -6
  119. js/tiny_mce/themes/advanced/editor_template.js +1 -1
  120. js/tiny_mce/themes/advanced/editor_template_src.js +176 -48
  121. js/tiny_mce/themes/advanced/img/icons.gif +0 -0
  122. js/tiny_mce/themes/advanced/js/anchor.js +19 -6
  123. js/tiny_mce/themes/advanced/js/color_picker.js +345 -329
  124. js/tiny_mce/themes/advanced/js/image.js +4 -2
  125. js/tiny_mce/themes/advanced/js/link.js +9 -3
  126. js/tiny_mce/themes/advanced/js/source_editor.js +27 -5
  127. js/tiny_mce/themes/advanced/langs/en_dlg.js +1 -1
  128. js/tiny_mce/themes/advanced/skins/default/dialog.css +3 -2
  129. js/tiny_mce/themes/advanced/skins/default/ui.css +6 -1
  130. js/tiny_mce/themes/advanced/skins/highcontrast/dialog.css +4 -3
  131. js/tiny_mce/themes/advanced/skins/highcontrast/ui.css +5 -1
  132. js/tiny_mce/themes/advanced/skins/o2k7/dialog.css +3 -2
  133. js/tiny_mce/themes/advanced/skins/o2k7/ui.css +6 -1
  134. js/tiny_mce/themes/advanced/source_editor.htm +1 -1
  135. js/tiny_mce/tiny_mce.js +1 -1
  136. js/tiny_mce/tiny_mce_dev.js +10 -2
  137. js/tiny_mce/tiny_mce_jquery.js +1 -1
  138. js/tiny_mce/tiny_mce_jquery_src.js +9807 -7770
  139. js/tiny_mce/tiny_mce_popup.js +1 -1
  140. js/tiny_mce/tiny_mce_prototype.js +1 -1
  141. js/tiny_mce/tiny_mce_prototype_src.js +8204 -5776
  142. js/tiny_mce/tiny_mce_src.js +9342 -6914
  143. package.xml +5 -5
js/tiny_mce/classes/AddOnManager.js CHANGED
@@ -1,11 +1,11 @@
1
/**
2
* AddOnManager.js
3
*
4
- * Copyright 2009, Moxiecode Systems AB
5
* Released under LGPL License.
6
*
7
- * License: http://tinymce.moxiecode.com/license
8
- * Contributing: http://tinymce.moxiecode.com/contributing
9
*/
10
11
(function(tinymce) {
@@ -110,12 +110,12 @@
110
},
111
112
/**
113
- * Add a set of components that will make up the add-on. Using the url of the add-on name as the base url.
114
* This should be used in development mode. A new compressor/javascript munger process will ensure that the
115
* components are put together into the editor_plugin.js file and compressed correctly.
116
* @param pluginName {String} name of the plugin to load scripts from (will be used to get the base url for the plugins).
117
* @param scripts {Array} Array containing the names of the scripts to load.
118
- */
119
addComponents: function(pluginName, scripts) {
120
var pluginUrl = this.urls[pluginName];
121
tinymce.each(scripts, function(script){
@@ -164,7 +164,7 @@
164
if (typeof u === "object")
165
url = u.prefix + u.resource + u.suffix;
166
167
- if (url.indexOf('/') != 0 && url.indexOf('://') == -1)
168
url = tinymce.baseURL + '/' + url;
169
170
t.urls[n] = url.substring(0, url.lastIndexOf('/'));
@@ -296,7 +296,7 @@
296
* return {
297
* longname : 'Example plugin',
298
* author : 'Some author',
299
- * authorurl : 'http://tinymce.moxiecode.com',
300
* infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',
301
* version : "1.0"
302
* };
1
/**
2
* AddOnManager.js
3
*
4
+ * Copyright, Moxiecode Systems AB
5
* Released under LGPL License.
6
*
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
*/
10
11
(function(tinymce) {
110
},
111
112
/**
113
+ * Add a set of components that will make up the add-on. Using the url of the add-on name as the base url.
114
* This should be used in development mode. A new compressor/javascript munger process will ensure that the
115
* components are put together into the editor_plugin.js file and compressed correctly.
116
* @param pluginName {String} name of the plugin to load scripts from (will be used to get the base url for the plugins).
117
* @param scripts {Array} Array containing the names of the scripts to load.
118
+ */
119
addComponents: function(pluginName, scripts) {
120
var pluginUrl = this.urls[pluginName];
121
tinymce.each(scripts, function(script){
164
if (typeof u === "object")
165
url = u.prefix + u.resource + u.suffix;
166
167
+ if (url.indexOf('/') !== 0 && url.indexOf('://') == -1)
168
url = tinymce.baseURL + '/' + url;
169
170
t.urls[n] = url.substring(0, url.lastIndexOf('/'));
296
* return {
297
* longname : 'Example plugin',
298
* author : 'Some author',
299
+ * authorurl : 'http://www.tinymce.com',
300
* infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/example',
301
* version : "1.0"
302
* };
js/tiny_mce/classes/ControlManager.js CHANGED
@@ -1,11 +1,11 @@
1
/**
2
* ControlManager.js
3
*
4
- * Copyright 2009, Moxiecode Systems AB
5
* Released under LGPL License.
6
*
7
- * License: http://tinymce.moxiecode.com/license
8
- * Contributing: http://tinymce.moxiecode.com/contributing
9
*/
10
11
(function(tinymce) {
@@ -113,31 +113,43 @@
113
* will be used.
114
*
115
* @method createControl
116
- * @param {String} n Control name to create for example "separator".
117
* @return {tinymce.ui.Control} Control instance that got created and added.
118
*/
119
- createControl : function(n) {
120
- var c, t = this, ed = t.editor;
121
122
- each(ed.plugins, function(p) {
123
- if (p.createControl) {
124
- c = p.createControl(n, t);
125
126
- if (c)
127
- return false;
128
}
129
- });
130
131
- switch (n) {
132
- case "|":
133
- case "separator":
134
- return t.createSeparator();
135
}
136
137
- if (!c && ed.buttons && (c = ed.buttons[n]))
138
- return t.createButton(n, c);
139
140
- return t.add(c);
141
},
142
143
/**
@@ -161,6 +173,8 @@
161
if (v = ed.getParam('skin_variant'))
162
s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
163
164
id = t.prefix + id;
165
cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
166
c = t.controls[id] = new cls(id, s);
1
/**
2
* ControlManager.js
3
*
4
+ * Copyright, Moxiecode Systems AB
5
* Released under LGPL License.
6
*
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
*/
10
11
(function(tinymce) {
113
* will be used.
114
*
115
* @method createControl
116
+ * @param {String} name Control name to create for example "separator".
117
* @return {tinymce.ui.Control} Control instance that got created and added.
118
*/
119
+ createControl : function(name) {
120
+ var ctrl, i, l, self = this, editor = self.editor, factories, ctrlName;
121
+
122
+ // Build control factory cache
123
+ if (!self.controlFactories) {
124
+ self.controlFactories = [];
125
+ each(editor.plugins, function(plugin) {
126
+ if (plugin.createControl) {
127
+ self.controlFactories.push(plugin);
128
+ }
129
+ });
130
+ }
131
132
+ // Create controls by asking cached factories
133
+ factories = self.controlFactories;
134
+ for (i = 0, l = factories.length; i < l; i++) {
135
+ ctrl = factories[i].createControl(name, self);
136
137
+ if (ctrl) {
138
+ return self.add(ctrl);
139
}
140
+ }
141
142
+ // Create sepearator
143
+ if (name === "|" || name === "separator") {
144
+ return self.createSeparator();
145
}
146
147
+ // Create control from button collection
148
+ if (editor.buttons && (ctrl = editor.buttons[name])) {
149
+ return self.createButton(name, ctrl);
150
+ }
151
152
+ return self.add(ctrl);
153
},
154
155
/**
173
if (v = ed.getParam('skin_variant'))
174
s['class'] += ' ' + ed.getParam('skin') + 'Skin' + v.substring(0, 1).toUpperCase() + v.substring(1);
175
176
+ s['class'] += ed.settings.directionality == "rtl" ? ' mceRtl' : '';
177
+
178
id = t.prefix + id;
179
cls = cc || t._cls.dropmenu || tinymce.ui.DropMenu;
180
c = t.controls[id] = new cls(id, s);
js/tiny_mce/classes/Editor.Events.js ADDED
@@ -0,0 +1,932 @@
1
+ /**
2
+ * Editor.Events.js
3
+ *
4
+ * Copyright, Moxiecode Systems AB
5
+ * Released under LGPL License.
6
+ *
7
+ * License: http://www.tinymce.com/license
8
+ * Contributing: http://www.tinymce.com/contributing
9
+ */
10
+
11
+ (function(tinymce) {
12
+ var each = tinymce.each;
13
+
14
+ /**
15
+ * Creates all event dispatcher instances for the editor instance and also adds
16
+ * passthoughs for legacy callback handlers.
17
+ */
18
+ tinymce.Editor.prototype.setupEvents = function() {
19
+ var self = this, settings = self.settings;
20
+
21
+ // Add events to the editor
22
+ each([
23
+ /**
24
+ * Fires before the initialization of the editor.
25
+ *
26
+ * @event onPreInit
27
+ * @param {tinymce.Editor} sender Editor instance.
28
+ * @see #onInit
29
+ * @example
30
+ * // Adds an observer to the onPreInit event using tinyMCE.init
31
+ * tinyMCE.init({
32
+ * ...
33
+ * setup : function(ed) {
34
+ * ed.onPreInit.add(function(ed) {
35
+ * console.debug('PreInit: ' + ed.id);
36
+ * });
37
+ * }
38
+ * });
39
+ */
40
+ 'onPreInit',
41
+
42
+ /**
43
+ * Fires before the initialization of the editor.
44
+ *
45
+ * @event onBeforeRenderUI
46
+ * @param {tinymce.Editor} sender Editor instance.
47
+ * @example
48
+ * // Adds an observer to the onBeforeRenderUI event using tinyMCE.init
49
+ * tinyMCE.init({
50
+ * ...
51
+ * setup : function(ed) {
52
+ * ed.onBeforeRenderUI.add(function(ed, cm) {
53
+ * console.debug('Before render: ' + ed.id);
54
+ * });
55
+ * }
56
+ * });
57
+ */
58
+ 'onBeforeRenderUI',
59
+
60
+ /**
61
+ * Fires after the rendering has completed.
62
+ *
63
+ * @event onPostRender
64
+ * @param {tinymce.Editor} sender Editor instance.
65
+ * @example
66
+ * // Adds an observer to the onPostRender event using tinyMCE.init
67
+ * tinyMCE.init({
68
+ * ...
69
+ * setup : function(ed) {
70
+ * ed.onPostRender.add(function(ed, cm) {
71
+ * console.debug('After render: ' + ed.id);
72
+ * });
73
+ * }
74
+ * });
75
+ */
76
+ 'onPostRender',
77
+
78
+ /**
79
+ * Fires when the onload event on the body occurs.
80
+ *
81
+ * @event onLoad
82
+ * @param {tinymce.Editor} sender Editor instance.
83
+ * @example
84
+ * // Adds an observer to the onLoad event using tinyMCE.init
85
+ * tinyMCE.init({
86
+ * ...
87
+ * setup : function(ed) {
88
+ * ed.onLoad.add(function(ed, cm) {
89
+ * console.debug('Document loaded: ' + ed.id);
90
+ * });
91
+ * }
92
+ * });
93
+ */
94
+ 'onLoad',
95
+
96
+ /**
97
+ * Fires after the initialization of the editor is done.
98
+ *
99
+ * @event onInit
100
+ * @param {tinymce.Editor} sender Editor instance.
101
+ * @see #onPreInit
102
+ * @example
103
+ * // Adds an observer to the onInit event using tinyMCE.init
104
+ * tinyMCE.init({
105
+ * ...
106
+ * setup : function(ed) {
107
+ * ed.onInit.add(function(ed) {
108
+ * console.debug('Editor is done: ' + ed.id);
109
+ * });
110
+ * }
111
+ * });
112
+ */
113
+ 'onInit',
114
+
115
+ /**
116
+ * Fires when the editor instance is removed from page.
117
+ *
118
+ * @event onRemove
119
+ * @param {tinymce.Editor} sender Editor instance.
120
+ * @example
121
+ * // Adds an observer to the onRemove event using tinyMCE.init
122
+ * tinyMCE.init({
123
+ * ...
124
+ * setup : function(ed) {
125
+ * ed.onRemove.add(function(ed) {
126
+ * console.debug('Editor was removed: ' + ed.id);
127
+ * });
128
+ * }
129
+ * });
130
+ */
131
+ 'onRemove',
132
+
133
+ /**
134
+ * Fires when the editor is activated.
135
+ *
136
+ * @event onActivate
137
+ * @param {tinymce.Editor} sender Editor instance.
138
+ * @example
139
+ * // Adds an observer to the onActivate event using tinyMCE.init
140
+ * tinyMCE.init({
141
+ * ...
142
+ * setup : function(ed) {
143
+ * ed.onActivate.add(function(ed) {
144
+ * console.debug('Editor was activated: ' + ed.id);
145
+ * });
146
+ * }
147
+ * });
148
+ */
149
+ 'onActivate',
150
+
151
+ /**
152
+ * Fires when the editor is deactivated.
153
+ *
154
+ * @event onDeactivate
155
+ * @param {tinymce.Editor} sender Editor instance.
156
+ * @example
157
+ * // Adds an observer to the onDeactivate event using tinyMCE.init
158
+ * tinyMCE.init({
159
+ * ...
160
+ * setup : function(ed) {
161
+ * ed.onDeactivate.add(function(ed) {
162
+ * console.debug('Editor was deactivated: ' + ed.id);
163
+ * });
164
+ * }
165
+ * });
166
+ */
167
+ 'onDeactivate',
168
+
169
+ /**
170
+ * Fires when something in the body of the editor is clicked.
171
+ *
172
+ * @event onClick
173
+ * @param {tinymce.Editor} sender Editor instance.
174
+ * @param {Event} evt W3C DOM Event instance.
175
+ * @example
176
+ * // Adds an observer to the onClick event using tinyMCE.init
177
+ * tinyMCE.init({
178
+ * ...
179
+ * setup : function(ed) {
180
+ * ed.onClick.add(function(ed, e) {
181
+ * console.debug('Editor was clicked: ' + e.target.nodeName);
182
+ * });
183
+ * }
184
+ * });
185
+ */
186
+ 'onClick',
187
+
188
+ /**
189
+ * Fires when a registered event is intercepted.
190
+ *
191
+ * @event onEvent
192
+ * @param {tinymce.Editor} sender Editor instance.
193
+ * @param {Event} evt W3C DOM Event instance.
194
+ * @example
195
+ * // Adds an observer to the onEvent event using tinyMCE.init
196
+ * tinyMCE.init({
197
+ * ...
198
+ * setup : function(ed) {
199
+ * ed.onEvent.add(function(ed, e) {
200
+ * console.debug('Editor event occurred: ' + e.target.nodeName);
201
+ * });
202
+ * }
203
+ * });
204
+ */
205
+ 'onEvent',
206
+
207
+ /**
208
+ * Fires when a mouseup event is intercepted inside the editor.
209
+ *
210
+ * @event onMouseUp
211
+ * @param {tinymce.Editor} sender Editor instance.
212
+ * @param {Event} evt W3C DOM Event instance.
213
+ * @example
214
+ * // Adds an observer to the onMouseUp event using tinyMCE.init
215
+ * tinyMCE.init({
216
+ * ...
217
+ * setup : function(ed) {
218
+ * ed.onMouseUp.add(function(ed, e) {
219
+ * console.debug('Mouse up event: ' + e.target.nodeName);
220
+ * });
221
+ * }
222
+ * });
223
+ */
224
+ 'onMouseUp',
225
+
226
+ /**
227
+ * Fires when a mousedown event is intercepted inside the editor.
228
+ *
229
+ * @event onMouseDown
230
+ * @param {tinymce.Editor} sender Editor instance.
231
+ * @param {Event} evt W3C DOM Event instance.
232
+ * @example
233
+ * // Adds an observer to the onMouseDown event using tinyMCE.init
234
+ * tinyMCE.init({
235
+ * ...
236
+ * setup : function(ed) {
237
+ * ed.onMouseDown.add(function(ed, e) {
238
+ * console.debug('Mouse down event: ' + e.target.nodeName);
239
+ * });
240
+ * }
241
+ * });
242
+ */
243
+ 'onMouseDown',
244
+
245
+ /**
246
+ * Fires when a dblclick event is intercepted inside the editor.
247
+ *
248
+ * @event onDblClick
249
+ * @param {tinymce.Editor} sender Editor instance.
250
+ * @param {Event} evt W3C DOM Event instance.
251
+ * @example
252
+ * // Adds an observer to the onDblClick event using tinyMCE.init
253
+ * tinyMCE.init({
254
+ * ...
255
+ * setup : function(ed) {
256
+ * ed.onDblClick.add(function(ed, e) {
257
+ * console.debug('Double click event: ' + e.target.nodeName);
258
+ * });
259
+ * }
260
+ * });
261
+ */
262
+ 'onDblClick',
263
+
264
+ /**
265
+ * Fires when a keydown event is intercepted inside the editor.
266
+ *
267
+ * @event onKeyDown
268
+ * @param {tinymce.Editor} sender Editor instance.
269
+ * @param {Event} evt W3C DOM Event instance.
270
+ * @example
271
+ * // Adds an observer to the onKeyDown event using tinyMCE.init
272
+ * tinyMCE.init({
273
+ * ...
274
+ * setup : function(ed) {
275
+ * ed.onKeyDown.add(function(ed, e) {
276
+ * console.debug('Key down event: ' + e.keyCode);
277
+ * });
278
+ * }
279
+ * });
280
+ */
281
+ 'onKeyDown',
282
+
283
+ /**
284
+ * Fires when a keydown event is intercepted inside the editor.
285
+ *
286
+ * @event onKeyUp
287
+ * @param {tinymce.Editor} sender Editor instance.
288
+ * @param {Event} evt W3C DOM Event instance.
289
+ * @example
290
+ * // Adds an observer to the onKeyUp event using tinyMCE.init
291
+ * tinyMCE.init({
292
+ * ...
293
+ * setup : function(ed) {
294
+ * ed.onKeyUp.add(function(ed, e) {
295
+ * console.debug('Key up event: ' + e.keyCode);
296
+ * });
297
+ * }
298
+ * });
299
+ */
300
+ 'onKeyUp',
301
+
302
+ /**
303
+ * Fires when a keypress event is intercepted inside the editor.
304
+ *
305
+ * @event onKeyPress
306
+ * @param {tinymce.Editor} sender Editor instance.
307
+ * @param {Event} evt W3C DOM Event instance.
308
+ * @example
309
+ * // Adds an observer to the onKeyPress event using tinyMCE.init
310
+ * tinyMCE.init({
311
+ * ...
312
+ * setup : function(ed) {
313
+ * ed.onKeyPress.add(function(ed, e) {
314
+ * console.debug('Key press event: ' + e.keyCode);
315
+ * });
316
+ * }
317
+ * });
318
+ */
319
+ 'onKeyPress',
320
+
321
+ /**
322
+ * Fires when a contextmenu event is intercepted inside the editor.
323
+ *
324
+ * @event onContextMenu
325
+ * @param {tinymce.Editor} sender Editor instance.
326
+ * @param {Event} evt W3C DOM Event instance.
327
+ * @example
328
+ * // Adds an observer to the onContextMenu event using tinyMCE.init
329
+ * tinyMCE.init({
330
+ * ...
331
+ * setup : function(ed) {
332
+ * ed.onContextMenu.add(function(ed, e) {
333
+ * console.debug('Context menu event:' + e.target);
334
+ * });
335
+ * }
336
+ * });
337
+ */
338
+ 'onContextMenu',
339
+
340
+ /**
341
+ * Fires when a form submit event is intercepted.
342
+ *
343
+ * @event onSubmit
344
+ * @param {tinymce.Editor} sender Editor instance.
345
+ * @param {Event} evt W3C DOM Event instance.
346
+ * @example
347
+ * // Adds an observer to the onSubmit event using tinyMCE.init
348
+ * tinyMCE.init({
349
+ * ...
350
+ * setup : function(ed) {
351
+ * ed.onSubmit.add(function(ed, e) {
352
+ * console.debug('Form submit:' + e.target);
353
+ * });
354
+ * }
355
+ * });
356
+ */
357
+ 'onSubmit',
358
+
359
+ /**
360
+ * Fires when a form reset event is intercepted.
361
+ *
362
+ * @event onReset
363
+ * @param {tinymce.Editor} sender Editor instance.
364
+ * @param {Event} evt W3C DOM Event instance.
365
+ * @example
366
+ * // Adds an observer to the onReset event using tinyMCE.init
367
+ * tinyMCE.init({
368
+ * ...
369
+ * setup : function(ed) {
370
+ * ed.onReset.add(function(ed, e) {
371
+ * console.debug('Form reset:' + e.target);
372
+ * });
373
+ * }
374
+ * });
375
+ */
376
+ 'onReset',
377
+
378
+ /**
379
+ * Fires when a paste event is intercepted inside the editor.
380
+ *
381
+ * @event onPaste
382
+ * @param {tinymce.Editor} sender Editor instance.
383
+ * @param {Event} evt W3C DOM Event instance.
384
+ * @example
385
+ * // Adds an observer to the onPaste event using tinyMCE.init
386
+ * tinyMCE.init({
387
+ * ...
388
+ * setup : function(ed) {
389
+ * ed.onPaste.add(function(ed, e) {
390
+ * console.debug('Pasted plain text');
391
+ * });
392
+ * }
393
+ * });
394
+ */
395
+ 'onPaste',
396
+
397
+ /**
398
+ * Fires when the Serializer does a preProcess on the contents.
399
+ *
400
+ * @event onPreProcess
401
+ * @param {tinymce.Editor} sender Editor instance.
402
+ * @param {Object} obj PreProcess object.
403
+ * @option {Node} node DOM node for the item being serialized.
404
+ * @option {String} format The specified output format normally "html".
405
+ * @option {Boolean} get Is true if the process is on a getContent operation.
406
+ * @option {Boolean} set Is true if the process is on a setContent operation.
407
+ * @option {Boolean} cleanup Is true if the process is on a cleanup operation.
408
+ * @example
409
+ * // Adds an observer to the onPreProcess event using tinyMCE.init
410
+ * tinyMCE.init({
411
+ * ...
412
+ * setup : function(ed) {
413
+ * ed.onPreProcess.add(function(ed, o) {
414
+ * // Add a class to each paragraph in the editor
415
+ * ed.dom.addClass(ed.dom.select('p', o.node), 'myclass');
416
+ * });
417
+ * }
418
+ * });
419
+ */
420
+ 'onPreProcess',
421
+
422
+ /**
423
+ * Fires when the Serializer does a postProcess on the contents.
424
+ *
425
+ * @event onPostProcess
426
+ * @param {tinymce.Editor} sender Editor instance.
427
+ * @param {Object} obj PreProcess object.
428
+ * @example
429
+ * // Adds an observer to the onPostProcess event using tinyMCE.init
430
+ * tinyMCE.init({
431
+ * ...
432
+ * setup : function(ed) {
433
+ * ed.onPostProcess.add(function(ed, o) {
434
+ * // Remove all paragraphs and replace with BR
435
+ * o.content = o.content.replace(/<p[^>]+>|<p>/g, '');
436
+ * o.content = o.content.replace(/<\/p>/g, '<br />');
437
+ * });
438
+ * }
439
+ * });
440
+ */
441
+ 'onPostProcess',
442
+
443
+ /**
444
+ * Fires before new contents is added to the editor. Using for example setContent.
445
+ *
446
+ * @event onBeforeSetContent
447
+ * @param {tinymce.Editor} sender Editor instance.
448
+ * @example
449
+ * // Adds an observer to the onBeforeSetContent event using tinyMCE.init
450
+ * tinyMCE.init({
451
+ * ...
452
+ * setup : function(ed) {
453
+ * ed.onBeforeSetContent.add(function(ed, o) {
454
+ * // Replaces all a characters with b characters
455
+ * o.content = o.content.replace(/a/g, 'b');
456
+ * });
457
+ * }
458
+ * });
459
+ */
460
+ 'onBeforeSetContent',
461
+
462
+ /**
463
+ * Fires before contents is extracted from the editor using for example getContent.
464
+ *
465
+ * @event onBeforeGetContent
466
+ * @param {tinymce.Editor} sender Editor instance.
467
+ * @param {Event} evt W3C DOM Event instance.
468
+ * @example
469
+ * // Adds an observer to the onBeforeGetContent event using tinyMCE.init
470
+ * tinyMCE.init({
471
+ * ...
472
+ * setup : function(ed) {
473
+ * ed.onBeforeGetContent.add(function(ed, o) {
474
+ * console.debug('Before get content.');
475
+ * });
476
+ * }
477
+ * });
478
+ */
479
+ 'onBeforeGetContent',
480
+
481
+ /**
482
+ * Fires after the contents has been added to the editor using for example onSetContent.
483
+ *
484
+ * @event onSetContent
485
+ * @param {tinymce.Editor} sender Editor instance.
486
+ * @example
487
+ * // Adds an observer to the onSetContent event using tinyMCE.init
488
+ * tinyMCE.init({
489
+ * ...
490
+ * setup : function(ed) {
491
+ * ed.onSetContent.add(function(ed, o) {
492
+ * // Replaces all a characters with b characters
493
+ * o.content = o.content.replace(/a/g, 'b');
494
+ * });
495
+ * }
496
+ * });
497
+ */
498
+ 'onSetContent',
499
+
500
+ /**
501
+ * Fires after the contents has been extracted from the editor using for example getContent.
502
+ *
503
+ * @event onGetContent
504
+ * @param {tinymce.Editor} sender Editor instance.
505
+ * @example
506
+ * // Adds an observer to the onGetContent event using tinyMCE.init
507
+ * tinyMCE.init({
508
+ * ...
509
+ * setup : function(ed) {
510
+ * ed.onGetContent.add(function(ed, o) {
511
+ * // Replace all a characters with b
512
+ * o.content = o.content.replace(/a/g, 'b');
513
+ * });
514
+ * }
515
+ * });
516
+ */
517
+ 'onGetContent',
518
+
519
+ /**
520
+ * Fires when the editor gets loaded with contents for example when the load method is executed.
521
+ *
522
+ * @event onLoadContent
523
+ * @param {tinymce.Editor} sender Editor instance.
524
+ * @example
525
+ * // Adds an observer to the onLoadContent event using tinyMCE.init
526
+ * tinyMCE.init({
527
+ * ...
528
+ * setup : function(ed) {
529
+ * ed.onLoadContent.add(function(ed, o) {
530
+ * // Output the element name
531
+ * console.debug(o.element.nodeName);
532
+ * });
533
+ * }
534
+ * });
535
+ */
536
+ 'onLoadContent',
537
+
538
+ /**
539
+ * Fires when the editor contents gets saved for example when the save method is executed.
540
+ *
541
+ * @event onSaveContent
542
+ * @param {tinymce.Editor} sender Editor instance.
543
+ * @example
544
+ * // Adds an observer to the onSaveContent event using tinyMCE.init
545
+ * tinyMCE.init({
546
+ * ...
547
+ * setup : function(ed) {
548
+ * ed.onSaveContent.add(function(ed, o) {
549
+ * // Output the element name
550
+ * console.debug(o.element.nodeName);
551
+ * });
552
+ * }
553
+ * });
554
+ */
555
+ 'onSaveContent',
556
+
557
+ /**
558
+ * Fires when the user changes node location using the mouse or keyboard.
559
+ *
560
+ * @event onNodeChange
561
+ * @param {tinymce.Editor} sender Editor instance.
562
+ * @example
563
+ * // Adds an observer to the onNodeChange event using tinyMCE.init
564
+ * tinyMCE.init({
565
+ * ...
566
+ * setup : function(ed) {
567
+ * ed.onNodeChange.add(function(ed, cm, e) {
568
+ * // Activates the link button when the caret is placed in a anchor element
569
+ * if (e.nodeName == 'A')
570
+ * cm.setActive('link', true);
571
+ * });
572
+ * }
573
+ * });
574
+ */
575
+ 'onNodeChange',
576
+
577
+ /**
578
+ * Fires when a new undo level is added to the editor.
579
+ *
580
+ * @event onChange
581
+ * @param {tinymce.Editor} sender Editor instance.
582
+ * @example
583
+ * // Adds an observer to the onChange event using tinyMCE.init
584
+ * tinyMCE.init({
585
+ * ...
586
+ * setup : function(ed) {
587
+ * ed.onChange.add(function(ed, l) {
588
+ * console.debug('Editor contents was modified. Contents: ' + l.content);
589
+ * });
590
+ * }
591
+ * });
592
+ */
593
+ 'onChange',
594
+
595
+ /**
596
+ * Fires before a command gets executed for example "Bold".
597
+ *
598
+ * @event onBeforeExecCommand
599
+ * @param {tinymce.Editor} sender Editor instance.
600
+ * @example
601
+ * // Adds an observer to the onBeforeExecCommand event using tinyMCE.init
602
+ * tinyMCE.init({
603
+ * ...
604
+ * setup : function(ed) {
605
+ * ed.onBeforeExecCommand.add(function(ed, cmd, ui, val) {
606
+ * console.debug('Command is to be executed: ' + cmd);
607
+ * });
608
+ * }
609
+ * });
610
+ */
611
+ 'onBeforeExecCommand',
612
+
613
+ /**
614
+ * Fires after a command is executed for example "Bold".
615
+ *
616
+ * @event onExecCommand
617
+ * @param {tinymce.Editor} sender Editor instance.
618
+ * @example
619
+ * // Adds an observer to the onExecCommand event using tinyMCE.init
620
+ * tinyMCE.init({
621
+ * ...
622
+ * setup : function(ed) {
623
+ * ed.onExecCommand.add(function(ed, cmd, ui, val) {
624
+ * console.debug('Command was executed: ' + cmd);
625
+ * });
626
+ * }
627
+ * });
628
+ */
629
+ 'onExecCommand',
630
+
631
+ /**
632
+ * Fires when the contents is undo:ed.
633
+ *
634
+ * @event onUndo
635
+ * @param {tinymce.Editor} sender Editor instance.
636
+ * @param {Object} level Undo level object.
637
+ * @ example
638
+ * // Adds an observer to the onUndo event using tinyMCE.init
639
+ * tinyMCE.init({
640
+ * ...
641
+ * setup : function(ed) {
642
+ * ed.onUndo.add(function(ed, level) {
643
+ * console.debug('Undo was performed: ' + level.content);
644
+ * });
645
+ * }
646
+ * });
647
+ */
648
+ 'onUndo',
649
+
650
+ /**
651
+ * Fires when the contents is redo:ed.
652
+ *
653
+ * @event onRedo
654
+ * @param {tinymce.Editor} sender Editor instance.
655
+ * @param {Object} level Undo level object.
656
+ * @example
657
+ * // Adds an observer to the onRedo event using tinyMCE.init
658
+ * tinyMCE.init({
659
+ * ...
660
+ * setup : function(ed) {
661
+ * ed.onRedo.add(function(ed, level) {
662
+ * console.debug('Redo was performed: ' +level.content);
663
+ * });
664
+ * }
665
+ * });
666
+ */
667
+ 'onRedo',
668
+
669
+ /**
670
+ * Fires when visual aids is enabled/disabled.
671
+ *
672
+ * @event onVisualAid
673
+ * @param {tinymce.Editor} sender Editor instance.
674
+ * @example
675
+ * // Adds an observer to the onVisualAid event using tinyMCE.init
676
+ * tinyMCE.init({
677
+ * ...
678
+ * setup : function(ed) {
679
+ * ed.onVisualAid.add(function(ed, e, s) {
680
+ * console.debug('onVisualAid event: ' + ed.id + ", State: " + s);
681
+ * });
682
+ * }
683
+ * });
684
+ */
685
+ 'onVisualAid',
686
+
687
+ /**
688
+ * Fires when the progress throbber is shown above the editor.
689
+ *
690
+ * @event onSetProgressState
691
+ * @param {tinymce.Editor} sender Editor instance.
692
+ * @example
693
+ * // Adds an observer to the onSetProgressState event using tinyMCE.init
694
+ * tinyMCE.init({
695
+ * ...
696
+ * setup : function(ed) {
697
+ * ed.onSetProgressState.add(function(ed, b) {
698
+ * if (b)
699
+ * console.debug('SHOW!');
700
+ * else
701
+ * console.debug('HIDE!');
702
+ * });
703
+ * }
704
+ * });
705
+ */
706
+ 'onSetProgressState',
707
+
708
+ /**
709
+ * Fires after an attribute is set using setAttrib.
710
+ *
711
+ * @event onSetAttrib
712
+ * @param {tinymce.Editor} sender Editor instance.
713
+ * @example
714
+ * // Adds an observer to the onSetAttrib event using tinyMCE.init
715
+ *tinyMCE.init({
716
+ * ...
717
+ * setup : function(ed) {
718
+ * ed.onSetAttrib.add(function(ed, node, attribute, attributeValue) {
719
+ * console.log('onSetAttrib tag');
720
+ * });
721
+ * }
722
+ * });
723
+ */
724
+ 'onSetAttrib'
725
+ ], function(name) {
726
+ self[name] = new tinymce.util.Dispatcher(self);
727
+ });
728
+
729
+ // Handle legacy cleanup_callback option
730
+ if (settings.cleanup_callback) {
731
+ self.onBeforeSetContent.add(function(ed, o) {
732
+ o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
733
+ });
734
+
735
+ self.onPreProcess.add(function(ed, o) {
736
+ if (o.set)
737
+ ed.execCallback('cleanup_callback', 'insert_to_editor_dom', o.node, o);
738
+
739
+ if (o.get)
740
+ ed.execCallback('cleanup_callback', 'get_from_editor_dom', o.node, o);
741
+ });
742
+
743
+ self.onPostProcess.add(function(ed, o) {
744
+ if (o.set)
745
+ o.content = ed.execCallback('cleanup_callback', 'insert_to_editor', o.content, o);
746
+
747
+ if (o.get)
748
+ o.content = ed.execCallback('cleanup_callback', 'get_from_editor', o.content, o);
749
+ });
750
+ }
751
+
752
+ // Handle legacy save_callback option
753
+ if (settings.save_callback) {
754
+ self.onGetContent.add(function(ed, o) {
755
+ if (o.save)
756
+ o.content = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
757
+ });
758
+ }
759
+
760
+ // Handle legacy handle_event_callback option
761
+ if (settings.handle_event_callback) {
762
+ self.onEvent.add(function(ed, e, o) {
763
+ if (self.execCallback('handle_event_callback', e, ed, o) === false) {
764
+ e.preventDefault();
765
+ e.stopPropagation();
766
+ }
767
+ });
768
+ }
769
+
770
+ // Handle legacy handle_node_change_callback option
771
+ if (settings.handle_node_change_callback) {
772
+ self.onNodeChange.add(function(ed, cm, n) {
773
+ ed.execCallback('handle_node_change_callback', ed.id, n, -1, -1, true, ed.selection.isCollapsed());
774
+ });
775
+ }
776
+
777
+ // Handle legacy save_callback option
778
+ if (settings.save_callback) {
779
+ self.onSaveContent.add(function(ed, o) {
780
+ var h = ed.execCallback('save_callback', ed.id, o.content, ed.getBody());
781
+
782
+ if (h)
783
+ o.content = h;
784
+ });
785
+ }
786
+
787
+ // Handle legacy onchange_callback option
788
+ if (settings.onchange_callback) {
789
+ self.onChange.add(function(ed, l) {
790
+ ed.execCallback('onchange_callback', ed, l);
791
+ });
792
+ }
793
+ };
794
+
795
+ /**
796
+ * Binds native DOM events and sends these out to the dispatchers.
797
+ */
798
+ tinymce.Editor.prototype.bindNativeEvents = function() {
799
+ // 'focus', 'blur', 'dblclick', 'beforedeactivate', submit, reset
800
+ var self = this, i, settings = self.settings, dom = self.dom, nativeToDispatcherMap;
801
+
802
+ nativeToDispatcherMap = {
803
+ mouseup : 'onMouseUp',
804
+ mousedown : 'onMouseDown',
805
+ click : 'onClick',
806
+ keyup : 'onKeyUp',
807
+ keydown : 'onKeyDown',
808
+ keypress : 'onKeyPress',
809
+ submit : 'onSubmit',
810
+ reset : 'onReset',
811
+ contextmenu : 'onContextMenu',
812
+ dblclick : 'onDblClick',
813
+ paste : 'onPaste' // Doesn't work in all browsers yet
814
+ };
815
+
816
+ // Handler that takes a native event and sends it out to a dispatcher like onKeyDown
817
+ function eventHandler(evt, args) {
818
+ var type = evt.type;
819
+
820
+ // Don't fire events when it's removed
821
+ if (self.removed)
822
+ return;
823
+
824
+ // Sends the native event out to a global dispatcher then to the specific event dispatcher
825
+ if (self.onEvent.dispatch(self, evt, args) !== false) {
826
+ self[nativeToDispatcherMap[evt.fakeType || evt.type]].dispatch(self, evt, args);
827
+ }
828
+ };
829
+
830
+ // Opera doesn't support focus event for contentEditable elements so we need to fake it
831
+ function doOperaFocus(e) {
832
+ self.focus(true);
833
+ };
834
+
835
+ function nodeChanged(ed, e) {
836
+ // Normalize selection for example <b>a</b><i>|a</i> becomes <b>a|</b><i>a</i> except for Ctrl+A since it selects everything
837
+ if (e.keyCode != 65 || !tinymce.VK.metaKeyPressed(e)) {
838
+ self.selection.normalize();
839
+ }
840
+
841
+ self.nodeChanged();
842
+ }
843
+
844
+ // Add DOM events
845
+ each(nativeToDispatcherMap, function(dispatcherName, nativeName) {
846
+ var root = settings.content_editable ? self.getBody() : self.getDoc();
847
+
848
+ switch (nativeName) {
849
+ case 'contextmenu':
850
+ dom.bind(root, nativeName, eventHandler);
851
+ break;
852
+
853
+ case 'paste':
854
+ dom.bind(self.getBody(), nativeName, eventHandler);
855
+ break;
856
+
857
+ case 'submit':
858
+ case 'reset':
859
+ dom.bind(self.getElement().form || tinymce.DOM.getParent(self.id, 'form'), nativeName, eventHandler);
860
+ break;
861
+
862
+ default:
863
+ dom.bind(root, nativeName, eventHandler);
864
+ }
865
+ });
866
+
867
+ // Set the editor as active when focused
868
+ dom.bind(settings.content_editable ? self.getBody() : (tinymce.isGecko ? self.getDoc() : self.getWin()), 'focus', function(e) {
869
+ self.focus(true);
870
+ });
871
+
872
+ if (settings.content_editable && tinymce.isOpera) {
873
+ dom.bind(self.getBody(), 'click', doOperaFocus);
874
+ dom.bind(self.getBody(), 'keydown', doOperaFocus);
875
+ }
876
+
877
+ // Add node change handler
878
+ self.onMouseUp.add(nodeChanged);
879
+
880
+ self.onKeyUp.add(function(ed, e) {
881
+ var keyCode = e.keyCode;
882
+
883
+ if ((keyCode >= 33 && keyCode <= 36) || (keyCode >= 37 && keyCode <= 40) || keyCode == 13 || keyCode == 45 || keyCode == 46 || keyCode == 8 || (tinymce.isMac && (keyCode == 91 || keyCode == 93)) || e.ctrlKey)
884
+ nodeChanged(ed, e);
885
+ });
886
+
887
+ // Add reset handler
888
+ self.onReset.add(function() {
889
+ self.setContent(self.startContent, {format : 'raw'});
890
+ });
891
+
892
+ // Add shortcuts
893
+ function handleShortcut(e, execute) {
894
+ if (e.altKey || e.ctrlKey || e.metaKey) {
895
+ each(self.shortcuts, function(shortcut) {
896
+ var ctrlState = tinymce.isMac ? e.metaKey : e.ctrlKey;
897
+
898
+ if (shortcut.ctrl != ctrlState || shortcut.alt != e.altKey || shortcut.shift != e.shiftKey)
899
+ return;
900
+
901
+ if (e.keyCode == shortcut.keyCode || (e.charCode && e.charCode == shortcut.charCode)) {
902
+ e.preventDefault();
903
+
904
+ if (execute) {
905
+ shortcut.func.call(shortcut.scope);
906
+ }
907
+
908
+ return true;
909
+ }
910
+ });
911
+ }
912
+ };
913
+
914
+ self.onKeyUp.add(function(ed, e) {
915
+ handleShortcut(e);
916
+ });
917
+
918
+ self.onKeyPress.add(function(ed, e) {
919
+ handleShortcut(e);
920
+ });
921
+
922
+ self.onKeyDown.add(function(ed, e) {
923
+ handleShortcut(e, true);
924
+ });
925
+
926
+ if (tinymce.isOpera) {
927
+ self.onClick.add(function(ed, e) {
928
+ e.preventDefault();
929
+ });
930
+ }
931
+ };
932
+ })(tinymce);
js/tiny_mce/classes/Editor.js CHANGED
@@ -1,20 +1,20 @@
1
/**
2
* Editor.js
3
*
4
- * Copyright 2009, Moxiecode Systems AB
5
* Released under LGPL License.
6
*
7
- * License: http://tinymce.moxiecode.com/license
8
- * Contributing: http://tinymce.moxiecode.com/contributing
9
*/
10
11
(function(tinymce) {
12
// Shorten these names
13
var DOM = tinymce.DOM, Event = tinymce.dom.Event, extend = tinymce.extend,
14
- Dispatcher = tinymce.util.Dispatcher, each = tinymce.each, isGecko = tinymce.isGecko,
15
isIE = tinymce.isIE, isWebKit = tinymce.isWebKit, is = tinymce.is,
16
ThemeManager = tinymce.ThemeManager, PluginManager = tinymce.PluginManager,
17
- inArray = tinymce.inArray, grep = tinymce.grep, explode = tinymce.explode;
18
19
/**
20
* This class contains the core logic for a TinyMCE editor.
@@ -46,11 +46,63 @@
46
* @constructor
47
* @method Editor
48
* @param {String} id Unique id for the editor.
49
- * @param {Object} s Optional settings string for the editor.
50
* @author Moxiecode
51
*/
52
- Editor : function(id, s) {
53
- var t = this;
54
55
/**
56
* Editor instance id, normally the same as the div/textarea that was replaced.
@@ -58,11 +110,7 @@
58
* @property id
59
* @type String
60
*/
61
- t.id = t.editorId = id;
62
-
63
- t.execCommands = {};
64
- t.queryStateCommands = {};
65
- t.queryValueCommands = {};
66
67
/**
68
* State to force the editor to return false on a isDirty call.
@@ -79,7 +127,7 @@
79
* ed.isNotDirty = 1; // Force not dirty state
80
* }
81
*/
82
- t.isNotDirty = false;
83
84
/**
85
* Name/Value object containting plugin instances.
@@ -90,741 +138,7 @@
90
* // Execute a method inside a plugin directly
91
* tinyMCE.activeEditor.plugins.someplugin.someMethod();
92
*/
93
- t.plugins = {};
94
-
95
- // Add events to the editor
96
- each([
97
- /**
98
- * Fires before the initialization of the editor.
99
- *
100
- * @event onPreInit
101
- * @param {tinymce.Editor} sender Editor instance.
102
- * @see #onInit
103
- * @example
104
- * // Adds an observer to the onPreInit event using tinyMCE.init
105
- * tinyMCE.init({
106
- * ...
107
- * setup : function(ed) {
108
- * ed.onPreInit.add(function(ed) {
109
- * console.debug('PreInit: ' + ed.id);
110
- * });
111
- * }
112
- * });
113
- */
114
- 'onPreInit',
115
-
116
- /**
117
- * Fires before the initialization of the editor.
118
- *
119
- * @event onBeforeRenderUI
120
- * @param {tinymce.Editor} sender Editor instance.
121
- * @example
122
- * // Adds an observer to the onBeforeRenderUI event using tinyMCE.init
123
- * tinyMCE.init({
124
- * ...
125
- * setup : function(ed) {
126
- * ed.onBeforeRenderUI.add(function(ed, cm) {
127
- * console.debug('Before render: ' + ed.id);
128
- * });
129
- * }
130
- * });
131
- */
132
- 'onBeforeRenderUI',
133
-
134
- /**
135
- * Fires after the rendering has completed.
136
- *
137
- * @event onPostRender
138
- * @param {tinymce.Editor} sender Editor instance.
139
- * @example
140
- * // Adds an observer to the onPostRender event using tinyMCE.init
141
- * tinyMCE.init({
142
- * ...
143
- * setup : function(ed) {
144
- * ed.onPostRender.add(function(ed, cm) {
145
- * console.debug('After render: ' + ed.id);
146
- * });
147
- * }
148
- * });
149
- */
150
- 'onPostRender',
151
-
152
- /**
153
- * Fires after the initialization of the editor is done.
154
- *
155
- * @event onInit
156
- * @param {tinymce.Editor} sender Editor instance.
157
- * @see #onPreInit
158
- * @example
159
- * // Adds an observer to the onInit event using tinyMCE.init
160
- * tinyMCE.init({
161
- * ...
162
- * setup : function(ed) {
163
- * ed.onInit.add(function(ed) {
164
- * console.debug('Editor is done: ' + ed.id);
165
- * });
166
- * }
167
- * });
168
- */
169
- 'onInit',
170
-
171
- /**
172
- * Fires when the editor instance is removed from page.
173
- *
174
- * @event onRemove
175
- * @param {tinymce.Editor} sender Editor instance.
176
- * @example
177
- * // Adds an observer to the onRemove event using tinyMCE.init
178
- * tinyMCE.init({
179
- * ...
180
- * setup : function(ed) {
181
- * ed.onRemove.add(function(ed) {
182
- * console.debug('Editor was removed: ' + ed.id);
183
- * });
184
- * }
185
- * });
186
- */
187
- 'onRemove',
188
-
189
- /**
190
- * Fires when the editor is activated.
191
- *
192
- * @event onActivate
193
- * @param {tinymce.Editor} sender Editor instance.
194
- * @example
195
- * // Adds an observer to the onActivate event using tinyMCE.init
196
- * tinyMCE.init({
197
- * ...
198
- * setup : function(ed) {
199
- * ed.onActivate.add(function(ed) {
200
- * console.debug('Editor was activated: ' + ed.id);
201
- * });
202
- * }
203
- * });
204
- */
205
- 'onActivate',
206
-
207
- /**
208
- * Fires when the editor is deactivated.
209
- *
210
- * @event onDeactivate
211
- * @param {tinymce.Editor} sender Editor instance.
212
- * @example
213
- * // Adds an observer to the onDeactivate event using tinyMCE.init
214
- * tinyMCE.init({
215
- * ...
216
- * setup : function(ed) {
217
- * ed.onDeactivate.add(function(ed) {
218
- * console.debug('Editor was deactivated: ' + ed.id);
219
- * });
220
- * }
221
- * });
222
- */
223
- 'onDeactivate',
224
-
225
- /**
226
- * Fires when something in the body of the editor is clicked.
227
- *
228
- * @event onClick
229
- * @param {tinymce.Editor} sender Editor instance.
230
- * @param {Event} evt W3C DOM Event instance.
231
- * @example
232
- * // Adds an observer to the onClick event using tinyMCE.init
233
- * tinyMCE.init({
234
- * ...
235
- * setup : function(ed) {
236
- * ed.onClick.add(function(ed, e) {
237
- * console.debug('Editor was clicked: ' + e.target.nodeName);
238
- * });
239
- * }
240
- * });
241
- */
242
- 'onClick',
243
-
244
- /**
245
- * Fires when a registered event is intercepted.
246
- *
247
- * @event onEvent
248
- * @param {tinymce.Editor} sender Editor instance.
249
- * @param {Event} evt W3C DOM Event instance.
250
- * @example
251
- * // Adds an observer to the onEvent event using tinyMCE.init
252
- * tinyMCE.init({
253
- * ...
254
- * setup : function(ed) {
255
- * ed.onEvent.add(function(ed, e) {
256
- * console.debug('Editor event occured: ' + e.target.nodeName);
257
- * });
258
- * }
259
- * });
260
- */
261
- 'onEvent',
262
-
263
- /**
264
- * Fires when a mouseup event is intercepted inside the editor.
265
- *
266
- * @event onMouseUp
267
- * @param {tinymce.Editor} sender Editor instance.
268
- * @param {Event} evt W3C DOM Event instance.
269
- * @example
270
- * // Adds an observer to the onMouseUp event using tinyMCE.init
271
- * tinyMCE.init({
272
- * ...
273
- * setup : function(ed) {
274
- * ed.onMouseUp.add(function(ed, e) {
275
- * console.debug('Mouse up event: ' + e.target.nodeName);
276
- * });
277
- * }
278
- * });
279
- */
280
- 'onMouseUp',
281
-
282
- /**
283
- * Fires when a mousedown event is intercepted inside the editor.
284
- *
285
- * @event onMouseDown
286
- * @param {tinymce.Editor} sender Editor instance.
287
- * @param {Event} evt W3C DOM Event instance.
288
- * @example
289
- * // Adds an observer to the onMouseDown event using tinyMCE.init
290
- * tinyMCE.init({
291
- * ...
292
- * setup : function(ed) {
293
- * ed.onMouseDown.add(function(ed, e) {
294
- * console.debug('Mouse down event: ' + e.target.nodeName);
295
- * });
296
- * }
297
- * });
298
- */
299
- 'onMouseDown',
300
-
301
- /**
302
- * Fires when a dblclick event is intercepted inside the editor.
303
- *
304
- * @event onDblClick
305
- * @param {tinymce.Editor} sender Editor instance.
306
- * @param {Event} evt W3C DOM Event instance.
307
- * @example
308
- * // Adds an observer to the onDblClick event using tinyMCE.init
309
- * tinyMCE.init({
310
- * ...
311
- * setup : function(ed) {
312
- * ed.onDblClick.add(function(ed, e) {
313
- * console.debug('Double click event: ' + e.target.nodeName);
314
- * });
315
- * }
316
- * });
317
- */
318
- 'onDblClick',
319
-
320
- /**
321
- * Fires when a keydown event is intercepted inside the editor.
322
- *
323
- * @event onKeyDown
324
- * @param {tinymce.Editor} sender Editor instance.
325
- * @param {Event} evt W3C DOM Event instance.
326
- * @example
327
- * // Adds an observer to the onKeyDown event using tinyMCE.init
328
- * tinyMCE.init({
329
- * ...
330
- * setup : function(ed) {
331
- * ed.onKeyDown.add(function(ed, e) {
332
- * console.debug('Key down event: ' + e.keyCode);
333
- * });
334
- * }
335
- * });
336
- */
337
- 'onKeyDown',
338
-
339
- /**
340
- * Fires when a keydown event is intercepted inside the editor.
341
- *
342
- * @event onKeyUp
343
- * @param {tinymce.Editor} sender Editor instance.
344
- * @param {Event} evt W3C DOM Event instance.
345
- * @example
346
- * // Adds an observer to the onKeyUp event using tinyMCE.init
347
- * tinyMCE.init({
348
- * ...
349
- * setup : function(ed) {
350
- * ed.onKeyUp.add(function(ed, e) {
351
- * console.debug('Key up event: ' + e.keyCode);
352
- * });
353
- * }
354
- * });
355
- */
356
- 'onKeyUp',
357
-
358
- /**
359
- * Fires when a keypress event is intercepted inside the editor.
360
- *
361
- * @event onKeyPress
362
- * @param {tinymce.Editor} sender Editor instance.
363
- * @param {Event} evt W3C DOM Event instance.
364
- * @example
365
- * // Adds an observer to the onKeyPress event using tinyMCE.init
366
- * tinyMCE.init({
367
- * ...
368
- * setup : function(ed) {
369
- * ed.onKeyPress.add(function(ed, e) {
370
- * console.debug('Key press event: ' + e.keyCode);
371
- * });
372
- * }
373
- * });
374
- */
375
- 'onKeyPress',
376
-
377
- /**
378
- * Fires when a contextmenu event is intercepted inside the editor.
379
- *
380
- * @event onContextMenu
381
- * @param {tinymce.Editor} sender Editor instance.
382
- * @param {Event} evt W3C DOM Event instance.
383
- * @example
384
- * // Adds an observer to the onContextMenu event using tinyMCE.init
385
- * tinyMCE.init({
386
- * ...
387
- * setup : function(ed) {
388
- * ed.onContextMenu.add(function(ed, e) {
389
- * console.debug('Context menu event:' + e.target);
390
- * });
391
- * }
392
- * });
393
- */
394
- 'onContextMenu',
395
-
396
- /**
397
- * Fires when a form submit event is intercepted.
398
- *
399
- * @event onSubmit
400
- * @param {tinymce.Editor} sender Editor instance.
401
- * @param {Event} evt W3C DOM Event instance.
402
- * @example
403
- * // Adds an observer to the onSubmit event using tinyMCE.init
404
- * tinyMCE.init({
405
- * ...
406
- * setup : function(ed) {
407
- * ed.onSubmit.add(function(ed, e) {
408
- * console.debug('Form submit:' + e.target);
409
- * });
410
- * }
411
- * });
412
- */
413
- 'onSubmit',
414
-
415
- /**
416
- * Fires when a form reset event is intercepted.
417
- *
418
- * @event onReset
419
- * @param {tinymce.Editor} sender Editor instance.
420
- * @param {Event} evt W3C DOM Event instance.
421
- * @example
422
- * // Adds an observer to the onReset event using tinyMCE.init
423
- * tinyMCE.init({
424
- * ...
425
- * setup : function(ed) {
426
- * ed.onReset.add(function(ed, e) {
427
- * console.debug('Form reset:' + e.target);
428
- * });
429
- * }
430
- * });
431
- */
432
- 'onReset',
433
-
434
- /**
435
- * Fires when a paste event is intercepted inside the editor.
436
- *
437
- * @event onPaste
438
- * @param {tinymce.Editor} sender Editor instance.
439
- * @param {Event} evt W3C DOM Event instance.
440
- * @example
441
- * // Adds an observer to the onPaste event using tinyMCE.init
442
- * tinyMCE.init({
443
- * ...
444
- * setup : function(ed) {
445
- * ed.onPaste.add(function(ed, e) {
446
- * console.debug('Pasted plain text');
447
- * });
448
- * }
449
- * });
450
- */
451
- 'onPaste',
452
-
453
- /**
454
- * Fires when the Serializer does a preProcess on the contents.
455
- *
456
- * @event onPreProcess
457
- * @param {tinymce.Editor} sender Editor instance.
458
- * @param {Object} obj PreProcess object.
459
- * @option {Node} node DOM node for the item being serialized.
460
- * @option {String} format The specified output format normally "html".
461
- * @option {Boolean} get Is true if the process is on a getContent operation.
462
- * @option {Boolean} set Is true if the process is on a setContent operation.
463
- * @option {Boolean} cleanup Is true if the process is on a cleanup operation.
464
- * @example
465
- * // Adds an observer to the onPreProcess event using tinyMCE.init
466
- * tinyMCE.init({
467
- * ...
468
- * setup : function(ed) {
469
- * ed.onPreProcess.add(function(ed, o) {
470
- * // Add a class to each paragraph in the editor
471
- * ed.dom.addClass(ed.dom.select('p', o.node), 'myclass');
472
- * });
473
- * }
474
- * });
475
- */
476
- 'onPreProcess',
477
-
478
- /**
479
- * Fires when the Serializer does a postProcess on the contents.
480
- *
481
- * @event onPostProcess
482
- * @param {tinymce.Editor} sender Editor instance.
483
- * @param {Object} obj PreProcess object.
484
- * @example
485
- * // Adds an observer to the onPostProcess event using tinyMCE.init
486
- * tinyMCE.init({
487
- * ...
488
- * setup : function(ed) {
489
- * ed.onPostProcess.add(function(ed, o) {
490
- * // Remove all paragraphs and replace with BR
491
- * o.content = o.content.replace(/<p[^>]+>|<p>/g, '');
492
- * o.content = o.content.replace(/<\/p>/g, '<br />');
493
- * });
494
- * }
495
- * });
496
- */
497
- 'onPostProcess',
498
-
499
- /**
500
- * Fires before new contents is added to the editor. Using for example setContent.
501
- *
502
- * @event onBeforeSetContent
503
- * @param {tinymce.Editor} sender Editor instance.
504
- * @example
505
- * // Adds an observer to the onBeforeSetContent event using tinyMCE.init
506
- * tinyMCE.init({
507
- * ...
508
- * setup : function(ed) {
509
- * ed.onBeforeSetContent.add(function(ed, o) {
510
- * // Replaces all a characters with b characters
511
- * o.content = o.content.replace(/a/g, 'b');
512
- * });
513
- * }
514
- * });
515
- */
516
- 'onBeforeSetContent',
517
-
518
- /**
519
- * Fires before contents is extracted from the editor using for example getContent.
520
- *
521
- * @event onBeforeGetContent
522
- * @param {tinymce.Editor} sender Editor instance.
523
- * @param {Event} evt W3C DOM Event instance.
524
- * @example
525
- * // Adds an observer to the onBeforeGetContent event using tinyMCE.init
526
- * tinyMCE.init({
527
- * ...
528
- * setup : function(ed) {
529
- * ed.onBeforeGetContent.add(function(ed, o) {
530
- * console.debug('Before get content.');
531
- * });
532
- * }
533
- * });
534
- */
535
- 'onBeforeGetContent',
536
-
537
- /**
538
- * Fires after the contents has been added to the editor using for example onSetContent.
539
- *
540
- * @event onSetContent
541
- * @param {tinymce.Editor} sender Editor instance.
542
- * @example
543
- * // Adds an observer to the onSetContent event using tinyMCE.init
544
- * tinyMCE.init({
545
- * ...
546
- * setup : function(ed) {
547
- * ed.onSetContent.add(function(ed, o) {
548
- * // Replaces all a characters with b characters
549
- * o.content = o.content.replace(/a/g, 'b');
550
- * });
551
- * }
552
- * });
553
- */
554
- 'onSetContent',
555
-
556
- /**
557
- * Fires after the contents has been extracted from the editor using for example getContent.
558
- *
559
- * @event onGetContent
560
- * @param {tinymce.Editor} sender Editor instance.
561
- * @example
562
- * // Adds an observer to the onGetContent event using tinyMCE.init
563
- * tinyMCE.init({
564
- * ...
565
- * setup : function(ed) {
566
- * ed.onGetContent.add(function(ed, o) {
567
- * // Replace all a characters with b
568
- * o.content = o.content.replace(/a/g, 'b');
569
- * });
570
- * }
571
- * });
572
- */
573
- 'onGetContent',
574
-
575
- /**
576
- * Fires when the editor gets loaded with contents for example when the load method is executed.
577
- *
578
- * @event onLoadContent
579
- * @param {tinymce.Editor} sender Editor instance.
580
- * @example
581
- * // Adds an observer to the onLoadContent event using tinyMCE.init
582
- * tinyMCE.init({
583
- * ...
584
- * setup : function(ed) {
585
- * ed.onLoadContent.add(function(ed, o) {
586
- * // Output the element name
587
- * console.debug(o.element.nodeName);
588
- * });
589
- * }
590
- * });
591
- */
592
- 'onLoadContent',
593
-
594
- /**
595
- * Fires when the editor contents gets saved for example when the save method is executed.
596
- *
597
- * @event onSaveContent
598
- * @param {tinymce.Editor} sender Editor instance.
599
- * @example
600
- * // Adds an observer to the onSaveContent event using tinyMCE.init
601
- * tinyMCE.init({
602
- * ...
603
- * setup : function(ed) {
604
- * ed.onSaveContent.add(function(ed, o) {
605
- * // Output the element name
606
- * console.debug(o.element.nodeName);
607
- * });
608
- * }
609
- * });
610
- */
611
- 'onSaveContent',
612
-
613
- /**
614
- * Fires when the user changes node location using the mouse or keyboard.
615
- *
616
- * @event onNodeChange
617
- * @param {tinymce.Editor} sender Editor instance.
618
- * @example
619
- * // Adds an observer to the onNodeChange event using tinyMCE.init
620
- * tinyMCE.init({
621
- * ...
622
- * setup : function(ed) {
623
- * ed.onNodeChange.add(function(ed, cm, e) {
624
- * // Activates the link button when the caret is placed in a anchor element
625
- * if (e.nodeName == 'A')
626
- * cm.setActive('link', true);
627
- * });
628
- * }
629
- * });
630
- */
631
- 'onNodeChange',
632
-
633
- /**
634
- * Fires when a new undo level is added to the editor.
635
- *
636
- * @event onChange
637
- * @param {tinymce.Editor} sender Editor instance.
638
- * @example
639
- * // Adds an observer to the onChange event using tinyMCE.init
640
- * tinyMCE.init({
641
- * ...
642
- * setup : function(ed) {
643
- * ed.onChange.add(function(ed, l) {
644
- * console.debug('Editor contents was modified. Contents: ' + l.content);
645
- * });
646
- * }
647
- * });
648
- */
649
- 'onChange',
650
-
651
- /**
652
- * Fires before a command gets executed for example "Bold".
653
- *
654
- * @event onBeforeExecCommand
655
- * @param {tinymce.Editor} sender Editor instance.
656
- * @example
657
- * // Adds an observer to the onBeforeExecCommand event using tinyMCE.init
658
- * tinyMCE.init({
659
- * ...
660
- * setup : function(ed) {
661
- * ed.onBeforeExecCommand.add(function(ed, cmd, ui, val) {
662
- * console.debug('Command is to be executed: ' + cmd);
663
- * });
664
- * }
665
- * });
666
- */
667
- 'onBeforeExecCommand',
668
-
669
- /**
670
- * Fires after a command is executed for example "Bold".
671
- *
672
- * @event onExecCommand
673
- * @param {tinymce.Editor} sender Editor instance.
674
- * @example
675
- * // Adds an observer to the onExecCommand event using tinyMCE.init
676
- * tinyMCE.init({
677
- * ...
678
- * setup : function(ed) {
679
- * ed.onExecCommand.add(function(ed, cmd, ui, val) {
680
- * console.debug('Command was executed: ' + cmd);
681
- * });
682
- * }
683
- * });
684
- */
685
- 'onExecCommand',
686
-
687
- /**
688
- * Fires when the contents is undo:ed.
689
- *
690
- * @event onUndo
691
- * @param {tinymce.Editor} sender Editor instance.
692
- * @param {Object} level Undo level object.
693
- * @ example
694
- * // Adds an observer to the onUndo event using tinyMCE.init
695
- * tinyMCE.init({
696
- * ...
697
- * setup : function(ed) {
698
- * ed.onUndo.add(function(ed, level) {
699
- * console.debug('Undo was performed: ' + level.content);
700
- * });
701
- * }
702
- * });
703
- */
704
- 'onUndo',
705
-
706
- /**
707
- * Fires when the contents is redo:ed.
708
- *
709
- * @event onRedo
710
- * @param {tinymce.Editor} sender Editor instance.
711
- * @param {Object} level Undo level object.
712
- * @example
713
- * // Adds an observer to the onRedo event using tinyMCE.init
714
- * tinyMCE.init({
715
- * ...
716
- * setup : function(ed) {
717
- * ed.onRedo.add(function(ed, level) {
718
- * console.debug('Redo was performed: ' +level.content);
719
- * });
720
- * }
721
- * });
722
- */
723
- 'onRedo',
724
-
725
- /**
726
- * Fires when visual aids is enabled/disabled.
727
- *
728
- * @event onVisualAid
729
- * @param {tinymce.Editor} sender Editor instance.
730
- * @example
731
- * // Adds an observer to the onVisualAid event using tinyMCE.init
732
- * tinyMCE.init({
733
- * ...
734
- * setup : function(ed) {
735
- * ed.onVisualAid.add(function(ed, e, s) {
736
- * console.debug('onVisualAid event: ' + ed.id + ", State: " + s);
737
- * });
738
- * }
739
- * });
740
- */
741
- 'onVisualAid',
742
-
743
- /**
744
- * Fires when the progress throbber is shown above the editor.
745
- *
746
- * @event onSetProgressState
747
- * @param {tinymce.Editor} sender Editor instance.
748
- * @example
749
- * // Adds an observer to the onSetProgressState event using tinyMCE.init
750
- * tinyMCE.init({
751
- * ...
752
- * setup : function(ed) {
753
- * ed.onSetProgressState.add(function(ed, b) {
754
- * if (b)
755
- * console.debug('SHOW!');
756
- * else
757
- * console.debug('HIDE!');
758
- * });
759
- * }
760
- * });
761
- */
762
- 'onSetProgressState'
763
- ], function(e) {
764
- t[e] = new Dispatcher(t);
765
- });
766
-
767
- /**
768
- * Name/value collection with editor settings.
769
- *
770
- * @property settings
771
- * @type Object
772
- * @example
773
- * // Get the value of the theme setting
774
- * tinyMCE.activeEditor.windowManager.alert("You are using the " + tinyMCE.activeEditor.settings.theme + " theme");
775
- */
776
- t.settings = s = extend({
777
- id : id,
778
- language : 'en',
779
- docs_language : 'en',
780
- theme : 'simple',
781
- skin : 'default',
782
- delta_width : 0,
783
- delta_height : 0,
784
- popup_css : '',
785
- plugins : '',
786
- document_base_url : tinymce.documentBaseURL,
787
- add_form_submit_trigger : 1,
788
- submit_patch : 1,
789
- add_unload_trigger : 1,
790
- convert_urls : 1,
791
- relative_urls : 1,
792
- remove_script_host : 1,
793
- table_inline_editing : 0,
794
- object_resizing : 1,
795
- cleanup : 1,
796
- accessibility_focus : 1,
797
- custom_shortcuts : 1,
798
- custom_undo_redo_keyboard_shortcuts : 1,
799
- custom_undo_redo_restore_selection : 1,
800
- custom_undo_redo : 1,
801
- doctype : tinymce.isIE6 ? '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">' : '<!DOCTYPE>', // Use old doctype on IE 6 to avoid horizontal scroll
802
- visual_table_class : 'mceItemTable',
803
- visual : 1,
804
- font_size_style_values : 'xx-small,x-small,small,medium,large,x-large,xx-large',
805
- font_size_legacy_values : 'xx-small,small,medium,large,x-large,xx-large,300%', // See: http://www.w3.org/TR/CSS2/fonts.html#propdef-font-size
806
- apply_source_formatting : 1,
807
- directionality : 'ltr',
808
- forced_root_block : 'p',
809
- hidden_input : 1,
810
- padd_empty_editor : 1,
811
- render_ui : 1,
812
- init_theme : 1,
813
- force_p_newlines : 1,
814
- indentation : '30px',
815
- keep_styles : 1,
816
- fix_table_elements : 1,
817
- inline_styles : 1,
818
- convert_fonts_to_spans : true,
819
- indent : 'simple',
820
- indent_before : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr',
821
- indent_after : 'p,h1,h2,h3,h4,h5,h6,blockquote,div,title,style,pre,script,td,ul,li,area,table,thead,tfoot,tbody,tr',
822
- validate : true,
823
- entity_encoding : 'named',
824
- url_converter : t.convertURL,
825
- url_converter_scope : t,
826
- ie7_compat : true
827
- }, s);
828
829
/**
830
* URI object to document configured for the TinyMCE instance.
@@ -838,7 +152,7 @@
838
* // Get absolute URL from the location of document_base_url
839
* tinyMCE.activeEditor.documentBaseURI.toAbsolute('somefile.htm');
840
*/
841
- t.documentBaseURI = new tinymce.util.URI(s.document_base_url || tinymce.documentBaseURL, {
842
base_uri : tinyMCE.baseURI
843
});
844
@@ -854,7 +168,7 @@
854
* // Get absolute URL from the location of the API
855
* tinyMCE.activeEditor.baseURI.toAbsolute('somefile.htm');
856
*/
857
- t.baseURI = tinymce.baseURI;
858
859
/**
860
* Array with CSS files to load into the iframe.
@@ -862,10 +176,26 @@
862
* @property contentCSS
863
* @type Array
864
*/
865
- t.contentCSS = [];
866
867
// Call setup
868
- t.execCallback('setup', t);
869
},
870
871
/**
@@ -878,7 +208,7 @@
878
879
// Page is not loaded yet, wait for it
880
if (!Event.domLoaded) {
881
- Event.add(document, 'init', function() {
882
t.render();
883
});
884
return;
@@ -891,8 +221,7 @@
891
return;
892
893
// Is a iPad/iPhone and not on iOS5, then skip initialization. We need to sniff
894
- // here since the browser says it has contentEditable support but there is no visible
895
- // caret We will remove this check ones Apple implements full contentEditable support
896
if (tinymce.isIDevice && !tinymce.isIOS5)
897
return;
898
@@ -900,6 +229,12 @@
900
if (!/TEXTAREA|INPUT/i.test(t.getElement().nodeName) && s.hidden_input && DOM.getParent(id, 'form'))
901
DOM.insertAfter(DOM.create('input', {type : 'hidden', name : id}), id);
902
903
/**
904
* Window manager reference, use this to open new windows and dialogs.
905
*
@@ -980,7 +315,7 @@
980
if (s.language && s.language_load !== false)
981
sl.add(tinymce.baseURL + '/langs/' + s.language + '.js');
982
983
- if (s.theme && s.theme.charAt(0) != '-' && !ThemeManager.urls[s.theme])
984
ThemeManager.load(s.theme, 'themes/' + s.theme + '/editor_template' + tinymce.suffix + '.js');
985
986
each(explode(s.plugins), function(p) {
@@ -990,9 +325,8 @@
990
var dependencies = PluginManager.dependencies(p);
991
each(dependencies, function(dep) {
992
var defaultSettings = {prefix:'plugins/', resource: dep, suffix:'/editor_plugin' + tinymce.suffix + '.js'};
993
- var dep = PluginManager.createUrl(defaultSettings, dep);
994
PluginManager.load(dep.resource, dep);
995
-
996
});
997
} else {
998
// Skip safari plugin, since it is removed as of 3.3b1
@@ -1022,7 +356,7 @@
1022
* @method init
1023
*/
1024
init : function() {
1025
- var n, t = this, s = t.settings, w, h, e = t.getElement(), o, ti, u, bi, bc, re, i, initializedPlugins = [];
1026
1027
tinymce.add(t);
1028
@@ -1038,13 +372,18 @@
1038
* tinyMCE.activeEditor.theme.someMethod();
1039
*/
1040
if (s.theme) {
1041
- s.theme = s.theme.replace(/-/, '');
1042
- o = ThemeManager.get(s.theme);
1043
- t.theme = new o();
1044
-
1045
- if (t.theme.init && s.init_theme)
1046
- t.theme.init(t, ThemeManager.urls[s.theme] || tinymce.documentBaseURL.replace(/\/#x2F;, ''));
1047
}
1048
function initPlugin(p) {
1049
var c = PluginManager.get(p), u = PluginManager.urls[p] || tinymce.documentBaseURL.replace(/\/#x2F;, ''), po;
1050
if (c && tinymce.inArray(initializedPlugins,p) === -1) {
@@ -1087,95 +426,100 @@
1087
*/
1088
t.controlManager = new tinymce.ControlManager(t);
1089
1090
- if (s.custom_undo_redo) {
1091
- t.onBeforeExecCommand.add(function(ed, cmd, ui, val, a) {
1092
- if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
1093
- t.undoManager.beforeChange();
1094
- });
1095
1096
- t.onExecCommand.add(function(ed, cmd, ui, val, a) {
1097
- if (cmd != 'Undo' && cmd != 'Redo' && cmd != 'mceRepaint' && (!a || !a.skip_undo))
1098
- t.undoManager.add();
1099
- });
1100
- }
1101
1102
- t.onExecCommand.add(function(ed, c) {
1103
- // Don't refresh the select lists until caret move
1104
- if (!/^(FontName|FontSize)#x2F;.test(c))
1105
- t.nodeChanged();
1106
- });
1107
1108
- // Remove ghost selections on images and tables in Gecko
1109
- if (isGecko) {
1110
- function repaint(a, o) {
1111
- if (!o || !o.initial)
1112
- t.execCommand('mceRepaint');
1113
- };
1114
1115
- t.onUndo.add(repaint);
1116
- t.onRedo.add(repaint);
1117
- t.onSetContent.add(repaint);
1118
- }
1119
1120
- // Enables users to override the control factory
1121
- t.onBeforeRenderUI.dispatch(t, t.controlManager);
1122
1123
- // Measure box
1124
- if (s.render_ui) {
1125
- w = s.width || e.style.width || e.offsetWidth;
1126
- h = s.height || e.style.height || e.offsetHeight;
1127
- t.orgDisplay = e.style.display;
1128
- re = /^[0-9\.]+(|px)#x2F;i;
1129
1130
- if (re.test('' + w))
1131
- w = Math.max(parseInt(w) + (o.deltaWidth || 0), 100);
1132
1133
- if (re.test('' + h))
1134
- h = Math.max(parseInt(h) + (o.deltaHeight || 0), 100);
1135
1136
- // Render UI
1137
- o = t.theme.renderUI({
1138
- targetNode : e,
1139
- width : w,
1140
- height : h,
1141
- deltaWidth : s.delta_width,
1142
- deltaHeight : s.delta_height
1143
- });
1144
1145
t.editorContainer = o.editorContainer;
1146
}
1147
1148
- // #ifdef contentEditable
1149
1150
// Content editable mode ends here
1151
if (s.content_editable) {
1152
e = n = o = null; // Fix IE leak
1153
- return t.setupContentEditable();
1154
}
1155
1156
- // #endif
1157
-
1158
// User specified a document.domain value
1159
if (document.domain && location.hostname != document.domain)
1160
tinymce.relaxedDomain = document.domain;
1161
1162
- // Resize editor
1163
- DOM.setStyles(o.sizeContainer || o.editorContainer, {
1164
- width : w,
1165
- height : h
1166
- });
1167
-
1168
- // Load specified content CSS last
1169
- if (s.content_css) {
1170
- tinymce.each(explode(s.content_css), function(u) {
1171
- t.contentCSS.push(t.documentBaseURI.toAbsolute(u));
1172
- });
1173
- }
1174
-
1175
- h = (o.iframeHeight || h) + (typeof(h) == 'number' ? (o.deltaHeight || 0) : '');
1176
- if (h < 100)
1177
- h = 100;
1178
-
1179
t.iframeHTML = s.doctype + '<html><head xmlns="http://www.w3.org/1999/xhtml">';
1180
1181
// We only need to override paths if we have to
@@ -1184,10 +528,12 @@
1184
t.iframeHTML += '<base href="' + t.documentBaseURI.getURI() + '" />';
1185
1186
// IE8 doesn't support carets behind images setting ie7_compat would force IE8+ to run in IE7 compat mode.
1187
- if (s.ie7_compat)
1188
- t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=7" />';
1189
- else
1190
- t.iframeHTML += '<meta http-equiv="X-UA-Compatible" content="IE=edge" />';
1191
1192
t.iframeHTML += '<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />';
1193
@@ -1196,6 +542,8 @@
1196
t.iframeHTML += '<link type="text/css" rel="stylesheet" href="' + t.contentCSS[i] + '" />';
1197
}
1198
1199
bi = s.body_id || 'tinymce';
1200
if (bi.indexOf('=') != -1) {
1201
bi = t.getParam('body_id', '', 'hash');
@@ -1208,12 +556,12 @@
1208
bc = bc[t.id] || '';
1209
}
1210
1211
- t.iframeHTML += '</head><body id="' + bi + '" class="mceContentBody ' + bc + '"><br></body></html>';
1212
1213
// Domain relaxing enabled, then set document domain
1214
if (tinymce.relaxedDomain && (isIE || (tinymce.isOpera && parseFloat(opera.version()) < 11))) {
1215
// We need to write the contents here in IE since multiple writes messes up refresh button and back button
1216
- u = 'javascript:(function(){document.open();document.domain="' + document.domain + '";var ed = window.parent.tinyMCE.get("' + t.id + '");document.write(ed.iframeHTML);document.close();ed.setupIframe();})()';
1217
}
1218
1219
// Create iframe
@@ -1232,12 +580,19 @@
1232
});
1233
1234
t.contentAreaContainer = o.iframeContainer;
1235
- DOM.get(o.editorContainer).style.display = t.orgDisplay;
1236
DOM.get(t.id).style.display = 'none';
1237
DOM.setAttrib(t.id, 'aria-hidden', true);
1238
1239
if (!tinymce.relaxedDomain || !u)
1240
- t.setupIframe();
1241
1242
e = n = o = null; // Cleanup
1243
},
@@ -1247,29 +602,39 @@
1247
* It will fill the iframe with contents, setups DOM and selection objects for the iframe.
1248
* This method should not be called directly.
1249
*
1250
- * @method setupIframe
1251
*/
1252
- setupIframe : function() {
1253
- var t = this, s = t.settings, e = DOM.get(t.id), d = t.getDoc(), h, b;
1254
1255
// Setup iframe body
1256
- if (!isIE || !tinymce.relaxedDomain) {
1257
- d.open();
1258
- d.write(t.iframeHTML);
1259
- d.close();
1260
1261
if (tinymce.relaxedDomain)
1262
- d.domain = tinymce.relaxedDomain;
1263
}
1264
1265
// It will not steal focus while setting contentEditable
1266
- b = t.getBody();
1267
- b.disabled = true;
1268
1269
- if (!s.readonly)
1270
- b.contentEditable = true;
1271
1272
- b.disabled = false;
1273
1274
/**
1275
* Schema instance, enables you to validate elements and it's children.
@@ -1277,7 +642,7 @@
1277
* @property schema
1278
* @type tinymce.html.Schema
1279
*/
1280
- t.schema = new tinymce.html.Schema(s);
1281
1282
/**
1283
* DOM instance for the editor.
@@ -1288,15 +653,15 @@
1288
* // Adds a class to all paragraphs within the editor
1289
* tinyMCE.activeEditor.dom.addClass(tinyMCE.activeEditor.dom.select('p'), 'someclass');
1290
*/
1291
- t.dom = new tinymce.dom.DOMUtils(t.getDoc(), {
1292
keep_values : true,
1293
- url_converter : t.convertURL,
1294
- url_converter_scope : t,
1295
- hex_colors : s.force_hex_style_colors,
1296
- class_filter : s.class_filter,
1297
- update_styles : 1,
1298
- fix_ie_paragraphs : 1,
1299
- schema : t.schema
1300
});
1301
1302
/**
@@ -1305,33 +670,11 @@
1305
* @property parser
1306
* @type tinymce.html.DomParser
1307
*/
1308
- t.parser = new tinymce.html.DomParser(s, t.schema);
1309
-
1310
- // Force anchor names closed, unless the setting "allow_html_in_named_anchor" is explicitly included.
1311
- if (!t.settings.allow_html_in_named_anchor) {
1312
- t.parser.addAttributeFilter('name', function(nodes, name) {
1313
-