Ticket #3165: 3165_4.patch
File 3165_4.patch, 7.1 KB (added by , 15 years ago) |
---|
-
_source/plugins/list/plugin.js
539 539 } 540 540 }; 541 541 542 var dtd = CKEDITOR.dtd; 543 var tailNbspRegex = /[\t\r\n ]*(?: |\xa0)$/; 544 545 function indexOfFirstChildElement( element, tagNameList ) 546 { 547 var children = element.children, 548 child, 549 length = children.length; 550 for ( var i = 0; i < length; i++ ) 551 { 552 child = children[ i ]; 553 if( child.name && ( child.name in tagNameList ) ) 554 return i; 555 } 556 } 557 558 function getExtendNestedListFilter( isHtmlFilter ) 559 { 560 // An element filter function that corrects nested list start in an empty 561 // list item for better displaying/outputting. (#3165) 562 return function( listItem ) 563 { 564 var children = listItem.children, 565 firstNestedListIndex = indexOfFirstChildElement( listItem, dtd.$list ), 566 firstNestedList = children[ firstNestedListIndex ], 567 nodeBefore = firstNestedList && firstNestedList.previous, 568 tailNbspmatch; 569 570 if( nodeBefore 571 && ( nodeBefore.name && nodeBefore.name == 'br' 572 || nodeBefore.value && ( tailNbspmatch = nodeBefore.value.match( tailNbspRegex ) ) ) ) 573 { 574 var fillerNode = nodeBefore; 575 576 // Always use 'nbsp' as filler node if we found a nested list appear 577 // in front of a list item. 578 if ( !( tailNbspmatch && tailNbspmatch.index ) && fillerNode == children[ 0 ] ) 579 children[ 0 ] = ( isHtmlFilter || CKEDITOR.env.ie ) ? 580 new CKEDITOR.htmlParser.text( '\xa0' ) : 581 new CKEDITOR.htmlParser.element( 'br', {} ); 582 583 // Otherwise the filler is not needed anymore. 584 else if ( fillerNode.name == 'br' ) 585 children.splice( firstNestedListIndex - 1, 1 ); 586 else 587 fillerNode.value = fillerNode.value.replace( tailNbspRegex, '' ); 588 } 589 590 }; 591 } 592 593 var defaultListDataFilterRules = { elements : {} }; 594 for( var i in dtd.$listItem ) 595 defaultListDataFilterRules.elements[ i ] = getExtendNestedListFilter(); 596 597 var defaultListHtmlFilterRules = { elements : {} }; 598 for( i in dtd.$listItem ) 599 defaultListHtmlFilterRules.elements[ i ] = getExtendNestedListFilter( true ); 600 542 601 CKEDITOR.plugins.add( 'list', 543 602 { 544 603 init : function( editor ) … … 566 625 editor.on( 'selectionChange', CKEDITOR.tools.bind( onSelectionChange, bulletedListCommand ) ); 567 626 }, 568 627 628 afterInit : function ( editor ) 629 { 630 var dataProcessor = editor.dataProcessor; 631 if( dataProcessor ) 632 { 633 dataProcessor.dataFilter.addRules( defaultListDataFilterRules ); 634 dataProcessor.htmlFilter.addRules( defaultListHtmlFilterRules ); 635 } 636 }, 637 569 638 requires : [ 'domiterator' ] 570 639 } ); 571 640 })(); -
_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
952 952 } 953 953 }; 954 954 })(); 955 ( function() 956 { 957 var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ); 958 var fillerTextRegex = /\ufeff|\u00a0/; 955 959 956 960 CKEDITOR.dom.range.prototype.select = 957 961 CKEDITOR.env.ie ? … … 996 1000 // will expand and that the cursor will be blinking on the right place. 997 1001 // Actually, we are using this flag just to avoid using this hack in all 998 1002 // situations, but just on those needed. 999 isStartMarkerAlone = forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ); 1003 var next = startNode.getNext( notWhitespaces ); 1004 isStartMarkerAlone = ( !( next && next.getText && next.getText().match( fillerTextRegex ) ) // already a filler there? 1005 && ( forceExpand || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) ); 1000 1006 1001 1007 // Append a temporary <span></span> before the selection. 1002 1008 // This is needed to avoid IE destroying selections inside empty … … 1080 1086 selection.removeAllRanges(); 1081 1087 selection.addRange( nativeRange ); 1082 1088 }; 1089 } )(); -
_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 424 // 'offsetHeight' instead of 'offsetWidth' for properly excluding 425 // all sorts of empty paragraph, e.g. <br />. 426 var isInvisible = whitespace( node ) || node.is && !node.$.offsetHeight; 427 return isReject ^ isInvisible; 428 }; 429 }; 430 411 431 })();