diff options
| author | chm@openerp.com <> | 2014-04-09 18:21:15 +0200 |
|---|---|---|
| committer | chm@openerp.com <> | 2014-04-09 18:21:15 +0200 |
| commit | cb9990f48213357d9af2f8928e2b253e312cb770 (patch) | |
| tree | dc7b0fec1ea3b3eb164240218add2d01b8ff78f0 /addons/website/static/src/js | |
| parent | 0e062e61b26d2cdbe9016400c968ba6502e6c081 (diff) | |
| parent | 35d6a6f8a8bb4b116e03d5781c89379bfa02feb2 (diff) | |
[MERGE] from trunk
bzr revid: chm@openerp.com-20140409162115-pelt0qn3ocvzaup5
Diffstat (limited to 'addons/website/static/src/js')
| -rw-r--r-- | addons/website/static/src/js/jQuery.transfo.js | 433 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.editor.js | 677 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.animation.js | 7 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.snippets.editor.js | 108 | ||||
| -rw-r--r-- | addons/website/static/src/js/website.tour.banner.js | 2 |
5 files changed, 1002 insertions, 225 deletions
diff --git a/addons/website/static/src/js/jQuery.transfo.js b/addons/website/static/src/js/jQuery.transfo.js new file mode 100644 index 00000000000..725e5a02216 --- /dev/null +++ b/addons/website/static/src/js/jQuery.transfo.js @@ -0,0 +1,433 @@ +/* +Copyright (c) 2014 Christophe Matthieu, + +Permission is hereby granted, free of charge, to any person +obtaining a copy of this software and associated documentation +files (the "Software"), to deal in the Software without +restriction, including without limitation the rights to use, +copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the +Software is furnished to do so, subject to the following +conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT +HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. +*/ + +(function($){ + 'use strict'; + var rad = Math.PI/180; + + // public methods + var methods = { + init : function(settings) { + return this.each(function() { + var $this = $(this), transfo = $this.data('transfo'); + if (!transfo) { + _init($this, settings); + } else { + _overwriteOptions($this, transfo, settings); + _targetCss($this, transfo); + } + }); + }, + + destroy : function() { + return this.each(function() { + var $this = $(this); + if ($this.data('transfo')) { + _destroy($this); + } + }); + }, + + reset : function() { + return this.each(function() { + var $this = $(this); + if ($this.data('transfo')) { + _reset($this); + } + }); + }, + + toggle : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = !transfo.settings.hide; + _showHide($this, transfo); + } + }); + }, + + hide : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = true; + _showHide($this, transfo); + } + }); + }, + + show : function() { + return this.each(function() { + var $this = $(this); + var transfo = $this.data('transfo'); + if (transfo) { + transfo.settings.hide = false; + _showHide($this, transfo); + } + }); + }, + + settings : function() { + if(this.length > 1) { + this.map(function () { + var $this = $(this); + return $this.data('transfo') && $this.data('transfo').settings; + }); + } + return this.data('transfo') && $this.data('transfo').settings; + }, + center : function() { + if(this.length > 1) { + this.map(function () { + var $this = $(this); + return $this.data('transfo') && $this.data('transfo').$center.offset(); + }); + } + return this.data('transfo') && this.data('transfo').$center.offset(); + } + }; + + $.fn.transfo = function( method ) { + if ( methods[method] ) { + return methods[method].apply( this, Array.prototype.slice.call( arguments, 1 )); + } else if ( typeof method === 'object' || ! method ) { + return methods.init.apply( this, arguments ); + } else { + $.error( 'Method ' + method + ' does not exist on jQuery.transfo' ); + } + return false; + }; + + function _init ($this, settings) { + var transfo = {}; + $this.data('transfo', transfo); + transfo.settings = settings; + + // generate all the controls markup + var css = "box-sizing: border-box; position: absolute; background-color: #fff; border: 1px solid #ccc; width: 8px; height: 8px; margin-left: -4px; margin-top: -4px;"; + transfo.$markup = $('' + + '<div class="transfo-controls">' + + '<div style="cursor: crosshair; position: absolute; margin: -30px; top: 0; right: 0; padding: 1px 0 0 1px;" class="transfo-rotator">' + + '<span class="fa-stack fa-lg">' + + '<i class="fa fa-circle fa-stack-2x"></i>' + + '<i class="fa fa-repeat fa-stack-1x fa-inverse"></i>' + + '</span>' + + '</div>' + + '<div style="' + css + 'top: 0%; left: 0%; cursor: nw-resize;" class="transfo-scaler-tl"></div>' + + '<div style="' + css + 'top: 0%; left: 100%; cursor: ne-resize;" class="transfo-scaler-tr"></div>' + + '<div style="' + css + 'top: 100%; left: 100%; cursor: se-resize;" class="transfo-scaler-br"></div>' + + '<div style="' + css + 'top: 100%; left: 0%; cursor: sw-resize;" class="transfo-scaler-bl"></div>' + + '<div style="' + css + 'top: 0%; left: 50%; cursor: n-resize;" class="transfo-scaler-tc"></div>' + + '<div style="' + css + 'top: 100%; left: 50%; cursor: s-resize;" class="transfo-scaler-bc"></div>' + + '<div style="' + css + 'top: 50%; left: 0%; cursor: w-resize;" class="transfo-scaler-ml"></div>' + + '<div style="' + css + 'top: 50%; left: 100%; cursor: e-resize;" class="transfo-scaler-mr"></div>' + + '<div style="' + css + 'border: 0; width: 0px; height: 0px; top: 50%; left: 50%;" class="transfo-scaler-mc"></div>' + + '</div>'); + transfo.$center = transfo.$markup.find(".transfo-scaler-mc"); + + // init setting and get css to set wrap + _setOptions($this, transfo); + _overwriteOptions ($this, transfo, settings); + + // append controls to container + $("body").append(transfo.$markup); + + // set transfo container and markup + setTimeout(function () { + _targetCss($this, transfo); + },0); + + _bind($this, transfo); + + _targetCss($this, transfo); + } + + function _overwriteOptions ($this, transfo, settings) { + transfo.settings = $.extend(transfo.settings, settings || {}); + } + + function _setOptions ($this, transfo) { + var style = $this.attr("style") || ""; + var transform = style.match(/transform\s*:([^;]+)/) ? style.match(/transform\s*:([^;]+)/)[1] : ""; + + transfo.settings = {}; + + transfo.settings.angle= transform.indexOf('rotate') != -1 ? parseFloat(transform.match(/rotate\(([^)]+)deg\)/)[1]) : 0; + transfo.settings.scalex= transform.indexOf('scaleX') != -1 ? parseFloat(transform.match(/scaleX\(([^)]+)\)/)[1]) : 1; + transfo.settings.scaley= transform.indexOf('scaleY') != -1 ? parseFloat(transform.match(/scaleY\(([^)]+)\)/)[1]) : 1; + + transfo.settings.style = style.replace(/[^;]*transform[^;]+/g, '').replace(/;+/g, ';'); + $this.attr("style", transfo.settings.style); + + transfo.settings.height = $this.innerHeight(); + transfo.settings.width = $this.innerWidth(); + + var translatex = transform.match(/translateX\(([0-9.-]+)(%|px)\)/); + var translatey = transform.match(/translateY\(([0-9.-]+)(%|px)\)/); + transfo.settings.translate = "%"; + + if (translatex && translatex[2] === "%") { + transfo.settings.translatexp = parseFloat(translatex[1]); + transfo.settings.translatex = transfo.settings.translatexp / 100 * transfo.settings.width; + } else { + transfo.settings.translatex = translatex ? parseFloat(translatex[1]) : 0; + } + if (translatey && translatey[2] === "%") { + transfo.settings.translateyp = parseFloat(translatey[1]); + transfo.settings.translatey = transfo.settings.translateyp / 100 * transfo.settings.height; + } else { + transfo.settings.translatey = translatey ? parseFloat(translatey[1]) : 0; + } + + transfo.settings.css = window.getComputedStyle($this[0], null); + transfo.settings.pos = $this.offset(); + + transfo.settings.rotationStep = 5; + transfo.settings.hide = false; + transfo.settings.callback = function () {}; + } + + function _bind ($this, transfo) { + function mousedown (event) { + _mouseDown($this, this, transfo, event); + $(document).on("mousemove", mousemove).on("mouseup", mouseup); + } + function mousemove (event) { + _mouseMove($this, this, transfo, event); + } + function mouseup (event) { + _mouseUp($this, this, transfo, event); + $(document).off("mousemove", mousemove).off("mouseup", mouseup); + } + + transfo.$markup.off().on("mousedown", mousedown); + transfo.$markup.find(">:not(.transfo-scaler-mc)").off().on("mousedown", mousedown); + } + + function _mouseDown($this, div, transfo, event) { + event.preventDefault(); + if (transfo.active || event.which !== 1) return; + + var type = "position", $e = $(div); + if ($e.hasClass("transfo-rotator")) type = "rotator"; + else if ($e.hasClass("transfo-scaler-tl")) type = "tl"; + else if ($e.hasClass("transfo-scaler-tr")) type = "tr"; + else if ($e.hasClass("transfo-scaler-br")) type = "br"; + else if ($e.hasClass("transfo-scaler-bl")) type = "bl"; + else if ($e.hasClass("transfo-scaler-tc")) type = "tc"; + else if ($e.hasClass("transfo-scaler-bc")) type = "bc"; + else if ($e.hasClass("transfo-scaler-ml")) type = "ml"; + else if ($e.hasClass("transfo-scaler-mr")) type = "mr"; + + transfo.active = { + "type": type, + "scalex": transfo.settings.scalex, + "scaley": transfo.settings.scaley, + "pageX": event.pageX, + "pageY": event.pageY, + "center": transfo.$center.offset(), + }; + } + function _mouseUp($this, div, transfo, event) { + transfo.active = null; + } + + function _mouseMove($this, div, transfo, event) { + event.preventDefault(); + if (!transfo.active) return; + var settings = transfo.settings; + var center = transfo.active.center; + var cdx = center.left - event.pageX; + var cdy = center.top - event.pageY; + + if (transfo.active.type == "rotator") { + var ang, dang = Math.atan((settings.width * settings.scalex) / (settings.height * settings.scaley)) / rad; + + if (cdy) ang = Math.atan(- cdx / cdy) / rad; + else ang = 0; + if (event.pageY >= center.top && event.pageX >= center.left) ang += 180; + else if (event.pageY >= center.top && event.pageX < center.left) ang += 180; + else if (event.pageY < center.top && event.pageX < center.left) ang += 360; + + ang -= dang; + if (settings.scaley < 0 && settings.scalex < 0) ang += 180; + + if (!event.ctrlKey) { + settings.angle = Math.round(ang / transfo.settings.rotationStep) * transfo.settings.rotationStep; + } else { + settings.angle = ang; + } + + // reset position : don't move center + _targetCss($this, transfo); + var new_center = transfo.$center.offset(); + var x = center.left - new_center.left; + var y = center.top - new_center.top; + var angle = ang * rad; + settings.translatex += x*Math.cos(angle) - y*Math.sin(-angle); + settings.translatey += - x*Math.sin(angle) + y*Math.cos(-angle); + } + else if (transfo.active.type == "position") { + var angle = settings.angle * rad; + var x = event.pageX - transfo.active.pageX; + var y = event.pageY - transfo.active.pageY; + transfo.active.pageX = event.pageX; + transfo.active.pageY = event.pageY; + var dx = x*Math.cos(angle) - y*Math.sin(-angle); + var dy = - x*Math.sin(angle) + y*Math.cos(-angle); + + settings.translatex += dx; + settings.translatey += dy; + } + else if (transfo.active.type.length === 2) { + var angle = settings.angle * rad; + var dx = cdx*Math.cos(angle) - cdy*Math.sin(-angle); + var dy = - cdx*Math.sin(angle) + cdy*Math.cos(-angle); + if (transfo.active.type.indexOf("t") != -1) { + settings.scaley = dy / (settings.height/2); + } + if (transfo.active.type.indexOf("b") != -1) { + settings.scaley = - dy / (settings.height/2); + } + if (transfo.active.type.indexOf("l") != -1) { + settings.scalex = dx / (settings.width/2); + } + if (transfo.active.type.indexOf("r") != -1) { + settings.scalex = - dx / (settings.width/2); + } + if (settings.scaley > 0 && settings.scaley < 0.05) settings.scaley = 0.05; + if (settings.scalex > 0 && settings.scalex < 0.05) settings.scalex = 0.05; + if (settings.scaley < 0 && settings.scaley > -0.05) settings.scaley = -0.05; + if (settings.scalex < 0 && settings.scalex > -0.05) settings.scalex = -0.05; + + if (event.shiftKey && + (transfo.active.type === "tl" || transfo.active.type === "bl" || + transfo.active.type === "tr" || transfo.active.type === "br")) { + settings.scaley = settings.scalex; + } + } + + settings.angle = Math.round(settings.angle); + settings.translatex = Math.round(settings.translatex); + settings.translatey = Math.round(settings.translatey); + settings.scalex = Math.round(settings.scalex*100)/100; + settings.scaley = Math.round(settings.scaley*100)/100; + + _targetCss($this, transfo); + return false; + } + + function _setCss($this, css, settings) { + var transform = ""; + var trans = false; + if (settings.angle !== 0) { + trans = true; + transform += " rotate("+settings.angle+"deg) "; + } + if (settings.translatex) { + trans = true; + transform += " translateX("+(settings.translate === "%" ? settings.translatexp+"%" : settings.translatex+"px")+") "; + } + if (settings.translatey) { + trans = true; + transform += " translateY("+(settings.translate === "%" ? settings.translateyp+"%" : settings.translatey+"px")+") "; + } + if (settings.scalex != 1) { + trans = true; + transform += " scaleX("+settings.scalex+") "; + } + if (settings.scaley != 1){ + trans = true; + transform += " scaleY("+settings.scaley+") "; + } + + if (trans) { + css += ";" + /* Safari */ + css += "-webkit-transform:" + transform + ";" + /* Firefox */ + + "-moz-transform:" + transform + ";" + /* IE */ + + "-ms-transform:" + transform + ";" + /* Opera */ + + "-o-transform:" + transform + ";" + /* Other */ + + "transform:" + transform + ";"; + } + + css = css.replace(/(\s*;)+/g, ';').replace(/^\s*;|;\s*$/g, ''); + + $this.attr("style", css); + } + + function _targetCss ($this, transfo) { + var settings = transfo.settings; + var width = parseFloat(settings.css.width); + var height = parseFloat(settings.css.height); + settings.translatexp = Math.round(settings.translatex/width*1000)/10; + settings.translateyp = Math.round(settings.translatey/height*1000)/10; + + _setCss($this, settings.style, settings); + + _setCss(transfo.$markup, + "position: absolute;" + + "top:" + settings.pos.top + "px;" + + "left:" + settings.pos.left + "px;" + + "width:" + width + "px;" + + "height:" + height + "px;" + + "cursor: move;", + settings); + transfo.$markup.find(">").css("transform", "scaleX("+(1/settings.scalex)+") scaleY("+(1/settings.scaley)+")"); + + _showHide($this, transfo); + + transfo.settings.callback.call($this[0], $this); + } + + function _showHide ($this, transfo) { + transfo.$markup.css("z-index", transfo.settings.hide ? -1 : 1000); + if (transfo.settings.hide) { + transfo.$markup.find(">").hide(); + transfo.$markup.find(".transfo-scaler-mc").show(); + } else { + transfo.$markup.find(">").show(); + } + } + + function _destroy ($this) { + $this.data('transfo').$markup.remove(); + $this.removeData('transfo'); + } + + function _reset ($this) { + var transfo = $this.data('transfo'); + _destroy($this); + $this.transfo(transfo.settings); + } + +})(jQuery); diff --git a/addons/website/static/src/js/website.editor.js b/addons/website/static/src/js/website.editor.js index c965c5ef834..365b8cf46ea 100644 --- a/addons/website/static/src/js/website.editor.js +++ b/addons/website/static/src/js/website.editor.js @@ -64,7 +64,7 @@ return new website.editor.RTELinkDialog(editor).appendTo(document.body); } function image_dialog(editor, image) { - return new website.editor.RTEImageDialog(editor, image).appendTo(document.body); + return new website.editor.MediaDialog(editor, image).appendTo(document.body); } // only enable editors manually @@ -80,14 +80,19 @@ website.init_editor = function () { CKEDITOR.plugins.add('customdialogs', { -// requires: 'link,image', + // requires: 'link,image', init: function (editor) { editor.on('doubleclick', function (evt) { var element = evt.data.element; - if (element.is('img') && is_editable_node(element)) { + if ((element.is('img') || element.$.className.indexOf(' fa-') != -1) && is_editable_node(element)) { image_dialog(editor, element); return; } + var parent = new CKEDITOR.dom.element(element.$.parentNode); + if (parent.$.className.indexOf('media_iframe_video') != -1 && is_editable_node(parent)) { + image_dialog(editor, parent); + return; + } element = get_selected_link(editor) || evt.data.element; if (!(element.is('a') && is_editable_node(element))) { @@ -109,7 +114,7 @@ context: 'a', }); //noinspection JSValidateTypes - editor.addCommand('image', { + editor.addCommand('cimage', { exec: function (editor) { image_dialog(editor); return true; @@ -126,7 +131,7 @@ }); editor.ui.addButton('Image', { label: 'Image', - command: 'image', + command: 'cimage', toolbar: 'insert,10', }); @@ -400,7 +405,7 @@ init: function () { this.on('edit', function () { - new website.editor.FontIconsDialog(editor, this.element.$) + new website.editor.MediaDialog(editor, this.element) .appendTo(document.body); }); }, @@ -629,22 +634,48 @@ }, /** - * Creates a "hover" button for image and link edition + * Creates a "hover" button for link edition * - * @param {String} label the button's label * @param {Function} editfn edition function, called when clicking the button - * @param {String} [classes] additional classes to set on the button * @returns {jQuery} */ - make_hover_button: function (label, editfn, classes) { - return $(openerp.qweb.render('website.editor.hoverbutton', { - label: label, - classes: classes, - })).hide().appendTo(document.body).click(function (e) { + make_hover_button_link: function (editfn) { + return $(openerp.qweb.render('website.editor.hoverbutton.link', {})) + .hide() + .click(function (e) { + e.preventDefault(); + e.stopPropagation(); + editfn.call(this, e); + }) + .appendTo(document.body); + }, + + /** + * Creates a "hover" button for image + * + * @param {Function} editfn edition function, called when clicking the button + * @param {Function} stylefn edition style function, called when clicking the button + * @returns {jQuery} + */ + make_hover_button_image: function (editfn, stylefn) { + var $div = $(openerp.qweb.render('website.editor.hoverbutton.media', {})) + .hide() + .appendTo(document.body); + + $div.find('[data-toggle="dropdown"]').dropdown(); + $div.find(".hover-edition-button").click(function (e) { e.preventDefault(); e.stopPropagation(); editfn.call(this, e); }); + if (stylefn) { + $div.find(".hover-style-button").click(function (e) { + e.preventDefault(); + e.stopPropagation(); + stylefn.call(this, e); + }); + } + return $div; }, /** * For UI clarity, during RTE edition when the user hovers links and @@ -653,23 +684,18 @@ */ setup_hover_buttons: function () { var editor = this.rte.editor; - var $link_button = this.make_hover_button(_t("Change"), function () { + var $link_button = this.make_hover_button_link(function () { var sel = new CKEDITOR.dom.element(previous); editor.getSelection().selectElement(sel); if(sel.hasClass('fa')) { - new website.editor.FontIconsDialog(editor, previous) + new website.editor.MediaDialog(editor, previous) .appendTo(document.body); } else if (previous.tagName.toUpperCase() === 'A') { link_dialog(editor); } $link_button.hide(); previous = null; - }, 'btn-xs'); - var $image_button = this.make_hover_button(_t("Change"), function () { - image_dialog(editor, new CKEDITOR.dom.element(previous)); - $image_button.hide(); - previous = null; - }, 'btn-sm'); + }); function is_icons_widget(element) { var w = editor.widgets.getByElement(element); @@ -681,7 +707,7 @@ // -ish, because when moving to the button itself ``previous`` is // still set to the element having triggered showing the button. var previous; - $(editor.element.$).on('mouseover', 'a, img, .fa', function () { + $(editor.element.$).on('mouseover', 'a', function () { // Back from edit button -> ignore if (previous && previous === this) { return; } @@ -700,34 +726,19 @@ previous = this; var $selected = $(this); var position = $selected.offset(); - if ($selected.is('img')) { - $link_button.hide(); - // center button on image - $image_button.show().offset({ - top: $selected.outerHeight() / 2 - + position.top - - $image_button.outerHeight() / 2, - left: $selected.outerWidth() / 2 - + position.left - - $image_button.outerWidth() / 2, - }); - } else { - $image_button.hide(); - // put button below link, horizontally centered - $link_button.show().offset({ - top: $selected.outerHeight() - + position.top, - left: $selected.outerWidth() / 2 - + position.left - - $link_button.outerWidth() / 2 - }) - } + $link_button.show().offset({ + top: $selected.outerHeight() + + position.top, + left: $selected.outerWidth() / 2 + + position.left + - $link_button.outerWidth() / 2 + }) }).on('mouseleave', 'a, img, .fa', function (e) { var current = document.elementFromPoint(e.clientX, e.clientY); - if (current === $link_button[0] || current === $image_button[0]) { + if (current === $link_button[0] || $(current).parent()[0] === $link_button[0]) { return; } - $image_button.add($link_button).hide(); + $link_button.hide(); previous = null; }); } @@ -1041,6 +1052,7 @@ }, save: function () { this.close(); + this.trigger("saved"); }, cancel: function () { }, @@ -1290,6 +1302,128 @@ }, }); + website.editor.Media = openerp.Widget.extend({ + init: function (parent, editor, media) { + this._super(); + this.parent = parent; + this.editor = editor; + this.media = media; + }, + start: function () { + this.$preview = this.$('.preview-container').detach(); + return this._super(); + }, + search: function (needle) { + }, + save: function () { + }, + clear: function () { + }, + cancel: function () { + }, + close: function () { + }, + }); + website.editor.MediaDialog = website.editor.Dialog.extend({ + template: 'website.editor.dialog.media', + events : _.extend({}, website.editor.Dialog.prototype.events, { + 'input input#icon-search': 'search', + }), + + init: function (editor, media) { + this._super(editor); + this.editor = editor; + this.page = 0; + this.media = media; + }, + start: function () { + var self = this; + + this.imageDialog = new website.editor.RTEImageDialog(this, this.editor, this.media); + this.imageDialog.appendTo(this.$("#editor-media-image")); + this.iconDialog = new website.editor.FontIconsDialog(this, this.editor, this.media); + this.iconDialog.appendTo(this.$("#editor-media-icon")); + this.videoDialog = new website.editor.VideoDialog(this, this.editor, this.media); + this.videoDialog.appendTo(this.$("#editor-media-video")); + + this.active = this.imageDialog; + + $('a[data-toggle="tab"]').on('shown.bs.tab', function (event) { + if ($(event.target).is('[href="#editor-media-image"]')) { + self.active = self.imageDialog; + self.$('li.search, li.previous, li.next').removeClass("hidden"); + } else if ($(event.target).is('[href="#editor-media-icon"]')) { + self.active = self.iconDialog; + self.$('li.search, li.previous, li.next').removeClass("hidden"); + self.$('.nav-tabs li.previous, .nav-tabs li.next').addClass("hidden"); + } else if ($(event.target).is('[href="#editor-media-video"]')) { + self.active = self.videoDialog; + self.$('.nav-tabs li.search').addClass("hidden"); + } + }); + + if (this.media) { + if (this.media.$.nodeName === "IMG") { + this.$('[href="#editor-media-image"]').tab('show'); + } else if (this.media.$.className.match(/(^|\s)media_iframe_video($|\s)/)) { + this.$('[href="#editor-media-video"]').tab('show'); + } else if (this.media.$.className.match(/(^|\s)fa($|\s)/)) { + this.$('[href="#editor-media-icon"]').tab('show'); + } + + if ($(this.media.$).parent().data("oe-field") === "image") { + this.$('[href="#editor-media-video"], [href="#editor-media-icon"]').addClass('hidden'); + } + } + + return this._super(); + }, + save: function () { + var self = this; + if (self.media) { + this.media.$.innerHTML = ""; + if (this.active !== this.imageDialog) { + this.imageDialog.clear(); + } + if (this.active !== this.iconDialog) { + this.iconDialog.clear(); + } + if (this.active !== this.videoDialog) { + this.videoDialog.clear(); + } + } else { + var selection = this.editor.getSelection(); + var range = selection.getRanges(true)[0]; + this.media = new CKEDITOR.dom.element("img"); + range.insertNode(this.media); + range.selectNodeContents(this.media); + this.active.media = this.media; + } + + var $el = $(self.active.media.$); + + this.active.save(); + + this.media.$.className = this.media.$.className.replace(/\s+/g, ' '); + + setTimeout(function () { + $el.trigger("saved", self.active.media.$); + $(document.body).trigger("media-saved", [$el[0], self.active.media.$]); + },0); + + this._super(); + }, + searchTimer: null, + search: function () { + var self = this; + var needle = this.$("input#icon-search").val(); + clearTimeout(this.searchTimer); + this.searchTimer = setTimeout(function () { + self.active.search(needle || ""); + },250); + } + }); + /** * ImageDialog widget. Lets users change an image, including uploading a * new image in OpenERP or selecting the image style (if supported by @@ -1307,73 +1441,118 @@ * selected by the users (or possibly the ones * originally passed in) */ - website.editor.ImageDialog = website.editor.Dialog.extend({ + var IMAGES_PER_ROW = 6; + var IMAGES_ROWS = 2; + website.editor.ImageDialog = website.editor.Media.extend({ template: 'website.editor.dialog.image', events: _.extend({}, website.editor.Dialog.prototype.events, { - 'change .url-source': function (e) { this.changed($(e.target)); }, + 'change .url-source': function (e) { + this.changed($(e.target)); + }, 'click button.filepicker': function () { this.$('input[type=file]').click(); }, 'change input[type=file]': 'file_selection', - 'change input.url': 'preview_image', - 'click a[href=#existing]': 'browse_existing', - 'change select.image-style': 'preview_image', + 'submit form': 'form_submit', + 'change input.url': "change_input", + 'keyup input.url': "change_input", + //'change select.image-style': 'preview_image', + 'click .existing-attachments img': 'select_existing', + 'click .existing-attachment-remove': 'try_remove', }), + init: function (parent, editor, media) { + this.page = 0; + this._super(parent, editor, media); + }, start: function () { - this.$('button.wait').text("Uploading…"); - var $options = this.$('.image-style').children(); - this.image_styles = $options.map(function () { return this.value; }).get(); + var self = this; + var res = this._super(); - var o = { url: null, style: null, }; + var o = { url: null }; // avoid typos, prevent addition of new properties to the object Object.preventExtensions(o); this.trigger('start', o); - if (o.url) { - if (o.style) { - this.$('.image-style').val(o.style); + this.parent.$(".pager > li").click(function (e) { + e.preventDefault(); + var $target = $(e.currentTarget); + if ($target.hasClass('disabled')) { + return; } - this.set_image(o.url); - } + self.page += $target.hasClass('previous') ? -1 : 1; + self.display_attachments(); + }); - return this._super(); + this.set_image(o.url); + + return res; }, save: function () { + if (!this.link) { + this.link = this.$(".existing-attachments img:first").attr('src'); + } this.trigger('save', { - url: this.$('input.url').val(), - style: this.$('.image-style').val(), + url: this.link }); + this.media.renameNode("img"); + this.media.$.attributes.src = this.link; return this._super(); }, + clear: function () { + this.media.$.className = this.media.$.className.replace(/(^|\s)(img(\s|$)|img-[^\s]*)/g, ' '); + }, cancel: function () { this.trigger('cancel'); }, - /** - * Sets the provided image url as the dialog's value-to-save and - * refreshes the preview element to use it. - */ - set_image: function (url, error) { - this.$('input.url').val( - error ? '' : url); - this.$('input.url').val(url); - this.preview_image(); + change_input: function (e) { + var $input = $(e.target); + var $button = $input.parent().find("button"); + if ($input.val() === "") { + $button.addClass("btn-default").removeClass("btn-primary"); + } else { + $button.removeClass("btn-default").addClass("btn-primary"); + } }, - file_selection: function () { - this.$el.addClass('nosave'); - this.$('form').removeClass('has-error').find('.help-block').empty(); - this.$('button.filepicker').removeClass('btn-danger btn-success'); + search: function (needle) { + var self = this; + this.fetch_existing(needle).then(function () { + self.selected_existing(self.$('input.url').val()); + }); + }, + + set_image: function (url, error) { + var self = this; + if (url) this.link = url; + this.$('input.url').val(''); + this.fetch_existing().then(function () { + self.selected_existing(url); + }); + }, + form_submit: function (event) { var self = this; + var $form = this.$('form[action="/website/attach"]'); + if (!$form.find('input[name="upload"]').val().length) { + var url = $form.find('input[name="url"]').val(); + if (this.selected_existing(url).size()) { + event.preventDefault(); + return false; + } + } var callback = _.uniqueId('func_'); this.$('input[name=func]').val(callback); - window[callback] = function (url, error) { delete window[callback]; self.file_selected(url, error); }; + }, + file_selection: function () { + this.$el.addClass('nosave'); + this.$('form').removeClass('has-error').find('.help-block').empty(); + this.$('button.filepicker').removeClass('btn-danger btn-success'); this.$('form').submit(); }, file_selected: function(url, error) { @@ -1387,125 +1566,27 @@ $button.addClass('btn-danger'); } this.set_image(url, error); + // auto save and close popup + this.parent.save(); }, - preview_image: function () { - var loaded = function () { - this.$el.removeClass('nosave'); - }.bind(this); - var image = this.$('input.url').val(); - if (!image) { loaded(); return; } - - var $img = this.$('img.image-preview') - .attr('src', image) - .removeClass(this.image_styles.join(' ')) - .addClass(this.$('select.image-style').val()); - if ($img.prop('complete')) { - loaded(); - } else { - $img.load(loaded) + fetch_existing: function (needle) { + var domain = [['res_model', '=', 'ir.ui.view'], '|', + ['mimetype', '=', false], ['mimetype', '=like', 'image/%']]; + if (needle && needle.length) { + domain.push('|', ['datas_fname', 'ilike', needle], ['name', 'ilike', needle]); } - }, - browse_existing: function (e) { - e.preventDefault(); - this.$('form').removeClass('has-error').find('.help-block').empty(); - this.$('button.filepicker').removeClass('btn-danger btn-success'); - new website.editor.ExistingImageDialog(this).appendTo(document.body); - }, - }); - website.editor.RTEImageDialog = website.editor.ImageDialog.extend({ - init: function (editor, image) { - this._super(editor); - - this.element = image; - - this.on('start', this, this.proxy('started')); - this.on('save', this, this.proxy('saved')); - }, - started: function (holder) { - if (!this.element) { - var selection = this.editor.getSelection(); - this.element = selection && selection.getSelectedElement(); - } - - var el = this.element; - if (!el || !el.is('img')) { - return; - } - _(this.image_styles).each(function (style) { - if (el.hasClass(style)) { - holder.style = style; - } - }); - holder.url = el.getAttribute('src'); - }, - saved: function (data) { - var element, editor = this.editor; - if (!(element = this.element)) { - element = editor.document.createElement('img'); - element.addClass('img'); - element.addClass('img-responsive'); - // focus event handler interactions between bootstrap (modal) - // and ckeditor (RTE) lead to blowing the stack in Safari and - // Chrome (but not FF) when this is done synchronously => - // defer insertion so modal has been hidden & destroyed before - // it happens - setTimeout(function () { - editor.insertElement(element); - }, 0); - } - - var style = data.style; - element.setAttribute('src', data.url); - element.removeAttribute('data-cke-saved-src'); - $(element.$).removeClass(this.image_styles.join(' ')); - if (style) { element.addClass(style); } - }, - }); - - var IMAGES_PER_ROW = 6; - var IMAGES_ROWS = 4; - website.editor.ExistingImageDialog = website.editor.Dialog.extend({ - template: 'website.editor.dialog.image.existing', - events: _.extend({}, website.editor.Dialog.prototype.events, { - 'click .existing-attachments img': 'select_existing', - 'click .pager > li': function (e) { - e.preventDefault(); - var $target = $(e.currentTarget); - if ($target.hasClass('disabled')) { - return; - } - this.page += $target.hasClass('previous') ? -1 : 1; - this.display_attachments(); - }, - 'click .existing-attachment-remove': 'try_remove', - }), - init: function (parent) { - this.image = null; - this.page = 0; - this.parent = parent; - this._super(parent.editor); - }, - - start: function () { - return $.when( - this._super(), - this.fetch_existing().then(this.proxy('fetched_existing'))); - }, - - fetch_existing: function () { return openerp.jsonRpc('/web/dataset/call_kw', 'call', { model: 'ir.attachment', method: 'search_read', args: [], kwargs: { fields: ['name', 'website_url'], - domain: [['res_model', '=', 'ir.ui.view'], '|', - ['mimetype', '=', false], ['mimetype', '=like', 'image/%']], + domain: domain, order: 'id desc', context: website.get_context(), } - }); + }).then(this.proxy('fetched_existing')); }, fetched_existing: function (records) { this.records = records; @@ -1528,24 +1609,33 @@ this.$('.existing-attachments').replaceWith( openerp.qweb.render( 'website.editor.dialog.image.existing.content', {rows: rows})); - this.$('.pager') + this.parent.$('.pager') .find('li.previous').toggleClass('disabled', (from === 0)).end() .find('li.next').toggleClass('disabled', (from + per_screen >= records.length)); - }, select_existing: function (e) { var link = $(e.currentTarget).attr('src'); - if (link) { - this.parent.set_image(link); - } - this.close() + this.link = link; + this.selected_existing(link); + }, + selected_existing: function (link) { + this.$('.existing-attachment-cell.media_selected').removeClass("media_selected"); + var $select = this.$('.existing-attachment-cell img').filter(function () { + return $(this).attr("src") == link; + }).first(); + $select.parent().addClass("media_selected"); + return $select; }, try_remove: function (e) { var $help_block = this.$('.help-block').empty(); var self = this; - var id = parseInt($(e.target).data('id'), 10); + var $a = $(e.target); + var id = parseInt($a.data('id'), 10); var attachment = _.findWhere(this.records, {id: id}); + var $both = $a.parent().children(); + + $both.css({borderWidth: "5px", borderColor: "#f00"}); return openerp.jsonRpc('/web/dataset/call_kw', 'call', { model: 'ir.attachment', @@ -1561,6 +1651,7 @@ self.display_attachments(); return; } + $both.css({borderWidth: "", borderColor: ""}); $help_block.replaceWith(openerp.qweb.render( 'website.editor.dialog.image.existing.error', { views: prevented[id] @@ -1570,6 +1661,48 @@ }, }); + website.editor.RTEImageDialog = website.editor.ImageDialog.extend({ + init: function (parent, editor, media) { + this._super(parent, editor, media); + + this.on('start', this, this.proxy('started')); + this.on('save', this, this.proxy('saved')); + }, + started: function (holder) { + if (!this.media) { + var selection = this.editor.getSelection(); + this.media = selection && selection.getSelectedElement(); + } + + var el = this.media; + if (!el || !el.is('img')) { + return; + } + holder.url = el.getAttribute('src'); + }, + saved: function (data) { + var element, editor = this.editor; + if (!(element = this.media)) { + element = editor.document.createElement('img'); + element.addClass('img'); + element.addClass('img-responsive'); + // focus event handler interactions between bootstrap (modal) + // and ckeditor (RTE) lead to blowing the stack in Safari and + // Chrome (but not FF) when this is done synchronously => + // defer insertion so modal has been hidden & destroyed before + // it happens + setTimeout(function () { + editor.insertElement(element); + }, 0); + } + + var style = data.style; + element.setAttribute('src', data.url); + element.removeAttribute('data-cke-saved-src'); + if (style) { element.addClass(style); } + }, + }); + function get_selected_link(editor) { var sel = editor.getSelection(), el = sel.getSelectedElement(); @@ -1581,7 +1714,7 @@ range.shrink(CKEDITOR.SHRINK_TEXT); var commonAncestor = range.getCommonAncestor(); var viewRoot = editor.elementPath(commonAncestor).contains(function (element) { - return element.data('oe-model') === 'ir.ui.view' + return element.data('oe-model') === 'ir.ui.view'; }); if (!viewRoot) { return null; } // if viewRoot is the first link, don't edit it. @@ -1589,7 +1722,7 @@ .contains('a', true); } - website.editor.FontIconsDialog = website.editor.Dialog.extend({ + website.editor.FontIconsDialog = website.editor.Media.extend({ template: 'website.editor.dialog.font-icons', events : _.extend({}, website.editor.Dialog.prototype.events, { change: 'update_preview', @@ -1607,20 +1740,6 @@ this.$('#fa-size').val(e.target.getAttribute('data-size')); this.update_preview(); }, - 'input input#icon-search': function () { - var needle = this.$('#icon-search').val(); - var icons = this.icons; - if (needle) { - icons = _(icons).filter(function (icon) { - return icon.id.substring(3).indexOf(needle) !== -1; - }); - } - - this.$('div.font-icons-icons').html( - openerp.qweb.render( - 'website.editor.dialog.font-icons.icons', - {icons: icons})); - }, }), // List of FontAwesome icons in 4.0.3, extracted from the cheatsheet. @@ -1630,10 +1749,6 @@ // where we still need to implement ``initSelection``) // TODO: add id/name to the text in order to allow FAYT selection of icons? icons: [{"text": "\uf000", "id": "fa-glass"}, {"text": "\uf001", "id": "fa-music"}, {"text": "\uf002", "id": "fa-search"}, {"text": "\uf003", "id": "fa-envelope-o"}, {"text": "\uf004", "id": "fa-heart"}, {"text": "\uf005", "id": "fa-star"}, {"text": "\uf006", "id": "fa-star-o"}, {"text": "\uf007", "id": "fa-user"}, {"text": "\uf008", "id": "fa-film"}, {"text": "\uf009", "id": "fa-th-large"}, {"text": "\uf00a", "id": "fa-th"}, {"text": "\uf00b", "id": "fa-th-list"}, {"text": "\uf00c", "id": "fa-check"}, {"text": "\uf00d", "id": "fa-times"}, {"text": "\uf00e", "id": "fa-search-plus"}, {"text": "\uf010", "id": "fa-search-minus"}, {"text": "\uf011", "id": "fa-power-off"}, {"text": "\uf012", "id": "fa-signal"}, {"text": "\uf013", "id": "fa-cog"}, {"text": "\uf014", "id": "fa-trash-o"}, {"text": "\uf015", "id": "fa-home"}, {"text": "\uf016", "id": "fa-file-o"}, {"text": "\uf017", "id": "fa-clock-o"}, {"text": "\uf018", "id": "fa-road"}, {"text": "\uf019", "id": "fa-download"}, {"text": "\uf01a", "id": "fa-arrow-circle-o-down"}, {"text": "\uf01b", "id": "fa-arrow-circle-o-up"}, {"text": "\uf01c", "id": "fa-inbox"}, {"text": "\uf01d", "id": "fa-play-circle-o"}, {"text": "\uf01e", "id": "fa-repeat"}, {"text": "\uf021", "id": "fa-refresh"}, {"text": "\uf022", "id": "fa-list-alt"}, {"text": "\uf023", "id": "fa-lock"}, {"text": "\uf024", "id": "fa-flag"}, {"text": "\uf025", "id": "fa-headphones"}, {"text": "\uf026", "id": "fa-volume-off"}, {"text": "\uf027", "id": "fa-volume-down"}, {"text": "\uf028", "id": "fa-volume-up"}, {"text": "\uf029", "id": "fa-qrcode"}, {"text": "\uf02a", "id": "fa-barcode"}, {"text": "\uf02b", "id": "fa-tag"}, {"text": "\uf02c", "id": "fa-tags"}, {"text": "\uf02d", "id": "fa-book"}, {"text": "\uf02e", "id": "fa-bookmark"}, {"text": "\uf02f", "id": "fa-print"}, {"text": "\uf030", "id": "fa-camera"}, {"text": "\uf031", "id": "fa-font"}, {"text": "\uf032", "id": "fa-bold"}, {"text": "\uf033", "id": "fa-italic"}, {"text": "\uf034", "id": "fa-text-height"}, {"text": "\uf035", "id": "fa-text-width"}, {"text": "\uf036", "id": "fa-align-left"}, {"text": "\uf037", "id": "fa-align-center"}, {"text": "\uf038", "id": "fa-align-right"}, {"text": "\uf039", "id": "fa-align-justify"}, {"text": "\uf03a", "id": "fa-list"}, {"text": "\uf03b", "id": "fa-outdent"}, {"text": "\uf03c", "id": "fa-indent"}, {"text": "\uf03d", "id": "fa-video-camera"}, {"text": "\uf03e", "id": "fa-picture-o"}, {"text": "\uf040", "id": "fa-pencil"}, {"text": "\uf041", "id": "fa-map-marker"}, {"text": "\uf042", "id": "fa-adjust"}, {"text": "\uf043", "id": "fa-tint"}, {"text": "\uf044", "id": "fa-pencil-square-o"}, {"text": "\uf045", "id": "fa-share-square-o"}, {"text": "\uf046", "id": "fa-check-square-o"}, {"text": "\uf047", "id": "fa-arrows"}, {"text": "\uf048", "id": "fa-step-backward"}, {"text": "\uf049", "id": "fa-fast-backward"}, {"text": "\uf04a", "id": "fa-backward"}, {"text": "\uf04b", "id": "fa-play"}, {"text": "\uf04c", "id": "fa-pause"}, {"text": "\uf04d", "id": "fa-stop"}, {"text": "\uf04e", "id": "fa-forward"}, {"text": "\uf050", "id": "fa-fast-forward"}, {"text": "\uf051", "id": "fa-step-forward"}, {"text": "\uf052", "id": "fa-eject"}, {"text": "\uf053", "id": "fa-chevron-left"}, {"text": "\uf054", "id": "fa-chevron-right"}, {"text": "\uf055", "id": "fa-plus-circle"}, {"text": "\uf056", "id": "fa-minus-circle"}, {"text": "\uf057", "id": "fa-times-circle"}, {"text": "\uf058", "id": "fa-check-circle"}, {"text": "\uf059", "id": "fa-question-circle"}, {"text": "\uf05a", "id": "fa-info-circle"}, {"text": "\uf05b", "id": "fa-crosshairs"}, {"text": "\uf05c", "id": "fa-times-circle-o"}, {"text": "\uf05d", "id": "fa-check-circle-o"}, {"text": "\uf05e", "id": "fa-ban"}, {"text": "\uf060", "id": "fa-arrow-left"}, {"text": "\uf061", "id": "fa-arrow-right"}, {"text": "\uf062", "id": "fa-arrow-up"}, {"text": "\uf063", "id": "fa-arrow-down"}, {"text": "\uf064", "id": "fa-share"}, {"text": "\uf065", "id": "fa-expand"}, {"text": "\uf066", "id": "fa-compress"}, {"text": "\uf067", "id": "fa-plus"}, {"text": "\uf068", "id": "fa-minus"}, {"text": "\uf069", "id": "fa-asterisk"}, {"text": "\uf06a", "id": "fa-exclamation-circle"}, {"text": "\uf06b", "id": "fa-gift"}, {"text": "\uf06c", "id": "fa-leaf"}, {"text": "\uf06d", "id": "fa-fire"}, {"text": "\uf06e", "id": "fa-eye"}, {"text": "\uf070", "id": "fa-eye-slash"}, {"text": "\uf071", "id": "fa-exclamation-triangle"}, {"text": "\uf072", "id": "fa-plane"}, {"text": "\uf073", "id": "fa-calendar"}, {"text": "\uf074", "id": "fa-random"}, {"text": "\uf075", "id": "fa-comment"}, {"text": "\uf076", "id": "fa-magnet"}, {"text": "\uf077", "id": "fa-chevron-up"}, {"text": "\uf078", "id": "fa-chevron-down"}, {"text": "\uf079", "id": "fa-retweet"}, {"text": "\uf07a", "id": "fa-shopping-cart"}, {"text": "\uf07b", "id": "fa-folder"}, {"text": "\uf07c", "id": "fa-folder-open"}, {"text": "\uf07d", "id": "fa-arrows-v"}, {"text": "\uf07e", "id": "fa-arrows-h"}, {"text": "\uf080", "id": "fa-bar-chart-o"}, {"text": "\uf081", "id": "fa-twitter-square"}, {"text": "\uf082", "id": "fa-facebook-square"}, {"text": "\uf083", "id": "fa-camera-retro"}, {"text": "\uf084", "id": "fa-key"}, {"text": "\uf085", "id": "fa-cogs"}, {"text": "\uf086", "id": "fa-comments"}, {"text": "\uf087", "id": "fa-thumbs-o-up"}, {"text": "\uf088", "id": "fa-thumbs-o-down"}, {"text": "\uf089", "id": "fa-star-half"}, {"text": "\uf08a", "id": "fa-heart-o"}, {"text": "\uf08b", "id": "fa-sign-out"}, {"text": "\uf08c", "id": "fa-linkedin-square"}, {"text": "\uf08d", "id": "fa-thumb-tack"}, {"text": "\uf08e", "id": "fa-external-link"}, {"text": "\uf090", "id": "fa-sign-in"}, {"text": "\uf091", "id": "fa-trophy"}, {"text": "\uf092", "id": "fa-github-square"}, {"text": "\uf093", "id": "fa-upload"}, {"text": "\uf094", "id": "fa-lemon-o"}, {"text": "\uf095", "id": "fa-phone"}, {"text": "\uf096", "id": "fa-square-o"}, {"text": "\uf097", "id": "fa-bookmark-o"}, {"text": "\uf098", "id": "fa-phone-square"}, {"text": "\uf099", "id": "fa-twitter"}, {"text": "\uf09a", "id": "fa-facebook"}, {"text": "\uf09b", "id": "fa-github"}, {"text": "\uf09c", "id": "fa-unlock"}, {"text": "\uf09d", "id": "fa-credit-card"}, {"text": "\uf09e", "id": "fa-rss"}, {"text": "\uf0a0", "id": "fa-hdd-o"}, {"text": "\uf0a1", "id": "fa-bullhorn"}, {"text": "\uf0f3", "id": "fa-bell"}, {"text": "\uf0a3", "id": "fa-certificate"}, {"text": "\uf0a4", "id": "fa-hand-o-right"}, {"text": "\uf0a5", "id": "fa-hand-o-left"}, {"text": "\uf0a6", "id": "fa-hand-o-up"}, {"text": "\uf0a7", "id": "fa-hand-o-down"}, {"text": "\uf0a8", "id": "fa-arrow-circle-left"}, {"text": "\uf0a9", "id": "fa-arrow-circle-right"}, {"text": "\uf0aa", "id": "fa-arrow-circle-up"}, {"text": "\uf0ab", "id": "fa-arrow-circle-down"}, {"text": "\uf0ac", "id": "fa-globe"}, {"text": "\uf0ad", "id": "fa-wrench"}, {"text": "\uf0ae", "id": "fa-tasks"}, {"text": "\uf0b0", "id": "fa-filter"}, {"text": "\uf0b1", "id": "fa-briefcase"}, {"text": "\uf0b2", "id": "fa-arrows-alt"}, {"text": "\uf0c0", "id": "fa-users"}, {"text": "\uf0c1", "id": "fa-link"}, {"text": "\uf0c2", "id": "fa-cloud"}, {"text": "\uf0c3", "id": "fa-flask"}, {"text": "\uf0c4", "id": "fa-scissors"}, {"text": "\uf0c5", "id": "fa-files-o"}, {"text": "\uf0c6", "id": "fa-paperclip"}, {"text": "\uf0c7", "id": "fa-floppy-o"}, {"text": "\uf0c8", "id": "fa-square"}, {"text": "\uf0c9", "id": "fa-bars"}, {"text": "\uf0ca", "id": "fa-list-ul"}, {"text": "\uf0cb", "id": "fa-list-ol"}, {"text": "\uf0cc", "id": "fa-strikethrough"}, {"text": "\uf0cd", "id": "fa-underline"}, {"text": "\uf0ce", "id": "fa-table"}, {"text": "\uf0d0", "id": "fa-magic"}, {"text": "\uf0d1", "id": "fa-truck"}, {"text": "\uf0d2", "id": "fa-pinterest"}, {"text": "\uf0d3", "id": "fa-pinterest-square"}, {"text": "\uf0d4", "id": "fa-google-plus-square"}, {"text": "\uf0d5", "id": "fa-google-plus"}, {"text": "\uf0d6", "id": "fa-money"}, {"text": "\uf0d7", "id": "fa-caret-down"}, {"text": "\uf0d8", "id": "fa-caret-up"}, {"text": "\uf0d9", "id": "fa-caret-left"}, {"text": "\uf0da", "id": "fa-caret-right"}, {"text": "\uf0db", "id": "fa-columns"}, {"text": "\uf0dc", "id": "fa-sort"}, {"text": "\uf0dd", "id": "fa-sort-asc"}, {"text": "\uf0de", "id": "fa-sort-desc"}, {"text": "\uf0e0", "id": "fa-envelope"}, {"text": "\uf0e1", "id": "fa-linkedin"}, {"text": "\uf0e2", "id": "fa-undo"}, {"text": "\uf0e3", "id": "fa-gavel"}, {"text": "\uf0e4", "id": "fa-tachometer"}, {"text": "\uf0e5", "id": "fa-comment-o"}, {"text": "\uf0e6", "id": "fa-comments-o"}, {"text": "\uf0e7", "id": "fa-bolt"}, {"text": "\uf0e8", "id": "fa-sitemap"}, {"text": "\uf0e9", "id": "fa-umbrella"}, {"text": "\uf0ea", "id": "fa-clipboard"}, {"text": "\uf0eb", "id": "fa-lightbulb-o"}, {"text": "\uf0ec", "id": "fa-exchange"}, {"text": "\uf0ed", "id": "fa-cloud-download"}, {"text": "\uf0ee", "id": "fa-cloud-upload"}, {"text": "\uf0f0", "id": "fa-user-md"}, {"text": "\uf0f1", "id": "fa-stethoscope"}, {"text": "\uf0f2", "id": "fa-suitcase"}, {"text": "\uf0a2", "id": "fa-bell-o"}, {"text": "\uf0f4", "id": "fa-coffee"}, {"text": "\uf0f5", "id": "fa-cutlery"}, {"text": "\uf0f6", "id": "fa-file-text-o"}, {"text": "\uf0f7", "id": "fa-building-o"}, {"text": "\uf0f8", "id": "fa-hospital-o"}, {"text": "\uf0f9", "id": "fa-ambulance"}, {"text": "\uf0fa", "id": "fa-medkit"}, {"text": "\uf0fb", "id": "fa-fighter-jet"}, {"text": "\uf0fc", "id": "fa-beer"}, {"text": "\uf0fd", "id": "fa-h-square"}, {"text": "\uf0fe", "id": "fa-plus-square"}, {"text": "\uf100", "id": "fa-angle-double-left"}, {"text": "\uf101", "id": "fa-angle-double-right"}, {"text": "\uf102", "id": "fa-angle-double-up"}, {"text": "\uf103", "id": "fa-angle-double-down"}, {"text": "\uf104", "id": "fa-angle-left"}, {"text": "\uf105", "id": "fa-angle-right"}, {"text": "\uf106", "id": "fa-angle-up"}, {"text": "\uf107", "id": "fa-angle-down"}, {"text": "\uf108", "id": "fa-desktop"}, {"text": "\uf109", "id": "fa-laptop"}, {"text": "\uf10a", "id": "fa-tablet"}, {"text": "\uf10b", "id": "fa-mobile"}, {"text": "\uf10c", "id": "fa-circle-o"}, {"text": "\uf10d", "id": "fa-quote-left"}, {"text": "\uf10e", "id": "fa-quote-right"}, {"text": "\uf110", "id": "fa-spinner"}, {"text": "\uf111", "id": "fa-circle"}, {"text": "\uf112", "id": "fa-reply"}, {"text": "\uf113", "id": "fa-github-alt"}, {"text": "\uf114", "id": "fa-folder-o"}, {"text": "\uf115", "id": "fa-folder-open-o"}, {"text": "\uf118", "id": "fa-smile-o"}, {"text": "\uf119", "id": "fa-frown-o"}, {"text": "\uf11a", "id": "fa-meh-o"}, {"text": "\uf11b", "id": "fa-gamepad"}, {"text": "\uf11c", "id": "fa-keyboard-o"}, {"text": "\uf11d", "id": "fa-flag-o"}, {"text": "\uf11e", "id": "fa-flag-checkered"}, {"text": "\uf120", "id": "fa-terminal"}, {"text": "\uf121", "id": "fa-code"}, {"text": "\uf122", "id": "fa-reply-all"}, {"text": "\uf122", "id": "fa-mail-reply-all"}, {"text": "\uf123", "id": "fa-star-half-o"}, {"text": "\uf124", "id": "fa-location-arrow"}, {"text": "\uf125", "id": "fa-crop"}, {"text": "\uf126", "id": "fa-code-fork"}, {"text": "\uf127", "id": "fa-chain-broken"}, {"text": "\uf128", "id": "fa-question"}, {"text": "\uf129", "id": "fa-info"}, {"text": "\uf12a", "id": "fa-exclamation"}, {"text": "\uf12b", "id": "fa-superscript"}, {"text": "\uf12c", "id": "fa-subscript"}, {"text": "\uf12d", "id": "fa-eraser"}, {"text": "\uf12e", "id": "fa-puzzle-piece"}, {"text": "\uf130", "id": "fa-microphone"}, {"text": "\uf131", "id": "fa-microphone-slash"}, {"text": "\uf132", "id": "fa-shield"}, {"text": "\uf133", "id": "fa-calendar-o"}, {"text": "\uf134", "id": "fa-fire-extinguisher"}, {"text": "\uf135", "id": "fa-rocket"}, {"text": "\uf136", "id": "fa-maxcdn"}, {"text": "\uf137", "id": "fa-chevron-circle-left"}, {"text": "\uf138", "id": "fa-chevron-circle-right"}, {"text": "\uf139", "id": "fa-chevron-circle-up"}, {"text": "\uf13a", "id": "fa-chevron-circle-down"}, {"text": "\uf13b", "id": "fa-html5"}, {"text": "\uf13c", "id": "fa-css3"}, {"text": "\uf13d", "id": "fa-anchor"}, {"text": "\uf13e", "id": "fa-unlock-alt"}, {"text": "\uf140", "id": "fa-bullseye"}, {"text": "\uf141", "id": "fa-ellipsis-h"}, {"text": "\uf142", "id": "fa-ellipsis-v"}, {"text": "\uf143", "id": "fa-rss-square"}, {"text": "\uf144", "id": "fa-play-circle"}, {"text": "\uf145", "id": "fa-ticket"}, {"text": "\uf146", "id": "fa-minus-square"}, {"text": "\uf147", "id": "fa-minus-square-o"}, {"text": "\uf148", "id": "fa-level-up"}, {"text": "\uf149", "id": "fa-level-down"}, {"text": "\uf14a", "id": "fa-check-square"}, {"text": "\uf14b", "id": "fa-pencil-square"}, {"text": "\uf14c", "id": "fa-external-link-square"}, {"text": "\uf14d", "id": "fa-share-square"}, {"text": "\uf14e", "id": "fa-compass"}, {"text": "\uf150", "id": "fa-caret-square-o-down"}, {"text": "\uf151", "id": "fa-caret-square-o-up"}, {"text": "\uf152", "id": "fa-caret-square-o-right"}, {"text": "\uf153", "id": "fa-eur"}, {"text": "\uf154", "id": "fa-gbp"}, {"text": "\uf155", "id": "fa-usd"}, {"text": "\uf156", "id": "fa-inr"}, {"text": "\uf157", "id": "fa-jpy"}, {"text": "\uf158", "id": "fa-rub"}, {"text": "\uf159", "id": "fa-krw"}, {"text": "\uf15a", "id": "fa-btc"}, {"text": "\uf15b", "id": "fa-file"}, {"text": "\uf15c", "id": "fa-file-text"}, {"text": "\uf15d", "id": "fa-sort-alpha-asc"}, {"text": "\uf15e", "id": "fa-sort-alpha-desc"}, {"text": "\uf160", "id": "fa-sort-amount-asc"}, {"text": "\uf161", "id": "fa-sort-amount-desc"}, {"text": "\uf162", "id": "fa-sort-numeric-asc"}, {"text": "\uf163", "id": "fa-sort-numeric-desc"}, {"text": "\uf164", "id": "fa-thumbs-up"}, {"text": "\uf165", "id": "fa-thumbs-down"}, {"text": "\uf166", "id": "fa-youtube-square"}, {"text": "\uf167", "id": "fa-youtube"}, {"text": "\uf168", "id": "fa-xing"}, {"text": "\uf169", "id": "fa-xing-square"}, {"text": "\uf16a", "id": "fa-youtube-play"}, {"text": "\uf16b", "id": "fa-dropbox"}, {"text": "\uf16c", "id": "fa-stack-overflow"}, {"text": "\uf16d", "id": "fa-instagram"}, {"text": "\uf16e", "id": "fa-flickr"}, {"text": "\uf170", "id": "fa-adn"}, {"text": "\uf171", "id": "fa-bitbucket"}, {"text": "\uf172", "id": "fa-bitbucket-square"}, {"text": "\uf173", "id": "fa-tumblr"}, {"text": "\uf174", "id": "fa-tumblr-square"}, {"text": "\uf175", "id": "fa-long-arrow-down"}, {"text": "\uf176", "id": "fa-long-arrow-up"}, {"text": "\uf177", "id": "fa-long-arrow-left"}, {"text": "\uf178", "id": "fa-long-arrow-right"}, {"text": "\uf179", "id": "fa-apple"}, {"text": "\uf17a", "id": "fa-windows"}, {"text": "\uf17b", "id": "fa-android"}, {"text": "\uf17c", "id": "fa-linux"}, {"text": "\uf17d", "id": "fa-dribbble"}, {"text": "\uf17e", "id": "fa-skype"}, {"text": "\uf180", "id": "fa-foursquare"}, {"text": "\uf181", "id": "fa-trello"}, {"text": "\uf182", "id": "fa-female"}, {"text": "\uf183", "id": "fa-male"}, {"text": "\uf184", "id": "fa-gittip"}, {"text": "\uf185", "id": "fa-sun-o"}, {"text": "\uf186", "id": "fa-moon-o"}, {"text": "\uf187", "id": "fa-archive"}, {"text": "\uf188", "id": "fa-bug"}, {"text": "\uf189", "id": "fa-vk"}, {"text": "\uf18a", "id": "fa-weibo"}, {"text": "\uf18b", "id": "fa-renren"}, {"text": "\uf18c", "id": "fa-pagelines"}, {"text": "\uf18d", "id": "fa-stack-exchange"}, {"text": "\uf18e", "id": "fa-arrow-circle-o-right"}, {"text": "\uf190", "id": "fa-arrow-circle-o-left"}, {"text": "\uf191", "id": "fa-caret-square-o-left"}, {"text": "\uf192", "id": "fa-dot-circle-o"}, {"text": "\uf193", "id": "fa-wheelchair"}, {"text": "\uf194", "id": "fa-vimeo-square"}, {"text": "\uf195", "id": "fa-try"}, {"text": "\uf196", "id": "fa-plus-square-o"}], - init: function (editor, element) { - this._super(editor); - this.element = element; - }, /** * Initializes select2: in Chrome and Safari, <select> font apparently * isn't customizable (?) and the fontawesome glyphs fail to appear. @@ -1641,17 +1756,33 @@ start: function () { return this._super().then(this.proxy('load_data')); }, + search: function (needle) { + var icons = this.icons; + if (needle) { + icons = _(icons).filter(function (icon) { + return icon.id.substring(3).indexOf(needle) !== -1; + }); + } + + this.$('div.font-icons-icons').html( + openerp.qweb.render( + 'website.editor.dialog.font-icons.icons', + {icons: icons})); + }, /** * Removes existing FontAwesome classes on the bound element, and sets * all the new ones if necessary. */ save: function () { - var classes = this.element.className.split(/\s+/); + var style = this.media.$.attributes.style ? this.media.$.attributes.style.textContent : ''; + var classes = (this.media.$.className||"").split(/\s+/); var non_fa_classes = _.reject(classes, function (cls) { return cls === 'fa' || /^fa-/.test(cls); }); var final_classes = non_fa_classes.concat(this.get_fa_classes()); - this.element.className = final_classes.join(' '); + this.media.$.className = final_classes.join(' '); + this.media.renameNode("span"); + this.media.$.attributes.style.textContent = style; this._super(); }, /** @@ -1662,7 +1793,7 @@ * which may not match the visual look of the element. */ load_data: function () { - var classes = this.element.className.split(/\s+/); + var classes = (this.media&&this.media.$.className||"").split(/\s+/); for (var i = 0; i < classes.length; i++) { var cls = classes[i]; switch(cls) { @@ -1701,7 +1832,9 @@ ]; }, update_preview: function () { + this.$preview.empty(); var $preview = this.$('#fa-preview').empty(); + var sizes = ['', 'fa-2x', 'fa-3x', 'fa-4x', 'fa-5x']; var classes = this.get_fa_classes(); var no_sizes = _.difference(classes, sizes).join(' '); @@ -1713,13 +1846,123 @@ .attr('data-size', size) .addClass(size) .addClass(no_sizes); - if ((size && _.contains(classes, size)) || (!size && !selected)) { + if ((size && _.contains(classes, size)) || (classes[2] === "" && !selected)) { + this.$preview.append($p.clone()); + this.$('#fa-size').val(size); $p.addClass('font-icons-selected'); selected = true; } $preview.prepend($p); } - } + }, + clear: function () { + this.media.$.className = this.media.$.className.replace(/(^|\s)(fa(\s|$)|fa-[^\s]*)/g, ' '); + }, + }); + + website.editor.VideoDialog = website.editor.Media.extend({ + template: 'website.editor.dialog.video', + events : _.extend({}, website.editor.Dialog.prototype.events, { + 'click input#urlvideo ~ button': 'get_video', + 'click input#embedvideo ~ button': 'get_embed_video', + 'change input#urlvideo': 'change_input', + 'keyup input#urlvideo': 'change_input', + 'change input#embedvideo': 'change_input', + 'keyup input#embedvideo': 'change_input' + }), + start: function () { + this.$iframe = this.$("iframe"); + var $media = $(this.media && this.media.$); + if ($media.hasClass("media_iframe_video")) { + var src = $media.data('src'); + this.$("input#urlvideo").val(src); + this.$("#autoplay").attr("checked", src.indexOf('autoplay=1') != -1); + this.get_video(); + } + return this._super(); + }, + change_input: function (e) { + var $input = $(e.target); + var $button = $input.parent().find("button"); + if ($input.val() === "") { + $button.addClass("btn-default").removeClass("btn-primary"); + } else { + $button.removeClass("btn-default").addClass("btn-primary"); + } + }, + get_url: function () { + var video_id = this.$("#video_id").val(); + var video_type = this.$("#video_type").val(); + switch (video_type) { + case "youtube": + return "//www.youtube.com/embed/" + video_id + "?autoplay=" + (this.$("#autoplay").is(":checked") ? 1 : 0); + case "vimeo": + return "//player.vimeo.com/video/" + video_id + "?autoplay=" + (this.$("#autoplay").is(":checked") ? 1 : 0); + case "dailymotion": + return "//www.dailymotion.com/embed/video/" + video_id + "?autoplay=" + (this.$("#autoplay").is(":checked") ? 1 : 0); + default: + return video_id; + } + }, + get_embed_video: function (event) { + event.preventDefault(); + var embedvideo = this.$("input#embedvideo").val().match(/src=["']?([^"']+)["' ]?/); + if (embedvideo) { + this.$("input#urlvideo").val(embedvideo[1]); + this.get_video(event); + } + return false; + }, + get_video: function (event) { + if (event) event.preventDefault(); + var needle = this.$("input#urlvideo").val(); + var video_id; + var video_type; + + if (needle.indexOf(".youtube.") != -1) { + video_type = "youtube"; + video_id = needle.match(/\.youtube\.[a-z]+\/(embed\/|watch\?v=)?([^\/?&]+)/i)[2]; + } else if (needle.indexOf("//youtu.") != -1) { + video_type = "youtube"; + video_id = needle.match(/youtube\.[a-z]+\/([^\/?&]+)/i)[1]; + } else if (needle.indexOf("player.vimeo.") != -1 || needle.indexOf("//vimeo.") != -1) { + video_type = "vimeo"; + video_id = needle.match(/vimeo\.[a-z]+\/(video\/)?([^?&]+)/i)[2]; + } else if (needle.indexOf(".dailymotion.") != -1) { + video_type = "dailymotion"; + video_id = needle.match(/dailymotion\.[a-z]+\/(embed\/)?(video\/)?([^\/?&]+)/i)[3]; + } else { + video_type = ""; + video_id = needle; + } + + this.$("#video_id").val(video_id); + this.$("#video_type").val(video_type); + + this.$iframe.attr("src", this.get_url()); + return false; + }, + save: function () { + var video_id = this.$("#video_id").val(); + if (!video_id) { + this.$("button.btn-primary").click(); + video_id = this.$("#video_id").val(); + } + var video_type = this.$("#video_type").val(); + var style = this.media.$.attributes.style ? this.media.$.attributes.style.textContent : ''; + var $iframe = $( + '<div class="media_iframe_video" data-src="'+this.get_url()+'" style="'+style+'">'+ + '<div class="css_editable_mode_display"> </div>'+ + '<iframe src="'+this.get_url()+'" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'+ + '</div>'); + $(this.media.$).replaceWith($iframe); + this.media.$ = $iframe[0]; + this._super(); + }, + clear: function () { + delete this.media.$.dataset.src; + this.media.$.className = this.media.$.className.replace(/(^|\s)media_iframe_video(\s|$)/g, ' '); + }, }); website.Observer = window.MutationObserver || window.WebkitMutationObserver || window.JsMutationObserver; diff --git a/addons/website/static/src/js/website.snippets.animation.js b/addons/website/static/src/js/website.snippets.animation.js index 56ad596d71a..1b8dfc0b320 100644 --- a/addons/website/static/src/js/website.snippets.animation.js +++ b/addons/website/static/src/js/website.snippets.animation.js @@ -148,4 +148,11 @@ }); }, }); + + website.snippet.animationRegistry.media_video = website.snippet.Animation.extend({ + selector: ".media_iframe_video", + start: function () { + this.$target.html('<div class="css_editable_mode_display"> </div><iframe src="'+this.$target.data("src")+'" frameborder="0" allowfullscreen="allowfullscreen"></iframe>'); + }, + }); })(); diff --git a/addons/website/static/src/js/website.snippets.editor.js b/addons/website/static/src/js/website.snippets.editor.js index 52deeabf5e6..fac4f9ab357 100644 --- a/addons/website/static/src/js/website.snippets.editor.js +++ b/addons/website/static/src/js/website.snippets.editor.js @@ -154,6 +154,7 @@ this.on('rte:ready', this, function () { self.snippets.$button.removeClass("hidden"); website.snippet.stop_animation(); + website.snippet.start_animation(true, $(".media_iframe_video")); }); return this._super.apply(this, arguments); @@ -265,7 +266,8 @@ '$el': $style, 'selector-siblings': $style.data('selector-siblings'), 'selector-children': $style.data('selector-children'), - 'selector-vertical-children': $style.data('selector-vertical-children') + 'selector-vertical-children': $style.data('selector-vertical-children'), + 'data': $style.data() }; selector.push($style.data('selector')); }); @@ -332,6 +334,7 @@ if (!$target.is(website.snippet.globalSelector)) { $target = $target.parents(website.snippet.globalSelector).first(); } + if (!self.dom_filter($target).length) { $target = false; } @@ -732,12 +735,15 @@ this.$target.data("snippet-option-ids", styles); this.$overlay = this.$target.data('overlay'); this['snippet-option-id'] = snippet_id; - this.$el = website.snippet.templateOptions[snippet_id].$el.find(">li").clone(); + var $option = website.snippet.templateOptions[snippet_id].$el; + this.$el = $option.find(">li").clone(); + this.data = $option.data(); this.required = this.$el.data("required"); this.set_active(); - this.$el.find('li[data-value] a').on('mouseover mouseout click', _.bind(this._mouse, this)); + this.$el.find('li[data-value] a').on('mouseenter mouseleave click', _.bind(this._mouse, this)); + this.$el.not(':not([data-value])').find("a").on('mouseenter mouseleave click', _.bind(this._mouse, this)); this.$target.on('snippet-style-reset', _.bind(this.set_active, this)); this.start(); @@ -745,7 +751,7 @@ _mouse: function (event) { var self = this; - if (event.type === 'mouseout') { + if (event.type === 'mouseleave') { if (!this.over) return; this.over = false; } else if (event.type === 'click') { @@ -755,7 +761,7 @@ } var $prev, $next; - if (event.type === 'mouseout') { + if (event.type === 'mouseleave') { $prev = $(event.currentTarget).parent(); $next = this.$el.find("li[data-value].active"); } else { @@ -837,7 +843,7 @@ var self = this; // add or remove html class - if (np.$prev && this.required) { + if (np.$prev) { this.$target.removeClass(np.$prev.data('value') || ""); } if (np.$next) { @@ -927,7 +933,7 @@ drop_and_build_snippet: function() { this.id = this.unique_id(); this.$target.attr("id", this.id); - this.$target.find("[data-slide]").attr("href", "#" + this.id); + this.$target.find("[data-slide]").attr("data-target", "#" + this.id); this.$target.find("[data-slide-to]").attr("data-target", "#" + this.id); this.rebind_event(); @@ -1171,6 +1177,7 @@ dy = dy - dy%resize; if (dy <= 0) dy = resize; self.$target.css("height", dy+"px"); + self.$target.css("overflow", "hidden"); self.on_resize(compass, null, dy); self.BuildingBlock.cover_target(self.$overlay, self.$target); return; @@ -1211,6 +1218,7 @@ }); this.$overlay.find(".oe_handle.size .auto_size").on('click', function (event){ self.$target.css("height", ""); + self.$target.css("overflow", ""); self.BuildingBlock.cover_target(self.$overlay, self.$target); return false; }); @@ -1425,6 +1433,88 @@ } }); + website.snippet.options.transform = website.snippet.Option.extend({ + start: function () { + var self = this; + this._super(); + + this.$el.find(".clear-style").click(function (event) { + self.$target.removeClass("fa-spin").attr("style", ""); + self.resetTransfo(); + }); + + this.$el.find(".style").click(function (event) { + var settings = self.$target.data("transfo").settings; + self.$target.transfo({ hide: (settings.hide = !settings.hide) }); + }); + + this.$overlay.find('.oe_snippet_clone, .oe_handles').addClass('hidden'); + + this.$overlay.find('[data-toggle="dropdown"]') + .on("mousedown", function () { + self.$target.transfo("hide"); + }); + }, + resetTransfo: function () { + var self = this; + this.$target.transfo("destroy"); + this.$target.transfo({ + hide: true, + callback: function () { + var pos = $(this).data("transfo").$center.offset(); + self.$overlay.css({ + 'top': pos.top, + 'left': pos.left, + 'position': 'absolute', + }); + self.$overlay.find(".oe_overlay_options").attr("style", "width:0; left:0!important; top:0;"); + self.$overlay.find(".oe_overlay_options > .btn-group").attr("style", "width:160px; left:-80px;"); + }}); + this.$target.data('transfo').$markup + .on("mouseover", function () { + self.$target.trigger("mouseover"); + }) + .mouseover(); + }, + onFocus : function () { + this.resetTransfo(); + }, + onBlur : function () { + this.$target.transfo("hide"); + }, + }); + + website.snippet.options.media = website.snippet.Option.extend({ + start: function () { + var self = this; + this._super(); + + website.snippet.start_animation(true, this.$target); + + $(document.body).on("media-saved", self, function (event, prev , item) { + self.editor.onBlur(); + self.BuildingBlock.make_active(false); + self.BuildingBlock.make_active($(item)); + }); + + this.$el.find(".edition").click(function (event) { + event.preventDefault(); + event.stopPropagation(); + self.element = new CKEDITOR.dom.element(self.$target[0]); + new website.editor.MediaDialog(self, self.element).appendTo(document.body); + }); + }, + onFocus : function () { + var self = this; + if (this.$target.parent().data("oe-field") === "image") { + this.$overlay.addClass("hidden"); + self.element = new CKEDITOR.dom.element(self.$target[0]); + new website.editor.MediaDialog(self, self.element).appendTo(document.body); + self.BuildingBlock.make_active(false); + } + }, + }); + website.snippet.Editor = openerp.Class.extend({ init: function (BuildingBlock, dom) { @@ -1564,6 +1654,10 @@ if (this.selector_vertical_children === "") this.selector_vertical_children = false; + if (!this.selector_siblings && !this.selector_children && !this.selector_vertical_children) { + this.$overlay.find(".oe_snippet_move").addClass('hidden'); + } + if ($ul.find("li").length) { $styles.removeClass("hidden"); diff --git a/addons/website/static/src/js/website.tour.banner.js b/addons/website/static/src/js/website.tour.banner.js index 9c8afcd61e5..63ef120d9a1 100644 --- a/addons/website/static/src/js/website.tour.banner.js +++ b/addons/website/static/src/js/website.tour.banner.js @@ -35,7 +35,7 @@ element: 'button[data-action=snippet]', placement: 'bottom', title: _t("Insert building blocks"), - content: _t("Click here to insert blocks of centent in the page."), + content: _t("Click here to insert blocks of content in the page."), popover: { fixed: true }, }, { |
