Ticket #3576: 3576.patch

File 3576.patch, 8.9 KB (added by Garry Yao, 10 years ago)
  • core/tools.js

     
    169169                },
    170170
    171171                /**
     172                 * Determine whether an given object has no own property.
     173                 * @param {Object|null|undefined} object
     174                 */
     175                isEmpty : function( object )
     176                {
     177                        for ( var property in object )
     178                                if ( object.hasOwnProperty( property ) )
     179                                        return false;
     180                        return true;
     181                },
     182
     183                /**
    172184                 * Transforms a CSS property name to its relative DOM style name.
    173185                 * @param {String} cssName The CSS property name.
    174186                 * @returns {String} The transformed name.
  • plugins/styles/plugin.js

     
    8181        var objectElements      = { a:1,embed:1,hr:1,img:1,li:1,object:1,ol:1,table:1,td:1,tr:1,ul:1 };
    8282
    8383        var semicolonFixRegex = /\s*(?:;\s*|$)/;
    84 
     84        // Customizing CKEDITOR.dom.node::getNext for ignoring bookmark nodes.
     85        function getNextSibling( currentNode )
     86        {
     87                var next = currentNode;
     88                do
     89                {
     90                        next = next.getNext();
     91                }
     92                while( next && next.getName
     93                                        && next.getName() == 'span'
     94                                        && next.getAttribute( '_fck_bookmark' ) );
     95                return next;
     96        }
    8597        CKEDITOR.style = function( styleDefinition, variablesValues )
    8698        {
    8799                if ( variablesValues )
     
    363375                                var nodeType = currentNode.type;
    364376                                var nodeName = nodeType == CKEDITOR.NODE_ELEMENT ? currentNode.getName() : null;
    365377
    366                                 if ( nodeName && currentNode.getAttribute( '_fck_bookmark' ) )
     378                                // Ignore bookmark nodes.
     379                                if ( nodeName && currentNode.hasAttribute( '_fck_bookmark' )
     380                                        || !nodeName && currentNode.getParent().hasAttribute( '_fck_bookmark' ) )
    367381                                {
    368382                                        currentNode = currentNode.getNextSourceNode( true );
    369383                                        continue;
     
    399413                                                        // if this is the last node in its parent, we must also
    400414                                                        // check if the parent itself can be added completelly
    401415                                                        // to the range.
    402                                                         while ( !includedNode.$.nextSibling
     416                                                        while ( !getNextSibling( includedNode )
    403417                                                                && ( parentNode = includedNode.getParent(), dtd[ parentNode.getName() ] )
    404418                                                                && ( parentNode.getPosition( firstNode ) | CKEDITOR.POSITION_FOLLOWING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED ) == ( CKEDITOR.POSITION_FOLLOWING + CKEDITOR.POSITION_IDENTICAL + CKEDITOR.POSITION_IS_CONTAINED ) )
    405                                                         {
    406419                                                                includedNode = parentNode;
    407                                                         }
    408420
    409421                                                        styleRange.setEndAfter( includedNode );
    410422
    411423                                                        // If the included node still is the last node in its
    412424                                                        // parent, it means that the parent can't be included
    413425                                                        // in this style DTD, so apply the style immediately.
    414                                                         if ( !includedNode.$.nextSibling )
     426                                                        if ( !getNextSibling( includedNode ) )
    415427                                                                applyStyle = true;
    416428
    417429                                                        if ( !hasContents )
     
    675687        function removeFromElement( style, element )
    676688        {
    677689                var def = style._.definition,
    678                         attributes = def.attributes,
     690                        attributes = CKEDITOR.tools.extend( {},
     691                                        def.attributes,
     692                                        // Override styles on the element.
     693                                        getOverrides( style )[ element.getName() ] ),
    679694                        styles = def.styles,
    680                         overrides = getOverrides( style );
     695                        // If the style is only about the element itself, we have to remove the element.
     696                        removeEmpty = CKEDITOR.tools.isEmpty( attributes ) && CKEDITOR.tools.isEmpty( styles );
    681697
    682                 function removeAttrs()
     698                //  If there's any to-be-removed style/attribute, remove them from the element,
     699                //  then only remove the element if it's empty.
     700                for ( var attName in attributes )
    683701                {
    684                         for ( var attName in attributes )
    685                         {
    686                                 // The 'class' element value must match (#1318).
    687                                 if ( attName == 'class' && element.getAttribute( attName ) != attributes[ attName ] )
    688                                         continue;
    689                                 element.removeAttribute( attName );
    690                         }
     702                        // The 'class' element value must match (#1318).
     703                        if ( attName == 'class' && element.getAttribute( attName ) != attributes[ attName ] )
     704                                continue;
     705                        element.removeAttribute( attName );
     706                        removeEmpty = true;
    691707                }
    692708
    693                 // Remove definition attributes/style from the elemnt.
    694                 removeAttrs();
    695709                for ( var styleName in styles )
     710                {
    696711                        element.removeStyle( styleName );
    697 
    698                 // Now remove override styles on the element.
    699                 attributes = overrides[ element.getName() ];
    700                 if( attributes )
    701                         removeAttrs();
    702                 removeNoAttribsElement( element );
     712                        removeEmpty = true;
     713                }
     714                if ( removeEmpty )
     715                        removeNoAttribsElement( element );
    703716        }
    704717
    705718        // Removes a style from inside an element.
  • tests/plugins/styles/styles.html

     
    206206                                } );
    207207                        style.applyToRange( range );
    208208
    209                         assert.areSame( '<b lang="it" style="font-size: 10pt; text-decoration: line-through;" title="test">this <b class="sample">is</b> some sample text</b>', getInnerHtml( '_P1' ) );
     209                        assert.areSame( '<b lang="it" style="font-size:10pt;text-decoration:line-through;" title="test">this <b class="sample">is</b> some sample text</b>', getInnerHtml( '_P1' ) );
    210210                },
    211211
    212                 test_inline11 : function()
     212                test_inline12 : function()
    213213                {
    214214                        doc.getById( '_P1' ).setHtml( 'this <span class="a">is</span> some <span class="b">sample</span> text' );
    215215
     
    223223                        assert.areSame( '<span class="b">this <span class="a">is</span> some sample text</span>', getInnerHtml( '_P1' ) );
    224224                },
    225225
    226                 test_inline12 : function()
     226                test_inline13 : function()
    227227                {
    228                         doc.getById( '_P1' ).setHtml( 'this <span style="font-size:12pt; font-weight:600">is</span> some <span style="font-size:10px;">sample</span> text' );
     228                        doc.getById( '_P1' ).setHtml( 'this <span style="font-size:12pt;font-weight:600">is</span> some <span style="font-size:10px;">sample</span> text' );
    229229
    230230                        var range = new CKEDITOR.dom.range( doc );
    231231                        range.setStart( doc.getById( '_P1' ), 0 );
     
    237237                        assert.areSame( '<span style="font-size:1.5em;">this <span style="font-weight:600;">is</span> some sample text</span>', getInnerHtml( '_P1' ) );
    238238                },
    239239
    240                 test_inline13 : function()
     240                test_inline14 : function()
    241241                {
    242242                        doc.getById( '_P1' ).setHtml( 'this <b>is some sample</b> text' );
    243243
     
    251251                        assert.areSame( 'this <b>is <i>some sample</i></b><i> text</i>', getInnerHtml( '_P1' ) );
    252252                },
    253253
    254                 test_inline14 : function()
     254                test_inline15 : function()
    255255                {
    256256                        var para = doc.getById( '_P1' );
    257257
     
    277277                        assert.areSame( '<b>this is some</b> sample text', getInnerHtml( '_P1' ), 'Second range' );
    278278                },
    279279
    280                 test_inline15 : function()
     280                test_inline16 : function()
    281281                {
    282282                        var para = doc.getById( '_P1' );
    283283
     
    304304                        assert.areSame( '<span style="font-family:arial,helvetica,sans-serif;">this <span style="font-family:georgia,serif;">is</span></span><span style="font-family:georgia,serif;"> some</span> sample text', getInnerHtml( '_P1' ), 'Second range' );
    305305                },
    306306
    307                 test_inline16 : function()
     307                test_inline17 : function()
    308308                {
    309309                        var para = doc.getById( '_P1' );
    310310
     
    336336
    337337                test_ticket_2040 : function()
    338338                {
    339                         doc.getById( '_P1' ).setHtml( 'This is some <strong>sample text<\/strong>. You are using <a href="http://www.fckeditor.net/">CKEditor<\/a>.' );
     339                        doc.getById( '_P1' ).setHtml( 'This is some <strong>sample text<\/strong>. You are using <a href="http://www.fckeditor.net/">ckeditor<\/a>.' );
    340340
    341341                        var range = new CKEDITOR.dom.range( doc );
    342342                        range.setStart( doc.getById( '_P1' ), 1 );
     
    345345                        var style = new CKEDITOR.style( { element : 'i' } );
    346346                        style.applyToRange( range );
    347347
    348                         assert.areSame( 'this is some <strong><i>sample</i> text<\/strong>. you are using <a href="http://www.fckeditor.net/">CKEditor<\/a>.', getInnerHtml( '_P1' ) );
     348                        assert.areSame( 'this is some <strong><i>sample</i> text<\/strong>. you are using <a href="http://www.fckeditor.net/">ckeditor<\/a>.', getInnerHtml( '_P1' ) );
    349349                },
    350350
    351351                test_checkElementRemovable1 : function()
     
    486486                        assert.areSame( '<p><i title="z">text</i></p><i title="z">outter</i>', getInnerHtml( element ) );
    487487                },
    488488
     489                test_ticket_3576 : function()
     490                {
     491                        var element = doc.getById( '_P1' );
     492                        element.setHtml( '<span>inline</span>' );
     493
     494                        var range = new CKEDITOR.dom.range( doc );
     495                        range.selectNodeContents( element.getFirst().getFirst() );
     496
     497                        var style = new CKEDITOR.style( { element : 'span', attributes : { class : 'style' } } );
     498                        style.applyToRange( range );
     499
     500                        assert.areSame( '<span class="style"><span>inline</span></span>', getInnerHtml( element ) );
     501                },
     502
    489503                name : document.title
    490504        };
    491505})() );
    492 
     506//window.onload = testCase.test_inline11;
    493507        //]]>
    494508        </script>
    495509</head>
© 2003 – 2019 CKSource – Frederico Knabben. All rights reserved. | Terms of use | Privacy policy