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,422 @@
1
+ /**
2
+ * Plugin.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 contains all core logic for the table plugin.
13
+ *
14
+ * @class tinymce.tableplugin.Plugin
15
+ * @private
16
+ */
17
+ define("tinymce/tableplugin/Plugin", [
18
+ "tinymce/tableplugin/TableGrid",
19
+ "tinymce/tableplugin/Quirks",
20
+ "tinymce/tableplugin/CellSelection",
21
+ "tinymce/tableplugin/Dialogs",
22
+ "tinymce/util/Tools",
23
+ "tinymce/dom/TreeWalker",
24
+ "tinymce/Env",
25
+ "tinymce/PluginManager"
26
+ ], function(TableGrid, Quirks, CellSelection, Dialogs, Tools, TreeWalker, Env, PluginManager) {
27
+ var each = Tools.each;
28
+
29
+ function Plugin(editor) {
30
+ var clipboardRows, self = this, dialogs = new Dialogs(editor);
31
+
32
+ function cmd(command) {
33
+ return function() {
34
+ editor.execCommand(command);
35
+ };
36
+ }
37
+
38
+ function insertTable(cols, rows) {
39
+ var y, x, html, tableElm;
40
+
41
+ html = '<table id="__mce"><tbody>';
42
+
43
+ for (y = 0; y < rows; y++) {
44
+ html += '<tr>';
45
+
46
+ for (x = 0; x < cols; x++) {
47
+ html += '<td>' + (Env.ie ? " " : '<br>') + '</td>';
48
+ }
49
+
50
+ html += '</tr>';
51
+ }
52
+
53
+ html += '</tbody></table>';
54
+
55
+ editor.undoManager.transact(function() {
56
+ editor.insertContent(html);
57
+
58
+ tableElm = editor.dom.get('__mce');
59
+ editor.dom.setAttrib(tableElm, 'id', null);
60
+
61
+ editor.dom.setAttribs(tableElm, editor.settings.table_default_attributes || {});
62
+ editor.dom.setStyles(tableElm, editor.settings.table_default_styles || {});
63
+ });
64
+
65
+ return tableElm;
66
+ }
67
+
68
+ function handleDisabledState(ctrl, selector) {
69
+ function bindStateListener() {
70
+ ctrl.disabled(!editor.dom.getParent(editor.selection.getStart(), selector));
71
+
72
+ editor.selection.selectorChanged(selector, function(state) {
73
+ ctrl.disabled(!state);
74
+ });
75
+ }
76
+
77
+ if (editor.initialized) {
78
+ bindStateListener();
79
+ } else {
80
+ editor.on('init', bindStateListener);
81
+ }
82
+ }
83
+
84
+ function postRender() {
85
+ /*jshint validthis:true*/
86
+ handleDisabledState(this, 'table');
87
+ }
88
+
89
+ function postRenderCell() {
90
+ /*jshint validthis:true*/
91
+ handleDisabledState(this, 'td,th');
92
+ }
93
+
94
+ function generateTableGrid() {
95
+ var html = '';
96
+
97
+ html = '<table role="grid" class="mce-grid mce-grid-border" aria-readonly="true">';
98
+
99
+ for (var y = 0; y < 10; y++) {
100
+ html += '<tr>';
101
+
102
+ for (var x = 0; x < 10; x++) {
103
+ html += '<td role="gridcell" tabindex="-1"><a id="mcegrid' + (y * 10 + x) + '" href="#" ' +
104
+ 'data-mce-x="' + x + '" data-mce-y="' + y + '"></a></td>';
105
+ }
106
+
107
+ html += '</tr>';
108
+ }
109
+
110
+ html += '</table>';
111
+
112
+ html += '<div class="mce-text-center" role="presentation">1 x 1</div>';
113
+
114
+ return html;
115
+ }
116
+
117
+ function selectGrid(tx, ty, control) {
118
+ var table = control.getEl().getElementsByTagName('table')[0];
119
+ var x, y, focusCell, cell, active;
120
+ var rtl = control.isRtl() || control.parent().rel == 'tl-tr';
121
+
122
+ table.nextSibling.innerHTML = (tx + 1) + ' x ' + (ty + 1);
123
+
124
+ if (rtl) {
125
+ tx = 9 - tx;
126
+ }
127
+
128
+ for (y = 0; y < 10; y++) {
129
+ for (x = 0; x < 10; x++) {
130
+ cell = table.rows[y].childNodes[x].firstChild;
131
+ active = (rtl ? x >= tx : x <= tx) && y <= ty;
132
+
133
+ editor.dom.toggleClass(cell, 'mce-active', active);
134
+
135
+ if (active) {
136
+ focusCell = cell;
137
+ }
138
+ }
139
+ }
140
+
141
+ return focusCell.parentNode;
142
+ }
143
+
144
+ if (editor.settings.table_grid === false) {
145
+ editor.addMenuItem('inserttable', {
146
+ text: 'Insert table',
147
+ icon: 'table',
148
+ context: 'table',
149
+ onclick: dialogs.table
150
+ });
151
+ } else {
152
+ editor.addMenuItem('inserttable', {
153
+ text: 'Insert table',
154
+ icon: 'table',
155
+ context: 'table',
156
+ ariaHideMenu: true,
157
+ onclick: function(e) {
158
+ if (e.aria) {
159
+ this.parent().hideAll();
160
+ e.stopImmediatePropagation();
161
+ dialogs.table();
162
+ }
163
+ },
164
+ onshow: function() {
165
+ selectGrid(0, 0, this.menu.items()[0]);
166
+ },
167
+ onhide: function() {
168
+ var elements = this.menu.items()[0].getEl().getElementsByTagName('a');
169
+ editor.dom.removeClass(elements, 'mce-active');
170
+ editor.dom.addClass(elements[0], 'mce-active');
171
+ },
172
+ menu: [
173
+ {
174
+ type: 'container',
175
+ html: generateTableGrid(),
176
+
177
+ onPostRender: function() {
178
+ this.lastX = this.lastY = 0;
179
+ },
180
+
181
+ onmousemove: function(e) {
182
+ var target = e.target, x, y;
183
+
184
+ if (target.tagName.toUpperCase() == 'A') {
185
+ x = parseInt(target.getAttribute('data-mce-x'), 10);
186
+ y = parseInt(target.getAttribute('data-mce-y'), 10);
187
+
188
+ if (this.isRtl() || this.parent().rel == 'tl-tr') {
189
+ x = 9 - x;
190
+ }
191
+
192
+ if (x !== this.lastX || y !== this.lastY) {
193
+ selectGrid(x, y, e.control);
194
+
195
+ this.lastX = x;
196
+ this.lastY = y;
197
+ }
198
+ }
199
+ },
200
+
201
+ onclick: function(e) {
202
+ var self = this;
203
+
204
+ if (e.target.tagName.toUpperCase() == 'A') {
205
+ e.preventDefault();
206
+ e.stopPropagation();
207
+ self.parent().cancel();
208
+
209
+ editor.undoManager.transact(function() {
210
+ insertTable(self.lastX + 1, self.lastY + 1);
211
+ });
212
+
213
+ editor.addVisual();
214
+ }
215
+ }
216
+ }
217
+ ]
218
+ });
219
+ }
220
+
221
+ editor.addMenuItem('tableprops', {
222
+ text: 'Table properties',
223
+ context: 'table',
224
+ onPostRender: postRender,
225
+ onclick: dialogs.tableProps
226
+ });
227
+
228
+ editor.addMenuItem('deletetable', {
229
+ text: 'Delete table',
230
+ context: 'table',
231
+ onPostRender: postRender,
232
+ cmd: 'mceTableDelete'
233
+ });
234
+
235
+ editor.addMenuItem('cell', {
236
+ separator: 'before',
237
+ text: 'Cell',
238
+ context: 'table',
239
+ menu: [
240
+ {text: 'Cell properties', onclick: cmd('mceTableCellProps'), onPostRender: postRenderCell},
241
+ {text: 'Merge cells', onclick: cmd('mceTableMergeCells'), onPostRender: postRenderCell},
242
+ {text: 'Split cell', onclick: cmd('mceTableSplitCells'), onPostRender: postRenderCell}
243
+ ]
244
+ });
245
+
246
+ editor.addMenuItem('row', {
247
+ text: 'Row',
248
+ context: 'table',
249
+ menu: [
250
+ {text: 'Insert row before', onclick: cmd('mceTableInsertRowBefore'), onPostRender: postRenderCell},
251
+ {text: 'Insert row after', onclick: cmd('mceTableInsertRowAfter'), onPostRender: postRenderCell},
252
+ {text: 'Delete row', onclick: cmd('mceTableDeleteRow'), onPostRender: postRenderCell},
253
+ {text: 'Row properties', onclick: cmd('mceTableRowProps'), onPostRender: postRenderCell},
254
+ {text: '-'},
255
+ {text: 'Cut row', onclick: cmd('mceTableCutRow'), onPostRender: postRenderCell},
256
+ {text: 'Copy row', onclick: cmd('mceTableCopyRow'), onPostRender: postRenderCell},
257
+ {text: 'Paste row before', onclick: cmd('mceTablePasteRowBefore'), onPostRender: postRenderCell},
258
+ {text: 'Paste row after', onclick: cmd('mceTablePasteRowAfter'), onPostRender: postRenderCell}
259
+ ]
260
+ });
261
+
262
+ editor.addMenuItem('column', {
263
+ text: 'Column',
264
+ context: 'table',
265
+ menu: [
266
+ {text: 'Insert column before', onclick: cmd('mceTableInsertColBefore'), onPostRender: postRenderCell},
267
+ {text: 'Insert column after', onclick: cmd('mceTableInsertColAfter'), onPostRender: postRenderCell},
268
+ {text: 'Delete column', onclick: cmd('mceTableDeleteCol'), onPostRender: postRenderCell}
269
+ ]
270
+ });
271
+
272
+ var menuItems = [];
273
+ each("inserttable tableprops deletetable | cell row column".split(' '), function(name) {
274
+ if (name == '|') {
275
+ menuItems.push({text: '-'});
276
+ } else {
277
+ menuItems.push(editor.menuItems[name]);
278
+ }
279
+ });
280
+
281
+ editor.addButton("table", {
282
+ type: "menubutton",
283
+ title: "Table",
284
+ menu: menuItems
285
+ });
286
+
287
+ // Select whole table is a table border is clicked
288
+ if (!Env.isIE) {
289
+ editor.on('click', function(e) {
290
+ e = e.target;
291
+
292
+ if (e.nodeName === 'TABLE') {
293
+ editor.selection.select(e);
294
+ editor.nodeChanged();
295
+ }
296
+ });
297
+ }
298
+
299
+ self.quirks = new Quirks(editor);
300
+
301
+ editor.on('Init', function() {
302
+ self.cellSelection = new CellSelection(editor);
303
+ });
304
+
305
+ // Register action commands
306
+ each({
307
+ mceTableSplitCells: function(grid) {
308
+ grid.split();
309
+ },
310
+
311
+ mceTableMergeCells: function(grid) {
312
+ var cell;
313
+
314
+ cell = editor.dom.getParent(editor.selection.getStart(), 'th,td');
315
+
316
+ if (!editor.dom.select('td.mce-item-selected,th.mce-item-selected').length) {
317
+ dialogs.merge(grid, cell);
318
+ } else {
319
+ grid.merge();
320
+ }
321
+ },
322
+
323
+ mceTableInsertRowBefore: function(grid) {
324
+ grid.insertRow(true);
325
+ },
326
+
327
+ mceTableInsertRowAfter: function(grid) {
328
+ grid.insertRow();
329
+ },
330
+
331
+ mceTableInsertColBefore: function(grid) {
332
+ grid.insertCol(true);
333
+ },
334
+
335
+ mceTableInsertColAfter: function(grid) {
336
+ grid.insertCol();
337
+ },
338
+
339
+ mceTableDeleteCol: function(grid) {
340
+ grid.deleteCols();
341
+ },
342
+
343
+ mceTableDeleteRow: function(grid) {
344
+ grid.deleteRows();
345
+ },
346
+
347
+ mceTableCutRow: function(grid) {
348
+ clipboardRows = grid.cutRows();
349
+ },
350
+
351
+ mceTableCopyRow: function(grid) {
352
+ clipboardRows = grid.copyRows();
353
+ },
354
+
355
+ mceTablePasteRowBefore: function(grid) {
356
+ grid.pasteRows(clipboardRows, true);
357
+ },
358
+
359
+ mceTablePasteRowAfter: function(grid) {
360
+ grid.pasteRows(clipboardRows);
361
+ },
362
+
363
+ mceTableDelete: function(grid) {
364
+ grid.deleteTable();
365
+ }
366
+ }, function(func, name) {
367
+ editor.addCommand(name, function() {
368
+ var grid = new TableGrid(editor);
369
+
370
+ if (grid) {
371
+ func(grid);
372
+ editor.execCommand('mceRepaint');
373
+ self.cellSelection.clear();
374
+ }
375
+ });
376
+ });
377
+
378
+ // Register dialog commands
379
+ each({
380
+ mceInsertTable: dialogs.table,
381
+ mceTableProps: function() {
382
+ dialogs.table(true);
383
+ },
384
+ mceTableRowProps: dialogs.row,
385
+ mceTableCellProps: dialogs.cell
386
+ }, function(func, name) {
387
+ editor.addCommand(name, function(ui, val) {
388
+ func(val);
389
+ });
390
+ });
391
+
392
+ // Enable tab key cell navigation
393
+ if (editor.settings.table_tab_navigation !== false) {
394
+ editor.on('keydown', function(e) {
395
+ var cellElm, grid, delta;
396
+
397
+ if (e.keyCode == 9) {
398
+ cellElm = editor.dom.getParent(editor.selection.getStart(), 'th,td');
399
+
400
+ if (cellElm) {
401
+ e.preventDefault();
402
+
403
+ grid = new TableGrid(editor);
404
+ delta = e.shiftKey ? -1 : 1;
405
+
406
+ editor.undoManager.transact(function() {
407
+ if (!grid.moveRelIdx(cellElm, delta) && delta > 0) {
408
+ grid.insertRow();
409
+ grid.refresh();
410
+ grid.moveRelIdx(cellElm, delta);
411
+ }
412
+ });
413
+ }
414
+ }
415
+ });
416
+ }
417
+
418
+ self.insertTable = insertTable;
419
+ }
420
+
421
+ PluginManager.add('table', Plugin);
422
+ });
@@ -0,0 +1,372 @@
1
+ /**
2
+ * Quirks.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 includes fixes for various browser quirks.
13
+ *
14
+ * @class tinymce.tableplugin.Quirks
15
+ * @private
16
+ */
17
+ define("tinymce/tableplugin/Quirks", [
18
+ "tinymce/util/VK",
19
+ "tinymce/Env",
20
+ "tinymce/util/Tools"
21
+ ], function(VK, Env, Tools) {
22
+ var each = Tools.each;
23
+
24
+ function getSpanVal(td, name) {
25
+ return parseInt(td.getAttribute(name) || 1, 10);
26
+ }
27
+
28
+ return function(editor) {
29
+ /**
30
+ * Fixed caret movement around tables on WebKit.
31
+ */
32
+ function moveWebKitSelection() {
33
+ function eventHandler(e) {
34
+ var key = e.keyCode;
35
+
36
+ function handle(upBool, sourceNode) {
37
+ var siblingDirection = upBool ? 'previousSibling' : 'nextSibling';
38
+ var currentRow = editor.dom.getParent(sourceNode, 'tr');
39
+ var siblingRow = currentRow[siblingDirection];
40
+
41
+ if (siblingRow) {
42
+ moveCursorToRow(editor, sourceNode, siblingRow, upBool);
43
+ e.preventDefault();
44
+ return true;
45
+ } else {
46
+ var tableNode = editor.dom.getParent(currentRow, 'table');
47
+ var middleNode = currentRow.parentNode;
48
+ var parentNodeName = middleNode.nodeName.toLowerCase();
49
+ if (parentNodeName === 'tbody' || parentNodeName === (upBool ? 'tfoot' : 'thead')) {
50
+ var targetParent = getTargetParent(upBool, tableNode, middleNode, 'tbody');
51
+ if (targetParent !== null) {
52
+ return moveToRowInTarget(upBool, targetParent, sourceNode);
53
+ }
54
+ }
55
+ return escapeTable(upBool, currentRow, siblingDirection, tableNode);
56
+ }
57
+ }
58
+
59
+ function getTargetParent(upBool, topNode, secondNode, nodeName) {
60
+ var tbodies = editor.dom.select('>' + nodeName, topNode);
61
+ var position = tbodies.indexOf(secondNode);
62
+ if (upBool && position === 0 || !upBool && position === tbodies.length - 1) {
63
+ return getFirstHeadOrFoot(upBool, topNode);
64
+ } else if (position === -1) {
65
+ var topOrBottom = secondNode.tagName.toLowerCase() === 'thead' ? 0 : tbodies.length - 1;
66
+ return tbodies[topOrBottom];
67
+ } else {
68
+ return tbodies[position + (upBool ? -1 : 1)];
69
+ }
70
+ }
71
+
72
+ function getFirstHeadOrFoot(upBool, parent) {
73
+ var tagName = upBool ? 'thead' : 'tfoot';
74
+ var headOrFoot = editor.dom.select('>' + tagName, parent);
75
+ return headOrFoot.length !== 0 ? headOrFoot[0] : null;
76
+ }
77
+
78
+ function moveToRowInTarget(upBool, targetParent, sourceNode) {
79
+ var targetRow = getChildForDirection(targetParent, upBool);
80
+
81
+ if (targetRow) {
82
+ moveCursorToRow(editor, sourceNode, targetRow, upBool);
83
+ }
84
+
85
+ e.preventDefault();
86
+ return true;
87
+ }
88
+
89
+ function escapeTable(upBool, currentRow, siblingDirection, table) {
90
+ var tableSibling = table[siblingDirection];
91
+
92
+ if (tableSibling) {
93
+ moveCursorToStartOfElement(tableSibling);
94
+ return true;
95
+ } else {
96
+ var parentCell = editor.dom.getParent(table, 'td,th');
97
+ if (parentCell) {
98
+ return handle(upBool, parentCell, e);
99
+ } else {
100
+ var backUpSibling = getChildForDirection(currentRow, !upBool);
101
+ moveCursorToStartOfElement(backUpSibling);
102
+ e.preventDefault();
103
+ return false;
104
+ }
105
+ }
106
+ }
107
+
108
+ function getChildForDirection(parent, up) {
109
+ var child = parent && parent[up ? 'lastChild' : 'firstChild'];
110
+ // BR is not a valid table child to return in this case we return the table cell
111
+ return child && child.nodeName === 'BR' ? editor.dom.getParent(child, 'td,th') : child;
112
+ }
113
+
114
+ function moveCursorToStartOfElement(n) {
115
+ editor.selection.setCursorLocation(n, 0);
116
+ }
117
+
118
+ function isVerticalMovement() {
119
+ return key == VK.UP || key == VK.DOWN;
120
+ }
121
+
122
+ function isInTable(editor) {
123
+ var node = editor.selection.getNode();
124
+ var currentRow = editor.dom.getParent(node, 'tr');
125
+ return currentRow !== null;
126
+ }
127
+
128
+ function columnIndex(column) {
129
+ var colIndex = 0;
130
+ var c = column;
131
+ while (c.previousSibling) {
132
+ c = c.previousSibling;
133
+ colIndex = colIndex + getSpanVal(c, "colspan");
134
+ }
135
+ return colIndex;
136
+ }
137
+
138
+ function findColumn(rowElement, columnIndex) {
139
+ var c = 0, r = 0;
140
+
141
+ each(rowElement.children, function(cell, i) {
142
+ c = c + getSpanVal(cell, "colspan");
143
+ r = i;
144
+ if (c > columnIndex) {
145
+ return false;
146
+ }
147
+ });
148
+ return r;
149
+ }
150
+
151
+ function moveCursorToRow(ed, node, row, upBool) {
152
+ var srcColumnIndex = columnIndex(editor.dom.getParent(node, 'td,th'));
153
+ var tgtColumnIndex = findColumn(row, srcColumnIndex);
154
+ var tgtNode = row.childNodes[tgtColumnIndex];
155
+ var rowCellTarget = getChildForDirection(tgtNode, upBool);
156
+ moveCursorToStartOfElement(rowCellTarget || tgtNode);
157
+ }
158
+
159
+ function shouldFixCaret(preBrowserNode) {
160
+ var newNode = editor.selection.getNode();
161
+ var newParent = editor.dom.getParent(newNode, 'td,th');
162
+ var oldParent = editor.dom.getParent(preBrowserNode, 'td,th');
163
+
164
+ return newParent && newParent !== oldParent && checkSameParentTable(newParent, oldParent);
165
+ }
166
+
167
+ function checkSameParentTable(nodeOne, NodeTwo) {
168
+ return editor.dom.getParent(nodeOne, 'TABLE') === editor.dom.getParent(NodeTwo, 'TABLE');
169
+ }
170
+
171
+ if (isVerticalMovement() && isInTable(editor)) {
172
+ var preBrowserNode = editor.selection.getNode();
173
+ setTimeout(function() {
174
+ if (shouldFixCaret(preBrowserNode)) {
175
+ handle(!e.shiftKey && key === VK.UP, preBrowserNode, e);
176
+ }
177
+ }, 0);
178
+ }
179
+ }
180
+
181
+ editor.on('KeyDown', function(e) {
182
+ eventHandler(e);
183
+ });
184
+ }
185
+
186
+ function fixBeforeTableCaretBug() {
187
+ // Checks if the selection/caret is at the start of the specified block element
188
+ function isAtStart(rng, par) {
189
+ var doc = par.ownerDocument, rng2 = doc.createRange(), elm;
190
+
191
+ rng2.setStartBefore(par);
192
+ rng2.setEnd(rng.endContainer, rng.endOffset);
193
+
194
+ elm = doc.createElement('body');
195
+ elm.appendChild(rng2.cloneContents());
196
+
197
+ // Check for text characters of other elements that should be treated as content
198
+ return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length === 0;
199
+ }
200
+
201
+ // Fixes an bug where it's impossible to place the caret before a table in Gecko
202
+ // this fix solves it by detecting when the caret is at the beginning of such a table
203
+ // and then manually moves the caret infront of the table
204
+ editor.on('KeyDown', function(e) {
205
+ var rng, table, dom = editor.dom;
206
+
207
+ // On gecko it's not possible to place the caret before a table
208
+ if (e.keyCode == 37 || e.keyCode == 38) {
209
+ rng = editor.selection.getRng();
210
+ table = dom.getParent(rng.startContainer, 'table');
211
+
212
+ if (table && editor.getBody().firstChild == table) {
213
+ if (isAtStart(rng, table)) {
214
+ rng = dom.createRng();
215
+
216
+ rng.setStartBefore(table);
217
+ rng.setEndBefore(table);
218
+
219
+ editor.selection.setRng(rng);
220
+
221
+ e.preventDefault();
222
+ }
223
+ }
224
+ }
225
+ });
226
+ }
227
+
228
+ // Fixes an issue on Gecko where it's impossible to place the caret behind a table
229
+ // This fix will force a paragraph element after the table but only when the forced_root_block setting is enabled
230
+ function fixTableCaretPos() {
231
+ editor.on('KeyDown SetContent VisualAid', function() {
232
+ var last;
233
+
234
+ // Skip empty text nodes from the end
235
+ for (last = editor.getBody().lastChild; last; last = last.previousSibling) {
236
+ if (last.nodeType == 3) {
237
+ if (last.nodeValue.length > 0) {
238
+ break;
239
+ }
240
+ } else if (last.nodeType == 1 && (last.tagName == 'BR' || !last.getAttribute('data-mce-bogus'))) {
241
+ break;
242
+ }
243
+ }
244
+
245
+ if (last && last.nodeName == 'TABLE') {
246
+ if (editor.settings.forced_root_block) {
247
+ editor.dom.add(
248
+ editor.getBody(),
249
+ editor.settings.forced_root_block,
250
+ editor.settings.forced_root_block_attrs,
251
+ Env.ie && Env.ie < 11 ? '&nbsp;' : '<br data-mce-bogus="1" />'
252
+ );
253
+ } else {
254
+ editor.dom.add(editor.getBody(), 'br', {'data-mce-bogus': '1'});
255
+ }
256
+ }
257
+ });
258
+
259
+ editor.on('PreProcess', function(o) {
260
+ var last = o.node.lastChild;
261
+
262
+ if (last && (last.nodeName == "BR" || (last.childNodes.length == 1 &&
263
+ (last.firstChild.nodeName == 'BR' || last.firstChild.nodeValue == '\u00a0'))) &&
264
+ last.previousSibling && last.previousSibling.nodeName == "TABLE") {
265
+ editor.dom.remove(last);
266
+ }
267
+ });
268
+ }
269
+
270
+ // this nasty hack is here to work around some WebKit selection bugs.
271
+ function fixTableCellSelection() {
272
+ function tableCellSelected(ed, rng, n, currentCell) {
273
+ // The decision of when a table cell is selected is somewhat involved. The fact that this code is
274
+ // required is actually a pointer to the root cause of this bug. A cell is selected when the start
275
+ // and end offsets are 0, the start container is a text, and the selection node is either a TR (most cases)
276
+ // or the parent of the table (in the case of the selection containing the last cell of a table).
277
+ var TEXT_NODE = 3, table = ed.dom.getParent(rng.startContainer, 'TABLE');
278
+ var tableParent, allOfCellSelected, tableCellSelection;
279
+
280
+ if (table) {
281
+ tableParent = table.parentNode;
282
+ }
283
+
284
+ allOfCellSelected = rng.startContainer.nodeType == TEXT_NODE &&
285
+ rng.startOffset === 0 &&
286
+ rng.endOffset === 0 &&
287
+ currentCell &&
288
+ (n.nodeName == "TR" || n == tableParent);
289
+
290
+ tableCellSelection = (n.nodeName == "TD" || n.nodeName == "TH") && !currentCell;
291
+
292
+ return allOfCellSelected || tableCellSelection;
293
+ }
294
+
295
+ function fixSelection() {
296
+ var rng = editor.selection.getRng();
297
+ var n = editor.selection.getNode();
298
+ var currentCell = editor.dom.getParent(rng.startContainer, 'TD,TH');
299
+
300
+ if (!tableCellSelected(editor, rng, n, currentCell)) {
301
+ return;
302
+ }
303
+
304
+ if (!currentCell) {
305
+ currentCell = n;
306
+ }
307
+
308
+ // Get the very last node inside the table cell
309
+ var end = currentCell.lastChild;
310
+ while (end.lastChild) {
311
+ end = end.lastChild;
312
+ }
313
+
314
+ // Select the entire table cell. Nothing outside of the table cell should be selected.
315
+ if (end.nodeType == 3) {
316
+ rng.setEnd(end, end.data.length);
317
+ editor.selection.setRng(rng);
318
+ }
319
+ }
320
+
321
+ editor.on('KeyDown', function() {
322
+ fixSelection();
323
+ });
324
+
325
+ editor.on('MouseDown', function(e) {
326
+ if (e.button != 2) {
327
+ fixSelection();
328
+ }
329
+ });
330
+ }
331
+
332
+ /**
333
+ * Delete table if all cells are selected.
334
+ */
335
+ function deleteTable() {
336
+ editor.on('keydown', function(e) {
337
+ if ((e.keyCode == VK.DELETE || e.keyCode == VK.BACKSPACE) && !e.isDefaultPrevented()) {
338
+ var table = editor.dom.getParent(editor.selection.getStart(), 'table');
339
+
340
+ if (table) {
341
+ var cells = editor.dom.select('td,th', table), i = cells.length;
342
+ while (i--) {
343
+ if (!editor.dom.hasClass(cells[i], 'mce-item-selected')) {
344
+ return;
345
+ }
346
+ }
347
+
348
+ e.preventDefault();
349
+ editor.execCommand('mceTableDelete');
350
+ }
351
+ }
352
+ });
353
+ }
354
+
355
+ deleteTable();
356
+
357
+ if (Env.webkit) {
358
+ moveWebKitSelection();
359
+ fixTableCellSelection();
360
+ }
361
+
362
+ if (Env.gecko) {
363
+ fixBeforeTableCaretBug();
364
+ fixTableCaretPos();
365
+ }
366
+
367
+ if (Env.ie > 10) {
368
+ fixBeforeTableCaretBug();
369
+ fixTableCaretPos();
370
+ }
371
+ };
372
+ });