aboutsummaryrefslogtreecommitdiff
path: root/sources/core/htmldataprocessor.js
diff options
context:
space:
mode:
Diffstat (limited to 'sources/core/htmldataprocessor.js')
-rw-r--r--sources/core/htmldataprocessor.js75
1 files changed, 46 insertions, 29 deletions
diff --git a/sources/core/htmldataprocessor.js b/sources/core/htmldataprocessor.js
index 56764be..79e996b 100644
--- a/sources/core/htmldataprocessor.js
+++ b/sources/core/htmldataprocessor.js
@@ -56,7 +56,7 @@
56 // it up and apply the filter. 56 // it up and apply the filter.
57 data = protectSource( data, editor ); 57 data = protectSource( data, editor );
58 58
59 // Protect content of textareas. (#9995) 59 // Protect content of textareas. (http://dev.ckeditor.com/ticket/9995)
60 // Do this before protecting attributes to avoid breaking: 60 // Do this before protecting attributes to avoid breaking:
61 // <textarea><img src="..." /></textarea> 61 // <textarea><img src="..." /></textarea>
62 data = protectElements( data, protectTextareaRegex ); 62 data = protectElements( data, protectTextareaRegex );
@@ -67,23 +67,23 @@
67 data = protectAttributes( data ); 67 data = protectAttributes( data );
68 68
69 // Protect elements than can't be set inside a DIV. E.g. IE removes 69 // Protect elements than can't be set inside a DIV. E.g. IE removes
70 // style tags from innerHTML. (#3710) 70 // style tags from innerHTML. (http://dev.ckeditor.com/ticket/3710)
71 data = protectElements( data, protectElementsRegex ); 71 data = protectElements( data, protectElementsRegex );
72 72
73 // Certain elements has problem to go through DOM operation, protect 73 // Certain elements has problem to go through DOM operation, protect
74 // them by prefixing 'cke' namespace. (#3591) 74 // them by prefixing 'cke' namespace. (http://dev.ckeditor.com/ticket/3591)
75 data = protectElementsNames( data ); 75 data = protectElementsNames( data );
76 76
77 // All none-IE browsers ignore self-closed custom elements, 77 // All none-IE browsers ignore self-closed custom elements,
78 // protecting them into open-close. (#3591) 78 // protecting them into open-close. (http://dev.ckeditor.com/ticket/3591)
79 data = protectSelfClosingElements( data ); 79 data = protectSelfClosingElements( data );
80 80
81 // Compensate one leading line break after <pre> open as browsers 81 // Compensate one leading line break after <pre> open as browsers
82 // eat it up. (#5789) 82 // eat it up. (http://dev.ckeditor.com/ticket/5789)
83 data = protectPreFormatted( data ); 83 data = protectPreFormatted( data );
84 84
85 // There are attributes which may execute JavaScript code inside fixBin. 85 // There are attributes which may execute JavaScript code inside fixBin.
86 // Encode them greedily. They will be unprotected right after getting HTML from fixBin. (#10) 86 // Encode them greedily. They will be unprotected right after getting HTML from fixBin. (http://dev.ckeditor.com/ticket/10)
87 data = protectInsecureAttributes( data ); 87 data = protectInsecureAttributes( data );
88 88
89 var fixBin = evtData.context || editor.editable().getName(), 89 var fixBin = evtData.context || editor.editable().getName(),
@@ -99,7 +99,7 @@
99 // Call the browser to help us fixing a possibly invalid HTML 99 // Call the browser to help us fixing a possibly invalid HTML
100 // structure. 100 // structure.
101 var el = editor.document.createElement( fixBin ); 101 var el = editor.document.createElement( fixBin );
102 // Add fake character to workaround IE comments bug. (#3801) 102 // Add fake character to workaround IE comments bug. (http://dev.ckeditor.com/ticket/3801)
103 el.setHtml( 'a' + data ); 103 el.setHtml( 'a' + data );
104 data = el.getHtml().substr( 1 ); 104 data = el.getHtml().substr( 1 );
105 105
@@ -128,7 +128,7 @@
128 data = CKEDITOR.htmlParser.fragment.fromHtml( data, evtData.context, fixBodyTag ); 128 data = CKEDITOR.htmlParser.fragment.fromHtml( data, evtData.context, fixBodyTag );
129 129
130 // The empty root element needs to be fixed by adding 'p' or 'div' into it. 130 // The empty root element needs to be fixed by adding 'p' or 'div' into it.
131 // This avoids the need to create that element on the first focus (#12630). 131 // This avoids the need to create that element on the first focus (http://dev.ckeditor.com/ticket/12630).
132 if ( fixBodyTag ) { 132 if ( fixBodyTag ) {
133 fixEmptyRoot( data, fixBodyTag ); 133 fixEmptyRoot( data, fixBodyTag );
134 } 134 }
@@ -163,7 +163,7 @@
163 editor.on( 'toDataFormat', function( evt ) { 163 editor.on( 'toDataFormat', function( evt ) {
164 var data = evt.data.dataValue; 164 var data = evt.data.dataValue;
165 165
166 // #10854 - we need to strip leading blockless <br> which FF adds 166 // http://dev.ckeditor.com/ticket/10854 - we need to strip leading blockless <br> which FF adds
167 // automatically when editable contains only non-editable content. 167 // automatically when editable contains only non-editable content.
168 // We do that for every browser (so it's a constant behavior) and 168 // We do that for every browser (so it's a constant behavior) and
169 // not in BR mode, in which chance of valid leading blockless <br> is higher. 169 // not in BR mode, in which chance of valid leading blockless <br> is higher.
@@ -192,7 +192,7 @@
192 data.writeChildrenHtml( writer ); 192 data.writeChildrenHtml( writer );
193 data = writer.getHtml( true ); 193 data = writer.getHtml( true );
194 194
195 // Restore those non-HTML protected source. (#4475,#4880) 195 // Restore those non-HTML protected source. (http://dev.ckeditor.com/ticket/4475,http://dev.ckeditor.com/ticket/4880)
196 data = unprotectRealComments( data ); 196 data = unprotectRealComments( data );
197 data = unprotectSource( data, editor ); 197 data = unprotectSource( data, editor );
198 198
@@ -448,7 +448,7 @@
448 return false; 448 return false;
449 449
450 // 1. For IE version >=8, empty blocks are displayed correctly themself in wysiwiyg; 450 // 1. For IE version >=8, empty blocks are displayed correctly themself in wysiwiyg;
451 // 2. For the rest, at least table cell and list item need no filler space. (#6248) 451 // 2. For the rest, at least table cell and list item need no filler space. (http://dev.ckeditor.com/ticket/6248)
452 if ( !isOutput && !CKEDITOR.env.needsBrFiller && 452 if ( !isOutput && !CKEDITOR.env.needsBrFiller &&
453 ( document.documentMode > 7 || 453 ( document.documentMode > 7 ||
454 block.name in CKEDITOR.dtd.tr || 454 block.name in CKEDITOR.dtd.tr ||
@@ -484,7 +484,7 @@
484 } 484 }
485 485
486 // Regex to scan for &nbsp; at the end of blocks, which are actually placeholders. 486 // Regex to scan for &nbsp; at the end of blocks, which are actually placeholders.
487 // Safari transforms the &nbsp; to \xa0. (#4172) 487 // Safari transforms the &nbsp; to \xa0. (http://dev.ckeditor.com/ticket/4172)
488 var tailNbspRegex = /(?:&nbsp;|\xa0)$/; 488 var tailNbspRegex = /(?:&nbsp;|\xa0)$/;
489 489
490 var protectedSourceMarker = '{cke_protected}'; 490 var protectedSourceMarker = '{cke_protected}';
@@ -563,18 +563,35 @@
563 // active in the editing area (IE|WebKit). 563 // active in the editing area (IE|WebKit).
564 [ ( /^on/ ), 'data-cke-pa-on' ], 564 [ ( /^on/ ), 'data-cke-pa-on' ],
565 565
566 // Prevent iframe's srcdoc attribute from being evaluated in the editable.
567 [ ( /^srcdoc/ ), 'data-cke-pa-srcdoc' ],
568
566 // Don't let some old expando enter editor. Concerns only IE8, 569 // Don't let some old expando enter editor. Concerns only IE8,
567 // but for consistency remove on all browsers. 570 // but for consistency remove on all browsers.
568 [ ( /^data-cke-expando$/ ), '' ] 571 [ ( /^data-cke-expando$/ ), '' ]
569 ] 572 ],
573
574 elements: {
575 // Prevent iframe's src attribute with javascript code or data protocol from being evaluated in the editable.
576 iframe: function( element ) {
577 if ( element.attributes && element.attributes.src ) {
578
579 var src = element.attributes.src.toLowerCase().replace( /[^a-z]/gi, '' );
580 if ( src.indexOf( 'javascript' ) === 0 || src.indexOf( 'data' ) === 0 ) {
581 element.attributes[ 'data-cke-pa-src' ] = element.attributes.src;
582 delete element.attributes.src;
583 }
584 }
585 }
586 }
570 }; 587 };
571 588
572 // Disable form elements editing mode provided by some browsers. (#5746) 589 // Disable form elements editing mode provided by some browsers. (http://dev.ckeditor.com/ticket/5746)
573 function protectReadOnly( element ) { 590 function protectReadOnly( element ) {
574 var attrs = element.attributes; 591 var attrs = element.attributes;
575 592
576 // We should flag that the element was locked by our code so 593 // We should flag that the element was locked by our code so
577 // it'll be editable by the editor functions (#6046). 594 // it'll be editable by the editor functions (http://dev.ckeditor.com/ticket/6046).
578 if ( attrs.contenteditable != 'false' ) 595 if ( attrs.contenteditable != 'false' )
579 attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1; 596 attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1;
580 597
@@ -602,7 +619,7 @@
602 } 619 }
603 }, 620 },
604 621
605 // Remove empty link but not empty anchor. (#3829, #13516) 622 // Remove empty link but not empty anchor. (http://dev.ckeditor.com/ticket/3829, http://dev.ckeditor.com/ticket/13516)
606 a: function( element ) { 623 a: function( element ) {
607 var attrs = element.attributes; 624 var attrs = element.attributes;
608 625
@@ -641,7 +658,7 @@
641 if ( attribs[ 'data-cke-temp' ] ) 658 if ( attribs[ 'data-cke-temp' ] )
642 return false; 659 return false;
643 660
644 // Remove duplicated attributes - #3789. 661 // Remove duplicated attributes - http://dev.ckeditor.com/ticket/3789.
645 var attributeNames = [ 'name', 'href', 'src' ], 662 var attributeNames = [ 'name', 'href', 'src' ],
646 savedAttributeName; 663 savedAttributeName;
647 for ( var i = 0; i < attributeNames.length; i++ ) { 664 for ( var i = 0; i < attributeNames.length; i++ ) {
@@ -653,7 +670,7 @@
653 return element; 670 return element;
654 }, 671 },
655 672
656 // The contents of table should be in correct order (#4809). 673 // The contents of table should be in correct order (http://dev.ckeditor.com/ticket/4809).
657 table: function( element ) { 674 table: function( element ) {
658 // Clone the array as it would become empty during the sort call. 675 // Clone the array as it would become empty during the sort call.
659 var children = element.children.slice( 0 ); 676 var children = element.children.slice( 0 );
@@ -712,7 +729,7 @@
712 title: function( element ) { 729 title: function( element ) {
713 var titleText = element.children[ 0 ]; 730 var titleText = element.children[ 0 ];
714 731
715 // Append text-node to title tag if not present (i.e. non-IEs) (#9882). 732 // Append text-node to title tag if not present (i.e. non-IEs) (http://dev.ckeditor.com/ticket/9882).
716 !titleText && append( element, titleText = new CKEDITOR.htmlParser.text() ); 733 !titleText && append( element, titleText = new CKEDITOR.htmlParser.text() );
717 734
718 // Transfer data-saved title to title tag. 735 // Transfer data-saved title to title tag.
@@ -733,7 +750,7 @@
733 750
734 if ( CKEDITOR.env.ie ) { 751 if ( CKEDITOR.env.ie ) {
735 // IE outputs style attribute in capital letters. We should convert 752 // IE outputs style attribute in capital letters. We should convert
736 // them back to lower case, while not hurting the values (#5930) 753 // them back to lower case, while not hurting the values (http://dev.ckeditor.com/ticket/5930)
737 defaultHtmlFilterRulesForAll.attributes.style = function( value ) { 754 defaultHtmlFilterRulesForAll.attributes.style = function( value ) {
738 return value.replace( /(^|;)([^\:]+)/g, function( match ) { 755 return value.replace( /(^|;)([^\:]+)/g, function( match ) {
739 return match.toLowerCase(); 756 return match.toLowerCase();
@@ -741,7 +758,7 @@
741 }; 758 };
742 } 759 }
743 760
744 // Disable form elements editing mode provided by some browsers. (#5746) 761 // Disable form elements editing mode provided by some browsers. (http://dev.ckeditor.com/ticket/5746)
745 function unprotectReadyOnly( element ) { 762 function unprotectReadyOnly( element ) {
746 var attrs = element.attributes; 763 var attrs = element.attributes;
747 switch ( attrs[ 'data-cke-editable' ] ) { 764 switch ( attrs[ 'data-cke-editable' ] ) {
@@ -773,7 +790,7 @@
773 // 790 //
774 // 'data-x' => '&lt;a href=&quot;X&quot;' 791 // 'data-x' => '&lt;a href=&quot;X&quot;'
775 // 792 //
776 // which, can be easily filtered out (#11508). 793 // which, can be easily filtered out (http://dev.ckeditor.com/ticket/11508).
777 protectAttributeRegex = /([\w-:]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi, 794 protectAttributeRegex = /([\w-:]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,
778 protectAttributeNameRegex = /^(href|src|name)$/i; 795 protectAttributeNameRegex = /^(href|src|name)$/i;
779 796
@@ -790,8 +807,8 @@
790 function protectAttributes( html ) { 807 function protectAttributes( html ) {
791 return html.replace( protectElementRegex, function( element, tag, attributes ) { 808 return html.replace( protectElementRegex, function( element, tag, attributes ) {
792 return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) { 809 return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) {
793 // Avoid corrupting the inline event attributes (#7243). 810 // Avoid corrupting the inline event attributes (http://dev.ckeditor.com/ticket/7243).
794 // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218) 811 // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (http://dev.ckeditor.com/ticket/5218)
795 if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 ) 812 if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 )
796 return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr; 813 return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr;
797 814
@@ -880,7 +897,7 @@
880 // <noscript> tags (get lost in IE and messed up in FF). 897 // <noscript> tags (get lost in IE and messed up in FF).
881 /<noscript[\s\S]*?<\/noscript>/gi, 898 /<noscript[\s\S]*?<\/noscript>/gi,
882 899
883 // Avoid meta tags being stripped (#8117). 900 // Avoid meta tags being stripped (http://dev.ckeditor.com/ticket/8117).
884 /<meta[\s\S]*?\/?>/gi 901 /<meta[\s\S]*?\/?>/gi
885 ].concat( protectRegexes ); 902 ].concat( protectRegexes );
886 903
@@ -894,7 +911,7 @@
894 911
895 for ( var i = 0; i < regexes.length; i++ ) { 912 for ( var i = 0; i < regexes.length; i++ ) {
896 data = data.replace( regexes[ i ], function( match ) { 913 data = data.replace( regexes[ i ], function( match ) {
897 match = match.replace( tempRegex, // There could be protected source inside another one. (#3869). 914 match = match.replace( tempRegex, // There could be protected source inside another one. (http://dev.ckeditor.com/ticket/3869).
898 function( $, isComment, id ) { 915 function( $, isComment, id ) {
899 return protectedHtml[ id ]; 916 return protectedHtml[ id ];
900 } ); 917 } );
@@ -912,7 +929,7 @@
912 929
913 // Different protection pattern is used for those that 930 // Different protection pattern is used for those that
914 // live in attributes to avoid from being HTML encoded. 931 // live in attributes to avoid from being HTML encoded.
915 // Why so serious? See #9205, #8216, #7805, #11754, #11846. 932 // 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.
916 data = data.replace( /<\w+(?:\s+(?:(?:[^\s=>]+\s*=\s*(?:[^'"\s>]+|'[^']*'|"[^"]*"))|[^\s=\/>]+))+\s*\/?>/g, function( match ) { 933 data = data.replace( /<\w+(?:\s+(?:(?:[^\s=>]+\s*=\s*(?:[^'"\s>]+|'[^']*'|"[^"]*"))|[^\s=\/>]+))+\s*\/?>/g, function( match ) {
917 return match.replace( /<!--\{cke_protected\}([^>]*)-->/g, function( match, data ) { 934 return match.replace( /<!--\{cke_protected\}([^>]*)-->/g, function( match, data ) {
918 store[ store.id ] = decodeURIComponent( data ); 935 store[ store.id ] = decodeURIComponent( data );
@@ -922,7 +939,7 @@
922 939
923 // This RegExp searches for innerText in all the title/iframe/textarea elements. 940 // This RegExp searches for innerText in all the title/iframe/textarea elements.
924 // This is because browser doesn't allow HTML in these elements, that's why we can't 941 // This is because browser doesn't allow HTML in these elements, that's why we can't
925 // nest comments in there. (#11223) 942 // nest comments in there. (http://dev.ckeditor.com/ticket/11223)
926 data = data.replace( /<(title|iframe|textarea)([^>]*)>([\s\S]*?)<\/\1>/g, function( match, tagName, tagAttributes, innerText ) { 943 data = data.replace( /<(title|iframe|textarea)([^>]*)>([\s\S]*?)<\/\1>/g, function( match, tagName, tagAttributes, innerText ) {
927 return '<' + tagName + tagAttributes + '>' + unprotectSource( unprotectRealComments( innerText ), editor ) + '</' + tagName + '>'; 944 return '<' + tagName + tagAttributes + '>' + unprotectSource( unprotectRealComments( innerText ), editor ) + '</' + tagName + '>';
928 } ); 945 } );
@@ -971,7 +988,7 @@
971 * {@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}. 988 * {@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
972 * * 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#dataFilter} 989 * * 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#dataFilter}
973 * is not applied yet. 990 * is not applied yet.
974 * * 6: Data is filtered with the {CKEDITOR.filter content filter}. 991 * * 6: Data is filtered with the {@link CKEDITOR.filter content filter}.
975 * * 10: Data is processed with {@link CKEDITOR.htmlDataProcessor#dataFilter}. 992 * * 10: Data is processed with {@link CKEDITOR.htmlDataProcessor#dataFilter}.
976 * * 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#dataFilter} 993 * * 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#dataFilter}
977 * has already been applied. 994 * has already been applied.