Uncommited changes synced
authorAlan <alan@roojs.com>
Thu, 7 Oct 2021 01:31:44 +0000 (09:31 +0800)
committerAlan <alan@roojs.com>
Thu, 7 Oct 2021 01:31:44 +0000 (09:31 +0800)
16 files changed:
Roo/HtmlEditorCore.js
Roo/htmleditor/FilterKeepChildren.js
Roo/htmleditor/FilterLongBr.js
Roo/htmleditor/FilterStyleToTag.js
buildSDK/dependancy_bootstrap.txt
buildSDK/dependancy_ui.txt
docs/json/roodata.json
docs/src/Roo_HtmlEditorCore.js.html
docs/src/Roo_form_HtmlEditor_ToolbarContext.js.html
docs/src/Roo_htmleditor_FilterAttributes.js.html
docs/symbols/Roo.HtmlEditorCore.json
docs/tree.json
roojs-all.js
roojs-debug.js
roojs-ui-debug.js
roojs-ui.js

index e3bdc58..de8e68a 100644 (file)
@@ -496,10 +496,14 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             'dblclick': this.onEditorEvent,
             'click': this.onEditorEvent,
             'keyup': this.onEditorEvent,
-            'paste': this.onPasteEvent,
+            
             buffer:100,
             scope: this
         });
+        Roo.EventManager.on(this.doc, {
+            'paste': this.onPasteEvent,
+            scope : this
+        });
         if(Roo.isGecko){
             Roo.EventManager.on(this.doc, 'keypress', this.mozKeyPress, this);
         }
@@ -524,15 +528,26 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         
         // even pasting into a 'email version' of this widget will have to clean up that mess.
         
-        var txt = e.browserEvent.clipboardData.getData('Text'); // clipboard event
-        var d = document.createElement('div');
-        d.innerHTML = txt;
+        var html = (e.browserEvent.clipboardData || window.clipboardData).getData('text/html'); // clipboard event
+        html = this.cleanWordChars(html);
+        
+        var d = (new DOMParser().parseFromString(html, 'text/html')).body;
+        
         new Roo.htmleditor.FilterStyleToTag({ node : d });
         new Roo.htmleditor.FilterAttributes({
             node : d,
-            attrib_white : ['href'],
+            attrib_white : ['href', 'src', 'name'],
+            attrib_clean : ['href', 'src', 'name'] 
         });
-         
+        new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
+        // should be fonts..
+        new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT' ]} );
+        new Roo.htmleditor.FilterParagraph({ node : d });
+        new Roo.htmleditor.FilterSpan({ node : d });
+        new Roo.htmleditor.FilterLongBr({ node : d });
+        
+        
+        
         this.insertAtCursor(d.innerHTML);
         
         e.preventDefault();
@@ -687,20 +702,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         if(!this.activated){
             return;
         }
-        /*
-        if(Roo.isIE){
-            this.win.focus();
-            var r = this.doc.selection.createRange();
-            if(r){
-                r.collapse(true);
-                r.pasteHTML(text);
-                this.syncValue();
-                this.deferFocus();
-            
-            }
-            return;
-        }
-        */
+         
         if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
             
@@ -710,6 +712,10 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             var win = this.win;
             
             if (win.getSelection && win.getSelection().getRangeAt) {
+                
+                // delete the existing?
+                
+                this.createRange(this.getSelection()).deleteContents();
                 range = win.getSelection().getRangeAt(0);
                 node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
                 range.insertNode(node);
@@ -1067,10 +1073,19 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
     },
  
     cleanWordChars : function(input) {// change the chars to hex code
-        var he = Roo.HtmlEditorCore;
         
+       var swapCodes  = [ 
+            [    8211, "&#8211;" ], 
+            [    8212, "&#8212;" ], 
+            [    8216,  "'" ],  
+            [    8217, "'" ],  
+            [    8220, '"' ],  
+            [    8221, '"' ],  
+            [    8226, "*" ],  
+            [    8230, "..." ]
+        ]; 
         var output = input;
-        Roo.each(he.swapCodes, function(sw) { 
+        Roo.each(swapCodes, function(sw) { 
             var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
             
             output = output.replace(swapper, sw[1]);
@@ -1314,36 +1329,39 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
 });
 
 Roo.HtmlEditorCore.white = [
-        'area', 'br', 'img', 'input', 'hr', 'wbr',
+        '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', 
+       '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', 
+       'CAPTION', 'COL', 'COLGROUP', 'TBODY', 'TD', 'TFOOT', 'TH', 
+      'THEAD',   'TR', 
      
-      'dir', 'menu', 'ol', 'ul', 'dl',
+      'DIR', 'MENU', 'OL', 'UL', 'DL',
        
-      'embed',  'object'
+      '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..
+        'APPLET', // 
+        'BASE',   'BASEFONT', 'BGSOUND', 'BLINK',  'BODY', 
+        'FRAME',  'FRAMESET', 'HEAD',    'HTML',   'ILAYER', 
+        'IFRAME', 'LAYER',  'LINK',     'META',    'OBJECT',   
+        'SCRIPT', 'STYLE' ,'TITLE',  'XML',
+        //'FONT' // CLEAN LATER..
+        'COLGROUP', 'COL'  // messy tables.
+        
 ];
-Roo.HtmlEditorCore.clean = [
-    'script', 'style', 'title', 'xml'
+Roo.HtmlEditorCore.clean = [ // ?? needed???
+     'SCRIPT', 'STYLE', 'TITLE', 'XML'
 ];
 Roo.HtmlEditorCore.tag_remove = [
-    'font'
+    'FONT', 'TBODY'  
 ];
 // attributes..
 
@@ -1374,15 +1392,6 @@ Roo.HtmlEditorCore.cblack= [
 ];
 
 
-Roo.HtmlEditorCore.swapCodes   =[ 
-    [    8211, "&#8211;" ], 
-    [    8212, "&#8212;" ], 
-    [    8216,  "'" ],  
-    [    8217, "'" ],  
-    [    8220, '"' ],  
-    [    8221, '"' ],  
-    [    8226, "*" ],  
-    [    8230, "..." ]
-]; 
+
 
     
\ No newline at end of file
index 496be17..fbee647 100644 (file)
@@ -22,13 +22,30 @@ Roo.extend(Roo.htmleditor.FilterKeepChildren, Roo.htmleditor.FilterBlack,
     replaceTag : function(node)
     {
         // walk children...
+        Roo.log(node);
         var ar = Array.from(node.childNodes);
+        //remove first..
         for (var i = 0; i < ar.length; i++) {
+            if (ar[i].nodeType == 1) {
+                if (
+                    (typeof(this.tag) == 'object' && this.tag.indexOf(ar[i].tagName) > -1)
+                    || // array and it matches
+                    (typeof(this.tag) == 'string' && this.tag == ar[i].tagName)
+                ) {
+                    this.replaceTag(ar[i]); // child is blacklisted as well...
+                    continue;
+                }
+            }
+        }  
+        ar = Array.from(node.childNodes);
+        for (var i = 0; i < ar.length; i++) {
+         
             node.removeChild(ar[i]);
             // what if we need to walk these???
             node.parentNode.insertBefore(ar[i], node);
             if (this.tag !== false) {
                 this.walk(ar[i]);
+                
             }
         }
         node.parentNode.removeChild(node);
index 3e0cc6f..39f464b 100644 (file)
@@ -22,27 +22,44 @@ Roo.extend(Roo.htmleditor.FilterLongBr, Roo.htmleditor.Filter,
     replaceTag : function(node)
     {
         
-        if (!node.previousSibling) {
+        var ps = node.nextSibling;
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.nextSibling;
+        }
+        
+        if (!ps &&  [ 'TD', 'TH', 'LI', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(node.parentNode.tagName) > -1) { 
+            node.parentNode.removeChild(node); // remove last BR inside one fo these tags
             return false;
         }
-        var ps = node.previousSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.previousSibling;
+        if (!ps || ps.nodeType != 1) {
+            return false;
         }
+        
         if (!ps || ps.tagName != 'BR') {
+           
             return false;
         }
         
-        var ps = node.nextSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.nextSibling;
-        }
-        if (!ps || ps.tagName != 'BR') {
+        
+        
+        
+        if (!node.previousSibling) {
             return false;
         }
+        var ps = node.previousSibling;
         
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.previousSibling;
+        }
+        if (!ps || ps.nodeType != 1) {
+            return false;
+        }
+        // if header or BR before.. then it's a candidate for removal.. - as we only want '2' of these..
+        if (!ps || [ 'BR', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(ps.tagName) < 0) {
+            return false;
+        }
         
         node.parentNode.removeChild(node); // remove me...
         
index 6ec5a24..a837349 100644 (file)
@@ -43,6 +43,8 @@ Roo.extend(Roo.htmleditor.FilterStyleToTag, Roo.htmleditor.Filter,
     
     replaceTag : function(node)
     {
+        
+        
         if (node.getAttribute("style") === null) {
             return true;
         }
index dddf0b4..18a379c 100644 (file)
@@ -137,6 +137,7 @@ Roo.htmleditor.FilterSpan
 Roo.htmleditor.FilterTableWidth
 Roo.htmleditor.FilterWord
 Roo.htmleditor.FilterStyleToTag
+Roo.htmleditor.FilterLongBr
 
 Roo.htmleditor.KeyEnter
 
index 48f5803..434c96d 100644 (file)
@@ -106,6 +106,7 @@ Roo.htmleditor.FilterSpan
 Roo.htmleditor.FilterTableWidth
 Roo.htmleditor.FilterWord
 Roo.htmleditor.FilterStyleToTag
+Roo.htmleditor.FilterLongBr
 Roo.htmleditor.Tidy
 Roo.htmleditor.KeyEnter
 
index 8500dc9..b170461 100644 (file)
         ],
         "returns" : []
       },
+      {
+        "name" : "selectNode",
+        "type" : "function",
+        "desc" : "Select a dom node",
+        "sig" : "(node)",
+        "static" : false,
+        "memberOf" : "",
+        "isStatic" : false,
+        "isConstructor" : false,
+        "isPrivate" : false,
+        "example" : "",
+        "deprecated" : "",
+        "since" : "",
+        "see" : "",
+        "exceptions" : "",
+        "requires" : "",
+        "params" : [
+          {
+            "name" : "node",
+            "type" : "DomElement",
+            "desc" : "the node to select",
+            "isOptional" : false
+          }
+        ],
+        "returns" : []
+      },
       {
         "name" : "setDisabled",
         "type" : "function",
     "tree_children" : [],
     "tree_parent" : []
   },
+  "Roo.htmleditor.FilterLongBr" : {
+    "props" : [],
+    "events" : [],
+    "methods" : [],
+    "isAbstract" : false,
+    "isBuilderTop" : false,
+    "implementations" : [],
+    "tree_children" : [],
+    "tree_parent" : []
+  },
   "Roo.htmleditor.FilterParagraph" : {
     "props" : [],
     "events" : [],
     "tree_children" : [],
     "tree_parent" : []
   },
+  "Roo.htmleditor.FilterStyleToTag" : {
+    "props" : [],
+    "events" : [],
+    "methods" : [],
+    "isAbstract" : false,
+    "isBuilderTop" : false,
+    "implementations" : [],
+    "tree_children" : [],
+    "tree_parent" : []
+  },
   "Roo.htmleditor.FilterTableWidth" : {
     "props" : [],
     "events" : [],
index bb2565f..6f15633 100644 (file)
             </span><span class="jsdoc-keyword">if</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.fireEvent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'beforepush'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">) !== </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">){
                 </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">d </span><span class="jsdoc-syntax">= (</span><span class="jsdoc-var">this.doc.body </span><span class="jsdoc-syntax">|| </span><span class="jsdoc-var">this.doc.documentElement</span><span class="jsdoc-syntax">);
                 </span><span class="jsdoc-var">d.innerHTML </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">;
-                </span><span class="jsdoc-comment">//this.cleanUpPaste();
+
                 </span><span class="jsdoc-var">this.el.dom.value </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">d.innerHTML</span><span class="jsdoc-syntax">;
                 </span><span class="jsdoc-var">this.owner.fireEvent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'push'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">);
             }
             </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">lc </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.doc.body.lastChild</span><span class="jsdoc-syntax">;
             </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">lc </span><span class="jsdoc-syntax">&amp;&amp; </span><span class="jsdoc-var">lc.nodeType </span><span class="jsdoc-syntax">== 1 &amp;&amp; </span><span class="jsdoc-var">lc.getAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">&quot;contenteditable&quot;</span><span class="jsdoc-syntax">) == </span><span class="jsdoc-string">&quot;false&quot;</span><span class="jsdoc-syntax">) {
                 </span><span class="jsdoc-comment">// add an extra line at the end.
-                </span><span class="jsdoc-var">this.doc.body.appendChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.doc.createChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'br'</span><span class="jsdoc-syntax">));
+                </span><span class="jsdoc-var">this.doc.body.appendChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.doc.createElement</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'br'</span><span class="jsdoc-syntax">));
             }
 
 
             </span><span class="jsdoc-string">'dblclick'</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.onEditorEvent</span><span class="jsdoc-syntax">,
             </span><span class="jsdoc-string">'click'</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.onEditorEvent</span><span class="jsdoc-syntax">,
             </span><span class="jsdoc-string">'keyup'</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.onEditorEvent</span><span class="jsdoc-syntax">,
-            </span><span class="jsdoc-string">'paste'</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.onPasteEvent</span><span class="jsdoc-syntax">,
+
             </span><span class="jsdoc-var">buffer</span><span class="jsdoc-syntax">:100,
             </span><span class="jsdoc-var">scope</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this
         </span><span class="jsdoc-syntax">});
+        </span><span class="jsdoc-var">Roo.EventManager.on</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.doc</span><span class="jsdoc-syntax">, {
+            </span><span class="jsdoc-string">'paste'</span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.onPasteEvent</span><span class="jsdoc-syntax">,
+            </span><span class="jsdoc-var">scope </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this
+        </span><span class="jsdoc-syntax">});
         </span><span class="jsdoc-keyword">if</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">Roo.isGecko</span><span class="jsdoc-syntax">){
             </span><span class="jsdoc-var">Roo.EventManager.on</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.doc</span><span class="jsdoc-syntax">, </span><span class="jsdoc-string">'keypress'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">this.mozKeyPress</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">);
         }
         </span><span class="jsdoc-var">this.pushValue</span><span class="jsdoc-syntax">();
     },
 
