diff --git a/addons/web_editor/static/lib/summernote/font/summernote.eot b/addons/web_editor/static/lib/summernote/font/summernote.eot new file mode 100644 index 00000000000..4b6f0f6b9fc Binary files /dev/null and b/addons/web_editor/static/lib/summernote/font/summernote.eot differ diff --git a/addons/web_editor/static/lib/summernote/font/summernote.ttf b/addons/web_editor/static/lib/summernote/font/summernote.ttf new file mode 100644 index 00000000000..514099b602e Binary files /dev/null and b/addons/web_editor/static/lib/summernote/font/summernote.ttf differ diff --git a/addons/web_editor/static/lib/summernote/font/summernote.woff b/addons/web_editor/static/lib/summernote/font/summernote.woff new file mode 100644 index 00000000000..63e49510b88 Binary files /dev/null and b/addons/web_editor/static/lib/summernote/font/summernote.woff differ diff --git a/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.css b/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.css new file mode 100755 index 00000000000..6232dde991f --- /dev/null +++ b/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.css @@ -0,0 +1,16 @@ +.ext-databasic { + position: relative; + display: block; + min-height: 50px; + background-color: cyan; + text-align: center; + padding: 20px; + border: 1px solid white; + border-radius: 10px; +} + +.ext-databasic p { + color: white; + font-size: 1.2em; + margin: 0; +} diff --git a/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.js b/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.js new file mode 100755 index 00000000000..efe0d4dc33e --- /dev/null +++ b/addons/web_editor/static/lib/summernote/plugin/databasic/summernote-ext-databasic.js @@ -0,0 +1,292 @@ +(function(factory) { + /* global define */ + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +}(function($) { + // pull in some summernote core functions + var ui = $.summernote.ui; + var dom = $.summernote.dom; + + // define the popover plugin + var DataBasicPlugin = function(context) { + var self = this; + var options = context.options; + var lang = options.langInfo; + + self.icon = ''; + + // add context menu button for dialog + context.memo('button.databasic', function() { + return ui.button({ + contents: self.icon, + tooltip: lang.databasic.insert, + click: context.createInvokeHandler('databasic.showDialog') + }).render(); + }); + + // add popover edit button + context.memo('button.databasicDialog', function() { + return ui.button({ + contents: self.icon, + tooltip: lang.databasic.edit, + click: context.createInvokeHandler('databasic.showDialog') + }).render(); + }); + + // add popover size buttons + context.memo('button.databasicSize100', function() { + return ui.button({ + contents: '100%', + tooltip: lang.image.resizeFull, + click: context.createInvokeHandler('editor.resize', '1') + }).render(); + }); + context.memo('button.databasicSize50', function() { + return ui.button({ + contents: '50%', + tooltip: lang.image.resizeHalf, + click: context.createInvokeHandler('editor.resize', '0.5') + }).render(); + }); + context.memo('button.databasicSize25', function() { + return ui.button({ + contents: '25%', + tooltip: lang.image.resizeQuarter, + click: context.createInvokeHandler('editor.resize', '0.25') + }).render(); + }); + + self.events = { + 'summernote.init': function(we, e) { + // update existing containers + $('data.ext-databasic', e.editable).each(function() { self.setContent($(this)); }); + // TODO: make this an undo snapshot... + }, + 'summernote.keyup summernote.mouseup summernote.change summernote.scroll': function() { + self.update(); + }, + 'summernote.dialog.shown': function() { + self.hidePopover(); + } + }; + + self.initialize = function() { + // create dialog markup + var $container = options.dialogsInBody ? $(document.body) : context.layoutInfo.editor; + + var body = '
' + self.icon + ' ' + lang.databasic.name + ': ' + + $node.attr('data-test') + '
'); + }; + + self.updateNode = function(info) { + self.setContent(info.node + .attr('data-test', info.test)); + }; + + self.createNode = function(info) { + var $node = $(''); + + if ($node) { + // save node to info structure + info.node = $node; + // insert node into editor dom + context.invoke('editor.insertNode', $node[0]); + } + + return $node; + }; + + self.showDialog = function() { + var info = self.getInfo(); + var newNode = !info.node; + context.invoke('editor.saveRange'); + + self + .openDialog(info) + .then(function(dialogInfo) { + // [workaround] hide dialog before restore range for IE range focus + ui.hideDialog(self.$dialog); + context.invoke('editor.restoreRange'); + + // insert a new node + if (newNode) { + self.createNode(info); + } + + // update info with dialog info + $.extend(info, dialogInfo); + + self.updateNode(info); + }) + .fail(function() { + context.invoke('editor.restoreRange'); + }); + }; + + self.openDialog = function(info) { + return $.Deferred(function(deferred) { + var $inpTest = self.$dialog.find('.ext-databasic-test'); + var $saveBtn = self.$dialog.find('.ext-databasic-save'); + var onKeyup = function(event) { + if (event.keyCode === 13) { + $saveBtn.trigger('click'); + } + }; + + ui.onDialogShown(self.$dialog, function() { + context.triggerEvent('dialog.shown'); + + $inpTest.val(info.test).on('input', function() { + ui.toggleBtn($saveBtn, $inpTest.val()); + }).trigger('focus').on('keyup', onKeyup); + + $saveBtn + .text(info.node ? lang.databasic.edit : lang.databasic.insert) + .click(function(event) { + event.preventDefault(); + + deferred.resolve({ test: $inpTest.val() }); + }); + + // init save button + ui.toggleBtn($saveBtn, $inpTest.val()); + }); + + ui.onDialogHidden(self.$dialog, function() { + $inpTest.off('input keyup'); + $saveBtn.off('click'); + + if (deferred.state() === 'pending') { + deferred.reject(); + } + }); + + ui.showDialog(self.$dialog); + }); + }; + }; + + // Extends summernote + $.extend(true, $.summernote, { + plugins: { + databasic: DataBasicPlugin + }, + + options: { + popover: { + databasic: [ + ['databasic', ['databasicDialog', 'databasicSize100', 'databasicSize50', 'databasicSize25']] + ] + } + }, + + // add localization texts + lang: { + 'en-US': { + databasic: { + name: 'Basic Data Container', + insert: 'insert basic data container', + edit: 'edit basic data container', + testLabel: 'test input' + } + } + } + + }); +})); diff --git a/addons/web_editor/static/lib/summernote/plugin/hello/summernote-ext-hello.js b/addons/web_editor/static/lib/summernote/plugin/hello/summernote-ext-hello.js new file mode 100644 index 00000000000..22e4f6ac034 --- /dev/null +++ b/addons/web_editor/static/lib/summernote/plugin/hello/summernote-ext-hello.js @@ -0,0 +1,81 @@ +(function(factory) { + /* global define */ + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +}(function($) { + // Extends plugins for adding hello. + // - plugin is external module for customizing. + $.extend($.summernote.plugins, { + /** + * @param {Object} context - context object has status of editor. + */ + 'hello': function(context) { + var self = this; + + // ui has renders to build ui elements. + // - you can create a button with `ui.button` + var ui = $.summernote.ui; + + // add hello button + context.memo('button.hello', function() { + // create button + var button = ui.button({ + contents: ' Hello', + tooltip: 'hello', + click: function() { + self.$panel.show(); + self.$panel.hide(500); + // invoke insertText method with 'hello' on editor module. + context.invoke('editor.insertText', 'hello'); + } + }); + + // create jQuery object from button instance. + var $hello = button.render(); + return $hello; + }); + + // This events will be attached when editor is initialized. + this.events = { + // This will be called after modules are initialized. + 'summernote.init': function(we, e) { + console.log('summernote initialized', we, e); + }, + // This will be called when user releases a key on editable. + 'summernote.keyup': function(we, e) { + console.log('summernote keyup', we, e); + } + }; + + // This method will be called when editor is initialized by $('..').summernote(); + // You can create elements for plugin + this.initialize = function() { + this.$panel = $('').css({ + position: 'absolute', + width: 100, + height: 100, + left: '50%', + top: '50%', + background: 'red' + }).hide(); + + this.$panel.appendTo('body'); + }; + + // This methods will be called when editor is destroyed by $('..').summernote('destroy'); + // You should remove elements on `initialize`. + this.destroy = function() { + this.$panel.remove(); + this.$panel = null; + }; + } + }); +})); diff --git a/addons/web_editor/static/lib/summernote/plugin/specialchars/summernote-ext-specialchars.js b/addons/web_editor/static/lib/summernote/plugin/specialchars/summernote-ext-specialchars.js new file mode 100644 index 00000000000..2ee4e512efd --- /dev/null +++ b/addons/web_editor/static/lib/summernote/plugin/specialchars/summernote-ext-specialchars.js @@ -0,0 +1,312 @@ +(function(factory) { + /* global define */ + if (typeof define === 'function' && define.amd) { + // AMD. Register as an anonymous module. + define(['jquery'], factory); + } else if (typeof module === 'object' && module.exports) { + // Node/CommonJS + module.exports = factory(require('jquery')); + } else { + // Browser globals + factory(window.jQuery); + } +}(function($) { + $.extend($.summernote.plugins, { + 'specialchars': function(context) { + var self = this; + var ui = $.summernote.ui; + + var $editor = context.layoutInfo.editor; + var options = context.options; + var lang = options.langInfo; + + var KEY = { + UP: 38, + DOWN: 40, + LEFT: 37, + RIGHT: 39, + ENTER: 13 + }; + var COLUMN_LENGTH = 15; + var COLUMN_WIDTH = 35; + + var currentColumn = 0; + var currentRow = 0; + var totalColumn = 0; + var totalRow = 0; + + // special characters data set + var specialCharDataSet = [ + '"', '&', '<', '>', '¡', '¢', + '£', '¤', '¥', '¦', '§', + '¨', '©', 'ª', '«', '¬', + '®', '¯', '°', '±', '²', + '³', '´', 'µ', '¶', '·', + '¸', '¹', 'º', '»', '¼', + '½', '¾', '¿', '×', '÷', + 'ƒ', 'ˆ', '˜', '–', '—', + '‘', '’', '‚', '“', '”', + '„', '†', '‡', '•', '…', + '‰', '′', '″', '‹', '›', + '‾', '⁄', '€', 'ℑ', '℘', + 'ℜ', '™', 'ℵ', '←', '↑', + '→', '↓', '↔', '↵', '⇐', + '⇑', '⇒', '⇓', '⇔', '∀', + '∂', '∃', '∅', '∇', '∈', + '∉', '∋', '∏', '∑', '−', + '∗', '√', '∝', '∞', '∠', + '∧', '∨', '∩', '∪', '∫', + '∴', '∼', '≅', '≈', '≠', + '≡', '≤', '≥', '⊂', '⊃', + '⊄', '⊆', '⊇', '⊕', '⊗', + '⊥', '⋅', '⌈', '⌉', '⌊', + '⌋', '◊', '♠', '♣', '♥', + '♦' + ]; + + context.memo('button.specialchars', function() { + return ui.button({ + contents: '', + tooltip: lang.specialChar.specialChar, + click: function() { + self.show(); + } + }).render(); + }); + + /** + * Make Special Characters Table + * + * @member plugin.specialChar + * @private + * @return {jQuery} + */ + this.makeSpecialCharSetTable = function() { + var $table = $('' + - 'Summernote @VERSION · ' + - 'Project · ' + - 'Issues' + - '
'; - return tplDialog('note-help-dialog', '', body, ''); - } - }; - - var tplDialogs = function (lang, options) { - var dialogs = ''; - - $.each(tplDialogInfo, function (idx, tplDialog) { - dialogs += tplDialog(lang, options); - }); - - return '] - var ancestors = listAncestor(point.node, func.eq(root)); - - if (!ancestors.length) { - return null; - } else if (ancestors.length === 1) { - return splitNode(point, options); - } - - return ancestors.reduce(function (node, parent) { - if (node === point.node) { - node = splitNode(point, options); - } - - return splitNode({ - node: parent, - offset: node ? dom.position(node) : nodeLength(parent) - }, options); - }); - }; - - /** - * split point - * - * @param {Point} point - * @param {Boolean} isInline - * @return {Object} - */ - var splitPoint = function (point, isInline) { - // find splitRoot, container - // - inline: splitRoot is a child of paragraph - // - block: splitRoot is a child of bodyContainer - var pred = isInline ? isPara : isBodyContainer; - var ancestors = listAncestor(point.node, pred); - var topAncestor = list.last(ancestors) || point.node; - - var splitRoot, container; - if (pred(topAncestor)) { - splitRoot = ancestors[ancestors.length - 2]; - container = topAncestor; - } else { - splitRoot = topAncestor; - container = splitRoot.parentNode; - } - - // if splitRoot is exists, split with splitTree - var pivot = splitRoot && splitTree(splitRoot, point, { - isSkipPaddingBlankHTML: isInline, - isNotSplitEdgePoint: isInline - }); - - // if container is point.node, find pivot with point.offset - if (!pivot && container === point.node) { - pivot = point.node.childNodes[point.offset]; - } - - return { - rightNode: pivot, - container: container - }; - }; - - var create = function (nodeName) { - return document.createElement(nodeName); - }; - - var createText = function (text) { - return document.createTextNode(text); - }; - - /** - * @method remove - * - * remove node, (isRemoveChild: remove child or not) - * - * @param {Node} node - * @param {Boolean} isRemoveChild - */ - var remove = function (node, isRemoveChild) { - if (!node || !node.parentNode) { return; } - if (node.removeNode) { return node.removeNode(isRemoveChild); } - - var parent = node.parentNode; - if (!isRemoveChild) { - var nodes = []; - var i, len; - for (i = 0, len = node.childNodes.length; i < len; i++) { - nodes.push(node.childNodes[i]); - } - - for (i = 0, len = nodes.length; i < len; i++) { - parent.insertBefore(nodes[i], node); - } - } - - parent.removeChild(node); - }; - - /** - * @method removeWhile - * - * @param {Node} node - * @param {Function} pred - */ - var removeWhile = function (node, pred) { - while (node) { - if (isEditable(node) || !pred(node)) { - break; - } - - var parent = node.parentNode; - remove(node); - node = parent; - } - }; - - /** - * @method replace - * - * replace node with provided nodeName - * - * @param {Node} node - * @param {String} nodeName - * @return {Node} - new node - */ - var replace = function (node, nodeName) { - if (node.nodeName.toUpperCase() === nodeName.toUpperCase()) { - return node; - } - - var newNode = create(nodeName); - - if (node.style.cssText) { - newNode.style.cssText = node.style.cssText; - } - - appendChildNodes(newNode, list.from(node.childNodes)); - insertAfter(newNode, node); - remove(node); - - return newNode; - }; - - var isTextarea = makePredByNodeName('TEXTAREA'); - - /** - * @param {jQuery} $node - * @param {Boolean} [stripLinebreaks] - default: false - */ - var value = function ($node, stripLinebreaks) { - var val = isTextarea($node[0]) ? $node.val() : $node.html(); - if (stripLinebreaks) { - return val.replace(/[\n\r]/g, ''); - } - return val; - }; - - /** - * @method html - * - * get the HTML contents of node - * - * @param {jQuery} $node - * @param {Boolean} [isNewlineOnBlock] - */ - var html = function ($node, isNewlineOnBlock) { - var markup = value($node); - - if (isNewlineOnBlock) { - var regexTag = /<(\/?)(\b(?!!)[^>\s]*)(.*?)(\s*\/?>)/g; - markup = markup.replace(regexTag, function (match, endSlash, name) { - name = name.toUpperCase(); - var isEndOfInlineContainer = /^DIV|^TD|^TH|^P|^LI|^H[1-7]/.test(name) && - !!endSlash; - var isBlockNode = /^BLOCKQUOTE|^TABLE|^TBODY|^TR|^HR|^UL|^OL/.test(name); - - return match + ((isEndOfInlineContainer || isBlockNode) ? '\n' : ''); - }); - markup = $.trim(markup); - } - - return markup; - }; - - return { - /** @property {String} NBSP_CHAR */ - NBSP_CHAR: NBSP_CHAR, - /** @property {String} ZERO_WIDTH_NBSP_CHAR */ - ZERO_WIDTH_NBSP_CHAR: ZERO_WIDTH_NBSP_CHAR, - /** @property {String} blank */ - blank: blankHTML, - /** @property {String} emptyPara */ - emptyPara: '
' + blankHTML + '
', - makePredByNodeName: makePredByNodeName, - isEditable: isEditable, - isControlSizing: isControlSizing, - buildLayoutInfo: buildLayoutInfo, - makeLayoutInfo: makeLayoutInfo, - isText: isText, - isVoid: isVoid, - isPara: isPara, - isPurePara: isPurePara, - isInline: isInline, - isBlock: func.not(isInline), - isBodyInline: isBodyInline, - isBody: isBody, - isParaInline: isParaInline, - isList: isList, - isTable: isTable, - isCell: isCell, - isBlockquote: isBlockquote, - isBodyContainer: isBodyContainer, - isAnchor: isAnchor, - isDiv: makePredByNodeName('DIV'), - isLi: isLi, - isBR: makePredByNodeName('BR'), - isSpan: makePredByNodeName('SPAN'), - isB: makePredByNodeName('B'), - isU: makePredByNodeName('U'), - isS: makePredByNodeName('S'), - isI: makePredByNodeName('I'), - isImg: makePredByNodeName('IMG'), - isTextarea: isTextarea, - isEmpty: isEmpty, - isEmptyAnchor: func.and(isAnchor, isEmpty), - isClosestSibling: isClosestSibling, - withClosestSiblings: withClosestSiblings, - nodeLength: nodeLength, - isLeftEdgePoint: isLeftEdgePoint, - isRightEdgePoint: isRightEdgePoint, - isEdgePoint: isEdgePoint, - isLeftEdgeOf: isLeftEdgeOf, - isRightEdgeOf: isRightEdgeOf, - isLeftEdgePointOf: isLeftEdgePointOf, - isRightEdgePointOf: isRightEdgePointOf, - prevPoint: prevPoint, - nextPoint: nextPoint, - isSamePoint: isSamePoint, - isVisiblePoint: isVisiblePoint, - prevPointUntil: prevPointUntil, - nextPointUntil: nextPointUntil, - isCharPoint: isCharPoint, - walkPoint: walkPoint, - ancestor: ancestor, - singleChildAncestor: singleChildAncestor, - listAncestor: listAncestor, - lastAncestor: lastAncestor, - listNext: listNext, - listPrev: listPrev, - listDescendant: listDescendant, - commonAncestor: commonAncestor, - wrap: wrap, - insertAfter: insertAfter, - appendChildNodes: appendChildNodes, - position: position, - hasChildren: hasChildren, - makeOffsetPath: makeOffsetPath, - fromOffsetPath: fromOffsetPath, - splitTree: splitTree, - splitPoint: splitPoint, - create: create, - createText: createText, - remove: remove, - removeWhile: removeWhile, - replace: replace, - html: html, - value: value - }; - })(); - - return dom; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/core/func.js b/addons/web_editor/static/lib/summernote/src/js/core/func.js deleted file mode 100644 index 11bfdf546e0..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/core/func.js +++ /dev/null @@ -1,130 +0,0 @@ -define('summernote/core/func', function () { - /** - * @class core.func - * - * func utils (for high-order func's arg) - * - * @singleton - * @alternateClassName func - */ - var func = (function () { - var eq = function (itemA) { - return function (itemB) { - return itemA === itemB; - }; - }; - - var eq2 = function (itemA, itemB) { - return itemA === itemB; - }; - - var peq2 = function (propName) { - return function (itemA, itemB) { - return itemA[propName] === itemB[propName]; - }; - }; - - var ok = function () { - return true; - }; - - var fail = function () { - return false; - }; - - var not = function (f) { - return function () { - return !f.apply(f, arguments); - }; - }; - - var and = function (fA, fB) { - return function (item) { - return fA(item) && fB(item); - }; - }; - - var self = function (a) { - return a; - }; - - var idCounter = 0; - - /** - * generate a globally-unique id - * - * @param {String} [prefix] - */ - var uniqueId = function (prefix) { - var id = ++idCounter + ''; - return prefix ? prefix + id : id; - }; - - /** - * returns bnd (bounds) from rect - * - * - IE Compatability Issue: http://goo.gl/sRLOAo - * - Scroll Issue: http://goo.gl/sNjUc - * - * @param {Rect} rect - * @return {Object} bounds - * @return {Number} bounds.top - * @return {Number} bounds.left - * @return {Number} bounds.width - * @return {Number} bounds.height - */ - var rect2bnd = function (rect) { - var $document = $(document); - return { - top: rect.top + $document.scrollTop(), - left: rect.left + $document.scrollLeft(), - width: rect.right - rect.left, - height: rect.bottom - rect.top - }; - }; - - /** - * returns a copy of the object where the keys have become the values and the values the keys. - * @param {Object} obj - * @return {Object} - */ - var invertObject = function (obj) { - var inverted = {}; - for (var key in obj) { - if (obj.hasOwnProperty(key)) { - inverted[obj[key]] = key; - } - } - return inverted; - }; - - /** - * @param {String} namespace - * @param {String} [prefix] - * @return {String} - */ - var namespaceToCamel = function (namespace, prefix) { - prefix = prefix || ''; - return prefix + namespace.split('.').map(function (name) { - return name.substring(0, 1).toUpperCase() + name.substring(1); - }).join(''); - }; - - return { - eq: eq, - eq2: eq2, - peq2: peq2, - ok: ok, - fail: fail, - self: self, - not: not, - and: and, - uniqueId: uniqueId, - rect2bnd: rect2bnd, - invertObject: invertObject, - namespaceToCamel: namespaceToCamel - }; - })(); - - return func; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/core/key.js b/addons/web_editor/static/lib/summernote/src/js/core/key.js deleted file mode 100644 index a17b2756328..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/core/key.js +++ /dev/null @@ -1,96 +0,0 @@ -define([ - 'summernote/core/list', - 'summernote/core/func' -], function (list, func) { - /** - * @class core.key - * - * Object for keycodes. - * - * @singleton - * @alternateClassName key - */ - var key = (function () { - var keyMap = { - 'BACKSPACE': 8, - 'TAB': 9, - 'ENTER': 13, - 'SPACE': 32, - - // Arrow - 'LEFT': 37, - 'UP': 38, - 'RIGHT': 39, - 'DOWN': 40, - - // Number: 0-9 - 'NUM0': 48, - 'NUM1': 49, - 'NUM2': 50, - 'NUM3': 51, - 'NUM4': 52, - 'NUM5': 53, - 'NUM6': 54, - 'NUM7': 55, - 'NUM8': 56, - - // Alphabet: a-z - 'B': 66, - 'E': 69, - 'I': 73, - 'J': 74, - 'K': 75, - 'L': 76, - 'R': 82, - 'S': 83, - 'U': 85, - 'V': 86, - 'Y': 89, - 'Z': 90, - - 'SLASH': 191, - 'LEFTBRACKET': 219, - 'BACKSLASH': 220, - 'RIGHTBRACKET': 221 - }; - - return { - /** - * @method isEdit - * - * @param {Number} keyCode - * @return {Boolean} - */ - isEdit: function (keyCode) { - return list.contains([ - keyMap.BACKSPACE, - keyMap.TAB, - keyMap.ENTER, - keyMap.SPACe - ], keyCode); - }, - /** - * @method isMove - * - * @param {Number} keyCode - * @return {Boolean} - */ - isMove: function (keyCode) { - return list.contains([ - keyMap.LEFT, - keyMap.UP, - keyMap.RIGHT, - keyMap.DOWN - ], keyCode); - }, - /** - * @property {Object} nameFromCode - * @property {String} nameFromCode.8 "BACKSPACE" - */ - nameFromCode: func.invertObject(keyMap), - code: keyMap - }; - })(); - - return key; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/core/list.js b/addons/web_editor/static/lib/summernote/src/js/core/list.js deleted file mode 100644 index 2d6708838df..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/core/list.js +++ /dev/null @@ -1,191 +0,0 @@ -define(['summernote/core/func'], function (func) { - /** - * @class core.list - * - * list utils - * - * @singleton - * @alternateClassName list - */ - var list = (function () { - /** - * returns the first item of an array. - * - * @param {Array} array - */ - var head = function (array) { - return array[0]; - }; - - /** - * returns the last item of an array. - * - * @param {Array} array - */ - var last = function (array) { - return array[array.length - 1]; - }; - - /** - * returns everything but the last entry of the array. - * - * @param {Array} array - */ - var initial = function (array) { - return array.slice(0, array.length - 1); - }; - - /** - * returns the rest of the items in an array. - * - * @param {Array} array - */ - var tail = function (array) { - return array.slice(1); - }; - - /** - * returns item of array - */ - var find = function (array, pred) { - for (var idx = 0, len = array.length; idx < len; idx ++) { - var item = array[idx]; - if (pred(item)) { - return item; - } - } - }; - - /** - * returns true if all of the values in the array pass the predicate truth test. - */ - var all = function (array, pred) { - for (var idx = 0, len = array.length; idx < len; idx ++) { - if (!pred(array[idx])) { - return false; - } - } - return true; - }; - - /** - * returns index of item - */ - var indexOf = function (array, item) { - return $.inArray(item, array); - }; - - /** - * returns true if the value is present in the list. - */ - var contains = function (array, item) { - return indexOf(array, item) !== -1; - }; - - /** - * get sum from a list - * - * @param {Array} array - array - * @param {Function} fn - iterator - */ - var sum = function (array, fn) { - fn = fn || func.self; - return array.reduce(function (memo, v) { - return memo + fn(v); - }, 0); - }; - - /** - * returns a copy of the collection with array type. - * @param {Collection} collection - collection eg) node.childNodes, ... - */ - var from = function (collection) { - var result = [], idx = -1, length = collection.length; - while (++idx < length) { - result[idx] = collection[idx]; - } - return result; - }; - - /** - * cluster elements by predicate function. - * - * @param {Array} array - array - * @param {Function} fn - predicate function for cluster rule - * @param {Array[]} - */ - var clusterBy = function (array, fn) { - if (!array.length) { return []; } - var aTail = tail(array); - return aTail.reduce(function (memo, v) { - var aLast = last(memo); - if (fn(last(aLast), v)) { - aLast[aLast.length] = v; - } else { - memo[memo.length] = [v]; - } - return memo; - }, [[head(array)]]); - }; - - /** - * returns a copy of the array with all falsy values removed - * - * @param {Array} array - array - * @param {Function} fn - predicate function for cluster rule - */ - var compact = function (array) { - var aResult = []; - for (var idx = 0, len = array.length; idx < len; idx ++) { - if (array[idx]) { aResult.push(array[idx]); } - } - return aResult; - }; - - /** - * produces a duplicate-free version of the array - * - * @param {Array} array - */ - var unique = function (array) { - var results = []; - - for (var idx = 0, len = array.length; idx < len; idx ++) { - if (!contains(results, array[idx])) { - results.push(array[idx]); - } - } - - return results; - }; - - /** - * returns next item. - * @param {Array} array - */ - var next = function (array, item) { - var idx = indexOf(array, item); - if (idx === -1) { return null; } - - return array[idx + 1]; - }; - - /** - * returns prev item. - * @param {Array} array - */ - var prev = function (array, item) { - var idx = indexOf(array, item); - if (idx === -1) { return null; } - - return array[idx - 1]; - }; - - return { head: head, last: last, initial: initial, tail: tail, - prev: prev, next: next, find: find, contains: contains, - all: all, sum: sum, from: from, - clusterBy: clusterBy, compact: compact, unique: unique }; - })(); - - return list; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/core/range.js b/addons/web_editor/static/lib/summernote/src/js/core/range.js deleted file mode 100644 index 5c2dbe3b32c..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/core/range.js +++ /dev/null @@ -1,790 +0,0 @@ -define([ - 'summernote/core/agent', - 'summernote/core/func', - 'summernote/core/list', - 'summernote/core/dom' -], function (agent, func, list, dom) { - - var range = (function () { - - /** - * return boundaryPoint from TextRange, inspired by Andy Na's HuskyRange.js - * - * @param {TextRange} textRange - * @param {Boolean} isStart - * @return {BoundaryPoint} - * - * @see http://msdn.microsoft.com/en-us/library/ie/ms535872(v=vs.85).aspx - */ - var textRangeToPoint = function (textRange, isStart) { - var container = textRange.parentElement(), offset; - - var tester = document.body.createTextRange(), prevContainer; - var childNodes = list.from(container.childNodes); - for (offset = 0; offset < childNodes.length; offset++) { - if (dom.isText(childNodes[offset])) { - continue; - } - tester.moveToElementText(childNodes[offset]); - if (tester.compareEndPoints('StartToStart', textRange) >= 0) { - break; - } - prevContainer = childNodes[offset]; - } - - if (offset !== 0 && dom.isText(childNodes[offset - 1])) { - var textRangeStart = document.body.createTextRange(), curTextNode = null; - textRangeStart.moveToElementText(prevContainer || container); - textRangeStart.collapse(!prevContainer); - curTextNode = prevContainer ? prevContainer.nextSibling : container.firstChild; - - var pointTester = textRange.duplicate(); - pointTester.setEndPoint('StartToStart', textRangeStart); - var textCount = pointTester.text.replace(/[\r\n]/g, '').length; - - while (textCount > curTextNode.nodeValue.length && curTextNode.nextSibling) { - textCount -= curTextNode.nodeValue.length; - curTextNode = curTextNode.nextSibling; - } - - /* jshint ignore:start */ - var dummy = curTextNode.nodeValue; // enforce IE to re-reference curTextNode, hack - /* jshint ignore:end */ - - if (isStart && curTextNode.nextSibling && dom.isText(curTextNode.nextSibling) && - textCount === curTextNode.nodeValue.length) { - textCount -= curTextNode.nodeValue.length; - curTextNode = curTextNode.nextSibling; - } - - container = curTextNode; - offset = textCount; - } - - return { - cont: container, - offset: offset - }; - }; - - /** - * return TextRange from boundary point (inspired by google closure-library) - * @param {BoundaryPoint} point - * @return {TextRange} - */ - var pointToTextRange = function (point) { - var textRangeInfo = function (container, offset) { - var node, isCollapseToStart; - - if (dom.isText(container)) { - var prevTextNodes = dom.listPrev(container, func.not(dom.isText)); - var prevContainer = list.last(prevTextNodes).previousSibling; - node = prevContainer || container.parentNode; - offset += list.sum(list.tail(prevTextNodes), dom.nodeLength); - isCollapseToStart = !prevContainer; - } else { - node = container.childNodes[offset] || container; - if (dom.isText(node)) { - return textRangeInfo(node, 0); - } - - offset = 0; - isCollapseToStart = false; - } - - return { - node: node, - collapseToStart: isCollapseToStart, - offset: offset - }; - }; - - var textRange = document.body.createTextRange(); - var info = textRangeInfo(point.node, point.offset); - - textRange.moveToElementText(info.node); - textRange.collapse(info.collapseToStart); - textRange.moveStart('character', info.offset); - return textRange; - }; - - /** - * Wrapped Range - * - * @constructor - * @param {Node} sc - start container - * @param {Number} so - start offset - * @param {Node} ec - end container - * @param {Number} eo - end offset - */ - var WrappedRange = function (sc, so, ec, eo) { - this.sc = sc; - this.so = so; - this.ec = ec; - this.eo = eo; - - // nativeRange: get nativeRange from sc, so, ec, eo - var nativeRange = function () { - if (agent.isW3CRangeSupport) { - var w3cRange = document.createRange(); - w3cRange.setStart(sc, so); - w3cRange.setEnd(ec, eo); - - return w3cRange; - } else { - var textRange = pointToTextRange({ - node: sc, - offset: so - }); - - textRange.setEndPoint('EndToEnd', pointToTextRange({ - node: ec, - offset: eo - })); - - return textRange; - } - }; - - this.getPoints = function () { - return { - sc: sc, - so: so, - ec: ec, - eo: eo - }; - }; - - this.getStartPoint = function () { - return { - node: sc, - offset: so - }; - }; - - this.getEndPoint = function () { - return { - node: ec, - offset: eo - }; - }; - - /** - * select update visible range - */ - this.select = function () { - var nativeRng = nativeRange(); - if (agent.isW3CRangeSupport) { - var selection = document.getSelection(); - if (selection.rangeCount > 0) { - selection.removeAllRanges(); - } - selection.addRange(nativeRng); - } else { - nativeRng.select(); - } - - return this; - }; - - /** - * @return {WrappedRange} - */ - this.normalize = function () { - - /** - * @param {BoundaryPoint} point - * @param {Boolean} isLeftToRight - * @return {BoundaryPoint} - */ - var getVisiblePoint = function (point, isLeftToRight) { - if ((dom.isVisiblePoint(point) && !dom.isEdgePoint(point)) || - (dom.isVisiblePoint(point) && dom.isRightEdgePoint(point) && !isLeftToRight) || - (dom.isVisiblePoint(point) && dom.isLeftEdgePoint(point) && isLeftToRight) || - (dom.isVisiblePoint(point) && dom.isBlock(point.node) && dom.isEmpty(point.node))) { - return point; - } - - // point on block's edge - var block = dom.ancestor(point.node, dom.isBlock); - if (((dom.isLeftEdgePointOf(point, block) || dom.isVoid(dom.prevPoint(point).node)) && !isLeftToRight) || - ((dom.isRightEdgePointOf(point, block) || dom.isVoid(dom.nextPoint(point).node)) && isLeftToRight)) { - - // returns point already on visible point - if (dom.isVisiblePoint(point)) { - return point; - } - // reverse direction - isLeftToRight = !isLeftToRight; - } - - var nextPoint = isLeftToRight ? dom.nextPointUntil(dom.nextPoint(point), dom.isVisiblePoint) : - dom.prevPointUntil(dom.prevPoint(point), dom.isVisiblePoint); - return nextPoint || point; - }; - - var endPoint = getVisiblePoint(this.getEndPoint(), false); - var startPoint = this.isCollapsed() ? endPoint : getVisiblePoint(this.getStartPoint(), true); - - return new WrappedRange( - startPoint.node, - startPoint.offset, - endPoint.node, - endPoint.offset - ); - }; - - /** - * returns matched nodes on range - * - * @param {Function} [pred] - predicate function - * @param {Object} [options] - * @param {Boolean} [options.includeAncestor] - * @param {Boolean} [options.fullyContains] - * @return {Node[]} - */ - this.nodes = function (pred, options) { - pred = pred || func.ok; - - var includeAncestor = options && options.includeAncestor; - var fullyContains = options && options.fullyContains; - - // TODO compare points and sort - var startPoint = this.getStartPoint(); - var endPoint = this.getEndPoint(); - - var nodes = []; - var leftEdgeNodes = []; - - dom.walkPoint(startPoint, endPoint, function (point) { - if (dom.isEditable(point.node)) { - return; - } - - var node; - if (fullyContains) { - if (dom.isLeftEdgePoint(point)) { - leftEdgeNodes.push(point.node); - } - if (dom.isRightEdgePoint(point) && list.contains(leftEdgeNodes, point.node)) { - node = point.node; - } - } else if (includeAncestor) { - node = dom.ancestor(point.node, pred); - } else { - node = point.node; - } - - if (node && pred(node)) { - nodes.push(node); - } - }, true); - - return list.unique(nodes); - }; - - /** - * returns commonAncestor of range - * @return {Element} - commonAncestor - */ - this.commonAncestor = function () { - return dom.commonAncestor(sc, ec); - }; - - /** - * returns expanded range by pred - * - * @param {Function} pred - predicate function - * @return {WrappedRange} - */ - this.expand = function (pred) { - var startAncestor = dom.ancestor(sc, pred); - var endAncestor = dom.ancestor(ec, pred); - - if (!startAncestor && !endAncestor) { - return new WrappedRange(sc, so, ec, eo); - } - - var boundaryPoints = this.getPoints(); - - if (startAncestor) { - boundaryPoints.sc = startAncestor; - boundaryPoints.so = 0; - } - - if (endAncestor) { - boundaryPoints.ec = endAncestor; - boundaryPoints.eo = dom.nodeLength(endAncestor); - } - - return new WrappedRange( - boundaryPoints.sc, - boundaryPoints.so, - boundaryPoints.ec, - boundaryPoints.eo - ); - }; - - /** - * @param {Boolean} isCollapseToStart - * @return {WrappedRange} - */ - this.collapse = function (isCollapseToStart) { - if (isCollapseToStart) { - return new WrappedRange(sc, so, sc, so); - } else { - return new WrappedRange(ec, eo, ec, eo); - } - }; - - /** - * splitText on range - */ - this.splitText = function () { - var isSameContainer = sc === ec; - var boundaryPoints = this.getPoints(); - - if (dom.isText(ec) && !dom.isEdgePoint(this.getEndPoint())) { - ec.splitText(eo); - } - - if (dom.isText(sc) && !dom.isEdgePoint(this.getStartPoint())) { - boundaryPoints.sc = sc.splitText(so); - boundaryPoints.so = 0; - - if (isSameContainer) { - boundaryPoints.ec = boundaryPoints.sc; - boundaryPoints.eo = eo - so; - } - } - - return new WrappedRange( - boundaryPoints.sc, - boundaryPoints.so, - boundaryPoints.ec, - boundaryPoints.eo - ); - }; - - /** - * delete contents on range - * @return {WrappedRange} - */ - if(_.isUndefined(this.deleteContents)) // ODOO: ability to override by prototype - this.deleteContents = function () { - if (this.isCollapsed()) { - return this; - } - - var rng = this.splitText(); - var nodes = rng.nodes(null, { - fullyContains: true - }); - - // find new cursor point - var point = dom.prevPointUntil(rng.getStartPoint(), function (point) { - return !list.contains(nodes, point.node); - }); - - var emptyParents = []; - $.each(nodes, function (idx, node) { - // find empty parents - var parent = node.parentNode; - if (point.node !== parent && dom.nodeLength(parent) === 1) { - emptyParents.push(parent); - } - dom.remove(node, false); - }); - - // remove empty parents - $.each(emptyParents, function (idx, node) { - dom.remove(node, false); - }); - - return new WrappedRange( - point.node, - point.offset, - point.node, - point.offset - ).normalize(); - }; - - /** - * makeIsOn: return isOn(pred) function - */ - var makeIsOn = function (pred) { - return function () { - var ancestor = dom.ancestor(sc, pred); - return !!ancestor && (ancestor === dom.ancestor(ec, pred)); - }; - }; - - // isOnEditable: judge whether range is on editable or not - this.isOnEditable = makeIsOn(dom.isEditable); - // isOnList: judge whether range is on list node or not - this.isOnList = makeIsOn(dom.isList); - // isOnAnchor: judge whether range is on anchor node or not - this.isOnAnchor = makeIsOn(dom.isAnchor); - // isOnAnchor: judge whether range is on cell node or not - this.isOnCell = makeIsOn(dom.isCell); - - /** - * @param {Function} pred - * @return {Boolean} - */ - this.isLeftEdgeOf = function (pred) { - if (!dom.isLeftEdgePoint(this.getStartPoint())) { - return false; - } - - var node = dom.ancestor(this.sc, pred); - return node && dom.isLeftEdgeOf(this.sc, node); - }; - - /** - * returns whether range was collapsed or not - */ - this.isCollapsed = function () { - return sc === ec && so === eo; - }; - - /** - * wrap inline nodes which children of body with paragraph - * - * @return {WrappedRange} - */ - this.wrapBodyInlineWithPara = function () { - if (dom.isBodyContainer(sc) && dom.isEmpty(sc)) { - sc.innerHTML = dom.emptyPara; - return new WrappedRange(sc.firstChild, 0, sc.firstChild, 0); - } - - /** - * [workaround] firefox often create range on not visible point. so normalize here. - * - firefox: |text
| - * - chrome:|text|
- */ - var rng = this.normalize(); - if (dom.isParaInline(sc) || dom.isPara(sc)) { - return rng; - } - - // ODOO: insert a p tag when try to insert a br with insertNode method, if the editor is inside a p, li, h1... (start_modification - // if apply the editor to a P, LI... or inside a P, LI... - if (dom.isText(sc)) { - var node = sc; - while (node.parentNode !== document) { - node = node.parentNode; - if (/^(P|LI|H[1-7]|BUTTON|A|SPAN)/.test(node.nodeName.toUpperCase())) { - return this.normalize(); - } - } - } - // ODOO: end_modification) - - // find inline top ancestor - var topAncestor; - if (dom.isInline(rng.sc)) { - var ancestors = dom.listAncestor(rng.sc, func.not(dom.isInline)); - topAncestor = list.last(ancestors); - if (!dom.isInline(topAncestor)) { - topAncestor = ancestors[ancestors.length - 2] || rng.sc.childNodes[rng.so]; - } - } else { - topAncestor = rng.sc.childNodes[rng.so > 0 ? rng.so - 1 : 0]; - } - - // siblings not in paragraph - var inlineSiblings = dom.listPrev(topAncestor, dom.isParaInline).reverse(); - inlineSiblings = inlineSiblings.concat(dom.listNext(topAncestor.nextSibling, dom.isParaInline)); - - // wrap with paragraph - if (inlineSiblings.length) { - var para = dom.wrap(list.head(inlineSiblings), 'p'); - dom.appendChildNodes(para, list.tail(inlineSiblings)); - } - - return this.normalize(); - }; - - /** - * insert node at current cursor - * - * @param {Node} node - * @return {Node} - */ - this.insertNode = function (node) { - var rng = this.wrapBodyInlineWithPara().deleteContents(); - // ODOO: override to not split world for inserting inline - // original: var info = dom.splitPoint(rng.getStartPoint(), dom.isInline(node)); - var info = dom.splitPoint(rng.getStartPoint(), !dom.isBodyContainer(dom.ancestor(rng.sc, function(node) { return dom.isBodyContainer(node) || dom.isPara(node) }))); - - if (info.rightNode) { - info.rightNode.parentNode.insertBefore(node, info.rightNode); - } else { - info.container.appendChild(node); - } - - return node; - }; - - /** - * insert html at current cursor - */ - this.pasteHTML = function (markup) { - var contentsContainer = $('').html(markup)[0]; - var childNodes = list.from(contentsContainer.childNodes); - - var rng = this.wrapBodyInlineWithPara().deleteContents(); - - return childNodes.reverse().map(function (childNode) { - return rng.insertNode(childNode); - }).reverse(); - }; - - /** - * returns text in range - * - * @return {String} - */ - this.toString = function () { - var nativeRng = nativeRange(); - return agent.isW3CRangeSupport ? nativeRng.toString() : nativeRng.text; - }; - - /** - * returns range for word before cursor - * - * @param {Boolean} [findAfter] - find after cursor, default: false - * @return {WrappedRange} - */ - this.getWordRange = function (findAfter) { - var endPoint = this.getEndPoint(); - - if (!dom.isCharPoint(endPoint)) { - return this; - } - - var startPoint = dom.prevPointUntil(endPoint, function (point) { - return !dom.isCharPoint(point); - }); - - if (findAfter) { - endPoint = dom.nextPointUntil(endPoint, function (point) { - return !dom.isCharPoint(point); - }); - } - - return new WrappedRange( - startPoint.node, - startPoint.offset, - endPoint.node, - endPoint.offset - ); - }; - - /** - * create offsetPath bookmark - * - * @param {Node} editable - */ - this.bookmark = function (editable) { - return { - s: { - path: dom.makeOffsetPath(editable, sc), - offset: so - }, - e: { - path: dom.makeOffsetPath(editable, ec), - offset: eo - } - }; - }; - - /** - * create offsetPath bookmark base on paragraph - * - * @param {Node[]} paras - */ - this.paraBookmark = function (paras) { - return { - s: { - path: list.tail(dom.makeOffsetPath(list.head(paras), sc)), - offset: so - }, - e: { - path: list.tail(dom.makeOffsetPath(list.last(paras), ec)), - offset: eo - } - }; - }; - - /** - * getClientRects - * @return {Rect[]} - */ - this.getClientRects = function () { - var nativeRng = nativeRange(); - return nativeRng.getClientRects(); - }; - }; - - /** - * @class core.range - * - * Data structure - * * BoundaryPoint: a point of dom tree - * * BoundaryPoints: two boundaryPoints corresponding to the start and the end of the Range - * - * See to http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position - * - * @singleton - * @alternateClassName range - */ - return { - WrappedRange: WrappedRange, // ODOO: give access to WrappedRange - /** - * @method - * - * create Range Object From arguments or Browser Selection - * - * @param {Node} sc - start container - * @param {Number} so - start offset - * @param {Node} ec - end container - * @param {Number} eo - end offset - * @return {WrappedRange} - */ - create : function (sc, so, ec, eo) { - if (!arguments.length) { // from Browser Selection - if (agent.isW3CRangeSupport) { - var selection = document.getSelection(); - if (!selection || selection.rangeCount === 0) { - return null; - } else if (dom.isBody(selection.anchorNode)) { - // Firefox: returns entire body as range on initialization. We won't never need it. - return null; - } - - var nativeRng = selection.getRangeAt(0); - sc = nativeRng.startContainer; - so = nativeRng.startOffset; - ec = nativeRng.endContainer; - eo = nativeRng.endOffset; - } else { // IE8: TextRange - var textRange = document.selection.createRange(); - var textRangeEnd = textRange.duplicate(); - textRangeEnd.collapse(false); - var textRangeStart = textRange; - textRangeStart.collapse(true); - - var startPoint = textRangeToPoint(textRangeStart, true), - endPoint = textRangeToPoint(textRangeEnd, false); - - // same visible point case: range was collapsed. - if (dom.isText(startPoint.node) && dom.isLeftEdgePoint(startPoint) && - dom.isTextNode(endPoint.node) && dom.isRightEdgePoint(endPoint) && - endPoint.node.nextSibling === startPoint.node) { - startPoint = endPoint; - } - - sc = startPoint.cont; - so = startPoint.offset; - ec = endPoint.cont; - eo = endPoint.offset; - } - } else if (arguments.length === 2) { //collapsed - ec = sc; - eo = so; - } - return new WrappedRange(sc, so, ec, eo); - }, - - /** - * @method - * - * create WrappedRange from node - * - * @param {Node} node - * @return {WrappedRange} - */ - createFromNode: function (node) { - var sc = node; - var so = 0; - var ec = node; - var eo = dom.nodeLength(ec); - - // browsers can't target a picture or void node - if (dom.isVoid(sc)) { - so = dom.listPrev(sc).length - 1; - sc = sc.parentNode; - } - if (dom.isBR(ec)) { - eo = dom.listPrev(ec).length - 1; - ec = ec.parentNode; - } else if (dom.isVoid(ec)) { - eo = dom.listPrev(ec).length; - ec = ec.parentNode; - } - - return this.create(sc, so, ec, eo); - }, - - /** - * create WrappedRange from node after position - * - * @param {Node} node - * @return {WrappedRange} - */ - createFromNodeBefore: function (node) { - return this.createFromNode(node).collapse(true); - }, - - /** - * create WrappedRange from node after position - * - * @param {Node} node - * @return {WrappedRange} - */ - createFromNodeAfter: function (node) { - return this.createFromNode(node).collapse(); - }, - - /** - * @method - * - * create WrappedRange from bookmark - * - * @param {Node} editable - * @param {Object} bookmark - * @return {WrappedRange} - */ - createFromBookmark : function (editable, bookmark) { - var sc = dom.fromOffsetPath(editable, bookmark.s.path); - var so = bookmark.s.offset; - var ec = dom.fromOffsetPath(editable, bookmark.e.path); - var eo = bookmark.e.offset; - return new WrappedRange(sc, so, ec, eo); - }, - - /** - * @method - * - * create WrappedRange from paraBookmark - * - * @param {Object} bookmark - * @param {Node[]} paras - * @return {WrappedRange} - */ - createFromParaBookmark: function (bookmark, paras) { - var so = bookmark.s.offset; - var eo = bookmark.e.offset; - var sc = dom.fromOffsetPath(list.head(paras), bookmark.s.path); - var ec = dom.fromOffsetPath(list.last(paras), bookmark.e.path); - - return new WrappedRange(sc, so, ec, eo); - } - }; - })(); - - return range; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/defaults.js b/addons/web_editor/static/lib/summernote/src/js/defaults.js deleted file mode 100644 index 9d8e0bab661..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/defaults.js +++ /dev/null @@ -1,416 +0,0 @@ -define('summernote/defaults', function () { - /** - * @class defaults - * - * @singleton - */ - var defaults = { - /** @property */ - version: '@VERSION', - - /** - * - * for event options, reference to EventHandler.attach - * - * @property {Object} options - * @property {String/Number} [options.width=null] set editor width - * @property {String/Number} [options.height=null] set editor height, ex) 300 - * @property {String/Number} options.minHeight set minimum height of editor - * @property {String/Number} options.maxHeight - * @property {String/Number} options.focus - * @property {Number} options.tabsize - * @property {Boolean} options.styleWithSpan - * @property {Object} options.codemirror - * @property {Object} [options.codemirror.mode='text/html'] - * @property {Object} [options.codemirror.htmlMode=true] - * @property {Object} [options.codemirror.lineNumbers=true] - * @property {String} [options.lang=en-US] language 'en-US', 'ko-KR', ... - * @property {String} [options.direction=null] text direction, ex) 'rtl' - * @property {Array} [options.toolbar] - * @property {Boolean} [options.airMode=false] - * @property {Array} [options.airPopover] - * @property {Fucntion} [options.onInit] initialize - * @property {Fucntion} [options.onsubmit] - */ - options: { - width: null, // set editor width - height: null, // set editor height, ex) 300 - - minHeight: null, // set minimum height of editor - maxHeight: null, // set maximum height of editor - - focus: false, // set focus to editable area after initializing summernote - - tabsize: 4, // size of tab ex) 2 or 4 - styleWithSpan: true, // style with span (Chrome and FF only) - - disableLinkTarget: false, // hide link Target Checkbox - disableDragAndDrop: false, // disable drag and drop event - disableResizeEditor: false, // disable resizing editor - disableResizeImage: false, // disable resizing image - - shortcuts: true, // enable keyboard shortcuts - - textareaAutoSync: true, // enable textarea auto sync - - placeholder: false, // enable placeholder text - prettifyHtml: true, // enable prettifying html while toggling codeview - - iconPrefix: 'fa fa-', // prefix for css icon classes - - icons: { - font: { - bold: 'bold', - italic: 'italic', - underline: 'underline', - clear: 'eraser', - height: 'text-height', - strikethrough: 'strikethrough', - superscript: 'superscript', - subscript: 'subscript' - }, - image: { - image: 'picture-o', - floatLeft: 'align-left', - floatRight: 'align-right', - floatNone: 'align-justify', - shapeRounded: 'square', - shapeCircle: 'circle-o', - shapeThumbnail: 'picture-o', - shapeNone: 'times', - remove: 'trash-o' - }, - link: { - link: 'link', - unlink: 'unlink', - edit: 'edit' - }, - table: { - table: 'table' - }, - hr: { - insert: 'minus' - }, - style: { - style: 'magic' - }, - lists: { - unordered: 'list-ul', - ordered: 'list-ol' - }, - options: { - help: 'question', - fullscreen: 'arrows-alt', - codeview: 'code' - }, - paragraph: { - paragraph: 'align-left', - outdent: 'outdent', - indent: 'indent', - left: 'align-left', - center: 'align-center', - right: 'align-right', - justify: 'align-justify' - }, - color: { - recent: 'font' - }, - history: { - undo: 'undo', - redo: 'repeat' - }, - misc: { - check: 'check' - } - }, - - dialogsInBody: false, // false will add dialogs into editor - - codemirror: { // codemirror options - mode: 'text/html', - htmlMode: true, - lineNumbers: true - }, - - // language - lang: 'en-US', // language 'en-US', 'ko-KR', ... - direction: null, // text direction, ex) 'rtl' - - // toolbar - toolbar: [ - ['style', ['style']], - ['font', ['bold', 'italic', 'underline', 'clear']], - // ['font', ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', 'clear']], - ['fontname', ['fontname']], - ['fontsize', ['fontsize']], - ['color', ['color']], - ['para', ['ul', 'ol', 'paragraph']], - ['height', ['height']], - ['table', ['table']], - ['insert', ['link', 'picture', 'hr']], - ['view', ['fullscreen', 'codeview']], - ['help', ['help']] - ], - - plugin : { }, - - // air mode: inline editor - airMode: false, - // airPopover: [ - // ['style', ['style']], - // ['font', ['bold', 'italic', 'underline', 'clear']], - // ['fontname', ['fontname']], - // ['color', ['color']], - // ['para', ['ul', 'ol', 'paragraph']], - // ['height', ['height']], - // ['table', ['table']], - // ['insert', ['link', 'picture']], - // ['help', ['help']] - // ], - airPopover: [ - ['color', ['color']], - ['font', ['bold', 'underline', 'clear']], - ['para', ['ul', 'paragraph']], - ['table', ['table']], - ['insert', ['link', 'picture']] - ], - - // style tag - styleTags: ['p', 'blockquote', 'pre', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6'], - - // default fontName - defaultFontName: 'Helvetica Neue', - - // fontName - fontNames: [ - 'Arial', 'Arial Black', 'Comic Sans MS', 'Courier New', - 'Helvetica Neue', 'Helvetica', 'Impact', 'Lucida Grande', - 'Tahoma', 'Times New Roman', 'Verdana' - ], - fontNamesIgnoreCheck: [], - - fontSizes: ['8', '9', '10', '11', '12', '14', '18', '24', '36'], - - // pallete colors(n x n) - colors: [ - ['#000000', '#424242', '#636363', '#9C9C94', '#CEC6CE', '#EFEFEF', '#F7F7F7', '#FFFFFF'], - ['#FF0000', '#FF9C00', '#FFFF00', '#00FF00', '#00FFFF', '#0000FF', '#9C00FF', '#FF00FF'], - ['#F7C6CE', '#FFE7CE', '#FFEFC6', '#D6EFD6', '#CEDEE7', '#CEE7F7', '#D6D6E7', '#E7D6DE'], - ['#E79C9C', '#FFC69C', '#FFE79C', '#B5D6A5', '#A5C6CE', '#9CC6EF', '#B5A5D6', '#D6A5BD'], - ['#E76363', '#F7AD6B', '#FFD663', '#94BD7B', '#73A5AD', '#6BADDE', '#8C7BC6', '#C67BA5'], - ['#CE0000', '#E79439', '#EFC631', '#6BA54A', '#4A7B8C', '#3984C6', '#634AA5', '#A54A7B'], - ['#9C0000', '#B56308', '#BD9400', '#397B21', '#104A5A', '#085294', '#311873', '#731842'], - ['#630000', '#7B3900', '#846300', '#295218', '#083139', '#003163', '#21104A', '#4A1031'] - ], - - // lineHeight - lineHeights: ['1.0', '1.2', '1.4', '1.5', '1.6', '1.8', '2.0', '3.0'], - - // insertTable max size - insertTableMaxSize: { - col: 10, - row: 10 - }, - - // image - maximumImageFileSize: null, // size in bytes, null = no limit - - // callbacks - oninit: null, // initialize - onfocus: null, // editable has focus - onblur: null, // editable out of focus - onenter: null, // enter key pressed - onkeyup: null, // keyup - onkeydown: null, // keydown - onImageUpload: null, // imageUpload - onImageUploadError: null, // imageUploadError - onMediaDelete: null, // media delete - onToolbarClick: null, - onsubmit: null, - - /** - * manipulate link address when user create link - * @param {String} sLinkUrl - * @return {String} - */ - onCreateLink: function (sLinkUrl) { - if (sLinkUrl.indexOf('@') !== -1 && sLinkUrl.indexOf(':') === -1) { - sLinkUrl = 'mailto:' + sLinkUrl; - } - - return sLinkUrl; - }, - - keyMap: { - pc: { - 'ENTER': 'insertParagraph', - 'CTRL+Z': 'undo', - 'CTRL+Y': 'redo', - 'TAB': 'tab', - 'SHIFT+TAB': 'untab', - 'CTRL+B': 'bold', - 'CTRL+I': 'italic', - 'CTRL+U': 'underline', - 'CTRL+SHIFT+S': 'strikethrough', - 'CTRL+BACKSLASH': 'removeFormat', - 'CTRL+SHIFT+L': 'justifyLeft', - 'CTRL+SHIFT+E': 'justifyCenter', - 'CTRL+SHIFT+R': 'justifyRight', - 'CTRL+SHIFT+J': 'justifyFull', - 'CTRL+SHIFT+NUM7': 'insertUnorderedList', - 'CTRL+SHIFT+NUM8': 'insertOrderedList', - 'CTRL+LEFTBRACKET': 'outdent', - 'CTRL+RIGHTBRACKET': 'indent', - 'CTRL+NUM0': 'formatPara', - 'CTRL+NUM1': 'formatH1', - 'CTRL+NUM2': 'formatH2', - 'CTRL+NUM3': 'formatH3', - 'CTRL+NUM4': 'formatH4', - 'CTRL+NUM5': 'formatH5', - 'CTRL+NUM6': 'formatH6', - 'CTRL+ENTER': 'insertHorizontalRule', - 'CTRL+K': 'showLinkDialog' - }, - - mac: { - 'ENTER': 'insertParagraph', - 'CMD+Z': 'undo', - 'CMD+SHIFT+Z': 'redo', - 'TAB': 'tab', - 'SHIFT+TAB': 'untab', - 'CMD+B': 'bold', - 'CMD+I': 'italic', - 'CMD+U': 'underline', - 'CMD+SHIFT+S': 'strikethrough', - 'CMD+BACKSLASH': 'removeFormat', - 'CMD+SHIFT+L': 'justifyLeft', - 'CMD+SHIFT+E': 'justifyCenter', - 'CMD+SHIFT+R': 'justifyRight', - 'CMD+SHIFT+J': 'justifyFull', - 'CMD+SHIFT+NUM7': 'insertUnorderedList', - 'CMD+SHIFT+NUM8': 'insertOrderedList', - 'CMD+LEFTBRACKET': 'outdent', - 'CMD+RIGHTBRACKET': 'indent', - 'CMD+NUM0': 'formatPara', - 'CMD+NUM1': 'formatH1', - 'CMD+NUM2': 'formatH2', - 'CMD+NUM3': 'formatH3', - 'CMD+NUM4': 'formatH4', - 'CMD+NUM5': 'formatH5', - 'CMD+NUM6': 'formatH6', - 'CMD+ENTER': 'insertHorizontalRule', - 'CMD+K': 'showLinkDialog' - } - } - }, - - // default language: en-US - lang: { - 'en-US': { - font: { - bold: 'Bold', - italic: 'Italic', - underline: 'Underline', - clear: 'Remove Font Style', - height: 'Line Height', - name: 'Font Family', - strikethrough: 'Strikethrough', - subscript: 'Subscript', - superscript: 'Superscript', - size: 'Font Size' - }, - image: { - image: 'Picture', - insert: 'Insert Image', - resizeFull: 'Resize Full', - resizeHalf: 'Resize Half', - resizeQuarter: 'Resize Quarter', - floatLeft: 'Float Left', - floatRight: 'Float Right', - floatNone: 'Float None', - shapeRounded: 'Shape: Rounded', - shapeCircle: 'Shape: Circle', - shapeThumbnail: 'Shape: Thumbnail', - shapeNone: 'Shape: None', - dragImageHere: 'Drag image or text here', - dropImage: 'Drop image or Text', - selectFromFiles: 'Select from files', - maximumFileSize: 'Maximum file size', - maximumFileSizeError: 'Maximum file size exceeded.', - url: 'Image URL', - remove: 'Remove Image' - }, - link: { - link: 'Link', - insert: 'Insert Link', - unlink: 'Unlink', - edit: 'Edit', - textToDisplay: 'Text to display', - url: 'To what URL should this link go?', - openInNewWindow: 'Open in new window' - }, - table: { - table: 'Table' - }, - hr: { - insert: 'Insert Horizontal Rule' - }, - style: { - style: 'Style', - normal: 'Paragraph', - blockquote: 'Quote', - pre: 'Code', - h1: 'Header 1', - h2: 'Header 2', - h3: 'Header 3', - h4: 'Header 4', - h5: 'Header 5', - h6: 'Header 6' - }, - lists: { - unordered: 'Unordered list', - ordered: 'Ordered list' - }, - options: { - help: 'Help', - fullscreen: 'Full Screen', - codeview: 'Code View' - }, - paragraph: { - paragraph: 'Paragraph', - outdent: 'Outdent', - indent: 'Indent', - left: 'Align left', - center: 'Align center', - right: 'Align right', - justify: 'Justify full' - }, - color: { - recent: 'Recent Color', - more: 'More Color', - background: 'Background Color', - foreground: 'Foreground Color', - transparent: 'Transparent', - setTransparent: 'Set transparent', - reset: 'Reset', - resetToDefault: 'Reset to default' - }, - shortcut: { - shortcuts: 'Keyboard shortcuts', - close: 'Close', - textFormatting: 'Text formatting', - action: 'Action', - paragraphFormatting: 'Paragraph formatting', - documentStyle: 'Document Style', - extraKeys: 'Extra keys' - }, - history: { - undo: 'Undo', - redo: 'Redo' - } - } - } - }; - - return defaults; -}); diff --git a/addons/web_editor/static/lib/summernote/src/js/editing/Bullet.js b/addons/web_editor/static/lib/summernote/src/js/editing/Bullet.js deleted file mode 100644 index 6a115edaa90..00000000000 --- a/addons/web_editor/static/lib/summernote/src/js/editing/Bullet.js +++ /dev/null @@ -1,235 +0,0 @@ -define([ - 'summernote/core/list', - 'summernote/core/func', - 'summernote/core/dom', - 'summernote/core/range' -], function (list, func, dom, range) { - - /** - * @class editing.Bullet - * - * @alternateClassName Bullet - */ - var Bullet = function () { - /** - * @method insertOrderedList - * - * toggle ordered list - * - * @type command - */ - this.insertOrderedList = function () { - this.toggleList('OL'); - }; - - /** - * @method insertUnorderedList - * - * toggle unordered list - * - * @type command - */ - this.insertUnorderedList = function () { - this.toggleList('UL'); - }; - - /** - * @method indent - * - * indent - * - * @type command - */ - this.indent = function () { - var self = this; - var rng = range.create().wrapBodyInlineWithPara(); - - var paras = rng.nodes(dom.isPara, { includeAncestor: true }); - var clustereds = list.clusterBy(paras, func.peq2('parentNode')); - - $.each(clustereds, function (idx, paras) { - var head = list.head(paras); - if (dom.isLi(head)) { - self.wrapList(paras, head.parentNode.nodeName); - } else { - $.each(paras, function (idx, para) { - $(para).css('marginLeft', function (idx, val) { - return (parseInt(val, 10) || 0) + 25; - }); - }); - } - }); - - rng.select(); - }; - - /** - * @method outdent - * - * outdent - * - * @type command - */ - this.outdent = function () { - var self = this; - var rng = range.create().wrapBodyInlineWithPara(); - - var paras = rng.nodes(dom.isPara, { includeAncestor: true }); - var clustereds = list.clusterBy(paras, func.peq2('parentNode')); - - $.each(clustereds, function (idx, paras) { - var head = list.head(paras); - if (dom.isLi(head)) { - self.releaseList([paras]); - } else { - $.each(paras, function (idx, para) { - $(para).css('marginLeft', function (idx, val) { - val = (parseInt(val, 10) || 0); - return val > 25 ? val - 25 : ''; - }); - }); - } - }); - - rng.select(); - }; - - /** - * @method toggleList - * - * toggle list - * - * @param {String} listName - OL or UL - */ - this.toggleList = function (listName) { - var self = this; - var rng = range.create().wrapBodyInlineWithPara(); - - var paras = rng.nodes(dom.isPara, { includeAncestor: true }); - var bookmark = rng.paraBookmark(paras); - var clustereds = list.clusterBy(paras, func.peq2('parentNode')); - - // paragraph to list - if (list.find(paras, dom.isPurePara)) { - var wrappedParas = []; - $.each(clustereds, function (idx, paras) { - wrappedParas = wrappedParas.concat(self.wrapList(paras, listName)); - }); - paras = wrappedParas; - // list to paragraph or change list style - } else { - var diffLists = rng.nodes(dom.isList, { - includeAncestor: true - }).filter(function (listNode) { - return !$.nodeName(listNode, listName); - }); - - if (diffLists.length) { - $.each(diffLists, function (idx, listNode) { - dom.replace(listNode, listName); - }); - } else { - paras = this.releaseList(clustereds, true); - } - } - - range.createFromParaBookmark(bookmark, paras).select(); - }; - - /** - * @method wrapList - * - * @param {Node[]} paras - * @param {String} listName - * @return {Node[]} - */ - this.wrapList = function (paras, listName) { - var head = list.head(paras); - var last = list.last(paras); - - var prevList = dom.isList(head.previousSibling) && head.previousSibling; - var nextList = dom.isList(last.nextSibling) && last.nextSibling; - - var listNode = prevList || dom.insertAfter(dom.create(listName || 'UL'), last); - - // P to LI - paras = paras.map(function (para) { - return dom.isPurePara(para) ? dom.replace(para, 'LI') : para; - }); - - // append to list(