From 74d7de465e38dc6a16aa6e395aa733ddb2e01240 Mon Sep 17 00:00:00 2001 From: qsm-odoo Date: Thu, 11 Aug 2016 13:49:46 +0200 Subject: [PATCH] [REF] website_blog: refactore cover option and change opacity behavior * Isolate website_blog style * Simplify/Correct the cover option JS * Allow to modify the cover from the blog list page * Change cover layout (use a more conventionnal odoo design with a div which is full width, which contains a container(-fluid) then its content) -> easier to customize. * Refactore code to be understandable * Change behavior of opacity filter: before this commit the cover filter was not intuitive and did not work on IE or Edge, it mixed the color of the bg-image and the bg-color in a complex way and the opacity was just controlling if the image was visible clearly or not (which led in general to ugly style if the opacity was used). Now, the color in applied *on top* of the image so that its color changes the hue of the underlying image. The opacity value controls only the opacity value of the color to mix. [MIGRATION] Note: as the opacity behavior has changed, the exact same behavior is not reproductible at all. But for the change to make a bit of sense in old databases, this should be applied for the field "cover_properties" of blog posts (with changes in layout): if cover_properties.background-color != "oe_none": cover_properties.opacity = 0.6 else: cover_properties.opacity = 1.0 - cover_properties.opacity --- .../website_blog/data/website_blog_demo.xml | 4 +- addons/website_blog/models/website_blog.py | 2 +- .../static/src/js/website_blog.editor.js | 112 +++--- .../static/src/js/website_blog.js | 9 +- .../static/src/less/website_blog.less | 365 +++++++++--------- addons/website_blog/views/snippets.xml | 46 +-- .../views/website_blog_templates.xml | 108 +++--- 7 files changed, 326 insertions(+), 320 deletions(-) diff --git a/addons/website_blog/data/website_blog_demo.xml b/addons/website_blog/data/website_blog_demo.xml index e153ddc8afe..fe6e9bfaae2 100644 --- a/addons/website_blog/data/website_blog_demo.xml +++ b/addons/website_blog/data/website_blog_demo.xml @@ -20,7 +20,7 @@ Odoo, email The Future of Emails - {"background-image": "url(/website_blog/static/src/img/library/flower_texture.jpg)", "background-color": "oe_yellow" ,"opacity": "1.0", "resize_class": "cover container cover_narrow"} + {"background-image": "url(/website_blog/static/src/img/library/flower_texture.jpg)", "background-color": "oe_yellow" ,"opacity": "0.6", "resize_class": "cover container cover_narrow"}
@@ -124,7 +124,7 @@ - {"background-image": "url(/website/static/src/img/library/ship_sea.jpg)", "background-color": "oe_green" ,"opacity": "0.8", "resize_class": "cover cover_full"} + {"background-image": "url(/website/static/src/img/library/ship_sea.jpg)", "background-color": "oe_green" ,"opacity": "0.6", "resize_class": "cover container-fluid cover_full"}
diff --git a/addons/website_blog/models/website_blog.py b/addons/website_blog/models/website_blog.py index 0bc1a670e33..6aa92d7df73 100644 --- a/addons/website_blog/models/website_blog.py +++ b/addons/website_blog/models/website_blog.py @@ -107,7 +107,7 @@ class BlogPost(models.Model): active = fields.Boolean('Active', default=True) cover_properties = fields.Text( 'Cover Properties', - default='{"background-image": "none", "background-color": "oe_none", "opacity": "0.6", "resize_class": ""}') + default='{"background-image": "none", "background-color": "oe_black", "opacity": "0.2", "resize_class": ""}') blog_id = fields.Many2one('blog.blog', 'Blog', required=True, ondelete='cascade') tag_ids = fields.Many2many('blog.tag', string='Tags') content = fields.Html('Content', default=_default_content, translate=html_translate, sanitize=False) diff --git a/addons/website_blog/static/src/js/website_blog.editor.js b/addons/website_blog/static/src/js/website_blog.editor.js index 196f6de7280..7bd025439ae 100644 --- a/addons/website_blog/static/src/js/website_blog.editor.js +++ b/addons/website_blog/static/src/js/website_blog.editor.js @@ -13,7 +13,7 @@ contentMenu.TopBar.include({ new_blog_post: function () { var model = new Model('blog.blog'); model.call('name_search', [], { context: base.get_context() }).then(function (blog_ids) { - if (blog_ids.length == 1) { + if (blog_ids.length === 1) { document.location = '/blog/' + blog_ids[0][0] + '/post/new'; } else if (blog_ids.length > 1) { website.prompt({ @@ -47,23 +47,22 @@ odoo.define('website_blog.editor', function (require) { rte.Class.include({ // Destroy popOver and stop listening mouseup event on edit mode start: function () { - var self = this; $(".js_tweet, .js_comment").off('mouseup').trigger('mousedown'); return this._super.apply(this, arguments); }, saveElement: function ($el, context) { - if ($el.is('.website_blog #title')) { + if ($el.is('.o_blog_cover_container')) { return ajax.jsonRpc("/blog/post_change_background", 'call', { - 'post_id' : +$el.find('#blog_post_name').data('oe-id'), + 'post_id' : parseInt($el.closest("[name=\"blog_post\"], .website_blog").find("[data-oe-model=\"blog.post\"]").first().data("oe-id"), 10), 'cover_properties' : { - "background-image": $el.find('#js_blogcover').css("background-image").replace(/"/g, ''), - "background-color": $el.find('#js_blogcover').attr("class"), - "opacity": $el.find('#js_blogcover').css("opacity"), - "resize_class": $el.attr('class'), + "background-image": $el.children(".o_blog_cover_image").css("background-image").replace(/"/g, ''), + "background-color": $el.data("filter_color"), + "opacity": $el.data("filter_value"), + "resize_class": $el.data("cover_class"), } }); } - return this._super($el, context); + return this._super.apply(this, arguments); }, }); @@ -84,59 +83,66 @@ odoo.define('website_blog.editor', function (require) { } }); - options.registry.website_blog = options.Class.extend({ - start : function() { - this.$cover = this.$target.find('#js_blogcover'); - this.src = this.$target.css("background-image").replace(/url\(|\)|"|'/g,'').replace(/.*none$/,''); - this.$image = $(''); - this._super(); + options.registry.blog_cover = options.Class.extend({ + init: function () { + this._super.apply(this, arguments); + + this.$image = this.$target.children(".o_blog_cover_image"); + this.$filter = this.$target.children(".o_blog_cover_filter"); }, - clear : function(type, value, $li) { + clear: function (type, value, $li) { if (type !== 'click') return; - this.src = null; - this.$cover.css({"background-image": '', 'min-height': ''}); - this.$image.removeAttr("src"); - this.$target.removeClass('cover cover_full cover_narrow cover_midscreen cover_mid_narrow'); + + this.select_class(type, "", $()); + this.$image.css("background-image", ""); + this.$target.addClass("o_dirty"); }, - change : function(type, value, $li) { + change: function (type, value, $li) { if (type !== 'click') return; - var self = this; - var editor = new widget.MediaDialog(null, {only_images: true}, this.$image, this.$image[0]).open(); - editor.on('saved', self, function (event, img) { - var url = self.$image.attr('src'); - self.$cover.css({"background-image": url ? 'url(' + url + ')' : ""}); - self.$target.addClass('o_dirty cover cover_full'); - self.set_active(); + + var $image = $("", {src: this.$image.css("background-image")}); + + var editor = new widget.MediaDialog(null, {only_images: true}, $image, $image[0]).open(); + editor.on("saved", this, function (event, img) { + var src = $image.attr("src"); + this.$image.css("background-image", src ? ("url(" + src + ")") : ""); + if (!this.$target.hasClass("cover")) { + var $li = this.$el.find("[data-select_class]").first(); + this.select_class(type, $li.data("select_class"), $li); + } + this.set_active(); + this.$target.addClass("o_dirty"); }); }, - cover_class : function(type, value, $li) { - this.$target.attr("class", (type === 'over' || type === 'click') ? value : this.class); + filter_value: function (type, value, $li) { + this.$filter.css("opacity", value); this.$target.addClass('o_dirty'); }, - opacity : function(type, value, $li) { - this.$cover.css("opacity", (type === 'over' || type === 'click') ? value : this.value); - this.$target.addClass('o_dirty'); - }, - bgcolor : function(type, value, $li) { - this.$cover.attr("class", (type === 'over' || type === 'click') ? value : this.background); - this.$target.addClass('o_dirty'); - }, - set_active: function(){ - this._super(); - this.background = this.$cover.attr("class"); - this.class = this.$target.attr('class'); - this.value = this.$cover.css('opacity'); - this.$el.parent().find('.snippet-option-website_blog:not(li[data-change])').toggleClass("hidden", !this.$target.hasClass("cover")); - this.$el.find('li[data-bgcolor], li[data-opacity], li[data-cover_class]').removeClass("active"); - this.$el.find('[data-bgcolor="' + this.background + '"], [data-opacity="' + parseFloat(this.value).toFixed(1) + '"]').addClass("active"); - - if ((this.class || '').indexOf('cover_narrow') != -1) { - this.$el.find('[data-cover_class*=cover_narrow]').addClass("active"); - } else if ((this.class || '').indexOf('cover_midscreen') != -1) { - this.$el.find('[data-cover_class*=cover_midscreen]').addClass("active"); - } else { - this.$el.find('[data-cover_class*=cover_full]').addClass("active"); + filter_color: function (type, value, $li) { + var $lis = this.$el.find("[data-filter_color]").addBack("[data-filter_color]"); + var classes = $lis.map(function () {return $(this).data("filter_color");}).get().join(" "); + this.$filter.removeClass(classes); + if (value) { + this.$filter.addClass(value); } + this.$target.addClass("o_dirty"); + }, + set_active: function () { + this._super.apply(this, arguments); + var self = this; + + this.$el.filter(":not([data-change])").toggleClass("hidden", !this.$target.hasClass("cover")); + + var $actives = this.$el.find('li[data-filter_value], li[data-filter_color]').removeClass("active") + .filter(function () { + var data = $(this).data(); + return (parseFloat(data.filter_value).toFixed(1) === parseFloat(self.$filter.css('opacity')).toFixed(1) + || self.$filter.hasClass(data.filter_color)); + }).addClass("active"); + + this.$target.data("cover_class", this.$el.find(".active[data-select_class]").data("select_class") || ""); + this.$target.data("filter_value", $actives.filter("[data-filter_value]").data("filter_value") || 0.0); + this.$target.data("filter_color", $actives.filter("[data-filter_color]").data("filter_color") || ""); }, }); }); diff --git a/addons/website_blog/static/src/js/website_blog.js b/addons/website_blog/static/src/js/website_blog.js index 33a61318c19..5c2d82f7646 100644 --- a/addons/website_blog/static/src/js/website_blog.js +++ b/addons/website_blog/static/src/js/website_blog.js @@ -1,8 +1,6 @@ odoo.define('website_blog.website_blog', function (require) { "use strict"; -var ajax = require('web.ajax'); - function page_transist(event) { event.preventDefault(); var newLocation = $('.js_next')[0].href; @@ -37,9 +35,9 @@ function shareArticle(event){ url = 'https://www.facebook.com/sharer/sharer.php?u='+window.location.href; } else if ($(this).hasClass('o_linkedin_complete')){ url = 'https://www.linkedin.com/shareArticle?mini=true&url='+window.location.href+'&title='+blog_title_complete; - } else{ + } else { url = 'https://plus.google.com/share?url='+window.location.href; - }; + } } else { var blog_post = $(this).parents("[name='blog_post']"); @@ -71,7 +69,6 @@ $(document).ready(function() { function() { $('div.o_blog_post_complete a').not('#'+this.id).addClass('unhover'); }, function() { $('div.o_blog_post_complete a').not('#'+this.id).removeClass('unhover'); } ); - - }); +}); }); diff --git a/addons/website_blog/static/src/less/website_blog.less b/addons/website_blog/static/src/less/website_blog.less index 7b6038fa4f9..dab718f9129 100644 --- a/addons/website_blog/static/src/less/website_blog.less +++ b/addons/website_blog/static/src/less/website_blog.less @@ -1,224 +1,221 @@ - -.css_website_mail { - .has-error { - border-color: red; - } - .css_nav_month { - display: none; - &:first-of-type { - display: block; +.website_blog { + .css_website_mail { + .has-error { + border-color: red; + } + .css_nav_month { + display: none; + &:first-of-type { + display: block; + } } } -} -.read_width { - max-width: 700px; - margin-left: auto; - margin-right: auto; -} - -.blog_content { - min-height: 350px !important; - a.oe_mail_expand:after { - content: " →"; + .read_width { + max-width: 700px; + margin-left: auto; + margin-right: auto; } - a.oe_mail_expand { - font-weight: bold; + + .blog_content { + min-height: 350px !important; + a.oe_mail_expand:after { + content: " →"; + } + a.oe_mail_expand { + font-weight: bold; + } } -} -p.post-meta { - position: relative; - top: -5px; -} + p.post-meta { + position: relative; + top: -5px; + } -div#blog_angle_down { - a:hover { + div#blog_angle_down a:hover { text-decoration: none; } -} -.cover { - color: white; - position: relative; - .blog_title { - position: absolute; - } -} + .o_blog_cover_container { + position: relative; -.blog_title { - text-align: center; - top: 20%; - margin-right: auto; - margin-left: auto; - left: 0; - right: 0; - h1 { - font-weight: bold; - } -} + > .o_blog_cover_component { + .o-position-absolute(0, 0, 0, 0); + display: none; -.cover_full { - height: 100vh; -} + .o-background-size(cover); + background-position: center; + background-repeat: no-repeat; + } -.cover_midscreen { - height: 50vh; -} + > .blog_title { + margin: 0 auto; + text-align: center; + font-weight: bold; + } + &.cover { + > .o_blog_cover_component { + display: block; + } + } + &.cover, &.cover_footer { + > .blog_title { + color: white; + .o-position-absolute(20%, @grid-gutter-width, auto, @grid-gutter-width); + } + } -.cover_narrow { - height: 50vh; - overflow: hidden; -} + &.cover_full { + height: 600px; + height: 100vh; + } + &.cover_narrow { + height: 300px; + height: 50vh; + } + &.o_list_cover { + display: none; + width: auto!important; + height: 250px!important; -.cover_footer_bg { - min-height: 350px; - height: 65vh; -} + &.cover { + display: block; + } + } -/* mobile preview: for blog h1,h2 font-size and cover-footer height of image overlapas */ -@media (max-width: 768px) { - .blog_title { - h1 { - font-size: 26px; + &.cover_footer { + min-height: 350px; + height: 65vh; + background-color: #B8B8B8; + cursor: pointer; } } - .blog_title { - h2 { - font-size: 20px; + /* mobile preview: for blog h1,h2 font-size and cover-footer height of image overlapas */ + @media (max-width: @screen-xs-max) { + .o_blog_cover_container { + > .blog_title { + > h1 { + font-size: 26px; + } + > h2 { + font-size: 20px; + } + } + &.cover > .blog_title { + top: 10%; + } + + &.cover_narrow { + height: 65vh; + } + + &.cover_footer { + min-height: 280px; + height: 50vh; + + > .blog_title { + top: 2%; + } + } } } - .cover_narrow { - height: 65vh; - } - - #title { - .blog_title { - top: 10%; - } - } - - .cover_footer { - min-height: 280px; - height: 50vh; - } - - .cover_footer { - .blog_title { - top: 2%; - } - } -} - -mark + .popover, .cover_footer { - cursor: pointer; -} - -.blog_publish_btn { - padding-top: 16px; -} - -.cover_footer_bg[style*="background-image: none;"] { - background-color: #B8B8B8; -} - -#js_blogcover { - background-blend-mode: multiply; - background-size: cover; - background-position: center; - background-repeat: no-repeat; - height: 100%; -} - -.o_blog_post_title { - font-size: 24px; -} - -.o_blog_post_teaser { - text-align: justify; -} - -/*To display the grid or inline presentation of the blog.post_list*/ -.o_grid { - margin: 0 6% 6% 0; - border: 1px solid #EEEEEE; - box-shadow: .5px .5px .5px .5px rgba(238,238,238,1); - padding-bottom: 15px; - .o_blog_post_teaser { - width: 100%; - } - > .text-muted > .mb0 > hr { - display: none; - } -} - -#js_blogcover { - height: 150px; - opacity: 1 !important; -} - -.o_author_avatar_little { - width: 40px; - display: inline; - margin-top: -5px; -} - -/* Sharing links style */ - -.o_sharing_links { - margin-top: 20px; - > p { - display: inline; - font-size: 12px; - } - > a { - color: #b3b3b3; - font: normal normal normal 28px/1 FontAwesome; - margin: 0 4px 0 4px; + mark + .popover, .cover_footer { cursor: pointer; - &:hover { - text-decoration: none; + } + + .js_publish_management { + .o-position-absolute(@grid-gutter-width/2, @grid-gutter-width/2); + z-index: 1; + + .dropdown-menu { + left: auto; + right: 0; } - &.o_twitter_complete, &.o_twitter:hover { - color: #4099FF; + } + + .o_blog_post_title { + font-size: 24px; + } + + .o_blog_post_teaser { + text-align: justify; + } + + /*To display the grid or inline presentation of the blog.post_list*/ + .o_grid { + margin: 0 6% 6% 0; + border: 1px solid #EEEEEE; + box-shadow: .5px .5px .5px .5px rgba(238,238,238,1); + padding-bottom: 15px; + .o_blog_post_teaser { + width: 100%; } - &.o_google_complete, &.o_google:hover { - color: #DD4B39; + > .text-muted > .mb0 > hr { + display: none; } - &.o_facebook_complete, &.o_facebook:hover { - color: #3b5998; + } + + .o_author_avatar_little { + width: 40px; + display: inline; + margin-top: -5px; + } + + /* Sharing links style */ + + .o_sharing_links { + margin-top: 20px; + > p { + display: inline; + font-size: 12px; } - &.o_linkedin_complete, &.o_linkedin:hover { - color: #0E76A8; - } - &.unhover { + > a { color: #b3b3b3; + font: normal normal normal 28px/1 FontAwesome; + margin: 0 4px 0 4px; + cursor: pointer; + &:hover { + text-decoration: none; + } + &.o_twitter_complete, &.o_twitter:hover { + color: #4099FF; + } + &.o_google_complete, &.o_google:hover { + color: #DD4B39; + } + &.o_facebook_complete, &.o_facebook:hover { + color: #3b5998; + } + &.o_linkedin_complete, &.o_linkedin:hover { + color: #0E76A8; + } + &.unhover { + color: #b3b3b3; + } } } -} -.o_blog_post_complete.o_sharing_links { - max-width: 700px; - margin: 50px auto 50px auto; - text-align: center; + .o_blog_post_complete.o_sharing_links { + max-width: 700px; + margin: 50px auto 50px auto; + text-align: center; - > p { - font-size: 16px; - font-weight: 600; + > p { + font-size: 16px; + font-weight: 600; + } + > a { + font: normal normal normal 40px/1 FontAwesome; + } } - > a { - font: normal normal normal 40px/1 FontAwesome; - } -} -div { - &[name="blog_post_data"] { + div[name="blog_post_data"] { margin-top: 20px !important; font-size: 13px; } - &[name="blog_post"] { + div[name="blog_post"] { position: relative; hr { margin-top: 10px; diff --git a/addons/website_blog/views/snippets.xml b/addons/website_blog/views/snippets.xml index 65b361a38a7..f4e639c2d8a 100644 --- a/addons/website_blog/views/snippets.xml +++ b/addons/website_blog/views/snippets.xml @@ -1,44 +1,40 @@ - diff --git a/addons/website_blog/views/website_blog_templates.xml b/addons/website_blog/views/website_blog_templates.xml index 54c1600b686..a0afb424c3e 100644 --- a/addons/website_blog/views/website_blog_templates.xml +++ b/addons/website_blog/views/website_blog_templates.xml @@ -179,12 +179,21 @@ + + @@ -207,42 +216,41 @@ - - - -