Ticket #4729: 4729.patch
File 4729.patch, 11.6 KB (added by , 13 years ago) |
---|
-
_source/core/dom/comment.js
1 /* 2 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved. 3 For licensing, see LICENSE.html or http://ckeditor.com/license 4 */ 5 6 /** 7 * @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents 8 * a DOM comment node. 9 */ 10 11 CKEDITOR.dom.comment = CKEDITOR.tools.createClass( 12 { 13 base : CKEDITOR.dom.node, 14 15 $ : function( text, ownerDocument ) 16 { 17 if ( typeof text == 'string' ) 18 text = ( ownerDocument ? ownerDocument.$ : document ).createComment( text ); 19 20 this.base( text ); 21 }, 22 23 proto : 24 { 25 type : CKEDITOR.NODE_COMMENT, 26 27 getText : function() 28 { 29 return this.$.nodeValue; 30 }, 31 32 getOuterHtml : function() 33 { 34 return '<!--' + this.getText() + '-->'; 35 } 36 } 37 }); 38 No newline at end of file -
_source/core/htmlparser/element.js
34 34 */ 35 35 this.children = []; 36 36 37 var tagName = attributes._cke_real_element_type || name; 38 37 39 var dtd = CKEDITOR.dtd, 38 isBlockLike = !!( dtd.$block[ name ] || dtd.$listItem[ name ] || dtd.$tableContent[ name ] || dtd.$nonEditable[ name ] || name == 'br' ),40 isBlockLike = !!( dtd.$block[ tagName ] || dtd.$listItem[ tagName ] || dtd.$tableContent[ tagName ] || dtd.$nonEditable[ tagName ] || tagName == 'br' ), 39 41 isEmpty = !!dtd.$empty[ name ]; 40 42 41 43 this.isEmpty = isEmpty; … … 127 129 if ( element.name == writeName ) 128 130 break; 129 131 132 // If the element has been replaced with something of a 133 // different type, then make the replacement write itself. 134 if ( element.type != CKEDITOR.NODE_ELEMENT ) 135 { 136 element.writeHtml( writer, filter ); 137 return; 138 } 139 130 140 writeName = element.name; 131 141 if ( !writeName ) // Send children. 132 142 { -
_source/core/htmlparser/filter.js
88 88 return null; 89 89 90 90 if ( ret && ret != element ) 91 return this.on Element( ret );91 return this.onNode( ret ); 92 92 } 93 93 } 94 94 95 95 return element; 96 96 }, 97 97 98 onNode : function( node ) 99 { 100 var type = node.type; 101 102 return type == CKEDITOR.NODE_ELEMENT ? this.onElement( node ) : 103 type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( node.value ) ) : 104 type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( node.value ) ): 105 null; 106 }, 107 98 108 onAttribute : function( element, name, value ) 99 109 { 100 110 var filter = this._.attributes[ name ]; -
_source/core/loader.js
23 23 // Table of script names and their dependencies. 24 24 var scripts = 25 25 { 26 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/ elementpath', 'core/dom/text', 'core/dom/range' ],26 'core/_bootstrap' : [ 'core/config', 'core/ckeditor', 'core/plugins', 'core/scriptloader', 'core/tools', /* The following are entries that we want to force loading at the end to avoid dependence recursion */ 'core/dom/comment', 'core/dom/elementpath', 'core/dom/text', 'core/dom/range' ], 27 27 'core/ajax' : [ 'core/xml' ], 28 28 'core/ckeditor' : [ 'core/ckeditor_basic', 'core/dom', 'core/dtd', 'core/dom/document', 'core/dom/element', 'core/editor', 'core/event', 'core/htmlparser', 'core/htmlparser/element', 'core/htmlparser/fragment', 'core/htmlparser/filter', 'core/htmlparser/basicwriter', 'core/tools' ], 29 29 'core/ckeditor_base' : [], … … 31 31 'core/command' : [], 32 32 'core/config' : [ 'core/ckeditor_base' ], 33 33 'core/dom' : [], 34 'core/dom/comment' : [ 'core/dom/node' ], 34 35 'core/dom/document' : [ 'core/dom', 'core/dom/domobject', 'core/dom/window' ], 35 36 'core/dom/documentfragment' : [ 'core/dom/element' ], 36 37 'core/dom/element' : [ 'core/dom', 'core/dom/document', 'core/dom/domobject', 'core/dom/node', 'core/dom/nodelist', 'core/tools' ], -
_source/plugins/fakeobjects/plugin.js
63 63 CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable ) 64 64 { 65 65 var lang = this.lang.fakeobjects; 66 66 67 var attributes = 67 68 { 68 69 'class' : className, 69 70 src : CKEDITOR.getUrl( 'images/spacer.gif' ), 70 71 _cke_realelement : encodeURIComponent( realElement.getOuterHtml() ), 72 _cke_real_node_type : realElement.type, 71 73 alt : lang[ realElementType ] || lang.unknown 72 74 }; 75 73 76 if ( realElementType ) 74 77 attributes._cke_real_element_type = realElementType; 78 75 79 if ( isResizable ) 76 80 attributes._cke_resizable = isResizable; 77 81 … … 80 84 81 85 CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable ) 82 86 { 87 var lang = this.lang.fakeobjects, 88 html, writer; 89 83 90 var writer = new CKEDITOR.htmlParser.basicWriter(); 84 85 91 realElement.writeHtml( writer ); 92 html = writer.getHtml(); 86 93 87 var html = writer.getHtml();88 var lang = this.lang.fakeobjects;89 90 94 var attributes = 91 95 { 92 96 'class' : className, 93 97 src : CKEDITOR.getUrl( 'images/spacer.gif' ), 94 98 _cke_realelement : encodeURIComponent( html ), 99 _cke_real_node_type : realElement.type, 95 100 alt : lang[ realElementType ] || lang.unknown 96 101 }; 97 102 … … 106 111 107 112 CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) 108 113 { 109 var html = decodeURIComponent( fakeElement.getAttribute( '_cke_realelement' ) ); 110 return CKEDITOR.dom.element.createFromHtml( html, this.document ); 114 if ( fakeElement.getAttribute( '_cke_real_node_type' ) == CKEDITOR.NODE_COMMENT ) 115 return null; 116 117 return CKEDITOR.dom.element.createFromHtml( 118 decodeURIComponent( fakeElement.getAttribute( '_cke_realelement' ) ), 119 this.document ); 111 120 }; -
_source/plugins/htmldataprocessor/plugin.js
11 11 12 12 var protectedSourceMarker = '{cke_protected}'; 13 13 14 15 14 // Return the last non-space child node of the block (#4344). 16 15 function lastNoneSpaceChild( block ) 17 16 { … … 177 176 178 177 comment : function( contents ) 179 178 { 179 // If this is a comment for protected source. 180 180 if ( contents.substr( 0, protectedSourceMarker.length ) == protectedSourceMarker ) 181 return new CKEDITOR.htmlParser.cdata( decodeURIComponent( contents.substr( protectedSourceMarker.length ) ) ); 181 { 182 // Remove the extra marker for real comments from it. 183 if ( contents.substr( protectedSourceMarker.length, 3 ) == '{C}' ) 184 contents = contents.substr( protectedSourceMarker.length + 3 ); 185 else 186 contents = contents.substr( protectedSourceMarker.length ); 182 187 188 return new CKEDITOR.htmlParser.cdata( decodeURIComponent( contents ) ); 189 } 190 183 191 return contents; 184 192 } 185 193 }; … … 239 247 return html.replace( encodedTagsRegex, unprotectEncodedTagsMatch ); 240 248 } 241 249 250 function unprotectRealComments( html ) 251 { 252 return html.replace( /<!--{cke_protected}{C}([\s\S]+?)-->/g, function( match, data ) 253 { 254 return decodeURIComponent( data ); 255 }); 256 } 257 258 function protectRealComments( html ) 259 { 260 return html.replace( /<!--(?!{cke_protected})[\s\S]+?-->/g, function( match ) 261 { 262 return '<!--' + protectedSourceMarker + 263 '{C}' + 264 encodeURIComponent( match ).replace( /--/g, '%2D%2D' ) + 265 '-->'; 266 }); 267 } 268 242 269 function protectSource( data, protectRegexes ) 243 270 { 244 271 var protectedHtml = [], 245 tempRegex = /<\!--\{cke_temp\}(\d*?)-->/g; 272 tempRegex = /<\!--\{cke_temp(comment)?\}(\d*?)-->/g; 273 246 274 var regexes = 247 275 [ 248 // First of any other protection, we must protect all comments249 // to avoid loosing them (of course, IE related).250 (/<!--[\s\S]*?-->/g),251 252 276 // Script tags will also be forced to be protected, otherwise 253 277 // IE will execute them. 254 278 /<script[\s\S]*?<\/script>/gi, … … 258 282 ] 259 283 .concat( protectRegexes ); 260 284 285 // First of any other protection, we must protect all comments 286 // to avoid loosing them (of course, IE related). 287 // Note that we use a different tag for comments, as we need to 288 // transform them when applying filters. 289 data = data.replace( (/<!--[\s\S]*?-->/g), function( match ) 290 { 291 return '<!--{cke_tempcomment}' + ( protectedHtml.push( match ) - 1 ) + '-->'; 292 }); 293 261 294 for ( var i = 0 ; i < regexes.length ; i++ ) 262 295 { 263 296 data = data.replace( regexes[i], function( match ) 264 297 { 265 298 match = match.replace( tempRegex, // There could be protected source inside another one. (#3869). 266 function( $, i d )299 function( $, isComment, id ) 267 300 { 268 301 return protectedHtml[ id ]; 269 302 } … … 271 304 return '<!--{cke_temp}' + ( protectedHtml.push( match ) - 1 ) + '-->'; 272 305 }); 273 306 } 274 data = data.replace( tempRegex, function( $, i d )307 data = data.replace( tempRegex, function( $, isComment, id ) 275 308 { 276 309 return '<!--' + protectedSourceMarker + 310 ( isComment ? '{C}' : '' ) + 277 311 encodeURIComponent( protectedHtml[ id ] ).replace( /--/g, '%2D%2D' ) + 278 312 '-->'; 279 313 } … … 291 325 292 326 dataProcessor.writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand; 293 327 294 dataProcessor.dataFilter.addRules( defaultDataFilterRules ); 295 dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules ); 296 dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules ); 297 dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules ); 328 // Rules are added with lower priority so, by default, other rules 329 // provided by end developers will be executed first. 330 dataProcessor.dataFilter.addRules( defaultDataFilterRules, 20 ); 331 dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules, 20 ); 332 dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules, 20 ); 333 dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules, 20 ); 298 334 } 299 335 }); 300 336 … … 343 379 if ( CKEDITOR.env.ie ) 344 380 data = unprotectEncodedTags( data ); 345 381 382 // Restore the comments that have been protected, in this way they 383 // can be properly filtered. 384 data = unprotectRealComments( data ); 385 346 386 // Now use our parser to make further fixes to the structure, as 347 387 // well as apply the filter. 348 388 var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data, fixForBody ), 349 389 writer = new CKEDITOR.htmlParser.basicWriter(); 350 390 351 391 fragment.writeHtml( writer, this.dataFilter ); 392 data = writer.getHtml( true ); 352 393 353 return writer.getHtml( true ); 394 // Protect the real comments again. 395 data = protectRealComments( data ); 396 397 return data; 354 398 }, 355 399 356 400 toDataFormat : function( html, fixForBody )