summaryrefslogtreecommitdiff
path: root/addons/website/static/src/js
diff options
context:
space:
mode:
authorThibault Delavallée <tde@openerp.com>2013-12-02 16:49:35 +0100
committerThibault Delavallée <tde@openerp.com>2013-12-02 16:49:35 +0100
commit3a96d971fa25becb3d348bac4b339b3a5d65fd16 (patch)
tree86e3b6a9b6dc018266b4a7b33e6acb2dbe54aca6 /addons/website/static/src/js
parent5ee3495ccbcf300d9bdbbcbaa6dfe677bab3dc61 (diff)
parentb54ec1c5a21f878b28decc6744a7899bc22af687 (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.js41
-rw-r--r--addons/website/static/src/js/website.backend.js32
-rw-r--r--addons/website/static/src/js/website.editor.js34
-rw-r--r--addons/website/static/src/js/website.menu.js2
-rw-r--r--addons/website/static/src/js/website.snippets.animation.js3
-rw-r--r--addons/website/static/src/js/website.snippets.editor.js240
-rw-r--r--addons/website/static/src/js/website.tour.banner.js2
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" }),
},
{