From 7d59a7355fae088ba32dfbd321fb103e175a9330 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Thu, 25 Jul 2013 16:55:05 +0200 Subject: [PATCH] [IMP] remove sharedspace plugin, disable ckeditor's own toolbar, build toolbar from scratch bzr revid: xmo@openerp.com-20130725145505-sb8ul41fd3nfmhwc --- .../static/lib/ckeditor.sharedspace/plugin.js | 124 ---------------- addons/website/static/src/js/website.js | 140 +++++++++++++----- addons/website/static/src/xml/website.xml | 1 - addons/website/views/views.xml | 1 - 4 files changed, 100 insertions(+), 166 deletions(-) delete mode 100644 addons/website/static/lib/ckeditor.sharedspace/plugin.js diff --git a/addons/website/static/lib/ckeditor.sharedspace/plugin.js b/addons/website/static/lib/ckeditor.sharedspace/plugin.js deleted file mode 100644 index ae8ddc79eb4..00000000000 --- a/addons/website/static/lib/ckeditor.sharedspace/plugin.js +++ /dev/null @@ -1,124 +0,0 @@ -/** - * @license Copyright (c) 2003-2012, CKSource - Frederico Knabben. All rights reserved. - * For licensing, see LICENSE.md or http://ckeditor.com/license - */ - -(function() { - - 'use strict'; - - var containerTpl = CKEDITOR.addTemplate( 'sharedcontainer', '' + - '
' + - '' + - '
' + - '' ); - - CKEDITOR.plugins.add( 'sharedspace', { - afterInit: function( editor ) { - var spaces = editor.config.sharedSpaces; - - if ( spaces ) { - for ( var spaceName in spaces ) { - create( editor, spaceName, spaces[ spaceName ] ); - } - } - } - }); - - function create( editor, spaceName, targetId ) { - var target = CKEDITOR.document.getById( targetId ), - innerHtml, space; - - if ( target ) { - // Have other plugins filling the space. - innerHtml = editor.fire( 'uiSpace', { space: spaceName, html: '' } ).html; - - if ( innerHtml ) { - // Block the uiSpace handling by others (e.g. themed-ui). - editor.on( 'uiSpace', function( ev ) { - if ( ev.data.space == spaceName ) - ev.cancel(); - }, null, null, 1 ); // Hi-priority - - // Inject the space into the target. - space = target.append( CKEDITOR.dom.element.createFromHtml( containerTpl.output({ - id: editor.id, - name: editor.name, - langDir: editor.lang.dir, - langCode: editor.langCode, - space: spaceName, - spaceId: editor.ui.spaceId( spaceName ), - content: innerHtml - }))); - - // Only the first container starts visible. Others get hidden. - if ( target.getCustomData( 'cke_hasshared' ) ) - space.hide(); - else - target.setCustomData( 'cke_hasshared', 1 ); - - // There's no need for the space to be selectable. - space.unselectable(); - - // Prevent clicking on non-buttons area of the space from blurring editor. - space.on( 'mousedown', function( evt ) { - evt = evt.data; - if ( !evt.getTarget().hasAscendant( 'a', 1 ) ) - evt.preventDefault(); - }); - - // Register this UI space to the focus manager. - editor.focusManager.add( space, 1 ); - - // When the editor gets focus, show the space container, hiding others. - editor.on( 'focus', function() { - for ( var i = 0, sibling, children = target.getChildren(); ( sibling = children.getItem( i ) ); i++ ) { - if ( sibling.type == CKEDITOR.NODE_ELEMENT && - !sibling.equals( space ) && - sibling.hasClass( 'cke_shared' ) ) { - sibling.hide(); - } - } - - space.show(); - }); - - editor.on( 'destroy', function() { - space.remove(); - }); - } - } - } -})(); - -/** - * Makes it possible to place some of the editor UI blocks, like the toolbar - * and the elements path, into any element in the page. - * - * The elements used to hold the UI blocks can be shared among several editor - * instances. In that case, only the blocks of the active editor instance will - * display. - * - * // Place the toolbar inside the element with ID "someElementId" and the - * // elements path into the element with ID "anotherId". - * config.sharedSpaces = { - * top: 'someElementId', - * bottom: 'anotherId' - * }; - * - * // Place the toolbar inside the element with ID "someElementId". The - * // elements path will remain attached to the editor UI. - * config.sharedSpaces = { - * top: 'someElementId' - * }; - * - * @cfg {Object} [sharedSpaces] - * @member CKEDITOR.config - */ diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 84f0cc70767..5fb341d1f32 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -1,4 +1,5 @@ openerp.website = function(instance) { +var _lt = instance.web._lt; instance.website.EditorBar = instance.web.Widget.extend({ template: 'Website.EditorBar', events: { @@ -8,52 +9,39 @@ instance.website.EditorBar = instance.web.Widget.extend({ 'click button[data-action=snippet]': 'snippet', }, container: 'body', + init: function () { + this._super.apply(this, arguments); + this.saving_mutex = new $.Mutex(); + }, start: function() { var self = this; - this.saving_mutex = new $.Mutex(); - self.$('button[data-action]').prop('disabled', true); - self.$('button[data-action=edit], button[data-action=snippet]').prop('disabled', false); + + this.$('button[data-action]').prop('disabled', true); + this.$buttons = { + edit: this.$('button[data-action=edit]'), + save: this.$('button[data-action=save]'), + cancel: this.$('button[data-action=cancel]'), + snippet: this.$('button[data-action=snippet]'), + }; + this.$buttons.edit.add(this.$buttons.snippet).prop('disabled', false); + self.snippet_start(); - $('body').on("keypress", ".oe_editable", function(e) { - var $e = $(e.currentTarget); - if (!$e.is('.oe_dirty')) { - $e.addClass('oe_dirty'); - self.$('button[data-action=save],button[data-action=cancel]').prop('disabled', false); - // TODO: Are we going to use a meta-data flag in order to know if the field shall be text or html ? - } - if (e.which == 13) { - $e.blur(); - e.preventDefault(); - } - }); + this.rte = new instance.website.RTE(this); + this.rte.on('change', this, this.proxy('rte_changed')); - return this._super.apply(this, arguments); + return $.when( + this._super.apply(this, arguments), + this.rte.appendTo(this.$el) + ); }, edit: function () { - this.$('button[data-action=edit]').prop('disabled', true); - $('[data-oe-model]') - .not('link, script, span') - .prop('contentEditable', true) - .addClass('oe_editable') - .each(function () { - CKEDITOR.inline(this, { - // Don't load ckeditor's style rules - stylesSet: [], - toolbar: [ - ['Bold', 'Italic'] - ], - uiColor: '', - // Ensure no config file is loaded - customConfig: '', - // Disable ACF - allowedContent: true, - // Support for sharedSpaces in 4.x - extraPlugins: 'sharedspace', - // Place toolbar in controlled location - sharedSpaces: { top: 'oe_rte_toolbar' }, - }); - }); + this.$buttons.edit.prop('disabled', true); + this.$buttons.cancel.prop('disabled', false); + this.rte.start_edition($('[data-oe-model]').addClass('oe_editable')); + }, + rte_changed: function () { + this.$buttons.save.prop('disabled', false); }, save: function () { var self = this; @@ -85,7 +73,6 @@ instance.website.EditorBar = instance.web.Widget.extend({ $w.removeClass('oe_dirty'); _.each(['model', 'id', 'field', 'xpath'], function(d) {$w.removeAttr('data-oe-' + d);}); $w - .each(function () { console.log(this); }) .removeClass('oe_editable') .prop('contentEditable', false); html = $w.wrap('
').parent().html(); @@ -124,6 +111,79 @@ instance.website.EditorBar = instance.web.Widget.extend({ }, }); +instance.website.RTE = instance.web.Widget.extend({ + tagName: 'li', + className: 'oe_right', + commands: [ + {name: _lt('Bold'), command: 'bold'}, + {name: _lt('Italic'), command: 'italic'}, + {name: _lt('Underline'), command: 'underline'}, + {name: _lt('Strikethrough'), command: 'strike'}, + {name: _lt('H1'), style: { element: 'h1' }}, + {name: _lt('H2'), style: { element: 'h2', }}, + {name: _lt('H3'), style: { element: 'h3', }}, + {name: _lt('H4'), style: { element: 'h4', }}, + {name: _lt("Red"), style: { element: 'span', styles: { color: 'red' } }} + ], + // editor.ui.items -> possible commands &al + // editor.applyStyle(new CKEDITOR.style({element: "span",styles: {color: "#(color)"},overrides: [{element: "font",attributes: {color: null}}]}, {color: '#ff0000'})); + start: function () { + var self = this; + this.$el.hide(); + + _(this.commands).foldl(function (jq, command) { + return jq.add(self.button_for(command)); + }, $()).appendTo(this.$el); + }, + start_edition: function ($elements) { + var self = this; + $elements + .not('link, script, span') + .prop('contentEditable', true) + .each(function () { + var $this = $(this); + CKEDITOR.inline(this, self._config()).on('change', function () { + $this.addClass('oe_dirty'); + self.trigger('change', this, null); + }); + }); + this.$el.show(); + }, + + button_for: function (command) { + var self = this; + return $('
  • -
  • diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index a79dd04df4f..d55fe182c32 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -64,7 +64,6 @@ -