mirador_rails 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (193) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -0
  3. data/app/controllers/mirador_rails/locales_controller.rb +10 -0
  4. data/config/routes.rb +7 -0
  5. data/lib/mirador_rails/exceptions.rb +6 -0
  6. data/lib/mirador_rails/locale.rb +24 -0
  7. data/lib/mirador_rails/version.rb +1 -1
  8. data/lib/mirador_rails.rb +9 -2
  9. data/mirador_rails.gemspec +3 -0
  10. data/tasks/mirador_rails.rake +44 -10
  11. data/vendor/assets/images/border_type_4.png +0 -0
  12. data/vendor/assets/images/border_type_5.png +0 -0
  13. data/vendor/assets/javascripts/mirador/mirador.js.erb +20105 -0
  14. data/vendor/assets/javascripts/mirador.js +4 -1
  15. data/vendor/assets/locales/de/translation.json +3 -0
  16. data/vendor/assets/locales/en/translation.json +11 -7
  17. data/vendor/assets/locales/ko/translation.json +18 -9
  18. data/vendor/assets/stylesheets/enhancements.scss +36 -0
  19. data/vendor/assets/stylesheets/mirador-combined.css +1488 -1642
  20. data/vendor/assets/stylesheets/mirador.css +1 -0
  21. metadata +52 -174
  22. data/vendor/assets/javascripts/mirador.min.js +0 -89
  23. data/vendor/assets/javascripts/mirador.min.js.map +0 -1
  24. data/vendor/assets/plugins/plugins/advlist/plugin.js +0 -97
  25. data/vendor/assets/plugins/plugins/advlist/plugin.min.js +0 -1
  26. data/vendor/assets/plugins/plugins/anchor/plugin.js +0 -45
  27. data/vendor/assets/plugins/plugins/anchor/plugin.min.js +0 -1
  28. data/vendor/assets/plugins/plugins/autolink/plugin.js +0 -194
  29. data/vendor/assets/plugins/plugins/autolink/plugin.min.js +0 -1
  30. data/vendor/assets/plugins/plugins/autoresize/plugin.js +0 -152
  31. data/vendor/assets/plugins/plugins/autoresize/plugin.min.js +0 -1
  32. data/vendor/assets/plugins/plugins/autosave/plugin.js +0 -165
  33. data/vendor/assets/plugins/plugins/autosave/plugin.min.js +0 -1
  34. data/vendor/assets/plugins/plugins/bbcode/plugin.js +0 -123
  35. data/vendor/assets/plugins/plugins/bbcode/plugin.min.js +0 -1
  36. data/vendor/assets/plugins/plugins/charmap/plugin.js +0 -370
  37. data/vendor/assets/plugins/plugins/charmap/plugin.min.js +0 -1
  38. data/vendor/assets/plugins/plugins/code/plugin.js +0 -60
  39. data/vendor/assets/plugins/plugins/code/plugin.min.js +0 -1
  40. data/vendor/assets/plugins/plugins/colorpicker/plugin.js +0 -112
  41. data/vendor/assets/plugins/plugins/colorpicker/plugin.min.js +0 -1
  42. data/vendor/assets/plugins/plugins/compat3x/css/dialog.css +0 -118
  43. data/vendor/assets/plugins/plugins/compat3x/img/buttons.png +0 -0
  44. data/vendor/assets/plugins/plugins/compat3x/img/icons.gif +0 -0
  45. data/vendor/assets/plugins/plugins/compat3x/img/items.gif +0 -0
  46. data/vendor/assets/plugins/plugins/compat3x/img/menu_arrow.gif +0 -0
  47. data/vendor/assets/plugins/plugins/compat3x/img/menu_check.gif +0 -0
  48. data/vendor/assets/plugins/plugins/compat3x/img/progress.gif +0 -0
  49. data/vendor/assets/plugins/plugins/compat3x/img/tabs.gif +0 -0
  50. data/vendor/assets/plugins/plugins/compat3x/plugin.js +0 -297
  51. data/vendor/assets/plugins/plugins/compat3x/plugin.min.js +0 -1
  52. data/vendor/assets/plugins/plugins/compat3x/tiny_mce_popup.js +0 -542
  53. data/vendor/assets/plugins/plugins/compat3x/utils/editable_selects.js +0 -70
  54. data/vendor/assets/plugins/plugins/compat3x/utils/form_utils.js +0 -210
  55. data/vendor/assets/plugins/plugins/compat3x/utils/mctabs.js +0 -164
  56. data/vendor/assets/plugins/plugins/compat3x/utils/validate.js +0 -252
  57. data/vendor/assets/plugins/plugins/contextmenu/plugin.js +0 -87
  58. data/vendor/assets/plugins/plugins/contextmenu/plugin.min.js +0 -1
  59. data/vendor/assets/plugins/plugins/directionality/plugin.js +0 -64
  60. data/vendor/assets/plugins/plugins/directionality/plugin.min.js +0 -1
  61. data/vendor/assets/plugins/plugins/emoticons/img/smiley-cool.gif +0 -0
  62. data/vendor/assets/plugins/plugins/emoticons/img/smiley-cry.gif +0 -0
  63. data/vendor/assets/plugins/plugins/emoticons/img/smiley-embarassed.gif +0 -0
  64. data/vendor/assets/plugins/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
  65. data/vendor/assets/plugins/plugins/emoticons/img/smiley-frown.gif +0 -0
  66. data/vendor/assets/plugins/plugins/emoticons/img/smiley-innocent.gif +0 -0
  67. data/vendor/assets/plugins/plugins/emoticons/img/smiley-kiss.gif +0 -0
  68. data/vendor/assets/plugins/plugins/emoticons/img/smiley-laughing.gif +0 -0
  69. data/vendor/assets/plugins/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
  70. data/vendor/assets/plugins/plugins/emoticons/img/smiley-sealed.gif +0 -0
  71. data/vendor/assets/plugins/plugins/emoticons/img/smiley-smile.gif +0 -0
  72. data/vendor/assets/plugins/plugins/emoticons/img/smiley-surprised.gif +0 -0
  73. data/vendor/assets/plugins/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
  74. data/vendor/assets/plugins/plugins/emoticons/img/smiley-undecided.gif +0 -0
  75. data/vendor/assets/plugins/plugins/emoticons/img/smiley-wink.gif +0 -0
  76. data/vendor/assets/plugins/plugins/emoticons/img/smiley-yell.gif +0 -0
  77. data/vendor/assets/plugins/plugins/emoticons/plugin.js +0 -65
  78. data/vendor/assets/plugins/plugins/emoticons/plugin.min.js +0 -1
  79. data/vendor/assets/plugins/plugins/example/dialog.html +0 -8
  80. data/vendor/assets/plugins/plugins/example/plugin.js +0 -68
  81. data/vendor/assets/plugins/plugins/example/plugin.min.js +0 -1
  82. data/vendor/assets/plugins/plugins/example_dependency/plugin.js +0 -22
  83. data/vendor/assets/plugins/plugins/example_dependency/plugin.min.js +0 -1
  84. data/vendor/assets/plugins/plugins/fullpage/plugin.js +0 -490
  85. data/vendor/assets/plugins/plugins/fullpage/plugin.min.js +0 -1
  86. data/vendor/assets/plugins/plugins/fullscreen/plugin.js +0 -136
  87. data/vendor/assets/plugins/plugins/fullscreen/plugin.min.js +0 -1
  88. data/vendor/assets/plugins/plugins/hr/plugin.js +0 -30
  89. data/vendor/assets/plugins/plugins/hr/plugin.min.js +0 -1
  90. data/vendor/assets/plugins/plugins/image/plugin.js +0 -439
  91. data/vendor/assets/plugins/plugins/image/plugin.min.js +0 -1
  92. data/vendor/assets/plugins/plugins/importcss/plugin.js +0 -195
  93. data/vendor/assets/plugins/plugins/importcss/plugin.min.js +0 -1
  94. data/vendor/assets/plugins/plugins/insertdatetime/plugin.js +0 -121
  95. data/vendor/assets/plugins/plugins/insertdatetime/plugin.min.js +0 -1
  96. data/vendor/assets/plugins/plugins/layer/plugin.js +0 -225
  97. data/vendor/assets/plugins/plugins/layer/plugin.min.js +0 -1
  98. data/vendor/assets/plugins/plugins/legacyoutput/plugin.js +0 -211
  99. data/vendor/assets/plugins/plugins/legacyoutput/plugin.min.js +0 -1
  100. data/vendor/assets/plugins/plugins/link/plugin.js +0 -400
  101. data/vendor/assets/plugins/plugins/link/plugin.min.js +0 -1
  102. data/vendor/assets/plugins/plugins/lists/plugin.js +0 -791
  103. data/vendor/assets/plugins/plugins/lists/plugin.min.js +0 -1
  104. data/vendor/assets/plugins/plugins/media/moxieplayer.swf +0 -0
  105. data/vendor/assets/plugins/plugins/media/plugin.js +0 -774
  106. data/vendor/assets/plugins/plugins/media/plugin.min.js +0 -1
  107. data/vendor/assets/plugins/plugins/nonbreaking/plugin.js +0 -53
  108. data/vendor/assets/plugins/plugins/nonbreaking/plugin.min.js +0 -1
  109. data/vendor/assets/plugins/plugins/noneditable/plugin.js +0 -540
  110. data/vendor/assets/plugins/plugins/noneditable/plugin.min.js +0 -1
  111. data/vendor/assets/plugins/plugins/pagebreak/plugin.js +0 -88
  112. data/vendor/assets/plugins/plugins/pagebreak/plugin.min.js +0 -1
  113. data/vendor/assets/plugins/plugins/paste/classes/Clipboard.js +0 -634
  114. data/vendor/assets/plugins/plugins/paste/classes/Plugin.js +0 -110
  115. data/vendor/assets/plugins/plugins/paste/classes/Quirks.js +0 -159
  116. data/vendor/assets/plugins/plugins/paste/classes/Utils.js +0 -130
  117. data/vendor/assets/plugins/plugins/paste/classes/WordFilter.js +0 -493
  118. data/vendor/assets/plugins/plugins/paste/plugin.dev.js +0 -120
  119. data/vendor/assets/plugins/plugins/paste/plugin.js +0 -1625
  120. data/vendor/assets/plugins/plugins/paste/plugin.min.js +0 -1
  121. data/vendor/assets/plugins/plugins/preview/plugin.js +0 -88
  122. data/vendor/assets/plugins/plugins/preview/plugin.min.js +0 -1
  123. data/vendor/assets/plugins/plugins/print/plugin.js +0 -32
  124. data/vendor/assets/plugins/plugins/print/plugin.min.js +0 -1
  125. data/vendor/assets/plugins/plugins/save/plugin.js +0 -94
  126. data/vendor/assets/plugins/plugins/save/plugin.min.js +0 -1
  127. data/vendor/assets/plugins/plugins/searchreplace/plugin.js +0 -594
  128. data/vendor/assets/plugins/plugins/searchreplace/plugin.min.js +0 -1
  129. data/vendor/assets/plugins/plugins/spellchecker/classes/DomTextMatcher.js +0 -470
  130. data/vendor/assets/plugins/plugins/spellchecker/classes/Plugin.js +0 -436
  131. data/vendor/assets/plugins/plugins/spellchecker/plugin.dev.js +0 -117
  132. data/vendor/assets/plugins/plugins/spellchecker/plugin.js +0 -996
  133. data/vendor/assets/plugins/plugins/spellchecker/plugin.min.js +0 -1
  134. data/vendor/assets/plugins/plugins/tabfocus/plugin.js +0 -120
  135. data/vendor/assets/plugins/plugins/tabfocus/plugin.min.js +0 -1
  136. data/vendor/assets/plugins/plugins/table/classes/CellSelection.js +0 -176
  137. data/vendor/assets/plugins/plugins/table/classes/Dialogs.js +0 -749
  138. data/vendor/assets/plugins/plugins/table/classes/Plugin.js +0 -422
  139. data/vendor/assets/plugins/plugins/table/classes/Quirks.js +0 -372
  140. data/vendor/assets/plugins/plugins/table/classes/TableGrid.js +0 -864
  141. data/vendor/assets/plugins/plugins/table/plugin.dev.js +0 -118
  142. data/vendor/assets/plugins/plugins/table/plugin.js +0 -2680
  143. data/vendor/assets/plugins/plugins/table/plugin.min.js +0 -1
  144. data/vendor/assets/plugins/plugins/template/plugin.js +0 -262
  145. data/vendor/assets/plugins/plugins/template/plugin.min.js +0 -1
  146. data/vendor/assets/plugins/plugins/textcolor/plugin.js +0 -272
  147. data/vendor/assets/plugins/plugins/textcolor/plugin.min.js +0 -1
  148. data/vendor/assets/plugins/plugins/textpattern/plugin.js +0 -268
  149. data/vendor/assets/plugins/plugins/textpattern/plugin.min.js +0 -1
  150. data/vendor/assets/plugins/plugins/visualblocks/css/visualblocks.css +0 -135
  151. data/vendor/assets/plugins/plugins/visualblocks/img/address.gif +0 -0
  152. data/vendor/assets/plugins/plugins/visualblocks/img/article.gif +0 -0
  153. data/vendor/assets/plugins/plugins/visualblocks/img/aside.gif +0 -0
  154. data/vendor/assets/plugins/plugins/visualblocks/img/blockquote.gif +0 -0
  155. data/vendor/assets/plugins/plugins/visualblocks/img/div.gif +0 -0
  156. data/vendor/assets/plugins/plugins/visualblocks/img/dl.gif +0 -0
  157. data/vendor/assets/plugins/plugins/visualblocks/img/figure.gif +0 -0
  158. data/vendor/assets/plugins/plugins/visualblocks/img/h1.gif +0 -0
  159. data/vendor/assets/plugins/plugins/visualblocks/img/h2.gif +0 -0
  160. data/vendor/assets/plugins/plugins/visualblocks/img/h3.gif +0 -0
  161. data/vendor/assets/plugins/plugins/visualblocks/img/h4.gif +0 -0
  162. data/vendor/assets/plugins/plugins/visualblocks/img/h5.gif +0 -0
  163. data/vendor/assets/plugins/plugins/visualblocks/img/h6.gif +0 -0
  164. data/vendor/assets/plugins/plugins/visualblocks/img/hgroup.gif +0 -0
  165. data/vendor/assets/plugins/plugins/visualblocks/img/ol.gif +0 -0
  166. data/vendor/assets/plugins/plugins/visualblocks/img/p.gif +0 -0
  167. data/vendor/assets/plugins/plugins/visualblocks/img/pre.gif +0 -0
  168. data/vendor/assets/plugins/plugins/visualblocks/img/section.gif +0 -0
  169. data/vendor/assets/plugins/plugins/visualblocks/img/ul.gif +0 -0
  170. data/vendor/assets/plugins/plugins/visualblocks/plugin.js +0 -86
  171. data/vendor/assets/plugins/plugins/visualblocks/plugin.min.js +0 -1
  172. data/vendor/assets/plugins/plugins/visualchars/plugin.js +0 -88
  173. data/vendor/assets/plugins/plugins/visualchars/plugin.min.js +0 -1
  174. data/vendor/assets/plugins/plugins/wordcount/plugin.js +0 -69
  175. data/vendor/assets/plugins/plugins/wordcount/plugin.min.js +0 -1
  176. data/vendor/assets/skins/skins/lightgray/content.inline.min.css +0 -1
  177. data/vendor/assets/skins/skins/lightgray/content.min.css +0 -1
  178. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.eot +0 -0
  179. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.svg +0 -62
  180. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  181. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.woff +0 -0
  182. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.eot +0 -0
  183. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.svg +0 -63
  184. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.ttf +0 -0
  185. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.woff +0 -0
  186. data/vendor/assets/skins/skins/lightgray/img/anchor.gif +0 -0
  187. data/vendor/assets/skins/skins/lightgray/img/loader.gif +0 -0
  188. data/vendor/assets/skins/skins/lightgray/img/object.gif +0 -0
  189. data/vendor/assets/skins/skins/lightgray/img/trans.gif +0 -0
  190. data/vendor/assets/skins/skins/lightgray/skin.ie7.min.css +0 -1
  191. data/vendor/assets/skins/skins/lightgray/skin.min.css +0 -1
  192. data/vendor/assets/themes/themes/modern/theme.js +0 -617
  193. data/vendor/assets/themes/themes/modern/theme.min.js +0 -1
