Roo/form/ComboBoxArray.js
[roojs1] / roojs-ui-debug.js
index 35f82b8..8f8d5a0 100644 (file)
@@ -5419,6 +5419,18 @@ Roo.extend(Roo.data.Store, Roo.util.Observable, {
         this.sortInfo = meta.sortInfo || this.sortInfo;
         this.modified = [];
         this.fireEvent('metachange', this, this.reader.meta);
+    },
+    
+    moveIndex : function(data, type)
+    {
+        var index = this.indexOf(data);
+        
+        var newIndex = index + type;
+        
+        this.remove(data);
+        
+        this.insert(newIndex, data);
+        
     }
 });/*
  * Based on:
@@ -6266,7 +6278,7 @@ Roo.extend(Roo.data.JsonReader, Roo.data.DataReader, {
                if (s.id) {
                        var g = this.getJsonAccessor(s.id);
                        this.getId = function(rec) {
-                               var r = g(rec);
+                               var r = g(rec);  
                                return (r === undefined || r === "") ? null : r;
                        };
                } else {
@@ -8416,6 +8428,8 @@ Roo.SplitBar.BOTTOM = 4;
  */
 Roo.View = function(config, depreciated_tpl, depreciated_config){
     
+    this.parent = false;
+    
     if (typeof(depreciated_tpl) == 'undefined') {
         // new way.. - universal constructor.
         Roo.apply(this, config);
@@ -8439,10 +8453,7 @@ Roo.View = function(config, depreciated_tpl, depreciated_config){
     
     
     this.tpl.compile();
-   
-  
     
-     
     /** @private */
     this.addEvents({
         /**
@@ -8593,6 +8604,11 @@ Roo.extend(Roo.View, Roo.util.Observable, {
      */
     toggleSelect : false,
     
+    /**
+     * @cfg {Boolean} tickable - selecting 
+     */
+    tickable : false,
+    
     /**
      * Returns the element this view is bound to.
      * @return {Roo.Element}
@@ -8607,6 +8623,7 @@ Roo.extend(Roo.View, Roo.util.Observable, {
      * Refreshes the view. - called by datachanged on the store. - do not call directly.
      */
     refresh : function(){
+        Roo.log('refresh');
         var t = this.tpl;
         
         // if we are using something like 'domtemplate', then
@@ -8640,10 +8657,26 @@ Roo.extend(Roo.View, Roo.util.Observable, {
         for(var i = 0, len = records.length; i < len; i++){
             var data = this.prepareData(records[i].data, i, records[i]);
             this.fireEvent("preparedata", this, data, i, records[i]);
+            
+            var d = Roo.apply({}, data);
+            
+            if(this.tickable){
+                Roo.apply(d, {'roo-id' : Roo.id()});
+                
+                var _this = this;
+            
+                Roo.each(this.parent.item, function(item){
+                    if(item[_this.parent.valueField] != data[_this.parent.valueField]){
+                        return;
+                    }
+                    Roo.apply(d, {'roo-data-checked' : 'checked'});
+                });
+            }
+            
             html[html.length] = Roo.util.Format.trim(
                 this.dataName ?
-                    t.applySubtemplate(this.dataName, data, this.store.meta) :
-                    t.apply(data)
+                    t.applySubtemplate(this.dataName, d, this.store.meta) :
+                    t.apply(d)
             );
         }
         
@@ -8653,6 +8686,7 @@ Roo.extend(Roo.View, Roo.util.Observable, {
         this.nodes = el.dom.childNodes;
         this.updateIndexes(0);
     },
+    
 
     /**
      * Function to override to reformat the data that is sent to
@@ -8668,6 +8702,7 @@ Roo.extend(Roo.View, Roo.util.Observable, {
     },
 
     onUpdate : function(ds, record){
+         Roo.log('on update');   
         this.clearSelections();
         var index = this.store.indexOf(record);
         var n = this.nodes[index];
@@ -8681,6 +8716,7 @@ Roo.extend(Roo.View, Roo.util.Observable, {
 // --------- FIXME     
     onAdd : function(ds, records, index)
     {
+        Roo.log(['on Add', ds, records, index] );        
         this.clearSelections();
         if(this.nodes.length == 0){
             this.refresh();
@@ -8700,10 +8736,12 @@ Roo.extend(Roo.View, Roo.util.Observable, {
     },
 
     onRemove : function(ds, record, index){
+        Roo.log('onRemove');
         this.clearSelections();
         var el = this.dataName  ?
             this.el.child('.roo-tpl-' + this.dataName) :
             this.el; 
+        
         el.dom.removeChild(this.nodes[index]);
         this.updateIndexes(index);
     },
@@ -8760,9 +8798,12 @@ Roo.extend(Roo.View, Roo.util.Observable, {
      * onbeforeLoad - masks the loading area.
      *
      */
-    onBeforeLoad : function()
+    onBeforeLoad : function(store,opts)
     {
-        this.el.update("");
+         Roo.log('onBeforeLoad');   
+        if (!opts.add) {
+            this.el.update("");
+        }
         this.el.mask(this.mask ? this.mask : "Loading" ); 
     },
     onLoad : function ()
@@ -8842,7 +8883,11 @@ Roo.extend(Roo.View, Roo.util.Observable, {
                 this.select(item, this.multiSelect && e.ctrlKey);
                 this.lastSelection = item;
             }
-            e.preventDefault();
+            
+            if(!this.tickable){
+                e.preventDefault();
+            }
+            
         }
         return true;
     },
@@ -8927,6 +8972,7 @@ Roo.extend(Roo.View, Roo.util.Observable, {
         if(!keepExisting){
             this.clearSelections(true);
         }
+        
         if(this.fireEvent("beforeselect", this, node, this.selections) !== false){
             Roo.fly(node).addClass(this.selectedClass);
             this.selections.push(node);
@@ -10770,7 +10816,11 @@ Roo.extend(Roo.TabPanelItem, Roo.util.Observable, {
     autoSize : function(){
         //this.el.beginMeasure();
         this.textEl.setWidth(1);
-        this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr"));
+        /*
+         *  #2804 [new] Tabs in Roojs
+         *  increase the width by 2-4 pixels to prevent the ellipssis showing in chrome
+         */
+        this.setWidth(this.textEl.dom.scrollWidth+this.pnode.getPadding("lr")+this.inner.getPadding("lr") + 2);
         //this.el.endMeasure();
     },
 
@@ -19150,7 +19200,8 @@ Roo.extend(Roo.menu.Menu, Roo.util.Observable, {
             tag: "a", cls: "x-menu-focus", href: "#", onclick: "return false;", tabIndex:"-1"
         });
         var ul = el.createChild({tag: "ul", cls: "x-menu-list"});
-        ul.on("click", this.onClick, this);
+        ul.on(Roo.isTouch ? 'touchstart' : 'click'   , this.onClick, this);
+        
         ul.on("mouseover", this.onMouseOver, this);
         ul.on("mouseout", this.onMouseOut, this);
         this.items.each(function(item){
@@ -19203,11 +19254,28 @@ Roo.extend(Roo.menu.Menu, Roo.util.Observable, {
 
     // private
     onClick : function(e){
-        var t;
-        if(t = this.findTargetItem(e)){
-            t.onClick(e);
-            this.fireEvent("click", this, t, e);
+        Roo.log("menu.onClick");
+        var t = this.findTargetItem(e);
+        if(!t){
+            return;
+        }
+        Roo.log(e);
+        if (Roo.isTouch && e.type == 'touchstart' && t.menu  && !t.disabled) {
+            if(t == this.activeItem && t.shouldDeactivate(e)){
+                this.activeItem.deactivate();
+                delete this.activeItem;
+                return;
+            }
+            if(t.canActivate){
+                this.setActiveItem(t, true);
+            }
+            return;
+            
+            
         }
+        
+        t.onClick(e);
+        this.fireEvent("click", this, t, e);
     },
 
     // private
@@ -23341,9 +23409,8 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
     getValue : function(){
         if(this.valueField){
             return typeof this.value != 'undefined' ? this.value : '';
-        }else{
-            return Roo.form.ComboBox.superclass.getValue.call(this);
         }
+        return Roo.form.ComboBox.superclass.getValue.call(this);
     },
 
     /**
@@ -23819,6 +23886,17 @@ Roo.extend(Roo.form.ComboBox, Roo.form.TriggerField, {
 
 Roo.form.ComboBoxArray = function(config)
 {
+    this.addEvents({
+        /**
+         * @event remove
+         * Fires when remove the value from the list
+            * @param {Roo.form.ComboBoxArray} _self This combo box array
+             * @param {Roo.form.ComboBoxArray.Item} item removed item
+            */
+        'remove' : true
+        
+        
+    });
     
     Roo.form.ComboBoxArray.superclass.constructor.call(this, config);
     
@@ -24080,7 +24158,7 @@ Roo.extend(Roo.form.ComboBoxArray, Roo.form.TextField,
             }, this) 
              
         }
-        if (typeof(v) == 'object') {
+        if (typeof(v) == 'object' ) {
             // then let's assume it's an array of objects..
             Roo.each(v, function(l) {
                 this.addItem(l);
@@ -24230,11 +24308,15 @@ Roo.extend(Roo.form.ComboBoxArray.Item, Roo.BoxComponent, {
    
     remove : function()
     {
-        
+        if(this.cb.disabled){
+            return;
+        }
         this.cb.items.remove(this);
         this.el.child('img').un('click', this.remove, this);
         this.el.remove();
         this.cb.updateHiddenEl();
+        
+        this.cb.fireEvent('remove', this.cb, this);
     }
 });/*
  * Based on:
@@ -24384,6 +24466,9 @@ Roo.extend(Roo.form.Checkbox, Roo.form.Field,  {
 
        // private
     onClick : function(){ 
+        if (this.disabled) {
+            return;
+        }
         this.setChecked(!this.checked);
 
         //if(this.el.dom.checked != this.checked){
@@ -24517,50 +24602,98 @@ Roo.extend(Roo.form.Radio, Roo.form.Checkbox, {
 });//<script type="text/javascript">
 
 /*
- * Ext JS Library 1.1.1
+ * Based  Ext JS Library 1.1.1
  * Copyright(c) 2006-2007, Ext JS, LLC.
- * licensing@extjs.com
- * 
- * http://www.extjs.com/license
+ * LGPL
+ *
  */
  
- /*
-  * 
-  * Known bugs:
-  * Default CSS appears to render it as fixed text by default (should really be Sans-Serif)
-  * - IE ? - no idea how much works there.
-  * 
-  * 
-  * 
-  */
-
 /**
- * @class Ext.form.HtmlEditor
- * @extends Ext.form.Field
- * Provides a lightweight HTML Editor component.
+ * @class Roo.HtmlEditorCore
+ * @extends Roo.Component
+ * Provides a the editing component for the HTML editors in Roo. (bootstrap and Roo.form)
  *
- * This has been tested on Fireforx / Chrome.. IE may not be so great..
- * 
- * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
- * supported by this editor.</b><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
  * any element that has display set to 'none' can cause problems in Safari and Firefox.<br/><br/>
  */
-Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
-      /**
-     * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
-     */
-    toolbars : false,
-    /**
-     * @cfg {String} createLinkText The default text for the create link prompt
-     */
-    createLinkText : 'Please enter the URL for the link:',
-    /**
-     * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
+
+Roo.HtmlEditorCore = function(config){
+    
+    
+    Roo.HtmlEditorCore.superclass.constructor.call(this, config);
+    
+    
+    this.addEvents({
+        /**
+         * @event initialize
+         * Fires when the editor is fully initialized (including the iframe)
+         * @param {Roo.HtmlEditorCore} this
+         */
+        initialize: true,
+        /**
+         * @event activate
+         * Fires when the editor is first receives the focus. Any insertion must wait
+         * until after this event.
+         * @param {Roo.HtmlEditorCore} this
+         */
+        activate: true,
+         /**
+         * @event beforesync
+         * Fires before the textarea is updated with content from the editor iframe. Return false
+         * to cancel the sync.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        beforesync: true,
+         /**
+         * @event beforepush
+         * Fires before the iframe editor is updated with content from the textarea. Return false
+         * to cancel the push.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        beforepush: true,
+         /**
+         * @event sync
+         * Fires when the textarea is updated with content from the editor iframe.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        sync: true,
+         /**
+         * @event push
+         * Fires when the iframe editor is updated with content from the textarea.
+         * @param {Roo.HtmlEditorCore} this
+         * @param {String} html
+         */
+        push: true,
+        
+        /**
+         * @event editorevent
+         * Fires when on any editor (mouse up/down cursor movement etc.) - used for toolbar hooks.
+         * @param {Roo.HtmlEditorCore} this
+         */
+        editorevent: true
+    });
+    
+    // at this point this.owner is set, so we can start working out the whitelisted / blacklisted elements
+    
+    // defaults : white / black...
+    this.applyBlacklists();
+    
+    
+    
+};
+
+
+Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
+
+
+     /**
+     * @cfg {Roo.form.HtmlEditor|Roo.bootstrap.HtmlEditor} the owner field 
      */
-    defaultLinkValue : 'http:/'+'/',
-   
+    
+    owner : false,
+    
      /**
      * @cfg {String} resizable  's' or 'se' or 'e' - wrapps the element in a
      *                        Roo.resizable.
@@ -24594,100 +24727,13 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     iframePad:3,
     hideMode:'offsets',
     
-    defaultAutoCreate : { // modified by initCompnoent..
-        tag: "textarea",
-        style:"width:500px;height:300px;",
-        autocomplete: "off"
-    },
-
-    // private
-    initComponent : function(){
-        this.addEvents({
-            /**
-             * @event initialize
-             * Fires when the editor is fully initialized (including the iframe)
-             * @param {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
-             */
-            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 {String} html
-             */
-            beforesync: true,
-             /**
-             * @event beforepush
-             * Fires before the iframe editor is updated with content from the textarea. Return false
-             * to cancel the push.
-             * @param {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 {String} html
-             */
-            sync: true,
-             /**
-             * @event push
-             * Fires when the iframe editor is updated with content from the textarea.
-             * @param {HtmlEditor} this
-             * @param {String} html
-             */
-            push: true,
-             /**
-             * @event editmodechange
-             * Fires when the editor switches edit modes
-             * @param {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
-             */
-            editorevent: true
-        });
-        this.defaultAutoCreate =  {
-            tag: "textarea",
-            style:'width: ' + this.width + 'px;height: ' + this.height + 'px;',
-            autocomplete: "off"
-        };
-    },
-
-    /**
-     * Protected method that will not generally be called directly. It
-     * is called when the editor creates its toolbar. Override this method if you need to
-     * add custom toolbar buttons.
-     * @param {HtmlEditor} editor
-     */
-    createToolbar : function(editor){
-        if (!editor.toolbars || !editor.toolbars.length) {
-            editor.toolbars = [ new Roo.form.HtmlEditor.ToolbarStandard() ]; // can be empty?
-        }
-        
-        for (var i =0 ; i < editor.toolbars.length;i++) {
-            editor.toolbars[i] = Roo.factory(
-                    typeof(editor.toolbars[i]) == 'string' ?
-                        { xtype: editor.toolbars[i]} : editor.toolbars[i],
-                Roo.form.HtmlEditor);
-            editor.toolbars[i].init(editor);
-        }
-         
-        
-    },
+    clearUp: true,
+    
+    // blacklist + whitelisted elements..
+    black: false,
+    white: false,
+     
+    
 
     /**
      * Protected method that will not generally be called directly. It
@@ -24697,6 +24743,9 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     getDocMarkup : function(){
         // body styles..
         var st = '';
+        Roo.log(this.stylesheets);
+        
+        // inherit styels from page...?? 
         if (this.stylesheets === false) {
             
             Roo.get(document.head).select('style').each(function(node) {
@@ -24735,43 +24784,28 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     onRender : function(ct, position)
     {
         var _t = this;
-        Roo.form.HtmlEditor.superclass.onRender.call(this, ct, position);
+        //Roo.HtmlEditorCore.superclass.onRender.call(this, ct, position);
+        this.el = this.owner.inputEl ? this.owner.inputEl() : this.owner.el;
+        
+        
         this.el.dom.style.border = '0 none';
         this.el.dom.setAttribute('tabIndex', -1);
-        this.el.addClass('x-hidden');
+        this.el.addClass('x-hidden hide');
+        
+        
+        
         if(Roo.isIE){ // fix IE 1px bogus margin
             this.el.applyStyles('margin-top:-1px;margin-bottom:-1px;')
         }
-        this.wrap = this.el.wrap({
-            cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
-        });
+       
         
-        if (this.resizable) {
-            this.resizeEl = new Roo.Resizable(this.wrap, {
-                pinned : true,
-                wrap: true,
-                dynamic : true,
-                minHeight : this.height,
-                height: this.height,
-                handles : this.resizable,
-                width: this.width,
-                listeners : {
-                    resize : function(r, w, h) {
-                        _t.onResize(w,h); // -something
-                    }
-                }
-            });
-            
-        }
-
         this.frameId = Roo.id();
         
-        this.createToolbar(this);
-        
-      
+         
         
-        var iframe = this.wrap.createChild({
+        var iframe = this.owner.wrap.createChild({
             tag: 'iframe',
+            cls: 'form-control', // bootstrap..
             id: this.frameId,
             name: this.frameId,
             frameBorder : 'no',
@@ -24779,9 +24813,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         }, this.el
         );
         
-       // console.log(iframe);
-        //this.wrap.dom.appendChild(iframe);
-
+        
         this.iframe = iframe.dom;
 
          this.assignDocWin();
@@ -24808,53 +24840,35 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
             },
             interval : 10,
-            duration:10000,
+            duration: 10000,
             scope: this
         };
         Roo.TaskMgr.start(task);
 
-        if(!this.width){
-            this.setSize(this.wrap.getSize());
-        }
-        if (this.resizeEl) {
-            this.resizeEl.resizeTo.defer(100, this.resizeEl,[ this.width,this.height ] );
-            // should trigger onReize..
-        }
+        
+         
     },
 
     // private
     onResize : function(w, h)
     {
-        //Roo.log('resize: ' +w + ',' + h );
-        Roo.form.HtmlEditor.superclass.onResize.apply(this, arguments);
-        if(this.el && this.iframe){
-            if(typeof w == 'number'){
-                var aw = w - this.wrap.getFrameWidth('lr');
-                this.el.setWidth(this.adjustWidth('textarea', aw));
-                this.iframe.style.width = aw + 'px';
-            }
-            if(typeof h == 'number'){
-                var tbh = 0;
-                for (var i =0; i < this.toolbars.length;i++) {
-                    // fixme - ask toolbars for heights?
-                    tbh += this.toolbars[i].tb.el.getHeight();
-                    if (this.toolbars[i].footer) {
-                        tbh += this.toolbars[i].footer.el.getHeight();
-                    }
-                }
-                
-                
-                
-                
-                var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
-                ah -= 5; // knock a few pixes off for look..
-                this.el.setHeight(this.adjustWidth('textarea', ah));
-                this.iframe.style.height = ah + 'px';
-                if(this.doc){
-                    (this.doc.body || this.doc.documentElement).style.height = (ah - (this.iframePad*2)) + 'px';
-                }
+         Roo.log('resize: ' +w + ',' + h );
+        //Roo.HtmlEditorCore.superclass.onResize.apply(this, arguments);
+        if(!this.iframe){
+            return;
+        }
+        if(typeof w == 'number'){
+            
+            this.iframe.style.width = w + 'px';
+        }
+        if(typeof h == 'number'){
+            
+            this.iframe.style.height = h + 'px';
+            if(this.doc){
+                (this.doc.body || this.doc.documentElement).style.height = (h - (this.iframePad*2)) + 'px';
             }
         }
+        
     },
 
     /**
@@ -24866,67 +24880,20 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         this.sourceEditMode = sourceEditMode === true;
         
         if(this.sourceEditMode){
-//            Roo.log('in');
-//            Roo.log(this.syncValue());
-            this.syncValue();
-            this.iframe.className = 'x-hidden';
-            this.el.removeClass('x-hidden');
-            this.el.dom.removeAttribute('tabIndex');
-            this.el.focus();
+            Roo.get(this.iframe).addClass(['x-hidden','hide']);     //FIXME - what's the BS styles for these
+            
         }else{
-//            Roo.log('out')
-//            Roo.log(this.pushValue()); 
-            this.pushValue();
-            this.iframe.className = '';
-            this.el.addClass('x-hidden');
-            this.el.dom.setAttribute('tabIndex', -1);
+            Roo.get(this.iframe).removeClass(['x-hidden','hide']);
+            //this.iframe.className = '';
             this.deferFocus();
         }
-        this.setSize(this.wrap.getSize());
-        this.fireEvent('editmodechange', this, this.sourceEditMode);
-    },
-
-    // private used internally
-    createLink : function(){
-        var url = prompt(this.createLinkText, this.defaultLinkValue);
-        if(url && url != 'http:/'+'/'){
-            this.relayCmd('createlink', url);
-        }
-    },
-
-    // private (for BoxComponent)
-    adjustSize : Roo.BoxComponent.prototype.adjustSize,
-
-    // private (for BoxComponent)
-    getResizeEl : function(){
-        return this.wrap;
-    },
-
-    // private (for BoxComponent)
-    getPositionEl : function(){
-        return this.wrap;
-    },
-
-    // private
-    initEvents : function(){
-        this.originalValue = this.getValue();
+        //this.setSize(this.owner.wrap.getSize());
+        //this.fireEvent('editmodechange', this, this.sourceEditMode);
     },
 
-    /**
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
-     * @method
-     */
-    markInvalid : Roo.emptyFn,
-    /**
-     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
-     * @method
-     */
-    clearInvalid : Roo.emptyFn,
-
-    setValue : function(v){
-        Roo.form.HtmlEditor.superclass.setValue.call(this, v);
-        this.pushValue();
-    },
+    
+  
 
     /**
      * Protected method that will not generally be called directly. If you need/want
@@ -24948,6 +24915,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     },
 
     /**
+     * HTML Editor -> Textarea
      * Protected method that will not generally be called directly. Syncs the contents
      * of the editor iframe with the textarea.
      */
@@ -24958,7 +24926,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             var html = bd.innerHTML;
             if(Roo.isSafari){
                 var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
-                var m = bs.match(/text-align:(.*?);/i);
+                var m = bs ? bs.match(/text-align:(.*?);/i) : false;
                 if(m && m[1]){
                     html = '<div style="'+m[0]+'">' + html + '</div>';
                 }
@@ -24977,9 +24945,9 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 }
                 return "&#"+cc+";" 
             });
-            if(this.fireEvent('beforesync', this, html) !== false){
+            if(this.owner.fireEvent('beforesync', this, html) !== false){
                 this.el.dom.value = html;
-                this.fireEvent('sync', this, html);
+                this.owner.fireEvent('sync', this, html);
             }
         }
     },
@@ -24990,18 +24958,18 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
      */
     pushValue : function(){
         if(this.initialized){
-            var v = this.el.dom.value;
+            var v = this.el.dom.value.trim();
             
-            if(v.length < 1){
-                v = '&#160;';
-            }
+//            if(v.length < 1){
+//                v = '&#160;';
+//            }
             
-            if(this.fireEvent('beforepush', this, v) !== false){
+            if(this.owner.fireEvent('beforepush', this, v) !== false){
                 var d = (this.doc.body || this.doc.documentElement);
                 d.innerHTML = v;
                 this.cleanUpPaste();
                 this.el.dom.value = d.innerHTML;
-                this.fireEvent('push', this, v);
+                this.owner.fireEvent('push', this, v);
             }
         }
     },
@@ -25028,11 +24996,18 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             this.doc = iframe.contentWindow.document;
             this.win = iframe.contentWindow;
         } else {
-            if (!Roo.get(this.frameId)) {
+//            if (!Roo.get(this.frameId)) {
+//                return;
+//            }
+//            this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
+//            this.win = Roo.get(this.frameId).dom.contentWindow;
+            
+            if (!Roo.get(this.frameId) && !iframe.contentDocument) {
                 return;
             }
+            
             this.doc = (iframe.contentDocument || Roo.get(this.frameId).dom.document);
-            this.win = Roo.get(this.frameId).dom.contentWindow;
+            this.win = (iframe.contentWindow || Roo.get(this.frameId).dom.contentWindow);
         }
     },
     
@@ -25052,10 +25027,12 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         //var ss = this.el.getStyles('font-size', 'font-family', 'background-image', 'background-repeat');
         // this copies styles from the containing element into thsi one..
         // not sure why we need all of this..
-        var ss = this.el.getStyles('font-size', 'background-image', 'background-repeat');
-        ss['background-attachment'] = 'fixed'; // w3c
+        //var ss = this.el.getStyles('font-size', 'background-image', 'background-repeat');
+        
+        //var ss = this.el.getStyles( 'background-image', 'background-repeat');
+        //ss['background-attachment'] = 'fixed'; // w3c
         dbody.bgProperties = 'fixed'; // ie
-        Roo.DomHelper.applyStyles(dbody, ss);
+        //Roo.DomHelper.applyStyles(dbody, ss);
         Roo.EventManager.on(this.doc, {
             //'mousedown': this.onEditorEvent,
             'mouseup': this.onEditorEvent,
@@ -25073,7 +25050,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         }
         this.initialized = true;
 
-        this.fireEvent('initialize', this);
+        this.owner.fireEvent('initialize', this);
         this.pushValue();
     },
 
@@ -25084,13 +25061,13 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         
         if(this.rendered){
             
-            for (var i =0; i < this.toolbars.length;i++) {
-                // fixme - ask toolbars for heights?
-                this.toolbars[i].onDestroy();
-            }
+            //for (var i =0; i < this.toolbars.length;i++) {
+            //    // fixme - ask toolbars for heights?
+            //    this.toolbars[i].onDestroy();
+           // }
             
-            this.wrap.dom.innerHTML = '';
-            this.wrap.remove();
+            //this.wrap.dom.innerHTML = '';
+            //this.wrap.remove();
         }
     },
 
@@ -25101,10 +25078,8 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         
         
         this.activated = true;
-        for (var i =0; i < this.toolbars.length;i++) {
-            this.toolbars[i].onFirstFocus();
-        }
-       
+         
+    
         if(Roo.isGecko){ // prevent silly gecko errors
             this.win.focus();
             var s = this.win.getSelection();
@@ -25119,7 +25094,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 this.execCmd('styleWithCSS', false);
             }catch(e){}
         }
-        this.fireEvent('activate', this);
+        this.owner.fireEvent('activate', this);
     },
 
     // private
@@ -25144,7 +25119,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     },
 
     onEditorEvent : function(e){
-        this.fireEvent('editorevent', this, e);
+        this.owner.fireEvent('editorevent', this, e);
       //  this.updateToolbar();
         this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
     },
@@ -25179,10 +25154,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
         range.insertNode(this.doc.createTextNode(txt));
     } ,
     
-    // private
-    relayBtnCmd : function(btn){
-        this.relayCmd(btn.cmd);
-    },
+     
 
     /**
      * Executes a Midas editor command on the editor document and performs necessary focus and
@@ -25193,9 +25165,9 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     relayCmd : function(cmd, value){
         this.win.focus();
         this.execCmd(cmd, value);
-        this.fireEvent('editorevent', this);
+        this.owner.fireEvent('editorevent', this);
         //this.updateToolbar();
-        this.deferFocus();
+        this.owner.deferFocus();
     },
 
     /**
@@ -25587,7 +25559,8 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     cleanUpPaste :  function()
     {
         // cleans up the whole document..
-         Roo.log('cleanuppaste');
+        Roo.log('cleanuppaste');
+        
         this.cleanUpChildren(this.doc.body);
         var clean = this.cleanWordChars(this.doc.body.innerHTML);
         if (clean != this.doc.body.innerHTML) {
@@ -25597,7 +25570,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
     },
     
     cleanWordChars : function(input) {// change the chars to hex code
-        var he = Roo.form.HtmlEditor;
+        var he = Roo.HtmlEditorCore;
         
         var output = input;
         Roo.each(he.swapCodes, function(sw) { 
@@ -25636,15 +25609,18 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             // clean up silly Windows -- stuff?
             return; 
         }
+        var lcname = node.tagName.toLowerCase();
+        // we ignore whitelists... ?? = not really the way to go, but we probably have not got a full
+        // whitelist of tags..
         
-        if (Roo.form.HtmlEditor.black.indexOf(node.tagName.toLowerCase()) > -1) {
+        if (this.black.indexOf(lcname) > -1 && this.clearUp ) {
             // remove node.
             node.parentNode.removeChild(node);
             return;
             
         }
         
-        var remove_keep_children= Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1;
+        var remove_keep_children= Roo.HtmlEditorCore.remove.indexOf(node.tagName.toLowerCase()) > -1;
         
         // remove <a name=....> as rendering on yahoo mailer is borked with this.
         // this will have to be flaged elsewhere - perhaps ablack=name... on the mailer..
@@ -25687,15 +25663,15 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
             
         }
         
+        var cwhite = this.cwhite;
+        var cblack = this.cblack;
+            
         function cleanStyle(n,v)
         {
             if (v.match(/expression/)) { //XSS?? should we even bother..
                 node.removeAttribute(n);
                 return;
             }
-            var cwhite = typeof(ed.cwhite) == 'undefined' ? Roo.form.HtmlEditor.cwhite : ed.cwhite;
-            var cblack = typeof(ed.cblack) == 'undefined' ? Roo.form.HtmlEditor.cblack : ed.cblack;
-            
             
             var parts = v.split(/;/);
             var clean = [];
@@ -25708,8 +25684,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 var l = p.split(':').shift().replace(/\s+/g,'');
                 l = l.replace(/^\s+/g,'').replace(/\s+$/g,'');
                 
-                
-                if ( cblack.indexOf(l) > -1) {
+                if ( cwhite.length && cblack.indexOf(l) > -1) {
 //                    Roo.log('(REMOVE CSS)' + node.tagName +'.' + n + ':'+l + '=' + v);
                     //node.removeAttribute(n);
                     return true;
@@ -25745,11 +25720,11 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 node.removeAttribute(a.name);
                 continue;
             }
-            if (Roo.form.HtmlEditor.ablack.indexOf(a.name.toLowerCase()) > -1) {
+            if (Roo.HtmlEditorCore.ablack.indexOf(a.name.toLowerCase()) > -1) {
                 node.removeAttribute(a.name);
                 continue;
             }
-            if (Roo.form.HtmlEditor.aclean.indexOf(a.name.toLowerCase()) > -1) {
+            if (Roo.HtmlEditorCore.aclean.indexOf(a.name.toLowerCase()) > -1) {
                 cleanAttr(a.name,a.value); // fixme..
                 continue;
             }
@@ -25757,32 +25732,854 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
                 cleanStyle(a.name,a.value);
                 continue;
             }
-            /// clean up MS crap..
-            // tecnically this should be a list of valid class'es..
-            
-            
-            if (a.name == 'class') {
-                if (a.value.match(/^Mso/)) {
-                    node.className = '';
+            /// clean up MS crap..
+            // tecnically this should be a list of valid class'es..
+            
+            
+            if (a.name == 'class') {
+                if (a.value.match(/^Mso/)) {
+                    node.className = '';
+                }
+                
+                if (a.value.match(/body/)) {
+                    node.className = '';
+                }
+                continue;
+            }
+            
+            // style cleanup!?
+            // class cleanup?
+            
+        }
+        
+        
+        this.cleanUpChildren(node);
+        
+        
+    },
+    /**
+     * Clean up MS wordisms...
+     */
+    cleanWord : function(node)
+    {
+        var _t = this;
+        var cleanWordChildren = function()
+        {
+            if (!node.childNodes.length) {
+                return;
+            }
+            for (var i = node.childNodes.length-1; i > -1 ; i--) {
+               _t.cleanWord(node.childNodes[i]);
+            }
+        }
+        
+        
+        if (!node) {
+            this.cleanWord(this.doc.body);
+            return;
+        }
+        if (node.nodeName == "#text") {
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        if (node.nodeName == "#comment") {
+            node.parentNode.removeChild(node);
+            // clean up silly Windows -- stuff?
+            return; 
+        }
+        
+        if (node.tagName.toLowerCase().match(/^(style|script|applet|embed|noframes|noscript)$/)) {
+            node.parentNode.removeChild(node);
+            return;
+        }
+        
+        // remove - but keep children..
+        if (node.tagName.toLowerCase().match(/^(meta|link|\\?xml:|st1:|o:|font)/)) {
+            while (node.childNodes.length) {
+                var cn = node.childNodes[0];
+                node.removeChild(cn);
+                node.parentNode.insertBefore(cn, node);
+            }
+            node.parentNode.removeChild(node);
+            cleanWordChildren();
+            return;
+        }
+        // clean styles
+        if (node.className.length) {
+            
+            var cn = node.className.split(/\W+/);
+            var cna = [];
+            Roo.each(cn, function(cls) {
+                if (cls.match(/Mso[a-zA-Z]+/)) {
+                    return;
+                }
+                cna.push(cls);
+            });
+            node.className = cna.length ? cna.join(' ') : '';
+            if (!cna.length) {
+                node.removeAttribute("class");
+            }
+        }
+        
+        if (node.hasAttribute("lang")) {
+            node.removeAttribute("lang");
+        }
+        
+        if (node.hasAttribute("style")) {
+            
+            var styles = node.getAttribute("style").split(";");
+            var nstyle = [];
+            Roo.each(styles, function(s) {
+                if (!s.match(/:/)) {
+                    return;
+                }
+                var kv = s.split(":");
+                if (kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)) {
+                    return;
+                }
+                // what ever is left... we allow.
+                nstyle.push(s);
+            });
+            node.setAttribute("style", nstyle.length ? nstyle.join(';') : '');
+            if (!nstyle.length) {
+                node.removeAttribute('style');
+            }
+        }
+        
+        cleanWordChildren();
+        
+        
+    },
+    domToHTML : function(currentElement, depth, nopadtext) {
+        
+        depth = depth || 0;
+        nopadtext = nopadtext || false;
+    
+        if (!currentElement) {
+            return this.domToHTML(this.doc.body);
+        }
+        
+        //Roo.log(currentElement);
+        var j;
+        var allText = false;
+        var nodeName = currentElement.nodeName;
+        var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
+        
+        if  (nodeName == '#text') {
+            return currentElement.nodeValue;
+        }
+        
+        
+        var ret = '';
+        if (nodeName != 'BODY') {
+             
+            var i = 0;
+            // Prints the node tagName, such as <A>, <IMG>, etc
+            if (tagName) {
+                var attr = [];
+                for(i = 0; i < currentElement.attributes.length;i++) {
+                    // quoting?
+                    var aname = currentElement.attributes.item(i).name;
+                    if (!currentElement.attributes.item(i).value.length) {
+                        continue;
+                    }
+                    attr.push(aname + '="' + Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"' );
+                }
+                
+                ret = "<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">";
+            } 
+            else {
+                
+                // eack
+            }
+        } else {
+            tagName = false;
+        }
+        if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
+            return ret;
+        }
+        if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { // or code?
+            nopadtext = true;
+        }
+        
+        
+        // Traverse the tree
+        i = 0;
+        var currentElementChild = currentElement.childNodes.item(i);
+        var allText = true;
+        var innerHTML  = '';
+        lastnode = '';
+        while (currentElementChild) {
+            // Formatting code (indent the tree so it looks nice on the screen)
+            var nopad = nopadtext;
+            if (lastnode == 'SPAN') {
+                nopad  = true;
+            }
+            // text
+            if  (currentElementChild.nodeName == '#text') {
+                var toadd = Roo.util.Format.htmlEncode(currentElementChild.nodeValue);
+                if (!nopad && toadd.length > 80) {
+                    innerHTML  += "\n" + (new Array( depth + 1 )).join( "  "  );
+                }
+                innerHTML  += toadd;
+                
+                i++;
+                currentElementChild = currentElement.childNodes.item(i);
+                lastNode = '';
+                continue;
+            }
+            allText = false;
+            
+            innerHTML  += nopad ? '' : "\n" + (new Array( depth + 1 )).join( "  "  );
+                
+            // Recursively traverse the tree structure of the child node
+            innerHTML   += this.domToHTML(currentElementChild, depth+1, nopadtext);
+            lastnode = currentElementChild.nodeName;
+            i++;
+            currentElementChild=currentElement.childNodes.item(i);
+        }
+        
+        ret += innerHTML;
+        
+        if (!allText) {
+                // The remaining code is mostly for formatting the tree
+            ret+= nopadtext ? '' : "\n" + (new Array( depth  )).join( "  "  );
+        }
+        
+        
+        if (tagName) {
+            ret+= "</"+tagName+">";
+        }
+        return ret;
+        
+    },
+        
+    applyBlacklists : function()
+    {
+        var w = typeof(this.owner.white) != 'undefined' && this.owner.white ? this.owner.white  : [];
+        var b = typeof(this.owner.black) != 'undefined' && this.owner.black ? this.owner.black :  [];
+        
+        this.white = [];
+        this.black = [];
+        Roo.each(Roo.HtmlEditorCore.white, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            this.white.push(tag);
+            
+        }, this);
+        
+        Roo.each(w, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.white.indexOf(tag) > -1) {
+                return;
+            }
+            this.white.push(tag);
+            
+        }, this);
+        
+        
+        Roo.each(Roo.HtmlEditorCore.black, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            this.black.push(tag);
+            
+        }, this);
+        
+        Roo.each(b, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.black.indexOf(tag) > -1) {
+                return;
+            }
+            this.black.push(tag);
+            
+        }, this);
+        
+        
+        w = typeof(this.owner.cwhite) != 'undefined' && this.owner.cwhite ? this.owner.cwhite  : [];
+        b = typeof(this.owner.cblack) != 'undefined' && this.owner.cblack ? this.owner.cblack :  [];
+        
+        this.cwhite = [];
+        this.cblack = [];
+        Roo.each(Roo.HtmlEditorCore.cwhite, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            this.cwhite.push(tag);
+            
+        }, this);
+        
+        Roo.each(w, function(tag) {
+            if (b.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.cwhite.indexOf(tag) > -1) {
+                return;
+            }
+            this.cwhite.push(tag);
+            
+        }, this);
+        
+        
+        Roo.each(Roo.HtmlEditorCore.cblack, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            this.cblack.push(tag);
+            
+        }, this);
+        
+        Roo.each(b, function(tag) {
+            if (w.indexOf(tag) > -1) {
+                return;
+            }
+            if (this.cblack.indexOf(tag) > -1) {
+                return;
+            }
+            this.cblack.push(tag);
+            
+        }, this);
+    }
+    
+    // hide stuff that is not compatible
+    /**
+     * @event blur
+     * @hide
+     */
+    /**
+     * @event change
+     * @hide
+     */
+    /**
+     * @event focus
+     * @hide
+     */
+    /**
+     * @event specialkey
+     * @hide
+     */
+    /**
+     * @cfg {String} fieldClass @hide
+     */
+    /**
+     * @cfg {String} focusClass @hide
+     */
+    /**
+     * @cfg {String} autoCreate @hide
+     */
+    /**
+     * @cfg {String} inputType @hide
+     */
+    /**
+     * @cfg {String} invalidClass @hide
+     */
+    /**
+     * @cfg {String} invalidText @hide
+     */
+    /**
+     * @cfg {String} msgFx @hide
+     */
+    /**
+     * @cfg {String} validateOnBlur @hide
+     */
+});
+
+Roo.HtmlEditorCore.white = [
+        'area', 'br', 'img', 'input', 'hr', 'wbr',
+        
+       'address', 'blockquote', 'center', 'dd',      'dir',       'div', 
+       'dl',      'dt',         'h1',     'h2',      'h3',        'h4', 
+       'h5',      'h6',         'hr',     'isindex', 'listing',   'marquee', 
+       'menu',    'multicol',   'ol',     'p',       'plaintext', 'pre', 
+       'table',   'ul',         'xmp', 
+       
+       'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', 
+      'thead',   'tr', 
+     
+      'dir', 'menu', 'ol', 'ul', 'dl',
+       
+      'embed',  'object'
+];
+
+
+Roo.HtmlEditorCore.black = [
+    //    'embed',  'object', // enable - backend responsiblity to clean thiese
+        'applet', // 
+        'base',   'basefont', 'bgsound', 'blink',  'body', 
+        'frame',  'frameset', 'head',    'html',   'ilayer', 
+        'iframe', 'layer',  'link',     'meta',    'object',   
+        'script', 'style' ,'title',  'xml' // clean later..
+];
+Roo.HtmlEditorCore.clean = [
+    'script', 'style', 'title', 'xml'
+];
+Roo.HtmlEditorCore.remove = [
+    'font'
+];
+// attributes..
+
+Roo.HtmlEditorCore.ablack = [
+    'on'
+];
+    
+Roo.HtmlEditorCore.aclean = [ 
+    'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc' 
+];
+
+// protocols..
+Roo.HtmlEditorCore.pwhite= [
+        'http',  'https',  'mailto'
+];
+
+// white listed style attributes.
+Roo.HtmlEditorCore.cwhite= [
+      //  'text-align', /// default is to allow most things..
+      
+         
+//        'font-size'//??
+];
+
+// black listed style attributes.
+Roo.HtmlEditorCore.cblack= [
+      //  'font-size' -- this can be set by the project 
+];
+
+
+Roo.HtmlEditorCore.swapCodes   =[ 
+    [    8211, "--" ], 
+    [    8212, "--" ], 
+    [    8216,  "'" ],  
+    [    8217, "'" ],  
+    [    8220, '"' ],  
+    [    8221, '"' ],  
+    [    8226, "*" ],  
+    [    8230, "..." ]
+]; 
+
+    //<script type="text/javascript">
+
+/*
+ * Ext JS Library 1.1.1
+ * Copyright(c) 2006-2007, Ext JS, LLC.
+ * Licence LGPL
+ * 
+ */
+Roo.form.HtmlEditor = function(config){
+    
+    
+    
+    Roo.form.HtmlEditor.superclass.constructor.call(this, config);
+    
+    if (!this.toolbars) {
+        this.toolbars = [];
+    }
+    this.editorcore = new Roo.HtmlEditorCore(Roo.apply({ owner : this} , config));
+    
+    
+};
+
+/**
+ * @class Roo.form.HtmlEditor
+ * @extends Roo.form.Field
+ * Provides a lightweight HTML Editor component.
+ *
+ * This has been tested on Fireforx / Chrome.. IE may not be so great..
+ * 
+ * <br><br><b>Note: The focus/blur and validation marking functionality inherited from Ext.form.Field is NOT
+ * supported by this editor.</b><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
+ * any element that has display set to 'none' can cause problems in Safari and Firefox.<br/><br/>
+ */
+Roo.extend(Roo.form.HtmlEditor, Roo.form.Field, {
+    /**
+     * @cfg {Boolean} clearUp
+     */
+    clearUp : true,
+      /**
+     * @cfg {Array} toolbars Array of toolbars. - defaults to just the Standard one
+     */
+    toolbars : false,
+   
+     /**
+     * @cfg {String} resizable  's' or 'se' or 'e' - wrapps the element in a
+     *                        Roo.resizable.
+     */
+    resizable : false,
+     /**
+     * @cfg {Number} height (in pixels)
+     */   
+    height: 300,
+   /**
+     * @cfg {Number} width (in pixels)
+     */   
+    width: 500,
+    
+    /**
+     * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+     * 
+     */
+    stylesheets: false,
+    
+    
+     /**
+     * @cfg {Array} blacklist of css styles style attributes (blacklist overrides whitelist)
+     * 
+     */
+    cblack: false,
+    /**
+     * @cfg {Array} whitelist of css styles style attributes (blacklist overrides whitelist)
+     * 
+     */
+    cwhite: false,
+    
+     /**
+     * @cfg {Array} blacklist of html tags - in addition to standard blacklist.
+     * 
+     */
+    black: false,
+    /**
+     * @cfg {Array} whitelist of html tags - in addition to statndard whitelist
+     * 
+     */
+    white: false,
+    
+    // id of frame..
+    frameId: false,
+    
+    // private properties
+    validationEvent : false,
+    deferHeight: true,
+    initialized : false,
+    activated : false,
+    
+    onFocus : Roo.emptyFn,
+    iframePad:3,
+    hideMode:'offsets',
+    
+    actionMode : 'container', // defaults to hiding it...
+    
+    defaultAutoCreate : { // modified by initCompnoent..
+        tag: "textarea",
+        style:"width:500px;height:300px;",
+        autocomplete: "off"
+    },
+
+    // private
+    initComponent : function(){
+        this.addEvents({
+            /**
+             * @event initialize
+             * Fires when the editor is fully initialized (including the iframe)
+             * @param {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
+             */
+            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 {String} html
+             */
+            beforesync: true,
+             /**
+             * @event beforepush
+             * Fires before the iframe editor is updated with content from the textarea. Return false
+             * to cancel the push.
+             * @param {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 {String} html
+             */
+            sync: true,
+             /**
+             * @event push
+             * Fires when the iframe editor is updated with content from the textarea.
+             * @param {HtmlEditor} this
+             * @param {String} html
+             */
+            push: true,
+             /**
+             * @event editmodechange
+             * Fires when the editor switches edit modes
+             * @param {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
+             */
+            editorevent: true,
+            /**
+             * @event firstfocus
+             * Fires when on first focus - needed by toolbars..
+             * @param {HtmlEditor} this
+             */
+            firstfocus: true,
+            /**
+             * @event autosave
+             * Auto save the htmlEditor value as a file into Events
+             * @param {HtmlEditor} this
+             */
+            autosave: true,
+            /**
+             * @event savedpreview
+             * preview the saved version of htmlEditor
+             * @param {HtmlEditor} this
+             */
+            savedpreview: true
+        });
+        this.defaultAutoCreate =  {
+            tag: "textarea",
+            style:'width: ' + this.width + 'px;height: ' + this.height + 'px;',
+            autocomplete: "off"
+        };
+    },
+
+    /**
+     * Protected method that will not generally be called directly. It
+     * is called when the editor creates its toolbar. Override this method if you need to
+     * add custom toolbar buttons.
+     * @param {HtmlEditor} editor
+     */
+    createToolbar : function(editor){
+        Roo.log("create toolbars");
+        if (!editor.toolbars || !editor.toolbars.length) {
+            editor.toolbars = [ new Roo.form.HtmlEditor.ToolbarStandard() ]; // can be empty?
+        }
+        
+        for (var i =0 ; i < editor.toolbars.length;i++) {
+            editor.toolbars[i] = Roo.factory(
+                    typeof(editor.toolbars[i]) == 'string' ?
+                        { xtype: editor.toolbars[i]} : editor.toolbars[i],
+                Roo.form.HtmlEditor);
+            editor.toolbars[i].init(editor);
+        }
+         
+        
+    },
+
+     
+    // private
+    onRender : function(ct, position)
+    {
+        var _t = this;
+        Roo.form.HtmlEditor.superclass.onRender.call(this, ct, position);
+        
+        this.wrap = this.el.wrap({
+            cls:'x-html-editor-wrap', cn:{cls:'x-html-editor-tb'}
+        });
+        
+        this.editorcore.onRender(ct, position);
+         
+        if (this.resizable) {
+            this.resizeEl = new Roo.Resizable(this.wrap, {
+                pinned : true,
+                wrap: true,
+                dynamic : true,
+                minHeight : this.height,
+                height: this.height,
+                handles : this.resizable,
+                width: this.width,
+                listeners : {
+                    resize : function(r, w, h) {
+                        _t.onResize(w,h); // -something
+                    }
+                }
+            });
+            
+        }
+        this.createToolbar(this);
+       
+        
+        if(!this.width){
+            this.setSize(this.wrap.getSize());
+        }
+        if (this.resizeEl) {
+            this.resizeEl.resizeTo.defer(100, this.resizeEl,[ this.width,this.height ] );
+            // should trigger onReize..
+        }
+        
+//        if(this.autosave && this.w){
+//            this.autoSaveFn = setInterval(this.autosave, 1000);
+//        }
+    },
+
+    // private
+    onResize : function(w, h)
+    {
+        //Roo.log('resize: ' +w + ',' + h );
+        Roo.form.HtmlEditor.superclass.onResize.apply(this, arguments);
+        var ew = false;
+        var eh = false;
+        
+        if(this.el ){
+            if(typeof w == 'number'){
+                var aw = w - this.wrap.getFrameWidth('lr');
+                this.el.setWidth(this.adjustWidth('textarea', aw));
+                ew = aw;
+            }
+            if(typeof h == 'number'){
+                var tbh = 0;
+                for (var i =0; i < this.toolbars.length;i++) {
+                    // fixme - ask toolbars for heights?
+                    tbh += this.toolbars[i].tb.el.getHeight();
+                    if (this.toolbars[i].footer) {
+                        tbh += this.toolbars[i].footer.el.getHeight();
+                    }
                 }
                 
-                if (a.value.match(/body/)) {
-                    node.className = '';
-                }
-                continue;
+                
+                
+                
+                var ah = h - this.wrap.getFrameWidth('tb') - tbh;// this.tb.el.getHeight();
+                ah -= 5; // knock a few pixes off for look..
+                this.el.setHeight(this.adjustWidth('textarea', ah));
+                var eh = ah;
             }
+        }
+        Roo.log('onResize:' + [w,h,ew,eh].join(',') );
+        this.editorcore.onResize(ew,eh);
+        
+    },
+
+    /**
+     * Toggles the editor between standard and source edit mode.
+     * @param {Boolean} sourceEdit (optional) True for source edit, false for standard
+     */
+    toggleSourceEdit : function(sourceEditMode)
+    {
+        this.editorcore.toggleSourceEdit(sourceEditMode);
+        
+        if(this.editorcore.sourceEditMode){
+            Roo.log('editor - showing textarea');
             
-            // style cleanup!?
-            // class cleanup?
+//            Roo.log('in');
+//            Roo.log(this.syncValue());
+            this.editorcore.syncValue();
+            this.el.removeClass('x-hidden');
+            this.el.dom.removeAttribute('tabIndex');
+            this.el.focus();
+        }else{
+            Roo.log('editor - hiding textarea');
+//            Roo.log('out')
+//            Roo.log(this.pushValue()); 
+            this.editorcore.pushValue();
             
+            this.el.addClass('x-hidden');
+            this.el.dom.setAttribute('tabIndex', -1);
+            //this.deferFocus();
         }
+         
+        this.setSize(this.wrap.getSize());
+        this.fireEvent('editmodechange', this, this.editorcore.sourceEditMode);
+    },
+    // private (for BoxComponent)
+    adjustSize : Roo.BoxComponent.prototype.adjustSize,
+
+    // private (for BoxComponent)
+    getResizeEl : function(){
+        return this.wrap;
+    },
+
+    // private (for BoxComponent)
+    getPositionEl : function(){
+        return this.wrap;
+    },
+
+    // private
+    initEvents : function(){
+        this.originalValue = this.getValue();
+    },
+
+    /**
+     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+     * @method
+     */
+    markInvalid : Roo.emptyFn,
+    /**
+     * Overridden and disabled. The editor element does not support standard valid/invalid marking. @hide
+     * @method
+     */
+    clearInvalid : Roo.emptyFn,
+
+    setValue : function(v){
+        Roo.form.HtmlEditor.superclass.setValue.call(this, v);
+        this.editorcore.pushValue();
+    },
+
+     
+    // private
+    deferFocus : function(){
+        this.focus.defer(10, this);
+    },
+
+    // doc'ed in Field
+    focus : function(){
+        this.editorcore.focus();
         
+    },
+      
+
+    // private
+    onDestroy : function(){
         
-        this.cleanUpChildren(node);
         
         
-    }
+        if(this.rendered){
+            
+            for (var i =0; i < this.toolbars.length;i++) {
+                // fixme - ask toolbars for heights?
+                this.toolbars[i].onDestroy();
+            }
+            
+            this.wrap.dom.innerHTML = '';
+            this.wrap.remove();
+        }
+    },
+
+    // private
+    onFirstFocus : function(){
+        //Roo.log("onFirstFocus");
+        this.editorcore.onFirstFocus();
+         for (var i =0; i < this.toolbars.length;i++) {
+            this.toolbars[i].onFirstFocus();
+        }
+        
+    },
+    
+    // private
+    syncValue : function()
+    {
+        this.editorcore.syncValue();
+    },
     
+    pushValue : function()
+    {
+        this.editorcore.pushValue();
+    }
+     
     
     // hide stuff that is not compatible
     /**
@@ -25826,79 +26623,7 @@ Roo.form.HtmlEditor = Roo.extend(Roo.form.Field, {
      * @cfg {String} validateOnBlur @hide
      */
 });
