Browse Source

Merge pull request #1225 from simahawk/10-web_ckeditor4-fix

[10.0] web_ckeditor4: fix no re-init on form discard
pull/831/merge
Pedro M. Baeza 6 years ago
committed by GitHub
parent
commit
16665c28cc
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 2
      web_ckeditor4/__manifest__.py
  2. 157
      web_ckeditor4/static/src/js/web_ckeditor4.js
  3. 99
      web_ckeditor4/static/src/js/web_ckeditor4_config.js
  4. 20
      web_ckeditor4/templates/assets.xml
  5. 20
      web_ckeditor4/views/qweb.xml

2
web_ckeditor4/__manifest__.py

@ -13,7 +13,7 @@
'web', 'web',
], ],
'data': [ 'data': [
'views/qweb.xml',
'templates/assets.xml',
], ],
'css': [ 'css': [
'static/src/css/web_ckeditor4.css', 'static/src/css/web_ckeditor4.css',

157
web_ckeditor4/static/src/js/web_ckeditor4.js

@ -25,114 +25,55 @@ odoo.define('web_ckeditor4', function(require){
var core = require('web.core'); var core = require('web.core');
var session = require('web.session'); var session = require('web.session');
var formats = require('web.formats'); var formats = require('web.formats');
var ckconfig = require('web_ckeditor4.config');
var ckeditor_addFunction_org = CKEDITOR.tools.addFunction;
//this is a quite complicated way to kind of monkey patch the private
//method onDomReady of ckeditor's plugin wysiwigarea, which causes problems
//when the editor is about to be destroyed but because of OpenERP's
//architecture updated one last time with its current value
CKEDITOR.tools.addFunction = function(fn, scope)
{
if(scope && scope._ && scope._.attrChanges && scope._.detach)
{
var scope_reference = scope;
return ckeditor_addFunction_org(function()
{
var self = this,
self_arguments=arguments;
setTimeout(function()
{
if(self.editor)
{
fn.apply(self, self_arguments);
}
}, 0);
}, scope);
}
return ckeditor_addFunction_org(fn, scope);
};
CKEDITOR.on('dialogDefinition', function(e)
{
_.each(e.data.definition.contents, function(element)
{
if(!element || element.filebrowser!='uploadButton')
{
return
}
_.each(element.elements, function(element)
{
if(!element.onClick || element.type!='fileButton')
{
return
}
var onClick_org = element.onClick;
element.onClick = function(e1)
{
onClick_org.apply(this, arguments);
_.each(jQuery('#'+this.domId).closest('table')
.find('iframe').contents().find(':file')
.get(0).files,
function(file)
{
var reader = new FileReader();
reader.onload = function(load_event)
{
CKEDITOR.tools.callFunction(
e.editor._.filebrowserFn,
load_event.target.result,
'');
}
reader.readAsDataURL(file);
});
return false;
}
});
});
});
function filter_html(value, ckeditor_filter, ckeditor_writer)
{
var fragment = CKEDITOR.htmlParser.fragment.fromHtml(value);
ckeditor_filter.applyTo(fragment);
ckeditor_writer.reset();
fragment.writeHtml(ckeditor_writer);
return ckeditor_writer.getHtml();
};
var default_ckeditor_filter = new CKEDITOR.filter(
{
'*':
{
attributes: 'href,src,style,alt,width,height,dir',
styles: '*',
classes: '*',
},
'html head title meta style body p div span a h1 h2 h3 h4 h5 img br hr table tr th td ul ol li dd dt strong pre b i': true,
});
var default_ckeditor_writer = new CKEDITOR.htmlParser.basicWriter();
var FieldCKEditor4 = core.form_widget_registry.get('text').extend({ var FieldCKEditor4 = core.form_widget_registry.get('text').extend({
ckeditor_config: function () { ckeditor_config: function () {
return {
removePlugins: this._getRemovePlugins(),
removeButtons: this._getRemoveButtons(),
filebrowserImageUploadUrl: 'dummy',
extraPlugins: 'filebrowser',
// this is '#39' per default which screws up single quoted text in ${}
entities_additional: ''
};
return {
removePlugins: this._getRemovePlugins(),
removeButtons: this._getRemoveButtons(),
filebrowserImageUploadUrl: 'dummy',
extraPlugins: 'filebrowser',
// this is '#39' per default which screws up single quoted text in ${}
entities_additional: ''
};
}, },
ckeditor_filter: default_ckeditor_filter,
ckeditor_writer: default_ckeditor_writer,
ckeditor_filter: ckconfig.default_ckeditor_filter,
ckeditor_writer: ckconfig.default_ckeditor_writer,
_getRemovePlugins: function () { _getRemovePlugins: function () {
return 'iframe,flash,forms,smiley,pagebreak,stylescombo'; return 'iframe,flash,forms,smiley,pagebreak,stylescombo';
}, },
_getRemoveButtons: function () { _getRemoveButtons: function () {
return ''; return '';
}, },
init: function () {
this._super.apply(this, arguments);
this.editor_lang = session.user_context.lang.split('_')[0];
this.view.on("load_record", this, this._on_load_record);
},
start: function() start: function()
{ {
this._super.apply(this, arguments); this._super.apply(this, arguments);
CKEDITOR.lang.load(session.user_context.lang.split('_')[0], 'en', function() {});
CKEDITOR.lang.load(this.editor_lang, 'en', function() {});
},
_on_load_record: function() {
/* Fix widget not re-initialized on form discard.
When you hit "cancel" button or when you navigate away
from the form, for instance by clicking on the breadcrumb
or on "edit translations", we have to remove the CKEditor widget.
BUT then if you hit "create" Odoo's form machinery is not initializing
the widget anymore (which really sounds inconsistent).
If the widget is not initialized again it means that if CKEditor
got destroyed there's no way to re-init again.
Here we make sure that on create (no id on datarecord)
if the editor is not initialized yet we force it.
*/
if (!this.view.datarecord.id && !this.editor) {
this.initialize_content();
}
}, },
initialize_content: function() initialize_content: function()
{ {
@ -141,12 +82,11 @@ odoo.define('web_ckeditor4', function(require){
if(!this.$el) if(!this.$el)
{ {
return; return;
} else if (!this.get('effective_readonly')) {
} else if (!this.get('effective_readonly') && !this.editor) {
this.editor = CKEDITOR.replace(this.$el.get(0), this.editor = CKEDITOR.replace(this.$el.get(0),
_.extend( _.extend(
{ {
language: session.user_context.lang.split('_')[0],
language: this.editor_lang,
on: on:
{ {
'change': function() 'change': function()
@ -166,7 +106,7 @@ odoo.define('web_ckeditor4', function(require){
}, },
filter_html: function(value) filter_html: function(value)
{ {
return filter_html(value, this.ckeditor_filter, this.ckeditor_writer);
return ckconfig.filter_html(value, this.ckeditor_filter, this.ckeditor_writer);
}, },
render_value: function() render_value: function()
{ {
@ -195,6 +135,9 @@ odoo.define('web_ckeditor4', function(require){
} }
} }
}, },
destroy_content: function () {
this._cleanup_editor();
},
undelegateEvents: function() undelegateEvents: function()
{ {
this._cleanup_editor(); this._cleanup_editor();
@ -202,35 +145,35 @@ odoo.define('web_ckeditor4', function(require){
}, },
_cleanup_editor: function() _cleanup_editor: function()
{ {
if(this.editor && this.editor.status != 'unloaded')
if(this.editor && this.editor.status == 'ready')
{ {
var id = this.editor.id
CKEDITOR.remove(this.editor.name);
$('#cke_' + this.editor.name).remove();
this.editor.removeAllListeners(); this.editor.removeAllListeners();
this.editor.destroy(); this.editor.destroy();
this.editor = null; this.editor = null;
$('.' + id).remove();
} }
}, },
destroy: function() destroy: function()
{ {
this._cleanup_editor();
this._super();
},
destroy_content: function()
{
this.view.off("load_record", this, this._on_load_record);
this._cleanup_editor(); this._cleanup_editor();
this._super();
} }
}); });
var FieldCKEditor4Raw = FieldCKEditor4.extend({ var FieldCKEditor4Raw = FieldCKEditor4.extend({
filter_html: function(value) filter_html: function(value)
{ {
return value; return value;
} }
}); });
core.form_widget_registry.add('text_ckeditor4', FieldCKEditor4); core.form_widget_registry.add('text_ckeditor4', FieldCKEditor4);
core.form_widget_registry.add('text_ckeditor4_raw', FieldCKEditor4Raw); core.form_widget_registry.add('text_ckeditor4_raw', FieldCKEditor4Raw);
core.form_widget_registry.add('text_html', FieldCKEditor4); core.form_widget_registry.add('text_html', FieldCKEditor4);
core.form_widget_registry.add('html', FieldCKEditor4); core.form_widget_registry.add('html', FieldCKEditor4);
return { return {
'FieldCKEditor4': FieldCKEditor4, 'FieldCKEditor4': FieldCKEditor4,
'FieldCKEditor4Raw': FieldCKEditor4Raw 'FieldCKEditor4Raw': FieldCKEditor4Raw

99
web_ckeditor4/static/src/js/web_ckeditor4_config.js

@ -0,0 +1,99 @@
/* -*- encoding: utf-8 -*-
##############################################################################
#
# OpenERP, Open Source Management Solution
# This module copyright (C) 2013 Therp BV (<http://therp.nl>)
# All Rights Reserved
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
############################################################################*/
odoo.define('web_ckeditor4.config', function (require) {
"use strict";
var ckeditor_addFunction_org = CKEDITOR.tools.addFunction;
// this is a quite complicated way to kind of monkey patch the private
// method onDomReady of ckeditor's plugin wysiwigarea, which causes problems
// when the editor is about to be destroyed but because of OpenERP's
// architecture updated one last time with its current value
CKEDITOR.tools.addFunction = function (fn, scope) {
if (scope && scope._ && scope._.attrChanges && scope._.detach) {
return ckeditor_addFunction_org(function () {
var self = this,
self_arguments = arguments;
setTimeout(function () {
if (self.editor) {
fn.apply(self, self_arguments);
}
}, 0);
}, scope);
}
return ckeditor_addFunction_org(fn, scope);
};
CKEDITOR.on('dialogDefinition', function (e) {
_.each(e.data.definition.contents, function (element) {
if (!element || element.filebrowser != 'uploadButton') {
return
}
_.each(element.elements, function (element) {
if (!element.onClick || element.type != 'fileButton') {
return
}
var onClick_org = element.onClick;
element.onClick = function (e1) {
onClick_org.apply(this, arguments);
_.each($('#' + this.domId).closest('table')
.find('iframe').contents().find(':file')
.get(0).files,
function (file) {
var reader = new FileReader();
reader.onload = function (load_event) {
CKEDITOR.tools.callFunction(
e.editor._.filebrowserFn,
load_event.target.result,
'');
}
reader.readAsDataURL(file);
});
return false;
}
});
});
});
var filter_html = function filter_html(value, ckeditor_filter, ckeditor_writer) {
var fragment = CKEDITOR.htmlParser.fragment.fromHtml(value);
ckeditor_filter.applyTo(fragment);
ckeditor_writer.reset();
fragment.writeHtml(ckeditor_writer);
return ckeditor_writer.getHtml();
};
var default_ckeditor_filter = new CKEDITOR.filter({
'*':
{
attributes: 'href,src,style,alt,width,height,dir',
styles: '*',
classes: '*',
},
'html head title meta style body p div span a h1 h2 h3 h4 h5 img br hr table tr th td ul ol li dd dt strong pre b i': true,
});
var default_ckeditor_writer = new CKEDITOR.htmlParser.basicWriter();
return {
'filter_html': filter_html,
'default_ckeditor_filter': default_ckeditor_filter,
'default_ckeditor_writer': default_ckeditor_writer
}
});

20
web_ckeditor4/templates/assets.xml

@ -0,0 +1,20 @@
<?xml version="1.0" encoding="UTF-8"?>
<odoo>
<template id="assets_backend" name="web_ckeditor4 assets"
inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/ckeditor_basepath.js" />
<script type="text/javascript"
src="/web_ckeditor4/static/lib/ckeditor/ckeditor.js" />
<script type="text/javascript"
src="/web_ckeditor4/static/lib/ckeditor/config.js" />
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/web_ckeditor4_config.js" />
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/web_ckeditor4_formview.js" />
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/web_ckeditor4.js" />
</xpath>
</template>
</odoo>

20
web_ckeditor4/views/qweb.xml

@ -1,20 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<openerp>
<data>
<template id="assets_backend" name="web_ckeditor4 assets"
inherit_id="web.assets_backend">
<xpath expr="." position="inside">
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/ckeditor_basepath.js"></script>
<script type="text/javascript"
src="/web_ckeditor4/static/lib/ckeditor/ckeditor.js"></script>
<script type="text/javascript"
src="/web_ckeditor4/static/lib/ckeditor/config.js"></script>
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/web_ckeditor4_formview.js"></script>
<script type="text/javascript"
src="/web_ckeditor4/static/src/js/web_ckeditor4.js"></script>
</xpath>
</template>
</data>
</openerp>
Loading…
Cancel
Save