You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

219 lines
8.1 KiB

  1. /* -*- encoding: utf-8 -*-
  2. ##############################################################################
  3. #
  4. # OpenERP, Open Source Management Solution
  5. # This module copyright (C) 2013 Therp BV (<http://therp.nl>)
  6. # All Rights Reserved
  7. #
  8. # This program is free software: you can redistribute it and/or modify
  9. # it under the terms of the GNU Affero General Public License as
  10. # published by the Free Software Foundation, either version 3 of the
  11. # License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. # GNU Affero General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU Affero General Public License
  19. # along with this program. If not, see <http://www.gnu.org/licenses/>.
  20. #
  21. ############################################################################*/
  22. openerp.web_ckeditor4 = function(instance)
  23. {
  24. var ckeditor_addFunction_org = CKEDITOR.tools.addFunction;
  25. //this is a quite complicated way to kind of monkey patch the private
  26. //method onDomReady of ckeditor's plugin wysiwigarea, which causes problems
  27. //when the editor is about to be destroyed but because of OpenERP's
  28. //architecture updated one last time with its current value
  29. CKEDITOR.tools.addFunction = function(fn, scope)
  30. {
  31. if(scope && scope._ && scope._.attrChanges && scope._.detach)
  32. {
  33. var scope_reference = scope;
  34. return ckeditor_addFunction_org(function()
  35. {
  36. var self = this,
  37. self_arguments=arguments;
  38. setTimeout(function()
  39. {
  40. if(CKEDITOR.instances[self.editor.name])
  41. {
  42. fn.apply(self, self_arguments);
  43. }
  44. }, 0);
  45. }, scope);
  46. }
  47. return ckeditor_addFunction_org(fn, scope);
  48. };
  49. CKEDITOR.on('dialogDefinition', function(e)
  50. {
  51. _.each(e.data.definition.contents, function(element)
  52. {
  53. if(!element || element.filebrowser!='uploadButton')
  54. {
  55. return
  56. }
  57. _.each(element.elements, function(element)
  58. {
  59. if(!element.onClick || element.type!='fileButton')
  60. {
  61. return
  62. }
  63. var onClick_org = element.onClick;
  64. element.onClick = function(e1)
  65. {
  66. onClick_org.apply(this, arguments);
  67. _.each(jQuery('#'+this.domId).closest('table')
  68. .find('iframe').contents().find(':file')
  69. .get(0).files,
  70. function(file)
  71. {
  72. var reader = new FileReader();
  73. reader.onload = function(load_event)
  74. {
  75. CKEDITOR.tools.callFunction(
  76. e.editor._.filebrowserFn,
  77. load_event.target.result,
  78. '');
  79. }
  80. reader.readAsDataURL(file);
  81. });
  82. return false;
  83. }
  84. });
  85. });
  86. });
  87. instance.web.form.widgets.add('text_ckeditor4',
  88. 'instance.web_ckeditor4.FieldCKEditor4');
  89. instance.web.form.widgets.add('text_ckeditor4_raw',
  90. 'instance.web_ckeditor4.FieldCKEditor4Raw');
  91. instance.web.form.widgets.add('text_html',
  92. 'instance.web_ckeditor4.FieldCKEditor4');
  93. instance.web.form.widgets.add('html',
  94. 'instance.web_ckeditor4.FieldCKEditor4');
  95. function filter_html(value, ckeditor_filter, ckeditor_writer)
  96. {
  97. var fragment = CKEDITOR.htmlParser.fragment.fromHtml(value);
  98. ckeditor_filter.applyTo(fragment);
  99. ckeditor_writer.reset();
  100. fragment.writeHtml(ckeditor_writer);
  101. return ckeditor_writer.getHtml();
  102. };
  103. default_ckeditor_filter = new CKEDITOR.filter(
  104. {
  105. '*':
  106. {
  107. attributes: 'href,src,style,alt,width,height,dir',
  108. styles: '*',
  109. classes: '*',
  110. },
  111. '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,
  112. });
  113. default_ckeditor_writer = new CKEDITOR.htmlParser.basicWriter();
  114. instance.web_ckeditor4.FieldCKEditor4 = instance.web.form.FieldText.extend({
  115. ckeditor_config: {
  116. removePlugins: 'iframe,flash,forms,smiley,pagebreak,stylescombo',
  117. filebrowserImageUploadUrl: 'dummy',
  118. extraPlugins: 'filebrowser',
  119. // this is '#39' per default which screws up single quoted text in ${}
  120. entities_additional: '',
  121. },
  122. ckeditor_filter: default_ckeditor_filter,
  123. ckeditor_writer: default_ckeditor_writer,
  124. start: function()
  125. {
  126. this._super.apply(this, arguments);
  127. CKEDITOR.lang.load(instance.session.user_context.lang.split('_')[0], 'en', function() {});
  128. },
  129. initialize_content: function()
  130. {
  131. var self = this;
  132. this._super.apply(this, arguments);
  133. if(!this.$textarea)
  134. {
  135. return;
  136. }
  137. this.editor = CKEDITOR.replace(this.$textarea.get(0),
  138. _.extend(
  139. {
  140. language: instance.session.user_context.lang.split('_')[0],
  141. on:
  142. {
  143. 'change': function()
  144. {
  145. self.store_dom_value();
  146. },
  147. },
  148. },
  149. this.ckeditor_config));
  150. },
  151. store_dom_value: function()
  152. {
  153. this.internal_set_value(this.editor ? this.editor.getData() : instance.web.parse_value(this.get('value'), this));
  154. },
  155. filter_html: function(value)
  156. {
  157. return filter_html(value, this.ckeditor_filter, this.ckeditor_writer);
  158. },
  159. render_value: function()
  160. {
  161. if(this.get("effective_readonly"))
  162. {
  163. this.$el.html(this.filter_html(this.get('value')));
  164. }
  165. else
  166. {
  167. if(this.editor)
  168. {
  169. var self = this;
  170. if(this.editor.status != 'ready')
  171. {
  172. var instanceReady = function()
  173. {
  174. self.editor.setData(self.get('value') || '');
  175. self.editor.removeListener('instanceReady', instanceReady);
  176. };
  177. this.editor.on('instanceReady', instanceReady);
  178. }
  179. else
  180. {
  181. self.editor.setData(self.get('value') || '');
  182. }
  183. }
  184. }
  185. },
  186. undelegateEvents: function()
  187. {
  188. this._cleanup_editor();
  189. return this._super.apply(this, arguments);
  190. },
  191. _cleanup_editor: function()
  192. {
  193. if(this.editor)
  194. {
  195. CKEDITOR.remove(this.editor);
  196. this.editor.removeAllListeners();
  197. this.editor = null;
  198. }
  199. },
  200. destroy_content: function()
  201. {
  202. this._cleanup_editor();
  203. }
  204. });
  205. instance.web_ckeditor4.FieldCKEditor4Raw = instance.web_ckeditor4.FieldCKEditor4.extend({
  206. filter_html: function(value)
  207. {
  208. return value;
  209. }
  210. });
  211. }