-
-Roo.form.HtmlEditor.white = [
-        'area', 'br', 'img', 'input', 'hr', 'wbr',
-        
-       'address', 'blockquote', 'center', 'dd',      'dir',       'div', 
-       'dl',      'dt',         'h1',     'h2',      'h3',        'h4', 
-       'h5',      'h6',         'hr',     'isindex', 'listing',   'marquee', 
-       'menu',    'multicol',   'ol',     'p',       'plaintext', 'pre', 
-       'table',   'ul',         'xmp', 
-       
-       'caption', 'col', 'colgroup', 'tbody', 'td', 'tfoot', 'th', 
-      'thead',   'tr', 
-     
-      'dir', 'menu', 'ol', 'ul', 'dl',
-       
-      'embed',  'object'
-];
-
-
-Roo.form.HtmlEditor.black = [
-    //    'embed',  'object', // enable - backend responsiblity to clean thiese
-        'applet', // 
-        'base',   'basefont', 'bgsound', 'blink',  'body', 
-        'frame',  'frameset', 'head',    'html',   'ilayer', 
-        'iframe', 'layer',  'link',     'meta',    'object',   
-        'script', 'style' ,'title',  'xml' // clean later..
-];
-Roo.form.HtmlEditor.clean = [
-    'script', 'style', 'title', 'xml'
-];
-Roo.form.HtmlEditor.remove = [
-    'font'
-];
-// attributes..
-
-Roo.form.HtmlEditor.ablack = [
-    'on'
-];
-    
-Roo.form.HtmlEditor.aclean = [ 
-    'action', 'background', 'codebase', 'dynsrc', 'href', 'lowsrc' 
-];
-
-// protocols..
-Roo.form.HtmlEditor.pwhite= [
-        'http',  'https',  'mailto'
-];
-
-// white listed style attributes.
-Roo.form.HtmlEditor.cwhite= [
-      //  'text-align', /// default is to allow most things..
-      
-         
-//        'font-size'//??
-];
-
-// black listed style attributes.
-Roo.form.HtmlEditor.cblack= [
-      //  'font-size' -- this can be set by the project 
-];
-
-
-Roo.form.HtmlEditor.swapCodes   =[ 
-    [    8211, "--" ], 
-    [    8212, "--" ], 
-    [    8216,  "'" ],  
-    [    8217, "'" ],  
-    [    8220, '"' ],  
-    [    8221, '"' ],  
-    [    8226, "*" ],  
-    [    8230, "..." ]
-]; 
-
     // <script type="text/javascript">
 /*
  * Based on
@@ -25957,11 +26682,24 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
     rendered: false,
     
     editor : false,
+    editorcore : false,
     /**
      * @cfg {Object} disable  List of toolbar elements to disable
          
      */
     disable : false,
