Changeset 4636 for CKEditor/branches/versions/3.1.x
- Timestamp:
- 2009-12-09 17:16:43 (2 years ago)
- Location:
- CKEditor/branches/versions/3.1.x
- Files:
-
- 14 edited
- 1 copied
-
. (modified) (1 prop)
-
CHANGES.html (modified) (1 diff)
-
_samples/fullpage.html (copied) (copied from CKEditor/branches/features/fullpage/_samples/fullpage.html)
-
_samples/index.html (modified) (1 diff)
-
_source/core/config.js (modified) (1 diff)
-
_source/core/dom/element.js (modified) (1 diff)
-
_source/core/dtd.js (modified) (4 diffs)
-
_source/core/htmlparser/basicwriter.js (modified) (1 diff)
-
_source/core/htmlparser/cdata.js (modified) (1 diff)
-
_source/core/htmlparser/element.js (modified) (1 diff)
-
_source/core/htmlparser/fragment.js (modified) (5 diffs)
-
_source/plugins/htmldataprocessor/plugin.js (modified) (8 diffs)
-
_source/plugins/htmlwriter/plugin.js (modified) (4 diffs)
-
_source/plugins/preview/plugin.js (modified) (1 diff)
-
_source/plugins/wysiwygarea/plugin.js (modified) (4 diffs)
Legend:
- Unmodified
- Added
- Removed
-
CKEditor/branches/versions/3.1.x
- Property svn:mergeinfo changed
/CKEditor/branches/features/fullpage (added) merged: 4615-4635
- Property svn:mergeinfo changed
-
CKEditor/branches/versions/3.1.x/CHANGES.html
r4626 r4636 49 49 <li><a href="http://dev.fckeditor.net/ticket/4340">#4340</a> : Added the email protection option for link dialog.</li> 50 50 <li><a href="http://dev.fckeditor.net/ticket/4210">#4210</a> : Added CKEditor plugin for jQuery.</li> 51 <li><a href="http://dev.fckeditor.net/ticket/4067">#4067</a> : Introduced the full page editing support (from <html> to </html>).</li> 51 52 </ul> 52 53 <p> -
CKEditor/branches/versions/3.1.x/_samples/index.html
r4623 r4636 19 19 <li><a href="replacebyclass.html">Replace textareas by class name</a></li> 20 20 <li><a href="replacebycode.html">Replace textareas by code</a></li> 21 <li><a href="fullpage.html">Full page support (editing from <html> to </html>)</a></li> 21 22 </ul> 22 23 <h2> -
CKEditor/branches/versions/3.1.x/_source/core/config.js
r4587 r4636 168 168 169 169 /** 170 * Sets the 'id' attribute to be used on body if it doesn't have one. 171 * @type String 172 * @default '' 173 */ 174 bodyId : '', 175 176 /** 177 * Sets the 'class' attribute to be used on body if it doesn't have one. 178 * @type String 179 * @default '' 180 */ 181 bodyClass : '', 182 183 /** 170 184 * Indicates whether the contents to be edited are being inputted as a full 171 185 * HTML page. A full page includes the <html>, <head> and -
CKEditor/branches/versions/3.1.x/_source/core/dom/element.js
r4555 r4636 329 329 getHtml : function() 330 330 { 331 return this.$.innerHTML; 331 var retval = this.$.innerHTML; 332 // Strip <?xml:namespace> tags in IE. (#3341). 333 return CKEDITOR.env.ie ? retval.replace( /<\?[^>]*>/g, '' ) : retval; 332 334 }, 333 335 -
CKEditor/branches/versions/3.1.x/_source/core/dtd.js
r4578 r4636 33 33 CKEDITOR.dtd = (function() 34 34 { 35 var X = CKEDITOR.tools.extend,35 var X = CKEDITOR.tools.extend, 36 36 37 37 A = {isindex:1,fieldset: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 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}; 57 62 58 return /** @lends CKEDITOR.dtd */ {63 return /** @lends CKEDITOR.dtd */ { 59 64 60 65 // The "$" items have been added manually. 61 66 67 // List of elements living outside body. 68 $nonBodyContent: X(V,U,S), 69 62 70 /** 63 71 * List of block elements, like "p" or "div". … … 74 82 $blockLimit : { body:1,div:1,td:1,th:1,caption:1,form:1 }, 75 83 76 $body : X({script:1 }, block),84 $body : X({script:1,style:1}, block), 77 85 78 86 $cdata : {script:1,style:1}, … … 128 136 $tableContent : {caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1}, 129 137 138 html: U, 139 head: T, 140 style: N, 141 script: N, 142 body: P, 143 base: {}, 144 link: {}, 145 meta: {}, 146 title: N, 130 147 col : {}, 131 148 tr : {td:1,th:1}, -
CKEditor/branches/versions/3.1.x/_source/core/htmlparser/basicwriter.js
r3308 r4636 118 118 { 119 119 this._.output = []; 120 this._.indent = false; 120 121 }, 121 122 -
CKEditor/branches/versions/3.1.x/_source/core/htmlparser/cdata.js
r3712 r4636 20 20 */ 21 21 this.value = value; 22 23 22 }; 24 23 -
CKEditor/branches/versions/3.1.x/_source/core/htmlparser/element.js
r4556 r4636 38 38 39 39 var dtd = CKEDITOR.dtd, 40 isBlockLike = !!( dtd.$ block[ tagName ] || dtd.$listItem[ tagName ] || dtd.$tableContent[ tagName ] || dtd.$nonEditable[ tagName ] || tagName == 'br' ),40 isBlockLike = !!( dtd.$nonBodyContent[ tagName ] || dtd.$block[ tagName ] || dtd.$listItem[ tagName ] || dtd.$tableContent[ tagName ] || dtd.$nonEditable[ tagName ] || tagName == 'br' ), 41 41 isEmpty = !!dtd.$empty[ name ]; 42 42 -
CKEditor/branches/versions/3.1.x/_source/core/htmlparser/fragment.js
r4625 r4636 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; … … 180 182 } 181 183 182 var currentName = currentNode.name, 183 currentDtd = ( currentName && CKEDITOR.dtd[ currentName ] ) || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ); 184 var currentName = currentNode.name; 185 186 var currentDtd = currentName 187 && ( CKEDITOR.dtd[ currentName ] 188 || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ); 184 189 185 190 // If the element cannot be child of the current element. 186 if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) 187 { 188 // If this is the fragment node, just ignore this tag and add 189 // its children. 190 if ( !currentName ) 191 return; 191 if ( currentDtd // Fragment could receive any elements. 192 && !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) 193 { 192 194 193 195 var reApply = false, … … 315 317 currentNode = currentNode.parent; 316 318 } 319 320 if( tagName == 'body' ) 321 fixForBody = false; 317 322 }; 318 323 … … 330 335 checkPending(); 331 336 332 if ( fixForBody && !currentNode.type ) 337 if ( fixForBody 338 && ( !currentNode.type || currentNode.name == 'body' ) 339 && CKEDITOR.tools.trim( text ) ) 340 { 333 341 this.onTagOpen( fixForBody, {} ); 342 } 334 343 335 344 // Shrinking consequential spaces into one single for all elements … … 360 369 node = currentNode; 361 370 362 if ( fixForBody && !parent.type && !CKEDITOR.dtd.$body[ node.name ] ) 371 if ( fixForBody 372 && ( !parent.type || parent.name == 'body' ) 373 && !CKEDITOR.dtd.$body[ node.name ] ) 363 374 { 364 375 currentNode = parent; -
CKEditor/branches/versions/3.1.x/_source/plugins/htmldataprocessor/plugin.js
r4556 r4636 110 110 111 111 // All "_cke" attributes are to be ignored. 112 [ ( /^_cke.*/ ), '' ] 112 [ ( /^_cke.*/ ), '' ], 113 114 [ 'hidefocus', '' ] 113 115 ], 114 116 … … 117 119 $ : function( element ) 118 120 { 119 // Remove duplicated attributes - #3789.120 121 var attribs = element.attributes; 121 122 122 123 if ( attribs ) 123 124 { 125 // Elements marked as temporary are to be ignored. 126 if ( attribs.cke_temp ) 127 return false; 128 129 // Remove duplicated attributes - #3789. 124 130 var attributeNames = [ 'name', 'href', 'src' ], 125 131 savedAttributeName; … … 130 136 } 131 137 } 138 139 return element; 132 140 }, 133 141 … … 163 171 return false; 164 172 } 173 }, 174 175 body : function( element ) 176 { 177 delete element.attributes.spellcheck; 178 delete element.attributes.contenteditable; 179 }, 180 181 style : function( element ) 182 { 183 var child = element.children[ 0 ]; 184 child && child.value && ( child.value = CKEDITOR.tools.trim( child.value )); 185 186 if ( !element.attributes.type ) 187 element.attributes.type = 'text/css'; 165 188 } 166 189 }, … … 210 233 var protectAttributeRegex = /<(?:a|area|img|input)[\s\S]*?\s((?:href|src|name)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+)))/gi; 211 234 235 var protectElementsRegex = /(?:<style(?=[ >])[^>]*>[\s\S]*<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi, 236 encodedElementsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi; 237 238 var protectElementNamesRegex = /(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi, 239 unprotectElementNamesRegex = /(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi; 240 241 var protectSelfClosingRegex = /<cke:(param|embed)([\s\S]*?)\/?>/gi; 242 212 243 function protectAttributes( html ) 213 244 { … … 215 246 } 216 247 217 var protectStyleTagsRegex = /<(style)(?=[ >])[^>]*>[^<]*<\/\1>/gi; 218 var encodedTagsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi; 219 var protectElementNamesRegex = /(<\/?)((?:object|embed|param)[\s\S]*?>)/gi; 220 var protectSelfClosingRegex = /<cke:(param|embed)([\s\S]*?)\/?>/gi; 221 222 function protectStyleTagsMatch( match ) 223 { 224 return '<cke:encoded>' + encodeURIComponent( match ) + '</cke:encoded>'; 225 } 226 227 function protectStyleTags( html ) 228 { 229 return html.replace( protectStyleTagsRegex, protectStyleTagsMatch ); 230 } 248 function protectElements( html ) 249 { 250 return html.replace( protectElementsRegex, function( match ) 251 { 252 return '<cke:encoded>' + encodeURIComponent( match ) + '</cke:encoded>'; 253 }); 254 } 255 256 function unprotectElements( html ) 257 { 258 return html.replace( encodedElementsRegex, function( match, encoded ) 259 { 260 return decodeURIComponent( encoded ); 261 }); 262 } 263 231 264 function protectElementsNames( html ) 232 265 { 233 266 return html.replace( protectElementNamesRegex, '$1cke:$2'); 234 267 } 268 269 function unprotectElementNames( html ) 270 { 271 return html.replace( unprotectElementNamesRegex, '$1$2' ); 272 } 273 235 274 function protectSelfClosingElements( html ) 236 275 { 237 276 return html.replace( protectSelfClosingRegex, '<cke:$1$2></cke:$1>' ); 238 }239 240 function unprotectEncodedTagsMatch( match, encoded )241 {242 return decodeURIComponent( encoded );243 }244 245 function unprotectEncodedTags( html )246 {247 return html.replace( encodedTagsRegex, unprotectEncodedTagsMatch );248 }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 277 } 257 278 … … 264 285 encodeURIComponent( match ).replace( /--/g, '%2D%2D' ) + 265 286 '-->'; 287 }); 288 } 289 290 function unprotectRealComments( html ) 291 { 292 return html.replace( /<!--{cke_protected}{C}([\s\S]+?)-->/g, function( match, data ) 293 { 294 return decodeURIComponent( data ); 266 295 }); 267 296 } … … 356 385 data = protectAttributes( data ); 357 386 358 // IE remvoes style tags from innerHTML. (#3710).359 if ( CKEDITOR.env.ie)360 data = protectStyleTags( data );387 // Protect elements than can't be set inside a DIV. E.g. IE removes 388 // style tags from innerHTML. (#3710) 389 data = protectElements( data ); 361 390 362 391 // Certain elements has problem to go through DOM operation, protect 363 // them by prefixing 'cke' namespace. (#3591)392 // them by prefixing 'cke' namespace. (#3591) 364 393 data = protectElementsNames( data ); 365 394 366 395 // All none-IE browsers ignore self-closed custom elements, 367 // protecting them into open-close. (#3591)396 // protecting them into open-close. (#3591) 368 397 data = protectSelfClosingElements( data ); 369 398 370 399 // Call the browser to help us fixing a possibly invalid HTML 371 400 // structure. 372 var div = document.createElement( 'div' );401 var div = new CKEDITOR.dom.element( 'div' ); 373 402 // Add fake character to workaround IE comments bug. (#3801) 374 div.innerHTML = 'a' + data; 375 data = div.innerHTML.substr( 1 ); 376 377 if ( CKEDITOR.env.ie ) 378 data = unprotectEncodedTags( data ); 403 div.setHtml( 'a' + data ); 404 data = div.getHtml().substr( 1 ); 405 406 // Unprotect "some" of the protected elements at this point. 407 data = unprotectElementNames( data ); 408 409 data = unprotectElements( data ); 379 410 380 411 // Restore the comments that have been protected, in this way they -
CKEditor/branches/versions/3.1.x/_source/plugins/htmlwriter/plugin.js
r3676 r4636 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, … … 79 79 }); 80 80 } 81 81 82 this.setRules( 'br', 82 83 { 83 84 breakAfterOpen : true 84 85 }); 86 87 this.setRules( 'title', 88 { 89 indent : false, 90 breakAfterOpen : false 91 }); 92 93 this.setRules( 'style', 94 { 95 indent : false, 96 breakBeforeClose : true 97 }); 98 85 99 // Disable indentation on <pre>. 86 100 this.setRules( 'pre', 87 {88 indent: false89 });101 { 102 indent: false 103 }); 90 104 }, 91 105 … … 263 277 * </ul> 264 278 * 265 * All rules default to "false". 279 * All rules default to "false". Each call to the function overrides 280 * already present rules, leaving the undefined untouched. 266 281 * 267 282 * By default, all elements available in the {@link CKEDITOR.dtd.$block), … … 284 299 setRules : function( tagName, rules ) 285 300 { 286 this._.rules[ tagName ] = rules; 301 var currentRules = this._.rules[ tagName ]; 302 303 if ( currentRules ) 304 CKEDITOR.tools.extend( currentRules, rules, true ); 305 else 306 this._.rules[ tagName ] = rules; 287 307 } 288 308 } -
CKEditor/branches/versions/3.1.x/_source/plugins/preview/plugin.js
r4621 r4636 17 17 { 18 18 var sHTML, 19 config = editor.config, 20 baseTag = config.baseHref ? '<base href="' + config.baseHref + '"/>' : '', 19 21 isCustomDomain = CKEDITOR.env.isCustomDomain(); 20 if ( editor.config.fullPage ) 21 sHTML = editor.getData(); 22 23 if ( config.fullPage ) 24 { 25 sHTML = editor.getData() 26 .replace( /<head>/, '$&' + baseTag ) 27 .replace( /[^>]*(?=<\/title>)/, editor.lang.preview ); 28 } 22 29 else 23 30 { 24 31 var bodyHtml = '<body ', 25 body = CKEDITOR.document.getBody(), 26 baseTag = ( editor.config.baseHref.length > 0 ) ? '<base href="' + editor.config.baseHref + '" _cktemp="true"></base>' : ''; 32 body = editor.document.getBody(); 27 33 28 34 if ( body.getAttribute( 'id' ) ) -
CKEditor/branches/versions/3.1.x/_source/plugins/wysiwygarea/plugin.js
r4621 r4636 11 11 (function() 12 12 { 13 /** 14 * List of elements in which has no way to move editing focus outside. 15 */ 13 // List of elements in which has no way to move editing focus outside. 16 14 var nonExitableElementNames = { table:1,pre:1 }; 15 17 16 // 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;17 var emptyParagraphRegexp = /\s*<(p|div|address|h\d|center)[^>]*>\s*(?:<br[^>]*>| |\u00A0| )\s*(:?<\/\1>)?\s*(?=$|<\/body>)/gi; 19 18 20 19 function onInsertHtml( evt ) … … 583 582 isLoadingData = true; 584 583 584 var config = editor.config, 585 fullPage = config.fullPage, 586 docType = config.docType; 587 588 // Build the additional stuff to be included into <head>. 589 var headExtra = 590 '<style type="text/css" cke_temp="1">' + 591 editor._.styles.join( '\n' ) + 592 '</style>'; 593 594 !fullPage && ( headExtra = 595 CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss ) + 596 headExtra ); 597 598 var baseTag = config.baseHref ? '<base href="' + config.baseHref + '" cke_temp="1" />' : ''; 599 600 if ( fullPage ) 601 { 602 // Search and sweep out the doctype declaration. 603 data = data.replace( /<!DOCTYPE[^>]*>/i, function( match ) 604 { 605 editor.docType = docType = match; 606 return ''; 607 }); 608 } 609 585 610 // Get the HTML version of the data. 586 611 if ( editor.dataProcessor ) 587 {588 612 data = editor.dataProcessor.toHtml( data, fixForBody ); 589 } 590 591 data = 592 editor.config.docType + 593 '<html dir="' + editor.config.contentsLangDirection + '">' + 594 '<head>' + 595 CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss ) + 596 '<style type="text/css" _fcktemp="true">' + 597 editor._.styles.join( '\n' ) + 598 '</style>'+ 599 '</head>' + 600 '<body>' + 601 data + 602 '</body>' + 603 '</html>' + 604 activationScript; 613 614 if ( fullPage ) 615 { 616 // Check if the <body> tag is available. 617 if ( !(/<body[\s|>]/).test( data ) ) 618 data = '<body>' + data; 619 620 // Check if the <html> tag is available. 621 if ( !(/<html[\s|>]/).test( data ) ) 622 data = '<html>' + data + '</html>'; 623 624 // Check if the <head> tag is available. 625 if ( !(/<head[\s|>]/).test( data ) ) 626 data = data.replace( /<html[^>]*>/, '$&<head><title></title></head>' ) ; 627 628 // The base must be the first tag in the HEAD, e.g. to get relative 629 // links on styles. 630 baseTag && ( data = data.replace( /<head>/, '$&' + baseTag ) ); 631 632 // Inject the extra stuff into <head>. 633 // Attention: do not change it before testing it well. (V2) 634 // This is tricky... if the head ends with <meta ... content type>, 635 // Firefox will break. But, it works if we place our extra stuff as 636 // the last elements in the HEAD. 637 data = data.replace( /<\/head\s*>/, headExtra + '$&' ); 638 639 // Add the DOCTYPE back to it. 640 data = docType + data; 641 } 642 else 643 { 644 data = 645 config.docType + 646 '<html dir="' + config.contentsLangDirection + '">' + 647 '<head>' + 648 baseTag + 649 headExtra + 650 '</head>' + 651 '<body' + ( config.bodyId ? ' id="' + config.bodyId + '"' : '' ) + 652 ( config.bodyClass ? ' class="' + config.bodyClass + '"' : '' ) + 653 '>' + 654 data + 655 '</html>'; 656 } 657 658 data += activationScript; 605 659 606 660 CKEDITOR._[ 'contentDomReady' + editor.name ] = contentDomReady; … … 610 664 getData : function() 611 665 { 612 var data = iframe.getFrameDocument().getBody().getHtml(); 666 var config = editor.config, 667 fullPage = config.fullPage, 668 docType = fullPage && editor.docType, 669 doc = iframe.getFrameDocument(); 670 671 var data = fullPage 672 ? doc.getDocumentElement().getOuterHtml() 673 : doc.getBody().getHtml(); 613 674 614 675 if ( editor.dataProcessor ) … … 616 677 617 678 // Strip the last blank paragraph within document. 618 if ( editor.config.ignoreEmptyParagraph )679 if ( config.ignoreEmptyParagraph ) 619 680 data = data.replace( emptyParagraphRegexp, '' ); 681 682 if ( docType ) 683 data = docType + '\n' + data; 620 684 621 685 return data;
Note: See TracChangeset
for help on using the changeset viewer.
