From: Xavier Morel Date: Fri, 13 Sep 2013 14:55:30 +0000 (+0200) Subject: [MERGE] from parent branch X-Git-Tag: InsPy_master01~73^2~1558^2~1 X-Git-Url: http://git.inspyration.org/?a=commitdiff_plain;h=1adb76aad079a3cebf66fa2f50558f93bacbc52e;hp=f16b61cbe61a77cf331a54ea11520322e7730739;p=odoo%2Fodoo.git [MERGE] from parent branch bzr revid: xmo@openerp.com-20130913145530-p1gm7k7ie5t3powp --- diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index 9607aef..494931d 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -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; diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index 1dd71ac..9b6bf98 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -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 diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index 77bed2f..6c14b29 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -315,6 +315,8 @@ '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, diff --git a/addons/website/static/src/js/website.seo.js b/addons/website/static/src/js/website.seo.js index e905374..e574112 100644 --- a/addons/website/static/src/js/website.seo.js +++ b/addons/website/static/src/js/website.seo.js @@ -20,12 +20,31 @@ 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); }); @@ -72,21 +92,37 @@ '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(); @@ -96,6 +132,10 @@ 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 () { @@ -114,7 +154,7 @@ // 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); @@ -141,9 +181,13 @@ 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); }); }, @@ -163,14 +207,32 @@ }, }); - 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 () { @@ -189,6 +251,18 @@ 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({ @@ -208,23 +282,26 @@ 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") @@ -242,11 +319,11 @@ 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) { @@ -255,14 +332,14 @@ 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 <h1> 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 <h1> tag on your page.", @@ -289,13 +366,28 @@ }, 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); }, }); })(); diff --git a/addons/website/static/src/js/website.snippets.js b/addons/website/static/src/js/website.snippets.js index 58970b6..36e72fc 100644 --- a/addons/website/static/src/js/website.snippets.js +++ b/addons/website/static/src/js/website.snippets.js @@ -203,7 +203,8 @@ 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' ){ @@ -238,20 +239,22 @@ 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); } }, @@ -275,6 +278,7 @@ var $snippet = get_snippet_from_id($instance.data('snippet-id')); $instance.draggable({ + greedy: true, helper: 'clone', zIndex: '1000', appendTo: 'body', @@ -284,7 +288,8 @@ 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') }); } @@ -299,28 +304,39 @@ // 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 = "
"; 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; @@ -333,12 +349,12 @@ $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'; @@ -348,15 +364,14 @@ 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 @@ -497,8 +512,8 @@ // 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: { @@ -508,34 +523,26 @@ 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(""); - 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); }, }); }, @@ -562,8 +569,6 @@ * (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 @@ -763,14 +768,24 @@ 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'; diff --git a/addons/website/static/src/xml/website.seo.xml b/addons/website/static/src/xml/website.seo.xml index f0cbd49..9471733 100644 --- a/addons/website/static/src/xml/website.seo.xml +++ b/addons/website/static/src/xml/website.seo.xml @@ -1,7 +1,7 @@ -