/**
- * @license Copyright (c) 2003-2016, CKSource - Frederico Knabben. All rights reserved.
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
* For licensing, see LICENSE.md or http://ckeditor.com/license
*/
// it up and apply the filter.
data = protectSource( data, editor );
- // Protect content of textareas. (#9995)
+ // Protect content of textareas. (http://dev.ckeditor.com/ticket/9995)
// Do this before protecting attributes to avoid breaking:
// <textarea><img src="..." /></textarea>
data = protectElements( data, protectTextareaRegex );
data = protectAttributes( data );
// Protect elements than can't be set inside a DIV. E.g. IE removes
- // style tags from innerHTML. (#3710)
+ // style tags from innerHTML. (http://dev.ckeditor.com/ticket/3710)
data = protectElements( data, protectElementsRegex );
// Certain elements has problem to go through DOM operation, protect
- // them by prefixing 'cke' namespace. (#3591)
+ // them by prefixing 'cke' namespace. (http://dev.ckeditor.com/ticket/3591)
data = protectElementsNames( data );
// All none-IE browsers ignore self-closed custom elements,
- // protecting them into open-close. (#3591)
+ // protecting them into open-close. (http://dev.ckeditor.com/ticket/3591)
data = protectSelfClosingElements( data );
// Compensate one leading line break after <pre> open as browsers
- // eat it up. (#5789)
+ // eat it up. (http://dev.ckeditor.com/ticket/5789)
data = protectPreFormatted( data );
// There are attributes which may execute JavaScript code inside fixBin.
- // Encode them greedily. They will be unprotected right after getting HTML from fixBin. (#10)
+ // Encode them greedily. They will be unprotected right after getting HTML from fixBin. (http://dev.ckeditor.com/ticket/10)
data = protectInsecureAttributes( data );
var fixBin = evtData.context || editor.editable().getName(),
// Call the browser to help us fixing a possibly invalid HTML
// structure.
var el = editor.document.createElement( fixBin );
- // Add fake character to workaround IE comments bug. (#3801)
+ // Add fake character to workaround IE comments bug. (http://dev.ckeditor.com/ticket/3801)
el.setHtml( 'a' + data );
data = el.getHtml().substr( 1 );
data = CKEDITOR.htmlParser.fragment.fromHtml( data, evtData.context, fixBodyTag );
// The empty root element needs to be fixed by adding 'p' or 'div' into it.
- // This avoids the need to create that element on the first focus (#12630).
+ // This avoids the need to create that element on the first focus (http://dev.ckeditor.com/ticket/12630).
if ( fixBodyTag ) {
fixEmptyRoot( data, fixBodyTag );
}
editor.on( 'toDataFormat', function( evt ) {
var data = evt.data.dataValue;
- // #10854 - we need to strip leading blockless <br> which FF adds
+ // http://dev.ckeditor.com/ticket/10854 - we need to strip leading blockless <br> which FF adds
// automatically when editable contains only non-editable content.
// We do that for every browser (so it's a constant behavior) and
// not in BR mode, in which chance of valid leading blockless <br> is higher.
data.writeChildrenHtml( writer );
data = writer.getHtml( true );
- // Restore those non-HTML protected source. (#4475,#4880)
+ // Restore those non-HTML protected source. (http://dev.ckeditor.com/ticket/4475,http://dev.ckeditor.com/ticket/4880)
data = unprotectRealComments( data );
data = unprotectSource( data, editor );
return false;
// 1. For IE version >=8, empty blocks are displayed correctly themself in wysiwiyg;
- // 2. For the rest, at least table cell and list item need no filler space. (#6248)
+ // 2. For the rest, at least table cell and list item need no filler space. (http://dev.ckeditor.com/ticket/6248)
if ( !isOutput && !CKEDITOR.env.needsBrFiller &&
( document.documentMode > 7 ||
block.name in CKEDITOR.dtd.tr ||
}
// Regex to scan for at the end of blocks, which are actually placeholders.
- // Safari transforms the to \xa0. (#4172)
+ // Safari transforms the to \xa0. (http://dev.ckeditor.com/ticket/4172)
var tailNbspRegex = /(?: |\xa0)$/;
var protectedSourceMarker = '{cke_protected}';
// active in the editing area (IE|WebKit).
[ ( /^on/ ), 'data-cke-pa-on' ],
+ // Prevent iframe's srcdoc attribute from being evaluated in the editable.
+ [ ( /^srcdoc/ ), 'data-cke-pa-srcdoc' ],
+
// Don't let some old expando enter editor. Concerns only IE8,
// but for consistency remove on all browsers.
[ ( /^data-cke-expando$/ ), '' ]
- ]
+ ],
+
+ elements: {
+ // Prevent iframe's src attribute with javascript code or data protocol from being evaluated in the editable.
+ iframe: function( element ) {
+ if ( element.attributes && element.attributes.src ) {
+
+ var src = element.attributes.src.toLowerCase().replace( /[^a-z]/gi, '' );
+ if ( src.indexOf( 'javascript' ) === 0 || src.indexOf( 'data' ) === 0 ) {
+ element.attributes[ 'data-cke-pa-src' ] = element.attributes.src;
+ delete element.attributes.src;
+ }
+ }
+ }
+ }
};
- // Disable form elements editing mode provided by some browsers. (#5746)
+ // Disable form elements editing mode provided by some browsers. (http://dev.ckeditor.com/ticket/5746)
function protectReadOnly( element ) {
var attrs = element.attributes;
// We should flag that the element was locked by our code so
- // it'll be editable by the editor functions (#6046).
+ // it'll be editable by the editor functions (http://dev.ckeditor.com/ticket/6046).
if ( attrs.contenteditable != 'false' )
attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1;
}
},
- // Remove empty link but not empty anchor. (#3829, #13516)
+ // Remove empty link but not empty anchor. (http://dev.ckeditor.com/ticket/3829, http://dev.ckeditor.com/ticket/13516)
a: function( element ) {
var attrs = element.attributes;
if ( attribs[ 'data-cke-temp' ] )
return false;
- // Remove duplicated attributes - #3789.
+ // Remove duplicated attributes - http://dev.ckeditor.com/ticket/3789.
var attributeNames = [ 'name', 'href', 'src' ],
savedAttributeName;
for ( var i = 0; i < attributeNames.length; i++ ) {
return element;
},
- // The contents of table should be in correct order (#4809).
+ // The contents of table should be in correct order (http://dev.ckeditor.com/ticket/4809).
table: function( element ) {
// Clone the array as it would become empty during the sort call.
var children = element.children.slice( 0 );
title: function( element ) {
var titleText = element.children[ 0 ];
- // Append text-node to title tag if not present (i.e. non-IEs) (#9882).
+ // Append text-node to title tag if not present (i.e. non-IEs) (http://dev.ckeditor.com/ticket/9882).
!titleText && append( element, titleText = new CKEDITOR.htmlParser.text() );
// Transfer data-saved title to title tag.
if ( CKEDITOR.env.ie ) {
// IE outputs style attribute in capital letters. We should convert
- // them back to lower case, while not hurting the values (#5930)
+ // them back to lower case, while not hurting the values (http://dev.ckeditor.com/ticket/5930)
defaultHtmlFilterRulesForAll.attributes.style = function( value ) {
return value.replace( /(^|;)([^\:]+)/g, function( match ) {
return match.toLowerCase();
};
}
- // Disable form elements editing mode provided by some browsers. (#5746)
+ // Disable form elements editing mode provided by some browsers. (http://dev.ckeditor.com/ticket/5746)
function unprotectReadyOnly( element ) {
var attrs = element.attributes;
switch ( attrs[ 'data-cke-editable' ] ) {
//
// 'data-x' => '<a href="X"'
//
- // which, can be easily filtered out (#11508).
+ // which, can be easily filtered out (http://dev.ckeditor.com/ticket/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)
+ // Avoid corrupting the inline event attributes (http://dev.ckeditor.com/ticket/7243).
+ // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (http://dev.ckeditor.com/ticket/5218)
if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 )
return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr;
// <noscript> tags (get lost in IE and messed up in FF).
/<noscript[\s\S]*?<\/noscript>/gi,
- // Avoid meta tags being stripped (#8117).
+ // Avoid meta tags being stripped (http://dev.ckeditor.com/ticket/8117).
/<meta[\s\S]*?\/?>/gi
].concat( protectRegexes );
for ( var i = 0; i < regexes.length; i++ ) {
data = data.replace( regexes[ i ], function( match ) {
- match = match.replace( tempRegex, // There could be protected source inside another one. (#3869).
+ match = match.replace( tempRegex, // There could be protected source inside another one. (http://dev.ckeditor.com/ticket/3869).
function( $, isComment, id ) {
return protectedHtml[ id ];
} );
// Different protection pattern is used for those that
// live in attributes to avoid from being HTML encoded.
- // Why so serious? See #9205, #8216, #7805, #11754, #11846.
+ // Why so serious? See http://dev.ckeditor.com/ticket/9205, http://dev.ckeditor.com/ticket/8216, http://dev.ckeditor.com/ticket/7805, http://dev.ckeditor.com/ticket/11754, http://dev.ckeditor.com/ticket/11846.
data = data.replace( /<\w+(?:\s+(?:(?:[^\s=>]+\s*=\s*(?:[^'"\s>]+|'[^']*'|"[^"]*"))|[^\s=\/>]+))+\s*\/?>/g, function( match ) {
return match.replace( /<!--\{cke_protected\}([^>]*)-->/g, function( match, data ) {
store[ store.id ] = decodeURIComponent( data );
// This RegExp searches for innerText in all the title/iframe/textarea elements.
// This is because browser doesn't allow HTML in these elements, that's why we can't
- // nest comments in there. (#11223)
+ // nest comments in there. (http://dev.ckeditor.com/ticket/11223)
data = data.replace( /<(title|iframe|textarea)([^>]*)>([\s\S]*?)<\/\1>/g, function( match, tagName, tagAttributes, innerText ) {
return '<' + tagName + tagAttributes + '>' + unprotectSource( unprotectRealComments( innerText ), editor ) + '</' + tagName + '>';
} );
* {@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
* * 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#dataFilter}
* is not applied yet.
- * * 6: Data is filtered with the {CKEDITOR.filter content filter}.
+ * * 6: Data is filtered with the {@link CKEDITOR.filter content filter}.
* * 10: Data is processed with {@link CKEDITOR.htmlDataProcessor#dataFilter}.
* * 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#dataFilter}
* has already been applied.