+    
+    
+     /**
+     * @cfg {String} createLinkText The default text for the create link prompt
+     */
+    createLinkText : 'Please enter the URL for the link:',
+    /**
+     * @cfg {String} defaultLinkValue The default value for the create link prompt (defaults to http:/ /)
+     */
+    defaultLinkValue : 'http:/'+'/',
+   
+    
       /**
      * @cfg {Array} fontFamilies An array of available font families
      */
@@ -26039,9 +26777,12 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
     init : function(editor)
     {
         this.editor = editor;
+        this.editorcore = editor.editorcore ? editor.editorcore : editor;
+        var editorcore = this.editorcore;
         
+        var _t = this;
         
-        var fid = editor.frameId;
+        var fid = editorcore.frameId;
         var etb = this;
         function btn(id, toggle, handler){
             var xid = fid + '-'+ id ;
@@ -26050,8 +26791,8 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                 cmd : id,
                 cls : 'x-btn-icon x-edit-'+id,
                 enableToggle:toggle !== false,
-                scope: editor, // was editor...
-                handler:handler||editor.relayBtnCmd,
+                scope: _t, // was editor...
+                handler:handler||_t.relayBtnCmd,
                 clickEvent:'mousedown',
                 tooltip: etb.buttonTips[id] || undefined, ///tips ???
                 tabIndex:-1
@@ -26109,7 +26850,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                 width:135,
                 listeners : {
                     'select': function(c, r, i) {
-                        editor.insertTag(r.get('tag'));
+                        editorcore.insertTag(r.get('tag'));
                         editor.focus();
                     }
                 }
@@ -26131,8 +26872,8 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                 '-',
                 
                 
-                btn('increasefontsize', false, editor.adjustFont),
-                btn('decreasefontsize', false, editor.adjustFont)
+                btn('increasefontsize', false, editorcore.adjustFont),
+                btn('decreasefontsize', false, editorcore.adjustFont)
             );
         };
         
