Ticket #3006: 3006.patch
File 3006.patch, 23.2 KB (added by , 16 years ago) |
---|
-
_source/core/dom/element.js
658 658 return false; 659 659 }, 660 660 661 isIdentical : function( otherElement ) 662 { 663 if ( this.getName() != otherElement.getName() ) 664 return false; 665 666 var thisAttribs = this.$.attributes, 667 otherAttribs = otherElement.$.attributes; 668 669 var thisLength = thisAttribs.length, 670 otherLength = otherAttribs.length; 671 672 if ( !CKEDITOR.env.ie && thisLength != otherLength ) 673 return false; 674 675 for ( var i = 0 ; i < thisLength ; i++ ) 676 { 677 var attribute = thisAttribs[ i ]; 678 679 if ( ( !CKEDITOR.env.ie || ( attribute.specified && attribute.nodeName != '_cke_expando' ) ) && attribute.nodeValue != otherElement.getAttribute( attribute.nodeName ) ) 680 return false; 681 } 682 683 // For IE, we have to for both elements, because it's difficult to 684 // know how the atttibutes collection is organized in its DOM. 685 if ( CKEDITOR.env.ie ) 686 { 687 for ( i = 0 ; i < otherLength ; i++ ) 688 { 689 attribute = otherAttribs[ i ]; 690 691 if ( ( !CKEDITOR.env.ie || ( attribute.specified && attribute.nodeName != '_cke_expando' ) ) && attribute.nodeValue != thisAttribs.getAttribute( attribute.nodeName ) ) 692 return false; 693 } 694 } 695 696 return true; 697 }, 698 661 699 /** 662 700 * Indicates that the element has defined attributes. 663 701 * @returns {Boolean} True if the element has attributes. … … 746 784 copyAttributes : function( target, skip ) 747 785 { 748 786 skip || ( skip = {} ); 749 var attributes = this.$.attributes 787 var attributes = this.$.attributes; 750 788 751 789 for ( var n = 0 ; n < attributes.length ; n++ ) 752 790 { 753 var attr = attributes[n] 791 var attr = attributes[n]; 754 792 755 793 if ( attr.specified ) 756 794 { 757 var attrName = attr.nodeName 795 var attrName = attr.nodeName; 758 796 if ( attrName in skip ) 759 continue 797 continue; 760 798 761 799 var attrValue = this.getAttribute( attrName ); 762 800 if ( !attrValue ) 763 attrValue = attr.nodeValue 801 attrValue = attr.nodeValue; 764 802 765 803 target.setAttribute( attrName, attrValue ); 766 804 } 767 805 } 768 806 769 807 if ( this.$.style.cssText !== '' ) 770 target.$.style.cssText = this.$.style.cssText 808 target.$.style.cssText = this.$.style.cssText; 771 809 }, 772 810 773 811 /** -
_source/core/test.js
71 71 { 72 72 if ( attName == 'style' ) 73 73 { 74 // Safari adds some extra space to the end. 75 attValue = attValue.replace( /\s+/g, '' ); 76 74 77 // IE doesn't add the final ";" 75 78 attValue = attValue.replace( /([^"';\s])\s*(["']?)$/, '$1;$2' ); 76 77 // Safari adds some extra space to the end.78 attValue = attValue.replace( /\s+(["']?)$/, '$1' );79 79 } 80 80 81 81 // IE may have 'class' more than once. -
_source/plugins/styles/plugin.js
80 80 var blockElements = { address:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1 }; 81 81 var objectElements = { a:1,embed:1,hr:1,img:1,li:1,object:1,ol:1,table:1,td:1,tr:1,ul:1 }; 82 82 83 CKEDITOR.style = function( styleDefinition )83 CKEDITOR.style = function( styleDefinition, variablesValues ) 84 84 { 85 if ( variablesValues ) 86 { 87 styleDefinition = CKEDITOR.tools.clone( styleDefinition ); 88 89 replaceVariables( styleDefinition.attributes, variablesValues ); 90 replaceVariables( styleDefinition.styles, variablesValues ); 91 } 92 85 93 var element = this.element = ( styleDefinition.element || '*' ).toLowerCase(); 86 94 87 95 this.type = … … 98 106 }; 99 107 }; 100 108 101 var applyStyle = function( document, remove )102 {103 // Get all ranges from the selection.104 var selection = document.getSelection();105 var ranges = selection.getRanges();106 var func = remove ? this.removeFromRange : this.applyToRange;107 108 // Apply the style to the ranges.109 for ( var i = 0 ; i < ranges.length ; i++ )110 func.call( this, ranges[ i ] );111 112 // Select the ranges again.113 selection.selectRanges( ranges );114 };115 116 109 CKEDITOR.style.prototype = 117 110 { 118 111 apply : function( document ) … … 137 130 138 131 removeFromRange : function( range ) 139 132 { 140 return ( this.removeFromRange = 133 return ( this.removeFromRange = 141 134 this.type == CKEDITOR.STYLE_INLINE ? 142 135 removeInlineStyle 143 136 : null ).call( this, range ); … … 179 172 if ( !element || element.getName() != this.element ) 180 173 return false; 181 174 182 var def = this._.definition; 183 var attribs = def.attributes; 184 var styles = def.styles; 175 var def = this._.definition, 176 attribs; 185 177 186 178 // If no attributes are defined in the element. 187 179 if ( !fullMatch && !element.hasAttributes() ) 188 180 return true; 189 181 190 for ( var attName in attribs ) 182 attribs = getAttributesForComparison( def ); 183 184 if ( attribs._length ) 191 185 { 192 if ( element.getAttribute( attName ) == attribs[ attName ])186 for ( var attName in attribs ) 193 187 { 194 if ( !fullMatch ) 195 return true; 188 if ( attName == '_length' ) 189 continue; 190 191 if ( compareAttributeValues( attName, attribs[ attName ], element.getAttribute( attName ) ) ) 192 { 193 if ( !fullMatch ) 194 return true; 195 } 196 else if ( fullMatch ) 197 return false; 196 198 } 197 else if ( fullMatch )198 return false;199 199 } 200 200 201 201 return true; 202 },203 204 /**205 * Sets the value of a variable attribute or style, to be used when206 * appliying the style. This function must be called before using any207 * other function in this object.208 */209 setVariable : function( name, value )210 {211 var variables = this._.variables || ( this._variables = {} );212 variables[ name ] = value;213 202 } 214 203 }; 215 204 216 var applyInlineStyle = function( range )205 function applyInlineStyle( range ) 217 206 { 218 207 var document = range.document; 219 208 … … 343 332 // Build the style element, based on the style object definition. 344 333 var styleNode = getElement( this, document ); 345 334 335 // Get the element that holds the entire range. 346 336 var parent = styleRange.getCommonAncestor(); 347 337 338 // Loop through the parents, removing the redundant attributes 339 // from the element to be applied. 348 340 while ( styleNode && parent ) 349 341 { 350 342 if ( parent.getName() == elementName ) … … 406 398 // this._FixBookmarkStart( startNode ); 407 399 408 400 range.moveToBookmark( bookmark ); 409 } ;401 } 410 402 411 var removeInlineStyle = function( range )403 function removeInlineStyle( range ) 412 404 { 413 405 /* 414 406 * Make sure our range has included all "collpased" parent inline nodes so … … 421 413 422 414 if ( range.collapsed ) 423 415 { 424 /* 416 /* 425 417 * If the range is collapsed, try to remove the style from all ancestor 426 418 * elements, until a block boundary is reached. 427 419 */ … … 519 511 currentNode = nextNode; 520 512 } 521 513 } 522 514 523 515 range.moveToBookmark( bookmark ); 524 } ;516 } 525 517 526 var applyBlockStyle = function( range )518 function applyBlockStyle( range ) 527 519 { 528 520 // Bookmark the range so we can re-select it after processing. 529 521 var bookmark = range.createBookmark(); … … 571 563 } 572 564 573 565 range.moveToBookmark( bookmark ); 574 } ;566 } 575 567 576 568 // Removes a style from an element itself, don't care about its subtree. 577 var removeFromElement = function( style, element )569 function removeFromElement( style, element ) 578 570 { 579 571 var def = style._.definition, 580 572 attributes = def.attributes, … … 592 584 element.removeStyle( styleName ); 593 585 594 586 removeNoAttribsElement( element ); 595 } ;587 } 596 588 597 589 // Removes a style from inside an element. 598 var removeFromInsideElement = function( style, element )590 function removeFromInsideElement( style, element ) 599 591 { 600 592 var def = style._.definition; 601 593 var attribs = def.attributes; … … 605 597 606 598 for ( var i = innerElements.count() ; --i >= 0 ; ) 607 599 removeFromElement( style, innerElements.getItem( i ) ); 608 } ;600 } 609 601 610 602 // If the element has no more attributes, remove it. 611 var removeNoAttribsElement = function( element )603 function removeNoAttribsElement( element ) 612 604 { 613 605 // If no more attributes remained in the element, remove it, 614 606 // leaving its children. … … 630 622 mergeSiblings( lastChild ); 631 623 } 632 624 } 633 } ;625 } 634 626 635 // Get the the collection used to compare the attributes defined in this 636 // style with attributes in an element. All information in it is lowercased. 637 // V2 638 // var getAttribsForComparison = function( style ) 639 // { 640 // // If we have already computed it, just return it. 641 // var attribs = style._.attribsForComparison; 642 // if ( attribs ) 643 // return attribs; 644 645 // attribs = {}; 646 647 // var def = style._.definition; 648 649 // // Loop through all defined attributes. 650 // var styleAttribs = def.attributes; 651 // if ( styleAttribs ) 652 // { 653 // for ( var styleAtt in styleAttribs ) 654 // { 655 // attribs[ styleAtt.toLowerCase() ] = styleAttribs[ styleAtt ].toLowerCase(); 656 // } 657 // } 658 659 // // Includes the style definitions. 660 // if ( this._GetStyleText().length > 0 ) 661 // { 662 // attribs['style'] = this._GetStyleText().toLowerCase(); 663 // } 664 665 // // Appends the "length" information to the object. 666 // FCKTools.AppendLengthProperty( attribs, '_length' ); 667 668 // // Return it, saving it to the next request. 669 // return ( this._GetAttribsForComparison_$ = attribs ); 670 // }, 671 672 var mergeSiblings = function( element ) 627 function mergeSiblings( element ) 673 628 { 674 629 if ( !element || element.type != CKEDITOR.NODE_ELEMENT || !CKEDITOR.dtd.$removeEmpty[ element.getName() ] ) 675 630 return; 676 631 677 632 mergeElements( element, element.getNext(), true ); 678 633 mergeElements( element, element.getPrevious() ); 679 } ;634 } 680 635 681 var mergeElements = function( element, sibling, isNext )636 function mergeElements( element, sibling, isNext ) 682 637 { 683 638 if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT ) 684 639 { … … 687 642 if ( hasBookmark ) 688 643 sibling = isNext ? sibling.getNext() : sibling.getPrevious(); 689 644 690 if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT && sibling.getName() == element.getName() )645 if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT && element.isIdentical( sibling ) ) 691 646 { 692 647 // Save the last child to be checked too, to merge things like 693 648 // <b><i></i></b><b><i></i></b> => <b><i></i></b> … … 704 659 mergeSiblings( innerSibling ); 705 660 } 706 661 } 707 } ;662 } 708 663 709 // Regex used to match all variables defined in an attribute or style 710 // value. The variable name is returned with $2. 711 var styleVariableAttNameRegex = /#\(\s*("|')(.+?)\1[^\)]*\s*\)/g; 712 713 var getElement = function( style, targetDocument ) 664 function getElement( style, targetDocument ) 714 665 { 715 666 var el; 716 667 717 668 var def = style._.definition; 718 var variables = style._.variables;719 669 720 670 var elementName = style.element; 721 671 var attributes = def.attributes; 722 var styles = def.styles;672 var styles = getStyleText( def ); 723 673 724 674 // The "*" element name will always be a span for this function. 725 675 if ( elementName == '*' ) … … 733 683 { 734 684 for ( var att in attributes ) 735 685 { 736 var attValue = attributes[ att ]; 737 if ( attValue && variables ) 738 { 739 attValue = attValue.replace( styleVariableAttNameRegex, function() 740 { 741 // The second group in the regex is the variable name. 742 return variables[ arguments[2] ] || arguments[0]; 743 }); 744 } 745 el.setAttribute( att, attValue ); 686 el.setAttribute( att, attributes[ att ] ); 746 687 } 747 688 } 748 689 749 690 // Assign all defined styles. 750 691 if ( styles ) 692 el.setAttribute( 'style', styles ); 693 694 return el; 695 } 696 697 var varRegex = /#\((.+?)\)/g; 698 function replaceVariables( list, variablesValues ) 699 { 700 for ( var item in list ) 751 701 { 752 for ( var styleName in styles ) 753 el.setStyle( styleName, styles[ styleName ] ); 702 list[ item ] = list[ item ].replace( varRegex, function( match, varName ) 703 { 704 return variablesValues[ varName ]; 705 }); 706 } 707 } 754 708 755 if ( variables ) 709 var spacesRegex = /\s+/g; 710 711 // Returns an object that can be used for style matching comparison. 712 // Attributes names and values are all lowercased, and the styles get 713 // merged with the style attribute. 714 function getAttributesForComparison( styleDefinition ) 715 { 716 // If we have already computed it, just return it. 717 var attribs = styleDefinition._AC; 718 if ( attribs ) 719 return attribs; 720 721 attribs = {}; 722 723 var length = 0; 724 725 // Loop through all defined attributes. 726 var styleAttribs = styleDefinition.attributes; 727 if ( styleAttribs ) 728 { 729 for ( var styleAtt in styleAttribs ) 756 730 { 757 attValue = el.getAttribute( 'style' ).replace( styleVariableAttNameRegex, function() 758 { 759 // The second group in the regex is the variable name. 760 return variables[ arguments[2] ] || arguments[0]; 761 }); 762 el.setAttribute( 'style', attValue ); 731 length++; 732 attribs[ styleAtt.toLowerCase() ] = styleAttribs[ styleAtt ].toLowerCase(); 763 733 } 764 734 } 765 735 766 return el; 767 }; 736 // Includes the style definitions. 737 var styleText = getStyleText( styleDefinition ); 738 if ( styleText.length > 0 ) 739 { 740 if ( !attribs[ 'style' ] ) 741 length++; 742 743 attribs['style'] = styleText.replace( spacesRegex, '' ).toLowerCase(); 744 } 745 746 // Appends the "length" information to the object. 747 attribs._length = length; 748 749 // Return it, saving it to the next request. 750 return ( styleDefinition._AC = attribs ); 751 } 752 753 var semicolonFixRegex = /\s*(?:;\s*|$)/; 754 755 // Build the cssText based on the styles definition. 756 function getStyleText( styleDefinition ) 757 { 758 // If we have already computed it, just return it. 759 var stylesDef = styleDefinition._ST; 760 if ( stylesDef ) 761 return stylesDef; 762 763 stylesDef = styleDefinition.styles; 764 765 // Builds the StyleText. 766 767 var stylesText = ( styleDefinition.attributes && styleDefinition.attributes[ 'style' ] ) || ''; 768 769 if ( stylesText.length ) 770 stylesText = stylesText.replace( semicolonFixRegex, ';' ); 771 772 for ( var style in stylesDef ) 773 stylesText += style + ':' + stylesDef[ style ] + ';'; 774 775 // Browsers make some changes to the style when applying them. So, here 776 // we normalize it to the browser format. 777 if ( stylesText.length ) 778 { 779 stylesText = normalizeCssText( stylesText ); 780 781 if ( stylesText.length ) 782 stylesText = stylesText.replace( semicolonFixRegex, ';' ); 783 } 784 785 // Return it, saving it to the next request. 786 return ( styleDefinition._ST = stylesText ); 787 } 788 789 function normalizeCssText( unparsedCssText ) 790 { 791 // Injects the style in a temporary span object, so the browser parses it, 792 // retrieving its final format. 793 var tempSpan = document.createElement( 'span' ); 794 tempSpan.style.cssText = unparsedCssText; 795 return tempSpan.style.cssText; 796 } 797 798 // valueA is our internal "for comparison" value. 799 // valueB is the value retrieved from the element. 800 function compareAttributeValues( attName, valueA, valueB ) 801 { 802 if ( valueA == valueB || ( !valueA && !valueB ) ) 803 return true; 804 else if ( !valueA || !valueB ) 805 return false; 806 807 valueB = valueB.toLowerCase(); 808 809 if ( attName == 'style' ) 810 { 811 valueB = valueB.replace( spacesRegex, '' ); 812 if ( valueB.charAt( valueB.length - 1 ) != ';' ) 813 valueB += ';'; 814 } 815 816 // Return true if they match or if valueA is null and valueB is an empty string 817 return ( valueA == valueB ); 818 } 819 820 function applyStyle( document, remove ) 821 { 822 // Get all ranges from the selection. 823 var selection = document.getSelection(); 824 var ranges = selection.getRanges(); 825 var func = remove ? this.removeFromRange : this.applyToRange; 826 827 // Apply the style to the ranges. 828 for ( var i = 0 ; i < ranges.length ; i++ ) 829 func.call( this, ranges[ i ] ); 830 831 // Select the ranges again. 832 selection.selectRanges( ranges ); 833 } 768 834 })(); 769 835 770 836 CKEDITOR.styleCommand = function( style ) -
_source/tests/plugins/styles/styles.html
179 179 } ); 180 180 style.applyToRange( range ); 181 181 182 assert.areSame( '<b lang="it" style="font-size: 10pt; text-decoration:line-through;" title="test">this is some sample text</b>', getInnerHtml( '_P1' ) );182 assert.areSame( '<b lang="it" style="font-size:10pt;text-decoration:line-through;" title="test">this is some sample text</b>', getInnerHtml( '_P1' ) ); 183 183 }, 184 184 185 185 test_inline11 : function() … … 234 234 var style = new CKEDITOR.style( { element : 'span', styles : { 'font-size' : '1.5em' } } ); 235 235 style.applyToRange( range ); 236 236 237 assert.areSame( '<span style="font-size: 1.5em;">this <span style="font-weight:600;">is</span> some sample text</span>', getInnerHtml( '_P1' ) );237 assert.areSame( '<span style="font-size:1.5em;">this <span style="font-weight:600;">is</span> some sample text</span>', getInnerHtml( '_P1' ) ); 238 238 }, 239 239 240 240 test_inline13 : function() … … 251 251 assert.areSame( 'this <b>is <i>some sample</i></b><i> text</i>', getInnerHtml( '_P1' ) ); 252 252 }, 253 253 254 test_inline14 : function() 255 { 256 var para = doc.getById( '_P1' ); 257 258 para.setHtml( 'this is some sample text' ); 259 260 var range = new CKEDITOR.dom.range( doc ); 261 range.setStart( para.getFirst(), 0 ); 262 range.setEnd( para.getFirst(), 7 ); 263 264 var style = new CKEDITOR.style( { element : 'b' } ); 265 style.applyToRange( range ); 266 267 assert.areSame( '<b>this is</b> some sample text', getInnerHtml( '_P1' ), 'First range' ); 268 269 para.setHtml( para.getHtml() ); 270 271 range = new CKEDITOR.dom.range( doc ); 272 range.setStart( para.getFirst().getFirst(), 5 ); 273 range.setEnd( para.getChild( 1 ), 5 ); 274 275 style.applyToRange( range ); 276 277 assert.areSame( '<b>this is some</b> sample text', getInnerHtml( '_P1' ), 'Second range' ); 278 }, 279 280 test_inline15 : function() 281 { 282 var para = doc.getById( '_P1' ); 283 284 para.setHtml( 'this is some sample text' ); 285 286 var range = new CKEDITOR.dom.range( doc ); 287 range.setStart( para.getFirst(), 0 ); 288 range.setEnd( para.getFirst(), 7 ); 289 290 var style = new CKEDITOR.style( { element : 'span', styles : { 'font-family' : '#(family)' } }, { family : 'Arial,Helvetica,sans-serif' } ); 291 style.applyToRange( range ); 292 293 assert.areSame( '<span style="font-family:arial,helvetica,sans-serif;">this is</span> some sample text', getInnerHtml( '_P1' ), 'First range' ); 294 295 para.setHtml( para.getHtml() ); 296 297 range = new CKEDITOR.dom.range( doc ); 298 range.setStart( para.getFirst().getFirst(), 5 ); 299 range.setEnd( para.getChild( 1 ), 5 ); 300 301 style = new CKEDITOR.style( { element : 'span', styles : { 'font-family' : '#(family)' } }, { family : 'Georgia,serif' } ); 302 style.applyToRange( range ); 303 304 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' ); 305 }, 306 307 test_inline16 : function() 308 { 309 var para = doc.getById( '_P1' ); 310 311 para.setHtml( '<b lang="pt" style="font-size:11pt;color:red;">this is some sample text</b>' ); 312 313 var range = new CKEDITOR.dom.range( doc ); 314 range.setStart( para.getFirst().getFirst(), 4 ); 315 range.setEnd( para.getFirst(), 10 ); 316 317 var style = new CKEDITOR.style( { element : 'b', styles : { color : 'red', 'font-weight' : '700' } } ); 318 style.applyToRange( range ); 319 320 assert.areSame( '<b lang="pt" style="font-size:11pt;color:red;">this<b style="font-weight:700;"> is some sample text</b></b>', getInnerHtml( '_P1' ), 'First range' ); 321 }, 322 254 323 test_inline_nobreak1 : function() 255 324 { 256 325 doc.getById( '_P1' ).setHtml( 'this is <a href="http://example.com/">some sample</a> text' ); … … 278 347 279 348 assert.areSame( 'this is some <strong><i>sample</i> text<\/strong>. you are using <a href="http://www.fckeditor.net/">fckeditor<\/a>.', getInnerHtml( '_P1' ) ); 280 349 }, 350 351 test_checkElementRemovable1 : function() 352 { 353 var element = CKEDITOR.dom.element.createFromHtml( '<b>Test</b>', doc ); 281 354 355 var style = new CKEDITOR.style( { element : 'b' } ); 356 357 assert.isTrue( style.checkElementRemovable( element ) ); 358 }, 359 360 test_checkElementRemovable2 : function() 361 { 362 var element = CKEDITOR.dom.element.createFromHtml( '<b>Test</b>', doc ); 363 364 var style = new CKEDITOR.style( { element : 'i' } ); 365 366 assert.isFalse( style.checkElementRemovable( element ) ); 367 }, 368 369 test_checkElementRemovable3 : function() 370 { 371 var element = CKEDITOR.dom.element.createFromHtml( '<b>Test</b>', doc ); 372 373 var style = new CKEDITOR.style( { element : 'b', attributes : { lang : 'pt' } } ); 374 375 assert.isTrue( style.checkElementRemovable( element ) ); 376 }, 377 378 test_checkElementRemovable4 : function() 379 { 380 var element = CKEDITOR.dom.element.createFromHtml( '<b>Test</b>', doc ); 381 382 var style = new CKEDITOR.style( { element : 'b', attributes : { lang : 'pt' } } ); 383 384 assert.isFalse( style.checkElementRemovable( element, true ) ); 385 }, 386 387 test_checkElementRemovable5 : function() 388 { 389 var element = CKEDITOR.dom.element.createFromHtml( '<span lang="pt" style="color : #fff">Test</span>', doc ); 390 391 var style = new CKEDITOR.style( { element : 'span', attributes : { lang : 'pt' }, style : { color : '#ffffff' } } ); 392 393 assert.isTrue( style.checkElementRemovable( element, true ) ); 394 }, 395 396 test_checkElementRemovable6 : function() 397 { 398 var element = CKEDITOR.dom.element.createFromHtml( '<span lang="pt" style="color : #fff">Test</span>', doc ); 399 400 var style = new CKEDITOR.style( { element : 'span', attributes : { lang : 'pt' }, style : { color : '#fffff0' } } ); 401 402 assert.isTrue( style.checkElementRemovable( element, true ) ); 403 }, 404 405 test_checkElementRemovable7 : function() 406 { 407 var element = CKEDITOR.dom.element.createFromHtml( '<span lang="pt" style="color : #fff">Test</span>', doc ); 408 409 var style = new CKEDITOR.style( { element : 'span', attributes : { lang : 'fr' }, style : { color : '#ffffff' } } ); 410 411 assert.isFalse( style.checkElementRemovable( element, true ) ); 412 }, 413 414 test_checkElementRemovable8 : function() 415 { 416 var element = CKEDITOR.dom.element.createFromHtml( '<span lang="pt" style="font-size: 10px">Test</span>', doc ); 417 418 var style = new CKEDITOR.style( { element : 'span', attributes : { lang : 'pt' , style : 'font-size:10px;' } } ); 419 420 assert.isTrue( style.checkElementRemovable( element, true ) ); 421 }, 422 282 423 name : document.title 283 424 }; 284 425 })() ); 285 426 286 427 //window.onload = function() 287 428 //{ 288 // testCase.test_ inline4();429 // testCase.test_checkElementRemovable8(); 289 430 //} 290 431 291 432 //]]>