Ticket #2976: 2976.2.patch
File 2976.2.patch, 6.7 KB (added by , 16 years ago) |
---|
-
_source/plugins/styles/plugin.js
519 519 var bookmark = range.createBookmark( true ), 520 520 startNode = range.document.getById( bookmark.startNode ); 521 521 522 if ( range.collapsed ) 522 523 var endNode = range.document.getById( bookmark.endNode ), 524 me = this; 525 526 /* 527 * Find out the style ancestor that needs to be broken down at startNode 528 * and endNode. 529 */ 530 function breakNodes() 523 531 { 524 /*525 * If the range is collapsed, try to remove the style from all ancestor526 * elements, until a block boundary is reached.527 */528 var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() );529 for ( var i = 0 , element ; i < startPath.elements.length && ( element = startPath.elements[i] ); i++ )532 var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() ), 533 endPath = endNode? 534 new CKEDITOR.dom.elementPath( endNode.getParent() ) : null, 535 breakStart = null, 536 breakEnd = null; 537 for ( var i = 0 ; i < startPath.elements.length ; i++ ) 530 538 { 539 var element = startPath.elements[ i ]; 540 531 541 if ( element == startPath.block || element == startPath.blockLimit ) 532 542 break; 533 543 534 if ( this.checkElementRemovable( element ) ) 535 { 536 /* 537 * Before removing the style node, there may be a sibling to the style node 538 * that's exactly the same to the one to be removed. To the user, it makes 539 * no difference that they're separate entities in the DOM tree. So, merge 540 * them before removal. 541 */ 542 mergeSiblings( element ); 543 removeFromElement( this, element ); 544 } 544 if ( me.checkElementRemovable( element ) ) 545 breakStart = element; 545 546 } 546 } 547 else 548 { 549 /* 550 * Now our range isn't collapsed. Lets walk from the start node to the end 551 * node via DFS and remove the styles one-by-one. 552 */ 553 var endNode = range.document.getById( bookmark.endNode ), 554 me = this; 555 556 /* 557 * Find out the style ancestor that needs to be broken down at startNode 558 * and endNode. 559 */ 560 function breakNodes() 547 548 for ( i = 0 ; endPath && ( i < endPath.elements.length ) ; i++ ) 561 549 { 562 var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() ), 563 endPath = new CKEDITOR.dom.elementPath( endNode.getParent() ), 564 breakStart = null, 565 breakEnd = null; 566 for ( var i = 0 ; i < startPath.elements.length ; i++ ) 567 { 568 var element = startPath.elements[ i ]; 550 element = endPath.elements[ i ]; 569 551 570 if ( element == startPath.block || element == startPath.blockLimit )571 552 if ( element == endPath.block || element == endPath.blockLimit ) 553 break; 572 554 573 if ( me.checkElementRemovable( element ) ) 574 breakStart = element; 575 } 576 for ( i = 0 ; i < endPath.elements.length ; i++ ) 577 { 578 element = endPath.elements[ i ]; 555 if ( me.checkElementRemovable( element ) ) 556 breakEnd = element; 557 } 579 558 580 if ( element == endPath.block || element == endPath.blockLimit ) 581 break; 582 583 if ( me.checkElementRemovable( element ) ) 584 breakEnd = element; 559 if ( breakEnd ) 560 endNode.breakParent( breakEnd ); 561 if ( breakStart ) 562 { 563 startNode.breakParent( breakStart ); 564 // Here it's necessary to repair the broken node if nothing inputed. 565 if ( range.collapsed ) 566 { 567 var checkingNode = startNode.getNext(); 568 569 // Merge the broken nodes once after selection change OR before switch mode. 570 function fixBroken( ev ){ 571 var sel = ev.editor.getSelection(); 572 sel.lock(); 573 mergeElements( checkingNode, checkingNode.getPrevious() ); 574 sel.unlock(); 575 ev.removeListener(); 576 } 577 setTimeout( function(){ 578 var editor = CKEDITOR.currentInstance; 579 editor.on( 'selectionChange', fixBroken ); 580 editor.on( 'unloadMode', fixBroken ); 581 }, 100 ); 585 582 } 586 587 if ( breakEnd )588 endNode.breakParent( breakEnd );589 if ( breakStart )590 startNode.breakParent( breakStart );591 583 } 592 breakNodes(); 584 } 585 breakNodes(); 593 586 594 // Now, do the DFS walk. 595 var currentNode = startNode.getNext(); 596 while ( !currentNode.equals( endNode ) ) 587 // If the range is not collapsed, DFS walk forward to remove any conflicting styles. 588 var currentNode = startNode.getNext(); 589 while ( endNode && !currentNode.equals( endNode ) ) 590 { 591 /* 592 * Need to get the next node first because removeFromElement() can remove 593 * the current node from DOM tree. 594 */ 595 var nextNode = currentNode.getNextSourceNode(); 596 if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) 597 597 { 598 // Remove style from element or overriding element. 599 if( currentNode.getName() == this.element ) 600 removeFromElement( this, currentNode ); 601 else 602 removeOverrides( currentNode, getOverrides( this )[ currentNode.getName() ] ); 603 598 604 /* 599 * Need to get the next node first because removeFromElement() can remove 600 * the current node from DOM tree. 605 * removeFromElement() may have merged the next node with something before 606 * the startNode via mergeSiblings(). In that case, the nextNode would 607 * contain startNode and we'll have to call breakNodes() again and also 608 * reassign the nextNode to something after startNode. 601 609 */ 602 var nextNode = currentNode.getNextSourceNode(); 603 if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) 610 if ( nextNode.type == CKEDITOR.NODE_ELEMENT && nextNode.contains( startNode ) ) 604 611 { 605 // Remove style from element or overriding element. 606 if( currentNode.getName() == this.element ) 607 removeFromElement( this, currentNode ); 608 else 609 removeOverrides( currentNode, getOverrides( this )[ currentNode.getName() ] ); 610 611 /* 612 * removeFromElement() may have merged the next node with something before 613 * the startNode via mergeSiblings(). In that case, the nextNode would 614 * contain startNode and we'll have to call breakNodes() again and also 615 * reassign the nextNode to something after startNode. 616 */ 617 if ( nextNode.type == CKEDITOR.NODE_ELEMENT && nextNode.contains( startNode ) ) 618 { 619 breakNodes(); 620 nextNode = startNode.getNext(); 621 } 612 breakNodes(); 613 nextNode = startNode.getNext(); 622 614 } 623 currentNode = nextNode;624 615 } 616 currentNode = nextNode; 625 617 } 626 618 627 619 range.moveToBookmark( bookmark );