vendor/assets/javascripts/simditor/simditor.js in simditor-2.1.15 vs vendor/assets/javascripts/simditor/simditor.js in simditor-2.2.0
- old
+ new
@@ -1,9 +1,9 @@
/*!
* Simditor v2.1.15
* http://simditor.tower.im/
-* 2015-07-01
+* 2015-07-28
*/
(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) {
@@ -32,82 +32,230 @@
return Selection.__super__.constructor.apply(this, arguments);
}
Selection.pluginName = 'Selection';
+ Selection.prototype._range = null;
+
+ Selection.prototype._startNodes = null;
+
+ Selection.prototype._endNodes = null;
+
+ Selection.prototype._containerNode = null;
+
+ Selection.prototype._nodes = null;
+
+ Selection.prototype._blockNodes = null;
+
+ Selection.prototype._rootNodes = null;
+
Selection.prototype._init = function() {
this.editor = this._module;
- return this.sel = document.getSelection();
+ this._selection = document.getSelection();
+ this.editor.on('selectionchanged', (function(_this) {
+ return function(e) {
+ _this._reset();
+ return _this._range = _this._selection.getRangeAt(0);
+ };
+ })(this));
+ return this.editor.on('blur', (function(_this) {
+ return function(e) {
+ return _this.clear();
+ };
+ })(this));
};
+ Selection.prototype._reset = function() {
+ this._range = null;
+ this._startNodes = null;
+ this._endNodes = null;
+ this._containerNode = null;
+ this._nodes = null;
+ this._blockNodes = null;
+ return this._rootNodes = null;
+ };
+
Selection.prototype.clear = function() {
var e;
try {
- return this.sel.removeAllRanges();
+ this._selection.removeAllRanges();
} catch (_error) {
e = _error;
}
+ return this._reset();
};
- Selection.prototype.getRange = function() {
- if (!this.editor.inputManager.focused || !this.sel.rangeCount) {
- return null;
+ Selection.prototype.range = function(range) {
+ var ffOrIE;
+ if (range) {
+ this.clear();
+ this._selection.addRange(range);
+ this._range = range;
+ ffOrIE = this.editor.util.browser.firefox || this.editor.util.browser.msie;
+ if (!this.editor.inputManager.focused && ffOrIE) {
+ this.editor.body.focus();
+ }
+ } else if (!this._range && this.editor.inputManager.focused && this._selection.rangeCount) {
+ this._range = this._selection.getRangeAt(0);
}
- return this.sel.getRangeAt(0);
+ return this._range;
};
- Selection.prototype.selectRange = function(range) {
- this.clear();
- this.sel.addRange(range);
- if (!this.editor.inputManager.focused && (this.editor.util.browser.firefox || this.editor.util.browser.msie)) {
- this.editor.body.focus();
+ Selection.prototype.startNodes = function() {
+ if (this._range) {
+ this._startNodes || (this._startNodes = (function(_this) {
+ return function() {
+ var startNodes;
+ startNodes = $(_this._range.startContainer).parentsUntil(_this.editor.body).get();
+ startNodes.unshift(_this._range.startContainer);
+ return $(startNodes);
+ };
+ })(this)());
}
- return range;
+ return this._startNodes;
};
+ Selection.prototype.endNodes = function() {
+ var endNodes;
+ if (this._range) {
+ this._endNodes || (this._endNodes = this._range.collapsed ? this.startNodes() : (endNodes = $(this._range.endContainer).parentsUntil(this.editor.body).get(), endNodes.unshift(this._range.endContainer), $(endNodes)));
+ }
+ return this._endNodes;
+ };
+
+ Selection.prototype.containerNode = function() {
+ if (this._range) {
+ this._containerNode || (this._containerNode = $(this._range.commonAncestorContainer));
+ }
+ return this._containerNode;
+ };
+
+ Selection.prototype.nodes = function() {
+ if (this._range) {
+ this._nodes || (this._nodes = (function(_this) {
+ return function() {
+ var nodes;
+ nodes = [];
+ if (_this.startNodes().first().is(_this.endNodes().first())) {
+ nodes = _this.startNodes().get();
+ } else {
+ _this.startNodes().each(function(i, node) {
+ var $endNode, $node, $nodes, endIndex, index, sharedIndex, startIndex;
+ $node = $(node);
+ if (_this.endNodes().index($node) > -1) {
+ return nodes.push(node);
+ } else if ($node.parent().is(_this.editor.body) || (sharedIndex = _this.endNodes().index($node.parent())) > -1) {
+ if (sharedIndex && sharedIndex > -1) {
+ $endNode = _this.endNodes().eq(sharedIndex - 1);
+ } else {
+ $endNode = _this.endNodes().last();
+ }
+ $nodes = $node.parent().contents();
+ startIndex = $nodes.index($node);
+ endIndex = $nodes.index($endNode);
+ return $.merge(nodes, $nodes.slice(startIndex, endIndex).get());
+ } else {
+ $nodes = $node.parent().contents();
+ index = $nodes.index($node);
+ return $.merge(nodes, $nodes.slice(index).get());
+ }
+ });
+ _this.endNodes().each(function(i, node) {
+ var $node, $nodes, index;
+ $node = $(node);
+ if ($node.parent().is(_this.editor.body) || _this.startNodes().index($node.parent()) > -1) {
+ nodes.push(node);
+ return false;
+ } else {
+ $nodes = $node.parent().contents();
+ index = $nodes.index($node);
+ return $.merge(nodes, $nodes.slice(0, index + 1));
+ }
+ });
+ }
+ return $($.unique(nodes));
+ };
+ })(this)());
+ }
+ return this._nodes;
+ };
+
+ Selection.prototype.blockNodes = function() {
+ if (!this._range) {
+ return;
+ }
+ this._blockNodes || (this._blockNodes = (function(_this) {
+ return function() {
+ return _this.nodes().filter(function(i, node) {
+ return _this.editor.util.isBlockNode(node);
+ });
+ };
+ })(this)());
+ return this._blockNodes;
+ };
+
+ Selection.prototype.rootNodes = function() {
+ if (!this._range) {
+ return;
+ }
+ this._rootNodes || (this._rootNodes = (function(_this) {
+ return function() {
+ return _this.nodes().filter(function(i, node) {
+ var $parent;
+ $parent = $(node).parent();
+ return $parent.is(_this.editor.body) || $parent.is('blockquote');
+ });
+ };
+ })(this)());
+ return this._rootNodes;
+ };
+
Selection.prototype.rangeAtEndOf = function(node, range) {
- var endNode, endNodeLength, result;
+ var afterLastNode, beforeLastNode, endNode, endNodeLength, lastNodeIsBr, result;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
- if (!((range != null) && range.collapsed)) {
+ if (!(range && range.collapsed)) {
return;
}
node = $(node)[0];
endNode = range.endContainer;
endNodeLength = this.editor.util.getNodeLength(endNode);
- if (!(range.endOffset === endNodeLength - 1 && $(endNode).contents().last().is('br')) && range.endOffset !== endNodeLength) {
+ beforeLastNode = range.endOffset === endNodeLength - 1;
+ lastNodeIsBr = $(endNode).contents().last().is('br');
+ afterLastNode = range.endOffset === endNodeLength;
+ if (!((beforeLastNode && lastNodeIsBr) || afterLastNode)) {
return false;
}
if (node === endNode) {
return true;
} else if (!$.contains(node, endNode)) {
return false;
}
result = true;
- $(endNode).parentsUntil(node).addBack().each((function(_this) {
- return function(i, n) {
- var $lastChild, nodes;
- nodes = $(n).parent().contents().filter(function() {
- return !(this !== n && this.nodeType === 3 && !this.nodeValue);
- });
- $lastChild = nodes.last();
- if (!($lastChild.get(0) === n || ($lastChild.is('br') && $lastChild.prev().get(0) === n))) {
- result = false;
- return false;
- }
- };
- })(this));
+ $(endNode).parentsUntil(node).addBack().each(function(i, n) {
+ var $lastChild, beforeLastbr, isLastNode, nodes;
+ nodes = $(n).parent().contents().filter(function() {
+ return !(this !== n && this.nodeType === 3 && !this.nodeValue);
+ });
+ $lastChild = nodes.last();
+ isLastNode = $lastChild.get(0) === n;
+ beforeLastbr = $lastChild.is('br') && $lastChild.prev().get(0) === n;
+ if (!(isLastNode || beforeLastbr)) {
+ result = false;
+ return false;
+ }
+ });
return result;
};
Selection.prototype.rangeAtStartOf = function(node, range) {
var result, startNode;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
- if (!((range != null) && range.collapsed)) {
+ if (!(range && range.collapsed)) {
return;
}
node = $(node)[0];
startNode = range.startContainer;
if (range.startOffset !== 0) {
@@ -117,88 +265,87 @@
return true;
} else if (!$.contains(node, startNode)) {
return false;
}
result = true;
- $(startNode).parentsUntil(node).addBack().each((function(_this) {
- return function(i, n) {
- var nodes;
- nodes = $(n).parent().contents().filter(function() {
- return !(this !== n && this.nodeType === 3 && !this.nodeValue);
- });
- if (nodes.first().get(0) !== n) {
- return result = false;
- }
- };
- })(this));
+ $(startNode).parentsUntil(node).addBack().each(function(i, n) {
+ var nodes;
+ nodes = $(n).parent().contents().filter(function() {
+ return !(this !== n && this.nodeType === 3 && !this.nodeValue);
+ });
+ if (nodes.first().get(0) !== n) {
+ return result = false;
+ }
+ });
return result;
};
Selection.prototype.insertNode = function(node, range) {
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
- if (range == null) {
+ if (!range) {
return;
}
node = $(node)[0];
range.insertNode(node);
return this.setRangeAfter(node, range);
};
Selection.prototype.setRangeAfter = function(node, range) {
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
if (range == null) {
return;
}
node = $(node)[0];
range.setEndAfter(node);
range.collapse(false);
- return this.selectRange(range);
+ return this.range(range);
};
Selection.prototype.setRangeBefore = function(node, range) {
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
if (range == null) {
return;
}
node = $(node)[0];
range.setEndBefore(node);
range.collapse(false);
- return this.selectRange(range);
+ return this.range(range);
};
Selection.prototype.setRangeAtStartOf = function(node, range) {
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
node = $(node).get(0);
range.setEnd(node, 0);
range.collapse(false);
- return this.selectRange(range);
+ return this.range(range);
};
Selection.prototype.setRangeAtEndOf = function(node, range) {
- var $lastNode, $node, contents, lastChild, lastText, nodeLength;
+ var $lastNode, $node, contents, lastChild, lastChildLength, lastText, nodeLength;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
$node = $(node);
- node = $node.get(0);
+ node = $node[0];
if ($node.is('pre')) {
contents = $node.contents();
if (contents.length > 0) {
lastChild = contents.last();
lastText = lastChild.text();
+ lastChildLength = this.editor.util.getNodeLength(lastChild[0]);
if (lastText.charAt(lastText.length - 1) === '\n') {
- range.setEnd(lastChild[0], this.editor.util.getNodeLength(lastChild[0]) - 1);
+ range.setEnd(lastChild[0], lastChildLength - 1);
} else {
- range.setEnd(lastChild[0], this.editor.util.getNodeLength(lastChild[0]));
+ range.setEnd(lastChild[0], lastChildLength);
}
} else {
range.setEnd(node, 0);
}
} else {
@@ -214,37 +361,39 @@
}
}
range.setEnd(node, nodeLength);
}
range.collapse(false);
- return this.selectRange(range);
+ return this.range(range);
};
Selection.prototype.deleteRangeContents = function(range) {
- var endRange, startRange;
+ var atEndOfBody, atStartOfBody, endRange, startRange;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
startRange = range.cloneRange();
endRange = range.cloneRange();
startRange.collapse(true);
endRange.collapse(false);
- if (!range.collapsed && this.rangeAtStartOf(this.editor.body, startRange) && this.rangeAtEndOf(this.editor.body, endRange)) {
+ atStartOfBody = this.rangeAtStartOf(this.editor.body, startRange);
+ atEndOfBody = this.rangeAtEndOf(this.editor.body, endRange);
+ if (!range.collapsed && atStartOfBody && atEndOfBody) {
this.editor.body.empty();
range.setStart(this.editor.body[0], 0);
range.collapse(true);
- this.selectRange(range);
+ this.range(range);
} else {
range.deleteContents();
}
return range;
};
Selection.prototype.breakBlockEl = function(el, range) {
var $el;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
$el = $(el);
if (!range.collapsed) {
return $el;
}
@@ -256,11 +405,11 @@
};
Selection.prototype.save = function(range) {
var endCaret, endRange, startCaret;
if (range == null) {
- range = this.getRange();
+ range = this.range();
}
if (this._selectionSaved) {
return;
}
endRange = range.cloneRange();
@@ -291,11 +440,11 @@
range = document.createRange();
range.setStart(startContainer.get(0), startOffset);
range.setEnd(endContainer.get(0), endOffset);
startCaret.remove();
endCaret.remove();
- this.selectRange(range);
+ this.range(range);
} else {
startCaret.remove();
endCaret.remove();
}
this._selectionSaved = false;
@@ -314,52 +463,55 @@
}
Formatter.pluginName = 'Formatter';
Formatter.prototype.opts = {
- allowedTags: null,
- allowedAttributes: null
+ allowedTags: [],
+ allowedAttributes: {},
+ allowedStyles: {}
};
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', 'code', 'h1', 'h2', 'h3', 'h4', 'hr'];
- this._allowedAttributes = this.opts.allowedAttributes || {
+ this._allowedTags = $.merge(['br', 'span', 'a', 'img', 'b', 'strong', 'i', 'u', 'font', 'p', 'ul', 'ol', 'li', 'blockquote', 'pre', 'code', 'h1', 'h2', 'h3', 'h4', 'hr'], this.opts.allowedTags);
+ this._allowedAttributes = $.extend({
img: ['src', 'alt', 'width', 'height', 'data-non-image'],
a: ['href', 'target'],
font: ['color'],
code: ['class']
- };
- this._allowedStyles = this.opts.allowedStyles || {
+ }, this.opts.allowedAttributes);
+ this._allowedStyles = $.extend({
+ span: ['color'],
p: ['margin-left', 'text-align'],
- h1: ['margin-left'],
- h2: ['margin-left'],
- h3: ['margin-left'],
- h4: ['margin-left']
- };
+ h1: ['margin-left', 'text-align'],
+ h2: ['margin-left', 'text-align'],
+ h3: ['margin-left', 'text-align'],
+ h4: ['margin-left', 'text-align']
+ }, this.opts.allowedStyles);
return this.editor.body.on('click', 'a', function(e) {
return false;
});
};
Formatter.prototype.decorate = function($el) {
if ($el == null) {
$el = this.editor.body;
}
- return this.editor.trigger('decorate', [$el]);
+ this.editor.trigger('decorate', [$el]);
+ return $el;
};
Formatter.prototype.undecorate = function($el) {
if ($el == null) {
$el = this.editor.body.clone();
}
this.editor.trigger('undecorate', [$el]);
- return $.trim($el.html());
+ return $el;
};
Formatter.prototype.autolink = function($el) {
- var $link, $node, findLinkNode, j, lastIndex, len, linkNodes, match, re, replaceEls, subStr, text, uri;
+ var $link, $node, findLinkNode, k, lastIndex, len, linkNodes, match, re, replaceEls, subStr, text, uri;
if ($el == null) {
$el = this.editor.body;
}
linkNodes = [];
findLinkNode = function($parentNode) {
@@ -367,21 +519,21 @@
var $node, text;
$node = $(node);
if ($node.is('a') || $node.closest('a, pre', $el).length) {
return;
}
- if ($node.contents().length) {
+ if (!$node.is('iframe') && $node.contents().length) {
return findLinkNode($node);
} else if ((text = $node.text()) && /https?:\/\/|www\./ig.test(text)) {
return linkNodes.push($node);
}
});
};
findLinkNode($el);
re = /(https?:\/\/|www\.)[\w\-\.\?&=\/#%:,@\!\+]+/ig;
- for (j = 0, len = linkNodes.length; j < len; j++) {
- $node = linkNodes[j];
+ for (k = 0, len = linkNodes.length; k < len; k++) {
+ $node = linkNodes[k];
text = $node.text();
replaceEls = [];
match = null;
lastIndex = 0;
while ((match = re.exec(text)) !== null) {
@@ -397,26 +549,26 @@
}
return $el;
};
Formatter.prototype.format = function($el) {
- var $node, blockNode, j, k, len, len1, n, node, ref, ref1;
+ var $node, blockNode, k, l, len, len1, n, node, ref, ref1;
if ($el == null) {
$el = this.editor.body;
}
if ($el.is(':empty')) {
$el.append('<p>' + this.editor.util.phBr + '</p>');
return $el;
}
ref = $el.contents();
- for (j = 0, len = ref.length; j < len; j++) {
- n = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ n = ref[k];
this.cleanNode(n, true);
}
ref1 = $el.contents();
- for (k = 0, len1 = ref1.length; k < len1; k++) {
- node = ref1[k];
+ for (l = 0, len1 = ref1.length; l < len1; l++) {
+ node = ref1[l];
$node = $(node);
if ($node.is('br')) {
if (typeof blockNode !== "undefined" && blockNode !== null) {
blockNode = null;
}
@@ -441,11 +593,11 @@
}
return $el;
};
Formatter.prototype.cleanNode = function(node, recursive) {
- var $childImg, $node, $p, $td, allowedAttributes, attr, contents, isDecoration, j, k, len, len1, n, ref, ref1, text, textNode;
+ var $childImg, $node, $p, $td, allowedAttributes, attr, contents, isDecoration, k, l, len, len1, n, ref, ref1, text, textNode;
$node = $(node);
if (!($node.length > 0)) {
return;
}
if ($node[0].nodeType === 3) {
@@ -456,12 +608,12 @@
} else {
$node.remove();
}
return;
}
- contents = $node.contents();
- isDecoration = $node.is('[class^="simditor-"]');
+ contents = $node.is('iframe') ? null : $node.contents();
+ isDecoration = this.editor.util.isDecoratedNode($node);
if ($node.is(this._allowedTags.join(',')) || isDecoration) {
if ($node.is('a') && ($childImg = $node.find('img')).length > 0) {
$node.replaceWith($childImg);
$node = $childImg;
contents = null;
@@ -470,20 +622,23 @@
$node.remove();
}
if (!isDecoration) {
allowedAttributes = this._allowedAttributes[$node[0].tagName.toLowerCase()];
ref = $.makeArray($node[0].attributes);
- for (j = 0, len = ref.length; j < len; j++) {
- attr = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ attr = ref[k];
if (attr.name === 'style') {
continue;
}
if (!((allowedAttributes != null) && (ref1 = attr.name, indexOf.call(allowedAttributes, ref1) >= 0))) {
$node.removeAttr(attr.name);
}
- this._cleanNodeStyles($node);
}
+ this._cleanNodeStyles($node);
+ if ($node.is('span') && $node[0].attributes.length === 0) {
+ $node.contents().first().unwrap();
+ }
}
} else if ($node[0].nodeType === 1 && !$node.is(':empty')) {
if ($node.is('div, article, dl, header, footer, tr')) {
$node.append('<br/>');
contents.first().unwrap();
@@ -506,20 +661,20 @@
} else {
$node.remove();
contents = null;
}
if (recursive && (contents != null) && !$node.is('pre')) {
- for (k = 0, len1 = contents.length; k < len1; k++) {
- n = contents[k];
+ for (l = 0, len1 = contents.length; l < len1; l++) {
+ n = contents[l];
this.cleanNode(n, true);
}
}
return null;
};
Formatter.prototype._cleanNodeStyles = function($node) {
- var allowedStyles, j, len, pair, ref, ref1, style, styleStr, styles;
+ var allowedStyles, k, len, pair, ref, ref1, style, styleStr, styles;
styleStr = $node.attr('style');
if (!styleStr) {
return;
}
$node.removeAttr('style');
@@ -527,12 +682,12 @@
if (!(allowedStyles && allowedStyles.length > 0)) {
return $node;
}
styles = {};
ref = styleStr.split(';');
- for (j = 0, len = ref.length; j < len; j++) {
- style = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ style = ref[k];
style = $.trim(style);
pair = style.split(':');
if (!(pair.length = 2)) {
continue;
}
@@ -559,12 +714,12 @@
var $node, children;
if (node.nodeType === 3) {
return result += node.nodeValue;
} else if (node.nodeType === 1) {
$node = $(node);
- children = $node.contents();
- if (children.length > 0) {
+ children = $node.is('iframe') ? null : $node.contents();
+ if (children && children.length > 0) {
result += _this.clearHtml(children);
}
if (lineBreak && i < contents.length - 1 && $node.is('br, p, div, li,tr, pre, address, artticle, aside, dl, figcaption, footer, h1, h2,h3, h4, header')) {
return result += '\n';
}
@@ -612,20 +767,22 @@
InputManager.prototype._arrowKeys = [37, 38, 39, 40];
InputManager.prototype._init = function() {
var submitKey;
this.editor = this._module;
- this.throttledTrigger = this.editor.util.throttle((function(_this) {
- return function() {
- var args;
- args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
+ this.throttledValueChanged = this.editor.util.throttle((function(_this) {
+ return function(params) {
return setTimeout(function() {
- var ref;
- return (ref = _this.editor).trigger.apply(ref, args);
+ return _this.editor.trigger('valuechanged', params);
}, 10);
};
})(this), 300);
+ this.throttledSelectionChanged = this.editor.util.throttle((function(_this) {
+ return function() {
+ return _this.editor.trigger('selectionchanged');
+ };
+ })(this), 50);
if (this.opts.pasteImage && typeof this.opts.pasteImage !== 'string') {
this.opts.pasteImage = 'inline';
}
this._keystrokeHandlers = {};
this.hotkeys = simpleHotkeys({
@@ -645,22 +802,17 @@
$(document).on('selectionchange.simditor' + this.editor.id, (function(_this) {
return function(e) {
if (!_this.focused) {
return;
}
- if (_this._selectionTimer) {
- clearTimeout(_this._selectionTimer);
- _this._selectionTimer = null;
- }
- return _this._selectionTimer = setTimeout(function() {
- return _this.editor.trigger('selectionchanged');
- }, 20);
+ return _this.throttledSelectionChanged();
};
})(this));
this.editor.on('valuechanged', (function(_this) {
return function() {
- if (!_this.editor.util.closestBlockEl() && _this.focused) {
+ _this.lastCaretPosition = null;
+ if (_this.focused && !_this.editor.selection.blockNodes().length) {
_this.editor.selection.save();
_this.editor.formatter.format();
_this.editor.selection.restore();
}
_this.editor.body.find('hr, pre, .simditor-table').each(function(i, el) {
@@ -675,40 +827,33 @@
if ($el.prev().length === 0) {
$('<p/>').append(_this.editor.util.phBr).insertBefore($el);
formatted = true;
}
if (formatted) {
- return setTimeout(function() {
- return _this.editor.trigger('valuechanged');
- }, 10);
+ return _this.throttledValueChanged();
}
}
});
_this.editor.body.find('pre:empty').append(_this.editor.util.phBr);
if (!_this.editor.util.support.onselectionchange && _this.focused) {
- return _this.editor.trigger('selectionchanged');
+ return _this.throttledValueChanged();
}
};
})(this));
- this.editor.on('selectionchanged', (function(_this) {
- return function(e) {
- return _this.editor.undoManager.update();
- };
- })(this));
this.editor.body.on('keydown', $.proxy(this._onKeyDown, this)).on('keypress', $.proxy(this._onKeyPress, this)).on('keyup', $.proxy(this._onKeyUp, this)).on('mouseup', $.proxy(this._onMouseUp, this)).on('focus', $.proxy(this._onFocus, this)).on('blur', $.proxy(this._onBlur, this)).on('paste', $.proxy(this._onPaste, this)).on('drop', $.proxy(this._onDrop, this)).on('input', $.proxy(this._onInput, this));
if (this.editor.util.browser.firefox) {
this.addShortcut('cmd+left', (function(_this) {
return function(e) {
e.preventDefault();
- _this.editor.selection.sel.modify('move', 'backward', 'lineboundary');
+ _this.editor.selection._selection.modify('move', 'backward', 'lineboundary');
return false;
};
})(this));
this.addShortcut('cmd+right', (function(_this) {
return function(e) {
e.preventDefault();
- _this.editor.selection.sel.modify('move', 'forward', 'lineboundary');
+ _this.editor.selection._selection.modify('move', 'forward', 'lineboundary');
return false;
};
})(this));
this.addShortcut((this.editor.util.os.mac ? 'cmd+a' : 'ctrl+a'), (function(_this) {
return function(e) {
@@ -720,11 +865,11 @@
firstBlock = $children.first().get(0);
lastBlock = $children.last().get(0);
range = document.createRange();
range.setStart(firstBlock, 0);
range.setEnd(lastBlock, _this.editor.util.getNodeLength(lastBlock));
- _this.editor.selection.selectRange(range);
+ _this.editor.selection.range(range);
return false;
};
})(this));
}
submitKey = this.editor.util.os.mac ? 'cmd+enter' : 'ctrl+enter';
@@ -748,11 +893,13 @@
this.focused = true;
this.lastCaretPosition = null;
return setTimeout((function(_this) {
return function() {
_this.editor.triggerHandler('focus');
- return _this.editor.trigger('selectionchanged');
+ if (!_this.editor.util.support.onselectionchange) {
+ return _this.throttledSelectionChanged();
+ }
};
})(this), 0);
};
InputManager.prototype._onBlur = function(e) {
@@ -764,15 +911,11 @@
return this.editor.triggerHandler('blur');
};
InputManager.prototype._onMouseUp = function(e) {
if (!this.editor.util.support.onselectionchange) {
- return setTimeout((function(_this) {
- return function() {
- return _this.editor.trigger('selectionchanged');
- };
- })(this), 0);
+ return this.throttledSelectionChanged();
}
};
InputManager.prototype._onKeyDown = function(e) {
var base, ref, ref1, result;
@@ -783,39 +926,39 @@
return;
}
if (e.which in this._keystrokeHandlers) {
result = typeof (base = this._keystrokeHandlers[e.which])['*'] === "function" ? base['*'](e) : void 0;
if (result) {
- this.editor.trigger('valuechanged');
+ this.throttledValueChanged();
return false;
}
- this.editor.util.traverseUp((function(_this) {
- return function(node) {
+ this.editor.selection.startNodes().each((function(_this) {
+ return function(i, node) {
var handler, ref;
- if (node.nodeType !== document.ELEMENT_NODE) {
+ if (node.nodeType !== Node.ELEMENT_NODE) {
return;
}
handler = (ref = _this._keystrokeHandlers[e.which]) != null ? ref[node.tagName.toLowerCase()] : void 0;
result = typeof handler === "function" ? handler(e, $(node)) : void 0;
if (result === true || result === false) {
return false;
}
};
})(this));
if (result) {
- this.editor.trigger('valuechanged');
+ this.throttledValueChanged();
return false;
}
}
if ((ref = e.which, indexOf.call(this._modifierKeys, ref) >= 0) || (ref1 = e.which, indexOf.call(this._arrowKeys, ref1) >= 0)) {
return;
}
if (this.editor.util.metaKey(e) && e.which === 86) {
return;
}
if (!this.editor.util.support.oninput) {
- this.throttledTrigger('valuechanged', ['typing']);
+ this.throttledValueChanged(['typing']);
}
return null;
};
InputManager.prototype._onKeyPress = function(e) {
@@ -828,11 +971,11 @@
var p, ref;
if (this.editor.triggerHandler(e) === false) {
return false;
}
if (!this.editor.util.support.onselectionchange && (ref = e.which, indexOf.call(this._arrowKeys, ref) >= 0)) {
- this.editor.trigger('selectionchanged');
+ this.throttledValueChanged();
return;
}
if ((e.which === 8 || e.which === 46) && this.editor.util.isEmptyNode(this.editor.body)) {
this.editor.body.empty();
p = $('<p/>').append(this.editor.util.phBr).appendTo(this.editor.body);
@@ -847,11 +990,12 @@
}
range = this.editor.selection.deleteRangeContents();
if (!range.collapsed) {
range.collapse(true);
}
- $blockEl = this.editor.util.closestBlockEl();
+ this.editor.selection.range(range);
+ $blockEl = this.editor.selection.blockNodes().last();
cleanPaste = $blockEl.is('pre, table');
if (e.originalEvent.clipboardData && e.originalEvent.clipboardData.items && e.originalEvent.clipboardData.items.length > 0) {
pasteItem = e.originalEvent.clipboardData.items[0];
if (/^image\//.test(pasteItem.type) && !cleanPaste) {
imageFile = pasteItem.getAsFile();
@@ -869,37 +1013,37 @@
return false;
}
}
processPasteContent = (function(_this) {
return function(pasteContent) {
- var $img, blob, children, insertPosition, j, k, l, lastLine, len, len1, len2, len3, len4, line, lines, m, node, o, ref1, ref2, ref3;
+ var $img, blob, children, insertPosition, k, l, lastLine, len, len1, len2, len3, len4, line, lines, m, node, o, q, ref1, ref2, ref3;
if (_this.editor.triggerHandler('pasting', [pasteContent]) === false) {
return;
}
if (!pasteContent) {
return;
} else if (cleanPaste) {
if ($blockEl.is('table')) {
lines = pasteContent.split('\n');
lastLine = lines.pop();
- for (j = 0, len = lines.length; j < len; j++) {
- line = lines[j];
+ for (k = 0, len = lines.length; k < len; k++) {
+ line = lines[k];
_this.editor.selection.insertNode(document.createTextNode(line));
_this.editor.selection.insertNode($('<br/>'));
}
_this.editor.selection.insertNode(document.createTextNode(lastLine));
} else {
pasteContent = $('<div/>').text(pasteContent);
ref1 = pasteContent.contents();
- for (k = 0, len1 = ref1.length; k < len1; k++) {
- node = ref1[k];
+ for (l = 0, len1 = ref1.length; l < len1; l++) {
+ node = ref1[l];
_this.editor.selection.insertNode($(node)[0], range);
}
}
} else if ($blockEl.is(_this.editor.body)) {
- for (l = 0, len2 = pasteContent.length; l < len2; l++) {
- node = pasteContent[l];
+ for (m = 0, len2 = pasteContent.length; m < len2; m++) {
+ node = pasteContent[m];
_this.editor.selection.insertNode(node, range);
}
} else if (pasteContent.length < 1) {
return;
} else if (pasteContent.length === 1) {
@@ -921,23 +1065,23 @@
return;
} else if ($img.is('img[src^="webkit-fake-url://"]')) {
return;
}
}
- for (m = 0, len3 = children.length; m < len3; m++) {
- node = children[m];
+ for (o = 0, len3 = children.length; o < len3; o++) {
+ node = children[o];
_this.editor.selection.insertNode(node, range);
}
} else if ($blockEl.is('p') && _this.editor.util.isEmptyNode($blockEl)) {
$blockEl.replaceWith(pasteContent);
_this.editor.selection.setRangeAtEndOf(pasteContent, range);
} else if (pasteContent.is('ul, ol')) {
if (pasteContent.find('li').length === 1) {
pasteContent = $('<div/>').text(pasteContent.text());
ref3 = pasteContent.contents();
- for (o = 0, len4 = ref3.length; o < len4; o++) {
- node = ref3[o];
+ for (q = 0, len4 = ref3.length; q < len4; q++) {
+ node = ref3[q];
_this.editor.selection.insertNode($(node)[0], range);
}
} else if ($blockEl.is('li')) {
$blockEl.parent().after(pasteContent);
_this.editor.selection.setRangeAtEndOf(pasteContent, range);
@@ -962,11 +1106,11 @@
insertPosition = 'before';
}
$blockEl[insertPosition](pasteContent);
_this.editor.selection.setRangeAtEndOf(pasteContent.last(), range);
}
- return _this.editor.trigger('valuechanged');
+ return _this.throttledValueChanged();
};
})(this);
if (cleanPaste) {
e.preventDefault();
if (this.editor.util.browser.msie) {
@@ -1004,19 +1148,15 @@
InputManager.prototype._onDrop = function(e) {
if (this.editor.triggerHandler(e) === false) {
return false;
}
- return setTimeout((function(_this) {
- return function() {
- return _this.editor.trigger('valuechanged');
- };
- })(this), 0);
+ return this.throttledValueChanged();
};
InputManager.prototype._onInput = function(e) {
- return this.throttledTrigger('valuechanged', ['oninput']);
+ return this.throttledValueChanged(['oninput']);
};
InputManager.prototype.addKeystrokeHandler = function(key, node, handler) {
if (!this._keystrokeHandlers[key]) {
this._keystrokeHandlers[key] = {};
@@ -1049,11 +1189,11 @@
return function(e) {
var $blockEl, $br;
if (!e.shiftKey) {
return;
}
- $blockEl = _this.editor.util.closestBlockEl();
+ $blockEl = _this.editor.selection.blockNodes().last();
if ($blockEl.is('pre')) {
return;
}
$br = $('<br/>');
if (_this.editor.selection.rangeAtEndOf($blockEl)) {
@@ -1086,21 +1226,22 @@
this.editor.inputManager.addKeystrokeHandler('13', 'h5', titleEnterHandler);
this.editor.inputManager.addKeystrokeHandler('13', 'h6', titleEnterHandler);
}
this.editor.inputManager.addKeystrokeHandler('8', '*', (function(_this) {
return function(e) {
- var $blockEl, $prevBlockEl, $rootBlock;
- $rootBlock = _this.editor.util.furthestBlockEl();
+ var $blockEl, $prevBlockEl, $rootBlock, isWebkit;
+ $rootBlock = _this.editor.selection.rootNodes().first();
$prevBlockEl = $rootBlock.prev();
if ($prevBlockEl.is('hr') && _this.editor.selection.rangeAtStartOf($rootBlock)) {
_this.editor.selection.save();
$prevBlockEl.remove();
_this.editor.selection.restore();
return true;
}
- $blockEl = _this.editor.util.closestBlockEl();
- if (_this.editor.util.browser.webkit && _this.editor.selection.rangeAtStartOf($blockEl)) {
+ $blockEl = _this.editor.selection.blockNodes().last();
+ isWebkit = _this.editor.util.browser.webkit;
+ if (isWebkit && _this.editor.selection.rangeAtStartOf($blockEl)) {
_this.editor.selection.save();
_this.editor.formatter.cleanNode($blockEl, true);
_this.editor.selection.restore();
return null;
}
@@ -1109,11 +1250,11 @@
this.editor.inputManager.addKeystrokeHandler('13', 'li', (function(_this) {
return function(e, $node) {
var $cloneNode, listEl, newBlockEl, newListEl;
$cloneNode = $node.clone();
$cloneNode.find('ul, ol').remove();
- if (!(_this.editor.util.isEmptyNode($cloneNode) && $node.is(_this.editor.util.closestBlockEl()))) {
+ if (!(_this.editor.util.isEmptyNode($cloneNode) && $node.is(_this.editor.selection.blockNodes().last()))) {
return;
}
listEl = $node.parent();
if ($node.next('li').length > 0) {
if (!_this.editor.util.isEmptyNode($node)) {
@@ -1159,11 +1300,11 @@
if (e.shiftKey) {
$p = $('<p/>').append(_this.editor.util.phBr).insertAfter($node);
_this.editor.selection.setRangeAtStartOf($p);
return true;
}
- range = _this.editor.selection.getRange();
+ range = _this.editor.selection.range();
breakNode = null;
range.deleteContents();
if (!_this.editor.util.browser.msie && _this.editor.selection.rangeAtEndOf($node)) {
breakNode = document.createTextNode('\n\n');
range.insertNode(breakNode);
@@ -1172,18 +1313,18 @@
breakNode = document.createTextNode('\n');
range.insertNode(breakNode);
range.setStartAfter(breakNode);
}
range.collapse(false);
- _this.editor.selection.selectRange(range);
+ _this.editor.selection.range(range);
return true;
};
})(this));
this.editor.inputManager.addKeystrokeHandler('13', 'blockquote', (function(_this) {
return function(e, $node) {
var $closestBlock, range;
- $closestBlock = _this.editor.util.closestBlockEl();
+ $closestBlock = _this.editor.selection.blockNodes().last();
if (!($closestBlock.is('p') && !$closestBlock.next().length && _this.editor.util.isEmptyNode($closestBlock))) {
return;
}
$node.after($closestBlock);
range = document.createRange();
@@ -1191,11 +1332,11 @@
return true;
};
})(this));
this.editor.inputManager.addKeystrokeHandler('8', 'li', (function(_this) {
return function(e, $node) {
- var $br, $childList, $newLi, $prevChildList, $prevNode, $textNode, range, text;
+ var $br, $childList, $newLi, $prevChildList, $prevNode, $textNode, isFF, range, text;
$childList = $node.children('ul, ol');
$prevNode = $node.prev('li');
if (!($childList.length > 0 && $prevNode.length > 0)) {
return false;
}
@@ -1213,11 +1354,12 @@
} else if (n.nodeType === 1) {
text += $(n).text();
}
return $textNode = $(n);
});
- if ($textNode && text.length === 1 && _this.editor.util.browser.firefox && !$textNode.next('br').length) {
+ isFF = _this.editor.util.browser.firefox && !$textNode.next('br').length;
+ if ($textNode && text.length === 1 && isFF) {
$br = $(_this.editor.util.phBr).insertAfter($textNode);
$textNode.remove();
_this.editor.selection.setRangeBefore($br);
return true;
} else if (text.length > 0) {
@@ -1232,23 +1374,23 @@
_this.editor.selection.setRangeAtEndOf($newLi, range);
} else {
_this.editor.selection.setRangeAtEndOf($prevNode, range);
$prevNode.append($childList);
$node.remove();
- _this.editor.selection.selectRange(range);
+ _this.editor.selection.range(range);
}
return true;
};
})(this));
this.editor.inputManager.addKeystrokeHandler('8', 'pre', (function(_this) {
return function(e, $node) {
var $newNode, codeStr, range;
if (!_this.editor.selection.rangeAtStartOf($node)) {
return;
}
- codeStr = $node.html().replace('\n', '<br/>');
- $newNode = $('<p/>').append(codeStr || _this.editor.util.phBr).insertAfter($node);
+ codeStr = $node.html().replace('\n', '<br/>') || _this.editor.util.phBr;
+ $newNode = $('<p/>').append(codeStr).insertAfter($node);
$node.remove();
range = document.createRange();
_this.editor.selection.setRangeAtStartOf($newNode, range);
return true;
};
@@ -1280,16 +1422,18 @@
UndoManager.pluginName = 'UndoManager';
UndoManager.prototype._index = -1;
- UndoManager.prototype._capacity = 50;
+ UndoManager.prototype._capacity = 20;
- UndoManager.prototype._timer = null;
+ UndoManager.prototype._startPosition = null;
+ UndoManager.prototype._endPosition = null;
+
UndoManager.prototype._init = function() {
- var redoShortcut, undoShortcut;
+ var redoShortcut, throttledPushState, undoShortcut;
this.editor = this._module;
this._stack = [];
if (this.editor.util.os.mac) {
undoShortcut = 'cmd+z';
redoShortcut = 'shift+cmd+z';
@@ -1312,27 +1456,59 @@
e.preventDefault();
_this.redo();
return false;
};
})(this));
- return this.editor.on('valuechanged', (function(_this) {
- return function(e, src) {
- if (src === 'undo' || src === 'redo') {
- return;
- }
- if (_this._timer) {
- clearTimeout(_this._timer);
- _this._timer = null;
- }
- return _this._timer = setTimeout(function() {
- _this._pushUndoState();
- return _this._timer = null;
- }, 200);
+ throttledPushState = this.editor.util.throttle((function(_this) {
+ return function() {
+ return _this._pushUndoState();
};
+ })(this), 500);
+ this.editor.on('valuechanged', function(e, src) {
+ if (src === 'undo' || src === 'redo') {
+ return;
+ }
+ return throttledPushState();
+ });
+ this.editor.on('selectionchanged', (function(_this) {
+ return function(e) {
+ _this._startPosition = null;
+ _this._endPosition = null;
+ return _this.update();
+ };
})(this));
+ return this.editor.on('blur', (function(_this) {
+ return function(e) {
+ _this._startPosition = null;
+ return _this._endPosition = null;
+ };
+ })(this));
};
+ UndoManager.prototype.startPosition = function() {
+ if (this.editor.selection._range) {
+ this._startPosition || (this._startPosition = this._getPosition('start'));
+ }
+ return this._startPosition;
+ };
+
+ UndoManager.prototype.endPosition = function() {
+ if (this.editor.selection._range) {
+ this._endPosition || (this._endPosition = (function(_this) {
+ return function() {
+ var range;
+ range = _this.editor.selection.range();
+ if (range.collapsed) {
+ return _this._startPosition;
+ }
+ return _this._getPosition('end');
+ };
+ })(this)());
+ }
+ return this._endPosition;
+ };
+
UndoManager.prototype._pushUndoState = function() {
var currentState, html;
if (this.editor.triggerHandler('pushundostate') === false) {
return;
}
@@ -1412,57 +1588,61 @@
} else {
$parent = $(node).parent();
}
offset = 0;
merging = false;
- $parent.contents().each((function(_this) {
- return function(i, child) {
- if (index === i || node === child) {
- return false;
- }
- if (child.nodeType === 3) {
- if (!merging) {
- offset += 1;
- merging = true;
- }
- } else {
+ $parent.contents().each(function(i, child) {
+ if (index === i || node === child) {
+ return false;
+ }
+ if (child.nodeType === 3) {
+ if (!merging) {
offset += 1;
- merging = false;
+ merging = true;
}
- return null;
- };
- })(this));
+ } else {
+ offset += 1;
+ merging = false;
+ }
+ return null;
+ });
return offset;
};
- UndoManager.prototype._getNodePosition = function(node, offset) {
- var position, prevNode;
- if (node.nodeType === 3) {
+ UndoManager.prototype._getPosition = function(type) {
+ var $nodes, node, nodes, offset, position, prevNode, range;
+ if (type == null) {
+ type = 'start';
+ }
+ range = this.editor.selection.range();
+ offset = range[type + "Offset"];
+ $nodes = this.editor.selection[type + "Nodes"]();
+ if ((node = $nodes.first()[0]).nodeType === Node.TEXT_NODE) {
prevNode = node.previousSibling;
- while (prevNode && prevNode.nodeType === 3) {
+ while (prevNode && prevNode.nodeType === Node.TEXT_NODE) {
node = prevNode;
offset += this.editor.util.getNodeLength(prevNode);
prevNode = prevNode.previousSibling;
}
- } else {
- offset = this._getNodeOffset(node, offset);
+ nodes = $nodes.get();
+ nodes[0] = node;
+ $nodes = $(nodes);
}
- position = [];
- position.unshift(offset);
- this.editor.util.traverseUp((function(_this) {
- return function(n) {
- return position.unshift(_this._getNodeOffset(n));
+ position = [offset];
+ $nodes.each((function(_this) {
+ return function(i, node) {
+ return position.unshift(_this._getNodeOffset(node));
};
- })(this), node);
+ })(this));
return position;
};
UndoManager.prototype._getNodeByPosition = function(position) {
- var child, childNodes, i, j, len, node, offset, ref;
+ var child, childNodes, i, k, len, node, offset, ref;
node = this.editor.body[0];
ref = position.slice(0, position.length - 1);
- for (i = j = 0, len = ref.length; j < len; i = ++j) {
+ for (i = k = 0, len = ref.length; k < len; i = ++k) {
offset = ref[i];
childNodes = node.childNodes;
if (offset > childNodes.length - 1) {
if (i === position.length - 2 && $(node).is('pre')) {
child = document.createTextNode('');
@@ -1479,24 +1659,16 @@
};
UndoManager.prototype.caretPosition = function(caret) {
var endContainer, endOffset, range, startContainer, startOffset;
if (!caret) {
- range = this.editor.selection.getRange();
- if (!(this.editor.inputManager.focused && (range != null))) {
- return {};
- }
- caret = {
- start: [],
- end: null,
- collapsed: true
- };
- caret.start = this._getNodePosition(range.startContainer, range.startOffset);
- if (!range.collapsed) {
- caret.end = this._getNodePosition(range.endContainer, range.endOffset);
- caret.collapsed = false;
- }
+ range = this.editor.selection.range();
+ caret = this.editor.inputManager.focused && (range != null) ? {
+ start: this.startPosition(),
+ end: this.endPosition(),
+ collapsed: range.collapsed
+ } : {};
return caret;
} else {
if (!this.editor.inputManager.focused) {
this.editor.body.focus();
}
@@ -1518,11 +1690,11 @@
return;
}
range = document.createRange();
range.setStart(startContainer, startOffset);
range.setEnd(endContainer, endOffset);
- return this.editor.selection.selectRange(range);
+ return this.editor.selection.range(range);
}
};
return UndoManager;
@@ -1643,75 +1815,26 @@
var $node;
$node = $(node);
return $node.is(':empty') || (!$node.text() && !$node.find(':not(br, span, div)').length);
};
+ Util.prototype.isDecoratedNode = function(node) {
+ return $(node).is('[class^="simditor-"]');
+ };
+
Util.prototype.blockNodes = ["div", "p", "ul", "ol", "li", "blockquote", "hr", "pre", "h1", "h2", "h3", "h4", "table"];
Util.prototype.isBlockNode = function(node) {
node = $(node)[0];
if (!node || node.nodeType === 3) {
return false;
}
return new RegExp("^(" + (this.blockNodes.join('|')) + ")$").test(node.nodeName.toLowerCase());
};
- Util.prototype.closestBlockEl = function(node) {
- var $node, blockEl, range;
- if (node == null) {
- range = this.editor.selection.getRange();
- node = range != null ? range.commonAncestorContainer : void 0;
- }
- $node = $(node);
- if (!$node.length) {
- return null;
- }
- blockEl = $node.parentsUntil(this.editor.body).addBack();
- blockEl = blockEl.filter((function(_this) {
- return function(i) {
- return _this.isBlockNode(blockEl.eq(i));
- };
- })(this));
- if (blockEl.length) {
- return blockEl.last();
- } else {
- return null;
- }
- };
-
- Util.prototype.furthestNode = function(node, filter) {
- var $node, blockEl, range;
- if (node == null) {
- range = this.editor.selection.getRange();
- node = range != null ? range.commonAncestorContainer : void 0;
- }
- $node = $(node);
- if (!$node.length) {
- return null;
- }
- blockEl = $node.parentsUntil(this.editor.body).addBack();
- blockEl = blockEl.filter(function(i) {
- var $n;
- $n = blockEl.eq(i);
- if ($.isFunction(filter)) {
- return filter($n);
- } else {
- return $n.is(filter);
- }
- });
- if (blockEl.length) {
- return blockEl.first();
- } else {
- return null;
- }
- };
-
- Util.prototype.furthestBlockEl = function(node) {
- return this.furthestNode(node, $.proxy(this.isBlockNode, this));
- };
-
Util.prototype.getNodeLength = function(node) {
+ node = $(node)[0];
switch (node.nodeType) {
case 7:
case 10:
return 0;
case 3:
@@ -1720,36 +1843,12 @@
default:
return node.childNodes.length;
}
};
- Util.prototype.traverseUp = function(callback, node) {
- var j, len, n, nodes, range, result, results1;
- if (node == null) {
- range = this.editor.selection.getRange();
- node = range != null ? range.commonAncestorContainer : void 0;
- }
- if ((node == null) || !$.contains(this.editor.body[0], node)) {
- return false;
- }
- nodes = $(node).parentsUntil(this.editor.body).get();
- nodes.unshift(node);
- results1 = [];
- for (j = 0, len = nodes.length; j < len; j++) {
- n = nodes[j];
- result = callback(n);
- if (result === false) {
- break;
- } else {
- results1.push(void 0);
- }
- }
- return results1;
- };
-
Util.prototype.dataURLtoBlob = function(dataURL) {
- var BlobBuilder, arrayBuffer, bb, blobArray, byteString, hasArrayBufferViewSupport, hasBlobConstructor, i, intArray, j, mimeString, ref, supportBlob;
+ var BlobBuilder, arrayBuffer, bb, blobArray, byteString, hasArrayBufferViewSupport, hasBlobConstructor, i, intArray, k, mimeString, ref, supportBlob;
hasBlobConstructor = window.Blob && (function() {
var e;
try {
return Boolean(new Blob());
} catch (_error) {
@@ -1776,11 +1875,11 @@
} else {
byteString = decodeURIComponent(dataURL.split(',')[1]);
}
arrayBuffer = new ArrayBuffer(byteString.length);
intArray = new Uint8Array(arrayBuffer);
- for (i = j = 0, ref = byteString.length; 0 <= ref ? j <= ref : j >= ref; i = 0 <= ref ? ++j : --j) {
+ for (i = k = 0, ref = byteString.length; 0 <= ref ? k <= ref : k >= ref; i = 0 <= ref ? ++k : --k) {
intArray[i] = byteString.charCodeAt(i);
}
mimeString = dataURL.split(',')[0].split(':')[1].split(';')[0];
if (hasBlobConstructor) {
blobArray = hasArrayBufferViewSupport ? intArray : arrayBuffer;
@@ -1792,42 +1891,34 @@
bb.append(arrayBuffer);
return bb.getBlob(mimeString);
};
Util.prototype.throttle = function(func, wait) {
- var delayedCallTimeout, previousCallTime, stopDelayedCall;
- delayedCallTimeout = null;
- previousCallTime = 0;
- stopDelayedCall = function() {
- if (delayedCallTimeout) {
- clearTimeout(delayedCallTimeout);
- return delayedCallTimeout = null;
- }
+ var args, call, ctx, last, rtn, throttled, timeoutID;
+ last = 0;
+ timeoutID = 0;
+ ctx = args = rtn = null;
+ call = function() {
+ timeoutID = 0;
+ last = +new Date();
+ rtn = func.apply(ctx, args);
+ ctx = null;
+ return args = null;
};
- return function() {
- var args, now, remaining, result;
- now = Date.now();
- previousCallTime || (previousCallTime = now);
- remaining = wait - (now - previousCallTime);
- result = null;
- if ((0 < remaining && remaining < wait)) {
- previousCallTime = now;
- stopDelayedCall();
- args = arguments;
- delayedCallTimeout = setTimeout(function() {
- previousCallTime = 0;
- delayedCallTimeout = null;
- return result = func.apply(null, args);
- }, wait);
- } else {
- stopDelayedCall();
- if (previousCallTime !== now) {
- previousCallTime = 0;
+ return throttled = function() {
+ var delta;
+ ctx = this;
+ args = arguments;
+ delta = new Date() - last;
+ if (!timeoutID) {
+ if (delta >= wait) {
+ call();
+ } else {
+ timeoutID = setTimeout(call, wait - delta);
}
- result = func.apply(null, arguments);
}
- return result;
+ return rtn;
};
};
Util.prototype.formatHTML = function(html) {
var cursor, indentString, lastMatch, level, match, re, repeatString, result, str;
@@ -1901,15 +1992,13 @@
}
if (!$.isArray(this.opts.toolbar)) {
this.opts.toolbar = ['bold', 'italic', 'underline', 'strikethrough', '|', 'ol', 'ul', 'blockquote', 'code', '|', 'link', 'image', '|', 'indent', 'outdent'];
}
this._render();
- this.list.on('click', (function(_this) {
- return function(e) {
- return false;
- };
- })(this));
+ this.list.on('click', function(e) {
+ return false;
+ });
this.wrapper.on('mousedown', (function(_this) {
return function(e) {
return _this.list.find('.menu-on').removeClass('.menu-on');
};
})(this));
@@ -1951,41 +2040,36 @@
}
}
};
})(this));
}
- this.editor.on('selectionchanged', (function(_this) {
- return function() {
- return _this.toolbarStatus();
- };
- })(this));
this.editor.on('destroy', (function(_this) {
return function() {
return _this.buttons.length = 0;
};
})(this));
- return $(document).on('mousedown.simditor-' + this.editor.id, (function(_this) {
+ return $(document).on("mousedown.simditor-" + this.editor.id, (function(_this) {
return function(e) {
return _this.list.find('li.menu-on').removeClass('menu-on');
};
})(this));
};
Toolbar.prototype._render = function() {
- var j, len, name, ref;
+ var k, len, name, ref;
this.buttons = [];
this.wrapper = $(this._tpl.wrapper).prependTo(this.editor.wrapper);
this.list = this.wrapper.find('ul');
ref = this.opts.toolbar;
- for (j = 0, len = ref.length; j < len; j++) {
- name = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ name = ref[k];
if (name === '|') {
$(this._tpl.separator).appendTo(this.list);
continue;
}
if (!this.constructor.buttons[name]) {
- throw new Error('simditor: invalid toolbar button "' + name + '"');
+ throw new Error("simditor: invalid toolbar button " + name);
continue;
}
this.buttons.push(new this.constructor.buttons[name]({
editor: this.editor
}));
@@ -1993,41 +2077,10 @@
if (this.opts.toolbarHidden) {
return this.wrapper.hide();
}
};
- Toolbar.prototype.toolbarStatus = function(name) {
- var buttons;
- if (!this.editor.inputManager.focused) {
- return;
- }
- buttons = this.buttons.slice(0);
- return this.editor.util.traverseUp((function(_this) {
- return function(node) {
- var button, i, j, k, len, len1, removeButtons;
- removeButtons = [];
- for (i = j = 0, len = buttons.length; j < len; i = ++j) {
- button = buttons[i];
- if ((name != null) && button.name !== name) {
- continue;
- }
- if (!button.status || button.status($(node)) === true) {
- removeButtons.push(button);
- }
- }
- for (k = 0, len1 = removeButtons.length; k < len1; k++) {
- button = removeButtons[k];
- i = $.inArray(button, buttons);
- buttons.splice(i, 1);
- }
- if (buttons.length === 0) {
- return false;
- }
- };
- })(this));
- };
-
Toolbar.prototype.findButton = function(name) {
var button;
button = this.list.find('.toolbar-item-' + name).data('button');
return button != null ? button : null;
};
@@ -2068,44 +2121,55 @@
};
})(this));
};
Indentation.prototype.indent = function(isBackward) {
- var $blockEls, $endBlock, $startBlock, range, result;
- range = this.editor.selection.getRange();
- if (!range) {
- return;
- }
- $startBlock = this.editor.util.closestBlockEl(range.startContainer);
- $endBlock = this.editor.util.closestBlockEl(range.endContainer);
- if (!($startBlock.is('li') && $endBlock.is('li') && $startBlock.parent().is($endBlock.parent()))) {
- $startBlock = this.editor.util.furthestBlockEl($startBlock);
- $endBlock = this.editor.util.furthestBlockEl($endBlock);
- }
- if ($startBlock.is($endBlock)) {
- $blockEls = $startBlock;
- } else {
- $blockEls = $startBlock.nextUntil($endBlock).add($startBlock).add($endBlock);
- }
+ var $blockNodes, $endNodes, $startNodes, nodes, result;
+ $startNodes = this.editor.selection.startNodes();
+ $endNodes = this.editor.selection.endNodes();
+ $blockNodes = this.editor.selection.blockNodes();
+ nodes = [];
+ $blockNodes = $blockNodes.each(function(i, node) {
+ var include, j, k, len, n;
+ include = true;
+ for (j = k = 0, len = nodes.length; k < len; j = ++k) {
+ n = nodes[j];
+ if ($.contains(node, n)) {
+ include = false;
+ break;
+ } else if ($.contains(n, node)) {
+ nodes.splice(j, 1, node);
+ include = false;
+ break;
+ }
+ }
+ if (include) {
+ return nodes.push(node);
+ }
+ });
+ $blockNodes = $(nodes);
result = false;
- $blockEls.each((function(_this) {
+ $blockNodes.each((function(_this) {
return function(i, blockEl) {
- return result = isBackward ? _this.outdentBlock(blockEl) : _this.indentBlock(blockEl);
+ var r;
+ r = isBackward ? _this.outdentBlock(blockEl) : _this.indentBlock(blockEl);
+ if (r) {
+ return result = r;
+ }
};
})(this));
return result;
};
Indentation.prototype.indentBlock = function(blockEl) {
- var $blockEl, $childList, $nextTd, $nextTr, $parentLi, $pre, $td, $tr, marginLeft, range, tagName;
+ var $blockEl, $childList, $nextTd, $nextTr, $parentLi, $pre, $td, $tr, marginLeft, tagName;
$blockEl = $(blockEl);
if (!$blockEl.length) {
return;
}
if ($blockEl.is('pre')) {
- range = this.editor.selection.getRange();
- $pre = $(range.commonAncestorContainer);
+ $pre = this.editor.selection.containerNode;
if (!($pre.is($blockEl) || $pre.closest('pre').is($blockEl))) {
return;
}
this.indentText(range);
} else if ($blockEl.is('li')) {
@@ -2125,25 +2189,26 @@
} else if ($blockEl.is('p, h1, h2, h3, h4')) {
marginLeft = parseInt($blockEl.css('margin-left')) || 0;
marginLeft = (Math.round(marginLeft / this.opts.indentWidth) + 1) * this.opts.indentWidth;
$blockEl.css('margin-left', marginLeft);
} else if ($blockEl.is('table') || $blockEl.is('.simditor-table')) {
- range = this.editor.selection.getRange();
- $td = $(range.commonAncestorContainer).closest('td, th');
+ $td = this.editor.selection.containerNode.closest('td, th');
$nextTd = $td.next('td, th');
if (!($nextTd.length > 0)) {
$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;
+ return;
}
this.editor.selection.setRangeAtEndOf($nextTd);
+ } else {
+ return false;
}
return true;
};
Indentation.prototype.indentText = function(range) {
@@ -2152,55 +2217,55 @@
textNode = document.createTextNode(text || '\u00A0\u00A0');
range.deleteContents();
range.insertNode(textNode);
if (text) {
range.selectNode(textNode);
- return this.editor.selection.selectRange(range);
+ return this.editor.selection.range(range);
} else {
return this.editor.selection.setRangeAfter(textNode);
}
};
Indentation.prototype.outdentBlock = function(blockEl) {
- var $blockEl, $parent, $parentLi, $pre, $prevTd, $prevTr, $td, $tr, button, marginLeft, range;
+ var $blockEl, $parent, $parentLi, $pre, $prevTd, $prevTr, $td, $tr, marginLeft, range;
$blockEl = $(blockEl);
if (!($blockEl && $blockEl.length > 0)) {
return;
}
if ($blockEl.is('pre')) {
- range = this.editor.selection.getRange();
- $pre = $(range.commonAncestorContainer);
+ $pre = this.editor.selection.containerNode;
if (!($pre.is($blockEl) || $pre.closest('pre').is($blockEl))) {
return;
}
this.outdentText(range);
} else if ($blockEl.is('li')) {
$parent = $blockEl.parent();
$parentLi = $parent.parent('li');
+ this.editor.selection.save();
if ($parentLi.length < 1) {
- button = this.editor.toolbar.findButton($parent[0].tagName.toLowerCase());
- if (button != null) {
- button.command();
+ range = document.createRange();
+ range.setStartBefore($parent[0]);
+ range.setEndBefore($blockEl[0]);
+ $parent.before(range.extractContents());
+ $('<p/>').insertBefore($parent).after($blockEl.children('ul, ol')).append($blockEl.contents());
+ $blockEl.remove();
+ } else {
+ if ($blockEl.next('li').length > 0) {
+ $('<' + $parent[0].tagName + '/>').append($blockEl.nextAll('li')).appendTo($blockEl);
}
- return;
+ $blockEl.insertAfter($parentLi);
+ if ($parent.children('li').length < 1) {
+ $parent.remove();
+ }
}
- this.editor.selection.save();
- if ($blockEl.next('li').length > 0) {
- $('<' + $parent[0].tagName + '/>').append($blockEl.nextAll('li')).appendTo($blockEl);
- }
- $blockEl.insertAfter($parentLi);
- if ($parent.children('li').length < 1) {
- $parent.remove();
- }
this.editor.selection.restore();
} else if ($blockEl.is('p, h1, h2, h3, h4')) {
marginLeft = parseInt($blockEl.css('margin-left')) || 0;
marginLeft = Math.max(Math.round(marginLeft / this.opts.indentWidth) - 1, 0) * this.opts.indentWidth;
$blockEl.css('margin-left', marginLeft === 0 ? '' : marginLeft);
} else if ($blockEl.is('table') || $blockEl.is('.simditor-table')) {
- range = this.editor.selection.getRange();
- $td = $(range.commonAncestorContainer).closest('td, th');
+ $td = this.editor.selection.containerNode.closest('td, th');
$prevTd = $td.prev('td, th');
if (!($prevTd.length > 0)) {
$tr = $td.parent('tr');
$prevTr = $tr.prev('tr');
if ($prevTr.length < 1 && $tr.parent().is('tbody')) {
@@ -2210,10 +2275,12 @@
}
if (!($td.length > 0 && $prevTd.length > 0)) {
return;
}
this.editor.selection.setRangeAtEndOf($prevTd);
+ } else {
+ return false;
}
return true;
};
Indentation.prototype.outdentText = function(range) {};
@@ -2231,18 +2298,18 @@
Simditor.connect(Util);
Simditor.connect(InputManager);
+ Simditor.connect(Selection);
+
Simditor.connect(UndoManager);
Simditor.connect(Keystroke);
Simditor.connect(Formatter);
- Simditor.connect(Selection);
-
Simditor.connect(Toolbar);
Simditor.connect(Indentation);
Simditor.count = 0;
@@ -2298,22 +2365,22 @@
};
})(this));
if (this.util.browser.mozilla) {
this.util.reflow();
try {
- document.execCommand("enableObjectResizing", false, false);
- return document.execCommand("enableInlineTableEditing", false, false);
+ document.execCommand('enableObjectResizing', false, false);
+ return document.execCommand('enableInlineTableEditing', false, false);
} catch (_error) {
e = _error;
}
}
};
Simditor.prototype._tpl = "<div class=\"simditor\">\n <div class=\"simditor-wrapper\">\n <div class=\"simditor-placeholder\"></div>\n <div class=\"simditor-body\" contenteditable=\"true\">\n </div>\n </div>\n</div>";
Simditor.prototype._render = function() {
- var key, ref, results1, val;
+ var key, ref, results, val;
this.el = $(this._tpl).insertBefore(this.textarea);
this.wrapper = this.el.find('.simditor-wrapper');
this.body = this.wrapper.find('.simditor-body');
this.placeholderEl = this.wrapper.find('.simditor-placeholder').append(this.opts.placeholder);
this.el.data('simditor', this);
@@ -2328,20 +2395,20 @@
if (this.util.os.mobile) {
this.el.addClass('simditor-mobile');
}
if (this.opts.params) {
ref = this.opts.params;
- results1 = [];
+ results = [];
for (key in ref) {
val = ref[key];
- results1.push($('<input/>', {
+ results.push($('<input/>', {
type: 'hidden',
name: key,
value: val
}).insertAfter(this.textarea));
}
- return results1;
+ return results;
}
};
Simditor.prototype._placeholder = function() {
var children;
@@ -2487,10 +2554,54 @@
'alignment': '水平对齐',
'alignCenter': '居中',
'alignLeft': '居左',
'alignRight': '居右',
'selectLanguage': '选择程序语言'
+ },
+ 'en-US': {
+ 'blockquote': 'Block Quote',
+ 'bold': 'Bold',
+ 'code': 'Code',
+ 'color': 'Text Color',
+ 'hr': 'Horizontal Line',
+ 'image': 'Insert Image',
+ 'externalImage': 'External Image',
+ 'uploadImage': 'Upload Image',
+ 'uploadFailed': 'Upload failed',
+ 'uploadError': 'Error occurs during upload',
+ 'imageUrl': 'Url',
+ 'imageSize': 'Size',
+ 'imageAlt': 'Alt',
+ 'restoreImageSize': 'Restore Origin Size',
+ 'uploading': 'Uploading',
+ 'indent': 'Indent',
+ 'outdent': 'Outdent',
+ 'italic': 'Italic',
+ 'link': 'Insert Link',
+ 'text': 'Text',
+ 'linkText': 'Link Text',
+ 'linkUrl': 'Link Url',
+ 'removeLink': 'Remove Link',
+ 'ol': 'Ordered List',
+ 'ul': 'Unordered List',
+ 'strikethrough': 'Strikethrough',
+ 'table': 'Table',
+ 'deleteRow': 'Delete Row',
+ 'insertRowAbove': 'Insert Row Above',
+ 'insertRowBelow': 'Insert Row Below',
+ 'deleteColumn': 'Delete Column',
+ 'insertColumnLeft': 'Insert Column Left',
+ 'insertColumnRight': 'Insert Column Right',
+ 'deleteTable': 'Delete Table',
+ 'title': 'Title',
+ 'normalText': 'Text',
+ 'underline': 'Underline',
+ 'alignment': 'Alignment',
+ 'alignCenter': 'Align Center',
+ 'alignLeft': 'Align Left',
+ 'alignRight': 'Align Right',
+ 'selectLanguage': 'Select Language'
}
};
Button = (function(superClass) {
extend(Button, superClass);
@@ -2529,17 +2640,18 @@
this.title = this._t(this.name);
Button.__super__.constructor.call(this, opts);
}
Button.prototype._init = function() {
- var j, len, ref, results1, tag;
+ var k, len, ref, tag;
this.render();
this.el.on('mousedown', (function(_this) {
return function(e) {
- var exceed, param;
+ var exceed, noFocus, param;
e.preventDefault();
- if (_this.el.hasClass('disabled') || (_this.needFocus && !_this.editor.inputManager.focused)) {
+ noFocus = _this.needFocus && !_this.editor.inputManager.focused;
+ if (_this.el.hasClass('disabled') || noFocus) {
return false;
}
if (_this.menu) {
_this.wrapper.toggleClass('menu-on').siblings('li').removeClass('menu-on');
if (_this.wrapper.is('.menu-on')) {
@@ -2559,31 +2671,32 @@
return false;
};
})(this));
this.wrapper.on('click', 'a.menu-item', (function(_this) {
return function(e) {
- var btn, param;
+ var btn, noFocus, param;
e.preventDefault();
btn = $(e.currentTarget);
_this.wrapper.removeClass('menu-on');
- if (btn.hasClass('disabled') || (_this.needFocus && !_this.editor.inputManager.focused)) {
+ noFocus = _this.needFocus && !_this.editor.inputManager.focused;
+ if (btn.hasClass('disabled') || noFocus) {
return false;
}
_this.editor.toolbar.wrapper.removeClass('menu-on');
param = btn.data('param');
_this.command(param);
return false;
};
})(this));
- this.wrapper.on('mousedown', 'a.menu-item', (function(_this) {
- return function(e) {
- return false;
- };
- })(this));
+ this.wrapper.on('mousedown', 'a.menu-item', function(e) {
+ return false;
+ });
this.editor.on('blur', (function(_this) {
return function() {
- if (!(_this.editor.body.is(':visible') && _this.editor.body.is('[contenteditable]'))) {
+ var editorActive;
+ editorActive = _this.editor.body.is(':visible') && _this.editor.body.is('[contenteditable]');
+ if (!editorActive) {
return;
}
_this.setActive(false);
return _this.setDisabled(false);
};
@@ -2595,21 +2708,24 @@
return false;
};
})(this));
}
ref = this.htmlTag.split(',');
- results1 = [];
- for (j = 0, len = ref.length; j < len; j++) {
- tag = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ tag = ref[k];
tag = $.trim(tag);
if (tag && $.inArray(tag, this.editor.formatter._allowedTags) < 0) {
- results1.push(this.editor.formatter._allowedTags.push(tag));
- } else {
- results1.push(void 0);
+ this.editor.formatter._allowedTags.push(tag);
}
}
- return results1;
+ return this.editor.on('selectionchanged', (function(_this) {
+ return function(e) {
+ if (_this.editor.inputManager.focused) {
+ return _this._status();
+ }
+ };
+ })(this));
};
Button.prototype.iconClassOf = function(icon) {
if (icon) {
return "simditor-icon simditor-icon-" + icon;
@@ -2634,68 +2750,85 @@
this.menuWrapper.addClass("toolbar-menu-" + this.name);
return this.renderMenu();
};
Button.prototype.renderMenu = function() {
- var $menuBtnEl, $menuItemEl, j, len, menuItem, ref, ref1, results1;
+ var $menuBtnEl, $menuItemEl, k, len, menuItem, ref, ref1, results;
if (!$.isArray(this.menu)) {
return;
}
this.menuEl = $('<ul/>').appendTo(this.menuWrapper);
ref = this.menu;
- results1 = [];
- for (j = 0, len = ref.length; j < len; j++) {
- menuItem = ref[j];
+ results = [];
+ for (k = 0, len = ref.length; k < len; k++) {
+ menuItem = ref[k];
if (menuItem === '|') {
$(this._tpl.separator).appendTo(this.menuEl);
continue;
}
$menuItemEl = $(this._tpl.menuItem).appendTo(this.menuEl);
$menuBtnEl = $menuItemEl.find('a.menu-item').attr({
'title': (ref1 = menuItem.title) != null ? ref1 : menuItem.text,
'data-param': menuItem.param
}).addClass('menu-item-' + menuItem.name);
if (menuItem.icon) {
- results1.push($menuBtnEl.find('span').addClass(this.iconClassOf(menuItem.icon)));
+ results.push($menuBtnEl.find('span').addClass(this.iconClassOf(menuItem.icon)));
} else {
- results1.push($menuBtnEl.find('span').text(menuItem.text));
+ results.push($menuBtnEl.find('span').text(menuItem.text));
}
}
- return results1;
+ return results;
};
Button.prototype.setActive = function(active) {
if (active === this.active) {
return;
}
this.active = active;
- this.el.toggleClass('active', this.active);
- return this.editor.toolbar.trigger('buttonstatus', [this]);
+ return this.el.toggleClass('active', this.active);
};
Button.prototype.setDisabled = function(disabled) {
if (disabled === this.disabled) {
return;
}
this.disabled = disabled;
- this.el.toggleClass('disabled', this.disabled);
- return this.editor.toolbar.trigger('buttonstatus', [this]);
+ return this.el.toggleClass('disabled', this.disabled);
};
- Button.prototype.status = function($node) {
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
+ Button.prototype._disableStatus = function() {
+ var disabled, endNodes, startNodes;
+ startNodes = this.editor.selection.startNodes();
+ endNodes = this.editor.selection.endNodes();
+ disabled = startNodes.filter(this.disableTag).length > 0 || endNodes.filter(this.disableTag).length > 0;
+ this.setDisabled(disabled);
if (this.disabled) {
- return true;
+ this.setActive(false);
}
- if ($node != null) {
- this.setActive($node.is(this.htmlTag));
- }
+ return this.disabled;
+ };
+
+ Button.prototype._activeStatus = function() {
+ var active, endNode, endNodes, startNode, startNodes;
+ startNodes = this.editor.selection.startNodes();
+ endNodes = this.editor.selection.endNodes();
+ startNode = startNodes.filter(this.htmlTag);
+ endNode = endNodes.filter(this.htmlTag);
+ active = startNode.length > 0 && endNode.length > 0 && startNode.is(endNode);
+ this.node = active ? startNode : null;
+ this.setActive(active);
return this.active;
};
+ Button.prototype._status = function() {
+ this._disableStatus();
+ if (this.disabled) {
+ return;
+ }
+ return this._activeStatus();
+ };
+
Button.prototype.command = function(param) {};
Button.prototype._t = function() {
var args, ref, result;
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
@@ -2752,18 +2885,16 @@
position = 'bottom';
}
if ($target == null) {
return;
}
- this.el.siblings('.simditor-popover').each((function(_this) {
- return function(i, popover) {
- popover = $(popover).data('popover');
- if (popover.active) {
- return popover.hide();
- }
- };
- })(this));
+ this.el.siblings('.simditor-popover').each(function(i, popover) {
+ popover = $(popover).data('popover');
+ if (popover.active) {
+ return popover.hide();
+ }
+ });
if (this.active && this.target) {
this.target.removeClass('selected');
}
this.target = $target.addClass('selected');
if (this.active) {
@@ -2772,16 +2903,13 @@
} else {
this.active = true;
this.el.css({
left: -9999
}).show();
- return setTimeout((function(_this) {
- return function() {
- _this.refresh(position);
- return _this.trigger('popovershow');
- };
- })(this), 0);
+ this.editor.util.reflow();
+ this.refresh(position);
+ return this.trigger('popovershow');
}
};
Popover.prototype.hide = function() {
if (!this.active) {
@@ -2795,11 +2923,11 @@
this.el.hide();
return this.trigger('popoverhide');
};
Popover.prototype.refresh = function(position) {
- var editorOffset, left, targetH, targetOffset, top;
+ var editorOffset, left, maxLeft, targetH, targetOffset, top;
if (position == null) {
position = 'bottom';
}
if (!this.active) {
return;
@@ -2810,11 +2938,12 @@
if (position === 'bottom') {
top = targetOffset.top - editorOffset.top + targetH;
} else if (position === 'top') {
top = targetOffset.top - editorOffset.top - this.el.height();
}
- left = Math.min(targetOffset.left - editorOffset.left, this.editor.wrapper.width() - this.el.outerWidth() - 10);
+ maxLeft = this.editor.wrapper.width() - this.el.outerWidth() - 10;
+ left = Math.min(targetOffset.left - editorOffset.left, maxLeft);
return this.el.css({
top: top + this.offset.top,
left: left + this.offset.left
});
};
@@ -2886,77 +3015,37 @@
return TitleButton.__super__._init.call(this);
};
TitleButton.prototype.setActive = function(active, param) {
TitleButton.__super__.setActive.call(this, active);
+ if (active) {
+ param || (param = this.node[0].tagName.toLowerCase());
+ }
this.el.removeClass('active-p active-h1 active-h2 active-h3');
if (active) {
return this.el.addClass('active active-' + param);
}
};
- TitleButton.prototype.status = function($node) {
- var param, ref;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
- if ($node != null) {
- param = (ref = $node[0].tagName) != null ? ref.toLowerCase() : void 0;
- this.setActive($node.is(this.htmlTag), param);
- }
- return this.active;
- };
-
TitleButton.prototype.command = function(param) {
- var $contents, $endBlock, $startBlock, endNode, j, len, node, range, ref, results, startNode;
- range = this.editor.selection.getRange();
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.closestBlockEl(startNode);
- $endBlock = this.editor.util.closestBlockEl(endNode);
+ var $rootNodes;
+ $rootNodes = this.editor.selection.rootNodes();
this.editor.selection.save();
- range.setStartBefore($startBlock[0]);
- range.setEndAfter($endBlock[0]);
- $contents = $(range.extractContents());
- results = [];
- $contents.children().each((function(_this) {
- return function(i, el) {
- var c, converted, j, len, results1;
- converted = _this._convertEl(el, param);
- results1 = [];
- for (j = 0, len = converted.length; j < len; j++) {
- c = converted[j];
- results1.push(results.push(c));
+ $rootNodes.each((function(_this) {
+ return function(i, node) {
+ var $node;
+ $node = $(node);
+ if ($node.is('blockquote') || $node.is(param) || $node.is(_this.disableTag) || _this.editor.util.isDecoratedNode($node)) {
+ return;
}
- return results1;
+ return $('<' + param + '/>').append($node.contents()).replaceAll($node);
};
})(this));
- ref = results.reverse();
- for (j = 0, len = ref.length; j < len; j++) {
- node = ref[j];
- range.insertNode(node[0]);
- }
this.editor.selection.restore();
return this.editor.trigger('valuechanged');
};
- TitleButton.prototype._convertEl = function(el, param) {
- var $block, $el, results;
- $el = $(el);
- results = [];
- if ($el.is(param)) {
- results.push($el);
- } else {
- $block = $('<' + param + '/>').append($el.contents());
- results.push($block);
- }
- return results;
- };
-
return TitleButton;
})(Button);
Simditor.Toolbar.addButton(TitleButton);
@@ -2986,21 +3075,15 @@
this.shortcut = 'ctrl+b';
}
return BoldButton.__super__._init.call(this);
};
- BoldButton.prototype.status = function($node) {
+ BoldButton.prototype._activeStatus = function() {
var active;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
active = document.queryCommandState('bold') === true;
this.setActive(active);
- return active;
+ return this.active;
};
BoldButton.prototype.command = function() {
document.execCommand('bold');
if (!this.editor.util.support.oninput) {
@@ -3032,29 +3115,23 @@
ItalicButton.prototype.shortcut = 'cmd+i';
ItalicButton.prototype._init = function() {
if (this.editor.util.os.mac) {
- this.title = this.title + ' ( Cmd + i )';
+ this.title = this.title + " ( Cmd + i )";
} else {
- this.title = this.title + ' ( Ctrl + i )';
+ this.title = this.title + " ( Ctrl + i )";
this.shortcut = 'ctrl+i';
}
return ItalicButton.__super__._init.call(this);
};
- ItalicButton.prototype.status = function($node) {
+ ItalicButton.prototype._activeStatus = function() {
var active;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return this.disabled;
- }
active = document.queryCommandState('italic') === true;
this.setActive(active);
- return active;
+ return this.active;
};
ItalicButton.prototype.command = function() {
document.execCommand('italic');
if (!this.editor.util.support.oninput) {
@@ -3094,21 +3171,15 @@
this.shortcut = 'ctrl+u';
}
return UnderlineButton.__super__.render.call(this);
};
- UnderlineButton.prototype.status = function($node) {
+ UnderlineButton.prototype._activeStatus = function() {
var active;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return this.disabled;
- }
active = document.queryCommandState('underline') === true;
this.setActive(active);
- return active;
+ return this.active;
};
UnderlineButton.prototype.command = function() {
document.execCommand('underline');
if (!this.editor.util.support.oninput) {
@@ -3143,11 +3214,11 @@
args = 1 <= arguments.length ? slice.call(arguments, 0) : [];
return ColorButton.__super__.render.apply(this, args);
};
ColorButton.prototype.renderMenu = function() {
- $('<ul class="color-list">\n <li><a href="javascript:;" class="font-color font-color-1" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-2" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-3" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-4" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-5" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-6" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-7" data-color=""></a></li>\n <li><a href="javascript:;" class="font-color font-color-default" data-color=""></a></li>\n</ul>').appendTo(this.menuWrapper);
+ $('<ul class="color-list">\n <li><a href="javascript:;" class="font-color font-color-1"></a></li>\n <li><a href="javascript:;" class="font-color font-color-2"></a></li>\n <li><a href="javascript:;" class="font-color font-color-3"></a></li>\n <li><a href="javascript:;" class="font-color font-color-4"></a></li>\n <li><a href="javascript:;" class="font-color font-color-5"></a></li>\n <li><a href="javascript:;" class="font-color font-color-6"></a></li>\n <li><a href="javascript:;" class="font-color font-color-7"></a></li>\n <li><a href="javascript:;" class="font-color font-color-default"></a></li>\n</ul>').appendTo(this.menuWrapper);
this.menuWrapper.on('mousedown', '.color-list', function(e) {
return false;
});
return this.menuWrapper.on('click', '.font-color', (function(_this) {
return function(e) {
@@ -3166,11 +3237,13 @@
hex = _this._convertRgbToHex(rgb);
}
if (!hex) {
return;
}
+ document.execCommand('styleWithCSS', false, true);
document.execCommand('foreColor', false, hex);
+ document.execCommand('styleWithCSS', false, false);
if (!_this.editor.util.support.oninput) {
return _this.editor.trigger('valuechanged');
}
};
})(this));
@@ -3214,133 +3287,47 @@
ListButton.prototype.type = '';
ListButton.prototype.disableTag = 'pre, table';
- ListButton.prototype.status = function($node) {
- var anotherType;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
- if ($node == null) {
- return this.active;
- }
- anotherType = this.type === 'ul' ? 'ol' : 'ul';
- if ($node.is(anotherType)) {
- this.setActive(false);
- return true;
- } else {
- this.setActive($node.is(this.htmlTag));
- return this.active;
- }
- };
-
ListButton.prototype.command = function(param) {
- var $contents, $endBlock, $furthestEnd, $furthestStart, $parent, $startBlock, endLevel, endNode, getListLevel, j, len, node, range, ref, results, startLevel, startNode;
- range = this.editor.selection.getRange();
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.closestBlockEl(startNode);
- $endBlock = this.editor.util.closestBlockEl(endNode);
+ var $list, $rootNodes, anotherType;
+ $rootNodes = this.editor.selection.blockNodes();
+ anotherType = this.type === 'ul' ? 'ol' : 'ul';
this.editor.selection.save();
- range.setStartBefore($startBlock[0]);
- range.setEndAfter($endBlock[0]);
- if ($startBlock.is('li') && $endBlock.is('li')) {
- $furthestStart = this.editor.util.furthestNode($startBlock, 'ul, ol');
- $furthestEnd = this.editor.util.furthestNode($endBlock, 'ul, ol');
- if ($furthestStart.is($furthestEnd)) {
- getListLevel = function($li) {
- var lvl;
- lvl = 1;
- while (!$li.parent().is($furthestStart)) {
- lvl += 1;
- $li = $li.parent();
- }
- return lvl;
- };
- startLevel = getListLevel($startBlock);
- endLevel = getListLevel($endBlock);
- if (startLevel > endLevel) {
- $parent = $endBlock.parent();
+ $list = null;
+ $rootNodes.each((function(_this) {
+ return function(i, node) {
+ var $node;
+ $node = $(node);
+ if ($node.is('blockquote, li') || $node.is(_this.disableTag) || _this.editor.util.isDecoratedNode($node) || !$.contains(document, node)) {
+ return;
+ }
+ if ($node.is(_this.type)) {
+ $node.children('li').each(function(i, li) {
+ var $childList, $li;
+ $li = $(li);
+ $childList = $li.children('ul, ol').insertAfter($node);
+ return $('<p/>').append($(li).html() || _this.editor.util.phBr).insertBefore($node);
+ });
+ return $node.remove();
+ } else if ($node.is(anotherType)) {
+ return $('<' + _this.type + '/>').append($node.contents()).replaceAll($node);
+ } else if ($list && $node.prev().is($list)) {
+ $('<li/>').append($node.html() || _this.editor.util.phBr).appendTo($list);
+ return $node.remove();
} else {
- $parent = $startBlock.parent();
+ $list = $("<" + _this.type + "><li></li></" + _this.type + ">");
+ $list.find('li').append($node.html() || _this.editor.util.phBr);
+ return $list.replaceAll($node);
}
- range.setStartBefore($parent[0]);
- range.setEndAfter($parent[0]);
- } else {
- range.setStartBefore($furthestStart[0]);
- range.setEndAfter($furthestEnd[0]);
- }
- }
- $contents = $(range.extractContents());
- results = [];
- $contents.children().each((function(_this) {
- return function(i, el) {
- var c, converted, j, len, results1;
- converted = _this._convertEl(el);
- results1 = [];
- for (j = 0, len = converted.length; j < len; j++) {
- c = converted[j];
- if (results.length && results[results.length - 1].is(_this.type) && c.is(_this.type)) {
- results1.push(results[results.length - 1].append(c.children()));
- } else {
- results1.push(results.push(c));
- }
- }
- return results1;
};
})(this));
- ref = results.reverse();
- for (j = 0, len = ref.length; j < len; j++) {
- node = ref[j];
- range.insertNode(node[0]);
- }
this.editor.selection.restore();
return this.editor.trigger('valuechanged');
};
- ListButton.prototype._convertEl = function(el) {
- var $el, anotherType, block, child, children, j, len, ref, results;
- $el = $(el);
- results = [];
- anotherType = this.type === 'ul' ? 'ol' : 'ul';
- if ($el.is(this.type)) {
- $el.children('li').each((function(_this) {
- return function(i, li) {
- var $childList, $li, block;
- $li = $(li);
- $childList = $li.children('ul, ol').remove();
- block = $('<p/>').append($(li).html() || _this.editor.util.phBr);
- results.push(block);
- if ($childList.length > 0) {
- return results.push($childList);
- }
- };
- })(this));
- } else if ($el.is(anotherType)) {
- block = $('<' + this.type + '/>').append($el.html());
- results.push(block);
- } else if ($el.is('blockquote')) {
- ref = $el.children().get();
- for (j = 0, len = ref.length; j < len; j++) {
- child = ref[j];
- children = this._convertEl(child);
- }
- $.merge(results, children);
- } else if ($el.is('table')) {
-
- } else {
- block = $('<' + this.type + '><li></li></' + this.type + '>');
- block.find('li').append($el.html() || this.editor.util.phBr);
- results.push(block);
- }
- return results;
- };
-
return ListButton;
})(Button);
OrderListButton = (function(superClass) {
@@ -3423,63 +3410,44 @@
BlockquoteButton.prototype.htmlTag = 'blockquote';
BlockquoteButton.prototype.disableTag = 'pre, table';
BlockquoteButton.prototype.command = function() {
- var $contents, $endBlock, $startBlock, endNode, j, len, node, range, ref, results, startNode;
- range = this.editor.selection.getRange();
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.furthestBlockEl(startNode);
- $endBlock = this.editor.util.furthestBlockEl(endNode);
+ var $rootNodes, clearCache, nodeCache;
+ $rootNodes = this.editor.selection.rootNodes();
this.editor.selection.save();
- range.setStartBefore($startBlock[0]);
- range.setEndAfter($endBlock[0]);
- $contents = $(range.extractContents());
- results = [];
- $contents.children().each((function(_this) {
- return function(i, el) {
- var c, converted, j, len, results1;
- converted = _this._convertEl(el);
- results1 = [];
- for (j = 0, len = converted.length; j < len; j++) {
- c = converted[j];
- if (results.length && results[results.length - 1].is(_this.htmlTag) && c.is(_this.htmlTag)) {
- results1.push(results[results.length - 1].append(c.children()));
- } else {
- results1.push(results.push(c));
- }
+ nodeCache = [];
+ clearCache = (function(_this) {
+ return function() {
+ if (nodeCache.length > 0) {
+ $("<" + _this.htmlTag + "/>").insertBefore(nodeCache[0]).append(nodeCache);
+ return nodeCache.length = 0;
}
- return results1;
};
+ })(this);
+ $rootNodes.each((function(_this) {
+ return function(i, node) {
+ var $node;
+ $node = $(node);
+ if (!$node.parent().is(_this.editor.body)) {
+ return;
+ }
+ if ($node.is(_this.htmlTag)) {
+ clearCache();
+ return $node.children().unwrap();
+ } else if ($node.is(_this.disableTag) || _this.editor.util.isDecoratedNode($node)) {
+ return clearCache();
+ } else {
+ return nodeCache.push(node);
+ }
+ };
})(this));
- ref = results.reverse();
- for (j = 0, len = ref.length; j < len; j++) {
- node = ref[j];
- range.insertNode(node[0]);
- }
+ clearCache();
this.editor.selection.restore();
return this.editor.trigger('valuechanged');
};
- BlockquoteButton.prototype._convertEl = function(el) {
- var $el, block, results;
- $el = $(el);
- results = [];
- if ($el.is(this.htmlTag)) {
- $el.children().each((function(_this) {
- return function(i, node) {
- return results.push($(node));
- };
- })(this));
- } else {
- block = $('<' + this.htmlTag + '/>').append($el);
- results.push(block);
- }
- return results;
- };
-
return BlockquoteButton;
})(Button);
Simditor.Toolbar.addButton(BlockquoteButton);
@@ -3495,11 +3463,11 @@
CodeButton.prototype.icon = 'code';
CodeButton.prototype.htmlTag = 'pre';
- CodeButton.prototype.disableTag = 'li, table';
+ CodeButton.prototype.disableTag = 'ul, ol, table';
CodeButton.prototype._init = function() {
CodeButton.__super__._init.call(this);
this.editor.on('decorate', (function(_this) {
return function(e, $el) {
@@ -3524,19 +3492,17 @@
return this.popover = new CodePopover({
button: this
});
};
- CodeButton.prototype.status = function($node) {
- var result;
- result = CodeButton.__super__.status.call(this, $node);
+ CodeButton.prototype._status = function() {
+ CodeButton.__super__._status.call(this);
if (this.active) {
- this.popover.show($node);
- } else if (this.editor.util.isBlockNode($node)) {
- this.popover.hide();
+ return this.popover.show(this.node);
+ } else {
+ return this.popover.hide();
}
- return result;
};
CodeButton.prototype.decorate = function($pre) {
var $code, lang, ref, ref1;
$code = $pre.find('> code');
@@ -3558,64 +3524,44 @@
}
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();
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.closestBlockEl(startNode);
- $endBlock = this.editor.util.closestBlockEl(endNode);
- range.setStartBefore($startBlock[0]);
- range.setEndAfter($endBlock[0]);
- $contents = $(range.extractContents());
- results = [];
- $contents.children().each((function(_this) {
- return function(i, el) {
- var c, converted, j, len, results1;
- converted = _this._convertEl(el);
- results1 = [];
- for (j = 0, len = converted.length; j < len; j++) {
- c = converted[j];
- if (results.length && results[results.length - 1].is(_this.htmlTag) && c.is(_this.htmlTag)) {
- results1.push(results[results.length - 1].append(c.contents()));
- } else {
- results1.push(results.push(c));
- }
+ var $rootNodes, clearCache, nodeCache, pres;
+ $rootNodes = this.editor.selection.rootNodes();
+ nodeCache = [];
+ pres = [];
+ clearCache = (function(_this) {
+ return function() {
+ var $pre;
+ if (!(nodeCache.length > 0)) {
+ return;
}
- return results1;
+ $pre = $("<" + _this.htmlTag + "/>").insertBefore(nodeCache[0]).text(_this.editor.formatter.clearHtml(nodeCache));
+ pres.push($pre[0]);
+ return nodeCache.length = 0;
};
+ })(this);
+ $rootNodes.each((function(_this) {
+ return function(i, node) {
+ var $node;
+ $node = $(node);
+ if ($node.is(_this.htmlTag)) {
+ clearCache();
+ return $('<p/>').append($node.html().replace('\n', '<br/>')).replaceAll($node);
+ } else if ($node.is(_this.disableTag) || _this.editor.util.isDecoratedNode($node) || $node.is('blockquote')) {
+ return clearCache();
+ } else {
+ return nodeCache.push(node);
+ }
+ };
})(this));
- ref = results.reverse();
- for (j = 0, len = ref.length; j < len; j++) {
- node = ref[j];
- range.insertNode(node[0]);
- }
- this.editor.selection.setRangeAtEndOf(results[0]);
+ clearCache();
+ this.editor.selection.setRangeAtEndOf($(pres).last());
return this.editor.trigger('valuechanged');
};
- CodeButton.prototype._convertEl = function(el) {
- var $el, block, codeStr, results;
- $el = $(el);
- results = [];
- if ($el.is(this.htmlTag)) {
- block = $('<p/>').append($el.html().replace('\n', '<br/>'));
- results.push(block);
- } else {
- if (!$el.text() && $el.children().length === 1 && $el.children().is('br')) {
- codeStr = '\n';
- } else {
- codeStr = this.editor.formatter.clearHtml($el);
- }
- block = $('<' + this.htmlTag + '/>').text(codeStr);
- results.push(block);
- }
- return results;
- };
-
return CodeButton;
})(Button);
CodePopover = (function(superClass) {
@@ -3624,11 +3570,11 @@
function CodePopover() {
return CodePopover.__super__.constructor.apply(this, arguments);
}
CodePopover.prototype.render = function() {
- var $option, j, lang, len, ref;
+ var $option, k, lang, len, ref;
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 </select>\n </div>\n</div>";
this.langs = this.editor.opts.codeLanguages || [
{
name: 'Bash',
value: 'bash'
@@ -3692,12 +3638,12 @@
}
];
this.el.addClass('code-popover').append(this._tpl);
this.selectEl = this.el.find('.select-lang');
ref = this.langs;
- for (j = 0, len = ref.length; j < len; j++) {
- lang = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ lang = ref[k];
$option = $('<option/>', {
text: lang.name,
value: lang.value
}).appendTo(this.selectEl);
}
@@ -3765,60 +3711,35 @@
return this.popover = new LinkPopover({
button: this
});
};
- LinkButton.prototype.status = function($node) {
- var showPopover;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
- if ($node == null) {
- return this.active;
- }
- showPopover = true;
- if (!$node.is(this.htmlTag) || $node.is('[class^="simditor-"]')) {
- this.setActive(false);
- showPopover = false;
- } else if (this.editor.selection.rangeAtEndOf($node)) {
- this.setActive(true);
- showPopover = false;
+ LinkButton.prototype._status = function() {
+ LinkButton.__super__._status.call(this);
+ if (this.active && !this.editor.selection.rangeAtEndOf(this.node)) {
+ return this.popover.show(this.node);
} else {
- this.setActive(true);
+ return this.popover.hide();
}
- if (showPopover) {
- this.popover.show($node);
- } else if (this.editor.util.isBlockNode($node)) {
- this.popover.hide();
- }
- return this.active;
};
LinkButton.prototype.command = function() {
- var $contents, $endBlock, $link, $newBlock, $startBlock, endNode, linkText, range, startNode, txtNode;
- range = this.editor.selection.getRange();
+ var $contents, $link, $newBlock, linkText, range, txtNode;
+ range = this.editor.selection.range();
if (this.active) {
- $link = $(range.commonAncestorContainer).closest('a');
- txtNode = document.createTextNode($link.text());
- $link.replaceWith(txtNode);
+ txtNode = document.createTextNode(this.node.text());
+ this.node.replaceWith(txtNode);
range.selectNode(txtNode);
} else {
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.closestBlockEl(startNode);
- $endBlock = this.editor.util.closestBlockEl(endNode);
$contents = $(range.extractContents());
linkText = this.editor.formatter.clearHtml($contents.contents(), false);
$link = $('<a/>', {
href: 'http://www.example.com',
target: '_blank',
text: linkText || this._t('linkText')
});
- if ($startBlock[0] === $endBlock[0]) {
+ if (this.editor.selection.blockNodes().length === 1) {
range.insertNode($link[0]);
} else {
$newBlock = $('<p/>').append($link);
range.insertNode($newBlock[0]);
}
@@ -3833,11 +3754,11 @@
return _this.popover.textEl[0].select();
}
};
})(this));
}
- this.editor.selection.selectRange(range);
+ this.editor.selection.range(range);
return this.editor.trigger('valuechanged');
};
return LinkButton;
@@ -3850,11 +3771,11 @@
return LinkPopover.__super__.constructor.apply(this, arguments);
}
LinkPopover.prototype.render = function() {
var tpl;
- tpl = "<div class=\"link-settings\">\n <div class=\"settings-field\">\n <label>" + (this._t('text')) + "</label>\n <input class=\"link-text\" type=\"text\"/>\n <a class=\"btn-unlink\" href=\"javascript:;\" title=\"" + (this._t('removeLink')) + "\" tabindex=\"-1\"><span class=\"simditor-icon simditor-icon-unlink\"></span></a>\n </div>\n <div class=\"settings-field\">\n <label>" + (this._t('linkUrl')) + "</label>\n <input class=\"link-url\" type=\"text\"/>\n </div>\n</div>";
+ tpl = "<div class=\"link-settings\">\n <div class=\"settings-field\">\n <label>" + (this._t('text')) + "</label>\n <input class=\"link-text\" type=\"text\"/>\n <a class=\"btn-unlink\" href=\"javascript:;\" title=\"" + (this._t('removeLink')) + "\"\n tabindex=\"-1\">\n <span class=\"simditor-icon simditor-icon-unlink\"></span>\n </a>\n </div>\n <div class=\"settings-field\">\n <label>" + (this._t('linkUrl')) + "</label>\n <input class=\"link-url\" type=\"text\"/>\n </div>\n</div>";
this.el.addClass('link-popover').append(tpl);
this.textEl = this.el.find('.link-text');
this.urlEl = this.el.find('.link-url');
this.unlinkEl = this.el.find('.btn-unlink');
this.textEl.on('keyup', (function(_this) {
@@ -3878,19 +3799,17 @@
return _this.target.attr('href', val);
};
})(this));
$([this.urlEl[0], this.textEl[0]]).on('keydown', (function(_this) {
return function(e) {
+ var range;
if (e.which === 13 || e.which === 27 || (!e.shiftKey && e.which === 9 && $(e.target).hasClass('link-url'))) {
e.preventDefault();
- return setTimeout(function() {
- var range;
- range = document.createRange();
- _this.editor.selection.setRangeAfter(_this.target, range);
- _this.hide();
- return _this.editor.trigger('valuechanged');
- }, 0);
+ range = document.createRange();
+ _this.editor.selection.setRangeAfter(_this.target, range);
+ _this.hide();
+ return _this.editor.trigger('valuechanged');
}
};
})(this));
return this.unlinkEl.on('click', (function(_this) {
return function(e) {
@@ -3937,17 +3856,17 @@
ImageButton.prototype.defaultImage = '';
ImageButton.prototype.needFocus = false;
ImageButton.prototype._init = function() {
- var item, j, len, ref;
+ var item, k, len, ref;
if (this.editor.opts.imageButton) {
if (Array.isArray(this.editor.opts.imageButton)) {
this.menu = [];
ref = this.editor.opts.imageButton;
- for (j = 0, len = ref.length; j < len; j++) {
- item = ref[j];
+ for (k = 0, len = ref.length; k < len; k++) {
+ item = ref[k];
this.menu.push({
name: item + '-image',
text: this._t(item + 'Image')
});
}
@@ -3974,26 +3893,24 @@
return function(e) {
var $img, range;
$img = $(e.currentTarget);
range = document.createRange();
range.selectNode($img[0]);
- _this.editor.selection.selectRange(range);
+ _this.editor.selection.range(range);
if (!_this.editor.util.support.onselectionchange) {
_this.editor.trigger('selectionchanged');
}
return false;
};
})(this));
- this.editor.body.on('mouseup', 'img:not([data-non-image])', (function(_this) {
- return function(e) {
- return false;
- };
- })(this));
+ this.editor.body.on('mouseup', 'img:not([data-non-image])', function(e) {
+ return false;
+ });
this.editor.on('selectionchanged.image', (function(_this) {
return function() {
var $contents, $img, range;
- range = _this.editor.selection.getRange();
+ range = _this.editor.selection.range();
if (range == null) {
return;
}
$contents = $(range.cloneContents()).contents();
if ($contents.length === 1 && $contents.is('img:not([data-non-image])')) {
@@ -4049,11 +3966,11 @@
ImageButton.__super__.renderMenu.call(this);
return this._initUploader();
};
ImageButton.prototype._initUploader = function($uploadItem) {
- var $input, createInput;
+ var $input, createInput, uploadProgress;
if ($uploadItem == null) {
$uploadItem = this.menuEl.find('.menu-item-upload-image');
}
if (this.editor.uploader == null) {
this.el.find('.btn-upload').remove();
@@ -4063,19 +3980,21 @@
createInput = (function(_this) {
return function() {
if ($input) {
$input.remove();
}
- return $input = $('<input type="file" title="' + _this._t('uploadImage') + '" accept="image/*">').appendTo($uploadItem);
+ return $input = $('<input/>', {
+ type: 'file',
+ title: _this._t('uploadImage'),
+ accept: 'image/*'
+ }).appendTo($uploadItem);
};
})(this);
createInput();
- $uploadItem.on('click mousedown', 'input[type=file]', (function(_this) {
- return function(e) {
- return e.stopPropagation();
- };
- })(this));
+ $uploadItem.on('click mousedown', 'input[type=file]', function(e) {
+ return e.stopPropagation();
+ });
$uploadItem.on('change', 'input[type=file]', (function(_this) {
return function(e) {
if (_this.editor.inputManager.focused) {
_this.editor.uploader.upload($input, {
inline: true
@@ -4120,11 +4039,11 @@
}
});
});
};
})(this));
- this.editor.uploader.on('uploadprogress', $.proxy(this.editor.util.throttle(function(e, file, loaded, total) {
+ uploadProgress = $.proxy(this.editor.util.throttle(function(e, file, loaded, total) {
var $img, $mask, percent;
if (!file.inline) {
return;
}
$mask = file.img.data('mask');
@@ -4140,11 +4059,12 @@
percent = (percent * 100).toFixed(0);
if (percent > 99) {
percent = 99;
}
return $mask.find('.progress').height((100 - percent) + "%");
- }, 500), this));
+ }, 500), this);
+ this.editor.uploader.on('uploadprogress', uploadProgress);
this.editor.uploader.on('uploadsuccess', (function(_this) {
return function(e, file, result) {
var $img, $mask, msg;
if (!file.inline) {
return;
@@ -4228,17 +4148,12 @@
}
};
})(this));
};
- ImageButton.prototype.status = function($node) {
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
+ ImageButton.prototype._status = function() {
+ return this._disableStatus();
};
ImageButton.prototype.loadImage = function($img, src, callback) {
var $mask, img, positionMask;
positionMask = (function(_this) {
@@ -4255,11 +4170,11 @@
};
})(this);
$img.addClass('loading');
$mask = $img.data('mask');
if (!$mask) {
- $mask = $('<div class="simditor-image-loading"><div class="progress"></div></div>').hide().appendTo(this.editor.wrapper);
+ $mask = $('<div class="simditor-image-loading">\n <div class="progress"></div>\n</div>').hide().appendTo(this.editor.wrapper);
positionMask();
$img.data('mask', $mask);
$mask.data('img', $img);
}
img = new Image();
@@ -4271,10 +4186,12 @@
}
width = img.width;
height = img.height;
$img.attr({
src: src,
+ width: width,
+ height: height,
'data-image-size': width + ',' + height
}).removeClass('loading');
if ($img.hasClass('uploading')) {
_this.editor.util.reflow(_this.editor.body);
positionMask();
@@ -4283,42 +4200,33 @@
$img.removeData('mask');
}
return callback(img);
};
})(this);
- img.onerror = (function(_this) {
- return function() {
- callback(false);
- $mask.remove();
- return $img.removeData('mask').removeClass('loading');
- };
- })(this);
+ img.onerror = function() {
+ callback(false);
+ $mask.remove();
+ return $img.removeData('mask').removeClass('loading');
+ };
return img.src = src;
};
ImageButton.prototype.createImage = function(name) {
- var $block, $img, $nextBlock, range;
+ var $img, range;
if (name == null) {
name = 'Image';
}
if (!this.editor.inputManager.focused) {
this.editor.focus();
}
- range = this.editor.selection.getRange();
+ range = this.editor.selection.range();
range.deleteContents();
- $block = this.editor.util.closestBlockEl();
- if ($block.is('p') && !this.editor.util.isEmptyNode($block)) {
- $block = $('<p/>').append(this.editor.util.phBr).insertAfter($block);
- this.editor.selection.setRangeAtStartOf($block, range);
- }
+ this.editor.selection.range(range);
$img = $('<img/>').attr('alt', name);
range.insertNode($img[0]);
- $nextBlock = $block.next('p');
- if (!($nextBlock.length > 0)) {
- $nextBlock = $('<p/>').append(this.editor.util.phBr).insertAfter($block);
- }
- this.editor.selection.setRangeAtStartOf($nextBlock);
+ this.editor.selection.setRangeAfter($img, range);
+ this.editor.trigger('valuechanged');
return $img;
};
ImageButton.prototype.command = function(src) {
var $img;
@@ -4352,11 +4260,11 @@
left: -4
};
ImagePopover.prototype.render = function() {
var tpl;
- tpl = "<div class=\"link-settings\">\n <div class=\"settings-field\">\n <label>" + (this._t('imageUrl')) + "</label>\n <input class=\"image-src\" type=\"text\" tabindex=\"1\" />\n <a class=\"btn-upload\" href=\"javascript:;\" title=\"" + (this._t('uploadImage')) + "\" tabindex=\"-1\">\n <span class=\"simditor-icon simditor-icon-upload\"></span>\n </a>\n </div>\n <div class='settings-field'>\n <label>" + (this._t('imageAlt')) + "</label>\n <input class=\"image-alt\" id=\"image-alt\" type=\"text\" tabindex=\"1\" />\n </div>\n <div class=\"settings-field\">\n <label>" + (this._t('imageSize')) + "</label>\n <input class=\"image-size\" id=\"image-width\" type=\"text\" tabindex=\"2\" />\n <span class=\"times\">×</span>\n <input class=\"image-size\" id=\"image-height\" type=\"text\" tabindex=\"3\" />\n <a class=\"btn-restore\" href=\"javascript:;\" title=\"" + (this._t('restoreImageSize')) + "\" tabindex=\"-1\">\n <span class=\"simditor-icon simditor-icon-undo\"></span>\n </a>\n </div>\n</div>";
+ tpl = "<div class=\"link-settings\">\n <div class=\"settings-field\">\n <label>" + (this._t('imageUrl')) + "</label>\n <input class=\"image-src\" type=\"text\" tabindex=\"1\" />\n <a class=\"btn-upload\" href=\"javascript:;\"\n title=\"" + (this._t('uploadImage')) + "\" tabindex=\"-1\">\n <span class=\"simditor-icon simditor-icon-upload\"></span>\n </a>\n </div>\n <div class='settings-field'>\n <label>" + (this._t('imageAlt')) + "</label>\n <input class=\"image-alt\" id=\"image-alt\" type=\"text\" tabindex=\"1\" />\n </div>\n <div class=\"settings-field\">\n <label>" + (this._t('imageSize')) + "</label>\n <input class=\"image-size\" id=\"image-width\" type=\"text\" tabindex=\"2\" />\n <span class=\"times\">×</span>\n <input class=\"image-size\" id=\"image-height\" type=\"text\" tabindex=\"3\" />\n <a class=\"btn-restore\" href=\"javascript:;\"\n title=\"" + (this._t('restoreImageSize')) + "\" tabindex=\"-1\">\n <span class=\"simditor-icon simditor-icon-undo\"></span>\n </a>\n </div>\n</div>";
this.el.addClass('image-popover').append(tpl);
this.srcEl = this.el.find('.image-src');
this.widthEl = this.el.find('#image-width');
this.heightEl = this.el.find('#image-height');
this.altEl = this.el.find('#image-alt');
@@ -4455,19 +4363,21 @@
createInput = (function(_this) {
return function() {
if (_this.input) {
_this.input.remove();
}
- return _this.input = $('<input type="file" title="' + _this._t('uploadImage') + '" accept="image/*">').appendTo($uploadBtn);
+ return _this.input = $('<input/>', {
+ type: 'file',
+ title: _this._t('uploadImage'),
+ accept: 'image/*'
+ }).appendTo($uploadBtn);
};
})(this);
createInput();
- this.el.on('click mousedown', 'input[type=file]', (function(_this) {
- return function(e) {
- return e.stopPropagation();
- };
- })(this));
+ this.el.on('click mousedown', 'input[type=file]', function(e) {
+ return e.stopPropagation();
+ });
return this.el.on('change', 'input[type=file]', (function(_this) {
return function(e) {
_this.editor.uploader.upload(_this.input, {
inline: true,
img: _this.target
@@ -4485,20 +4395,22 @@
value = inputEl.val() * 1;
if (!($.isNumeric(value) || value < 0)) {
return;
}
if (inputEl.is(this.widthEl)) {
+ width = value;
height = this.height * value / this.width;
this.heightEl.val(height);
} else {
+ height = value;
width = this.width * value / this.height;
this.widthEl.val(width);
}
if (!onlySetVal) {
this.target.attr({
- width: width || value,
- height: height || value
+ width: width,
+ height: height
});
}
return this.editor.trigger('valuechanged');
};
@@ -4519,10 +4431,13 @@
if (callback) {
callback(false);
}
return;
}
+ if (this.target.attr('src') === src) {
+ return;
+ }
return this.button.loadImage(this.target, src, (function(_this) {
return function(img) {
var blob;
if (!img) {
return;
@@ -4530,11 +4445,10 @@
if (_this.active) {
_this.width = img.width;
_this.height = img.height;
_this.widthEl.val(_this.width);
_this.heightEl.val(_this.height);
- _this.target.removeAttr('width').removeAttr('height');
}
if (/^data:image/.test(src)) {
blob = _this.editor.util.dataURLtoBlob(src);
blob.name = "Base64 Image.png";
_this.editor.uploader.upload(blob, {
@@ -4589,13 +4503,11 @@
IndentButton.prototype._init = function() {
this.title = this._t(this.name) + ' (Tab)';
return IndentButton.__super__._init.call(this);
};
- IndentButton.prototype.status = function($node) {
- return true;
- };
+ IndentButton.prototype._status = function() {};
IndentButton.prototype.command = function() {
return this.editor.indentation.indent();
};
@@ -4619,13 +4531,11 @@
OutdentButton.prototype._init = function() {
this.title = this._t(this.name) + ' (Shift + Tab)';
return OutdentButton.__super__._init.call(this);
};
- OutdentButton.prototype.status = function($node) {
- return true;
- };
+ OutdentButton.prototype._status = function() {};
OutdentButton.prototype.command = function() {
return this.editor.indentation.indent(true);
};
@@ -4646,17 +4556,15 @@
HrButton.prototype.icon = 'minus';
HrButton.prototype.htmlTag = 'hr';
- HrButton.prototype.status = function($node) {
- return true;
- };
+ HrButton.prototype._status = function() {};
HrButton.prototype.command = function() {
var $hr, $newBlock, $nextBlock, $rootBlock;
- $rootBlock = this.editor.util.furthestBlockEl();
+ $rootBlock = this.editor.selection.rootNodes().first();
$nextBlock = $rootBlock.next();
if ($nextBlock.length > 0) {
this.editor.selection.save();
} else {
$newBlock = $('<p/>').append(this.editor.util.phBr);
@@ -4699,10 +4607,14 @@
$.merge(this.editor.formatter._allowedTags, ['thead', 'th', 'tbody', 'tr', 'td', 'colgroup', 'col']);
$.extend(this.editor.formatter._allowedAttributes, {
td: ['rowspan', 'colspan'],
col: ['width']
});
+ $.extend(this.editor.formatter._allowedStyles, {
+ td: ['text-align'],
+ th: ['text-align']
+ });
this._initShortcuts();
this.editor.on('decorate', (function(_this) {
return function(e, $el) {
return $el.find('table').each(function(i, table) {
return _this.decorate($(table));
@@ -4718,15 +4630,15 @@
})(this));
this.editor.on('selectionchanged.table', (function(_this) {
return function(e) {
var $container, range;
_this.editor.body.find('.simditor-table td, .simditor-table th').removeClass('active');
- range = _this.editor.selection.getRange();
- if (range == null) {
+ range = _this.editor.selection.range();
+ if (!range) {
return;
}
- $container = $(range.commonAncestorContainer);
+ $container = _this.editor.selection.containerNode();
if (range.collapsed && $container.is('.simditor-table')) {
if (_this.editor.selection.rangeAtStartOf($container)) {
$container = $container.find('th:first');
} else {
$container = $container.find('td:last');
@@ -4805,92 +4717,87 @@
var $colgroup, $resizeHandle, $wrapper;
$wrapper = $table.parent('.simditor-table');
$colgroup = $table.find('colgroup');
if ($colgroup.length < 1) {
$colgroup = $('<colgroup/>').prependTo($table);
- $table.find('thead tr th').each((function(_this) {
- return function(i, td) {
- var $col;
- return $col = $('<col/>').appendTo($colgroup);
- };
- })(this));
+ $table.find('thead tr th').each(function(i, td) {
+ var $col;
+ return $col = $('<col/>').appendTo($colgroup);
+ });
this.refreshTableWidth($table);
}
- $resizeHandle = $('<div class="simditor-resize-handle" contenteditable="false"></div>').appendTo($wrapper);
- $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, 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, th').index($td);
- $col = $colgroup.find('col').eq(index);
- if ((ref1 = $resizeHandle.data('col')) != null ? ref1.is($col) : void 0) {
- $resizeHandle.show();
- return;
- }
- return $resizeHandle.css('left', $td.position().left + $td.outerWidth() - 5).data('td', $td).data('col', $col).show();
- };
- })(this));
- $wrapper.on('mouseleave', (function(_this) {
- return function(e) {
- return $resizeHandle.hide();
- };
- })(this));
- return $wrapper.on('mousedown', '.simditor-resize-handle', (function(_this) {
- 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, th');
- $rightCol = $leftCol.next('col');
- startX = e.pageX;
- startLeftWidth = $leftTd.outerWidth() * 1;
- startRightWidth = $rightTd.outerWidth() * 1;
- startHandleLeft = parseFloat($handle.css('left'));
- tableWidth = $leftTd.closest('table').width();
- minWidth = 50;
- $(document).on('mousemove.simditor-resize-table', function(e) {
- var deltaX, leftWidth, rightWidth;
- deltaX = e.pageX - startX;
- leftWidth = startLeftWidth + deltaX;
+ $resizeHandle = $('<div />', {
+ "class": 'simditor-resize-handle',
+ contenteditable: 'false'
+ }).appendTo($wrapper);
+ $wrapper.on('mousemove', 'td, th', 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, 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, th').index($td);
+ $col = $colgroup.find('col').eq(index);
+ if ((ref1 = $resizeHandle.data('col')) != null ? ref1.is($col) : void 0) {
+ $resizeHandle.show();
+ return;
+ }
+ return $resizeHandle.css('left', $td.position().left + $td.outerWidth() - 5).data('td', $td).data('col', $col).show();
+ });
+ $wrapper.on('mouseleave', function(e) {
+ return $resizeHandle.hide();
+ });
+ return $wrapper.on('mousedown', '.simditor-resize-handle', 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, th');
+ $rightCol = $leftCol.next('col');
+ startX = e.pageX;
+ startLeftWidth = $leftTd.outerWidth() * 1;
+ startRightWidth = $rightTd.outerWidth() * 1;
+ startHandleLeft = parseFloat($handle.css('left'));
+ tableWidth = $leftTd.closest('table').width();
+ minWidth = 50;
+ $(document).on('mousemove.simditor-resize-table', function(e) {
+ var deltaX, leftWidth, rightWidth;
+ deltaX = e.pageX - startX;
+ leftWidth = startLeftWidth + deltaX;
+ rightWidth = startRightWidth - deltaX;
+ if (leftWidth < minWidth) {
+ leftWidth = minWidth;
+ deltaX = minWidth - startLeftWidth;
rightWidth = startRightWidth - deltaX;
- if (leftWidth < minWidth) {
- leftWidth = minWidth;
- deltaX = minWidth - startLeftWidth;
- rightWidth = startRightWidth - deltaX;
- } else if (rightWidth < minWidth) {
- rightWidth = minWidth;
- deltaX = startRightWidth - minWidth;
- leftWidth = startLeftWidth + deltaX;
- }
- $leftCol.attr('width', (leftWidth / tableWidth * 100) + '%');
- $rightCol.attr('width', (rightWidth / tableWidth * 100) + '%');
- return $handle.css('left', startHandleLeft + deltaX);
- });
- $(document).one('mouseup.simditor-resize-table', function(e) {
- $(document).off('.simditor-resize-table');
- return $wrapper.removeClass('resizing');
- });
- $wrapper.addClass('resizing');
- return false;
- };
- })(this));
+ } else if (rightWidth < minWidth) {
+ rightWidth = minWidth;
+ deltaX = startRightWidth - minWidth;
+ leftWidth = startLeftWidth + deltaX;
+ }
+ $leftCol.attr('width', (leftWidth / tableWidth * 100) + '%');
+ $rightCol.attr('width', (rightWidth / tableWidth * 100) + '%');
+ return $handle.css('left', startHandleLeft + deltaX);
+ });
+ $(document).one('mouseup.simditor-resize-table', function(e) {
+ $(document).off('.simditor-resize-table');
+ return $wrapper.removeClass('resizing');
+ });
+ $wrapper.addClass('resizing');
+ return false;
+ });
};
TableButton.prototype._initShortcuts = function() {
this.editor.inputManager.addShortcut('ctrl+alt+up', (function(_this) {
return function(e) {
@@ -4934,11 +4841,11 @@
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);
+ $("<div class=\"menu-create-table\">\n</div>\n<div class=\"menu-edit-table\">\n <ul>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"deleteRow\">\n <span>" + (this._t('deleteRow')) + "</span>\n </a>\n </li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"insertRowAbove\">\n <span>" + (this._t('insertRowAbove')) + " ( Ctrl + Alt + ↑ )</span>\n </a>\n </li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"insertRowBelow\">\n <span>" + (this._t('insertRowBelow')) + " ( Ctrl + Alt + ↓ )</span>\n </a>\n </li>\n <li><span class=\"separator\"></span></li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"deleteCol\">\n <span>" + (this._t('deleteColumn')) + "</span>\n </a>\n </li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"insertColLeft\">\n <span>" + (this._t('insertColumnLeft')) + " ( Ctrl + Alt + ← )</span>\n </a>\n </li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"insertColRight\">\n <span>" + (this._t('insertColumnRight')) + " ( Ctrl + Alt + → )</span>\n </a>\n </li>\n <li><span class=\"separator\"></span></li>\n <li>\n <a tabindex=\"-1\" unselectable=\"on\" class=\"menu-item\"\n href=\"javascript:;\" data-param=\"deleteTable\">\n <span>" + (this._t('deleteTable')) + "</span>\n </a>\n </li>\n </ul>\n</div>").appendTo(this.menuWrapper);
this.createMenu = this.menuWrapper.find('.menu-create-table');
this.editMenu = this.menuWrapper.find('.menu-edit-table');
$table = this.createTable(6, 6).appendTo(this.createMenu);
this.createMenu.on('mouseenter', 'td, th', (function(_this) {
return function(e) {
@@ -4952,15 +4859,13 @@
$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, th').removeClass('selected');
- };
- })(this));
+ this.createMenu.on('mouseleave', function(e) {
+ return $(e.currentTarget).find('td, th').removeClass('selected');
+ });
return this.createMenu.on('mousedown', 'td, th', (function(_this) {
return function(e) {
var $closestBlock, $td, $tr, colNum, rowNum;
_this.wrapper.removeClass('menu-on');
if (!_this.editor.inputManager.focused) {
@@ -4972,11 +4877,11 @@
rowNum = $tr.prevAll('tr').length + 1;
if ($tr.parent().is('tbody')) {
rowNum += 1;
}
$table = _this.createTable(rowNum, colNum, true);
- $closestBlock = _this.editor.util.closestBlockEl();
+ $closestBlock = _this.editor.selection.blockNodes().last();
if (_this.editor.util.isEmptyNode($closestBlock)) {
$closestBlock.replaceWith($table);
} else {
$closestBlock.after($table);
}
@@ -4987,18 +4892,18 @@
};
})(this));
};
TableButton.prototype.createTable = function(row, col, phBr) {
- var $table, $tbody, $td, $thead, $tr, c, j, k, r, ref, ref1;
+ var $table, $tbody, $td, $thead, $tr, c, k, l, 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) {
+ for (r = k = 0, ref = row; 0 <= ref ? k < ref : k > ref; r = 0 <= ref ? ++k : --k) {
$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) {
+ for (c = l = 0, ref1 = col; 0 <= ref1 ? l < ref1 : l > ref1; c = 0 <= ref1 ? ++l : --l) {
$td = $(r === 0 ? '<th/>' : '<td/>').appendTo($tr);
if (phBr) {
$td.append(this.editor.util.phBr);
}
}
@@ -5008,17 +4913,15 @@
TableButton.prototype.refreshTableWidth = function($table) {
var cols, tableWidth;
tableWidth = $table.width();
cols = $table.find('col');
- 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) + '%');
- };
- })(this));
+ return $table.find('thead tr th').each(function(i, td) {
+ var $col;
+ $col = cols.eq(i);
+ return $col.attr('width', ($(td).outerWidth() / tableWidth * 100) + '%');
+ });
};
TableButton.prototype.setActive = function(active) {
TableButton.__super__.setActive.call(this, active);
if (active) {
@@ -5029,17 +4932,15 @@
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));
+ return $tr.find('td, th').each(function(i, cell) {
+ var $cell;
+ $cell = $(cell);
+ return $cell.replaceWith("<" + tagName + ">" + ($cell.html()) + "</" + tagName + ">");
+ });
};
TableButton.prototype.deleteRow = function($td) {
var $newTr, $tr, index;
$tr = $td.parent('tr');
@@ -5059,22 +4960,20 @@
return this.editor.selection.setRangeAtEndOf($newTr.find('td, th').eq(index));
}
};
TableButton.prototype.insertRow = function($td, direction) {
- var $newTr, $table, $tr, cellTag, colNum, i, index, j, ref;
+ var $newTr, $table, $tr, cellTag, colNum, i, index, k, ref;
if (direction == null) {
direction = 'after';
}
$tr = $td.parent('tr');
$table = $tr.closest('table');
colNum = 0;
- $table.find('tr').each((function(_this) {
- return function(i, tr) {
- return colNum = Math.max(colNum, $(tr).find('td').length);
- };
- })(this));
+ $table.find('tr').each(function(i, tr) {
+ return colNum = Math.max(colNum, $(tr).find('td').length);
+ });
index = $tr.find('td, th').index($td);
$newTr = $('<tr/>');
cellTag = 'td';
if (direction === 'after' && $tr.parent().is('thead')) {
$tr.parent().next('tbody').prepend($newTr);
@@ -5084,34 +4983,34 @@
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) {
+ for (i = k = 1, ref = colNum; 1 <= ref ? k <= ref : k >= ref; i = 1 <= ref ? ++k : --k) {
$("<" + cellTag + "/>").append(this.editor.util.phBr).appendTo($newTr);
}
return this.editor.selection.setRangeAtStartOf($newTr.find('td, th').eq(index));
};
TableButton.prototype.deleteCol = function($td) {
- var $newTd, $table, $tr, index;
+ var $newTd, $table, $tr, index, noOtherCol, noOtherRow;
$tr = $td.parent('tr');
- if ($tr.closest('table').find('tr').length < 1 && $td.siblings('td, th').length < 1) {
+ noOtherRow = $tr.closest('table').find('tr').length < 2;
+ noOtherCol = $td.siblings('td, th').length < 1;
+ if (noOtherRow && noOtherCol) {
return this.deleteTable($td);
} else {
index = $tr.find('td, th').index($td);
$newTd = $td.next('td, th');
if (!($newTd.length > 0)) {
$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, th').eq(index).remove();
- };
- })(this));
+ $table.find('tr').each(function(i, tr) {
+ return $(tr).find('td, th').eq(index).remove();
+ });
this.refreshTableWidth($table);
return this.editor.selection.setRangeAtEndOf($newTd);
}
};
@@ -5152,13 +5051,12 @@
return this.editor.selection.setRangeAtStartOf($block);
}
};
TableButton.prototype.command = function(param) {
- var $td, range;
- range = this.editor.selection.getRange();
- $td = $(range.commonAncestorContainer).closest('td, th');
+ var $td;
+ $td = this.editor.selection.containerNode.closest('td, th');
if (!($td.length > 0)) {
return;
}
if (param === 'deleteRow') {
this.deleteRow($td);
@@ -5199,21 +5097,15 @@
StrikethroughButton.prototype.htmlTag = 'strike';
StrikethroughButton.prototype.disableTag = 'pre';
- StrikethroughButton.prototype.status = function($node) {
+ StrikethroughButton.prototype._activeStatus = function() {
var active;
- if ($node != null) {
- this.setDisabled($node.is(this.disableTag));
- }
- if (this.disabled) {
- return true;
- }
active = document.queryCommandState('strikethrough') === true;
this.setActive(active);
- return active;
+ return this.active;
};
StrikethroughButton.prototype.command = function() {
document.execCommand('strikethrough');
if (!this.editor.util.support.oninput) {
@@ -5237,11 +5129,11 @@
AlignmentButton.prototype.name = "alignment";
AlignmentButton.prototype.icon = 'align-left';
- AlignmentButton.prototype.htmlTag = 'p, h1, h2, h3, h4';
+ AlignmentButton.prototype.htmlTag = 'p, h1, h2, h3, h4, td, th';
AlignmentButton.prototype._init = function() {
this.menu = [
{
name: 'left',
@@ -5281,43 +5173,27 @@
}
this.setIcon('align-' + align);
return this.menuEl.find('.menu-item').show().end().find('.menu-item-' + align).hide();
};
- AlignmentButton.prototype.status = function($node) {
- if ($node == null) {
- return true;
+ AlignmentButton.prototype._status = function() {
+ this.nodes = this.editor.selection.nodes().filter(this.htmlTag);
+ if (this.nodes.length < 1) {
+ this.setDisabled(true);
+ return this.setActive(false);
+ } else {
+ this.setDisabled(false);
+ return this.setActive(true, this.nodes.first().css('text-align'));
}
- if (!this.editor.util.isBlockNode($node)) {
- return;
- }
- this.setDisabled(!$node.is(this.htmlTag));
- if (this.disabled) {
- this.setActive(false);
- return true;
- }
- this.setActive(true, $node.css('text-align'));
- return this.active;
};
AlignmentButton.prototype.command = function(align) {
- var $blockEls, $endBlock, $startBlock, block, endNode, j, len, range, ref, startNode;
- if (['left', 'center', 'right'].indexOf(align) < 0) {
- throw new Error("invalid " + align);
+ if (align !== 'left' && align !== 'center' && align !== 'right') {
+ throw new Error("simditor alignment button: invalid align " + align);
}
- range = this.editor.selection.getRange();
- startNode = range.startContainer;
- endNode = range.endContainer;
- $startBlock = this.editor.util.closestBlockEl(startNode);
- $endBlock = this.editor.util.closestBlockEl(endNode);
- this.editor.selection.save();
- $blockEls = $startBlock.is($endBlock) ? $startBlock : $startBlock.nextUntil($endBlock).addBack().add($endBlock);
- ref = $blockEls.filter(this.htmlTag);
- for (j = 0, len = ref.length; j < len; j++) {
- block = ref[j];
- $(block).css('text-align', align === 'left' ? '' : align);
- }
- this.editor.selection.restore();
+ this.nodes.css({
+ 'text-align': align === 'left' ? '' : align
+ });
return this.editor.trigger('valuechanged');
};
return AlignmentButton;