Ticket #3152: 3152.patch

File 3152.patch, 9.6 KB (added by garry.yao, 5 years ago)
  • _source/plugins/styles/plugin.js

     
    176176                // current style definition. 
    177177                checkElementRemovable : function( element, fullMatch ) 
    178178                { 
    179                         if ( !element || element.getName() != this.element ) 
     179                        if ( !element ) 
    180180                                return false; 
    181181 
    182182                        var def = this._.definition, 
     
    204204                                                return false; 
    205205                                } 
    206206                        } 
     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                }, 
    207238 
    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                 
    210302        }; 
    211303 
    212304        // Build the cssText based on the styles definition. 
     
    483575                         * elements, until a block boundary is reached. 
    484576                         */ 
    485577                        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++ ) 
    487579                        { 
    488580                                if ( element == startPath.block || element == startPath.blockLimit ) 
    489581                                        break; 
     
    520612                                        endPath = new CKEDITOR.dom.elementPath( endNode.getParent() ), 
    521613                                        breakStart = null, 
    522614                                        breakEnd = null; 
    523                                 for ( var i = 0 ; i < startPath.elements.length ; i++ ) 
     615                                for ( var i = 0; i < startPath.elements.length; i++ ) 
    524616                                { 
    525617                                        var element = startPath.elements[ i ]; 
    526618 
     
    530622                                        if ( me.checkElementRemovable( element ) ) 
    531623                                                breakStart = element; 
    532624                                } 
    533                                 for ( i = 0 ; i < endPath.elements.length ; i++ ) 
     625                                for ( i = 0; i < endPath.elements.length; i++ ) 
    534626                                { 
    535627                                        element = endPath.elements[ i ]; 
    536628 
     
    559651                                var nextNode = currentNode.getNextSourceNode(); 
    560652                                if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) 
    561653                                { 
    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() ] ); 
    563659 
    564660                                        /* 
    565661                                         * removeFromElement() may have merged the next node with something before 
     
    620716//                      if ( newBlockIsPre ) 
    621717//                      { 
    622718//                              if ( previousPreBlock ) 
    623 //                                      this._CheckAndMergePre( previousPreBlock, newBlock ) ;  // Merge successive <pre> blocks. 
     719//                                      this._CheckAndMergePre( previousPreBlock, newBlock );   // Merge successive <pre> blocks. 
    624720//                              previousPreBlock = newBlock; 
    625721//                      } 
    626722//                      else if ( fromPre ) 
    627 //                              this._CheckAndSplitPre( newBlock ) ;    // Split <br><br> in successive <pre>s. 
     723//                              this._CheckAndSplitPre( newBlock );     // Split <br><br> in successive <pre>s. 
    628724                } 
    629725 
    630726                range.moveToBookmark( bookmark ); 
     
    635731        { 
    636732                var def = style._.definition, 
    637733                        attributes = def.attributes, 
    638                         styles = def.styles; 
    639  
     734                        styles = def.styles, 
     735                        overrides = style.getOverrides(); 
     736                 
    640737                for ( var attName in attributes ) 
    641738                { 
    642739                        // The 'class' element value must match (#1318). 
     
    648745                for ( var styleName in styles ) 
    649746                        element.removeStyle( styleName ); 
    650747 
     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                } 
    651760                removeNoAttribsElement( element ); 
    652761        } 
    653762 
     
    654763        // Removes a style from inside an element. 
    655764        function removeFromInsideElement( style, element ) 
    656765        { 
    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(); 
    660770 
    661771                var innerElements = element.getElementsByTag( style.element ); 
    662772 
    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 
    665791        } 
     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 ; 
    666802 
     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         
    667830        // If the element has no more attributes, remove it. 
    668831        function removeNoAttribsElement( element ) 
    669832        { 
     
    821984                // Return it, saving it to the next request. 
    822985                return ( styleDefinition._AC = attribs ); 
    823986        } 
    824  
     987         
    825988        function normalizeCssText( unparsedCssText ) 
    826989        { 
    827990                // Injects the style in a temporary span object, so the browser parses it, 
     
    8611024                var func = remove ? this.removeFromRange : this.applyToRange; 
    8621025 
    8631026                // Apply the style to the ranges. 
    864                 for ( var i = 0 ; i < ranges.length ; i++ ) 
     1027                for ( var i = 0; i < ranges.length; i++ ) 
    8651028                        func.call( this, ranges[ i ] ); 
    8661029 
    8671030                // Select the ranges again. 
© 2003 – 2012 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy