Ticket #3309: 3309.patch
File 3309.patch, 6.3 KB (added by , 15 years ago) |
---|
-
_source/core/dom/documentfragment.js
43 43 'getDocument' : 1, 44 44 'getChildCount' : 1, 45 45 'getChild' : 1, 46 'getChildren' : 1 46 'getChildren' : 1, 47 'type' : 1 47 48 } ); -
_source/plugins/styles/plugin.js
516 516 */ 517 517 range.enlarge( CKEDITOR.ENLARGE_ELEMENT ); 518 518 519 var bookmark = range.createBookmark( true),520 startNode = range.document.getById( bookmark.startNode );519 var bookmark = range.createBookmark(), 520 startNode = bookmark.startNode; 521 521 522 522 if ( range.collapsed ) 523 523 { … … 531 531 if ( element == startPath.block || element == startPath.blockLimit ) 532 532 break; 533 533 534 if ( this.checkElementRemovable( element ) ) 534 var newStyleRange, 535 startOfElement = range.checkBoundaryOfElement( CKEDITOR.START_OF_ELEMENT ), 536 endOfElement = range.checkBoundaryOfElement( CKEDITOR.END_OF_ELEMENT ); 537 // Moving the selection outside the styles instead of remove the whole tag.(#3309) 538 if ( startOfElement || endOfElement ) 539 { 540 // Range is guaranteed to be collapsed inside the inner-most inline element, 541 // so simply start from a cloned range. 542 if( !newStyleRange ) 543 newStyleRange = range.clone(); 544 // Include the to-be-removed elements. 545 if ( this.checkElementRemovable( element ) ) 546 newStyleRange[ startOfElement ? 547 'setStartBefore' : 'setEndAfter'].call( newStyleRange, element ); 548 } 549 else if ( this.checkElementRemovable( element ) ) 535 550 { 536 551 /* 537 552 * Before removing the style node, there may be a sibling to the style node … … 543 558 removeFromElement( this, element ); 544 559 } 545 560 } 546 } 561 // Indicate target style found when we're on the element boundaries, 562 // so move selection out of the style with inner style preserverd. 563 if ( newStyleRange && !newStyleRange.collapsed ) 564 { 565 var styleElements = newStyleRange.cloneContents(); 566 567 // We need build a temp node here for 'removeFromInsideElement'. 568 var temp = range.document.createElement( 'div' ); 569 temp.append( styleElements ); 570 removeFromInsideElement( this, temp ); 571 572 // It's guaranteed that style elements is single rooted. 573 styleElements = temp.getFirst(); 574 575 // Start from the new position right before/after the topmost target style element. 576 newStyleRange.collapse( startOfElement ? true : false ); 577 578 // Continue with the inner styles. 579 if ( styleElements ) 580 { 581 newStyleRange.insertNode( styleElements ); 582 mergeSiblings( styleElements ); 583 // Destroy the bookmark node. 584 startNode.remove(); 585 range.moveToElementEditStart( styleElements ); 586 return; 587 } 588 else // No inner styles found. 589 // Simply jump out of the target style element. 590 newStyleRange.insertNode( bookmark.startNode ); 591 } 592 } 547 593 else 548 594 { 549 595 /* -
_source/core/dom/range.js
133 133 134 134 while( currentNode ) 135 135 { 136 // Avoid cloning bookmark nodes. 137 if ( action == 2 && 138 currentNode.hasAttribute && currentNode.hasAttribute( '_fck_bookmark' ) ) 139 { 140 currentNode = currentSibling; 141 continue; 142 } 136 143 // Stop processing when the current node matches a node in the 137 144 // endParents tree or if it is the endNode. 138 145 if ( currentNode.equals( endParents[ j ] ) || currentNode.equals( endNode ) ) … … 180 187 181 188 while( currentNode ) 182 189 { 190 // Avoid cloning bookmark nodes. 191 if ( action == 2 && 192 currentNode.hasAttribute && currentNode.hasAttribute( '_fck_bookmark' ) ) 193 { 194 currentNode = currentSibling; 195 continue; 196 } 183 197 // Stop processing when the current node matches a node in the 184 198 // startParents tree or if it is the startNode. 185 199 if ( currentNode.equals( startParents[ k ] ) || currentNode.equals( startNode ) ) … … 290 304 }; 291 305 } 292 306 307 // Evaluator for CKEDITOR.dom.element::checkBoundaryOfElement. 308 function elementBoundaryEval( node ) 309 { 310 // Reject any text node unless it's being bookmark. 311 return node.type != CKEDITOR.NODE_TEXT || node.getParent().hasAttribute( '_fck_bookmark' ); 312 }; 313 // Guard for CKEDITOR.dom.element::checkBoundaryOfElement. 314 function elementBoundaryGuard( node ) 315 { 316 return !node.type == CKEDITOR.NODE_ELEMENT || 317 ( node.hasAttribute && node.hasAttribute( '_fck_bookmark') ); 318 }; 319 293 320 CKEDITOR.dom.range.prototype = 294 321 { 295 322 clone : function() … … 1398 1425 }; 1399 1426 }, 1400 1427 1428 /** 1429 * Whether range is on the boundary of an element node. 1430 * @param {Number} checkType ( CKEDITOR.START_OF_ELEMENT|CKEDITOR.END_OF_ELEMENT) 1431 * Specify check the range is at the start OR end of the element. 1432 */ 1433 checkBoundaryOfElement : function( checkType ) 1434 { 1435 var walkerRange = this.clone(); 1436 // Expand the range clockwise. 1437 walkerRange[ checkType == CKEDITOR.START_OF_ELEMENT ? 1438 'setStartBefore' : 'setEndAfter'].call( 1439 walkerRange, this.document.getBody() ); 1440 var walker = new CKEDITOR.dom.walker( walkerRange ), 1441 retval = false; 1442 walker.evaluator = elementBoundaryEval; 1443 walker.guard = elementBoundaryGuard; 1444 return checkType == CKEDITOR.START_OF_ELEMENT ? 1445 walker.checkBackward() : walker.checkForward(); 1446 }, 1447 1401 1448 // Calls to this function may produce changes to the DOM. The range may 1402 1449 // be updated to reflect such changes. 1403 1450 checkStartOfBlock : function() … … 1524 1571 CKEDITOR.ENLARGE_ELEMENT = 1; 1525 1572 CKEDITOR.ENLARGE_BLOCK_CONTENTS = 2; 1526 1573 CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS = 3; 1574 1575 /** 1576 * Check boundary types. 1577 * @see CKEDITOR.dom.range::checkBoundaryOfElement 1578 */ 1579 CKEDITOR.START_OF_ELEMENT = 1; 1580 CKEDITOR.END_OF_ELEMENT = 2; 1581 CKEDITOR.STARTEND_OF_ELEMENT = 3;