Ticket #3165: 3165_3.patch
File 3165_3.patch, 8.1 KB (added by , 14 years ago) |
---|
-
_source/plugins/enterkey/plugin.js
101 101 if ( !isStartOfBlock && !isEndOfBlock ) 102 102 { 103 103 // If the next block is an <li> with another list tree as the first 104 // child, we'll need to append a placeholderor the list item104 // child, we'll need to append a filler (<br>/NBSP) or the list item 105 105 // wouldn't be editable. (#1420) 106 if ( nextBlock.is( 'li' ) && ( node = nextBlock.getFirst() ) 107 && node.is && node.is( 'ul', 'ol') ) 108 nextBlock.insertBefore( doc.createText( '\xa0' ), node ); 106 if ( nextBlock.is( 'li' ) 107 && ( node = nextBlock.getFirst( CKEDITOR.dom.walker.invisible( true ) ) ) 108 && node.is && node.is( 'ul', 'ol' ) ) 109 ( CKEDITOR.env.ie ? doc.createText( '\xa0' ) : doc.createElement( 'br' ) ).insertBefore( node ); 109 110 110 111 // Move the selection to the end block. 111 112 if ( nextBlock ) -
_source/core/dom/element.js
627 627 628 628 /** 629 629 * Gets the first child node of this element. 630 * @param {Function} evaluator Filtering the result node. 630 631 * @returns {CKEDITOR.dom.node} The first child node or null if not 631 632 * available. 632 633 * @example … … 634 635 * var first = <b>element.getFirst()</b>; 635 636 * alert( first.getName() ); // "b" 636 637 */ 637 getFirst : function( )638 getFirst : function( evaluator ) 638 639 { 639 var $ = this.$.firstChild; 640 return $ ? new CKEDITOR.dom.node( $ ) : null; 640 var first = this.$.firstChild, 641 retval = first && new CKEDITOR.dom.node( first ); 642 if ( retval && evaluator && !evaluator( retval ) ) 643 retval = retval.getNext( evaluator ); 644 645 return retval; 641 646 }, 642 647 643 648 /** -
_source/plugins/selection/plugin.js
986 986 // will expand and that the cursor will be blinking on the right place. 987 987 // Actually, we are using this flag just to avoid using this hack in all 988 988 // situations, but just on those needed. 989 isStartMarkerAlone = forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ); 989 var next = startNode.getNext(); 990 isStartMarkerAlone = ( !( next && next.getText && next.getText() && !CKEDITOR.tools.trim( next.getText() ) ) 991 && ( forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) ); 990 992 991 993 // Append a temporary <span></span> before the selection. 992 994 // This is needed to avoid IE destroying selections inside empty -
_source/core/dom/walker.js
408 408 return isReject ^ isWhitespace; 409 409 }; 410 410 }; 411 412 /** 413 * Whether the node is invisible in wysiwyg mode. 414 * @param isReject 415 */ 416 CKEDITOR.dom.walker.invisible = function( isReject ) 417 { 418 var whitespace = CKEDITOR.dom.walker.whitespaces(); 419 return function( node ) 420 { 421 // Nodes that take no spaces in wysiwyg: 422 // 1. White-spaces but not including NBSP; 423 // 2. Empty inline elements, e.g. <b></b> we're checking here 'offsetHeight' 424 // instead of width for properly excluding all sorts of empty paragraph, e.g. <br />. 425 var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight; 426 return isReject ^ isInvisible; 427 }; 428 }; 429 411 430 })(); -
_source/plugins/htmldataprocessor/plugin.js
7 7 { 8 8 // Regex to scan for at the end of blocks, which are actually placeholders. 9 9 // Safari transforms the to \xa0. (#4172) 10 var tailNbspRegex = /^[\t\r\n ]*(?: |\xa0)$/; 11 10 var tailNbspRegex = /[\t\r\n ]*(?: |\xa0)[\t\r\n ]*$/; 12 11 var protectedSourceMarker = '{cke_protected}'; 12 var dtd = CKEDITOR.dtd; 13 13 14 14 15 15 // Return the last non-space child node of the block (#4344). … … 22 22 return last; 23 23 } 24 24 25 function indexOfFirstChildElement( element, tagNameList ) 26 { 27 var children = element.children, 28 child, 29 length = children.length; 30 for ( var i = 0; i < length; i++ ) 31 { 32 child = children[ i ]; 33 if( child.name && ( child.name in tagNameList ) ) 34 return i; 35 } 36 } 37 25 38 function trimFillers( block, fromSource ) 26 39 { 27 40 // If the current node is a block, and if we're converting from source or … … 35 48 if ( ( fromSource || !CKEDITOR.env.ie ) && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.name == 'br' ) 36 49 children.pop(); 37 50 if ( lastChild.type == CKEDITOR.NODE_TEXT && tailNbspRegex.test( lastChild.value ) ) 38 children.pop();51 lastChild.value = lastChild.value.replace( tailNbspRegex, '' ); 39 52 } 40 53 } 41 54 … … 66 79 block.add( new CKEDITOR.htmlParser.text( '\xa0' ) ); 67 80 } 68 81 69 var dtd = CKEDITOR.dtd; 82 function getExtendNestedListFilter( isHtmlFilter ) 83 { 84 return function( listItem ) 85 { 86 var children = listItem.children, 87 firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ), 88 firstNestedList = children[ firstNestedListIndex ], 89 nodeBefore = firstNestedList && firstNestedList.previous, 90 tailNbspmatch; 70 91 92 if( nodeBefore 93 && ( nodeBefore.name && nodeBefore.name == 'br' 94 || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) ) 95 { 96 var fillerNode = nodeBefore; 97 98 // Always use 'nbsp' as filler node if we found a nested list appear 99 // in front of a list item. 100 if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] ) 101 children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ? 102 new CKEDITOR.htmlParser.text( '\xa0' ) : 103 new CKEDITOR.htmlParser.element( 'br', {} ); 104 105 // Otherwise the filler is not needed anymore. 106 else if ( fillerNode.name == 'br' ) 107 children.splice( firstNestedListIndex - 1, 1 ); 108 else 109 fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' ); 110 } 111 112 }; 113 } 114 71 115 // Find out the list of block-like tags that can contain <br>. 72 116 var blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$block, dtd.$listItem, dtd.$tableContent ); 73 117 for ( var i in blockLikeTags ) … … 93 137 for ( i in blockLikeTags ) 94 138 defaultDataBlockFilterRules.elements[ i ] = extendBlockForDisplay; 95 139 140 var defaultListDataFilterRules = { elements : {} }; 141 for( i in dtd.$listItem ) 142 defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter(); 143 96 144 var defaultHtmlFilterRules = 97 145 { 98 146 elementNames : … … 189 237 for ( i in blockLikeTags ) 190 238 defaultHtmlBlockFilterRules.elements[ i ] = extendBlockForOutput; 191 239 240 var defaultListHtmlFilterRules = { elements : {} }; 241 for( i in dtd.$listItem ) 242 defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true ); 243 192 244 if ( CKEDITOR.env.ie ) 193 245 { 194 246 // IE outputs style attribute in capital letters. We should convert … … 293 345 294 346 dataProcessor.dataFilter.addRules( defaultDataFilterRules ); 295 347 dataProcessor.dataFilter.addRules( defaultDataBlockFilterRules ); 348 dataProcessor.dataFilter.addRules( defaultListDataFilterRules ); 296 349 dataProcessor.htmlFilter.addRules( defaultHtmlFilterRules ); 297 350 dataProcessor.htmlFilter.addRules( defaultHtmlBlockFilterRules ); 351 dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules ); 298 352 } 299 353 }); 300 354