-    </span><span class="jsdoc-var">onPasteEvent </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">,</span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">)  {
-         </span><span class="jsdoc-comment">// default behaveiour should be our local cleanup paste? (optional?)
-         // for simple editor - we want to hammer the paste and get rid of everything... - so over-rideable..
-         </span><span class="jsdoc-var">this.owner.fireEvent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'paste'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">);
-    },
+    </span><span class="jsdoc-var">onPasteEvent </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">,</span><span class="jsdoc-var">v</span><span class="jsdoc-syntax">)
+    {
+        </span><span class="jsdoc-comment">// I think we better assume paste is going to be a dirty load of rubish from word..
+
+        // even pasting into a 'email version' of this widget will have to clean up that mess.
+
+        </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">html </span><span class="jsdoc-syntax">= (</span><span class="jsdoc-var">e.browserEvent.clipboardData </span><span class="jsdoc-syntax">|| </span><span class="jsdoc-var">window.clipboardData</span><span class="jsdoc-syntax">)</span><span class="jsdoc-var">.getData</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'text/html'</span><span class="jsdoc-syntax">); </span><span class="jsdoc-comment">// clipboard event
+
+        </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">d </span><span class="jsdoc-syntax">= (</span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">DOMParser</span><span class="jsdoc-syntax">()</span><span class="jsdoc-var">.parseFromString</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">html</span><span class="jsdoc-syntax">, </span><span class="jsdoc-string">'text/html'</span><span class="jsdoc-syntax">))</span><span class="jsdoc-var">.body</span><span class="jsdoc-syntax">;
+
+
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterStyleToTag</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d </span><span class="jsdoc-syntax">});
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterAttributes</span><span class="jsdoc-syntax">({
+            </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d</span><span class="jsdoc-syntax">,
+            </span><span class="jsdoc-var">attrib_white </span><span class="jsdoc-syntax">: [</span><span class="jsdoc-string">'href'</span><span class="jsdoc-syntax">],
+            </span><span class="jsdoc-var">attrib_clean </span><span class="jsdoc-syntax">: [</span><span class="jsdoc-string">'href'</span><span class="jsdoc-syntax">]
+        });
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterBlack</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">tag </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.black</span><span class="jsdoc-syntax">});
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterKeepChildren</span><span class="jsdoc-syntax">({</span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">tag </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.tag_remove</span><span class="jsdoc-syntax">} );
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterParagraph</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d </span><span class="jsdoc-syntax">});
+        </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterLongBr</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">d </span><span class="jsdoc-syntax">});
+        </span><span class="jsdoc-var">this.insertAtCursor</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">d.innerHTML</span><span class="jsdoc-syntax">);
+
+        </span><span class="jsdoc-var">e.preventDefault</span><span class="jsdoc-syntax">();
+        </span><span class="jsdoc-keyword">return false</span><span class="jsdoc-syntax">;
+        </span><span class="jsdoc-comment">// default behaveiour should be our local cleanup paste? (optional?)
+        // for simple editor - we want to hammer the paste and get rid of everything... - so over-rideable..
+        //this.owner.fireEvent('paste', e, v);
+    </span><span class="jsdoc-syntax">},
     </span><span class="jsdoc-comment">// private
     </span><span class="jsdoc-var">onDestroy </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(){
 
         </span><span class="jsdoc-var">this.assignDocWin</span><span class="jsdoc-syntax">();
         </span><span class="jsdoc-keyword">return </span><span class="jsdoc-var">Roo.isIE </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.doc.selection </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.win.getSelection</span><span class="jsdoc-syntax">();
     },
+    </span><span class="jsdoc-comment">/**
+     * Select a dom node
+     * @param {DomElement} node the node to select
+     */
+    </span><span class="jsdoc-var">selectNode </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">)
+    {
+
+            </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">nodeRange </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">node.ownerDocument.createRange</span><span class="jsdoc-syntax">();
+            </span><span class="jsdoc-keyword">try </span><span class="jsdoc-syntax">{
+                </span><span class="jsdoc-var">nodeRange.selectNode</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+            } </span><span class="jsdoc-keyword">catch </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">) {
+                </span><span class="jsdoc-var">nodeRange.selectNodeContents</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+            }
+            </span><span class="jsdoc-comment">//nodeRange.collapse(true);
+            </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">s </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.win.getSelection</span><span class="jsdoc-syntax">();
+            </span><span class="jsdoc-var">s.removeAllRanges</span><span class="jsdoc-syntax">();
+            </span><span class="jsdoc-var">s.addRange</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">nodeRange</span><span class="jsdoc-syntax">);
+    },
 
     </span><span class="jsdoc-var">getSelectedNode</span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">()
     {
         </span><span class="jsdoc-comment">// fully contined.
         </span><span class="jsdoc-keyword">return </span><span class="jsdoc-syntax">3;
     },
-</span><span class="jsdoc-comment">/*
-    // private? - in a new class?
-    cleanUpPaste :  function()
-    {
-        // cleans up the whole document..
-        Roo.log('cleanuppaste');
-        
-        this.cleanUpChild(this.doc.body);
-        var clean = this.cleanWordChars(this.doc.body.innerHTML);
-        if (clean != this.doc.body.innerHTML) {
-            this.doc.body.innerHTML = clean;
-        }
-        
-    },
-    */
+
     </span><span class="jsdoc-var">cleanWordChars </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">input</span><span class="jsdoc-syntax">) {</span><span class="jsdoc-comment">// change the chars to hex code
         </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">he </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Roo.HtmlEditorCore</span><span class="jsdoc-syntax">;
 
index dc0202f..d66f028 100644 (file)
             // let's see if we can change the selection...
             </span><span class="jsdoc-var">sel </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">ev.target</span><span class="jsdoc-syntax">;
 
-            </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">nodeRange </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">sel.ownerDocument.createRange</span><span class="jsdoc-syntax">();
-            </span><span class="jsdoc-keyword">try </span><span class="jsdoc-syntax">{
-                </span><span class="jsdoc-var">nodeRange.selectNode</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">);
-            } </span><span class="jsdoc-keyword">catch </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">) {
-                </span><span class="jsdoc-var">nodeRange.selectNodeContents</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">);
-            }
-            </span><span class="jsdoc-comment">//nodeRange.collapse(true);
-            </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">s </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.editorcore.win.getSelection</span><span class="jsdoc-syntax">();
-            </span><span class="jsdoc-var">s.removeAllRanges</span><span class="jsdoc-syntax">();
-            </span><span class="jsdoc-var">s.addRange</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">nodeRange</span><span class="jsdoc-syntax">);
+
+            </span><span class="jsdoc-var">this.editorcore.selectNode</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">);
+
         }
 
 
         </span><span class="jsdoc-comment">// ok see if we are editing a block?
 
         </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">db </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Roo.get</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">)</span><span class="jsdoc-var">.findParent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'[data-block]'</span><span class="jsdoc-syntax">);
+        </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">cepar </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Roo.get</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">)</span><span class="jsdoc-var">.findParent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'[contenteditable=true]'</span><span class="jsdoc-syntax">);
+        </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">db </span><span class="jsdoc-syntax">&amp;&amp; </span><span class="jsdoc-var">cepar </span><span class="jsdoc-syntax">&amp;&amp; </span><span class="jsdoc-var">cepar.tagName </span><span class="jsdoc-syntax">!= </span><span class="jsdoc-string">'BODY'</span><span class="jsdoc-syntax">) {
+            </span><span class="jsdoc-var">db </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">; </span><span class="jsdoc-comment">// we are inside an editable block.. = not sure how we are going to handle nested blocks!?
+        </span><span class="jsdoc-syntax">}
         </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">block </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">;