@@ -26140,7 +26881,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
         if(!this.disable.colors){
             tb.add(
                 '-', {
-                    id:editor.frameId +'-forecolor',
+                    id:editorcore.frameId +'-forecolor',
                     cls:'x-btn-icon x-edit-forecolor',
                     clickEvent:'mousedown',
                     tooltip: this.buttonTips['forecolor'] || undefined,
@@ -26151,14 +26892,14 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                         value:'000000',
                         plain:true,
                         selectHandler: function(cp, color){
-                            editor.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
+                            editorcore.execCmd('forecolor', Roo.isSafari || Roo.isIE ? '#'+color : color);
                             editor.deferFocus();
                         },
-                        scope: editor,
+                        scope: editorcore,
                         clickEvent:'mousedown'
                     })
                 }, {
-                    id:editor.frameId +'backcolor',
+                    id:editorcore.frameId +'backcolor',
                     cls:'x-btn-icon x-edit-backcolor',
                     clickEvent:'mousedown',
                     tooltip: this.buttonTips['backcolor'] || undefined,
@@ -26170,17 +26911,17 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                         allowReselect: true,
                         selectHandler: function(cp, color){
                             if(Roo.isGecko){
-                                editor.execCmd('useCSS', false);
-                                editor.execCmd('hilitecolor', color);
-                                editor.execCmd('useCSS', true);
+                                editorcore.execCmd('useCSS', false);
+                                editorcore.execCmd('hilitecolor', color);
+                                editorcore.execCmd('useCSS', true);
                                 editor.deferFocus();
                             }else{
-                                editor.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor', 
+                                editorcore.execCmd(Roo.isOpera ? 'hilitecolor' : 'backcolor', 
                                     Roo.isSafari || Roo.isIE ? '#'+color : color);
                                 editor.deferFocus();
                             }
                         },
-                        scope:editor,
+                        scope:editorcore,
                         clickEvent:'mousedown'
                     })
                 }
