From b84ecaacaa43d545c0b76931a7a42fe62517f8c4 Mon Sep 17 00:00:00 2001 From: Alan Date: Fri, 17 Feb 2023 14:29:57 +0800 Subject: [PATCH] Fix #7586 - more events for editor --- Roo/HtmlEditorCore.js | 2 +- Roo/bootstrap/form/HtmlEditor.js | 72 ++++++--- .../form/HtmlEditorToolbar/Standard.js | 34 +++- Roo/form/HtmlEditor.js | 3 +- docs/json/roodata.json | 128 ++++++++++++--- .../src/Roo_bootstrap_form_HtmlEditor.js.html | 70 +++++--- ...ap_form_HtmlEditorToolbar_Standard.js.html | 34 +++- docs/src/Roo_form_HtmlEditor.js.html | 5 +- .../Roo.bootstrap.form.HtmlEditor.json | 152 ++++++++++++++---- examples/bootstrap/Editor.js | 9 ++ roojs-all.js | 8 +- roojs-bootstrap-debug.js | 108 +++++++++---- roojs-bootstrap.js | 23 +-- roojs-debug.js | 14 +- roojs-ui-debug.js | 14 +- roojs-ui.js | 8 +- 16 files changed, 524 insertions(+), 160 deletions(-) diff --git a/Roo/HtmlEditorCore.js b/Roo/HtmlEditorCore.js index 967be2b70b..26d1cd0bf9 100644 --- a/Roo/HtmlEditorCore.js +++ b/Roo/HtmlEditorCore.js @@ -72,7 +72,7 @@ Roo.HtmlEditorCore = function(config){ * @param {Roo.HtmlEditorCore} this */ editorevent: true - + }); diff --git a/Roo/bootstrap/form/HtmlEditor.js b/Roo/bootstrap/form/HtmlEditor.js index 987a3d7533..448413edc6 100644 --- a/Roo/bootstrap/form/HtmlEditor.js +++ b/Roo/bootstrap/form/HtmlEditor.js @@ -16,31 +16,26 @@ */ Roo.bootstrap.form.HtmlEditor = function(config){ - Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this, config); - if (!this.toolbars) { - this.toolbars = []; - } - - this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config)); + this.addEvents({ /** * @event initialize * Fires when the editor is fully initialized (including the iframe) - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ initialize: true, /** * @event activate * Fires when the editor is first receives the focus. Any insertion must wait * until after this event. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ activate: true, /** * @event beforesync * Fires before the textarea is updated with content from the editor iframe. Return false * to cancel the sync. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ beforesync: true, @@ -48,56 +43,95 @@ Roo.bootstrap.form.HtmlEditor = function(config){ * @event beforepush * Fires before the iframe editor is updated with content from the textarea. Return false * to cancel the push. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ beforepush: true, /** * @event sync * Fires when the textarea is updated with content from the editor iframe. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ sync: true, /** * @event push * Fires when the iframe editor is updated with content from the textarea. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ push: true, /** * @event editmodechange * Fires when the editor switches edit modes - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {Boolean} sourceEdit True if source edit, false if standard editing. */ editmodechange: true, /** * @event editorevent * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ editorevent: true, /** * @event firstfocus * Fires when on first focus - needed by toolbars.. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ firstfocus: true, /** * @event autosave * Auto save the htmlEditor value as a file into Events - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ autosave: true, /** * @event savedpreview * preview the saved version of htmlEditor - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ - savedpreview: true - }); + savedpreview: true, + /** + * @event stylesheetsclick + * Fires when press the Sytlesheets button + * @param {Roo.HtmlEditorCore} this + */ + stylesheetsclick: true, + /** + * @event paste + * Fires when press user pastes into the editor + * @param {Roo.HtmlEditorCore} this + */ + paste: true, + /** + * @event imageadd + * Fires when on any editor when an image is added (excluding paste) + * @param {Roo.bootstrap.form.HtmlEditor} this + */ + imageadd: true , + /** + * @event imageupdated + * Fires when on any editor when an image is changed (excluding paste) + * @param {Roo.bootstrap.form.HtmlEditor} this + * @param {HTMLElement} img could also be a figure if blocks are enabled + */ + imageupdate: true , + /** + * @event imagedelete + * Fires when on any editor when an image is deleted + * @param {Roo.bootstrap.form.HtmlEditor} this + * @param {HTMLElement} img could also be a figure if blocks are enabled + */ + imagedelete: true + }); + Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this, config); + if (!this.toolbars) { + this.toolbars = []; + } + + this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config)); + }; diff --git a/Roo/bootstrap/form/HtmlEditorToolbar/Standard.js b/Roo/bootstrap/form/HtmlEditorToolbar/Standard.js index 108c25026b..72ccc6800b 100644 --- a/Roo/bootstrap/form/HtmlEditorToolbar/Standard.js +++ b/Roo/bootstrap/form/HtmlEditorToolbar/Standard.js @@ -221,19 +221,26 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp } - this.addFiles(Array.prototype.slice.call(this.input.dom.files)); + this.addFiles(Array.prototype.slice.call(this.input.dom.files), false); }, - addFiles : function(far) { + addFiles : function(far, fire_add) { + + var editor = this.editorcore; + if (!far.length) { + if (fire_add) { + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageadd', editor.owner, false); + } return; } var f = far.pop(); if (!f.type.match(/^image/)) { - this.addFiles(far); + this.addFiles(far, fire_add); return; } @@ -241,7 +248,6 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp var bl = sn && this.editorcore.enableBlocks ? Roo.htmleditor.Block.factory(sn) : false; - var editor = this.editorcore; var reader = new FileReader(); reader.addEventListener('load', (function() { @@ -249,7 +255,8 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp bl.image_src = reader.result; //bl.caption = f.name; bl.updateElement(sn); - editor.owner.fireEvent('editorevent', editor, false); + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageupdate', editor.owner, sn); // we only do the first file!! and replace. return; } @@ -260,17 +267,18 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp caption_display : 'none' //default to hide captions.. }); editor.insertAtCursor(fig.toHTML()); - editor.owner.fireEvent('editorevent', editor, false); + this.addFiles(far, true); return; } // just a standard img.. if (sn && sn.tagName.toUpperCase() == 'IMG') { sn.src = reader.result; - editor.owner.fireEvent('editorevent', editor, false); + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageupdate', editor.owner, sn); return; } editor.insertAtCursor(''); - editor.owner.fireEvent('editorevent', editor, false); + this.addFiles(far, true); }).createDelegate(this)); reader.readAsDataURL(f); @@ -436,6 +444,11 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp selection.removeAllRanges(); selection.addRange(range); this.updateToolbar(null, null, null); + if (sn.tagName.toUpperCase() == 'FIGURE') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); return; } @@ -455,6 +468,11 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp selection.removeAllRanges(); selection.addRange(range); + if (sn.tagName.toUpperCase() == 'IMG"') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); diff --git a/Roo/form/HtmlEditor.js b/Roo/form/HtmlEditor.js index a6baf6f37e..de06645be9 100644 --- a/Roo/form/HtmlEditor.js +++ b/Roo/form/HtmlEditor.js @@ -221,7 +221,8 @@ Roo.extend(Roo.form.HtmlEditor, Roo.form.Field, { * Fires when press user pastes into the editor * @param {Roo.HtmlEditorCore} this */ - paste: true + paste: true, + }); this.defaultAutoCreate = { tag: "textarea", diff --git a/docs/json/roodata.json b/docs/json/roodata.json index 820212758c..e5929846a9 100644 --- a/docs/json/roodata.json +++ b/docs/json/roodata.json @@ -134413,7 +134413,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134433,7 +134433,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134493,7 +134493,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -134559,7 +134559,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -134671,7 +134671,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -134697,7 +134697,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134737,7 +134737,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134777,6 +134777,78 @@ ], "returns" : [] }, + { + "name" : "imageadd", + "type" : "function", + "desc" : "Fires when on any editor when an image is added (excluding paste)", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", + "isOptional" : false + } + ], + "returns" : [] + }, + { + "name" : "imagedelete", + "type" : "function", + "desc" : "Fires when on any editor when an image is deleted", + "sig" : "function (_self, img)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", + "isOptional" : false + }, + { + "name" : "img", + "type" : "HTMLElement", + "desc" : "could also be a figure if blocks are enabled", + "isOptional" : false + } + ], + "returns" : [] + }, + { + "name" : "imageupdated", + "type" : "function", + "desc" : "Fires when on any editor when an image is changed (excluding paste)", + "sig" : "function (_self, img)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", + "isOptional" : false + }, + { + "name" : "img", + "type" : "HTMLElement", + "desc" : "could also be a figure if blocks are enabled", + "isOptional" : false + } + ], + "returns" : [] + }, { "name" : "initialize", "type" : "function", @@ -134790,7 +134862,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134852,9 +134924,9 @@ { "name" : "paste", "type" : "function", - "desc" : "Fires after the user pastes into input", - "sig" : "function (_self, e)\n{\n\n}", - "memberOf" : "Roo.bootstrap.form.Input", + "desc" : "Fires when press user pastes into the editor", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", "example" : "", "deprecated" : "", "since" : "", @@ -134862,15 +134934,9 @@ "params" : [ { "name" : "this", - "type" : "Roo.form.Field", + "type" : "Roo.HtmlEditorCore", "desc" : "", "isOptional" : false - }, - { - "name" : "e", - "type" : "Roo.EventObject", - "desc" : "The event Object", - "isOptional" : false } ], "returns" : [] @@ -134888,7 +134954,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -134934,7 +135000,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -134974,6 +135040,26 @@ "params" : [], "returns" : [] }, + { + "name" : "stylesheetsclick", + "type" : "function", + "desc" : "Fires when press the Sytlesheets button", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.HtmlEditorCore", + "desc" : "", + "isOptional" : false + } + ], + "returns" : [] + }, { "name" : "sync", "type" : "function", @@ -134987,7 +135073,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, diff --git a/docs/src/Roo_bootstrap_form_HtmlEditor.js.html b/docs/src/Roo_bootstrap_form_HtmlEditor.js.html index 52dbdb53cf..653ba0127f 100644 --- a/docs/src/Roo_bootstrap_form_HtmlEditor.js.html +++ b/docs/src/Roo_bootstrap_form_HtmlEditor.js.html @@ -16,31 +16,26 @@ */ Roo.bootstrap.form.HtmlEditor = function(config){ - Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this, config); - if (!this.toolbars) { - this.toolbars = []; - } - this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config)); this.addEvents({ /** * @event initialize * Fires when the editor is fully initialized (including the iframe) - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ initialize: true, /** * @event activate * Fires when the editor is first receives the focus. Any insertion must wait * until after this event. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ activate: true, /** * @event beforesync * Fires before the textarea is updated with content from the editor iframe. Return false * to cancel the sync. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ beforesync: true, @@ -48,56 +43,95 @@ * @event beforepush * Fires before the iframe editor is updated with content from the textarea. Return false * to cancel the push. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ beforepush: true, /** * @event sync * Fires when the textarea is updated with content from the editor iframe. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ sync: true, /** * @event push * Fires when the iframe editor is updated with content from the textarea. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {String} html */ push: true, /** * @event editmodechange * Fires when the editor switches edit modes - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this * @param {Boolean} sourceEdit True if source edit, false if standard editing. */ editmodechange: true, /** * @event editorevent * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ editorevent: true, /** * @event firstfocus * Fires when on first focus - needed by toolbars.. - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ firstfocus: true, /** * @event autosave * Auto save the htmlEditor value as a file into Events - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ autosave: true, /** * @event savedpreview * preview the saved version of htmlEditor - * @param {HtmlEditor} this + * @param {Roo.bootstrap.form.HtmlEditor} this */ - savedpreview: true - }); + savedpreview: true, + /** + * @event stylesheetsclick + * Fires when press the Sytlesheets button + * @param {Roo.HtmlEditorCore} this + */ + stylesheetsclick: true, + /** + * @event paste + * Fires when press user pastes into the editor + * @param {Roo.HtmlEditorCore} this + */ + paste: true, + /** + * @event imageadd + * Fires when on any editor when an image is added (excluding paste) + * @param {Roo.bootstrap.form.HtmlEditor} this + */ + imageadd: true , + /** + * @event imageupdated + * Fires when on any editor when an image is changed (excluding paste) + * @param {Roo.bootstrap.form.HtmlEditor} this + * @param {HTMLElement} img could also be a figure if blocks are enabled + */ + imageupdate: true , + /** + * @event imagedelete + * Fires when on any editor when an image is deleted + * @param {Roo.bootstrap.form.HtmlEditor} this + * @param {HTMLElement} img could also be a figure if blocks are enabled + */ + imagedelete: true + }); + Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this, config); + if (!this.toolbars) { + this.toolbars = []; + } + + this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config)); + }; diff --git a/docs/src/Roo_bootstrap_form_HtmlEditorToolbar_Standard.js.html b/docs/src/Roo_bootstrap_form_HtmlEditorToolbar_Standard.js.html index 7b28b6c9eb..21a44fd4e4 100644 --- a/docs/src/Roo_bootstrap_form_HtmlEditorToolbar_Standard.js.html +++ b/docs/src/Roo_bootstrap_form_HtmlEditorToolbar_Standard.js.html @@ -221,19 +221,26 @@ } - this.addFiles(Array.prototype.slice.call(this.input.dom.files)); + this.addFiles(Array.prototype.slice.call(this.input.dom.files), false); }, - addFiles : function(far) { + addFiles : function(far, fire_add) { + + + var editor = this.editorcore; if (!far.length) { + if (fire_add) { + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageadd', editor.owner, false); + } return; } var f = far.pop(); if (!f.type.match(/^image/)) { - this.addFiles(far); + this.addFiles(far, fire_add); return; } @@ -241,7 +248,6 @@ var bl = sn && this.editorcore.enableBlocks ? Roo.htmleditor.Block.factory(sn) : false; - var editor = this.editorcore; var reader = new FileReader(); reader.addEventListener('load', (function() { @@ -249,7 +255,8 @@ bl.image_src = reader.result; //bl.caption = f.name; bl.updateElement(sn); - editor.owner.fireEvent('editorevent', editor, false); + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageupdate', editor.owner, sn); // we only do the first file!! and replace. return; } @@ -260,17 +267,18 @@ caption_display : 'none' //default to hide captions.. }); editor.insertAtCursor(fig.toHTML()); - editor.owner.fireEvent('editorevent', editor, false); + this.addFiles(far, true); return; } // just a standard img.. if (sn && sn.tagName.toUpperCase() == 'IMG') { sn.src = reader.result; - editor.owner.fireEvent('editorevent', editor, false); + editor.owner.fireEvent('editorevent', editor.owner, false); + editor.owner.fireEvent('imageupdate', editor.owner, sn); return; } editor.insertAtCursor('<img src="' + reader.result +'">'); - editor.owner.fireEvent('editorevent', editor, false); + this.addFiles(far, true); }).createDelegate(this)); reader.readAsDataURL(f); @@ -436,6 +444,11 @@ selection.removeAllRanges(); selection.addRange(range); this.updateToolbar(null, null, null); + if (sn.tagName.toUpperCase() == 'FIGURE') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); return; } @@ -455,6 +468,11 @@ selection.removeAllRanges(); selection.addRange(range); + if (sn.tagName.toUpperCase() == 'IMG"') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); diff --git a/docs/src/Roo_form_HtmlEditor.js.html b/docs/src/Roo_form_HtmlEditor.js.html index 98dc47cfa0..7e651fcd0a 100644 --- a/docs/src/Roo_form_HtmlEditor.js.html +++ b/docs/src/Roo_form_HtmlEditor.js.html @@ -221,8 +221,9 @@ * Fires when press user pastes into the editor * @param {Roo.HtmlEditorCore} this */ - paste: true - }); + paste: true, + + }); this.defaultAutoCreate = { tag: "textarea", style:'width: ' + this.width + 'px;height: ' + this.height + 'px;', diff --git a/docs/symbols/Roo.bootstrap.form.HtmlEditor.json b/docs/symbols/Roo.bootstrap.form.HtmlEditor.json index 52eafc17a1..ffaf9ea289 100644 --- a/docs/symbols/Roo.bootstrap.form.HtmlEditor.json +++ b/docs/symbols/Roo.bootstrap.form.HtmlEditor.json @@ -1746,7 +1746,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -1772,7 +1772,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -1798,6 +1798,26 @@ "params" : [], "returns" : [] }, + { + "name" : "stylesheetsclick", + "type" : "function", + "desc" : "Fires when press the Sytlesheets button", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.HtmlEditorCore", + "desc" : "", + "isOptional" : false + } + ], + "returns" : [] + }, { "name" : "initialize", "type" : "function", @@ -1811,7 +1831,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -1870,7 +1890,27 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", + "isOptional" : false + } + ], + "returns" : [] + }, + { + "name" : "imageadd", + "type" : "function", + "desc" : "Fires when on any editor when an image is added (excluding paste)", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -1890,7 +1930,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -1910,7 +1950,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -1923,6 +1963,32 @@ ], "returns" : [] }, + { + "name" : "imagedelete", + "type" : "function", + "desc" : "Fires when on any editor when an image is deleted", + "sig" : "function (_self, img)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", + "isOptional" : false + }, + { + "name" : "img", + "type" : "HTMLElement", + "desc" : "could also be a figure if blocks are enabled", + "isOptional" : false + } + ], + "returns" : [] + }, { "name" : "beforesync", "type" : "function", @@ -1936,7 +2002,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, @@ -1962,7 +2028,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -1970,10 +2036,10 @@ "returns" : [] }, { - "name" : "savedpreview", + "name" : "imageupdated", "type" : "function", - "desc" : "preview the saved version of htmlEditor", - "sig" : "function (_self)\n{\n\n}", + "desc" : "Fires when on any editor when an image is changed (excluding paste)", + "sig" : "function (_self, img)\n{\n\n}", "memberOf" : "", "example" : "", "deprecated" : "", @@ -1982,18 +2048,24 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false + }, + { + "name" : "img", + "type" : "HTMLElement", + "desc" : "could also be a figure if blocks are enabled", + "isOptional" : false } ], "returns" : [] }, { - "name" : "push", + "name" : "savedpreview", "type" : "function", - "desc" : "Fires when the iframe editor is updated with content from the textarea.", - "sig" : "function (_self, html)\n{\n\n}", + "desc" : "preview the saved version of htmlEditor", + "sig" : "function (_self)\n{\n\n}", "memberOf" : "", "example" : "", "deprecated" : "", @@ -2002,13 +2074,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", - "desc" : "", - "isOptional" : false - }, - { - "name" : "html", - "type" : "String", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false } @@ -2016,9 +2082,9 @@ "returns" : [] }, { - "name" : "autosave", + "name" : "paste", "type" : "function", - "desc" : "Auto save the htmlEditor value as a file into Events", + "desc" : "Fires when press user pastes into the editor", "sig" : "function (_self)\n{\n\n}", "memberOf" : "", "example" : "", @@ -2028,7 +2094,7 @@ "params" : [ { "name" : "this", - "type" : "HtmlEditor", + "type" : "Roo.HtmlEditorCore", "desc" : "", "isOptional" : false } @@ -2036,11 +2102,11 @@ "returns" : [] }, { - "name" : "paste", + "name" : "push", "type" : "function", - "desc" : "Fires after the user pastes into input", - "sig" : "function (_self, e)\n{\n\n}", - "memberOf" : "Roo.bootstrap.form.Input", + "desc" : "Fires when the iframe editor is updated with content from the textarea.", + "sig" : "function (_self, html)\n{\n\n}", + "memberOf" : "", "example" : "", "deprecated" : "", "since" : "", @@ -2048,14 +2114,34 @@ "params" : [ { "name" : "this", - "type" : "Roo.form.Field", + "type" : "Roo.bootstrap.form.HtmlEditor", "desc" : "", "isOptional" : false }, { - "name" : "e", - "type" : "Roo.EventObject", - "desc" : "The event Object", + "name" : "html", + "type" : "String", + "desc" : "", + "isOptional" : false + } + ], + "returns" : [] + }, + { + "name" : "autosave", + "type" : "function", + "desc" : "Auto save the htmlEditor value as a file into Events", + "sig" : "function (_self)\n{\n\n}", + "memberOf" : "", + "example" : "", + "deprecated" : "", + "since" : "", + "see" : "", + "params" : [ + { + "name" : "this", + "type" : "Roo.bootstrap.form.HtmlEditor", + "desc" : "", "isOptional" : false } ], diff --git a/examples/bootstrap/Editor.js b/examples/bootstrap/Editor.js index 537273182b..9dde1eb917 100644 --- a/examples/bootstrap/Editor.js +++ b/examples/bootstrap/Editor.js @@ -63,6 +63,15 @@ Roo.example.Editor = new Roo.XComponent({ render : function (_self) { _this.previewPanel = _self; + }, + imageadd : function(a) { + Roo.log(['imageadd', a]) + }, + imageupdate : function(a,b) { + Roo.log(['imageupdate', a,b]) + }, + imagedelete : function(a,b) { + Roo.log(['imagedelete', a,b]) } } } diff --git a/roojs-all.js b/roojs-all.js index ec0fa8aa49..08309a6e46 100644 --- a/roojs-all.js +++ b/roojs-all.js @@ -2144,10 +2144,10 @@ Roo.HtmlEditorCore.tag_remove=['FONT','TBODY'];Roo.HtmlEditorCore.ablack=['on']; // Roo/form/HtmlEditor.js Roo.form.HtmlEditor=function(A){Roo.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));};Roo.extend(Roo.form.HtmlEditor,Roo.form.Field,{clearUp:true,toolbars:false,resizable:false,height:300,width:500,stylesheets:false,cblack:false,cwhite:false,black:false,white:false,allowComments:false,enableBlocks:true,autoClean:true,bodyCls:'',language:'en',frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',actionMode:'container',defaultAutoCreate:{tag:"textarea",style:"width:500px;height:300px;",autocomplete:"new-password"} -,initComponent:function(){this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true,stylesheetsclick:true,paste:true});this.defaultAutoCreate={tag:"textarea",style:'width: '+this.width+'px;height: '+this.height+'px;',autocomplete:"new-password"} -;},createToolbar:function(A){Roo.log("create toolbars");if(!A.toolbars||!A.toolbars.length){A.toolbars=[new Roo.form.HtmlEditor.ToolbarStandard()];}for(var i=0;i'); - editor.owner.fireEvent('editorevent', editor, false); + this.addFiles(far, true); }).createDelegate(this)); reader.readAsDataURL(f); @@ -33305,6 +33347,11 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp selection.removeAllRanges(); selection.addRange(range); this.updateToolbar(null, null, null); + if (sn.tagName.toUpperCase() == 'FIGURE') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); return; } @@ -33324,6 +33371,11 @@ Roo.extend(Roo.bootstrap.form.HtmlEditorToolbar.Standard, Roo.bootstrap.nav.Simp selection.removeAllRanges(); selection.addRange(range); + if (sn.tagName.toUpperCase() == 'IMG"') { + this.editor.fireEvent('imagedelete', this.editor, sn); + } + + this.selectedNode = false; this.editorcore.fireEditorEvent(false); diff --git a/roojs-bootstrap.js b/roojs-bootstrap.js index 50acf69c99..bb37c5dacc 100644 --- a/roojs-bootstrap.js +++ b/roojs-bootstrap.js @@ -1400,8 +1400,8 @@ Roo.HtmlEditorCore.black=['APPLET','BASE','BASEFONT','BGSOUND','BLINK','BODY','F Roo.HtmlEditorCore.tag_remove=['FONT','TBODY'];Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[]; // Roo/bootstrap/form/HtmlEditor.js -Roo.bootstrap.form.HtmlEditor=function(A){Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true} -);};Roo.extend(Roo.bootstrap.form.HtmlEditor,Roo.bootstrap.form.TextArea,{toolbars:true,btns:[],resize:false,height:300,width:false,stylesheets:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',tbContainer:false,bodyCls:'',toolbarContainer:function(){return this.wrap.select('.x-html-editor-tb',true).first(); +Roo.bootstrap.form.HtmlEditor=function(A){this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true,stylesheetsclick:true,paste:true,imageadd:true,imageupdate:true,imagedelete:true} +);Roo.bootstrap.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));};Roo.extend(Roo.bootstrap.form.HtmlEditor,Roo.bootstrap.form.TextArea,{toolbars:true,btns:[],resize:false,height:300,width:false,stylesheets:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',tbContainer:false,bodyCls:'',toolbarContainer:function(){return this.wrap.select('.x-html-editor-tb',true).first(); },createToolbar:function(){if(this.toolbars===false){return;}if(this.toolbars===true){this.toolbars=['Standard'];}var ar=Array.from(this.toolbars);this.toolbars=[];ar.forEach(function(t,i){if(typeof(t)=='string'){t={xtype:t};}if(typeof(t)=='object'&&typeof(t.xtype)=='string'){t.editor=this; t.xns=t.xns||Roo.bootstrap.form.HtmlEditorToolbar;t=Roo.factory(t);}this.toolbars[i]=t;this.toolbars[i].render(this.toolbarContainer());},this);},onRender:function(ct,A){var _t=this;Roo.bootstrap.form.HtmlEditor.superclass.onRender.call(this,ct,A);this.wrap=this.inputEl().wrap({cls:'x-html-editor-wrap',cn:{cls:'x-html-editor-tb'} });this.editorcore.onRender(ct,A);this.createToolbar(this);},onResize:function(w,h){Roo.log('resize: '+w+','+h);Roo.bootstrap.form.HtmlEditor.superclass.onResize.apply(this,arguments);var ew=false;var eh=false;if(this.inputEl()){if(typeof w=='number'){var aw=w-this.wrap.getFrameWidth('lr'); @@ -1422,11 +1422,12 @@ F('italic','italic',true);F('underline','underline',true);F('align-left','justif F('list-ol','insertorderedlist',true);F('pencil',false,true,function(G){Roo.log(this);this.toggleSourceEdit(G.pressed);});if(this.editor.btns.length>0){for(var i=0;i');B.owner.fireEvent('editorevent',B,false);}).createDelegate(this));C.readAsDataURL(f);},onBtnClick:function(id){this.editorcore.relayCmd(id); -this.editorcore.focus();},onLinkClick:function(A){var B=this.selectedNode&&this.selectedNode.tagName.toUpperCase()=='A'?this.selectedNode.getAttribute('href'):'';Roo.bootstrap.MessageBox.show({title:"Add / Edit Link URL",msg:"Enter the URL for the link",buttons:Roo.bootstrap.MessageBox.OKCANCEL,minWidth:250,scope:this,prompt:true,multiline:false,modal:true,value:B,fn:function(C,D){if(C!='ok'){this.editorcore.focus(); +this.input.dom.click();},onFileSelected:function(e){e.preventDefault();if(typeof(this.input.dom.files)=='undefined'||!this.input.dom.files.length){return;}this.addFiles(Array.prototype.slice.call(this.input.dom.files),false);},addFiles:function(A,B){var C=this.editorcore; +if(!A.length){if(B){C.owner.fireEvent('editorevent',C.owner,false);C.owner.fireEvent('imageadd',C.owner,false);}return;}var f=A.pop();if(!f.type.match(/^image/)){this.addFiles(A,B);return;}var sn=this.selectedNode;var bl=sn&&this.editorcore.enableBlocks?Roo.htmleditor.Block.factory(sn):false; +var D=new FileReader();D.addEventListener('load',(function(){if(bl){bl.image_src=D.result;bl.updateElement(sn);C.owner.fireEvent('editorevent',C.owner,false);C.owner.fireEvent('imageupdate',C.owner,sn);return;}if(this.editorcore.enableBlocks){var E=new Roo.htmleditor.BlockFigure({image_src:D.result,caption:'',caption_display:'none'} +);C.insertAtCursor(E.toHTML());this.addFiles(A,true);return;}if(sn&&sn.tagName.toUpperCase()=='IMG'){sn.src=D.result;C.owner.fireEvent('editorevent',C.owner,false);C.owner.fireEvent('imageupdate',C.owner,sn);return;}C.insertAtCursor(''); +this.addFiles(A,true);}).createDelegate(this));D.readAsDataURL(f);},onBtnClick:function(id){this.editorcore.relayCmd(id);this.editorcore.focus();},onLinkClick:function(A){var B=this.selectedNode&&this.selectedNode.tagName.toUpperCase()=='A'?this.selectedNode.getAttribute('href'):''; +Roo.bootstrap.MessageBox.show({title:"Add / Edit Link URL",msg:"Enter the URL for the link",buttons:Roo.bootstrap.MessageBox.OKCANCEL,minWidth:250,scope:this,prompt:true,multiline:false,modal:true,value:B,fn:function(C,D){if(C!='ok'){this.editorcore.focus(); return;}if(B!=''){this.selectedNode.setAttribute('href',D);return;}if(D&&D.match(/http(s):\/\/.+/)){this.editorcore.relayCmd('createlink',D);}this.editorcore.focus();}});},updateToolbar:function(A,ev,B){if(!this.editorcore.activated){this.editor.onFirstFocus(); return;}var C=this.buttons;var D=this.editorcore.doc;var E=false;C.each(function(e){if(e.enableToggle&&e.cmd){E=E||(['align-left','align-right','align-center','image','link','underline'].indexOf(e.btnid)<0&&D.queryCommandState(e.cmd));e.setActive(D.queryCommandState(e.cmd)); }},this);if(ev&&(ev.type=='mouseup'||ev.type=='click')&&ev.target&&ev.target.tagName!='BODY'){B=ev.target;}var F=this.editorcore.getAllAncestors();if(!B){B=F.length?(F[0]?F[0]:F[1]):this.editorcore.doc.body;B=B?B:this.editorcore.doc.body;B=B.tagName.length?B:this.editorcore.doc.body; @@ -1434,10 +1435,10 @@ return;}var C=this.buttons;var D=this.editorcore.doc;var E=false;C.each(function });var H=false;if(db&&this.editorcore.enableBlocks){H=Roo.htmleditor.Block.factory(db);if(H){db.className=(db.classList.length>0?db.className+' ':'')+' roo-ed-selection';B=this.selectedNode=db;}}var tn=B&&B.tagName.toUpperCase()||'';if(!H&&B&&tn!='A'){var I=B.closest('A'); if(I){B=I;}}C.get('link').setActive(tn=='A'&&this.selectedNode.hasAttribute('href'));C.get('image').setActive(tn=='IMG'||this.editorcore.enableBlocks&&tn=='FIGURE');C.get('underline').setActive(tn=='U'||B.closest('u')?true:false);Roo.bootstrap.menu.Manager.hideAll(); if(E||(tn.length&&tn=='BODY')){this.deleteBtn.hide();return;}this.deleteBtn.show();},onFirstFocus:function(){this.buttons.each(function(A){A.enable();});},onDelete:function(){var A=this.editorcore.createRange();var B=this.editorcore.getSelection();var sn=this.selectedNode; -A.setStart(sn,0);A.setEnd(sn,0);if(sn.hasAttribute('data-block')){var C=Roo.htmleditor.Block.factory(this.selectedNode);if(C){sn=C.removeNode();sn.parentNode.removeChild(sn);B.removeAllRanges();B.addRange(A);this.updateToolbar(null,null,null);this.editorcore.fireEditorEvent(false); -return;}}if(!sn){return;}if(sn&&sn.tagName=='BODY'){return;}var D=sn.childNodes[0]||sn.nextSibling||sn.previousSibling||sn.parentNode;a=new Roo.htmleditor.FilterKeepChildren({tag:false});a.replaceTag(sn);B.removeAllRanges();B.addRange(A);this.editorcore.fireEditorEvent(false); -},toggleSourceEdit:function(A){if(A){Roo.log("disabling buttons");this.buttons.each(function(B){if(B.cmd!='pencil'){B.disable();}});}else{Roo.log("enabling buttons");if(this.editorcore.initialized){this.buttons.each(function(B){B.enable();});}}Roo.log("calling toggole on editor"); -this.editor.toggleSourceEdit(A);}}); +A.setStart(sn,0);A.setEnd(sn,0);if(sn.hasAttribute('data-block')){var C=Roo.htmleditor.Block.factory(this.selectedNode);if(C){sn=C.removeNode();sn.parentNode.removeChild(sn);B.removeAllRanges();B.addRange(A);this.updateToolbar(null,null,null);if(sn.tagName.toUpperCase()=='FIGURE'){this.editor.fireEvent('imagedelete',this.editor,sn); +}this.selectedNode=false;this.editorcore.fireEditorEvent(false);return;}}if(!sn){return;}if(sn&&sn.tagName=='BODY'){return;}var D=sn.childNodes[0]||sn.nextSibling||sn.previousSibling||sn.parentNode;a=new Roo.htmleditor.FilterKeepChildren({tag:false});a.replaceTag(sn); +B.removeAllRanges();B.addRange(A);if(sn.tagName.toUpperCase()=='IMG"'){this.editor.fireEvent('imagedelete',this.editor,sn);}this.selectedNode=false;this.editorcore.fireEditorEvent(false);},toggleSourceEdit:function(A){if(A){Roo.log("disabling buttons");this.buttons.each(function(B){if(B.cmd!='pencil'){B.disable(); +}});}else{Roo.log("enabling buttons");if(this.editorcore.initialized){this.buttons.each(function(B){B.enable();});}}Roo.log("calling toggole on editor");this.editor.toggleSourceEdit(A);}}); // Roo/bootstrap/form/Markdown.js Roo.bootstrap.form.Markdown=function(A){Roo.bootstrap.form.Markdown.superclass.constructor.call(this,A);};Roo.extend(Roo.bootstrap.form.Markdown,Roo.bootstrap.form.TextArea,{editing:false,initEvents:function(){Roo.bootstrap.form.TextArea.prototype.initEvents.call(this); this.markdownEl=this.el.createChild({cls:'roo-markdown-area'});this.inputEl().addClass('d-none');if(this.getValue()==''){this.markdownEl.dom.innerHTML=String.format('{0}',this.placeholder||'');}else{this.markdownEl.dom.innerHTML=Roo.Markdown.toHtml(Roo.util.Format.htmlEncode(this.getValue())); diff --git a/roojs-debug.js b/roojs-debug.js index d140c10bd7..fe613f9f1e 100644 --- a/roojs-debug.js +++ b/roojs-debug.js @@ -51836,7 +51836,19 @@ Roo.extend(Roo.form.HtmlEditor, Roo.form.Field, { * Fires when press user pastes into the editor * @param {Roo.HtmlEditorCore} this */ - paste: true + paste: true, + /** + * @event imageadd + * Fires when on any editor when an image is added (excluding paste) + * @param {Roo.HtmlEditorCore} this + */ + imageadd: true , + /** + * @event imagedelete + * Fires when on any editor when an image is deleted + * @param {Roo.HtmlEditorCore} this + */ + imagedelete: true }); this.defaultAutoCreate = { tag: "textarea", diff --git a/roojs-ui-debug.js b/roojs-ui-debug.js index f42a03b9e5..6fbd580460 100644 --- a/roojs-ui-debug.js +++ b/roojs-ui-debug.js @@ -27334,7 +27334,19 @@ Roo.extend(Roo.form.HtmlEditor, Roo.form.Field, { * Fires when press user pastes into the editor * @param {Roo.HtmlEditorCore} this */ - paste: true + paste: true, + /** + * @event imageadd + * Fires when on any editor when an image is added (excluding paste) + * @param {Roo.HtmlEditorCore} this + */ + imageadd: true , + /** + * @event imagedelete + * Fires when on any editor when an image is deleted + * @param {Roo.HtmlEditorCore} this + */ + imagedelete: true }); this.defaultAutoCreate = { tag: "textarea", diff --git a/roojs-ui.js b/roojs-ui.js index 74c0a88979..e07413e015 100644 --- a/roojs-ui.js +++ b/roojs-ui.js @@ -1197,10 +1197,10 @@ Roo.HtmlEditorCore.tag_remove=['FONT','TBODY'];Roo.HtmlEditorCore.ablack=['on']; // Roo/form/HtmlEditor.js Roo.form.HtmlEditor=function(A){Roo.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));};Roo.extend(Roo.form.HtmlEditor,Roo.form.Field,{clearUp:true,toolbars:false,resizable:false,height:300,width:500,stylesheets:false,cblack:false,cwhite:false,black:false,white:false,allowComments:false,enableBlocks:true,autoClean:true,bodyCls:'',language:'en',frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',actionMode:'container',defaultAutoCreate:{tag:"textarea",style:"width:500px;height:300px;",autocomplete:"new-password"} -,initComponent:function(){this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editmodechange:true,editorevent:true,firstfocus:true,autosave:true,savedpreview:true,stylesheetsclick:true,paste:true});this.defaultAutoCreate={tag:"textarea",style:'width: '+this.width+'px;height: '+this.height+'px;',autocomplete:"new-password"} -;},createToolbar:function(A){Roo.log("create toolbars");if(!A.toolbars||!A.toolbars.length){A.toolbars=[new Roo.form.HtmlEditor.ToolbarStandard()];}for(var i=0;i