roojs-ui.js
authorAlan <alan@roojs.com>
Tue, 12 Oct 2021 03:02:58 +0000 (11:02 +0800)
committerAlan <alan@roojs.com>
Tue, 12 Oct 2021 03:02:58 +0000 (11:02 +0800)
roojs-ui-debug.js
roojs-all.js
roojs-debug.js
Roo/rtf/Parser.js

Roo/rtf/Parser.js
roojs-all.js
roojs-debug.js
roojs-ui-debug.js
roojs-ui.js

index 963fb0e..5d2f10b 100644 (file)
@@ -310,7 +310,7 @@ Roo.rtf.Parser.prototype = {
     },
     emitStartGroup : function ()
     {
-        this.emitText()
+        this.emitText();
         this.push({
             type: 'groupstart',
             pos: this.cpos,
index 1565bc8..436cab7 100644 (file)
@@ -1828,6 +1828,38 @@ this.el.on('DOMAttrModified',this.setFromHidden,this);this.el.on('propertychange
 Roo.form.Radio=function(){Roo.form.Radio.superclass.constructor.apply(this,arguments);};Roo.extend(Roo.form.Radio,Roo.form.Checkbox,{inputType:'radio',getGroupValue:function(){return this.el.up('form').child('input[name='+this.el.dom.name+']:checked',true).value;
 },onRender:function(ct,A){Roo.form.Checkbox.superclass.onRender.call(this,ct,A);if(this.inputValue!==undefined){this.el.dom.value=this.inputValue;}this.wrap=this.el.wrap({cls:"x-form-check-wrap"});if(this.boxLabel){this.wrap.createChild({tag:'label',htmlFor:this.el.id,cls:'x-form-cb-label',html:this.boxLabel}
 );}if(this.checked){this.el.dom.checked='checked';}}});
+// Roo/rtf/namespace.js
+Roo.rtf={};
+// Roo/rtf/Hex.js
+Roo.rtf.Hex=function(A){this.hexstr=A;};
+// Roo/rtf/Paragraph.js
+Roo.rtf.Paragraph=function(A){this.content=[];}
+// Roo/rtf/Span.js
+Roo.rtf.Span=function(A){this.value=A.value;};
+// Roo/rtf/Group.js
+Roo.rtf.Group=function(A){this.content=[];};Roo.rtf.Group.prototype={ignorable:false,content:false,addContent:function(A){this.content.push(A);},toDataURL:function(){var A=false;switch(true){case this.content.filter(function(a){return a.value=='pngblip'}).length>0:A="image/png";
+break;case this.content.filter(function(a){return a.value=='jpegblip'}).length>0:A="image/jpeg";break;default:return 'about:blank';}var B=this.content[this.content.length-1].value;return A+';base64,'+btoa(B.match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a,16));
+}).join(""));}}
+// Roo/rtf/Ctrl.js
+Roo.rtf.Ctrl=function(A){this.value=A.value;this.param=A.param;};
+// Roo/rtf/Parser.js
+Roo.rtf.Parser=function(){this.text='';this.parserState=this.parseText;this.doc=document;this.groupStack=[];this.hexStore=[];this.doc=false;this.groups=[];};Roo.rtf.Parser.prototype={text:'',controlWord:'',controlWordParam:'',hexChar:'',doc:false,group:false,groupStack:false,hexStore:false,cpos:0,row:1,col:1,parse:function(A){for(var ii=0;
+ii<A.length;++ii){++this.cpos;if(A[ii]==='\n'){++this.row;this.col=1;}else{++this.col;}this.parserState(A[ii]);}return this.groups;},push:function(el){var m='cmd'+el.type;if(typeof(this[m])=='undefined'){Roo.log('invalid cmd:'+el.type);return;}this[m](el);
+},flushHexStore:function(){if(this.hexStore.length<1){return;}var A=this.hexStore.map(function(B){return B.value;}).join('');this.group.addContent(new Roo.rtf.Hex(A));this.hexStore.splice(0)},cmdgroupstart:function(){this.flushHexStore();if(this.group){this.groupStack.push(this.group);
+}this.group=new Roo.rtf.Group(this.group||this.doc);},cmdignorable:function(){this.flushHexStore();this.group.ignorable=true;},cmdendparagraph:function(){this.flushHexStore();this.group.addContent(new Roo.rtf.Paragraph());},cmdgroupend:function(){this.flushHexStore();
+var A=this.group;this.group=this.groupStack.pop();var B=this.group||this.doc;if(A.ignorable===false){this.groups.push(A);}},cmdtext:function(A){this.flushHexStore();if(!this.group){}this.group.addContent(new Roo.rtf.Span(A));},cmdcontrolword:function(A){this.flushHexStore();
+if(!this.group.type){this.group.type=A.value;return;}this.group.addContent(new Roo.rtf.Ctrl(A));return;},cmdhexchar:function(A){this.hexStore.push(A);},cmderror:function(A){throw new Exception(A.value);},parseText:function(c){if(c==='\\'){this.parserState=this.parseEscapes;
+}else if(c==='{'){this.emitStartGroup();}else if(c==='}'){this.emitEndGroup();}else if(c==='\x0A'||c==='\x0D'){}else{this.text+=c;}},parseEscapes:function(c){if(c==='\\'||c==='{'||c==='}'){this.text+=c;this.parserState=this.parseText;}else{this.parserState=this.parseControlSymbol;
+this.parseControlSymbol(c);}},parseControlSymbol:function(c){if(c==='~'){this.text+='\u00a0';this.parserState=this.parseText}else if(c==='-'){this.text+='\u00ad';}else if(c==='_'){this.text+='\u2011';}else if(c==='*'){this.emitIgnorable();this.parserState=this.parseText;
+}else if(c==="'"){this.parserState=this.parseHexChar;}else if(c==='|'){this.emitFormula();this.parserState=this.parseText;}else if(c===':'){this.emitIndexSubEntry();this.parserState=this.parseText;}else if(c==='\x0a'){this.emitEndParagraph();this.parserState=this.parseText;
+}else if(c==='\x0d'){this.emitEndParagraph();this.parserState=this.parseText;}else{this.parserState=this.parseControlWord;this.parseControlWord(c);}},parseHexChar:function(c){if(/^[A-Fa-f0-9]$/.test(c)){this.hexChar+=c;if(this.hexChar.length>=2){this.emitHexChar();
+this.parserState=this.parseText;}return;}this.emitError("Invalid character \""+c+"\" in hex literal.");this.parserState=this.parseText;},parseControlWord:function(c){if(c===' '){this.emitControlWord();this.parserState=this.parseText;}else if(/^[-\d]$/.test(c)){this.parserState=this.parseControlWordParam;
+this.controlWordParam+=c;}else if(/^[A-Za-z]$/.test(c)){this.controlWord+=c;}else{this.emitControlWord();this.parserState=this.parseText;this.parseText(c);}},parseControlWordParam:function(c){if(/^\d$/.test(c)){this.controlWordParam+=c;}else if(c===' '){this.emitControlWord();
+this.parserState=this.parseText;}else{this.emitControlWord();this.parserState=this.parseText;this.parseText(c);}},emitText:function(){if(this.text===''){return;}this.push({type:'text',value:this.text,pos:this.cpos,row:this.row,col:this.col});this.text=''}
+,emitControlWord:function(){this.emitText();if(this.controlWord===''){this.emitError('empty control word');}else{this.push({type:'controlword',value:this.controlWord,param:this.controlWordParam!==''&&Number(this.controlWordParam),pos:this.cpos,row:this.row,col:this.col}
+);}this.controlWord='';this.controlWordParam='';},emitStartGroup:function(){this.emitText();this.push({type:'groupstart',pos:this.cpos,row:this.row,col:this.col});},emitEndGroup:function(){this.emitText();this.push({type:'groupend',pos:this.cpos,row:this.row,col:this.col}
+);},emitIgnorable:function(){this.emitText();this.push({type:'ignorable',pos:this.cpos,row:this.row,col:this.col});},emitHexChar:function(){this.emitText();this.push({type:'hexchar',value:this.hexChar,pos:this.cpos,row:this.row,col:this.col});this.hexChar=''}
+,emitError:function(A){this.emitText();this.push({type:'error',value:A,row:this.row,col:this.col,char:this.cpos});},emitEndParagraph:function(){this.emitText();this.push({type:'endparagraph',pos:this.cpos,row:this.row,col:this.col});}}
 // Roo/htmleditor/namespace.js
 Roo.htmleditor={};
 // Roo/htmleditor/Filter.js