-        </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">db</span><span class="jsdoc-syntax">) {
+        </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">db </span><span class="jsdoc-syntax">&amp;&amp; !</span><span class="jsdoc-var">sel.hasAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'contenteditable'</span><span class="jsdoc-syntax">) &amp;&amp; </span><span class="jsdoc-var">sel.getAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'contenteditable'</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'true' </span><span class="jsdoc-syntax">) {
             </span><span class="jsdoc-var">block </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Roo.htmleditor.Block.factory</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">db</span><span class="jsdoc-syntax">);
             </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">block</span><span class="jsdoc-syntax">) {
                 </span><span class="jsdoc-var">tn </span><span class="jsdoc-syntax">= </span><span class="jsdoc-string">'BLOCK.' </span><span class="jsdoc-syntax">+ </span><span class="jsdoc-var">db.getAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'data-block'</span><span class="jsdoc-syntax">);
                 </span><span class="jsdoc-var">this.tb.selectedNode </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">db</span><span class="jsdoc-syntax">;
+                </span><span class="jsdoc-var">this.editorcore.selectNode</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">db</span><span class="jsdoc-syntax">);
                 </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.toolbars</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">tn</span><span class="jsdoc-syntax">]) == </span><span class="jsdoc-string">'undefined'</span><span class="jsdoc-syntax">) {
                    </span><span class="jsdoc-var">this.toolbars</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">tn</span><span class="jsdoc-syntax">] = </span><span class="jsdoc-var">this.buildToolbar</span><span class="jsdoc-syntax">( </span><span class="jsdoc-var">block.context</span><span class="jsdoc-syntax">,</span><span class="jsdoc-var">tn </span><span class="jsdoc-syntax">,</span><span class="jsdoc-var">block.friendly_name</span><span class="jsdoc-syntax">);
                 }
                 </span><span class="jsdoc-var">left_label </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">block.friendly_name</span><span class="jsdoc-syntax">;
+                </span><span class="jsdoc-var">ans </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.editorcore.getAllAncestors</span><span class="jsdoc-syntax">();
             }
 
 
             });
 
 
-        } </span><span class="jsdoc-keyword">else  if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tb.fields</span><span class="jsdoc-syntax">) {
-            </span><span class="jsdoc-var">this.tb.fields.each</span><span class="jsdoc-syntax">(</span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">) {
+        } </span><span class="jsdoc-keyword">else  if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tb.fields </span><span class="jsdoc-syntax">&amp;&amp; </span><span class="jsdoc-var">this.tb.selectedNode</span><span class="jsdoc-syntax">) {
+            </span><span class="jsdoc-var">this.tb.fields.each</span><span class="jsdoc-syntax">( </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">) {
                 </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e.stylename</span><span class="jsdoc-syntax">) {
-                    </span><span class="jsdoc-var">e.setValue</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel.style</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">e.stylename</span><span class="jsdoc-syntax">]);
+                    </span><span class="jsdoc-var">e.setValue</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tb.selectedNode.style</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">e.stylename</span><span class="jsdoc-syntax">]);
                     </span><span class="jsdoc-keyword">return</span><span class="jsdoc-syntax">;
                 }
-                </span><span class="jsdoc-var">e.setValue</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel.getAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e.attrname</span><span class="jsdoc-syntax">));
-            });
+                </span><span class="jsdoc-var">e.setValue</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tb.selectedNode.getAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e.attrname</span><span class="jsdoc-syntax">));
+            }, </span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">);
+            </span><span class="jsdoc-var">this.updateToolbarStyles</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tb.selectedNode</span><span class="jsdoc-syntax">);
         }
-        </span><span class="jsdoc-var">this.updateToolbarStyles</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">sel</span><span class="jsdoc-syntax">);
 
 
 
                     </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">range </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">editorcore.createRange</span><span class="jsdoc-syntax">();
 
                     </span><span class="jsdoc-var">range.setStart</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">stn</span><span class="jsdoc-syntax">,0);
-                    </span><span class="jsdoc-var">range.setEnd</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">en</span><span class="jsdoc-syntax">,0); </span><span class="jsdoc-comment">//????
+                    </span><span class="jsdoc-var">range.setEnd</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">stn</span><span class="jsdoc-syntax">,0);
                     </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">selection </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">editorcore.getSelection</span><span class="jsdoc-syntax">();
                     </span><span class="jsdoc-var">selection.removeAllRanges</span><span class="jsdoc-syntax">();
                     </span><span class="jsdoc-var">selection.addRange</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">range</span><span class="jsdoc-syntax">);
index 5af5598..dd31da9 100644 (file)
@@ -11,6 +11,8 @@
 {
     </span><span class="jsdoc-var">Roo.apply</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">cfg</span><span class="jsdoc-syntax">);
     </span><span class="jsdoc-var">this.attrib_black </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.attrib_black </span><span class="jsdoc-syntax">|| [];
+    </span><span class="jsdoc-var">this.attrib_white </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.attrib_white </span><span class="jsdoc-syntax">|| [];
+
     </span><span class="jsdoc-var">this.attrib_clean </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.attrib_clean </span><span class="jsdoc-syntax">|| [];
     </span><span class="jsdoc-var">this.style_white </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.style_white </span><span class="jsdoc-syntax">|| [];
     </span><span class="jsdoc-var">this.style_black </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">this.style_black </span><span class="jsdoc-syntax">|| [];
@@ -23,6 +25,8 @@
 
     </span><span class="jsdoc-var">attrib_black </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">, </span><span class="jsdoc-comment">// array
     </span><span class="jsdoc-var">attrib_clean </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">,
+    </span><span class="jsdoc-var">attrib_white </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">,
+
     </span><span class="jsdoc-var">style_white </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">,
     </span><span class="jsdoc-var">style_black </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">false</span><span class="jsdoc-syntax">,
 
         </span><span class="jsdoc-keyword">for </span><span class="jsdoc-syntax">(</span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">node.attributes.length</span><span class="jsdoc-syntax">-1; </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">&gt; -1 ; </span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">--) {
             </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">a </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">node.attributes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">];
             </span><span class="jsdoc-comment">//console.log(a);
+            </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.attrib_white.length </span><span class="jsdoc-syntax">&amp;&amp; </span><span class="jsdoc-var">this.attrib_white.indexOf</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">a.name.toLowerCase</span><span class="jsdoc-syntax">()) &lt; 0) {
+                </span><span class="jsdoc-var">node.removeAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">a.name</span><span class="jsdoc-syntax">);
+                </span><span class="jsdoc-keyword">continue</span><span class="jsdoc-syntax">;
+            }
+
+
 
             </span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">a.name.toLowerCase</span><span class="jsdoc-syntax">()</span><span class="jsdoc-var">.substr</span><span class="jsdoc-syntax">(0,2)==</span><span class="jsdoc-string">'on'</span><span class="jsdoc-syntax">)  {
                 </span><span class="jsdoc-var">node.removeAttribute</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">a.name</span><span class="jsdoc-syntax">);
index 00ef842..7898ee5 100644 (file)
       ],
       "returns" : []
     },
+    {
+      "name" : "selectNode",
+      "type" : "function",
+      "desc" : "Select a dom node",
+      "sig" : "(node)",
+      "static" : false,
+      "memberOf" : "",
+      "isStatic" : false,
+      "isConstructor" : false,
+      "isPrivate" : false,
+      "example" : "",
+      "deprecated" : "",
+      "since" : "",
+      "see" : "",
+      "exceptions" : "",
+      "requires" : "",
+      "params" : [
+        {
+          "name" : "node",
+          "type" : "DomElement",
+          "desc" : "the node to select",
+          "isOptional" : false
+        }
+      ],
+      "returns" : []
+    },
     {
       "name" : "execCmd",
       "type" : "function",
index e5db028..1bdfa85 100644 (file)
             "cn" : [],
             "is_class" : false
           },
+          {
+            "name" : "Roo.htmleditor.FilterLongBr",
+            "cn" : [],
+            "is_class" : false
+          },
           {
             "name" : "Roo.htmleditor.FilterParagraph",
             "cn" : [],
             "cn" : [],
             "is_class" : false
           },
+          {
+            "name" : "Roo.htmleditor.FilterStyleToTag",
+            "cn" : [],
+            "is_class" : false
+          },
           {
             "name" : "Roo.htmleditor.FilterTableWidth",
             "cn" : [],
index 3fa07f5..80ce93e 100644 (file)
@@ -1848,8 +1848,9 @@ Roo.htmleditor.FilterBlack=function(A){Roo.apply(this,A);this.walk(A.node);};Roo
 // Roo/htmleditor/FilterComment.js
 Roo.htmleditor.FilterComment=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterComment,Roo.htmleditor.Filter,{replaceComment:function(n){n.parentNode.removeChild(n);}});
 // Roo/htmleditor/FilterKeepChildren.js
-Roo.htmleditor.FilterKeepChildren=function(A){Roo.apply(this,A);if(this.tag===false){return;}this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterKeepChildren,Roo.htmleditor.FilterBlack,{replaceTag:function(A){var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;
-i++){A.removeChild(ar[i]);A.parentNode.insertBefore(ar[i],A);if(this.tag!==false){this.walk(ar[i]);}}A.parentNode.removeChild(A);return false;}});
+Roo.htmleditor.FilterKeepChildren=function(A){Roo.apply(this,A);if(this.tag===false){return;}this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterKeepChildren,Roo.htmleditor.FilterBlack,{replaceTag:function(A){Roo.log(A);var ar=Array.from(A.childNodes);for(var i=0;
+i<ar.length;i++){if(ar[i].nodeType==1){if((typeof(this.tag)=='object'&&this.tag.indexOf(ar[i].tagName)>-1)||(typeof(this.tag)=='string'&&this.tag==ar[i].tagName)){this.replaceTag(ar[i]);continue;}}}ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){A.removeChild(ar[i]);
+A.parentNode.insertBefore(ar[i],A);if(this.tag!==false){this.walk(ar[i]);}}A.parentNode.removeChild(A);return false;}});
 // Roo/htmleditor/FilterParagraph.js
 Roo.htmleditor.FilterParagraph=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterParagraph,Roo.htmleditor.Filter,{tag:'P',replaceTag:function(A){if(A.childNodes.length==1&&A.childNodes[0].nodeType==3&&A.childNodes[0].textContent.trim().length<1){A.parentNode.replaceChild(A.ownerDocument.createElement('BR'),A);
 return false;}var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){A.removeChild(ar[i]);A.parentNode.insertBefore(ar[i],A);}A.parentNode.insertBefore(A.ownerDocument.createElement('BR'),A);A.parentNode.removeChild(A);return false;}});
@@ -1872,8 +1873,9 @@ Roo.htmleditor.FilterStyleToTag=function(A){this.tags={B:['fontWeight','bold'],I
 }var B=[];for(var k in this.tags){if(A.style[this.tags[k][0]]==this.tags[k][1]){B.push(k);A.style.removeProperty(this.tags[k][0]);}}if(!B.length){return true;}var cn=Array.from(A.childNodes);var nn=A;Roo.each(B,function(t){var nc=A.ownerDocument.createelement(t);
 nn.appendChild(nc);nn=nc;});for(var i=0;i<cn.length;cn++){A.removeChild(cn[i]);nn.appendChild(cn[i]);}return true}})
 // Roo/htmleditor/FilterLongBr.js
