From 31f64313c033b346530980f3d84f5a2cc5fe71c4 Mon Sep 17 00:00:00 2001 From: Christophe Matthieu Date: Thu, 21 Nov 2013 13:34:39 +0100 Subject: [PATCH 1/1] [IMP] website snippet: create website.snippet.StyleEditor to add styles with html class and other logical process into snippet options bzr revid: chm@openerp.com-20131121123439-wvvcdegvc1bornux --- addons/website/static/src/css/website.css | 7 +- addons/website/static/src/css/website.sass | 8 +- .../static/src/js/website.snippets.animation.js | 4 +- .../static/src/js/website.snippets.editor.js | 525 ++++++++++---------- addons/website/views/snippets.xml | 143 +++--- 5 files changed, 332 insertions(+), 355 deletions(-) diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index 68e40e9..f10cb6f 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -1,3 +1,4 @@ +@charset "utf-8"; /* THIS CSS FILE IS FOR WEBSITE THEMING CUSTOMIZATION ONLY * * css for editor buttons, openerp widget included in the website and other @@ -434,7 +435,6 @@ ul.nav-stacked > li > a { .oe_dark { background: #eff8f8; background: rgba(100, 200, 200, 0.14); - background-image: none !important; -webkit-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; -moz-box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; box-shadow: 0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset; @@ -442,20 +442,17 @@ ul.nav-stacked > li > a { .oe_black { background-color: rgba(0, 0, 0, 0.9); - background-image: none !important; } .oe_green { background-color: rgba(0, 128, 0, 0.8); - background-image: none !important; } .oe_red { background-color: rgba(255, 0, 0, 0.8); - background-image: none !important; } -.oe_custom_bg { +.oe_img_bg { height: 100%; background-size: 100%; } diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index ec99225..932f46a 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -328,17 +328,13 @@ ul.nav-stacked > li > a .oe_dark background: #eff8f8 background: rgba(100, 200, 200, 0.14) - background-image: none !important +box-shadow(0px 5px 9px -7px rgba(0, 0, 255, 0.5) inset, 0px -3px 9px -7px rgba(0, 0, 255, 0.5) inset) .oe_black background-color: rgba(0, 0, 0, 0.9) - background-image: none !important .oe_green background-color: rgba(0, 128, 0, 0.8) - background-image: none !important .oe_red background-color: rgba(255, 0, 0, 0.8) - background-image: none !important -.oe_custom_bg +.oe_img_bg height: 100% - background-size: 100% + background-size: 100% \ No newline at end of file diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js index 7277f80..34edfe9 100644 --- a/addons/website/static/src/js/website.snippets.animation.js +++ b/addons/website/static/src/js/website.snippets.animation.js @@ -82,7 +82,7 @@ var self = this; var speed = parseFloat(self.$target.attr("data-scroll-background-ratio") || 0); - if (speed == 1) { + if (speed === 1 || this.$target.css("background-image") === "none") { this.$target.css("background-attachment", "fixed").css("background-position", "0px 0px"); return; } else { @@ -101,7 +101,7 @@ } else { offset = - self.$target.offset().top * speed; } - self.$target.attr("data-scroll-background-offset", offset); + self.$target.attr("data-scroll-background-offset", offset > 0 ? 0 : offset); $(window).scroll(); }; img.src = this.$target.css("background-image").replace(/url\(['"]*|['"]*\)/g, ""); diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 7d7aade..a4f51c6 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -77,6 +77,7 @@ hack_to_add_snippet_id(); }); + website.snippet.styles = {}; website.snippet.selector = []; website.snippet.BuildingBlock = openerp.Widget.extend({ template: 'website.snippets', @@ -138,22 +139,19 @@ }, fetch_snippet_templates: function () { var self = this; - this.style_templates = {}; openerp.jsonRpc("/website/snippets", 'call', {}) .then(function (html) { var $html = $(html); - var $styles = $html.find("#snippet_styles"); - $styles.find("> [data-snippet-id]").each(function () { + var $styles = $html.find("[data-snippet-style-id]"); + $styles.each(function () { var $style = $(this); - var snipped_id = $style.data('snippet-id'); - self.style_templates[snipped_id] = { - 'snipped-id' : snipped_id, + var style_id = $style.data('snippet-style-id'); + website.snippet.styles[style_id] = { + 'snippet-style-id' : style_id, 'selector': $style.data('selector'), - 'class': $style.data("class"), - 'label': $style.find(".oe_snippet_label").text(), - 'group': $style.find(".oe_snippet_group").text() + '$el': $style, }; }); $styles.addClass("hidden"); @@ -529,13 +527,212 @@ }); + website.snippet.styleRegistry = {}; + website.snippet.StyleEditor = openerp.Class.extend({ + // initialisation (don't overwrite) + init: function (parent, $target, snippet_id) { + this.parent = parent; + this.$target = $target; + var styles = this.$target.data("snippet-style-ids") || {}; + styles[snippet_id] = this; + this.$target.data("snippet-style-ids", styles); + this.$overlay = this.$target.data('overlay'); + this['snippet-style-id'] = snippet_id; + this.$el = website.snippet.styles[snippet_id].$el.find(">li").clone(); + + this.required = this.$el.data("required"); + + this.set_active(); + this.$el.find('li[data-class] a').on('mouseover mouseout click', _.bind(this._mouse, this)); + this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); + + this.start(); + }, + _mouse: function (event) { + var self = this; + + if (event.type === 'mouseout') { + if (!this.over) return; + this.over = false; + } else if (event.type === 'click') { + this.over = false; + }else { + this.over = true; + } + + var $prev, $next; + if (event.type === 'mouseout') { + $prev = $(event.currentTarget).parent(); + $next = this.$el.find("li[data-class].active"); + } else { + $prev = this.$el.find("li[data-class].active"); + $next = $(event.currentTarget).parent(); + } + if (!$prev.length) { + $prev = false; + } + if ($prev && $prev[0] === $next[0]) { + $next = false; + if (this.required) { + return; + } + } + + var np = {'$next': $next, '$prev': $prev}; + + if (event.type === 'click') { + setTimeout(function () { + self.set_active(); + self.$target.trigger("snippet-style-change", [self, np]); + },0); + this.select(event, {'$next': $next, '$prev': $prev}); + } else { + setTimeout(function () { + self.$target.trigger("snippet-style-preview", [self, np]); + },0); + this.preview(event, np); + } + }, + // start is call just after the init + start: function () { + }, + /* select + * called when a user select an item + * variables: np = {$next, $prev} + * $next is false if they are no next item selected + * $prev is false if they are no previous item selected + */ + select: function (event, np) { + var self = this; + // add or remove html class + if (np.$prev) { + this.$target.removeClass(np.$prev.data('class' || "")); + } + if (np.$next) { + this.$target.addClass(np.$next.data('class') || ""); + } + }, + /* preview + * called when a user is on mouse over or mouse out of an item + * variables: np = {$next, $prev} + * $next is false if they are no next item selected + * $prev is false if they are no previous item selected + */ + preview: function (event, np) { + var self = this; + + // add or remove html class + if (np.$prev) { + this.$target.removeClass(np.$prev.data('class') || ""); + } + if (np.$next) { + this.$target.addClass(np.$next.data('class') || ""); + } + }, + /* set_active + * select and set item active or not (add highlight item and his parents) + * called before start + */ + set_active: function () { + var self = this; + this.$el.find('li').removeClass("active"); + var $active = this.$el.find('li[data-class]') + .filter(function () { + var $li = $(this); + return ($li.data('class') && self.$target.hasClass($li.data('class'))); + }) + .first() + .addClass("active"); + this.$el.find('li:has(li[data-class].active)').addClass("active"); + } + }); + + + website.snippet.styleRegistry['size'] = website.snippet.StyleEditor.extend({ + select: function(event, np) { + this._super(event, np); + this.parent.parent.cover_target(this.$overlay, this.$target); + }, + preview: function (event, np) { + this._super(event, np); + this.parent.parent.cover_target(this.$overlay, this.$target); + } + }); + + website.snippet.styleRegistry.background = website.snippet.StyleEditor.extend({ + _get_bg: function () { + return this.$target.css("background-image").replace(/url\(['"]*|['"]*\)|^none$/g, ""); + }, + _set_bg: function (src) { + this.$target.css("background-image", src && src !== "" ? 'url(' + src + ')' : ""); + }, + start: function () { + this._super(); + var src = this._get_bg(); + this.$el.find("li[data-class].active.oe_custom_bg").data("src", src); + }, + select: function(event, np) { + var self = this; + this._super(event, np); + if (np.$next) { + if (np.$next.hasClass("oe_custom_bg")) { + var editor = new website.editor.ImageDialog(); + editor.on('start', self, function (o) {o.url = np.$prev && np.$prev.data("src") || "";}); + editor.on('save', self, function (o) { + self._set_bg(o.url); + np.$next.data("src", o.url); + self.$target.trigger("snippet-style-change", [self, np]); + }); + editor.on('cancel', self, function () { + if (!np.$prev || np.$prev.data("src") === "") { + np.$next.removeClass('active'); + self.$target.removeClass(np.$next.data("class")); + self.$target.trigger("snippet-style-change", [self, np]); + } + }); + editor.appendTo($('body')); + } else { + this._set_bg(np.$next.data("src")); + } + } else { + this._set_bg(false); + } + }, + preview: function (event, np) { + this._super(event, np); + if (np.$next) { + this._set_bg(np.$next.data("src")); + } + }, + set_active: function () { + var self = this; + var bg = self.$target.css("background-image"); + this.$el.find('li').removeClass("active"); + var $active = this.$el.find('li[data-class]') + .filter(function () { + var $li = $(this); + return ($li.data('src') && bg.indexOf($li.data('src')) >= 0) || + (!$li.data('src') && self.$target.hasClass($li.data('class'))); + }) + .first(); + if (!$active.length) { + $active = this.$target.css("background-image") !== 'none' ? + this.$el.find('li[data-class].oe_custom_bg') : + this.$el.find('li[data-class=""]'); + } + $active.addClass("active"); + this.$el.find('li:has(li[data-class].active)').addClass("active"); + } + }); + + website.snippet.editorRegistry = {}; website.snippet.Editor = openerp.Class.extend({ - init: function (parent, dom, force_snippet_id) { + init: function (parent, dom) { this.parent = parent; this.$target = $(dom); this.$overlay = this.$target.data('overlay'); - this.snippet_id = force_snippet_id || this.$target.data("snippet-id"); + this.snippet_id = this.$target.data("snippet-id"); this._readXMLData(); this.load_style_options(); this.get_parent_block(); @@ -652,90 +849,21 @@ }, load_style_options: function () { - if (this.$target.data('snippetStyles')) { - return; - } - var self = this; var $styles = this.$overlay.find('.oe_options'); var $ul = $styles.find('ul:first'); - _.each(this.parent.style_templates, function (val) { + _.each(website.snippet.styles, function (val) { if (!self.parent.dom_filter(val.selector).is(self.$target)) { return; } - var $li = $("
  • ").data(val); - $li.append($('').text(val.label)); - if (self.$target.hasClass( val.class )) { - $li.addClass("active"); - } - - if (val.group.length) { - var $group = $ul.find("li.dropdown-submenu").filter(function () { - return $("a:first", this).text() === val.group; - }); - if (!$group.length) { - $group = $('