vendor/assets/javascripts/simditor/simditor.js in simditor-2.1.11.0 vs vendor/assets/javascripts/simditor/simditor.js in simditor-2.1.13.0

- old
+ new

@@ -1,9 +1,9 @@ /*! -* Simditor v2.1.11 +* Simditor v2.1.13 * http://simditor.tower.im/ -* 2015-20-05 +* 2015-09-06 */ (function (root, factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module unless amdModuleId is set define('simditor', ["jquery","simple-module","simple-hotkeys","simple-uploader"], function ($, SimpleModule, simpleHotkeys, simpleUploader) { @@ -320,16 +320,17 @@ allowedAttributes: null }; Formatter.prototype._init = function() { this.editor = this._module; - this._allowedTags = this.opts.allowedTags || ['br', 'a', 'img', 'b', 'strong', 'i', 'u', 'font', 'p', 'ul', 'ol', 'li', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'hr']; + this._allowedTags = this.opts.allowedTags || ['br', 'a', 'img', 'b', 'strong', 'i', 'u', 'font', 'p', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'h1', 'h2', 'h3', 'h4', 'hr']; this._allowedAttributes = this.opts.allowedAttributes || { img: ['src', 'alt', 'width', 'height', 'data-image-src', 'data-image-size', 'data-image-name', 'data-non-image'], a: ['href', 'target'], font: ['color'], - pre: ['data-lang', 'class'], + pre: ['data-lang'], + code: ['class'], p: ['data-indent', 'data-align'], h1: ['data-indent'], h2: ['data-indent'], h3: ['data-indent'], h4: ['data-indent'] @@ -678,11 +679,11 @@ e.preventDefault(); _this.editor.selection.sel.modify('move', 'forward', 'lineboundary'); return false; }; })(this)); - this.addShortcut('cmd+a', (function(_this) { + this.addShortcut((this.editor.util.os.mac ? 'cmd+a' : 'ctrl+a'), (function(_this) { return function(e) { var $children, firstBlock, lastBlock, range; $children = _this.editor.body.children(); if (!($children.length > 0)) { return; @@ -2064,11 +2065,11 @@ })(this)); return result; }; Indentation.prototype.indentBlock = function(blockEl) { - var $blockEl, $childList, $nextTd, $parentLi, $pre, $td, indentLevel, range, tagName; + var $blockEl, $childList, $nextTd, $nextTr, $parentLi, $pre, $td, $tr, indentLevel, range, tagName; $blockEl = $(blockEl); if (!$blockEl.length) { return; } if ($blockEl.is('pre')) { @@ -2096,14 +2097,19 @@ indentLevel = $blockEl.attr('data-indent') || 0; indentLevel = Math.min(indentLevel * 1 + 1, 10); $blockEl.attr('data-indent', indentLevel); } else if ($blockEl.is('table') || $blockEl.is('.simditor-table')) { range = this.editor.selection.getRange(); - $td = $(range.commonAncestorContainer).closest('td'); - $nextTd = $td.next('td'); + $td = $(range.commonAncestorContainer).closest('td, th'); + $nextTd = $td.next('td, th'); if (!($nextTd.length > 0)) { - $nextTd = $td.parent('tr').next('tr').find('td:first'); + $tr = $td.parent('tr'); + $nextTr = $tr.next('tr'); + if ($nextTr.length < 1 && $tr.parent().is('thead')) { + $nextTr = $tr.parent('thead').next('tbody').find('tr:first'); + } + $nextTd = $nextTr.find('td:first, th:first'); } if (!($td.length > 0 && $nextTd.length > 0)) { return false; } this.editor.selection.setRangeAtEndOf($nextTd); @@ -2124,11 +2130,11 @@ return this.editor.selection.setRangeAfter(textNode); } }; Indentation.prototype.outdentBlock = function(blockEl) { - var $blockEl, $parent, $parentLi, $pre, $prevTd, $td, button, indentLevel, range, ref; + var $blockEl, $parent, $parentLi, $pre, $prevTd, $prevTr, $td, $tr, button, indentLevel, range, ref; $blockEl = $(blockEl); if (!($blockEl && $blockEl.length > 0)) { return; } if ($blockEl.is('pre')) { @@ -2164,14 +2170,19 @@ indentLevel = 0; } $blockEl.attr('data-indent', indentLevel); } else if ($blockEl.is('table') || $blockEl.is('.simditor-table')) { range = this.editor.selection.getRange(); - $td = $(range.commonAncestorContainer).closest('td'); - $prevTd = $td.prev('td'); + $td = $(range.commonAncestorContainer).closest('td, th'); + $prevTd = $td.prev('td, th'); if (!($prevTd.length > 0)) { - $prevTd = $td.parent('tr').prev('tr').find('td:last'); + $tr = $td.parent('tr'); + $prevTr = $tr.prev('tr'); + if ($prevTr.length < 1 && $tr.parent().is('tbody')) { + $prevTr = $tr.parent('tbody').prev('thead').find('tr:first'); + } + $prevTd = $prevTr.find('td:last, th:last'); } if (!($td.length > 0 && $prevTd.length > 0)) { return; } this.editor.selection.setRangeAtEndOf($prevTd); @@ -2446,14 +2457,15 @@ 'insertColumnRight': '在右边插入列', 'deleteTable': '删除表格', 'title': '标题', 'normalText': '普通文本', 'underline': '下划线文字', - 'alignment': '排版', + 'alignment': '水平对齐', 'alignCenter': '居中', 'alignLeft': '居左', - 'alignRight': '居右' + 'alignRight': '居右', + 'selectLanguage': '选择程序语言' } }; Button = (function(superClass) { extend(Button, superClass); @@ -3496,25 +3508,29 @@ } return result; }; CodeButton.prototype.decorate = function($pre) { - var lang; - lang = $pre.attr('data-lang'); - $pre.removeClass(); - if (lang && lang !== -1) { - return $pre.addClass('lang-' + lang); + var $code, lang, ref, ref1; + $code = $pre.find('> code'); + if ($code.length > 0) { + lang = (ref = $code.attr('class')) != null ? (ref1 = ref.match(/lang-(\S+)/)) != null ? ref1[1] : void 0 : void 0; + $code.contents().unwrap(); + if (lang) { + return $pre.attr('data-lang', lang); + } } }; CodeButton.prototype.undecorate = function($pre) { - var lang; + var $code, lang; lang = $pre.attr('data-lang'); - $pre.removeClass(); + $code = $('<code/>'); if (lang && lang !== -1) { - return $pre.addClass('lang-' + lang); + $code.addClass('lang-' + lang); } + return $pre.wrapInner($code).removeAttr('data-lang'); }; CodeButton.prototype.command = function() { var $contents, $endBlock, $startBlock, endNode, j, len, node, range, ref, results, startNode; range = this.editor.selection.getRange(); @@ -3579,23 +3595,21 @@ function CodePopover() { return CodePopover.__super__.constructor.apply(this, arguments); } - CodePopover.prototype._tpl = "<div class=\"code-settings\">\n <div class=\"settings-field\">\n <select class=\"select-lang\">\n <option value=\"-1\">选择程序语言</option>\n <option value=\"bash\">Bash</option>\n <option value=\"c++\">C++</option>\n <option value=\"cs\">C#</option>\n <option value=\"css\">CSS</option>\n <option value=\"erlang\">Erlang</option>\n <option value=\"less\">Less</option>\n <option value=\"scss\">Sass</option>\n <option value=\"diff\">Diff</option>\n <option value=\"coffeeScript\">CoffeeScript</option>\n <option value=\"html\">Html,XML</option>\n <option value=\"json\">JSON</option>\n <option value=\"java\">Java</option>\n <option value=\"js\">JavaScript</option>\n <option value=\"markdown\">Markdown</option>\n <option value=\"oc\">Objective C</option>\n <option value=\"php\">PHP</option>\n <option value=\"perl\">Perl</option>\n <option value=\"python\">Python</option>\n <option value=\"ruby\">Ruby</option>\n <option value=\"sql\">SQL</option>\n </select>\n </div>\n</div>"; - CodePopover.prototype.render = function() { + this._tpl = "<div class=\"code-settings\">\n <div class=\"settings-field\">\n <select class=\"select-lang\">\n <option value=\"-1\">" + (this._t('selectLanguage')) + "</option>\n <option value=\"bash\">Bash</option>\n <option value=\"c++\">C++</option>\n <option value=\"cs\">C#</option>\n <option value=\"css\">CSS</option>\n <option value=\"erlang\">Erlang</option>\n <option value=\"less\">Less</option>\n <option value=\"scss\">Sass</option>\n <option value=\"diff\">Diff</option>\n <option value=\"coffeeScript\">CoffeeScript</option>\n <option value=\"html\">Html,XML</option>\n <option value=\"json\">JSON</option>\n <option value=\"java\">Java</option>\n <option value=\"js\">JavaScript</option>\n <option value=\"markdown\">Markdown</option>\n <option value=\"oc\">Objective C</option>\n <option value=\"php\">PHP</option>\n <option value=\"perl\">Perl</option>\n <option value=\"python\">Python</option>\n <option value=\"ruby\">Ruby</option>\n <option value=\"sql\">SQL</option>\n </select>\n </div>\n</div>"; this.el.addClass('code-popover').append(this._tpl); this.selectEl = this.el.find('.select-lang'); this.selectEl.on('change', (function(_this) { return function(e) { var selected; _this.lang = _this.selectEl.val(); selected = _this.target.hasClass('selected'); _this.target.removeClass().removeAttr('data-lang'); if (_this.lang !== -1) { - _this.target.addClass('lang-' + _this.lang); _this.target.attr('data-lang', _this.lang); } if (selected) { return _this.target.addClass('selected'); } @@ -4579,11 +4593,11 @@ TableButton.prototype.menu = true; TableButton.prototype._init = function() { TableButton.__super__._init.call(this); - $.merge(this.editor.formatter._allowedTags, ['tbody', 'tr', 'td', 'colgroup', 'col']); + $.merge(this.editor.formatter._allowedTags, ['thead', 'th', 'tbody', 'tr', 'td', 'colgroup', 'col']); $.extend(this.editor.formatter._allowedAttributes, { td: ['rowspan', 'colspan'], col: ['width'] }); this._initShortcuts(); @@ -4602,95 +4616,127 @@ }; })(this)); this.editor.on('selectionchanged.table', (function(_this) { return function(e) { var $container, range; - _this.editor.body.find('.simditor-table td').removeClass('active'); + _this.editor.body.find('.simditor-table td, .simditor-table th').removeClass('active'); range = _this.editor.selection.getRange(); if (range == null) { return; } $container = $(range.commonAncestorContainer); if (range.collapsed && $container.is('.simditor-table')) { if (_this.editor.selection.rangeAtStartOf($container)) { - $container = $container.find('td:first'); + $container = $container.find('th:first'); } else { $container = $container.find('td:last'); } _this.editor.selection.setRangeAtEndOf($container); } - return $container.closest('td', _this.editor.body).addClass('active'); + return $container.closest('td, th', _this.editor.body).addClass('active'); }; })(this)); this.editor.on('blur.table', (function(_this) { return function(e) { - return _this.editor.body.find('.simditor-table td').removeClass('active'); + return _this.editor.body.find('.simditor-table td, .simditor-table th').removeClass('active'); }; })(this)); this.editor.inputManager.addKeystrokeHandler('38', 'td', (function(_this) { return function(e, $node) { - var $prevTr, $tr, index; - $tr = $node.parent('tr'); - $prevTr = $tr.prev('tr'); - if (!($prevTr.length > 0)) { - return true; - } - index = $tr.find('td').index($node); - _this.editor.selection.setRangeAtEndOf($prevTr.find('td').eq(index)); + _this._tdNav($node, 'up'); return true; }; })(this)); - return this.editor.inputManager.addKeystrokeHandler('40', 'td', (function(_this) { + this.editor.inputManager.addKeystrokeHandler('38', 'th', (function(_this) { return function(e, $node) { - var $nextTr, $tr, index; - $tr = $node.parent('tr'); - $nextTr = $tr.next('tr'); - if (!($nextTr.length > 0)) { - return true; - } - index = $tr.find('td').index($node); - _this.editor.selection.setRangeAtEndOf($nextTr.find('td').eq(index)); + _this._tdNav($node, 'up'); return true; }; })(this)); + this.editor.inputManager.addKeystrokeHandler('40', 'td', (function(_this) { + return function(e, $node) { + _this._tdNav($node, 'down'); + return true; + }; + })(this)); + return this.editor.inputManager.addKeystrokeHandler('40', 'th', (function(_this) { + return function(e, $node) { + _this._tdNav($node, 'down'); + return true; + }; + })(this)); }; + TableButton.prototype._tdNav = function($td, direction) { + var $anotherTr, $tr, action, anotherTag, index, parentTag, ref; + if (direction == null) { + direction = 'up'; + } + action = direction === 'up' ? 'prev' : 'next'; + ref = direction === 'up' ? ['tbody', 'thead'] : ['thead', 'tbody'], parentTag = ref[0], anotherTag = ref[1]; + $tr = $td.parent('tr'); + $anotherTr = this["_" + action + "Row"]($tr); + if (!($anotherTr.length > 0)) { + return true; + } + index = $tr.find('td, th').index($td); + return this.editor.selection.setRangeAtEndOf($anotherTr.find('td, th').eq(index)); + }; + + TableButton.prototype._nextRow = function($tr) { + var $nextTr; + $nextTr = $tr.next('tr'); + if ($nextTr.length < 1 && $tr.parent('thead').length > 0) { + $nextTr = $tr.parent('thead').next('tbody').find('tr:first'); + } + return $nextTr; + }; + + TableButton.prototype._prevRow = function($tr) { + var $prevTr; + $prevTr = $tr.prev('tr'); + if ($prevTr.length < 1 && $tr.parent('tbody').length > 0) { + $prevTr = $tr.parent('tbody').prev('thead').find('tr'); + } + return $prevTr; + }; + TableButton.prototype.initResize = function($table) { var $colgroup, $resizeHandle, $wrapper; $wrapper = $table.parent('.simditor-table'); $colgroup = $table.find('colgroup'); if ($colgroup.length < 1) { $colgroup = $('<colgroup/>').prependTo($table); - $table.find('tr:first td').each((function(_this) { + $table.find('thead tr th').each((function(_this) { return function(i, td) { var $col; return $col = $('<col/>').appendTo($colgroup); }; })(this)); this.refreshTableWidth($table); } $resizeHandle = $('<div class="simditor-resize-handle" contenteditable="false"></div>').appendTo($wrapper); - $wrapper.on('mousemove', 'td', (function(_this) { + $wrapper.on('mousemove', 'td, th', (function(_this) { return function(e) { var $col, $td, index, ref, ref1, x; if ($wrapper.hasClass('resizing')) { return; } $td = $(e.currentTarget); x = e.pageX - $(e.currentTarget).offset().left; if (x < 5 && $td.prev().length > 0) { $td = $td.prev(); } - if ($td.next('td').length < 1) { + if ($td.next('td, th').length < 1) { $resizeHandle.hide(); return; } if ((ref = $resizeHandle.data('td')) != null ? ref.is($td) : void 0) { $resizeHandle.show(); return; } - index = $td.parent().find('td').index($td); + index = $td.parent().find('td, th').index($td); $col = $colgroup.find('col').eq(index); if ((ref1 = $resizeHandle.data('col')) != null ? ref1.is($col) : void 0) { $resizeHandle.show(); return; } @@ -4706,11 +4752,11 @@ return function(e) { var $handle, $leftCol, $leftTd, $rightCol, $rightTd, minWidth, startHandleLeft, startLeftWidth, startRightWidth, startX, tableWidth; $handle = $(e.currentTarget); $leftTd = $handle.data('td'); $leftCol = $handle.data('col'); - $rightTd = $leftTd.next('td'); + $rightTd = $leftTd.next('td, th'); $rightCol = $leftCol.next('col'); startX = e.pageX; startLeftWidth = $leftTd.outerWidth() * 1; startRightWidth = $rightTd.outerWidth() * 1; startHandleLeft = parseFloat($handle.css('left')); @@ -4786,63 +4832,73 @@ } return $table.parent().replaceWith($table); }; TableButton.prototype.renderMenu = function() { + var $table; $("<div class=\"menu-create-table\">\n</div>\n<div class=\"menu-edit-table\">\n <ul>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"deleteRow\"><span>" + (this._t('deleteRow')) + "</span></a></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"insertRowAbove\"><span>" + (this._t('insertRowAbove')) + " ( Ctrl + Alt + ↑ )</span></a></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"insertRowBelow\"><span>" + (this._t('insertRowBelow')) + " ( Ctrl + Alt + ↓ )</span></a></li>\n <li><span class=\"separator\"></span></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"deleteCol\"><span>" + (this._t('deleteColumn')) + "</span></a></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"insertColLeft\"><span>" + (this._t('insertColumnLeft')) + " ( Ctrl + Alt + ← )</span></a></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"insertColRight\"><span>" + (this._t('insertColumnRight')) + " ( Ctrl + Alt + → )</span></a></li>\n <li><span class=\"separator\"></span></li>\n <li><a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\" href=\"javascript:;\" data-param=\"deleteTable\"><span>" + (this._t('deleteTable')) + "</span></a></li>\n </ul>\n</div>").appendTo(this.menuWrapper); this.createMenu = this.menuWrapper.find('.menu-create-table'); this.editMenu = this.menuWrapper.find('.menu-edit-table'); - this.createTable(6, 6).appendTo(this.createMenu); - this.createMenu.on('mouseenter', 'td', (function(_this) { + $table = this.createTable(6, 6).appendTo(this.createMenu); + this.createMenu.on('mouseenter', 'td, th', (function(_this) { return function(e) { - var $td, $tr, num; - _this.createMenu.find('td').removeClass('selected'); + var $td, $tr, $trs, num; + _this.createMenu.find('td, th').removeClass('selected'); $td = $(e.currentTarget); $tr = $td.parent(); - num = $tr.find('td').index($td) + 1; - return $tr.prevAll('tr').addBack().find('td:lt(' + num + ')').addClass('selected'); + num = $tr.find('td, th').index($td) + 1; + $trs = $tr.prevAll('tr').addBack(); + if ($tr.parent().is('tbody')) { + $trs = $trs.add($table.find('thead tr')); + } + return $trs.find("td:lt(" + num + "), th:lt(" + num + ")").addClass('selected'); }; })(this)); this.createMenu.on('mouseleave', (function(_this) { return function(e) { - return $(e.currentTarget).find('td').removeClass('selected'); + return $(e.currentTarget).find('td, th').removeClass('selected'); }; })(this)); - return this.createMenu.on('mousedown', 'td', (function(_this) { + return this.createMenu.on('mousedown', 'td, th', (function(_this) { return function(e) { - var $closestBlock, $table, $td, $tr, colNum, rowNum; + var $closestBlock, $td, $tr, colNum, rowNum; _this.wrapper.removeClass('menu-on'); if (!_this.editor.inputManager.focused) { return; } $td = $(e.currentTarget); $tr = $td.parent(); colNum = $tr.find('td').index($td) + 1; rowNum = $tr.prevAll('tr').length + 1; + if ($tr.parent().is('tbody')) { + rowNum += 1; + } $table = _this.createTable(rowNum, colNum, true); $closestBlock = _this.editor.util.closestBlockEl(); if (_this.editor.util.isEmptyNode($closestBlock)) { $closestBlock.replaceWith($table); } else { $closestBlock.after($table); } _this.decorate($table); - _this.editor.selection.setRangeAtStartOf($table.find('td:first')); + _this.editor.selection.setRangeAtStartOf($table.find('th:first')); _this.editor.trigger('valuechanged'); return false; }; })(this)); }; TableButton.prototype.createTable = function(row, col, phBr) { - var $table, $tbody, $td, $tr, c, j, k, r, ref, ref1; + var $table, $tbody, $td, $thead, $tr, c, j, k, r, ref, ref1; $table = $('<table/>'); + $thead = $('<thead/>').appendTo($table); $tbody = $('<tbody/>').appendTo($table); for (r = j = 0, ref = row; 0 <= ref ? j < ref : j > ref; r = 0 <= ref ? ++j : --j) { - $tr = $('<tr/>').appendTo($tbody); + $tr = $('<tr/>'); + $tr.appendTo(r === 0 ? $thead : $tbody); for (c = k = 0, ref1 = col; 0 <= ref1 ? k < ref1 : k > ref1; c = 0 <= ref1 ? ++k : --k) { - $td = $('<td/>').appendTo($tr); + $td = $(r === 0 ? '<th/>' : '<td/>').appendTo($tr); if (phBr) { $td.append(this.editor.util.phBr); } } } @@ -4851,11 +4907,11 @@ TableButton.prototype.refreshTableWidth = function($table) { var cols, tableWidth; tableWidth = $table.width(); cols = $table.find('col'); - return $table.find('tr:first td').each((function(_this) { + return $table.find('thead tr th').each((function(_this) { return function(i, td) { var $col; $col = cols.eq(i); return $col.attr('width', ($(td).outerWidth() / tableWidth * 100) + '%'); }; @@ -4871,28 +4927,42 @@ this.createMenu.show(); return this.editMenu.hide(); } }; + TableButton.prototype._changeCellTag = function($tr, tagName) { + return $tr.find('td, th').each((function(_this) { + return function(i, cell) { + var $cell; + $cell = $(cell); + return $cell.replaceWith("<" + tagName + ">" + ($cell.html()) + "</" + tagName + ">"); + }; + })(this)); + }; + TableButton.prototype.deleteRow = function($td) { var $newTr, $tr, index; $tr = $td.parent('tr'); - if ($tr.siblings('tr').length < 1) { + if ($tr.closest('table').find('tr').length < 1) { return this.deleteTable($td); } else { - $newTr = $tr.next('tr'); + $newTr = this._nextRow($tr); if (!($newTr.length > 0)) { - $newTr = $tr.prev('tr'); + $newTr = this._prevRow($tr); } - index = $tr.find('td').index($td); + index = $tr.find('td, th').index($td); + if ($tr.parent().is('thead')) { + $newTr.appendTo($tr.parent()); + this._changeCellTag($newTr, 'th'); + } $tr.remove(); - return this.editor.selection.setRangeAtEndOf($newTr.find('td').eq(index)); + return this.editor.selection.setRangeAtEndOf($newTr.find('td, th').eq(index)); } }; TableButton.prototype.insertRow = function($td, direction) { - var $newTr, $table, $tr, colNum, i, index, j, ref; + var $newTr, $table, $tr, cellTag, colNum, i, index, j, ref; if (direction == null) { direction = 'after'; } $tr = $td.parent('tr'); $table = $tr.closest('table'); @@ -4900,35 +4970,45 @@ $table.find('tr').each((function(_this) { return function(i, tr) { return colNum = Math.max(colNum, $(tr).find('td').length); }; })(this)); + index = $tr.find('td, th').index($td); $newTr = $('<tr/>'); + cellTag = 'td'; + if (direction === 'after' && $tr.parent().is('thead')) { + $tr.parent().next('tbody').prepend($newTr); + } else if (direction === 'before' && $tr.parent().is('thead')) { + $tr.before($newTr); + $tr.parent().next('tbody').prepend($tr); + this._changeCellTag($tr, 'td'); + cellTag = 'th'; + } else { + $tr[direction]($newTr); + } for (i = j = 1, ref = colNum; 1 <= ref ? j <= ref : j >= ref; i = 1 <= ref ? ++j : --j) { - $('<td/>').append(this.editor.util.phBr).appendTo($newTr); + $("<" + cellTag + "/>").append(this.editor.util.phBr).appendTo($newTr); } - $tr[direction]($newTr); - index = $tr.find('td').index($td); - return this.editor.selection.setRangeAtStartOf($newTr.find('td').eq(index)); + return this.editor.selection.setRangeAtStartOf($newTr.find('td, th').eq(index)); }; TableButton.prototype.deleteCol = function($td) { var $newTd, $table, $tr, index; $tr = $td.parent('tr'); - if ($tr.siblings('tr').length < 1 && $td.siblings('td').length < 1) { + if ($tr.closest('table').find('tr').length < 1 && $td.siblings('td, th').length < 1) { return this.deleteTable($td); } else { - index = $tr.find('td').index($td); - $newTd = $td.next('td'); + index = $tr.find('td, th').index($td); + $newTd = $td.next('td, th'); if (!($newTd.length > 0)) { - $newTd = $tr.prev('td'); + $newTd = $tr.prev('td, th'); } $table = $tr.closest('table'); $table.find('col').eq(index).remove(); $table.find('tr').each((function(_this) { return function(i, tr) { - return $(tr).find('td').eq(index).remove(); + return $(tr).find('td, th').eq(index).remove(); }; })(this)); this.refreshTableWidth($table); return this.editor.selection.setRangeAtEndOf($newTd); } @@ -4938,28 +5018,29 @@ var $col, $newCol, $newTd, $table, $tr, index, tableWidth, width; if (direction == null) { direction = 'after'; } $tr = $td.parent('tr'); - index = $tr.find('td').index($td); + index = $tr.find('td, th').index($td); $table = $td.closest('table'); $col = $table.find('col').eq(index); $table.find('tr').each((function(_this) { return function(i, tr) { - var $newTd; - $newTd = $('<td/>').append(_this.editor.util.phBr); - return $(tr).find('td').eq(index)[direction]($newTd); + var $newTd, cellTag; + cellTag = $(tr).parent().is('thead') ? 'th' : 'td'; + $newTd = $("<" + cellTag + "/>").append(_this.editor.util.phBr); + return $(tr).find('td, th').eq(index)[direction]($newTd); }; })(this)); $newCol = $('<col/>'); $col[direction]($newCol); tableWidth = $table.width(); width = Math.max(parseFloat($col.attr('width')) / 2, 50 / tableWidth * 100); $col.attr('width', width + '%'); $newCol.attr('width', width + '%'); this.refreshTableWidth($table); - $newTd = direction === 'after' ? $td.next('td') : $td.prev('td'); + $newTd = direction === 'after' ? $td.next('td, th') : $td.prev('td, th'); return this.editor.selection.setRangeAtStartOf($newTd); }; TableButton.prototype.deleteTable = function($td) { var $block, $table; @@ -4972,10 +5053,10 @@ }; TableButton.prototype.command = function(param) { var $td, range; range = this.editor.selection.getRange(); - $td = $(range.commonAncestorContainer).closest('td'); + $td = $(range.commonAncestorContainer).closest('td, th'); if (!($td.length > 0)) { return; } if (param === 'deleteRow') { this.deleteRow($td);