Merge lp:~openerp-dev/openerp-web/trunk-mail-ie-chm into lp:openerp-web

Proposed by Christophe Matthieu (OpenERP)
Status: Work in progress
Proposed branch: lp:~openerp-dev/openerp-web/trunk-mail-ie-chm
Merge into: lp:openerp-web
Diff against target: 1326 lines (+378/-341)
2 files modified
addons/web/static/lib/cleditor/jquery.cleditor.js (+374/-336)
addons/web/static/src/js/view_form.js (+4/-5)
To merge this branch: bzr merge lp:~openerp-dev/openerp-web/trunk-mail-ie-chm
Reviewer Review Type Date Requested Status
OpenERP R&D Web Team Pending
Review via email: mp+139924@code.launchpad.net
To post a comment you must log in.
3613. By Christophe Matthieu (OpenERP)

[FIX] web cleditor: bind and trigger event change inside cleditor

3614. By Christophe Matthieu (OpenERP)

[IMP] cleditor: rewrite braces, spaces, ponctuation

3615. By Christophe Matthieu (OpenERP)

[IMP] web form: fieldtexthtml

3616. By Christophe Matthieu (OpenERP)

[IMP] cleditor: remove spaces

3617. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

Unmerged revisions

3617. By Christophe Matthieu (OpenERP)

[MERGE] from trunk

3616. By Christophe Matthieu (OpenERP)

[IMP] cleditor: remove spaces

3615. By Christophe Matthieu (OpenERP)

[IMP] web form: fieldtexthtml

3614. By Christophe Matthieu (OpenERP)

[IMP] cleditor: rewrite braces, spaces, ponctuation

3613. By Christophe Matthieu (OpenERP)

[FIX] web cleditor: bind and trigger event change inside cleditor

3612. By Christophe Matthieu (OpenERP)

[IMP] web form: change for cleditor field html

3611. By Christophe Matthieu (OpenERP)