@@ -26202,7 +26943,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             if(!this.disable.links){
                 tb.add(
                     '-',
-                    btn('createlink', false, editor.createLink)    /// MOVE TO HERE?!!?!?!?!
+                    btn('createlink', false, this.createLink)    /// MOVE TO HERE?!!?!?!?!
                 );
             };
 
@@ -26217,6 +26958,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                 tb.add(
                     '-',
                     btn('sourceedit', true, function(btn){
+                        Roo.log(this);
                         this.toggleSourceEdit(btn.pressed);
                     })
                 );
@@ -26239,7 +26981,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     
                     html: this.specialChars[i],
                     handler: function(a,b) {
-                        editor.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
+                        editorcore.insertAtCursor(String.fromCharCode(a.html.replace('&#','').replace(';', '')));
                         //editor.insertAtCursor(a.html);
                         
                     },
@@ -26269,15 +27011,48 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
                     handler: function(a,b) {
                         Roo.log(a);
                         Roo.log(b);
-                        var c = Roo.get(editor.doc.body);
+                        var c = Roo.get(editorcore.doc.body);
                         c.select('[style]').each(function(s) {
                             s.dom.style.removeProperty(a.actiontype);
                         });
-                        
+                        editorcore.syncValue();
                     },
                     tabIndex:-1
                 });
             }
