mirador_rails 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (206) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +12 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +5 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +13 -0
  7. data/README.md +97 -0
  8. data/Rakefile +6 -0
  9. data/bin/console +14 -0
  10. data/bin/setup +8 -0
  11. data/lib/mirador_rails.rb +16 -0
  12. data/lib/mirador_rails/version.rb +3 -0
  13. data/lib/mirador_rails/view_helpers.rb +30 -0
  14. data/mirador_rails.gemspec +30 -0
  15. data/vendor/assets/images/border_type_1.png +0 -0
  16. data/vendor/assets/images/border_type_2.png +0 -0
  17. data/vendor/assets/images/border_type_3.png +0 -0
  18. data/vendor/assets/images/debut_dark.png +0 -0
  19. data/vendor/assets/javascripts/mirador.js +1 -0
  20. data/vendor/assets/javascripts/mirador.min.js +88 -0
  21. data/vendor/assets/javascripts/mirador.min.js.map +1 -0
  22. data/vendor/assets/locales/ar/translation.json +42 -0
  23. data/vendor/assets/locales/de/translation.json +77 -0
  24. data/vendor/assets/locales/en/translation.json +82 -0
  25. data/vendor/assets/locales/es/translation.json +35 -0
  26. data/vendor/assets/locales/fr/translation.json +77 -0
  27. data/vendor/assets/locales/ga/translation.json +39 -0
  28. data/vendor/assets/locales/ja/translation.json +82 -0
  29. data/vendor/assets/locales/ko/translation.json +74 -0
  30. data/vendor/assets/locales/nl/translation.json +39 -0
  31. data/vendor/assets/locales/zh-CN/translation.json +74 -0
  32. data/vendor/assets/locales/zh-TW/translation.json +74 -0
  33. data/vendor/assets/locales/zh/translation.json +74 -0
  34. data/vendor/assets/plugins/plugins/advlist/plugin.js +97 -0
  35. data/vendor/assets/plugins/plugins/advlist/plugin.min.js +1 -0
  36. data/vendor/assets/plugins/plugins/anchor/plugin.js +45 -0
  37. data/vendor/assets/plugins/plugins/anchor/plugin.min.js +1 -0
  38. data/vendor/assets/plugins/plugins/autolink/plugin.js +194 -0
  39. data/vendor/assets/plugins/plugins/autolink/plugin.min.js +1 -0
  40. data/vendor/assets/plugins/plugins/autoresize/plugin.js +152 -0
  41. data/vendor/assets/plugins/plugins/autoresize/plugin.min.js +1 -0
  42. data/vendor/assets/plugins/plugins/autosave/plugin.js +165 -0
  43. data/vendor/assets/plugins/plugins/autosave/plugin.min.js +1 -0
  44. data/vendor/assets/plugins/plugins/bbcode/plugin.js +123 -0
  45. data/vendor/assets/plugins/plugins/bbcode/plugin.min.js +1 -0
  46. data/vendor/assets/plugins/plugins/charmap/plugin.js +370 -0
  47. data/vendor/assets/plugins/plugins/charmap/plugin.min.js +1 -0
  48. data/vendor/assets/plugins/plugins/code/plugin.js +60 -0
  49. data/vendor/assets/plugins/plugins/code/plugin.min.js +1 -0
  50. data/vendor/assets/plugins/plugins/colorpicker/plugin.js +112 -0
  51. data/vendor/assets/plugins/plugins/colorpicker/plugin.min.js +1 -0
  52. data/vendor/assets/plugins/plugins/compat3x/css/dialog.css +118 -0
  53. data/vendor/assets/plugins/plugins/compat3x/img/buttons.png +0 -0
  54. data/vendor/assets/plugins/plugins/compat3x/img/icons.gif +0 -0
  55. data/vendor/assets/plugins/plugins/compat3x/img/items.gif +0 -0
  56. data/vendor/assets/plugins/plugins/compat3x/img/menu_arrow.gif +0 -0
  57. data/vendor/assets/plugins/plugins/compat3x/img/menu_check.gif +0 -0
  58. data/vendor/assets/plugins/plugins/compat3x/img/progress.gif +0 -0
  59. data/vendor/assets/plugins/plugins/compat3x/img/tabs.gif +0 -0
  60. data/vendor/assets/plugins/plugins/compat3x/plugin.js +297 -0
  61. data/vendor/assets/plugins/plugins/compat3x/plugin.min.js +1 -0
  62. data/vendor/assets/plugins/plugins/compat3x/tiny_mce_popup.js +542 -0
  63. data/vendor/assets/plugins/plugins/compat3x/utils/editable_selects.js +70 -0
  64. data/vendor/assets/plugins/plugins/compat3x/utils/form_utils.js +210 -0
  65. data/vendor/assets/plugins/plugins/compat3x/utils/mctabs.js +164 -0
  66. data/vendor/assets/plugins/plugins/compat3x/utils/validate.js +252 -0
  67. data/vendor/assets/plugins/plugins/contextmenu/plugin.js +87 -0
  68. data/vendor/assets/plugins/plugins/contextmenu/plugin.min.js +1 -0
  69. data/vendor/assets/plugins/plugins/directionality/plugin.js +64 -0
  70. data/vendor/assets/plugins/plugins/directionality/plugin.min.js +1 -0
  71. data/vendor/assets/plugins/plugins/emoticons/img/smiley-cool.gif +0 -0
  72. data/vendor/assets/plugins/plugins/emoticons/img/smiley-cry.gif +0 -0
  73. data/vendor/assets/plugins/plugins/emoticons/img/smiley-embarassed.gif +0 -0
  74. data/vendor/assets/plugins/plugins/emoticons/img/smiley-foot-in-mouth.gif +0 -0
  75. data/vendor/assets/plugins/plugins/emoticons/img/smiley-frown.gif +0 -0
  76. data/vendor/assets/plugins/plugins/emoticons/img/smiley-innocent.gif +0 -0
  77. data/vendor/assets/plugins/plugins/emoticons/img/smiley-kiss.gif +0 -0
  78. data/vendor/assets/plugins/plugins/emoticons/img/smiley-laughing.gif +0 -0
  79. data/vendor/assets/plugins/plugins/emoticons/img/smiley-money-mouth.gif +0 -0
  80. data/vendor/assets/plugins/plugins/emoticons/img/smiley-sealed.gif +0 -0
  81. data/vendor/assets/plugins/plugins/emoticons/img/smiley-smile.gif +0 -0
  82. data/vendor/assets/plugins/plugins/emoticons/img/smiley-surprised.gif +0 -0
  83. data/vendor/assets/plugins/plugins/emoticons/img/smiley-tongue-out.gif +0 -0
  84. data/vendor/assets/plugins/plugins/emoticons/img/smiley-undecided.gif +0 -0
  85. data/vendor/assets/plugins/plugins/emoticons/img/smiley-wink.gif +0 -0
  86. data/vendor/assets/plugins/plugins/emoticons/img/smiley-yell.gif +0 -0
  87. data/vendor/assets/plugins/plugins/emoticons/plugin.js +65 -0
  88. data/vendor/assets/plugins/plugins/emoticons/plugin.min.js +1 -0
  89. data/vendor/assets/plugins/plugins/example/dialog.html +8 -0
  90. data/vendor/assets/plugins/plugins/example/plugin.js +68 -0
  91. data/vendor/assets/plugins/plugins/example/plugin.min.js +1 -0
  92. data/vendor/assets/plugins/plugins/example_dependency/plugin.js +22 -0
  93. data/vendor/assets/plugins/plugins/example_dependency/plugin.min.js +1 -0
  94. data/vendor/assets/plugins/plugins/fullpage/plugin.js +490 -0
  95. data/vendor/assets/plugins/plugins/fullpage/plugin.min.js +1 -0
  96. data/vendor/assets/plugins/plugins/fullscreen/plugin.js +136 -0
  97. data/vendor/assets/plugins/plugins/fullscreen/plugin.min.js +1 -0
  98. data/vendor/assets/plugins/plugins/hr/plugin.js +30 -0
  99. data/vendor/assets/plugins/plugins/hr/plugin.min.js +1 -0
  100. data/vendor/assets/plugins/plugins/image/plugin.js +439 -0
  101. data/vendor/assets/plugins/plugins/image/plugin.min.js +1 -0
  102. data/vendor/assets/plugins/plugins/importcss/plugin.js +195 -0
  103. data/vendor/assets/plugins/plugins/importcss/plugin.min.js +1 -0
  104. data/vendor/assets/plugins/plugins/insertdatetime/plugin.js +121 -0
  105. data/vendor/assets/plugins/plugins/insertdatetime/plugin.min.js +1 -0
  106. data/vendor/assets/plugins/plugins/layer/plugin.js +225 -0
  107. data/vendor/assets/plugins/plugins/layer/plugin.min.js +1 -0
  108. data/vendor/assets/plugins/plugins/legacyoutput/plugin.js +211 -0
  109. data/vendor/assets/plugins/plugins/legacyoutput/plugin.min.js +1 -0
  110. data/vendor/assets/plugins/plugins/link/plugin.js +400 -0
  111. data/vendor/assets/plugins/plugins/link/plugin.min.js +1 -0
  112. data/vendor/assets/plugins/plugins/lists/plugin.js +791 -0
  113. data/vendor/assets/plugins/plugins/lists/plugin.min.js +1 -0
  114. data/vendor/assets/plugins/plugins/media/moxieplayer.swf +0 -0
  115. data/vendor/assets/plugins/plugins/media/plugin.js +774 -0
  116. data/vendor/assets/plugins/plugins/media/plugin.min.js +1 -0
  117. data/vendor/assets/plugins/plugins/nonbreaking/plugin.js +53 -0
  118. data/vendor/assets/plugins/plugins/nonbreaking/plugin.min.js +1 -0
  119. data/vendor/assets/plugins/plugins/noneditable/plugin.js +540 -0
  120. data/vendor/assets/plugins/plugins/noneditable/plugin.min.js +1 -0
  121. data/vendor/assets/plugins/plugins/pagebreak/plugin.js +88 -0
  122. data/vendor/assets/plugins/plugins/pagebreak/plugin.min.js +1 -0
  123. data/vendor/assets/plugins/plugins/paste/classes/Clipboard.js +634 -0
  124. data/vendor/assets/plugins/plugins/paste/classes/Plugin.js +110 -0
  125. data/vendor/assets/plugins/plugins/paste/classes/Quirks.js +159 -0
  126. data/vendor/assets/plugins/plugins/paste/classes/Utils.js +130 -0
  127. data/vendor/assets/plugins/plugins/paste/classes/WordFilter.js +493 -0
  128. data/vendor/assets/plugins/plugins/paste/plugin.dev.js +120 -0
  129. data/vendor/assets/plugins/plugins/paste/plugin.js +1625 -0
  130. data/vendor/assets/plugins/plugins/paste/plugin.min.js +1 -0
  131. data/vendor/assets/plugins/plugins/preview/plugin.js +88 -0
  132. data/vendor/assets/plugins/plugins/preview/plugin.min.js +1 -0
  133. data/vendor/assets/plugins/plugins/print/plugin.js +32 -0
  134. data/vendor/assets/plugins/plugins/print/plugin.min.js +1 -0
  135. data/vendor/assets/plugins/plugins/save/plugin.js +94 -0
  136. data/vendor/assets/plugins/plugins/save/plugin.min.js +1 -0
  137. data/vendor/assets/plugins/plugins/searchreplace/plugin.js +594 -0
  138. data/vendor/assets/plugins/plugins/searchreplace/plugin.min.js +1 -0
  139. data/vendor/assets/plugins/plugins/spellchecker/classes/DomTextMatcher.js +470 -0
  140. data/vendor/assets/plugins/plugins/spellchecker/classes/Plugin.js +436 -0
  141. data/vendor/assets/plugins/plugins/spellchecker/plugin.dev.js +117 -0
  142. data/vendor/assets/plugins/plugins/spellchecker/plugin.js +996 -0
  143. data/vendor/assets/plugins/plugins/spellchecker/plugin.min.js +1 -0
  144. data/vendor/assets/plugins/plugins/tabfocus/plugin.js +120 -0
  145. data/vendor/assets/plugins/plugins/tabfocus/plugin.min.js +1 -0
  146. data/vendor/assets/plugins/plugins/table/classes/CellSelection.js +176 -0
  147. data/vendor/assets/plugins/plugins/table/classes/Dialogs.js +749 -0
  148. data/vendor/assets/plugins/plugins/table/classes/Plugin.js +422 -0
  149. data/vendor/assets/plugins/plugins/table/classes/Quirks.js +372 -0
  150. data/vendor/assets/plugins/plugins/table/classes/TableGrid.js +864 -0
  151. data/vendor/assets/plugins/plugins/table/plugin.dev.js +118 -0
  152. data/vendor/assets/plugins/plugins/table/plugin.js +2680 -0
  153. data/vendor/assets/plugins/plugins/table/plugin.min.js +1 -0
  154. data/vendor/assets/plugins/plugins/template/plugin.js +262 -0
  155. data/vendor/assets/plugins/plugins/template/plugin.min.js +1 -0
  156. data/vendor/assets/plugins/plugins/textcolor/plugin.js +272 -0
  157. data/vendor/assets/plugins/plugins/textcolor/plugin.min.js +1 -0
  158. data/vendor/assets/plugins/plugins/textpattern/plugin.js +268 -0
  159. data/vendor/assets/plugins/plugins/textpattern/plugin.min.js +1 -0
  160. data/vendor/assets/plugins/plugins/visualblocks/css/visualblocks.css +135 -0
  161. data/vendor/assets/plugins/plugins/visualblocks/img/address.gif +0 -0
  162. data/vendor/assets/plugins/plugins/visualblocks/img/article.gif +0 -0
  163. data/vendor/assets/plugins/plugins/visualblocks/img/aside.gif +0 -0
  164. data/vendor/assets/plugins/plugins/visualblocks/img/blockquote.gif +0 -0
  165. data/vendor/assets/plugins/plugins/visualblocks/img/div.gif +0 -0
  166. data/vendor/assets/plugins/plugins/visualblocks/img/dl.gif +0 -0
  167. data/vendor/assets/plugins/plugins/visualblocks/img/figure.gif +0 -0
  168. data/vendor/assets/plugins/plugins/visualblocks/img/h1.gif +0 -0
  169. data/vendor/assets/plugins/plugins/visualblocks/img/h2.gif +0 -0
  170. data/vendor/assets/plugins/plugins/visualblocks/img/h3.gif +0 -0
  171. data/vendor/assets/plugins/plugins/visualblocks/img/h4.gif +0 -0
  172. data/vendor/assets/plugins/plugins/visualblocks/img/h5.gif +0 -0
  173. data/vendor/assets/plugins/plugins/visualblocks/img/h6.gif +0 -0
  174. data/vendor/assets/plugins/plugins/visualblocks/img/hgroup.gif +0 -0
  175. data/vendor/assets/plugins/plugins/visualblocks/img/ol.gif +0 -0
  176. data/vendor/assets/plugins/plugins/visualblocks/img/p.gif +0 -0
  177. data/vendor/assets/plugins/plugins/visualblocks/img/pre.gif +0 -0
  178. data/vendor/assets/plugins/plugins/visualblocks/img/section.gif +0 -0
  179. data/vendor/assets/plugins/plugins/visualblocks/img/ul.gif +0 -0
  180. data/vendor/assets/plugins/plugins/visualblocks/plugin.js +86 -0
  181. data/vendor/assets/plugins/plugins/visualblocks/plugin.min.js +1 -0
  182. data/vendor/assets/plugins/plugins/visualchars/plugin.js +88 -0
  183. data/vendor/assets/plugins/plugins/visualchars/plugin.min.js +1 -0
  184. data/vendor/assets/plugins/plugins/wordcount/plugin.js +69 -0
  185. data/vendor/assets/plugins/plugins/wordcount/plugin.min.js +1 -0
  186. data/vendor/assets/skins/skins/lightgray/content.inline.min.css +1 -0
  187. data/vendor/assets/skins/skins/lightgray/content.min.css +1 -0
  188. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.eot +0 -0
  189. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.svg +62 -0
  190. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.ttf +0 -0
  191. data/vendor/assets/skins/skins/lightgray/fonts/tinymce-small.woff +0 -0
  192. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.eot +0 -0
  193. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.svg +63 -0
  194. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.ttf +0 -0
  195. data/vendor/assets/skins/skins/lightgray/fonts/tinymce.woff +0 -0
  196. data/vendor/assets/skins/skins/lightgray/img/anchor.gif +0 -0
  197. data/vendor/assets/skins/skins/lightgray/img/loader.gif +0 -0
  198. data/vendor/assets/skins/skins/lightgray/img/object.gif +0 -0
  199. data/vendor/assets/skins/skins/lightgray/img/trans.gif +0 -0
  200. data/vendor/assets/skins/skins/lightgray/skin.ie7.min.css +1 -0
  201. data/vendor/assets/skins/skins/lightgray/skin.min.css +1 -0
  202. data/vendor/assets/stylesheets/mirador-combined.css +3969 -0
  203. data/vendor/assets/stylesheets/mirador.css +11 -0
  204. data/vendor/assets/themes/themes/modern/theme.js +617 -0
  205. data/vendor/assets/themes/themes/modern/theme.min.js +1 -0
  206. metadata +318 -0
