diff --git a/addons/payment_acquirer/__init__.py b/addons/payment_acquirer/__init__.py index 0ce2de595b2..8de510372ee 100644 --- a/addons/payment_acquirer/__init__.py +++ b/addons/payment_acquirer/__init__.py @@ -20,3 +20,4 @@ ############################################################################## import payment_acquirer +import controllers diff --git a/addons/website/models/ir_ui_view.py b/addons/website/models/ir_ui_view.py index 1b680549164..d6ad607fa3f 100644 --- a/addons/website/models/ir_ui_view.py +++ b/addons/website/models/ir_ui_view.py @@ -11,8 +11,8 @@ class view(osv.osv): 'inherited_option_ids': fields.one2many('ir.ui.view','inherit_option_id','Optional Inheritancies'), 'page': fields.boolean("Whether this view is a web page template (complete)"), 'website_meta_title': fields.char("Website meta title", size=70, translate=True), - 'website_meta_description': fields.text("Website meta description", translate=True), - 'website_meta_keywords': fields.char("Website meta keywords", size=70, translate=True), + 'website_meta_description': fields.text("Website meta description", size=160, translate=True), + 'website_meta_keywords': fields.char("Website meta keywords", translate=True), } _defaults = { 'page': False, diff --git a/addons/website/models/website.py b/addons/website/models/website.py index ec9d56632f5..c79ada6e9e4 100644 --- a/addons/website/models/website.py +++ b/addons/website/models/website.py @@ -14,6 +14,7 @@ import traceback from openerp.tools.safe_eval import safe_eval from openerp.exceptions import AccessError, AccessDenied import werkzeug +from openerp.addons.base.ir.ir_qweb import QWebException import logging logger = logging.getLogger(__name__) @@ -181,11 +182,12 @@ class website(osv.osv): logger.error("Website Rendering Error.\n\n%s" % traceback.format_exc()) return self.render(cr, uid, ids, 'website.404', qweb_context) - try: - main_object = request.registry[view_ref[0]].browse(cr, uid, view_ref[1]) - qweb_context['main_object'] = main_object - except Exception: - pass + if 'main_object' not in qweb_context: + try: + main_object = request.registry[view_ref[0]].browse(cr, uid, view_ref[1]) + qweb_context['main_object'] = main_object + except Exception: + pass try: return view.render( @@ -196,6 +198,16 @@ class website(osv.osv): qweb_context['error'] = err[1] logger.warn("Website Rendering Error.\n\n%s" % traceback.format_exc()) return self.render(cr, uid, ids, 'website.401', qweb_context) + except (QWebException,), err: + qweb_context['traceback'] = traceback.format_exc() + qweb_context['template'] = err.template + qweb_context['message'] = err.message + qweb_context['node'] = err.node and err.node.toxml() + logger.error("Website Rendering Error.\n%(message)s\n%(node)s\n\n%(traceback)s" % qweb_context) + return view.render( + cr, uid, + 'website.500' if qweb_context['editable'] else 'website.404', + qweb_context, context=context) except Exception: logger.exception("Website Rendering Error.") qweb_context['traceback'] = traceback.format_exc() @@ -392,3 +404,13 @@ class base_language_install(osv.osv): 'target': 'self' } return action + +class SeoMetadata(osv.Model): + _name = 'website.seo.metadata' + _description = 'SEO metadata' + + _columns = { + 'website_meta_title': fields.char("Website meta title", size=70, translate=True), + 'website_meta_description': fields.text("Website meta description", size=160, translate=True), + 'website_meta_keywords': fields.char("Website meta keywords", translate=True), + } diff --git a/addons/website/static/src/css/editor.css b/addons/website/static/src/css/editor.css index dc9bb076e59..a009bf61f23 100644 --- a/addons/website/static/src/css/editor.css +++ b/addons/website/static/src/css/editor.css @@ -305,87 +305,53 @@ table.editorbar-panel td.selected { } /* ---- SNIPPETS DROP ZONES ---- */ -#dark_for_dropzone { - width: 100%; - position: absolute; - top: 0; - left: 0; - opacity: 0.4; - z-index: 1000; - pointer-events: none; -} -#dark_for_dropzone td { - background: black; -} -#dark_for_dropzone td.center.active { - background: transparent; -} - -.oe_drop_zone, .oe_drop_zone_style { - border: none; - background: rgba(100, 255, 255, 0.9); - -webkit-border-radius: 4px; - -moz-border-radius: 4px; - -ms-border-radius: 4px; - -o-border-radius: 4px; - border-radius: 4px; -} -.oe_drop_zone div, .oe_drop_zone_style div { - margin: 0; - line-height: 48px; - text-align: center; - color: magenta; - font-weight: bold; - font-size: 24px; -} -.oe_drop_zone .oe_active, .oe_drop_zone_style .oe_active { - display: none; -} - -.oe_drop_zone_style div { - line-height: 24px; -} - -.oe_drop_zone { +.oe_drop_zone.oe_insert { display: block; height: 48px; margin: 0px; margin-top: -4px; margin-bottom: -44px; - z-index: 1002; + -webkit-transition: margin 250ms linear; + -moz-transition: margin 250ms linear; + -o-transition: margin 250ms linear; + transition: margin 250ms linear; width: 100%; position: absolute; + z-index: 1000; } -.oe_drop_zone:not(.oe_vertical):before { +.oe_drop_zone.oe_insert:not(.oe_vertical):before { content: ""; display: block; border-top: dashed 2px rgba(209, 178, 255, 0.72); position: relative; top: 0px; } -.oe_drop_zone.oe_hover:before { +.oe_drop_zone.oe_insert.oe_hover:before { border-top: dashed 2px rgba(116, 255, 161, 0.72); } -.oe_drop_zone.oe_vertical { +.oe_drop_zone.oe_insert.oe_vertical { width: 48px; float: left; position: relative; - margin: 4px -24px !important; + margin: 0px -24px !important; } -.oe_drop_zone.oe_vertical div { - display: none; -} -.oe_drop_zone.oe_overlay { +.oe_drop_zone.oe_insert.oe_overlay { border-radius: 3px; + background: rgba(153, 0, 255, 0.5); } -.oe_drop_zone.oe_drop_active { - background: rgba(100, 255, 255, 0.3); + +.oe_drop_zone, .oe_drop_zone_style { + border: none; + background: rgba(153, 0, 255, 0.3); + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + -ms-border-radius: 4px; + -o-border-radius: 4px; + border-radius: 4px; } -.oe_drop_zone.oe_drop_active div { - display: none; -} -.oe_drop_zone.oe_drop_active .oe_active { - display: block; +.oe_drop_zone.oe_hover, .oe_drop_zone_style.oe_hover { + background: rgba(0, 255, 133, 0.3); + z-index: 1001; } .oe_drop_zone_style { diff --git a/addons/website/static/src/css/editor.sass b/addons/website/static/src/css/editor.sass index bc8b238736e..461667d8e54 100644 --- a/addons/website/static/src/css/editor.sass +++ b/addons/website/static/src/css/editor.sass @@ -242,45 +242,16 @@ table.editorbar-panel /* ---- SNIPPETS DROP ZONES ---- */ -#dark_for_dropzone - width: 100% - position: absolute - top: 0 - left: 0 - opacity: 0.4 - z-index: 1000 - pointer-events: none - td - background: #000 - &.center.active - background: transparent - -.oe_drop_zone, .oe_drop_zone_style - border: none - background: rgba(100, 255, 255, .9) - +border-radius(4px) - div - margin: 0 - line-height: 48px - text-align: center - color: #FF00FF - font-weight: bold - font-size: 24px - .oe_active - display: none - -.oe_drop_zone_style div - line-height: 24px - -.oe_drop_zone +.oe_drop_zone.oe_insert display: block height: 48px margin: 0px margin-top: -4px margin-bottom: -44px - z-index: 1002 + @include transition(margin 250ms linear) width: 100% position: absolute + z-index: 1000 &:not(.oe_vertical):before content: "" display: block @@ -293,17 +264,22 @@ table.editorbar-panel width: 48px float: left position: relative - margin: 4px -24px !important - div - display: none + margin: 0px -24px !important &.oe_overlay border-radius: 3px - &.oe_drop_active - background: rgba(100, 255, 255, .3) - div - display: none - .oe_active - display: block + //@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px)) + //background-size: 100px 100px + background: rgba(153, 0, 255,.5) + +.oe_drop_zone, .oe_drop_zone_style + border: none + //@include background-image( repeating-linear-gradient(45deg, rgba(255,255,255,.1) ,rgba(255,255,255,.1) 35px, rgba(0,0,0,.1) 35px, rgba(0,0,0,.1) 75px)) + //background-size: 100px 100px + background: rgba(153, 0, 255, .3) + +border-radius(4px) + &.oe_hover + background: rgba(0, 255, 133, .3) + z-index: 1001 .oe_drop_zone_style color: white diff --git a/addons/website/static/src/css/snippets.css b/addons/website/static/src/css/snippets.css index c6bb24d04f0..63e8fbefa76 100644 --- a/addons/website/static/src/css/snippets.css +++ b/addons/website/static/src/css/snippets.css @@ -216,4 +216,5 @@ [data-snippet-id] { min-height: 10px; min-width: 10px; -} \ No newline at end of file +} + diff --git a/addons/website/static/src/css/website.css b/addons/website/static/src/css/website.css index c5b58815c67..ce87e592136 100644 --- a/addons/website/static/src/css/website.css +++ b/addons/website/static/src/css/website.css @@ -235,10 +235,7 @@ footer { } .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child { - position: relative; -} -.oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child div, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child div { - display: none; + position: static; } .oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before { diff --git a/addons/website/static/src/css/website.sass b/addons/website/static/src/css/website.sass index 2735dfe9fc8..5197653429c 100644 --- a/addons/website/static/src/css/website.sass +++ b/addons/website/static/src/css/website.sass @@ -161,9 +161,7 @@ footer height: 220px !important .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child - position: relative - div - display: none + position: static .oe_structure.oe_empty:empty:before, [data-oe-type=html]:empty:before, .oe_structure.oe_empty > .oe_drop_zone.oe_insert:only-child:before, [data-oe-type=html] > .oe_drop_zone.oe_insert:only-child:before content: 'Click Edit To Create Content' diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index aef390027c5..c1f05d9b661 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -311,6 +311,7 @@ }, }); + var blocks_selector = _.keys(CKEDITOR.dtd.$block).join(','); /* ----- RICH TEXT EDITOR ---- */ website.RTE = openerp.Widget.extend({ tagName: 'li', @@ -324,6 +325,103 @@ this._super.apply(this, arguments); }, + /** + * In Webkit-based browsers, triple-click will select a paragraph up to + * the start of the next "paragraph" including any empty space + * inbetween. When said paragraph is removed or altered, it nukes + * the empty space and brings part of the content of the next + * "paragraph" (which may well be e.g. an image) into the current one, + * completely fucking up layouts and breaking snippets. + * + * Try to fuck around with selections on triple-click to attempt to + * fix this garbage behavior. + * + * Note: for consistent behavior we may actually want to take over + * triple-clicks, in all browsers in order to ensure consistent cross- + * platform behavior instead of being at the mercy of rendering engines + * & platform selection quirks? + */ + webkitSelectionFixer: function (root) { + root.addEventListener('click', function (e) { + // only webkit seems to have a fucked up behavior, ignore others + // FIXME: $.browser goes away in jquery 1.9... + if (!$.browser.webkit) { return; } + // http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-eventgroupings-mouseevents + // The detail attribute indicates the number of times a mouse button has been pressed + // we just want the triple click + if (e.detail !== 3) { return; } + + // Get closest block-level element to the triple-clicked + // element (using ckeditor's block list because why not) + var $closest_block = $(e.target).closest(blocks_selector); + + // manually set selection range to the content of the + // triple-clicked block-level element, to avoid crossing over + // between block-level elements + document.getSelection().selectAllChildren($closest_block[0]); + }); + }, + tableNavigation: function (root) { + var self = this; + $(root).on('keydown', function (e) { + // ignore non-TAB + if (e.which !== 9) { return; } + + if (self.handleTab(e)) { + e.preventDefault(); + } + }); + }, + /** + * Performs whatever operation is necessary on a [TAB] hit, returns + * ``true`` if the event's default should be cancelled (if the TAB was + * handled by the function) + */ + handleTab: function (event) { + var forward = !event.shiftKey; + + var root = window.getSelection().getRangeAt(0).commonAncestorContainer; + var $cell = $(root).closest('td,th'); + + if (!$cell.length) { return false; } + + var cell = $cell[0]; + + // find cell in same row + var row = cell.parentNode; + var sibling = row.cells[cell.cellIndex + (forward ? 1 : -1)]; + if (sibling) { + document.getSelection().selectAllChildren(sibling); + return true; + } + + // find cell in previous/next row + var table = row.parentNode; + var sibling_row = table.rows[row.rowIndex + (forward ? 1 : -1)]; + if (sibling_row) { + var new_cell = sibling_row.cells[forward ? 0 : sibling_row.cells.length - 1]; + document.getSelection().selectAllChildren(new_cell); + return true; + } + + // at edge cells, copy word/openoffice behavior: if going backwards + // from first cell do nothing, if going forwards from last cell add + // a row + if (forward) { + var row_size = row.cells.length; + var new_row = document.createElement('tr'); + while(row_size--) { + var newcell = document.createElement('td'); + // zero-width space + newcell.textContent = '\u200B'; + new_row.appendChild(newcell); + } + table.appendChild(new_row); + document.getSelection().selectAllChildren(new_row.cells[0]); + } + + return true; + }, start_edition: function ($elements) { var self = this; // create a single editor for the whole page @@ -331,6 +429,8 @@ $(root).on('dragstart', 'img', function (e) { e.preventDefault(); }); + this.webkitSelectionFixer(root); + this.tableNavigation(root); var editor = this.editor = CKEDITOR.inline(root, self._config()); editor.on('instanceReady', function () { editor.setReadOnly(false); @@ -341,6 +441,10 @@ self.setup_editables(root); + // disable firefox's broken table resizing thing + document.execCommand("enableObjectResizing", false, "false"); + document.execCommand("enableInlineTableEditing", false, "false"); + self.trigger('rte:ready'); }); }, @@ -394,14 +498,14 @@ // - contextmenu & tabletools (disable contextual menu) // - bunch of unused plugins var plugins = [ - 'a11yhelp', 'basicstyles', 'bidi', 'blockquote', + 'a11yhelp', 'basicstyles', 'blockquote', 'clipboard', 'colorbutton', 'colordialog', 'dialogadvtab', 'elementspath', 'enterkey', 'entities', 'filebrowser', 'find', 'floatingspace','format', 'htmlwriter', 'iframe', 'indentblock', 'indentlist', 'justify', 'list', 'pastefromword', 'pastetext', 'preview', 'removeformat', 'resize', 'save', 'selectall', 'stylescombo', - 'tab', 'table', 'templates', 'toolbar', 'undo', 'wysiwygarea' + 'table', 'templates', 'toolbar', 'undo', 'wysiwygarea' ]; return { // FIXME @@ -927,7 +1031,7 @@ } - var Observer = window.MutationObserver || window.WebkitMutationObserver || window.JsMutationObserver; + website.Observer = window.MutationObserver || window.WebkitMutationObserver || window.JsMutationObserver; var OBSERVER_CONFIG = { childList: true, attributes: true, @@ -935,7 +1039,7 @@ subtree: true, attributeOldValue: true, }; - var observer = new Observer(function (mutations) { + var observer = new website.Observer(function (mutations) { // NOTE: Webkit does not fire DOMAttrModified => webkit browsers // relying on JsMutationObserver shim (Chrome < 18, Safari < 6) // will not mark dirty on attribute changes (@class, img/@src, diff --git a/addons/website/static/src/js/website.seo.js b/addons/website/static/src/js/website.seo.js index 0d20253290a..342837f43c1 100644 --- a/addons/website/static/src/js/website.seo.js +++ b/addons/website/static/src/js/website.seo.js @@ -241,7 +241,8 @@ return hashIndex >= 0 ? url.substring(0, hashIndex) : url; }, title: function () { - return ($('title').length > 0) && $('title').text() && $('title').text().trim(); + var $title = $('title'); + return ($title.length > 0) && $title.text() && $title.text().trim(); }, changeTitle: function (title) { // TODO create tag if missing @@ -250,7 +251,7 @@ }, description: function () { var $description = $('meta[name=description]'); - return ($description.length > 0) && $description.attr('value') && $description.attr('value').trim(); + return ($description.length > 0) && ($description.attr('value') && $description.attr('value').trim()); }, changeDescription: function (description) { // TODO create tag if missing @@ -322,6 +323,9 @@ 'click button[data-action=update]': 'update', 'hidden.bs.modal': 'destroy', }, + canEditTitle: false, + canEditDescription: false, + canEditKeywords: false, maxTitleSize: 65, maxDescriptionSize: 155, start: function () { @@ -331,13 +335,13 @@ $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, { page: htmlPage }); - if (htmlPage.images().length === 0) { - $modal.find('.js_image_section').remove(); - } else { - self.imageList.appendTo($modal.find('.js_seo_image_list')); - } + // self.suggestImprovements(); + // self.imageList = new website.seo.ImageList(self, { page: htmlPage }); + // if (htmlPage.images().length === 0) { + // $modal.find('.js_image_section').remove(); + // } else { + // self.imageList.appendTo($modal.find('.js_seo_image_list')); + // } self.keywordList = new website.seo.KeywordList(self, { page: htmlPage }); self.keywordList.on('list-full', self, function () { $modal.find('input[name=seo_page_keywords]') @@ -356,8 +360,27 @@ self.keywordList.add(word); }); self.keywordList.appendTo($modal.find('.js_seo_keywords_list')); + self.disableUnsavableFields(); $modal.modal(); }, + disableUnsavableFields: function () { + var self = this; + var $modal = self.$el; + self.loadMetaData().then(function (data) { + self.canEditTitle = data && ('website_meta_title' in data); + self.canEditDescription = data && ('website_meta_description' in data); + self.canEditKeywords = data && ('website_meta_keywords' in data); + if (!self.canEditTitle) { + $modal.find('input[name=seo_page_title]').attr('disabled', true); + } + if (!self.canEditDescription) { + $modal.find('textarea[name=seo_page_description]').attr('disabled', true); + } + if (!self.canEditTitle && !canEditDescription && !canEditKeywords) { + $modal.find('button[data-action=update]').attr('disabled', true); + } + }); + }, suggestImprovements: function () { var tips = []; var self = this; @@ -397,11 +420,16 @@ }, update: function () { var self = this; - var data = { - website_meta_title: self.htmlPage.title(), - website_meta_description: self.htmlPage.description(), - website_meta_keywords: self.keywordList.keywords().join(", "), - }; + var data = {}; + if (self.canEditTitle) { + data.website_meta_title = self.htmlPage.title(); + } + if (self.canEditDescription) { + data.website_meta_description = self.htmlPage.description(); + } + if (self.canEditKeywords) { + data.website_meta_keywords = self.keywordList.keywords().join(", "); + } self.saveMetaData(data).then(function () { self.$el.modal('hide'); }); diff --git a/addons/website/static/src/js/website.snippets.js b/addons/website/static/src/js/website.snippets.js index 5f6d8b5073c..35568e8336e 100644 --- a/addons/website/static/src/js/website.snippets.js +++ b/addons/website/static/src/js/website.snippets.js @@ -45,7 +45,14 @@ /* ----- SNIPPET SELECTOR ---- */ website.snippet = {}; - + var observer = new website.Observer(function (mutations) { + if (!_(mutations).find(function (m) { + return m.type === 'childList' && m.addedNodes.length > 0; + })) { + return; + } + hack_to_add_snippet_id() + }); // puts $el at the same absolute position as $target function hack_to_add_snippet_id () { @@ -80,7 +87,11 @@ this.$active_snipped_id = false; hack_to_add_snippet_id(); this.snippets = []; - $("body").on('DOMNodeInserted', hack_to_add_snippet_id); + + observer.observe(document.body, { + childList: true, + subtree: true, + }); }, dom_filter: function (dom, sibling) { if (typeof dom === "string") { @@ -308,32 +319,17 @@ } - var $dark = $(openerp.qweb.render('website.snippet_dark_for_dropzone')) - .css('height', $("body")[0].scrollHeight + 'px'); - $("body").append($dark); - $('.oe_drop_zone').droppable({ over: function(){ if( action === 'insert'){ dropped = true; - $(this).first().addClass("oe_drop_active").after($toInsert); - $dark.find("td:first") - .css('height', $toInsert.offset().top+'px'); - $dark.find("tr:eq(1) td:first") - .css('width', $toInsert.offset().left+'px'); - $dark.find("td.center") - .addClass("active") - .css('height', $toInsert.outerHeight()+'px') - .css('width', $toInsert.outerWidth()+'px'); + $(this).first().after($toInsert); } }, out: function(){ if( action === 'insert'){ - $(this).removeClass("oe_drop_active"); dropped = false; $toInsert.detach(); - $dark.find("td.center").removeClass("active"); - $("body").scroll(); // trigger a scroll to reset position for jquery api } }, drop: function(){ @@ -342,8 +338,15 @@ }); }, stop: function(ev, ui){ + if (action === 'insert' && ! dropped) { + var el = $('.oe_drop_zone').nearest({x: ui.position.left, y: ui.position.top}).first() + if (el) { + el.after($toInsert) + dropped = true; + } + } + $('.oe_drop_zone').droppable('destroy').remove(); - $("#dark_for_dropzone").remove(); if (dropped) { var $target = false; if(action === 'insert'){ @@ -394,7 +397,7 @@ var sibling_selector = selector.siblings; var vertical_child_selector = selector.vertical_children; - var zone_template = openerp.qweb.render('website.snippet_drop_zone'); + var zone_template = "
"; if(child_selector){ self.dom_filter(child_selector).each(function (){ @@ -414,7 +417,7 @@ var temp_left = 0; $zone.find('> *:not(.oe_drop_zone):visible').each(function () { var $col = $(this); - $template.css('height', ($col.outerHeight() + parseInt($col.css("margin-top")) + parseInt($col.css("margin-bottom")) - 8)+'px'); + $template.css('height', ($col.outerHeight() + parseInt($col.css("margin-top")) + parseInt($col.css("margin-bottom")))+'px'); $lastinsert = $template.clone(); $(this).after($lastinsert); @@ -583,8 +586,7 @@ * Displayed into the overlay options on focus */ _readXMLData: function() { - var self = this; - this.$el = this.parent.$snippets.filter(function () { return $(this).data("snippet-id") == self.snippet_id; }).clone(); + this.$el = this.parent.$snippets.siblings("[data-snippet-id='"+this.snippet_id+"']").clone(); this.$editor = this.$el.find(".oe_snippet_options"); var $options = this.$overlay.find(".oe_overlay_options"); this.$editor.prependTo($options.find(".oe_options ul")); @@ -619,28 +621,18 @@ }); }, _drag_and_drop_after_insert_dropzone: function (){}, - _drag_and_drop_active_drop_zone: function (){ + _drag_and_drop_active_drop_zone: function ($zones){ var self = this; - var $dark = $("#dark_for_dropzone"); - $('.oe_drop_zone').droppable({ + $zones.droppable({ over: function(){ - $(this).first().addClass("oe_drop_active").after(self.$target); - $dark.find("td:first") - .css('height', self.$target.offset().top+'px'); - $dark.find("tr:eq(1) td:first") - .css('width', self.$target.offset().left+'px'); - $dark.find("td.center") - .addClass("active") - .css('height', self.$target.outerHeight()+'px') - .css('width', self.$target.outerWidth()+'px'); + $(".oe_drop_zone.hide").removeClass("hide"); + $(this).addClass("hide").first().after(self.$target); self.dropped = true; }, out: function(){ - $(this).removeClass("oe_drop_active"); - $dark.find("td.center").removeClass("active"); + $(this).removeClass("hide"); self.$target.detach(); self.dropped = false; - $("body").scroll(); // trigger a scroll to reset position for jquery api }, }); }, @@ -664,12 +656,8 @@ $("body").addClass('move-important'); - var $dark = $(openerp.qweb.render('website.snippet_dark_for_dropzone')) - .css('height', $("body")[0].scrollHeight + 'px'); - $("body").append($dark); - self._drag_and_drop_after_insert_dropzone(); - self._drag_and_drop_active_drop_zone(); + self._drag_and_drop_active_drop_zone($('.oe_drop_zone')); }, _drag_and_drop_stop: function (){ var self = this; @@ -679,7 +667,6 @@ self.$overlay.removeClass("hidden"); $("body").removeClass('move-important'); $('.oe_drop_zone').droppable('destroy').remove(); - $('#dark_for_dropzone').remove(); $(".oe_drop_clone, .oe_drop_to_remove").remove(); self.parent.editor_busy = false; self.get_parent_block(); @@ -977,25 +964,23 @@ _drag_and_drop_after_insert_dropzone: function(){ var self = this; - // commented for perf - - // var $zones = $(".row:has(> .oe_drop_zone)").each(function () { - // var $row = $(this); - // var width = $row.innerWidth(); - // var pos = 0; - // while (width > pos + self.size.width) { - // var $last = $row.find("> .oe_drop_zone:last"); - // $last.each(function () { - // pos = $(this).position().left; - // }); - // if (width > pos + self.size.width) { - // $row.append(""); - // var $add_drop = $last.clone(); - // $row.append($add_drop); - // self._drag_and_drop_active_drop_zone($add_drop); - // } - // } - // }); + var $zones = $(".row:has(> .oe_drop_zone)").each(function () { + var $row = $(this); + var width = $row.innerWidth(); + var pos = 0; + while (width > pos + self.size.width) { + var $last = $row.find("> .oe_drop_zone:last"); + $last.each(function () { + pos = $(this).position().left; + }); + if (width > pos + self.size.width) { + $row.append(""); + var $add_drop = $last.clone(); + $row.append($add_drop); + self._drag_and_drop_active_drop_zone($add_drop); + } + } + }); }, _drag_and_drop_start: function () { this._super(); @@ -1089,6 +1074,14 @@ self.$target.carousel(); }); + this.$target.on('dblclick', '.item.active .carousel-image img', function (event) { + var $img = $(event.currentTarget); + var editor = new website.editor.ImageDialog(); + editor.on('start', self, function (o) {o.url = $img.attr("src");}); + editor.on('save', self, function (o) {$img.attr("src", o.url);}); + editor.appendTo($('body')); + }); + this.rebind_event(); }, // rebind event to active carousel on edit mode diff --git a/addons/website/static/src/xml/website.seo.xml b/addons/website/static/src/xml/website.seo.xml index 96a38a75d32..580779283ad 100644 --- a/addons/website/static/src/xml/website.seo.xml +++ b/addons/website/static/src/xml/website.seo.xml @@ -48,12 +48,13 @@ + + -->