[IMP] remove sharedspace plugin, disable ckeditor's own toolbar, build toolbar from scratch
bzr revid: xmo@openerp.com-20130725145505-sb8ul41fd3nfmhwc
This commit is contained in:
@@ -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', '<div' +
|
||||
' id="cke_{name}"' +
|
||||
' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_shared cke_detached cke_{langDir} ' + CKEDITOR.env.cssClass + '"' +
|
||||
' dir="{langDir}"' +
|
||||
' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' +
|
||||
' lang="{langCode}"' +
|
||||
' role="presentation"' +
|
||||
'>' +
|
||||
'<div class="cke_inner">' +
|
||||
'<div id="{spaceId}" class="cke_{space}" role="presentation">{content}</div>' +
|
||||
'</div>' +
|
||||
'</div>' );
|
||||
|
||||
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
|
||||
*/
|
||||
@@ -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('<div>').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 $('<button type="button">').click(function () {
|
||||
var editor = self._current_editor();
|
||||
editor.fire('saveSnapshot');
|
||||
|
||||
if (command.style) {
|
||||
editor.applyStyle(new CKEDITOR.style(command.style));
|
||||
} else if (typeof command.command === 'string') {
|
||||
editor.execCommand(command.command);
|
||||
} else {
|
||||
command.command(editor);
|
||||
}
|
||||
}).text(command.name);
|
||||
},
|
||||
|
||||
_current_editor: function () {
|
||||
return CKEDITOR.currentInstance;
|
||||
},
|
||||
_config: function () {
|
||||
return {
|
||||
// Don't load ckeditor's style rules
|
||||
stylesSet: [],
|
||||
// Remove toolbar entirely
|
||||
removePlugins: 'toolbar,elementspath,resize',
|
||||
uiColor: '',
|
||||
// Ensure no config file is loaded
|
||||
customConfig: '',
|
||||
// Disable ACF
|
||||
allowedContent: true,
|
||||
};
|
||||
},
|
||||
});
|
||||
|
||||
$(function(){
|
||||
|
||||
function make_static(){
|
||||
|
||||
@@ -9,7 +9,6 @@
|
||||
<li class="oe_right"><button data-action="cancel">Cancel</button></li>
|
||||
<li class="oe_right"><button data-action="snippet">Snippet</button></li>
|
||||
<li class="oe_right"><button data-action="edit">Edit</button></li>
|
||||
<li class="oe_right" id="oe_rte_toolbar"></li>
|
||||
</ul>
|
||||
</t>
|
||||
</templates>
|
||||
|
||||
@@ -64,7 +64,6 @@
|
||||
|
||||
<script type="text/javascript" src="/web/static/lib/jquery/jquery-1.8.3.js"></script>
|
||||
<script type="text/javascript" src="//cdnjs.cloudflare.com/ajax/libs/ckeditor/4.2/ckeditor.js"></script>
|
||||
<script type="text/javascript" src="/website/static/lib/ckeditor.sharedspace/plugin.js"></script>
|
||||
<script type="text/javascript">
|
||||
CKEDITOR.disableAutoInline = true;
|
||||
CKEDITOR.dtd.$editable.li = 1;
|
||||
|
||||
Reference in New Issue
Block a user