@@ -1,2680 +0,0 @@
1
- /**
2
- * Compiled inline version. (Library mode)
3
- */
4
-
5
- /*jshint smarttabs:true, undef:true, latedef:true, curly:true, bitwise:true, camelcase:true */
6
- /*globals $code */
7
-
8
- (function(exports, undefined) {
9
- "use strict";
10
-
11
- var modules = {};
12
-
13
- function require(ids, callback) {
14
- var module, defs = [];
15
-
16
- for (var i = 0; i < ids.length; ++i) {
17
- module = modules[ids[i]] || resolve(ids[i]);
18
- if (!module) {
19
- throw 'module definition dependecy not found: ' + ids[i];
20
- }
21
-
22
- defs.push(module);
23
- }
24
-
25
- callback.apply(null, defs);
26
- }
27
-
28
- function define(id, dependencies, definition) {
29
- if (typeof id !== 'string') {
30
- throw 'invalid module definition, module id must be defined and be a string';
31
- }
32
-
33
- if (dependencies === undefined) {
34
- throw 'invalid module definition, dependencies must be specified';
35
- }
36
-
37
- if (definition === undefined) {
38
- throw 'invalid module definition, definition function must be specified';
39
- }
40
-
41
- require(dependencies, function() {
42
- modules[id] = definition.apply(null, arguments);
43
- });
44
- }
45
-
46
- function defined(id) {
47
- return !!modules[id];
48
- }
49
-
50
- function resolve(id) {
51
- var target = exports;
52
- var fragments = id.split(/[.\/]/);
53
-
54
- for (var fi = 0; fi < fragments.length; ++fi) {
55
- if (!target[fragments[fi]]) {
56
- return;
57
- }
58
-
59
- target = target[fragments[fi]];
60
- }
61
-
62
- return target;
63
- }
64
-
65
- function expose(ids) {
66
- for (var i = 0; i < ids.length; i++) {
67
- var target = exports;
68
- var id = ids[i];
69
- var fragments = id.split(/[.\/]/);
70
-
71
- for (var fi = 0; fi < fragments.length - 1; ++fi) {
72
- if (target[fragments[fi]] === undefined) {
73
- target[fragments[fi]] = {};
74
- }
75
-
76
- target = target[fragments[fi]];
77
- }
78
-
79
- target[fragments[fragments.length - 1]] = modules[id];
80
- }
81
- }
82
-
83
- // Included from: js/tinymce/plugins/table/classes/TableGrid.js
84
-
85
- /**
86
- * TableGrid.js
87
- *
88
- * Copyright, Moxiecode Systems AB
89
- * Released under LGPL License.
90
- *
91
- * License: http://www.tinymce.com/license
92
- * Contributing: http://www.tinymce.com/contributing
93
- */
94
-
95
- /**
96
- * This class creates a grid out of a table element. This
97
- * makes it a whole lot easier to handle complex tables with
98
- * col/row spans.
99
- *
100
- * @class tinymce.tableplugin.TableGrid
101
- * @private
102
- */
103
- define("tinymce/tableplugin/TableGrid", [
104
- "tinymce/util/Tools",
105
- "tinymce/Env"
106
- ], function(Tools, Env) {
107
- var each = Tools.each;
108
-
109
- function getSpanVal(td, name) {
110
- return parseInt(td.getAttribute(name) || 1, 10);
111
- }
112
-
113
- return function(editor, table) {
114
- var grid, gridWidth, startPos, endPos, selectedCell, selection = editor.selection, dom = selection.dom;
115
-
116
- function buildGrid() {
117
- var startY = 0;
118
-
119
- grid = [];
120
- gridWidth = 0;
121
-
122
- each(['thead', 'tbody', 'tfoot'], function(part) {
123
- var rows = dom.select('> ' + part + ' tr', table);
124
-
125
- each(rows, function(tr, y) {
126
- y += startY;
127
-
128
- each(dom.select('> td, > th', tr), function(td, x) {
129
- var x2, y2, rowspan, colspan;
130
-
131
- // Skip over existing cells produced by rowspan
132
- if (grid[y]) {
133
- while (grid[y][x]) {
134
- x++;
135
- }
136
- }
137
-
138
- // Get col/rowspan from cell
139
- rowspan = getSpanVal(td, 'rowspan');
140
- colspan = getSpanVal(td, 'colspan');
141
-
142
- // Fill out rowspan/colspan right and down
143
- for (y2 = y; y2 < y + rowspan; y2++) {
144
- if (!grid[y2]) {
145
- grid[y2] = [];
146
- }
147
-
148
- for (x2 = x; x2 < x + colspan; x2++) {
149
- grid[y2][x2] = {
150
- part: part,
151
- real: y2 == y && x2 == x,
152
- elm: td,
153
- rowspan: rowspan,
154
- colspan: colspan
155
- };
156
- }
157
- }
158
-
159
- gridWidth = Math.max(gridWidth, x + 1);
160
- });
161
- });
162
-
163
- startY += rows.length;
164
- });
165
- }
166
-
167
- function cloneNode(node, children) {
168
- node = node.cloneNode(children);
169
- node.removeAttribute('id');
170
-
171
- return node;
172
- }
173
-
174
- function getCell(x, y) {
175
- var row;
176
-
177
- row = grid[y];
178
- if (row) {
179
- return row[x];
180
- }
181
- }
182
-
183
- function setSpanVal(td, name, val) {
184
- if (td) {
185
- val = parseInt(val, 10);
186
-
187
- if (val === 1) {
188
- td.removeAttribute(name, 1);
189
- } else {
190
- td.setAttribute(name, val, 1);
191
- }
192
- }
193
- }
194
-
195
- function isCellSelected(cell) {
196
- return cell && (dom.hasClass(cell.elm, 'mce-item-selected') || cell == selectedCell);
197
- }
198
-
199
- function getSelectedRows() {
200
- var rows = [];
201
-
202
- each(table.rows, function(row) {
203
- each(row.cells, function(cell) {
204
- if (dom.hasClass(cell, 'mce-item-selected') || (selectedCell && cell == selectedCell.elm)) {
205
- rows.push(row);
206
- return false;
207
- }
208
- });
209
- });
210
-
211
- return rows;
212
- }
213
-
214
- function deleteTable() {
215
- var rng = dom.createRng();
216
-
217
- rng.setStartAfter(table);
218
- rng.setEndAfter(table);
219
-
220
- selection.setRng(rng);
221
-
222
- dom.remove(table);
223
- }
224
-
225
- function cloneCell(cell) {
226
- var formatNode, cloneFormats = {};
227
-
228
- if (editor.settings.table_clone_elements !== false) {
229
- cloneFormats = Tools.makeMap(
230
- (editor.settings.table_clone_elements || 'strong em b i span font h1 h2 h3 h4 h5 h6 p div').toUpperCase(),
231
- /[ ,]/
232
- );
233
- }
234
-
235
- // Clone formats
236
- Tools.walk(cell, function(node) {
237
- var curNode;
238
-
239
- if (node.nodeType == 3) {
240
- each(dom.getParents(node.parentNode, null, cell).reverse(), function(node) {
241
- if (!cloneFormats[node.nodeName]) {
242
- return;
243
- }
244
-
245
- node = cloneNode(node, false);
246
-
247
- if (!formatNode) {
248
- formatNode = curNode = node;
249
- } else if (curNode) {
250
- curNode.appendChild(node);
251
- }
252
-
253
- curNode = node;
254
- });
255
-
256
- // Add something to the inner node
257
- if (curNode) {
258
- curNode.innerHTML = Env.ie ? '&nbsp;' : '<br data-mce-bogus="1" />';
259
- }
260
-
261
- return false;
262
- }
263
- }, 'childNodes');
264
-
265
- cell = cloneNode(cell, false);
266
- setSpanVal(cell, 'rowSpan', 1);
267
- setSpanVal(cell, 'colSpan', 1);
268
-
269
- if (formatNode) {
270
- cell.appendChild(formatNode);
271
- } else {
272
- if (!Env.ie || Env.ie > 10) {
273
- cell.innerHTML = '<br data-mce-bogus="1" />';
274
- }
275
- }
276
-
277
- return cell;
278
- }
279
-
280
- function cleanup() {
281
- var rng = dom.createRng(), row;
282
-
283
- // Empty rows
284
- each(dom.select('tr', table), function(tr) {
285
- if (tr.cells.length === 0) {
286
- dom.remove(tr);
287
- }
288
- });
289
-
290
- // Empty table
291
- if (dom.select('tr', table).length === 0) {
292
- rng.setStartBefore(table);
293
- rng.setEndBefore(table);
294
- selection.setRng(rng);
295
- dom.remove(table);
296
- return;
297
- }
298
-
299
- // Empty header/body/footer
300
- each(dom.select('thead,tbody,tfoot', table), function(part) {
301
- if (part.rows.length === 0) {
302
- dom.remove(part);
303
- }
304
- });
305
-
306
- // Restore selection to start position if it still exists
307
- buildGrid();
308
-
309
- // If we have a valid startPos object
310
- if (startPos) {
311
- // Restore the selection to the closest table position
312
- row = grid[Math.min(grid.length - 1, startPos.y)];
313
- if (row) {
314
- selection.select(row[Math.min(row.length - 1, startPos.x)].elm, true);
315
- selection.collapse(true);
316
- }
317
- }
318
- }
319
-
320
- function fillLeftDown(x, y, rows, cols) {
321
- var tr, x2, r, c, cell;
322
-
323
- tr = grid[y][x].elm.parentNode;
324
- for (r = 1; r <= rows; r++) {
325
- tr = dom.getNext(tr, 'tr');
326
-
327
- if (tr) {
328
- // Loop left to find real cell
329
- for (x2 = x; x2 >= 0; x2--) {
330
- cell = grid[y + r][x2].elm;
331
-
332
- if (cell.parentNode == tr) {
333
- // Append clones after
334
- for (c = 1; c <= cols; c++) {
335
- dom.insertAfter(cloneCell(cell), cell);
336
- }
337
-
338
- break;
339
- }
340
- }
341
-
342
- if (x2 == -1) {
343
- // Insert nodes before first cell
344
- for (c = 1; c <= cols; c++) {
345
- tr.insertBefore(cloneCell(tr.cells[0]), tr.cells[0]);
346
- }
347
- }
348
- }
349
- }
350
- }
351
-
352
- function split() {
353
- each(grid, function(row, y) {
354
- each(row, function(cell, x) {
355
- var colSpan, rowSpan, i;
356
-
357
- if (isCellSelected(cell)) {
358
- cell = cell.elm;
359
- colSpan = getSpanVal(cell, 'colspan');
360
- rowSpan = getSpanVal(cell, 'rowspan');
361
-
362
- if (colSpan > 1 || rowSpan > 1) {
363
- setSpanVal(cell, 'rowSpan', 1);
364
- setSpanVal(cell, 'colSpan', 1);
365
-
366
- // Insert cells right
367
- for (i = 0; i < colSpan - 1; i++) {
368
- dom.insertAfter(cloneCell(cell), cell);
369
- }
370
-
371
- fillLeftDown(x, y, rowSpan - 1, colSpan);
372
- }
373
- }
374
- });
375
- });
376
- }
377
-
378
- function merge(cell, cols, rows) {
379
- var pos, startX, startY, endX, endY, x, y, startCell, endCell, children, count;
380
-
381
- // Use specified cell and cols/rows
382
- if (cell) {
383
- pos = getPos(cell);
384
- startX = pos.x;
385
- startY = pos.y;
386
- endX = startX + (cols - 1);
387
- endY = startY + (rows - 1);
388
- } else {
389
- startPos = endPos = null;
390
-
391
- // Calculate start/end pos by checking for selected cells in grid works better with context menu
392
- each(grid, function(row, y) {
393
- each(row, function(cell, x) {
394
- if (isCellSelected(cell)) {
395
- if (!startPos) {
396
- startPos = {x: x, y: y};
397
- }
398
-
399
- endPos = {x: x, y: y};
400
- }
401
- });
402
- });
403
-
404
- // Use selection, but make sure startPos is valid before accessing
405
- if (startPos) {
406
- startX = startPos.x;
407
- startY = startPos.y;
408
- endX = endPos.x;
409
- endY = endPos.y;
410
- }
411
- }
412
-
413
- // Find start/end cells
414
- startCell = getCell(startX, startY);
415
- endCell = getCell(endX, endY);
416
-
417
- // Check if the cells exists and if they are of the same part for example tbody = tbody
418
- if (startCell && endCell && startCell.part == endCell.part) {
419
- // Split and rebuild grid
420
- split();
421
- buildGrid();
422
-
423
- // Set row/col span to start cell
424
- startCell = getCell(startX, startY).elm;
425
- setSpanVal(startCell, 'colSpan', (endX - startX) + 1);
426
- setSpanVal(startCell, 'rowSpan', (endY - startY) + 1);
427
-
428
- // Remove other cells and add it's contents to the start cell
429
- for (y = startY; y <= endY; y++) {
430
- for (x = startX; x <= endX; x++) {
431
- if (!grid[y] || !grid[y][x]) {
432
- continue;
433
- }
434
-
435
- cell = grid[y][x].elm;
436
-
437
- /*jshint loopfunc:true */
438
- /*eslint no-loop-func:0 */
439
- if (cell != startCell) {
440
- // Move children to startCell
441
- children = Tools.grep(cell.childNodes);
442
- each(children, function(node) {
443
- startCell.appendChild(node);
444
- });
445
-
446
- // Remove bogus nodes if there is children in the target cell
447
- if (children.length) {
448
- children = Tools.grep(startCell.childNodes);
449
- count = 0;
450
- each(children, function(node) {
451
- if (node.nodeName == 'BR' && dom.getAttrib(node, 'data-mce-bogus') && count++ < children.length - 1) {
452
- startCell.removeChild(node);
453
- }
454
- });
455
- }
456
-
457
- dom.remove(cell);
458
- }
459
- }
460
- }
461
-
462
- // Remove empty rows etc and restore caret location
463
- cleanup();
464
- }
465
- }
466
-
467
- function insertRow(before) {
468
- var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell, rowSpan;
469
-
470
- // Find first/last row
471
- each(grid, function(row, y) {
472
- each(row, function(cell) {
473
- if (isCellSelected(cell)) {
474
- cell = cell.elm;
475
- rowElm = cell.parentNode;
476
- newRow = cloneNode(rowElm, false);
477
- posY = y;
478
-
479
- if (before) {
480
- return false;
481
- }
482
- }
483
- });
484
-
485
- if (before) {
486
- return !posY;
487
- }
488
- });
489
-
490
- // If posY is undefined there is nothing for us to do here...just return to avoid crashing below
491
- if (posY === undefined) {
492
- return;
493
- }
494
-
495
- for (x = 0; x < grid[0].length; x++) {
496
- // Cell not found could be because of an invalid table structure
497
- if (!grid[posY][x]) {
498
- continue;
499
- }
500
-
501
- cell = grid[posY][x].elm;
502
-
503
- if (cell != lastCell) {
504
- if (!before) {
505
- rowSpan = getSpanVal(cell, 'rowspan');
506
- if (rowSpan > 1) {
507
- setSpanVal(cell, 'rowSpan', rowSpan + 1);
508
- continue;
509
- }
510
- } else {
511
- // Check if cell above can be expanded
512
- if (posY > 0 && grid[posY - 1][x]) {
513
- otherCell = grid[posY - 1][x].elm;
514
- rowSpan = getSpanVal(otherCell, 'rowSpan');
515
- if (rowSpan > 1) {
516
- setSpanVal(otherCell, 'rowSpan', rowSpan + 1);
517
- continue;
518
- }
519
- }
520
- }
521
-
522
- // Insert new cell into new row
523
- newCell = cloneCell(cell);
524
- setSpanVal(newCell, 'colSpan', cell.colSpan);
525
-
526
- newRow.appendChild(newCell);
527
-
528
- lastCell = cell;
529
- }
530
- }
531
-
532
- if (newRow.hasChildNodes()) {
533
- if (!before) {
534
- dom.insertAfter(newRow, rowElm);
535
- } else {
536
- rowElm.parentNode.insertBefore(newRow, rowElm);
537
- }
538
- }
539
- }
540
-
541
- function insertCol(before) {
542
- var posX, lastCell;
543
-
544
- // Find first/last column
545
- each(grid, function(row) {
546
- each(row, function(cell, x) {
547
- if (isCellSelected(cell)) {
548
- posX = x;
549
-
550
- if (before) {
551
- return false;
552
- }
553
- }
554
- });
555
-
556
- if (before) {
557
- return !posX;
558
- }
559
- });
560
-
561
- each(grid, function(row, y) {
562
- var cell, rowSpan, colSpan;
563
-
564
- if (!row[posX]) {
565
- return;
566
- }
567
-
568
- cell = row[posX].elm;
569
- if (cell != lastCell) {
570
- colSpan = getSpanVal(cell, 'colspan');
571
- rowSpan = getSpanVal(cell, 'rowspan');
572
-
573
- if (colSpan == 1) {
574
- if (!before) {
575
- dom.insertAfter(cloneCell(cell), cell);
576
- fillLeftDown(posX, y, rowSpan - 1, colSpan);
577
- } else {
578
- cell.parentNode.insertBefore(cloneCell(cell), cell);
579
- fillLeftDown(posX, y, rowSpan - 1, colSpan);
580
- }
581
- } else {
582
- setSpanVal(cell, 'colSpan', cell.colSpan + 1);
583
- }
584
-
585
- lastCell = cell;
586
- }
587
- });
588
- }
589
-
590
- function deleteCols() {
591
- var cols = [];
592
-
593
- // Get selected column indexes
594
- each(grid, function(row) {
595
- each(row, function(cell, x) {
596
- if (isCellSelected(cell) && Tools.inArray(cols, x) === -1) {
597
- each(grid, function(row) {
598
- var cell = row[x].elm, colSpan;
599
-
600
- colSpan = getSpanVal(cell, 'colSpan');
601
-
602
- if (colSpan > 1) {
603
- setSpanVal(cell, 'colSpan', colSpan - 1);
604
- } else {
605
- dom.remove(cell);
606
- }
607
- });
608
-
609
- cols.push(x);
610
- }
611
- });
612
- });
613
-
614
- cleanup();
615
- }
616
-
617
- function deleteRows() {
618
- var rows;
619
-
620
- function deleteRow(tr) {
621
- var pos, lastCell;
622
-
623
- // Move down row spanned cells
624
- each(tr.cells, function(cell) {
625
- var rowSpan = getSpanVal(cell, 'rowSpan');
626
-
627
- if (rowSpan > 1) {
628
- setSpanVal(cell, 'rowSpan', rowSpan - 1);
629
- pos = getPos(cell);
630
- fillLeftDown(pos.x, pos.y, 1, 1);
631
- }
632
- });
633
-
634
- // Delete cells
635
- pos = getPos(tr.cells[0]);
636
- each(grid[pos.y], function(cell) {
637
- var rowSpan;
638
-
639
- cell = cell.elm;
640
-
641
- if (cell != lastCell) {
642
- rowSpan = getSpanVal(cell, 'rowSpan');
643
-
644
- if (rowSpan <= 1) {
645
- dom.remove(cell);
646
- } else {
647
- setSpanVal(cell, 'rowSpan', rowSpan - 1);
648
- }
649
-
650
- lastCell = cell;
651
- }
652
- });
653
- }
654
-
655
- // Get selected rows and move selection out of scope
656
- rows = getSelectedRows();
657
-
658
- // Delete all selected rows
659
- each(rows.reverse(), function(tr) {
660
- deleteRow(tr);
661
- });
662
-
663
- cleanup();
664
- }
665
-
666
- function cutRows() {
667
- var rows = getSelectedRows();
668
-
669
- dom.remove(rows);
670
- cleanup();
671
-
672
- return rows;
673
- }
674
-
675
- function copyRows() {
676
- var rows = getSelectedRows();
677
-
678
- each(rows, function(row, i) {
679
- rows[i] = cloneNode(row, true);
680
- });
681
-
682
- return rows;
683
- }
684
-
685
- function pasteRows(rows, before) {
686
- var selectedRows = getSelectedRows(),
687
- targetRow = selectedRows[before ? 0 : selectedRows.length - 1],
688
- targetCellCount = targetRow.cells.length;
689
-
690
- // Nothing to paste
691
- if (!rows) {
692
- return;
693
- }
694
-
695
- // Calc target cell count
696
- each(grid, function(row) {
697
- var match;
698
-
699
- targetCellCount = 0;
700
- each(row, function(cell) {
701
- if (cell.real) {
702
- targetCellCount += cell.colspan;
703
- }
704
-
705
- if (cell.elm.parentNode == targetRow) {
706
- match = 1;
707
- }
708
- });
709
-
710
- if (match) {
711
- return false;
712
- }
713
- });
714
-
715
- if (!before) {
716
- rows.reverse();
717
- }
718
-
719
- each(rows, function(row) {
720
- var i, cellCount = row.cells.length, cell;
721
-
722
- // Remove col/rowspans
723
- for (i = 0; i < cellCount; i++) {
724
- cell = row.cells[i];
725
- setSpanVal(cell, 'colSpan', 1);
726
- setSpanVal(cell, 'rowSpan', 1);
727
- }
728
-
729
- // Needs more cells
730
- for (i = cellCount; i < targetCellCount; i++) {
731
- row.appendChild(cloneCell(row.cells[cellCount - 1]));
732
- }
733
-
734
- // Needs less cells
735
- for (i = targetCellCount; i < cellCount; i++) {
736
- dom.remove(row.cells[i]);
737
- }
738
-
739
- // Add before/after
740
- if (before) {
741
- targetRow.parentNode.insertBefore(row, targetRow);
742
- } else {
743
- dom.insertAfter(row, targetRow);
744
- }
745
- });
746
-
747
- // Remove current selection
748
- dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
749
- }
750
-
751
- function getPos(target) {
752
- var pos;
753
-
754
- each(grid, function(row, y) {
755
- each(row, function(cell, x) {
756
- if (cell.elm == target) {
757
- pos = {x : x, y : y};
758
- return false;
759
- }
760
- });
761
-
762
- return !pos;
763
- });
764
-
765
- return pos;
766
- }
767
-
768
- function setStartCell(cell) {
769
- startPos = getPos(cell);
770
- }
771
-
772
- function findEndPos() {
773
- var maxX, maxY;
774
-
775
- maxX = maxY = 0;
776
-
777
- each(grid, function(row, y) {
778
- each(row, function(cell, x) {
779
- var colSpan, rowSpan;
780
-
781
- if (isCellSelected(cell)) {
782
- cell = grid[y][x];
783
-
784
- if (x > maxX) {
785
- maxX = x;
786
- }
787
-
788
- if (y > maxY) {
789
- maxY = y;
790
- }
791
-
792
- if (cell.real) {
793
- colSpan = cell.colspan - 1;
794
- rowSpan = cell.rowspan - 1;
795
-
796
- if (colSpan) {
797
- if (x + colSpan > maxX) {
798
- maxX = x + colSpan;
799
- }
800
- }
801
-
802
- if (rowSpan) {
803
- if (y + rowSpan > maxY) {
804
- maxY = y + rowSpan;
805
- }
806
- }
807
- }
808
- }
809
- });
810
- });
811
-
812
- return {x : maxX, y : maxY};
813
- }
814
-
815
- function setEndCell(cell) {
816
- var startX, startY, endX, endY, maxX, maxY, colSpan, rowSpan, x, y;
817
-
818
- endPos = getPos(cell);
819
-
820
- if (startPos && endPos) {
821
- // Get start/end positions
822
- startX = Math.min(startPos.x, endPos.x);
823
- startY = Math.min(startPos.y, endPos.y);
824
- endX = Math.max(startPos.x, endPos.x);
825
- endY = Math.max(startPos.y, endPos.y);
826
-
827
- // Expand end positon to include spans
828
- maxX = endX;
829
- maxY = endY;
830
-
831
- // Expand startX
832
- for (y = startY; y <= maxY; y++) {
833
- cell = grid[y][startX];
834
-
835
- if (!cell.real) {
836
- if (startX - (cell.colspan - 1) < startX) {
837
- startX -= cell.colspan - 1;
838
- }
839
- }
840
- }
841
-
842
- // Expand startY
843
- for (x = startX; x <= maxX; x++) {
844
- cell = grid[startY][x];
845
-
846
- if (!cell.real) {
847
- if (startY - (cell.rowspan - 1) < startY) {
848
- startY -= cell.rowspan - 1;
849
- }
850
- }
851
- }
852
-
853
- // Find max X, Y
854
- for (y = startY; y <= endY; y++) {
855
- for (x = startX; x <= endX; x++) {
856
- cell = grid[y][x];
857
-
858
- if (cell.real) {
859
- colSpan = cell.colspan - 1;
860
- rowSpan = cell.rowspan - 1;
861
-
862
- if (colSpan) {
863
- if (x + colSpan > maxX) {
864
- maxX = x + colSpan;
865
- }
866
- }
867
-
868
- if (rowSpan) {
869
- if (y + rowSpan > maxY) {
870
- maxY = y + rowSpan;
871
- }
872
- }
873
- }
874
- }
875
- }
876
-
877
- // Remove current selection
878
- dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
879
-
880
- // Add new selection
881
- for (y = startY; y <= maxY; y++) {
882
- for (x = startX; x <= maxX; x++) {
883
- if (grid[y][x]) {
884
- dom.addClass(grid[y][x].elm, 'mce-item-selected');
885
- }
886
- }
887
- }
888
- }
889
- }
890
-
891
- function moveRelIdx(cellElm, delta) {
892
- var pos, index, cell;
893
-
894
- pos = getPos(cellElm);
895
- index = pos.y * gridWidth + pos.x;
896
-
897
- do {
898
- index += delta;
899
- cell = getCell(index % gridWidth, Math.floor(index / gridWidth));
900
-
901
- if (!cell) {
902
- break;
903
- }
904
-
905
- if (cell.elm != cellElm) {
906
- selection.select(cell.elm, true);
907
-
908
- if (dom.isEmpty(cell.elm)) {
909
- selection.collapse(true);
910
- }
911
-
912
- return true;
913
- }
914
- } while (cell.elm == cellElm);
915
-
916
- return false;
917
- }
918
-
919
- table = table || dom.getParent(selection.getStart(), 'table');
920
-
921
- buildGrid();
922
-
923
- selectedCell = dom.getParent(selection.getStart(), 'th,td');
924
- if (selectedCell) {
925
- startPos = getPos(selectedCell);
926
- endPos = findEndPos();
927
- selectedCell = getCell(startPos.x, startPos.y);
928
- }
929
-
930
- Tools.extend(this, {
931
- deleteTable: deleteTable,
932
- split: split,
933
- merge: merge,
934
- insertRow: insertRow,
935
- insertCol: insertCol,
936
- deleteCols: deleteCols,
937
- deleteRows: deleteRows,
938
- cutRows: cutRows,
939
- copyRows: copyRows,
940
- pasteRows: pasteRows,
941
- getPos: getPos,
942
- setStartCell: setStartCell,
943
- setEndCell: setEndCell,
944
- moveRelIdx: moveRelIdx,
945
- refresh: buildGrid
946
- });
947
- };
948
- });
949
-
950
- // Included from: js/tinymce/plugins/table/classes/Quirks.js
951
-
952
- /**
953
- * Quirks.js
954
- *
955
- * Copyright, Moxiecode Systems AB
956
- * Released under LGPL License.
957
- *
958
- * License: http://www.tinymce.com/license
959
- * Contributing: http://www.tinymce.com/contributing
960
- */
961
-
962
- /**
963
- * This class includes fixes for various browser quirks.
964
- *
965
- * @class tinymce.tableplugin.Quirks
966
- * @private
967
- */
968
- define("tinymce/tableplugin/Quirks", [
969
- "tinymce/util/VK",
970
- "tinymce/Env",
971
- "tinymce/util/Tools"
972
- ], function(VK, Env, Tools) {
973
- var each = Tools.each;
974
-
975
- function getSpanVal(td, name) {
976
- return parseInt(td.getAttribute(name) || 1, 10);
977
- }
978
-
979
- return function(editor) {
980
- /**
981
- * Fixed caret movement around tables on WebKit.
982
- */
983
- function moveWebKitSelection() {
984
- function eventHandler(e) {
985
- var key = e.keyCode;
986
-
987
- function handle(upBool, sourceNode) {
988
- var siblingDirection = upBool ? 'previousSibling' : 'nextSibling';
989
- var currentRow = editor.dom.getParent(sourceNode, 'tr');
990
- var siblingRow = currentRow[siblingDirection];
991
-
992
- if (siblingRow) {
993
- moveCursorToRow(editor, sourceNode, siblingRow, upBool);
994
- e.preventDefault();
995
- return true;
996
- } else {
997
- var tableNode = editor.dom.getParent(currentRow, 'table');
998
- var middleNode = currentRow.parentNode;
999
- var parentNodeName = middleNode.nodeName.toLowerCase();
1000
- if (parentNodeName === 'tbody' || parentNodeName === (upBool ? 'tfoot' : 'thead')) {
1001
- var targetParent = getTargetParent(upBool, tableNode, middleNode, 'tbody');
1002
- if (targetParent !== null) {
1003
- return moveToRowInTarget(upBool, targetParent, sourceNode);
1004
- }
1005
- }
1006
- return escapeTable(upBool, currentRow, siblingDirection, tableNode);
1007
- }
1008
- }
1009
-
1010
- function getTargetParent(upBool, topNode, secondNode, nodeName) {
1011
- var tbodies = editor.dom.select('>' + nodeName, topNode);
1012
- var position = tbodies.indexOf(secondNode);
1013
- if (upBool && position === 0 || !upBool && position === tbodies.length - 1) {
1014
- return getFirstHeadOrFoot(upBool, topNode);
1015
- } else if (position === -1) {
1016
- var topOrBottom = secondNode.tagName.toLowerCase() === 'thead' ? 0 : tbodies.length - 1;
1017
- return tbodies[topOrBottom];
1018
- } else {
1019
- return tbodies[position + (upBool ? -1 : 1)];
1020
- }
1021
- }
1022
-
1023
- function getFirstHeadOrFoot(upBool, parent) {
1024
- var tagName = upBool ? 'thead' : 'tfoot';
1025
- var headOrFoot = editor.dom.select('>' + tagName, parent);
1026
- return headOrFoot.length !== 0 ? headOrFoot[0] : null;
1027
- }
1028
-
1029
- function moveToRowInTarget(upBool, targetParent, sourceNode) {
1030
- var targetRow = getChildForDirection(targetParent, upBool);
1031
-
1032
- if (targetRow) {
1033
- moveCursorToRow(editor, sourceNode, targetRow, upBool);
1034
- }
1035
-
1036
- e.preventDefault();
1037
- return true;
1038
- }
1039
-
1040
- function escapeTable(upBool, currentRow, siblingDirection, table) {
1041
- var tableSibling = table[siblingDirection];
1042
-
1043
- if (tableSibling) {
1044
- moveCursorToStartOfElement(tableSibling);
1045
- return true;
1046
- } else {
1047
- var parentCell = editor.dom.getParent(table, 'td,th');
1048
- if (parentCell) {
1049
- return handle(upBool, parentCell, e);
1050
- } else {
1051
- var backUpSibling = getChildForDirection(currentRow, !upBool);
1052
- moveCursorToStartOfElement(backUpSibling);
1053
- e.preventDefault();
1054
- return false;
1055
- }
1056
- }
1057
- }
1058
-
1059
- function getChildForDirection(parent, up) {
1060
- var child = parent && parent[up ? 'lastChild' : 'firstChild'];
1061
- // BR is not a valid table child to return in this case we return the table cell
1062
- return child && child.nodeName === 'BR' ? editor.dom.getParent(child, 'td,th') : child;
1063
- }
1064
-
1065
- function moveCursorToStartOfElement(n) {
1066
- editor.selection.setCursorLocation(n, 0);
1067
- }
1068
-
1069
- function isVerticalMovement() {
1070
- return key == VK.UP || key == VK.DOWN;
1071
- }
1072
-
1073
- function isInTable(editor) {
1074
- var node = editor.selection.getNode();
1075
- var currentRow = editor.dom.getParent(node, 'tr');
1076
- return currentRow !== null;
1077
- }
1078
-
1079
- function columnIndex(column) {
1080
- var colIndex = 0;
1081
- var c = column;
1082
- while (c.previousSibling) {
1083
- c = c.previousSibling;
1084
- colIndex = colIndex + getSpanVal(c, "colspan");
1085
- }
1086
- return colIndex;
1087
- }
1088
-
1089
- function findColumn(rowElement, columnIndex) {
1090
- var c = 0, r = 0;
1091
-
1092
- each(rowElement.children, function(cell, i) {
1093
- c = c + getSpanVal(cell, "colspan");
1094
- r = i;
1095
- if (c > columnIndex) {
1096
- return false;
1097
- }
1098
- });
1099
- return r;
1100
- }
1101
-
1102
- function moveCursorToRow(ed, node, row, upBool) {
1103
- var srcColumnIndex = columnIndex(editor.dom.getParent(node, 'td,th'));
1104
- var tgtColumnIndex = findColumn(row, srcColumnIndex);
1105
- var tgtNode = row.childNodes[tgtColumnIndex];
1106
- var rowCellTarget = getChildForDirection(tgtNode, upBool);
1107
- moveCursorToStartOfElement(rowCellTarget || tgtNode);
1108
- }
1109
-
1110
- function shouldFixCaret(preBrowserNode) {
1111
- var newNode = editor.selection.getNode();
1112
- var newParent = editor.dom.getParent(newNode, 'td,th');
1113
- var oldParent = editor.dom.getParent(preBrowserNode, 'td,th');
1114
-
1115
- return newParent && newParent !== oldParent && checkSameParentTable(newParent, oldParent);
1116
- }
1117
-
1118
- function checkSameParentTable(nodeOne, NodeTwo) {
1119
- return editor.dom.getParent(nodeOne, 'TABLE') === editor.dom.getParent(NodeTwo, 'TABLE');
1120
- }
1121
-
1122
- if (isVerticalMovement() && isInTable(editor)) {
1123
- var preBrowserNode = editor.selection.getNode();
1124
- setTimeout(function() {
1125
- if (shouldFixCaret(preBrowserNode)) {
1126
- handle(!e.shiftKey && key === VK.UP, preBrowserNode, e);
1127
- }
1128
- }, 0);
1129
- }
1130
- }
1131
-
1132
- editor.on('KeyDown', function(e) {
1133
- eventHandler(e);
1134
- });
1135
- }
1136
-
1137
- function fixBeforeTableCaretBug() {
1138
- // Checks if the selection/caret is at the start of the specified block element
1139
- function isAtStart(rng, par) {
1140
- var doc = par.ownerDocument, rng2 = doc.createRange(), elm;
1141
-
1142
- rng2.setStartBefore(par);
1143
- rng2.setEnd(rng.endContainer, rng.endOffset);
1144
-
1145
- elm = doc.createElement('body');
1146
- elm.appendChild(rng2.cloneContents());
1147
-
1148
- // Check for text characters of other elements that should be treated as content
1149
- return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length === 0;
1150
- }
1151
-
1152
- // Fixes an bug where it's impossible to place the caret before a table in Gecko
1153
- // this fix solves it by detecting when the caret is at the beginning of such a table
1154
- // and then manually moves the caret infront of the table
1155
- editor.on('KeyDown', function(e) {
1156
- var rng, table, dom = editor.dom;
1157
-
1158
- // On gecko it's not possible to place the caret before a table
1159
- if (e.keyCode == 37 || e.keyCode == 38) {
1160
- rng = editor.selection.getRng();
1161
- table = dom.getParent(rng.startContainer, 'table');
1162
-
1163
- if (table && editor.getBody().firstChild == table) {
1164
- if (isAtStart(rng, table)) {
1165
- rng = dom.createRng();
1166
-
1167
- rng.setStartBefore(table);
1168
- rng.setEndBefore(table);
1169
-
1170
- editor.selection.setRng(rng);
1171
-
1172
- e.preventDefault();
1173
- }
1174
- }
1175
- }
1176
- });
1177
- }
1178
-
1179
- // Fixes an issue on Gecko where it's impossible to place the caret behind a table
1180
- // This fix will force a paragraph element after the table but only when the forced_root_block setting is enabled
1181
- function fixTableCaretPos() {
1182
- editor.on('KeyDown SetContent VisualAid', function() {
1183
- var last;
1184
-
1185
- // Skip empty text nodes from the end
1186
- for (last = editor.getBody().lastChild; last; last = last.previousSibling) {
1187
- if (last.nodeType == 3) {
1188
- if (last.nodeValue.length > 0) {
1189
- break;
1190
- }
1191
- } else if (last.nodeType == 1 && (last.tagName == 'BR' || !last.getAttribute('data-mce-bogus'))) {
1192
- break;
1193
- }
1194
- }
1195
-
1196
- if (last && last.nodeName == 'TABLE') {
1197
- if (editor.settings.forced_root_block) {
1198
- editor.dom.add(
1199
- editor.getBody(),
1200
- editor.settings.forced_root_block,
1201
- editor.settings.forced_root_block_attrs,
1202
- Env.ie && Env.ie < 11 ? '&nbsp;' : '<br data-mce-bogus="1" />'
1203
- );
1204
- } else {
1205
- editor.dom.add(editor.getBody(), 'br', {'data-mce-bogus': '1'});
1206
- }
1207
- }
1208
- });
1209
-
1210
- editor.on('PreProcess', function(o) {
1211
- var last = o.node.lastChild;
1212
-
1213
- if (last && (last.nodeName == "BR" || (last.childNodes.length == 1 &&
1214
- (last.firstChild.nodeName == 'BR' || last.firstChild.nodeValue == '\u00a0'))) &&
1215
- last.previousSibling && last.previousSibling.nodeName == "TABLE") {
1216
- editor.dom.remove(last);
1217
- }
1218
- });
1219
- }
1220
-
1221
- // this nasty hack is here to work around some WebKit selection bugs.
1222
- function fixTableCellSelection() {
1223
- function tableCellSelected(ed, rng, n, currentCell) {
1224
- // The decision of when a table cell is selected is somewhat involved. The fact that this code is
1225
- // required is actually a pointer to the root cause of this bug. A cell is selected when the start
1226
- // and end offsets are 0, the start container is a text, and the selection node is either a TR (most cases)
1227
- // or the parent of the table (in the case of the selection containing the last cell of a table).
1228
- var TEXT_NODE = 3, table = ed.dom.getParent(rng.startContainer, 'TABLE');
1229
- var tableParent, allOfCellSelected, tableCellSelection;
1230
-
1231
- if (table) {
1232
- tableParent = table.parentNode;
1233
- }
1234
-
1235
- allOfCellSelected = rng.startContainer.nodeType == TEXT_NODE &&
1236
- rng.startOffset === 0 &&
1237
- rng.endOffset === 0 &&
1238
- currentCell &&
1239
- (n.nodeName == "TR" || n == tableParent);
1240
-
1241
- tableCellSelection = (n.nodeName == "TD" || n.nodeName == "TH") && !currentCell;
1242
-
1243
- return allOfCellSelected || tableCellSelection;
1244
- }
1245
-
1246
- function fixSelection() {
1247
- var rng = editor.selection.getRng();
1248
- var n = editor.selection.getNode();
1249
- var currentCell = editor.dom.getParent(rng.startContainer, 'TD,TH');
1250
-
1251
- if (!tableCellSelected(editor, rng, n, currentCell)) {
1252
- return;
1253
- }
1254
-
1255
- if (!currentCell) {
1256
- currentCell = n;
1257
- }
1258
-
1259
- // Get the very last node inside the table cell
1260
- var end = currentCell.lastChild;
1261
- while (end.lastChild) {
1262
- end = end.lastChild;
1263
- }
1264
-
1265
- // Select the entire table cell. Nothing outside of the table cell should be selected.
1266
- if (end.nodeType == 3) {
1267
- rng.setEnd(end, end.data.length);
1268
- editor.selection.setRng(rng);
1269
- }
1270
- }
1271
-
1272
- editor.on('KeyDown', function() {
1273
- fixSelection();
1274
- });
1275
-
1276
- editor.on('MouseDown', function(e) {
1277
- if (e.button != 2) {
1278
- fixSelection();
1279
- }
1280
- });
1281
- }
1282
-
1283
- /**
1284
- * Delete table if all cells are selected.
1285
- */
1286
- function deleteTable() {
1287
- editor.on('keydown', function(e) {
1288
- if ((e.keyCode == VK.DELETE || e.keyCode == VK.BACKSPACE) && !e.isDefaultPrevented()) {
1289
- var table = editor.dom.getParent(editor.selection.getStart(), 'table');
1290
-
1291
- if (table) {
1292
- var cells = editor.dom.select('td,th', table), i = cells.length;
1293
- while (i--) {
1294
- if (!editor.dom.hasClass(cells[i], 'mce-item-selected')) {
1295
- return;
1296
- }
1297
- }
1298
-
1299
- e.preventDefault();
1300
- editor.execCommand('mceTableDelete');
1301
- }
1302
- }
1303
- });
1304
- }
1305
-
1306
- deleteTable();
1307
-
1308
- if (Env.webkit) {
1309
- moveWebKitSelection();
1310
- fixTableCellSelection();
1311
- }
1312
-
1313
- if (Env.gecko) {
1314
- fixBeforeTableCaretBug();
1315
- fixTableCaretPos();
1316
- }
1317
-
1318
- if (Env.ie > 10) {
1319
- fixBeforeTableCaretBug();
1320
- fixTableCaretPos();
1321
- }
1322
- };
1323
- });
1324
-
1325
- // Included from: js/tinymce/plugins/table/classes/CellSelection.js
1326
-
1327
- /**
1328
- * CellSelection.js
1329
- *
1330
- * Copyright, Moxiecode Systems AB
1331
- * Released under LGPL License.
1332
- *
1333
- * License: http://www.tinymce.com/license
1334
- * Contributing: http://www.tinymce.com/contributing
1335
- */
1336
-
1337
- /**
1338
- * This class handles table cell selection by faking it using a css class that gets applied
1339
- * to cells when dragging the mouse from one cell to another.
1340
- *
1341
- * @class tinymce.tableplugin.CellSelection
1342
- * @private
1343
- */
1344
- define("tinymce/tableplugin/CellSelection", [
1345
- "tinymce/tableplugin/TableGrid",
1346
- "tinymce/dom/TreeWalker",
1347
- "tinymce/util/Tools"
1348
- ], function(TableGrid, TreeWalker, Tools) {
1349
- return function(editor) {
1350
- var dom = editor.dom, tableGrid, startCell, startTable, hasCellSelection = true, resizing;
1351
-
1352
- function clear(force) {
1353
- // Restore selection possibilities
1354
- editor.getBody().style.webkitUserSelect = '';
1355
-
1356
- if (force || hasCellSelection) {
1357
- editor.dom.removeClass(
1358
- editor.dom.select('td.mce-item-selected,th.mce-item-selected'),
1359
- 'mce-item-selected'
1360
- );
1361
-
1362
- hasCellSelection = false;
1363
- }
1364
- }
1365
-
1366
- function cellSelectionHandler(e) {
1367
- var sel, table, target = e.target;
1368
-
1369
- if (resizing) {
1370
- return;
1371
- }
1372
-
1373
- if (startCell && (tableGrid || target != startCell) && (target.nodeName == 'TD' || target.nodeName == 'TH')) {
1374
- table = dom.getParent(target, 'table');
1375
- if (table == startTable) {
1376
- if (!tableGrid) {
1377
- tableGrid = new TableGrid(editor, table);
1378
- tableGrid.setStartCell(startCell);
1379
-
1380
- editor.getBody().style.webkitUserSelect = 'none';
1381
- }
1382
-
1383
- tableGrid.setEndCell(target);
1384
- hasCellSelection = true;
1385
- }
1386
-
1387
- // Remove current selection
1388
- sel = editor.selection.getSel();
1389
-
1390
- try {
1391
- if (sel.removeAllRanges) {
1392
- sel.removeAllRanges();
1393
- } else {
1394
- sel.empty();
1395
- }
1396
- } catch (ex) {
1397
- // IE9 might throw errors here
1398
- }
1399
-
1400
- e.preventDefault();
1401
- }
1402
- }
1403
-
1404
- // Add cell selection logic
1405
- editor.on('MouseDown', function(e) {
1406
- if (e.button != 2 && !resizing) {
1407
- clear();
1408
-
1409
- startCell = dom.getParent(e.target, 'td,th');
1410
- startTable = dom.getParent(startCell, 'table');
1411
- }
1412
- });
1413
-
1414
- editor.on('mouseover', cellSelectionHandler);
1415
-
1416
- editor.on('remove', function() {
1417
- dom.unbind(editor.getDoc(), 'mouseover', cellSelectionHandler);
1418
- });
1419
-
1420
- editor.on('MouseUp', function() {
1421
- var rng, sel = editor.selection, selectedCells, walker, node, lastNode;
1422
-
1423
- function setPoint(node, start) {
1424
- var walker = new TreeWalker(node, node);
1425
-
1426
- do {
1427
- // Text node
1428
- if (node.nodeType == 3 && Tools.trim(node.nodeValue).length !== 0) {
1429
- if (start) {
1430
- rng.setStart(node, 0);
1431
- } else {
1432
- rng.setEnd(node, node.nodeValue.length);
1433
- }
1434
-
1435
- return;
1436
- }
1437
-
1438
- // BR element
1439
- if (node.nodeName == 'BR') {
1440
- if (start) {
1441
- rng.setStartBefore(node);
1442
- } else {
1443
- rng.setEndBefore(node);
1444
- }
1445
-
1446
- return;
1447
- }
1448
- } while ((node = (start ? walker.next() : walker.prev())));
1449
- }
1450
-
1451
- // Move selection to startCell
1452
- if (startCell) {
1453
- if (tableGrid) {
1454
- editor.getBody().style.webkitUserSelect = '';
1455
- }
1456
-
1457
- // Try to expand text selection as much as we can only Gecko supports cell selection
1458
- selectedCells = dom.select('td.mce-item-selected,th.mce-item-selected');
1459
- if (selectedCells.length > 0) {
1460
- rng = dom.createRng();
1461
- node = selectedCells[0];
1462
- rng.setStartBefore(node);
1463
- rng.setEndAfter(node);
1464
-
1465
- setPoint(node, 1);
1466
- walker = new TreeWalker(node, dom.getParent(selectedCells[0], 'table'));
1467
-
1468
- do {
1469
- if (node.nodeName == 'TD' || node.nodeName == 'TH') {
1470
- if (!dom.hasClass(node, 'mce-item-selected')) {
1471
- break;
1472
- }
1473
-
1474
- lastNode = node;
1475
- }
1476
- } while ((node = walker.next()));
1477
-
1478
- setPoint(lastNode);
1479
-
1480
- sel.setRng(rng);
1481
- }
1482
-
1483
- editor.nodeChanged();
1484
- startCell = tableGrid = startTable = null;
1485
- }
1486
- });
1487
-
1488
- editor.on('KeyUp Drop SetContent', function(e) {
1489
- clear(e.type == 'setcontent');
1490
- startCell = tableGrid = startTable = null;
1491
- resizing = false;
1492
- });
1493
-
1494
- editor.on('ObjectResizeStart ObjectResized', function(e) {
1495
- resizing = e.type != 'objectresized';
1496
- });
1497
-
1498
- return {
1499
- clear: clear
1500
- };
1501
- };
1502
- });
1503
-
1504
- // Included from: js/tinymce/plugins/table/classes/Dialogs.js
1505
-
1506
- /**
1507
- * Dialogs.js
1508
- *
1509
- * Copyright, Moxiecode Systems AB
1510
- * Released under LGPL License.
1511
- *
1512
- * License: http://www.tinymce.com/license
1513
- * Contributing: http://www.tinymce.com/contributing
1514
- */
1515
-
1516
- /**
1517
- * ...
1518
- *
1519
- * @class tinymce.tableplugin.Dialogs
1520
- * @private
1521
- */
1522
- define("tinymce/tableplugin/Dialogs", [
1523
- "tinymce/util/Tools",
1524
- "tinymce/Env"
1525
- ], function(Tools, Env) {
1526
- var each = Tools.each;
1527
-
1528
- return function(editor) {
1529
- var self = this;
1530
-
1531
- function createColorPickAction() {
1532
- var colorPickerCallback = editor.settings.color_picker_callback;
1533
-
1534
- if (colorPickerCallback) {
1535
- return function() {
1536
- var self = this;
1537
-
1538
- colorPickerCallback.call(
1539
- editor,
1540
- function(value) {
1541
- self.value(value).fire('change');
1542
- },
1543
- self.value()
1544
- );
1545
- };
1546
- }
1547
- }
1548
-
1549
- function createStyleForm(dom) {
1550
- return {
1551
- title: 'Advanced',
1552
- type: 'form',
1553
- defaults: {
1554
- onchange: function() {
1555
- updateStyle(dom, this.parents().reverse()[0], this.name() == "style");
1556
- }
1557
- },
1558
- items: [
1559
- {
1560
- label: 'Style',
1561
- name: 'style',
1562
- type: 'textbox'
1563
- },
1564
-
1565
- {
1566
- type: 'form',
1567
- padding: 0,
1568
- formItemDefaults: {
1569
- layout: 'grid',
1570
- alignH: ['start', 'right']
1571
- },
1572
- defaults: {
1573
- size: 7
1574
- },
1575
- items: [
1576
- {
1577
- label: 'Border color',
1578
- type: 'colorbox',
1579
- name: 'borderColor',
1580
- onaction: createColorPickAction()
1581
- },
1582
-
1583
- {
1584
- label: 'Background color',
1585
- type: 'colorbox',
1586
- name: 'backgroundColor',
1587
- onaction: createColorPickAction()
1588
- }
1589
- ]
1590
- }
1591
- ]
1592
- };
1593
- }
1594
-
1595
- function removePxSuffix(size) {
1596
- return size ? size.replace(/px$/, '') : "";
1597
- }
1598
-
1599
- function addSizeSuffix(size) {
1600
- if (/^[0-9]+$/.test(size)) {
1601
- size += "px";
1602
- }
1603
-
1604
- return size;
1605
- }
1606
-
1607
- function unApplyAlign(elm) {
1608
- each('left center right'.split(' '), function(name) {
1609
- editor.formatter.remove('align' + name, {}, elm);
1610
- });
1611
- }
1612
-
1613
- function unApplyVAlign(elm) {
1614
- each('top middle bottom'.split(' '), function(name) {
1615
- editor.formatter.remove('valign' + name, {}, elm);
1616
- });
1617
- }
1618
-
1619
- function buildListItems(inputList, itemCallback, startItems) {
1620
- function appendItems(values, output) {
1621
- output = output || [];
1622
-
1623
- Tools.each(values, function(item) {
1624
- var menuItem = {text: item.text || item.title};
1625
-
1626
- if (item.menu) {
1627
- menuItem.menu = appendItems(item.menu);
1628
- } else {
1629
- menuItem.value = item.value;
1630
-
1631
- if (itemCallback) {
1632
- itemCallback(menuItem);
1633
- }
1634
- }
1635
-
1636
- output.push(menuItem);
1637
- });
1638
-
1639
- return output;
1640
- }
1641
-
1642
- return appendItems(inputList, startItems || []);
1643
- }
1644
-
1645
- function updateStyle(dom, win, isStyleCtrl) {
1646
- var data = win.toJSON();
1647
- var css = dom.parseStyle(data.style);
1648
-
1649
- if (isStyleCtrl) {
1650
- win.find('#borderColor').value(css["border-color"] || '')[0].fire('change');
1651
- win.find('#backgroundColor').value(css["background-color"] || '')[0].fire('change');
1652
- } else {
1653
- css["border-color"] = data.borderColor;
1654
- css["background-color"] = data.backgroundColor;
1655
- }
1656
-
1657
- win.find('#style').value(dom.serializeStyle(dom.parseStyle(dom.serializeStyle(css))));
1658
- }
1659
-
1660
- function appendStylesToData(dom, data, elm) {
1661
- var css = dom.parseStyle(dom.getAttrib(elm, 'style'));
1662
-
1663
- if (css["border-color"]) {
1664
- data.borderColor = css["border-color"];
1665
- }
1666
-
1667
- if (css["background-color"]) {
1668
- data.backgroundColor = css["background-color"];
1669
- }
1670
-
1671
- data.style = dom.serializeStyle(css);
1672
- }
1673
-
1674
- self.tableProps = function() {
1675
- self.table(true);
1676
- };
1677
-
1678
- self.table = function(isProps) {
1679
- var dom = editor.dom, tableElm, colsCtrl, rowsCtrl, classListCtrl, data = {}, generalTableForm;
1680
-
1681
- function onSubmitTableForm() {
1682
- var captionElm;
1683
-
1684
- updateStyle(dom, this);
1685
- data = Tools.extend(data, this.toJSON());
1686
-
1687
- Tools.each('backgroundColor borderColor'.split(' '), function(name) {
1688
- delete data[name];
1689
- });
1690
-
1691
- if (data["class"] === false) {
1692
- delete data["class"];
1693
- }
1694
-
1695
- editor.undoManager.transact(function() {
1696
- if (!tableElm) {
1697
- tableElm = editor.plugins.table.insertTable(data.cols || 1, data.rows || 1);
1698
- }
1699
-
1700
- editor.dom.setAttribs(tableElm, {
1701
- cellspacing: data.cellspacing,
1702
- cellpadding: data.cellpadding,
1703
- border: data.border,
1704
- style: data.style,
1705
- 'class': data['class']
1706
- });
1707
-
1708
- if (dom.getAttrib(tableElm, 'width')) {
1709
- dom.setAttrib(tableElm, 'width', removePxSuffix(data.width));
1710
- } else {
1711
- dom.setStyle(tableElm, 'width', addSizeSuffix(data.width));
1712
- }
1713
-
1714
- dom.setStyle(tableElm, 'height', addSizeSuffix(data.height));
1715
-
1716
- // Toggle caption on/off
1717
- captionElm = dom.select('caption', tableElm)[0];
1718
-
1719
- if (captionElm && !data.caption) {
1720
- dom.remove(captionElm);
1721
- }
1722
-
1723
- if (!captionElm && data.caption) {
1724
- captionElm = dom.create('caption');
1725
- captionElm.innerHTML = !Env.ie ? '<br data-mce-bogus="1"/>' : '\u00a0';
1726
- tableElm.insertBefore(captionElm, tableElm.firstChild);
1727
- }
1728
-
1729
- unApplyAlign(tableElm);
1730
- if (data.align) {
1731
- editor.formatter.apply('align' + data.align, {}, tableElm);
1732
- }
1733
-
1734
- editor.focus();
1735
- editor.addVisual();
1736
- });
1737
- }
1738
-
1739
- if (isProps === true) {
1740
- tableElm = dom.getParent(editor.selection.getStart(), 'table');
1741
-
1742
- if (tableElm) {
1743
- data = {
1744
- width: removePxSuffix(dom.getStyle(tableElm, 'width') || dom.getAttrib(tableElm, 'width')),
1745
- height: removePxSuffix(dom.getStyle(tableElm, 'height') || dom.getAttrib(tableElm, 'height')),
1746
- cellspacing: tableElm ? dom.getAttrib(tableElm, 'cellspacing') : '',
1747
- cellpadding: tableElm ? dom.getAttrib(tableElm, 'cellpadding') : '',
1748
- border: tableElm ? dom.getAttrib(tableElm, 'border') : '',
1749
- caption: !!dom.select('caption', tableElm)[0],
1750
- 'class': dom.getAttrib(tableElm, 'class')
1751
- };
1752
-
1753
- each('left center right'.split(' '), function(name) {
1754
- if (editor.formatter.matchNode(tableElm, 'align' + name)) {
1755
- data.align = name;
1756
- }
1757
- });
1758
- }
1759
- } else {
1760
- colsCtrl = {label: 'Cols', name: 'cols'};
1761
- rowsCtrl = {label: 'Rows', name: 'rows'};
1762
- }
1763
-
1764
- if (editor.settings.table_class_list) {
1765
- if (data["class"]) {
1766
- data["class"] = data["class"].replace(/\s*mce\-item\-table\s*/g, '');
1767
- }
1768
-
1769
- classListCtrl = {
1770
- name: 'class',
1771
- type: 'listbox',
1772
- label: 'Class',
1773
- values: buildListItems(
1774
- editor.settings.table_class_list,
1775
- function(item) {
1776
- if (item.value) {
1777
- item.textStyle = function() {
1778
- return editor.formatter.getCssText({block: 'table', classes: [item.value]});
1779
- };
1780
- }
1781
- }
1782
- )
1783
- };
1784
- }
1785
-
1786
- generalTableForm = {
1787
- type: 'form',
1788
- layout: 'flex',
1789
- direction: 'column',
1790
- labelGapCalc: 'children',
1791
- padding: 0,
1792
- items: [
1793
- {
1794
- type: 'form',
1795
- labelGapCalc: false,
1796
- padding: 0,
1797
- layout: 'grid',
1798
- columns: 2,
1799
- defaults: {
1800
- type: 'textbox',
1801
- maxWidth: 50
1802
- },
1803
- items: [
1804
- colsCtrl,
1805
- rowsCtrl,
1806
- {label: 'Width', name: 'width'},
1807
- {label: 'Height', name: 'height'},
1808
- {label: 'Cell spacing', name: 'cellspacing'},
1809
- {label: 'Cell padding', name: 'cellpadding'},
1810
- {label: 'Border', name: 'border'},
1811
- {label: 'Caption', name: 'caption', type: 'checkbox'}
1812
- ]
1813
- },
1814
-
1815
- {
1816
- label: 'Alignment',
1817
- name: 'align',
1818
- type: 'listbox',
1819
- text: 'None',
1820
- values: [
1821
- {text: 'None', value: ''},
1822
- {text: 'Left', value: 'left'},
1823
- {text: 'Center', value: 'center'},
1824
- {text: 'Right', value: 'right'}
1825
- ]
1826
- },
1827
-
1828
- classListCtrl
1829
- ]
1830
- };
1831
-
1832
- if (editor.settings.table_advtab !== false) {
1833
- appendStylesToData(dom, data, tableElm);
1834
-
1835
- editor.windowManager.open({
1836
- title: "Table properties",
1837
- data: data,
1838
- bodyType: 'tabpanel',
1839
- body: [
1840
- {
1841
- title: 'General',
1842
- type: 'form',
1843
- items: generalTableForm
1844
- },
1845
- createStyleForm(dom)
1846
- ],
1847
-
1848
- onsubmit: onSubmitTableForm
1849
- });
1850
- } else {
1851
- editor.windowManager.open({
1852
- title: "Table properties",
1853
- data: data,
1854
- body: generalTableForm,
1855
- onsubmit: onSubmitTableForm
1856
- });
1857
- }
1858
- };
1859
-
1860
- self.merge = function(grid, cell) {
1861
- editor.windowManager.open({
1862
- title: "Merge cells",
1863
- body: [
1864
- {label: 'Cols', name: 'cols', type: 'textbox', value: '1', size: 10},
1865
- {label: 'Rows', name: 'rows', type: 'textbox', value: '1', size: 10}
1866
- ],
1867
- onsubmit: function() {
1868
- var data = this.toJSON();
1869
-
1870
- editor.undoManager.transact(function() {
1871
- grid.merge(cell, data.cols, data.rows);
1872
- });
1873
- }
1874
- });
1875
- };
1876
-
1877
- self.cell = function() {
1878
- var dom = editor.dom, cellElm, data, classListCtrl, cells = [];
1879
-
1880
- function onSubmitCellForm() {
1881
- updateStyle(dom, this);
1882
- data = Tools.extend(data, this.toJSON());
1883
-
1884
- editor.undoManager.transact(function() {
1885
- each(cells, function(cellElm) {
1886
- editor.dom.setAttribs(cellElm, {
1887
- scope: data.scope,
1888
- style: data.style,
1889
- 'class': data['class']
1890
- });
1891
-
1892
- editor.dom.setStyles(cellElm, {
1893
- width: addSizeSuffix(data.width),
1894
- height: addSizeSuffix(data.height)
1895
- });
1896
-
1897
- // Switch cell type
1898
- if (data.type && cellElm.nodeName.toLowerCase() != data.type) {
1899
- cellElm = dom.rename(cellElm, data.type);
1900
- }
1901
-
1902
- // Apply/remove alignment
1903
- unApplyAlign(cellElm);
1904
- if (data.align) {
1905
- editor.formatter.apply('align' + data.align, {}, cellElm);
1906
- }
1907
-
1908
- // Apply/remove vertical alignment
1909
- unApplyVAlign(cellElm);
1910
- if (data.valign) {
1911
- editor.formatter.apply('valign' + data.valign, {}, cellElm);
1912
- }
1913
- });
1914
-
1915
- editor.focus();
1916
- });
1917
- }
1918
-
1919
- // Get selected cells or the current cell
1920
- cells = editor.dom.select('td.mce-item-selected,th.mce-item-selected');
1921
- cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th');
1922
- if (!cells.length && cellElm) {
1923
- cells.push(cellElm);
1924
- }
1925
-
1926
- cellElm = cellElm || cells[0];
1927
-
1928
- if (!cellElm) {
1929
- // If this element is null, return now to avoid crashing.
1930
- return;
1931
- }
1932
-
1933
- data = {
1934
- width: removePxSuffix(dom.getStyle(cellElm, 'width') || dom.getAttrib(cellElm, 'width')),
1935
- height: removePxSuffix(dom.getStyle(cellElm, 'height') || dom.getAttrib(cellElm, 'height')),
1936
- scope: dom.getAttrib(cellElm, 'scope'),
1937
- 'class': dom.getAttrib(cellElm, 'class')
1938
- };
1939
-
1940
- data.type = cellElm.nodeName.toLowerCase();
1941
-
1942
- each('left center right'.split(' '), function(name) {
1943
- if (editor.formatter.matchNode(cellElm, 'align' + name)) {
1944
- data.align = name;
1945
- }
1946
- });
1947
-
1948
- each('top middle bottom'.split(' '), function(name) {
1949
- if (editor.formatter.matchNode(cellElm, 'valign' + name)) {
1950
- data.valign = name;
1951
- }
1952
- });
1953
-
1954
- if (editor.settings.table_cell_class_list) {
1955
- classListCtrl = {
1956
- name: 'class',
1957
- type: 'listbox',
1958
- label: 'Class',
1959
- values: buildListItems(
1960
- editor.settings.table_cell_class_list,
1961
- function(item) {
1962
- if (item.value) {
1963
- item.textStyle = function() {
1964
- return editor.formatter.getCssText({block: 'td', classes: [item.value]});
1965
- };
1966
- }
1967
- }
1968
- )
1969
- };
1970
- }
1971
-
1972
- var generalCellForm = {
1973
- type: 'form',
1974
- layout: 'flex',
1975
- direction: 'column',
1976
- labelGapCalc: 'children',
1977
- padding: 0,
1978
- items: [
1979
- {
1980
- type: 'form',
1981
- layout: 'grid',
1982
- columns: 2,
1983
- labelGapCalc: false,
1984
- padding: 0,
1985
- defaults: {
1986
- type: 'textbox',
1987
- maxWidth: 50
1988
- },
1989
- items: [
1990
- {label: 'Width', name: 'width'},
1991
- {label: 'Height', name: 'height'},
1992
- {
1993
- label: 'Cell type',
1994
- name: 'type',
1995
- type: 'listbox',
1996
- text: 'None',
1997
- minWidth: 90,
1998
- maxWidth: null,
1999
- values: [
2000
- {text: 'Cell', value: 'td'},
2001
- {text: 'Header cell', value: 'th'}
2002
- ]
2003
- },
2004
- {
2005
- label: 'Scope',
2006
- name: 'scope',
2007
- type: 'listbox',
2008
- text: 'None',
2009
- minWidth: 90,
2010
- maxWidth: null,
2011
- values: [
2012
- {text: 'None', value: ''},
2013
- {text: 'Row', value: 'row'},
2014
- {text: 'Column', value: 'col'},
2015
- {text: 'Row group', value: 'rowgroup'},
2016
- {text: 'Column group', value: 'colgroup'}
2017
- ]
2018
- },
2019
- {
2020
- label: 'H Align',
2021
- name: 'align',
2022
- type: 'listbox',
2023
- text: 'None',
2024
- minWidth: 90,
2025
- maxWidth: null,
2026
- values: [
2027
- {text: 'None', value: ''},
2028
- {text: 'Left', value: 'left'},
2029
- {text: 'Center', value: 'center'},
2030
- {text: 'Right', value: 'right'}
2031
- ]
2032
- },
2033
- {
2034
- label: 'V Align',
2035
- name: 'valign',
2036
- type: 'listbox',
2037
- text: 'None',
2038
- minWidth: 90,
2039
- maxWidth: null,
2040
- values: [
2041
- {text: 'None', value: ''},
2042
- {text: 'Top', value: 'top'},
2043
- {text: 'Middle', value: 'middle'},
2044
- {text: 'Bottom', value: 'bottom'}
2045
- ]
2046
- }
2047
- ]
2048
- },
2049
-
2050
- classListCtrl
2051
- ]
2052
- };
2053
-
2054
- if (editor.settings.table_cell_advtab !== false) {
2055
- appendStylesToData(dom, data, cellElm);
2056
-
2057
- editor.windowManager.open({
2058
- title: "Cell properties",
2059
- bodyType: 'tabpanel',
2060
- data: data,
2061
- body: [
2062
- {
2063
- title: 'General',
2064
- type: 'form',
2065
- items: generalCellForm
2066
- },
2067
-
2068
- createStyleForm(dom)
2069
- ],
2070
-
2071
- onsubmit: onSubmitCellForm
2072
- });
2073
- } else {
2074
- editor.windowManager.open({
2075
- title: "Cell properties",
2076
- data: data,
2077
- body: generalCellForm,
2078
- onsubmit: onSubmitCellForm
2079
- });
2080
- }
2081
- };
2082
-
2083
- self.row = function() {
2084
- var dom = editor.dom, tableElm, cellElm, rowElm, classListCtrl, data, rows = [], generalRowForm;
2085
-
2086
- function onSubmitRowForm() {
2087
- var tableElm, oldParentElm, parentElm;
2088
-
2089
- updateStyle(dom, this);
2090
- data = Tools.extend(data, this.toJSON());
2091
-
2092
- editor.undoManager.transact(function() {
2093
- var toType = data.type;
2094
-
2095
- each(rows, function(rowElm) {
2096
- editor.dom.setAttribs(rowElm, {
2097
- scope: data.scope,
2098
- style: data.style,
2099
- 'class': data['class']
2100
- });
2101
-
2102
- editor.dom.setStyles(rowElm, {
2103
- height: addSizeSuffix(data.height)
2104
- });
2105
-
2106
- if (toType != rowElm.parentNode.nodeName.toLowerCase()) {
2107
- tableElm = dom.getParent(rowElm, 'table');
2108
-
2109
- oldParentElm = rowElm.parentNode;
2110
- parentElm = dom.select(toType, tableElm)[0];
2111
- if (!parentElm) {
2112
- parentElm = dom.create(toType);
2113
- if (tableElm.firstChild) {
2114
- tableElm.insertBefore(parentElm, tableElm.firstChild);
2115
- } else {
2116
- tableElm.appendChild(parentElm);
2117
- }
2118
- }
2119
-
2120
- parentElm.appendChild(rowElm);
2121
-
2122
- if (!oldParentElm.hasChildNodes()) {
2123
- dom.remove(oldParentElm);
2124
- }
2125
- }
2126
-
2127
- // Apply/remove alignment
2128
- unApplyAlign(rowElm);
2129
- if (data.align) {
2130
- editor.formatter.apply('align' + data.align, {}, rowElm);
2131
- }
2132
- });
2133
-
2134
- editor.focus();
2135
- });
2136
- }
2137
-
2138
- tableElm = editor.dom.getParent(editor.selection.getStart(), 'table');
2139
- cellElm = editor.dom.getParent(editor.selection.getStart(), 'td,th');
2140
-
2141
- each(tableElm.rows, function(row) {
2142
- each(row.cells, function(cell) {
2143
- if (dom.hasClass(cell, 'mce-item-selected') || cell == cellElm) {
2144
- rows.push(row);
2145
- return false;
2146
- }
2147
- });
2148
- });
2149
-
2150
- rowElm = rows[0];
2151
- if (!rowElm) {
2152
- // If this element is null, return now to avoid crashing.
2153
- return;
2154
- }
2155
-
2156
- data = {
2157
- height: removePxSuffix(dom.getStyle(rowElm, 'height') || dom.getAttrib(rowElm, 'height')),
2158
- scope: dom.getAttrib(rowElm, 'scope'),
2159
- 'class': dom.getAttrib(rowElm, 'class')
2160
- };
2161
-
2162
- data.type = rowElm.parentNode.nodeName.toLowerCase();
2163
-
2164
- each('left center right'.split(' '), function(name) {
2165
- if (editor.formatter.matchNode(rowElm, 'align' + name)) {
2166
- data.align = name;
2167
- }
2168
- });
2169
-
2170
- if (editor.settings.table_row_class_list) {
2171
- classListCtrl = {
2172
- name: 'class',
2173
- type: 'listbox',
2174
- label: 'Class',
2175
- values: buildListItems(
2176
- editor.settings.table_row_class_list,
2177
- function(item) {
2178
- if (item.value) {
2179
- item.textStyle = function() {
2180
- return editor.formatter.getCssText({block: 'tr', classes: [item.value]});
2181
- };
2182
- }
2183
- }
2184
- )
2185
- };
2186
- }
2187
-
2188
- generalRowForm = {
2189
- type: 'form',
2190
- columns: 2,
2191
- padding: 0,
2192
- defaults: {
2193
- type: 'textbox'
2194
- },
2195
- items: [
2196
- {
2197
- type: 'listbox',
2198
- name: 'type',
2199
- label: 'Row type',
2200
- text: 'None',
2201
- maxWidth: null,
2202
- values: [
2203
- {text: 'Header', value: 'thead'},
2204
- {text: 'Body', value: 'tbody'},
2205
- {text: 'Footer', value: 'tfoot'}
2206
- ]
2207
- },
2208
- {
2209
- type: 'listbox',
2210
- name: 'align',
2211
- label: 'Alignment',
2212
- text: 'None',
2213
- maxWidth: null,
2214
- values: [
2215
- {text: 'None', value: ''},
2216
- {text: 'Left', value: 'left'},
2217
- {text: 'Center', value: 'center'},
2218
- {text: 'Right', value: 'right'}
2219
- ]
2220
- },
2221
- {label: 'Height', name: 'height'},
2222
- classListCtrl
2223
- ]
2224
- };
2225
-
2226
- if (editor.settings.table_row_advtab !== false) {
2227
- appendStylesToData(dom, data, rowElm);
2228
-
2229
- editor.windowManager.open({
2230
- title: "Row properties",
2231
- data: data,
2232
- bodyType: 'tabpanel',
2233
- body: [
2234
- {
2235
- title: 'General',
2236
- type: 'form',
2237
- items: generalRowForm
2238
- },
2239
- createStyleForm(dom)
2240
- ],
2241
-
2242
- onsubmit: onSubmitRowForm
2243
- });
2244
- } else {
2245
- editor.windowManager.open({
2246
- title: "Row properties",
2247
- data: data,
2248
- body: generalRowForm,
2249
- onsubmit: onSubmitRowForm
2250
- });
2251
- }
2252
- };
2253
- };
2254
- });
2255
-
2256
- // Included from: js/tinymce/plugins/table/classes/Plugin.js
2257
-
2258
- /**
2259
- * Plugin.js
2260
- *
2261
- * Copyright, Moxiecode Systems AB
2262
- * Released under LGPL License.
2263
- *
2264
- * License: http://www.tinymce.com/license
2265
- * Contributing: http://www.tinymce.com/contributing
2266
- */
2267
-
2268
- /**
2269
- * This class contains all core logic for the table plugin.
2270
- *
2271
- * @class tinymce.tableplugin.Plugin
2272
- * @private
2273
- */
2274
- define("tinymce/tableplugin/Plugin", [
2275
- "tinymce/tableplugin/TableGrid",
2276
- "tinymce/tableplugin/Quirks",
2277
- "tinymce/tableplugin/CellSelection",
2278
- "tinymce/tableplugin/Dialogs",
2279
- "tinymce/util/Tools",
2280
- "tinymce/dom/TreeWalker",
2281
- "tinymce/Env",
2282
- "tinymce/PluginManager"
2283
- ], function(TableGrid, Quirks, CellSelection, Dialogs, Tools, TreeWalker, Env, PluginManager) {
2284
- var each = Tools.each;
2285
-
2286
- function Plugin(editor) {
2287
- var clipboardRows, self = this, dialogs = new Dialogs(editor);
2288
-
2289
- function cmd(command) {
2290
- return function() {
2291
- editor.execCommand(command);
2292
- };
2293
- }
2294
-
2295
- function insertTable(cols, rows) {
2296
- var y, x, html, tableElm;
2297
-
2298
- html = '<table id="__mce"><tbody>';
2299
-
2300
- for (y = 0; y < rows; y++) {
2301
- html += '<tr>';
2302
-
2303
- for (x = 0; x < cols; x++) {
2304
- html += '<td>' + (Env.ie ? " " : '<br>') + '</td>';
2305
- }
2306
-
2307
- html += '</tr>';
2308
- }
2309
-
2310
- html += '</tbody></table>';
2311
-
2312
- editor.undoManager.transact(function() {
2313
- editor.insertContent(html);
2314
-
2315
- tableElm = editor.dom.get('__mce');
2316
- editor.dom.setAttrib(tableElm, 'id', null);
2317
-
2318
- editor.dom.setAttribs(tableElm, editor.settings.table_default_attributes || {});
2319
- editor.dom.setStyles(tableElm, editor.settings.table_default_styles || {});
2320
- });
2321
-
2322
- return tableElm;
2323
- }
2324
-
2325
- function handleDisabledState(ctrl, selector) {
2326
- function bindStateListener() {
2327
- ctrl.disabled(!editor.dom.getParent(editor.selection.getStart(), selector));
2328
-
2329
- editor.selection.selectorChanged(selector, function(state) {
2330
- ctrl.disabled(!state);
2331
- });
2332
- }
2333
-
2334
- if (editor.initialized) {
2335
- bindStateListener();
2336
- } else {
2337
- editor.on('init', bindStateListener);
2338
- }
2339
- }
2340
-
2341
- function postRender() {
2342
- /*jshint validthis:true*/
2343
- handleDisabledState(this, 'table');
2344
- }
2345
-
2346
- function postRenderCell() {
2347
- /*jshint validthis:true*/
2348
- handleDisabledState(this, 'td,th');
2349
- }
2350
-
2351
- function generateTableGrid() {
2352
- var html = '';
2353
-
2354
- html = '<table role="grid" class="mce-grid mce-grid-border" aria-readonly="true">';
2355
-
2356
- for (var y = 0; y < 10; y++) {
2357
- html += '<tr>';
2358
-
2359
- for (var x = 0; x < 10; x++) {
2360
- html += '<td role="gridcell" tabindex="-1"><a id="mcegrid' + (y * 10 + x) + '" href="#" ' +
2361
- 'data-mce-x="' + x + '" data-mce-y="' + y + '"></a></td>';
2362
- }
2363
-
2364
- html += '</tr>';
2365
- }
2366
-
2367
- html += '</table>';
2368
-
2369
- html += '<div class="mce-text-center" role="presentation">1 x 1</div>';
2370
-
2371
- return html;
2372
- }
2373
-
2374
- function selectGrid(tx, ty, control) {
2375
- var table = control.getEl().getElementsByTagName('table')[0];
2376
- var x, y, focusCell, cell, active;
2377
- var rtl = control.isRtl() || control.parent().rel == 'tl-tr';
2378
-
2379
- table.nextSibling.innerHTML = (tx + 1) + ' x ' + (ty + 1);
2380
-
2381
- if (rtl) {
2382
- tx = 9 - tx;
2383
- }
2384
-
2385
- for (y = 0; y < 10; y++) {
2386
- for (x = 0; x < 10; x++) {
2387
- cell = table.rows[y].childNodes[x].firstChild;
2388
- active = (rtl ? x >= tx : x <= tx) && y <= ty;
2389
-
2390
- editor.dom.toggleClass(cell, 'mce-active', active);
2391
-
2392
- if (active) {
2393
- focusCell = cell;
2394
- }
2395
- }
2396
- }
2397
-
2398
- return focusCell.parentNode;
2399
- }
2400
-
2401
- if (editor.settings.table_grid === false) {
2402
- editor.addMenuItem('inserttable', {
2403
- text: 'Insert table',
2404
- icon: 'table',
2405
- context: 'table',
2406
- onclick: dialogs.table
2407
- });
2408
- } else {
2409
- editor.addMenuItem('inserttable', {
2410
- text: 'Insert table',
2411
- icon: 'table',
2412
- context: 'table',
2413
- ariaHideMenu: true,
2414
- onclick: function(e) {
2415
- if (e.aria) {
2416
- this.parent().hideAll();
2417
- e.stopImmediatePropagation();
2418
- dialogs.table();
2419
- }
2420
- },
2421
- onshow: function() {
2422
- selectGrid(0, 0, this.menu.items()[0]);
2423
- },
2424
- onhide: function() {
2425
- var elements = this.menu.items()[0].getEl().getElementsByTagName('a');
2426
- editor.dom.removeClass(elements, 'mce-active');
2427
- editor.dom.addClass(elements[0], 'mce-active');
2428
- },
2429
- menu: [
2430
- {
2431
- type: 'container',
2432
- html: generateTableGrid(),
2433
-
2434
- onPostRender: function() {
2435
- this.lastX = this.lastY = 0;
2436
- },
2437
-
2438
- onmousemove: function(e) {
2439
- var target = e.target, x, y;
2440
-
2441
- if (target.tagName.toUpperCase() == 'A') {
2442
- x = parseInt(target.getAttribute('data-mce-x'), 10);
2443
- y = parseInt(target.getAttribute('data-mce-y'), 10);
2444
-
2445
- if (this.isRtl() || this.parent().rel == 'tl-tr') {
2446
- x = 9 - x;
2447
- }
2448
-
2449
- if (x !== this.lastX || y !== this.lastY) {
2450
- selectGrid(x, y, e.control);
2451
-
2452
- this.lastX = x;
2453
- this.lastY = y;
2454
- }
2455
- }
2456
- },
2457
-
2458
- onclick: function(e) {
2459
- var self = this;
2460
-
2461
- if (e.target.tagName.toUpperCase() == 'A') {
2462
- e.preventDefault();
2463
- e.stopPropagation();
2464
- self.parent().cancel();
2465
-
2466
- editor.undoManager.transact(function() {
2467
- insertTable(self.lastX + 1, self.lastY + 1);
2468
- });
2469
-
2470
- editor.addVisual();
2471
- }
2472
- }
2473
- }
2474
- ]
2475
- });
2476
- }
2477
-
2478
- editor.addMenuItem('tableprops', {
2479
- text: 'Table properties',
2480
- context: 'table',
2481
- onPostRender: postRender,
2482
- onclick: dialogs.tableProps
2483
- });
2484
-
2485
- editor.addMenuItem('deletetable', {
2486
- text: 'Delete table',
2487
- context: 'table',
2488
- onPostRender: postRender,
2489
- cmd: 'mceTableDelete'
2490
- });
2491
-
2492
- editor.addMenuItem('cell', {
2493
- separator: 'before',
2494
- text: 'Cell',
2495
- context: 'table',
2496
- menu: [
2497
- {text: 'Cell properties', onclick: cmd('mceTableCellProps'), onPostRender: postRenderCell},
2498
- {text: 'Merge cells', onclick: cmd('mceTableMergeCells'), onPostRender: postRenderCell},
2499
- {text: 'Split cell', onclick: cmd('mceTableSplitCells'), onPostRender: postRenderCell}
2500
- ]
2501
- });
2502
-
2503
- editor.addMenuItem('row', {
2504
- text: 'Row',
2505
- context: 'table',
2506
- menu: [
2507
- {text: 'Insert row before', onclick: cmd('mceTableInsertRowBefore'), onPostRender: postRenderCell},
2508
- {text: 'Insert row after', onclick: cmd('mceTableInsertRowAfter'), onPostRender: postRenderCell},
2509
- {text: 'Delete row', onclick: cmd('mceTableDeleteRow'), onPostRender: postRenderCell},
2510
- {text: 'Row properties', onclick: cmd('mceTableRowProps'), onPostRender: postRenderCell},
2511
- {text: '-'},
2512
- {text: 'Cut row', onclick: cmd('mceTableCutRow'), onPostRender: postRenderCell},
2513
- {text: 'Copy row', onclick: cmd('mceTableCopyRow'), onPostRender: postRenderCell},
2514
- {text: 'Paste row before', onclick: cmd('mceTablePasteRowBefore'), onPostRender: postRenderCell},
2515
- {text: 'Paste row after', onclick: cmd('mceTablePasteRowAfter'), onPostRender: postRenderCell}
2516
- ]
2517
- });
2518
-
2519
- editor.addMenuItem('column', {
2520
- text: 'Column',
2521
- context: 'table',
2522
- menu: [
2523
- {text: 'Insert column before', onclick: cmd('mceTableInsertColBefore'), onPostRender: postRenderCell},
2524
- {text: 'Insert column after', onclick: cmd('mceTableInsertColAfter'), onPostRender: postRenderCell},
2525
- {text: 'Delete column', onclick: cmd('mceTableDeleteCol'), onPostRender: postRenderCell}
2526
- ]
2527
- });
2528
-
2529
- var menuItems = [];
2530
- each("inserttable tableprops deletetable | cell row column".split(' '), function(name) {
2531
- if (name == '|') {
2532
- menuItems.push({text: '-'});
2533
- } else {
2534
- menuItems.push(editor.menuItems[name]);
2535
- }
2536
- });
2537
-
2538
- editor.addButton("table", {
2539
- type: "menubutton",
2540
- title: "Table",
2541
- menu: menuItems
2542
- });
2543
-
2544
- // Select whole table is a table border is clicked
2545
- if (!Env.isIE) {
2546
- editor.on('click', function(e) {
2547
- e = e.target;
2548
-
2549
- if (e.nodeName === 'TABLE') {
2550
- editor.selection.select(e);
2551
- editor.nodeChanged();
2552
- }
2553
- });
2554
- }
2555
-
2556
- self.quirks = new Quirks(editor);
2557
-
2558
- editor.on('Init', function() {
2559
- self.cellSelection = new CellSelection(editor);
2560
- });
2561
-
2562
- // Register action commands
2563
- each({
2564
- mceTableSplitCells: function(grid) {
2565
- grid.split();
2566
- },
2567
-
2568
- mceTableMergeCells: function(grid) {
2569
- var cell;
2570
-
2571
- cell = editor.dom.getParent(editor.selection.getStart(), 'th,td');
2572
-
2573
- if (!editor.dom.select('td.mce-item-selected,th.mce-item-selected').length) {
2574
- dialogs.merge(grid, cell);
2575
- } else {
2576
- grid.merge();
2577
- }
2578
- },
2579
-
2580
- mceTableInsertRowBefore: function(grid) {
2581
- grid.insertRow(true);
2582
- },
2583
-
2584
- mceTableInsertRowAfter: function(grid) {
2585
- grid.insertRow();
2586
- },
2587
-
2588
- mceTableInsertColBefore: function(grid) {
2589
- grid.insertCol(true);
2590
- },
2591
-
2592
- mceTableInsertColAfter: function(grid) {
2593
- grid.insertCol();
2594
- },
2595
-
2596
- mceTableDeleteCol: function(grid) {
2597
- grid.deleteCols();
2598
- },
2599
-
2600
- mceTableDeleteRow: function(grid) {
2601
- grid.deleteRows();
2602
- },
2603
-
2604
- mceTableCutRow: function(grid) {
2605
- clipboardRows = grid.cutRows();
2606
- },
2607
-
2608
- mceTableCopyRow: function(grid) {
2609
- clipboardRows = grid.copyRows();
2610
- },
2611
-
2612
- mceTablePasteRowBefore: function(grid) {
2613
- grid.pasteRows(clipboardRows, true);
2614
- },
2615
-
2616
- mceTablePasteRowAfter: function(grid) {
2617
- grid.pasteRows(clipboardRows);
2618
- },
2619
-
2620
- mceTableDelete: function(grid) {
2621
- grid.deleteTable();
2622
- }
2623
- }, function(func, name) {
2624
- editor.addCommand(name, function() {
2625
- var grid = new TableGrid(editor);
2626
-
2627
- if (grid) {
2628
- func(grid);
2629
- editor.execCommand('mceRepaint');
2630
- self.cellSelection.clear();
2631
- }
2632
- });
2633
- });
2634
-
2635
- // Register dialog commands
2636
- each({
2637
- mceInsertTable: dialogs.table,
2638
- mceTableProps: function() {
2639
- dialogs.table(true);
2640
- },
2641
- mceTableRowProps: dialogs.row,
2642
- mceTableCellProps: dialogs.cell
2643
- }, function(func, name) {
2644
- editor.addCommand(name, function(ui, val) {
2645
- func(val);
2646
- });
2647
- });
2648
-
2649
- // Enable tab key cell navigation
2650
- if (editor.settings.table_tab_navigation !== false) {
2651
- editor.on('keydown', function(e) {
2652
- var cellElm, grid, delta;
2653
-
2654
- if (e.keyCode == 9) {
2655
- cellElm = editor.dom.getParent(editor.selection.getStart(), 'th,td');
2656
-
2657
- if (cellElm) {
2658
- e.preventDefault();
2659
-
2660
- grid = new TableGrid(editor);
2661
- delta = e.shiftKey ? -1 : 1;
2662
-
2663
- editor.undoManager.transact(function() {
2664
- if (!grid.moveRelIdx(cellElm, delta) && delta > 0) {
2665
- grid.insertRow();
2666
- grid.refresh();
2667
- grid.moveRelIdx(cellElm, delta);
2668
- }
2669
- });
2670
- }
2671
- }
2672
- });
2673
- }
2674
-
2675
- self.insertTable = insertTable;
2676
- }
2677
-
2678
- PluginManager.add('table', Plugin);
2679
- });
2680
- })(this);