@@ -1918,13 +1950,14 @@ 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 cd=(e.browserEvent.clipboardData||window.clipboardData);var A=cd.getData('text/html');A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;
-Roo.log(cd.getData('text/rtf'));Roo.log(cd.getData('text/richtext'));Roo.each(cd.items,function(B){Roo.log(B);});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());
+new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var cd=(e.browserEvent.clipboardData||window.clipboardData);var A=cd.getData('text/html');var B=(new Roo.rtf.Parser()).parse(cd.getData('text/rtf')).filter(function(g){return g.type=='pict';
+}).map(function(g){return g.toDataURL();});A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;if(B.length>0){Roo.each(d.getElementsByTagName('img'),function(C,i){C.setAttribute('src',B[i]);});}Roo.log(cd.getData('text/rtf'));
+Roo.log(cd.getData('text/richtext'));Roo.each(cd.items,function(C){Roo.log(C);});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){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;
index 7f9b8c0..8055a03 100644 (file)
@@ -44509,7 +44509,437 @@ Roo.extend(Roo.form.Radio, Roo.form.Checkbox, {
     } 
     
     
-});Roo.htmleditor = {}; 
+});Roo.rtf = {}; // namespace
+Roo.rtf.Hex = function(hex)
+{
+    this.hexstr = hex;
+}
+Roo.rtf.Paragraph = function(opts)
+{
+    this.content = []; ///??? is that used?
+}Roo.rtf.Span = function(opts)
+{
+    this.value = opts.value;
+}
+
+Roo.rtf.Group = function(parent)
+{
+    // we dont want to acutally store parent - it will make debug a nightmare..
+    this.content = [];
+    
+}
+Roo.rtf.Group.prototype = {
+    ignorable : false,
+    content: false,
+    addContent : function(node) {
+        // could set styles...
+        this.content.push(node);
+    },
+    
+    // only for images really...
+    toDataURL : function()
+    {
+        var mimetype = false;
+        switch(true) {
+            case this.content.filter(function(a) { return a.value == 'pngblip' } ).length > 0: 
+                mimetype = "image/png";
+                break;
+             case this.content.filter(function(a) { return a.value == 'jpegblip' } ).length > 0:
+                mimetype = "image/jpeg";
+                break;
+            default :
+                return 'about:blank'; // ?? error?
+        }
+        
+        
+        var hexstring = this.content[this.content.length-1].value;
+        
+        return mimetype + ';base64,' + btoa(hexstring.match(/\w{2}/g).map(function(a) {
+            return String.fromCharCode(parseInt(a, 16));
+        }).join(""));
+    }
+    
+} 
+Roo.rtf.Ctrl = function(opts)
+{
+    this.value = opts.value;
+    this.param = opts.param;
+}
+/**
+ *
+ *
+ * based on this https://github.com/iarna/rtf-parser
+ * it's really only designed to extract pict from pasted RTF 
+ *
+ * usage:
+ *
+ *  var images = new Roo.rtf.Parser().parse(a_string).filter(function(g) { return g.type == 'pict'; });
+ *  
+ *
+ */
+
+
+
+
+Roo.rtf.Parser = function() {
+    //super({objectMode: true})
+    this.text = '';
+    this.parserState = this.parseText;
+    
+    // these are for interpeter...
+    this.doc = document;
+    ///this.parserState = this.parseTop
+    this.groupStack = [];
+    this.hexStore = [];
+    this.doc = false; //new Roo.rtf.Document();
+    
+    this.groups = []; // where we put the return.
+    // default is to parse TEXT...
+    
+}
+Roo.rtf.Parser.prototype = {
+    text : '', // string being parsed..
+    controlWord : '',
+    controlWordParam :  '',
+    hexChar : '',
+    doc : false,
+    group: false,
+    groupStack : false,
+    hexStore : false,
+    
+    
+    cpos : 0, 
+    row : 1, // reportin?
+    col : 1, //
+
+    parse : function (text) {
+         
+        for (var ii = 0; ii < text.length; ++ii) {
+            ++this.cpos;
+            
+            if (text[ii] === '\n') {
+                ++this.row;
+                this.col = 1;
+            } else {
+                ++this.col;
+            }
+            this.parserState(text[ii]);
+        }
+        return this.groups;
+    },
+    
+    push : function (el)
+    {
+        var m = 'cmd'+ el.type;
+        if (typeof(this[m]) == 'undefined') {
+            Roo.log('invalid cmd:' + el.type);
+            return;
+        }
+        this[m](el);
+        //Roo.log(el);
+    },
+    flushHexStore : function()
+    {
+        if (this.hexStore.length < 1) {
+            return;
+        }
+        var hexstr = this.hexStore.map(
+            function(cmd) {
+                return cmd.value;
+        }).join('');
+        
+        this.group.addContent( new Roo.rtf.Hex( hexstr ));
+                /*iconv.decode(
+                        Buffer.from(hexstr, 'hex'), this.group.get('charset'))
+                    }
+                )
+                */
+            
+        this.hexStore.splice(0)
+        
+    },
+    
+    cmdgroupstart : function()
+    {
+        this.flushHexStore();
+        if (this.group) {
+            this.groupStack.push(this.group);
+        }
+        this.group = new Roo.rtf.Group(this.group || this.doc); // parent..
+    },
+    cmdignorable : function()
+    {
+        this.flushHexStore();
+        this.group.ignorable = true;
+    },
+    cmdendparagraph : function()
+    {
+        this.flushHexStore();
+        this.group.addContent(new Roo.rtf.Paragraph());
+    },
+    cmdgroupend : function () {
+        this.flushHexStore();
+        var endingGroup = this.group;
+        this.group = this.groupStack.pop();
+        
+        var doc = this.group || this.doc;
+        //if (endingGroup instanceof FontTable) {
+        //  doc.fonts = endingGroup.table
+        //} else if (endingGroup instanceof ColorTable) {
+        //  doc.colors = endingGroup.table
+        //} else if (endingGroup !== this.doc && !endingGroup.get('ignorable')) {
+        if (endingGroup.ignorable === false) {
+            //code
+            this.groups.push(endingGroup);
+           // Roo.log( endingGroup );
+        }
+            //Roo.each(endingGroup.content, function(item)) {
+            //    doc.addContent(item);
+            //}
+            //process.emit('debug', 'GROUP END', endingGroup.type, endingGroup.get('ignorable'))
+        //}
+    },
+    cmdtext : function (cmd)
+    {
+        this.flushHexStore();
+        if (!this.group) { // an RTF fragment, missing the {\rtf1 header
+            //this.group = this.doc
+        }
+        this.group.addContent(new Roo.rtf.Span(cmd));
+    },
+    cmdcontrolword : function (cmd)
+    {
+        this.flushHexStore();
+        if (!this.group.type) {
+            this.group.type = cmd.value;
+            return;
+        }
+        this.group.addContent(new Roo.rtf.Ctrl(cmd));
+        // we actually don't care about ctrl words...
+        return ;
+        /*
+        var method = 'ctrl$' + cmd.value.replace(/-(.)/g, (_, char) => char.toUpperCase())
+        if (this[method]) {
+            this[method](cmd.param)
+        } else {
+            if (!this.group.get('ignorable')) process.emit('debug', method, cmd.param)
+        }
+        */
+    },
+    cmdhexchar : function(cmd) {
+        this.hexStore.push(cmd);
+    },
+    cmderror : function(cmd) {
+        throw new Exception (cmd.value);
+    },
+    
+    /*
+      _flush (done) {
+        if (this.text !== '\u0000') this.emitText()
+        done()
+      }
+      */
+      
+      
+    parseText : function(c)
+    {
+        if (c === '\\') {
+            this.parserState = this.parseEscapes;
+        } else if (c === '{') {
+            this.emitStartGroup();
+        } else if (c === '}') {
+            this.emitEndGroup();
+        } else if (c === '\x0A' || c === '\x0D') {
+            // cr/lf are noise chars
+        } else {
+            this.text += c;
+        }
+    },
+    
+    parseEscapes: function (c)
+    {
+        if (c === '\\' || c === '{' || c === '}') {
+            this.text += c;
+            this.parserState = this.parseText;
+        } else {
+            this.parserState = this.parseControlSymbol;
+            this.parseControlSymbol(c);
+        }
+    },
+    parseControlSymbol: function(c)
+    {
+        if (c === '~') {
+            this.text += '\u00a0'; // nbsp
+            this.parserState = this.parseText
+        } else if (c === '-') {
+             this.text += '\u00ad'; // soft hyphen
+        } else if (c === '_') {
+            this.text += '\u2011'; // non-breaking hyphen
+        } else if (c === '*') {
+            this.emitIgnorable();
+            this.parserState = this.parseText;
+        } else if (c === "'") {
+            this.parserState = this.parseHexChar;
+        } else if (c === '|') { // formula cacter
+            this.emitFormula();
+            this.parserState = this.parseText;
+        } else if (c === ':') { // subentry in an index entry
+            this.emitIndexSubEntry();
+            this.parserState = this.parseText;
+        } else if (c === '\x0a') {
+            this.emitEndParagraph();
+            this.parserState = this.parseText;
+        } else if (c === '\x0d') {
+            this.emitEndParagraph();
+            this.parserState = this.parseText;
+        } else {
+            this.parserState = this.parseControlWord;
+            this.parseControlWord(c);
+        }
+    },
+    parseHexChar: function (c)
+    {
+        if (/^[A-Fa-f0-9]$/.test(c)) {
+            this.hexChar += c;
+            if (this.hexChar.length >= 2) {
+              this.emitHexChar();
+              this.parserState = this.parseText;
+            }
+            return;
+        }
+        this.emitError("Invalid character \"" + c + "\" in hex literal.");
+        this.parserState = this.parseText;
+        
+    },
+    parseControlWord : function(c)
+    {
+        if (c === ' ') {
+            this.emitControlWord();
+            this.parserState = this.parseText;
+        } else if (/^[-\d]$/.test(c)) {
+            this.parserState = this.parseControlWordParam;
+            this.controlWordParam += c;
+        } else if (/^[A-Za-z]$/.test(c)) {
+          this.controlWord += c;
+        } else {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+          this.parseText(c);
+        }
+    },
+    parseControlWordParam : function (c) {
+        if (/^\d$/.test(c)) {
+          this.controlWordParam += c;
+        } else if (c === ' ') {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+        } else {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+          this.parseText(c);
+        }
+    },
+    
+    
+    
+    
+    emitText : function () {
+        if (this.text === '') {
+            return;
+        }
+        this.push({
+            type: 'text',
+            value: this.text,
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+        this.text = ''
+    },
+    emitControlWord : function ()
+    {
+        this.emitText();
+        if (this.controlWord === '') {
+            this.emitError('empty control word');
+        } else {
+            this.push({
+                  type: 'controlword',
+                  value: this.controlWord,
+                  param: this.controlWordParam !== '' && Number(this.controlWordParam),
+                  pos: this.cpos,
+                  row: this.row,
+                  col: this.col
+            });
+        }
+        this.controlWord = '';
+        this.controlWordParam = '';
+    },
+    emitStartGroup : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'groupstart',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitEndGroup : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'groupend',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitIgnorable : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'ignorable',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitHexChar : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'hexchar',
+            value: this.hexChar,
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+        this.hexChar = ''
+    },
+    emitError : function (message)
+    {
+      this.emitText();
+      this.push({
+            type: 'error',
+            value: message,
+            row: this.row,
+            col: this.col,
+            char: this.cpos //,
+            //stack: new Error().stack
+        });
+    },
+    emitEndParagraph : function () {
+        this.emitText();
+        this.push({
+            type: 'endparagraph',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    }
+     
+} Roo.htmleditor = {}; 
 /**
  * @class Roo.htmleditor.Filter
  * Base Class for filtering htmleditor stuff. - do not use this directly - extend it.
@@ -46220,10 +46650,24 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         var cd = (e.browserEvent.clipboardData || window.clipboardData);
         
         var html = cd.getData('text/html'); // clipboard event
+        var images = (new Roo.rtf.Parser())
+                    .parse(cd.getData('text/rtf'))
+                    .filter(function(g) { return g.type == 'pict'; })
+                    .map(function(g) { return g.toDataURL(); });
+        
+        
         html = this.cleanWordChars(html);
         
         var d = (new DOMParser().parseFromString(html, 'text/html')).body;
-         Roo.log(cd.getData('text/rtf'));
+        
+        if (images.length > 0) {
+            Roo.each(d.getElementsByTagName('img'), function(img, i) {
+            img.setAttribute('src', images[i]);
+        });
+        }
+        
+        
+        Roo.log(cd.getData('text/rtf'));
          Roo.log(cd.getData('text/richtext'));
         
         Roo.each(cd.items, function(item) {
index 2804fbc..90f406c 100644 (file)
@@ -20541,7 +20541,437 @@ Roo.extend(Roo.form.Radio, Roo.form.Checkbox, {
     } 
     
     
-});Roo.htmleditor = {}; 
+});Roo.rtf = {}; // namespace
+Roo.rtf.Hex = function(hex)
+{
+    this.hexstr = hex;
+}
+Roo.rtf.Paragraph = function(opts)
+{
+    this.content = []; ///??? is that used?
+}Roo.rtf.Span = function(opts)
+{
+    this.value = opts.value;
+}
+
+Roo.rtf.Group = function(parent)
+{
+    // we dont want to acutally store parent - it will make debug a nightmare..
+    this.content = [];
+    
+}
+Roo.rtf.Group.prototype = {
+    ignorable : false,
+    content: false,
+    addContent : function(node) {
+        // could set styles...
+        this.content.push(node);
+    },
+    
+    // only for images really...
+    toDataURL : function()
+    {
+        var mimetype = false;
+        switch(true) {
+            case this.content.filter(function(a) { return a.value == 'pngblip' } ).length > 0: 
+                mimetype = "image/png";
+                break;
+             case this.content.filter(function(a) { return a.value == 'jpegblip' } ).length > 0:
+                mimetype = "image/jpeg";
+                break;
+            default :
+                return 'about:blank'; // ?? error?
+        }
+        
+        
+        var hexstring = this.content[this.content.length-1].value;
+        
+        return mimetype + ';base64,' + btoa(hexstring.match(/\w{2}/g).map(function(a) {
+            return String.fromCharCode(parseInt(a, 16));
+        }).join(""));
+    }
+    
+} 
+Roo.rtf.Ctrl = function(opts)
+{
+    this.value = opts.value;
+    this.param = opts.param;
+}
+/**
+ *
+ *
+ * based on this https://github.com/iarna/rtf-parser
+ * it's really only designed to extract pict from pasted RTF 
+ *
+ * usage:
+ *
+ *  var images = new Roo.rtf.Parser().parse(a_string).filter(function(g) { return g.type == 'pict'; });
+ *  
+ *
+ */
+
+
+
+
+Roo.rtf.Parser = function() {
+    //super({objectMode: true})
+    this.text = '';
+    this.parserState = this.parseText;
+    
+    // these are for interpeter...
+    this.doc = document;
+    ///this.parserState = this.parseTop
+    this.groupStack = [];
+    this.hexStore = [];
+    this.doc = false; //new Roo.rtf.Document();
+    
+    this.groups = []; // where we put the return.
+    // default is to parse TEXT...
+    
+}
+Roo.rtf.Parser.prototype = {
+    text : '', // string being parsed..
+    controlWord : '',
+    controlWordParam :  '',
+    hexChar : '',
+    doc : false,
+    group: false,
+    groupStack : false,
+    hexStore : false,
+    
+    
+    cpos : 0, 
+    row : 1, // reportin?
+    col : 1, //
+
+    parse : function (text) {
+         
+        for (var ii = 0; ii < text.length; ++ii) {
+            ++this.cpos;
+            
+            if (text[ii] === '\n') {
+                ++this.row;
+                this.col = 1;
+            } else {
+                ++this.col;
+            }
+            this.parserState(text[ii]);
+        }
+        return this.groups;
+    },
+    
+    push : function (el)
+    {
+        var m = 'cmd'+ el.type;
+        if (typeof(this[m]) == 'undefined') {
+            Roo.log('invalid cmd:' + el.type);
+            return;
+        }
+        this[m](el);
+        //Roo.log(el);
+    },
+    flushHexStore : function()
+    {
+        if (this.hexStore.length < 1) {
+            return;
+        }
+        var hexstr = this.hexStore.map(
+            function(cmd) {
+                return cmd.value;
+        }).join('');
+        
+        this.group.addContent( new Roo.rtf.Hex( hexstr ));
+                /*iconv.decode(
+                        Buffer.from(hexstr, 'hex'), this.group.get('charset'))
+                    }
+                )
+                */
+            
+        this.hexStore.splice(0)
+        
+    },
+    
+    cmdgroupstart : function()
+    {
+        this.flushHexStore();
+        if (this.group) {
+            this.groupStack.push(this.group);
+        }
+        this.group = new Roo.rtf.Group(this.group || this.doc); // parent..
+    },
+    cmdignorable : function()
+    {
+        this.flushHexStore();
+        this.group.ignorable = true;
+    },
+    cmdendparagraph : function()
+    {
+        this.flushHexStore();
+        this.group.addContent(new Roo.rtf.Paragraph());
+    },
+    cmdgroupend : function () {
+        this.flushHexStore();
+        var endingGroup = this.group;
+        this.group = this.groupStack.pop();
+        
+        var doc = this.group || this.doc;
+        //if (endingGroup instanceof FontTable) {
+        //  doc.fonts = endingGroup.table
+        //} else if (endingGroup instanceof ColorTable) {
+        //  doc.colors = endingGroup.table
+        //} else if (endingGroup !== this.doc && !endingGroup.get('ignorable')) {
+        if (endingGroup.ignorable === false) {
+            //code
+            this.groups.push(endingGroup);
+           // Roo.log( endingGroup );
+        }
+            //Roo.each(endingGroup.content, function(item)) {
+            //    doc.addContent(item);
+            //}
+            //process.emit('debug', 'GROUP END', endingGroup.type, endingGroup.get('ignorable'))
+        //}
+    },
+    cmdtext : function (cmd)
+    {
+        this.flushHexStore();
+        if (!this.group) { // an RTF fragment, missing the {\rtf1 header
+            //this.group = this.doc
+        }
+        this.group.addContent(new Roo.rtf.Span(cmd));
+    },
+    cmdcontrolword : function (cmd)
+    {
+        this.flushHexStore();
+        if (!this.group.type) {
+            this.group.type = cmd.value;
+            return;
+        }
+        this.group.addContent(new Roo.rtf.Ctrl(cmd));
+        // we actually don't care about ctrl words...
+        return ;
+        /*
+        var method = 'ctrl$' + cmd.value.replace(/-(.)/g, (_, char) => char.toUpperCase())
+        if (this[method]) {
+            this[method](cmd.param)
+        } else {
+            if (!this.group.get('ignorable')) process.emit('debug', method, cmd.param)
+        }
+        */
+    },
+    cmdhexchar : function(cmd) {
+        this.hexStore.push(cmd);
+    },
+    cmderror : function(cmd) {
+        throw new Exception (cmd.value);
+    },
+    
+    /*
+      _flush (done) {
+        if (this.text !== '\u0000') this.emitText()
+        done()
+      }
+      */
+      
+      
+    parseText : function(c)
+    {
+        if (c === '\\') {
+            this.parserState = this.parseEscapes;
+        } else if (c === '{') {
+            this.emitStartGroup();
+        } else if (c === '}') {
+            this.emitEndGroup();
+        } else if (c === '\x0A' || c === '\x0D') {
+            // cr/lf are noise chars
+        } else {
+            this.text += c;
+        }
+    },
+    
+    parseEscapes: function (c)
+    {
+        if (c === '\\' || c === '{' || c === '}') {
+            this.text += c;
+            this.parserState = this.parseText;
+        } else {
+            this.parserState = this.parseControlSymbol;
+            this.parseControlSymbol(c);
+        }
+    },
+    parseControlSymbol: function(c)
+    {
+        if (c === '~') {
+            this.text += '\u00a0'; // nbsp
+            this.parserState = this.parseText
+        } else if (c === '-') {
+             this.text += '\u00ad'; // soft hyphen
+        } else if (c === '_') {
+            this.text += '\u2011'; // non-breaking hyphen
+        } else if (c === '*') {
+            this.emitIgnorable();
+            this.parserState = this.parseText;
+        } else if (c === "'") {
+            this.parserState = this.parseHexChar;
+        } else if (c === '|') { // formula cacter
+            this.emitFormula();
+            this.parserState = this.parseText;
+        } else if (c === ':') { // subentry in an index entry
+            this.emitIndexSubEntry();
+            this.parserState = this.parseText;
+        } else if (c === '\x0a') {
+            this.emitEndParagraph();
+            this.parserState = this.parseText;
+        } else if (c === '\x0d') {
+            this.emitEndParagraph();
+            this.parserState = this.parseText;
+        } else {
+            this.parserState = this.parseControlWord;
+            this.parseControlWord(c);
+        }
+    },
+    parseHexChar: function (c)
+    {
+        if (/^[A-Fa-f0-9]$/.test(c)) {
+            this.hexChar += c;
+            if (this.hexChar.length >= 2) {
+              this.emitHexChar();
+              this.parserState = this.parseText;
+            }
+            return;
+        }
+        this.emitError("Invalid character \"" + c + "\" in hex literal.");
+        this.parserState = this.parseText;
+        
+    },
+    parseControlWord : function(c)
+    {
+        if (c === ' ') {
+            this.emitControlWord();
+            this.parserState = this.parseText;
+        } else if (/^[-\d]$/.test(c)) {
+            this.parserState = this.parseControlWordParam;
+            this.controlWordParam += c;
+        } else if (/^[A-Za-z]$/.test(c)) {
+          this.controlWord += c;
+        } else {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+          this.parseText(c);
+        }
+    },
+    parseControlWordParam : function (c) {
+        if (/^\d$/.test(c)) {
+          this.controlWordParam += c;
+        } else if (c === ' ') {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+        } else {
+          this.emitControlWord();
+          this.parserState = this.parseText;
+          this.parseText(c);
+        }
+    },
+    
+    
+    
+    
+    emitText : function () {
+        if (this.text === '') {
+            return;
+        }
+        this.push({
+            type: 'text',
+            value: this.text,
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+        this.text = ''
+    },
+    emitControlWord : function ()
+    {
+        this.emitText();
+        if (this.controlWord === '') {
+            this.emitError('empty control word');
+        } else {
+            this.push({
+                  type: 'controlword',
+                  value: this.controlWord,
+                  param: this.controlWordParam !== '' && Number(this.controlWordParam),
+                  pos: this.cpos,
+                  row: this.row,
+                  col: this.col
+            });
+        }
+        this.controlWord = '';
+        this.controlWordParam = '';
+    },
+    emitStartGroup : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'groupstart',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitEndGroup : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'groupend',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitIgnorable : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'ignorable',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    },
+    emitHexChar : function ()
+    {
+        this.emitText();
+        this.push({
+            type: 'hexchar',
+            value: this.hexChar,
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+        this.hexChar = ''
+    },
+    emitError : function (message)
+    {
+      this.emitText();
+      this.push({
+            type: 'error',
+            value: message,
+            row: this.row,
+            col: this.col,
+            char: this.cpos //,
+            //stack: new Error().stack
+        });
+    },
+    emitEndParagraph : function () {
+        this.emitText();
+        this.push({
+            type: 'endparagraph',
+            pos: this.cpos,
+            row: this.row,
+            col: this.col
+        });
+    }
+     
+} Roo.htmleditor = {}; 
 /**
  * @class Roo.htmleditor.Filter
  * Base Class for filtering htmleditor stuff. - do not use this directly - extend it.
@@ -22252,10 +22682,24 @@ Roo.extend(Roo.HtmlEditorCore, Roo.Component,  {
         var cd = (e.browserEvent.clipboardData || window.clipboardData);
         
         var html = cd.getData('text/html'); // clipboard event
+        var images = (new Roo.rtf.Parser())
+                    .parse(cd.getData('text/rtf'))
+                    .filter(function(g) { return g.type == 'pict'; })
+                    .map(function(g) { return g.toDataURL(); });
+        
+        
         html = this.cleanWordChars(html);
         
         var d = (new DOMParser().parseFromString(html, 'text/html')).body;
-         Roo.log(cd.getData('text/rtf'));
+        
+        if (images.length > 0) {
+            Roo.each(d.getElementsByTagName('img'), function(img, i) {
+            img.setAttribute('src', images[i]);
+        });
+        }
+        
+        
+        Roo.log(cd.getData('text/rtf'));
          Roo.log(cd.getData('text/richtext'));
         
         Roo.each(cd.items, function(item) {
index 23c9010..08a46a9 100644 (file)
@@ -904,6 +904,38 @@ this.el.on('DOMAttrModified',this.setFromHidden,this);this.el.on('propertychange
 Roo.form.Radio=function(){Roo.form.Radio.superclass.constructor.apply(this,arguments);};Roo.extend(Roo.form.Radio,Roo.form.Checkbox,{inputType:'radio',getGroupValue:function(){return this.el.up('form').child('input[name='+this.el.dom.name+']:checked',true).value;
 },onRender:function(ct,A){Roo.form.Checkbox.superclass.onRender.call(this,ct,A);if(this.inputValue!==undefined){this.el.dom.value=this.inputValue;}this.wrap=this.el.wrap({cls:"x-form-check-wrap"});if(this.boxLabel){this.wrap.createChild({tag:'label',htmlFor:this.el.id,cls:'x-form-cb-label',html:this.boxLabel}
 );}if(this.checked){this.el.dom.checked='checked';}}});
+// Roo/rtf/namespace.js
+Roo.rtf={};
+// Roo/rtf/Hex.js
+Roo.rtf.Hex=function(A){this.hexstr=A;};
+// Roo/rtf/Paragraph.js
+Roo.rtf.Paragraph=function(A){this.content=[];}
+// Roo/rtf/Span.js
+Roo.rtf.Span=function(A){this.value=A.value;};
+// Roo/rtf/Group.js
+Roo.rtf.Group=function(A){this.content=[];};Roo.rtf.Group.prototype={ignorable:false,content:false,addContent:function(A){this.content.push(A);},toDataURL:function(){var A=false;switch(true){case this.content.filter(function(a){return a.value=='pngblip'}).length>0:A="image/png";
+break;case this.content.filter(function(a){return a.value=='jpegblip'}).length>0:A="image/jpeg";break;default:return 'about:blank';}var B=this.content[this.content.length-1].value;return A+';base64,'+btoa(B.match(/\w{2}/g).map(function(a){return String.fromCharCode(parseInt(a,16));
+}).join(""));}}
+// Roo/rtf/Ctrl.js
+Roo.rtf.Ctrl=function(A){this.value=A.value;this.param=A.param;};
+// Roo/rtf/Parser.js
+Roo.rtf.Parser=function(){this.text='';this.parserState=this.parseText;this.doc=document;this.groupStack=[];this.hexStore=[];this.doc=false;this.groups=[];};Roo.rtf.Parser.prototype={text:'',controlWord:'',controlWordParam:'',hexChar:'',doc:false,group:false,groupStack:false,hexStore:false,cpos:0,row:1,col:1,parse:function(A){for(var ii=0;
+ii<A.length;++ii){++this.cpos;if(A[ii]==='\n'){++this.row;this.col=1;}else{++this.col;}this.parserState(A[ii]);}return this.groups;},push:function(el){var m='cmd'+el.type;if(typeof(this[m])=='undefined'){Roo.log('invalid cmd:'+el.type);return;}this[m](el);
+},flushHexStore:function(){if(this.hexStore.length<1){return;}var A=this.hexStore.map(function(B){return B.value;}).join('');this.group.addContent(new Roo.rtf.Hex(A));this.hexStore.splice(0)},cmdgroupstart:function(){this.flushHexStore();if(this.group){this.groupStack.push(this.group);
+}this.group=new Roo.rtf.Group(this.group||this.doc);},cmdignorable:function(){this.flushHexStore();this.group.ignorable=true;},cmdendparagraph:function(){this.flushHexStore();this.group.addContent(new Roo.rtf.Paragraph());},cmdgroupend:function(){this.flushHexStore();
+var A=this.group;this.group=this.groupStack.pop();var B=this.group||this.doc;if(A.ignorable===false){this.groups.push(A);}},cmdtext:function(A){this.flushHexStore();if(!this.group){}this.group.addContent(new Roo.rtf.Span(A));},cmdcontrolword:function(A){this.flushHexStore();
+if(!this.group.type){this.group.type=A.value;return;}this.group.addContent(new Roo.rtf.Ctrl(A));return;},cmdhexchar:function(A){this.hexStore.push(A);},cmderror:function(A){throw new Exception(A.value);},parseText:function(c){if(c==='\\'){this.parserState=this.parseEscapes;
+}else if(c==='{'){this.emitStartGroup();}else if(c==='}'){this.emitEndGroup();}else if(c==='\x0A'||c==='\x0D'){}else{this.text+=c;}},parseEscapes:function(c){if(c==='\\'||c==='{'||c==='}'){this.text+=c;this.parserState=this.parseText;}else{this.parserState=this.parseControlSymbol;
+this.parseControlSymbol(c);}},parseControlSymbol:function(c){if(c==='~'){this.text+='\u00a0';this.parserState=this.parseText}else if(c==='-'){this.text+='\u00ad';}else if(c==='_'){this.text+='\u2011';}else if(c==='*'){this.emitIgnorable();this.parserState=this.parseText;
+}else if(c==="'"){this.parserState=this.parseHexChar;}else if(c==='|'){this.emitFormula();this.parserState=this.parseText;}else if(c===':'){this.emitIndexSubEntry();this.parserState=this.parseText;}else if(c==='\x0a'){this.emitEndParagraph();this.parserState=this.parseText;
+}else if(c==='\x0d'){this.emitEndParagraph();this.parserState=this.parseText;}else{this.parserState=this.parseControlWord;this.parseControlWord(c);}},parseHexChar:function(c){if(/^[A-Fa-f0-9]$/.test(c)){this.hexChar+=c;if(this.hexChar.length>=2){this.emitHexChar();
+this.parserState=this.parseText;}return;}this.emitError("Invalid character \""+c+"\" in hex literal.");this.parserState=this.parseText;},parseControlWord:function(c){if(c===' '){this.emitControlWord();this.parserState=this.parseText;}else if(/^[-\d]$/.test(c)){this.parserState=this.parseControlWordParam;
+this.controlWordParam+=c;}else if(/^[A-Za-z]$/.test(c)){this.controlWord+=c;}else{this.emitControlWord();this.parserState=this.parseText;this.parseText(c);}},parseControlWordParam:function(c){if(/^\d$/.test(c)){this.controlWordParam+=c;}else if(c===' '){this.emitControlWord();
+this.parserState=this.parseText;}else{this.emitControlWord();this.parserState=this.parseText;this.parseText(c);}},emitText:function(){if(this.text===''){return;}this.push({type:'text',value:this.text,pos:this.cpos,row:this.row,col:this.col});this.text=''}
+,emitControlWord:function(){this.emitText();if(this.controlWord===''){this.emitError('empty control word');}else{this.push({type:'controlword',value:this.controlWord,param:this.controlWordParam!==''&&Number(this.controlWordParam),pos:this.cpos,row:this.row,col:this.col}
+);}this.controlWord='';this.controlWordParam='';},emitStartGroup:function(){this.emitText();this.push({type:'groupstart',pos:this.cpos,row:this.row,col:this.col});},emitEndGroup:function(){this.emitText();this.push({type:'groupend',pos:this.cpos,row:this.row,col:this.col}
+);},emitIgnorable:function(){this.emitText();this.push({type:'ignorable',pos:this.cpos,row:this.row,col:this.col});},emitHexChar:function(){this.emitText();this.push({type:'hexchar',value:this.hexChar,pos:this.cpos,row:this.row,col:this.col});this.hexChar=''}
+,emitError:function(A){this.emitText();this.push({type:'error',value:A,row:this.row,col:this.col,char:this.cpos});},emitEndParagraph:function(){this.emitText();this.push({type:'endparagraph',pos:this.cpos,row:this.row,col:this.col});}}
 // Roo/htmleditor/namespace.js
 Roo.htmleditor={};
 // Roo/htmleditor/Filter.js
@@ -994,13 +1026,14 @@ 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 cd=(e.browserEvent.clipboardData||window.clipboardData);var A=cd.getData('text/html');A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;
-Roo.log(cd.getData('text/rtf'));Roo.log(cd.getData('text/richtext'));Roo.each(cd.items,function(B){Roo.log(B);});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());
+new Roo.htmleditor.KeyEnter({core:this});this.owner.fireEvent('initialize',this);this.pushValue();},onPasteEvent:function(e,v){var cd=(e.browserEvent.clipboardData||window.clipboardData);var A=cd.getData('text/html');var B=(new Roo.rtf.Parser()).parse(cd.getData('text/rtf')).filter(function(g){return g.type=='pict';
+}).map(function(g){return g.toDataURL();});A=this.cleanWordChars(A);var d=(new DOMParser().parseFromString(A,'text/html')).body;if(B.length>0){Roo.each(d.getElementsByTagName('img'),function(C,i){C.setAttribute('src',B[i]);});}Roo.log(cd.getData('text/rtf'));
+Roo.log(cd.getData('text/richtext'));Roo.each(cd.items,function(C){Roo.log(C);});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){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;