diff --git a/web_ckeditor4/__init__.py b/web_ckeditor4/__init__.py new file mode 100644 index 00000000..a97ee816 --- /dev/null +++ b/web_ckeditor4/__init__.py @@ -0,0 +1,22 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV () +# 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 . +# +############################################################################## + diff --git a/web_ckeditor4/__openerp__.py b/web_ckeditor4/__openerp__.py new file mode 100644 index 00000000..6465c7e7 --- /dev/null +++ b/web_ckeditor4/__openerp__.py @@ -0,0 +1,114 @@ +# -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV () +# 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 . +# +############################################################################## + +{ + 'name': 'CKEditor 4.x widget', + 'version': '1.0', + 'description': """ + This addon provides a widget for editing html fields via CKEditor 4.x + + Use widget="text_html" if you need just html display. In the unlikely case + you need specific features of ckeditor, use widget="text_ckeditor4". + """, + 'author': 'Therp BV', + 'website': 'http://www.therp.nl', + "category": "Tools", + "depends": [ + 'web', + ], + 'css': [ + 'static/src/css/web_ckeditor4.css', + ], + 'data': [ + ], + 'js': [ + 'static/src/js/ckeditor_basepath.js', + 'static/lib/ckeditor/ckeditor.js', + 'static/lib/ckeditor/config.js', + #to debug ckeditor, comment the lines above, + #do a + #cd static/lib + #git clone https://github.com/ckeditor/ckeditor-dev.git trunk + #cd trunk + #git checkout remotes/origin/release/4.1.x + #and uncomment the lines below +# 'static/lib/trunk/ckeditor.js', +# 'static/lib/trunk/core/event.js', +# 'static/lib/trunk/core/editor_basic.js', +# 'static/lib/trunk/core/env.js', +# 'static/lib/trunk/core/ckeditor_basic.js', +# 'static/lib/trunk/core/dom.js', +# 'static/lib/trunk/core/tools.js', +# 'static/lib/trunk/core/dtd.js', +# 'static/lib/trunk/core/dom/event.js', +# 'static/lib/trunk/core/dom/domobject.js', +# 'static/lib/trunk/core/dom/node.js', +# 'static/lib/trunk/core/dom/window.js', +# 'static/lib/trunk/core/dom/document.js', +# 'static/lib/trunk/core/dom/nodelist.js', +# 'static/lib/trunk/core/dom/element.js', +# 'static/lib/trunk/core/dom/documentfragment.js', +# 'static/lib/trunk/core/dom/walker.js', +# 'static/lib/trunk/core/dom/range.js', +# 'static/lib/trunk/core/dom/iterator.js', +# 'static/lib/trunk/core/command.js', +# 'static/lib/trunk/core/ckeditor_base.js', +# 'static/lib/trunk/core/config.js', +# 'static/lib/trunk/core/filter.js', +# 'static/lib/trunk/core/focusmanager.js', +# 'static/lib/trunk/core/keystrokehandler.js', +# 'static/lib/trunk/core/lang.js', +# 'static/lib/trunk/core/scriptloader.js', +# 'static/lib/trunk/core/resourcemanager.js', +# 'static/lib/trunk/core/plugins.js', +# 'static/lib/trunk/core/ui.js', +# 'static/lib/trunk/core/editor.js', +# 'static/lib/trunk/core/htmlparser.js', +# 'static/lib/trunk/core/htmlparser/basicwriter.js', +# 'static/lib/trunk/core/htmlparser/node.js', +# 'static/lib/trunk/core/htmlparser/comment.js', +# 'static/lib/trunk/core/htmlparser/text.js', +# 'static/lib/trunk/core/htmlparser/cdata.js', +# 'static/lib/trunk/core/htmlparser/fragment.js', +# 'static/lib/trunk/core/htmlparser/filter.js', +# 'static/lib/trunk/core/htmldataprocessor.js', +# 'static/lib/trunk/core/htmlparser/element.js', +# 'static/lib/trunk/core/template.js', +# 'static/lib/trunk/core/ckeditor.js', +# 'static/lib/trunk/core/creators/inline.js', +# 'static/lib/trunk/core/creators/themedui.js', +# 'static/lib/trunk/core/editable.js', +# 'static/lib/trunk/core/selection.js', +# 'static/lib/trunk/core/style.js', +# 'static/lib/trunk/core/dom/comment.js', +# 'static/lib/trunk/core/dom/elementpath.js', +# 'static/lib/trunk/core/dom/text.js', +# 'static/lib/trunk/core/dom/rangelist.js', +# 'static/lib/trunk/core/skin.js', +# 'static/lib/trunk/core/_bootstrap.js', + #end of ckeditor debug + 'static/src/js/web_ckeditor4.js', + ], + 'installable': True, + 'auto_install': False, + 'certificate': '', +} diff --git a/web_ckeditor4/static/src/css/web_ckeditor4.css b/web_ckeditor4/static/src/css/web_ckeditor4.css new file mode 100644 index 00000000..6bfad78b --- /dev/null +++ b/web_ckeditor4/static/src/css/web_ckeditor4.css @@ -0,0 +1,6 @@ +.openerp .oe_form_field_text_ckeditor4.disabled, .openerp td.oe_form_field_text_ckeditor4, .openerp .oe_form_field_text_ckeditor4_raw.disabled.openerp, .openerp td.oe_form_field_text_ckeditor4_raw { + /* here we need to reset openerp's styles to + * have the HTML display as (probably) intended + */ + white-space: normal; +} diff --git a/web_ckeditor4/static/src/img/icon.png b/web_ckeditor4/static/src/img/icon.png new file mode 100644 index 00000000..841a7ed0 Binary files /dev/null and b/web_ckeditor4/static/src/img/icon.png differ diff --git a/web_ckeditor4/static/src/js/ckeditor_basepath.js b/web_ckeditor4/static/src/js/ckeditor_basepath.js new file mode 100644 index 00000000..930a6c40 --- /dev/null +++ b/web_ckeditor4/static/src/js/ckeditor_basepath.js @@ -0,0 +1 @@ +CKEDITOR_BASEPATH='/web_ckeditor4/static/lib/ckeditor/' diff --git a/web_ckeditor4/static/src/js/web_ckeditor4.js b/web_ckeditor4/static/src/js/web_ckeditor4.js new file mode 100644 index 00000000..3fc59675 --- /dev/null +++ b/web_ckeditor4/static/src/js/web_ckeditor4.js @@ -0,0 +1,217 @@ +/* -*- encoding: utf-8 -*- +############################################################################## +# +# OpenERP, Open Source Management Solution +# This module copyright (C) 2013 Therp BV () +# 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 . +# +############################################################################*/ + +openerp.web_ckeditor4 = function(openerp) +{ + 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(CKEDITOR.instances[self.editor.name]) + { + 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.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; + } + }); + }); + }); + + openerp.web.form.widgets.add('text_ckeditor4', + 'openerp.web_ckeditor4.FieldCKEditor4'); + openerp.web.form.widgets.add('text_ckeditor4_raw', + 'openerp.web_ckeditor4.FieldCKEditor4Raw'); + openerp.web.form.widgets.add('text_html', + 'openerp.web_ckeditor4.FieldCKEditor4'); + openerp.web.form.widgets.add('html', + 'openerp.web_ckeditor4.FieldCKEditor4'); + + 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(); + }; + + 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, + }); + default_ckeditor_writer = new CKEDITOR.htmlParser.basicWriter(); + + openerp.web_ckeditor4.FieldCKEditor4 = openerp.web.form.FieldText.extend({ + ckeditor_config: { + removePlugins: 'iframe,flash,forms,smiley,pagebreak,stylescombo', + filebrowserImageUploadUrl: 'dummy', + extraPlugins: 'filebrowser', + }, + ckeditor_filter: default_ckeditor_filter, + ckeditor_writer: default_ckeditor_writer, + start: function() + { + this._super.apply(this, arguments); + + CKEDITOR.lang.load(openerp.session.user_context.lang.split('_')[0], 'en', function() {}); + }, + initialize_content: function() + { + var self = this; + this._super.apply(this, arguments); + if(!this.$textarea) + { + return; + } + this.editor = CKEDITOR.replace(this.$textarea.get(0), + _.extend( + { + language: openerp.session.user_context.lang.split('_')[0], + on: + { + 'change': function() + { + self.store_dom_value(); + }, + }, + }, + this.ckeditor_config)); + }, + store_dom_value: function() + { + this.internal_set_value(this.editor ? this.editor.getData() : openerp.web.parse_value(this.get('value'), this)); + }, + filter_html: function(value) + { + return filter_html(value, this.ckeditor_filter, this.ckeditor_writer); + }, + render_value: function() + { + if(this.get("effective_readonly")) + { + this.$el.html(this.filter_html(this.get('value'))); + } + else + { + if(this.editor) + { + var self = this; + if(this.editor.status != 'ready') + { + var instanceReady = function() + { + self.editor.setData(self.get('value') || ''); + self.editor.removeListener('instanceReady', instanceReady); + }; + this.editor.on('instanceReady', instanceReady); + } + else + { + self.editor.setData(self.get('value') || ''); + } + } + } + }, + undelegateEvents: function() + { + this._cleanup_editor(); + return this._super.apply(this, arguments); + }, + _cleanup_editor: function() + { + if(this.editor) + { + CKEDITOR.remove(this.editor); + this.editor.removeAllListeners(); + this.editor = null; + } + }, + destroy_content: function() + { + this._cleanup_editor(); + } + }); + openerp.web_ckeditor4.FieldCKEditor4Raw = openerp.web_ckeditor4.FieldCKEditor4.extend({ + filter_html: function(value) + { + return value; + } + }); +} +