* Re-added tiny_mce, this time with the language packs
[citadel.git] / webcit / tiny_mce / plugins / table / editor_plugin_src.js
1 /**\r
2  * $Id: editor_plugin_src.js 953 2008-11-04 10:16:50Z spocke $\r
3  *\r
4  * @author Moxiecode\r
5  * @copyright Copyright © 2004-2008, Moxiecode Systems AB, All rights reserved.\r
6  */\r
7 \r
8 (function() {\r
9         var each = tinymce.each;\r
10 \r
11         tinymce.create('tinymce.plugins.TablePlugin', {\r
12                 init : function(ed, url) {\r
13                         var t = this;\r
14 \r
15                         t.editor = ed;\r
16                         t.url = url;\r
17 \r
18                         // Register buttons\r
19                         each([\r
20                                 ['table', 'table.desc', 'mceInsertTable', true],\r
21                                 ['delete_table', 'table.del', 'mceTableDelete'],\r
22                                 ['delete_col', 'table.delete_col_desc', 'mceTableDeleteCol'],\r
23                                 ['delete_row', 'table.delete_row_desc', 'mceTableDeleteRow'],\r
24                                 ['col_after', 'table.col_after_desc', 'mceTableInsertColAfter'],\r
25                                 ['col_before', 'table.col_before_desc', 'mceTableInsertColBefore'],\r
26                                 ['row_after', 'table.row_after_desc', 'mceTableInsertRowAfter'],\r
27                                 ['row_before', 'table.row_before_desc', 'mceTableInsertRowBefore'],\r
28                                 ['row_props', 'table.row_desc', 'mceTableRowProps', true],\r
29                                 ['cell_props', 'table.cell_desc', 'mceTableCellProps', true],\r
30                                 ['split_cells', 'table.split_cells_desc', 'mceTableSplitCells', true],\r
31                                 ['merge_cells', 'table.merge_cells_desc', 'mceTableMergeCells', true]\r
32                         ], function(c) {\r
33                                 ed.addButton(c[0], {title : c[1], cmd : c[2], ui : c[3]});\r
34                         });\r
35 \r
36                         if (ed.getParam('inline_styles')) {\r
37                                 // Force move of attribs to styles in strict mode\r
38                                 ed.onPreProcess.add(function(ed, o) {\r
39                                         var dom = ed.dom;\r
40 \r
41                                         each(dom.select('table', o.node), function(n) {\r
42                                                 var v;\r
43 \r
44                                                 if (v = dom.getAttrib(n, 'width')) {\r
45                                                         dom.setStyle(n, 'width', v);\r
46                                                         dom.setAttrib(n, 'width');\r
47                                                 }\r
48 \r
49                                                 if (v = dom.getAttrib(n, 'height')) {\r
50                                                         dom.setStyle(n, 'height', v);\r
51                                                         dom.setAttrib(n, 'height');\r
52                                                 }\r
53                                         });\r
54                                 });\r
55                         }\r
56 \r
57                         ed.onInit.add(function() {\r
58                                 if (ed && ed.plugins.contextmenu) {\r
59                                         ed.plugins.contextmenu.onContextMenu.add(function(th, m, e) {\r
60                                                 var sm, se = ed.selection, el = se.getNode() || ed.getBody();\r
61 \r
62                                                 if (ed.dom.getParent(e, 'td') || ed.dom.getParent(e, 'th')) {\r
63                                                         m.removeAll();\r
64 \r
65                                                         if (el.nodeName == 'A' && !ed.dom.getAttrib(el, 'name')) {\r
66                                                                 m.add({title : 'advanced.link_desc', icon : 'link', cmd : ed.plugins.advlink ? 'mceAdvLink' : 'mceLink', ui : true});\r
67                                                                 m.add({title : 'advanced.unlink_desc', icon : 'unlink', cmd : 'UnLink'});\r
68                                                                 m.addSeparator();\r
69                                                         }\r
70 \r
71                                                         if (el.nodeName == 'IMG' && el.className.indexOf('mceItem') == -1) {\r
72                                                                 m.add({title : 'advanced.image_desc', icon : 'image', cmd : ed.plugins.advimage ? 'mceAdvImage' : 'mceImage', ui : true});\r
73                                                                 m.addSeparator();\r
74                                                         }\r
75 \r
76                                                         m.add({title : 'table.desc', icon : 'table', cmd : 'mceInsertTable', ui : true, value : {action : 'insert'}});\r
77                                                         m.add({title : 'table.props_desc', icon : 'table_props', cmd : 'mceInsertTable', ui : true});\r
78                                                         m.add({title : 'table.del', icon : 'delete_table', cmd : 'mceTableDelete', ui : true});\r
79                                                         m.addSeparator();\r
80 \r
81                                                         // Cell menu\r
82                                                         sm = m.addMenu({title : 'table.cell'});\r
83                                                         sm.add({title : 'table.cell_desc', icon : 'cell_props', cmd : 'mceTableCellProps', ui : true});\r
84                                                         sm.add({title : 'table.split_cells_desc', icon : 'split_cells', cmd : 'mceTableSplitCells', ui : true});\r
85                                                         sm.add({title : 'table.merge_cells_desc', icon : 'merge_cells', cmd : 'mceTableMergeCells', ui : true});\r
86 \r
87                                                         // Row menu\r
88                                                         sm = m.addMenu({title : 'table.row'});\r
89                                                         sm.add({title : 'table.row_desc', icon : 'row_props', cmd : 'mceTableRowProps', ui : true});\r
90                                                         sm.add({title : 'table.row_before_desc', icon : 'row_before', cmd : 'mceTableInsertRowBefore'});\r
91                                                         sm.add({title : 'table.row_after_desc', icon : 'row_after', cmd : 'mceTableInsertRowAfter'});\r
92                                                         sm.add({title : 'table.delete_row_desc', icon : 'delete_row', cmd : 'mceTableDeleteRow'});\r
93                                                         sm.addSeparator();\r
94                                                         sm.add({title : 'table.cut_row_desc', icon : 'cut', cmd : 'mceTableCutRow'});\r
95                                                         sm.add({title : 'table.copy_row_desc', icon : 'copy', cmd : 'mceTableCopyRow'});\r
96                                                         sm.add({title : 'table.paste_row_before_desc', icon : 'paste', cmd : 'mceTablePasteRowBefore'});\r
97                                                         sm.add({title : 'table.paste_row_after_desc', icon : 'paste', cmd : 'mceTablePasteRowAfter'});\r
98 \r
99                                                         // Column menu\r
100                                                         sm = m.addMenu({title : 'table.col'});\r
101                                                         sm.add({title : 'table.col_before_desc', icon : 'col_before', cmd : 'mceTableInsertColBefore'});\r
102                                                         sm.add({title : 'table.col_after_desc', icon : 'col_after', cmd : 'mceTableInsertColAfter'});\r
103                                                         sm.add({title : 'table.delete_col_desc', icon : 'delete_col', cmd : 'mceTableDeleteCol'});\r
104                                                 } else\r
105                                                         m.add({title : 'table.desc', icon : 'table', cmd : 'mceInsertTable', ui : true});\r
106                                         });\r
107                                 }\r
108                         });\r
109 \r
110                         // Add undo level when new rows are created using the tab key\r
111                         ed.onKeyDown.add(function(ed, e) {\r
112                                 if (e.keyCode == 9 && ed.dom.getParent(ed.selection.getNode(), 'TABLE')) {\r
113                                         if (!tinymce.isGecko && !tinymce.isOpera) {\r
114                                                 tinyMCE.execInstanceCommand(ed.editorId, "mceTableMoveToNextRow", true);\r
115                                                 return tinymce.dom.Event.cancel(e);\r
116                                         }\r
117 \r
118                                         ed.undoManager.add();\r
119                                 }\r
120                         });\r
121 \r
122                         // Select whole table is a table border is clicked\r
123                         if (!tinymce.isIE) {\r
124                                 if (ed.getParam('table_selection', true)) {\r
125                                         ed.onClick.add(function(ed, e) {\r
126                                                 e = e.target;\r
127 \r
128                                                 if (e.nodeName === 'TABLE')\r
129                                                         ed.selection.select(e);\r
130                                         });\r
131                                 }\r
132                         }\r
133 \r
134                         ed.onNodeChange.add(function(ed, cm, n) {\r
135                                 var p = ed.dom.getParent(n, 'td,th,caption');\r
136 \r
137                                 cm.setActive('table', n.nodeName === 'TABLE' || !!p);\r
138                                 if (p && p.nodeName === 'CAPTION')\r
139                                         p = null;\r
140 \r
141                                 cm.setDisabled('delete_table', !p);\r
142                                 cm.setDisabled('delete_col', !p);\r
143                                 cm.setDisabled('delete_table', !p);\r
144                                 cm.setDisabled('delete_row', !p);\r
145                                 cm.setDisabled('col_after', !p);\r
146                                 cm.setDisabled('col_before', !p);\r
147                                 cm.setDisabled('row_after', !p);\r
148                                 cm.setDisabled('row_before', !p);\r
149                                 cm.setDisabled('row_props', !p);\r
150                                 cm.setDisabled('cell_props', !p);\r
151                                 cm.setDisabled('split_cells', !p || (parseInt(ed.dom.getAttrib(p, 'colspan', '1')) < 2 && parseInt(ed.dom.getAttrib(p, 'rowspan', '1')) < 2));\r
152                                 cm.setDisabled('merge_cells', !p);\r
153                         });\r
154 \r
155                         // Padd empty table cells\r
156                         if (!tinymce.isIE) {\r
157                                 ed.onBeforeSetContent.add(function(ed, o) {\r
158                                         if (o.initial)\r
159                                                 o.content = o.content.replace(/<(td|th)([^>]+|)>\s*<\/(td|th)>/g, tinymce.isOpera ? '<$1$2>&nbsp;</$1>' : '<$1$2><br mce_bogus="1" /></$1>');\r
160                                 });\r
161                         }\r
162                 },\r
163 \r
164                 execCommand : function(cmd, ui, val) {\r
165                         var ed = this.editor, b;\r
166 \r
167                         // Is table command\r
168                         switch (cmd) {\r
169                                 case "mceTableMoveToNextRow":\r
170                                 case "mceInsertTable":\r
171                                 case "mceTableRowProps":\r
172                                 case "mceTableCellProps":\r
173                                 case "mceTableSplitCells":\r
174                                 case "mceTableMergeCells":\r
175                                 case "mceTableInsertRowBefore":\r
176                                 case "mceTableInsertRowAfter":\r
177                                 case "mceTableDeleteRow":\r
178                                 case "mceTableInsertColBefore":\r
179                                 case "mceTableInsertColAfter":\r
180                                 case "mceTableDeleteCol":\r
181                                 case "mceTableCutRow":\r
182                                 case "mceTableCopyRow":\r
183                                 case "mceTablePasteRowBefore":\r
184                                 case "mceTablePasteRowAfter":\r
185                                 case "mceTableDelete":\r
186                                         ed.execCommand('mceBeginUndoLevel');\r
187                                         this._doExecCommand(cmd, ui, val);\r
188                                         ed.execCommand('mceEndUndoLevel');\r
189 \r
190                                         return true;\r
191                         }\r
192 \r
193                         // Pass to next handler in chain\r
194                         return false;\r
195                 },\r
196 \r
197                 getInfo : function() {\r
198                         return {\r
199                                 longname : 'Tables',\r
200                                 author : 'Moxiecode Systems AB',\r
201                                 authorurl : 'http://tinymce.moxiecode.com',\r
202                                 infourl : 'http://wiki.moxiecode.com/index.php/TinyMCE:Plugins/table',\r
203                                 version : tinymce.majorVersion + "." + tinymce.minorVersion\r
204                         };\r
205                 },\r
206 \r
207                 // Private plugin internal methods\r
208 \r
209                 /**\r
210                  * Executes the table commands.\r
211                  */\r
212                 _doExecCommand : function(command, user_interface, value) {\r
213                         var inst = this.editor, ed = inst, url = this.url;\r
214                         var focusElm = inst.selection.getNode();\r
215                         var trElm = inst.dom.getParent(focusElm, "tr");\r
216                         var tdElm = inst.dom.getParent(focusElm, "td,th");\r
217                         var tableElm = inst.dom.getParent(focusElm, "table");\r
218                         var doc = inst.contentWindow.document;\r
219                         var tableBorder = tableElm ? tableElm.getAttribute("border") : "";\r
220 \r
221                         // Get first TD if no TD found\r
222                         if (trElm && tdElm == null)\r
223                                 tdElm = trElm.cells[0];\r
224 \r
225                         function inArray(ar, v) {\r
226                                 for (var i=0; i<ar.length; i++) {\r
227                                         // Is array\r
228                                         if (ar[i].length > 0 && inArray(ar[i], v))\r
229                                                 return true;\r
230 \r
231                                         // Found value\r
232                                         if (ar[i] == v)\r
233                                                 return true;\r
234                                 }\r
235 \r
236                                 return false;\r
237                         }\r
238 \r
239                         function select(dx, dy) {\r
240                                 var td;\r
241 \r
242                                 grid = getTableGrid(tableElm);\r
243                                 dx = dx || 0;\r
244                                 dy = dy || 0;\r
245                                 dx = Math.max(cpos.cellindex + dx, 0);\r
246                                 dy = Math.max(cpos.rowindex + dy, 0);\r
247 \r
248                                 // Recalculate grid and select\r
249                                 inst.execCommand('mceRepaint');\r
250                                 td = getCell(grid, dy, dx);\r
251 \r
252                                 if (td) {\r
253                                         inst.selection.select(td.firstChild || td);\r
254                                         inst.selection.collapse(1);\r
255                                 }\r
256                         };\r
257 \r
258                         function makeTD() {\r
259                                 var newTD = doc.createElement("td");\r
260 \r
261                                 if (!tinymce.isIE)\r
262                                         newTD.innerHTML = '<br mce_bogus="1"/>';\r
263                         }\r
264 \r
265                         function getColRowSpan(td) {\r
266                                 var colspan = inst.dom.getAttrib(td, "colspan");\r
267                                 var rowspan = inst.dom.getAttrib(td, "rowspan");\r
268 \r
269                                 colspan = colspan == "" ? 1 : parseInt(colspan);\r
270                                 rowspan = rowspan == "" ? 1 : parseInt(rowspan);\r
271 \r
272                                 return {colspan : colspan, rowspan : rowspan};\r
273                         }\r
274 \r
275                         function getCellPos(grid, td) {\r
276                                 var x, y;\r
277 \r
278                                 for (y=0; y<grid.length; y++) {\r
279                                         for (x=0; x<grid[y].length; x++) {\r
280                                                 if (grid[y][x] == td)\r
281                                                         return {cellindex : x, rowindex : y};\r
282                                         }\r
283                                 }\r
284 \r
285                                 return null;\r
286                         }\r
287 \r
288                         function getCell(grid, row, col) {\r
289                                 if (grid[row] && grid[row][col])\r
290                                         return grid[row][col];\r
291 \r
292                                 return null;\r
293                         }\r
294 \r
295                         function getNextCell(table, cell) {\r
296                                 var cells = [], x = 0, i, j, cell, nextCell;\r
297 \r
298                                 for (i = 0; i < table.rows.length; i++)\r
299                                         for (j = 0; j < table.rows[i].cells.length; j++, x++)\r
300                                                 cells[x] = table.rows[i].cells[j];\r
301 \r
302                                 for (i = 0; i < cells.length; i++)\r
303                                         if (cells[i] == cell)\r
304                                                 if (nextCell = cells[i+1])\r
305                                                         return nextCell;\r
306                         }\r
307 \r
308                         function getTableGrid(table) {\r
309                                 var grid = [], rows = table.rows, x, y, td, sd, xstart, x2, y2;\r
310 \r
311                                 for (y=0; y<rows.length; y++) {\r
312                                         for (x=0; x<rows[y].cells.length; x++) {\r
313                                                 td = rows[y].cells[x];\r
314                                                 sd = getColRowSpan(td);\r
315 \r
316                                                 // All ready filled\r
317                                                 for (xstart = x; grid[y] && grid[y][xstart]; xstart++) ;\r
318 \r
319                                                 // Fill box\r
320                                                 for (y2=y; y2<y+sd['rowspan']; y2++) {\r
321                                                         if (!grid[y2])\r
322                                                                 grid[y2] = [];\r
323 \r
324                                                         for (x2=xstart; x2<xstart+sd['colspan']; x2++)\r
325                                                                 grid[y2][x2] = td;\r
326                                                 }\r
327                                         }\r
328                                 }\r
329 \r
330                                 return grid;\r
331                         }\r
332 \r
333                         function trimRow(table, tr, td, new_tr) {\r
334                                 var grid = getTableGrid(table), cpos = getCellPos(grid, td);\r
335                                 var cells, lastElm;\r
336 \r
337                                 // Time to crop away some\r
338                                 if (new_tr.cells.length != tr.childNodes.length) {\r
339                                         cells = tr.childNodes;\r
340                                         lastElm = null;\r
341 \r
342                                         for (var x=0; td = getCell(grid, cpos.rowindex, x); x++) {\r
343                                                 var remove = true;\r
344                                                 var sd = getColRowSpan(td);\r
345 \r
346                                                 // Remove due to rowspan\r
347                                                 if (inArray(cells, td)) {\r
348                                                         new_tr.childNodes[x]._delete = true;\r
349                                                 } else if ((lastElm == null || td != lastElm) && sd.colspan > 1) { // Remove due to colspan\r
350                                                         for (var i=x; i<x+td.colSpan; i++)\r
351                                                                 new_tr.childNodes[i]._delete = true;\r
352                                                 }\r
353 \r
354                                                 if ((lastElm == null || td != lastElm) && sd.rowspan > 1)\r
355                                                         td.rowSpan = sd.rowspan + 1;\r
356 \r
357                                                 lastElm = td;\r
358                                         }\r
359 \r
360                                         deleteMarked(tableElm);\r
361                                 }\r
362                         }\r
363 \r
364                         function prevElm(node, name) {\r
365                                 while ((node = node.previousSibling) != null) {\r
366                                         if (node.nodeName == name)\r
367                                                 return node;\r
368                                 }\r
369 \r
370                                 return null;\r
371                         }\r
372 \r
373                         function nextElm(node, names) {\r
374                                 var namesAr = names.split(',');\r
375 \r
376                                 while ((node = node.nextSibling) != null) {\r
377                                         for (var i=0; i<namesAr.length; i++) {\r
378                                                 if (node.nodeName.toLowerCase() == namesAr[i].toLowerCase() )\r
379                                                         return node;\r
380                                         }\r
381                                 }\r
382 \r
383                                 return null;\r
384                         }\r
385 \r
386                         function deleteMarked(tbl) {\r
387                                 if (tbl.rows == 0)\r
388                                         return;\r
389 \r
390                                 var tr = tbl.rows[0];\r
391                                 do {\r
392                                         var next = nextElm(tr, "TR");\r
393 \r
394                                         // Delete row\r
395                                         if (tr._delete) {\r
396                                                 tr.parentNode.removeChild(tr);\r
397                                                 continue;\r
398                                         }\r
399 \r
400                                         // Delete cells\r
401                                         var td = tr.cells[0];\r
402                                         if (td.cells > 1) {\r
403                                                 do {\r
404                                                         var nexttd = nextElm(td, "TD,TH");\r
405 \r
406                                                         if (td._delete)\r
407                                                                 td.parentNode.removeChild(td);\r
408                                                 } while ((td = nexttd) != null);\r
409                                         }\r
410                                 } while ((tr = next) != null);\r
411                         }\r
412 \r
413                         function addRows(td_elm, tr_elm, rowspan) {\r
414                                 // Add rows\r
415                                 td_elm.rowSpan = 1;\r
416                                 var trNext = nextElm(tr_elm, "TR");\r
417                                 for (var i=1; i<rowspan && trNext; i++) {\r
418                                         var newTD = doc.createElement("td");\r
419 \r
420                                         if (!tinymce.isIE)\r
421                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
422 \r
423                                         if (tinymce.isIE)\r
424                                                 trNext.insertBefore(newTD, trNext.cells(td_elm.cellIndex));\r
425                                         else\r
426                                                 trNext.insertBefore(newTD, trNext.cells[td_elm.cellIndex]);\r
427 \r
428                                         trNext = nextElm(trNext, "TR");\r
429                                 }\r
430                         }\r
431 \r
432                         function copyRow(doc, table, tr) {\r
433                                 var grid = getTableGrid(table);\r
434                                 var newTR = tr.cloneNode(false);\r
435                                 var cpos = getCellPos(grid, tr.cells[0]);\r
436                                 var lastCell = null;\r
437                                 var tableBorder = inst.dom.getAttrib(table, "border");\r
438                                 var tdElm = null;\r
439 \r
440                                 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) {\r
441                                         var newTD = null;\r
442 \r
443                                         if (lastCell != tdElm) {\r
444                                                 for (var i=0; i<tr.cells.length; i++) {\r
445                                                         if (tdElm == tr.cells[i]) {\r
446                                                                 newTD = tdElm.cloneNode(true);\r
447                                                                 break;\r
448                                                         }\r
449                                                 }\r
450                                         }\r
451 \r
452                                         if (newTD == null) {\r
453                                                 newTD = doc.createElement("td");\r
454 \r
455                                                 if (!tinymce.isIE)\r
456                                                         newTD.innerHTML = '<br mce_bogus="1"/>';\r
457                                         }\r
458 \r
459                                         // Reset col/row span\r
460                                         newTD.colSpan = 1;\r
461                                         newTD.rowSpan = 1;\r
462 \r
463                                         newTR.appendChild(newTD);\r
464 \r
465                                         lastCell = tdElm;\r
466                                 }\r
467 \r
468                                 return newTR;\r
469                         }\r
470 \r
471                         // ---- Commands -----\r
472 \r
473                         // Handle commands\r
474                         switch (command) {\r
475                                 case "mceTableMoveToNextRow":\r
476                                         var nextCell = getNextCell(tableElm, tdElm);\r
477 \r
478                                         if (!nextCell) {\r
479                                                 inst.execCommand("mceTableInsertRowAfter", tdElm);\r
480                                                 nextCell = getNextCell(tableElm, tdElm);\r
481                                         }\r
482 \r
483                                         inst.selection.select(nextCell);\r
484                                         inst.selection.collapse(true);\r
485 \r
486                                         return true;\r
487 \r
488                                 case "mceTableRowProps":\r
489                                         if (trElm == null)\r
490                                                 return true;\r
491 \r
492                                         if (user_interface) {\r
493                                                 inst.windowManager.open({\r
494                                                         url : url + '/row.htm',\r
495                                                         width : 400 + parseInt(inst.getLang('table.rowprops_delta_width', 0)),\r
496                                                         height : 295 + parseInt(inst.getLang('table.rowprops_delta_height', 0)),\r
497                                                         inline : 1\r
498                                                 }, {\r
499                                                         plugin_url : url\r
500                                                 });\r
501                                         }\r
502 \r
503                                         return true;\r
504 \r
505                                 case "mceTableCellProps":\r
506                                         if (tdElm == null)\r
507                                                 return true;\r
508 \r
509                                         if (user_interface) {\r
510                                                 inst.windowManager.open({\r
511                                                         url : url + '/cell.htm',\r
512                                                         width : 400 + parseInt(inst.getLang('table.cellprops_delta_width', 0)),\r
513                                                         height : 295 + parseInt(inst.getLang('table.cellprops_delta_height', 0)),\r
514                                                         inline : 1\r
515                                                 }, {\r
516                                                         plugin_url : url\r
517                                                 });\r
518                                         }\r
519 \r
520                                         return true;\r
521 \r
522                                 case "mceInsertTable":\r
523                                         if (user_interface) {\r
524                                                 inst.windowManager.open({\r
525                                                         url : url + '/table.htm',\r
526                                                         width : 400 + parseInt(inst.getLang('table.table_delta_width', 0)),\r
527                                                         height : 320 + parseInt(inst.getLang('table.table_delta_height', 0)),\r
528                                                         inline : 1\r
529                                                 }, {\r
530                                                         plugin_url : url,\r
531                                                         action : value ? value.action : 0\r
532                                                 });\r
533                                         }\r
534 \r
535                                         return true;\r
536 \r
537                                 case "mceTableDelete":\r
538                                         var table = inst.dom.getParent(inst.selection.getNode(), "table");\r
539                                         if (table) {\r
540                                                 table.parentNode.removeChild(table);\r
541                                                 inst.execCommand('mceRepaint');\r
542                                         }\r
543                                         return true;\r
544 \r
545                                 case "mceTableSplitCells":\r
546                                 case "mceTableMergeCells":\r
547                                 case "mceTableInsertRowBefore":\r
548                                 case "mceTableInsertRowAfter":\r
549                                 case "mceTableDeleteRow":\r
550                                 case "mceTableInsertColBefore":\r
551                                 case "mceTableInsertColAfter":\r
552                                 case "mceTableDeleteCol":\r
553                                 case "mceTableCutRow":\r
554                                 case "mceTableCopyRow":\r
555                                 case "mceTablePasteRowBefore":\r
556                                 case "mceTablePasteRowAfter":\r
557                                         // No table just return (invalid command)\r
558                                         if (!tableElm)\r
559                                                 return true;\r
560 \r
561                                         // Table has a tbody use that reference\r
562                                         // Changed logic by ApTest 2005.07.12 (www.aptest.com)\r
563                                         // Now lookk at the focused element and take its parentNode.  That will be a tbody or a table.\r
564                                         if (trElm && tableElm != trElm.parentNode)\r
565                                                 tableElm = trElm.parentNode;\r
566 \r
567                                         if (tableElm && trElm) {\r
568                                                 switch (command) {\r
569                                                         case "mceTableCutRow":\r
570                                                                 if (!trElm || !tdElm)\r
571                                                                         return true;\r
572 \r
573                                                                 inst.tableRowClipboard = copyRow(doc, tableElm, trElm);\r
574                                                                 inst.execCommand("mceTableDeleteRow");\r
575                                                                 break;\r
576 \r
577                                                         case "mceTableCopyRow":\r
578                                                                 if (!trElm || !tdElm)\r
579                                                                         return true;\r
580 \r
581                                                                 inst.tableRowClipboard = copyRow(doc, tableElm, trElm);\r
582                                                                 break;\r
583 \r
584                                                         case "mceTablePasteRowBefore":\r
585                                                                 if (!trElm || !tdElm)\r
586                                                                         return true;\r
587 \r
588                                                                 var newTR = inst.tableRowClipboard.cloneNode(true);\r
589 \r
590                                                                 var prevTR = prevElm(trElm, "TR");\r
591                                                                 if (prevTR != null)\r
592                                                                         trimRow(tableElm, prevTR, prevTR.cells[0], newTR);\r
593 \r
594                                                                 trElm.parentNode.insertBefore(newTR, trElm);\r
595                                                                 break;\r
596 \r
597                                                         case "mceTablePasteRowAfter":\r
598                                                                 if (!trElm || !tdElm)\r
599                                                                         return true;\r
600                                                                 \r
601                                                                 var nextTR = nextElm(trElm, "TR");\r
602                                                                 var newTR = inst.tableRowClipboard.cloneNode(true);\r
603 \r
604                                                                 trimRow(tableElm, trElm, tdElm, newTR);\r
605 \r
606                                                                 if (nextTR == null)\r
607                                                                         trElm.parentNode.appendChild(newTR);\r
608                                                                 else\r
609                                                                         nextTR.parentNode.insertBefore(newTR, nextTR);\r
610 \r
611                                                                 break;\r
612 \r
613                                                         case "mceTableInsertRowBefore":\r
614                                                                 if (!trElm || !tdElm)\r
615                                                                         return true;\r
616 \r
617                                                                 var grid = getTableGrid(tableElm);\r
618                                                                 var cpos = getCellPos(grid, tdElm);\r
619                                                                 var newTR = doc.createElement("tr");\r
620                                                                 var lastTDElm = null;\r
621 \r
622                                                                 cpos.rowindex--;\r
623                                                                 if (cpos.rowindex < 0)\r
624                                                                         cpos.rowindex = 0;\r
625 \r
626                                                                 // Create cells\r
627                                                                 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) {\r
628                                                                         if (tdElm != lastTDElm) {\r
629                                                                                 var sd = getColRowSpan(tdElm);\r
630 \r
631                                                                                 if (sd['rowspan'] == 1) {\r
632                                                                                         var newTD = doc.createElement("td");\r
633 \r
634                                                                                         if (!tinymce.isIE)\r
635                                                                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
636 \r
637                                                                                         newTD.colSpan = tdElm.colSpan;\r
638 \r
639                                                                                         newTR.appendChild(newTD);\r
640                                                                                 } else\r
641                                                                                         tdElm.rowSpan = sd['rowspan'] + 1;\r
642 \r
643                                                                                 lastTDElm = tdElm;\r
644                                                                         }\r
645                                                                 }\r
646 \r
647                                                                 trElm.parentNode.insertBefore(newTR, trElm);\r
648                                                                 select(0, 1);\r
649                                                         break;\r
650 \r
651                                                         case "mceTableInsertRowAfter":\r
652                                                                 if (!trElm || !tdElm)\r
653                                                                         return true;\r
654 \r
655                                                                 var grid = getTableGrid(tableElm);\r
656                                                                 var cpos = getCellPos(grid, tdElm);\r
657                                                                 var newTR = doc.createElement("tr");\r
658                                                                 var lastTDElm = null;\r
659 \r
660                                                                 // Create cells\r
661                                                                 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) {\r
662                                                                         if (tdElm != lastTDElm) {\r
663                                                                                 var sd = getColRowSpan(tdElm);\r
664 \r
665                                                                                 if (sd['rowspan'] == 1) {\r
666                                                                                         var newTD = doc.createElement("td");\r
667 \r
668                                                                                         if (!tinymce.isIE)\r
669                                                                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
670 \r
671                                                                                         newTD.colSpan = tdElm.colSpan;\r
672 \r
673                                                                                         newTR.appendChild(newTD);\r
674                                                                                 } else\r
675                                                                                         tdElm.rowSpan = sd['rowspan'] + 1;\r
676 \r
677                                                                                 lastTDElm = tdElm;\r
678                                                                         }\r
679                                                                 }\r
680 \r
681                                                                 if (newTR.hasChildNodes()) {\r
682                                                                         var nextTR = nextElm(trElm, "TR");\r
683                                                                         if (nextTR)\r
684                                                                                 nextTR.parentNode.insertBefore(newTR, nextTR);\r
685                                                                         else\r
686                                                                                 tableElm.appendChild(newTR);\r
687                                                                 }\r
688 \r
689                                                                 select(0, 1);\r
690                                                         break;\r
691 \r
692                                                         case "mceTableDeleteRow":\r
693                                                                 if (!trElm || !tdElm)\r
694                                                                         return true;\r
695 \r
696                                                                 var grid = getTableGrid(tableElm);\r
697                                                                 var cpos = getCellPos(grid, tdElm);\r
698 \r
699                                                                 // Only one row, remove whole table\r
700                                                                 if (grid.length == 1 && tableElm.nodeName == 'TBODY') {\r
701                                                                         inst.dom.remove(inst.dom.getParent(tableElm, "table"));\r
702                                                                         return true;\r
703                                                                 }\r
704 \r
705                                                                 // Move down row spanned cells\r
706                                                                 var cells = trElm.cells;\r
707                                                                 var nextTR = nextElm(trElm, "TR");\r
708                                                                 for (var x=0; x<cells.length; x++) {\r
709                                                                         if (cells[x].rowSpan > 1) {\r
710                                                                                 var newTD = cells[x].cloneNode(true);\r
711                                                                                 var sd = getColRowSpan(cells[x]);\r
712 \r
713                                                                                 newTD.rowSpan = sd.rowspan - 1;\r
714 \r
715                                                                                 var nextTD = nextTR.cells[x];\r
716 \r
717                                                                                 if (nextTD == null)\r
718                                                                                         nextTR.appendChild(newTD);\r
719                                                                                 else\r
720                                                                                         nextTR.insertBefore(newTD, nextTD);\r
721                                                                         }\r
722                                                                 }\r
723 \r
724                                                                 // Delete cells\r
725                                                                 var lastTDElm = null;\r
726                                                                 for (var x=0; tdElm = getCell(grid, cpos.rowindex, x); x++) {\r
727                                                                         if (tdElm != lastTDElm) {\r
728                                                                                 var sd = getColRowSpan(tdElm);\r
729 \r
730                                                                                 if (sd.rowspan > 1) {\r
731                                                                                         tdElm.rowSpan = sd.rowspan - 1;\r
732                                                                                 } else {\r
733                                                                                         trElm = tdElm.parentNode;\r
734 \r
735                                                                                         if (trElm.parentNode)\r
736                                                                                                 trElm._delete = true;\r
737                                                                                 }\r
738 \r
739                                                                                 lastTDElm = tdElm;\r
740                                                                         }\r
741                                                                 }\r
742 \r
743                                                                 deleteMarked(tableElm);\r
744 \r
745                                                                 select(0, -1);\r
746                                                         break;\r
747 \r
748                                                         case "mceTableInsertColBefore":\r
749                                                                 if (!trElm || !tdElm)\r
750                                                                         return true;\r
751 \r
752                                                                 var grid = getTableGrid(inst.dom.getParent(tableElm, "table"));\r
753                                                                 var cpos = getCellPos(grid, tdElm);\r
754                                                                 var lastTDElm = null;\r
755 \r
756                                                                 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) {\r
757                                                                         if (tdElm != lastTDElm) {\r
758                                                                                 var sd = getColRowSpan(tdElm);\r
759 \r
760                                                                                 if (sd['colspan'] == 1) {\r
761                                                                                         var newTD = doc.createElement(tdElm.nodeName);\r
762 \r
763                                                                                         if (!tinymce.isIE)\r
764                                                                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
765 \r
766                                                                                         newTD.rowSpan = tdElm.rowSpan;\r
767 \r
768                                                                                         tdElm.parentNode.insertBefore(newTD, tdElm);\r
769                                                                                 } else\r
770                                                                                         tdElm.colSpan++;\r
771 \r
772                                                                                 lastTDElm = tdElm;\r
773                                                                         }\r
774                                                                 }\r
775 \r
776                                                                 select();\r
777                                                         break;\r
778 \r
779                                                         case "mceTableInsertColAfter":\r
780                                                                 if (!trElm || !tdElm)\r
781                                                                         return true;\r
782 \r
783                                                                 var grid = getTableGrid(inst.dom.getParent(tableElm, "table"));\r
784                                                                 var cpos = getCellPos(grid, tdElm);\r
785                                                                 var lastTDElm = null;\r
786 \r
787                                                                 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) {\r
788                                                                         if (tdElm != lastTDElm) {\r
789                                                                                 var sd = getColRowSpan(tdElm);\r
790 \r
791                                                                                 if (sd['colspan'] == 1) {\r
792                                                                                         var newTD = doc.createElement(tdElm.nodeName);\r
793 \r
794                                                                                         if (!tinymce.isIE)\r
795                                                                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
796 \r
797                                                                                         newTD.rowSpan = tdElm.rowSpan;\r
798 \r
799                                                                                         var nextTD = nextElm(tdElm, "TD,TH");\r
800                                                                                         if (nextTD == null)\r
801                                                                                                 tdElm.parentNode.appendChild(newTD);\r
802                                                                                         else\r
803                                                                                                 nextTD.parentNode.insertBefore(newTD, nextTD);\r
804                                                                                 } else\r
805                                                                                         tdElm.colSpan++;\r
806 \r
807                                                                                 lastTDElm = tdElm;\r
808                                                                         }\r
809                                                                 }\r
810 \r
811                                                                 select(1);\r
812                                                         break;\r
813 \r
814                                                         case "mceTableDeleteCol":\r
815                                                                 if (!trElm || !tdElm)\r
816                                                                         return true;\r
817 \r
818                                                                 var grid = getTableGrid(tableElm);\r
819                                                                 var cpos = getCellPos(grid, tdElm);\r
820                                                                 var lastTDElm = null;\r
821 \r
822                                                                 // Only one col, remove whole table\r
823                                                                 if ((grid.length > 1 && grid[0].length <= 1) && tableElm.nodeName == 'TBODY') {\r
824                                                                         inst.dom.remove(inst.dom.getParent(tableElm, "table"));\r
825                                                                         return true;\r
826                                                                 }\r
827 \r
828                                                                 // Delete cells\r
829                                                                 for (var y=0; tdElm = getCell(grid, y, cpos.cellindex); y++) {\r
830                                                                         if (tdElm != lastTDElm) {\r
831                                                                                 var sd = getColRowSpan(tdElm);\r
832 \r
833                                                                                 if (sd['colspan'] > 1)\r
834                                                                                         tdElm.colSpan = sd['colspan'] - 1;\r
835                                                                                 else {\r
836                                                                                         if (tdElm.parentNode)\r
837                                                                                                 tdElm.parentNode.removeChild(tdElm);\r
838                                                                                 }\r
839 \r
840                                                                                 lastTDElm = tdElm;\r
841                                                                         }\r
842                                                                 }\r
843 \r
844                                                                 select(-1);\r
845                                                         break;\r
846 \r
847                                                 case "mceTableSplitCells":\r
848                                                         if (!trElm || !tdElm)\r
849                                                                 return true;\r
850 \r
851                                                         var spandata = getColRowSpan(tdElm);\r
852 \r
853                                                         var colspan = spandata["colspan"];\r
854                                                         var rowspan = spandata["rowspan"];\r
855 \r
856                                                         // Needs splitting\r
857                                                         if (colspan > 1 || rowspan > 1) {\r
858                                                                 // Generate cols\r
859                                                                 tdElm.colSpan = 1;\r
860                                                                 for (var i=1; i<colspan; i++) {\r
861                                                                         var newTD = doc.createElement("td");\r
862 \r
863                                                                         if (!tinymce.isIE)\r
864                                                                                 newTD.innerHTML = '<br mce_bogus="1"/>';\r
865 \r
866                                                                         trElm.insertBefore(newTD, nextElm(tdElm, "TD,TH"));\r
867 \r
868                                                                         if (rowspan > 1)\r
869                                                                                 addRows(newTD, trElm, rowspan);\r
870                                                                 }\r
871 \r
872                                                                 addRows(tdElm, trElm, rowspan);\r
873                                                         }\r
874 \r
875                                                         // Apply visual aids\r
876                                                         tableElm = inst.dom.getParent(inst.selection.getNode(), "table");\r
877                                                         break;\r
878 \r
879                                                 case "mceTableMergeCells":\r
880                                                         var rows = [];\r
881                                                         var sel = inst.selection.getSel();\r
882                                                         var grid = getTableGrid(tableElm);\r
883 \r
884                                                         if (tinymce.isIE || sel.rangeCount == 1) {\r
885                                                                 if (user_interface) {\r
886                                                                         // Setup template\r
887                                                                         var sp = getColRowSpan(tdElm);\r
888 \r
889                                                                         inst.windowManager.open({\r
890                                                                                 url : url + '/merge_cells.htm',\r
891                                                                                 width : 240 + parseInt(inst.getLang('table.merge_cells_delta_width', 0)),\r
892                                                                                 height : 110 + parseInt(inst.getLang('table.merge_cells_delta_height', 0)),\r
893                                                                                 inline : 1\r
894                                                                         }, {\r
895                                                                                 action : "update",\r
896                                                                                 numcols : sp.colspan,\r
897                                                                                 numrows : sp.rowspan,\r
898                                                                                 plugin_url : url\r
899                                                                         });\r
900 \r
901                                                                         return true;\r
902                                                                 } else {\r
903                                                                         var numRows = parseInt(value['numrows']);\r
904                                                                         var numCols = parseInt(value['numcols']);\r
905                                                                         var cpos = getCellPos(grid, tdElm);\r
906 \r
907                                                                         if (("" + numRows) == "NaN")\r
908                                                                                 numRows = 1;\r
909 \r
910                                                                         if (("" + numCols) == "NaN")\r
911                                                                                 numCols = 1;\r
912 \r
913                                                                         // Get rows and cells\r
914                                                                         var tRows = tableElm.rows;\r
915                                                                         for (var y=cpos.rowindex; y<grid.length; y++) {\r
916                                                                                 var rowCells = [];\r
917 \r
918                                                                                 for (var x=cpos.cellindex; x<grid[y].length; x++) {\r
919                                                                                         var td = getCell(grid, y, x);\r
920 \r
921                                                                                         if (td && !inArray(rows, td) && !inArray(rowCells, td)) {\r
922                                                                                                 var cp = getCellPos(grid, td);\r
923 \r
924                                                                                                 // Within range\r
925                                                                                                 if (cp.cellindex < cpos.cellindex+numCols && cp.rowindex < cpos.rowindex+numRows)\r
926                                                                                                         rowCells[rowCells.length] = td;\r
927                                                                                         }\r
928                                                                                 }\r
929 \r
930                                                                                 if (rowCells.length > 0)\r
931                                                                                         rows[rows.length] = rowCells;\r
932 \r
933                                                                                 var td = getCell(grid, cpos.rowindex, cpos.cellindex);\r
934                                                                                 each(ed.dom.select('br', td), function(e, i) {\r
935                                                                                         if (i > 0 && ed.dom.getAttrib('mce_bogus'))\r
936                                                                                                 ed.dom.remove(e);\r
937                                                                                 });\r
938                                                                         }\r
939 \r
940                                                                         //return true;\r
941                                                                 }\r
942                                                         } else {\r
943                                                                 var cells = [];\r
944                                                                 var sel = inst.selection.getSel();\r
945                                                                 var lastTR = null;\r
946                                                                 var curRow = null;\r
947                                                                 var x1 = -1, y1 = -1, x2, y2;\r
948 \r
949                                                                 // Only one cell selected, whats the point?\r
950                                                                 if (sel.rangeCount < 2)\r
951                                                                         return true;\r
952 \r
953                                                                 // Get all selected cells\r
954                                                                 for (var i=0; i<sel.rangeCount; i++) {\r
955                                                                         var rng = sel.getRangeAt(i);\r
956                                                                         var tdElm = rng.startContainer.childNodes[rng.startOffset];\r
957 \r
958                                                                         if (!tdElm)\r
959                                                                                 break;\r
960 \r
961                                                                         if (tdElm.nodeName == "TD" || tdElm.nodeName == "TH")\r
962                                                                                 cells[cells.length] = tdElm;\r
963                                                                 }\r
964 \r
965                                                                 // Get rows and cells\r
966                                                                 var tRows = tableElm.rows;\r
967                                                                 for (var y=0; y<tRows.length; y++) {\r
968                                                                         var rowCells = [];\r
969 \r
970                                                                         for (var x=0; x<tRows[y].cells.length; x++) {\r
971                                                                                 var td = tRows[y].cells[x];\r
972 \r
973                                                                                 for (var i=0; i<cells.length; i++) {\r
974                                                                                         if (td == cells[i]) {\r
975                                                                                                 rowCells[rowCells.length] = td;\r
976                                                                                         }\r
977                                                                                 }\r
978                                                                         }\r
979 \r
980                                                                         if (rowCells.length > 0)\r
981                                                                                 rows[rows.length] = rowCells;\r
982                                                                 }\r
983 \r
984                                                                 // Find selected cells in grid and box\r
985                                                                 var curRow = [];\r
986                                                                 var lastTR = null;\r
987                                                                 for (var y=0; y<grid.length; y++) {\r
988                                                                         for (var x=0; x<grid[y].length; x++) {\r
989                                                                                 grid[y][x]._selected = false;\r
990 \r
991                                                                                 for (var i=0; i<cells.length; i++) {\r
992                                                                                         if (grid[y][x] == cells[i]) {\r
993                                                                                                 // Get start pos\r
994                                                                                                 if (x1 == -1) {\r
995                                                                                                         x1 = x;\r
996                                                                                                         y1 = y;\r
997                                                                                                 }\r
998 \r
999                                                                                                 // Get end pos\r
1000                                                                                                 x2 = x;\r
1001                                                                                                 y2 = y;\r
1002 \r
1003                                                                                                 grid[y][x]._selected = true;\r
1004                                                                                         }\r
1005                                                                                 }\r
1006                                                                         }\r
1007                                                                 }\r
1008 \r
1009                                                                 // Is there gaps, if so deny\r
1010                                                                 for (var y=y1; y<=y2; y++) {\r
1011                                                                         for (var x=x1; x<=x2; x++) {\r
1012                                                                                 if (!grid[y][x]._selected) {\r
1013                                                                                         alert("Invalid selection for merge.");\r
1014                                                                                         return true;\r
1015                                                                                 }\r
1016                                                                         }\r
1017                                                                 }\r
1018                                                         }\r
1019 \r
1020                                                         // Validate selection and get total rowspan and colspan\r
1021                                                         var rowSpan = 1, colSpan = 1;\r
1022 \r
1023                                                         // Validate horizontal and get total colspan\r
1024                                                         var lastRowSpan = -1;\r
1025                                                         for (var y=0; y<rows.length; y++) {\r
1026                                                                 var rowColSpan = 0;\r
1027 \r
1028                                                                 for (var x=0; x<rows[y].length; x++) {\r
1029                                                                         var sd = getColRowSpan(rows[y][x]);\r
1030 \r
1031                                                                         rowColSpan += sd['colspan'];\r
1032 \r
1033                                                                         if (lastRowSpan != -1 && sd['rowspan'] != lastRowSpan) {\r
1034                                                                                 alert("Invalid selection for merge.");\r
1035                                                                                 return true;\r
1036                                                                         }\r
1037 \r
1038                                                                         lastRowSpan = sd['rowspan'];\r
1039                                                                 }\r
1040 \r
1041                                                                 if (rowColSpan > colSpan)\r
1042                                                                         colSpan = rowColSpan;\r
1043 \r
1044                                                                 lastRowSpan = -1;\r
1045                                                         }\r
1046 \r
1047                                                         // Validate vertical and get total rowspan\r
1048                                                         var lastColSpan = -1;\r
1049                                                         for (var x=0; x<rows[0].length; x++) {\r
1050                                                                 var colRowSpan = 0;\r
1051 \r
1052                                                                 for (var y=0; y<rows.length; y++) {\r
1053                                                                         var sd = getColRowSpan(rows[y][x]);\r
1054 \r
1055                                                                         colRowSpan += sd['rowspan'];\r
1056 \r
1057                                                                         if (lastColSpan != -1 && sd['colspan'] != lastColSpan) {\r
1058                                                                                 alert("Invalid selection for merge.");\r
1059                                                                                 return true;\r
1060                                                                         }\r
1061 \r
1062                                                                         lastColSpan = sd['colspan'];\r
1063                                                                 }\r
1064 \r
1065                                                                 if (colRowSpan > rowSpan)\r
1066                                                                         rowSpan = colRowSpan;\r
1067 \r
1068                                                                 lastColSpan = -1;\r
1069                                                         }\r
1070 \r
1071                                                         // Setup td\r
1072                                                         tdElm = rows[0][0];\r
1073                                                         tdElm.rowSpan = rowSpan;\r
1074                                                         tdElm.colSpan = colSpan;\r
1075 \r
1076                                                         // Merge cells\r
1077                                                         for (var y=0; y<rows.length; y++) {\r
1078                                                                 for (var x=0; x<rows[y].length; x++) {\r
1079                                                                         var html = rows[y][x].innerHTML;\r
1080                                                                         var chk = html.replace(/[ \t\r\n]/g, "");\r
1081 \r
1082                                                                         if (chk != "<br/>" && chk != "<br>" && chk != '<br mce_bogus="1"/>' && (x+y > 0))\r
1083                                                                                 tdElm.innerHTML += html;\r
1084 \r
1085                                                                         // Not current cell\r
1086                                                                         if (rows[y][x] != tdElm && !rows[y][x]._deleted) {\r
1087                                                                                 var cpos = getCellPos(grid, rows[y][x]);\r
1088                                                                                 var tr = rows[y][x].parentNode;\r
1089 \r
1090                                                                                 tr.removeChild(rows[y][x]);\r
1091                                                                                 rows[y][x]._deleted = true;\r
1092 \r
1093                                                                                 // Empty TR, remove it\r
1094                                                                                 if (!tr.hasChildNodes()) {\r
1095                                                                                         tr.parentNode.removeChild(tr);\r
1096 \r
1097                                                                                         var lastCell = null;\r
1098                                                                                         for (var x=0; cellElm = getCell(grid, cpos.rowindex, x); x++) {\r
1099                                                                                                 if (cellElm != lastCell && cellElm.rowSpan > 1)\r
1100                                                                                                         cellElm.rowSpan--;\r
1101 \r
1102                                                                                                 lastCell = cellElm;\r
1103                                                                                         }\r
1104 \r
1105                                                                                         if (tdElm.rowSpan > 1)\r
1106                                                                                                 tdElm.rowSpan--;\r
1107                                                                                 }\r
1108                                                                         }\r
1109                                                                 }\r
1110                                                         }\r
1111 \r
1112                                                         // Remove all but one bogus br\r
1113                                                         each(ed.dom.select('br', tdElm), function(e, i) {\r
1114                                                                 if (i > 0 && ed.dom.getAttrib(e, 'mce_bogus'))\r
1115                                                                         ed.dom.remove(e);\r
1116                                                         });\r
1117 \r
1118                                                         break;\r
1119                                                 }\r
1120 \r
1121                                                 tableElm = inst.dom.getParent(inst.selection.getNode(), "table");\r
1122                                                 inst.addVisual(tableElm);\r
1123                                                 inst.nodeChanged();\r
1124                                         }\r
1125 \r
1126                                 return true;\r
1127                         }\r
1128 \r
1129                         // Pass to next handler in chain\r
1130                         return false;\r
1131                 }\r
1132         });\r
1133 \r
1134         // Register plugin\r
1135         tinymce.PluginManager.add('table', tinymce.plugins.TablePlugin);\r
1136 })();