(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) { return (root['Simditor'] = factory($, SimpleModule, simpleHotkeys, simpleUploader)); }); } else if (typeof exports === 'object') { // Node. Does not work with strict CommonJS, but // only CommonJS-like environments that support module.exports, // like Node. module.exports = factory(require("jquery"), require("simple-module"), require("simple-hotkeys"), require("simple-uploader")); } else { root['Simditor'] = factory(jQuery, SimpleModule, simple.hotkeys, simple.uploader); } }(this, function ($, SimpleModule, simpleHotkeys, simpleUploader) { var AlignmentButton, BlockquoteButton, BoldButton, Button, Clipboard, CodeButton, CodePopover, ColorButton, FontScaleButton, Formatter, HrButton, ImageButton, ImagePopover, IndentButton, Indentation, InputManager, ItalicButton, Keystroke, LinkButton, LinkPopover, ListButton, OrderListButton, OutdentButton, Popover, Selection, Simditor, StrikethroughButton, TableButton, TitleButton, Toolbar, UnderlineButton, UndoManager, UnorderListButton, Util, extend = function (child, parent) { for (var key in parent) { if (hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }, hasProp = {}.hasOwnProperty, indexOf = [].indexOf || function (item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; }, slice = [].slice; Selection = (function (superClass) { extend(Selection, superClass); function Selection() { 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; this._selection = document.getSelection(); this.editor.on('selectionchanged', (function (_this) { return function (e) { _this.reset(); return _this._range = _this._selection.getRangeAt(0); }; })(this)); this.editor.on('blur', (function (_this) { return function (e) { return _this.reset(); }; })(this)); return this.editor.on('focus', (function (_this) { return function (e) { _this.reset(); return _this._range = _this._selection.getRangeAt(0); }; })(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 { this._selection.removeAllRanges(); } catch (_error) { e = _error; } return this.reset(); }; 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._range; }; 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 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 afterLastNode, beforeLastNode, endNode, endNodeLength, lastNodeIsBr, result; if (range == null) { range = this.range(); } if (!(range && range.collapsed)) { return; } node = $(node)[0]; endNode = range.endContainer; endNodeLength = this.editor.util.getNodeLength(endNode); 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 (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.range(); } if (!(range && range.collapsed)) { return; } node = $(node)[0]; startNode = range.startContainer; if (range.startOffset !== 0) { return false; } if (node === startNode) { return true; } else if (!$.contains(node, startNode)) { return false; } result = true; $(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.range(); } 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.range(); } if (range == null) { return; } node = $(node)[0]; range.setEndAfter(node); range.collapse(false); return this.range(range); }; Selection.prototype.setRangeBefore = function (node, range) { if (range == null) { range = this.range(); } if (range == null) { return; } node = $(node)[0]; range.setEndBefore(node); range.collapse(false); return this.range(range); }; Selection.prototype.setRangeAtStartOf = function (node, range) { if (range == null) { range = this.range(); } node = $(node).get(0); range.setEnd(node, 0); range.collapse(false); return this.range(range); }; Selection.prototype.setRangeAtEndOf = function (node, range) { var $lastNode, $node, contents, lastChild, lastChildLength, lastText, nodeLength; if (range == null) { range = this.range(); } $node = $(node); 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], lastChildLength - 1); } else { range.setEnd(lastChild[0], lastChildLength); } } else { range.setEnd(node, 0); } } else { nodeLength = this.editor.util.getNodeLength(node); if (node.nodeType !== 3 && nodeLength > 0) { $lastNode = $(node).contents().last(); if ($lastNode.is('br')) { nodeLength -= 1; } else if ($lastNode[0].nodeType !== 3 && this.editor.util.isEmptyNode($lastNode)) { $lastNode.append(this.editor.util.phBr); node = $lastNode[0]; nodeLength = 0; } } range.setEnd(node, nodeLength); } range.collapse(false); return this.range(range); }; Selection.prototype.deleteRangeContents = function (range) { var atEndOfBody, atStartOfBody, endRange, startRange; if (range == null) { range = this.range(); } startRange = range.cloneRange(); endRange = range.cloneRange(); startRange.collapse(true); endRange.collapse(false); 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.range(range); } else { range.deleteContents(); } return range; }; Selection.prototype.breakBlockEl = function (el, range) { var $el; if (range == null) { range = this.range(); } $el = $(el); if (!range.collapsed) { return $el; } range.setStartBefore($el.get(0)); if (range.collapsed) { return $el; } return $el.before(range.extractContents()); }; Selection.prototype.save = function (range) { var endCaret, endRange, startCaret; if (range == null) { range = this.range(); } if (this._selectionSaved) { return; } endRange = range.cloneRange(); endRange.collapse(false); startCaret = $('').addClass('simditor-caret-start'); endCaret = $('').addClass('simditor-caret-end'); endRange.insertNode(endCaret[0]); range.insertNode(startCaret[0]); this.clear(); return this._selectionSaved = true; }; Selection.prototype.restore = function () { var endCaret, endContainer, endOffset, range, startCaret, startContainer, startOffset; if (!this._selectionSaved) { return false; } startCaret = this.editor.body.find('.simditor-caret-start'); endCaret = this.editor.body.find('.simditor-caret-end'); if (startCaret.length && endCaret.length) { startContainer = startCaret.parent(); startOffset = startContainer.contents().index(startCaret); endContainer = endCaret.parent(); endOffset = endContainer.contents().index(endCaret); if (startContainer[0] === endContainer[0]) { endOffset -= 1; } range = document.createRange(); range.setStart(startContainer.get(0), startOffset); range.setEnd(endContainer.get(0), endOffset); startCaret.remove(); endCaret.remove(); this.range(range); } else { startCaret.remove(); endCaret.remove(); } this._selectionSaved = false; return range; }; return Selection; })(SimpleModule); Formatter = (function (superClass) { extend(Formatter, superClass); function Formatter() { return Formatter.__super__.constructor.apply(this, arguments); } Formatter.pluginName = 'Formatter'; Formatter.prototype.opts = { allowedTags: [], allowedAttributes: {}, allowedStyles: {} }; Formatter.prototype._init = function () { this.editor = this._module; this._allowedTags = $.merge(['br', 'span', 'a', 'img', 'b', 'strong', 'i', 'strike', '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.opts.allowedAttributes); this._allowedStyles = $.extend({ span: ['color', 'font-size'], b: ['color'], i: ['color'], strong: ['color'], strike: ['color'], u: ['color'], p: ['margin-left', 'text-align'], 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; } 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 $el; }; Formatter.prototype.autolink = function ($el) { 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) { return $parentNode.contents().each(function (i, node) { var $node, text; $node = $(node); if ($node.is('a') || $node.closest('a, pre', $el).length) { return; } 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 (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) { subStr = text.substring(lastIndex, match.index); replaceEls.push(document.createTextNode(subStr)); lastIndex = re.lastIndex; uri = /^(http(s)?:\/\/|\/)/.test(match[0]) ? match[0] : 'http://' + match[0]; $link = $("").text(match[0]); replaceEls.push($link[0]); } replaceEls.push(document.createTextNode(text.substring(lastIndex))); $node.replaceWith($(replaceEls)); } return $el; }; Formatter.prototype.format = function ($el) { var $node, blockNode, k, l, len, len1, n, node, ref, ref1; if ($el == null) { $el = this.editor.body; } if ($el.is(':empty')) { $el.append('

' + this.editor.util.phBr + '

'); return $el; } ref = $el.contents(); for (k = 0, len = ref.length; k < len; k++) { n = ref[k]; this.cleanNode(n, true); } ref1 = $el.contents(); 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; } $node.remove(); } else if (this.editor.util.isBlockNode(node)) { if ($node.is('li')) { if (blockNode && blockNode.is('ul, ol')) { blockNode.append(node); } else { blockNode = $('