[MERGE] from parent branch
authorXavier Morel <xmo@openerp.com>
Fri, 13 Sep 2013 14:55:30 +0000 (16:55 +0200)
committerXavier Morel <xmo@openerp.com>
Fri, 13 Sep 2013 14:55:30 +0000 (16:55 +0200)
bzr revid: xmo@openerp.com-20130913145530-p1gm7k7ie5t3powp

addons/website/static/src/css/editor.css
addons/website/static/src/css/editor.sass
addons/website/static/src/js/website.editor.js
addons/website/static/src/js/website.seo.js
addons/website/static/src/js/website.snippets.js
addons/website/static/src/xml/website.seo.xml
addons/website/static/src/xml/website.snippets.xml
addons/website/views/views.xml

index 9607aef..494931d 100644 (file)
@@ -191,6 +191,11 @@ table.editorbar-panel td.selected {
   height: 32px;
   margin: -16px 0px;
   -webkit-transition: margin 250ms linear;
+  width: 100%;
+  z-index: 1000;
+  position: absolute;
+  background: rgba(153, 0, 255, 0.17);
+  border-radius: 3px;
 }
 .oe_drop_zone.oe_insert:first-child:not(:last-child) {
   margin-top: -8px;
@@ -216,11 +221,11 @@ table.editorbar-panel td.selected {
 .oe_drop_zone.oe_insert.oe_hover:before {
   border-top: dashed 2px rgba(116, 255, 161, 0.72);
 }
-
-.oe_drop_zone.oe_overlay {
+.oe_drop_zone.oe_insert.oe_vertical {
+  width: 16px;
+  display: inline-block;
   position: absolute;
-  background: rgba(153, 0, 255, 0.17);
-  border-radius: 3px;
+  margin: 0px !important;
 }
 
 .oe_drop_zone {
@@ -299,6 +304,9 @@ table.editorbar-panel td.selected {
 .oe_overlay .oe_overlay_options .oe_move .js_box_move {
   margin-left: -50%;
 }
+.oe_overlay .oe_overlay_options .dropdown-menu select, .oe_overlay .oe_overlay_options .dropdown-menu input {
+  display: block;
+}
 .oe_overlay.oe_active .oe_overlay_options {
   display: block;
 }
@@ -426,6 +434,10 @@ table.editorbar-panel td.selected {
 /* ---- ACE EDITOR ---- */
 .oe_ace_view_editor {
   transition: all 0.2s ease-in;
+  -webkit-transition: all 0.2s ease-in;
+  -ms-transition: all 0.2s ease-in;
+  -o-transition: all 0.2s ease-in;
+  -moz-transition: all 0.2s ease-in;
   opacity: 0.3;
   position: fixed;
   top: 51px;
index 1dd71ac..9b6bf98 100644 (file)
@@ -181,6 +181,8 @@ table.editorbar-panel
     height: 32px
     margin: -16px 0px
     -webkit-transition: margin 250ms linear
+    width: 100%
+    z-index: 1000
     &:first-child:not(:last-child)
         margin-top: -8px
         margin-bottom: -24px
@@ -199,8 +201,12 @@ table.editorbar-panel
         top: 24px
     &.oe_hover:before
         border-top: dashed 2px rgba(116, 255, 161, 0.72)
-
-.oe_drop_zone.oe_overlay
+    &.oe_vertical
+        width: 16px
+        display: inline-block
+        position: absolute
+        margin: 0px !important
+    &.oe_overlay
     position: absolute
     background: rgba(153, 0, 255, 0.17)
     border-radius: 3px
@@ -267,6 +273,8 @@ table.editorbar-panel
             left: 50%
             .js_box_move
                 margin-left: -50%
+        .dropdown-menu select,.dropdown-menu input
+            display: block
     &.oe_active .oe_overlay_options
         display: block
 
@@ -380,6 +388,10 @@ $navbar_height: 51px
 
 .oe_ace_view_editor
     transition: all 0.2s ease-in
+    -webkit-transition: all 0.2s ease-in
+    -ms-transition: all 0.2s ease-in
+    -o-transition: all 0.2s ease-in
+    -moz-transition: all 0.2s ease-in
     opacity: 0.3
     position: fixed
     top: $navbar_height
index 77bed2f..6c14b29 100644 (file)
                     'magicline'
             ];
             return {
+                // FIXME
+                language: 'en',
                 // Disable auto-generated titles
                 // FIXME: accessibility, need to generate user-sensible title, used for @title and @aria-label
                 title: false,
index e905374..e574112 100644 (file)
         events: {
             'click .js_seo_suggestion': 'select',
         },
-        init: function (parent, keyword) {
+        init: function (parent, keyword, htmlPage) {
             this.keyword = keyword;
+            this.htmlPage = htmlPage;
+            this.type = this.computeType();
+            this._super(parent);
+        },
+        start: function () {
+            var self = this;
+            function update () {
+                self.updateType();
+            }
+            self.htmlPage.on('title-changed', self, update);
+            self.htmlPage.on('description-changed', self, update);
+        },
+        computeType: function () {
             // cf. http://getbootstrap.com/components/#labels
             // default, primary, success, info, warning, danger
-            this.type = 'default';
-            this._super(parent);
+            return this.htmlPage.isInTitle(this.keyword) ? 'success'
+                    : this.htmlPage.isInDescription(this.keyword) ? 'primary'
+                    : this.htmlPage.isInBody(this.keyword) ? 'info'
+                    : 'default';
+        },
+        updateType: function () {
+            this.type = this.computeType();
+            this.renderElement();
         },
         select: function () {
             this.trigger('selected', this.keyword);
@@ -34,8 +53,9 @@
 
     website.seo.SuggestionList = openerp.Widget.extend({
         template: 'website.seo_list',
-        init: function (parent, word) {
+        init: function (parent, word, htmlPage) {
             this.word = word;
+            this.htmlPage = htmlPage;
             this._super(parent);
         },
         start: function () {
@@ -54,7 +74,7 @@
                 // TODO Order properly ?
                 _.each(_.uniq(cleanList), function (keyword) {
                     if (keyword) {
-                        var suggestion = new website.seo.Suggestion(self, keyword);
+                        var suggestion = new website.seo.Suggestion(self, keyword, self.htmlPage);
                         suggestion.on('selected', self, function (word) {
                             self.trigger('selected', word);
                         });
             'click a[data-action=remove-keyword]': 'destroy',
         },
         maxWordsPerKeyword: 4, // TODO Check
-        init: function (parent, keyword) {
+        init: function (parent, keyword, htmlPage) {
             this.keyword = keyword;
-            // cf. http://getbootstrap.com/components/#labels
-            // default, primary, success, info, warning, danger
-            this.type = 'warning';
+            this.htmlPage = htmlPage;
+            this.type = this.computeType();
             this._super(parent);
         },
         start: function () {
             var self = this;
-            self.suggestionList = new website.seo.SuggestionList(self, this.keyword);
+            function update () {
+                self.updateType();
+            }
+            self.htmlPage.on('title-changed', self, update);
+            self.htmlPage.on('description-changed', self, update);
+            self.suggestionList = new website.seo.SuggestionList(self, this.keyword, this.htmlPage);
             self.suggestionList.on('selected', self, function (word) {
                 self.trigger('selected', word);
             });
             this.suggestionList.appendTo(this.$('.js_seo_keyword_suggestion'));
         },
+        computeType: function () {
+            // cf. http://getbootstrap.com/components/#labels
+            // default, primary, success, info, warning, danger
+            return this.htmlPage.isInTitle(this.keyword) ? 'success'
+                    : this.htmlPage.isInDescription(this.keyword) ? 'primary'
+                    : this.htmlPage.isInBody(this.keyword) ? 'warning'
+                    : 'default';
+        },
+        updateType: function () {
+            this.type = this.computeType();
+            this.$('span.js_seo_keyword').attr('class', "label label-"+this.type+" js_seo_keyword");
+        },
         destroy: function () {
             this.trigger('removed');
             this._super();
     website.seo.KeywordList = openerp.Widget.extend({
         template: 'website.seo_list',
         maxKeywords: 10,
+        init: function (parent, htmlPage) {
+            this.htmlPage = htmlPage;
+            this._super(parent);
+        },
         keywords: function () {
             var result = [];
             this.$('span.js_seo_keyword').each(function () {
             // TODO Refine
             var word = candidate ? candidate.replace(/[,;.:<>]+/g, " ").replace(/ +/g, " ").trim() : "";
             if (word && !self.isKeywordListFull() && !self.isExistingKeyword(word)) {
-                var keyword = new website.seo.Keyword(self, word);
+                var keyword = new website.seo.Keyword(self, word, this.htmlPage);
                 keyword.on('removed', self, function () {
                    self.trigger('list-not-full');
                    self.trigger('removed', word);
 
 
     website.seo.ImageList = openerp.Widget.extend({
+        init: function (parent, htmlPage) {
+            this.htmlPage = htmlPage;
+            this._super(parent);
+        },
         start: function () {
             var self = this;
-            new website.seo.PageParser().images().each(function (index, image) {
+            this.htmlPage.images().each(function (index, image) {
                 new website.seo.Image(self, image).appendTo(self.$el);
             });
         },
         },
     });
 
-    website.seo.PageParser = openerp.Class.extend({
+    website.seo.HtmlPage = openerp.Class.extend(openerp.PropertiesMixin, {
         url: function () {
             var url = window.location.href;
             var hashIndex = url.indexOf('#');
             return hashIndex >= 0 ? url.substring(0, hashIndex) : url;
         },
         title: function () {
-            return $(document.title).text();
+            return $('title').text();
+        },
+        changeTitle: function (title) {
+            $('title').text(title);
+            this.trigger('title-changed', title);
+        },
+        description: function () {
+            return $('meta[name=description]').attr('value');
+        },
+        changeDescription: function (description) {
+            $('meta[name=description]').attr('value', description);
+            this.trigger('description-changed', description);
+        },
+        keywords: function () {
+            return $('meta[name=keywords]').attr('value').split(",");
+        },
+        changeKeywords: function (keywords) {
+            $('meta[name=keywords]').attr('value', keyword.join(","));
+            this.trigger('keywords-changed', keywords);
         },
         headers: function (tag) {
             return $('#wrap '+tag).map(function () {
         company: function () {
             return $('meta[name="openerp.company"]').attr('value');
         },
+        bodyText: function () {
+            return $('body').children().not('.js_seo_configuration').text();
+        },
+        isInBody: function (text) {
+            return new RegExp(text, "gi").test(this.bodyText());
+        },
+        isInTitle: function (text) {
+            return new RegExp(text, "gi").test(this.title());
+        },
+        isInDescription: function (text) {
+            return new RegExp(text, "gi").test(this.description());
+        },
     });
 
     website.seo.Tip = openerp.Widget.extend({
     website.seo.Configurator = openerp.Widget.extend({
         template: 'website.seo_configuration',
         events: {
-            'keypress input[name=seo_page_keywords]': 'confirmKeyword',
+            'keyup input[name=seo_page_keywords]': 'confirmKeyword',
+            'keyup input[name=seo_page_title]': 'titleChanged',
+            'keyup textarea[name=seo_page_description]': 'descriptionChanged',
             'click button[data-action=add]': 'addKeyword',
             'click button[data-action=update]': 'update',
-            'hidden.bs.modal': 'destroy'
+            'hidden.bs.modal': 'destroy',
         },
         maxTitleSize: 65,
         maxDescriptionSize: 155,
         start: function () {
             var self = this;
             var $modal = self.$el;
-            var pageParser = new website.seo.PageParser();
-            $modal.find('.js_seo_page_url').text(pageParser.url());
-            $modal.find('input[name=seo_page_title]').val(pageParser.title());
-            self.suggestImprovements(pageParser);
-            self.imageList = new website.seo.ImageList(self);
+            var htmlPage = this.htmlPage = new website.seo.HtmlPage();
+            $modal.find('.js_seo_page_url').text(htmlPage.url());
+            $modal.find('input[name=seo_page_title]').val(htmlPage.title());
+            $modal.find('textarea[name=seo_page_description]').val(htmlPage.description());
+            self.suggestImprovements();
+            self.imageList = new website.seo.ImageList(self, htmlPage);
             self.imageList.appendTo($modal.find('.js_seo_image_list'));
-            self.keywordList = new website.seo.KeywordList(self);
+            self.keywordList = new website.seo.KeywordList(self, htmlPage);
             self.keywordList.on('list-full', self, function () {
                 $modal.find('input[name=seo_page_keywords]')
                     .attr('readonly', "readonly")
                 self.keywordList.add(word);
             });
             self.keywordList.appendTo($modal.find('.js_seo_keywords_list'));
-            var companyName = pageParser.company().toLowerCase();
+            var companyName = htmlPage.company().toLowerCase();
             self.addKeyword(companyName);
             $modal.modal();
         },
-        suggestImprovements: function (parser) {
+        suggestImprovements: function () {
             var tips = [];
             var self = this;
             function displayTip(message, type) {
                    type: type,
                 }).appendTo(self.$('.js_seo_tips'));
             }
-            var pageParser = parser || new website.seo.PageParser();
-            if (pageParser.headers('h1').length === 0) {
+            var htmlPage = this.htmlPage;
+            if (htmlPage.headers('h1').length === 0) {
                 tips.push({
                     type: 'warning',
                     message: "You don't have an &lt;h1&gt; tag on your page.",
                 });
             }
-            if (pageParser.headers('h1').length > 1) {
+            if (htmlPage.headers('h1').length > 1) {
                 tips.push({
                     type: 'warning',
                     message: "You have more than one &lt;h1&gt; tag on your page.",
         },
         update: function () {
             var data = {
-                title: this.$('input[name=seo_page_title]').val(),
-                description: this.$('input[name=seo_page_title]').val(),
+                title: this.htmlPage.title(),
+                description: this.htmlPage.description(),
                 keywords: this.keywordList.keywords(),
                 images: this.imageList.images(),
             };
             console.log(data);
             // TODO Persist changes
+            this.$el.modal('hide');
+        },
+        titleChanged: function () {
+            var self = this;
+            setTimeout(function () {
+                var title = self.$('input[name=seo_page_title]').val();
+                self.htmlPage.changeTitle(title);
+            }, 1);
+        },
+        descriptionChanged: function () {
+            var self = this;
+            setTimeout(function () {
+                var description = self.$('textarea[name=seo_page_description]').attr('value');
+                self.htmlPage.changeDescription(description);
+            }, 1);
         },
     });
 })();
index 58970b6..36e72fc 100644 (file)
                     if( action === 'insert'){
                         self.activate_insertion_zones({
                             siblings: $snippet.data('selector-siblings'),
-                            childs:   $snippet.data('selector-childs')
+                            childs:   $snippet.data('selector-childs'),
+                            vertical_childs:   $snippet.data('selector-vertical-childs')
                         });
                     } else if( action === 'mutate' ){
 
                                 var $toInsert = $snippet.find('.oe_snippet_body').clone();
                                 $toInsert.removeClass('oe_snippet_body');
                                 $toInsert.attr('data-snippet-id', snipped_id);
-                                $(".oe_drop_zone.oe_hover").after($toInsert);
+                                $(".oe_drop_zone.oe_hover").first().after($toInsert);
                                 $target = $toInsert;
                                 hack_to_add_snippet_id();
                             } else {
-                                $target = $(".oe_drop_zone.oe_hover").data('target');
+                                $target = $(".oe_drop_zone.oe_hover").first().data('target');
                             }
+                            
+                            $('.oe_drop_zone').droppable('destroy').remove();
 
                             if (website.snippet.animationRegistry[snipped_id]) {
                                 new website.snippet.animationRegistry[snipped_id]($target);
                             }
                             if (website.snippet.editorRegistry[snipped_id]) {
                                 self.create_overlay($target);
-                                var snippet = new website.snippet.editorRegistry[snipped_id](self, $target);
-                                snippet.build_snippet($target);
+                                $target.data("snippet-editor").build_snippet($target);
+                                setTimeout(function () {self.make_active($target);},0);
                             }
 
                         },
             var $snippet = get_snippet_from_id($instance.data('snippet-id'));
 
             $instance.draggable({
+                greedy: true,
                 helper:   'clone',
                 zIndex:   '1000',
                 appendTo: 'body',
 
                         self.activate_insertion_zones({
                             siblings: $snippet.data('selector-siblings'),
-                            child: $snippet.data('selector-childs')
+                            child: $snippet.data('selector-childs'),
+                            vertical_childs: $snippet.data('selector-vertical-childs')
                         });
 
                     }
         // selector.siblings -> will insert drop zones after and before selected elements
         activate_insertion_zones: function(selector){
             var self = this;
-            var child_selector   =  selector.childs   ?  this.parent_of_editable_box + (selector.childs).split(",").join(this.parent_of_editable_box) : false;
-            var sibling_selector =  selector.siblings ?  this.parent_of_editable_box + (selector.siblings).split(",").join(this.parent_of_editable_box)  : false;
+            var child_selector = selector.childs ? this.parent_of_editable_box + (selector.childs).split(",").join(this.parent_of_editable_box) : false;
+            var sibling_selector = selector.siblings ? this.parent_of_editable_box + (selector.siblings).split(",").join(this.parent_of_editable_box) : false;
+            var vertical_child_selector   =  selector.vertical_childs   ?  this.parent_of_editable_box + (selector.vertical_childs).split(",").join(this.parent_of_editable_box) : false;
+
             var zone_template = "<div class='oe_drop_zone oe_insert'></div>";
 
             if(child_selector){
-                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);
-                }
+                $(child_selector).each(function (){
+                    var $zone = $(this);
+                    $zone.find('> *:not(.oe_drop_zone):visible').after(zone_template);
+                    $zone.prepend(zone_template);
+                });
+            }
+
+            if(vertical_child_selector){
+                $(vertical_child_selector).each(function (){
+                    var $zone = $(this);
+                    var $template = $(zone_template).addClass("oe_vertical").css('height', $zone.outerHeight()+'px');
+                    $zone.find('> *:not(.oe_drop_zone):visible').after($template);
+                    $zone.prepend($template.clone());
+                });
             }
 
             if(sibling_selector){
-                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);
+                $(sibling_selector).each(function (){
+                    var $zone = $(this);
+                    if($zone.prev('.oe_drop_zone:visible').length === 0){
+                        $zone.before(zone_template);
                     }
-                    if($zones.eq(i).next('.oe_drop_zone').length === 0){
-                        $zones.eq(i).after(zone_template);
+                    if($zone.next('.oe_drop_zone:visible').length === 0){
+                        $zone.after(zone_template);
                     }
-                }
+                });
             }
 
             var count;
                 $zones = $('.oe_drop_zone > .oe_drop_zone').remove();   // no recusrive zones
                 count += $zones.length;
                 $zones.remove();
-            }while(count > 0);
+            } while (count > 0);
 
             // Cleaning up zones placed between floating or inline elements. We do not like these kind of zones.
-            var $zones = $('.oe_drop_zone');
-            for( var i = 0, len = $zones.length; i < len; i++ ){
-                var zone = $zones.eq(i);
+            var $zones = $('.oe_drop_zone:not(.oe_vertical)');
+            $zones.each(function (){
+                var zone = $(this);
                 var prev = zone.prev();
                 var next = zone.next();
                 var float_prev = zone.prev().css('float')   || 'none';
                 if(     (float_prev === 'left' || float_prev === 'right')
                     &&  (float_next === 'left' || float_next === 'right')  ){
                     zone.remove();
-                    continue;
+                    return;
                 }else if( !( disp_prev === null
                           || disp_next === null
                           || disp_prev === 'block'
                           || disp_next === 'block' )){
                     zone.remove();
-                    continue;
                 }
-            }
+            });
         },
 
         // generate drop zones covering the elements selected by the selector
         // activate drag and drop for the snippets in the snippet toolbar
         _drag_and_drop: function(){
             var self = this;
-            var drop = false;
             this.$overlay.draggable({
+                greedy: true,
                 appendTo: 'body',
                 cursor: "move",
                 cursorAt: {
                 handle: ".js_box_move",
                 start: function(){
                     self.parent.editor_busy = true;
+                    self.$target.css("display", "none");
                     self.parent.activate_insertion_zones({
                         siblings: self.$el ? self.$el.data('selector-siblings') : false,
                         childs:   self.$el ? self.$el.data('selector-childs') : false,
+                        vertical_childs: self.$el ? self.$el.data('selector-vertical-childs') : false,
                     });
-                    self.$target.after("<div id='oe_pointer_drag_and_drop' style='display:none;'></div>");
-                    self.$target.detach();
                     $("body").addClass('move-important');
-                    drop = false;
                     $('.oe_drop_zone').droppable({
                         hoverClass: "oe_hover",
                         drop:   function(){
-                            if (!$(".oe_drop_zone.oe_hover").length) {
-                                return false;
-                            }
-                            $(".oe_drop_zone.oe_hover").after(self.$target);
-                            drop = true;
+                            $(this).after(self.$target);
                         },
                     });
                 },
                 stop: function(){
                     $("body").removeClass('move-important');
                     $('.oe_drop_zone').droppable('destroy').remove();
-                    if (!drop) {
-                        $('#oe_pointer_drag_and_drop').after(self.$target);
-                    }
-                    $('#oe_pointer_drag_and_drop').remove();
+                    self.$target.css("display", "");
                     self.parent.editor_busy = false;
-                    setTimeout(function () {self.parent.make_active(self.$target);},0);
+                    setTimeout(function () {self.parent.create_overlay(self.$target);},0);
                 },
             });
         },
         *  (after the insertion of this.$body, if this.$body exists)
         */
         build_snippet: function ($target) {
-            var self = this;
-            setTimeout(function () {self.parent.make_active(self.$target);},0);
         },
 
         /* onFocus
             this.$editor.find(".js_add").on('click', this.on_add);
             this.$editor.find(".js_remove").on('click', this.on_remove);
 
+
+            //background
             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);
+            var selected = 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).length;
+            if (!selected) {
+                this.$editor.find('.carousel-background input').val(bg);
+            }
+
+            this.$editor.find('select[name="carousel-background"], input')
+                .on('click', function (event) {event.preventDefault(); return false;})
+                .on('change', function () {
+                    self.$target.find('.carousel-inner .item.active').css('background-image', 'url(' + $(this).val() + ')');
+                    $(this).next().val("");
+                });
 
-            this.$editor.find('select[name="carousel-background"]').on('change', function () {
-                self.$target.find('.carousel-inner .item.active').css('background-image', 'url(' + $(this).val() + ')');
-            });
 
+            //style
             var style = false;
             if (this.$target.find('.carousel-inner .item.active .container .content_image.col-lg-offset-1'))
                 style = 'image_right';
index f0cbd49..9471733 100644 (file)
@@ -1,7 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <templates id="template" xml:space="preserve">
     <t t-name="website.seo_configuration">
-        <div class="modal fade oe_seo_configuration" tabindex="-1" role="dialog">
+        <div class="modal fade oe_seo_configuration js_seo_configuration" tabindex="-1" role="dialog">
             <div class="modal-dialog">
                 <div class="modal-content">
                     <div class="modal-header">
index f4c83c1..be1304a 100644 (file)
@@ -27,6 +27,7 @@
                 <div class="dropdown oe_options">
                     <i data-toggle="dropdown" class="btn btn-primary icon icon-cog"></i>
                     <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
+                        <li class="divider"></li>
                         <li><a href="#" class="button js_box_remove">Remove this snippet</a></li>
                     </ul>
                 </div>
@@ -53,7 +54,7 @@
         <div class='oe_snippet_thumbnail oe_label'>Margin resize</div>
     </div>
 
-    <div t-name="website.snippets.colmd" data-snippet-id='colmd' data-action='insert' data-selector-childs='.row'>
+    <div t-name="website.snippets.colmd" data-snippet-id='colmd' data-action='insert' data-selector-vertical-childs='.row'>
         <div class='oe_snippet_thumbnail oe_label'>Column</div>
     </div>
 
         <li class='oe_snippet_options'>
             <a href="#" class="button js_remove">Remove current layer</a>
         </li>
-        <li>
-            <div class="dropdown">
-                <a data-toggle="dropdown" href="#">test</a>
-                <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
-                    <li>inside</li>
-                </ul>
-            </div>
-        </li>
         <li class='oe_snippet_options'>
-            <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>
-        </li>
-        <li class='oe_snippet_options'>
-            <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>
+            <a class="carousel-background">
+                Background
+                <select class="form-control" 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>
+                <input class="form-control input-sm" type="text" placeholder="http://...."/>
+            </a>
         </li>
+        <!--li class='oe_snippet_options'>
+            <a class="carousel-style">
+                Style
+                <select class="form-control" 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>
+            </a>
+        </li-->
 
         <!-- thumbnail to display inside the bottom widget list editor -->
         <div class='oe_snippet_thumbnail oe_label'>carousel</div>
@@ -98,7 +98,7 @@
             <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="content" style="padding-top: 90px; padding-bottom:45px;">
+                        <div class="content mt48 mb48" data-snippet-id='resize'>
                             <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>
         </section>
     </div>
 
+    <div t-name="website.snippets.text-image" data-snippet-id='text-image' data-category='structure' data-action='insert' data-selector-childs='.container'>
+        <div class='oe_snippet_thumbnail oe_label'>Text-Image</div>
+        <section class="oe_snippet_body container">
+            <div class="row">
+                <div class="col-md-7">
+                    <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.
+                        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-5">
+                    <img class="img-rounded img-responsive" src="/website/static/src/img/island.jpg"/>
+                </div>
+            </div>
+        </section>
+    </div>
+    <div t-name="website.snippets.image-text" data-snippet-id='image-text' data-category='structure' data-action='insert' data-selector-childs='.container'>
+        <div class='oe_snippet_thumbnail oe_label'>Image-Text</div>
+        <section class="oe_snippet_body container">
+            <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-7">
+                    <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.
+                        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>
+        </section>
+    </div>
+
     <div t-name="website.snippets.three-collumns" data-snippet-id='three-collumns' data-category='structure' data-action='insert' data-selector-siblings='.container'>
         <div class='oe_snippet_thumbnail oe_label'>three-collumns</div>
         <section class="oe_snippet_body container">
index 14b020b..d8c385f 100644 (file)
@@ -19,6 +19,8 @@
                     <head>
                         <title><t t-esc="title or res_company.name"/></title>
                         <meta name="openerp.company" t-att-value="res_company.name" />
+                        <meta name="description" value="" />
+                        <meta name="keywords" value="" />
                         <script type="text/javascript" src="/web/static/lib/underscore/underscore.js"></script>
                         <script type="text/javascript" src="/web/static/lib/underscore.string/lib/underscore.string.js"></script>
                         <script type="text/javascript" src="/web/static/lib/jquery/jquery.js"></script>
                     <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="content" style="padding-top: 90px; padding-bottom:45px;">
+                                <div class="content mt48 mb48" data-snippet-id='resize'>
                                     <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>