diff options
| author | qsm-odoo <qsm@odoo.com> | 2016-05-18 18:02:51 +0200 |
|---|---|---|
| committer | qsm-odoo <qsm@odoo.com> | 2016-07-04 17:23:59 +0200 |
| commit | 62fb1bb92493b00bd45ed3f4eced5ca8b23f81d6 (patch) | |
| tree | 911fcb10158fa89ddd75ff2aac195f79236f3e59 /addons/web_editor/static/src/js/snippets.editor.js | |
| parent | c1ab17337bdc816222be372aff314fcf5de8ba92 (diff) | |
[REF] web_editor: code refactoring and simplification
* Remove dead code + optimization
* Use Dialog API from web module
* Reorganize files
* Correct buggy $() function for snippet option class
* Add comments
* Fix the snippet parent navigation :
If a page contained a three level snippet structure (i.e A contains
B contains C), when editing the following bug occured :
If B or C was selected first, parenting buttons were correctly set.
But if selecting A then C, clicking on the parent lead to going back
on A instead of going on B.
* Fix snippet thumbnail layout
* Better isolate ui css from themes
* MediaDialog image list : prevent displaying empty attachments
* ...
Diffstat (limited to 'addons/web_editor/static/src/js/snippets.editor.js')
| -rw-r--r-- | addons/web_editor/static/src/js/snippets.editor.js | 274 |
1 files changed, 131 insertions, 143 deletions
diff --git a/addons/web_editor/static/src/js/snippets.editor.js b/addons/web_editor/static/src/js/snippets.editor.js index ca8819bff50..1bfab9d3dc2 100644 --- a/addons/web_editor/static/src/js/snippets.editor.js +++ b/addons/web_editor/static/src/js/snippets.editor.js @@ -5,80 +5,42 @@ var Class = require('web.Class'); var ajax = require('web.ajax'); var core = require('web.core'); var Widget = require('web.Widget'); -var base = require('web_editor.base'); var editor = require('web_editor.editor'); var animation = require('web_editor.snippets.animation'); var options = require('web_editor.snippets.options'); var qweb = core.qweb; -var dummy = editor.dummy; - -/* ----- SNIPPET SELECTOR ---- */ ajax.loadXML('/web_editor/static/src/xml/snippets.xml', qweb); -editor.Class.include({ - init: function () { - var self = this; - var res = this._super.apply(this, arguments); - var $editable = this.rte.editable(); - this.buildingBlock = new BuildingBlock(this, $editable); - this.buildingBlock.on("snippets:ready", this, function () { - self.trigger("snippets:ready"); - }); - return res; - }, - start: function () { - var self = this; - animation.stop(); - this.buildingBlock.insertAfter(this.$el); - animation.start(true); - - this.rte.editable().find("*").off('mousedown mouseup click'); - return this._super(); - }, - save: function () { - this.buildingBlock.clean_for_save(); - return this._super.apply(this, arguments); - }, -}); +var data = {}; /* ----- SNIPPET SELECTOR ---- */ -$.extend($.expr[':'],{ - hasData: function (node,i,m) { +$.extend($.expr[':'], { + hasData: function (node) { return !!_.toArray(node.dataset).length; }, - data: function (node,i,m) { + data: function (node, i, m) { return $(node).data(m[3]); } }); -var globalSelector = { +data.globalSelector = { closest: function () { return $(); }, all: function () { return $(); }, is: function () { return false; }, }; -/* ----- Jquery activate block ---- */ - -$.fn.extend({ - activateBlock: function () { - var target = globalSelector.closest($(this))[0] || (dom.isBR(this) ? this.parentNode : dom.node(this)); - var evt = document.createEvent("MouseEvents"); - evt.initMouseEvent("click", true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0, target); - target.dispatchEvent(evt); - return this; - } -}); - -/* ----- BuildingBlock (managment of drag&drop and focus/blur snippets) ---- */ - -var BuildingBlock = Widget.extend({ +/** + * Snippet editor main class. + * Management of drag&drop and focus/blur of snippets. + * Previously named "BuildingBlock". + */ +data.Class = Widget.extend({ id: "oe_snippets", activeSnippets: [], init: function (parent, $editable) { - this.parent = parent; this.$editable = $editable; this._super.apply(this, arguments); @@ -87,14 +49,14 @@ var BuildingBlock = Widget.extend({ } this.$active_snipped_id = false; this.snippets = []; - + data.instance = this; }, start: function () { var self = this; $(window).resize(function () { - setTimeout('$(document).click()',0); + _.defer(function () { $(document).click(); }); }); this.fetch_snippet_templates(); @@ -106,7 +68,7 @@ var BuildingBlock = Widget.extend({ var _isNotBreakable = $.summernote.core.dom.isNotBreakable; $.summernote.core.dom.isNotBreakable = function (node) { - return _isNotBreakable(node) || $(node).is('div') || globalSelector.is($(node)); + return _isNotBreakable(node) || $(node).is('div') || data.globalSelector.is($(node)); }; $(window).on('resize', function () { @@ -136,7 +98,7 @@ var BuildingBlock = Widget.extend({ }, _add_check_selector : function (selector, no_check, is_children) { var self = this; - var selector = selector.split(/\s*,/).join(":not(.o_snippet_not_selectable), ") + ":not(.o_snippet_not_selectable)"; + selector = selector.split(/\s*,/).join(":not(.o_snippet_not_selectable), ") + ":not(.o_snippet_not_selectable)"; if (no_check) { return { @@ -151,7 +113,7 @@ var BuildingBlock = Widget.extend({ } }; } else { - var selector = selector.split(/\s*,/).join(":o_editable, ") + ":o_editable"; + selector = selector.split(/\s*,/).join(":o_editable, ") + ":o_editable"; return { closest: function ($from, parentNode) { var parents = self.$editable.get(); @@ -203,14 +165,14 @@ var BuildingBlock = Widget.extend({ } $ul.children().tooltip({ - delay: { "show": 500, "hide": 100 }, - container: 'body', - title: function () { - return (navigator.appVersion.indexOf('Mac') > -1 ? 'CMD' : 'CTRL')+'+SHIFT+'+($(this).index()+1); - }, - trigger: 'hover', - placement: 'top' - }).on('click', function () {$(this).tooltip('hide');}); + delay: { "show": 500, "hide": 100 }, + container: 'body', + title: function () { + return (navigator.appVersion.indexOf('Mac') > -1 ? 'CMD' : 'CTRL')+'+SHIFT+'+($(this).index()+1); + }, + trigger: 'hover', + placement: 'top' + }).on('click', function () {$(this).tooltip('hide');}); // t-snippet $html.find('[data-oe-type="snippet"]').each(function () { @@ -239,35 +201,35 @@ var BuildingBlock = Widget.extend({ }); $styles.addClass("hidden"); - globalSelector.closest = function ($from) { - var $temp; - var $target; - var len = selector.length; - for (var i = 0; i<len; i++) { - $temp = selector[i].closest($from, $target && $target[0]); - if (!$target || $temp.length) { - $target = $temp; - } + data.globalSelector.closest = function ($from) { + var $temp; + var $target; + var len = selector.length; + for (var i = 0; i<len; i++) { + $temp = selector[i].closest($from, $target && $target[0]); + if (!$target || $temp.length) { + $target = $temp; } - return $target; + } + return $target; }; - globalSelector.all = function ($from) { - var $target; - var len = selector.length; - for (var i = 0; i<len; i++) { - if (!$target) $target = selector[i].all($from); - else $target = $target.add(selector[i].all($from)); - } - return $target; + data.globalSelector.all = function ($from) { + var $target; + var len = selector.length; + for (var i = 0; i<len; i++) { + if (!$target) $target = selector[i].all($from); + else $target = $target.add(selector[i].all($from)); + } + return $target; }; - globalSelector.is = function ($from) { - var len = selector.length; - for (var i = 0; i<len; i++) { - if (selector[i].is($from)) { - return true; - } + data.globalSelector.is = function ($from) { + var len = selector.length; + for (var i = 0; i<len; i++) { + if (selector[i].is($from)) { + return true; } - return false; + } + return false; }; var number = 0; @@ -364,7 +326,6 @@ var BuildingBlock = Widget.extend({ } var pos = $target.offset(); var mt = parseInt($target.css("margin-top") || 0); - var mb = parseInt($target.css("margin-bottom") || 0); $el.css({ width: $target.outerWidth(), left: pos.left, @@ -432,8 +393,8 @@ var BuildingBlock = Widget.extend({ return; } - if (!globalSelector.is($target)) { - $target = globalSelector.closest($target); + if (!data.globalSelector.is($target)) { + $target = data.globalSelector.closest($target); } if (self.$active_snipped_id && self.$active_snipped_id.is($target)) { @@ -462,14 +423,14 @@ var BuildingBlock = Widget.extend({ var template = self.templateOptions; for (var k in template) { var Option = opt[template[k]['option']]; - if (Option && Option.prototype.clean_for_save !== dummy) { + if (Option && Option.prototype.clean_for_save !== editor.dummy) { template[k].selector.all().filter(function () { - var node = this; - while (!/o_dirty|o_editable/.test(node.className) && node !== document) { - node = node.parentNode; - } - return node.className.indexOf("o_dirty") !== -1; - }).each(function () { + var node = this; + while (!/o_dirty|o_editable/.test(node.className) && node !== document) { + node = node.parentNode; + } + return node.className.indexOf("o_dirty") !== -1; + }).each(function () { new Option(self, null, $(this), k).clean_for_save(); }); } @@ -505,7 +466,7 @@ var BuildingBlock = Widget.extend({ create_snippet_editor: function ($snippet) { if (typeof $snippet.data("snippet-editor") === 'undefined') { if (!this.activate_overlay_zones($snippet).length) return; - $snippet.data("snippet-editor", new Editor(this, $snippet)); + $snippet.data("snippet-editor", new data.Editor(this, $snippet)); } }, @@ -515,7 +476,7 @@ var BuildingBlock = Widget.extend({ var $tumb = $snippets.find(".oe_snippet_thumbnail_img:first"); var left = $tumb.outerWidth()/2; var top = $tumb.outerHeight()/2; - var $toInsert, dropped, $snippet, action, snipped_id; + var $toInsert, dropped, $snippet; $snippets.draggable({ greedy: true, @@ -535,7 +496,6 @@ var BuildingBlock = Widget.extend({ var $base_body = $snippet.find('.oe_snippet_body'); var $selector_siblings = $(); var $selector_children = $(); - var vertical = false; var temp = self.templateOptions; for (var k in temp) { if ($base_body.is(temp[k].base_selector)) { @@ -553,7 +513,7 @@ var BuildingBlock = Widget.extend({ $toInsert = $base_body.clone(); if (!$selector_siblings.length && !$selector_children.length) { - console.debug($snippet.find(".oe_snippet_thumbnail_title").text() + " have not insert action: data-drop-near or data-drop-in"); + console.warn($snippet.find(".oe_snippet_thumbnail_title").text() + " have not insert action: data-drop-near or data-drop-in"); return; } @@ -577,7 +537,7 @@ var BuildingBlock = Widget.extend({ }, stop: function (ev, ui) { $toInsert.removeClass('oe_snippet_body'); - + if (! dropped && self.$editable.find('.oe_drop_zone') && ui.position.top > 3) { var el = self.$editable.find('.oe_drop_zone').nearest({x: ui.position.left, y: ui.position.top}).first(); if (el.length) { @@ -587,12 +547,12 @@ var BuildingBlock = Widget.extend({ } self.$editable.find('.oe_drop_zone').droppable('destroy').remove(); - + if (dropped) { var prev = $toInsert.first()[0].previousSibling; var next = $toInsert.last()[0].nextSibling; - var rte = self.parent.rte; + var rte = self.getParent().rte; if (prev) { $toInsert.detach(); @@ -638,7 +598,7 @@ var BuildingBlock = Widget.extend({ // call a method on a snippet and all his children call_for_all_snippets: function ($snippet, callback) { var self = this; - $snippet.add(globalSelector.all($snippet)).each(function () { + $snippet.add(data.globalSelector.all($snippet)).each(function () { var $snippet = $(this); setTimeout(function () { self.create_snippet_editor($snippet); @@ -652,8 +612,8 @@ var BuildingBlock = Widget.extend({ // return the original snippet in the editor bar from a snippet id (string) get_snippet_from_id: function (id) { return $('.oe_snippet').filter(function () { - return $(this).data('option') === id; - }).first(); + return $(this).data('option') === id; + }).first(); }, // Create element insertion drop zones. two css selectors can be provided @@ -677,10 +637,10 @@ var BuildingBlock = Widget.extend({ var test = !!(node && ((!node.tagName && node.textContent.match(/\S/)) || node.tagName === "BR")); if (test) { $drop.addClass("oe_vertical").css({ - 'height': parseInt(window.getComputedStyle($zone[0]).lineHeight), - 'float': 'none', - 'display': 'inline-block' - }); + 'height': parseInt(window.getComputedStyle($zone[0]).lineHeight), + 'float': 'none', + 'display': 'inline-block' + }); } else if (float === "left" || float === "right") { $drop.addClass("oe_vertical").css('height', Math.max(Math.min($zone.outerHeight(), $zone.children().last().outerHeight()), 30)); } @@ -688,14 +648,14 @@ var BuildingBlock = Widget.extend({ $drop = $drop.clone(); $zone.prepend($drop); - var node = $drop[0].nextSibling; - var test = !!(node && ((!node.tagName && node.textContent.match(/\S/)) || node.tagName === "BR")); + node = $drop[0].nextSibling; + test = !!(node && ((!node.tagName && node.textContent.match(/\S/)) || node.tagName === "BR")); if (test) { $drop.addClass("oe_vertical").css({ - 'height': parseInt(window.getComputedStyle($zone[0]).lineHeight), - 'float': 'none', - 'display': 'inline-block' - }); + 'height': parseInt(window.getComputedStyle($zone[0]).lineHeight), + 'float': 'none', + 'display': 'inline-block' + }); } else if (float === "left" || float === "right") { $drop.addClass("oe_vertical").css('height', Math.max(Math.min($zone.outerHeight(), $zone.children().first().outerHeight()), 30)); } @@ -816,8 +776,8 @@ var BuildingBlock = Widget.extend({ if ($target.data('overlay') && $target.data('overlay').hasClass("oe_active")) { self.cover_target($target.data('overlay'), $target); } - },50); - }); + }, 50); + }); var resize = function () { if ($zone.parent().length) { @@ -834,9 +794,11 @@ var BuildingBlock = Widget.extend({ } }); -/* ----- Editor (object who contain overlay and the option list) ---- */ - -var Editor = Class.extend({ +/** + * Snippet editor Editor class. + * Management of the overlay and option list for a snippet. + */ +data.Editor = Class.extend({ init: function (BuildingBlock, dom) { this.buildingBlock = BuildingBlock; this.$target = $(dom); @@ -874,12 +836,12 @@ var Editor = Class.extend({ _drag_and_drop_active_drop_zone: function ($zones) { var self = this; $zones.droppable({ - over: function () { + over: function () { $(".oe_drop_zone.hide").removeClass("hide"); $(this).addClass("hide").first().after(self.$target); self.dropped = true; }, - out: function () { + out: function () { $(this).removeClass("hide"); self.$target.detach(); self.dropped = false; @@ -898,12 +860,12 @@ var Editor = Class.extend({ self.$overlay.addClass("hidden"); var $selector_siblings; - for (var i=0; i<self.selector_siblings.length; i++) { + for (var i = 0 ; i < self.selector_siblings.length ; i++) { if (!$selector_siblings) $selector_siblings = self.selector_siblings[i].all(); else $selector_siblings = $selector_siblings.add(self.selector_siblings[i].all()); } var $selector_children; - for (var i=0; i<self.selector_children.length; i++) { + for (i = 0 ; i < self.selector_children.length ; i++) { if (!$selector_children) $selector_children = self.selector_children[i].all(); else $selector_children = $selector_children.add(self.selector_children[i].all()); } @@ -931,7 +893,7 @@ var Editor = Class.extend({ $(".oe_drop_clone, .oe_drop_to_remove").remove(); if (this.dropped) { - this.buildingBlock.parent.rte.historyRecordUndo(this.$target); + this.buildingBlock.getParent().rte.historyRecordUndo(this.$target); if (prev) { this.$target.insertAfter(prev); @@ -961,6 +923,7 @@ var Editor = Class.extend({ this.styles = {}; this.selector_siblings = []; this.selector_children = []; + _.each(this.buildingBlock.templateOptions, function (val, option_id) { if (!val.selector.is(self.$target)) { return; @@ -979,7 +942,7 @@ var Editor = Class.extend({ this.$overlay.find(".oe_snippet_move, .oe_snippet_clone, .oe_snippet_remove").addClass('hidden'); } - if ($ul.find("li").length) { + if ($ul.children().length) { $styles.removeClass("hidden"); } this.$overlay.find('[data-toggle="dropdown"]').dropdown(); @@ -988,10 +951,7 @@ var Editor = Class.extend({ get_parent_block: function () { var self = this; var $button = this.$overlay.find('.oe_snippet_parent'); - var $parent = this.$target.parents().filter(function () { return $(this).data("snippet-editor"); }); - if (!$parent.length) { - $parent = globalSelector.closest(this.$target.parent()); - } + var $parent = data.globalSelector.closest(this.$target.parent()); if ($parent.length) { $button.removeClass("hidden"); $button.off("click").on('click', function (event) { @@ -1010,7 +970,6 @@ var Editor = Class.extend({ * This method is called after init and _readXMLData */ start: function () { - var self = this; if (!this.$target.parent().is(':o_editable')) { this.$overlay.find('.oe_snippet_move, .oe_snippet_clone, .oe_snippet_remove').remove(); } else { @@ -1024,7 +983,7 @@ var Editor = Class.extend({ event.preventDefault(); var $clone = this.$target.clone(false); - this.buildingBlock.parent.rte.historyRecordUndo(this.$target); + this.buildingBlock.getParent().rte.historyRecordUndo(this.$target); this.$target.after($clone); this.buildingBlock.call_for_all_snippets($clone, function (editor, $snippet) { @@ -1039,7 +998,7 @@ var Editor = Class.extend({ event.preventDefault(); this.on_blur(); - this.buildingBlock.parent.rte.historyRecordUndo(this.$target); + this.buildingBlock.getParent().rte.historyRecordUndo(this.$target); var index = _.indexOf(this.buildingBlock.snippets, this.$target.get(0)); this.buildingBlock.call_for_all_snippets(this.$target, function (editor, $snippet) { @@ -1049,8 +1008,6 @@ var Editor = Class.extend({ }); delete this.buildingBlock.snippets[index]; - var $editable = this.$target.closest(".o_editable"); - // remove node and his empty var node = this.$target.parent()[0]; @@ -1103,11 +1060,42 @@ var Editor = Class.extend({ }, }); -var data = { - Class: BuildingBlock, - Editor: Editor, - globalSelector: globalSelector, -}; -return data; +/** + * Add the ability on the main editor class to instantiate the snippet editor component + */ +editor.Class.include({ + init: function () { + var self = this; + var res = this._super.apply(this, arguments); + var $editable = this.rte.editable(); + this.buildingBlock = new data.Class(this, $editable); + this.buildingBlock.on("snippets:ready", this, function () { + self.trigger("snippets:ready"); + }); + return res; + }, + start: function () { + this.buildingBlock.insertAfter(this.$el); + this.rte.editable().find("*").off('mousedown mouseup click'); + return this._super.apply(this, arguments); + }, + save: function () { + this.buildingBlock.clean_for_save(); + return this._super.apply(this, arguments); + }, +}); + +/** + * Add the ability the restart the animations + */ +editor.Class.include({ + start: function () { + animation.stop(); + return this._super.apply(this, arguments).then(function () { + animation.start(true); + }); + }, +}); +return data; }); |
