}
this.initialized = true;
+
+ // initialize special key events - enter
+ new Roo.htmleditor.KeyEnter({core : this});
+
+
+
+
this.owner.fireEvent('initialize', this);
this.pushValue();
},
style_white : this.cwhite,
style_black : this.cblack
});
- new Roo.htmleditor.FilterBlack({ node : node, black : this.black});
- new Roo.htmleditor.FilterKeepChildren({node : node, black : this.remove} );
+ new Roo.htmleditor.FilterBlack({ node : node, tag : this.black});
+ new Roo.htmleditor.FilterKeepChildren({node : node, tag : this.tag_remove} );
},
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(tag) {
Roo.HtmlEditorCore.clean = [
'script', 'style', 'title', 'xml'
];
-Roo.HtmlEditorCore.remove = [
+Roo.HtmlEditorCore.tag_remove = [
'font'
];
// attributes..
tabIndex:-1
});
}
- cmenu.menu.items.push({
+ cmenu.menu.items.push({
actiontype : 'tablewidths',
html: 'Remove Table Widths',
handler: function(a,b) {
this.replaceComment(e);
return;
- case e.nodeType != 3: //not a node.
+ case e.nodeType != 1: //not a node.
return;
case this.tag === true: // everything
Roo.htmleditor.FilterAttributes = function(cfg)
{
Roo.apply(this, cfg);
+ this.attrib_black = this.attrib_black || [];
+ this.attrib_clean = this.attrib_clean || [];
+ this.style_white = this.style_white || [];
+ this.style_black = this.style_black || [];
this.walk(cfg.node);
}
-/**
- * Filter Clean
- *
- * Based on White / Blacklists etc...
- *
- *
- * usually call Roo.apply(Roo.htmleditor.FilterClean)
- *
- */
-
/**
* @class Roo.htmleditor.FilterBlack
* remove blacklisted elements.
Roo.extend(Roo.htmleditor.FilterBlack, Roo.htmleditor.Filter,
{
tag : true, // all elements.
- /**
- * @cfg {array} black blacklist of elements
- */
- black : false, // array
-
-
+
replace : function(n)
{
n.parentNode.removeChild(n);
replaceTag : function(node)
{
// walk children...
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
+ var 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.insertBefore(node.childNodes[i], node);
- this.walk(node.childNodes[i]);
+ node.parentNode.insertBefore(ar[i], node);
+ this.walk(ar[i]);
}
node.parentNode.removeChild(node);
return false; // don't walk children
{
- tag : 'p',
+ tag : 'P',
replaceTag : function(node)
if (node.childNodes.length == 1 &&
node.childNodes[0].nodeType == 3 &&
- node.childNodes[0].nodeType.textContent.trim().length < 1
+ node.childNodes[0].textContent.trim().length < 1
) {
// remove and replace with '<BR>';
- node.parentNode.replaceChild(node.documentOwner.createElement('BR'),node);
+ node.parentNode.replaceChild(node.ownerDocument.createElement('BR'),node);
return false; // no need to walk..
}
-
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
+ var 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.insertBefore(node.childNodes[i], node);
+ node.parentNode.insertBefore(ar[i], node);
}
// now what about this?
// <p> </p>
// double BR.
- node.insertBefore(node.documentOwner.createElement('BR'), node);
+ node.parentNode.insertBefore(node.ownerDocument.createElement('BR'), node);
node.parentNode.removeChild(node);
return false;
this.walk(cfg.node);
}
-Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.Filter,
+Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.FilterKeepChildren,
{
tag : 'SPAN',
replaceTag : function(node)
{
if (node.attributes && node.attributes.length > 0) {
- this.walk(node);
- return true;
+ return true; // walk if there are any.
}
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
- // what if we need to walk these???
- node.insertBefore(node.childNodes[i], node);
- this.walk(node.childNodes[i]);
- }
- n.parentNode.removeChild(n);
- return false; // don't walk children
+ Roo.htmleditor.FilterKeepChildren.prototype.replaceTag.call(this, node);
+ return false;
}
Roo.htmleditor.FilterTableWidth = function(cfg)
{
// no need to apply config.
- this.tag = ['table', 'td', 'tr', 'th', 'thead', 'tbody' ];
+ this.tag = ['TABLE', 'TD', 'TR', 'TH', 'THEAD', 'TBODY' ];
this.walk(cfg.node);
}
}
}
- this.walk(node);
+ return true; // continue doing children..
}
});
\ No newline at end of file
this.core.doc.body.innerHTML = this.tidy(this.core.doc.body, '');
}
+
+Roo.htmleditor.Tidy.toString = function(node)
+{
+ return Roo.htmleditor.Tidy.prototype.tidy(node, '');
+}
+
Roo.htmleditor.Tidy.prototype = {
},
- /* ?? why ?? */
tidy : function(node, indent) {
-
-
- //Roo.log(currentElement);
-
- var nodeName = node.nodeName;
- //var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
- var tagName = node.tagName; /// why encode tagname?
-
+
if (node.nodeType == 3) {
// text.
- return indent === false ? node.nodeValue :
- this.wrap(node.nodeValue.trim()).split("\n").join("\n" + indent)
+
+
+ return indent === false ? node.nodeValue : this.wrap(node.nodeValue.trim()).split("\n").join("\n" + indent);
+
}
}
// Prints the node tagName, such as <A>, <IMG>, etc
- var ret = (indent === false ? '' : indent ) + "<"+ node.node.tagName + _this.attr(node)
+ var ret = "<" + node.tagName + this.attr(node) ;
// elements with no children..
- if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
+ if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(node.tagName) > -1) {
return ret + '/>';
}
ret += '>';
- var cindent = indent + ' ';
- if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { // or code?
+
+ var cindent = indent === false ? '' : (indent + ' ');
+ // tags where we will not pad the children.. (inline text tags etc..)
+ if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN', 'B', 'I', 'S'].indexOf(node.tagName) > -1) { // or code?
cindent = false;
+
+
}
- return ret +
- this.cn(node, cindent ) +
- '</' + node.tagName + '>' +
- (indent === false ? '' : "\n");
+ var cn = this.cn(node, cindent );
+
+ return ret + cn + '</' + node.tagName + '>';
},
cn: function(node, indent)
{
var ret = [];
- var allText = true;
+
var ar = Array.from(node.childNodes);
for (var i = 0 ; i < ar.length ; i++) {
+ if (indent !== false // indent==false preservies everything
+ && i > 0
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/^\s+/)
+ ) {
+ ret.push(" "); // add a space if i'm a text item with a space at the front, as tidy will strip spaces.
+ }
+ if (indent !== false
+ && ar[i].nodeType == 1 // element - and indent is not set...
+ ) {
+ ret.push("\n" + indent);
+ }
+
ret.push(this.tidy(ar[i], indent));
- if (ar[i].nodeType != 3) { //text
- allText = false;
+ // text + trailing indent
+ if (indent !== false
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/\s+$/)
+ ){
+ ret.push("\n" + indent);
}
+
+
+
+
}
// what if all text?
continue;
}
attr.push( node.attributes.item(i).name + '="' +
- Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"'
+ Roo.util.Format.htmlEncode(node.attributes.item(i).value) + '"'
);
}
return attr.length ? (' ' + attr.join(' ') ) : '';
Roo.htmleditor.FilterTableWidth
Roo.htmleditor.FilterWord
+Roo.htmleditor.KeyEnter
+
Roo.HtmlEditorCore
Roo.bootstrap.form.HtmlEditor
Roo.bootstrap.form.HtmlEditorToolbarStandard
Roo.htmleditor.FilterSpan
Roo.htmleditor.FilterTableWidth
Roo.htmleditor.FilterWord
+Roo.htmleditor.Tidy
+Roo.htmleditor.KeyEnter
Roo.HtmlEditorCore
"tree_parent" : []
},
"Roo.htmleditor.FilterBlack" : {
- "props" : [
- {
- "name" : "black",
- "type" : "array",
- "desc" : "blacklist of elements",
- "memberOf" : ""
- }
- ],
+ "props" : [],
"events" : [],
"methods" : [],
"isAbstract" : false,
"tree_children" : [],
"tree_parent" : []
},
+ "Roo.htmleditor.KeyEnter" : {
+ "props" : [
+ {
+ "name" : "core",
+ "type" : "Roo.HtmlEditorCore",
+ "desc" : "the editor.",
+ "memberOf" : ""
+ }
+ ],
+ "events" : [],
+ "methods" : [],
+ "isAbstract" : false,
+ "isBuilderTop" : false,
+ "implementations" : [],
+ "tree_children" : [],
+ "tree_parent" : []
+ },
+ "Roo.htmleditor.Tidy" : {
+ "props" : [
+ {
+ "name" : "core",
+ "type" : "Roo.HtmlEditorCore",
+ "desc" : "the editor.",
+ "memberOf" : ""
+ }
+ ],
+ "events" : [],
+ "methods" : [],
+ "isAbstract" : false,
+ "isBuilderTop" : false,
+ "implementations" : [],
+ "tree_children" : [],
+ "tree_parent" : []
+ },
"Roo.lib" : {
"props" : [],
"events" : [],
}
</span><span class="jsdoc-var">this.initialized </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">true</span><span class="jsdoc-syntax">;
+
+ </span><span class="jsdoc-comment">// initialize special key events - enter
+ </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.KeyEnter</span><span class="jsdoc-syntax">({</span><span class="jsdoc-var">core </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this</span><span class="jsdoc-syntax">});
+
+
+
+
</span><span class="jsdoc-var">this.owner.fireEvent</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'initialize'</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">style_white </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.cwhite</span><span class="jsdoc-syntax">,
</span><span class="jsdoc-var">style_black </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.cblack
</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">node</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">black </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">node</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">black </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.remove</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">node</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">node</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-var">cleanTableWidths </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">new </span><span class="jsdoc-var">Roo.htmleditor.FilterTable</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.doc.body</span><span class="jsdoc-syntax">});
+ </span><span class="jsdoc-keyword">new </span><span class="jsdoc-var">Roo.htmleditor.FilterTableWidth</span><span class="jsdoc-syntax">({ </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">node </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">this.doc.body</span><span class="jsdoc-syntax">});
},
</span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">w </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.white</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'undefined' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.owner.white </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.owner.white </span><span class="jsdoc-syntax">: [];
</span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">b </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.black</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'undefined' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.owner.black </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.owner.black </span><span class="jsdoc-syntax">: [];
+ </span><span class="jsdoc-var">this.aclean </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.aclean</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'undefined' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.owner.aclean </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.owner.aclean </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">Roo.HtmlEditorCore.aclean</span><span class="jsdoc-syntax">;
+ </span><span class="jsdoc-var">this.ablack </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.ablack</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'undefined' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.owner.ablack </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.owner.ablack </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">Roo.HtmlEditorCore.ablack</span><span class="jsdoc-syntax">;
+ </span><span class="jsdoc-var">this.tag_remove </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.owner.tag_remove</span><span class="jsdoc-syntax">) != </span><span class="jsdoc-string">'undefined' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.owner.tag_remove </span><span class="jsdoc-syntax">? </span><span class="jsdoc-var">this.owner.tag_remove </span><span class="jsdoc-syntax">: </span><span class="jsdoc-var">Roo.HtmlEditorCore.tag_remove</span><span class="jsdoc-syntax">;
+
</span><span class="jsdoc-var">this.white </span><span class="jsdoc-syntax">= [];
</span><span class="jsdoc-var">this.black </span><span class="jsdoc-syntax">= [];
</span><span class="jsdoc-var">Roo.each</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">Roo.HtmlEditorCore.white</span><span class="jsdoc-syntax">, </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">tag</span><span class="jsdoc-syntax">) {
</span><span class="jsdoc-var">Roo.HtmlEditorCore.clean </span><span class="jsdoc-syntax">= [
</span><span class="jsdoc-string">'script'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-string">'style'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-string">'title'</span><span class="jsdoc-syntax">, </span><span class="jsdoc-string">'xml'
</span><span class="jsdoc-syntax">];
-</span><span class="jsdoc-var">Roo.HtmlEditorCore.remove </span><span class="jsdoc-syntax">= [
+</span><span class="jsdoc-var">Roo.HtmlEditorCore.tag_remove </span><span class="jsdoc-syntax">= [
</span><span class="jsdoc-string">'font'
</span><span class="jsdoc-syntax">];
</span><span class="jsdoc-comment">// attributes..
</span><span class="jsdoc-var">tabIndex</span><span class="jsdoc-syntax">:-1
});
}
- </span><span class="jsdoc-var">cmenu.menu.items.push</span><span class="jsdoc-syntax">({
+ </span><span class="jsdoc-var">cmenu.menu.items.push</span><span class="jsdoc-syntax">({
</span><span class="jsdoc-var">actiontype </span><span class="jsdoc-syntax">: </span><span class="jsdoc-string">'tablewidths'</span><span class="jsdoc-syntax">,
</span><span class="jsdoc-var">html</span><span class="jsdoc-syntax">: </span><span class="jsdoc-string">'Remove Table Widths'</span><span class="jsdoc-syntax">,
</span><span class="jsdoc-var">handler</span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">a</span><span class="jsdoc-syntax">,</span><span class="jsdoc-var">b</span><span class="jsdoc-syntax">) {
-<html><head><title>Roo/htmleditor/Filter.js</title><link rel="stylesheet" type="text/css" href="../../css/highlight-js.css"/></head><body class="highlightpage"><code class="jsdoc-pretty"><span class="jsdoc-comment">/**
- *
- * Base Class for filtering htmleditor stuff.
- *
- */
-
-/**
+<html><head><title>Roo/htmleditor/Filter.js</title><link rel="stylesheet" type="text/css" href="../../css/highlight-js.css"/></head><body class="highlightpage"><code class="jsdoc-pretty">
+<span class="jsdoc-comment">/**
* @class Roo.htmleditor.Filter
* Base Class for filtering htmleditor stuff. - do not use this directly - extend it.
* @cfg {DomElement} node The node to iterate and filter
</span><span class="jsdoc-var">this.replaceComment</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">);
</span><span class="jsdoc-keyword">return</span><span class="jsdoc-syntax">;
- </span><span class="jsdoc-keyword">case </span><span class="jsdoc-var">e.nodeType </span><span class="jsdoc-syntax">!= 3: </span><span class="jsdoc-comment">//not a node.
+ </span><span class="jsdoc-keyword">case </span><span class="jsdoc-var">e.nodeType </span><span class="jsdoc-syntax">!= 1: </span><span class="jsdoc-comment">//not a node.
</span><span class="jsdoc-keyword">return</span><span class="jsdoc-syntax">;
- </span><span class="jsdoc-keyword">case </span><span class="jsdoc-var">tag </span><span class="jsdoc-syntax">=== </span><span class="jsdoc-keyword">true</span><span class="jsdoc-syntax">: </span><span class="jsdoc-comment">// everything
- </span><span class="jsdoc-keyword">case typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">tag</span><span class="jsdoc-syntax">) == </span><span class="jsdoc-string">'object' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">tag.indexOf</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e.tagName</span><span class="jsdoc-syntax">) > -1: </span><span class="jsdoc-comment">// array and it matches.
- </span><span class="jsdoc-keyword">case typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">tag</span><span class="jsdoc-syntax">) == </span><span class="jsdoc-string">'string' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">tag </span><span class="jsdoc-syntax">== </span><span class="jsdoc-var">e.tagName</span><span class="jsdoc-syntax">: </span><span class="jsdoc-comment">// array and it matches.
+ </span><span class="jsdoc-keyword">case </span><span class="jsdoc-var">this.tag </span><span class="jsdoc-syntax">=== </span><span class="jsdoc-keyword">true</span><span class="jsdoc-syntax">: </span><span class="jsdoc-comment">// everything
+ </span><span class="jsdoc-keyword">case typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tag</span><span class="jsdoc-syntax">) == </span><span class="jsdoc-string">'object' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.tag.indexOf</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e.tagName</span><span class="jsdoc-syntax">) > -1: </span><span class="jsdoc-comment">// array and it matches.
+ </span><span class="jsdoc-keyword">case typeof</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.tag</span><span class="jsdoc-syntax">) == </span><span class="jsdoc-string">'string' </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-var">this.tag </span><span class="jsdoc-syntax">== </span><span class="jsdoc-var">e.tagName</span><span class="jsdoc-syntax">: </span><span class="jsdoc-comment">// array and it matches.
</span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">this.replaceTag </span><span class="jsdoc-syntax">&& </span><span class="jsdoc-keyword">false </span><span class="jsdoc-syntax">=== </span><span class="jsdoc-var">this.replaceTag</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">e</span><span class="jsdoc-syntax">)) {
</span><span class="jsdoc-keyword">return</span><span class="jsdoc-syntax">;
}
</span><span class="jsdoc-var">Roo.htmleditor.FilterAttributes </span><span class="jsdoc-syntax">= </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">cfg</span><span class="jsdoc-syntax">)
{
</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_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">|| [];
</span><span class="jsdoc-var">this.walk</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">cfg.node</span><span class="jsdoc-syntax">);
}
<html><head><title>Roo/htmleditor/FilterBlack.js</title><link rel="stylesheet" type="text/css" href="../../css/highlight-js.css"/></head><body class="highlightpage"><code class="jsdoc-pretty"><span class="jsdoc-comment">/**
- * Filter Clean
- *
- * Based on White / Blacklists etc...
- *
- *
- * usually call Roo.apply(Roo.htmleditor.FilterClean)
- *
- */
-
-/**
* @class Roo.htmleditor.FilterBlack
* remove blacklisted elements.
* @constructor
</span><span class="jsdoc-var">Roo.extend</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">Roo.htmleditor.FilterBlack</span><span class="jsdoc-syntax">, </span><span class="jsdoc-var">Roo.htmleditor.Filter</span><span class="jsdoc-syntax">,
{
</span><span class="jsdoc-var">tag </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">true</span><span class="jsdoc-syntax">, </span><span class="jsdoc-comment">// all elements.
- /**
- * @cfg {array} black blacklist of elements
- */
- </span><span class="jsdoc-var">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">replace </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">n</span><span class="jsdoc-syntax">)
{
{
- </span><span class="jsdoc-var">replaceTag </span><span class="jsdoc-syntax">: </span><span class="jsdoc-keyword">function</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">n</span><span class="jsdoc-syntax">)
+ </span><span class="jsdoc-var">replaceTag </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-comment">// walk children...
- </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">= 0; </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">< </span><span class="jsdoc-var">node.childNodes.length</span><span class="jsdoc-syntax">; </span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">++) {
- </span><span class="jsdoc-var">node.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
+ </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">ar </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Array.from</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</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">= 0; </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">< </span><span class="jsdoc-var">ar.length</span><span class="jsdoc-syntax">; </span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">++) {
+ </span><span class="jsdoc-var">node.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">ar</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
</span><span class="jsdoc-comment">// what if we need to walk these???
- </span><span class="jsdoc-var">node.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">], </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
- </span><span class="jsdoc-var">this.walk</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
+ </span><span class="jsdoc-var">node.parentNode.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">ar</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">], </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+ </span><span class="jsdoc-var">this.walk</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">ar</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
}
- </span><span class="jsdoc-var">n.parentNode.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">n</span><span class="jsdoc-syntax">);
+ </span><span class="jsdoc-var">node.parentNode.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
</span><span class="jsdoc-keyword">return false</span><span class="jsdoc-syntax">; </span><span class="jsdoc-comment">// don't walk children
</span><span class="jsdoc-keyword">if </span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes.length </span><span class="jsdoc-syntax">== 1 &&
</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[0]</span><span class="jsdoc-var">.nodeType </span><span class="jsdoc-syntax">== 3 &&
- </span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[0]</span><span class="jsdoc-var">.nodeType.textContent.trim</span><span class="jsdoc-syntax">()</span><span class="jsdoc-var">.length </span><span class="jsdoc-syntax">< 1
+ </span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[0]</span><span class="jsdoc-var">.textContent.trim</span><span class="jsdoc-syntax">()</span><span class="jsdoc-var">.length </span><span class="jsdoc-syntax">< 1
) {
</span><span class="jsdoc-comment">// remove and replace with '<BR>';
- </span><span class="jsdoc-var">node.parentNode.replaceChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.documentOwner.createElement</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'BR'</span><span class="jsdoc-syntax">),</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+ </span><span class="jsdoc-var">node.parentNode.replaceChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.ownerDocument.createElement</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'BR'</span><span class="jsdoc-syntax">),</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
</span><span class="jsdoc-keyword">return false</span><span class="jsdoc-syntax">; </span><span class="jsdoc-comment">// no need to walk..
</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">= 0; </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">< </span><span class="jsdoc-var">node.childNodes.length</span><span class="jsdoc-syntax">; </span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">++) {
- </span><span class="jsdoc-var">node.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
+ </span><span class="jsdoc-keyword">var </span><span class="jsdoc-var">ar </span><span class="jsdoc-syntax">= </span><span class="jsdoc-var">Array.from</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</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">= 0; </span><span class="jsdoc-var">i </span><span class="jsdoc-syntax">< </span><span class="jsdoc-var">ar.length</span><span class="jsdoc-syntax">; </span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">++) {
+ </span><span class="jsdoc-var">node.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">ar</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">]);
</span><span class="jsdoc-comment">// what if we need to walk these???
- </span><span class="jsdoc-var">node.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.childNodes</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">], </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+ </span><span class="jsdoc-var">node.parentNode.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">ar</span><span class="jsdoc-syntax">[</span><span class="jsdoc-var">i</span><span class="jsdoc-syntax">], </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
}
</span><span class="jsdoc-comment">// now what about this?
// <p> &nbsp; </p>
// double BR.
- </span><span class="jsdoc-var">node.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.documentOwner.createElement</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'BR'</span><span class="jsdoc-syntax">), </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
+ </span><span class="jsdoc-var">node.parentNode.insertBefore</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node.ownerDocument.createElement</span><span class="jsdoc-syntax">(</span><span class="jsdoc-string">'BR'</span><span class="jsdoc-syntax">), </span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
</span><span class="jsdoc-var">node.parentNode.removeChild</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
</span><span class="jsdoc-keyword">return false</span><span class="jsdoc-syntax">;
}
-
-
-};</span></code></body></html>
\ No newline at end of file
+});</span></code></body></html>
\ No newline at end of file
}
}
- </span><span class="jsdoc-var">this.walk</span><span class="jsdoc-syntax">(</span><span class="jsdoc-var">node</span><span class="jsdoc-syntax">);
- }
+ </span><span class="jsdoc-keyword">return true</span><span class="jsdoc-syntax">; </span><span class="jsdoc-comment">// continue doing children..
+ </span><span class="jsdoc-syntax">}
});</span></code></body></html>
\ No newline at end of file
"name" : "Roo.htmleditor.FilterWord",
"cn" : [],
"is_class" : true
+ },
+ {
+ "name" : "Roo.htmleditor.KeyEnter",
+ "cn" : [],
+ "is_class" : false
+ },
+ {
+ "name" : "Roo.htmleditor.Tidy",
+ "cn" : [],
+ "is_class" : false
}
],
"is_class" : false
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;}});
// Roo/htmleditor/FilterSpan.js
-Roo.htmleditor.FilterSpan=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterSpan,Roo.htmleditor.Filter,{tag:'SPAN',replaceTag:function(A){if(A.attributes&&A.attributes.length>0){this.walk(A);return true;}for(var i=0;i<A.childNodes.length;i++){A.removeChild(A.childNodes[i]);
-A.insertBefore(A.childNodes[i],A);this.walk(A.childNodes[i]);}n.parentNode.removeChild(n);return false;}});
+Roo.htmleditor.FilterSpan=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterSpan,Roo.htmleditor.FilterKeepChildren,{tag:'SPAN',replaceTag:function(A){if(A.attributes&&A.attributes.length>0){return true;}Roo.htmleditor.FilterKeepChildren.prototype.replaceTag.call(this,A);
+return false;}});
// Roo/htmleditor/FilterTableWidth.js
Roo.htmleditor.FilterTableWidth=function(A){this.tag=['TABLE','TD','TR','TH','THEAD','TBODY'];this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterTableWidth,Roo.htmleditor.Filter,{replaceTag:function(A){if(A.hasAttribute('width')){A.removeAttribute('width');
}if(A.hasAttribute("style")){var B=A.getAttribute("style").split(";");var C=[];Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");if(kv[0].match(/^\s*(width|min-width)\s*$/)){return;}C.push(s);});A.setAttribute("style",C.length?C.join(';'):'');
if(!C.length){A.removeAttribute("class");}}if(A.hasAttribute("lang")){A.removeAttribute("lang");}if(A.hasAttribute("style")){var D=A.getAttribute("style").split(";");var E=[];Roo.each(D,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");if(kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)){return;
}E.push(s);});A.setAttribute("style",E.length?E.join(';'):'');if(!E.length){A.removeAttribute('style');}}return true;}});
// Roo/htmleditor/Tidy.js
-Roo.htmleditor.Tidy=function(A){Roo.apply(this,A);this.core.doc.body.innerHTML=this.tidy(this.core.doc.body,-1,false);};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,C){B=B||0;
-C=C||false;var D=C||B<1?'':(new Array(B)).join(" ");var j;var E=false;var F=A.nodeName;var G=A.tagName;if(F=='#text'){return C?A.nodeValue:this.wrap(A.nodeValue.trim()).split("\n").join("\n"+D);}var H='';if(F!='BODY'){var i=0;if(G){var I=[];for(i=0;i<A.attributes.length;
-i++){if(!A.attributes.item(i).value.length){continue;}I.push(A.attributes.item(i).name+'="'+Roo.util.Format.htmlEncode(A.attributes.item(i).value)+'"');}H="<"+A.tagName+(I.length?(' '+I.join(' ')):'');}else{}}else{G=false;}if(['IMG','BR','HR','INPUT'].indexOf(G)>-1){return H+'/>';
-}H+='>';if(['PRE','TEXTAREA','TD','A','SPAN'].indexOf(G)>-1){C=true;}i=0;var ar=Array.from(A.childNodes);var E=true;var J='';var K='';for(var i=0;i<ar.length;i++){var L=C;if(K=='SPAN'){L=true;}if(ar[i].nodeName=='#text'){var M=Roo.util.Format.htmlEncode(ar[i].nodeValue);
-J+=C?M:this.wrap(ar[i].nodeValue.trim()).split("\n").join("\n"+D+" ");lastNode='';continue;}E=false;J+=L?'':"\n"+D+" ";J+=this.tidy(ar[i],B+1,C);K=ar[i].nodeName;}H+=J;if(!E){H+=C?'':("\n"+D);}if(G){H+="</"+G+">";}return H;}}
+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+'/>';
+}C+='>';var D=B===false?'':(B+' ');if(['PRE','TEXTAREA','TD','A','SPAN','B','I','S'].indexOf(A.tagName)>-1){D=false;}var cn=this.cn(A,D);return C+cn+'</'+A.tagName+'>';},cn:function(A,B){var C=[];var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){if(B!==false&&i>0&&ar[i].nodeType==3&&ar[i].nodeValue.length>0&&ar[i].nodeValue.match(/^\s+/)){C.push(" ");
+}if(B!==false&&ar[i].nodeType==1){C.push("\n"+B);}C.push(this.tidy(ar[i],B));if(B!==false&&ar[i].nodeType==3&&ar[i].nodeValue.length>0&&ar[i].nodeValue.match(/\s+$/)){C.push("\n"+B);}}return C.join('');},attr:function(A){var B=[];for(i=0;i<A.attributes.length;
+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);
this.walk(cfg.node);
}
-Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.Filter,
+Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.FilterKeepChildren,
{
tag : 'SPAN',
replaceTag : function(node)
{
if (node.attributes && node.attributes.length > 0) {
- this.walk(node);
- return true;
- }
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
- // what if we need to walk these???
- node.insertBefore(node.childNodes[i], node);
- this.walk(node.childNodes[i]);
+ return true; // walk if there are any.
}
- n.parentNode.removeChild(n);
- return false; // don't walk children
+ Roo.htmleditor.FilterKeepChildren.prototype.replaceTag.call(this, node);
+ return false;
}
Roo.htmleditor.Tidy = function(cfg) {
Roo.apply(this, cfg);
- this.core.doc.body.innerHTML = this.tidy(this.core.doc.body, -1 , false);
+ this.core.doc.body.innerHTML = this.tidy(this.core.doc.body, '');
}
+
+Roo.htmleditor.Tidy.toString = function(node)
+{
+ return Roo.htmleditor.Tidy.prototype.tidy(node, '');
+}
+
Roo.htmleditor.Tidy.prototype = {
},
- /* ?? why ?? */
- tidy : function(currentElement, depth, nopadtext) {
-
- depth = depth || 0;
- nopadtext = nopadtext || false;
- var pad = nopadtext || depth < 1 ? '' : (new Array( depth )).join( " " );
+ tidy : function(node, indent) {
- //Roo.log(currentElement);
- var j;
- var allText = false;
- var nodeName = currentElement.nodeName;
- //var tagName = Roo.util.Format.htmlEncode(currentElement.tagName);
- var tagName = currentElement.tagName; /// why encode tagname?
+ if (node.nodeType == 3) {
+ // text.
+
+
+ return indent === false ? node.nodeValue : this.wrap(node.nodeValue.trim()).split("\n").join("\n" + indent);
+
+
+ }
- if (nodeName == '#text') {
- return nopadtext ? currentElement.nodeValue : this.wrap(currentElement.nodeValue.trim()).split("\n").join("\n" + pad);
+ if (node.nodeType != 1) {
+ return '';
}
- var ret = '';
- if (nodeName != 'BODY') {
-
- var i = 0;
- // Prints the node tagName, such as <A>, <IMG>, etc
- if (tagName) {
- var attr = [];
- for(i = 0; i < currentElement.attributes.length;i++) {
-
- // skip empty values?
- if (!currentElement.attributes.item(i).value.length) {
- continue;
- }
- attr.push(
- currentElement.attributes.item(i).name + '="' +
- Roo.util.Format.htmlEncode(currentElement.attributes.item(i).value) + '"'
- );
- }
-
- ret = "<"+currentElement.tagName+ ( attr.length ? (' ' + attr.join(' ') ) : '') ;
- }
- else {
- // dont add any attributes to body...
- // eack
- }
- } else {
- tagName = false;
+
+ if (node.tagName == 'BODY') {
+
+ return this.cn(node, '');
}
- if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(tagName) > -1) {
- return ret + '/>';
+
+ // Prints the node tagName, such as <A>, <IMG>, etc
+ var ret = "<" + node.tagName + this.attr(node) ;
+
+ // elements with no children..
+ if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(node.tagName) > -1) {
+ return ret + '/>';
}
ret += '>';
- if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN'].indexOf(tagName) > -1) { // or code?
- nopadtext = true;
+
+
+ var cindent = indent === false ? '' : (indent + ' ');
+ // tags where we will not pad the children.. (inline text tags etc..)
+ if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN', 'B', 'I', 'S'].indexOf(node.tagName) > -1) { // or code?
+ cindent = false;
+
+
}
+ var cn = this.cn(node, cindent );
- // Traverse the tree
- i = 0;
- var ar = Array.from(currentElement.childNodes);
- var allText = true;
- var innerHTML = '';
- var lastnode = '';
- for (var i = 0 ; i < ar.length ; i++) {
-
- // Formatting code (indent the tree so it looks nice on the screen)
- var nopad = nopadtext;
- if (lastnode == 'SPAN') {
- nopad = true;
+ return ret + cn + '</' + node.tagName + '>';
+
+ },
+ cn: function(node, indent)
+ {
+ var ret = [];
+
+ var ar = Array.from(node.childNodes);
+ for (var i = 0 ; i < ar.length ; i++) {
+ if (indent !== false // indent==false preservies everything
+ && i > 0
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/^\s+/)
+ ) {
+ ret.push(" "); // add a space if i'm a text item with a space at the front, as tidy will strip spaces.
}
- // text
- if (ar[i].nodeName == '#text') {
- var toadd = Roo.util.Format.htmlEncode(ar[i].nodeValue);
- innerHTML += nopadtext ? toadd : this.wrap(ar[i].nodeValue.trim()).split("\n").join("\n" + pad + " ");
- lastNode = '';
- continue;
+ if (indent !== false
+ && ar[i].nodeType == 1 // element - and indent is not set...
+ ) {
+ ret.push("\n" + indent);
}
- allText = false;
- innerHTML += nopad ? '' : "\n" + pad + " ";
-
- // Recursively traverse the tree structure of the child node
- innerHTML += this.tidy(ar[i], depth+1, nopadtext);
- lastnode = ar[i].nodeName;
-
- }
-
- ret += innerHTML;
-
- if (!allText) {
- // The remaining code is mostly for formatting the tree
- ret+= nopadtext ? '' : ("\n" + pad);
+ ret.push(this.tidy(ar[i], indent));
+ // text + trailing indent
+ if (indent !== false
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/\s+$/)
+ ){
+ ret.push("\n" + indent);
+ }
+
+
+
+
}
+ // what if all text?
- if (tagName) {
- ret+= "</"+tagName+">";
+ return ret.join('');
+ },
+
+
+
+ attr : function(node)
+ {
+ var attr = [];
+ for(i = 0; i < node.attributes.length;i++) {
+
+ // skip empty values?
+ if (!node.attributes.item(i).value.length) {
+ continue;
+ }
+ attr.push( node.attributes.item(i).name + '="' +
+ Roo.util.Format.htmlEncode(node.attributes.item(i).value) + '"'
+ );
}
- return ret;
+ return attr.length ? (' ' + attr.join(' ') ) : '';
}
+
+
+
}
/**
* @class Roo.htmleditor.KeyEnter
this.replaceComment(e);
return;
- case e.nodeType != 3: //not a node.
+ case e.nodeType != 1: //not a node.
return;
case this.tag === true: // everything
Roo.htmleditor.FilterAttributes = function(cfg)
{
Roo.apply(this, cfg);
+ this.attrib_black = this.attrib_black || [];
+ this.attrib_clean = this.attrib_clean || [];
+ this.style_white = this.style_white || [];
+ this.style_black = this.style_black || [];
this.walk(cfg.node);
}
});/**
- * Filter Clean
- *
- * Based on White / Blacklists etc...
- *
- *
- * usually call Roo.apply(Roo.htmleditor.FilterClean)
- *
- */
-
-/**
* @class Roo.htmleditor.FilterBlack
* remove blacklisted elements.
* @constructor
Roo.extend(Roo.htmleditor.FilterBlack, Roo.htmleditor.Filter,
{
tag : true, // all elements.
- /**
- * @cfg {array} black blacklist of elements
- */
- black : false, // array
-
-
+
replace : function(n)
{
n.parentNode.removeChild(n);
replaceTag : function(node)
{
// walk children...
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
+ var 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.insertBefore(node.childNodes[i], node);
- this.walk(node.childNodes[i]);
+ node.parentNode.insertBefore(ar[i], node);
+ this.walk(ar[i]);
}
node.parentNode.removeChild(node);
return false; // don't walk children
{
- tag : 'p',
+ tag : 'P',
replaceTag : function(node)
if (node.childNodes.length == 1 &&
node.childNodes[0].nodeType == 3 &&
- node.childNodes[0].nodeType.textContent.trim().length < 1
+ node.childNodes[0].textContent.trim().length < 1
) {
// remove and replace with '<BR>';
- node.parentNode.replaceChild(node.documentOwner.createElement('BR'),node);
+ node.parentNode.replaceChild(node.ownerDocument.createElement('BR'),node);
return false; // no need to walk..
}
-
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
+ var 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.insertBefore(node.childNodes[i], node);
+ node.parentNode.insertBefore(ar[i], node);
}
// now what about this?
// <p> </p>
// double BR.
- node.insertBefore(node.documentOwner.createElement('BR'), node);
+ node.parentNode.insertBefore(node.ownerDocument.createElement('BR'), node);
node.parentNode.removeChild(node);
return false;
this.walk(cfg.node);
}
-Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.Filter,
+Roo.extend(Roo.htmleditor.FilterSpan, Roo.htmleditor.FilterKeepChildren,
{
tag : 'SPAN',
replaceTag : function(node)
{
if (node.attributes && node.attributes.length > 0) {
- this.walk(node);
- return true;
+ return true; // walk if there are any.
}
- for (var i = 0; i < node.childNodes.length; i++) {
- node.removeChild(node.childNodes[i]);
- // what if we need to walk these???
- node.insertBefore(node.childNodes[i], node);
- this.walk(node.childNodes[i]);
- }
- n.parentNode.removeChild(n);
- return false; // don't walk children
+ Roo.htmleditor.FilterKeepChildren.prototype.replaceTag.call(this, node);
+ return false;
}
Roo.htmleditor.FilterTableWidth = function(cfg)
{
// no need to apply config.
- this.tag = ['table', 'td', 'tr', 'th', 'thead', 'tbody' ];
+ this.tag = ['TABLE', 'TD', 'TR', 'TH', 'THEAD', 'TBODY' ];
this.walk(cfg.node);
}
}
}
- this.walk(node);
+ return true; // continue doing children..
}
});/**
* @class Roo.htmleditor.FilterWord
}
-});//<script type="text/javascript">
+});
+/**
+ * @class Roo.htmleditor.Tidy
+ * Tidy HTML
+ * @cfg {Roo.HtmlEditorCore} core the editor.
+ * @constructor
+ * Create a new Filter.
+ * @param {Object} config Configuration options
+ */
+
+
+Roo.htmleditor.Tidy = function(cfg) {
+ Roo.apply(this, cfg);
+
+ this.core.doc.body.innerHTML = this.tidy(this.core.doc.body, '');
+
+}
+
+Roo.htmleditor.Tidy.toString = function(node)
+{
+ return Roo.htmleditor.Tidy.prototype.tidy(node, '');
+}
+
+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(node, indent) {
+
+ if (node.nodeType == 3) {
+ // text.
+
+
+ return indent === false ? node.nodeValue : this.wrap(node.nodeValue.trim()).split("\n").join("\n" + indent);
+
+
+ }
+
+ if (node.nodeType != 1) {
+ return '';
+ }
+
+
+
+ if (node.tagName == 'BODY') {
+
+ return this.cn(node, '');
+ }
+
+ // Prints the node tagName, such as <A>, <IMG>, etc
+ var ret = "<" + node.tagName + this.attr(node) ;
+
+ // elements with no children..
+ if (['IMG', 'BR', 'HR', 'INPUT'].indexOf(node.tagName) > -1) {
+ return ret + '/>';
+ }
+ ret += '>';
+
+
+ var cindent = indent === false ? '' : (indent + ' ');
+ // tags where we will not pad the children.. (inline text tags etc..)
+ if (['PRE', 'TEXTAREA', 'TD', 'A', 'SPAN', 'B', 'I', 'S'].indexOf(node.tagName) > -1) { // or code?
+ cindent = false;
+
+
+ }
+
+ var cn = this.cn(node, cindent );
+
+ return ret + cn + '</' + node.tagName + '>';
+
+ },
+ cn: function(node, indent)
+ {
+ var ret = [];
+
+ var ar = Array.from(node.childNodes);
+ for (var i = 0 ; i < ar.length ; i++) {
+ if (indent !== false // indent==false preservies everything
+ && i > 0
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/^\s+/)
+ ) {
+ ret.push(" "); // add a space if i'm a text item with a space at the front, as tidy will strip spaces.
+ }
+ if (indent !== false
+ && ar[i].nodeType == 1 // element - and indent is not set...
+ ) {
+ ret.push("\n" + indent);
+ }
+
+ ret.push(this.tidy(ar[i], indent));
+ // text + trailing indent
+ if (indent !== false
+ && ar[i].nodeType == 3
+ && ar[i].nodeValue.length > 0
+ && ar[i].nodeValue.match(/\s+$/)
+ ){
+ ret.push("\n" + indent);
+ }
+
+
+
+
+ }
+ // what if all text?
+
+
+ return ret.join('');
+ },
+
+
+
+ attr : function(node)
+ {
+ var attr = [];
+ for(i = 0; i < node.attributes.length;i++) {
+
+ // skip empty values?
+ if (!node.attributes.item(i).value.length) {
+ continue;
+ }
+ attr.push( node.attributes.item(i).name + '="' +
+ Roo.util.Format.htmlEncode(node.attributes.item(i).value) + '"'
+ );
+ }
+ return attr.length ? (' ' + attr.join(' ') ) : '';
+
+ }
+
+
+
+}
+/**
+ * @class Roo.htmleditor.KeyEnter
+ * Handle Enter press..
+ * @cfg {Roo.HtmlEditorCore} core the editor.
+ * @constructor
+ * Create a new Filter.
+ * @param {Object} config Configuration options
+ */
+
+
+
+Roo.htmleditor.KeyEnter = function(cfg) {
+ Roo.apply(this, cfg);
+ // this does not actually call walk as it's really just a abstract class
+
+ 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();
+ // https://stackoverflow.com/questions/18552336/prevent-contenteditable-adding-div-on-enter-chrome
+ var doc = this.core.doc;
+
+ var docFragment = doc.createDocumentFragment();
+
+ //add a new line
+ var newEle = doc.createTextNode('\n');
+ docFragment.appendChild(newEle);
+
+ //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
+ range = doc.createRange();
+ range.setStartAfter(newEle);
+ range.collapse(true);
+
+ //make the cursor there
+ var sel = this.core.win.getSelection();
+ sel.removeAllRanges();
+ sel.addRange(range);
+
+ return false;
+
+ }
+};
+ //<script type="text/javascript">
/*
* Based Ext JS Library 1.1.1
}
this.initialized = true;
+
+ // initialize special key events - enter
+ new Roo.htmleditor.KeyEnter({core : this});
+
+
+
+
this.owner.fireEvent('initialize', this);
this.pushValue();
},
style_white : this.cwhite,
style_black : this.cblack
});
- new Roo.htmleditor.FilterBlack({ node : node, black : this.black});
- new Roo.htmleditor.FilterKeepChildren({node : node, black : this.remove} );
+ new Roo.htmleditor.FilterBlack({ node : node, tag : this.black});
+ new Roo.htmleditor.FilterKeepChildren({node : node, tag : this.tag_remove} );
},
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(tag) {
Roo.HtmlEditorCore.clean = [
'script', 'style', 'title', 'xml'
];
-Roo.HtmlEditorCore.remove = [
+Roo.HtmlEditorCore.tag_remove = [
'font'
];
// attributes..
tabIndex:-1
});
}
- cmenu.menu.items.push({
+ cmenu.menu.items.push({
actiontype : 'tablewidths',
html: 'Remove Table Widths',
handler: function(a,b) {
Roo.htmleditor={};
// Roo/htmleditor/Filter.js
Roo.htmleditor.Filter=function(A){Roo.apply(this.cfg);};Roo.htmleditor.Filter.prototype={node:false,tag:false,replaceComment:false,replaceTag:false,walk:function(A){Roo.each(Array.from(A.childNodes),function(e){switch(true){case e.nodeType==8&&typeof(this.replaceComment)!='undefined':this.replaceComment(e);
-return;case e.nodeType!=3:return;case this.tag===true:case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;}if(e.hasChildNodes()){this.walk(e);
+return;case e.nodeType!=1:return;case this.tag===true:case typeof(this.tag)=='object'&&this.tag.indexOf(e.tagName)>-1:case typeof(this.tag)=='string'&&this.tag==e.tagName:if(this.replaceTag&&false===this.replaceTag(e)){return;}if(e.hasChildNodes()){this.walk(e);
}return;default:if(e.hasChildNodes()){this.walk(e);}}},this);}};
// Roo/htmleditor/FilterAttributes.js
-Roo.htmleditor.FilterAttributes=function(A){Roo.apply(this,A);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterAttributes,Roo.htmleditor.Filter,{tag:true,attrib_black:false,attrib_clean:false,style_white:false,style_black:false,replaceTag:function(A){if(!A.attributes||!A.attributes.length){return true;
+Roo.htmleditor.FilterAttributes=function(A){Roo.apply(this,A);this.attrib_black=this.attrib_black||[];this.attrib_clean=this.attrib_clean||[];this.style_white=this.style_white||[];this.style_black=this.style_black||[];this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterAttributes,Roo.htmleditor.Filter,{tag:true,attrib_black:false,attrib_clean:false,style_white:false,style_black:false,replaceTag:function(A){if(!A.attributes||!A.attributes.length){return true;
}for(var i=A.attributes.length-1;i>-1;i--){var a=A.attributes[i];if(a.name.toLowerCase().substr(0,2)=='on'){A.removeAttribute(a.name);continue;}if(this.attrib_black.indexOf(a.name.toLowerCase())>-1){A.removeAttribute(a.name);continue;}if(this.attrib_clean.indexOf(a.name.toLowerCase())>-1){this.cleanAttr(A,a.name,a.value);
continue;}if(a.name=='style'){this.cleanStyle(A,a.name,a.value);continue;}if(a.name=='class'){if(a.value.match(/^Mso/)){A.removeAttribute('class');}if(a.value.match(/^body$/)){A.removeAttribute('class');}continue;}}return true;},cleanAttr:function(A,n,v){if(v.match(/^\./)||v.match(/^\//)){return;
}if(v.match(/^(http|https):\/\//)||v.match(/^mailto:/)||v.match(/^ftp:/)){return;}if(v.match(/^#/)){return;}if(v.match(/^\{/)){return;}A.removeAttribute(n);},cleanStyle:function(A,n,v){if(v.match(/expression/)){A.removeAttribute(n);return;}var B=v.split(/;/);
var C=[];Roo.each(B,function(p){p=p.replace(/^\s+/g,'').replace(/\s+$/g,'');if(!p.length){return true;}var l=p.split(':').shift().replace(/\s+/g,'');l=l.replace(/^\s+/g,'').replace(/\s+$/g,'');if(this.style_black.length&&(this.style_black.indexOf(l)>-1||this.style_black.indexOf(l.toLowerCase())>-1)){return true;
}if(this.style_white.length&&style_white.indexOf(l)<0&&style_white.indexOf(l.toLowerCase())<0){return true;}C.push(p);return true;},this);if(C.length){A.setAttribute(n,C.join(';'));}else{A.removeAttribute(n);}}});
// Roo/htmleditor/FilterBlack.js
-Roo.htmleditor.FilterBlack=function(A){Roo.apply(this,A);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterBlack,Roo.htmleditor.Filter,{tag:true,black:false,replace:function(n){n.parentNode.removeChild(n);}});
+Roo.htmleditor.FilterBlack=function(A){Roo.apply(this,A);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterBlack,Roo.htmleditor.Filter,{tag:true,replace:function(n){n.parentNode.removeChild(n);}});
// 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);this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterKeepChildren,Roo.htmleditor.FilterBlack,{replaceTag:function(A){for(var i=0;i<A.childNodes.length;i++){A.removeChild(A.childNodes[i]);A.insertBefore(A.childNodes[i],A);
-this.walk(A.childNodes[i]);}A.parentNode.removeChild(A);return false;}});
+Roo.htmleditor.FilterKeepChildren=function(A){Roo.apply(this,A);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);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].nodeType.textContent.trim().length<1){A.parentNode.replaceChild(A.documentOwner.createElement('BR'),A);
-return false;}for(var i=0;i<A.childNodes.length;i++){A.removeChild(A.childNodes[i]);A.insertBefore(A.childNodes[i],A);}A.insertBefore(A.documentOwner.createElement('BR'),A);A.parentNode.removeChild(A);return false;}});
+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;}});
// Roo/htmleditor/FilterSpan.js
-Roo.htmleditor.FilterSpan=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterSpan,Roo.htmleditor.Filter,{tag:'SPAN',replaceTag:function(A){if(A.attributes&&A.attributes.length>0){this.walk(A);return true;}for(var i=0;i<A.childNodes.length;i++){A.removeChild(A.childNodes[i]);
-A.insertBefore(A.childNodes[i],A);this.walk(A.childNodes[i]);}n.parentNode.removeChild(n);return false;}});
+Roo.htmleditor.FilterSpan=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterSpan,Roo.htmleditor.FilterKeepChildren,{tag:'SPAN',replaceTag:function(A){if(A.attributes&&A.attributes.length>0){return true;}Roo.htmleditor.FilterKeepChildren.prototype.replaceTag.call(this,A);
+return false;}});
// Roo/htmleditor/FilterTableWidth.js
-Roo.htmleditor.FilterTableWidth=function(A){this.tag=['table','td','tr','th','thead','tbody'];this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterTableWidth,Roo.htmleditor.Filter,{replaceTag:function(A){if(A.hasAttribute('width')){A.removeAttribute('width');
+Roo.htmleditor.FilterTableWidth=function(A){this.tag=['TABLE','TD','TR','TH','THEAD','TBODY'];this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterTableWidth,Roo.htmleditor.Filter,{replaceTag:function(A){if(A.hasAttribute('width')){A.removeAttribute('width');
}if(A.hasAttribute("style")){var B=A.getAttribute("style").split(";");var C=[];Roo.each(B,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");if(kv[0].match(/^\s*(width|min-width)\s*$/)){return;}C.push(s);});A.setAttribute("style",C.length?C.join(';'):'');
-if(!C.length){A.removeAttribute('style');}}this.walk(A);}});
+if(!C.length){A.removeAttribute('style');}}return true;}});
// Roo/htmleditor/FilterWord.js
Roo.htmleditor.FilterWord=function(A){this.walk(A.node);};Roo.extend(Roo.htmleditor.FilterWord,Roo.htmleditor.Filter,{tag:true,replaceTag:function(A){if(A.nodeName=='SPAN'&&!A.hasAttributes()&&A.childNodes.length==1&&A.firstChild.nodeName=="#text"){var B=A.firstChild;
A.removeChild(B);if(A.getAttribute('lang')!='zh-CN'){A.parentNode.insertBefore(A.ownerDocument.createTextNode(" "),A);}A.parentNode.insertBefore(B,A);if(A.getAttribute('lang')!='zh-CN'){A.parentNode.insertBefore(A.ownerDocument.createTextNode(" "),A);}A.parentNode.removeChild(A);
A.removeChild(cn);A.parentNode.insertBefore(cn,A);this.replaceTag(cn);}A.parentNode.removeChild(A);return false;}if(A.className.length){var cn=A.className.split(/\W+/);var C=[];Roo.each(cn,function(F){if(F.match(/Mso[a-zA-Z]+/)){return;}C.push(F);});A.className=C.length?C.join(' '):'';
if(!C.length){A.removeAttribute("class");}}if(A.hasAttribute("lang")){A.removeAttribute("lang");}if(A.hasAttribute("style")){var D=A.getAttribute("style").split(";");var E=[];Roo.each(D,function(s){if(!s.match(/:/)){return;}var kv=s.split(":");if(kv[0].match(/^(mso-|line|font|background|margin|padding|color)/)){return;
}E.push(s);});A.setAttribute("style",E.length?E.join(';'):'');if(!E.length){A.removeAttribute('style');}}return true;}});
+// 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+'/>';
+}C+='>';var D=B===false?'':(B+' ');if(['PRE','TEXTAREA','TD','A','SPAN','B','I','S'].indexOf(A.tagName)>-1){D=false;}var cn=this.cn(A,D);return C+cn+'</'+A.tagName+'>';},cn:function(A,B){var C=[];var ar=Array.from(A.childNodes);for(var i=0;i<ar.length;i++){if(B!==false&&i>0&&ar[i].nodeType==3&&ar[i].nodeValue.length>0&&ar[i].nodeValue.match(/^\s+/)){C.push(" ");
+}if(B!==false&&ar[i].nodeType==1){C.push("\n"+B);}C.push(this.tidy(ar[i],B));if(B!==false&&ar[i].nodeType==3&&ar[i].nodeValue.length>0&&ar[i].nodeValue.match(/\s+$/)){C.push("\n"+B);}}return C.join('');},attr:function(A){var B=[];for(i=0;i<A.attributes.length;
+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;}};
// Roo/HtmlEditorCore.js
Roo.HtmlEditorCore=function(A){Roo.HtmlEditorCore.superclass.constructor.call(this,A);this.addEvents({initialize:true,activate:true,beforesync:true,beforepush:true,sync:true,push:true,editorevent:true});this.applyBlacklists();};Roo.extend(Roo.HtmlEditorCore,Roo.Component,{owner:false,resizable:false,height:300,width:500,stylesheets:false,allowComments:false,frameId:false,validationEvent:false,deferHeight:true,initialized:false,activated:false,sourceEditMode:false,onFocus:Roo.emptyFn,iframePad:3,hideMode:'offsets',clearUp:true,black:false,white:false,bodyCls:'',getDocMarkup:function(){var st='';
if(this.stylesheets===false){Roo.get(document.head).select('style').each(function(B){st+=B.dom.outerHTML||new XMLSerializer().serializeToString(B.dom);});Roo.get(document.head).select('link').each(function(B){st+=B.dom.outerHTML||new XMLSerializer().serializeToString(B.dom);
d.innerHTML=v;this.cleanUpPaste();this.el.dom.value=d.innerHTML;this.owner.fireEvent('push',this,v);}}},deferFocus:function(){this.focus.defer(10,this);},focus:function(){if(this.win&&!this.sourceEditMode){this.win.focus();}else{this.el.focus();}},assignDocWin:function(){var A=this.iframe;
if(Roo.isIE){this.doc=A.contentWindow.document;this.win=A.contentWindow;}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}
-);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;this.owner.fireEvent('initialize',this);this.pushValue();
-},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));
+);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();},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());
},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;},cleanUpPaste:function(){Roo.log('cleanuppaste');this.cleanUpChild(this.doc.body);var A=this.cleanWordChars(this.doc.body.innerHTML);if(A!=this.doc.body.innerHTML){this.doc.body.innerHTML=A;
}},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,black:this.black});new Roo.htmleditor.FilterKeepChildren({node:A,black:this.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}
+);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}
);},domToHTML:function(A,B,C){B=B||0;C=C||false;if(!A){return this.domToHTML(this.doc.body);}var j;var D=false;var E=A.nodeName;var F=Roo.util.Format.htmlEncode(A.tagName);if(E=='#text'){return C?A.nodeValue:A.nodeValue.trim();}var G='';if(E!='BODY'){var i=0;
if(F){var H=[];for(i=0;i<A.attributes.length;i++){var I=A.attributes.item(i).name;if(!A.attributes.item(i).value.length){continue;}H.push(I+'="'+Roo.util.Format.htmlEncode(A.attributes.item(i).value)+'"');}G="<"+A.tagName+(H.length?(' '+H.join(' ')):'')+">";
}else{}}else{F=false;}if(['IMG','BR','HR','INPUT'].indexOf(F)>-1){return G;}if(['PRE','TEXTAREA','TD','A','SPAN'].indexOf(F)>-1){C=true;}i=0;var J=A.childNodes.item(i);var D=true;var K='';lastnode='';while(J){var L=C;if(lastnode=='SPAN'){L=true;}if(J.nodeName=='#text'){var M=Roo.util.Format.htmlEncode(J.nodeValue);
M=C?M:M.trim();if(!L&&M.length>80){K+="\n"+(new Array(B+1)).join(" ");}K+=M;i++;J=A.childNodes.item(i);lastNode='';continue;}D=false;K+=L?'':"\n"+(new Array(B+1)).join(" ");K+=this.domToHTML(J,B+1,C);lastnode=J.nodeName;i++;J=A.childNodes.item(i);}G+=K;
if(!D){G+=C?'':"\n"+(new Array(B)).join(" ");}if(F){G+="</"+F+">";}return G;},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;}if(this.black.indexOf(A)>-1){return;}this.black.push(A);},this);w=typeof(this.owner.cwhite)!='undefined'&&this.owner.cwhite?this.owner.cwhite:[];b=typeof(this.owner.cblack)!='undefined'&&this.owner.cblack?this.owner.cblack:[];
this.cwhite=[];this.cblack=[];Roo.each(Roo.HtmlEditorCore.cwhite,function(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.remove=['font'];
+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,"–"],[8212,"—"],[8216,"'"],[8217,"'"],[8220,'"'],[8221,'"'],[8226,"*"],[8230,"..."]];
// Roo/form/HtmlEditor.js