summaryrefslogtreecommitdiff
path: root/addons/website/static/lib/summernote/src/js/editing/Editor.js
diff options
context:
space:
mode:
authorChristophe Matthieu <chm@odoo.com>2014-12-10 15:59:48 +0100
committerChristophe Matthieu <chm@odoo.com>2015-01-05 10:17:10 +0100
commit1596e45e8174cd736d4f7c78f85ec76a8e34888d (patch)
tree4ff318ee78bccc6c0bb6253670e85977f8f5a643 /addons/website/static/lib/summernote/src/js/editing/Editor.js
parentf9a7ed6b9406d657fda33ec55c4e237576b77a42 (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.js457
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;
+});