Upgrade to ExtJS 3.1.1 - Released 02/08/2010
[extjs.git] / pkgs / pkg-forms-debug.js
index aa61db0..910f07e 100644 (file)
@@ -1,6 +1,6 @@
 /*!
- * Ext JS Library 3.1.0
- * Copyright(c) 2006-2009 Ext JS, LLC
+ * Ext JS Library 3.1.1
+ * Copyright(c) 2006-2010 Ext JS, LLC
  * licensing@extjs.com
  * http://www.extjs.com/license
  */
@@ -86,7 +86,7 @@ Ext.form.Field = Ext.extend(Ext.BoxComponent,  {
      */
     fieldClass : 'x-form-field',
     /**
-     * @cfg {String} msgTarget<p>The location where the message text set through {@link #markInvalid} should display. 
+     * @cfg {String} msgTarget<p>The location where the message text set through {@link #markInvalid} should display.
      * Must be one of the following values:</p>
      * <div class="mdetail-params"><ul>
      * <li><code>qtip</code> Display a quick tip containing the message when the user hovers over the field. This is the default.
@@ -289,7 +289,7 @@ var form = new Ext.form.FormPanel({
         }
         return String(this.getValue()) !== String(this.originalValue);
     },
-    
+
     /**
      * Sets the read only state of this field.
      * @param {Boolean} readOnly Whether the field should be read only.
@@ -430,13 +430,13 @@ var form = new Ext.form.FormPanel({
     validateValue : function(value){
         return true;
     },
-    
+
     /**
      * Gets the active error message for this field.
      * @return {String} Returns the active error message on the field, if there is no error, an empty string is returned.
      */
     getActiveError : function(){
-        return this.activeError || '';    
+        return this.activeError || '';
     },
 
     /**
@@ -503,7 +503,12 @@ var form = new Ext.form.FormPanel({
             this.el.findParent('.x-form-field-wrap', 5, true);   // else direct field wrap
     },
 
-    // private
+    // Alignment for 'under' target
+    alignErrorEl : function(){
+        this.errorEl.setWidth(this.getErrorCt().getWidth(true) - 20);
+    },
+
+    // Alignment for 'side' target
     alignErrorIcon : function(){
         this.errorIcon.alignTo(this.el, 'tl-tr', [2, 0]);
     },
@@ -610,8 +615,12 @@ Ext.form.MessageTargets = {
                     return;
                 }
                 field.errorEl = elp.createChild({cls:'x-form-invalid-msg'});
-                field.errorEl.setWidth(elp.getWidth(true)-20);
+                field.on('resize', field.alignErrorEl, field);
+                field.on('destroy', function(){
+                    Ext.destroy(this.errorEl);
+                }, field);
             }
+            field.alignErrorEl();
             field.errorEl.update(msg);
             Ext.form.Field.msgFx[field.msgFx].show(field.errorEl, field);
         },
@@ -634,19 +643,21 @@ Ext.form.MessageTargets = {
                     return;
                 }
                 field.errorIcon = elp.createChild({cls:'x-form-invalid-icon'});
+                field.on('resize', field.alignErrorIcon, field);
+                field.on('destroy', function(){
+                    Ext.destroy(this.errorIcon);
+                }, field);
             }
             field.alignErrorIcon();
             field.errorIcon.dom.qtip = msg;
             field.errorIcon.dom.qclass = 'x-form-invalid-tip';
             field.errorIcon.show();
-            field.on('resize', field.alignErrorIcon, field);
         },
         clear: function(field){
             field.el.removeClass(field.invalidClass);
             if(field.errorIcon){
                 field.errorIcon.dom.qtip = '';
                 field.errorIcon.hide();
-                field.un('resize', field.alignErrorIcon, field);
             }else{
                 field.el.dom.title = '';
             }
@@ -1300,8 +1311,6 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
     actionMode: 'wrap',
 
-    removeMode: 'container',
-
     defaultTriggerWidth: 17,
 
     // private
@@ -1342,7 +1351,6 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
             this.wrap.setWidth(this.el.getWidth()+this.trigger.getWidth());
         }
         this.resizeEl = this.positionEl = this.wrap;
-        this.updateEditState();
     },
 
     updateEditState: function(){
@@ -1405,6 +1413,7 @@ Ext.form.TriggerField = Ext.extend(Ext.form.TextField,  {
 
     afterRender : function(){
         Ext.form.TriggerField.superclass.afterRender.call(this);
+        this.updateEditState();
     },
 
     // private
@@ -2532,8 +2541,10 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
      */
     shadow : 'sides',
     /**
-     * @cfg {String} listAlign A valid anchor position value. See <tt>{@link Ext.Element#alignTo}</tt> for details
-     * on supported anchor positions (defaults to <tt>'tl-bl?'</tt>)
+     * @cfg {String/Array} listAlign A valid anchor position value. See <tt>{@link Ext.Element#alignTo}</tt> for details
+     * on supported anchor positions and offsets. To specify x/y offsets as well, this value
+     * may be specified as an Array of <tt>{@link Ext.Element#alignTo}</tt> method arguments.</p>
+     * <pre><code>[ 'tl-bl?', [6,0] ]</code></pre>(defaults to <tt>'tl-bl?'</tt>)
      */
     listAlign : 'tl-bl?',
     /**
@@ -2564,6 +2575,12 @@ Ext.form.ComboBox = Ext.extend(Ext.form.TriggerField, {
      * <tt>{@link Ext.form.TriggerField#editable editable} = false</tt>).
      */
     minChars : 4,
+    /**
+     * @cfg {Boolean} autoSelect <tt>true</tt> to select the first result gathered by the data store (defaults
+     * to <tt>true</tt>).  A false value would require a manual selection from the dropdown list to set the components value
+     * unless the value of ({@link #typeAheadDelay}) were true.
+     */
+    autoSelect : true,
     /**
      * @cfg {Boolean} typeAhead <tt>true</tt> to populate and autoselect the remainder of the text being
      * typed after a configurable delay ({@link #typeAheadDelay}) if it matches a known value (defaults
@@ -2732,6 +2749,7 @@ var combo = new Ext.form.ComboBox({
              * @param {Ext.form.ComboBox} combo This combo box
              */
             'collapse',
+
             /**
              * @event beforeselect
              * Fires before a list item is selected. Return false to cancel the selection.
@@ -2844,22 +2862,30 @@ var combo = new Ext.form.ComboBox({
         Ext.form.ComboBox.superclass.initValue.call(this);
         if(this.hiddenField){
             this.hiddenField.value =
-                Ext.isDefined(this.hiddenValue) ? this.hiddenValue :
-                Ext.isDefined(this.value) ? this.value : '';
+                Ext.value(Ext.isDefined(this.hiddenValue) ? this.hiddenValue : this.value, '');
         }
     },
 
     // private
     initList : function(){
         if(!this.list){
-            var cls = 'x-combo-list';
+            var cls = 'x-combo-list',
+                listParent = Ext.getDom(this.getListParent() || Ext.getBody()),
+                zindex = parseInt(Ext.fly(listParent).getStyle('z-index') ,10);
+
+            if (this.ownerCt && !zindex){
+                this.findParentBy(function(ct){
+                    zindex = parseInt(ct.getPositionEl().getStyle('z-index'), 10);
+                    return !!zindex;
+                });
+            }
 
             this.list = new Ext.Layer({
-                parentEl: this.getListParent(),
+                parentEl: listParent,
                 shadow: this.shadow,
                 cls: [cls, this.listClass].join(' '),
                 constrain:false,
-                zindex: 12000
+                zindex: (zindex || 12000) + 5
             });
 
             var lw = this.listWidth || Math.max(this.wrap.getWidth(), this.minListWidth);
@@ -2930,10 +2956,15 @@ var combo = new Ext.form.ComboBox({
                 singleSelect: true,
                 selectedClass: this.selectedClass,
                 itemSelector: this.itemSelector || '.' + cls + '-item',
-                emptyText: this.listEmptyText
+                emptyText: this.listEmptyText,
+                deferEmptyText: false
             });
 
-            this.mon(this.view, 'click', this.onViewClick, this);
+            this.mon(this.view, {
+                containerclick : this.onViewClick,
+                click : this.onViewClick,
+                scope :this
+            });
 
             this.bindStore(this.store, true);
 
@@ -3056,6 +3087,7 @@ var menu = new Ext.menu.Menu({
     initEvents : function(){
         Ext.form.ComboBox.superclass.initEvents.call(this);
 
+
         this.keyNav = new Ext.KeyNav(this.el, {
             "up" : function(e){
                 this.inKeyMode = true;
@@ -3080,7 +3112,7 @@ var menu = new Ext.menu.Menu({
             },
 
             "tab" : function(e){
-                this.onViewClick(false);
+                this.collapse();
                 return true;
             },
 
@@ -3113,6 +3145,7 @@ var menu = new Ext.menu.Menu({
         }
     },
 
+
     // private
     onDestroy : function(){
         if (this.dqTask){
@@ -3194,19 +3227,22 @@ var menu = new Ext.menu.Menu({
                 if(this.editable){
                     this.el.dom.select();
                 }
-                if(!this.selectByValue(this.value, true)){
+
+                if(this.autoSelect !== false && !this.selectByValue(this.value, true)){
                     this.select(0, true);
                 }
             }else{
-                this.selectNext();
+                if(this.autoSelect !== false){
+                    this.selectNext();
+                }
                 if(this.typeAhead && this.lastKey != Ext.EventObject.BACKSPACE && this.lastKey != Ext.EventObject.DELETE){
                     this.taTask.delay(this.typeAheadDelay);
                 }
             }
         }else{
-            this.onEmptyResults();
+            this.collapse();
         }
-        //this.el.focus();
+
     },
 
     // private
@@ -3223,6 +3259,28 @@ var menu = new Ext.menu.Menu({
         }
     },
 
+    // private
+    assertValue  : function(){
+
+        var val = this.getRawValue(),
+            rec = this.findRecord(this.displayField, val);
+
+        if(!rec && this.forceSelection){
+            if(val.length > 0 && val != this.emptyText){
+                this.el.dom.value = Ext.value(this.lastSelectionText, '');
+                this.applyEmptyText();
+            }else{
+                this.clearValue();
+            }
+        }else{
+            if(rec){
+                val = rec.get(this.valueField || this.displayField);
+            }
+            this.setValue(val);
+        }
+
+    },
+
     // private
     onSelect : function(record, index){
         if(this.fireEvent('beforeselect', this, record, index) !== false){
@@ -3283,7 +3341,7 @@ var menu = new Ext.menu.Menu({
         }
         this.lastSelectionText = text;
         if(this.hiddenField){
-            this.hiddenField.value = v;
+            this.hiddenField.value = Ext.value(v, '');
         }
         Ext.form.ComboBox.superclass.setValue.call(this, text);
         this.value = v;
@@ -3328,14 +3386,15 @@ var menu = new Ext.menu.Menu({
             r = s.getAt(index);
         if(r){
             this.onSelect(r, index);
-        }else if(s.getCount() === 0){
-            this.onEmptyResults();
+        }else {
+            this.collapse();
         }
         if(doFocus !== false){
             this.el.focus();
         }
     },
 
+
     // private
     restrictHeight : function(){
         this.innerList.dom.style.height = '';
@@ -3351,15 +3410,10 @@ var menu = new Ext.menu.Menu({
         this.innerList.setHeight(h);
         this.list.beginUpdate();
         this.list.setHeight(h+pad);
-        this.list.alignTo(this.wrap, this.listAlign);
+        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
         this.list.endUpdate();
     },
 
-    // private
-    onEmptyResults : function(){
-        this.collapse();
-    },
-
     /**
      * Returns true if the dropdown list is expanded, else false.
      */
@@ -3402,6 +3456,7 @@ var menu = new Ext.menu.Menu({
                 this.innerList.scrollChildIntoView(el, false);
             }
         }
+
     },
 
     // private
@@ -3432,6 +3487,7 @@ var menu = new Ext.menu.Menu({
     onKeyUp : function(e){
         var k = e.getKey();
         if(this.editable !== false && this.readOnly !== true && (k == e.BACKSPACE || !e.isSpecialKey())){
+
             this.lastKey = k;
             this.dqTask.delay(this.queryDelay);
         }
@@ -3450,21 +3506,14 @@ var menu = new Ext.menu.Menu({
 
     // private
     beforeBlur : function(){
-        var val = this.getRawValue(),
-            rec = this.findRecord(this.displayField, val);
-        if(!rec && this.forceSelection){
-            if(val.length > 0 && val != this.emptyText){
-                this.el.dom.value = Ext.isEmpty(this.lastSelectionText) ? '' : this.lastSelectionText;
-                this.applyEmptyText();
-            }else{
-                this.clearValue();
-            }
-        }else{
-            if(rec){
-                val = rec.get(this.valueField || this.displayField);
-            }
-            this.setValue(val);
-        }
+        this.assertValue();
+    },
+
+    // private
+    postBlur  : function(){
+        Ext.form.ComboBox.superclass.postBlur.call(this);
+        this.collapse();
+        this.inKeyMode = false;
     },
 
     /**
@@ -3555,7 +3604,7 @@ var menu = new Ext.menu.Menu({
             this.doResize(this.bufferSize);
             delete this.bufferSize;
         }
-        this.list.alignTo(this.wrap, this.listAlign);
+        this.list.alignTo.apply(this.list, [this.el].concat(this.listAlign));
         this.list.show();
         if(Ext.isGecko2){
             this.innerList.setOverflow('auto'); // necessary for FF 2.0/Mac
@@ -4272,7 +4321,7 @@ Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
     setValue : function(v){
        if (typeof v == 'boolean') {
             Ext.form.Radio.superclass.setValue.call(this, v);
-        } else {
+        } else if (this.rendered) {
             var r = this.getCheckEl().child('input[name=' + this.el.dom.name + '][value=' + v + ']', true);
             if(r){
                 Ext.getCmp(r.id).setValue(true);
@@ -4280,7 +4329,7 @@ Ext.form.Radio = Ext.extend(Ext.form.Checkbox, {
         }
         return this;
     },
-    
+
     // private
     getCheckEl: function(){
         if(this.inGroup){
@@ -4468,50 +4517,51 @@ Ext.reg('hidden', Ext.form.Hidden);/**
  * @param {Mixed} el The form element or its id
  * @param {Object} config Configuration options
  */
-Ext.form.BasicForm = function(el, config){
-    Ext.apply(this, config);
-    if(Ext.isString(this.paramOrder)){
-        this.paramOrder = this.paramOrder.split(/[\s,|]/);
-    }
-    /**
-     * A {@link Ext.util.MixedCollection MixedCollection} containing all the Ext.form.Fields in this form.
-     * @type MixedCollection
-     * @property items
-     */
-    this.items = new Ext.util.MixedCollection(false, function(o){
-        return o.getItemId();
-    });
-    this.addEvents(
-        /**
-         * @event beforeaction
-         * Fires before any action is performed. Return false to cancel the action.
-         * @param {Form} this
-         * @param {Action} action The {@link Ext.form.Action} to be performed
-         */
-        'beforeaction',
-        /**
-         * @event actionfailed
-         * Fires when an action fails.
-         * @param {Form} this
-         * @param {Action} action The {@link Ext.form.Action} that failed
-         */
-        'actionfailed',
+Ext.form.BasicForm = Ext.extend(Ext.util.Observable, {
+    
+    constructor: function(el, config){
+        Ext.apply(this, config);
+        if(Ext.isString(this.paramOrder)){
+            this.paramOrder = this.paramOrder.split(/[\s,|]/);
+        }
         /**
-         * @event actioncomplete
-         * Fires when an action is completed.
-         * @param {Form} this
-         * @param {Action} action The {@link Ext.form.Action} that completed
+         * A {@link Ext.util.MixedCollection MixedCollection} containing all the Ext.form.Fields in this form.
+         * @type MixedCollection
+         * @property items
          */
-        'actioncomplete'
-    );
-
-    if(el){
-        this.initEl(el);
-    }
-    Ext.form.BasicForm.superclass.constructor.call(this);
-};
+        this.items = new Ext.util.MixedCollection(false, function(o){
+            return o.getItemId();
+        });
+        this.addEvents(
+            /**
+             * @event beforeaction
+             * Fires before any action is performed. Return false to cancel the action.
+             * @param {Form} this
+             * @param {Action} action The {@link Ext.form.Action} to be performed
+             */
+            'beforeaction',
+            /**
+             * @event actionfailed
+             * Fires when an action fails.
+             * @param {Form} this
+             * @param {Action} action The {@link Ext.form.Action} that failed
+             */
+            'actionfailed',
+            /**
+             * @event actioncomplete
+             * Fires when an action is completed.
+             * @param {Form} this
+             * @param {Action} action The {@link Ext.form.Action} that completed
+             */
+            'actioncomplete'
+        );
 
-Ext.extend(Ext.form.BasicForm, Ext.util.Observable, {
+        if(el){
+            this.initEl(el);
+        }
+        Ext.form.BasicForm.superclass.constructor.call(this);    
+    },
+    
     /**
      * @cfg {String} method
      * The request method to use (GET or POST) for form actions if one isn't supplied in the action options.
@@ -5664,7 +5714,7 @@ Ext.form.FieldSet = Ext.extend(Ext.Panel, {
             this.el = document.createElement('fieldset');\r
             this.el.id = this.id;\r
             if (this.title || this.header || this.checkboxToggle) {\r
-                this.el.appendChild(document.createElement('legend')).className = 'x-fieldset-header';\r
+                this.el.appendChild(document.createElement('legend')).className = this.baseCls + '-header';\r
             }\r
         }\r
 \r
@@ -6041,7 +6091,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     createToolbar : function(editor){
         var items = [];
         var tipsEnabled = Ext.QuickTips && Ext.QuickTips.isEnabled();\r
-        
+
 
         function btn(id, toggle, handler){
             return {
@@ -6067,7 +6117,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                     html: this.createFontOptions()\r
                }\r
             });
-            
+
             items.push(
                 fontSelectItem,
                 '-'
@@ -6178,16 +6228,16 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 );
             }
         }\r
\r
+\r
         // build the toolbar\r
         var tb = new Ext.Toolbar({\r
             renderTo: this.wrap.dom.firstChild,\r
             items: items\r
         });\r
-        \r
+\r
         if (fontSelectItem) {\r
             this.fontSelect = fontSelectItem.el;\r
-            \r
+\r
             this.mon(this.fontSelect, 'change', function(){\r
                 var font = this.fontSelect.dom.value;\r
                 this.relayCmd('fontname', font);\r
@@ -6200,9 +6250,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         this.mon(tb.el, 'click', function(e){\r
             e.preventDefault();\r
         });\r
-       \r
-        \r
-        
+
         this.tb = tb;
     },
 
@@ -6217,24 +6265,27 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     },
 
     setReadOnly: function(readOnly){
-        if(this.initialized){
-            var newDM = readOnly ? 'off' : 'on',
-                doc = this.getDoc();
-            if(String(doc.designMode).toLowerCase() != newDM){
-                doc.designMode = newDM;
-            }
-            this.disableItems(!readOnly);
-        }
+
         Ext.form.HtmlEditor.superclass.setReadOnly.call(this, readOnly);
+        if(this.initialized){\r
+            this.setDesignMode(!readOnly);\r
+            var bd = this.getEditorBody();\r
+            if(bd){\r
+                bd.style.cursor = this.readOnly ? 'default' : 'text';\r
+            }\r
+            this.disableItems(readOnly);\r
+        }\r
     },
 
     /**
      * Protected method that will not generally be called directly. It
      * is called when the editor initializes the iframe with HTML contents. Override this method if you
      * want to change the initialization markup of the iframe (e.g. to add stylesheets).
+     *\r
+     * Note: IE8-Standards has unwanted scroller behavior, so the default meta tag forces IE7 compatibility\r
      */
     getDocMarkup : function(){
-        return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
+        return '<html><head><meta http-equiv="X-UA-Compatible" content="IE=EmulateIE7" /><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
     },
 
     // private
@@ -6269,8 +6320,8 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         this.createToolbar(this);
 
         this.disableItems(true);
-        // is this needed?
-        // this.tb.doLayout();
+
+        this.tb.doLayout();
 
         this.createIFrame();
 
@@ -6285,9 +6336,9 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         var iframe = document.createElement('iframe');
         iframe.name = Ext.id();
         iframe.frameBorder = '0';
-        iframe.src = Ext.SSL_SECURE_URL;
-        this.wrap.dom.appendChild(iframe);
+        iframe.style.overflow = 'auto';\r
 
+        this.wrap.dom.appendChild(iframe);
         this.iframe = iframe;
 
         this.monitorTask = Ext.TaskMgr.start({
@@ -6311,7 +6362,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 var doc = this.getDoc();
                 if(doc.body || doc.readyState == 'complete'){
                     Ext.TaskMgr.stop(task);
-                    doc.designMode="on";
+                    this.setDesignMode(true);
                     this.initEditor.defer(10, this);
                 }
             },
@@ -6329,12 +6380,34 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             if(!doc){
                 return;
             }
-            if(!doc.editorInitialized || String(doc.designMode).toLowerCase() != 'on'){
+            if(!doc.editorInitialized || this.getDesignMode() != 'on'){
                 this.initFrame();
             }
         }
     },
-
+\r
+    /* private\r
+     * set current design mode. To enable, mode can be true or 'on', off otherwise\r
+     */\r
+    setDesignMode : function(mode){\r
+        var doc ;\r
+        if(doc = this.getDoc()){\r
+            if(this.readOnly){\r
+                mode = false;\r
+            }\r
+            doc.designMode = (/on|true/i).test(String(mode).toLowerCase()) ?'on':'off';\r
+        }\r
+\r
+    },\r
+\r
+    // private\r
+    getDesignMode : function(){
+        var doc = this.getDoc();\r
+        if(!doc){ return ''; }\r
+        return String(doc.designMode).toLowerCase();\r
+\r
+    },\r
+\r
     disableItems: function(disabled){
         if(this.fontSelect){
             this.fontSelect.dom.disabled = disabled;
@@ -6378,7 +6451,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
         }
         this.sourceEditMode = sourceEditMode === true;
         var btn = this.tb.getComponent('sourceedit');
-        
+
         if(btn.pressed !== this.sourceEditMode){
             btn.toggle(this.sourceEditMode);
             if(!btn.xtbHidden){
@@ -6393,8 +6466,8 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             this.el.dom.removeAttribute('tabIndex');
             this.el.focus();
         }else{
-            if(this.initialized && !this.readOnly){
-                this.disableItems(false);
+            if(this.initialized){
+                this.disableItems(this.readOnly);
             }
             this.pushValue();
             this.iframe.className = '';
@@ -6508,14 +6581,13 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 this.getEditorBody().innerHTML = v;
                 if(Ext.isGecko){
                     // Gecko hack, see: https://bugzilla.mozilla.org/show_bug.cgi?id=232791#c8
-                    var d = this.getDoc(),
-                        mode = d.designMode.toLowerCase();
-
-                    d.designMode = mode.toggle('on', 'off');
-                    d.designMode = mode;
+                    this.setDesignMode(false);  //toggle off first\r
+\r
                 }
+                this.setDesignMode(true);\r
                 this.fireEvent('push', this, v);
             }
+\r
         }
     },
 
@@ -6541,12 +6613,12 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat'),
                 doc,
                 fn;
-                
+
             ss['background-attachment'] = 'fixed'; // w3c
             dbody.bgProperties = 'fixed'; // ie
 
             Ext.DomHelper.applyStyles(dbody, ss);
-            
+
             doc = this.getDoc();
 
             if(doc){
@@ -6605,7 +6677,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
                 this.wrap.remove();
             }
         }
-        
+
         if(this.el){
             this.el.removeAllListeners();
             this.el.remove();
@@ -6616,7 +6688,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     // private
     onFirstFocus : function(){
         this.activated = true;
-        this.disableItems(false);
+        this.disableItems(this.readOnly);
         if(Ext.isGecko){ // prevent silly gecko errors
             this.win.focus();
             var s = this.win.getSelection();
@@ -6686,7 +6758,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
             return;
         }
 
-        var btns = this.tb.items.map, 
+        var btns = this.tb.items.map,
             doc = this.getDoc();
 
         if(this.enableFont && !Ext.isSafari2){
@@ -6803,7 +6875,7 @@ Ext.form.HtmlEditor = Ext.extend(Ext.form.Field, {
     fixKeys : function(){ // load time branching for fastest keydown performance
         if(Ext.isIE){
             return function(e){
-                var k = e.getKey(), 
+                var k = e.getKey(),
                     doc = this.getDoc(),
                         r;
                 if(k == e.TAB){