diff options
| author | Thibault Delavallée <tde@openerp.com> | 2013-12-02 16:49:35 +0100 |
|---|---|---|
| committer | Thibault Delavallée <tde@openerp.com> | 2013-12-02 16:49:35 +0100 |
| commit | 3a96d971fa25becb3d348bac4b339b3a5d65fd16 (patch) | |
| tree | 86e3b6a9b6dc018266b4a7b33e6acb2dbe54aca6 /addons/website/static/src/js | |
| parent | 5ee3495ccbcf300d9bdbbcbaa6dfe677bab3dc61 (diff) | |
| parent | b54ec1c5a21f878b28decc6744a7899bc22af687 (diff) | |
[MERGE] Sync with website-al
bzr revid: tde@openerp.com-20131202154935-t8wcgt180bbop8yy
Diffstat (limited to 'addons/website/static/src/js')
| -rw-r--r-- | addons/website/static/src/js/website.ace.js | 41 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.backend.js | 32 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.editor.js | 34 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.menu.js | 2 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.animation.js | 3 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.editor.js | 240 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.tour.banner.js | 2 |
7 files changed, 247 insertions, 107 deletions
diff --git a/addons/website/static/src/js/website.ace.js b/addons/website/static/src/js/website.ace.js index 685ace69467..1156ac5165e 100644 --- a/addons/website/static/src/js/website.ace.js +++ b/addons/website/static/src/js/website.ace.js @@ -59,8 +59,12 @@ website.ace.ViewOption = openerp.Widget.extend({ template: 'website.ace_view_option', init: function (parent, options) { + var indent = "- "; this.view_id = options.id; this.view_name = options.name; + for (var i = 0; i<options.level; i++) { + this.view_name = indent + this.view_name; + } this._super(parent); }, }); @@ -133,18 +137,47 @@ }, loadViews: function (views) { var self = this; + var $viewList = self.$('#ace-view-list'); + var views = this.buildViewGraph(views); + _.each(views, function (view) { + if (view.id) { + new website.ace.ViewOption(self, view).appendTo($viewList); + self.loadView(view.id); + } + }); + }, + buildViewGraph: function (views) { var activeViews = _.uniq(_.filter(views, function (view) { return view.active; }), false, function (view) { return view.id; }); - var $viewList = self.$('#ace-view-list'); + var index = {}; + var roots = []; _.each(activeViews, function (view) { - if (view.id) { - new website.ace.ViewOption(self, view).appendTo($viewList); - self.loadView(view.id); + index[view.id] = view; + view.children = []; + }); + _.each(index, function (view) { + var parentId = view.inherit_id; + if (parentId) { + index[parentId].children.push(view); + } else { + roots.push(view); } }); + var result = []; + function visit (node, level) { + node.level = level; + result.push(node); + _.each(node.children, function (child) { + visit(child, level + 1); + }); + } + _.each(roots, function (node) { + visit(node, 0); + }); + return result; }, loadView: function (id) { var viewId = parseInt(id, 10); diff --git a/addons/website/static/src/js/website.backend.js b/addons/website/static/src/js/website.backend.js new file mode 100644 index 00000000000..43347b85cb7 --- /dev/null +++ b/addons/website/static/src/js/website.backend.js @@ -0,0 +1,32 @@ +openerp.website = function(instance) { +var _t = instance.web._t; + +instance.web.form.WidgetWebsiteButton = instance.web.form.AbstractField.extend({ + template: 'WidgetWebsiteButton', + render_value: function() { + this._super(); + this.$("button:first") + .toggleClass("btn-success", this.get_value()) + .toggleClass("btn-danger", !this.get_value()); + this.$("a:first").attr("href", this.view.datarecord.website_url || "/" ); + if (this.node.attrs.class) { + this.$el.addClass(this.node.attrs.class); + } + }, + start: function() { + var self = this; + this._super.apply(this, arguments); + + this.$("button:first").on("click", function () { + console.log("click", !!$(this).hasClass("btn-danger")); + self.set_value(!!$(this).hasClass("btn-danger")); + return self.view.recursive_save(); + }); + }, +}); + +instance.web.form.widgets = instance.web.form.widgets.extend({ + 'website_button': 'instance.web.form.WidgetWebsiteButton', +}); + +}; diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index c50ad392887..b5caac71d74 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -104,6 +104,7 @@ left: $el.width() / 2 + image_left - $btn.outerWidth() / 2, }); }).on('mouseleave', 'img', function (e) { + if (!previousSelection) { return; } var $previous = $(previousSelection.$); var $button = $previous.next('button'); $button.css('visibility', 'hidden'); @@ -1370,6 +1371,11 @@ // a/@href, ...) _(mutations).chain() .filter(function (m) { + // ignore any change related to mundane image-edit-button + if (m.target && m.target.className + && m.target.className.indexOf('image-edit-button') !== -1) { + return false; + } switch(m.type) { case 'attributes': // ignore .cke_focus being added or removed // if attribute is not a class, can't be .cke_focus change @@ -1383,8 +1389,11 @@ // ignore mutation if the *only* change is .cke_focus return change.length !== 1 || change[0] === 'cke_focus'; case 'childList': - // <br type="_moz"> appears when focusing RTE in FF, ignore - return m.addedNodes.length !== 1 || m.addedNodes[0].nodeName !== 'BR'; + // Remove ignorable nodes from addedNodes or removedNodes, + // if either set remains non-empty it's considered to be an + // impactful change. Otherwise it's ignored. + return !!remove_mundane_nodes(m.addedNodes).length || + !!remove_mundane_nodes(m.removedNodes).length; default: return true; } @@ -1394,11 +1403,30 @@ while (node && !$(node).hasClass('oe_editable')) { node = node.parentNode; } - $(m.target).trigger('node_changed'); return node; }) .compact() .uniq() .each(function (node) { $(node).trigger('content_changed'); }) }); + function remove_mundane_nodes(nodes) { + if (!nodes || !nodes.length) { return []; } + + var output = []; + for(var i=0; i<nodes.length; ++i) { + var node = nodes[i]; + if (node.nodeName === 'BR' && node.getAttribute('type') === '_moz') { + // <br type="_moz"> appears when focusing RTE in FF, ignore + continue; + } + if (node.className.indexOf('image-edit-button') !== -1) { + // [Edit] button added and removed on image hover, don't count + // as making parent node dirty + continue; + } + + output.push(node); + } + return output; + } })(); diff --git a/addons/website/static/src/js/website.menu.js b/addons/website/static/src/js/website.menu.js index b3554b9e7c5..87dd46dafe9 100644 --- a/addons/website/static/src/js/website.menu.js +++ b/addons/website/static/src/js/website.menu.js @@ -15,7 +15,7 @@ openerp.jsonRpc('/web/dataset/call_kw', 'call', { model: 'website.menu', method: 'get_tree', - args: [[context.website_id]], + args: [context.website_id], kwargs: { context: context }, diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js index e491912da15..1dbb2d7426e 100644 --- a/addons/website/static/src/js/website.snippets.animation.js +++ b/addons/website/static/src/js/website.snippets.animation.js @@ -51,7 +51,8 @@ }, }); - website.snippet.animationRegistry.carousel = website.snippet.Animation.extend({ + website.snippet.animationRegistry.carousel = + website.snippet.animationRegistry.slider = website.snippet.Animation.extend({ start: function () { this.$target.carousel({interval: 10000}); }, diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index e296850e54b..ebbe0bf5dd8 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -350,7 +350,18 @@ website.snippet.start_animation(); self.create_overlay($target); - $target.data("snippet-editor").drop_and_build_snippet($target); + if ($snippet.data("snippet-editor")) { + $target.data("snippet-editor").drop_and_build_snippet($target); + } + + $target.find("[data-snippet-id]").each(function () { + var $snippet = $(this); + var snippet_id = $snippet.data("data-snippet-id"); + self.create_overlay($snippet); + if ($snippet.data("snippet-editor")) { + $snippet.data("snippet-editor").drop_and_build_snippet($snippet); + } + }); } else { $target = $(this).data('target'); @@ -837,15 +848,6 @@ setTimeout(function () {self.parent.create_overlay(self.$target);},0); }, - _clone: function () { - var self = this; - this.$overlay.on('click', '.oe_snippet_clone', function () { - var $clone = self.$target.clone(false); - self.$target.after($clone); - return false; - }); - }, - load_style_options: function () { var self = this; var $styles = this.$overlay.find('.oe_options'); @@ -887,16 +889,24 @@ */ start: function () { var self = this; - this.$overlay.on('click', '.oe_snippet_remove', function () { - self.onBlur(); - var index = _.indexOf(self.parent.snippets, self.$target.get(0)); - delete self.parent.snippets[index]; - self.$target.remove(); - self.$overlay.remove(); - return false; - }); + this.$overlay.on('click', '.oe_snippet_clone', _.bind(this.on_clone, this)); + this.$overlay.on('click', '.oe_snippet_remove', _.bind(this.on_remove, this)); this._drag_and_drop(); - this._clone(); + }, + + on_clone: function () { + var $clone = this.$target.clone(false); + this.$target.after($clone); + return false; + }, + + on_remove: function () { + this.onBlur(); + var index = _.indexOf(this.parent.snippets, this.$target.get(0)); + delete this.parent.snippets[index]; + this.$target.remove(); + this.$overlay.remove(); + return false; }, /* @@ -925,7 +935,7 @@ * function called just before save vue */ clean_for_save: function () { - + this.$target.find(".row:empty").remove(); }, }); @@ -1059,7 +1069,6 @@ return this.grid; }, - _drag_and_drop_after_insert_dropzone: function(){ var self = this; var $zones = $(".row:has(> .oe_drop_zone)").each(function () { @@ -1088,7 +1097,24 @@ this.$target.addClass("col-md-offset-" + this.$target.prevAll(".oe_drop_to_remove").length); this._super(); }, - + onFocus : function () { + this._super(); + this.$overlay.find('.oe_snippet_remove').toggleClass("hidden", !this.$target.siblings().length); + }, + on_clone: function () { + var $clone = this.$target.clone(false); + var _class = $clone.attr("class").replace(/\s*(col-md-|col-lg-offset-|col-md-offset-)([0-9-]+)/g, ''); + _class += ' col-md-1'; + $clone.attr("class", _class); + this.$target.after($clone); + return false; + }, + on_remove: function () { + if (!this.$target.siblings().length){ + return false; + } + return this._super(); + }, on_resize: function (compass, beginClass, current) { if (compass !== 'w') return; @@ -1113,12 +1139,12 @@ } }, }); - - website.snippet.editorRegistry.carousel = website.snippet.editorRegistry.resize.extend({ + + website.snippet.editorRegistry.slider = website.snippet.editorRegistry.resize.extend({ drop_and_build_snippet: function() { var id = 0; - $("body .carousel").each(function () { - var _id = +$(this).attr("id").replace(/^myCarousel/, ''); + $(".carousel").each(function () { + var _id = +$(this).attr("id").replace(/^[^a-z]+/i, ''); if (id <= _id) { id = _id + 1; } @@ -1126,44 +1152,108 @@ this.id = "myCarousel" + id; this.$target.attr("id", this.id); this.$target.find(".carousel-control").attr("href", "#myCarousel" + id); - this.$target.find("[data-target='#myCarousel']").attr("data-target", "#myCarousel" + id); + this.$target.find("[data-target]").attr("data-target", "#myCarousel" + id); this.rebind_event(); }, - onFocus: function () { - this._super(); + // rebind event to active carousel on edit mode + rebind_event: function () { + var self = this; + this.$target.find('.carousel-indicators [data-target]').off('click').on('click', function () { + self.$target.carousel(+$(this).data('slide-to')); }); + + this.$target.attr('contentEditable', 'false') + .find('.oe_structure, blockquote').attr('contentEditable', 'true'); + this.$target.carousel('pause'); }, - onBlur: function () { - this._super(); - this.$target.carousel('cycle'); - }, clean_for_save: function () { this._super(); this.$target.find(".item").removeClass("next prev left right"); if(!this.$target.find(".item.active").length) { this.$target.find(".item:first").addClass("active"); } - this.$target.css("background-image", ""); - console.log(this._class); - this.$target.removeClass(this._class); this.$target.removeAttr('contentEditable') - .find('.content, .carousel-image img') - .removeAttr('contentEditable'); + .find('*').removeAttr('contentEditable'); + }, + onFocus: function () { + this._super(); + this.$target.carousel('pause'); + }, + onBlur: function () { + this._super(); + this.$target.carousel('cycle'); }, start : function () { - var self = this; this._super(); - this.id = this.$target.attr("id"); - this.$inner = this.$target.find('.carousel-inner'); this.$indicators = this.$target.find('.carousel-indicators'); - this.$editor.find(".js_add").on('click', _.bind(this.on_add, this)); - this.$editor.find(".js_remove").on('click', _.bind(this.on_remove, this)); + this.$editor.find(".js_add").on('click', _.bind(this.on_add_slide, this)); + this.$editor.find(".js_remove").on('click', _.bind(this.on_remove_slide, this)); this.rebind_event(); + }, + on_add_slide: function () { + var self = this; + var cycle = this.$inner.find('.item').length; + var $active = this.$inner.find('.item.active, .item.prev, .item.next').first(); + var index = $active.index(); + this.$target.find('.carousel-control, .carousel-indicators').removeClass("hidden"); + this.$indicators.append('<li data-target="#' + this.id + '" data-slide-to="' + cycle + '"></li>'); + + var $clone = this.$el.find(".item.active").clone(); + + // insert + $clone.removeClass('active').insertAfter($active); + setTimeout(function() { + self.$target.carousel().carousel(++index); + self.rebind_event(); + },0); + return $clone; + }, + on_remove_slide: function () { + if (this.remove_process) { + return; + } + var self = this; + var new_index = 0; + var cycle = this.$inner.find('.item').length - 1; + var index = this.$inner.find('.item.active').index(); + + if (cycle > 0) { + this.remove_process = true; + var $el = this.$inner.find('.item.active'); + self.$target.on('slid.bs.carousel', function (event) { + $el.remove(); + self.$indicators.find("li:last").remove(); + self.$target.off('slid.bs.carousel'); + self.rebind_event(); + self.remove_process = false; + if (cycle == 1) { + self.on_remove_slide(event); + } + }); + setTimeout(function () { + self.$target.carousel( index > 0 ? --index : cycle ); + }, 500); + } else { + this.$target.find('.carousel-control, .carousel-indicators').addClass("hidden"); + } + }, + }); + + website.snippet.editorRegistry.carousel = website.snippet.editorRegistry.slider.extend({ + clean_for_save: function () { + this._super(); + this.$target.css("background-image", ""); + this.$target.removeClass(this._class); + this.$target.find('.content, .carousel-image img').attr('contentEditable', 'true'); + }, + start : function () { + var self = this; + this._super(); // set background and prepare to clean for save var add_class = function (c){ @@ -1196,27 +1286,8 @@ }); this.$target.trigger('slid'); }, - // rebind event to active carousel on edit mode - rebind_event: function () { - var self = this; - this.$target.off('click').on('click', '.carousel-control', function () { - self.$target.carousel($(this).data('slide')); }); - this.$target.off('click').on('click', '.carousel-indicators [data-target]', function () { - self.$target.carousel(+$(this).data('slide-to')); }); - - this.$target.attr('contentEditable', 'false') - .find('.content, .carousel-image img') - .attr('contentEditable', 'true'); - }, - on_add: function (e) { - e.preventDefault(); - var cycle = this.$inner.find('.item').length; - var $active = this.$inner.find('.item.active, .item.prev, .item.next').first(); - var index = $active.index(); - this.$target.find('.carousel-control, .carousel-indicators').removeClass("hidden"); - this.$indicators.append('<li data-target="#' + this.id + '" data-slide-to="' + cycle + '"></li>'); - - var $clone = this.$el.find(".item.active").clone(); + on_add_slide: function () { + var $clone = this._super(); // choose an other background var $styles = this.$target.data("snippet-style-ids").background.$el.find("li[data-class]:not(.oe_custom_bg)"); @@ -1225,40 +1296,14 @@ $clone.css("background-image", $select.data("src") ? "url('"+ $select.data("src") +"')" : ""); $clone.addClass($select.data("class") || ""); - // insert - $clone.removeClass('active').insertAfter($active); - this.$target.carousel().carousel(++index); - this.rebind_event(); + return $clone; }, - on_remove: function (e) { - e.preventDefault(); - if (this.remove_process) { - return; - } + // rebind event to active carousel on edit mode + rebind_event: function () { var self = this; - var new_index = 0; - var cycle = this.$inner.find('.item').length - 1; - var index = this.$inner.find('.item.active').index(); - - if (cycle > 0) { - this.remove_process = true; - var $el = this.$inner.find('.item.active'); - self.$target.on('slid.bs.carousel', function (event) { - $el.remove(); - self.$indicators.find("li:last").remove(); - self.$target.off('slid.bs.carousel'); - self.rebind_event(); - self.remove_process = false; - if (cycle == 1) { - self.on_remove(e); - } - }); - setTimeout(function () { - self.$target.carousel( index > 0 ? --index : cycle ); - }, 500); - } else { - this.$target.find('.carousel-control, .carousel-indicators').addClass("hidden"); - } + this.$target.find('.carousel-control').off('click').on('click', function () { + self.$target.carousel( $(this).data('slide')); }); + this._super(); }, }); @@ -1300,7 +1345,8 @@ * Don't need to add data-snippet-id="..." into the views */ - website.snippet.selector.push([".row > div[class*='col-md-']", 'colmd']); + website.snippet.selector.push([".row > [class*='col-md-']", 'colmd']); website.snippet.selector.push(['hr', 'hr']); + website.snippet.selector.push(['blockquote', 'quote']); })(); diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 3c812b00268..0632eab3cc9 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -76,7 +76,7 @@ element: '.oe_overlay_options .oe_options', placement: 'left', title: "Customize the banner", - content: "You can customize characteristic of any blocks through the Customize menu. For instance, change the background of the banner.", + content: "Customize any block through this menu. Try to change the background of the banner.", template: self.popover({ next: "Continue" }), }, { |
