From d8792fc1a9c6b759100b96f91942283250d0f511 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 24 Jul 2013 14:36:26 +0200 Subject: [PATCH 3/9] [ADD] basic ckeditor integration bzr revid: xmo@openerp.com-20130724123626-c220vibm5mvukudv --- addons/website/static/src/js/website.js | 27 +++++++++++++++++++++---- addons/website/views/views.xml | 5 +++++ 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 34c866cc3b9..2ed9d0197f1 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -1,4 +1,7 @@ openerp.website = function(instance) { +var block = ['section', 'div']; +var block_inline = ['p', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; +var terminal = block.concat(block_inline).join(', '); instance.website.EditorBar = instance.web.Widget.extend({ template: 'Website.EditorBar', @@ -13,7 +16,7 @@ instance.website.EditorBar = instance.web.Widget.extend({ 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); + self.$('button[data-action=edit], button[data-action=snippet]').prop('disabled', false); self.snippet_start(); $('body').on("keypress", ".oe_editable", function(e) { @@ -33,7 +36,20 @@ instance.website.EditorBar = instance.web.Widget.extend({ }, edit: function () { this.$('button[data-action=edit]').prop('disabled', true); - $('[data-oe-model]').prop('contentEditable', true).addClass('oe_editable'); + var $root = $('[data-oe-model]'); + $root.add($root.find(terminal)) + .not('link, script, span') + .not(':has(' + terminal + ')') + .prop('contentEditable', true) + .addClass('oe_editable') + .each(function () { + CKEDITOR.inline(this, { + // Don't load ckeditor's style rules + stylesSet: [], + toolbar: 'Basic', + customConfig: '', + }); + }); }, save: function () { var self = this; @@ -62,9 +78,12 @@ instance.website.EditorBar = instance.web.Widget.extend({ var xpath = data.oeXpath; if (xpath) { var $w = $el.clone(); - $w.removeClass('aloha-editable aloha-editable-highlight oe_dirty'); + $w.removeClass('oe_dirty'); _.each(['model', 'id', 'field', 'xpath'], function(d) {$w.removeAttr('data-oe-' + d);}); - $w.prop('contentEditable', false).removeClass('oe_editable'); + $w + .each(function () { console.log(this); }) + .removeClass('oe_editable') + .prop('contentEditable', false); html = $w.wrap('
').parent().html(); } return (new instance.web.DataSet(this, 'ir.ui.view')).call('save', [data.oeModel, data.oeId, data.oeField, html, xpath]); diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index 572aa5f1c3e..d55fe182c32 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -63,6 +63,11 @@ + + From 5c20973bf9c191fa694ce682ba90117e575deda9 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 24 Jul 2013 14:54:35 +0200 Subject: [PATCH 4/9] [IMP] disable ACF to fix ckeditor removing nodes and classes, breaking layout and styling bzr revid: xmo@openerp.com-20130724125435-02c8j92p0tq894nq --- addons/website/static/src/js/website.js | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/addons/website/static/src/js/website.js b/addons/website/static/src/js/website.js index 2ed9d0197f1..34805db6fbd 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -1,8 +1,4 @@ openerp.website = function(instance) { -var block = ['section', 'div']; -var block_inline = ['p', 'li', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6']; -var terminal = block.concat(block_inline).join(', '); - instance.website.EditorBar = instance.web.Widget.extend({ template: 'Website.EditorBar', events: { @@ -36,18 +32,19 @@ instance.website.EditorBar = instance.web.Widget.extend({ }, edit: function () { this.$('button[data-action=edit]').prop('disabled', true); - var $root = $('[data-oe-model]'); - $root.add($root.find(terminal)) + $('[data-oe-model]') .not('link, script, span') - .not(':has(' + terminal + ')') .prop('contentEditable', true) .addClass('oe_editable') .each(function () { CKEDITOR.inline(this, { // Don't load ckeditor's style rules stylesSet: [], - toolbar: 'Basic', + // toolbar: TODO, + // Ensure no config file is loaded customConfig: '', + // Disable ACF + allowedContent: true, }); }); }, From f3aabcc2560ecd29c06586761aa6aa46f829e271 Mon Sep 17 00:00:00 2001 From: Xavier Morel Date: Wed, 24 Jul 2013 16:48:51 +0200 Subject: [PATCH 5/9] [ADD] fixed toolbar positioning for ckeditor bzr revid: xmo@openerp.com-20130724144851-40f69hkuantjbgtg --- .../static/lib/ckeditor.sharedspace/plugin.js | 124 ++++++++++++++++++ addons/website/static/src/js/website.js | 9 +- addons/website/static/src/xml/website.xml | 1 + addons/website/views/views.xml | 1 + 4 files changed, 134 insertions(+), 1 deletion(-) create 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 new file mode 100644 index 00000000000..ae8ddc79eb4 --- /dev/null +++ b/addons/website/static/lib/ckeditor.sharedspace/plugin.js @@ -0,0 +1,124 @@ +/** + * @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 34805db6fbd..84f0cc70767 100644 --- a/addons/website/static/src/js/website.js +++ b/addons/website/static/src/js/website.js @@ -40,11 +40,18 @@ instance.website.EditorBar = instance.web.Widget.extend({ CKEDITOR.inline(this, { // Don't load ckeditor's style rules stylesSet: [], - // toolbar: TODO, + 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' }, }); }); }, diff --git a/addons/website/static/src/xml/website.xml b/addons/website/static/src/xml/website.xml index 1754b7b81b6..8715a74184a 100644 --- a/addons/website/static/src/xml/website.xml +++ b/addons/website/static/src/xml/website.xml @@ -9,6 +9,7 @@
  • +
  • diff --git a/addons/website/views/views.xml b/addons/website/views/views.xml index d55fe182c32..a79dd04df4f 100644 --- a/addons/website/views/views.xml +++ b/addons/website/views/views.xml @@ -64,6 +64,7 @@ + -