+            cmenu.menu.items.push({
+                actiontype : 'word',
+                html: 'Remove MS Word Formating',
+                handler: function(a,b) {
+                    editorcore.cleanWord();
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+            
+            cmenu.menu.items.push({
+                actiontype : 'all',
+                html: 'Remove All Styles',
+                handler: function(a,b) {
+                    
+                    var c = Roo.get(editorcore.doc.body);
+                    c.select('[style]').each(function(s) {
+                        s.dom.removeAttribute('style');
+                    });
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+             cmenu.menu.items.push({
+                actiontype : 'word',
+                html: 'Tidy HTML Source',
+                handler: function(a,b) {
+                    editorcore.doc.body.innerHTML = editorcore.domToHTML();
+                    editorcore.syncValue();
+                },
+                tabIndex:-1
+            });
+            
             
             tb.add(cmenu);
         }
@@ -26311,7 +27086,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             for(var i =0; i< this.btns.length;i++) {
                 var b = Roo.factory(this.btns[i],Roo.form);
                 b.cls =  'x-edit-none';
-                b.scope = editor;
+                b.scope = editorcore;
                 tb.add(b);
             }
         
@@ -26322,7 +27097,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
         // disable everything...
         
         this.tb.items.each(function(item){
-           if(item.id != editor.frameId+ '-sourceedit'){
+           if(item.id != editorcore.frameId+ '-sourceedit'){
                 item.disable();
             }
         });
@@ -26335,6 +27110,18 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
     },
     
     
+    relayBtnCmd : function(btn) {
+        this.editorcore.relayCmd(btn.cmd);
+    },
+    // private used internally
+    createLink : function(){
+        Roo.log("create link?");
+        var url = prompt(this.createLinkText, this.defaultLinkValue);
+        if(url && url != 'http:/'+'/'){
+            this.editorcore.relayCmd('createlink', url);
+        }
+    },
+
     
     /**
      * Protected method that will not generally be called directly. It triggers
@@ -26342,14 +27129,14 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
      */
     updateToolbar: function(){
 
-        if(!this.editor.activated){
+        if(!this.editorcore.activated){
             this.editor.onFirstFocus();
             return;
         }
 
         var btns = this.tb.items.map, 
-            doc = this.editor.doc,
-            frameId = this.editor.frameId;
+            doc = this.editorcore.doc,
+            frameId = this.editorcore.frameId;
 
         if(!this.disable.font && !Roo.isSafari){
             /*
@@ -26374,7 +27161,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             btns[frameId + '-insertunorderedlist'].toggle(doc.queryCommandState('insertunorderedlist'));
         }
         
-        var ans = this.editor.getAllAncestors();
+        var ans = this.editorcore.getAllAncestors();
         if (this.formatCombo) {
             
             
@@ -26417,18 +27204,21 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
     },
     
     toggleSourceEdit : function(sourceEditMode){
+        
+        Roo.log("toolbar toogle");
         if(sourceEditMode === undefined){
             sourceEditMode = !this.sourceEditMode;
         }
         this.sourceEditMode = sourceEditMode === true;
-        var btn = this.tb.items.get(this.editor.frameId +'-sourceedit');
+        var btn = this.tb.items.get(this.editorcore.frameId +'-sourceedit');
         // just toggle the button?
-        if(btn.pressed !== this.editor.sourceEditMode){
-            btn.toggle(this.editor.sourceEditMode);
+        if(btn.pressed !== this.sourceEditMode){
+            btn.toggle(this.sourceEditMode);
             return;
         }
         
-        if(this.sourceEditMode){
+        if(sourceEditMode){
+            Roo.log("disabling buttons");
             this.tb.items.each(function(item){
                 if(item.cmd != 'sourceedit'){
                     item.disable();
@@ -26436,13 +27226,15 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarStandard.prototype,  {
             });
           
         }else{
-            if(this.initialized){
+            Roo.log("enabling buttons");
+            if(this.editorcore.initialized){
                 this.tb.items.each(function(item){
                     item.enable();
                 });
             }
             
         }
+        Roo.log("calling toggole on editor");
         // tell the editor that it's been pressed..
         this.editor.toggleSourceEdit(sourceEditMode);
        
@@ -26820,6 +27612,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     rendered: false,
     
     editor : false,
+    editorcore : false,
     /**
      * @cfg {Object} disable  List of toolbar elements to disable
          
@@ -26843,9 +27636,10 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     init : function(editor)
     {
         this.editor = editor;
+        this.editorcore = editor.editorcore ? editor.editorcore : editor;
+        var editorcore = this.editorcore;
         
-        
-        var fid = editor.frameId;
+        var fid = editorcore.frameId;
         var etb = this;
         function btn(id, toggle, handler){
             var xid = fid + '-'+ id ;
@@ -26854,8 +27648,8 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                 cmd : id,
                 cls : 'x-btn-icon x-edit-'+id,
                 enableToggle:toggle !== false,
-                scope: editor, // was editor...
-                handler:handler||editor.relayBtnCmd,
+                scope: editorcore, // was editor...
+                handler:handler||editorcore.relayBtnCmd,
                 clickEvent:'mousedown',
                 tooltip: etb.buttonTips[id] || undefined, ///tips ???
                 tabIndex:-1
@@ -26906,7 +27700,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         //Roo.log(ev);
         // capture mouse up - this is handy for selecting images..
         // perhaps should go somewhere else...
-        if(!this.editor.activated){
+        if(!this.editorcore.activated){
              this.editor.onFirstFocus();
             return;
         }
@@ -26927,7 +27721,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                 nodeRange.selectNodeContents(sel);
             }
             //nodeRange.collapse(true);
-            var s = editor.win.getSelection();
+            var s = this.editorcore.win.getSelection();
             s.removeAllRanges();
             s.addRange(nodeRange);
         }  
@@ -26936,15 +27730,15 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         var updateFooter = sel ? false : true;
         
         
-        var ans = this.editor.getAllAncestors();
+        var ans = this.editorcore.getAllAncestors();
         
         // pick
         var ty= Roo.form.HtmlEditor.ToolbarContext.types;
         
         if (!sel) { 
-            sel = ans.length ? (ans[0] ?  ans[0]  : ans[1]) : this.editor.doc.body;
-            sel = sel ? sel : this.editor.doc.body;
-            sel = sel.tagName.length ? sel : this.editor.doc.body;
+            sel = ans.length ? (ans[0] ?  ans[0]  : ans[1]) : this.editorcore.doc.body;
+            sel = sel ? sel : this.editorcore.doc.body;
+            sel = sel.tagName.length ? sel : this.editorcore.doc.body;
             
         }
         // pick a menu that exists..
@@ -27076,6 +27870,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
     buildToolbar: function(tlist, nm)
     {
         var editor = this.editor;
+        var editorcore = this.editorcore;
          // create a new element.
         var wdiv = editor.wrap.createChild({
                 tag: 'div'
@@ -27116,7 +27911,7 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                     'select': function(c, r, i) {
                         // initial support only for on class per el..
                         tb.selectedNode.className =  r ? r.get('val') : '';
-                        editor.syncValue();
+                        editorcore.syncValue();
                     }
                 }
     
@@ -27222,14 +28017,14 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
                         
                     }
                     pn.removeChild(sn);
-                    var range = editor.createRange();
+                    var range = editorcore.createRange();
         
                     range.setStart(stn,0);
                     range.setEnd(en,0); //????
                     //range.selectNode(sel);
                     
                     
-                    var selection = editor.getSelection();
+                    var selection = editorcore.getSelection();
                     selection.removeAllRanges();
                     selection.addRange(range);
                     
@@ -27309,13 +28104,13 @@ Roo.apply(Roo.form.HtmlEditor.ToolbarContext.prototype,  {
         var sel = ans[n];
         
          // pick
-        var range = this.editor.createRange();
+        var range = this.editorcore.createRange();
         
         range.selectNodeContents(sel);
         //range.selectNode(sel);
         
         
-        var selection = this.editor.getSelection();
+        var selection = this.editorcore.getSelection();
         selection.removeAllRanges();
         selection.addRange(range);
         
@@ -35230,7 +36025,9 @@ Roo.extend(Roo.grid.Grid, Roo.util.Observable, {
         var v = this.view;
         var header = v.findHeaderIndex(t);
         if(header !== false){
-            this.fireEvent("header" + (name == 'touchstart' ? 'click' : name), this, header, e);
+            var ename = name == 'touchstart' ? 'click' : name;
+             
+            this.fireEvent("header" + ename, this, header, e);
         }else{
             var row = v.findRowIndex(t);
             var cell = v.findCellIndex(t);
@@ -35443,7 +36240,7 @@ Roo.extend(Roo.grid.AbstractGridView, Roo.util.Observable, {
     hdClass : "x-grid-hd",
     splitClass : "x-grid-hd-split",
     
-       init: function(grid){
+    init: function(grid){
         this.grid = grid;
                var cid = this.grid.getGridEl().id;
         this.colSelector = "#" + cid + " ." + this.cellClass + "-";
@@ -35452,7 +36249,7 @@ Roo.extend(Roo.grid.AbstractGridView, Roo.util.Observable, {
         this.splitSelector = "#" + cid + " ." + this.splitClass + "-";
        },
        
-       getColumnRenderers : function(){
+    getColumnRenderers : function(){
        var renderers = [];
        var cm = this.grid.colModel;
         var colCount = cm.getColumnCount();
@@ -36952,7 +37749,17 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     },
 
 
-    handleHeaderClick : function(g, index){
+    handleHeaderClick : function(g, index,e){
+        
+        Roo.log("header click");
+        
+        if (Roo.isTouch) {
+            // touch events on header are handled by context
+            this.handleHdCtx(g,index,e);
+            return;
+        }
+        
+        
         if(this.headersDisabled){
             return;
         }
@@ -37065,6 +37872,15 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                     cm.setLocked(index, false);
                 }
             break;
+            case 'wider': // used to expand cols on touch..
+            case 'narrow':
+                var cw = cm.getColumnWidth(index);
+                cw += (item.id == 'wider' ? 1 : -1) * 50;
+                cw = Math.max(0, cw);
+                cw = Math.min(cw,4000);
+                cm.setColumnWidth(index, cw);
+                break;
+                
             default:
                 index = cm.getIndexById(item.id.substr(4));
                 if(index != -1){
@@ -37194,6 +38010,15 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
                     {id:"unlock", text: this.unlockText, cls: "xg-hmenu-unlock"}
                 );
             }
+            if (Roo.isTouch) {
+                 this.hmenu.add('-',
+                    {id:"wider", text: this.columnsWiderText},
+                    {id:"narrow", text: this.columnsNarrowText }
+                );
+                
+                 
+            }
+            
             if(this.grid.enableColumnHide !== false){
 
                 this.colMenu = new Roo.menu.Menu({id:this.grid.id + "-hcols-menu"});
@@ -37396,7 +38221,10 @@ Roo.extend(Roo.grid.GridView, Roo.grid.AbstractGridView, {
     sortDescText : "Sort Descending",
     lockText : "Lock Column",
     unlockText : "Unlock Column",
-    columnsText : "Columns"
+    columnsText : "Columns",
+    columnsWiderText : "Wider",
+    columnsNarrowText : "Thinner"
 });
 
 
@@ -37737,7 +38565,8 @@ Roo.extend(Roo.grid.ColumnModel, Roo.util.Observable, {
     /**
      * @cfg {Function} renderer (Optional) A function used to generate HTML markup for a cell
      * given the cell's data value. See {@link #setRenderer}. If not specified, the
-     * default renderer uses the raw data value.
+     * default renderer uses the raw data value. If an object is returned (bootstrap only)
+     * then it is treated as a Roo Component object instance, and it is rendered after the initial row is rendered
      */
        /**
      * @cfg {Roo.grid.GridEditor} editor (Optional) For grid editors - returns the grid editor