-Roo.htmleditor.FilterLongBr=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterLongBr,Roo.htmleditor.Filter,{tag:'BR',replaceTag:function(A){if(!A.previousSibling){return false;}var ps=A.previousSibling;if(ps&&ps.nodeType==3&&ps.nodeValue.trim()){ps=ps.previousSibling;
-}if(!ps||ps.tagName!='BR'){return false;}var ps=A.nextSibling;if(ps&&ps.nodeType==3&&ps.nodeValue.trim()){ps=ps.nextSibling;}if(!ps||ps.tagName!='BR'){return false;}A.parentNode.removeChild(A);return false;}});
+Roo.htmleditor.FilterLongBr=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterLongBr,Roo.htmleditor.Filter,{tag:'BR',replaceTag:function(A){var ps=A.nextSibling;while(ps&&ps.nodeType==3&&ps.nodeValue.trim().length<1){ps=ps.nextSibling;}if(!ps&&['TD','TH','LI','H1','H2','H3','H4','H5','H6'].indexOf(A.parentNode.tagName)>-1){A.parentNode.removeChild(A);
+return false;}if(!ps||ps.nodeType!=1){return false;}if(!ps||ps.tagName!='BR'){return false;}if(!A.previousSibling){return false;}var ps=A.previousSibling;while(ps&&ps.nodeType==3&&ps.nodeValue.trim().length<1){ps=ps.previousSibling;}if(!ps||ps.nodeType!=1){return false;
+}if(!ps||['BR','H1','H2','H3','H4','H5','H6'].indexOf(ps.tagName)<0){return false;}A.parentNode.removeChild(A);return false;}});
 // Roo/htmleditor/Tidy.js
 Roo.htmleditor.Tidy=function(A){Roo.apply(this,A);this.core.doc.body.innerHTML=this.tidy(this.core.doc.body,'');};Roo.htmleditor.Tidy.toString=function(A){return Roo.htmleditor.Tidy.prototype.tidy(A,'');};Roo.htmleditor.Tidy.prototype={wrap:function(s){return s.replace(/\n/g," ").replace(/(?![^\n]{1,80}$)([^\n]{1,80})\s/g,'$1\n');
 },tidy:function(A,B){if(A.nodeType==3){return B===false?A.nodeValue:this.wrap(A.nodeValue.trim()).split("\n").join("\n"+B);}if(A.nodeType!=1){return '';}if(A.tagName=='BODY'){return this.cn(A,'');}var C="<"+A.tagName+this.attr(A);if(['IMG','BR','HR','INPUT'].indexOf(A.tagName)>-1){return C+'/>';
@@ -1882,8 +1884,10 @@ Roo.htmleditor.Tidy=function(A){Roo.apply(this,A);this.core.doc.body.innerHTML=t
 i++){if(!A.attributes.item(i).value.length){continue;}B.push(A.attributes.item(i).name+'="'+Roo.util.Format.htmlEncode(A.attributes.item(i).value)+'"');}return B.length?(' '+B.join(' ')):'';}}
 // Roo/htmleditor/KeyEnter.js
 Roo.htmleditor.KeyEnter=function(A){Roo.apply(this,A);Roo.get(this.core.doc.body).on('keypress',this.keypress,this);};Roo.htmleditor.KeyEnter.prototype={core:false,keypress:function(e){if(e.charCode!=13){return true;}e.preventDefault();var A=this.core.doc;
-var B=A.createDocumentFragment();var C=A.createTextNode('\n');B.appendChild(C);C=A.createElement('br');B.appendChild(C);var D=this.core.win.getSelection().getRangeAt(0);D.deleteContents();D.insertNode(B);D=A.createRange();D.setStartAfter(C);D.collapse(true);
-var E=this.core.win.getSelection();E.removeAllRanges();E.addRange(D);return false;}};
+var B=A.createDocumentFragment();var C=A.createTextNode('\n');B.appendChild(C);var D=this.core.win.getSelection().getRangeAt(0);var n=D.commonAncestorContainer;while(n&&n.nodeType!=1){n=n.parentNode;}var li=false;if(n&&n.tagName=='UL'){li=A.createElement('LI');
+n.appendChild(li);}if(n&&n.tagName=='LI'){li=A.createElement('LI');if(n.nextSibling){n.parentNode.insertBefore(li,n.firstSibling);}else{n.parentNode.appendChild(li);}}if(li){D=A.createRange();D.setStartAfter(li);D.collapse(true);var E=this.core.win.getSelection();
+E.removeAllRanges();E.addRange(D);return false;}C=A.createElement('br');B.appendChild(C);D.deleteContents();D.insertNode(B);D=A.createRange();D.setStartAfter(C);D.collapse(true);var E=this.core.win.getSelection();E.removeAllRanges();E.addRange(D);return false;
+}};
 // Roo/htmleditor/Block.js
 Roo.htmleditor.Block=function(A){};Roo.htmleditor.Block.factory=function(A){var B=Roo.htmleditor['Block'+Roo.get(A).attr('data-block')];if(typeof(B)=='undefined'){Roo.log("OOps missing block : "+'Block'+Roo.get(A).attr('data-block'));return false;}return new B({node:A}
 );};Roo.htmleditor.Block.prototype={friendly_name:'Image with caption',context:false,updateElement:function(A){Roo.DomHelper.update(A,this.toObject());},toHTML:function(){return Roo.DomHelper.markup(this.toObject());},getVal:function(A,B,C,D){var n=A;if(n.tagName!=B.toUpperCase()){n=A.getElementsByTagName(B).item(0);
@@ -1914,32 +1918,32 @@ d.innerHTML=v;this.el.dom.value=d.innerHTML;this.owner.fireEvent('push',this,v);
 }else{if(!Roo.get(this.frameId)&&!A.contentDocument){return;}this.doc=(A.contentDocument||Roo.get(this.frameId).dom.document);this.win=(A.contentWindow||Roo.get(this.frameId).dom.contentWindow);}},initEditor:function(){this.assignDocWin();this.doc.designMode="on";
 this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var A=(this.doc.body||this.doc.documentElement);A.bgProperties='fixed';Roo.EventManager.on(this.doc,{'mouseup':this.onEditorEvent,'dblclick':this.onEditorEvent,'click':this.onEditorEvent,'keyup':this.onEditorEvent,buffer:100,scope:this}
 );Roo.EventManager.on(this.doc,{'paste':this.onPasteEvent,scope:this});if(Roo.isGecko){Roo.EventManager.on(this.doc,'keypress',this.mozKeyPress,this);}if(Roo.isIE||Roo.isSafari||Roo.isOpera){Roo.EventManager.on(this.doc,'keydown',this.fixKeys,this);}this.initialized=true;
-new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var A=(e.browserEvent.clipboardData||window.clipboardData).getData('text/html');var d=(new DOMParser().parseFromString(A,'text/html')).body;
-new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href'],attrib_clean:['href']});new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:this.tag_remove}
-);new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterLongBr({node:d});this.insertAtCursor(d.innerHTML);e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();this.activated=true;
-if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);
+new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var A=(e.browserEvent.clipboardData||window.clipboardData).getData('text/html');A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;
+new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href','src','name'],attrib_clean:['href','src','name']});new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT']}
+);new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});this.insertAtCursor(d.innerHTML);e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();
+this.activated=true;if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);
 this.execCmd('styleWithCSS',false);}catch(e){}}this.owner.fireEvent('activate',this);},adjustFont:function(A){var B=A.cmd=='increasefontsize'?1:-1;var v=parseInt(this.doc.queryCommandValue('FontSize')||3,10);if(Roo.isSafari){var sm={10:1,13:2,16:3,18:4,24:5,32:6,48:7}
 ;v=(v<10)?10:v;v=(v>48)?48:v;v=typeof(sm[v])=='undefined'?1:sm[v];}v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.owner.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){if(tg.toLowerCase()=='span'||tg.toLowerCase()=='code'||tg.toLowerCase()=='sup'||tg.toLowerCase()=='sub'){range=this.createRange(this.getSelection());
 var A=this.doc.createElement(tg.toLowerCase());A.appendChild(range.extractContents());range.insertNode(A);return;}this.execCmd("formatblock",tg);},insertText:function(A){var B=this.createRange();B.deleteContents();B.insertNode(this.doc.createTextNode(A));
 },relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.owner.fireEvent('editorevent',this);this.owner.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;
-}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;
-D.document.selection.createRange().pasteHTML(E);}else{var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();
-switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();
-r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();
-r.pasteHTML('<br/>');r.collapse(false);r.select();}}}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}};}else if(Roo.isSafari){return function(e){var k=e.getKey();
-if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);
-p=p.parentNode;}a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();},selectNode:function(A){var B=A.ownerDocument.createRange();try{B.selectNode(A);
-}catch(e){B.selectNodeContents(A);}var s=this.win.getSelection();s.removeAllRanges();s.addRange(B);},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);
-if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;
-i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);
+}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){this.createRange(this.getSelection()).deleteContents();B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;
+B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;D.document.selection.createRange().pasteHTML(E);}else{var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();
+this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;}if(A){this.win.focus();this.execCmd(A);
+this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();
+}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br/>');r.collapse(false);r.select();}}}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();
+this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();
+var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();
+},selectNode:function(A){var B=A.ownerDocument.createRange();try{B.selectNode(A);}catch(e){B.selectNodeContents(A);}var s=this.win.getSelection();s.removeAllRanges();s.addRange(B);},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();
+if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;
+}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);
 continue;}if(!this.rangeIntersectsNode(A,ar[i])||(this.rangeCompareNode(A,ar[i])==0)){continue;}F=true;}if(!D.length&&E.length){D=E;}if(F||!D.length||(D.length>1)){return false;}return D[0];},createRange:function(A){if(typeof A!="undefined"){try{return A.getRangeAt?A.getRangeAt(0):A.createRange();
 }catch(e){return this.doc.createRange();}}else{return this.doc.createRange();}},getParentElement:function(){this.assignDocWin();var A=Roo.isIE?this.doc.selection:this.win.getSelection();var B=this.createRange(A);try{var p=B.commonAncestorContainer;while(p.nodeType==3){p=p.parentNode;
 }return p;}catch(e){return null;}},rangeIntersectsNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){C.selectNodeContents(B);}var D=A.cloneRange();D.collapse(true);var E=A.cloneRange();E.collapse(false);var F=C.cloneRange();
 F.collapse(true);var G=C.cloneRange();G.collapse(false);return D.compareBoundaryPoints(Range.START_TO_START,G)==-1&&E.compareBoundaryPoints(Range.START_TO_START,F)==1;},rangeCompareNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);
 }catch(e){C.selectNodeContents(B);}A.collapse(true);C.collapse(true);var ss=A.compareBoundaryPoints(Range.START_TO_START,C);var ee=A.compareBoundaryPoints(Range.END_TO_END,C);var D=ss==1;var E=ee==-1;if(D&&E){return 0;}if(!D&&E){return 1;}if(D&&!E){return 2;
-}return 3;},cleanWordChars:function(A){var he=Roo.HtmlEditorCore;var B=A;Roo.each(he.swapCodes,function(sw){var C=new RegExp("\\u"+sw[0].toString(16),"g");B=B.replace(C,sw[1]);});return B;},cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A}
-);new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove}
-);},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];
+}return 3;},cleanWordChars:function(A){var B=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];var C=A;Roo.each(B,function(sw){var D=new RegExp("\\u"+sw[0].toString(16),"g");C=C.replace(D,sw[1]);});return C;
+},cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A});new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black}
+);new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},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.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;
 this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);
 },this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;}this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;
