diff options
Diffstat (limited to 'addons/web_editor/static/lib/summernote/src/js/summernote.js')
| -rw-r--r-- | addons/web_editor/static/lib/summernote/src/js/summernote.js | 279 |
1 files changed, 215 insertions, 64 deletions
diff --git a/addons/web_editor/static/lib/summernote/src/js/summernote.js b/addons/web_editor/static/lib/summernote/src/js/summernote.js index 791a9452e85..329ba7fa126 100644 --- a/addons/web_editor/static/lib/summernote/src/js/summernote.js +++ b/addons/web_editor/static/lib/summernote/src/js/summernote.js @@ -1,39 +1,140 @@ define([ - 'summernote/core/agent', 'summernote/core/dom', + 'summernote/core/agent', + 'summernote/core/list', + 'summernote/core/dom', 'summernote/core/range', - 'summernote/settings', - 'summernote/EventHandler', 'summernote/Renderer', - 'summernote/core/list', // odoo change for overwrite - 'summernote/core/key' // odoo change for overwrite -], function (agent, dom, range, settings, EventHandler, Renderer, list, key) { // odoo change for overwrite + 'summernote/defaults', + 'summernote/EventHandler', + 'summernote/Renderer', + 'summernote/core/key' // ODOO: change for override +], function (agent, list, dom, range, + defaults, EventHandler, Renderer, key) { + // jQuery namespace for summernote + /** + * @class $.summernote + * + * summernote attribute + * + * @mixin defaults + * @singleton + * + */ $.summernote = $.summernote || {}; - // extends default `settings` - $.extend($.summernote, settings); + // extends default settings + // - $.summernote.version + // - $.summernote.options + // - $.summernote.lang + $.extend($.summernote, defaults); var renderer = new Renderer(); var eventHandler = new EventHandler(); $.extend($.summernote, { + /** @property {Renderer} */ renderer: renderer, + /** @property {EventHandler} */ eventHandler: eventHandler, + /** + * @property {Object} core + * @property {core.agent} core.agent + * @property {core.dom} core.dom + * @property {core.range} core.range + */ core: { agent: agent, + list : list, dom: dom, range: range, - list: list, // odoo change for overwrite - key: key // odoo change for overwrite + key: key // ODOO: change for override }, - pluginEvents: {} + /** + * @property {Object} + * pluginEvents event list for plugins + * event has name and callback function. + * + * ``` + * $.summernote.addPlugin({ + * events : { + * 'hello' : function(layoutInfo, value, $target) { + * console.log('event name is hello, value is ' + value ); + * } + * } + * }) + * ``` + * + * * event name is data-event property. + * * layoutInfo is a summernote layout information. + * * value is data-value property. + */ + pluginEvents: {}, + + plugins : [] }); /** - * addPlugin + * @method addPlugin + * + * add Plugin in Summernote + * + * Summernote can make a own plugin. * + * ### Define plugin + * ``` + * // get template function + * var tmpl = $.summernote.renderer.getTemplate(); + * + * // add a button + * $.summernote.addPlugin({ + * buttons : { + * // "hello" is button's namespace. + * "hello" : function(lang, options) { + * // make icon button by template function + * return tmpl.iconButton(options.iconPrefix + 'header', { + * // callback function name when button clicked + * event : 'hello', + * // set data-value property + * value : 'hello', + * hide : true + * }); + * } + * + * }, + * + * events : { + * "hello" : function(layoutInfo, value) { + * // here is event code + * } + * } + * }); + * ``` + * ### Use a plugin in toolbar + * + * ``` + * $("#editor").summernote({ + * ... + * toolbar : [ + * // display hello plugin in toolbar + * ['group', [ 'hello' ]] + * ] + * ... + * }); + * ``` + * + * * @param {Object} plugin + * @param {Object} [plugin.buttons] define plugin button. for detail, see to Renderer.addButtonInfo + * @param {Object} [plugin.dialogs] define plugin dialog. for detail, see to Renderer.addDialogInfo + * @param {Object} [plugin.events] add event in $.summernote.pluginEvents + * @param {Object} [plugin.langs] update $.summernote.lang + * @param {Object} [plugin.options] update $.summernote.options */ $.summernote.addPlugin = function (plugin) { + + // save plugin list + $.summernote.plugins.push(plugin); + if (plugin.buttons) { $.each(plugin.buttons, function (name, button) { renderer.addButtonInfo(name, button); @@ -65,107 +166,157 @@ define([ } }; - /** - * extend jquery fn + /* + * extend $.fn */ $.fn.extend({ /** - * initialize summernote + * @method + * Initialize summernote * - create editor layout and attach Mouse and keyboard events. - * - * @param {Object} options - * @returns {this} + * + * ``` + * $("#summernote").summernote( { options ..} ); + * ``` + * + * @member $.fn + * @param {Object|String} options reference to $.summernote.options + * @return {this} */ - summernote: function (options) { - // extend default options + summernote: function () { + // check first argument's type + // - {String}: External API call {{module}}.{{method}} + // - {Object}: init options + var type = $.type(list.head(arguments)); + var isExternalAPICalled = type === 'string'; + var hasInitOptions = type === 'object'; + + // extend default options with custom user options + var options = hasInitOptions ? list.head(arguments) : {}; + options = $.extend({}, $.summernote.options, options); + options.icons = $.extend({}, $.summernote.options.icons, options.icons); // Include langInfo in options for later use, e.g. for image drag-n-drop // Setup language info with en-US as default options.langInfo = $.extend(true, {}, $.summernote.lang['en-US'], $.summernote.lang[options.lang]); + // override plugin options + if (!isExternalAPICalled && hasInitOptions) { + for (var i = 0, len = $.summernote.plugins.length; i < len; i++) { + var plugin = $.summernote.plugins[i]; + + if (options.plugin[plugin.name]) { + $.summernote.plugins[i] = $.extend(true, plugin, options.plugin[plugin.name]); + } + } + } + this.each(function (idx, holder) { var $holder = $(holder); - // createLayout with options - renderer.createLayout($holder, options); + // if layout isn't created yet, createLayout and attach events + if (!renderer.hasNoteEditor($holder)) { + renderer.createLayout($holder, options); - var info = renderer.layoutInfoFromHolder($holder); - eventHandler.attach(info, options); - - // Textarea: auto filling the code before form submit. - if (dom.isTextarea($holder[0])) { - $holder.closest('form').submit(function () { - var contents = $holder.code(); - $holder.val(contents); - - // callback on submit - if (options.onsubmit) { - options.onsubmit(contents); - } - }); + var layoutInfo = renderer.layoutInfoFromHolder($holder); + $holder.data('layoutInfo', layoutInfo); + + eventHandler.attach(layoutInfo, options); + eventHandler.attachCustomEvent(layoutInfo, options); } }); - // focus on first editable element - if (this.first().length && options.focus) { - var info = renderer.layoutInfoFromHolder(this.first()); - info.editable.focus(); - } + var $first = this.first(); + if ($first.length) { + var layoutInfo = renderer.layoutInfoFromHolder($first); + + // external API + if (isExternalAPICalled) { + var moduleAndMethod = list.head(list.from(arguments)); + var args = list.tail(list.from(arguments)); - // callback on init - if (this.length && options.oninit) { - options.oninit(); + // TODO now external API only works for editor + var params = [moduleAndMethod, layoutInfo.editable()].concat(args); + return eventHandler.invoke.apply(eventHandler, params); + } else if (options.focus) { + // focus on first editable element for initialize editor + layoutInfo.editable().focus(); + } } return this; }, - // /** + * @method + * * get the HTML contents of note or set the HTML contents of note. * - * @param {String} [sHTML] - HTML contents(optional, set) - * @returns {this|String} - context(set) or HTML contents of note(get). + * * get contents + * ``` + * var content = $("#summernote").code(); + * ``` + * * set contents + * + * ``` + * $("#summernote").code(html); + * ``` + * + * @member $.fn + * @param {String} [html] - HTML contents(optional, set) + * @return {this|String} - context(set) or HTML contents of note(get). */ - code: function (sHTML) { + code: function (html) { // get the HTML contents of note - if (sHTML === undefined) { + if (html === undefined) { var $holder = this.first(); - if (!$holder.length) { return; } - var info = renderer.layoutInfoFromHolder($holder); - if (!!(info && info.editable)) { - var isCodeview = info.editor.hasClass('codeview'); - if (isCodeview && agent.hasCodeMirror) { - info.codable.data('cmEditor').save(); - } - return isCodeview ? info.codable.val() : info.editable.html(); + if (!$holder.length) { + return; + } + + var layoutInfo = renderer.layoutInfoFromHolder($holder); + var $editable = layoutInfo && layoutInfo.editable(); + + if ($editable && $editable.length) { + var isCodeview = eventHandler.invoke('codeview.isActivated', layoutInfo); + eventHandler.invoke('codeview.sync', layoutInfo); + return isCodeview ? layoutInfo.codable().val() : + layoutInfo.editable().html(); } - return dom.isTextarea($holder[0]) ? $holder.val() : $holder.html(); + return dom.value($holder); } // set the HTML contents of note this.each(function (i, holder) { - var info = renderer.layoutInfoFromHolder($(holder)); - if (info && info.editable) { info.editable.html(sHTML); } + var layoutInfo = renderer.layoutInfoFromHolder($(holder)); + var $editable = layoutInfo && layoutInfo.editable(); + if ($editable) { + $editable.html(html); + } }); return this; }, /** + * @method + * * destroy Editor Layout and detach Key and Mouse Event * - * @returns {this} + * @member $.fn + * @return {this} */ destroy: function () { this.each(function (idx, holder) { var $holder = $(holder); - var info = renderer.layoutInfoFromHolder($holder); - if (!info || !info.editable) { return; } + if (!renderer.hasNoteEditor($holder)) { + return; + } - var options = info.editor.data('options'); + var info = renderer.layoutInfoFromHolder($holder); + var options = info.editor().data('options'); eventHandler.detach(info, options); renderer.removeLayout($holder, info, options); |