@@ -0,0 +1,864 @@
1
+ /**
2
+ * TableGrid.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
+ /**
12
+ * This class creates a grid out of a table element. This
13
+ * makes it a whole lot easier to handle complex tables with
14
+ * col/row spans.
15
+ *
16
+ * @class tinymce.tableplugin.TableGrid
17
+ * @private
18
+ */
19
+ define("tinymce/tableplugin/TableGrid", [
20
+ "tinymce/util/Tools",
21
+ "tinymce/Env"
22
+ ], function(Tools, Env) {
23
+ var each = Tools.each;
24
+
25
+ function getSpanVal(td, name) {
26
+ return parseInt(td.getAttribute(name) || 1, 10);
27
+ }
28
+
29
+ return function(editor, table) {
30
+ var grid, gridWidth, startPos, endPos, selectedCell, selection = editor.selection, dom = selection.dom;
31
+
32
+ function buildGrid() {
33
+ var startY = 0;
34
+
35
+ grid = [];
36
+ gridWidth = 0;
37
+
38
+ each(['thead', 'tbody', 'tfoot'], function(part) {
39
+ var rows = dom.select('> ' + part + ' tr', table);
40
+
41
+ each(rows, function(tr, y) {
42
+ y += startY;
43
+
44
+ each(dom.select('> td, > th', tr), function(td, x) {
45
+ var x2, y2, rowspan, colspan;
46
+
47
+ // Skip over existing cells produced by rowspan
48
+ if (grid[y]) {
49
+ while (grid[y][x]) {
50
+ x++;
51
+ }
52
+ }
53
+
54
+ // Get col/rowspan from cell
55
+ rowspan = getSpanVal(td, 'rowspan');
56
+ colspan = getSpanVal(td, 'colspan');
57
+
58
+ // Fill out rowspan/colspan right and down
59
+ for (y2 = y; y2 < y + rowspan; y2++) {
60
+ if (!grid[y2]) {
61
+ grid[y2] = [];
62
+ }
63
+
64
+ for (x2 = x; x2 < x + colspan; x2++) {
65
+ grid[y2][x2] = {
66
+ part: part,
67
+ real: y2 == y && x2 == x,
68
+ elm: td,
69
+ rowspan: rowspan,
70
+ colspan: colspan
71
+ };
72
+ }
73
+ }
74
+
75
+ gridWidth = Math.max(gridWidth, x + 1);
76
+ });
77
+ });
78
+
79
+ startY += rows.length;
80
+ });
81
+ }
82
+
83
+ function cloneNode(node, children) {
84
+ node = node.cloneNode(children);
85
+ node.removeAttribute('id');
86
+
87
+ return node;
88
+ }
89
+
90
+ function getCell(x, y) {
91
+ var row;
92
+
93
+ row = grid[y];
94
+ if (row) {
95
+ return row[x];
96
+ }
97
+ }
98
+
99
+ function setSpanVal(td, name, val) {
100
+ if (td) {
101
+ val = parseInt(val, 10);
102
+
103
+ if (val === 1) {
104
+ td.removeAttribute(name, 1);
105
+ } else {
106
+ td.setAttribute(name, val, 1);
107
+ }
108
+ }
109
+ }
110
+
111
+ function isCellSelected(cell) {
112
+ return cell && (dom.hasClass(cell.elm, 'mce-item-selected') || cell == selectedCell);
113
+ }
114
+
115
+ function getSelectedRows() {
116
+ var rows = [];
117
+
118
+ each(table.rows, function(row) {
119
+ each(row.cells, function(cell) {
120
+ if (dom.hasClass(cell, 'mce-item-selected') || (selectedCell && cell == selectedCell.elm)) {
121
+ rows.push(row);
122
+ return false;
123
+ }
124
+ });
125
+ });
126
+
127
+ return rows;
128
+ }
129
+
130
+ function deleteTable() {
131
+ var rng = dom.createRng();
132
+
133
+ rng.setStartAfter(table);
134
+ rng.setEndAfter(table);
135
+
136
+ selection.setRng(rng);
137
+
138
+ dom.remove(table);
139
+ }
140
+
141
+ function cloneCell(cell) {
142
+ var formatNode, cloneFormats = {};
143
+
144
+ if (editor.settings.table_clone_elements !== false) {
145
+ cloneFormats = Tools.makeMap(
146
+ (editor.settings.table_clone_elements || 'strong em b i span font h1 h2 h3 h4 h5 h6 p div').toUpperCase(),
147
+ /[ ,]/
148
+ );
149
+ }
150
+
151
+ // Clone formats
152
+ Tools.walk(cell, function(node) {
153
+ var curNode;
154
+
155
+ if (node.nodeType == 3) {
156
+ each(dom.getParents(node.parentNode, null, cell).reverse(), function(node) {
157
+ if (!cloneFormats[node.nodeName]) {
158
+ return;
159
+ }
160
+
161
+ node = cloneNode(node, false);
162
+
163
+ if (!formatNode) {
164
+ formatNode = curNode = node;
165
+ } else if (curNode) {
166
+ curNode.appendChild(node);
167
+ }
168
+
169
+ curNode = node;
170
+ });
171
+
172
+ // Add something to the inner node
173
+ if (curNode) {
174
+ curNode.innerHTML = Env.ie ? '&nbsp;' : '<br data-mce-bogus="1" />';
175
+ }
176
+
177
+ return false;
178
+ }
179
+ }, 'childNodes');
180
+
181
+ cell = cloneNode(cell, false);
182
+ setSpanVal(cell, 'rowSpan', 1);
183
+ setSpanVal(cell, 'colSpan', 1);
184
+
185
+ if (formatNode) {
186
+ cell.appendChild(formatNode);
187
+ } else {
188
+ if (!Env.ie || Env.ie > 10) {
189
+ cell.innerHTML = '<br data-mce-bogus="1" />';
190
+ }
191
+ }
192
+
193
+ return cell;
194
+ }
195
+
196
+ function cleanup() {
197
+ var rng = dom.createRng(), row;
198
+
199
+ // Empty rows
200
+ each(dom.select('tr', table), function(tr) {
201
+ if (tr.cells.length === 0) {
202
+ dom.remove(tr);
203
+ }
204
+ });
205
+
206
+ // Empty table
207
+ if (dom.select('tr', table).length === 0) {
208
+ rng.setStartBefore(table);
209
+ rng.setEndBefore(table);
210
+ selection.setRng(rng);
211
+ dom.remove(table);
212
+ return;
213
+ }
214
+
215
+ // Empty header/body/footer
216
+ each(dom.select('thead,tbody,tfoot', table), function(part) {
217
+ if (part.rows.length === 0) {
218
+ dom.remove(part);
219
+ }
220
+ });
221
+
222
+ // Restore selection to start position if it still exists
223
+ buildGrid();
224
+
225
+ // If we have a valid startPos object
226
+ if (startPos) {
227
+ // Restore the selection to the closest table position
228
+ row = grid[Math.min(grid.length - 1, startPos.y)];
229
+ if (row) {
230
+ selection.select(row[Math.min(row.length - 1, startPos.x)].elm, true);
231
+ selection.collapse(true);
232
+ }
233
+ }
234
+ }
235
+
236
+ function fillLeftDown(x, y, rows, cols) {
237
+ var tr, x2, r, c, cell;
238
+
239
+ tr = grid[y][x].elm.parentNode;
240
+ for (r = 1; r <= rows; r++) {
241
+ tr = dom.getNext(tr, 'tr');
242
+
243
+ if (tr) {
244
+ // Loop left to find real cell
245
+ for (x2 = x; x2 >= 0; x2--) {
246
+ cell = grid[y + r][x2].elm;
247
+
248
+ if (cell.parentNode == tr) {
249
+ // Append clones after
250
+ for (c = 1; c <= cols; c++) {
251
+ dom.insertAfter(cloneCell(cell), cell);
252
+ }
253
+
254
+ break;
255
+ }
256
+ }
257
+
258
+ if (x2 == -1) {
259
+ // Insert nodes before first cell
260
+ for (c = 1; c <= cols; c++) {
261
+ tr.insertBefore(cloneCell(tr.cells[0]), tr.cells[0]);
262
+ }
263
+ }
264
+ }
265
+ }
266
+ }
267
+
268
+ function split() {
269
+ each(grid, function(row, y) {
270
+ each(row, function(cell, x) {
271
+ var colSpan, rowSpan, i;
272
+
273
+ if (isCellSelected(cell)) {
274
+ cell = cell.elm;
275
+ colSpan = getSpanVal(cell, 'colspan');
276
+ rowSpan = getSpanVal(cell, 'rowspan');
277
+
278
+ if (colSpan > 1 || rowSpan > 1) {
279
+ setSpanVal(cell, 'rowSpan', 1);
280
+ setSpanVal(cell, 'colSpan', 1);
281
+
282
+ // Insert cells right
283
+ for (i = 0; i < colSpan - 1; i++) {
284
+ dom.insertAfter(cloneCell(cell), cell);
285
+ }
286
+
287
+ fillLeftDown(x, y, rowSpan - 1, colSpan);
288
+ }
289
+ }
290
+ });
291
+ });
292
+ }
293
+
294
+ function merge(cell, cols, rows) {
295
+ var pos, startX, startY, endX, endY, x, y, startCell, endCell, children, count;
296
+
297
+ // Use specified cell and cols/rows
298
+ if (cell) {
299
+ pos = getPos(cell);
300
+ startX = pos.x;
301
+ startY = pos.y;
302
+ endX = startX + (cols - 1);
303
+ endY = startY + (rows - 1);
304
+ } else {
305
+ startPos = endPos = null;
306
+
307
+ // Calculate start/end pos by checking for selected cells in grid works better with context menu
308
+ each(grid, function(row, y) {
309
+ each(row, function(cell, x) {
310
+ if (isCellSelected(cell)) {
311
+ if (!startPos) {
312
+ startPos = {x: x, y: y};
313
+ }
314
+
315
+ endPos = {x: x, y: y};
316
+ }
317
+ });
318
+ });
319
+
320
+ // Use selection, but make sure startPos is valid before accessing
321
+ if (startPos) {
322
+ startX = startPos.x;
323
+ startY = startPos.y;
324
+ endX = endPos.x;
325
+ endY = endPos.y;
326
+ }
327
+ }
328
+
329
+ // Find start/end cells
330
+ startCell = getCell(startX, startY);
331
+ endCell = getCell(endX, endY);
332
+
333
+ // Check if the cells exists and if they are of the same part for example tbody = tbody
334
+ if (startCell && endCell && startCell.part == endCell.part) {
335
+ // Split and rebuild grid
336
+ split();
337
+ buildGrid();
338
+
339
+ // Set row/col span to start cell
340
+ startCell = getCell(startX, startY).elm;
341
+ setSpanVal(startCell, 'colSpan', (endX - startX) + 1);
342
+ setSpanVal(startCell, 'rowSpan', (endY - startY) + 1);
343
+
344
+ // Remove other cells and add it's contents to the start cell
345
+ for (y = startY; y <= endY; y++) {
346
+ for (x = startX; x <= endX; x++) {
347
+ if (!grid[y] || !grid[y][x]) {
348
+ continue;
349
+ }
350
+
351
+ cell = grid[y][x].elm;
352
+
353
+ /*jshint loopfunc:true */
354
+ /*eslint no-loop-func:0 */
355
+ if (cell != startCell) {
356
+ // Move children to startCell
357
+ children = Tools.grep(cell.childNodes);
358
+ each(children, function(node) {
359
+ startCell.appendChild(node);
360
+ });
361
+
362
+ // Remove bogus nodes if there is children in the target cell
363
+ if (children.length) {
364
+ children = Tools.grep(startCell.childNodes);
365
+ count = 0;
366
+ each(children, function(node) {
367
+ if (node.nodeName == 'BR' && dom.getAttrib(node, 'data-mce-bogus') && count++ < children.length - 1) {
368
+ startCell.removeChild(node);
369
+ }
370
+ });
371
+ }
372
+
373
+ dom.remove(cell);
374
+ }
375
+ }
376
+ }
377
+
378
+ // Remove empty rows etc and restore caret location
379
+ cleanup();
380
+ }
381
+ }
382
+
383
+ function insertRow(before) {
384
+ var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell, rowSpan;
385
+
386
+ // Find first/last row
387
+ each(grid, function(row, y) {
388
+ each(row, function(cell) {
389
+ if (isCellSelected(cell)) {
390
+ cell = cell.elm;
391
+ rowElm = cell.parentNode;
392
+ newRow = cloneNode(rowElm, false);
393
+ posY = y;
394
+
395
+ if (before) {
396
+ return false;
397
+ }
398
+ }
399
+ });
400
+
401
+ if (before) {
402
+ return !posY;
403
+ }
404
+ });
405
+
406
+ // If posY is undefined there is nothing for us to do here...just return to avoid crashing below
407
+ if (posY === undefined) {
408
+ return;
409
+ }
410
+
411
+ for (x = 0; x < grid[0].length; x++) {
412
+ // Cell not found could be because of an invalid table structure
413
+ if (!grid[posY][x]) {
414
+ continue;
415
+ }
416
+
417
+ cell = grid[posY][x].elm;
418
+
419
+ if (cell != lastCell) {
420
+ if (!before) {
421
+ rowSpan = getSpanVal(cell, 'rowspan');
422
+ if (rowSpan > 1) {
423
+ setSpanVal(cell, 'rowSpan', rowSpan + 1);
424
+ continue;
425
+ }
426
+ } else {
427
+ // Check if cell above can be expanded
428
+ if (posY > 0 && grid[posY - 1][x]) {
429
+ otherCell = grid[posY - 1][x].elm;
430
+ rowSpan = getSpanVal(otherCell, 'rowSpan');
431
+ if (rowSpan > 1) {
432
+ setSpanVal(otherCell, 'rowSpan', rowSpan + 1);
433
+ continue;
434
+ }
435
+ }
436
+ }
437
+
438
+ // Insert new cell into new row
439
+ newCell = cloneCell(cell);
440
+ setSpanVal(newCell, 'colSpan', cell.colSpan);
441
+
442
+ newRow.appendChild(newCell);
443
+
444
+ lastCell = cell;
445
+ }
446
+ }
447
+
448
+ if (newRow.hasChildNodes()) {
449
+ if (!before) {
450
+ dom.insertAfter(newRow, rowElm);
451
+ } else {
452
+ rowElm.parentNode.insertBefore(newRow, rowElm);
453
+ }
454
+ }
455
+ }
456
+
457
+ function insertCol(before) {
458
+ var posX, lastCell;
459
+
460
+ // Find first/last column
461
+ each(grid, function(row) {
462
+ each(row, function(cell, x) {
463
+ if (isCellSelected(cell)) {
464
+ posX = x;
465
+
466
+ if (before) {
467
+ return false;
468
+ }
469
+ }
470
+ });
471
+
472
+ if (before) {
473
+ return !posX;
474
+ }
475
+ });
476
+
477
+ each(grid, function(row, y) {
478
+ var cell, rowSpan, colSpan;
479
+
480
+ if (!row[posX]) {
481
+ return;
482
+ }
483
+
484
+ cell = row[posX].elm;
485
+ if (cell != lastCell) {
486
+ colSpan = getSpanVal(cell, 'colspan');
487
+ rowSpan = getSpanVal(cell, 'rowspan');
488
+
489
+ if (colSpan == 1) {
490
+ if (!before) {
491
+ dom.insertAfter(cloneCell(cell), cell);
492
+ fillLeftDown(posX, y, rowSpan - 1, colSpan);
493
+ } else {
494
+ cell.parentNode.insertBefore(cloneCell(cell), cell);
495
+ fillLeftDown(posX, y, rowSpan - 1, colSpan);
496
+ }
497
+ } else {
498
+ setSpanVal(cell, 'colSpan', cell.colSpan + 1);
499
+ }
500
+
501
+ lastCell = cell;
502
+ }
503
+ });
504
+ }
505
+
506
+ function deleteCols() {
507
+ var cols = [];
508
+
509
+ // Get selected column indexes
510
+ each(grid, function(row) {
511
+ each(row, function(cell, x) {
512
+ if (isCellSelected(cell) && Tools.inArray(cols, x) === -1) {
513
+ each(grid, function(row) {
514
+ var cell = row[x].elm, colSpan;
515
+
516
+ colSpan = getSpanVal(cell, 'colSpan');
517
+
518
+ if (colSpan > 1) {
519
+ setSpanVal(cell, 'colSpan', colSpan - 1);
520
+ } else {
521
+ dom.remove(cell);
522
+ }
523
+ });
524
+
525
+ cols.push(x);
526
+ }
527
+ });
528
+ });
529
+
530
+ cleanup();
531
+ }
532
+
533
+ function deleteRows() {
534
+ var rows;
535
+
536
+ function deleteRow(tr) {
537
+ var pos, lastCell;
538
+
539
+ // Move down row spanned cells
540
+ each(tr.cells, function(cell) {
541
+ var rowSpan = getSpanVal(cell, 'rowSpan');
542
+
543
+ if (rowSpan > 1) {
544
+ setSpanVal(cell, 'rowSpan', rowSpan - 1);
545
+ pos = getPos(cell);
546
+ fillLeftDown(pos.x, pos.y, 1, 1);
547
+ }
548
+ });
549
+
550
+ // Delete cells
551
+ pos = getPos(tr.cells[0]);
552
+ each(grid[pos.y], function(cell) {
553
+ var rowSpan;
554
+
555
+ cell = cell.elm;
556
+
557
+ if (cell != lastCell) {
558
+ rowSpan = getSpanVal(cell, 'rowSpan');
559
+
560
+ if (rowSpan <= 1) {
561
+ dom.remove(cell);
562
+ } else {
563
+ setSpanVal(cell, 'rowSpan', rowSpan - 1);
564
+ }
565
+
566
+ lastCell = cell;
567
+ }
568
+ });
569
+ }
570
+
571
+ // Get selected rows and move selection out of scope
572
+ rows = getSelectedRows();
573
+
574
+ // Delete all selected rows
575
+ each(rows.reverse(), function(tr) {
576
+ deleteRow(tr);
577
+ });
578
+
579
+ cleanup();
580
+ }
581
+
582
+ function cutRows() {
583
+ var rows = getSelectedRows();
584
+
585
+ dom.remove(rows);
586
+ cleanup();
587
+
588
+ return rows;
589
+ }
590
+
591
+ function copyRows() {
592
+ var rows = getSelectedRows();
593
+
594
+ each(rows, function(row, i) {
595
+ rows[i] = cloneNode(row, true);
596
+ });
597
+
598
+ return rows;
599
+ }
600
+
601
+ function pasteRows(rows, before) {
602
+ var selectedRows = getSelectedRows(),
603
+ targetRow = selectedRows[before ? 0 : selectedRows.length - 1],
604
+ targetCellCount = targetRow.cells.length;
605
+
606
+ // Nothing to paste
607
+ if (!rows) {
608
+ return;
609
+ }
610
+
611
+ // Calc target cell count
612
+ each(grid, function(row) {
613
+ var match;
614
+
615
+ targetCellCount = 0;
616
+ each(row, function(cell) {
617
+ if (cell.real) {
618
+ targetCellCount += cell.colspan;
619
+ }
620
+
621
+ if (cell.elm.parentNode == targetRow) {
622
+ match = 1;
623
+ }
624
+ });
625
+
626
+ if (match) {
627
+ return false;
628
+ }
629
+ });
630
+
631
+ if (!before) {
632
+ rows.reverse();
633
+ }
634
+
635
+ each(rows, function(row) {
636
+ var i, cellCount = row.cells.length, cell;
637
+
638
+ // Remove col/rowspans
639
+ for (i = 0; i < cellCount; i++) {
640
+ cell = row.cells[i];
641
+ setSpanVal(cell, 'colSpan', 1);
642
+ setSpanVal(cell, 'rowSpan', 1);
643
+ }
644
+
645
+ // Needs more cells
646
+ for (i = cellCount; i < targetCellCount; i++) {
647
+ row.appendChild(cloneCell(row.cells[cellCount - 1]));
648
+ }
649
+
650
+ // Needs less cells
651
+ for (i = targetCellCount; i < cellCount; i++) {
652
+ dom.remove(row.cells[i]);
653
+ }
654
+
655
+ // Add before/after
656
+ if (before) {
657
+ targetRow.parentNode.insertBefore(row, targetRow);
658
+ } else {
659
+ dom.insertAfter(row, targetRow);
660
+ }
661
+ });
662
+
663
+ // Remove current selection
664
+ dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
665
+ }
666
+
667
+ function getPos(target) {
668
+ var pos;
669
+
670
+ each(grid, function(row, y) {
671
+ each(row, function(cell, x) {
672
+ if (cell.elm == target) {
673
+ pos = {x : x, y : y};
674
+ return false;
675
+ }
676
+ });
677
+
678
+ return !pos;
679
+ });
680
+
681
+ return pos;
682
+ }
683
+
684
+ function setStartCell(cell) {
685
+ startPos = getPos(cell);
686
+ }
687
+
688
+ function findEndPos() {
689
+ var maxX, maxY;
690
+
691
+ maxX = maxY = 0;
692
+
693
+ each(grid, function(row, y) {
694
+ each(row, function(cell, x) {
695
+ var colSpan, rowSpan;
696
+
697
+ if (isCellSelected(cell)) {
698
+ cell = grid[y][x];
699
+
700
+ if (x > maxX) {
701
+ maxX = x;
702
+ }
703
+
704
+ if (y > maxY) {
705
+ maxY = y;
706
+ }
707
+
708
+ if (cell.real) {
709
+ colSpan = cell.colspan - 1;
710
+ rowSpan = cell.rowspan - 1;
711
+
712
+ if (colSpan) {
713
+ if (x + colSpan > maxX) {
714
+ maxX = x + colSpan;
715
+ }
716
+ }
717
+
718
+ if (rowSpan) {
719
+ if (y + rowSpan > maxY) {
720
+ maxY = y + rowSpan;
721
+ }
722
+ }
723
+ }
724
+ }
725
+ });
726
+ });
727
+
728
+ return {x : maxX, y : maxY};
729
+ }
730
+
731
+ function setEndCell(cell) {
732
+ var startX, startY, endX, endY, maxX, maxY, colSpan, rowSpan, x, y;
733
+
734
+ endPos = getPos(cell);
735
+
736
+ if (startPos && endPos) {
737
+ // Get start/end positions
738
+ startX = Math.min(startPos.x, endPos.x);
739
+ startY = Math.min(startPos.y, endPos.y);
740
+ endX = Math.max(startPos.x, endPos.x);
741
+ endY = Math.max(startPos.y, endPos.y);
742
+
743
+ // Expand end positon to include spans
744
+ maxX = endX;
745
+ maxY = endY;
746
+
747
+ // Expand startX
748
+ for (y = startY; y <= maxY; y++) {
749
+ cell = grid[y][startX];
750
+
751
+ if (!cell.real) {
752
+ if (startX - (cell.colspan - 1) < startX) {
753
+ startX -= cell.colspan - 1;
754
+ }
755
+ }
756
+ }
757
+
758
+ // Expand startY
759
+ for (x = startX; x <= maxX; x++) {
760
+ cell = grid[startY][x];
761
+
762
+ if (!cell.real) {
763
+ if (startY - (cell.rowspan - 1) < startY) {
764
+ startY -= cell.rowspan - 1;
765
+ }
766
+ }
767
+ }
768
+
769
+ // Find max X, Y
770
+ for (y = startY; y <= endY; y++) {
771
+ for (x = startX; x <= endX; x++) {
772
+ cell = grid[y][x];
773
+
774
+ if (cell.real) {
775
+ colSpan = cell.colspan - 1;
776
+ rowSpan = cell.rowspan - 1;
777
+
778
+ if (colSpan) {
779
+ if (x + colSpan > maxX) {
780
+ maxX = x + colSpan;
781
+ }
782
+ }
783
+
784
+ if (rowSpan) {
785
+ if (y + rowSpan > maxY) {
786
+ maxY = y + rowSpan;
787
+ }
788
+ }
789
+ }
790
+ }
791
+ }
792
+
793
+ // Remove current selection
794
+ dom.removeClass(dom.select('td.mce-item-selected,th.mce-item-selected'), 'mce-item-selected');
795
+
796
+ // Add new selection
797
+ for (y = startY; y <= maxY; y++) {
798
+ for (x = startX; x <= maxX; x++) {
799
+ if (grid[y][x]) {
800
+ dom.addClass(grid[y][x].elm, 'mce-item-selected');
801
+ }
802
+ }
803
+ }
804
+ }
805
+ }
806
+
807
+ function moveRelIdx(cellElm, delta) {
808
+ var pos, index, cell;
809
+
810
+ pos = getPos(cellElm);
811
+ index = pos.y * gridWidth + pos.x;
812
+
813
+ do {
814
+ index += delta;
815
+ cell = getCell(index % gridWidth, Math.floor(index / gridWidth));
816
+
817
+ if (!cell) {
818
+ break;
819
+ }
820
+
821
+ if (cell.elm != cellElm) {
822
+ selection.select(cell.elm, true);
823
+
824
+ if (dom.isEmpty(cell.elm)) {
825
+ selection.collapse(true);
826
+ }
827
+
828
+ return true;
829
+ }
830
+ } while (cell.elm == cellElm);
831
+
832
+ return false;
833
+ }
834
+
835
+ table = table || dom.getParent(selection.getStart(), 'table');
836
+
837
+ buildGrid();
838
+
839
+ selectedCell = dom.getParent(selection.getStart(), 'th,td');
840
+ if (selectedCell) {
841
+ startPos = getPos(selectedCell);
842
+ endPos = findEndPos();
843
+ selectedCell = getCell(startPos.x, startPos.y);
844
+ }
845
+
846
+ Tools.extend(this, {
847
+ deleteTable: deleteTable,
848
+ split: split,
849
+ merge: merge,
850
+ insertRow: insertRow,
851
+ insertCol: insertCol,
852
+ deleteCols: deleteCols,
853
+ deleteRows: deleteRows,
854
+ cutRows: cutRows,
855
+ copyRows: copyRows,
856
+ pasteRows: pasteRows,
857
+ getPos: getPos,
858
+ setStartCell: setStartCell,
859
+ setEndCell: setEndCell,
860
+ moveRelIdx: moveRelIdx,
861
+ refresh: buildGrid
862
+ });
863
+ };
864
+ });