Ticket #3152: 3152.patch
File 3152.patch, 9.6 KB (added by , 15 years ago) |
---|
-
_source/plugins/styles/plugin.js
176 176 // current style definition. 177 177 checkElementRemovable : function( element, fullMatch ) 178 178 { 179 if ( !element || element.getName() != this.element)179 if ( !element ) 180 180 return false; 181 181 182 182 var def = this._.definition, … … 204 204 return false; 205 205 } 206 206 } 207 208 // Check if the element can be somehow overriden. 209 var override = this.getOverrides()[ element.getName() ] ; 210 if ( override ) 211 { 212 // If no attributes have been defined, remove the element. 213 if ( !( attribs = override.attributes ) ) 214 return true; 215 216 for ( var i = 0; i < attribs.length; i++ ) 217 { 218 var attName = attribs[i][0], actualAttrValue; 219 if ( actualAttrValue = element.getAttribute( attName ) ) 220 { 221 var attValue = attribs[i][1]; 222 223 // Remove the attribute if: 224 // - The override definition value is null; 225 // - The override definition valie is a string that 226 // matches the attribute value exactly. 227 // - The override definition value is a regex that 228 // has matches in the attribute value. 229 if ( attValue == null || 230 ( typeof attValue == 'string' && actualAttrValue == attValue ) || 231 attValue.test( actualAttrValue ) ) 232 return true; 233 } 234 } 235 } 236 237 }, 207 238 208 return true; 209 } 239 /** 240 * Get the the collection used to compare the elements and attributes, 241 * defined in this style overrides, with other element. All information in 242 * it is lowercased. 243 */ 244 getOverrides: function() 245 { 246 var overrides = {}, 247 definition = this._.definition.overrides; 248 249 if ( definition ) 250 { 251 // The override description can be a string, object or array. 252 // Internally, well handle arrays only, so transform it if needed. 253 if ( !CKEDITOR.tools.isArray( definition ) ) 254 definition = [ definition ]; 255 256 // Loop through all override definitions. 257 for ( var i = 0; i < definition.length; i++ ) 258 { 259 var override = definition[i]; 260 var elementName; 261 var overrideEl; 262 var attrs; 263 264 // If can be a string with the element name. 265 if ( typeof override == 'string' ) 266 elementName = override.toLowerCase(); 267 // Or an object. 268 else 269 { 270 elementName = override.element ? override.element.toLowerCase() : this.element; 271 attrs = override.attributes; 272 } 273 274 // We can have more than one override definition for the same 275 // element name, so we attempt to simply append information to 276 // it if it already exists. 277 overrideEl = overrides[ elementName ] || ( overrides[ elementName ] = {} ); 278 279 if ( attrs ) 280 { 281 // The returning attributes list is an array, because we 282 // could have different override definitions for the same 283 // attribute name. 284 var overrideAttrs = ( overrideEl.attributes = overrideEl.attributes || new Array() ); 285 for ( var attName in attrs ) 286 { 287 // Each item in the attributes array is also an array, 288 // where [0] is the attribute name and [1] is the 289 // override value. 290 overrideAttrs.push( [ attName.toLowerCase(), attrs[ attName ] ] ); 291 } 292 } 293 } 294 } 295 296 // Cache the overrides resolution. 297 return ( this.getOverrides = function(){ 298 return overrides; 299 } )(); 300 }, 301 210 302 }; 211 303 212 304 // Build the cssText based on the styles definition. … … 483 575 * elements, until a block boundary is reached. 484 576 */ 485 577 var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() ); 486 for ( var i = 0, element ; i < startPath.elements.length && ( element = startPath.elements[i] ); i++ )578 for ( var i = 0, element; i < startPath.elements.length && ( element = startPath.elements[i] ) ; i++ ) 487 579 { 488 580 if ( element == startPath.block || element == startPath.blockLimit ) 489 581 break; … … 520 612 endPath = new CKEDITOR.dom.elementPath( endNode.getParent() ), 521 613 breakStart = null, 522 614 breakEnd = null; 523 for ( var i = 0 ; i < startPath.elements.length; i++ )615 for ( var i = 0; i < startPath.elements.length; i++ ) 524 616 { 525 617 var element = startPath.elements[ i ]; 526 618 … … 530 622 if ( me.checkElementRemovable( element ) ) 531 623 breakStart = element; 532 624 } 533 for ( i = 0 ; i < endPath.elements.length; i++ )625 for ( i = 0; i < endPath.elements.length; i++ ) 534 626 { 535 627 element = endPath.elements[ i ]; 536 628 … … 559 651 var nextNode = currentNode.getNextSourceNode(); 560 652 if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) 561 653 { 562 removeFromElement( this, currentNode ); 654 // Remove style from element or overriding element. 655 if( currentNode.getName() == this.element ) 656 removeFromElement( this, currentNode ); 657 else 658 removeOverrides( currentNode, this.getOverrides()[ currentNode.getName() ] ); 563 659 564 660 /* 565 661 * removeFromElement() may have merged the next node with something before … … 620 716 // if ( newBlockIsPre ) 621 717 // { 622 718 // if ( previousPreBlock ) 623 // this._CheckAndMergePre( previousPreBlock, newBlock ) 719 // this._CheckAndMergePre( previousPreBlock, newBlock ); // Merge successive <pre> blocks. 624 720 // previousPreBlock = newBlock; 625 721 // } 626 722 // else if ( fromPre ) 627 // this._CheckAndSplitPre( newBlock ) 723 // this._CheckAndSplitPre( newBlock ); // Split <br><br> in successive <pre>s. 628 724 } 629 725 630 726 range.moveToBookmark( bookmark ); … … 635 731 { 636 732 var def = style._.definition, 637 733 attributes = def.attributes, 638 styles = def.styles; 639 734 styles = def.styles, 735 overrides = style.getOverrides(); 736 640 737 for ( var attName in attributes ) 641 738 { 642 739 // The 'class' element value must match (#1318). … … 648 745 for ( var styleName in styles ) 649 746 element.removeStyle( styleName ); 650 747 748 // Now scan override styles on the element. 749 attributes = overrides[ element.getName() ]; 750 if( attributes ) 751 { 752 for( attName in attributes ) 753 { 754 // The 'class' element value must match (#1318). 755 if ( attName == 'class' && element.getAttribute( attName ) != attributes[ attName ] ) 756 continue; 757 element.removeAttribute( attName ); 758 } 759 } 651 760 removeNoAttribsElement( element ); 652 761 } 653 762 … … 654 763 // Removes a style from inside an element. 655 764 function removeFromInsideElement( style, element ) 656 765 { 657 var def = style._.definition; 658 var attribs = def.attributes; 659 var styles = def.styles; 766 var def = style._.definition, 767 attribs = def.attributes, 768 styles = def.styles, 769 overrides = style.getOverrides(); 660 770 661 771 var innerElements = element.getElementsByTag( style.element ); 662 772 663 for ( var i = innerElements.count() ; --i >= 0 ; ) 664 removeFromElement( style, innerElements.getItem( i ) ); 773 for ( var i = innerElements.count(); --i >= 0; ) 774 removeFromElement( style, innerElements.getItem( i ) ); 775 776 // Now remove any other element with different name that is 777 // defined to be overriden. 778 for ( var overrideElement in overrides ) 779 { 780 if ( overrideElement != style.element ) 781 { 782 var innerElements = element.getElementsByTag( overrideElement ) ; 783 for ( var i = innerElements.count() - 1; i >= 0 ; i-- ) 784 { 785 var innerElement = innerElements.getItem( i ); 786 removeOverrides( innerElement, overrides[ overrideElement ] ) ; 787 } 788 } 789 } 790 665 791 } 792 793 /** 794 * Remove overriding styles/attributes from the specific element. 795 * Note: Remove the element if no attributes remain. 796 * @param {Object} element 797 * @param {Object} overrides 798 */ 799 function removeOverrides( element, overrides ) 800 { 801 var attributes = overrides && overrides.attributes ; 666 802 803 if ( attributes ) 804 { 805 for ( var i = 0 ; i < attributes.length ; i++ ) 806 { 807 var attName = attributes[i][0], actualAttrValue ; 808 809 if ( actualAttrValue = element.getAttribute( attName ) ) 810 { 811 var attValue = attributes[i][1] ; 812 813 // Remove the attribute if: 814 // - The override definition value is null ; 815 // - The override definition valie is a string that 816 // matches the attribute value exactly. 817 // - The override definition value is a regex that 818 // has matches in the attribute value. 819 if ( attValue == null || 820 ( attValue.test && attValue.test( actualAttrValue ) ) || 821 ( typeof attValue == 'string' && actualAttrValue == attValue ) ) 822 element.removeAttribute( attName ) ; 823 } 824 } 825 } 826 827 removeNoAttribsElement( element ); 828 } 829 667 830 // If the element has no more attributes, remove it. 668 831 function removeNoAttribsElement( element ) 669 832 { … … 821 984 // Return it, saving it to the next request. 822 985 return ( styleDefinition._AC = attribs ); 823 986 } 824 987 825 988 function normalizeCssText( unparsedCssText ) 826 989 { 827 990 // Injects the style in a temporary span object, so the browser parses it, … … 861 1024 var func = remove ? this.removeFromRange : this.applyToRange; 862 1025 863 1026 // Apply the style to the ranges. 864 for ( var i = 0 ; i < ranges.length; i++ )1027 for ( var i = 0; i < ranges.length; i++ ) 865 1028 func.call( this, ranges[ i ] ); 866 1029 867 1030 // Select the ranges again.