]> git.donarmstrong.com Git - roundcube.git/blobdiff - program/js/tiny_mce/plugins/table/editor_plugin_src.js
Imported Upstream version 0.5.2+dfsg
[roundcube.git] / program / js / tiny_mce / plugins / table / editor_plugin_src.js
index c2f307f045c2a4c3c5befb0176db93a3ce40c6b1..442e465c43a31db6ef418bdaa087c030489e7ecf 100644 (file)
 (function(tinymce) {\r
        var each = tinymce.each;\r
 \r
+       // Checks if the selection/caret is at the start of the specified block element\r
+       function isAtStart(rng, par) {\r
+               var doc = par.ownerDocument, rng2 = doc.createRange(), elm;\r
+\r
+               rng2.setStartBefore(par);\r
+               rng2.setEnd(rng.endContainer, rng.endOffset);\r
+\r
+               elm = doc.createElement('body');\r
+               elm.appendChild(rng2.cloneContents());\r
+\r
+               // Check for text characters of other elements that should be treated as content\r
+               return elm.innerHTML.replace(/<(br|img|object|embed|input|textarea)[^>]*>/gi, '-').replace(/<[^>]+>/g, '').length == 0;\r
+       };\r
+\r
        /**\r
         * Table Grid class.\r
         */\r
                        grid = [];\r
 \r
                        each(['thead', 'tbody', 'tfoot'], function(part) {\r
-                               var rows = dom.select(part + ' tr', table);\r
+                               var rows = dom.select('> ' + part + ' tr', table);\r
 \r
                                each(rows, function(tr, y) {\r
                                        y += startY;\r
 \r
-                                       each(dom.select('td,th', tr), function(td, x) {\r
+                                       each(dom.select('> td, > th', tr), function(td, x) {\r
                                                var x2, y2, rowspan, colspan;\r
 \r
                                                // Skip over existing cells produced by rowspan\r
                        return parseInt(td.getAttribute(name) || 1);\r
                };\r
 \r
+               function setSpanVal(td, name, val) {\r
+                       if (td) {\r
+                               val = parseInt(val);\r
+\r
+                               if (val === 1)\r
+                                       td.removeAttribute(name, 1);\r
+                               else\r
+                                       td.setAttribute(name, val, 1);\r
+                       }\r
+               }\r
+\r
                function isCellSelected(cell) {\r
-                       return dom.hasClass(cell.elm, 'mceSelected') || cell == selectedCell;\r
+                       return cell && (dom.hasClass(cell.elm, 'mceSelected') || cell == selectedCell);\r
                };\r
 \r
                function getSelectedRows() {\r
 \r
                                        // Add something to the inner node\r
                                        if (curNode)\r
-                                               curNode.innerHTML = tinymce.isIE ? '&nbsp;' : '<br _mce_bogus="1" />';\r
+                                               curNode.innerHTML = tinymce.isIE ? '&nbsp;' : '<br data-mce-bogus="1" />';\r
 \r
                                        return false;\r
                                }\r
                        }, 'childNodes');\r
 \r
                        cell = cloneNode(cell, false);\r
-                       cell.rowSpan = cell.colSpan = 1;\r
+                       setSpanVal(cell, 'rowSpan', 1);\r
+                       setSpanVal(cell, 'colSpan', 1);\r
 \r
                        if (formatNode) {\r
                                cell.appendChild(formatNode);\r
                        } else {\r
                                if (!tinymce.isIE)\r
-                                       cell.innerHTML = '<br _mce_bogus="1" />';\r
+                                       cell.innerHTML = '<br data-mce-bogus="1" />';\r
                        }\r
 \r
                        return cell;\r
                                                rowSpan = getSpanVal(cell, 'rowspan');\r
 \r
                                                if (colSpan > 1 || rowSpan > 1) {\r
-                                                       cell.colSpan = cell.rowSpan = 1;\r
+                                                       setSpanVal(cell, 'rowSpan', 1);\r
+                                                       setSpanVal(cell, 'colSpan', 1);\r
 \r
                                                        // Insert cells right\r
                                                        for (i = 0; i < colSpan - 1; i++)\r
                };\r
 \r
                function merge(cell, cols, rows) {\r
-                       var startX, startY, endX, endY, x, y, startCell, endCell, cell, children;\r
+                       var startX, startY, endX, endY, x, y, startCell, endCell, cell, children, count;\r
 \r
                        // Use specified cell and cols/rows\r
                        if (cell) {\r
 \r
                                // Set row/col span to start cell\r
                                startCell = getCell(startX, startY).elm;\r
-                               startCell.colSpan = (endX - startX) + 1;\r
-                               startCell.rowSpan = (endY - startY) + 1;\r
+                               setSpanVal(startCell, 'colSpan', (endX - startX) + 1);\r
+                               setSpanVal(startCell, 'rowSpan', (endY - startY) + 1);\r
 \r
                                // Remove other cells and add it's contents to the start cell\r
                                for (y = startY; y <= endY; y++) {\r
                                        for (x = startX; x <= endX; x++) {\r
+                                               if (!grid[y] || !grid[y][x])\r
+                                                       continue;\r
+\r
                                                cell = grid[y][x].elm;\r
 \r
                                                if (cell != startCell) {\r
                                                        // Move children to startCell\r
                                                        children = tinymce.grep(cell.childNodes);\r
-                                                       each(children, function(node, i) {\r
-                                                               // Jump over last BR element\r
-                                                               if (node.nodeName != 'BR' || i != children.length - 1)\r
-                                                                       startCell.appendChild(node);\r
+                                                       each(children, function(node) {\r
+                                                               startCell.appendChild(node);\r
                                                        });\r
 \r
+                                                       // Remove bogus nodes if there is children in the target cell\r
+                                                       if (children.length) {\r
+                                                               children = tinymce.grep(startCell.childNodes);\r
+                                                               count = 0;\r
+                                                               each(children, function(node) {\r
+                                                                       if (node.nodeName == 'BR' && dom.getAttrib(node, 'data-mce-bogus') && count++ < children.length - 1)\r
+                                                                               startCell.removeChild(node);\r
+                                                               });\r
+                                                       }\r
+                                                       \r
                                                        // Remove cell\r
                                                        dom.remove(cell);\r
                                                }\r
                };\r
 \r
                function insertRow(before) {\r
-                       var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell;\r
+                       var posY, cell, lastCell, x, rowElm, newRow, newCell, otherCell, rowSpan;\r
 \r
                        // Find first/last row\r
                        each(grid, function(row, y) {\r
                        });\r
 \r
                        for (x = 0; x < grid[0].length; x++) {\r
+                               // Cell not found could be because of an invalid table structure\r
+                               if (!grid[posY][x])\r
+                                       continue;\r
+\r
                                cell = grid[posY][x].elm;\r
 \r
                                if (cell != lastCell) {\r
                                        if (!before) {\r
                                                rowSpan = getSpanVal(cell, 'rowspan');\r
                                                if (rowSpan > 1) {\r
-                                                       cell.rowSpan = rowSpan + 1;\r
+                                                       setSpanVal(cell, 'rowSpan', rowSpan + 1);\r
                                                        continue;\r
                                                }\r
                                        } else {\r
                                                // Check if cell above can be expanded\r
                                                if (posY > 0 && grid[posY - 1][x]) {\r
                                                        otherCell = grid[posY - 1][x].elm;\r
-                                                       rowSpan = getSpanVal(otherCell, 'rowspan');\r
+                                                       rowSpan = getSpanVal(otherCell, 'rowSpan');\r
                                                        if (rowSpan > 1) {\r
-                                                               otherCell.rowSpan = rowSpan + 1;\r
+                                                               setSpanVal(otherCell, 'rowSpan', rowSpan + 1);\r
                                                                continue;\r
                                                        }\r
                                                }\r
                                        }\r
 \r
                                        // Insert new cell into new row\r
-                                       newCell = cloneCell(cell)\r
-                                       newCell.colSpan = cell.colSpan;\r
+                                       newCell = cloneCell(cell);\r
+                                       setSpanVal(newCell, 'colSpan', cell.colSpan);\r
+\r
                                        newRow.appendChild(newCell);\r
 \r
                                        lastCell = cell;\r
                        });\r
 \r
                        each(grid, function(row, y) {\r
-                               var cell = row[posX].elm, rowSpan, colSpan;\r
+                               var cell, rowSpan, colSpan;\r
+\r
+                               if (!row[posX])\r
+                                       return;\r
 \r
+                               cell = row[posX].elm;\r
                                if (cell != lastCell) {\r
                                        colSpan = getSpanVal(cell, 'colspan');\r
                                        rowSpan = getSpanVal(cell, 'rowspan');\r
                                                        fillLeftDown(posX, y, rowSpan - 1, colSpan);\r
                                                }\r
                                        } else\r
-                                               cell.colSpan++;\r
+                                               setSpanVal(cell, 'colSpan', cell.colSpan + 1);\r
 \r
                                        lastCell = cell;\r
                                }\r
                                                each(grid, function(row) {\r
                                                        var cell = row[x].elm, colSpan;\r
 \r
-                                                       colSpan = getSpanVal(cell, 'colspan');\r
+                                                       colSpan = getSpanVal(cell, 'colSpan');\r
 \r
                                                        if (colSpan > 1)\r
-                                                               cell.colSpan = colSpan - 1;\r
+                                                               setSpanVal(cell, 'colSpan', colSpan - 1);\r
                                                        else\r
                                                                dom.remove(cell);\r
                                                });\r
 \r
                                // Move down row spanned cells\r
                                each(tr.cells, function(cell) {\r
-                                       var rowSpan = getSpanVal(cell, 'rowspan');\r
+                                       var rowSpan = getSpanVal(cell, 'rowSpan');\r
 \r
                                        if (rowSpan > 1) {\r
-                                               cell.rowSpan = rowSpan - 1;\r
+                                               setSpanVal(cell, 'rowSpan', rowSpan - 1);\r
                                                pos = getPos(cell);\r
                                                fillLeftDown(pos.x, pos.y, 1, 1);\r
                                        }\r
                                        cell = cell.elm;\r
 \r
                                        if (cell != lastCell) {\r
-                                               rowSpan = getSpanVal(cell, 'rowspan');\r
+                                               rowSpan = getSpanVal(cell, 'rowSpan');\r
 \r
                                                if (rowSpan <= 1)\r
                                                        dom.remove(cell);\r
                                                else\r
-                                                       cell.rowSpan = rowSpan - 1;\r
+                                                       setSpanVal(cell, 'rowSpan', rowSpan - 1);\r
 \r
                                                lastCell = cell;\r
                                        }\r
                                // Remove col/rowspans\r
                                for (i = 0; i < cellCount; i++) {\r
                                        cell = row.cells[i];\r
-                                       cell.colSpan = cell.rowSpan = 1;\r
+                                       setSpanVal(cell, 'colSpan', 1);\r
+                                       setSpanVal(cell, 'rowSpan', 1);\r
                                }\r
 \r
                                // Needs more cells\r
 \r
                                // Add new selection\r
                                for (y = startY; y <= maxY; y++) {\r
-                                       for (x = startX; x <= maxX; x++)\r
-                                               dom.addClass(grid[y][x].elm, 'mceSelected');\r
+                                       for (x = startX; x <= maxX; x++) {\r
+                                               if (grid[y][x])\r
+                                                       dom.addClass(grid[y][x].elm, 'mceSelected');\r
+                                       }\r
                                }\r
                        }\r
                };\r
                                ed.onClick.add(function(ed, e) {\r
                                        e = e.target;\r
 \r
-                                       if (e.nodeName === 'TABLE')\r
+                                       if (e.nodeName === 'TABLE') {\r
                                                ed.selection.select(e);\r
+                                               ed.nodeChanged();\r
+                                       }\r
                                });\r
                        }\r
 \r
+                       ed.onPreProcess.add(function(ed, args) {\r
+                               var nodes, i, node, dom = ed.dom, value;\r
+\r
+                               nodes = dom.select('table', args.node);\r
+                               i = nodes.length;\r
+                               while (i--) {\r
+                                       node = nodes[i];\r
+                                       dom.setAttrib(node, 'data-mce-style', '');\r
+\r
+                                       if ((value = dom.getAttrib(node, 'width'))) {\r
+                                               dom.setStyle(node, 'width', value);\r
+                                               dom.setAttrib(node, 'width', '');\r
+                                       }\r
+\r
+                                       if ((value = dom.getAttrib(node, 'height'))) {\r
+                                               dom.setStyle(node, 'height', value);\r
+                                               dom.setAttrib(node, 'height', '');\r
+                                       }\r
+                               }\r
+                       });\r
+\r
                        // Handle node change updates\r
                        ed.onNodeChange.add(function(ed, cm, n) {\r
                                var p;\r
                                                // Remove current selection\r
                                                sel = ed.selection.getSel();\r
 \r
-                                               if (sel.removeAllRanges)\r
-                                                       sel.removeAllRanges();\r
-                                               else\r
-                                                       sel.empty();\r
+                                               try {\r
+                                                       if (sel.removeAllRanges)\r
+                                                               sel.removeAllRanges();\r
+                                                       else\r
+                                                               sel.empty();\r
+                                               } catch (ex) {\r
+                                                       // IE9 might throw errors here\r
+                                               }\r
 \r
                                                e.preventDefault();\r
                                        }\r