* @cfg {Number} width (in pixels)
*/
width: 500,
+
+ /**
+ * @cfg {Array} stylesheets url of stylesheets. set to [] to disable stylesheets.
+ *
+ */
+ stylesheets: false,
+
// id of frame..
frameId: false,
* want to change the initialization markup of the iframe (e.g. to add stylesheets).
*/
getDocMarkup : function(){
- return '<html><head><style type="text/css">body{border:0;margin:0;padding:3px;height:98%;cursor:text;}</style></head><body></body></html>';
+ // body styles..
+ var st = '';
+ if (this.stylesheets === false) {
+
+ Roo.get(document.head).select('style').each(function(node) {
+ st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+ });
+
+ Roo.get(document.head).select('link').each(function(node) {
+ st += node.dom.outerHTML || new XMLSerializer().serializeToString(node.dom);
+ });
+
+ } else if (!this.stylesheets.length) {
+ // simple..
+ st = '<style type="text/css">' +
+ 'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+ '</style>';
+ } else {
+ Roo.each(this.stylesheets, function(s) {
+ st += '<link rel="stylesheet" type="text/css" href="' + s +'" />'
+ });
+
+ }
+
+ return '<html><head>' + st +
+ //<style type="text/css">' +
+ //'body{border:0;margin:0;padding:3px;height:98%;cursor:text;}' +
+ //'</style>' +
+ ' </head><body></body></html>';
},
// private
syncValue : function(){
if(this.initialized){
var bd = (this.doc.body || this.doc.documentElement);
- this.cleanUpPaste();
+ //this.cleanUpPaste();
var html = bd.innerHTML;
if(Roo.isSafari){
var bs = bd.getAttribute('style'); // Safari puts text-align styles on the body element!
onEditorEvent : function(e){
this.fireEvent('editorevent', this, e);
// this.updateToolbar();
- this.syncValue();
+ this.syncValue(); //we can not sync so often.. sync cleans, so this breaks stuff
},
insertTag : function(tg)
break;
case 'u':
cmd = 'underline';
+ break;
case 'v':
this.cleanUpPaste.defer(100, this);
return;
- var range = this.createRange(this.getSelection());
+ var range = this.createRange(this.getSelection()).cloneRange();
if (Roo.isIE) {
var parent = range.parentElement();
return parent;
}
+ // is ancestor a text element.
+ var ac = range.commonAncestorContainer;
+ if (ac.nodeType == 3) {
+ ac = ac.parentNode;
+ }
- var ar = range.commonAncestorContainer.childNodes;
+ var ar = ac.childNodes;
var nodes = [];
var other_nodes = [];
other_nodes.push(ar[i]);
continue;
}
+ // outer..
if (!this.rangeIntersectsNode(range,ar[i])|| (this.rangeCompareNode(range,ar[i]) == 0)) {
continue;
}
**/
- // BC Hacks - cause I cant work out what i was trying to do..
+ // @see http://www.thismuchiknow.co.uk/?p=64.
rangeIntersectsNode : function(range, node)
{
- var nodeRange = this.createRange(node);
+ var nodeRange = node.ownerDocument.createRange();
try {
nodeRange.selectNode(node);
- }
- catch (e) {
+ } catch (e) {
nodeRange.selectNodeContents(node);
}
- // [ -- selected range --- ]
- // [node]
- // node start inside?
-
- var es = range.compareBoundaryPoints(Range.END_TO_START, nodeRange) ;
- var se = range.compareBoundaryPoints(Range.START_TO_END, nodeRange) ;
- // good = es=-1, se = 1
- return es = -1 & se =1 ;
+
+ var rangeStartRange = range.cloneRange();
+ rangeStartRange.collapse(true);
+
+ var rangeEndRange = range.cloneRange();
+ rangeEndRange.collapse(false);
+
+ var nodeStartRange = nodeRange.cloneRange();
+ nodeStartRange.collapse(true);
+
+ var nodeEndRange = nodeRange.cloneRange();
+ nodeEndRange.collapse(false);
+
+ return rangeStartRange.compareBoundaryPoints(
+ Range.START_TO_START, nodeEndRange) == -1 &&
+ rangeEndRange.compareBoundaryPoints(
+ Range.START_TO_START, nodeStartRange) == 1;
},
} catch (e) {
nodeRange.selectNodeContents(node);
}
- var nodeIsBefore = range.compareBoundaryPoints(Range.START_TO_START, nodeRange) == 1;
- var nodeIsAfter = range.compareBoundaryPoints(Range.END_TO_END, nodeRange) == -1;
-
- if (nodeIsBefore && !nodeIsAfter)
- return 0;
- if (!nodeIsBefore && nodeIsAfter)
- return 1;
+
+
+ range.collapse(true);
+
+ nodeRange.collapse(true);
+
+ var ss = range.compareBoundaryPoints( Range.START_TO_START, nodeRange);
+ var ee = range.compareBoundaryPoints( Range.END_TO_END, nodeRange);
+
+ //Roo.log(node.tagName + ': ss='+ss +', ee='+ee)
+
+ var nodeIsBefore = ss == 1;
+ var nodeIsAfter = ee == -1;
+
if (nodeIsBefore && nodeIsAfter)
- return 2;
-
+ return 0; // outer
+ if (!nodeIsBefore && nodeIsAfter)
+ return 1; //right trailed.
+
+ if (nodeIsBefore && !nodeIsAfter)
+ return 2; // left trailed.
+ // fully contined.
return 3;
},
cleanUpPaste : function()
{
// cleans up the whole document..
- // console.log('cleanuppaste');
+ Roo.log('cleanuppaste');
this.cleanUpChildren(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.form.HtmlEditor;
+
+ var output = input;
+ Roo.each(he.swapCodes, function(sw) {
+ var swapper = new RegExp("\\u" + sw[0].toString(16), "g"); // hex codes
+ output = output.replace(swapper, sw[1]);
+ });
+ return output;
},
+
+
cleanUpChildren : function (n)
{
if (!n.childNodes.length) {
return;
}
- if (Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1) {
+
+ var remove_keep_children= Roo.form.HtmlEditor.remove.indexOf(node.tagName.toLowerCase()) > -1;
+
+ // remove <a name=....> as rendering on yahoo mailer is bored with this.
+
+ if (node.tagName.toLowerCase() == 'a' && !node.hasAttribute('href')) {
+ remove_keep_children = true;
+ }
+
+ if (remove_keep_children) {
this.cleanUpChildren(node);
// inserts everything just before this node...
while (node.childNodes.length) {
}
var l = p.split(':').shift().replace(/\s+/g,'');
+ // only allow 'c whitelisted system attributes'
if (Roo.form.HtmlEditor.cwhite.indexOf(l) < 0) {
Roo.log('(REMOVE)' + node.tagName +'.' + n + ':'+l + '=' + v);
node.removeAttribute(n);
cleanStyle(a.name,a.value);
}
/// clean up MS crap..
+ // tecnically this should be a list of valid class'es..
+
+
if (a.name == 'class') {
if (a.value.match(/^Mso/)) {
node.className = '';
}
+
+ if (a.value.match(/body/)) {
+ node.className = '';
+ }
}
// style cleanup!?
'http', 'https', 'mailto'
];
+// white listed style attributes.
Roo.form.HtmlEditor.cwhite= [
'text-align',
'font-size'
];
+
+Roo.form.HtmlEditor.swapCodes =[
+ [ 8211, "--" ],
+ [ 8212, "--" ],
+ [ 8216, "'" ],
+ [ 8217, "'" ],
+ [ 8220, '"' ],
+ [ 8221, '"' ],
+ [ 8226, "*" ],
+ [ 8230, "..." ]
+];
+
+
\ No newline at end of file