diff options
| author | Christophe Matthieu <chm@odoo.com> | 2014-12-10 15:59:48 +0100 |
|---|---|---|
| committer | Christophe Matthieu <chm@odoo.com> | 2015-01-05 10:17:10 +0100 |
| commit | 1596e45e8174cd736d4f7c78f85ec76a8e34888d (patch) | |
| tree | 4ff318ee78bccc6c0bb6253670e85977f8f5a643 /addons/website/static/lib/summernote/src/js/editing/Editor.js | |
| parent | f9a7ed6b9406d657fda33ec55c4e237576b77a42 (diff) | |
[IMP] website: add summernote lib
Diffstat (limited to 'addons/website/static/lib/summernote/src/js/editing/Editor.js')
| -rw-r--r-- | addons/website/static/lib/summernote/src/js/editing/Editor.js | 457 |
1 files changed, 457 insertions, 0 deletions
diff --git a/addons/website/static/lib/summernote/src/js/editing/Editor.js b/addons/website/static/lib/summernote/src/js/editing/Editor.js new file mode 100644 index 00000000000..35af842afe8 --- /dev/null +++ b/addons/website/static/lib/summernote/src/js/editing/Editor.js @@ -0,0 +1,457 @@ +define([ + 'summernote/core/agent', + 'summernote/core/func', + 'summernote/core/list', + 'summernote/core/dom', + 'summernote/core/range', + 'summernote/core/async', + 'summernote/editing/Style', + 'summernote/editing/Typing', + 'summernote/editing/Table', + 'summernote/editing/Bullet' +], function (agent, func, list, dom, range, async, + Style, Typing, Table, Bullet) { + /** + * Editor + * @class + */ + var Editor = function () { + + var style = new Style(); + var table = new Table(); + var typing = new Typing(); + var bullet = new Bullet(); + + /** + * create range + */ + this.createRange = function ($editable) { + $editable.focus(); + return range.create(); + }; + + /** + * save current range + * + * @param {jQuery} $editable + */ + this.saveRange = function ($editable, thenCollapse) { + $editable.focus(); + $editable.data('range', range.create()); + if (thenCollapse) { + range.create().collapse().select(); + } + }; + + /** + * restore lately range + * + * @param {jQuery} $editable + */ + this.restoreRange = function ($editable) { + var rng = $editable.data('range'); + if (rng) { + rng.select(); + $editable.focus(); + } + }; + + /** + * current style + * @param {Node} target + */ + this.currentStyle = function (target) { + var rng = range.create(); + return rng ? rng.isOnEditable() && style.current(rng, target) : false; + }; + + var triggerOnChange = this.triggerOnChange = function ($editable) { + var onChange = $editable.data('callbacks').onChange; + if (onChange) { + onChange($editable.html(), $editable); + } + }; + + /** + * undo + * @param {jQuery} $editable + */ + this.undo = function ($editable) { + $editable.data('NoteHistory').undo(); + triggerOnChange($editable); + }; + + /** + * redo + * @param {jQuery} $editable + */ + this.redo = function ($editable) { + $editable.data('NoteHistory').redo(); + triggerOnChange($editable); + }; + + /** + * after command + * @param {jQuery} $editable + */ + var afterCommand = this.afterCommand = function ($editable) { + $editable.data('NoteHistory').recordUndo(); + triggerOnChange($editable); + }; + + /* jshint ignore:start */ + // native commands(with execCommand), generate function for execCommand + var commands = ['bold', 'italic', 'underline', 'strikethrough', 'superscript', 'subscript', + 'justifyLeft', 'justifyCenter', 'justifyRight', 'justifyFull', + 'formatBlock', 'removeFormat', + 'backColor', 'foreColor', 'insertHorizontalRule', 'fontName']; + + for (var idx = 0, len = commands.length; idx < len; idx ++) { + this[commands[idx]] = (function (sCmd) { + return function ($editable, value) { + document.execCommand(sCmd, false, value); + + afterCommand($editable); + }; + })(commands[idx]); + } + /* jshint ignore:end */ + + /** + * handle tab key + * + * @param {jQuery} $editable + * @param {Object} options + */ + this.tab = function ($editable, options) { + var rng = range.create(); + if (rng.isCollapsed() && rng.isOnCell()) { + table.tab(rng); + } else { + typing.insertTab($editable, rng, options.tabsize); + afterCommand($editable); + } + }; + + /** + * handle shift+tab key + */ + this.untab = function () { + var rng = range.create(); + if (rng.isCollapsed() && rng.isOnCell()) { + table.tab(rng, true); + } + }; + + /** + * insert paragraph + * + * @param {Node} $editable + */ + this.insertParagraph = function ($editable) { + typing.insertParagraph($editable); + afterCommand($editable); + }; + + /** + * @param {jQuery} $editable + */ + this.insertOrderedList = function ($editable) { + bullet.insertOrderedList($editable); + afterCommand($editable); + }; + + /** + * @param {jQuery} $editable + */ + this.insertUnorderedList = function ($editable) { + bullet.insertUnorderedList($editable); + afterCommand($editable); + }; + + /** + * @param {jQuery} $editable + */ + this.indent = function ($editable) { + bullet.indent($editable); + afterCommand($editable); + }; + + /** + * @param {jQuery} $editable + */ + this.outdent = function ($editable) { + bullet.outdent($editable); + afterCommand($editable); + }; + + /** + * insert image + * + * @param {jQuery} $editable + * @param {String} sUrl + */ + this.insertImage = function ($editable, sUrl, filename) { + async.createImage(sUrl, filename).then(function ($image) { + $image.css({ + display: '', + width: Math.min($editable.width(), $image.width()) + }); + range.create().insertNode($image[0]); + afterCommand($editable); + }).fail(function () { + var callbacks = $editable.data('callbacks'); + if (callbacks.onImageUploadError) { + callbacks.onImageUploadError(); + } + }); + }; + + /** + * insert node + * @param {Node} $editable + * @param {Node} node + * @param {Boolean} [isInline] + */ + this.insertNode = function ($editable, node, isInline) { + range.create().insertNode(node, isInline); + afterCommand($editable); + }; + + /** + * insert text + * @param {Node} $editable + * @param {String} text + */ + this.insertText = function ($editable, text) { + var textNode = this.createRange($editable).insertNode(dom.createText(text), true); + range.create(textNode, dom.nodeLength(textNode)).select(); + afterCommand($editable); + }; + + /** + * formatBlock + * + * @param {jQuery} $editable + * @param {String} tagName + */ + this.formatBlock = function ($editable, tagName) { + tagName = agent.isMSIE ? '<' + tagName + '>' : tagName; + document.execCommand('FormatBlock', false, tagName); + afterCommand($editable); + }; + + this.formatPara = function ($editable) { + this.formatBlock($editable, 'P'); + afterCommand($editable); + }; + + /* jshint ignore:start */ + for (var idx = 1; idx <= 6; idx ++) { + this['formatH' + idx] = function (idx) { + return function ($editable) { + this.formatBlock($editable, 'H' + idx); + }; + }(idx); + }; + /* jshint ignore:end */ + + /** + * fontsize + * FIXME: Still buggy + * + * @param {jQuery} $editable + * @param {String} value - px + */ + this.fontSize = function ($editable, value) { + document.execCommand('fontSize', false, 3); + if (agent.isFF) { + // firefox: <font size="3"> to <span style='font-size={value}px;'>, buggy + $editable.find('font[size=3]').removeAttr('size').css('font-size', value + 'px'); + } else { + // chrome: <span style="font-size: medium"> to <span style='font-size={value}px;'> + $editable.find('span').filter(function () { + return this.style.fontSize === 'medium'; + }).css('font-size', value + 'px'); + } + + afterCommand($editable); + }; + + /** + * lineHeight + * @param {jQuery} $editable + * @param {String} value + */ + this.lineHeight = function ($editable, value) { + style.stylePara(range.create(), { + lineHeight: value + }); + afterCommand($editable); + }; + + /** + * unlink + * + * @type command + * + * @param {jQuery} $editable + */ + this.unlink = function ($editable) { + var rng = range.create(); + if (rng.isOnAnchor()) { + var anchor = dom.ancestor(rng.sc, dom.isAnchor); + rng = range.createFromNode(anchor); + rng.select(); + document.execCommand('unlink'); + + afterCommand($editable); + } + }; + + /** + * create link + * + * @type command + * + * @param {jQuery} $editable + * @param {Object} linkInfo + * @param {Object} options + */ + this.createLink = function ($editable, linkInfo, options) { + var linkUrl = linkInfo.url; + var linkText = linkInfo.text; + var isNewWindow = linkInfo.newWindow; + var rng = linkInfo.range; + + if (options.onCreateLink) { + linkUrl = options.onCreateLink(linkUrl); + } + + rng = rng.deleteContents(); + + // Create a new link when there is no anchor on range. + var anchor = rng.insertNode($('<A>' + linkText + '</A>')[0], true); + $(anchor).attr({ + href: linkUrl, + target: isNewWindow ? '_blank' : '' + }); + + range.createFromNode(anchor).select(); + afterCommand($editable); + }; + + /** + * returns link info + * + * @return {Object} + */ + this.getLinkInfo = function ($editable) { + $editable.focus(); + + var rng = range.create().expand(dom.isAnchor); + + // Get the first anchor on range(for edit). + var $anchor = $(list.head(rng.nodes(dom.isAnchor))); + + return { + range: rng, + text: rng.toString(), + isNewWindow: $anchor.length ? $anchor.attr('target') === '_blank' : true, + url: $anchor.length ? $anchor.attr('href') : '' + }; + }; + + this.color = function ($editable, sObjColor) { + var oColor = JSON.parse(sObjColor); + var foreColor = oColor.foreColor, backColor = oColor.backColor; + + if (foreColor) { document.execCommand('foreColor', false, foreColor); } + if (backColor) { document.execCommand('backColor', false, backColor); } + + afterCommand($editable); + }; + + this.insertTable = function ($editable, sDim) { + var dimension = sDim.split('x'); + var rng = range.create(); + rng = rng.deleteContents(); + rng.insertNode(table.createTable(dimension[0], dimension[1])); + afterCommand($editable); + }; + + /** + * @param {jQuery} $editable + * @param {String} value + * @param {jQuery} $target + */ + this.floatMe = function ($editable, value, $target) { + $target.css('float', value); + afterCommand($editable); + }; + + this.imageShape = function ($editable, value, $target) { + $target.removeClass('img-rounded img-circle img-thumbnail'); + + if (value) { + $target.addClass(value); + } + + afterCommand($editable); + }; + + /** + * resize overlay element + * @param {jQuery} $editable + * @param {String} value + * @param {jQuery} $target - target element + */ + this.resize = function ($editable, value, $target) { + $target.css({ + width: value * 100 + '%', + height: '' + }); + + afterCommand($editable); + }; + + /** + * @param {Position} pos + * @param {jQuery} $target - target element + * @param {Boolean} [bKeepRatio] - keep ratio + */ + this.resizeTo = function (pos, $target, bKeepRatio) { + var imageSize; + if (bKeepRatio) { + var newRatio = pos.y / pos.x; + var ratio = $target.data('ratio'); + imageSize = { + width: ratio > newRatio ? pos.x : pos.y / ratio, + height: ratio > newRatio ? pos.x * ratio : pos.y + }; + } else { + imageSize = { + width: pos.x, + height: pos.y + }; + } + + $target.css(imageSize); + }; + + /** + * remove media object + * + * @param {jQuery} $editable + * @param {String} value - dummy argument (for keep interface) + * @param {jQuery} $target - target element + */ + this.removeMedia = function ($editable, value, $target) { + $target.detach(); + + afterCommand($editable); + }; + }; + + return Editor; +}); |
