Ticket #2886: 2886_3.patch
File 2886_3.patch, 10.5 KB (added by , 16 years ago) |
---|
-
_source/plugins/htmldataprocessor/plugin.js
5 5 6 6 (function() 7 7 { 8 function extendBlocksForDisplay( block ) 9 { 10 if ( !block.addedBlockExtensor ) 11 { 12 if ( !CKEDITOR.env.ie ) 13 block.children.push( new CKEDITOR.htmlParser.element( 'br', {} ) ); 14 else 15 block.children.push( new CKEDITOR.htmlParser.text( '\xa0' ) ); 16 17 block.addedBlockExtensor = true; 18 } 19 } 20 21 function extendBlocksForOutput( block ) 22 { 23 block.children.push( new CKEDITOR.htmlParser.text( '\xa0' ) ); 24 } 25 8 26 var defaultDataFilterRules = 9 27 { 10 28 elementNames : … … 18 36 // Event attributes (onXYZ) must not be directly set. They can become 19 37 // active in the editing area (IE|WebKit). 20 38 [ ( /^on/ ), '_cke_pa_on' ] 21 ] 39 ], 40 41 lastNodeOfBlock : 42 { 43 br : extendBlocksForDisplay 44 }, 45 46 emptyBlock : 47 { 48 $ : extendBlocksForDisplay 49 } 22 50 }; 23 51 24 52 /** … … 33 61 }; 34 62 35 63 var defaultHtmlFilterRules = 36 37 38 39 40 64 { 65 elementNames : 66 [ 67 // Remove the "cke:" namespace prefix. 68 [ ( /^cke:/ ), '' ], 41 69 42 43 44 70 // Ignore <?xml:namespace> tags. 71 [ ( /^\?xml:namespace$/ ), '' ] 72 ], 45 73 46 47 48 49 74 attributeNames : 75 [ 76 // Attributes saved for changes and protected attributes. 77 [ ( /^_cke_(saved|pa)_/ ), '' ], 50 78 51 52 53 79 // All "_cke" attributes are to be ignored. 80 [ ( /^_cke.*/ ), '' ] 81 ], 54 82 55 elements : 83 elements : 84 { 85 embed : function( element ) 56 86 { 57 embed : function( element ) 58 { 59 var parent = element.parent; 87 var parent = element.parent; 60 88 61 // If the <embed> is child of a <object>, copy the width 62 // and height attributes from it. 63 if ( parent && parent.name == 'object' ) 64 { 65 element.attributes.width = parent.attributes.width; 66 element.attributes.height = parent.attributes.height; 67 } 68 }, 69 70 img : function( element ) 89 // If the <embed> is child of a <object>, copy the width 90 // and height attributes from it. 91 if ( parent && parent.name == 'object' ) 71 92 { 72 var attribs = element.attributes; 93 element.attributes.width = parent.attributes.width; 94 element.attributes.height = parent.attributes.height; 95 } 96 }, 73 97 74 if ( attribs._cke_saved_name ) 75 delete attribs.name; 76 if ( attribs._cke_saved_src ) 77 delete attribs.src; 78 }, 98 img : function( element ) 99 { 100 var attribs = element.attributes; 79 101 80 a : function( element ) 81 { 82 var attribs = element.attributes; 102 if ( attribs._cke_saved_name ) 103 delete attribs.name; 104 if ( attribs._cke_saved_src ) 105 delete attribs.src; 106 }, 83 107 84 if ( attribs._cke_saved_name ) 85 delete attribs.name; 86 if ( attribs._cke_saved_href ) 87 delete attribs.href; 88 }, 108 a : function( element ) 109 { 110 var attribs = element.attributes; 89 111 90 i nput : removeName,91 textarea : removeName,92 select : removeName,93 form : removeName112 if ( attribs._cke_saved_name ) 113 delete attribs.name; 114 if ( attribs._cke_saved_href ) 115 delete attribs.href; 94 116 }, 95 117 96 attributes : 118 input : removeName, 119 textarea : removeName, 120 select : removeName, 121 form : removeName 122 }, 123 124 attributes : 125 { 126 'class' : function( value, element ) 97 127 { 98 'class' : function( value, element ) 99 { 100 // Remove all class names starting with "cke_". 101 return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false; 102 } 128 // Remove all class names starting with "cke_". 129 return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false; 103 130 } 104 } ;131 }, 105 132 133 lastNodeOfBlock : 134 { 135 br : extendBlocksForOutput 136 }, 137 138 emptyBlock : 139 { 140 $ : extendBlocksForOutput 141 } 142 }; 143 106 144 if ( CKEDITOR.env.ie ) 107 145 { 108 146 // IE outputs style attribute in capital letters. We should convert -
_source/core/htmlparser/filter.js
5 5 6 6 (function() 7 7 { 8 function applyElementFilter( filters, element, filterArgs, callback ) 9 { 10 var filter, ret; 11 12 for ( var i = 0 ; i < 2 ; i++ ) 13 { 14 filter = filters[ i ]; 15 if ( filter ) 16 { 17 ret = filter.filter.apply( filter, filterArgs ); 18 19 if ( ret === false ) 20 return null; 21 22 if ( ret && ret != block ) 23 return callback.call( this, ret ); 24 } 25 } 26 27 return element; 28 } 29 8 30 CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( 9 31 { 10 32 $ : function( rules ) … … 14 36 elementNames : [], 15 37 attributeNames : [], 16 38 elements : { $length : 0 }, 17 attributes : { $length : 0 } 39 attributes : { $length : 0 }, 40 lastNodeOfBlock : { $length : 0 }, 41 emptyBlock : { $length : 0 } 18 42 }; 19 43 20 44 if ( rules ) … … 40 64 // Add the attributes. 41 65 addNamedItems( this._.attributes, rules.attributes, priority ); 42 66 67 // Add the last node handlers. 68 addNamedItems( this._.lastNodeOfBlock, rules.lastNodeOfBlock, priority ); 69 70 // Add empty block handlers. 71 addNamedItems( this._.emptyBlock, rules.emptyBlock, priority ); 72 43 73 // Add the text. 44 74 this._.text = transformNamedItem( this._.text, rules.text, priority ) || this._.text; 45 75 … … 74 104 // We must apply filters set to the specific element name as 75 105 // well as those set to the generic $ name. So, add both to an 76 106 // array and process them in a small loop. 77 var filters = [ this._.elements[ element.name ], this._.elements.$ ], 78 filter, ret; 79 80 for ( var i = 0 ; i < 2 ; i++ ) 81 { 82 filter = filters[ i ]; 83 if ( filter ) 84 { 85 ret = filter.filter( element, this ); 86 87 if ( ret === false ) 88 return null; 89 90 if ( ret && ret != element ) 91 return this.onElement( ret ); 92 } 93 } 94 95 return element; 107 var filters = [ this._.elements[ element.name ], this._.elements.$ ]; 108 return applyElementFilter.call( this, filters, element, [ element, this ], this.onElement ); 96 109 }, 97 110 98 111 onAttribute : function( element, name, value ) … … 111 124 } 112 125 113 126 return value; 127 }, 128 129 onLastNodeOfBlock : function( block, lastNode ) 130 { 131 var filter = this._.lastNodeOfBlock[ lastNode.name || lastNode.type ]; 132 133 if ( filter ) 134 { 135 var retval = filter.filter( block, lastNode, this ); 136 137 if ( retval === false ) 138 return false; 139 140 if ( typeof retval != 'undefined' ) 141 return retval; 142 } 143 144 return lastNode; 145 }, 146 147 onEmptyBlock : function( block ) 148 { 149 var filters = [ this._.emptyBlock[ block.name ], this._.emptyBlock.$ ]; 150 return applyElementFilter.call( this, filters, block, [ block, this ], this.onEmptyBlock ); 114 151 } 115 152 } 116 153 }); -
_source/core/htmlparser/element.js
121 121 122 122 element.name = writeName; 123 123 124 if ( this._.isBlockLike && this.children.length < 1 ) 125 { 126 if ( !( element = filter.onEmptyBlock( element ) ) ) 127 return; 128 } 129 124 130 if ( !( element = filter.onElement( element ) ) ) 125 131 return; 126 132 -
_source/core/htmlparser/fragment.js
47 47 {table:1,ul:1,ol:1,dl:1}, 48 48 CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl ); 49 49 50 // Regex to scan for at the end of blocks, which is actually placeholders. 51 var tailNbspRegex = /^[\t\r\n ]* $/; 52 50 53 /** 51 54 * Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string. 52 55 * @param {String} fragmentHtml The HTML to be parsed, filling the fragment. … … 117 120 currentNode = savedCurrent; 118 121 } 119 122 120 // Rtrim empty spaces on block end boundary. (#3585)121 123 if ( element._.isBlockLike ) 122 124 { 123 124 var length = element.children.length,125 lastChild = element.children[length - 1 ],125 // Rtrim empty spaces on block end boundary. (#3585) 126 var children = element.children, 127 lastChild = children[ children.length - 1 ], 126 128 text; 127 129 if ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT ) 128 130 { 129 131 if ( !( text = CKEDITOR.tools.rtrim( lastChild.value ) ) ) 130 element.children.length = length -1;132 children.pop(); 131 133 else 132 134 lastChild.value = text; 133 135 } 136 137 // If the current node is a block, and the current browser is not IE; then 138 // search for and remove the tailing BR node, if any. (#2862) 139 lastChild = children[ children.length - 1 ]; 140 if ( lastChild ) 141 { 142 if ( !CKEDITOR.env.ie && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br' ) 143 children.pop(); 144 if ( lastChild.type == CKEDITOR.NODE_TEXT && tailNbspRegex.test( lastChild.value ) ) 145 children.pop(); 146 } 134 147 } 135 148 136 149 target.add( element ); … … 394 407 */ 395 408 writeHtml : function( writer, filter ) 396 409 { 397 for ( var i = 0, len = this.children.length ; i < len ; i++ ) 410 var isBlockLike = ( this.type == CKEDITOR.NODE_ELEMENT && this._.isBlockLike ); 411 412 for ( var i = 0 ; i < this.children.length ; i++ ) 413 { 414 // Apply filter on the last node of a block. 415 if ( isBlockLike && i == this.children.length - 1 ) 416 { 417 var retval = filter.onLastNodeOfBlock( this, this.children[i] ); 418 if ( !retval ) 419 break; 420 this.children[i] = retval; 421 } 422 398 423 this.children[i].writeHtml( writer, filter ); 424 } 399 425 } 400 426 }; 401 427 })();