odoo.define('website.snippets.animation', function (require) {
'use strict';
var ajax = require('web.ajax');
var core = require('web.core');
var base = require('web_editor.base');
var animation = require('web_editor.snippets.animation');
var qweb = core.qweb;
function load_called_template () {
var ids_or_xml_ids = _.uniq($("[data-oe-call]").map(function () {return $(this).data('oe-call');}).get());
if (ids_or_xml_ids.length) {
ajax.jsonRpc('/website/multi_render', 'call', {
'ids_or_xml_ids': ids_or_xml_ids
}).then(function (data) {
for (var k in data) {
var $data = $(data[k]).addClass('o_block_'+k);
$("[data-oe-call='"+k+"']").each(function () {
$(this).replaceWith($data.clone());
});
}
});
}
}
base.ready().then(function () {
load_called_template();
if ($(".o_gallery:not(.oe_slideshow)").size()) {
// load gallery modal template
ajax.loadXML('/website/static/src/xml/website.gallery.xml', qweb);
}
});
animation.registry.slider = animation.Class.extend({
selector: ".carousel",
start: function () {
this.$target.carousel();
},
stop: function () {
this.$target.carousel('pause');
this.$target.removeData("bs.carousel");
},
});
animation.registry.parallax = animation.Class.extend({
selector: ".parallax",
start: function () {
var self = this;
setTimeout(function () {self.set_values();});
this.on_scroll = function () {
var speed = parseFloat(self.$target.attr("data-scroll-background-ratio") || 0);
if (speed == 1) return;
var offset = parseFloat(self.$target.attr("data-scroll-background-offset") || 0);
var top = offset + window.scrollY * speed;
self.$target.css("background-position", "0px " + top + "px");
};
this.on_resize = function () {
self.set_values();
};
$(window).on("scroll", this.on_scroll);
$(window).on("resize", this.on_resize);
},
stop: function () {
$(window).off("scroll", this.on_scroll)
.off("resize", this.on_resize);
},
set_values: function () {
var self = this;
var speed = parseFloat(self.$target.attr("data-scroll-background-ratio") || 0);
if (speed === 1 || this.$target.css("background-image") === "none") {
this.$target.css("background-attachment", "fixed").css("background-position", "0px 0px");
return;
} else {
this.$target.css("background-attachment", "scroll");
}
this.$target.attr("data-scroll-background-offset", 0);
var img = new Image();
img.onload = function () {
var offset = 0;
var padding = parseInt($(document.body).css("padding-top"));
if (speed > 1) {
var inner_offset = - self.$target.outerHeight() + this.height / this.width * document.body.clientWidth;
var outer_offset = self.$target.offset().top - (document.body.clientHeight - self.$target.outerHeight()) - padding;
offset = - outer_offset * speed + inner_offset;
} else {
offset = - self.$target.offset().top * speed;
}
self.$target.attr("data-scroll-background-offset", offset > 0 ? 0 : offset);
$(window).scroll();
};
img.src = this.$target.css("background-image").replace(/url\(['"]*|['"]*\)/g, "");
$(window).scroll();
}
});
animation.registry.share = animation.Class.extend({
selector: ".oe_share",
start: function () {
var url_regex = /(\?(?:|.*&)(?:u|url|body)=)(.*?)(&|#|$)/;
var title_regex = /(\?(?:|.*&)(?:title|text|subject)=)(.*?)(&|#|$)/;
var url = encodeURIComponent(window.location.href);
var title = encodeURIComponent($("title").text());
this.$("a").each(function () {
var $a = $(this);
$a.attr("href", function(i, href) {
return href.replace(url_regex, function (match, a, b, c) {
return a + url + c;
}).replace(title_regex, function (match, a, b, c) {
return a + title + c;
});
});
if ($a.attr("target") && $a.attr("target").match(/_blank/i) && !$a.closest('.o_editable').length) {
$a.on('click', function () {
window.open(this.href,'','menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=550,width=600');
return false;
});
}
});
}
});
animation.registry.media_video = animation.Class.extend({
selector: ".media_iframe_video",
start: function () {
if (!this.$target.has('.media_iframe_video_size').length) {
var editor = '
';
var size = '
';
this.$target.html(editor+size+'');
}
},
});
animation.registry.ul = animation.Class.extend({
selector: "ul.o_ul_folded, ol.o_ul_folded",
start: function (editable_mode) {
this.$('.o_ul_toggle_self').off('click').on('click', function (event) {
$(this).toggleClass('o_open');
$(this).closest('li').find('ul,ol').toggleClass('o_close');
event.preventDefault();
});
this.$('.o_ul_toggle_next').off('click').on('click', function (event) {
$(this).toggleClass('o_open');
$(this).closest('li').next().toggleClass('o_close');
event.preventDefault();
});
},
});
/* -------------------------------------------------------------------------
Gallery Animation
This ads a Modal window containing a slider when an image is clicked
inside a gallery
-------------------------------------------------------------------------*/
animation.registry.gallery = animation.Class.extend({
selector: ".o_gallery:not(.o_slideshow)",
start: function () {
var self = this;
this.$el.on("click", "img", this.click_handler);
},
click_handler : function (event) {
var self = this;
var $cur = $(event.currentTarget);
var edition_mode = ($cur.closest("[contenteditable='true']").size() !== 0);
// show it only if not in edition mode
if (!edition_mode) {
var urls = [],
idx = undefined,
milliseconds = undefined,
params = undefined,
$images = $cur.closest(".o_gallery").find("img"),
size = 0.8,
dimensions = {
min_width : Math.round( window.innerWidth * size*0.9),
min_height : Math.round( window.innerHeight * size),
max_width : Math.round( window.innerWidth * size*0.9),
max_height : Math.round( window.innerHeight * size),
width : Math.round( window.innerWidth * size*0.9),
height : Math.round( window.innerHeight * size)
};
$images.each(function () {
urls.push($(this).attr("src"));
});
var $img = ($cur.is("img") === true) ? $cur : $cur.closest("img");
idx = urls.indexOf($img.attr("src"));
milliseconds = $cur.closest(".o_gallery").data("interval") || false;
var params = {
srcs : urls,
index: idx,
dim : dimensions,
interval : milliseconds,
id: _.uniqueId("slideshow_")
};
var $modal = $(qweb.render('website.gallery.slideshow.lightbox', params));
$modal.modal({
keyboard : true,
backdrop : true
});
$modal.on('hidden.bs.modal', function () {
$(this).hide();
$(this).siblings().filter(".modal-backdrop").remove(); // bootstrap leaves a modal-backdrop
$(this).remove();
});
$modal.find(".modal-content, .modal-body.o_slideshow").css("height", "100%");
$modal.appendTo(document.body);
this.carousel = new animation.registry.gallery_slider($modal.find(".carousel").carousel());
}
} // click_handler
});
animation.registry.gallery_slider = animation.Class.extend({
selector: ".o_slideshow",
start: function () {
var $carousel = this.$target.is(".carousel") ? this.$target : this.$target.find(".carousel");
var self = this;
var $indicator = $carousel.find('.carousel-indicators');
var $lis = $indicator.find('li:not(.fa)');
var $prev = $indicator.find('li.fa:first');
var $next = $indicator.find('li.fa:last');
var index = ($lis.filter('.active').index() || 1) -1;
var page = Math.floor(index / 10);
var nb = Math.ceil($lis.length / 10);
// fix bootstrap use index insead of data-slide-to
$carousel.on('slide.bs.carousel', function () {
setTimeout(function () {
var $item = $carousel.find('.carousel-inner .prev, .carousel-inner .next');
var index = $item.index();
$lis.removeClass("active")
.filter('[data-slide-to="'+index+'"]')
.addClass("active");
},0);
});
function hide () {
$lis.addClass('hidden').each(function (i) {
if (i >= page*10 && i < (page+1)*10) {
$(this).removeClass('hidden');
}
});
$prev.css('visibility', page === 0 ? 'hidden' : '');
$next.css('visibility', (page+1) >= nb ? 'hidden' : '');
}
$indicator.find('li.fa').on('click', function () {
page = (page + ($(this).hasClass('o_indicators_left')?-1:1)) % nb;
$carousel.carousel(page*10);
hide();
});
hide();
$carousel.on('slid.bs.carousel', function () {
var index = ($lis.filter('.active').index() || 1) -1;
page = Math.floor(index / 10);
hide();
});
}
});
});