In contenteditable
regions, if you paste an element with a URL attribute, in some browsers it converts the URL from relative to absolute.
I've read through some bug reports that claim it's "fixed" in the latest release, but it's not.
I threw together this fiddle to demonstrate: Hurray for Demos!
It's there, it's ugly, and I'm wondering what is the best way to fix it.
The 1st idea that comes to mind is onpaste
, find all anchors
in the current node and parse it with regex
. Not ideal I suppose, but it might be effective.
???
???
I really wish they'd just leave things alone and not create so many browser related issues with contenteditable
, but I guess that would make it too easy.
Any thoughts on the best way to address this?
CKEditor, before letting browser break the data, copies all src
, name
and href
attributes to data-cke-saved-src|href
attributes. Unfortunately, since data is a string, it has to be done by regexp. You can find the code here: /core/htmldataprocessor.js#L772-L783.
var protectElementRegex = /<(a|area|img|input|source)\b([^>]*)>/gi,
// Be greedy while looking for protected attributes. This will let us avoid an unfortunate
// situation when "nested attributes", which may appear valid, are also protected.
// I.e. if we consider the following HTML:
//
// <img data-x="<a href="X"" />
//
// then the "non-greedy match" returns:
//
// 'href' => '"X"' // It's wrong! Href is not an attribute of <img>.
//
// while greedy match returns:
//
// 'data-x' => '<a href="X"'
//
// which, can be easily filtered out (#11508).
protectAttributeRegex = /([\w-]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,
protectAttributeNameRegex = /^(href|src|name)$/i;
function protectAttributes( html ) {
return html.replace( protectElementRegex, function( element, tag, attributes ) {
return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) {
// Avoid corrupting the inline event attributes (#7243).
// We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218)
if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 )
return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr;
return fullAttr;
} ) + '>';
} );
}
Then, while processing HTML taken from editable element, data-cke-saved-*
attributes override the original ones.