[FIX] website snippets: quote, quotes slider, parallax
authorChristophe Matthieu <chm@openerp.com>
Fri, 29 Nov 2013 16:00:45 +0000 (17:00 +0100)
committerChristophe Matthieu <chm@openerp.com>
Fri, 29 Nov 2013 16:00:45 +0000 (17:00 +0100)
bzr revid: chm@openerp.com-20131129160045-527o2i6unyyymr6e

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

index c7fa9ca..71f030a 100644 (file)
@@ -254,6 +254,13 @@ footer {
   content: "Drag Building Blocks Here";
 }
 
+.oe_structure.oe_editable [data-snippet-id]:empty {
+  background: rgba(255, 0, 0, 0.1);
+}
+.oe_structure.oe_editable [data-snippet-id]:empty:before {
+  content: "Please Edit This Empty Block";
+}
+
 /* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
 .navbar .nav > li > p {
   margin-bottom: 0px;
@@ -406,14 +413,14 @@ ul.nav-stacked > li > a {
 }
 
 /* Parallax Theme */
-.parallax_quote {
+.parallax_quote, [data-snippet-id="slider"] {
   background: center center no-repeat fixed;
   background-size: contain;
 }
-.parallax_quote .carousel-indicators li {
+.parallax_quote .carousel-indicators li, [data-snippet-id="slider"] .carousel-indicators li {
   border: 1px solid grey;
 }
-.parallax_quote .carousel-indicators .active {
+.parallax_quote .carousel-indicators .active, [data-snippet-id="slider"] .carousel-indicators .active {
   background-color: grey;
 }
 
index faa17d0..157fd19 100644 (file)
@@ -171,6 +171,11 @@ footer
 .oe_structure.oe_editable.oe_empty:empty:before, .oe_editable[data-oe-type=html]:empty:before, .oe_structure.oe_editable.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before
     content: 'Drag Building Blocks Here'
 
+.oe_structure.oe_editable [data-snippet-id]:empty
+    background: rgba(255,0,0,0.1)
+    &:before
+        content: 'Please Edit This Empty Block'
+
 /* ---- HACK FOR COVERING UP CK EDITOR BOGUS P INSERTION --- */
 
 .navbar .nav > li > p
@@ -304,7 +309,7 @@ ul.nav-stacked > li > a
 
 /* Parallax Theme */
 
-.parallax_quote
+.parallax_quote, [data-snippet-id="slider"]
     background: center center no-repeat fixed
     background-size: contain
     .carousel-indicators
index c50ad39..c1d31bc 100644 (file)
                         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');
index e491912..1dbb2d7 100644 (file)
@@ -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});
         },
index e296850..ebbe0bf 100644 (file)
                             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');
             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');
         */
         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;
         },
 
         /*
         *  function called just before save vue
         */
         clean_for_save: function () {
-
+            this.$target.find(".row:empty").remove();
         },
     });
 
 
             return this.grid;
         },
-
         _drag_and_drop_after_insert_dropzone: function(){
             var self = this;
             var $zones = $(".row:has(> .oe_drop_zone)").each(function () {
             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;
             }
         },
     });
-
-    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;
                 }
             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){
             });
             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)");
             $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();
         },
     });
 
     * 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']);
 
 })();
index 1af045b..857e1db 100644 (file)
@@ -51,7 +51,6 @@
         </div>
     </div>
 
-
     <div data-snippet-id="text-image" data-selector-children=".oe_structure, [data-oe-type=html]">
         <div class="oe_snippet_thumbnail">
             <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_text_image.png"/>
         </section>
     </div>
 
+    <div data-snippet-id="slider" data-selector-children=".oe_structure, [data-oe-type=html]">
+        <li class="oe_snippet_options divider"></li>
+        <li class="oe_snippet_options">
+            <a href="#" class="button js_add">Add Slide</a>
+        </li>
+        <li class="oe_snippet_options">
+            <a href="#" class="button js_remove">Remove Slide</a>
+        </li>
+        <div class="oe_snippet_thumbnail">
+            <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
+            <span class="oe_snippet_thumbnail_title">Quotes Slider</span>         
+        </div>
+        <div id="myQuoteCarousel" class="oe_snippet_body carousel slide oe_small mb0">
+            <!-- Indicators -->
+            <ol class="carousel-indicators mb0">
+                <li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
+                <li data-target="#myQuoteCarousel" data-slide-to="1"></li>
+            </ol>
+            <div class="carousel-inner">
+
+                <div class="item text_only active">
+                    <div class="container">
+                        <div class="content">
+
+                            <div class="row">
+                                <blockquote class="col-md-5 col-md-offset-4 mt64">
+                                        <p>
+                                            Write here a quote from one of your customer. Quotes are are
+                                            great way to give confidence in your products or services.
+                                        </p>
+                                        <small>Author of this quote</small>
+                                </blockquote>
+                            </div>
+
+                        </div>
+                    </div>
+                </div>
+
+                <div class="item text_only">
+                    <div class="container">
+                        <div class="content">
+
+                            <div class="row">
+                                <blockquote class="col-md-5 col-md-offset-4 mt64">
+                                        <p>
+                                            OpenERP provides essential platform for our project management.
+                                            Things are better organized and more visible with it.
+                                        </p>
+                                        <small>John Doe, CEO</small>
+                                </blockquote>
+                            </div>
+
+                        </div>
+                    </div>
+
+                </div>
+            </div>
+        </div>
+    </div>
+
 </div>
 
 <div id="snippet_content" class="tab-pane fade">
 