@@ -1947,9 +1951,9 @@ this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remov
 Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
 }this.cblack.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.cblack.indexOf(A)>-1){return;}this.cblack.push(A);},this);},setStylesheets:function(A){if(typeof(A)=='string'){Roo.get(this.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:A}
 );return;}var B=this;Roo.each(A,function(s){if(!s.length){return;}Roo.get(B.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:s});});},removeStylesheets:function(){var A=this;Roo.each(Roo.get(A.iframe.contentDocument.head).select('link[rel=stylesheet]',true).elements,function(s){s.remove();
-});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A});return;}});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=['applet','base','basefont','bgsound','blink','body','frame','frameset','head','html','ilayer','iframe','layer','link','meta','object','script','style','title','xml'];Roo.HtmlEditorCore.clean=['script','style','title','xml'];Roo.HtmlEditorCore.tag_remove=['font'];
-Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[];Roo.HtmlEditorCore.swapCodes=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];
+});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A});return;}});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=['APPLET','BASE','BASEFONT','BGSOUND','BLINK','BODY','FRAME','FRAMESET','HEAD','HTML','ILAYER','IFRAME','LAYER','LINK','META','OBJECT','SCRIPT','STYLE','TITLE','XML','COLGROUP','COL'];Roo.HtmlEditorCore.clean=['SCRIPT','STYLE','TITLE','XML'];
+Roo.HtmlEditorCore.tag_remove=['FONT','TBODY'];Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[];
 
 // Roo/form/HtmlEditor.js
 Roo.form.HtmlEditor=function(A){Roo.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));};Roo.extend(Roo.form.HtmlEditor,Roo.form.Field,{clearUp:true,toolbars:false,resizable:false,height:300,width:500,stylesheets:false,cblack:false,cwhite:false,black:false,white:false,allowComments:false,bodyCls:'',frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',actionMode:'container',defaultAutoCreate:{tag:"textarea",style:"width:500px;height:300px;",autocomplete:"new-password"}
index 2358d0e..2900172 100644 (file)
@@ -44789,13 +44789,30 @@ Roo.extend(Roo.htmleditor.FilterKeepChildren, Roo.htmleditor.FilterBlack,
     replaceTag : function(node)
     {
         // walk children...
+        Roo.log(node);
         var ar = Array.from(node.childNodes);
+        //remove first..
         for (var i = 0; i < ar.length; i++) {
+            if (ar[i].nodeType == 1) {
+                if (
+                    (typeof(this.tag) == 'object' && this.tag.indexOf(ar[i].tagName) > -1)
+                    || // array and it matches
+                    (typeof(this.tag) == 'string' && this.tag == ar[i].tagName)
+                ) {
+                    this.replaceTag(ar[i]); // child is blacklisted as well...
+                    continue;
+                }
+            }
+        }  
+        ar = Array.from(node.childNodes);
+        for (var i = 0; i < ar.length; i++) {
+         
             node.removeChild(ar[i]);
             // what if we need to walk these???
             node.parentNode.insertBefore(ar[i], node);
             if (this.tag !== false) {
                 this.walk(ar[i]);
+                
             }
         }
         node.parentNode.removeChild(node);
@@ -45104,6 +45121,8 @@ Roo.extend(Roo.htmleditor.FilterStyleToTag, Roo.htmleditor.Filter,
     
     replaceTag : function(node)
     {
+        
+        
         if (node.getAttribute("style") === null) {
             return true;
         }
@@ -45155,27 +45174,44 @@ Roo.extend(Roo.htmleditor.FilterLongBr, Roo.htmleditor.Filter,
     replaceTag : function(node)
     {
         
-        if (!node.previousSibling) {
+        var ps = node.nextSibling;
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.nextSibling;
+        }
+        
+        if (!ps &&  [ 'TD', 'TH', 'LI', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(node.parentNode.tagName) > -1) { 
+            node.parentNode.removeChild(node); // remove last BR inside one fo these tags
             return false;
         }
-        var ps = node.previousSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.previousSibling;
+        if (!ps || ps.nodeType != 1) {
+            return false;
         }
+        
         if (!ps || ps.tagName != 'BR') {
+           
             return false;
         }
         
-        var ps = node.nextSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.nextSibling;
-        }
-        if (!ps || ps.tagName != 'BR') {
+        
+        
+        
+        if (!node.previousSibling) {
             return false;
         }
+        var ps = node.previousSibling;
         
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.previousSibling;
+        }
+        if (!ps || ps.nodeType != 1) {
+            return false;
+        }
+        // if header or BR before.. then it's a candidate for removal.. - as we only want '2' of these..
+        if (!ps || [ 'BR', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(ps.tagName) < 0) {
+            return false;
+        }
         
         node.parentNode.removeChild(node); // remove me...
         
@@ -45365,13 +45401,48 @@ Roo.htmleditor.KeyEnter.prototype = {
         var newEle = doc.createTextNode('\n');
         docFragment.appendChild(newEle);
     
+    
+        var range = this.core.win.getSelection().getRangeAt(0);
+        var n = range.commonAncestorContainer ;
+        while (n && n.nodeType != 1) {
+            n  = n.parentNode;
+        }
+        var li = false;
+        if (n && n.tagName == 'UL') {
+            li = doc.createElement('LI');
+            n.appendChild(li);
+            
+        }
+        if (n && n.tagName == 'LI') {
+            li = doc.createElement('LI');
+            if (n.nextSibling) {
+                n.parentNode.insertBefore(li, n.firstSibling);
+                
+            } else {
+                n.parentNode.appendChild(li);
+            }
+        }
+        if (li) {   
+            range = doc.createRange();
+            range.setStartAfter(li);
+            range.collapse(true);
+        
+            //make the cursor there
+            var sel = this.core.win.getSelection();
+            sel.removeAllRanges();
+            sel.addRange(range);
+            return false;
+            
+            
+        }
         //add the br, or p, or something else
         newEle = doc.createElement('br');
         docFragment.appendChild(newEle);
     
         //make the br replace selection
-        var range = this.core.win.getSelection().getRangeAt(0);
+        
         range.deleteContents();
+        
         range.insertNode(docFragment);
     
         //create a new range
@@ -46148,20 +46219,25 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         // even pasting into a 'email version' of this widget will have to clean up that mess.
         
         var html = (e.browserEvent.clipboardData || window.clipboardData).getData('text/html'); // clipboard event
+        html = this.cleanWordChars(html);
         
         var d = (new DOMParser().parseFromString(html, 'text/html')).body;
         
-        
         new Roo.htmleditor.FilterStyleToTag({ node : d });
         new Roo.htmleditor.FilterAttributes({
             node : d,
-            attrib_white : ['href'],
-            attrib_clean : ['href'] 
+            attrib_white : ['href', 'src', 'name'],
+            attrib_clean : ['href', 'src', 'name'
         });
         new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
-        new Roo.htmleditor.FilterKeepChildren({node : d, tag : this.tag_remove} );
+        // should be fonts..
+        new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT' ]} );
         new Roo.htmleditor.FilterParagraph({ node : d });
+        new Roo.htmleditor.FilterSpan({ node : d });
         new Roo.htmleditor.FilterLongBr({ node : d });
+        
+        
+        
         this.insertAtCursor(d.innerHTML);
         
         e.preventDefault();
@@ -46316,20 +46392,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         if(!this.activated){
             return;
         }
-        /*
-        if(Roo.isIE){
-            this.win.focus();
-            var r = this.doc.selection.createRange();
-            if(r){
-                r.collapse(true);
-                r.pasteHTML(text);
-                this.syncValue();
-                this.deferFocus();
-            
-            }
-            return;
-        }
-        */
+         
         if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
             
@@ -46339,6 +46402,10 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             var win = this.win;
             
             if (win.getSelection && win.getSelection().getRangeAt) {
+                
+                // delete the existing?
+                
+                this.createRange(this.getSelection()).deleteContents();
                 range = win.getSelection().getRangeAt(0);
                 node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
                 range.insertNode(node);
@@ -46696,10 +46763,19 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
     },
  
     cleanWordChars : function(input) {// change the chars to hex code
-        var he = Roo.HtmlEditorCore;
         
+       var swapCodes  = [ 
+            [    8211, "&#8211;" ], 
+            [    8212, "&#8212;" ], 
+            [    8216,  "'" ],  
+            [    8217, "'" ],  
+            [    8220, '"' ],  
+            [    8221, '"' ],  
+            [    8226, "*" ],  
+            [    8230, "..." ]
+        ]; 
         var output = input;
-        Roo.each(he.swapCodes, function(sw) { 
+        Roo.each(swapCodes, function(sw) { 
             var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
             
             output = output.replace(swapper, sw[1]);
@@ -46943,36 +47019,39 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
 });
 
 Roo.HtmlEditorCore.white = [
-        'area', 'br', 'img', 'input', 'hr', 'wbr',
+        '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', 
+       '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', 
+       'CAPTION', 'COL', 'COLGROUP', 'TBODY', 'TD', 'TFOOT', 'TH', 
+      'THEAD',   'TR', 
      
-      'dir', 'menu', 'ol', 'ul', 'dl',
+      'DIR', 'MENU', 'OL', 'UL', 'DL',
        
-      'embed',  'object'
+      '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..
+        'APPLET', // 
+        'BASE',   'BASEFONT', 'BGSOUND', 'BLINK',  'BODY', 
+        'FRAME',  'FRAMESET', 'HEAD',    'HTML',   'ILAYER', 
+        'IFRAME', 'LAYER',  'LINK',     'META',    'OBJECT',   
+        'SCRIPT', 'STYLE' ,'TITLE',  'XML',
+        //'FONT' // CLEAN LATER..
+        'COLGROUP', 'COL'  // messy tables.
+        
 ];
-Roo.HtmlEditorCore.clean = [
-    'script', 'style', 'title', 'xml'
+Roo.HtmlEditorCore.clean = [ // ?? needed???
+     'SCRIPT', 'STYLE', 'TITLE', 'XML'
 ];
 Roo.HtmlEditorCore.tag_remove = [
-    'font'
+    'FONT', 'TBODY'  
 ];
 // attributes..
 
@@ -47003,16 +47082,7 @@ Roo.HtmlEditorCore.cblack= [
 ];
 
 
-Roo.HtmlEditorCore.swapCodes   =[ 
-    [    8211, "&#8211;" ], 
-    [    8212, "&#8212;" ], 
-    [    8216,  "'" ],  
-    [    8217, "'" ],  
-    [    8220, '"' ],  
-    [    8221, '"' ],  
-    [    8226, "*" ],  
-    [    8230, "..." ]
-]; 
+
 
     //<script type="text/javascript">
 
index 63bec29..7a2084c 100644 (file)
@@ -20821,13 +20821,30 @@ Roo.extend(Roo.htmleditor.FilterKeepChildren, Roo.htmleditor.FilterBlack,
     replaceTag : function(node)
     {
         // walk children...
+        Roo.log(node);
         var ar = Array.from(node.childNodes);
+        //remove first..
         for (var i = 0; i < ar.length; i++) {
+            if (ar[i].nodeType == 1) {
+                if (
+                    (typeof(this.tag) == 'object' && this.tag.indexOf(ar[i].tagName) > -1)
+                    || // array and it matches
+                    (typeof(this.tag) == 'string' && this.tag == ar[i].tagName)
+                ) {
+                    this.replaceTag(ar[i]); // child is blacklisted as well...
+                    continue;
+                }
+            }
+        }  
+        ar = Array.from(node.childNodes);
+        for (var i = 0; i < ar.length; i++) {
+         
             node.removeChild(ar[i]);
             // what if we need to walk these???
             node.parentNode.insertBefore(ar[i], node);
             if (this.tag !== false) {
                 this.walk(ar[i]);
+                
             }
         }
         node.parentNode.removeChild(node);
@@ -21136,6 +21153,8 @@ Roo.extend(Roo.htmleditor.FilterStyleToTag, Roo.htmleditor.Filter,
     
     replaceTag : function(node)
     {
+        
+        
         if (node.getAttribute("style") === null) {
             return true;
         }
@@ -21187,27 +21206,44 @@ Roo.extend(Roo.htmleditor.FilterLongBr, Roo.htmleditor.Filter,
     replaceTag : function(node)
     {
         
-        if (!node.previousSibling) {
+        var ps = node.nextSibling;
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.nextSibling;
+        }
+        
+        if (!ps &&  [ 'TD', 'TH', 'LI', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(node.parentNode.tagName) > -1) { 
+            node.parentNode.removeChild(node); // remove last BR inside one fo these tags
             return false;
         }
-        var ps = node.previousSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.previousSibling;
+        if (!ps || ps.nodeType != 1) {
+            return false;
         }
+        
         if (!ps || ps.tagName != 'BR') {
+           
             return false;
         }
         
-        var ps = node.nextSibling;
         
-        if (ps && ps.nodeType == 3 && ps.nodeValue.trim()) {
-            ps = ps.nextSibling;
-        }
-        if (!ps || ps.tagName != 'BR') {
+        
+        
+        
+        if (!node.previousSibling) {
             return false;
         }
+        var ps = node.previousSibling;
         
+        while (ps && ps.nodeType == 3 && ps.nodeValue.trim().length < 1) {
+            ps = ps.previousSibling;
+        }
+        if (!ps || ps.nodeType != 1) {
+            return false;
+        }
+        // if header or BR before.. then it's a candidate for removal.. - as we only want '2' of these..
+        if (!ps || [ 'BR', 'H1', 'H2', 'H3', 'H4', 'H5', 'H6' ].indexOf(ps.tagName) < 0) {
+            return false;
+        }
         
         node.parentNode.removeChild(node); // remove me...
         
@@ -21397,13 +21433,48 @@ Roo.htmleditor.KeyEnter.prototype = {
         var newEle = doc.createTextNode('\n');
         docFragment.appendChild(newEle);
     
+    
+        var range = this.core.win.getSelection().getRangeAt(0);
+        var n = range.commonAncestorContainer ;
+        while (n && n.nodeType != 1) {
+            n  = n.parentNode;
+        }
+        var li = false;
+        if (n && n.tagName == 'UL') {
+            li = doc.createElement('LI');
+            n.appendChild(li);
+            
+        }
+        if (n && n.tagName == 'LI') {
+            li = doc.createElement('LI');
+            if (n.nextSibling) {
+                n.parentNode.insertBefore(li, n.firstSibling);
+                
+            } else {
+                n.parentNode.appendChild(li);
+            }
+        }
+        if (li) {   
+            range = doc.createRange();
+            range.setStartAfter(li);
+            range.collapse(true);
+        
+            //make the cursor there
+            var sel = this.core.win.getSelection();
+            sel.removeAllRanges();
+            sel.addRange(range);
+            return false;
+            
+            
+        }
         //add the br, or p, or something else
         newEle = doc.createElement('br');
         docFragment.appendChild(newEle);
     
         //make the br replace selection
-        var range = this.core.win.getSelection().getRangeAt(0);
+        
         range.deleteContents();
+        
         range.insertNode(docFragment);
     
         //create a new range
@@ -22180,20 +22251,25 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         // even pasting into a 'email version' of this widget will have to clean up that mess.
         
         var html = (e.browserEvent.clipboardData || window.clipboardData).getData('text/html'); // clipboard event
+        html = this.cleanWordChars(html);
         
         var d = (new DOMParser().parseFromString(html, 'text/html')).body;
         
-        
         new Roo.htmleditor.FilterStyleToTag({ node : d });
         new Roo.htmleditor.FilterAttributes({
             node : d,
-            attrib_white : ['href'],
-            attrib_clean : ['href'] 
+            attrib_white : ['href', 'src', 'name'],
+            attrib_clean : ['href', 'src', 'name'
         });
         new Roo.htmleditor.FilterBlack({ node : d, tag : this.black});
-        new Roo.htmleditor.FilterKeepChildren({node : d, tag : this.tag_remove} );
+        // should be fonts..
+        new Roo.htmleditor.FilterKeepChildren({node : d, tag : [ 'FONT' ]} );
         new Roo.htmleditor.FilterParagraph({ node : d });
+        new Roo.htmleditor.FilterSpan({ node : d });
         new Roo.htmleditor.FilterLongBr({ node : d });
+        
+        
+        
         this.insertAtCursor(d.innerHTML);
         
         e.preventDefault();
@@ -22348,20 +22424,7 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         if(!this.activated){
             return;
         }
-        /*
-        if(Roo.isIE){
-            this.win.focus();
-            var r = this.doc.selection.createRange();
-            if(r){
-                r.collapse(true);
-                r.pasteHTML(text);
-                this.syncValue();
-                this.deferFocus();
-            
-            }
-            return;
-        }
-        */
+         
         if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
             this.win.focus();
             
@@ -22371,6 +22434,10 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
             var win = this.win;
             
             if (win.getSelection && win.getSelection().getRangeAt) {
+                
+                // delete the existing?
+                
+                this.createRange(this.getSelection()).deleteContents();
                 range = win.getSelection().getRangeAt(0);
                 node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
                 range.insertNode(node);
@@ -22728,10 +22795,19 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
     },
  
     cleanWordChars : function(input) {// change the chars to hex code
-        var he = Roo.HtmlEditorCore;
         
+       var swapCodes  = [ 
+            [    8211, "&#8211;" ], 
+            [    8212, "&#8212;" ], 
+            [    8216,  "'" ],  
+            [    8217, "'" ],  
+            [    8220, '"' ],  
+            [    8221, '"' ],  
+            [    8226, "*" ],  
+            [    8230, "..." ]
+        ]; 
         var output = input;
-        Roo.each(he.swapCodes, function(sw) { 
+        Roo.each(swapCodes, function(sw) { 
             var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
             
             output = output.replace(swapper, sw[1]);
@@ -22975,36 +23051,39 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
 });
 
 Roo.HtmlEditorCore.white = [
-        'area', 'br', 'img', 'input', 'hr', 'wbr',
+        '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', 
+       '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', 
+       'CAPTION', 'COL', 'COLGROUP', 'TBODY', 'TD', 'TFOOT', 'TH', 
+      'THEAD',   'TR', 
      
-      'dir', 'menu', 'ol', 'ul', 'dl',
+      'DIR', 'MENU', 'OL', 'UL', 'DL',
        
-      'embed',  'object'
+      '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..
+        'APPLET', // 
+        'BASE',   'BASEFONT', 'BGSOUND', 'BLINK',  'BODY', 
+        'FRAME',  'FRAMESET', 'HEAD',    'HTML',   'ILAYER', 
+        'IFRAME', 'LAYER',  'LINK',     'META',    'OBJECT',   
+        'SCRIPT', 'STYLE' ,'TITLE',  'XML',
+        //'FONT' // CLEAN LATER..
+        'COLGROUP', 'COL'  // messy tables.
+        
 ];
-Roo.HtmlEditorCore.clean = [
-    'script', 'style', 'title', 'xml'
+Roo.HtmlEditorCore.clean = [ // ?? needed???
+     'SCRIPT', 'STYLE', 'TITLE', 'XML'
 ];
 Roo.HtmlEditorCore.tag_remove = [
-    'font'
+    'FONT', 'TBODY'  
 ];
 // attributes..
 
@@ -23035,16 +23114,7 @@ Roo.HtmlEditorCore.cblack= [
 ];
 
 
-Roo.HtmlEditorCore.swapCodes   =[ 
-    [    8211, "&#8211;" ], 
-    [    8212, "&#8212;" ], 
-    [    8216,  "'" ],  
-    [    8217, "'" ],  
-    [    8220, '"' ],  
-    [    8221, '"' ],  
-    [    8226, "*" ],  
-    [    8230, "..." ]
-]; 
+
 
     //<script type="text/javascript">
 
index b5fb60c..1338eda 100644 (file)
@@ -924,8 +924,9 @@ Roo.htmleditor.FilterBlack=function(A){Roo.apply(this,A);this.walk(A.node);};Roo
 // Roo/htmleditor/FilterComment.js
 Roo.htmleditor.FilterComment=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterComment,Roo.htmleditor.Filter,{replaceComment:function(n){n.parentNode.removeChild(n);}});
 // Roo/htmleditor/FilterKeepChildren.js
-Roo.htmleditor.FilterKeepChildren=function(A){Roo.apply(this,A);if(this.tag===false){return;}this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterKeepChildren,Roo.htmleditor.FilterBlack,{replaceTag:function(A){var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;
-i++){A.removeChild(ar[i]);A.parentNode.insertBefore(ar[i],A);if(this.tag!==false){this.walk(ar[i]);}}A.parentNode.removeChild(A);return false;}});
+Roo.htmleditor.FilterKeepChildren=function(A){Roo.apply(this,A);if(this.tag===false){return;}this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterKeepChildren,Roo.htmleditor.FilterBlack,{replaceTag:function(A){Roo.log(A);var ar=Array.from(A.childNodes);for(var i=0;
+i<ar.length;i++){if(ar[i].nodeType==1){if((typeof(this.tag)=='object'&&this.tag.indexOf(ar[i].tagName)>-1)||(typeof(this.tag)=='string'&&this.tag==ar[i].tagName)){this.replaceTag(ar[i]);continue;}}}ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){A.removeChild(ar[i]);
+A.parentNode.insertBefore(ar[i],A);if(this.tag!==false){this.walk(ar[i]);}}A.parentNode.removeChild(A);return false;}});
 // Roo/htmleditor/FilterParagraph.js
 Roo.htmleditor.FilterParagraph=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterParagraph,Roo.htmleditor.Filter,{tag:'P',replaceTag:function(A){if(A.childNodes.length==1&&A.childNodes[0].nodeType==3&&A.childNodes[0].textContent.trim().length<1){A.parentNode.replaceChild(A.ownerDocument.createElement('BR'),A);
 return false;}var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){A.removeChild(ar[i]);A.parentNode.insertBefore(ar[i],A);}A.parentNode.insertBefore(A.ownerDocument.createElement('BR'),A);A.parentNode.removeChild(A);return false;}});
@@ -948,8 +949,9 @@ Roo.htmleditor.FilterStyleToTag=function(A){this.tags={B:['fontWeight','bold'],I
 }var B=[];for(var k in this.tags){if(A.style[this.tags[k][0]]==this.tags[k][1]){B.push(k);A.style.removeProperty(this.tags[k][0]);}}if(!B.length){return true;}var cn=Array.from(A.childNodes);var nn=A;Roo.each(B,function(t){var nc=A.ownerDocument.createelement(t);
 nn.appendChild(nc);nn=nc;});for(var i=0;i<cn.length;cn++){A.removeChild(cn[i]);nn.appendChild(cn[i]);}return true}})
 // Roo/htmleditor/FilterLongBr.js
-Roo.htmleditor.FilterLongBr=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterLongBr,Roo.htmleditor.Filter,{tag:'BR',replaceTag:function(A){if(!A.previousSibling){return false;}var ps=A.previousSibling;if(ps&&ps.nodeType==3&&ps.nodeValue.trim()){ps=ps.previousSibling;
-}if(!ps||ps.tagName!='BR'){return false;}var ps=A.nextSibling;if(ps&&ps.nodeType==3&&ps.nodeValue.trim()){ps=ps.nextSibling;}if(!ps||ps.tagName!='BR'){return false;}A.parentNode.removeChild(A);return false;}});
+Roo.htmleditor.FilterLongBr=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterLongBr,Roo.htmleditor.Filter,{tag:'BR',replaceTag:function(A){var ps=A.nextSibling;while(ps&&ps.nodeType==3&&ps.nodeValue.trim().length<1){ps=ps.nextSibling;}if(!ps&&['TD','TH','LI','H1','H2','H3','H4','H5','H6'].indexOf(A.parentNode.tagName)>-1){A.parentNode.removeChild(A);
+return false;}if(!ps||ps.nodeType!=1){return false;}if(!ps||ps.tagName!='BR'){return false;}if(!A.previousSibling){return false;}var ps=A.previousSibling;while(ps&&ps.nodeType==3&&ps.nodeValue.trim().length<1){ps=ps.previousSibling;}if(!ps||ps.nodeType!=1){return false;
+}if(!ps||['BR','H1','H2','H3','H4','H5','H6'].indexOf(ps.tagName)<0){return false;}A.parentNode.removeChild(A);return false;}});
 // Roo/htmleditor/Tidy.js
 Roo.htmleditor.Tidy=function(A){Roo.apply(this,A);this.core.doc.body.innerHTML=this.tidy(this.core.doc.body,'');};Roo.htmleditor.Tidy.toString=function(A){return Roo.htmleditor.Tidy.prototype.tidy(A,'');};Roo.htmleditor.Tidy.prototype={wrap:function(s){return s.replace(/\n/g," ").replace(/(?![^\n]{1,80}$)([^\n]{1,80})\s/g,'$1\n');
 },tidy:function(A,B){if(A.nodeType==3){return B===false?A.nodeValue:this.wrap(A.nodeValue.trim()).split("\n").join("\n"+B);}if(A.nodeType!=1){return '';}if(A.tagName=='BODY'){return this.cn(A,'');}var C="<"+A.tagName+this.attr(A);if(['IMG','BR','HR','INPUT'].indexOf(A.tagName)>-1){return C+'/>';
@@ -958,8 +960,10 @@ Roo.htmleditor.Tidy=function(A){Roo.apply(this,A);this.core.doc.body.innerHTML=t
 i++){if(!A.attributes.item(i).value.length){continue;}B.push(A.attributes.item(i).name+'="'+Roo.util.Format.htmlEncode(A.attributes.item(i).value)+'"');}return B.length?(' '+B.join(' ')):'';}}
 // Roo/htmleditor/KeyEnter.js
 Roo.htmleditor.KeyEnter=function(A){Roo.apply(this,A);Roo.get(this.core.doc.body).on('keypress',this.keypress,this);};Roo.htmleditor.KeyEnter.prototype={core:false,keypress:function(e){if(e.charCode!=13){return true;}e.preventDefault();var A=this.core.doc;
-var B=A.createDocumentFragment();var C=A.createTextNode('\n');B.appendChild(C);C=A.createElement('br');B.appendChild(C);var D=this.core.win.getSelection().getRangeAt(0);D.deleteContents();D.insertNode(B);D=A.createRange();D.setStartAfter(C);D.collapse(true);
-var E=this.core.win.getSelection();E.removeAllRanges();E.addRange(D);return false;}};
+var B=A.createDocumentFragment();var C=A.createTextNode('\n');B.appendChild(C);var D=this.core.win.getSelection().getRangeAt(0);var n=D.commonAncestorContainer;while(n&&n.nodeType!=1){n=n.parentNode;}var li=false;if(n&&n.tagName=='UL'){li=A.createElement('LI');
+n.appendChild(li);}if(n&&n.tagName=='LI'){li=A.createElement('LI');if(n.nextSibling){n.parentNode.insertBefore(li,n.firstSibling);}else{n.parentNode.appendChild(li);}}if(li){D=A.createRange();D.setStartAfter(li);D.collapse(true);var E=this.core.win.getSelection();
+E.removeAllRanges();E.addRange(D);return false;}C=A.createElement('br');B.appendChild(C);D.deleteContents();D.insertNode(B);D=A.createRange();D.setStartAfter(C);D.collapse(true);var E=this.core.win.getSelection();E.removeAllRanges();E.addRange(D);return false;
+}};
 // Roo/htmleditor/Block.js
 Roo.htmleditor.Block=function(A){};Roo.htmleditor.Block.factory=function(A){var B=Roo.htmleditor['Block'+Roo.get(A).attr('data-block')];if(typeof(B)=='undefined'){Roo.log("OOps missing block : "+'Block'+Roo.get(A).attr('data-block'));return false;}return new B({node:A}
 );};Roo.htmleditor.Block.prototype={friendly_name:'Image with caption',context:false,updateElement:function(A){Roo.DomHelper.update(A,this.toObject());},toHTML:function(){return Roo.DomHelper.markup(this.toObject());},getVal:function(A,B,C,D){var n=A;if(n.tagName!=B.toUpperCase()){n=A.getElementsByTagName(B).item(0);
@@ -990,32 +994,32 @@ d.innerHTML=v;this.el.dom.value=d.innerHTML;this.owner.fireEvent('push',this,v);
 }else{if(!Roo.get(this.frameId)&&!A.contentDocument){return;}this.doc=(A.contentDocument||Roo.get(this.frameId).dom.document);this.win=(A.contentWindow||Roo.get(this.frameId).dom.contentWindow);}},initEditor:function(){this.assignDocWin();this.doc.designMode="on";
 this.doc.open();this.doc.write(this.getDocMarkup());this.doc.close();var A=(this.doc.body||this.doc.documentElement);A.bgProperties='fixed';Roo.EventManager.on(this.doc,{'mouseup':this.onEditorEvent,'dblclick':this.onEditorEvent,'click':this.onEditorEvent,'keyup':this.onEditorEvent,buffer:100,scope:this}
 );Roo.EventManager.on(this.doc,{'paste':this.onPasteEvent,scope:this});if(Roo.isGecko){Roo.EventManager.on(this.doc,'keypress',this.mozKeyPress,this);}if(Roo.isIE||Roo.isSafari||Roo.isOpera){Roo.EventManager.on(this.doc,'keydown',this.fixKeys,this);}this.initialized=true;
-new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var A=(e.browserEvent.clipboardData||window.clipboardData).getData('text/html');var d=(new DOMParser().parseFromString(A,'text/html')).body;
-new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href'],attrib_clean:['href']});new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:this.tag_remove}
-);new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterLongBr({node:d});this.insertAtCursor(d.innerHTML);e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();this.activated=true;
-if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);
+new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var A=(e.browserEvent.clipboardData||window.clipboardData).getData('text/html');A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;
+new Roo.htmleditor.FilterStyleToTag({node:d});new Roo.htmleditor.FilterAttributes({node:d,attrib_white:['href','src','name'],attrib_clean:['href','src','name']});new Roo.htmleditor.FilterBlack({node:d,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:d,tag:['FONT']}
+);new Roo.htmleditor.FilterParagraph({node:d});new Roo.htmleditor.FilterSpan({node:d});new Roo.htmleditor.FilterLongBr({node:d});this.insertAtCursor(d.innerHTML);e.preventDefault();return false;},onDestroy:function(){if(this.rendered){}},onFirstFocus:function(){this.assignDocWin();
+this.activated=true;if(Roo.isGecko){this.win.focus();var s=this.win.getSelection();if(!s.focusNode||s.focusNode.nodeType!=3){var r=s.getRangeAt(0);r.selectNodeContents((this.doc.body||this.doc.documentElement));r.collapse(true);this.deferFocus();}try{this.execCmd('useCSS',true);
 this.execCmd('styleWithCSS',false);}catch(e){}}this.owner.fireEvent('activate',this);},adjustFont:function(A){var B=A.cmd=='increasefontsize'?1:-1;var v=parseInt(this.doc.queryCommandValue('FontSize')||3,10);if(Roo.isSafari){var sm={10:1,13:2,16:3,18:4,24:5,32:6,48:7}
 ;v=(v<10)?10:v;v=(v>48)?48:v;v=typeof(sm[v])=='undefined'?1:sm[v];}v=Math.max(1,v+B);this.execCmd('FontSize',v);},onEditorEvent:function(e){this.owner.fireEvent('editorevent',this,e);this.syncValue();},insertTag:function(tg){if(tg.toLowerCase()=='span'||tg.toLowerCase()=='code'||tg.toLowerCase()=='sup'||tg.toLowerCase()=='sub'){range=this.createRange(this.getSelection());
 var A=this.doc.createElement(tg.toLowerCase());A.appendChild(range.extractContents());range.insertNode(A);return;}this.execCmd("formatblock",tg);},insertText:function(A){var B=this.createRange();B.deleteContents();B.insertNode(this.doc.createTextNode(A));
 },relayCmd:function(A,B){this.win.focus();this.execCmd(A,B);this.owner.fireEvent('editorevent',this);this.owner.deferFocus();},execCmd:function(A,B){this.doc.execCommand(A,false,B===undefined?null:B);this.syncValue();},insertAtCursor:function(A){if(!this.activated){return;
-}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;
-D.document.selection.createRange().pasteHTML(E);}else{var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();
-switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;}if(A){this.win.focus();this.execCmd(A);this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();
-r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();
-r.pasteHTML('<br/>');r.collapse(false);r.select();}}}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}};}else if(Roo.isSafari){return function(e){var k=e.getKey();
-if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);
-p=p.parentNode;}a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();},selectNode:function(A){var B=A.ownerDocument.createRange();try{B.selectNode(A);
-}catch(e){B.selectNodeContents(A);}var s=this.win.getSelection();s.removeAllRanges();s.addRange(B);},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);
-if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;
-i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);
+}if(Roo.isGecko||Roo.isOpera||Roo.isSafari){this.win.focus();var B,C;var D=this.win;if(D.getSelection&&D.getSelection().getRangeAt){this.createRange(this.getSelection()).deleteContents();B=D.getSelection().getRangeAt(0);C=typeof(A)=='string'?B.createContextualFragment(A):A;
+B.insertNode(C);}else if(D.document.selection&&D.document.selection.createRange){var E=typeof(A)=='string'?A:A.outerHTML;D.document.selection.createRange().pasteHTML(E);}else{var E=typeof(A)=='string'?A:A.outerHTML;this.execCmd('InsertHTML',E);}this.syncValue();
+this.deferFocus();}},mozKeyPress:function(e){if(e.ctrlKey){var c=e.getCharCode(),A;if(c>0){c=String.fromCharCode(c).toLowerCase();switch(c){case 'b':A='bold';break;case 'i':A='italic';break;case 'u':A='underline';break;}if(A){this.win.focus();this.execCmd(A);
+this.deferFocus();e.preventDefault();}}}},fixKeys:function(){if(Roo.isIE){return function(e){var k=e.getKey(),r;if(k==e.TAB){e.stopEvent();r=this.doc.selection.createRange();if(r){r.collapse(true);r.pasteHTML('&#160;&#160;&#160;&#160;');this.deferFocus();
+}return;}if(k==e.ENTER){r=this.doc.selection.createRange();if(r){var A=r.parentElement();if(!A||A.tagName.toLowerCase()!='li'){e.stopEvent();r.pasteHTML('<br/>');r.collapse(false);r.select();}}}};}else if(Roo.isOpera){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();
+this.win.focus();this.execCmd('InsertHTML','&#160;&#160;&#160;&#160;');this.deferFocus();}};}else if(Roo.isSafari){return function(e){var k=e.getKey();if(k==e.TAB){e.stopEvent();this.execCmd('InsertText','\t');this.deferFocus();return;}};}}(),getAllAncestors:function(){var p=this.getSelectedNode();
+var a=[];if(!p){a.push(p);p=this.getParentElement();}while(p&&(p.nodeType==1)&&(p.tagName.toLowerCase()!='body')){a.push(p);p=p.parentNode;}a.push(this.doc.body);return a;},lastSel:false,lastSelNode:false,getSelection:function(){this.assignDocWin();return Roo.isIE?this.doc.selection:this.win.getSelection();
+},selectNode:function(A){var B=A.ownerDocument.createRange();try{B.selectNode(A);}catch(e){B.selectNodeContents(A);}var s=this.win.getSelection();s.removeAllRanges();s.addRange(B);},getSelectedNode:function(){var A=this.createRange(this.getSelection()).cloneRange();
+if(Roo.isIE){var B=A.parentElement();while(true){var C=A.duplicate();C.moveToElementText(B);if(C.inRange(A)){break;}if((B.nodeType!=1)||(B.tagName.toLowerCase()=='body')){break;}B=B.parentElement;}return B;}var ac=A.commonAncestorContainer;if(ac.nodeType==3){ac=ac.parentNode;
+}var ar=ac.childNodes;var D=[];var E=[];var F=false;for(var i=0;i<ar.length;i++){if((ar[i].nodeType==3)&&(!ar[i].data.length)){continue;}if(this.rangeIntersectsNode(A,ar[i])&&this.rangeCompareNode(A,ar[i])==3){D.push(ar[i]);continue;}if((ar[i].nodeType==1)&&this.rangeIntersectsNode(A,ar[i])&&(this.rangeCompareNode(A,ar[i])>0)){E.push(ar[i]);
 continue;}if(!this.rangeIntersectsNode(A,ar[i])||(this.rangeCompareNode(A,ar[i])==0)){continue;}F=true;}if(!D.length&&E.length){D=E;}if(F||!D.length||(D.length>1)){return false;}return D[0];},createRange:function(A){if(typeof A!="undefined"){try{return A.getRangeAt?A.getRangeAt(0):A.createRange();
 }catch(e){return this.doc.createRange();}}else{return this.doc.createRange();}},getParentElement:function(){this.assignDocWin();var A=Roo.isIE?this.doc.selection:this.win.getSelection();var B=this.createRange(A);try{var p=B.commonAncestorContainer;while(p.nodeType==3){p=p.parentNode;
 }return p;}catch(e){return null;}},rangeIntersectsNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);}catch(e){C.selectNodeContents(B);}var D=A.cloneRange();D.collapse(true);var E=A.cloneRange();E.collapse(false);var F=C.cloneRange();
 F.collapse(true);var G=C.cloneRange();G.collapse(false);return D.compareBoundaryPoints(Range.START_TO_START,G)==-1&&E.compareBoundaryPoints(Range.START_TO_START,F)==1;},rangeCompareNode:function(A,B){var C=B.ownerDocument.createRange();try{C.selectNode(B);
 }catch(e){C.selectNodeContents(B);}A.collapse(true);C.collapse(true);var ss=A.compareBoundaryPoints(Range.START_TO_START,C);var ee=A.compareBoundaryPoints(Range.END_TO_END,C);var D=ss==1;var E=ee==-1;if(D&&E){return 0;}if(!D&&E){return 1;}if(D&&!E){return 2;
-}return 3;},cleanWordChars:function(A){var he=Roo.HtmlEditorCore;var B=A;Roo.each(he.swapCodes,function(sw){var C=new RegExp("\\u"+sw[0].toString(16),"g");B=B.replace(C,sw[1]);});return B;},cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A}
-);new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black});new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove}
-);},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},applyBlacklists:function(){var w=typeof(this.owner.white)!='undefined'&&this.owner.white?this.owner.white:[];
+}return 3;},cleanWordChars:function(A){var B=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];var C=A;Roo.each(B,function(sw){var D=new RegExp("\\u"+sw[0].toString(16),"g");C=C.replace(D,sw[1]);});return C;
+},cleanUpChild:function(A){new Roo.htmleditor.FilterComment({node:A});new Roo.htmleditor.FilterAttributes({node:A,attrib_black:this.ablack,attrib_clean:this.aclean,style_white:this.cwhite,style_black:this.cblack});new Roo.htmleditor.FilterBlack({node:A,tag:this.black}
+);new Roo.htmleditor.FilterKeepChildren({node:A,tag:this.tag_remove});},cleanWord:function(A){new Roo.htmleditor.FilterWord({node:A?A:this.doc.body});},cleanTableWidths:function(A){new Roo.htmleditor.FilterTableWidth({node:A?A:this.doc.body});},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.aclean=typeof(this.owner.aclean)!='undefined'&&this.owner.aclean?this.owner.aclean:Roo.HtmlEditorCore.aclean;this.ablack=typeof(this.owner.ablack)!='undefined'&&this.owner.ablack?this.owner.ablack:Roo.HtmlEditorCore.ablack;
 this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remove?this.owner.tag_remove:Roo.HtmlEditorCore.tag_remove;this.white=[];this.black=[];Roo.each(Roo.HtmlEditorCore.white,function(A){if(b.indexOf(A)>-1){return;}this.white.push(A);
 },this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.white.indexOf(A)>-1){return;}this.white.push(A);},this);Roo.each(Roo.HtmlEditorCore.black,function(A){if(w.indexOf(A)>-1){return;}this.black.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;
@@ -1023,9 +1027,9 @@ this.tag_remove=typeof(this.owner.tag_remove)!='undefined'&&this.owner.tag_remov
 Roo.each(Roo.HtmlEditorCore.cwhite,function(A){if(b.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(w,function(A){if(b.indexOf(A)>-1){return;}if(this.cwhite.indexOf(A)>-1){return;}this.cwhite.push(A);},this);Roo.each(Roo.HtmlEditorCore.cblack,function(A){if(w.indexOf(A)>-1){return;
 }this.cblack.push(A);},this);Roo.each(b,function(A){if(w.indexOf(A)>-1){return;}if(this.cblack.indexOf(A)>-1){return;}this.cblack.push(A);},this);},setStylesheets:function(A){if(typeof(A)=='string'){Roo.get(this.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:A}
 );return;}var B=this;Roo.each(A,function(s){if(!s.length){return;}Roo.get(B.iframe.contentDocument.head).createChild({tag:'link',rel:'stylesheet',type:'text/css',href:s});});},removeStylesheets:function(){var A=this;Roo.each(Roo.get(A.iframe.contentDocument.head).select('link[rel=stylesheet]',true).elements,function(s){s.remove();
-});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A});return;}});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=['applet','base','basefont','bgsound','blink','body','frame','frameset','head','html','ilayer','iframe','layer','link','meta','object','script','style','title','xml'];Roo.HtmlEditorCore.clean=['script','style','title','xml'];Roo.HtmlEditorCore.tag_remove=['font'];
-Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[];Roo.HtmlEditorCore.swapCodes=[[8211,"&#8211;"],[8212,"&#8212;"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];
+});},setStyle:function(A){Roo.get(this.iframe.contentDocument.head).createChild({tag:'style',type:'text/css',html:A});return;}});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=['APPLET','BASE','BASEFONT','BGSOUND','BLINK','BODY','FRAME','FRAMESET','HEAD','HTML','ILAYER','IFRAME','LAYER','LINK','META','OBJECT','SCRIPT','STYLE','TITLE','XML','COLGROUP','COL'];Roo.HtmlEditorCore.clean=['SCRIPT','STYLE','TITLE','XML'];
+Roo.HtmlEditorCore.tag_remove=['FONT','TBODY'];Roo.HtmlEditorCore.ablack=['on'];Roo.HtmlEditorCore.aclean=['action','background','codebase','dynsrc','href','lowsrc'];Roo.HtmlEditorCore.pwhite=['http','https','mailto'];Roo.HtmlEditorCore.cwhite=[];Roo.HtmlEditorCore.cblack=[];
 
 // Roo/form/HtmlEditor.js
 Roo.form.HtmlEditor=function(A){Roo.form.HtmlEditor.superclass.constructor.call(this,A);if(!this.toolbars){this.toolbars=[];}this.editorcore=new Roo.HtmlEditorCore(Roo.apply({owner:this},A));};Roo.extend(Roo.form.HtmlEditor,Roo.form.Field,{clearUp:true,toolbars:false,resizable:false,height:300,width:500,stylesheets:false,cblack:false,cwhite:false,black:false,white:false,allowComments:false,bodyCls:'',frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',actionMode:'container',defaultAutoCreate:{tag:"textarea",style:"width:500px;height:300px;",autocomplete:"new-password"}