[MERGE] from website-fva: snippets editor and building block

bzr revid: chm@openerp.com-20130910100348-w9kxnxc9tavyanqt
This commit is contained in:
Christophe Matthieu
2013-09-10 12:03:48 +02:00
9 changed files with 863 additions and 344 deletions
+77 -8
View File
@@ -137,6 +137,7 @@ table.editorbar-panel td.selected {
line-height: 120px;
color: white;
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.95);
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.07) inset;
}
.oe_snippet .oe_snippet_body {
display: none;
@@ -144,6 +145,9 @@ table.editorbar-panel td.selected {
.oe_snippet > * {
pointer-events: none;
}
.oe_snippet > :not(.oe_snippet_body):not(.oe_snippet_thumbnail) {
display: none !important;
}
.oe_snippet > *:first-child:not(.oe_snippet_thumbnail) {
display: block;
-webkit-transform-origin-x: 5px;
@@ -202,35 +206,68 @@ table.editorbar-panel td.selected {
.oe_snippet_manipulator {
display: block;
position: absolute;
background: rgba(153, 0, 255, 0.1);
background: transparent;
border-radius: 3px;
border: solid 1px rgba(153, 0, 255, 0.5);
opacity: 0;
transition: opacity 100ms linear;
box-sizing: border-box;
pointer-events: none;
}
.oe_snippet_manipulator > .oe_handle {
.oe_snippet_manipulator .oe_boxsize, .oe_snippet_manipulator .oe_margin {
position: absolute;
pointer-events: none;
}
.oe_snippet_manipulator .oe_handle {
display: none;
}
.oe_snippet_manipulator:hover, .oe_snippet_manipulator.oe_hover {
.oe_snippet_manipulator.oe_hover {
opacity: 1;
cursor: pointer;
}
.oe_snippet_manipulator:hover > .oe_handle, .oe_snippet_manipulator.oe_hover > .oe_handle {
.oe_snippet_manipulator.oe_selected, .oe_snippet_manipulator.oe_active, .oe_snippet_manipulator .oe_boxsize, .oe_snippet_manipulator .oe_margin {
opacity: 1;
background: transparent;
border: dashed 1px rgba(153, 0, 255, 0.5);
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.3), 0px 0px 0px 1px rgba(255, 255, 255, 0.3) inset;
}
.oe_snippet_manipulator.oe_selected .oe_handle, .oe_snippet_manipulator.oe_active .oe_handle, .oe_snippet_manipulator .oe_boxsize .oe_handle, .oe_snippet_manipulator .oe_margin .oe_handle {
pointer-events: auto;
}
.oe_snippet_manipulator .oe_buttons {
display: none;
position: absolute;
right: 16px;
top: 16px;
background: #ad00ff;
color: white;
padding: 0px 2px;
border-radius: 3px;
}
.oe_snippet_manipulator .oe_buttons .oe_icon {
display: inline-block;
padding: 8px;
cursor: pointer;
}
.oe_snippet_manipulator.oe_active {
z-index: 100000;
}
.oe_snippet_manipulator.oe_active .oe_handle, .oe_snippet_manipulator.oe_active .oe_buttons {
display: block;
}
.oe_handle {
pointer-events: auto;
position: absolute;
top: 50%;
left: 50%;
display: block;
background: white;
border: solid 1px rgba(153, 0, 255, 0.5);
border: solid 1px #9900ff;
box-sizing: border-box;
border-radius: 2px;
border-radius: 8px;
width: 16px;
height: 16px;
margin: -8px;
cursor: move;
-webkit-transition: background 100ms linear;
}
.oe_handle:hover {
@@ -255,6 +292,38 @@ table.editorbar-panel td.selected {
left: 0px;
}
.oe_handle.n {
cursor: n-resize;
}
.oe_handle.ne {
cursor: ne-resize;
}
.oe_handle.nw {
cursor: nw-resize;
}
.oe_handle.s {
cursor: s-resize;
}
.oe_handle.se {
cursor: se-resize;
}
.oe_handle.sw {
cursor: sw-resize;
}
.oe_handle.e {
cursor: e-resize;
}
.oe_handle.w {
cursor: w-resize;
}
/* ---- MOBILE PREVIEW ---- */
.oe_mobile_preview.modal .modal-content {
height: 660px;
+55 -8
View File
@@ -129,11 +129,14 @@ table.editorbar-panel
line-height: 120px
color: white
text-shadow: 0px 1px 2px rgba(0, 0, 0, 0.95)
box-shadow: 0px 0px 0px 1px rgba(255, 255, 255, 0.07) inset
.oe_snippet_body
display: none
& > *
pointer-events: none
& > :not(.oe_snippet_body):not(.oe_snippet_thumbnail)
display: none !important
& > *:first-child:not(.oe_snippet_thumbnail)
display: block
@@ -186,31 +189,58 @@ table.editorbar-panel
.oe_snippet_manipulator
display: block
position: absolute
background: rgba(153, 0, 255, 0.1)
background: transparent //rgba(153, 0, 255, 0.05)
border-radius: 3px
border: solid 1px rgba(153, 0, 255, 0.5)
opacity: 0
transition: opacity 100ms linear
& > .oe_handle
box-sizing: border-box
pointer-events: none
.oe_boxsize, .oe_margin
position: absolute
pointer-events: none
.oe_handle
display: none
&:hover,&.oe_hover
&.oe_hover
opacity: 1
& > .oe_handle
cursor: pointer
&.oe_selected, &.oe_active, .oe_boxsize, .oe_margin
opacity: 1
background: transparent
border: dashed 1px rgba(153, 0, 255, 0.5)
box-shadow: 0px 0px 0px 1px rgba(255,255,255,0.3), 0px 0px 0px 1px rgba(255,255,255,0.3) inset
.oe_handle
pointer-events: auto
.oe_buttons
display: none
position: absolute
right: 16px
top: 16px
background: rgb(173, 0, 255)
color: white
padding: 0px 2px
border-radius: 3px
.oe_icon
display: inline-block
padding: 8px
cursor: pointer
&.oe_active
z-index: 100000
.oe_handle, .oe_buttons
display: block
.oe_handle
pointer-events: auto
position: absolute
top: 50%
left: 50%
display: block
background: rgba(255, 255, 255, 1)
border: solid 1px rgba(153, 0, 255, 0.5)
border: solid 1px rgba(153, 0, 255, 1)
box-sizing: border-box
border-radius: 2px
border-radius: 8px
width: 16px
height: 16px
margin: -8px
cursor: move
-webkit-transition: background 100ms linear
&:hover
background: rgb(153, 0, 255)
@@ -225,6 +255,23 @@ table.editorbar-panel
bottom: 0px
.oe_handle.nw,.oe_handle.w,.oe_handle.sw
left: 0px
.oe_handle.n
cursor: n-resize
.oe_handle.ne
cursor: ne-resize
.oe_handle.nw
cursor: nw-resize
.oe_handle.s
cursor: s-resize
.oe_handle.se
cursor: se-resize
.oe_handle.sw
cursor: sw-resize
.oe_handle.e
cursor: e-resize
.oe_handle.w
cursor: w-resize
/* ---- MOBILE PREVIEW ---- */
+28 -2
View File
@@ -88,7 +88,7 @@
padding: 8px;
}
.oe_snippet_editor .oe_snippet.oe_selected{
.oe_snippet_editor .oe_snippet.oe_selected, .oe_snippet_editor .oe_snippet.oe_active{
border: 2px solid rgb(151, 137, 255);
box-shadow: 0px 3px 17px rgba(99, 53, 150, 0.59);
@@ -134,7 +134,7 @@
box-shadow: 0px 1px 3px rgb(90,90,90) inset;
border: 0px;
}
.oe_snippet_editor .oe_snippet.oe_new.oe_selected{
.oe_snippet_editor .oe_snippet.oe_new.oe_selected, .oe_snippet_editor .oe_snippet.oe_new.oe_active{
box-shadow: 0px 2px 0px 0px rgb(151,137,255) inset, 0px 3px 17px rgba(99, 53, 150, 0.59) inset;
}
.oe_snippet_editor .oe_snippet.oe_new > *{
@@ -176,3 +176,29 @@
margin-left: 0px !important;
}
*/
#website-top-edit li.oe_snippet_editorbar {
padding: 1px 8px 2px;
font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;
float: left;
margin-top: 6px;
border: 1px solid #a6a6a6;
border-bottom-color: #979797;
background: #eeeeee;
border-radius: 3px;
}
#website-top-edit li.oe_snippet_editorbar > * {
display: inline-block;
height: 22px;
padding: 4px 6px;
outline: 0;
border: 0;
}
#website-top-edit li.oe_snippet_editorbar a.button .icon {
cursor: inherit;
background-repeat: no-repeat;
margin-top: 1px;
width: 16px;
height: 16px;
display: inline-block;
}
@@ -275,6 +275,11 @@
// editor.ui.items -> possible commands &al
// editor.applyStyle(new CKEDITOR.style({element: "span",styles: {color: "#(color)"},overrides: [{element: "font",attributes: {color: null}}]}, {color: '#ff0000'}));
init: function (EditorBar) {
this.EditorBar = EditorBar;
this._super.apply(this, arguments);
},
start_edition: function ($elements) {
var self = this;
$elements
@@ -284,6 +289,7 @@
var $node = $(node);
var editor = CKEDITOR.inline(this, self._config());
editor.on('instanceReady', function () {
self.trigger('instanceReady');
observer.observe(node, OBSERVER_CONFIG);
});
$node.one('content_changed', function () {
@@ -511,7 +517,7 @@
this.$('input.pages').val($target.text()).change();
// No #dropdown('close'), and using #dropdown('toggle') sur
// #closest('.dropdown') makes the dropdown not work correctly
$target.closest('.open').removeClass('open')
$target.closest('.open').removeClass('open');
},
/**
* CKEDITOR.plugins.link.getSelectedLink ignores the editor's root,
-29
View File
@@ -31,35 +31,6 @@
return def;
};
website.mutations = {
darken: function($el){
var $parent = $el.parent();
if($parent.hasClass('dark')){
$parent.replaceWith($el);
}else{
$el.replaceWith($("<div class='dark'></div>").append($el.clone()));
}
},
vomify: function($el){
var hue=0;
var beat = false;
var a = setInterval(function(){
$el.css({'-webkit-filter':'hue-rotate('+hue+'deg)'}); hue += 5;
}, 10);
setTimeout(function(){
clearInterval(a);
setInterval(function(){
var filter = 'hue-rotate('+hue+'deg)'+ (beat ? ' invert()' : '');
$(document.documentElement).css({'-webkit-filter': filter}); hue += 5;
if(hue % 35 === 0){
beat = !beat;
}
}, 10);
},5000);
$('<iframe width="1px" height="1px" src="http://www.youtube.com/embed/WY24YNsOefk?autoplay=1" frameborder="0"></iframe>').appendTo($el);
},
};
var all_ready = null;
var dom_ready = website.dom_ready = $.Deferred();
+515 -158
View File
@@ -2,98 +2,135 @@
'use strict';
var website = openerp.website;
website.templates.push('/website/static/src/xml/website.snippets.xml');
website.EditorBar.include({
events: _.extend({}, website.EditorBar.prototype.events, {
'click button[data-action=snippet]': 'snippet',
}),
start: function () {
return this._super().then(function () {
this.$buttons.snippet = this.$('button[data-action=snippet]');
window.snippets = this.snippets = new website.Snippets();
this.snippets.appendTo($(document.body));
}.bind(this));
},
edit: function () {
var res = this._super.apply(this, arguments);
var self = this;
var instanceReady = false;
this.rte.on('instanceReady', this, function () {
clearTimeout(instanceReady);
instanceReady = setTimeout(function () {
self.activate_building_block_manipulators();
self.activate_snippet_click_editor();
}, 0);
});
return res;
},
activate_building_block_manipulators: function () {
window.snippets = this.snippets = new website.snippet.BuildingBlock(this);
this.snippets.appendTo($(document.body));
this.snippets.activate_snippet_manipulators();
},
snippet: function (ev) {
this.snippets.toggle();
},
});
website.RTE.include({
start_edition: function ($elements) {
this.snippet_carousel();
return this._super($elements);
},
// TODO clean
snippet_carousel: function () {
activate_snippet_click_editor: function () {
var self = this;
$('.carousel').each(function () {
var $carousel = $(this);
var $options = $('.js_carousel_options', $carousel);
$options.on('click', '.label', function (e) {
e.preventDefault();
var $button = $(e.currentTarget);
var $c = $button.parents(".carousel:first");
var $carousel_inner = $c.find('.carousel-inner');
var $snipped_id = false;
var snipped_event_flag = false;
$("body").on('click', "[data-snippet-id]", function (event) {
if (snipped_event_flag) {
return;
}
if($button.hasClass("js_add")) {
var cycle = $carousel_inner.find('.item').size();
$carousel_inner.append(openerp.qweb.render('website.carousel'));
$c.carousel(cycle);
snipped_event_flag = true;
setTimeout(function () {snipped_event_flag = false;}, 0);
if ($snipped_id && $snipped_id.get(0) == event.currentTarget) {
return;
}
else if ($carousel_inner.find('.item').size() > 1) {
$carousel_inner
.find('.item.active').remove().end()
.find('.item:first').addClass('active');
$c.carousel(0);
self.trigger('change', self, null);
self.snippet_blur($snipped_id);
$snipped_id = $(event.currentTarget);
if (typeof $snipped_id.data("snippet-editor") === 'undefined') {
$snipped_id.data("snippet-editor", new (website.snippet.editorRegistry[$snipped_id.data("snippet-id")] || website.snippet.editorRegistry.box)(self, $snipped_id));
}
self.snippet_focus($snipped_id);
});
$("body > :not(:has(#website-top-view))").on('click', function (ev) {
if (!snipped_event_flag && $snipped_id) {
self.snippet_blur($snipped_id);
$snipped_id = false;
}
});
$options.on('change', 'select[name="carousel-background"]', function () {
$('.carousel-inner .item.active', $carousel).css('background-image', 'url(' + $(this).val() + ')');
$(this).val("");
});
$options.on('change', 'select[name="carousel-style"]', function () {
var $container = $('.carousel-inner .item.active .container', $carousel);
$('.content_image', $container).remove();
switch ($(this).val()) {
case 'no_image':
$('.content', $container).attr("class", "content");
break;
case 'image_left':
$('.content', $container).attr("class", "content col-md-6")
.before('<div class="content_image col-md-5"><img class="img-rounded img-responsive" src="/website/static/src/img/china.jpg"></div>');
break;
case 'image_right':
$('.content', $container).attr("class", "content col-md-6")
.after('<div class="content_image col-md-5 col-lg-offset-1"><img class="img-rounded img-responsive" src="/website/static/src/img/china.jpg"></div>');
break;
}
$(this).val("");
});
$options.show();
});
},
snippet_blur: function ($snipped_id) {
if ($snipped_id) {
if ($snipped_id.data("snippet-editor")) {
$snipped_id.data("snippet-editor").onBlur();
}
if ($snipped_id.data("snippet-view")) {
$snipped_id.data("snippet-view").onBlurEdit();
}
}
},
snippet_focus: function ($snipped_id) {
if ($snipped_id) {
if ($snipped_id.data("snippet-view")) {
$snipped_id.data("snippet-view").onFocusEdit();
}
if ($snipped_id.data("snippet-editor")) {
$snipped_id.data("snippet-editor").onFocus();
}
}
},
});
/* ----- SNIPPET SELECTOR ---- */
website.Snippets = openerp.Widget.extend({
website.snippet = {};
// puts $el at the same absolute position as $target
website.snippet.cover_target = function cover_target($el, $target){
$el.css({
'position': 'absolute',
'width': $target.outerWidth(),
'height': $target.outerHeight(),
});
$el.css($target.offset());
}
website.snippet.BuildingBlock = openerp.Widget.extend({
template: 'website.snippets',
init: function () {
init: function (parent) {
this.parent = parent;
this._super.apply(this, arguments);
if(!$('#oe_manipulators').length){
$("<div id='oe_manipulators'></div>").appendTo('body');
}
},
start: function() {
var self = this;
$.ajax({
type: "GET",
url: "/page/website.snippets",
dataType: "text",
success: function(snippets){
self.$el.html(snippets);
self.start_snippets();
},
var snippets_template = [];
_.each(openerp.qweb.compiled_templates, function (val, key) {
if (key.indexOf('website.snippets.') === 0) {
var $snippet = $(openerp.qweb.render(key)).addClass("oe_snippet");
if ($snippet.data("action")) {
self.$el.append($snippet);
self.make_snippet_draggable($snippet);
}
}
});
this.bind_selected_manipulator();
},
path_eval: function(path){
var obj = window;
@@ -104,26 +141,40 @@
return obj;
},
// setup widget and drag and drop
start_snippets: function(){
bind_selected_manipulator: function () {
var $selected_target = null;
$("body").mouseover(function (event){
var $target = $(event.srcElement).parents("[data-snippet-id]:first");
if($target.length && $selected_target != $target){
if($selected_target){
$selected_target.data('manipulator').removeClass('oe_selected');
}
$selected_target = $target;
$target.data('manipulator').addClass('oe_selected');
}
});
},
// activate drag and drop for the snippets in the snippet toolbar
make_snippet_draggable: function($snippet){
var self = this;
this.$('.oe_snippet').draggable({
$snippet.draggable({
helper: 'clone',
zIndex: '1000',
appendTo: 'body',
start: function(){
var snippet = $(this);
var action = snippet.data('action');
var action = $snippet.data('action');
self.deactivate_snippet_manipulators();
if( action === 'insert'){
self.activate_insertion_zones({
siblings: snippet.data('selector-siblings'),
childs: snippet.data('selector-childs')
siblings: $snippet.data('selector-siblings'),
childs: $snippet.data('selector-childs')
});
}else if( action === 'mutate' ){
self.activate_overlay_zones(snippet.data('selector'));
self.activate_overlay_zones($snippet.data('selector'));
}
$('.oe_drop_zone').droppable({
@@ -137,12 +188,25 @@
$(this).removeClass("oe_hover");
},
drop: function(){
if( action === 'insert' ){
$(".oe_drop_zone.oe_hover")
.replaceWith(snippet.find('.oe_snippet_body').clone())
.removeClass('oe_snippet_body');
}else if( action === 'mutate' ){
self.path_eval(snippet.data('action-function'))( $(".oe_drop_zone.oe_hover").data('target') );
var snipped_id = $snippet.data('snippet-id');
if($snippet.find('.oe_snippet_body').size()){
var $toInsert = $snippet.find('.oe_snippet_body').clone();
$toInsert.removeClass('oe_snippet_body');
$toInsert.addClass('oe_snippet_instance');
$toInsert.attr('data-snippet-id', snipped_id);
$(".oe_drop_zone.oe_hover").replaceWith($toInsert);
var $target = $toInsert;
self.deactivate_snippet_manipulators();
self.activate_snippet_manipulators();
} else {
var $target = $(".oe_drop_zone.oe_hover").data('target');
}
if (website.snippet.editorRegistry[snipped_id]) {
var snippet = new website.snippet.editorRegistry[snipped_id](this.parent, $target);
snippet.build_snippet($target);
$target.click();
}
},
});
@@ -152,8 +216,38 @@
self.activate_snippet_manipulators();
},
});
},
// return the original snippet in the editor bar from a snippet id (string)
get_snippet_from_id: function(id){
return $('.oe_snippet').filter(function(){
return $(this).data('snippet-id') === id;
}).first();
},
// WIP
make_draggable_instance: function($instance){
var self = this;
var $snippet = get_snippet_from_id($instance.data('snippet-id'));
$instance.draggable({
helper: 'clone',
zIndex: '1000',
appendTo: 'body',
start: function(){
var action = $snippet.data('action');
if(action === 'insert'){
self.deactivate_snippet_manipulators();
self.activate_insertion_zones({
siblings: $snippet.data('selector-siblings'),
child: $snippet.data('selector-childs')
});
}
}
});
},
// Create element insertion drop zones. two css selectors can be provided
// selector.childs -> will insert drop zones as direct child of the selected elements
// in case the selected elements have children themselves, dropzones will be interleaved
@@ -161,25 +255,23 @@
// selector.siblings -> will insert drop zones after and before selected elements
activate_insertion_zones: function(selector){
var self = this;
var i, len, $zones;
var child_selector = selector.childs || '';
var sibling_selector = selector.siblings || '';
var zone_template = "<div class='oe_drop_zone oe_insert'></div>";
var $drop_zone = $('.oe_drop_zone');
$drop_zone.remove();
$('.oe_drop_zone').remove();
if(child_selector){
$zones = $(child_selector);
for(i = 0, len = $zones.length; i < len; i++ ){
var $zones = $(child_selector);
for( var i = 0, len = $zones.length; i < len; i++ ){
$zones.eq(i).find('> *:not(.oe_drop_zone)').after(zone_template);
$zones.eq(i).prepend(zone_template);
}
}
if(sibling_selector){
$zones = $(sibling_selector);
for(i = 0, len = $zones.length; i < len; i++ ){
var $zones = $(sibling_selector);
for( var i = 0, len = $zones.length; i < len; i++ ){
if($zones.eq(i).prev('.oe_drop_zone').length === 0){
$zones.eq(i).before(zone_template);
}
@@ -191,12 +283,12 @@
// Cleaning up unnecessary zones
$('.oe_snippets .oe_drop_zone').remove(); // no zone in the snippet selector ...
$('#website-top-view').find('.oe_drop_zone').remove(); // no zone in the top bars ...
$('#website-top-edit').find('.oe_drop_zone').remove();
$('#website-top-view .oe_drop_zone').remove(); // no zone in the top bars ...
$('#website-top-edit .oe_drop_zone').remove();
var count;
do {
count = 0;
$zones = $('.oe_drop_zone + .oe_drop_zone'); // no two consecutive zones
var $zones = $('.oe_drop_zone + .oe_drop_zone'); // no two consecutive zones
count += $zones.length;
$zones.remove();
@@ -206,23 +298,25 @@
}while(count > 0);
// Cleaning up zones placed between floating or inline elements. We do not like these kind of zones.
$zones = $drop_zone;
for(i = 0, len = $zones.length; i < len; i++ ){
var $zones = $('.oe_drop_zone');
for( var i = 0, len = $zones.length; i < len; i++ ){
var zone = $zones.eq(i);
var prev = zone.prev();
var next = zone.next();
var float_prev = prev.css('float') || 'none';
var float_next = next.css('float') || 'none';
var disp_prev = prev.css('display') || null;
var disp_next = next.css('display') || null;
var float_prev = zone.prev().css('float') || 'none';
var float_next = zone.next().css('float') || 'none';
var disp_prev = zone.prev().css('display') || null;
var disp_next = zone.next().css('display') || null;
if( (float_prev === 'left' || float_prev === 'right')
&& (float_next === 'left' || float_next === 'right') ){
zone.remove();
continue;
}else if( !( disp_prev === null
|| disp_next === null
|| disp_prev === 'block'
|| disp_next === 'block' )){
zone.remove();
continue;
}
}
},
@@ -230,9 +324,10 @@
$('.oe_drop_zone').remove();
},
// generate drop zones covering the elements selected by the selector
activate_overlay_zones: function(selector){
var $targets = $(selector);
function is_visible($el){
return $el.css('display') != 'none'
&& $el.css('opacity') != '0'
@@ -247,82 +342,43 @@
var parents = $(this).parents().filter(function(){ return !is_visible($(this)); });
return parents.length === 0;
});
var zone_template = "<div class='oe_drop_zone oe_overlay'></div>";
$('.oe_drop_zone').remove();
for(var i = 0, len = $targets.length; i < len; i++){
var $target = $targets.eq(i);
var $zone = $(zone_template);
this.cover_target($zone,$target);
$zone.appendTo('body');
website.snippet.cover_target($zone,$target);
$zone.appendTo('#oe_manipulators');
$zone.data('target',$target);
}
},
cover_target: function($el, $target){
$el.css({
'position': 'absolute',
'width': $target.outerWidth(),
'height': $target.outerHeight(),
});
$el.css($target.offset());
},
// activates the manipulator boxes (with resizing handles) for all snippets
activate_snippet_manipulators: function(){
var self = this;
this.activate_overlay_zones('#wrap .container');
var $snippets = $('.oe_drop_zone');
// we generate overlay drop zones only to get an idea of where the snippet are, the drop
// zones are replaced by manipulators
this.activate_overlay_zones('#wrap [data-snippet-id]');
for(var i = 0, len = $snippets.length; i < len; i++){
var $snippet = $snippets.eq(i);
$('.oe_drop_zone').each(function(){
var $zone = $(this);
var $snippet = $zone.data('target');
var $manipulator = $(openerp.qweb.render('website.snippet_manipulator'));
$manipulator.css({
'top': $snippet.css('top'),
'left': $snippet.css('left'),
'width': $snippet.css('width'),
'height': $snippet.css('height'),
});
$manipulator.data('target',$snippet.data('target'));
$manipulator.appendTo('body');
$snippet.remove();
$manipulator.find('.oe_handle').mousedown(function(event){
var $handle = $(this);
var $manipulator = $handle.parent();
var $snippet = $manipulator.data('target');
var x = event.pageX;
var y = event.pageY;
var pt = $snippet.css('padding-top');
var pb = $snippet.css('padding-bottom');
pt = Number(pt.slice(0, -2)) || 0; //FIXME something cleaner to remove 'px'
pb = Number(pb.slice(0, -2)) || 0;
$manipulator.addClass('oe_hover');
event.preventDefault();
$(document.body).on({
mousemove: function(event){
var dx = event.pageX - x;
var dy = event.pageY - y;
event.preventDefault();
if($handle.hasClass('n') || $handle.hasClass('nw') || $handle.hasClass('ne')){
$snippet.css('padding-top',pt-dy+'px');
self.cover_target($manipulator,$snippet);
}else if($handle.hasClass('s') || $handle.hasClass('sw') || $handle.hasClass('se')){
$snippet.css('padding-bottom',pb+dy+'px');
self.cover_target($manipulator,$snippet);
}
},
mouseup: function(){
$body.off('mouseup mousemove');
self.deactivate_snippet_manipulators();
self.activate_snippet_manipulators();
}
});
website.snippet.cover_target($manipulator, $zone);
$manipulator.data('target',$snippet);
$snippet.data('manipulator',$manipulator);
$manipulator.appendTo('#oe_manipulators');
$zone.remove();
$snippet.off("resize").on("resize", function () {
self.deactivate_snippet_manipulators();
self.activate_snippet_manipulators();
});
}
});
},
deactivate_snippet_manipulators: function(){
$('.oe_snippet_manipulator').remove();
@@ -330,11 +386,312 @@
toggle: function(){
if(this.$el.hasClass('hide')){
this.$el.removeClass('hide');
this.activate_snippet_manipulators();
//this.activate_snippet_manipulators();
}else{
this.$el.addClass('hide');
this.deactivate_snippet_manipulators();
//this.deactivate_snippet_manipulators();
}
},
});
})();
website.snippet.animationRegistry = {};
website.snippet.Animation = openerp.Class.extend({
$: function () {
return this.$el.find.apply(this.$el, arguments);
},
init: function (dom) {
this.$el = $(dom);
this._super.apply(this, arguments);
},
/* onFocusEdit
* if they are an editor for this snippet-id
* Called before onFocus of snippet editor
*/
onFocusEdit : function () {},
/* onBlurEdit
* if they are an editor for this snippet-id
* Called after onBlur of snippet editor
*/
onBlurEdit : function () {},
/* getOptions
* get the options saved in the html view
*/
getOptions: function () {
var options = this.$el.data("snippet-options");
return options ? JSON.parse(options) : undefined;
},
});
$(document).ready(function () {
$("[data-snippet-id]").each(function() {
var $snipped_id = $(this);
if (typeof $snipped_id.data("snippet-view") === 'undefined' &&
website.snippet.animationRegistry[$snipped_id.data("snippet-id")]) {
$snipped_id.data("snippet-view", new website.snippet.animationRegistry[$snipped_id.data("snippet-id")]($snipped_id));
}
});
});
website.snippet.editorRegistry = {};
website.snippet.Editor = openerp.Widget.extend({
init: function (parent, dom) {
this.$target = $(dom);
this.parent = parent;
this._super.apply(this, arguments);
this.renderElement();
this.start();
},
renderElement: function() {
var $el;
if (this.template) {
$el = $(openerp.qweb.render(this.template, {widget: this}).trim());
this.$editor = $el.find(".oe_snippet_editorbar");
this.$thumbnail = $el.find(".oe_snippet_thumbnail");
this.$body = $el.find(".oe_snippet_body");
} else {
$el = this._make_descriptive();
}
this.replaceElement($el);
},
// create the snippet into the view
build_snippet: function () {
},
/* onFocus
* called when the user click inside the snippet dom
*/
onFocus : function () {
if(this.$editor) this.$editor.prependTo(this.parent.$('#website-top-edit .nav.pull-right'));
},
/* onFocus
* called when the user click outide the snippet dom
*/
onBlur : function () {
if(this.$editor) this.$editor.detach();
},
/* setOptions
* saved the options in the html view
*/
setOptions: function (options) {
$target.attr("data-snippet-options", JSON.stringify(options));
},
/* getOptions
* get the options saved in the html view
*/
getOptions: function () {
var options = this.$target.data("snippet-options");
return options ? JSON.parse(options) : undefined;
},
});
website.snippet.editorRegistry.box = website.snippet.Editor.extend({
onFocus : function () {
var self = this;
var $box = $(openerp.qweb.render("website.snippets.box"));
$box.find(".oe_snippet_editorbar").prependTo(this.parent.$('#website-top-edit .nav.pull-right'));
this.$target.data('manipulator').append($box.find(".oe_handles").html()).addClass('oe_active');
function padding_margin_cover ($manipulator, $snippet) {
var height = parseInt($snippet.height() || 0);
var width = parseInt($snippet.width() || 0);
var pcss = {
top: parseInt($snippet.css('padding-top')) + 'px',
bottom: parseInt($snippet.css('padding-bottom')) + 'px',
left: parseInt($snippet.css('padding-left')) + 'px',
right: parseInt($snippet.css('padding-right')) + 'px',
};
var $padding = $manipulator.find(".oe_boxsize").css(pcss);
var mcss = {
top: -parseInt($snippet.css('margin-top')) + 'px',
bottom: -parseInt($snippet.css('margin-bottom')) + 'px',
left: -parseInt($snippet.css('margin-left')) + 'px',
right: -parseInt($snippet.css('margin-right')) + 'px',
};
var $margin = $manipulator.find(".oe_margin").css(mcss);
}
padding_margin_cover( this.$target.data('manipulator'), this.$target);
this.$target.data('manipulator').find(".oe_handle").on('mousedown', function (event){
event.preventDefault();
var $handle = $(this);
var $manipulator = self.$target.data('manipulator');
var $snippet = self.$target;
var x = event.pageX;
var y = event.pageY;
var padding=[parseInt($snippet.css('padding-top') || 0),
parseInt($snippet.css('padding-bottom') || 0),
parseInt($snippet.css('padding-left') || 0),
parseInt($snippet.css('padding-right') || 0)];
$manipulator.addClass('oe_hover');
var body_mousemove = function (event){
event.preventDefault();
var dx = event.pageX - x;
var dy = event.pageY - y;
if($handle.hasClass('n') || $handle.hasClass('nw') || $handle.hasClass('ne')){
$snippet.css('padding-top', (padding[0]+dy)+'px');
}
if($handle.hasClass('s') || $handle.hasClass('sw') || $handle.hasClass('se')){
$snippet.css('padding-bottom',(padding[1]-dy)+'px');
}
if($handle.hasClass('w') || $handle.hasClass('sw') || $handle.hasClass('nw')){
$snippet.css('padding-left',(padding[2]+dx)+'px');
}
if($handle.hasClass('e') || $handle.hasClass('se') || $handle.hasClass('ne')){
$snippet.css('padding-right',(padding[3]-dx)+'px');
}
website.snippet.cover_target($manipulator, $snippet);
padding_margin_cover($manipulator, $snippet);
};
$('body').mousemove(body_mousemove);
var body_mouseup = function(){
$('body').unbind('mousemove', body_mousemove);
$('body').unbind('mouseup', body_mouseup);
$snippet.trigger("resize");
self.onBlur();
self.onFocus();
};
$('body').mouseup(body_mouseup);
});
this._super();
},
onBlur : function () {
this._super();
this.$target.data('manipulator')
.removeClass('oe_active')
.empty();
this.parent.$('#website-top-edit .nav.pull-right > .box_resize').remove();
},
});
website.snippet.editorRegistry.carousel = website.snippet.editorRegistry.box.extend({
template : "website.snippets.carousel",
build_snippet: function($target) {
var id = "myCarousel" + $("body .carousel").size();
$target.attr("id", id);
$target.find(".carousel-control").attr("href", "#"+id);
},
start : function () {
var self = this;
this.$editor.find(".js_add").on('click', this.on_add);
this.$editor.find(".js_remove").on('click', this.on_remove);
var bg = this.$target.find('.carousel-inner .item.active').css('background-image').replace(/url\((.*)\)/g, '\$1');
this.$editor.find('select[name="carousel-background"] option[value="'+bg+'"], select[name="carousel-background"] option[value="'+bg.replace(window.location.protocol+'//'+window.location.host, '')+'"]')
.prop('selected', true);
this.$editor.find('select[name="carousel-background"]').on('change', function () {
self.$target.find('.carousel-inner .item.active').css('background-image', 'url(' + $(this).val() + ')');
});
var style = false;
if (this.$target.find('.carousel-inner .item.active .container .content_image.col-lg-offset-1'))
style = 'image_right';
if (this.$target.find('.carousel-inner .item.active .container .content_image'))
style = 'image_left';
this.$editor.find('select[name="carousel-style"] option[value="'+style+'"]').prop('selected', true);
this.$editor.find('select[name="carousel-style"]').on('change', this.on_bg_change);
},
on_add: function (e) {
e.preventDefault();
var $inner = this.$target.find('.carousel-inner');
var cycle = $inner.find('.item').size();
$inner.append(this.$('> .item'));
this.$target.carousel(cycle);
this.$target.trigger("resize");
},
on_remove: function (e) {
e.preventDefault();
var $inner = this.$target.find('.carousel-inner');
if ($inner.find('.item').size() > 1) {
$inner
.find('.item.active').remove().end()
.find('.item:first').addClass('active');
this.$target.carousel(0);
this.$target.trigger("resize");
}
},
on_bg_change: function (e) {
var $container = this.$target.find('.carousel-inner .item.active .container');
var img_url = $('.content_image img', $container).attr("src");
if (!img_url) {
img_url = this.img_url || "/website/static/src/img/china.jpg";
} else {
this.img_url = img_url;
}
$('.content_image', $container).remove();
switch ($(e.currentTarget).val()) {
case 'no_image':
$('.content', $container).attr("class", "content");
break;
case 'image_left':
$('.content', $container).attr("class", "content col-md-6")
.before('<div class="content_image col-md-5"><img class="img-rounded img-responsive" src="'+img_url+'"></div>');
break;
case 'image_right':
$('.content', $container).attr("class", "content col-md-6")
.after('<div class="content_image col-md-5 col-lg-offset-1"><img class="img-rounded img-responsive" src="'+img_url+'"></div>');
break;
}
},
});
website.snippet.editorRegistry.darken = website.snippet.Editor.extend({
build_snippet: function($target) {
$target.toggleClass('dark');
var $parent = $target.parent();
if($parent.hasClass('dark')){
$parent.replaceWith($target);
}else{
$target.replaceWith($("<div class='dark'></div>").append($target.clone()));
}
}
});
website.snippet.editorRegistry.vomify = website.snippet.Editor.extend({
build_snippet: function($target) {
var hue=0;
var beat = false;
var a = setInterval(function(){
$target.css({'-webkit-filter':'hue-rotate('+hue+'deg)'}); hue += 5;
}, 10);
setTimeout(function(){
clearInterval(a);
setInterval(function(){
var filter = 'hue-rotate('+hue+'deg)'+ (beat ? ' invert()' : '');
$(document.documentElement).css({'-webkit-filter': filter}); hue += 5;
if(hue % 35 === 0){
beat = !beat;
}
}, 10);
},5000);
$('<iframe width="1px" height="1px" src="http://www.youtube.com/embed/WY24YNsOefk?autoplay=1" frameborder="0"></iframe>').appendTo($target);
}
});
})();
@@ -0,0 +1,177 @@
<?xml version="1.0" encoding="utf-8"?>
<templates id="template" xml:space="preserve">
<!-- Editor -->
<t t-name="website.snippets">
<div class='oe_snippets hide'>
</div>
</t>
<t t-name="website.snippet_manipulator">
<div class='oe_snippet_manipulator'></div>
</t>
<!-- Snippets -->
<div t-name="website.snippets.box" data-snippet-id='box'>
<!-- editor bar to display inside the top edit bar -->
<li class='oe_snippet_editorbar box_resize'>
<a href="#" class="button js_box_move"><i class='icon icon-move'></i></a>
<a href="#" class="button js_box_remove"><i class="icon icon-remove"></i></a>
</li>
<!-- custom data for the widget -->
<div class='oe_handles'>
<div class='oe_boxsize'>
<div class='oe_handle n'></div>
<div class='oe_handle ne'></div>
<div class='oe_handle e'></div>
<div class='oe_handle se'></div>
<div class='oe_handle s'></div>
<div class='oe_handle sw'></div>
<div class='oe_handle w'></div>
<div class='oe_handle nw'></div>
</div>
<div class='oe_margin'></div>
</div>
</div>
<div t-name="website.snippets.carousel" data-snippet-id='carousel' data-action='insert' data-selector-siblings='#wrap .container'>
<!-- editor bar to display inside the top edit bar -->
<li class='oe_snippet_editorbar'>
<a href="#" class="button js_add"><i class="icon icon-plus-sign"></i></a>
<a href="#" class="button js_remove"><i class="icon icon-minus-sign"></i></a>
<select name="carousel-background">
<option value="/website/static/src/img/greenfields.jpg">greenfields</option>
<option value="/website/static/src/img/landscape.png">landscape</option>
<option value="/website/static/src/img/aqua.jpg">aqua</option>
</select>
<select name="carousel-style">
<option value="no_image">No image</option>
<option value="image_left">Image left</option>
<option value="image_right">Image right</option>
</select>
</li>
<!-- thumbnail to display inside the bottom widget list editor -->
<div class='oe_snippet_thumbnail oe_label'>carousel</div>
<!-- body to insert after drag and drop thumbnail -->
<div id="myCarousel" class="oe_snippet_body carousel slide" data-interval="100000">
<!-- Carousel items -->
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;">
<div class="container" data-snippet-id="container">
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<h1>Create Awesome Websites</h1>
<h3>Super easy, fully flexible</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
</div>
</div>
</div>
</div>
<!-- Carousel nav -->
<a class="carousel-control left" href="#myCarousel" data-slide="prev"></a>
<a class="carousel-control right" href="#myCarousel" data-slide="next"></a>
</div>
<!-- custom data for the widget -->
<div class="item" style="background-image: url(/website/static/src/img/china.jpg); background-size: cover; background-position: bottom;" >
<div class='container' data-snippet-id="container">
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<h1>Your New Banner Slide</h1>
<h3>With another convincing subtitle</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
</div>
</div>
</div>
</div>
<div t-name="website.snippets.darken" data-snippet-id='darken' data-action='mutate' data-selector='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label'>Darken</div>
</div>
<div t-name="website.snippets.surprise" data-snippet-id='vomify' data-action='mutate' data-selector='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label' style='background-image:radial-gradient(red,orange,yellow,green,blue);'>Surprise!</div>
</div>
<div t-name="website.snippets.spacer" data-snippet-id='spacer' data-action='insert' data-selector-siblings='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label'>Spacer</div>
<div class="oe_snippet_body container mt32"></div>
</div>
<div t-name="website.snippets.title" data-snippet-id='title' data-action='insert' data-selector-siblings='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label'>
Main Title
</div>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-12 text-center">
<h1 class="mt64">Welcome To Your New Homepage,</h1>
<h2 class="mt32 subheader">where <b><em>everything</em></b> can be customized </h2>
</div>
</div>
</section>
</div>
<div t-name="website.snippets.three-collumns" data-snippet-id='three-collumns' data-action='insert' data-selector-siblings='#wrap .container'>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-12 text-center">
<h2 class="mt48">Ut enim ad minim veniam</h2>
</div>
</div>
<div class="row mt32">
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg"/>
<h4 class="mt16">Cillum Dolore</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/desert_thumb.jpg"/>
<h4 class="mt16">Mollit Anim</h4>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/deers_thumb.jpg"/>
<h4 class="mt16">Nemo Enim Ipsam</h4>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas</p>
</div>
</div>
</section>
</div>
<div t-name="website.snippets.header-block" data-snippet-id='header-block' data-action='insert' data-selector-siblings='#wrap .container'>
<section class="container oe_snippet_body">
<div class="row">
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg"/>
</div>
<div class="col-md-6 col-lg-offset-1">
<p class="mt16">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<div class="text-center">
<a href="http://www.openerp.com/start" class="btn btn-default mt16 btn-lg btn-primary">Call To <em>Action</em></a>
</div>
</div>
</div>
</section>
</div>
</templates>
-30
View File
@@ -57,34 +57,4 @@
</div>
</t>
<t t-name="website.carousel">
<div class="item" style="background-image: url(/website/static/src/img/china.jpg); background-size: cover; background-position: bottom;" >
<div class='container'>
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<h1>Your New Banner Slide</h1>
<h3>With another convincing subtitle</h3>
<a href="/page/website.contactus" class="btn btn-success btn-large mt16">Contact us</a>
</div>
</div>
</div>
</t>
<t t-name="website.snippets">
<div class='oe_snippets hide'>
</div>
</t>
<t t-name="website.snippet_manipulator">
<div class='oe_snippet_manipulator'>
<div class='oe_handle n'></div>
<div class='oe_handle ne'></div>
<div class='oe_handle e'></div>
<div class='oe_handle se'></div>
<div class='oe_handle s'></div>
<div class='oe_handle sw'></div>
<div class='oe_handle w'></div>
<div class='oe_handle nw'></div>
</div>
</t>
</templates>
+4 -108
View File
@@ -157,27 +157,11 @@
<template id="homepage" page="True">
<t t-call="website.layout">
<section>
<div id="myCarousel" class="carousel slide" data-interval="1000000">
<div class="oe_carousel_options js_carousel_options" t-ignore="1" t-if="editable">
<span class="label label-default js_add"><i class="icon-plus-sign"></i></span>
<span class="label label-default js_remove"><i class="icon-minus-sign"></i></span>
<select name="carousel-background" class="form-control">
<option value="">Chose an other background</option>
<option value="/website/static/src/img/greenfields.jpg">greenfields</option>
<option value="/website/static/src/img/landscape.png">landscape</option>
<option value="/website/static/src/img/aqua.jpg">aqua</option>
</select>
<select name="carousel-style" class="form-control">
<option value="">Chose an other style</option>
<option value="no_image">No image</option>
<option value="image_left">Image left</option>
<option value="image_right">Image right</option>
</select>
</div>
<div id="myCarousel" data-snippet-id="carousel" class="carousel slide" data-interval="1000000">
<!-- Carousel items -->
<div class="carousel-inner">
<div class="item active" style="background-image: url(/website/static/src/img/greenfields.jpg); background-size: cover;">
<div class="container">
<div class="container" data-snippet-id="container">
<div class="content" style="padding-top: 90px; padding-bottom:45px;">
<h1>Create Awesome Websites</h1>
<h3>Super easy, fully flexible</h3>
@@ -193,7 +177,7 @@
</section>
<div>
<section class="container">
<section class="container" data-snippet-id="container">
<div class="row">
<div class="col-md-12 text-center">
<h1>Welcome To Your New Homepage,</h1>
@@ -203,7 +187,7 @@
</section>
<div class="dark mt64">
<section class="container">
<section class="container" data-snippet-id="container">
<div class="row">
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg" />
@@ -418,94 +402,6 @@
</a>
</template>
<template id="snippets">
<div class='oe_snippet' data-snippet-id='darken' data-action='mutate' data-selector='#wrap .container' data-action-function='openerp.website.mutations.darken'>
<div class='oe_snippet_thumbnail oe_label'>Darken</div>
</div>
<div class='oe_snippet' data-snippet-id='surprise' data-action='mutate' data-selector='#wrap .container' data-action-function='openerp.website.mutations.vomify'>
<div class='oe_snippet_thumbnail oe_label' style='background-image:radial-gradient(red,orange,yellow,green,blue);'>Surprise!</div>
</div>
<div class='oe_snippet' data-snippet-id='spacer' data-action='insert' data-selector-siblings='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label'>Spacer</div>
<div class="oe_snippet_body container mt32"></div>
</div>
<div class='oe_snippet' data-snippet-id='title' data-action='insert' data-selector-siblings='#wrap .container'>
<div class='oe_snippet_thumbnail oe_label'>
Main Title
</div>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-12 text-center">
<h1 class="mt64">Welcome To Your New Homepage,</h1>
<h2 class="mt32 subheader">where <b><em>everything</em></b> can be customized </h2>
</div>
</div>
</section>
</div>
<div class='oe_snippet' data-snippet-id='' data-action='insert' data-selector-siblings='#wrap .container'>
<section class="oe_snippet_body container">
<div class="row">
<div class="col-md-12 text-center">
<h2 class="mt48">Ut enim ad minim veniam</h2>
</div>
</div>
<div class="row mt32">
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/china_thumb.jpg"/>
<h4 class="mt16">Cillum Dolore</h4>
<p>Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/desert_thumb.jpg"/>
<h4 class="mt16">Mollit Anim</h4>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
</div>
<div class="col-md-4">
<img class="img-rounded img-responsive" src="/website/static/src/img/deers_thumb.jpg"/>
<h4 class="mt16">Nemo Enim Ipsam</h4>
<p>Sed ut perspiciatis unde omnis iste natus error sit voluptatem accusantium
doloremque laudantium, totam rem aperiam, eaque ipsa quae ab illo inventore
veritatis et quasi architecto beatae vitae dicta sunt explicabo. Nemo enim
ipsam voluptatem quia voluptas</p>
</div>
</div>
</section>
</div>
<div class='oe_snippet' name='Header' data-action='insert' data-selector-siblings='#wrap .container'>
<section class="container oe_snippet_body">
<div class="row">
<div class="col-md-5">
<img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg"/>
</div>
<div class="col-md-6 col-lg-offset-1">
<p class="mt16">Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod
tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam,
quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo
consequat.</p>
<p>Duis aute irure dolor in reprehenderit in voluptate velit esse cillum
dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non
proident, sunt in culpa qui officia deserunt mollit anim id est laborum</p>
<div class="text-center">
<a href="http://www.openerp.com/start" class="btn btn-default mt16 btn-lg btn-primary">Call To <em>Action</em></a>
</div>
</div>
</div>
</section>
</div>
</template>
<template id="kanban">
<t t-set="step"><t t-esc="step or 0"/></t>
<t t-set="scope"><t t-esc="scope or 0"/></t>