X-Git-Url: http://git.roojs.org/?a=blobdiff_plain;f=docs%2Fsrc%2FRoo_HtmlEditorCore.js.html;h=806a0ecf8f5acf877dd2d6918d7589f5e2af46a6;hb=1fabf2900a91b646b5406619aac5cf18e1550d53;hp=c9100c612a1eebcd52248341e6c70dcba42d068c;hpb=e968e7a74bed1c1be5ab9049fccb72272b141502;p=roojs1
diff --git a/docs/src/Roo_HtmlEditorCore.js.html b/docs/src/Roo_HtmlEditorCore.js.html
index c9100c612a..806a0ecf8f 100644
--- a/docs/src/Roo_HtmlEditorCore.js.html
+++ b/docs/src/Roo_HtmlEditorCore.js.html
@@ -73,6 +73,7 @@
*/
editorevent: true
+
});
width: 500,
+ autoClean: true,
+ enableBlocks : true,
stylesheets: false,
+ language: 'en',
allowComments: false,
bodyCls : '',
+
+ undoManager : false,
'IMG { cursor: pointer } ' +
'</style>';
- var cls = 'roo-htmleditor-body';
+ st += '<meta name="google" content="notranslate">'
+
+ var cls = 'notranslate roo-htmleditor-body';
if(this.bodyCls.length){
cls += ' ' + this.bodyCls;
}
- return '<html><head>' + st +
+ return '<html class="notranslate" translate="no"><head>' + st +
this.iframe = iframe.dom;
- this.assignDocWin();
+ this.assignDocWin();
this.doc.designMode = 'on';
@@ -243,6 +263,7 @@
if(this.doc.body || this.doc.readyState == 'complete'){
try {
this.doc.designMode="on";
+
} catch (e) {
return;
}
@@ -290,10 +311,10 @@
if(this.sourceEditMode){
- Roo.get(this.iframe).addClass(['x-hidden','hide']); Roo.get(this.iframe).addClass(['x-hidden','hide', 'd-none']); }else{
- Roo.get(this.iframe).removeClass(['x-hidden','hide']);
+ Roo.get(this.iframe).removeClass(['x-hidden','hide', 'd-none']);
this.deferFocus();
}
@@ -310,7 +331,8 @@
* @param {String} html The HTML to be cleaned
* return {String} The cleaned HTML
*/
- cleanHtml : function(html){
+ cleanHtml : function(html)
+ {
html = String(html);
if(html.length > 5){
if(Roo.isSafari){ syncValue : function(){
+ syncValue : function()
+ {
+ if(this.initialized){
+
+ this.undoManager.addEvent();
+
+
var bd = (this.doc.body || this.doc.documentElement);
- var html = bd.innerHTML;
+
+
+ var sel = this.win.getSelection();
+
+ var div = document.createElement('div');
+ div.innerHTML = bd.innerHTML;
+ var gtx = div.getElementsByClassName('gtx-trans-icon'); if (gtx.length > 0) {
+ var rm = gtx.item(0).parentNode;
+ rm.parentNode.removeChild(rm);
+ }
+
+
+ if (this.enableBlocks) {
+ new Roo.htmleditor.FilterBlock({ node : div });
+ }
+ var tidy = new Roo.htmleditor.TidySerializer({
+ inner: true
+ });
+ var html = tidy.serialize(div)
+
+
if(Roo.isSafari){
var bs = bd.getAttribute('style'); var m = bs ? bs.match(/text-align:(.*?);/i) : false;
@@ -377,24 +426,39 @@
},
pushValue : function(){
+ pushValue : function()
+ {
+ if(this.initialized){
var v = this.el.dom.value.trim();
-if(this.owner.fireEvent('beforepush', this, v) !== false){
var d = (this.doc.body || this.doc.documentElement);
d.innerHTML = v;
- this.cleanUpPaste();
+
this.el.dom.value = d.innerHTML;
this.owner.fireEvent('push', this, v);
}
+ if (this.autoClean) {
+ new Roo.htmleditor.FilterParagraph({node : this.doc.body}); new Roo.htmleditor.FilterSpan({node : this.doc.body}); }
+
+ Roo.htmleditor.Block.initAll(this.doc.body);
+ this.updateLanguage();
+
+ var lc = this.doc.body.lastChild;
+ if (lc && lc.nodeType == 1 && lc.getAttribute("contenteditable") == "false") {
+ this.doc.body.appendChild(this.doc.createElement('br'));
+ }
+
+
}
},
@@ -456,19 +520,27 @@
//var ss = this.el.getStyles( 'background-image', 'background-repeat');
//ss['background-attachment'] = 'fixed'; // w3c
dbody.bgProperties = 'fixed'; dbody.setAttribute("translate", "no");
+
+ 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);
}
@@ -480,11 +552,103 @@
-
this.owner.fireEvent('initialize', this);
this.pushValue();
},
+ onPasteEvent : function(e,v)
+ {
+ var cd = (e.browserEvent.clipboardData || window.clipboardData);
+
+ if (cd.files.length > 0) {
+ var urlAPI = (window.createObjectURL && window) ||
+ (window.URL && URL.revokeObjectURL && URL) ||
+ (window.webkitURL && webkitURL);
+
+ var url = urlAPI.createObjectURL( cd.files[0]);
+ this.insertAtCursor('<img src=" + url + ">');
+ return false;
+ }
+ var html = cd.getData('text/html'); var parser = new Roo.rtf.Parser(cd.getData('text/rtf'));
+ var images = parser.doc ? parser.doc.getElementsByType('pict') : [];
+ Roo.log(images);
+ images = images.filter(function(g) { return !g.path.match(/^rtf\/(head|pgdsctbl|listtable)/); }) .map(function(g) { return g.toDataURL(); });
+
+
+ html = this.cleanWordChars(html);
+
+ var d = (new DOMParser().parseFromString(html, 'text/html')).body;
+
+
+ var sn = this.getParentElement();
+ if (d.getElementsByTagName('table').length && sn && sn.closest('table')) {
+ e.preventDefault();
+ this.insertAtCursor("You can not nest tables");
+ return false;
+ }
+
+ if (images.length > 0) {
+ Roo.each(d.getElementsByTagName('img'), function(img, i) {
+ img.setAttribute('src', images[i]);
+ });
+ }
+ if (this.autoClean) {
+ new Roo.htmleditor.FilterStyleToTag({ node : d });
+ new Roo.htmleditor.FilterAttributes({
+ node : d,
+ attrib_white : ['href', 'src', 'name', 'align'],
+ attrib_clean : ['href', 'src' ]
+ });
+ 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 });
+ }
+ if (this.enableBlocks) {
+
+ Array.from(d.getElementsByTagName('img')).forEach(function(img) {
+ if (img.closest('figure')) { return;
+ }
+ var fig = new Roo.htmleditor.BlockFigure({
+ image_src : img.src
+ });
+ fig.updateElement(img); });
+ }
+
+
+ this.insertAtCursor(d.innerHTML.replace(/ /g,' '));
+ if (this.enableBlocks) {
+ Roo.htmleditor.Block.initAll(this.doc.body);
+ }
+
+
+ e.preventDefault();
+ return false;
+ },
onDestroy : function(){
@@ -506,7 +670,7 @@
onFirstFocus : function(){
this.assignDocWin();
-
+ this.undoManager = new Roo.lib.UndoManager(100,(this.doc.body || this.doc.documentElement));
this.activated = true;
@@ -551,11 +715,49 @@
onEditorEvent : function(e)
{
- this.owner.fireEvent('editorevent', this, e);
+
+
+ if (e && (e.ctrlKey || e.metaKey) && e.keyCode === 90) {
+ return; }
+ if (e &&
+ e.target.nodeName == 'BODY' &&
+ e.type == "mouseup" &&
+ this.doc.body.lastChild
+ ) {
+ var lc = this.doc.body.lastChild;
+ while ((lc.nodeType == 3 && lc.nodeValue == '') || lc.id == 'gtx-trans') {
+ lc = lc.previousSibling;
+ }
+ if (lc.nodeType == 1 && lc.nodeName != 'BR') {
+ var ns = this.doc.createElement('br');
+ this.doc.body.appendChild(ns);
+ range = this.doc.createRange();
+ range.setStartAfter(ns);
+ range.collapse(true);
+ var sel = this.win.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+ }
+ }
+
+
+
+ this.fireEditorEvent(e);
this.syncValue(); },
+ fireEditorEvent: function(e)
+ {
+ this.owner.fireEvent('editorevent', this, e);
+ },
+
insertTag : function(tg)
{
this.execCmd("formatblock", tg);
-
+ this.undoManager.addEvent();
},
insertText : function(txt)
@@ -588,6 +790,7 @@
range.insertNode(this.doc.createTextNode(txt));
+ this.undoManager.addEvent();
} ,
@@ -598,7 +801,37 @@
* @param {String} cmd The Midas command
* @param {String/Boolean} value (optional) The value to pass to the command (defaults to null)
*/
- relayCmd : function(cmd, value){
+ relayCmd : function(cmd, value)
+ {
+
+ switch (cmd) {
+ case 'justifyleft':
+ case 'justifyright':
+ case 'justifycenter':
+ var n = this.getParentElement();
+ var td = n.closest('td');
+ if (td) {
+ var bl = Roo.htmleditor.Block.factory(td);
+ bl.textAlign = cmd.replace('justify','');
+ bl.updateElement();
+ this.owner.fireEvent('editorevent', this);
+ return;
+ }
+ this.execCmd('styleWithCSS', true); break;
+ case 'bold':
+ case 'italic':
+ this.execCmd('styleWithCSS', false);
+ break;
+
+
+ default:
+ break;
+ }
+
+
this.win.focus();
this.execCmd(cmd, value);
this.owner.fireEvent('editorevent', this);
@@ -631,20 +864,7 @@
if(!this.activated){
return;
}
- if(Roo.isGecko || Roo.isOpera || Roo.isSafari){
this.win.focus();
@@ -654,19 +874,31 @@
var win = this.win;
if (win.getSelection && win.getSelection().getRangeAt) {
+
+ this.createRange(this.getSelection()).deleteContents();
range = win.getSelection().getRangeAt(0);
node = typeof(text) == 'string' ? range.createContextualFragment(text) : text;
range.insertNode(node);
+ range = range.cloneRange();
+ range.collapse(false);
+
+ win.getSelection().removeAllRanges();
+ win.getSelection().addRange(range);
+
+
+
} else if (win.document.selection && win.document.selection.createRange) {
var txt = typeof(text) == 'string' ? text : text.outerHTML;
win.document.selection.createRange().pasteHTML(txt);
+
} else {
var txt = typeof(text) == 'string' ? text : text.outerHTML;
this.execCmd('InsertHTML', txt);
}
-
this.syncValue();
this.deferFocus();
@@ -691,15 +923,17 @@
cmd = 'underline';
break;
- case 'v':
- this.cleanUpPaste.defer(100, this);
- return;
+ }
if(cmd){
- this.win.focus();
- this.execCmd(cmd);
- this.deferFocus();
+
+ this.relayCmd(cmd);
+ e.preventDefault();
}
@@ -709,6 +943,8 @@
fixKeys : function(){ if(Roo.isIE){
return function(e){
var k = e.getKey(), r;
@@ -722,26 +958,28 @@
}
return;
}
-
- if(k == e.ENTER){
- r = this.doc.selection.createRange();
- if(r){
- var target = r.parentElement();
- if(!target || target.tagName.toLowerCase() != 'li'){
- e.stopEvent();
- r.pasteHTML('<br />');
- r.collapse(false);
- r.select();
+ if (String.fromCharCode(k).toLowerCase() == 'v') { this.cleanUpPaste.defer(100, this);
- return;
- }
+ */
+ //if (String.fromCharCode(k).toLowerCase() == 'v') { // paste
+ // this.cleanUpPaste.defer(100, this);
+ // return;
+ //}
- };
+ };
}else if(Roo.isOpera){
return function(e){
var k = e.getKey();
@@ -751,12 +989,13 @@
this.execCmd('InsertHTML','    ');
this.deferFocus();
}
- if (String.fromCharCode(k).toLowerCase() == 'v') { this.cleanUpPaste.defer(100, this);
- return;
- }
- };
+ };
}else if(Roo.isSafari){
return function(e){
var k = e.getKey();
@@ -767,12 +1006,14 @@
this.deferFocus();
return;
}
- if (String.fromCharCode(k).toLowerCase() == 'v') { this.cleanUpPaste.defer(100, this);
- return;
- }
+ this.mozKeyPress(e);
+
+ };
}
}(),
@@ -800,7 +1041,27 @@
getSelection : function()
{
this.assignDocWin();
- return Roo.isIE ? this.doc.selection : this.win.getSelection();
+ return Roo.lib.Selection.wrap(Roo.isIE ? this.doc.selection : this.win.getSelection(), this.doc);
+ },
+ selectNode : function(node, collapse)
+ {
+ var nodeRange = node.ownerDocument.createRange();
+ try {
+ nodeRange.selectNode(node);
+ } catch (e) {
+ nodeRange.selectNodeContents(node);
+ }
+ if (collapse === true) {
+ nodeRange.collapse(true);
+ }
+ var s = this.win.getSelection();
+ s.removeAllRanges();
+ s.addRange(nodeRange);
},
getSelectedNode: function()
@@ -811,7 +1072,6 @@
-
var range = this.createRange(this.getSelection()).cloneRange();
if (Roo.isIE) {
@@ -874,6 +1134,8 @@
return nodes[0];
},
+
+
createRange: function(sel)
{
return 3;
},
- cleanUpPaste : function()
- {
- 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;
- }
-
- },
-
cleanWordChars : function(input) {var he = Roo.HtmlEditorCore;
+ var swapCodes = [
+ [ 8211, "–" ],
+ [ 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"); output = output.replace(swapper, sw[1]);
@@ -1064,113 +1321,6 @@
- domToHTML : function(currentElement, depth, nopadtext) {
-
- depth = depth || 0;
- nopadtext = nopadtext || false;
-
- if (!currentElement) {
- return this.domToHTML(this.doc.body);
- }
-
- var j;
- var allText = false;
- var nodeName = currentElement.nodeName;
- var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
-
- if (nodeName == '#text') {
-
- return nopadtext ? currentElement.nodeValue : currentElement.nodeValue.trim();
- }
-
-
- var ret = '';
- if (nodeName != 'BODY') {
-
- var i = 0;
- if (tagName) {
- var attr = [];
- for(i = 0; i < currentElement.attributes.length;i++) {
- var aname = currentElement.attributes.item(i).name;
- if (!currentElement.attributes.item(i).value.length) {
- continue;
- }
- attr.push(aname + '="' + Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"' );
- }
-
- ret = "<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') + ">";
- }
- else {
-
- }
- } else {
- tagName = false;
- }
- if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
- return ret;
- }
- if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { nopadtext = true;
- }
-
-
- i = 0;
- var currentElementChild = currentElement.childNodes.item(i);
- var allText = true;
- var innerHTML = '';
- lastnode = '';
- while (currentElementChild) {
- var nopad = nopadtext;
- if (lastnode == 'SPAN') {
- nopad = true;
- }
- if (currentElementChild.nodeName == '#text') {
- var toadd = Roo.util.Format.htmlEncode(currentElementChild.nodeValue);
- toadd = nopadtext ? toadd : toadd.trim();
- if (!nopad && toadd.length > 80) {
- innerHTML += "\n" + (new Array( depth + 1 )).join( " " );
- }
- innerHTML += toadd;
-
- i++;
- currentElementChild = currentElement.childNodes.item(i);
- lastNode = '';
- continue;
- }
- allText = false;
-
- innerHTML += nopad ? '' : "\n" + (new Array( depth + 1 )).join( " " );
-
- innerHTML += this.domToHTML(currentElementChild, depth+1, nopadtext);
- lastnode = currentElementChild.nodeName;
- i++;
- currentElementChild=currentElement.childNodes.item(i);
- }
-
- ret += innerHTML;
-
- if (!allText) {
- ret+= nopadtext ? '' : "\n" + (new Array( depth )).join( " " );
- }
-
-
- if (tagName) {
- ret+= "</"+tagName+">";
- }
- return ret;
-
- },
-
applyBlacklists : function()
{
var w = typeof(this.owner.white) != 'undefined' && this.owner.white ? this.owner.white : [];
@@ -1297,6 +1447,16 @@
},
+
+ updateLanguage : function()
+ {
+ if (!this.iframe || !this.iframe.contentDocument) {
+ return;
+ }
+ Roo.get(this.iframe.contentDocument.body).attr("lang", this.language);
+ },
+
+
removeStylesheets : function()
{
var _this = this;
@@ -1361,36 +1521,39 @@
});
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 = [
'applet', 'base', 'basefont', 'bgsound', 'blink', 'body',
- 'frame', 'frameset', 'head', 'html', 'ilayer',
- 'iframe', 'layer', 'link', 'meta', 'object',
- 'script', 'style' ,'title', 'xml' '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.clean = [ 'SCRIPT', 'STYLE', 'TITLE', 'XML'
];
Roo.HtmlEditorCore.tag_remove = [
- 'font'
+ 'FONT', 'TBODY'
];
];
-Roo.HtmlEditorCore.swapCodes =[
- [ 8211, "–" ],
- [ 8212, "—" ],
- [ 8216, "'" ],
- [ 8217, "'" ],
- [ 8220, '"' ],
- [ 8221, '"' ],
- [ 8226, "*" ],
- [ 8230, "..." ]
-];
+