Ticket #4067: 4067_4.patch
File 4067_4.patch, 26.9 KB (added by , 10 years ago) |
---|
-
_source/plugins/htmlwriter/plugin.js
67 67 68 68 var dtd = CKEDITOR.dtd; 69 69 70 for ( var e in CKEDITOR.tools.extend( {}, dtd.$ block, dtd.$listItem, dtd.$tableContent ) )70 for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) 71 71 { 72 72 this.setRules( e, 73 73 { -
_source/core/tools.js
63 63 { 64 64 var clone; 65 65 66 // Array.67 if ( obj && ( obj instanceof Array ) )68 {69 clone = [];70 71 for ( var i = 0 ; i < obj.length ; i++ )72 clone[ i ] = this.clone( obj[ i ] );73 74 return clone;75 }76 77 66 // "Static" types. 78 67 if ( obj === null 79 68 || ( typeof( obj ) != 'object' ) 80 69 || ( obj instanceof String ) 81 70 || ( obj instanceof Number ) 82 71 || ( obj instanceof Boolean ) 83 || ( obj instanceof Date ) ) 72 || ( obj instanceof Date ) 73 || ( obj instanceof RegExp ) ) 84 74 { 85 75 return obj; 86 76 } -
_source/core/htmlparser/element.js
35 35 this.children = []; 36 36 37 37 var dtd = CKEDITOR.dtd, 38 isBlockLike = !!( dtd.$ block[ name ] || dtd.$listItem[ name ] || dtd.$tableContent[ name ] || dtd.$nonEditable[ name ] || name == 'br' ),38 isBlockLike = !!( dtd.$nonBodyContent[ name ] || dtd.$block[ name ] || dtd.$listItem[ name ] || dtd.$tableContent[ name ] || dtd.$nonEditable[ name ] || name == 'br' ), 39 39 isEmpty = !!dtd.$empty[ name ]; 40 40 41 41 this.isEmpty = isEmpty; -
_source/plugins/wysiwygarea/plugin.js
15 15 */ 16 16 var nonExitableElementNames = { table:1,pre:1 }; 17 17 // Matching an empty paragraph at the end of document. 18 var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )\s*(:?<\/\1>)?\s* $/gi;18 var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )\s*(:?<\/\1>)?\s*(?=$|<\/body>)/gi; 19 19 20 20 function onInsertHtml( evt ) 21 21 { … … 555 555 556 556 // Get the HTML version of the data. 557 557 if ( editor.dataProcessor ) 558 { 559 data = editor.dataProcessor.toHtml( data, fixForBody ); 560 } 558 data = editor.dataProcessor.toFullPageHtml( data, fixForBody ); 561 559 562 data = 563 editor.config.docType + 564 '<html dir="' + editor.config.contentsLangDirection + '">' + 565 '<head>' + 566 '<link type="text/css" rel="stylesheet" href="' + 567 [].concat( editor.config.contentsCss ).join( '"><link type="text/css" rel="stylesheet" href="' ) + 568 '">' + 569 '<style type="text/css" _fcktemp="true">' + 570 editor._.styles.join( '\n' ) + 571 '</style>'+ 572 '</head>' + 573 '<body>' + 574 data + 575 '</body>' + 576 '</html>' + 577 activationScript; 560 if( !editor.config.fullPage ) 561 { 562 data = 563 editor.config.docType + 564 '<html dir="' + editor.config.contentsLangDirection + '">' + 565 '<head>' + 566 '<link type="text/css" rel="stylesheet" href="' + 567 [].concat( editor.config.contentsCss ).join( '"><link type="text/css" rel="stylesheet" href="' ) + 568 '">' + 569 '<style type="text/css" _fcktemp="true">' + 570 editor._.styles.join( '\n' ) + 571 '</style>'+ 572 '</head>' + 573 '<body>' + 574 data + 575 '</body>' + 576 '</html>'; 577 } 578 578 579 data += activationScript; 580 579 581 window[ '_cke_htmlToLoad_' + editor.name ] = data; 580 582 CKEDITOR._[ 'contentDomReady' + editor.name ] = contentDomReady; 581 583 createIFrame(); … … 592 594 593 595 getData : function() 594 596 { 595 var data = iframe.getFrameDocument().getBody().getHtml(); 597 var frameDoc = iframe.getFrameDocument(), 598 documentElement = frameDoc.getDocumentElement(), 599 data = editor.config.fullPage ? documentElement.getOuterHtml() : frameDoc.getBody().getHtml(); 596 600 597 601 if ( editor.dataProcessor ) 598 data = editor.dataProcessor.to DataFormat( data, fixForBody );602 data = editor.dataProcessor.toFullPageData( data, fixForBody ); 599 603 600 604 // Strip the last blank paragraph within document. 601 605 if ( editor.config.ignoreEmptyParagraph ) … … 673 677 } 674 678 } ) + ')' ); 675 679 } 676 })();680 })(); 677 681 678 682 } 679 683 })(); -
_source/core/dom/element.js
328 328 */ 329 329 getHtml : function() 330 330 { 331 return this.$.innerHTML; 331 var retval = this.$.innerHTML; 332 // Strip <?xml:namespace> tag in the output HTML of 333 // namespaced element in IE(#3341). 334 return CKEDITOR.env.ie ? retval.replace( /<\?[^>]*>/g, '' ) : retval; 332 335 }, 333 336 334 337 getOuterHtml : function() -
_source/core/htmlparser/filter.js
45 45 46 46 // Add the comment. 47 47 this._.comment = transformNamedItem( this._.comment, rules.comment, priority ) || this._.comment; 48 49 // Add root fragment. 50 this._.root = transformNamedItem( this._.root, rules.root, priority ) || this._.root; 48 51 }, 49 52 50 53 onElementName : function( name ) … … 69 72 return textFilter ? textFilter.filter( commentText ) : commentText; 70 73 }, 71 74 75 onFragment : function( element ) 76 { 77 var rootFilter = this._.root; 78 return rootFilter ? rootFilter.filter( element ) : element; 79 }, 80 72 81 onElement : function( element ) 73 82 { 74 83 // We must apply filters set to the specific element name as … … 111 120 } 112 121 113 122 return value; 123 }, 124 125 clone : function() 126 { 127 var clone = new CKEDITOR.htmlParser.filter(); 128 // Shallow copy all the rules. 129 clone._ = CKEDITOR.tools.clone( this._ ); 130 return clone; 114 131 } 115 132 } 116 133 }); -
_source/plugins/fullpage/plugin.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 The "wysiwygarea" plugin. It registers the "wysiwyg" editing 8 * mode, which handles the main editing area space. 9 */ 10 11 ( function() 12 { 13 var docTypeRegex = /<!DOCTYPE[^>]*>\s*/i; 14 15 var dtd = CKEDITOR.dtd; 16 CKEDITOR.plugins.add( 'fullpage', 17 { 18 requires : [ 'htmldataprocessor' ], 19 afterInit : function( editor ) 20 { 21 if( editor.config.fullPage ) 22 { 23 var fullPageDataFilterRules = 24 { 25 root : function( element ) 26 { 27 // Adding missing parts of full page. 28 var firstChild = element.children[ 0 ]; 29 // Full document. 30 if ( firstChild && firstChild.name == 'html' ) 31 return; 32 // Missing <html>. 33 if ( !firstChild || firstChild.name in dtd.html ) 34 wrapContent( element, 'html' ); 35 // Missing <html> and <body>/<head>. 36 else 37 { 38 wrapContent( wrapContent( element, 'html' ), 39 firstChild.name in dtd.head ? 'head' : 'body' ); 40 } 41 }, 42 43 // Full page support. ( #4067 ) 44 elements : 45 { 46 html : function ( element ) 47 { 48 // Both <head> and <body> are mandatory. 49 if ( !childByTagName( element, 'head' ) ) 50 element.children.splice( 0, 0, new CKEDITOR.htmlParser.element( 'head', {} ) ); 51 if ( !childByTagName( element, 'body' ) ) 52 element.children.splice( element.children.length, 0, new CKEDITOR.htmlParser.element( 'body', {} ) ); 53 54 // 1. Save doc-type as a custom attribute; 55 // 2. Adding missing xml namespace attribute; 56 // 3. Adding missing language direction attribute. 57 var attrs = element.attributes, 58 configDir = editor.config.contentsLangDirection; 59 if( docType ) 60 { 61 attrs.cke_doctype = encodeURIComponent( docType ); 62 docType.match( /xhtml/i ) 63 && !attrs.xmlns 64 && ( attrs.xmlns = 'http://www.w3.org/1999/xhtml' ); 65 !attrs.dir && configDir && ( attrs.dir = configDir ); 66 } 67 }, 68 69 head : function ( element ) 70 { 71 // <title> is mandatory. 72 if ( !childByTagName( element, 'title' ) ) 73 element.children.splice( 0, 0, new CKEDITOR.htmlParser.element( 'title', {} ) ); 74 75 // Adding default styles. 76 var styleLinks = [].concat( editor.config.contentsCss ), 77 styleText = editor._.styles.join( '\n' ); 78 79 if ( styleLinks ) 80 { 81 for ( var i = 0; i < styleLinks.length; i++ ) 82 { 83 var link = new CKEDITOR.htmlParser.element( 'link', 84 { 85 type: 'text/css' , 86 rel : 'stylesheet', 87 href : styleLinks[ i ], 88 cke_temp : 1 89 } ); 90 element.add( link ); 91 } 92 } 93 if ( styleText ) 94 { 95 var style = new CKEDITOR.htmlParser.element( 'style', 96 { 97 type: 'text/css', 98 cke_temp : 1 99 } ); 100 style.add( new CKEDITOR.htmlParser.text( styleText ) ); 101 element.add( style ); 102 } 103 } 104 } 105 }; 106 107 var fullPageHtmlFilterRules = 108 { 109 elements : 110 { 111 html : function ( element ) 112 { 113 var attrs = element.attributes, 114 docTypeAttr = attrs.cke_doctype; 115 116 if( docTypeAttr ) 117 { 118 docType = decodeURIComponent( docTypeAttr ); 119 delete attrs.cke_doctype; 120 } 121 }, 122 123 body : function( element ) 124 { 125 delete element.attributes.spellcheck; 126 delete element.attributes.contenteditable; 127 }, 128 // Elements used interally in 'wysiwyg' mode shouldn't appear in output. 129 style : removeInternal, 130 link : removeInternal 131 }, 132 attributeNames : 133 [ 134 [ 'hidefocus', '' ] 135 ] 136 }; 137 138 var dataProcessor = editor.dataProcessor; 139 dataProcessor.fullPageDataFilter.addRules( fullPageDataFilterRules ); 140 dataProcessor.fullPageHtmlFilter.addRules( fullPageHtmlFilterRules ); 141 142 var docType = editor.config.docType; 143 144 function removeDocType( evt ) 145 { 146 var data = evt.data; 147 // Record and sweep the doc-type declaration. 148 evt.data = data.replace( docTypeRegex, function( match ) 149 { 150 docType = match; 151 return ''; 152 } ); 153 } 154 155 function prependDocType( evt ) 156 { 157 // Prepend doc type to final data format. 158 if( docType ) 159 evt.data = docType + '\n' + evt.data; 160 } 161 162 // Properly apply doc-type on html or vice versa. 163 dataProcessor.on( 'fullPageHtmlPreProcess', removeDocType ); 164 dataProcessor.on( 'fullPageHtmlPostProcess', prependDocType ); 165 dataProcessor.on( 'fullPageDataPostProcess', prependDocType ); 166 } 167 } 168 } ); 169 170 function removeInternal( element ) 171 { 172 if( element.attributes.cke_temp ) 173 return false; 174 } 175 176 function childByTagName( element, tagName ) 177 { 178 var children = element.children, 179 child; 180 for ( var i = 0; i < children.length; i++ ) 181 { 182 child = children[ i ]; 183 if( child.name && child.name == tagName ) 184 return child; 185 } 186 } 187 function wrapContent( element, tagName ) 188 { 189 var childrens = element.children, 190 root = new CKEDITOR.htmlParser.element( tagName, {} ); 191 element.children = []; 192 element.add( root ); 193 for ( var i = 0; i < childrens.length; i++ ) 194 { 195 root.add( childrens[ i ] ); 196 } 197 return root; 198 } 199 200 } )(); -
_source/core/config.js
198 198 * @type String 199 199 * @example 200 200 */ 201 plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,colordialog,contextmenu,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms, horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc',201 plugins : 'about,basicstyles,blockquote,button,clipboard,colorbutton,colordialog,contextmenu,elementspath,enterkey,entities,filebrowser,find,flash,font,format,forms,fullpage,horizontalrule,htmldataprocessor,image,indent,justify,keystrokes,link,list,maximize,newpage,pagebreak,pastefromword,pastetext,popup,preview,print,removeformat,resize,save,scayt,smiley,showblocks,sourcearea,stylescombo,table,tabletools,specialchar,tab,templates,toolbar,undo,wysiwygarea,wsc', 202 202 203 203 /** 204 204 * List of additional plugins to be loaded. This is a tool setting which -
_source/core/dtd.js
51 51 N = {'#':1}, 52 52 O = X({param:1},K), 53 53 P = X({form:1},A,D,E,I), 54 Q = {li:1}; 54 Q = {li:1}, 55 R = {style:1,script:1}, 56 S = {base:1,link:1,meta:1,title:1}, 57 T = X(S,R), 58 U = {head:1,body:1}, 59 V = {html:1}; 55 60 56 var block = {address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}; 61 var block = {address:1,blockquote:1,center:1,dir:1,div:1,dl:1,fieldset:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,isindex:1,menu:1,noframes:1,ol:1,p:1,pre:1,table:1,ul:1}, 62 inline = {a:1,abbr:1,acronym:1,b:1,basefont:1,bdo:1,big:1,br:1,cite:1,code:1,dfn:1,em:1,font:1,i:1,img:1,input:1,kbd:1,label:1,q:1,s:1,samp:1,select:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,textarea:1,tt:1,u:1,'var':1,applet:1,button:1,del:1,iframe:1,ins:1,map:1,object:1,script:1}; 57 63 58 64 return /** @lends CKEDITOR.dtd */ { 59 65 60 66 // The "$" items have been added manually. 61 67 62 /** 68 $ : V, 69 70 // List of elements living outside body. 71 $nonBodyContent: X(V,U,S), 72 73 /** 63 74 * List of block elements, like "p" or "div". 64 75 * @type Object 65 76 * @example 66 77 */ 67 78 $block : block, 68 79 69 $body : X({script:1 }, block),80 $body : X({script:1,style:1}, block), 70 81 71 82 $cdata : {script:1,style:1}, 72 83 … … 120 131 */ 121 132 $tableContent : {caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1}, 122 133 123 col : {}, 134 html: U, 135 head: T, 136 style: N, 137 script: N, 138 body: X(inline, block), 139 col : {}, 124 140 tr : {td:1,th:1}, 125 141 img : {}, 126 142 colgroup : {col:1}, … … 200 216 pre : X(G,C), 201 217 p : L, 202 218 em : L, 203 dfn : L 219 dfn : L, 220 base: {}, 221 link: {}, 222 meta: {}, 223 title: N 204 224 }; 205 225 })(); 206 226 -
_source/core/htmlparser/basicwriter.js
117 117 reset : function() 118 118 { 119 119 this._.output = []; 120 this._.indent = false; 120 121 }, 121 122 122 123 /** -
_source/core/htmlparser/fragment.js
114 114 elementName = realElementName; 115 115 else 116 116 elementName = element.name; 117 if ( !( elementName in CKEDITOR.dtd.$body ) ) 117 if ( elementName 118 && !( elementName in CKEDITOR.dtd.$body ) 119 && !( elementName in CKEDITOR.dtd.$nonBodyContent ) ) 118 120 { 119 121 var savedCurrent = currentNode; 120 122 … … 180 182 } 181 183 182 184 var currentName = currentNode.name, 183 currentDtd = ( currentName && CKEDITOR.dtd[ currentName ] ) || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ); 185 currentDtd = currentName && 186 ( CKEDITOR.dtd[ currentName ] 187 || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ); 184 188 185 189 // If the element cannot be child of the current element. 186 if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) 190 if ( currentDtd // Fragment could receive any elements. 191 && !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) 187 192 { 188 // If this is the fragment node, just ignore this tag and add189 // its children.190 if ( !currentName )191 return;192 193 193 194 var reApply = false, 194 195 addPoint; // New position to start adding nodes. … … 330 331 index--; 331 332 } 332 333 } 334 335 if( tagName == 'body' ) 336 fixForBody = false; 333 337 }; 334 338 335 339 parser.onText = function( text ) … … 345 349 346 350 checkPending(); 347 351 348 if ( fixForBody && !currentNode.type ) 352 if ( fixForBody 353 && CKEDITOR.tools.trim( text ) 354 && ( !currentNode.type || currentNode.name == 'body' ) ) 349 355 this.onTagOpen( fixForBody, {} ); 350 356 351 357 // Shrinking consequential spaces into one single for all elements … … 375 381 var parent = currentNode.parent, 376 382 node = currentNode; 377 383 378 if ( fixForBody && !parent.type && !CKEDITOR.dtd.$body[ node.name ] ) 384 if ( fixForBody 385 && ( !parent.type || parent.name == 'body' ) 386 && !CKEDITOR.dtd.$body[ node.name ] ) 379 387 { 380 388 currentNode = parent; 381 389 parser.onTagOpen( fixForBody, {} ); … … 444 452 */ 445 453 writeHtml : function( writer, filter ) 446 454 { 455 // Filtering the root fragment. 456 if ( !this.name ) 457 filter && filter.onFragment( this ); 458 447 459 for ( var i = 0, len = this.children.length ; i < len ; i++ ) 448 460 this.children[i].writeHtml( writer, filter ); 449 461 } -
_source/plugins/htmldataprocessor/plugin.js
206 206 return html.replace( protectAttributeRegex, '$& _cke_saved_$1' ); 207 207 } 208 208 209 var protectStyleTagsRegex = /<(style)(?=[ >])[^>]*>[^<]*<\/\1>/gi; 210 var encodedTagsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi; 209 var protectTagContentsRegex = /<(style)(?=[ >])[^>]*>[^<]*<\/\1>|<(:?link|meta|base).*?>/gi, 210 encodedTagsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi; 211 212 var shelveTagNamesRegex = /(<\/?)((?:html|body|head|title).*?>)/gi, 213 unshelveTagNamesRegex = /(<\/?)cke_shelved:([^>]*>)/gi; 214 211 215 var protectElementNamesRegex = /(<\/?)((?:object|embed|param)[\s\S]*?>)/gi; 212 216 var protectSelfClosingRegex = /<cke:(param|embed)([\s\S]*?)\/?>/gi; 213 217 214 function protectStyleTagsMatch( match )218 function encodeMatched( match ) 215 219 { 216 220 return '<cke:encoded>' + encodeURIComponent( match ) + '</cke:encoded>'; 217 221 } 222 function unprotectEncodedTagsMatch( match, encoded ) 223 { 224 return decodeURIComponent( encoded ); 225 } 218 226 219 function protect StyleTags( html )227 function protectTagContents( html ) 220 228 { 221 return html.replace( protect StyleTagsRegex, protectStyleTagsMatch);229 return html.replace( protectTagContentsRegex, encodeMatched ); 222 230 } 223 function protectElementsNames( html )231 function unprotectTagContents( html ) 224 232 { 225 return html.replace( protectElementNamesRegex, '$1cke:$2');233 return html.replace( encodedTagsRegex, unprotectEncodedTagsMatch ); 226 234 } 227 function protectSelfClosingElements( html ) 235 236 function shelveTagNames( html, isUnShelve ) 228 237 { 229 return html.replace( protectSelfClosingRegex, '<cke:$1$2></cke:$1>' );238 return html.replace( shelveTagNamesRegex, '$1cke_shelved:$2' ); 230 239 } 231 240 232 function un protectEncodedTagsMatch( match, encoded)241 function unShelveTagNames( html ) 233 242 { 234 return decodeURIComponent( encoded);243 return html.replace( unshelveTagNamesRegex, '$1$2' ); 235 244 } 236 245 237 function unprotectEncodedTags( html )246 function protectElementsNames( html ) 238 247 { 239 return html.replace( encodedTagsRegex, unprotectEncodedTagsMatch);248 return html.replace( protectElementNamesRegex, '$1cke:$2'); 240 249 } 250 function protectSelfClosingElements( html ) 251 { 252 return html.replace( protectSelfClosingRegex, '<cke:$1$2></cke:$1>' ); 253 } 241 254 242 255 function protectSource( data, protectRegexes ) 243 256 { … … 295 308 dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules ); 296 309 dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules ); 297 310 dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules ); 298 }299 });300 311 301 CKEDITOR.htmlDataProcessor = function( editor )302 {303 this.editor = editor;312 // Full page specialized filters. 313 dataProcessor.fullPageHtmlFilter = dataProcessor.htmlFilter.clone(); 314 dataProcessor.fullPageDataFilter = dataProcessor.dataFilter.clone(); 304 315 305 this.writer = new CKEDITOR.htmlWriter(); 306 this.dataFilter = new CKEDITOR.htmlParser.filter(); 307 this.htmlFilter = new CKEDITOR.htmlParser.filter(); 308 }; 309 310 CKEDITOR.htmlDataProcessor.prototype = 311 { 312 toHtml : function( data, fixForBody ) 313 { 314 // The source data is already HTML, but we need to clean 315 // it up and apply the filter. 316 317 data = protectSource( data, this.editor.config.protectedSource ); 316 // The source data is already HTML, but we need to clean it up. 317 dataProcessor.on( 'htmlPreProcess', function( evt ) 318 { 319 var data = evt.data; 320 data = protectSource( data, this.editor.config.protectedSource ); 318 321 319 // Before anything, we must protect the URL attributes as the320 // browser may changing them when setting the innerHTML later in321 // the code.322 data = protectAttributes( data );322 // Before anything, we must protect the URL attributes as the 323 // browser may changing them when setting the innerHTML later in 324 // the code. 325 data = protectAttributes( data ); 323 326 324 // IE remvoes style tags from innerHTML. (#3710).325 if ( CKEDITOR.env.ie )326 data = protectStyleTags( data );327 // IE remvoes style tags from innerHTML. (#3710). 328 if ( CKEDITOR.env.ie ) 329 data = protectTagContents( data ); 327 330 328 // Certain elements has problem to go through DOM operation, protect329 // them by prefixing 'cke' namespace.(#3591)330 data = protectElementsNames( data );331 // Certain elements has problem to go through DOM operation, protect 332 // them by prefixing 'cke' namespace.(#3591) 333 data = protectElementsNames( data ); 331 334 332 // All none-IE browsers ignore self-closed custom elements,333 // protecting them into open-close.(#3591)334 data = protectSelfClosingElements( data );335 // All none-IE browsers ignore self-closed custom elements, 336 // protecting them into open-close.(#3591) 337 data = protectSelfClosingElements( data ); 335 338 336 // Call the browser to help us fixing a possibly invalid HTML 337 // structure. 338 var div = document.createElement( 'div' ); 339 // Add fake character to workaround IE comments bug. (#3801) 340 div.innerHTML = 'a' + data; 341 data = div.innerHTML.substr( 1 ); 339 data = shelveTagNames( data ); 340 // Call the browser to help us fixing a possibly invalid HTML 341 // structure. 342 var div = new CKEDITOR.dom.element( 'div' ); 343 // Add fake character to workaround IE comments bug. (#3801) 344 div.setHtml( 'a' + data ); 345 data = div.getHtml().substr( 1 ); 342 346 343 if ( CKEDITOR.env.ie ) 344 data = unprotectEncodedTags( data ); 347 data = unShelveTagNames( data ); 348 if ( CKEDITOR.env.ie ) 349 data = unprotectTagContents( data ); 345 350 346 // Now use our parser to make further fixes to the structure, as347 // well as apply the filter.348 var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data, fixForBody ),349 writer = new CKEDITOR.htmlParser.basicWriter();351 evt.data = data; 352 } ); 353 } 354 }); 350 355 351 fragment.writeHtml( writer, this.dataFilter ); 356 CKEDITOR.htmlDataProcessor = function( editor ) 357 { 358 this.editor = editor; 352 359 353 return writer.getHtml( true ); 354 }, 360 this.writer = new CKEDITOR.htmlWriter(); 361 this.basicWriter = new CKEDITOR.htmlParser.basicWriter(); 362 this.dataFilter = new CKEDITOR.htmlParser.filter(); 363 this.htmlFilter = new CKEDITOR.htmlParser.filter(); 364 }; 355 365 356 toDataFormat : function( html, fixForBody ) 357 { 358 var writer = this.writer, 359 fragment = CKEDITOR.htmlParser.fragment.fromHtml( html, fixForBody ); 366 CKEDITOR.htmlDataProcessor.prototype = 367 { 368 process : function( type, data, filter, writer, fixForBody ) 369 { 370 data = this.fire( type + 'PreProcess', data ); 360 371 372 // Now use our parser to make fixes to the structure, as 373 // well as apply the filter. 374 var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data, fixForBody ); 361 375 writer.reset(); 376 fragment.writeHtml( writer, filter ); 377 data = writer.getHtml( true ); 362 378 363 fragment.writeHtml( writer, this.htmlFilter ); 379 return this.fire( type + 'PostProcess', data ); 380 }, 364 381 365 return writer.getHtml( true ); 382 toFullPageHtml : function( data, fixForBody ) 383 { 384 data = this.fire( 'fullPageHtmlPreProcess', data ); 385 data = this.process( 'html', data, this.fullPageDataFilter, this.basicWriter, fixForBody ); 386 return this.fire( 'fullPageHtmlPostProcess', data ) 387 }, 388 389 toFullPageData : function( data, fixForBody ) 390 { 391 data = this.fire( 'fullPageDataPreProcess', data ); 392 data = this.process( 'dataFormat', data, this.fullPageHtmlFilter, this.writer, fixForBody ); 393 return this.fire( 'fullPageDataPostProcess', data ); 394 }, 395 396 toHtml : function( data, fixForBody ) 397 { 398 return this.process( 'html', data, this.dataFilter, this.basicWriter, fixForBody ); 399 }, 400 401 toDataFormat : function( html, fixForBody ) 402 { 403 return this.process( 'dataFormat', html, this.htmlFilter, this.writer, fixForBody ); 366 404 } 367 405 }; 406 407 CKEDITOR.event.implementOn( CKEDITOR.htmlDataProcessor.prototype, true ); 368 408 })(); 369 409 370 410 /**