3 * Copyright(c) 2006-2010 Sencha Inc.
5 * http://www.sencha.com/license
8 * @class Ext.form.HtmlEditor
9 * @extends Ext.form.Field
10 * Provides a lightweight HTML Editor component. Some toolbar features are not supported by Safari and will be
11 * automatically hidden when needed. These are noted in the config options where appropriate.
12 * <br><br>The editor's toolbar buttons have tooltips defined in the {@link #buttonTips} property, but they are not
13 * enabled by default unless the global {@link Ext.QuickTips} singleton is {@link Ext.QuickTips#init initialized}.
14 * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
15 * supported by this editor.</b>
16 * <br><br>An Editor is a sensitive component that can't be used in all spots standard fields can be used. Putting an Editor within
17 * any element that has display set to 'none' can cause problems in Safari and Firefox due to their default iframe reloading bugs.
18 * <br><br>Example usage:
20 // Simple example rendered with default options:
21 Ext.QuickTips.init(); // enable tooltips
22 new Ext.form.HtmlEditor({
23 renderTo: Ext.getBody(),
28 // Passed via xtype into a container and with custom options:
29 Ext.QuickTips.init(); // enable tooltips
32 renderTo: Ext.getBody(),
40 enableAlignments: false
45 * Create a new HtmlEditor
46 * @param {Object} config
50 Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
52 * @cfg {Boolean} enableFormat Enable the bold, italic and underline buttons (defaults to true)
56 * @cfg {Boolean} enableFontSize Enable the increase/decrease font size buttons (defaults to true)
58 enableFontSize : true,
60 * @cfg {Boolean} enableColors Enable the fore/highlight color buttons (defaults to true)
64 * @cfg {Boolean} enableAlignments Enable the left, center, right alignment buttons (defaults to true)
66 enableAlignments : true,
68 * @cfg {Boolean} enableLists Enable the bullet and numbered list buttons. Not available in Safari. (defaults to true)
72 * @cfg {Boolean} enableSourceEdit Enable the switch to source edit button. Not available in Safari. (defaults to true)
74 enableSourceEdit : true,
76 * @cfg {Boolean} enableLinks Enable the create link button. Not available in Safari. (defaults to true)
80 * @cfg {Boolean} enableFont Enable font selection. Not available in Safari. (defaults to true)
84 * @cfg {String} createLinkText The default text for the create link prompt
86 createLinkText : 'Please enter the URL for the link:',
88 * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
90 defaultLinkValue : 'http:/'+'/',
92 * @cfg {Array} fontFamilies An array of available font families
101 defaultFont: 'tahoma',
103 * @cfg {String} defaultValue A default value to be put into the editor to resolve focus issues (defaults to   (Non-breaking space) in Opera and IE6, ​ (Zero-width space) in all other browsers).
105 defaultValue: (Ext.isOpera || Ext.isIE6) ? ' ' : '​',
107 // private properties
109 validationEvent : false,
113 sourceEditMode : false,
114 onFocus : Ext.emptyFn,
117 defaultAutoCreate : {
119 style:"width:500px;height:300px;",
124 initComponent : function(){
128 * Fires when the editor is fully initialized (including the iframe)
129 * @param {HtmlEditor} this
134 * Fires when the editor is first receives the focus. Any insertion must wait
135 * until after this event.
136 * @param {HtmlEditor} this
141 * Fires before the textarea is updated with content from the editor iframe. Return false
142 * to cancel the sync.
143 * @param {HtmlEditor} this
144 * @param {String} html
149 * Fires before the iframe editor is updated with content from the textarea. Return false
150 * to cancel the push.
151 * @param {HtmlEditor} this
152 * @param {String} html
157 * Fires when the textarea is updated with content from the editor iframe.
158 * @param {HtmlEditor} this
159 * @param {String} html
164 * Fires when the iframe editor is updated with content from the textarea.
165 * @param {HtmlEditor} this
166 * @param {String} html
170 * @event editmodechange
171 * Fires when the editor switches edit modes
172 * @param {HtmlEditor} this
173 * @param {Boolean} sourceEdit True if source edit, false if standard editing.
177 Ext.form.HtmlEditor.superclass.initComponent.call(this);
181 createFontOptions : function(){
182 var buf = [], fs = this.fontFamilies, ff, lc;
183 for(var i = 0, len = fs.length; i< len; i++){
185 lc = ff.toLowerCase();
187 '<option value="',lc,'" style="font-family:',ff,';"',
188 (this.defaultFont == lc ? ' selected="true">' : '>'),
197 * Protected method that will not generally be called directly. It
198 * is called when the editor creates its toolbar. Override this method if you need to
199 * add custom toolbar buttons.
200 * @param {HtmlEditor} editor
202 createToolbar : function(editor){
204 var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();
207 function btn(id, toggle, handler){
211 iconCls: 'x-edit-'+id,
212 enableToggle:toggle !== false,
214 handler:handler||editor.relayBtnCmd,
215 clickEvent:'mousedown',
216 tooltip: tipsEnabled ? editor.buttonTips[id] || undefined : undefined,
217 overflowText: editor.buttonTips[id].title || undefined,
223 if(this.enableFont && !Ext.isSafari2){
224 var fontSelectItem = new Ext.Toolbar.Item({
228 html: this.createFontOptions()
238 if(this.enableFormat){
246 if(this.enableFontSize){
249 btn('increasefontsize', false, this.adjustFont),
250 btn('decreasefontsize', false, this.adjustFont)
254 if(this.enableColors){
259 iconCls: 'x-edit-forecolor',
260 clickEvent:'mousedown',
261 tooltip: tipsEnabled ? editor.buttonTips.forecolor || undefined : undefined,
263 menu : new Ext.menu.ColorMenu({
270 select: function(cp, color){
271 this.execCmd('forecolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
275 clickEvent:'mousedown'
280 iconCls: 'x-edit-backcolor',
281 clickEvent:'mousedown',
282 tooltip: tipsEnabled ? editor.buttonTips.backcolor || undefined : undefined,
284 menu : new Ext.menu.ColorMenu({
291 select: function(cp, color){
293 this.execCmd('useCSS', false);
294 this.execCmd('hilitecolor', color);
295 this.execCmd('useCSS', true);
298 this.execCmd(Ext.isOpera ? 'hilitecolor' : 'backcolor', Ext.isWebKit || Ext.isIE ? '#'+color : color);
303 clickEvent:'mousedown'
309 if(this.enableAlignments){
313 btn('justifycenter'),
319 if(this.enableLinks){
322 btn('createlink', false, this.createLink)
326 if(this.enableLists){
329 btn('insertorderedlist'),
330 btn('insertunorderedlist')
333 if(this.enableSourceEdit){
336 btn('sourceedit', true, function(btn){
337 this.toggleSourceEdit(!this.sourceEditMode);
344 var tb = new Ext.Toolbar({
345 renderTo: this.wrap.dom.firstChild,
349 if (fontSelectItem) {
350 this.fontSelect = fontSelectItem.el;
352 this.mon(this.fontSelect, 'change', function(){
353 var font = this.fontSelect.dom.value;
354 this.relayCmd('fontname', font);
360 this.mon(tb.el, 'click', function(e){
368 onDisable: function(){
370 Ext.form.HtmlEditor.superclass.onDisable.call(this);
373 onEnable: function(){
375 Ext.form.HtmlEditor.superclass.onEnable.call(this);
378 setReadOnly: function(readOnly){
380 Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
381 if(this.initialized){
383 this.getEditorBody().contentEditable = !readOnly;
385 this.setDesignMode(!readOnly);
387 var bd = this.getEditorBody();
389 bd.style.cursor = this.readOnly ? 'default' : 'text';
391 this.disableItems(readOnly);
396 * Protected method that will not generally be called directly. It
397 * is called when the editor initializes the iframe with HTML contents. Override this method if you
398 * want to change the initialization markup of the iframe (e.g. to add stylesheets).
400 * Note: IE8-Standards has unwanted scroller behavior, so the default meta tag forces IE7 compatibility
402 getDocMarkup : function(){
403 var h = Ext.fly(this.iframe).getHeight() - this.iframePad * 2;
404 return String.format('<html><head><style type="text/css">body{border: 0; margin: 0; padding: {0}px; height: {1}px; cursor: text}</style></head><body></body></html>', this.iframePad, h);
408 getEditorBody : function(){
409 var doc = this.getDoc();
410 return doc.body || doc.documentElement;
415 return Ext.isIE ? this.getWin().document : (this.iframe.contentDocument || this.getWin().document);
420 return Ext.isIE ? this.iframe.contentWindow : window.frames[this.iframe.name];
424 onRender : function(ct, position){
425 Ext.form.HtmlEditor.superclass.onRender.call(this, ct, position);
426 this.el.dom.style.border = '0 none';
427 this.el.dom.setAttribute('tabIndex', -1);
428 this.el.addClass('x-hidden');
429 if(Ext.isIE){ // fix IE 1px bogus margin
430 this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;');
432 this.wrap = this.el.wrap({
433 cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
436 this.createToolbar(this);
438 this.disableItems(true);
445 var sz = this.el.getSize();
446 this.setSize(sz.width, this.height || sz.height);
448 this.resizeEl = this.positionEl = this.wrap;
451 createIFrame: function(){
452 var iframe = document.createElement('iframe');
453 iframe.name = Ext.id();
454 iframe.frameBorder = '0';
455 iframe.style.overflow = 'auto';
456 iframe.src = Ext.SSL_SECURE_URL;
458 this.wrap.dom.appendChild(iframe);
459 this.iframe = iframe;
461 this.monitorTask = Ext.TaskMgr.start({
462 run: this.checkDesignMode,
468 initFrame : function(){
469 Ext.TaskMgr.stop(this.monitorTask);
470 var doc = this.getDoc();
471 this.win = this.getWin();
474 doc.write(this.getDocMarkup());
477 var task = { // must defer to wait for browser to be ready
479 var doc = this.getDoc();
480 if(doc.body || doc.readyState == 'complete'){
481 Ext.TaskMgr.stop(task);
482 this.setDesignMode(true);
483 this.initEditor.defer(10, this);
490 Ext.TaskMgr.start(task);
494 checkDesignMode : function(){
495 if(this.wrap && this.wrap.dom.offsetWidth){
496 var doc = this.getDoc();
500 if(!doc.editorInitialized || this.getDesignMode() != 'on'){
507 * set current design mode. To enable, mode can be true or 'on', off otherwise
509 setDesignMode : function(mode){
510 var doc = this.getDoc();
515 doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';
521 getDesignMode : function(){
522 var doc = this.getDoc();
523 if(!doc){ return ''; }
524 return String(doc.designMode).toLowerCase();
528 disableItems: function(disabled){
530 this.fontSelect.dom.disabled = disabled;
532 this.tb.items.each(function(item){
533 if(item.getItemId() != 'sourceedit'){
534 item.setDisabled(disabled);
540 onResize : function(w, h){
541 Ext.form.HtmlEditor.superclass.onResize.apply(this, arguments);
542 if(this.el && this.iframe){
544 var aw = w - this.wrap.getFrameWidth('lr');
545 this.el.setWidth(aw);
546 this.tb.setWidth(aw);
547 this.iframe.style.width = Math.max(aw, 0) + 'px';
550 var ah = h - this.wrap.getFrameWidth('tb') - this.tb.el.getHeight();
551 this.el.setHeight(ah);
552 this.iframe.style.height = Math.max(ah, 0) + 'px';
553 var bd = this.getEditorBody();
555 bd.style.height = Math.max((ah - (this.iframePad*2)), 0) + 'px';
562 * Toggles the editor between standard and source edit mode.
563 * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
565 toggleSourceEdit : function(sourceEditMode){
569 if (sourceEditMode === undefined) {
570 sourceEditMode = !this.sourceEditMode;
572 this.sourceEditMode = sourceEditMode === true;
573 var btn = this.tb.getComponent('sourceedit');
575 if (btn.pressed !== this.sourceEditMode) {
576 btn.toggle(this.sourceEditMode);
577 if (!btn.xtbHidden) {
581 if (this.sourceEditMode) {
582 // grab the height of the containing panel before we hide the iframe
583 this.previousSize = this.getSize();
585 iframeHeight = Ext.get(this.iframe).getHeight();
587 this.disableItems(true);
589 this.iframe.className = 'x-hidden';
590 this.el.removeClass('x-hidden');
591 this.el.dom.removeAttribute('tabIndex');
593 this.el.dom.style.height = iframeHeight + 'px';
596 elHeight = parseInt(this.el.dom.style.height, 10);
597 if (this.initialized) {
598 this.disableItems(this.readOnly);
601 this.iframe.className = '';
602 this.el.addClass('x-hidden');
603 this.el.dom.setAttribute('tabIndex', -1);
606 this.setSize(this.previousSize);
607 delete this.previousSize;
608 this.iframe.style.height = elHeight + 'px';
610 this.fireEvent('editmodechange', this, this.sourceEditMode);
613 // private used internally
614 createLink : function() {
615 var url = prompt(this.createLinkText, this.defaultLinkValue);
616 if(url && url != 'http:/'+'/'){
617 this.relayCmd('createlink', url);
622 initEvents : function(){
623 this.originalValue = this.getValue();
627 * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
630 markInvalid : Ext.emptyFn,
633 * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
636 clearInvalid : Ext.emptyFn,
638 // docs inherit from Field
639 setValue : function(v){
640 Ext.form.HtmlEditor.superclass.setValue.call(this, v);
646 * Protected method that will not generally be called directly. If you need/want
647 * custom HTML cleanup, this is the method you should override.
648 * @param {String} html The HTML to be cleaned
649 * @return {String} The cleaned HTML
651 cleanHtml: function(html) {
653 if(Ext.isWebKit){ // strip safari nonsense
654 html = html.replace(/\sclass="(?:Apple-style-span|khtml-block-placeholder)"/gi, '');
658 * Neat little hack. Strips out all the non-digit characters from the default
659 * value and compares it to the character code of the first character in the string
660 * because it can cause encoding issues when posted to the server.
662 if(html.charCodeAt(0) == this.defaultValue.replace(/\D/g, '')){
663 html = html.substring(1);
669 * Protected method that will not generally be called directly. Syncs the contents
670 * of the editor iframe with the textarea.
672 syncValue : function(){
673 if(this.initialized){
674 var bd = this.getEditorBody();
675 var html = bd.innerHTML;
677 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
678 var m = bs.match(/text-align:(.*?);/i);
680 html = '<div style="'+m[0]+'">' + html + '</div>';
683 html = this.cleanHtml(html);
684 if(this.fireEvent('beforesync', this, html) !== false){
685 this.el.dom.value = html;
686 this.fireEvent('sync', this, html);
691 //docs inherit from Field
692 getValue : function() {
693 this[this.sourceEditMode ? 'pushValue' : 'syncValue']();
694 return Ext.form.HtmlEditor.superclass.getValue.call(this);
698 * Protected method that will not generally be called directly. Pushes the value of the textarea
699 * into the iframe editor.
701 pushValue : function(){
702 if(this.initialized){
703 var v = this.el.dom.value;
704 if(!this.activated && v.length < 1){
705 v = this.defaultValue;
707 if(this.fireEvent('beforepush', this, v) !== false){
708 this.getEditorBody().innerHTML = v;
710 // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
711 this.setDesignMode(false); //toggle off first
712 this.setDesignMode(true);
714 this.fireEvent('push', this, v);
721 deferFocus : function(){
722 this.focus.defer(10, this);
725 // docs inherit from Field
727 if(this.win && !this.sourceEditMode){
735 initEditor : function(){
736 //Destroying the component during/before initEditor can cause issues.
738 var dbody = this.getEditorBody(),
739 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat', 'background-color', 'color'),
743 ss['background-attachment'] = 'fixed'; // w3c
744 dbody.bgProperties = 'fixed'; // ie
746 Ext.DomHelper.applyStyles(dbody, ss);
752 Ext.EventManager.removeAll(doc);
757 * We need to use createDelegate here, because when using buffer, the delayed task is added
758 * as a property to the function. When the listener is removed, the task is deleted from the function.
759 * Since onEditorEvent is shared on the prototype, if we have multiple html editors, the first time one of the editors
760 * is destroyed, it causes the fn to be deleted from the prototype, which causes errors. Essentially, we're just anonymizing the function.
762 fn = this.onEditorEvent.createDelegate(this);
763 Ext.EventManager.on(doc, {
772 Ext.EventManager.on(doc, 'keypress', this.applyCommand, this);
774 if(Ext.isIE || Ext.isWebKit || Ext.isOpera){
775 Ext.EventManager.on(doc, 'keydown', this.fixKeys, this);
777 doc.editorInitialized = true;
778 this.initialized = true;
780 this.setReadOnly(this.readOnly);
781 this.fireEvent('initialize', this);
786 beforeDestroy : function(){
787 if(this.monitorTask){
788 Ext.TaskMgr.stop(this.monitorTask);
791 Ext.destroy(this.tb);
792 var doc = this.getDoc();
795 Ext.EventManager.removeAll(doc);
796 for (var prop in doc){
802 this.wrap.dom.innerHTML = '';
806 Ext.form.HtmlEditor.superclass.beforeDestroy.call(this);
810 onFirstFocus : function(){
811 this.activated = true;
812 this.disableItems(this.readOnly);
813 if(Ext.isGecko){ // prevent silly gecko errors
815 var s = this.win.getSelection();
816 if(!s.focusNode || s.focusNode.nodeType != 3){
817 var r = s.getRangeAt(0);
818 r.selectNodeContents(this.getEditorBody());
823 this.execCmd('useCSS', true);
824 this.execCmd('styleWithCSS', false);
827 this.fireEvent('activate', this);
831 adjustFont: function(btn){
832 var adjust = btn.getItemId() == 'increasefontsize' ? 1 : -1,
834 v = parseInt(doc.queryCommandValue('FontSize') || 2, 10);
835 if((Ext.isSafari && !Ext.isSafari2) || Ext.isChrome || Ext.isAir){
837 // 1 = 10px, 2 = 13px, 3 = 16px, 4 = 18px, 5 = 24px, 6 = 32px
851 v = v.constrain(1, 6);
853 if(Ext.isSafari){ // safari
856 v = Math.max(1, v+adjust) + (Ext.isSafari ? 'px' : 0);
858 this.execCmd('FontSize', v);
862 onEditorEvent : function(e){
863 this.updateToolbar();
868 * Protected method that will not generally be called directly. It triggers
869 * a toolbar update by reading the markup state of the current selection in the editor.
871 updateToolbar: function(){
882 var btns = this.tb.items.map,
885 if(this.enableFont && !Ext.isSafari2){
886 var name = (doc.queryCommandValue('FontName')||this.defaultFont).toLowerCase();
887 if(name != this.fontSelect.dom.value){
888 this.fontSelect.dom.value = name;
891 if(this.enableFormat){
892 btns.bold.toggle(doc.queryCommandState('bold'));
893 btns.italic.toggle(doc.queryCommandState('italic'));
894 btns.underline.toggle(doc.queryCommandState('underline'));
896 if(this.enableAlignments){
897 btns.justifyleft.toggle(doc.queryCommandState('justifyleft'));
898 btns.justifycenter.toggle(doc.queryCommandState('justifycenter'));
899 btns.justifyright.toggle(doc.queryCommandState('justifyright'));
901 if(!Ext.isSafari2 && this.enableLists){
902 btns.insertorderedlist.toggle(doc.queryCommandState('insertorderedlist'));
903 btns.insertunorderedlist.toggle(doc.queryCommandState('insertunorderedlist'));
906 Ext.menu.MenuMgr.hideAll();
912 relayBtnCmd : function(btn){
913 this.relayCmd(btn.getItemId());
917 * Executes a Midas editor command on the editor document and performs necessary focus and
918 * toolbar updates. <b>This should only be called after the editor is initialized.</b>
919 * @param {String} cmd The Midas command
920 * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
922 relayCmd : function(cmd, value){
925 this.execCmd(cmd, value);
926 this.updateToolbar();
931 * Executes a Midas editor command directly on the editor document.
932 * For visual commands, you should use {@link #relayCmd} instead.
933 * <b>This should only be called after the editor is initialized.</b>
934 * @param {String} cmd The Midas command
935 * @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
937 execCmd : function(cmd, value){
938 var doc = this.getDoc();
939 doc.execCommand(cmd, false, value === undefined ? null : value);
944 applyCommand : function(e){
946 var c = e.getCharCode(), cmd;
948 c = String.fromCharCode(c);
971 * Inserts the passed text at the current cursor position. Note: the editor must be initialized and activated
973 * @param {String} text
975 insertAtCursor : function(text){
981 var doc = this.getDoc(),
982 r = doc.selection.createRange();
990 this.execCmd('InsertHTML', text);
996 fixKeys : function(){ // load time branching for fastest keydown performance
1000 doc = this.getDoc(),
1004 r = doc.selection.createRange();
1007 r.pasteHTML(' ');
1010 }else if(k == e.ENTER){
1011 r = doc.selection.createRange();
1013 var target = r.parentElement();
1014 if(!target || target.tagName.toLowerCase() != 'li'){
1016 r.pasteHTML('<br />');
1023 }else if(Ext.isOpera){
1029 this.execCmd('InsertHTML',' ');
1033 }else if(Ext.isWebKit){
1038 this.execCmd('InsertText','\t');
1040 }else if(k == e.ENTER){
1042 this.execCmd('InsertHtml','<br /><br />');
1050 * Returns the editor's toolbar. <b>This is only available after the editor has been rendered.</b>
1051 * @return {Ext.Toolbar}
1053 getToolbar : function(){
1058 * Object collection of toolbar tooltips for the buttons in the editor. The key
1059 * is the command id associated with that button and the value is a valid QuickTips object.
1064 title: 'Bold (Ctrl+B)',
1065 text: 'Make the selected text bold.',
1066 cls: 'x-html-editor-tip'
1069 title: 'Italic (Ctrl+I)',
1070 text: 'Make the selected text italic.',
1071 cls: 'x-html-editor-tip'
1079 title: 'Bold (Ctrl+B)',
1080 text: 'Make the selected text bold.',
1081 cls: 'x-html-editor-tip'
1084 title: 'Italic (Ctrl+I)',
1085 text: 'Make the selected text italic.',
1086 cls: 'x-html-editor-tip'
1089 title: 'Underline (Ctrl+U)',
1090 text: 'Underline the selected text.',
1091 cls: 'x-html-editor-tip'
1093 increasefontsize : {
1095 text: 'Increase the font size.',
1096 cls: 'x-html-editor-tip'
1098 decreasefontsize : {
1099 title: 'Shrink Text',
1100 text: 'Decrease the font size.',
1101 cls: 'x-html-editor-tip'
1104 title: 'Text Highlight Color',
1105 text: 'Change the background color of the selected text.',
1106 cls: 'x-html-editor-tip'
1109 title: 'Font Color',
1110 text: 'Change the color of the selected text.',
1111 cls: 'x-html-editor-tip'
1114 title: 'Align Text Left',
1115 text: 'Align text to the left.',
1116 cls: 'x-html-editor-tip'
1119 title: 'Center Text',
1120 text: 'Center text in the editor.',
1121 cls: 'x-html-editor-tip'
1124 title: 'Align Text Right',
1125 text: 'Align text to the right.',
1126 cls: 'x-html-editor-tip'
1128 insertunorderedlist : {
1129 title: 'Bullet List',
1130 text: 'Start a bulleted list.',
1131 cls: 'x-html-editor-tip'
1133 insertorderedlist : {
1134 title: 'Numbered List',
1135 text: 'Start a numbered list.',
1136 cls: 'x-html-editor-tip'
1140 text: 'Make the selected text a hyperlink.',
1141 cls: 'x-html-editor-tip'
1144 title: 'Source Edit',
1145 text: 'Switch to source editing mode.',
1146 cls: 'x-html-editor-tip'
1150 // hide stuff that is not compatible
1168 * @cfg {String} fieldClass @hide
1171 * @cfg {String} focusClass @hide
1174 * @cfg {String} autoCreate @hide
1177 * @cfg {String} inputType @hide
1180 * @cfg {String} invalidClass @hide
1183 * @cfg {String} invalidText @hide
1186 * @cfg {String} msgFx @hide
1189 * @cfg {String} validateOnBlur @hide
1192 * @cfg {Boolean} allowDomMove @hide
1195 * @cfg {String} applyTo @hide
1198 * @cfg {String} autoHeight @hide
1201 * @cfg {String} autoWidth @hide
1204 * @cfg {String} cls @hide
1207 * @cfg {String} disabled @hide
1210 * @cfg {String} disabledClass @hide
1213 * @cfg {String} msgTarget @hide
1216 * @cfg {String} readOnly @hide
1219 * @cfg {String} style @hide
1222 * @cfg {String} validationDelay @hide
1225 * @cfg {String} validationEvent @hide
1228 * @cfg {String} tabIndex @hide
1231 * @property disabled
1235 * @method applyToMarkup
1255 * @method setDisabled
1263 Ext.reg('htmleditor', Ext.form.HtmlEditor);