diff options
| author | Fabien Meghazi <fme@openerp.com> | 2014-03-26 16:24:33 +0100 |
|---|---|---|
| committer | Fabien Meghazi <fme@openerp.com> | 2014-03-26 16:24:33 +0100 |
| commit | eb5cbea318478a0adfe347e8e486cd5b8643a51d (patch) | |
| tree | 3ab4f76a906c258818f37ea6997d7a1af8f58de0 /addons/website/static/src | |
| parent | 0195f0d8170e06ab2b83aca2209034bafda4702e (diff) | |
| parent | 6ad8096210ab355fe22e7256e99ad2695d11c9c6 (diff) | |
[MERGE] upstream
bzr revid: fme@openerp.com-20140326152433-vegu5tuvr8vc1s8v
Diffstat (limited to 'addons/website/static/src')
| -rw-r--r-- | addons/website/static/src/js/website.editor.js | 3 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.editor.newpage.js | 2 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.js | 3 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.mobile.js | 4 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.editor.js | 252 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.tour.js | 74 |
6 files changed, 225 insertions, 113 deletions
diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 24c97bce311..c965c5ef834 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -1790,6 +1790,9 @@ if (node.nodeName === 'BR' && node.getAttribute('type') === '_moz') { // <br type="_moz"> appears when focusing RTE in FF, ignore continue; + } else if (node.nodeName === 'DIV' && $(node).hasClass('oe_drop_zone')) { + // ignore dropzone inserted by snippets + continue } } diff --git a/addons/website/static/src/js/website.editor.newpage.js b/addons/website/static/src/js/website.editor.newpage.js index b475223ecd9..77a086790fa 100644 --- a/addons/website/static/src/js/website.editor.newpage.js +++ b/addons/website/static/src/js/website.editor.newpage.js @@ -48,7 +48,7 @@ } }).then(function (val, field, $dialog) { if (val) { - var url = '/website/add/' + encodeURI(val); + var url = '/website/add' + encodeURI(val); if ($dialog.find('input[type="checkbox"]').is(':checked')) url +="?add_menu=1"; document.location = url; } diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 065928df1cf..31e39b3bbc4 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -53,6 +53,7 @@ /* ---------------------------------------------------- Widgets ---------------------------------------------------- */ + website.prompt = function (options) { /** * A bootstrapped version of prompt() albeit asynchronous @@ -198,7 +199,7 @@ var page = +$a.attr("href").split(",").pop().split('-')[1]; data['page'] = page; - $.post('/website/kanban/', data, function (col) { + $.post('/website/kanban', data, function (col) { $col.find("> .thumbnail").remove(); $pagination.last().before(col); }); diff --git a/addons/website/static/src/js/website.mobile.js b/addons/website/static/src/js/website.mobile.js index 59c2328e09b..88a558f5094 100644 --- a/addons/website/static/src/js/website.mobile.js +++ b/addons/website/static/src/js/website.mobile.js @@ -18,9 +18,9 @@ }, start: function () { if (!window.location.origin) { // fix for ie9 - window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: '') + '/'; + window.location.origin = window.location.protocol + "//" + window.location.hostname + (window.location.port ? ':' + window.location.port: ''); } - document.getElementById("mobile-viewport").src = window.location.origin + window.location.pathname + "#mobile-preview"; + document.getElementById("mobile-viewport").src = window.location.origin + (window.location.pathname.length ? '/' : '') + window.location.pathname + "#mobile-preview"; this.$el.modal(); }, destroy: function () { diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 1eee1fee65b..52deeabf5e6 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -1,6 +1,136 @@ (function () { 'use strict'; +/* Building block / Snippet Editor + + The building blocks appear in the edit bar website. These prebuilt html block + allowing the designer to easily generate content on a page (drag and drop). + Options allow snippets to add customizations part html code according to their + selector (jQuery) and javascript object. + + How to create content? + + Designers can add their own html block in the "snippets" (/website/views/snippets.xml). + The block must be added in one of four menus (structure, content, feature or effect). + Structure: + <div> + <div class="oe_snippet_thumbnail"> + <img class="oe_snippet_thumbnail_img" src="...image src..."/> + <span class="oe_snippet_thumbnail_title">...Block Name...</span> + </div> + <div class="oe_snippet_body"> + ... + <!-- + The block with class 'oe_snippet_body' is inserted in the page. + This class is removed when the block is dropped. + The block can be made of any html tag and content. --> + </div> + </div> + + How to create options? + + Designers can add their own html block in the "snippet_options" (/website/views/snippets.xml). + Structure: + + <div data-snippet-option-id='...' <!-- Required: javascript object id (but javascript + for this option object is not required) --> + data-selector="..." <!-- Required: jQuery selector. + Apply options on all The part of html who + match with this jQuery selector. + E.g.: If the selector is div, all div will be selected + and can be highlighted and assigned an editor. --> + data-selector-siblings="..." <!-- Optional: jQuery selector. + The html part can be insert or move beside + the selected html block --> + data-selector-children="..." <!-- Optional: jQuery selector. + The html part can be insert or move inside + the selected html block --> + data-selector-vertical-children='...'> <!-- Optional: jQuery selector. + The html part can be insert or move inside + the selected html block. The drop zone is + displayed vertically --> + ... + <li><a href="#">...</a></li> <!-- Optional: html li list. + List of menu items displayed in customize + menu. If the li tag have 'data-class', the + class is automaticcally added or removed to + the html content when the user select this item. --> + ... + <li class="dropdown-submenu" <!-- Optional: html li list exemple. !--> + data-required="true"> <!-- Optional: if only one item can be selected + and can't be unselect. !--> + <a tabindex="-1" href="#">...</a> <!-- bootstrap dropdown button !--> + <ul class="dropdown-menu"> + <li data-value="text_only"><a>...</a></li> <!-- by default data-value is apply + like a class to html block !--> + </ul> + </li> + </div> + + How to create a javascript object for an options? + + openerp.website.snippet.options["...option-id..."] = website.snippet.Option.extend({ + // start is called when the user click into a block or when the user drop a block + // into the page (just after the init method). + // start is usually used to bind event. + // + // this.$target: block html inserted inside the page + // this.$el: html li list of this options + // this.$overlay: html editor overlay who content resize bar, customize menu... + start: function () {}, + + + // onFocus is called when the user click inside the block inserted in page + // and when the user drop on block into the page + onFocus : function () {}, + + + // onBlur is called when the user click outside the block inserted in page, if + // the block is focused + onBlur : function () {}, + + + // on_clone is called when the snippet is duplicate + // @variables: $clone is allready inserted is the page + on_clone: function ($clone) {}, + + + // on_remove is called when the snippet is removed (dom is removing after this tigger) + on_remove: function () {}, + + + // drop_and_build_snippet is called just after that a thumbnail is drag and dropped + // into a drop zone. The content is already inserted in the page. + drop_and_build_snippet: function () {}, + + // select is called when a user select an item in the li list of options + // By default, if the li item have a data-value attribute, the data-vlue it's apply + // like a class to the html block (this.$target) + // @variables: next_previous = {$next, $prev} + // $next = next item selected or false + // $prev = previous item selected or false + select: function (event, next_previous) {} + + // preview is called when a user is on mouse over or mouse out of an item + // variables: next_previous = {$next, $prev} + // $next = next item selected or false + // $prev = previous item selected or false + preview: function (event, next_previous) {} + + // clean_for_save + // clean_for_save is called just before to save the vue + // Sometime it's important to remove or add some datas (contentEditable, added + // classes to a running animation...) + clean_for_save: function () {} + }); + + + // 'snippet-dropped' is triggered on '#oe_snippets' whith $target as attribute when a snippet is dropped + // 'snippet-activated' is triggered on '#oe_snippets' (and on snippet) when a snippet is activated + +*/ + + var website = openerp.website; website.add_template_file('/website/static/src/xml/website.snippets.xml'); @@ -19,23 +149,11 @@ edit: function () { var self = this; $("[data-oe-model] *, [data-oe-type=html] *").off('click'); - website.snippet.stop_animation(); window.snippets = this.snippets = new website.snippet.BuildingBlock(this); this.snippets.appendTo(this.$el); this.on('rte:ready', this, function () { self.snippets.$button.removeClass("hidden"); - website.snippet.start_animation(); - $(website.snippet.readyAnimation).each(function() { - var animation = $(this).data("snippet-view"); - if (animation) { - animation.$target.on('focus', '*', function(){ - animation.stop(); - }); - animation.$target.on('blur', '*', function(){ - animation.start(); - }); - } - }); + website.snippet.stop_animation(); }); return this._super.apply(this, arguments); @@ -56,9 +174,6 @@ } }); - // 'snippet-dropped' is triggered on '#oe_snippets' whith $target as attribute when a snippet is dropped - // 'snippet-activated' is triggered on '#oe_snippets' (and on snippet) when a snippet is activated - if (!website.snippet) website.snippet = {}; website.snippet.templateOptions = {}; website.snippet.globalSelector = ""; @@ -397,18 +512,17 @@ $("#oe_snippets").trigger('snippet-dropped', $target); website.snippet.start_animation(true, $target); - // drop_and_build_snippet self.create_overlay($target); if ($target.data("snippet-editor")) { - $target.data("snippet-editor").drop_and_build_snippet($target); + $target.data("snippet-editor").drop_and_build_snippet(); } for (var k in website.snippet.templateOptions) { $target.find(website.snippet.templateOptions[k].selector).each(function () { var $snippet = $(this); self.create_overlay($snippet); if ($snippet.data("snippet-editor")) { - $snippet.data("snippet-editor").drop_and_build_snippet($snippet); + $snippet.data("snippet-editor").drop_and_build_snippet(); } }); } @@ -665,101 +779,72 @@ self.set_active(); self.$target.trigger("snippet-style-change", [self, np]); },0); - this.select(event, {'$next': $next, '$prev': $prev}); + this.select({'$next': $next, '$prev': $prev}); } else { setTimeout(function () { self.$target.trigger("snippet-style-preview", [self, np]); },0); - this.preview(event, np); + this.preview(np); } }, - // start is call just after the init + /* 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-value]') + .filter(function () { + var $li = $(this); + return ($li.data('value') && self.$target.hasClass($li.data('value'))); + }) + .first() + .addClass("active"); + this.$el.find('li:has(li[data-value].active)').addClass("active"); + }, + start: function () { }, - /* onFocus - * This method is called when the user click inside the snippet in the dom - */ + onFocus : function () { }, - /* onFocus - * This method is called when the user click outside the snippet in the dom, after a focus - */ onBlur : function () { }, - /* on_clone - * This method is called when the snippet is cloned ($clone is allready inserted) - */ on_clone: function ($clone) { }, - /* on_remove - * This method is called when the snippet is removed (dom is removing after this call) - */ on_remove: function () { }, - /* - * drop_and_build_snippet - * This method is called just after that a thumbnail is drag and dropped into a drop zone - * (after the insertion of this.$body, if this.$body exists) - */ - drop_and_build_snippet: function ($target) { - }, - /* select - * called when a user select an item - * li must have data-value attribute - * 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) { + drop_and_build_snippet: function () { + }, + + select: function (np) { var self = this; // add or remove html class - if (np.$prev) { + if (np.$prev && this.required) { this.$target.removeClass(np.$prev.data('value' || "")); } if (np.$next) { this.$target.addClass(np.$next.data('value') || ""); } }, - /* 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) { + + preview: function (np) { var self = this; // add or remove html class - if (np.$prev) { + if (np.$prev && this.required) { this.$target.removeClass(np.$prev.data('value') || ""); } if (np.$next) { this.$target.addClass(np.$next.data('value') || ""); } }, - /* 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-value]') - .filter(function () { - var $li = $(this); - return ($li.data('value') && self.$target.hasClass($li.data('value'))); - }) - .first() - .addClass("active"); - this.$el.find('li:has(li[data-value].active)').addClass("active"); - }, - /* clean_for_save - * function called just before save vue - */ + clean_for_save: function () { } }); @@ -776,9 +861,9 @@ var src = this._get_bg(); this.$el.find("li[data-value].active.oe_custom_bg").data("src", src); }, - select: function(event, np) { + select: function(np) { var self = this; - this._super(event, np); + this._super(np); if (np.$next) { if (np.$next.hasClass("oe_custom_bg")) { var editor = new website.editor.ImageDialog(); @@ -803,8 +888,8 @@ this.$target.removeClass(np.$prev.data("value")); } }, - preview: function (event, np) { - this._super(event, np); + preview: function (np) { + this._super(np); if (np.$next) { this._set_bg(np.$next.data("src")); } @@ -872,6 +957,7 @@ start : function () { var self = this; this._super(); + this.$target.carousel({interval: false}); this.id = this.$target.attr("id"); this.$inner = this.$target.find('.carousel-inner'); this.$indicators = this.$target.find('.carousel-indicators'); @@ -1539,9 +1625,9 @@ * This method is called just after that a thumbnail is drag and dropped into a drop zone * (after the insertion of this.$body, if this.$body exists) */ - drop_and_build_snippet: function ($target) { + drop_and_build_snippet: function () { for (var i in this.styles){ - this.styles[i].drop_and_build_snippet($target); + this.styles[i].drop_and_build_snippet(); } }, diff --git a/addons/website/static/src/js/website.tour.js b/addons/website/static/src/js/website.tour.js index 61b8f851339..b7e55fe166b 100644 --- a/addons/website/static/src/js/website.tour.js +++ b/addons/website/static/src/js/website.tour.js @@ -1,11 +1,30 @@ (function () { 'use strict'; -var website = openerp.website; +// raise an error in test mode if openerp don't exist +if (typeof openerp === "undefined") { + var error = "openerp is undefined" + + "\nhref: " + window.location.href + + "\nreferrer: " + document.referrer + + "\nlocalStorage: " + JSON.stringify(window.localStorage); + if (typeof $ !== "undefined") { + error += '\n\n' + $("body").html(); + } + throw new Error(error); +} + +var website = window.openerp.website; + +// don't rewrite website.Tour in test mode +if (typeof website.Tour !== "undefined") { + return; +} // don't need template to use bootstrap Tour in automatic mode -if (typeof QWeb2 !== "undefined") -website.add_template_file('/website/static/src/xml/website.tour.xml'); +if (typeof QWeb2 !== "undefined") { + website.add_template_file('/website/static/src/xml/website.tour.xml'); + +} // don't need to use bootstrap Tour to launch an automatic tour function bootstrap_tour_stub () { @@ -19,27 +38,28 @@ function bootstrap_tour_stub () { -if (website.EditorBar) -website.EditorBar.include({ - tours: [], - start: function () { - var self = this; - var menu = $('#help-menu'); - _.each(this.tours, function (tour) { - var $menuItem = $($.parseHTML('<li><a href="#">'+tour.name+'</a></li>')); - $menuItem.click(function () { - tour.reset(); - tour.run(); +if (website.EditorBar) { + website.EditorBar.include({ + tours: [], + start: function () { + var self = this; + var menu = $('#help-menu'); + _.each(this.tours, function (tour) { + var $menuItem = $($.parseHTML('<li><a href="#">'+tour.name+'</a></li>')); + $menuItem.click(function () { + tour.reset(); + tour.run(); + }); + menu.append($menuItem); }); - menu.append($menuItem); - }); - return this._super(); - }, - registerTour: function (tour) { - website.Tour.add(tour); - this.tours.push(tour); - } -}); + return this._super(); + }, + registerTour: function (tour) { + website.Tour.add(tour); + this.tours.push(tour); + } + }); +} ///////////////////////////////////////////////// @@ -308,7 +328,8 @@ website.Tour = openerp.Class.extend({ self.timer = setTimeout(checkNext, self.defaultDelay); } else { self.reset(); - throw new Error("Time overlaps to arrive to step " + step.stepId + ": '" + step._title + "'" + throw new Error("Can't arrive to step " + step.stepId + ": '" + step._title + "'" + + '\nhref: ' + window.location.href + '\nelement: ' + Boolean(!step.element || ($(step.element).size() && $(step.element).is(":visible") && !$(step.element).is(":hidden"))) + '\nwaitNot: ' + Boolean(!step.waitNot || !$(step.waitNot).size()) + '\nwaitFor: ' + Boolean(!step.waitFor || $(step.waitFor).size()) @@ -363,12 +384,13 @@ website.Tour = openerp.Class.extend({ } }, endTour: function () { - if (parseInt(this.localStorage.getItem("tour-"+this.id+"-test"),10) >= this.steps.length-1) { + var test = parseInt(this.localStorage.getItem("tour-"+this.id+"-test"),10) >= this.steps.length-1; + this.reset(); + if (test) { console.log('ok'); } else { console.log('error'); } - this.reset(); }, autoNextStep: function () { var self = this; |