[IMP] view_form: add console in cleditor for ie debugging

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'addons/web/static/lib/cleditor/jquery.cleditor.js'
2--- addons/web/static/lib/cleditor/jquery.cleditor.js 2012-10-29 14:35:27 +0000
3+++ addons/web/static/lib/cleditor/jquery.cleditor.js 2012-12-21 17:26:22 +0000
4@@ -12,7 +12,8 @@
5 // @output_file_name jquery.cleditor.min.js
6 // ==/ClosureCompiler==
7
8-(function($) {
9+(function ($) {
10+ 'use strict';
11
12 //==============
13 // jQuery Plugin
14@@ -25,93 +26,91 @@
15 width: 500, // width not including margins, borders or padding
16 height: 250, // height not including margins, borders or padding
17 controls: // controls to add to the toolbar
18- "bold italic underline strikethrough subscript superscript | font size " +
19- "style | color highlight removeformat | bullets numbering | outdent " +
20- "indent | alignleft center alignright justify | undo redo | " +
21- "rule image link unlink | cut copy paste pastetext | print source",
22+ 'bold italic underline strikethrough subscript superscript | font size ' +
23+ 'style | color highlight removeformat | bullets numbering | outdent ' +
24+ 'indent | alignleft center alignright justify | undo redo | ' +
25+ 'rule image link unlink | cut copy paste pastetext | print source',
26 colors: // colors in the color popup
27- "FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF " +
28- "CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F " +
29- "BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C " +
30- "999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C " +
31- "666 900 C60 C93 990 090 399 33F 60C 939 " +
32- "333 600 930 963 660 060 366 009 339 636 " +
33- "000 300 630 633 330 030 033 006 309 303",
34+ 'FFF FCC FC9 FF9 FFC 9F9 9FF CFF CCF FCF ' +
35+ 'CCC F66 F96 FF6 FF3 6F9 3FF 6FF 99F F9F ' +
36+ 'BBB F00 F90 FC6 FF0 3F3 6CC 3CF 66C C6C ' +
37+ '999 C00 F60 FC3 FC0 3C0 0CC 36F 63F C3C ' +
38+ '666 900 C60 C93 990 090 399 33F 60C 939 ' +
39+ '333 600 930 963 660 060 366 009 339 636 ' +
40+ '000 300 630 633 330 030 033 006 309 303',
41 fonts: // font names in the font popup
42- "Arial,Arial Black,Comic Sans MS,Courier New,Narrow,Garamond," +
43- "Georgia,Impact,Sans Serif,Serif,Tahoma,Trebuchet MS,Verdana",
44+ 'Arial, Arial Black, Comic Sans MS, Courier New, Narrow, Garamond, ' +
45+ 'Georgia, Impact, Sans Serif, Serif, Tahoma, Trebuchet MS, Verdana',
46 sizes: // sizes in the font size popup
47- "1,2,3,4,5,6,7",
48+ '1, 2, 3, 4, 5, 6, 7',
49 styles: // styles in the style popup
50- [["Paragraph", "<p>"], ["Header 1", "<h1>"], ["Header 2", "<h2>"],
51- ["Header 3", "<h3>"], ["Header 4","<h4>"], ["Header 5","<h5>"],
52- ["Header 6","<h6>"]],
53+ [['Paragraph', '<p>'], ['Header 1', '<h1>'], ['Header 2', '<h2>'],
54+ ['Header 3', '<h3>'], ['Header 4', '<h4>'], ['Header 5', '<h5>'],
55+ ['Header 6', '<h6>']],
56 useCSS: false, // use CSS to style HTML when possible (not supported in ie)
57 docType: // Document type contained within the editor
58- '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
59+ '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">',
60 docCSSFile: // CSS file used to style the document contained within the editor
61- "",
62+ '',
63 bodyStyle: // style to assign to document body contained within the editor
64- "margin:4px; font:10pt Arial,Verdana; cursor:text"
65- },
66-
67+ 'margin:4px; font:10pt Arial, Verdana; cursor:text'
68+ },
69 // Define all usable toolbar buttons - the init string property is
70 // expanded during initialization back into the buttons object and
71 // seperate object properties are created for each button.
72- // e.g. buttons.size.title = "Font Size"
73+ // e.g. buttons.size.title = 'Font Size'
74 buttons: {
75- // name,title,command,popupName (""=use name)
76+ // name, title, command, popupName (''=use name)
77 init:
78- "bold,,|" +
79- "italic,,|" +
80- "underline,,|" +
81- "strikethrough,,|" +
82- "subscript,,|" +
83- "superscript,,|" +
84- "font,,fontname,|" +
85- "size,Font Size,fontsize,|" +
86- "style,,formatblock,|" +
87- "color,Font Color,forecolor,|" +
88- "highlight,Text Highlight Color,hilitecolor,color|" +
89- "removeformat,Remove Formatting,|" +
90- "bullets,,insertunorderedlist|" +
91- "numbering,,insertorderedlist|" +
92- "outdent,,|" +
93- "indent,,|" +
94- "alignleft,Align Text Left,justifyleft|" +
95- "center,,justifycenter|" +
96- "alignright,Align Text Right,justifyright|" +
97- "justify,,justifyfull|" +
98- "undo,,|" +
99- "redo,,|" +
100- "rule,Insert Horizontal Rule,inserthorizontalrule|" +
101- "image,Insert Image,insertimage,url|" +
102- "link,Insert Hyperlink,createlink,url|" +
103- "unlink,Remove Hyperlink,|" +
104- "cut,,|" +
105- "copy,,|" +
106- "paste,,|" +
107- "pastetext,Paste as Text,inserthtml,|" +
108- "print,,|" +
109- "source,Show Source"
110- },
111-
112+ 'bold,,|' +
113+ 'italic,,|' +
114+ 'underline,,|' +
115+ 'strikethrough,,|' +
116+ 'subscript,,|' +
117+ 'superscript,,|' +
118+ 'font,,fontname,|' +
119+ 'size,Font Size,fontsize,|' +
120+ 'style,,formatblock,|' +
121+ 'color,Font Color,forecolor,|' +
122+ 'highlight,Text Highlight Color,hilitecolor,color|' +
123+ 'removeformat,Remove Formatting,|' +
124+ 'bullets,,insertunorderedlist|' +
125+ 'numbering,,insertorderedlist|' +
126+ 'outdent,,|' +
127+ 'indent,,|' +
128+ 'alignleft,Align Text Left,justifyleft|' +
129+ 'center,,justifycenter|' +
130+ 'alignright,Align Text Right,justifyright|' +
131+ 'justify,,justifyfull|' +
132+ 'undo,,|' +
133+ 'redo,,|' +
134+ 'rule,Insert Horizontal Rule,inserthorizontalrule|' +
135+ 'image,Insert Image,insertimage,url|' +
136+ 'link,Insert Hyperlink,createlink,url|' +
137+ 'unlink,Remove Hyperlink,|' +
138+ 'cut,,|' +
139+ 'copy,,|' +
140+ 'paste,,|' +
141+ 'pastetext,Paste as Text,inserthtml,|' +
142+ 'print,,|' +
143+ 'source,Show Source'
144+ },
145 // imagesPath - returns the path to the images folder
146- imagesPath: function() { return imagesPath(); }
147+ imagesPath: function () { return imagesPath(); }
148
149 };
150
151 // cleditor - creates a new editor for each of the matched textareas
152- $.fn.cleditor = function(options) {
153+ $.fn.cleditor = function (options) {
154
155 // Create a new jQuery object to hold the results
156 var $result = $([]);
157
158 // Loop through all matching textareas and create the editors
159- this.each(function(idx, elem) {
160- if (elem.tagName == "TEXTAREA") {
161+ this.each(function (idx, elem) {
162+ if (elem.tagName === 'TEXTAREA') {
163 var data = $.data(elem, CLEDITOR);
164- if (!data) data = new cleditor(elem, options);
165+ if (!data) {data = new cleditor(elem, options);}
166 $result = $result.add(data);
167 }
168 });
169@@ -128,45 +127,40 @@
170 var
171
172 // Misc constants
173- BACKGROUND_COLOR = "backgroundColor",
174- BUTTON = "button",
175- BUTTON_NAME = "buttonName",
176- CHANGE = "change",
177- CLEDITOR = "cleditor",
178- CLICK = "click",
179- DISABLED = "disabled",
180- DIV_TAG = "<div>",
181- TRANSPARENT = "transparent",
182- UNSELECTABLE = "unselectable",
183-
184- // Class name constants
185- MAIN_CLASS = "cleditorMain", // main containing div
186- TOOLBAR_CLASS = "cleditorToolbar", // toolbar div inside main div
187- GROUP_CLASS = "cleditorGroup", // group divs inside the toolbar div
188- BUTTON_CLASS = "cleditorButton", // button divs inside group div
189- DISABLED_CLASS = "cleditorDisabled",// disabled button divs
190- DIVIDER_CLASS = "cleditorDivider", // divider divs inside group div
191- POPUP_CLASS = "cleditorPopup", // popup divs inside body
192- LIST_CLASS = "cleditorList", // list popup divs inside body
193- COLOR_CLASS = "cleditorColor", // color popup div inside body
194- PROMPT_CLASS = "cleditorPrompt", // prompt popup divs inside body
195- MSG_CLASS = "cleditorMsg", // message popup div inside body
196-
197- // Test for ie
198- ie = $.browser.msie,
199- ie6 = /msie\s6/i.test(navigator.userAgent),
200-
201- // Test for iPhone/iTouch/iPad
202- iOS = /iphone|ipad|ipod/i.test(navigator.userAgent),
203-
204- // Popups are created once as needed and shared by all editor instances
205- popups = {},
206-
207- // Used to prevent the document click event from being bound more than once
208- documentClickAssigned,
209-
210- // Local copy of the buttons object
211- buttons = $.cleditor.buttons;
212+ BACKGROUND_COLOR = 'backgroundColor',
213+ BUTTON = 'button',
214+ BUTTON_NAME = 'buttonName',
215+ CHANGE = 'change',
216+ CLEDITOR = 'cleditor',
217+ CLICK = 'click',
218+ DISABLED = 'disabled',
219+ DIV_TAG = '<div>',
220+ TRANSPARENT = 'transparent',
221+ UNSELECTABLE = 'unselectable',
222+ // Class name constants
223+ MAIN_CLASS = 'cleditorMain', // main containing div
224+ TOOLBAR_CLASS = 'cleditorToolbar', // toolbar div inside main div
225+ GROUP_CLASS = 'cleditorGroup', // group divs inside the toolbar div
226+ BUTTON_CLASS = 'cleditorButton', // button divs inside group div
227+ DISABLED_CLASS = 'cleditorDisabled', // disabled button divs
228+ DIVIDER_CLASS = 'cleditorDivider', // divider divs inside group div
229+ POPUP_CLASS = 'cleditorPopup', // popup divs inside body
230+ LIST_CLASS = 'cleditorList', // list popup divs inside body
231+ COLOR_CLASS = 'cleditorColor', // color popup div inside body
232+ PROMPT_CLASS = 'cleditorPrompt', // prompt popup divs inside body
233+ MSG_CLASS = 'cleditorMsg', // message popup div inside body
234+
235+ // Test for ie
236+ ie = $.browser.msie,
237+ ie6 = /msie\s6/i.test(navigator.userAgent),
238+ // Test for iPhone/iTouch/iPad
239+ iOS = /iphone|ipad|ipod/i.test(navigator.userAgent),
240+ // Popups are created once as needed and shared by all editor instances
241+ popups = {},
242+ // Used to prevent the document click event from being bound more than once
243+ documentClickAssigned,
244+ // Local copy of the buttons object
245+ buttons = $.cleditor.buttons;
246
247 //===============
248 // Initialization
249@@ -174,15 +168,15 @@
250
251 // Expand the buttons.init string back into the buttons object
252 // and create seperate object properties for each button.
253- // e.g. buttons.size.title = "Font Size"
254- $.each(buttons.init.split("|"), function(idx, button) {
255- var items = button.split(","), name = items[0];
256+ // e.g. buttons.size.title = 'Font Size'
257+ $.each(buttons.init.split('|'), function (idx, button) {
258+ var items = button.split(','), name = items[0];
259 buttons[name] = {
260- stripIndex: idx,
261- name: name,
262- title: items[1] === "" ? name.charAt(0).toUpperCase() + name.substr(1) : items[1],
263- command: items[2] === "" ? name : items[2],
264- popupName: items[3] === "" ? name : items[3]
265+ stripIndex: idx,
266+ name: name,
267+ title: items[1] === '' ? name.charAt(0).toUpperCase() + name.substr(1) : items[1],
268+ command: items[2] === '' ? name : items[2],
269+ popupName: items[3] === '' ? name : items[3]
270 };
271 });
272 delete buttons.init;
273@@ -192,7 +186,7 @@
274 //============
275
276 // cleditor - creates a new editor for the passed in textarea element
277- cleditor = function(area, options) {
278+ var cleditor = function (area, options) {
279
280 var editor = this;
281
282@@ -203,7 +197,7 @@
283 var $area = editor.$area = $(area)
284 .hide()
285 .data(CLEDITOR, editor)
286- .blur(function() {
287+ .blur(function () {
288 // Update the iframe when the textarea loses focus
289 updateFrame(editor, true);
290 });
291@@ -225,11 +219,11 @@
292 .appendTo($toolbar);
293
294 // Add the buttons to the toolbar
295- $.each(options.controls.split(" "), function(idx, buttonName) {
296- if (buttonName === "") return true;
297+ $.each(options.controls.split(' '), function (idx, buttonName) {
298+ if (buttonName === '') {return true;}
299
300 // Divider
301- if (buttonName == "|") {
302+ if (buttonName === '|') {
303
304 // Add a new divider to the group
305 var $div = $(DIV_TAG)
306@@ -253,27 +247,28 @@
307 var $buttonDiv = $(DIV_TAG)
308 .data(BUTTON_NAME, button.name)
309 .addClass(BUTTON_CLASS)
310- .attr("title", button.title)
311+ .attr('title', button.title)
312 .bind(CLICK, $.proxy(buttonClick, editor))
313 .appendTo($group)
314 .hover(hoverEnter, hoverLeave);
315
316 // Prepare the button image
317 var map = {};
318- if (button.css) map = button.css;
319- else if (button.image) map.backgroundImage = imageUrl(button.image);
320- if (button.stripIndex) map.backgroundPosition = button.stripIndex * -24;
321+ if (button.css) {map = button.css;}
322+ else if (button.image) {map.backgroundImage = imageUrl(button.image);}
323+ if (button.stripIndex) {map.backgroundPosition = button.stripIndex * -24;}
324 $buttonDiv.css(map);
325
326 // Add the unselectable attribute for ie
327- if (ie)
328- $buttonDiv.attr(UNSELECTABLE, "on");
329+ if (ie) {
330+ $buttonDiv.attr(UNSELECTABLE, 'on');
331+ }
332
333 // Create the popup
334- if (button.popupName)
335- createPopup(button.popupName, options, button.popupClass,
336+ if (button.popupName) {
337+ createPopup(button.popupName, options, button.popupClass,
338 button.popupContent, button.popupHover);
339-
340+ }
341 }
342
343 });
344@@ -284,23 +279,25 @@
345
346 // Bind the document click event handler
347 if (!documentClickAssigned) {
348- $(document).click(function(e) {
349+ $(document).click(function (e) {
350 // Dismiss all non-prompt popups
351 var $target = $(e.target);
352- if (!$target.add($target.parents()).is("." + PROMPT_CLASS))
353+ if (!$target.add($target.parents()).is('.' + PROMPT_CLASS)) {
354 hidePopups();
355+ }
356 });
357 documentClickAssigned = true;
358 }
359
360 // Bind the window resize event when the width or height is auto or %
361- if (/auto|%/.test("" + options.width + options.height))
362- $(window).resize(function() {
363+ if (/auto|%/.test('' + options.width + options.height)) {
364+ $(window).resize(function () {
365 // CHM Note MonkeyPatch: if the DOM is not remove, refresh the cleditor
366 if(editor.$main.parent().parent().size()) {
367 refresh(editor);
368 }
369 });
370+ }
371
372 // Create the iframe and resize the controls
373 refresh(editor);
374@@ -311,40 +308,39 @@
375 // Public Methods
376 //===============
377
378- var fn = cleditor.prototype,
379-
380+ var fn = cleditor.prototype,
381 // Expose the following private functions as methods on the cleditor object.
382 // The closure compiler will rename the private functions. However, the
383 // exposed method names on the cleditor object will remain fixed.
384 methods = [
385- ["clear", clear],
386- ["disable", disable],
387- ["execCommand", execCommand],
388- ["focus", focus],
389- ["hidePopups", hidePopups],
390- ["sourceMode", sourceMode, true],
391- ["refresh", refresh],
392- ["select", select],
393- ["selectedHTML", selectedHTML, true],
394- ["selectedText", selectedText, true],
395- ["showMessage", showMessage],
396- ["updateFrame", updateFrame],
397- ["updateTextArea", updateTextArea]
398+ ['clear', clear],
399+ ['disable', disable],
400+ ['execCommand', execCommand],
401+ ['focus', focus],
402+ ['hidePopups', hidePopups],
403+ ['sourceMode', sourceMode, true],
404+ ['refresh', refresh],
405+ ['select', select],
406+ ['selectedHTML', selectedHTML, true],
407+ ['selectedText', selectedText, true],
408+ ['showMessage', showMessage],
409+ ['updateFrame', updateFrame],
410+ ['updateTextArea', updateTextArea]
411 ];
412
413- $.each(methods, function(idx, method) {
414- fn[method[0]] = function() {
415+ $.each(methods, function (idx, method) {
416+ fn[method[0]] = function () {
417 var editor = this, args = [editor];
418 // using each here would cast booleans into objects!
419 for(var x = 0; x < arguments.length; x++) {args.push(arguments[x]);}
420 var result = method[1].apply(editor, args);
421- if (method[2]) return result;
422+ if (method[2]) {return result;}
423 return editor;
424 };
425 });
426
427- // change - shortcut for .bind("change", handler) or .trigger("change")
428- fn.change = function(handler) {
429+ // change - shortcut for .bind('change', handler) or .trigger('change')
430+ fn.change = function (handler) {
431 var $this = $(this);
432 return handler ? $this.bind(CHANGE, handler) : $this.trigger(CHANGE);
433 };
434@@ -356,33 +352,35 @@
435 // buttonClick - click event handler for toolbar buttons
436 function buttonClick(e) {
437
438- var editor = this,
439- buttonDiv = e.target,
440- buttonName = $.data(buttonDiv, BUTTON_NAME),
441- button = buttons[buttonName],
442- popupName = button.popupName,
443+ var editor = this,
444+ buttonDiv = e.target,
445+ buttonName = $.data(buttonDiv, BUTTON_NAME),
446+ button = buttons[buttonName],
447+ popupName = button.popupName,
448 popup = popups[popupName];
449
450 // Check if disabled
451- if (editor.disabled || $(buttonDiv).attr(DISABLED) == DISABLED)
452+ if (editor.disabled || $(buttonDiv).attr(DISABLED) === DISABLED) {
453 return;
454+ }
455
456 // Fire the buttonClick event
457 var data = {
458- editor: editor,
459- button: buttonDiv,
460- buttonName: buttonName,
461- popup: popup,
462- popupName: popupName,
463- command: button.command,
464+ editor: editor,
465+ button: buttonDiv,
466+ buttonName: buttonName,
467+ popup: popup,
468+ popupName: popupName,
469+ command: button.command,
470 useCSS: editor.options.useCSS
471 };
472
473- if (button.buttonClick && button.buttonClick(e, data) === false)
474+ if (button.buttonClick && button.buttonClick(e, data) === false) {
475 return false;
476+ }
477
478 // Toggle source
479- if (buttonName == "source") {
480+ if (buttonName === 'source') {
481
482 // Show the iframe
483 if (sourceMode(editor)) {
484@@ -396,12 +394,12 @@
485 else {
486 editor.$frame.hide();
487 editor.$area.show();
488- buttonDiv.title = "Show Rich Text";
489+ buttonDiv.title = 'Show Rich Text';
490 }
491
492 // Enable or disable the toolbar buttons
493 // IE requires the timeout
494- setTimeout(function() {refreshButtons(editor);}, 100);
495+ setTimeout(function () {refreshButtons(editor);}, 100);
496
497 }
498
499@@ -413,27 +411,28 @@
500 var $popup = $(popup);
501
502 // URL
503- if (popupName == "url") {
504+ if (popupName === 'url') {
505
506 // Check for selection before showing the link url popup
507- if (buttonName == "link" && selectedText(editor) === "") {
508- showMessage(editor, "A selection is required when inserting a link.", buttonDiv);
509+ if (buttonName === 'link' && selectedText(editor) === '') {
510+ showMessage(editor, 'A selection is required when inserting a link.', buttonDiv);
511 return false;
512 }
513
514 // Wire up the submit button click event handler
515- $popup.children(":button")
516+ $popup.children(':button')
517 .unbind(CLICK)
518- .bind(CLICK, function() {
519+ .bind(CLICK, function () {
520
521 // Insert the image or link if a url was entered
522- var $text = $popup.find(":text"),
523+ var $text = $popup.find(':text'),
524 url = $.trim($text.val());
525- if (url !== "")
526+ if (url !== '') {
527 execCommand(editor, data.command, url, null, data.button);
528+ }
529
530 // Reset the text, hide the popup and set focus
531- $text.val("http://");
532+ $text.val('http://');
533 hidePopups();
534 focus(editor);
535
536@@ -442,21 +441,22 @@
537 }
538
539 // Paste as Text
540- else if (popupName == "pastetext") {
541+ else if (popupName === 'pastetext') {
542
543 // Wire up the submit button click event handler
544- $popup.children(":button")
545+ $popup.children(':button')
546 .unbind(CLICK)
547- .bind(CLICK, function() {
548+ .bind(CLICK, function () {
549
550 // Insert the unformatted text replacing new lines with break tags
551- var $textarea = $popup.find("textarea"),
552- text = $textarea.val().replace(/\n/g, "<br />");
553- if (text !== "")
554+ var $textarea = $popup.find('textarea'),
555+ text = $textarea.val().replace(/\n/g, '<br />');
556+ if (text !== '') {
557 execCommand(editor, data.command, text, null, data.button);
558+ }
559
560 // Reset the text, hide the popup and set focus
561- $textarea.val("");
562+ $textarea.val('');
563 hidePopups();
564 focus(editor);
565
566@@ -476,12 +476,14 @@
567 }
568
569 // Print
570- else if (buttonName == "print")
571+ else if (buttonName === 'print') {
572 editor.$frame[0].contentWindow.print();
573+ }
574
575 // All other buttons
576- else if (!execCommand(editor, data.command, data.value, data.useCSS, buttonDiv))
577+ else if (!execCommand(editor, data.command, data.value, data.useCSS, buttonDiv)) {
578 return false;
579+ }
580
581 }
582
583@@ -492,71 +494,78 @@
584
585 // hoverEnter - mouseenter event handler for buttons and popup items
586 function hoverEnter(e) {
587- var $div = $(e.target).closest("div");
588- $div.css(BACKGROUND_COLOR, $div.data(BUTTON_NAME) ? "#FFF" : "#FFC");
589+ var $div = $(e.target).closest('div');
590+ $div.css(BACKGROUND_COLOR, $div.data(BUTTON_NAME) ? '#FFF' : '#FFC');
591 }
592
593 // hoverLeave - mouseleave event handler for buttons and popup items
594 function hoverLeave(e) {
595- $(e.target).closest("div").css(BACKGROUND_COLOR, "transparent");
596+ $(e.target).closest('div').css(BACKGROUND_COLOR, 'transparent');
597 }
598
599 // popupClick - click event handler for popup items
600 function popupClick(e) {
601
602- var editor = this,
603- popup = e.data.popup,
604+ var editor = this,
605+ popup = e.data.popup,
606 target = e.target;
607
608 // Check for message and prompt popups
609- if (popup === popups.msg || $(popup).hasClass(PROMPT_CLASS))
610+ if (popup === popups.msg || $(popup).hasClass(PROMPT_CLASS)) {
611 return;
612+ }
613
614 // Get the button info
615- var buttonDiv = $.data(popup, BUTTON),
616- buttonName = $.data(buttonDiv, BUTTON_NAME),
617- button = buttons[buttonName],
618- command = button.command,
619- value,
620+ var buttonDiv = $.data(popup, BUTTON),
621+ buttonName = $.data(buttonDiv, BUTTON_NAME),
622+ button = buttons[buttonName],
623+ command = button.command,
624+ value,
625 useCSS = editor.options.useCSS;
626
627 // Get the command value
628- if (buttonName == "font")
629+ if (buttonName === 'font') {
630 // Opera returns the fontfamily wrapped in quotes
631- value = target.style.fontFamily.replace(/"/g, "");
632- else if (buttonName == "size") {
633- if (target.tagName == "DIV")
634+ value = target.style.fontFamily.replace(/'/g, '');
635+ }
636+ else if (buttonName === 'size') {
637+ if (target.tagName === 'DIV') {
638 target = target.children[0];
639+ }
640 value = target.innerHTML;
641 }
642- else if (buttonName == "style")
643- value = "<" + target.tagName + ">";
644- else if (buttonName == "color")
645- value = hex(target.style.backgroundColor);
646- else if (buttonName == "highlight") {
647- value = hex(target.style.backgroundColor);
648- if (ie) command = 'backcolor';
649- else useCSS = true;
650+ else if (buttonName === 'style') {
651+ value = '<' + target.tagName + '>';
652+ }
653+ else if (buttonName === 'color') {
654+ value = hex(target.style.backgroundColor);
655+ }
656+ else if (buttonName === 'highlight') {
657+ value = hex(target.style.backgroundColor);
658+ if (ie) {command = 'backcolor';}
659+ else {useCSS = true;}
660 }
661
662 // Fire the popupClick event
663 var data = {
664- editor: editor,
665- button: buttonDiv,
666- buttonName: buttonName,
667- popup: popup,
668- popupName: button.popupName,
669- command: command,
670- value: value,
671+ editor: editor,
672+ button: buttonDiv,
673+ buttonName: buttonName,
674+ popup: popup,
675+ popupName: button.popupName,
676+ command: command,
677+ value: value,
678 useCSS: useCSS
679 };
680
681- if (button.popupClick && button.popupClick(e, data) === false)
682+ if (button.popupClick && button.popupClick(e, data) === false) {
683 return;
684+ }
685
686 // Execute the command
687- if (data.command && !execCommand(editor, data.command, data.value, data.useCSS, buttonDiv))
688+ if (data.command && !execCommand(editor, data.command, data.value, data.useCSS, buttonDiv)) {
689 return false;
690+ }
691
692 // Hide the popup and focus the editor
693 hidePopups();
694@@ -581,7 +590,7 @@
695
696 // clear - clears the contents of the editor
697 function clear(editor) {
698- editor.$area.val("");
699+ editor.$area.val('');
700 updateFrame(editor);
701 }
702
703@@ -589,82 +598,90 @@
704 function createPopup(popupName, options, popupTypeClass, popupContent, popupHover) {
705
706 // Check if popup already exists
707- if (popups[popupName])
708+ if (popups[popupName]) {
709 return popups[popupName];
710+ }
711
712 // Create the popup
713 var $popup = $(DIV_TAG)
714 .hide()
715 .addClass(POPUP_CLASS)
716- .appendTo("body");
717+ .appendTo('body');
718
719 // Add the content
720
721 // Custom popup
722- if (popupContent)
723+ if (popupContent) {
724 $popup.html(popupContent);
725+ }
726
727 // Color
728- else if (popupName == "color") {
729- var colors = options.colors.split(" ");
730- if (colors.length < 10)
731- $popup.width("auto");
732- $.each(colors, function(idx, color) {
733+ else if (popupName === 'color') {
734+ var colors = options.colors.split(' ');
735+ if (colors.length < 10) {
736+ $popup.width('auto');
737+ }
738+ $.each(colors, function (idx, color) {
739 $(DIV_TAG).appendTo($popup)
740- .css(BACKGROUND_COLOR, "#" + color);
741+ .css(BACKGROUND_COLOR, '#' + color);
742 });
743 popupTypeClass = COLOR_CLASS;
744 }
745
746 // Font
747- else if (popupName == "font")
748- $.each(options.fonts.split(","), function(idx, font) {
749+ else if (popupName === 'font') {
750+ $.each(options.fonts.split(','), function (idx, font) {
751 $(DIV_TAG).appendTo($popup)
752- .css("fontFamily", font)
753+ .css('fontFamily', font)
754 .html(font);
755 });
756+ }
757
758 // Size
759- else if (popupName == "size")
760- $.each(options.sizes.split(","), function(idx, size) {
761+ else if (popupName === 'size') {
762+ $.each(options.sizes.split(','), function (idx, size) {
763 $(DIV_TAG).appendTo($popup)
764- .html("<font size=" + size + ">" + size + "</font>");
765+ .html('<font size=' + size + '>' + size + '</font>');
766 });
767+ }
768
769 // Style
770- else if (popupName == "style")
771- $.each(options.styles, function(idx, style) {
772+ else if (popupName === 'style') {
773+ $.each(options.styles, function (idx, style) {
774 $(DIV_TAG).appendTo($popup)
775- .html(style[1] + style[0] + style[1].replace("<", "</"));
776+ .html(style[1] + style[0] + style[1].replace('<', '</'));
777 });
778+ }
779
780 // URL
781- else if (popupName == "url") {
782+ else if (popupName === 'url') {
783 $popup.html('Enter URL:<br><input type=text value="http://" size=35><br><input type=button value="Submit">');
784 popupTypeClass = PROMPT_CLASS;
785 }
786
787 // Paste as Text
788- else if (popupName == "pastetext") {
789+ else if (popupName === 'pastetext') {
790 $popup.html('Paste your content here and click submit.<br /><textarea cols=40 rows=3></textarea><br /><input type=button value=Submit>');
791 popupTypeClass = PROMPT_CLASS;
792 }
793
794 // Add the popup type class name
795- if (!popupTypeClass && !popupContent)
796+ if (!popupTypeClass && !popupContent) {
797 popupTypeClass = LIST_CLASS;
798+ }
799 $popup.addClass(popupTypeClass);
800
801 // Add the unselectable attribute to all items
802 if (ie) {
803- $popup.attr(UNSELECTABLE, "on")
804- .find("div,font,p,h1,h2,h3,h4,h5,h6")
805- .attr(UNSELECTABLE, "on");
806+ $popup.attr(UNSELECTABLE, 'on')
807+ .find('div, font, p, h1, h2, h3, h4, h5, h6')
808+ .attr(UNSELECTABLE, 'on');
809 }
810
811 // Add the hover effect to all items
812- if ($popup.hasClass(LIST_CLASS) || popupHover === true)
813+ if ($popup.hasClass(LIST_CLASS) || popupHover === true) {
814 $popup.children().hover(hoverEnter, hoverLeave);
815+ }
816
817 // Add the popup to the array and return it
818 popups[popupName] = $popup[0];
819@@ -687,10 +704,10 @@
820
821 // Switch the iframe into design mode.
822 // ie6 does not support designMode.
823- // ie7 & ie8 do not properly support designMode="off".
824+ // ie7 & ie8 do not properly support designMode='off'.
825 try {
826- if (ie) editor.doc.body.contentEditable = !disabled;
827- else editor.doc.designMode = !disabled ? "on" : "off";
828+ if (ie) {editor.doc.body.contentEditable = !disabled;}
829+ else {editor.doc.designMode = !disabled ? 'on' : 'off';}
830 }
831 // Firefox 1.5 throws an exception that can be ignored
832 // when toggling designMode from off to on.
833@@ -709,27 +726,31 @@
834
835 // Set the styling method
836 if (!ie) {
837- if (useCSS === undefined || useCSS === null)
838+ if (useCSS === undefined || useCSS === null) {
839 useCSS = editor.options.useCSS;
840- editor.doc.execCommand("styleWithCSS", 0, useCSS.toString());
841+ }
842+ editor.doc.execCommand('styleWithCSS', 0, useCSS.toString());
843 }
844
845 // Execute the command and check for error
846 var success = true, description;
847- if (ie && command.toLowerCase() == "inserthtml")
848+ if (ie && command.toLowerCase() === 'inserthtml') {
849 getRange(editor).pasteHTML(value);
850+ }
851 else {
852 try { success = editor.doc.execCommand(command, 0, value || null); }
853 catch (err) { description = err.description; success = false; }
854 if (!success) {
855- if ("cutcopypaste".indexOf(command) > -1)
856- showMessage(editor, "For security reasons, your browser does not support the " +
857- command + " command. Try using the keyboard shortcut or context menu instead.",
858- button);
859- else
860- showMessage(editor,
861- (description ? description : "Error executing the " + command + " command."),
862- button);
863+ if ('cutcopypaste'.indexOf(command) > -1) {
864+ showMessage(editor, 'For security reasons, your browser does not support the ' +
865+ command + ' command. Try using the keyboard shortcut or context menu instead.',
866+ button);
867+ }
868+ else {
869+ showMessage(editor,
870+ (description ? description : 'Error executing the ' + command + ' command.'),
871+ button);
872+ }
873 }
874 }
875
876@@ -741,43 +762,44 @@
877
878 // focus - sets focus to either the textarea or iframe
879 function focus(editor) {
880- setTimeout(function() {
881- if (sourceMode(editor)) editor.$area.focus();
882- else editor.$frame[0].contentWindow.focus();
883+ setTimeout(function () {
884+ if (sourceMode(editor)) {editor.$area.focus();}
885+ else {editor.$frame[0].contentWindow.focus();}
886 refreshButtons(editor);
887 }, 0);
888 }
889
890 // getRange - gets the current text range object
891 function getRange(editor) {
892- if (ie) return getSelection(editor).createRange();
893+ if (ie) {return getSelection(editor).createRange();}
894 return getSelection(editor).getRangeAt(0);
895 }
896
897 // getSelection - gets the current text range object
898 function getSelection(editor) {
899- if (ie) return editor.doc.selection;
900+ if (ie) {return editor.doc.selection;}
901 return editor.$frame[0].contentWindow.getSelection();
902 }
903
904 // Returns the hex value for the passed in string.
905- // hex("rgb(255, 0, 0)"); // #FF0000
906- // hex("#FF0000"); // #FF0000
907- // hex("#F00"); // #FF0000
908+ // hex('rgb(255, 0, 0)'); // #FF0000
909+ // hex('#FF0000'); // #FF0000
910+ // hex('#F00'); // #FF0000
911 function hex(s) {
912- var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s),
913- c = s.split("");
914+ var m = /rgba?\((\d+), (\d+), (\d+)/.exec(s),
915+ c = s.split('');
916 if (m) {
917 s = ( m[1] << 16 | m[2] << 8 | m[3] ).toString(16);
918- while (s.length < 6)
919- s = "0" + s;
920+ while (s.length < 6) {
921+ s = '0' + s;
922+ }
923 }
924- return "#" + (s.length == 6 ? s : c[1] + c[1] + c[2] + c[2] + c[3] + c[3]);
925+ return '#' + (s.length === 6 ? s : c[1] + c[1] + c[2] + c[2] + c[3] + c[3]);
926 }
927
928 // hidePopups - hides all popups
929 function hidePopups() {
930- $.each(popups, function(idx, popup) {
931+ $.each(popups, function (idx, popup) {
932 $(popup)
933 .hide()
934 .unbind(CLICK)
935@@ -787,25 +809,26 @@
936
937 // imagesPath - returns the path to the images folder
938 function imagesPath() {
939- var cssFile = "jquery.cleditor.css",
940- href = $("link[href$='" + cssFile +"']").attr("href");
941- return href.substr(0, href.length - cssFile.length) + "images/";
942+ var cssFile = 'jquery.cleditor.css',
943+ href = $('link[href$="' + cssFile +'"]').attr('href');
944+ return href.substr(0, href.length - cssFile.length) + 'images/';
945 }
946
947 // imageUrl - Returns the css url string for a filemane
948 function imageUrl(filename) {
949- return "url(" + imagesPath() + filename + ")";
950+ return 'url(' + imagesPath() + filename + ')';
951 }
952
953 // refresh - creates the iframe and resizes the controls
954 function refresh(editor) {
955
956- var $main = editor.$main,
957+ var $main = editor.$main,
958 options = editor.options;
959
960 // Remove the old iframe
961- if (editor.$frame)
962+ if (editor.$frame) {
963 editor.$frame.remove();
964+ }
965
966 // Create a new iframe
967 var $frame = editor.$frame = $('<iframe frameborder="0" src="javascript:true;">')
968@@ -813,8 +836,8 @@
969 .appendTo($main);
970
971 // Load the iframe document content
972- var contentWindow = $frame[0].contentWindow,
973- doc = editor.doc = contentWindow.document,
974+ var contentWindow = $frame[0].contentWindow,
975+ doc = editor.doc = contentWindow.document,
976 $doc = $(doc);
977
978 doc.open();
979@@ -828,8 +851,9 @@
980
981 // Work around for bug in IE which causes the editor to lose
982 // focus when clicking below the end of the document.
983- if (ie)
984- $doc.click(function() {focus(editor);});
985+ if (ie) {
986+ $doc.click(function () {focus(editor);});
987+ }
988
989 // Load the content
990 updateFrame(editor);
991@@ -840,60 +864,64 @@
992 // Save the current user selection. This code is needed since IE will
993 // reset the selection just after the beforedeactivate event and just
994 // before the beforeactivate event.
995- $doc.bind("beforedeactivate beforeactivate selectionchange keypress", function(e) {
996+ $doc.bind('beforedeactivate beforeactivate selectionchange keypress', function (e) {
997
998 // Flag the editor as inactive
999- if (e.type == "beforedeactivate")
1000+ if (e.type === 'beforedeactivate') {
1001 editor.inactive = true;
1002+ }
1003
1004 // Get rid of the bogus selection and flag the editor as active
1005- else if (e.type == "beforeactivate") {
1006- if (!editor.inactive && editor.range && editor.range.length > 1)
1007+ else if (e.type === 'beforeactivate') {
1008+ if (!editor.inactive && editor.range && editor.range.length > 1) {
1009 editor.range.shift();
1010+ }
1011 delete editor.inactive;
1012 }
1013
1014 // Save the selection when the editor is active
1015 else if (!editor.inactive) {
1016- if (!editor.range)
1017+ if (!editor.range) {
1018 editor.range = [];
1019+ }
1020 editor.range.unshift(getRange(editor));
1021
1022 // We only need the last 2 selections
1023- while (editor.range.length > 2)
1024+ while (editor.range.length > 2) {
1025 editor.range.pop();
1026+ }
1027 }
1028
1029 });
1030
1031 // Restore the text range when the iframe gains focus
1032- $frame.focus(function() {
1033+ $frame.focus(function () {
1034 restoreRange(editor);
1035 });
1036
1037 }
1038
1039 // Update the textarea when the iframe loses focus
1040- ($.browser.mozilla ? $doc : $(contentWindow)).blur(function() {
1041+ ($.browser.mozilla ? $doc : $(contentWindow)).blur(function () {
1042 updateTextArea(editor, true);
1043 });
1044
1045 // Enable the toolbar buttons as the user types or clicks
1046 $doc.click(hidePopups)
1047- .bind("keyup mouseup", function() {
1048+ .bind('keyup mouseup', function () {
1049 refreshButtons(editor);
1050 });
1051
1052 // Show the textarea for iPhone/iTouch/iPad or
1053 // the iframe when design mode is supported.
1054- if (iOS) editor.$area.show();
1055- else $frame.show();
1056+ if (iOS) {editor.$area.show();}
1057+ else {$frame.show();}
1058
1059 // Wait for the layout to finish - shortcut for $(document).ready()
1060- $(function() {
1061+ $(function () {
1062
1063- var $toolbar = editor.$toolbar,
1064- $group = $toolbar.children("div:last"),
1065+ var $toolbar = editor.$toolbar,
1066+ $group = $toolbar.children('div:last'),
1067 wid = $main.width();
1068
1069 // Resize the toolbar
1070@@ -901,7 +929,7 @@
1071 $toolbar.height(hgt);
1072
1073 // Resize the iframe
1074- hgt = (/%/.test("" + options.height) ? $main.height() : parseInt(options.height)) - hgt;
1075+ hgt = (/%/.test('' + options.height) ? $main.height() : parseInt(options.height)) - hgt;
1076 $frame.width(wid).height(hgt);
1077
1078 // Resize the textarea. IE6 textareas have a 1px top
1079@@ -930,42 +958,46 @@
1080
1081 // Get the object used for checking queryCommandEnabled
1082 var queryObj = editor.doc;
1083- if (ie) queryObj = getRange(editor);
1084+ if (ie) {queryObj = getRange(editor);}
1085
1086 // Loop through each button
1087 var inSourceMode = sourceMode(editor);
1088- $.each(editor.$toolbar.find("." + BUTTON_CLASS), function(idx, elem) {
1089+ $.each(editor.$toolbar.find('.' + BUTTON_CLASS), function (idx, elem) {
1090
1091- var $elem = $(elem),
1092- button = $.cleditor.buttons[$.data(elem, BUTTON_NAME)],
1093- command = button.command,
1094+ var $elem = $(elem),
1095+ button = $.cleditor.buttons[$.data(elem, BUTTON_NAME)],
1096+ command = button.command,
1097 enabled = true;
1098
1099 // Determine the state
1100- if (editor.disabled)
1101+ if (editor.disabled) {
1102 enabled = false;
1103+ }
1104 else if (button.getEnabled) {
1105 var data = {
1106- editor: editor,
1107- button: elem,
1108- buttonName: button.name,
1109- popup: popups[button.popupName],
1110- popupName: button.popupName,
1111- command: button.command,
1112+ editor: editor,
1113+ button: elem,
1114+ buttonName: button.name,
1115+ popup: popups[button.popupName],
1116+ popupName: button.popupName,
1117+ command: button.command,
1118 useCSS: editor.options.useCSS
1119 };
1120 enabled = button.getEnabled(data);
1121- if (enabled === undefined)
1122+ if (enabled === undefined) {
1123 enabled = true;
1124+ }
1125 }
1126- else if (((inSourceMode || iOS) && button.name != "source") ||
1127- (ie && (command == "undo" || command == "redo")))
1128+ else if (((inSourceMode || iOS) && button.name !== 'source') ||
1129+ (ie && (command === 'undo' || command === 'redo'))) {
1130 enabled = false;
1131- else if (command && command != "print") {
1132- if (ie && command == "hilitecolor")
1133- command = "backcolor";
1134+ }
1135+ else if (command && command !== 'print') {
1136+ if (ie && command === 'hilitecolor') {
1137+ command = 'backcolor';
1138+ }
1139 // IE does not support inserthtml, so it's always enabled
1140- if (!ie || command != "inserthtml") {
1141+ if (!ie || command !== 'inserthtml') {
1142 try {enabled = queryObj.queryCommandEnabled(command);}
1143 catch (err) {enabled = false;}
1144 }
1145@@ -986,15 +1018,16 @@
1146
1147 // restoreRange - restores the current ie selection
1148 function restoreRange(editor) {
1149- if (ie && editor.range)
1150+ if (ie && editor.range) {
1151 editor.range[0].select();
1152+ }
1153 }
1154
1155 // select - selects all the text in either the textarea or iframe
1156 function select(editor) {
1157- setTimeout(function() {
1158- if (sourceMode(editor)) editor.$area.select();
1159- else execCommand(editor, "selectall");
1160+ setTimeout(function () {
1161+ if (sourceMode(editor)) {editor.$area.select();}
1162+ else {execCommand(editor, 'selectall');}
1163 }, 0);
1164 }
1165
1166@@ -1002,9 +1035,10 @@
1167 function selectedHTML(editor) {
1168 restoreRange(editor);
1169 var range = getRange(editor);
1170- if (ie)
1171+ if (ie) {
1172 return range.htmlText;
1173- var layer = $("<layer>")[0];
1174+ }
1175+ var layer = $('<layer>')[0];
1176 layer.appendChild(range.cloneContents());
1177 var html = layer.innerHTML;
1178 layer = null;
1179@@ -1014,13 +1048,13 @@
1180 // selectedText - returns the current text selection or and empty string
1181 function selectedText(editor) {
1182 restoreRange(editor);
1183- if (ie) return getRange(editor).text;
1184+ if (ie) {return getRange(editor).text;}
1185 return getSelection(editor).toString();
1186 }
1187
1188 // showMessage - alert replacement
1189 function showMessage(editor, message, button) {
1190- var popup = createPopup("msg", editor.options, MSG_CLASS);
1191+ var popup = createPopup('msg', editor.options, MSG_CLASS);
1192 popup.innerHTML = message;
1193 showPopup(editor, popup, button);
1194 }
1195@@ -1056,31 +1090,32 @@
1196 }
1197
1198 // Focus the first input element if any
1199- setTimeout(function() {
1200- $popup.find(":text,textarea").eq(0).focus().select();
1201+ setTimeout(function () {
1202+ $popup.find(':text, textarea').eq(0).focus().select();
1203 }, 100);
1204
1205 }
1206
1207 // sourceMode - returns true if the textarea is showing
1208 function sourceMode(editor) {
1209- return editor.$area.is(":visible");
1210+ return editor.$area.is(':visible');
1211 }
1212
1213 // updateFrame - updates the iframe with the textarea contents
1214 function updateFrame(editor, checkForChange) {
1215
1216- var code = editor.$area.val(),
1217- options = editor.options,
1218- updateFrameCallback = options.updateFrame,
1219+ var code = editor.$area.val(),
1220+ options = editor.options,
1221+ updateFrameCallback = options.updateFrame,
1222 $body = $(editor.doc.body);
1223
1224 // Check for textarea change to avoid unnecessary firing
1225 // of potentially heavy updateFrame callbacks.
1226 if (updateFrameCallback) {
1227 var sum = checksum(code);
1228- if (checkForChange && editor.areaChecksum == sum)
1229+ if (checkForChange && editor.areaChecksum === sum) {
1230 return;
1231+ }
1232 editor.areaChecksum = sum;
1233 }
1234
1235@@ -1088,14 +1123,15 @@
1236 var html = updateFrameCallback ? updateFrameCallback(code) : code;
1237
1238 // Prevent script injection attacks by html encoding script tags
1239- html = html.replace(/<(?=\/?script)/ig, "&lt;");
1240+ html = html.replace(/<(?=\/?script)/ig, '&lt;');
1241
1242 // Update the iframe checksum
1243- if (options.updateTextArea)
1244+ if (options.updateTextArea) {
1245 editor.frameChecksum = checksum(html);
1246+ }
1247
1248 // Update the iframe and trigger the change event
1249- if (html != $body.html()) {
1250+ if (html !== $body.html()) {
1251 $body.html(html);
1252 $(editor).triggerHandler(CHANGE);
1253 }
1254@@ -1105,17 +1141,18 @@
1255 // updateTextArea - updates the textarea with the iframe contents
1256 function updateTextArea(editor, checkForChange) {
1257
1258- var html = $(editor.doc.body).html(),
1259- options = editor.options,
1260- updateTextAreaCallback = options.updateTextArea,
1261+ var html = $(editor.doc.body).html(),
1262+ options = editor.options,
1263+ updateTextAreaCallback = options.updateTextArea,
1264 $area = editor.$area;
1265
1266 // Check for iframe change to avoid unnecessary firing
1267 // of potentially heavy updateTextArea callbacks.
1268 if (updateTextAreaCallback) {
1269 var sum = checksum(html);
1270- if (checkForChange && editor.frameChecksum == sum)
1271+ if (checkForChange && editor.frameChecksum === sum) {
1272 return;
1273+ }
1274 editor.frameChecksum = sum;
1275 }
1276
1277@@ -1123,11 +1160,12 @@
1278 var code = updateTextAreaCallback ? updateTextAreaCallback(html) : html;
1279
1280 // Update the textarea checksum
1281- if (options.updateFrame)
1282+ if (options.updateFrame) {
1283 editor.areaChecksum = checksum(code);
1284+ }
1285
1286 // Update the textarea and trigger the change event
1287- if (code != $area.val()) {
1288+ if (code !== $area.val()) {
1289 $area.val(code);
1290 $(editor).triggerHandler(CHANGE);
1291 }
1292
1293=== modified file 'addons/web/static/src/js/view_form.js'
1294--- addons/web/static/src/js/view_form.js 2012-12-21 14:02:36 +0000
1295+++ addons/web/static/src/js/view_form.js 2012-12-21 17:26:22 +0000
1296@@ -2624,7 +2624,7 @@
1297 this.$textarea = this.$el.find('textarea');
1298 var width = ((this.node.attrs || {}).editor_width || '100%');
1299 var height = ((this.node.attrs || {}).editor_height || 250);
1300- this.$textarea.cleditor({
1301+ this.$cleditor = this.$textarea.cleditor({
1302 width: width, // width not including margins, borders or padding
1303 height: height, // height not including margins, borders or padding
1304 controls: // controls to add to the toolbar
1305@@ -2634,10 +2634,9 @@
1306 bodyStyle: // style to assign to document body contained within the editor
1307 "margin:4px; font:12px monospace; cursor:text; color:#1F1F1F"
1308 });
1309- this.$cleditor = this.$textarea.cleditor()[0];
1310- this.$cleditor.change(function() {
1311+ this.$cleditor.on('change', function() {
1312 if (! self._updating_editor) {
1313- self.$cleditor.updateTextArea();
1314+ self.$cleditor[0].updateTextArea();
1315 self.internal_set_value(self.$textarea.val());
1316 }
1317 });
1318@@ -2647,7 +2646,7 @@
1319 if (! this.get("effective_readonly")) {
1320 this.$textarea.val(this.get('value') || '');
1321 this._updating_editor = true;
1322- this.$cleditor.updateFrame();
1323+ this.$cleditor[0].updateFrame();
1324 this._updating_editor = false;
1325 } else {
1326 this.$el.html(this.get('value'));