-    <div data-snippet-id="well" data-selector-siblings="p, h1, h2, h3, blockquote">
+    <div data-snippet-id="well" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
         <div class="oe_snippet_thumbnail">
             <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_well.png"/>
             <span class="oe_snippet_thumbnail_title">Well</span>
     </div>
 
 
-    <div data-snippet-id="quote" data-selector-siblings="p, h1, h2, h3, blockquote">
+    <div data-snippet-id="quote" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
         <div class="oe_snippet_thumbnail">            
             <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quote.png"/>
             <span class="oe_snippet_thumbnail_title">Quote</span>
     </div>
 
 
-    <div data-snippet-id="panel" data-selector-siblings="p, h1, h2, h3, blockquote">
+    <div data-snippet-id="panel" data-selector-siblings="p, h1, h2, h3, blockquote" data-selector-children=".content">
         <div class="oe_snippet_thumbnail">
             <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_panel.png"/>
             <span class="oe_snippet_thumbnail_title">Panel</span>
     <div data-snippet-id="parallax_quote" data-selector-children=".oe_structure, [data-oe-type=html]">
         <div class="oe_snippet_thumbnail">
             <img class="oe_snippet_thumbnail_img" src="/website/static/src/img/blocks/block_quotes_slider.png"/>
-            <span class="oe_snippet_thumbnail_title">Quotes Slider</span>        
+            <span class="oe_snippet_thumbnail_title">Parallax Slider</span>        
         </div>
         <section class="oe_snippet_body parallax_quote oe_structure" style="background-image: url('/website/static/src/img/parallax/quote.png')">
-            <div id="myQuoteCarousel" class="carousel slide oe_medium mb32" data-snippet-id="carousel">
+            <div id="myQuoteCarousel" class="carousel slide oe_medium mb32" data-snippet-id="slider">
                 <!-- Indicators -->
                 <ol class="carousel-indicators mb0">
                     <li data-target="#myQuoteCarousel" data-slide-to="0" class="active"></li>
                             <div class="content">
 
                                 <div class="row">
-                                    <div class="col-md-5 col-md-offset-4 mt64">
-                                        <blockquote>
+                                    <blockquote class="col-md-5 col-md-offset-4 mt64">
                                             <p>
                                                 Write here a quote from one of your customer. Quotes are are
                                                 great way to give confidence in your products or services.
                                             </p>
                                             <small>Author of this quote</small>
-                                        </blockquote>
-                                    </div>
+                                    </blockquote>
                                 </div>
 
                             </div>
-                            <div class="carousel-image hidden-xs">
-                                <img src="/website/static/src/img/banner/banner_picture.png" alt="Banner OpenERP Image"/>
-                            </div>
                         </div>
                     </div>
 
                             <div class="content">
 
                                 <div class="row">
-                                    <div class="col-md-5 col-md-offset-4 mt64">
-                                        <blockquote>
+                                    <blockquote class="col-md-5 col-md-offset-4 mt64">
                                             <p>
                                                 OpenERP provides essential platform for our project management.
                                                 Things are better organized and more visible with it.
                                             </p>
                                             <small>John Doe, CEO</small>
-                                        </blockquote>
-                                    </div>
+                                    </blockquote>
                                 </div>
 
                             </div>
-                            <div class="carousel-image hidden-xs">
-                                <img src="/website/static/src/img/banner/banner_picture.png" alt="Banner OpenERP Image"/>
-                            </div>
                         </div>
 
                     </div>
                 </div>
-                <a class="carousel-control left hidden" href="#myQuoteCarousel" data-slide="prev" style="width: 10%"><span class="glyphicon glyphicon-chevron-left"><span class="hidden">.</span></span></a>
-                <a class="carousel-control right hidden" href="#myQuoteCarousel" data-slide="next" style="width: 10%"><span class="glyphicon glyphicon-chevron-right"><span class="hidden">.</span></span></a>
             </div>
-
-
         </section>
     </div>
 
-
 </div>
 
 <div id="snippet_hidden" class="hidden">
         </li>
     </div>
 
-    <div data-snippet-style-id='size' data-selector='div[data-snippet-id="parallax"], div[data-snippet-id="carousel"]'>
+    <div data-snippet-style-id='size' data-selector='div[data-snippet-id="parallax"], div[data-snippet-id="carousel"], div[data-snippet-id="slider"]'>
         <li class="dropdown-submenu" data-required="true">
             <a tabindex="-1" href="#">Size</a>
             <ul class="dropdown-menu">
                 <li class="dropdown-submenu">
                     <a tabindex="-1" href="#">Various</a>
                     <ul class="dropdown-menu">
+                        <li data-class="oe_img_bg" data-src="/website/static/src/img/parallax/quote.png"><a>Aqua</a></li>
                         <li data-class="oe_img_bg" data-src="/website/static/src/img/banner/aqua.jpg"><a>Aqua</a></li>
                         <li data-class="oe_img_bg" data-src="/website/static/src/img/banner/baby_blue.jpg"><a>Baby Blue</a></li>
                         <li data-class="oe_img_bg" data-src="/website/static/src/img/banner/black.jpg"><a>Black</a></li>