Changeset 107484 in webkit


Ignore:
Timestamp:
Feb 11, 2012 11:29:49 AM (12 years ago)
Author:
kling@webkit.org
Message:

Attribute styles should be created lazily.
<http://webkit.org/b/78381>

Reviewed by Antti Koivisto.

TL;DR summary: Lazily construct the StyledElement::attributeStyle() instead of
moving properties in/out of it in parseAttribute(). This allows us to enable
the matched declaration cache for elements with presentation attributes.

The matched declaration cache has been disabled for elements with presentation
attributes because attributeStyle() was mutable, and (simply put) the cache maps
a set of StylePropertySet pointers to a resulting RenderStyle. This requires
that the StylePropertySets are immutable.

To make them immutable, we now construct the attribute style lazily by adding
a flag (to Node) that gets set in parseAttribute() when a presentation attribute
respected by the element changes. A subsequent call to attributeStyle() checks
the flag and rebuilds the style by looping over the attributes and calling the
new virtual StyledElement::collectStyleForAttribute() on each one. Any dangling
references to the previous attribute style will be garbage collected by the
cache in CSSStyleSelector::sweepMatchedDeclarationCache().

  • css/CSSStyleSelector.cpp:

(WebCore::CSSStyleSelector::matchAllRules):

Enable matched declaration cache for elements with attribute style.

  • dom/Node.h:

(WebCore::Node::attributeStyleDirty):
(WebCore::Node::setAttributeStyleDirty):
(WebCore::Node::clearAttributeStyleDirty):

Add a Node flag to signify that a presentation attribute has changed and
the attribute style needs to be rebuilt.

  • dom/ElementAttributeData.h:
  • dom/ElementAttributeData.cpp:

(WebCore::ElementAttributeData::setAttributeStyle):

Added a setter for the attribute style, called by updateAttributeStyle().

  • dom/StyledElement.cpp:

(WebCore::StyledElement::addHTMLLengthToStyle):
(WebCore::StyledElement::addHTMLColorToStyle):

Moved and renamed two of the old addCSS* helpers from StyledElement.

(WebCore::StyledElement::updateAttributeStyle):

Called by attributeStyle() in case the "attribute style dirty" flag is
set. Rebuilds the attribute style from scratch by looping over the
attribute map and calling collectStyleForAttribute() on each attribute.

  • dom/StyledElement.h:

(WebCore::StyledElement::collectStyleForAttribute):
(WebCore::StyledElement::attributeStyle):
(WebCore::StyledElement::setNeedsAttributeStyleUpdate):

Helper, sets the attribute style dirty flag and marks the element for
full style recalc. This is what parseAttribute() calls in subclasses
when they encounter a presentation attribute.

  • html/HTMLBRElement.cpp:

(WebCore::HTMLBRElement::collectStyleForAttribute):
(WebCore::HTMLBRElement::parseAttribute):

  • html/HTMLBRElement.h:
  • html/HTMLBodyElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLBodyElement::collectStyleForAttribute):
(WebCore::HTMLBodyElement::parseAttribute):

  • html/HTMLBodyElement.h:
  • html/HTMLDivElement.cpp:

(WebCore::HTMLDivElement::collectStyleForAttribute):
(WebCore::HTMLDivElement::parseAttribute):

  • html/HTMLDivElement.h:
  • html/HTMLElement.cpp:

(WebCore::HTMLElement::applyBorderAttributeToStyle):
(WebCore::HTMLElement::mapLanguageAttributeToLocale):
(WebCore::HTMLElement::collectStyleForAttribute):
(WebCore::HTMLElement::parseAttribute):
(WebCore::HTMLElement::applyAlignmentAttributeToStyle):

  • html/HTMLElement.h:
  • html/HTMLEmbedElement.cpp:

(WebCore::HTMLEmbedElement::collectStyleForAttribute):
(WebCore::HTMLEmbedElement::parseAttribute):

  • html/HTMLEmbedElement.h:
  • html/HTMLFontElement.cpp:

(WebCore::HTMLFontElement::collectStyleForAttribute):
(WebCore::HTMLFontElement::parseAttribute):

  • html/HTMLFontElement.h:
  • html/HTMLFrameSetElement.cpp:

(WebCore::HTMLFrameSetElement::collectStyleForAttribute):
(WebCore::HTMLFrameSetElement::parseAttribute):

  • html/HTMLFrameSetElement.h:
  • html/HTMLHRElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLHRElement::collectStyleForAttribute):
(WebCore::HTMLHRElement::parseAttribute):

  • html/HTMLHRElement.h:
  • html/HTMLIFrameElement.cpp:

(WebCore::HTMLIFrameElement::collectStyleForAttribute):
(WebCore::HTMLIFrameElement::parseAttribute):

  • html/HTMLIFrameElement.h:
  • html/HTMLImageElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLImageElement::collectStyleForAttribute):
(WebCore::HTMLImageElement::parseAttribute):

  • html/HTMLImageElement.h:
  • html/HTMLInputElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLInputElement::collectStyleForAttribute):
(WebCore::HTMLInputElement::parseAttribute):

  • html/HTMLInputElement.h:
  • html/HTMLLIElement.cpp:

(WebCore::HTMLLIElement::collectStyleForAttribute):
(WebCore::HTMLLIElement::parseAttribute):

  • html/HTMLLIElement.h:
  • html/HTMLMarqueeElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLMarqueeElement::collectStyleForAttribute):
(WebCore::HTMLMarqueeElement::parseAttribute):

  • html/HTMLMarqueeElement.h:
  • html/HTMLOListElement.cpp:

(WebCore::HTMLOListElement::collectStyleForAttribute):
(WebCore::HTMLOListElement::parseAttribute):

  • html/HTMLOListElement.h:
  • html/HTMLObjectElement.cpp:

(WebCore::HTMLObjectElement::collectStyleForAttribute):
(WebCore::HTMLObjectElement::parseAttribute):

  • html/HTMLObjectElement.h:
  • html/HTMLParagraphElement.cpp:

(WebCore::HTMLParagraphElement::collectStyleForAttribute):
(WebCore::HTMLParagraphElement::parseAttribute):

  • html/HTMLParagraphElement.h:
  • html/HTMLPlugInElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLPlugInElement::collectStyleForAttribute):
(WebCore::HTMLPlugInElement::parseAttribute):

  • html/HTMLPlugInElement.h:
  • html/HTMLPreElement.cpp:

(WebCore::HTMLPreElement::collectStyleForAttribute):
(WebCore::HTMLPreElement::parseAttribute):

  • html/HTMLPreElement.h:
  • html/HTMLTableCaptionElement.cpp:

(WebCore::HTMLTableCaptionElement::collectStyleForAttribute):
(WebCore::HTMLTableCaptionElement::parseAttribute):

  • html/HTMLTableCaptionElement.h:
  • html/HTMLTableCellElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLTableCellElement::collectStyleForAttribute):
(WebCore::HTMLTableCellElement::parseAttribute):

  • html/HTMLTableCellElement.h:
  • html/HTMLTableColElement.cpp:

(WebCore::HTMLTableColElement::collectStyleForAttribute):
(WebCore::HTMLTableColElement::parseAttribute):

  • html/HTMLTableColElement.h:
  • html/HTMLTableElement.cpp:

(WebCore::getBordersFromFrameAttributeValue):
(WebCore::HTMLTableElement::collectStyleForAttribute):
(WebCore::HTMLTableElement::parseAttribute):

  • html/HTMLTableElement.h:
  • html/HTMLTablePartElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::HTMLTablePartElement::collectStyleForAttribute):
(WebCore::HTMLTablePartElement::parseAttribute):

  • html/HTMLTablePartElement.h:
  • html/HTMLTextAreaElement.cpp:

(WebCore::HTMLTextAreaElement::collectStyleForAttribute):
(WebCore::HTMLTextAreaElement::parseAttribute):

  • html/HTMLTextAreaElement.h:
  • html/HTMLUListElement.cpp:

(WebCore::HTMLUListElement::collectStyleForAttribute):
(WebCore::HTMLUListElement::parseAttribute):

  • html/HTMLUListElement.h:
  • html/HTMLVideoElement.cpp:

(WebCore::HTMLVideoElement::collectStyleForAttribute):
(WebCore::HTMLVideoElement::parseAttribute):

  • html/HTMLVideoElement.h:
  • mathml/MathMLElement.cpp:

(WebCore::isRespectedPresentationAttribute):
(WebCore::MathMLElement::collectStyleForAttribute):
(WebCore::MathMLElement::parseAttribute):

  • mathml/MathMLElement.h:
  • svg/SVGImageElement.cpp:

(WebCore::SVGImageElement::collectStyleForAttribute):
(WebCore::SVGImageElement::parseAttribute):

  • svg/SVGImageElement.h:
  • svg/SVGStyledElement.cpp:

(WebCore::SVGStyledElement::collectStyleForAttribute):
(WebCore::SVGStyledElement::parseAttribute):

  • svg/SVGStyledElement.h:
  • svg/SVGTextContentElement.cpp:

(WebCore::SVGTextContentElement::collectStyleForAttribute):
(WebCore::SVGTextContentElement::parseAttribute):

  • svg/SVGTextContentElement.h:

Split handling of presentation attributes between parseAttribute() and
collectStyleForAttribute() as appropriate. Some minor refactorings here and
there (mostly in HTMLTableElement) to avoid excessive code duplication.
Also sprinkled FIXMEs about inefficiencies we should clean up.

Location:
trunk/Source/WebCore
Files:
67 edited

Legend:

Unmodified
Added
Removed
  • trunk/Source/WebCore/ChangeLog

    r107483 r107484  
     12012-02-11  Andreas Kling  <awesomekling@apple.com>
     2
     3        Attribute styles should be created lazily.
     4        <http://webkit.org/b/78381>
     5
     6        Reviewed by Antti Koivisto.
     7
     8        TL;DR summary: Lazily construct the StyledElement::attributeStyle() instead of
     9        moving properties in/out of it in parseAttribute(). This allows us to enable
     10        the matched declaration cache for elements with presentation attributes.
     11
     12        The matched declaration cache has been disabled for elements with presentation
     13        attributes because attributeStyle() was mutable, and (simply put) the cache maps
     14        a set of StylePropertySet pointers to a resulting RenderStyle. This requires
     15        that the StylePropertySets are immutable.
     16
     17        To make them immutable, we now construct the attribute style lazily by adding
     18        a flag (to Node) that gets set in parseAttribute() when a presentation attribute
     19        respected by the element changes. A subsequent call to attributeStyle() checks
     20        the flag and rebuilds the style by looping over the attributes and calling the
     21        new virtual StyledElement::collectStyleForAttribute() on each one. Any dangling
     22        references to the previous attribute style will be garbage collected by the
     23        cache in CSSStyleSelector::sweepMatchedDeclarationCache().
     24
     25        * css/CSSStyleSelector.cpp:
     26        (WebCore::CSSStyleSelector::matchAllRules):
     27
     28            Enable matched declaration cache for elements with attribute style.
     29
     30        * dom/Node.h:
     31        (WebCore::Node::attributeStyleDirty):
     32        (WebCore::Node::setAttributeStyleDirty):
     33        (WebCore::Node::clearAttributeStyleDirty):
     34
     35            Add a Node flag to signify that a presentation attribute has changed and
     36            the attribute style needs to be rebuilt.
     37
     38        * dom/ElementAttributeData.h:
     39        * dom/ElementAttributeData.cpp:
     40        (WebCore::ElementAttributeData::setAttributeStyle):
     41
     42            Added a setter for the attribute style, called by updateAttributeStyle().
     43
     44        * dom/StyledElement.cpp:
     45        (WebCore::StyledElement::addHTMLLengthToStyle):
     46        (WebCore::StyledElement::addHTMLColorToStyle):
     47
     48            Moved and renamed two of the old addCSS* helpers from StyledElement.
     49
     50        (WebCore::StyledElement::updateAttributeStyle):
     51
     52            Called by attributeStyle() in case the "attribute style dirty" flag is
     53            set. Rebuilds the attribute style from scratch by looping over the
     54            attribute map and calling collectStyleForAttribute() on each attribute.
     55
     56        * dom/StyledElement.h:
     57        (WebCore::StyledElement::collectStyleForAttribute):
     58        (WebCore::StyledElement::attributeStyle):
     59        (WebCore::StyledElement::setNeedsAttributeStyleUpdate):
     60
     61            Helper, sets the attribute style dirty flag and marks the element for
     62            full style recalc. This is what parseAttribute() calls in subclasses
     63            when they encounter a presentation attribute.
     64
     65        * html/HTMLBRElement.cpp:
     66        (WebCore::HTMLBRElement::collectStyleForAttribute):
     67        (WebCore::HTMLBRElement::parseAttribute):
     68        * html/HTMLBRElement.h:
     69        * html/HTMLBodyElement.cpp:
     70        (WebCore::isRespectedPresentationAttribute):
     71        (WebCore::HTMLBodyElement::collectStyleForAttribute):
     72        (WebCore::HTMLBodyElement::parseAttribute):
     73        * html/HTMLBodyElement.h:
     74        * html/HTMLDivElement.cpp:
     75        (WebCore::HTMLDivElement::collectStyleForAttribute):
     76        (WebCore::HTMLDivElement::parseAttribute):
     77        * html/HTMLDivElement.h:
     78        * html/HTMLElement.cpp:
     79        (WebCore::HTMLElement::applyBorderAttributeToStyle):
     80        (WebCore::HTMLElement::mapLanguageAttributeToLocale):
     81        (WebCore::HTMLElement::collectStyleForAttribute):
     82        (WebCore::HTMLElement::parseAttribute):
     83        (WebCore::HTMLElement::applyAlignmentAttributeToStyle):
     84        * html/HTMLElement.h:
     85        * html/HTMLEmbedElement.cpp:
     86        (WebCore::HTMLEmbedElement::collectStyleForAttribute):
     87        (WebCore::HTMLEmbedElement::parseAttribute):
     88        * html/HTMLEmbedElement.h:
     89        * html/HTMLFontElement.cpp:
     90        (WebCore::HTMLFontElement::collectStyleForAttribute):
     91        (WebCore::HTMLFontElement::parseAttribute):
     92        * html/HTMLFontElement.h:
     93        * html/HTMLFrameSetElement.cpp:
     94        (WebCore::HTMLFrameSetElement::collectStyleForAttribute):
     95        (WebCore::HTMLFrameSetElement::parseAttribute):
     96        * html/HTMLFrameSetElement.h:
     97        * html/HTMLHRElement.cpp:
     98        (WebCore::isRespectedPresentationAttribute):
     99        (WebCore::HTMLHRElement::collectStyleForAttribute):
     100        (WebCore::HTMLHRElement::parseAttribute):
     101        * html/HTMLHRElement.h:
     102        * html/HTMLIFrameElement.cpp:
     103        (WebCore::HTMLIFrameElement::collectStyleForAttribute):
     104        (WebCore::HTMLIFrameElement::parseAttribute):
     105        * html/HTMLIFrameElement.h:
     106        * html/HTMLImageElement.cpp:
     107        (WebCore::isRespectedPresentationAttribute):
     108        (WebCore::HTMLImageElement::collectStyleForAttribute):
     109        (WebCore::HTMLImageElement::parseAttribute):
     110        * html/HTMLImageElement.h:
     111        * html/HTMLInputElement.cpp:
     112        (WebCore::isRespectedPresentationAttribute):
     113        (WebCore::HTMLInputElement::collectStyleForAttribute):
     114        (WebCore::HTMLInputElement::parseAttribute):
     115        * html/HTMLInputElement.h:
     116        * html/HTMLLIElement.cpp:
     117        (WebCore::HTMLLIElement::collectStyleForAttribute):
     118        (WebCore::HTMLLIElement::parseAttribute):
     119        * html/HTMLLIElement.h:
     120        * html/HTMLMarqueeElement.cpp:
     121        (WebCore::isRespectedPresentationAttribute):
     122        (WebCore::HTMLMarqueeElement::collectStyleForAttribute):
     123        (WebCore::HTMLMarqueeElement::parseAttribute):
     124        * html/HTMLMarqueeElement.h:
     125        * html/HTMLOListElement.cpp:
     126        (WebCore::HTMLOListElement::collectStyleForAttribute):
     127        (WebCore::HTMLOListElement::parseAttribute):
     128        * html/HTMLOListElement.h:
     129        * html/HTMLObjectElement.cpp:
     130        (WebCore::HTMLObjectElement::collectStyleForAttribute):
     131        (WebCore::HTMLObjectElement::parseAttribute):
     132        * html/HTMLObjectElement.h:
     133        * html/HTMLParagraphElement.cpp:
     134        (WebCore::HTMLParagraphElement::collectStyleForAttribute):
     135        (WebCore::HTMLParagraphElement::parseAttribute):
     136        * html/HTMLParagraphElement.h:
     137        * html/HTMLPlugInElement.cpp:
     138        (WebCore::isRespectedPresentationAttribute):
     139        (WebCore::HTMLPlugInElement::collectStyleForAttribute):
     140        (WebCore::HTMLPlugInElement::parseAttribute):
     141        * html/HTMLPlugInElement.h:
     142        * html/HTMLPreElement.cpp:
     143        (WebCore::HTMLPreElement::collectStyleForAttribute):
     144        (WebCore::HTMLPreElement::parseAttribute):
     145        * html/HTMLPreElement.h:
     146        * html/HTMLTableCaptionElement.cpp:
     147        (WebCore::HTMLTableCaptionElement::collectStyleForAttribute):
     148        (WebCore::HTMLTableCaptionElement::parseAttribute):
     149        * html/HTMLTableCaptionElement.h:
     150        * html/HTMLTableCellElement.cpp:
     151        (WebCore::isRespectedPresentationAttribute):
     152        (WebCore::HTMLTableCellElement::collectStyleForAttribute):
     153        (WebCore::HTMLTableCellElement::parseAttribute):
     154        * html/HTMLTableCellElement.h:
     155        * html/HTMLTableColElement.cpp:
     156        (WebCore::HTMLTableColElement::collectStyleForAttribute):
     157        (WebCore::HTMLTableColElement::parseAttribute):
     158        * html/HTMLTableColElement.h:
     159        * html/HTMLTableElement.cpp:
     160        (WebCore::getBordersFromFrameAttributeValue):
     161        (WebCore::HTMLTableElement::collectStyleForAttribute):
     162        (WebCore::HTMLTableElement::parseAttribute):
     163        * html/HTMLTableElement.h:
     164        * html/HTMLTablePartElement.cpp:
     165        (WebCore::isRespectedPresentationAttribute):
     166        (WebCore::HTMLTablePartElement::collectStyleForAttribute):
     167        (WebCore::HTMLTablePartElement::parseAttribute):
     168        * html/HTMLTablePartElement.h:
     169        * html/HTMLTextAreaElement.cpp:
     170        (WebCore::HTMLTextAreaElement::collectStyleForAttribute):
     171        (WebCore::HTMLTextAreaElement::parseAttribute):
     172        * html/HTMLTextAreaElement.h:
     173        * html/HTMLUListElement.cpp:
     174        (WebCore::HTMLUListElement::collectStyleForAttribute):
     175        (WebCore::HTMLUListElement::parseAttribute):
     176        * html/HTMLUListElement.h:
     177        * html/HTMLVideoElement.cpp:
     178        (WebCore::HTMLVideoElement::collectStyleForAttribute):
     179        (WebCore::HTMLVideoElement::parseAttribute):
     180        * html/HTMLVideoElement.h:
     181        * mathml/MathMLElement.cpp:
     182        (WebCore::isRespectedPresentationAttribute):
     183        (WebCore::MathMLElement::collectStyleForAttribute):
     184        (WebCore::MathMLElement::parseAttribute):
     185        * mathml/MathMLElement.h:
     186        * svg/SVGImageElement.cpp:
     187        (WebCore::SVGImageElement::collectStyleForAttribute):
     188        (WebCore::SVGImageElement::parseAttribute):
     189        * svg/SVGImageElement.h:
     190        * svg/SVGStyledElement.cpp:
     191        (WebCore::SVGStyledElement::collectStyleForAttribute):
     192        (WebCore::SVGStyledElement::parseAttribute):
     193        * svg/SVGStyledElement.h:
     194        * svg/SVGTextContentElement.cpp:
     195        (WebCore::SVGTextContentElement::collectStyleForAttribute):
     196        (WebCore::SVGTextContentElement::parseAttribute):
     197        * svg/SVGTextContentElement.h:
     198
     199            Split handling of presentation attributes between parseAttribute() and
     200            collectStyleForAttribute() as appropriate. Some minor refactorings here and
     201            there (mostly in HTMLTableElement) to avoid excessive code duplication.
     202            Also sprinkled FIXMEs about inefficiencies we should clean up.
     203
    12042012-02-11   Arko Saha  <arko@motorola.com>
    2205
  • trunk/Source/WebCore/css/CSSStyleSelector.cpp

    r107289 r107484  
    10031003                    result.ranges.firstAuthorRule = result.ranges.lastAuthorRule;
    10041004                addMatchedDeclaration(attributeStyle);
    1005                 result.isCacheable = false;
    10061005            }
    10071006        }
  • trunk/Source/WebCore/dom/ElementAttributeData.cpp

    r106863 r107484  
    5454}
    5555
    56 StylePropertySet* ElementAttributeData::ensureAttributeStyle(StyledElement* element)
    57 {
    58     if (!m_attributeStyle)
    59         m_attributeStyle = StylePropertySet::createAttributeStyle(element);
    60     return m_attributeStyle.get();
    6156}
    62 
    63 }
  • trunk/Source/WebCore/dom/ElementAttributeData.h

    r106863 r107484  
    4848
    4949    StylePropertySet* attributeStyle() const { return m_attributeStyle.get(); }
    50     StylePropertySet* ensureAttributeStyle(StyledElement*);
     50    void setAttributeStyle(PassRefPtr<StylePropertySet> style) { m_attributeStyle = style; }
    5151
    5252private:
  • trunk/Source/WebCore/dom/Node.h

    r107347 r107484  
    301301    virtual void startLoadingDynamicSheet() { ASSERT_NOT_REACHED(); }
    302302
     303    bool attributeStyleDirty() const { return getFlag(AttributeStyleDirtyFlag); }
    303304    bool hasName() const { return getFlag(HasNameFlag); }
    304305    bool hasID() const { return getFlag(HasIDFlag); }
     
    315316    bool childNeedsStyleRecalc() const { return getFlag(ChildNeedsStyleRecalcFlag); }
    316317    bool isLink() const { return getFlag(IsLinkFlag); }
     318
     319    void setAttributeStyleDirty() { setFlag(AttributeStyleDirtyFlag); }
     320    void clearAttributeStyleDirty() { clearFlag(AttributeStyleDirtyFlag); }
    317321
    318322    void setHasName(bool f) { setFlag(f, HasNameFlag); }
     
    677681        HasNameFlag = 1 << 30,
    678682
     683        AttributeStyleDirtyFlag = 1 << 31,
     684
    679685#if ENABLE(SVG)
    680686        DefaultNodeFlags = IsParsingChildrenFinishedFlag | IsStyleAttributeValidFlag | AreSVGAttributesValidFlag
  • trunk/Source/WebCore/dom/StyledElement.cpp

    r107061 r107484  
    106106}
    107107
    108 void StyledElement::removeCSSProperties(int id1, int id2, int id3, int id4, int id5, int id6, int id7, int id8)
    109 {
    110     StylePropertySet* style = attributeStyle();
    111     if (!style)
    112         return;
    113 
    114     ASSERT(id1 != CSSPropertyInvalid);
    115     style->removeProperty(id1);
    116 
    117     if (id2 == CSSPropertyInvalid)
    118         return;
    119     style->removeProperty(id2);
    120     if (id3 == CSSPropertyInvalid)
    121         return;
    122     style->removeProperty(id3);
    123     if (id4 == CSSPropertyInvalid)
    124         return;
    125     style->removeProperty(id4);
    126     if (id5 == CSSPropertyInvalid)
    127         return;
    128     style->removeProperty(id5);
    129     if (id6 == CSSPropertyInvalid)
    130         return;
    131     style->removeProperty(id6);
    132     if (id7 == CSSPropertyInvalid)
    133         return;
    134     style->removeProperty(id7);
    135     if (id8 == CSSPropertyInvalid)
    136         return;
    137     style->removeProperty(id8);
    138 }
    139 
    140 void StyledElement::addCSSProperty(int id, const String &value)
    141 {
    142     if (!ensureAttributeStyle()->setProperty(id, value))
    143         removeCSSProperty(id);
    144 }
    145 
    146 void StyledElement::addCSSProperty(int propertyID, int identifier)
    147 {
    148     ensureAttributeStyle()->setProperty(CSSProperty(propertyID, document()->cssValuePool()->createIdentifierValue(identifier)));
    149     setNeedsStyleRecalc();
    150 }
    151 
    152 void StyledElement::addCSSImageProperty(int id, const String& url)
    153 {
    154     ensureAttributeStyle()->setProperty(CSSProperty(id, CSSImageValue::create(url)));
    155     setNeedsStyleRecalc();
    156 }
    157 
    158 void StyledElement::addCSSLength(int id, const String &value)
    159 {
    160     // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
    161     // length unit and make the appropriate parsed value.
    162 
    163     // strip attribute garbage..
    164     StringImpl* v = value.impl();
    165     if (v) {
    166         unsigned int l = 0;
    167        
    168         while (l < v->length() && (*v)[l] <= ' ')
    169             l++;
    170        
    171         for (; l < v->length(); l++) {
    172             UChar cc = (*v)[l];
    173             if (cc > '9')
    174                 break;
    175             if (cc < '0') {
    176                 if (cc == '%' || cc == '*')
    177                     l++;
    178                 if (cc != '.')
    179                     break;
    180             }
    181         }
    182 
    183         if (l != v->length()) {
    184             addCSSProperty(id, v->substring(0, l));
    185             return;
    186         }
    187     }
    188 
    189     addCSSProperty(id, value);
    190 }
    191 
    192 static String parseColorStringWithCrazyLegacyRules(const String& colorString)
    193 {
    194     // Per spec, only look at the first 128 digits of the string.
    195     const size_t maxColorLength = 128;
    196     // We'll pad the buffer with two extra 0s later, so reserve two more than the max.
    197     Vector<char, maxColorLength+2> digitBuffer;
    198    
    199     size_t i = 0;
    200     // Skip a leading #.
    201     if (colorString[0] == '#')
    202         i = 1;
    203    
    204     // Grab the first 128 characters, replacing non-hex characters with 0.
    205     // Non-BMP characters are replaced with "00" due to them appearing as two "characters" in the String.
    206     for (; i < colorString.length() && digitBuffer.size() < maxColorLength; i++) {
    207         if (!isASCIIHexDigit(colorString[i]))
    208             digitBuffer.append('0');
    209         else
    210             digitBuffer.append(colorString[i]);
    211     }
    212 
    213     if (!digitBuffer.size())
    214         return "#000000";
    215 
    216     // Pad the buffer out to at least the next multiple of three in size.
    217     digitBuffer.append('0');
    218     digitBuffer.append('0');
    219 
    220     if (digitBuffer.size() < 6)
    221         return String::format("#0%c0%c0%c", digitBuffer[0], digitBuffer[1], digitBuffer[2]);
    222    
    223     // Split the digits into three components, then search the last 8 digits of each component.
    224     ASSERT(digitBuffer.size() >= 6);
    225     size_t componentLength = digitBuffer.size() / 3;
    226     size_t componentSearchWindowLength = min<size_t>(componentLength, 8);
    227     size_t redIndex = componentLength - componentSearchWindowLength;
    228     size_t greenIndex = componentLength * 2 - componentSearchWindowLength;
    229     size_t blueIndex = componentLength * 3 - componentSearchWindowLength;
    230     // Skip digits until one of them is non-zero, or we've only got two digits left in the component.
    231     while (digitBuffer[redIndex] == '0' && digitBuffer[greenIndex] == '0' && digitBuffer[blueIndex] == '0' && (componentLength - redIndex) > 2) {
    232         redIndex++;
    233         greenIndex++;
    234         blueIndex++;
    235     }
    236     ASSERT(redIndex + 1 < componentLength);
    237     ASSERT(greenIndex >= componentLength);
    238     ASSERT(greenIndex + 1 < componentLength * 2);
    239     ASSERT(blueIndex >= componentLength * 2);
    240     ASSERT(blueIndex + 1 < digitBuffer.size());
    241     return String::format("#%c%c%c%c%c%c", digitBuffer[redIndex], digitBuffer[redIndex + 1], digitBuffer[greenIndex], digitBuffer[greenIndex + 1], digitBuffer[blueIndex], digitBuffer[blueIndex + 1]);   
    242 }
    243 
    244 // Color parsing that matches HTML's "rules for parsing a legacy color value"
    245 void StyledElement::addCSSColor(int id, const String& attributeValue)
    246 {
    247     // An empty string doesn't apply a color. (One containing only whitespace does, which is why this check occurs before stripping.)
    248     if (attributeValue.isEmpty()) {
    249         removeCSSProperty(id);
    250         return;
    251     }
    252 
    253     String colorString = attributeValue.stripWhiteSpace();
    254 
    255     // "transparent" doesn't apply a color either.
    256     if (equalIgnoringCase(colorString, "transparent")) {
    257         removeCSSProperty(id);
    258         return;
    259     }
    260 
    261     // If the string is a named CSS color or a 3/6-digit hex color, use that.
    262     Color parsedColor(colorString);
    263     if (parsedColor.isValid()) {
    264         addCSSProperty(id, colorString);
    265         return;
    266     }
    267 
    268     addCSSProperty(id, parseColorStringWithCrazyLegacyRules(colorString));
    269 }
    270 
    271 void StyledElement::copyNonAttributeProperties(const Element* sourceElement)
    272 {
    273     ASSERT(sourceElement);
    274     ASSERT(sourceElement->isStyledElement());
    275 
    276     const StyledElement* source = static_cast<const StyledElement*>(sourceElement);
    277     if (!source->inlineStyleDecl())
    278         return;
    279 
    280     StylePropertySet* inlineStyle = ensureInlineStyleDecl();
    281     inlineStyle->copyPropertiesFrom(*source->inlineStyleDecl());
    282     inlineStyle->setStrictParsing(source->inlineStyleDecl()->useStrictParsing());
    283 
    284     setIsStyleAttributeValid(source->isStyleAttributeValid());
    285     setIsSynchronizingStyleAttribute(source->isSynchronizingStyleAttribute());
    286    
    287     Element::copyNonAttributeProperties(sourceElement);
    288 }
    289 
    290108void StyledElement::addSubresourceAttributeURLs(ListHashSet<KURL>& urls) const
    291109{
     
    294112}
    295113
     114void StyledElement::updateAttributeStyle()
     115{
     116    RefPtr<StylePropertySet> style = StylePropertySet::createAttributeStyle(this);
     117    for (unsigned i = 0; i < attributeCount(); ++i) {
     118        Attribute* attribute = attributeItem(i);
     119        collectStyleForAttribute(attribute, style.get());
     120    }
     121    clearAttributeStyleDirty();
     122    ensureAttributeDataWithoutUpdate()->setAttributeStyle(style.release());
    296123}
     124
     125}
  • trunk/Source/WebCore/dom/StyledElement.h

    r107185 r107484  
    3737    virtual ~StyledElement();
    3838
    39     void addCSSLength(int id, const String& value);
    40     void addCSSProperty(int id, const String& value);
    41     void addCSSProperty(int id, int value);
    42     void addCSSImageProperty(int propertyID, const String& url);
    43     void addCSSColor(int id, const String& color);
    44     void removeCSSProperties(int id1, int id2 = CSSPropertyInvalid, int id3 = CSSPropertyInvalid, int id4 = CSSPropertyInvalid, int id5 = CSSPropertyInvalid, int id6 = CSSPropertyInvalid, int id7 = CSSPropertyInvalid, int id8 = CSSPropertyInvalid);
    45     void removeCSSProperty(int id) { removeCSSProperties(id); }
    46 
    4739    virtual StylePropertySet* additionalAttributeStyle() { return 0; }
    4840    void invalidateStyleAttribute();
     
    5244    virtual CSSStyleDeclaration* style() OVERRIDE { return ensureInlineStyleDecl()->ensureCSSStyleDeclaration(); }
    5345
    54     StylePropertySet* attributeStyle() const { return attributeData() ? attributeData()->attributeStyle() : 0; }
    55     StylePropertySet* ensureAttributeStyle() { return ensureAttributeDataWithoutUpdate()->ensureAttributeStyle(this); }
     46    StylePropertySet* attributeStyle();
    5647
    5748    const SpaceSplitString& classNames() const;
     
    6354    }
    6455
     56    void setNeedsAttributeStyleUpdate();
     57
    6558    virtual void attributeChanged(Attribute*) OVERRIDE;
    6659    virtual void parseAttribute(Attribute*);
    6760    virtual void copyNonAttributeProperties(const Element*);
     61
     62    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) { }
    6863
    6964    virtual void addSubresourceAttributeURLs(ListHashSet<KURL>&) const;
     
    7671private:
    7772    virtual void updateStyleAttribute() const;
     73
     74    void updateAttributeStyle();
    7875
    7976    void destroyInlineStyleDecl()
     
    9693}
    9794
     95inline StylePropertySet* StyledElement::attributeStyle()
     96{
     97    if (attributeStyleDirty())
     98        updateAttributeStyle();
     99    return attributeData() ? attributeData()->attributeStyle() : 0;
     100}
     101
     102inline void StyledElement::setNeedsAttributeStyleUpdate()
     103{
     104    setAttributeStyleDirty();
     105    setNeedsStyleRecalc();
     106}
     107
    98108} //namespace
    99109
  • trunk/Source/WebCore/html/HTMLBRElement.cpp

    r106769 r107484  
    4949}
    5050
     51void HTMLBRElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     52{
     53    if (attr->name() == clearAttr) {
     54        // If the string is empty, then don't add the clear property.
     55        // <br clear> and <br clear=""> are just treated like <br> by Gecko, Mac IE, etc. -dwh
     56        if (!attr->isEmpty()) {
     57            if (equalIgnoringCase(attr->value(), "all"))
     58                style->setProperty(CSSPropertyClear, "both");
     59            else
     60                style->setProperty(CSSPropertyClear, attr->value());
     61        }
     62    } else
     63        HTMLElement::collectStyleForAttribute(attr, style);
     64}
     65
    5166void HTMLBRElement::parseAttribute(Attribute* attr)
    5267{
    53     if (attr->name() == clearAttr) {
    54         // If the string is empty, then don't add the clear property.
    55         // <br clear> and <br clear=""> are just treated like <br> by Gecko, Mac IE, etc. -dwh
    56         if (attr->value().isNull())
    57             removeCSSProperty(CSSPropertyClear);
    58         else if (!attr->value().isEmpty()) {
    59             if (equalIgnoringCase(attr->value(), "all"))
    60                 addCSSProperty(CSSPropertyClear, "both");
    61             else
    62                 addCSSProperty(CSSPropertyClear, attr->value());
    63         }
    64     } else
     68    if (attr->name() == clearAttr)
     69        setNeedsAttributeStyleUpdate();
     70    else
    6571        HTMLElement::parseAttribute(attr);
    6672}
  • trunk/Source/WebCore/html/HTMLBRElement.h

    r106769 r107484  
    4040
    4141    virtual void parseAttribute(Attribute*) OVERRIDE;
    42    
     42    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
     43
    4344    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    4445};
  • trunk/Source/WebCore/html/HTMLBodyElement.cpp

    r106899 r107484  
    2626
    2727#include "Attribute.h"
     28#include "CSSImageValue.h"
    2829#include "CSSParser.h"
    2930#include "CSSValueKeywords.h"
     
    6162}
    6263
    63 void HTMLBodyElement::parseAttribute(Attribute* attr)
     64static inline bool isRespectedPresentationAttribute(Attribute* attr)
     65{
     66    return attr->name() == backgroundAttr || attr->name() == marginwidthAttr || attr->name() == leftmarginAttr || attr->name() == marginheightAttr || attr->name() == topmarginAttr || attr->name() == bgcolorAttr || attr->name() == textAttr || attr->name() == bgpropertiesAttr;
     67
     68}
     69
     70void HTMLBodyElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    6471{
    6572    if (attr->name() == backgroundAttr) {
    6673        String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
    6774        if (!url.isEmpty())
    68             addCSSImageProperty(CSSPropertyBackgroundImage, document()->completeURL(url).string());
    69         else
    70             removeCSSProperty(CSSPropertyBackgroundImage);
     75            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document()->completeURL(url).string())));
    7176    } else if (attr->name() == marginwidthAttr || attr->name() == leftmarginAttr) {
    72         if (attr->value().isNull())
    73             removeCSSProperties(CSSPropertyMarginRight, CSSPropertyMarginLeft);
    74         else {
    75             addCSSLength(CSSPropertyMarginRight, attr->value());
    76             addCSSLength(CSSPropertyMarginLeft, attr->value());
    77         }
     77        addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     78        addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
    7879    } else if (attr->name() == marginheightAttr || attr->name() == topmarginAttr) {
    79         if (attr->value().isNull())
    80             removeCSSProperties(CSSPropertyMarginBottom, CSSPropertyMarginTop);
    81         else {
    82             addCSSLength(CSSPropertyMarginBottom, attr->value());
    83             addCSSLength(CSSPropertyMarginTop, attr->value());
    84         }
     80        addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     81        addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
    8582    } else if (attr->name() == bgcolorAttr) {
    86         if (attr->value().isNull())
    87             removeCSSProperty(CSSPropertyBackgroundColor);
    88         else
    89             addCSSColor(CSSPropertyBackgroundColor, attr->value());
     83        addHTMLColorToStyle(style, CSSPropertyBackgroundColor, attr->value());
    9084    } else if (attr->name() == textAttr) {
    91         if (attr->value().isNull())
    92             removeCSSProperty(CSSPropertyColor);
    93         else
    94             addCSSColor(CSSPropertyColor, attr->value());
     85        addHTMLColorToStyle(style, CSSPropertyColor, attr->value());
    9586    } else if (attr->name() == bgpropertiesAttr) {
    9687        if (equalIgnoringCase(attr->value(), "fixed"))
    97             addCSSProperty(CSSPropertyBackgroundAttachment, CSSValueFixed);
    98         else
    99             removeCSSProperty(CSSPropertyBackgroundAttachment);
    100     } else if (attr->name() == vlinkAttr ||
    101                attr->name() == alinkAttr ||
    102                attr->name() == linkAttr) {
     88           style->setProperty(CSSPropertyBackgroundAttachment, CSSValueFixed);
     89    } else {
     90        ASSERT(!isRespectedPresentationAttribute(attr));
     91        HTMLElement::collectStyleForAttribute(attr, style);
     92    }
     93}
     94
     95void HTMLBodyElement::parseAttribute(Attribute* attr)
     96{
     97    if (isRespectedPresentationAttribute(attr))
     98        setNeedsAttributeStyleUpdate();
     99    else if (attr->name() == vlinkAttr || attr->name() == alinkAttr || attr->name() == linkAttr) {
    103100        if (attr->isNull()) {
    104101            if (attr->name() == linkAttr)
  • trunk/Source/WebCore/html/HTMLBodyElement.h

    r106769 r107484  
    7272
    7373    virtual void parseAttribute(Attribute*) OVERRIDE;
     74    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    7475
    7576    virtual void insertedIntoDocument();
  • trunk/Source/WebCore/html/HTMLDivElement.cpp

    r106769 r107484  
    4949}
    5050
     51void HTMLDivElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     52{
     53    if (attr->name() == alignAttr) {
     54        if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
     55            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
     56        else if (equalIgnoringCase(attr->value(), "left"))
     57            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
     58        else if (equalIgnoringCase(attr->value(), "right"))
     59            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
     60        else
     61            style->setProperty(CSSPropertyTextAlign, attr->value());
     62    } else
     63        HTMLElement::collectStyleForAttribute(attr, style);
     64}
     65
    5166void HTMLDivElement::parseAttribute(Attribute* attr)
    5267{
    53     if (attr->name() == alignAttr) {
    54         if (attr->value().isNull())
    55             removeCSSProperty(CSSPropertyTextAlign);
    56         if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
    57            addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
    58         else if (equalIgnoringCase(attr->value(), "left"))
    59             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
    60         else if (equalIgnoringCase(attr->value(), "right"))
    61             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
    62         else
    63             addCSSProperty(CSSPropertyTextAlign, attr->value());
    64     } else
     68    if (attr->name() == alignAttr)
     69        setNeedsAttributeStyleUpdate();
     70    else
    6571        HTMLElement::parseAttribute(attr);
    6672}
  • trunk/Source/WebCore/html/HTMLDivElement.h

    r106769 r107484  
    3838private:
    3939    virtual void parseAttribute(Attribute*) OVERRIDE;
     40    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4041};
    4142
  • trunk/Source/WebCore/html/HTMLElement.cpp

    r106769 r107484  
    141141}
    142142
    143 void HTMLElement::applyBorderAttribute(Attribute* attr)
    144 {
    145     addCSSLength(CSSPropertyBorderWidth, String::number(parseBorderWidthAttribute(attr)));
    146     addCSSProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
    147     addCSSProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
    148     addCSSProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
    149     addCSSProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
    150 }
    151 
    152 void HTMLElement::mapLanguageAttributeToLocale(Attribute* attribute)
     143void HTMLElement::applyBorderAttributeToStyle(Attribute* attr, StylePropertySet* style)
     144{
     145    style->setProperty(CSSPropertyBorderWidth, String::number(parseBorderWidthAttribute(attr)));
     146    style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
     147    style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
     148    style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
     149    style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
     150}
     151
     152void HTMLElement::mapLanguageAttributeToLocale(Attribute* attribute, StylePropertySet* style)
    153153{
    154154    ASSERT(attribute && (attribute->name() == langAttr || attribute->name().matches(XMLNames::langAttr)));
    155     const AtomicString& value = attribute->value();
    156     if (value.isNull())
    157         removeCSSProperty(CSSPropertyWebkitLocale);
    158     else if (!value.isEmpty()) {
     155    if (!attribute->isEmpty()) {
    159156        // Have to quote so the locale id is treated as a string instead of as a CSS keyword.
    160         addCSSProperty(CSSPropertyWebkitLocale, quoteCSSString(value));
     157        style->setProperty(CSSPropertyWebkitLocale, quoteCSSString(attribute->value()));
    161158    } else {
    162159        // The empty string means the language is explicitly unknown.
    163         addCSSProperty(CSSPropertyWebkitLocale, CSSValueAuto);
    164     }
    165     setNeedsStyleRecalc();
     160        style->setProperty(CSSPropertyWebkitLocale, CSSValueAuto);
     161    }
     162}
     163
     164void HTMLElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     165{
     166    if (attr->name() == alignAttr) {
     167        if (equalIgnoringCase(attr->value(), "middle"))
     168            style->setProperty(CSSPropertyTextAlign, "center");
     169        else
     170            style->setProperty(CSSPropertyTextAlign, attr->value());
     171    } else if (attr->name() == contenteditableAttr) {
     172        if (attr->isEmpty() || equalIgnoringCase(attr->value(), "true")) {
     173            style->setProperty(CSSPropertyWebkitUserModify, CSSValueReadWrite);
     174            style->setProperty(CSSPropertyWordWrap, CSSValueBreakWord);
     175            style->setProperty(CSSPropertyWebkitNbspMode, CSSValueSpace);
     176            style->setProperty(CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
     177        } else if (equalIgnoringCase(attr->value(), "plaintext-only")) {
     178            style->setProperty(CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
     179            style->setProperty(CSSPropertyWordWrap, CSSValueBreakWord);
     180            style->setProperty(CSSPropertyWebkitNbspMode, CSSValueSpace);
     181            style->setProperty(CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
     182        } else if (equalIgnoringCase(attr->value(), "false"))
     183            style->setProperty(CSSPropertyWebkitUserModify, CSSValueReadOnly);
     184    } else if (attr->name() == hiddenAttr) {
     185        style->setProperty(CSSPropertyDisplay, CSSValueNone);
     186    } else if (attr->name() == draggableAttr) {
     187        if (equalIgnoringCase(attr->value(), "true")) {
     188            style->setProperty(CSSPropertyWebkitUserDrag, CSSValueElement);
     189            style->setProperty(CSSPropertyWebkitUserSelect, CSSValueNone);
     190        } else if (equalIgnoringCase(attr->value(), "false"))
     191            style->setProperty(CSSPropertyWebkitUserDrag, CSSValueNone);
     192    } else if (attr->name() == dirAttr) {
     193        if (equalIgnoringCase(attr->value(), "auto"))
     194            style->setProperty(CSSPropertyUnicodeBidi, unicodeBidiAttributeForDirAuto(this));
     195        else {
     196            style->setProperty(CSSPropertyDirection, attr->value());
     197            if (!hasTagName(bdiTag) && !hasTagName(bdoTag) && !hasTagName(outputTag))
     198                style->setProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
     199        }
     200    } else if (attr->name().matches(XMLNames::langAttr)) {
     201        mapLanguageAttributeToLocale(attr, style);
     202    } else if (attr->name() == langAttr) {
     203        // xml:lang has a higher priority than lang.
     204        if (!fastHasAttribute(XMLNames::langAttr))
     205            mapLanguageAttributeToLocale(attr, style);
     206    } else
     207        StyledElement::collectStyleForAttribute(attr, style);
    166208}
    167209
     
    171213        return StyledElement::parseAttribute(attr);
    172214
    173     if (attr->name() == alignAttr) {
    174         if (attr->isNull())
    175             removeCSSProperty(CSSPropertyTextAlign);
    176         else if (equalIgnoringCase(attr->value(), "middle"))
    177             addCSSProperty(CSSPropertyTextAlign, "center");
    178         else
    179             addCSSProperty(CSSPropertyTextAlign, attr->value());
    180     } else if (attr->name() == contenteditableAttr) {
    181         setContentEditable(attr);
    182     } else if (attr->name() == hiddenAttr) {
    183         if (attr->isNull())
    184             removeCSSProperty(CSSPropertyDisplay);
    185         else
    186             addCSSProperty(CSSPropertyDisplay, CSSValueNone);
    187     } else if (attr->name() == tabindexAttr) {
     215    if (attr->name() == alignAttr || attr->name() == contenteditableAttr || attr->name() == hiddenAttr || attr->name() == langAttr || attr->name().matches(XMLNames::langAttr) || attr->name() == draggableAttr)
     216        setNeedsAttributeStyleUpdate();
     217    else if (attr->name() == tabindexAttr) {
    188218        int tabindex = 0;
    189219        if (attr->isEmpty())
     
    193223            setTabIndexExplicitly(max(static_cast<int>(std::numeric_limits<short>::min()), min(tabindex, static_cast<int>(std::numeric_limits<short>::max()))));
    194224        }
    195     } else if (attr->name().matches(XMLNames::langAttr)) {
    196         mapLanguageAttributeToLocale(attr);
    197     } else if (attr->name() == langAttr) {
    198         // xml:lang has a higher priority than lang.
    199         if (!fastHasAttribute(XMLNames::langAttr))
    200             mapLanguageAttributeToLocale(attr);
    201225    } else if (attr->name() == dirAttr) {
    202         if (attr->isNull())
    203             removeCSSProperties(CSSPropertyDirection, CSSPropertyUnicodeBidi);
    204         else {
    205             bool dirIsAuto = equalIgnoringCase(attr->value(), "auto");
    206             if (!dirIsAuto)
    207                 addCSSProperty(CSSPropertyDirection, attr->value());
    208             else
    209                 removeCSSProperty(CSSPropertyDirection);
    210 
    211             dirAttributeChanged(attr);
    212             if (dirIsAuto)
    213                 addCSSProperty(CSSPropertyUnicodeBidi, unicodeBidiAttributeForDirAuto(this));
    214             else if (!hasTagName(bdiTag) && !hasTagName(bdoTag) && !hasTagName(outputTag))
    215                 addCSSProperty(CSSPropertyUnicodeBidi, CSSValueEmbed);
    216             else
    217                 removeCSSProperty(CSSPropertyUnicodeBidi);
    218         }
    219     } else if (attr->name() == draggableAttr) {
    220         const AtomicString& value = attr->value();
    221         if (equalIgnoringCase(value, "true")) {
    222             addCSSProperty(CSSPropertyWebkitUserDrag, CSSValueElement);
    223             addCSSProperty(CSSPropertyWebkitUserSelect, CSSValueNone);
    224         } else if (equalIgnoringCase(value, "false")) {
    225             addCSSProperty(CSSPropertyWebkitUserDrag, CSSValueNone);
    226             removeCSSProperty(CSSPropertyWebkitUserSelect);
    227         } else
    228             removeCSSProperties(CSSPropertyWebkitUserDrag, CSSPropertyWebkitUserSelect);
     226        setNeedsAttributeStyleUpdate();
     227        dirAttributeChanged(attr);
    229228#if ENABLE(MICRODATA)
    230229    } else if (attr->name() == itempropAttr) {
     
    679678}
    680679
    681 void HTMLElement::addHTMLAlignment(Attribute* attr)
    682 {
    683     addHTMLAlignmentToStyledElement(this, attr);
    684 }
    685 
    686 void HTMLElement::removeHTMLAlignment()
    687 {
    688     removeCSSProperties(CSSPropertyFloat, CSSPropertyVerticalAlign);
    689 }
    690 
    691 void HTMLElement::addHTMLAlignmentToStyledElement(StyledElement* element, Attribute* attr)
     680void HTMLElement::applyAlignmentAttributeToStyle(Attribute* attr, StylePropertySet* style)
    692681{
    693682    // Vertical alignment with respect to the current baseline of the text
     
    719708
    720709    if (floatValue != CSSValueInvalid)
    721         element->addCSSProperty(CSSPropertyFloat, floatValue);
    722     else
    723         element->removeCSSProperty(CSSPropertyFloat);
     710        style->setProperty(CSSPropertyFloat, floatValue);
    724711
    725712    if (verticalAlignValue != CSSValueInvalid)
    726         element->addCSSProperty(CSSPropertyVerticalAlign, verticalAlignValue);
    727     else
    728         element->removeCSSProperty(CSSPropertyVerticalAlign);
     713        style->setProperty(CSSPropertyVerticalAlign, verticalAlignValue);
    729714}
    730715
     
    748733
    749734    return "inherit";
    750 }
    751 
    752 void HTMLElement::setContentEditable(Attribute* attr)
    753 {
    754     const AtomicString& enabled = attr->value();
    755     if (enabled.isNull())
    756         removeCSSProperties(CSSPropertyWebkitUserModify, CSSPropertyWordWrap, CSSPropertyWebkitNbspMode, CSSPropertyWebkitLineBreak);
    757     else if (enabled.isEmpty() || equalIgnoringCase(enabled, "true")) {
    758         addCSSProperty(CSSPropertyWebkitUserModify, CSSValueReadWrite);
    759         addCSSProperty(CSSPropertyWordWrap, CSSValueBreakWord);
    760         addCSSProperty(CSSPropertyWebkitNbspMode, CSSValueSpace);
    761         addCSSProperty(CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
    762     } else if (equalIgnoringCase(enabled, "false")) {
    763         addCSSProperty(CSSPropertyWebkitUserModify, CSSValueReadOnly);
    764         removeCSSProperties(CSSPropertyWordWrap, CSSPropertyWebkitNbspMode, CSSPropertyWebkitLineBreak);
    765     } else if (equalIgnoringCase(enabled, "plaintext-only")) {
    766         addCSSProperty(CSSPropertyWebkitUserModify, CSSValueReadWritePlaintextOnly);
    767         addCSSProperty(CSSPropertyWordWrap, CSSValueBreakWord);
    768         addCSSProperty(CSSPropertyWebkitNbspMode, CSSValueSpace);
    769         addCSSProperty(CSSPropertyWebkitLineBreak, CSSValueAfterWhiteSpace);
    770     }
    771735}
    772736
     
    10661030#endif
    10671031
     1032void HTMLElement::addHTMLLengthToStyle(StylePropertySet* style, int propertyID, const String& value)
     1033{
     1034    // FIXME: This function should not spin up the CSS parser, but should instead just figure out the correct
     1035    // length unit and make the appropriate parsed value.
     1036
     1037    // strip attribute garbage..
     1038    StringImpl* v = value.impl();
     1039    if (v) {
     1040        unsigned int l = 0;
     1041
     1042        while (l < v->length() && (*v)[l] <= ' ')
     1043            l++;
     1044
     1045        for (; l < v->length(); l++) {
     1046            UChar cc = (*v)[l];
     1047            if (cc > '9')
     1048                break;
     1049            if (cc < '0') {
     1050                if (cc == '%' || cc == '*')
     1051                    l++;
     1052                if (cc != '.')
     1053                    break;
     1054            }
     1055        }
     1056
     1057        if (l != v->length()) {
     1058            style->setProperty(propertyID, v->substring(0, l));
     1059            return;
     1060        }
     1061    }
     1062
     1063    style->setProperty(propertyID, value);
     1064}
     1065
     1066static String parseColorStringWithCrazyLegacyRules(const String& colorString)
     1067{
     1068    // Per spec, only look at the first 128 digits of the string.
     1069    const size_t maxColorLength = 128;
     1070    // We'll pad the buffer with two extra 0s later, so reserve two more than the max.
     1071    Vector<char, maxColorLength+2> digitBuffer;
     1072
     1073    size_t i = 0;
     1074    // Skip a leading #.
     1075    if (colorString[0] == '#')
     1076        i = 1;
     1077
     1078    // Grab the first 128 characters, replacing non-hex characters with 0.
     1079    // Non-BMP characters are replaced with "00" due to them appearing as two "characters" in the String.
     1080    for (; i < colorString.length() && digitBuffer.size() < maxColorLength; i++) {
     1081        if (!isASCIIHexDigit(colorString[i]))
     1082            digitBuffer.append('0');
     1083        else
     1084            digitBuffer.append(colorString[i]);
     1085    }
     1086
     1087    if (!digitBuffer.size())
     1088        return "#000000";
     1089
     1090    // Pad the buffer out to at least the next multiple of three in size.
     1091    digitBuffer.append('0');
     1092    digitBuffer.append('0');
     1093
     1094    if (digitBuffer.size() < 6)
     1095        return String::format("#0%c0%c0%c", digitBuffer[0], digitBuffer[1], digitBuffer[2]);
     1096
     1097    // Split the digits into three components, then search the last 8 digits of each component.
     1098    ASSERT(digitBuffer.size() >= 6);
     1099    size_t componentLength = digitBuffer.size() / 3;
     1100    size_t componentSearchWindowLength = min<size_t>(componentLength, 8);
     1101    size_t redIndex = componentLength - componentSearchWindowLength;
     1102    size_t greenIndex = componentLength * 2 - componentSearchWindowLength;
     1103    size_t blueIndex = componentLength * 3 - componentSearchWindowLength;
     1104    // Skip digits until one of them is non-zero, or we've only got two digits left in the component.
     1105    while (digitBuffer[redIndex] == '0' && digitBuffer[greenIndex] == '0' && digitBuffer[blueIndex] == '0' && (componentLength - redIndex) > 2) {
     1106        redIndex++;
     1107        greenIndex++;
     1108        blueIndex++;
     1109    }
     1110    ASSERT(redIndex + 1 < componentLength);
     1111    ASSERT(greenIndex >= componentLength);
     1112    ASSERT(greenIndex + 1 < componentLength * 2);
     1113    ASSERT(blueIndex >= componentLength * 2);
     1114    ASSERT(blueIndex + 1 < digitBuffer.size());
     1115    return String::format("#%c%c%c%c%c%c", digitBuffer[redIndex], digitBuffer[redIndex + 1], digitBuffer[greenIndex], digitBuffer[greenIndex + 1], digitBuffer[blueIndex], digitBuffer[blueIndex + 1]);
     1116}
     1117
     1118// Color parsing that matches HTML's "rules for parsing a legacy color value"
     1119void HTMLElement::addHTMLColorToStyle(StylePropertySet* style, int propertyID, const String& attributeValue)
     1120{
     1121    // An empty string doesn't apply a color. (One containing only whitespace does, which is why this check occurs before stripping.)
     1122    if (attributeValue.isEmpty())
     1123        return;
     1124
     1125    String colorString = attributeValue.stripWhiteSpace();
     1126
     1127    // "transparent" doesn't apply a color either.
     1128    if (equalIgnoringCase(colorString, "transparent"))
     1129        return;
     1130
     1131    // If the string is a named CSS color or a 3/6-digit hex color, use that.
     1132    Color parsedColor(colorString);
     1133    if (parsedColor.isValid()) {
     1134        style->setProperty(propertyID, colorString);
     1135        return;
     1136    }
     1137
     1138    style->setProperty(propertyID, parseColorStringWithCrazyLegacyRules(colorString));
     1139}
     1140
     1141void StyledElement::copyNonAttributeProperties(const Element* sourceElement)
     1142{
     1143    ASSERT(sourceElement);
     1144    ASSERT(sourceElement->isStyledElement());
     1145
     1146    const StyledElement* source = static_cast<const StyledElement*>(sourceElement);
     1147    if (!source->inlineStyleDecl())
     1148        return;
     1149
     1150    StylePropertySet* inlineStyle = ensureInlineStyleDecl();
     1151    inlineStyle->copyPropertiesFrom(*source->inlineStyleDecl());
     1152    inlineStyle->setStrictParsing(source->inlineStyleDecl()->useStrictParsing());
     1153
     1154    setIsStyleAttributeValid(source->isStyleAttributeValid());
     1155    setIsSynchronizingStyleAttribute(source->isSynchronizingStyleAttribute());
     1156   
     1157    Element::copyNonAttributeProperties(sourceElement);
     1158}
     1159
     1160
    10681161} // namespace WebCore
    10691162
  • trunk/Source/WebCore/html/HTMLElement.h

    r106769 r107484  
    8080    HTMLFormElement* form() const { return virtualForm(); }
    8181
    82     static void addHTMLAlignmentToStyledElement(StyledElement*, Attribute*);
    83 
    8482    HTMLFormElement* findFormAncestor() const;
    8583
     
    9492    HTMLElement(const QualifiedName& tagName, Document*);
    9593
    96     void addHTMLAlignment(Attribute*);
    97     void removeHTMLAlignment();
     94    static void addHTMLLengthToStyle(StylePropertySet*, int propertyID, const String& value);
     95    static void addHTMLColorToStyle(StylePropertySet*, int propertyID, const String& color);
     96
     97    void applyAlignmentAttributeToStyle(Attribute*, StylePropertySet*);
     98    void applyBorderAttributeToStyle(Attribute*, StylePropertySet*);
    9899
    99100    virtual void parseAttribute(Attribute*) OVERRIDE;
    100     void applyBorderAttribute(Attribute*);
     101    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    101102
    102103    virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
     
    108109    virtual String nodeName() const;
    109110
    110     void mapLanguageAttributeToLocale(Attribute*);
    111 
    112     void setContentEditable(Attribute*);
     111    void mapLanguageAttributeToLocale(Attribute*, StylePropertySet*);
    113112
    114113    virtual HTMLFormElement* virtualForm() const;
  • trunk/Source/WebCore/html/HTMLEmbedElement.cpp

    r107477 r107484  
    7575}
    7676
     77void HTMLEmbedElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     78{
     79    if (attr->name() == hiddenAttr) {
     80        if (equalIgnoringCase(attr->value(), "yes") || equalIgnoringCase(attr->value(), "true")) {
     81            addHTMLLengthToStyle(style, CSSPropertyWidth, "0"); // FIXME: Pass as integer.
     82            addHTMLLengthToStyle(style, CSSPropertyHeight, "0"); // FIXME: Pass as integer.
     83        }
     84    } else
     85        HTMLPlugInImageElement::collectStyleForAttribute(attr, style);
     86}
     87
    7788void HTMLEmbedElement::parseAttribute(Attribute* attr)
    7889{
     
    95106            m_imageLoader->updateFromElementIgnoringPreviousError();
    96107        }
    97     } else if (attr->name() == hiddenAttr) {
    98         if (equalIgnoringCase(value.string(), "yes") || equalIgnoringCase(value.string(), "true")) {
    99             // FIXME: Not dynamic, since we add this but don't remove it, but it may be OK for now
    100             // that this rarely-used attribute won't work properly if you remove it.
    101             addCSSLength(CSSPropertyWidth, "0");
    102             addCSSLength(CSSPropertyHeight, "0");
    103         } else
    104             removeCSSProperties(CSSPropertyWidth, CSSPropertyHeight);
    105     } else
     108    } else if (attr->name() == hiddenAttr)
     109        setNeedsAttributeStyleUpdate();
     110    else
    106111        HTMLPlugInImageElement::parseAttribute(attr);
    107112}
  • trunk/Source/WebCore/html/HTMLEmbedElement.h

    r106769 r107484  
    3636
    3737    virtual void parseAttribute(Attribute*) OVERRIDE;
     38    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3839
    3940    virtual bool rendererIsNeeded(const NodeRenderingContext&);
  • trunk/Source/WebCore/html/HTMLFontElement.cpp

    r106769 r107484  
    159159}
    160160
    161 void HTMLFontElement::parseAttribute(Attribute* attr)
     161void HTMLFontElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    162162{
    163163    if (attr->name() == sizeAttr) {
    164164        int size = 0;
    165165        if (cssValueFromFontSizeNumber(attr->value(), size))
    166             addCSSProperty(CSSPropertyFontSize, size);
    167         else
    168             removeCSSProperty(CSSPropertyFontSize);
    169     } else if (attr->name() == colorAttr) {
    170         if (attr->value().isNull())
    171             removeCSSProperty(CSSPropertyColor);
    172         else
    173             addCSSColor(CSSPropertyColor, attr->value());
    174     } else if (attr->name() == faceAttr) {
    175         if (attr->value().isNull())
    176             removeCSSProperty(CSSPropertyFontFamily);
    177         else
    178             addCSSProperty(CSSPropertyFontFamily, attr->value());
    179     } else
     166            style->setProperty(CSSPropertyFontSize, size);
     167    } else if (attr->name() == colorAttr)
     168        addHTMLColorToStyle(style, CSSPropertyColor, attr->value());
     169    else if (attr->name() == faceAttr)
     170        style->setProperty(CSSPropertyFontFamily, attr->value());
     171    else
     172        HTMLElement::collectStyleForAttribute(attr, style);
     173}
     174
     175void HTMLFontElement::parseAttribute(Attribute* attr)
     176{
     177    if (attr->name() == sizeAttr || attr->name() == colorAttr || attr->name() == faceAttr)
     178        setNeedsAttributeStyleUpdate();
     179    else
    180180        HTMLElement::parseAttribute(attr);
    181181}
  • trunk/Source/WebCore/html/HTMLFontElement.h

    r106769 r107484  
    3939
    4040    virtual void parseAttribute(Attribute*) OVERRIDE;
     41    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4142};
    4243
  • trunk/Source/WebCore/html/HTMLFrameSetElement.cpp

    r106769 r107484  
    6565}
    6666
     67void HTMLFrameSetElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     68{
     69    if (attr->name() == bordercolorAttr)
     70        addHTMLColorToStyle(style, CSSPropertyBorderColor, attr->value());
     71    else
     72        HTMLElement::collectStyleForAttribute(attr, style);
     73}
     74
    6775void HTMLFrameSetElement::parseAttribute(Attribute* attr)
    6876{
     
    101109    } else if (attr->name() == bordercolorAttr) {
    102110        m_borderColorSet = !attr->isEmpty();
    103         if (attr->value().isNull())
    104             removeCSSProperty(CSSPropertyBorderColor);
    105         else
    106             addCSSColor(CSSPropertyBorderColor, attr->value());
     111        setNeedsAttributeStyleUpdate();
    107112    } else if (attr->name() == onloadAttr)
    108113        document()->setWindowAttributeEventListener(eventNames().loadEvent, createAttributeEventListener(document()->frame(), attr));
  • trunk/Source/WebCore/html/HTMLFrameSetElement.h

    r106769 r107484  
    6969
    7070    virtual void parseAttribute(Attribute*) OVERRIDE;
     71    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    7172
    7273    virtual void attach();
  • trunk/Source/WebCore/html/HTMLHRElement.cpp

    r106769 r107484  
    4949}
    5050
     51static inline bool isRespectedPresentationAttribute(Attribute* attr)
     52{
     53    return attr->name() == alignAttr || attr->name() == widthAttr || attr->name() == colorAttr || attr->name() == noshadeAttr || attr->name() == sizeAttr;
     54}
     55
     56void HTMLHRElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     57{
     58    if (attr->name() == alignAttr) {
     59        if (equalIgnoringCase(attr->value(), "left")) {
     60            style->setProperty(CSSPropertyMarginLeft, "0"); // FIXME: Pass as integer.
     61            style->setProperty(CSSPropertyMarginRight, CSSValueAuto);
     62        } else if (equalIgnoringCase(attr->value(), "right")) {
     63            style->setProperty(CSSPropertyMarginLeft, CSSValueAuto);
     64            style->setProperty(CSSPropertyMarginRight, "0"); // FIXME: Pass as integer.
     65        } else {
     66            style->setProperty(CSSPropertyMarginLeft, CSSValueAuto);
     67            style->setProperty(CSSPropertyMarginRight, CSSValueAuto);
     68        }
     69    } else if (attr->name() == widthAttr) {
     70        bool ok;
     71        int v = attr->value().toInt(&ok);
     72        if (ok && !v)
     73            addHTMLLengthToStyle(style, CSSPropertyWidth, "1"); // FIXME: Pass as integer.
     74        else
     75            addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     76    } else if (attr->name() == colorAttr) {
     77        style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
     78        style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
     79        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
     80        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
     81        addHTMLColorToStyle(style, CSSPropertyBorderColor, attr->value());
     82        addHTMLColorToStyle(style, CSSPropertyBackgroundColor, attr->value());
     83    } else if (attr->name() == noshadeAttr) {
     84        style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
     85        style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
     86        style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
     87        style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
     88        addHTMLColorToStyle(style, CSSPropertyBorderColor, String("grey")); // FIXME: Pass as rgb() value.
     89        addHTMLColorToStyle(style, CSSPropertyBackgroundColor, String("grey")); // FIXME: Pass as rgb() value.
     90    } else if (attr->name() == sizeAttr) {
     91        StringImpl* si = attr->value().impl();
     92        int size = si->toInt();
     93        if (size <= 1)
     94            style->setProperty(CSSPropertyBorderBottomWidth, String("0")); // FIXME: Pass as integer.
     95        else
     96            addHTMLLengthToStyle(style, CSSPropertyHeight, String::number(size - 2)); // FIXME: Pass as integer.
     97    } else {
     98        ASSERT(!isRespectedPresentationAttribute(attr));
     99        HTMLElement::collectStyleForAttribute(attr, style);
     100    }
     101}
     102
    51103void HTMLHRElement::parseAttribute(Attribute* attr)
    52104{
    53     if (attr->name() == alignAttr) {
    54         if (attr->value().isNull()) {
    55             removeCSSProperties(CSSPropertyMarginLeft, CSSPropertyMarginRight);
    56         } else if (equalIgnoringCase(attr->value(), "left")) {
    57             addCSSProperty(CSSPropertyMarginLeft, "0");
    58             addCSSProperty(CSSPropertyMarginRight, CSSValueAuto);
    59         } else if (equalIgnoringCase(attr->value(), "right")) {
    60             addCSSProperty(CSSPropertyMarginLeft, CSSValueAuto);
    61             addCSSProperty(CSSPropertyMarginRight, "0");
    62         } else {
    63             addCSSProperty(CSSPropertyMarginLeft, CSSValueAuto);
    64             addCSSProperty(CSSPropertyMarginRight, CSSValueAuto);
    65         }
    66     } else if (attr->name() == widthAttr) {
    67         if (attr->value().isNull())
    68             removeCSSProperty(CSSPropertyWidth);
    69         else {
    70             bool ok;
    71             int v = attr->value().toInt(&ok);
    72             if (ok && !v)
    73                 addCSSLength(CSSPropertyWidth, "1");
    74             else
    75                 addCSSLength(CSSPropertyWidth, attr->value());
    76         }
    77     } else if (attr->name() == colorAttr) {
    78         if (attr->value().isNull())
    79             removeCSSProperties(CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle, CSSPropertyBorderColor, CSSPropertyBackgroundColor);
    80         else {
    81             addCSSProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
    82             addCSSProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
    83             addCSSProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
    84             addCSSProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
    85             addCSSColor(CSSPropertyBorderColor, attr->value());
    86             addCSSColor(CSSPropertyBackgroundColor, attr->value());
    87         }
    88     } else if (attr->name() == noshadeAttr) {
    89         if (attr->value().isNull())
    90             removeCSSProperties(CSSPropertyBorderTopStyle, CSSPropertyBorderRightStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle, CSSPropertyBorderColor, CSSPropertyBackgroundColor);
    91         else {
    92             addCSSProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
    93             addCSSProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
    94             addCSSProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
    95             addCSSProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
    96             addCSSColor(CSSPropertyBorderColor, String("grey"));
    97             addCSSColor(CSSPropertyBackgroundColor, String("grey"));
    98         }
    99     } else if (attr->name() == sizeAttr) {
    100         if (attr->value().isNull())
    101             removeCSSProperties(CSSPropertyBorderBottomWidth, CSSPropertyHeight);
    102         else {
    103             StringImpl* si = attr->value().impl();
    104             int size = si->toInt();
    105             if (size <= 1) {
    106                 addCSSProperty(CSSPropertyBorderBottomWidth, String("0"));
    107                 removeCSSProperty(CSSPropertyHeight);
    108             } else {
    109                 addCSSLength(CSSPropertyHeight, String::number(size-2));
    110                 removeCSSProperty(CSSPropertyBorderBottomWidth);
    111             }
    112         }
    113     } else
     105    if (isRespectedPresentationAttribute(attr))
     106        setNeedsAttributeStyleUpdate();
     107    else
    114108        HTMLElement::parseAttribute(attr);
    115109}
  • trunk/Source/WebCore/html/HTMLHRElement.h

    r106769 r107484  
    3939
    4040    virtual void parseAttribute(Attribute*) OVERRIDE;
     41    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4142};
    4243
  • trunk/Source/WebCore/html/HTMLIFrameElement.cpp

    r106769 r107484  
    4949}
    5050
     51static inline bool isRespectedPresentationAttribute(Attribute* attr)
     52{
     53    return attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == alignAttr || attr->name() == frameborderAttr;
     54}
     55
     56void HTMLIFrameElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     57{
     58    if (attr->name() == widthAttr)
     59        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     60    else if (attr->name() == heightAttr)
     61        addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     62    else if (attr->name() == alignAttr)
     63        applyAlignmentAttributeToStyle(attr, style);
     64    else if (attr->name() == frameborderAttr) {
     65        // Frame border doesn't really match the HTML4 spec definition for iframes. It simply adds
     66        // a presentational hint that the border should be off if set to zero.
     67        if (!attr->isNull() && !attr->value().toInt()) {
     68            // Add a rule that nulls out our border width.
     69            addHTMLLengthToStyle(style, CSSPropertyBorderWidth, "0"); // FIXME: Pass as integer.
     70        }
     71    } else {
     72        ASSERT(!isRespectedPresentationAttribute(attr));
     73        HTMLFrameElementBase::collectStyleForAttribute(attr, style);
     74    }
     75}
     76
    5177void HTMLIFrameElement::parseAttribute(Attribute* attr)
    5278{
    53     if (attr->name() == widthAttr)
    54         addCSSLength(CSSPropertyWidth, attr->value());
    55     else if (attr->name() == heightAttr)
    56         addCSSLength(CSSPropertyHeight, attr->value());
    57     else if (attr->name() == alignAttr)
    58         addHTMLAlignment(attr);
     79    if (isRespectedPresentationAttribute(attr))
     80        setNeedsAttributeStyleUpdate();
    5981    else if (attr->name() == nameAttr) {
    6082        const AtomicString& newName = attr->value();
     
    6587        }
    6688        m_name = newName;
    67     } else if (attr->name() == frameborderAttr) {
    68         // Frame border doesn't really match the HTML4 spec definition for iframes.  It simply adds
    69         // a presentational hint that the border should be off if set to zero.
    70         if (!attr->isNull() && !attr->value().toInt()) {
    71             // Add a rule that nulls out our border width.
    72             addCSSLength(CSSPropertyBorderWidth, "0");
    73         } else
    74             removeCSSProperty(CSSPropertyBorderWidth);
    7589    } else if (attr->name() == sandboxAttr)
    7690        setSandboxFlags(attr->isNull() ? SandboxNone : SecurityContext::parseSandboxPolicy(attr->value()));
  • trunk/Source/WebCore/html/HTMLIFrameElement.h

    r106769 r107484  
    3737
    3838    virtual void parseAttribute(Attribute*) OVERRIDE;
     39    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3940
    4041    virtual void insertedIntoDocument();
  • trunk/Source/WebCore/html/HTMLImageElement.cpp

    r106769 r107484  
    7979}
    8080
     81static inline bool isRespectedPresentationAttribute(Attribute* attr)
     82{
     83    return attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == borderAttr || attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == alignAttr || attr->name() == valignAttr;
     84}
     85
     86void HTMLImageElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     87{
     88    if (attr->name() == widthAttr)
     89        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     90    else if (attr->name() == heightAttr)
     91        addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     92    else if (attr->name() == borderAttr)
     93        applyBorderAttributeToStyle(attr, style);
     94    else if (attr->name() == vspaceAttr) {
     95        addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
     96        addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     97    } else if (attr->name() == hspaceAttr) {
     98        addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
     99        addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     100    } else if (attr->name() == alignAttr)
     101        applyAlignmentAttributeToStyle(attr, style);
     102    else if (attr->name() == valignAttr)
     103        style->setProperty(CSSPropertyVerticalAlign, attr->value());
     104    else {
     105        ASSERT(!isRespectedPresentationAttribute(attr));
     106        HTMLElement::collectStyleForAttribute(attr, style);
     107    }
     108}
     109
    81110void HTMLImageElement::parseAttribute(Attribute* attr)
    82111{
    83112    const QualifiedName& attrName = attr->name();
    84     if (attrName == altAttr) {
     113    if (isRespectedPresentationAttribute(attr))
     114        setNeedsAttributeStyleUpdate();
     115    else if (attrName == altAttr) {
    85116        if (renderer() && renderer()->isImage())
    86117            toRenderImage(renderer())->updateAltText();
    87118    } else if (attrName == srcAttr)
    88119        m_imageLoader.updateFromElementIgnoringPreviousError();
    89     else if (attrName == widthAttr)
    90         if (attr->value().isNull())
    91             removeCSSProperty(CSSPropertyWidth);
    92         else
    93             addCSSLength(CSSPropertyWidth, attr->value());
    94     else if (attrName == heightAttr)
    95         if (attr->value().isNull())
    96             removeCSSProperty(CSSPropertyHeight);
    97         else
    98             addCSSLength(CSSPropertyHeight, attr->value());
    99     else if (attrName == borderAttr) {
    100         // border="noborder" -> border="0"
    101         applyBorderAttribute(attr);
    102     } else if (attrName == vspaceAttr) {
    103         if (attr->value().isNull())
    104             removeCSSProperties(CSSPropertyMarginTop, CSSPropertyMarginBottom);
    105         else {
    106             addCSSLength(CSSPropertyMarginTop, attr->value());
    107             addCSSLength(CSSPropertyMarginBottom, attr->value());
    108         }
    109     } else if (attrName == hspaceAttr) {
    110         if (attr->value().isNull())
    111             removeCSSProperties(CSSPropertyMarginLeft, CSSPropertyMarginRight);
    112         else {
    113             addCSSLength(CSSPropertyMarginLeft, attr->value());
    114             addCSSLength(CSSPropertyMarginRight, attr->value());
    115         }
    116     } else if (attrName == alignAttr)
    117         addHTMLAlignment(attr);
    118     else if (attrName == valignAttr)
    119         if (attr->value().isNull())
    120             removeCSSProperty(CSSPropertyVerticalAlign);
    121         else
    122             addCSSProperty(CSSPropertyVerticalAlign, attr->value());
    123120    else if (attrName == usemapAttr)
    124121        setIsLink(!attr->isNull());
  • trunk/Source/WebCore/html/HTMLImageElement.h

    r106769 r107484  
    8585private:
    8686    virtual void parseAttribute(Attribute*) OVERRIDE;
     87    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    8788
    8889    virtual void attach();
  • trunk/Source/WebCore/html/HTMLInputElement.cpp

    r107175 r107484  
    659659}
    660660
     661static inline bool isRespectedPresentationAttribute(HTMLInputElement* element, Attribute* attr)
     662{
     663    return attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == alignAttr || attr->name() == widthAttr || attr->name() == heightAttr || (attr->name() == borderAttr && element->isImageButton());
     664}
     665
     666void HTMLInputElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     667{
     668    if (attr->name() == vspaceAttr) {
     669        addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
     670        addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     671    } else if (attr->name() == hspaceAttr) {
     672        addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
     673        addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     674    } else if (attr->name() == alignAttr) {
     675        if (m_inputType->shouldRespectAlignAttribute())
     676            applyAlignmentAttributeToStyle(attr, style);
     677    } else if (attr->name() == widthAttr) {
     678        if (m_inputType->shouldRespectHeightAndWidthAttributes())
     679            addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     680    } else if (attr->name() == heightAttr) {
     681        if (m_inputType->shouldRespectHeightAndWidthAttributes())
     682            addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     683    } else if (attr->name() == borderAttr && isImageButton())
     684        applyBorderAttributeToStyle(attr, style);
     685    else {
     686        ASSERT(!isRespectedPresentationAttribute(this, attr));
     687        return HTMLTextFormControlElement::collectStyleForAttribute(attr, style);
     688    }
     689}
     690
    661691void HTMLInputElement::parseAttribute(Attribute* attr)
    662692{
    663     if (attr->name() == nameAttr) {
     693    if (isRespectedPresentationAttribute(this, attr))
     694        setNeedsAttributeStyleUpdate();
     695    else if (attr->name() == nameAttr) {
    664696        checkedRadioButtons().removeButton(this);
    665697        m_name = attr->value();
     
    714746    else if (attr->name() == usemapAttr || attr->name() == accesskeyAttr) {
    715747        // FIXME: ignore for the moment
    716     } else if (attr->name() == vspaceAttr) {
    717         addCSSLength(CSSPropertyMarginTop, attr->value());
    718         addCSSLength(CSSPropertyMarginBottom, attr->value());
    719     } else if (attr->name() == hspaceAttr) {
    720         addCSSLength(CSSPropertyMarginLeft, attr->value());
    721         addCSSLength(CSSPropertyMarginRight, attr->value());
    722     } else if (attr->name() == alignAttr) {
    723         if (m_inputType->shouldRespectAlignAttribute())
    724             addHTMLAlignment(attr);
    725         else
    726             removeHTMLAlignment();
    727     } else if (attr->name() == widthAttr) {
    728         if (m_inputType->shouldRespectHeightAndWidthAttributes())
    729             addCSSLength(CSSPropertyWidth, attr->value());
    730         else
    731             removeCSSProperty(CSSPropertyWidth);
    732     } else if (attr->name() == heightAttr) {
    733         if (m_inputType->shouldRespectHeightAndWidthAttributes())
    734             addCSSLength(CSSPropertyHeight, attr->value());
    735         else
    736             removeCSSProperty(CSSPropertyHeight);
    737     } else if (attr->name() == borderAttr && isImageButton()) {
    738         applyBorderAttribute(attr);
    739748    } else if (attr->name() == onsearchAttr) {
    740749        // Search field and slider attributes all just cause updateFromElement to be called through style recalcing.
  • trunk/Source/WebCore/html/HTMLInputElement.h

    r107175 r107484  
    277277
    278278    virtual void parseAttribute(Attribute*) OVERRIDE;
     279    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    279280    virtual void finishParsingChildren();
    280281
  • trunk/Source/WebCore/html/HTMLLIElement.cpp

    r106769 r107484  
    5050}
    5151
     52void HTMLLIElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     53{
     54    if (attr->name() == typeAttr) {
     55        if (attr->value() == "a")
     56            style->setProperty(CSSPropertyListStyleType, CSSValueLowerAlpha);
     57        else if (attr->value() == "A")
     58            style->setProperty(CSSPropertyListStyleType, CSSValueUpperAlpha);
     59        else if (attr->value() == "i")
     60            style->setProperty(CSSPropertyListStyleType, CSSValueLowerRoman);
     61        else if (attr->value() == "I")
     62            style->setProperty(CSSPropertyListStyleType, CSSValueUpperRoman);
     63        else if (attr->value() == "1")
     64            style->setProperty(CSSPropertyListStyleType, CSSValueDecimal);
     65        else
     66            style->setProperty(CSSPropertyListStyleType, attr->value());
     67    } else
     68        HTMLElement::collectStyleForAttribute(attr, style);
     69}
     70
    5271void HTMLLIElement::parseAttribute(Attribute* attr)
    5372{
     
    5574        if (renderer() && renderer()->isListItem())
    5675            parseValue(attr->value());
    57     } else if (attr->name() == typeAttr) {
    58         if (attr->value().isNull())
    59             removeCSSProperty(CSSPropertyListStyleType);
    60         else if (attr->value() == "a")
    61             addCSSProperty(CSSPropertyListStyleType, CSSValueLowerAlpha);
    62         else if (attr->value() == "A")
    63             addCSSProperty(CSSPropertyListStyleType, CSSValueUpperAlpha);
    64         else if (attr->value() == "i")
    65             addCSSProperty(CSSPropertyListStyleType, CSSValueLowerRoman);
    66         else if (attr->value() == "I")
    67             addCSSProperty(CSSPropertyListStyleType, CSSValueUpperRoman);
    68         else if (attr->value() == "1")
    69             addCSSProperty(CSSPropertyListStyleType, CSSValueDecimal);
    70         else
    71             addCSSProperty(CSSPropertyListStyleType, attr->value());
    72     } else
     76    } else if (attr->name() == typeAttr)
     77        setNeedsAttributeStyleUpdate();
     78    else
    7379        HTMLElement::parseAttribute(attr);
    7480}
  • trunk/Source/WebCore/html/HTMLLIElement.h

    r106769 r107484  
    3737
    3838    virtual void parseAttribute(Attribute*) OVERRIDE;
     39    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3940
    4041    virtual void attach();
  • trunk/Source/WebCore/html/HTMLMarqueeElement.cpp

    r107239 r107484  
    5454}
    5555
    56 void HTMLMarqueeElement::parseAttribute(Attribute* attr)
     56static inline bool isRespectedPresentationAttribute(Attribute* attr)
     57{
     58    return attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == bgcolorAttr || attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == scrollamountAttr || attr->name() == scrolldelayAttr || attr->name() == loopAttr || attr->name() == behaviorAttr || attr->name() == directionAttr;
     59}
     60
     61void HTMLMarqueeElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    5762{
    5863    if (attr->name() == widthAttr) {
    59         if (!attr->value().isEmpty())
    60             addCSSLength(CSSPropertyWidth, attr->value());
    61         else
    62             removeCSSProperty(CSSPropertyWidth);
     64        if (!attr->isEmpty())
     65            addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
    6366    } else if (attr->name() == heightAttr) {
    6467        if (!attr->value().isEmpty())
    65             addCSSLength(CSSPropertyHeight, attr->value());
    66         else
    67             removeCSSProperty(CSSPropertyHeight);
     68            addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
    6869    } else if (attr->name() == bgcolorAttr) {
    6970        if (!attr->value().isEmpty())
    70             addCSSColor(CSSPropertyBackgroundColor, attr->value());
    71         else
    72             removeCSSProperty(CSSPropertyBackgroundColor);
     71            addHTMLColorToStyle(style, CSSPropertyBackgroundColor, attr->value());
    7372    } else if (attr->name() == vspaceAttr) {
    7473        if (!attr->value().isEmpty()) {
    75             addCSSLength(CSSPropertyMarginTop, attr->value());
    76             addCSSLength(CSSPropertyMarginBottom, attr->value());
    77         } else
    78             removeCSSProperties(CSSPropertyMarginTop, CSSPropertyMarginBottom);
     74            addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
     75            addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     76        }
    7977    } else if (attr->name() == hspaceAttr) {
    8078        if (!attr->value().isEmpty()) {
    81             addCSSLength(CSSPropertyMarginLeft, attr->value());
    82             addCSSLength(CSSPropertyMarginRight, attr->value());
    83         } else
    84             removeCSSProperties(CSSPropertyMarginLeft, CSSPropertyMarginRight);
     79            addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
     80            addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     81        }
    8582    } else if (attr->name() == scrollamountAttr) {
    8683        if (!attr->value().isEmpty())
    87             addCSSLength(CSSPropertyWebkitMarqueeIncrement, attr->value());
    88         else
    89             removeCSSProperty(CSSPropertyWebkitMarqueeIncrement);
     84            addHTMLLengthToStyle(style, CSSPropertyWebkitMarqueeIncrement, attr->value());
    9085    } else if (attr->name() == scrolldelayAttr) {
    9186        if (!attr->value().isEmpty())
    92             addCSSLength(CSSPropertyWebkitMarqueeSpeed, attr->value());
    93         else
    94             removeCSSProperty(CSSPropertyWebkitMarqueeSpeed);
     87            addHTMLLengthToStyle(style, CSSPropertyWebkitMarqueeSpeed, attr->value());
    9588    } else if (attr->name() == loopAttr) {
    9689        if (!attr->value().isEmpty()) {
    9790            if (attr->value() == "-1" || equalIgnoringCase(attr->value(), "infinite"))
    98                 addCSSProperty(CSSPropertyWebkitMarqueeRepetition, CSSValueInfinite);
     91                style->setProperty(CSSPropertyWebkitMarqueeRepetition, CSSValueInfinite);
    9992            else
    100                 addCSSLength(CSSPropertyWebkitMarqueeRepetition, attr->value());
    101         } else
    102             removeCSSProperty(CSSPropertyWebkitMarqueeRepetition);
     93                addHTMLLengthToStyle(style, CSSPropertyWebkitMarqueeRepetition, attr->value());
     94        }
    10395    } else if (attr->name() == behaviorAttr) {
    10496        if (!attr->value().isEmpty())
    105             addCSSProperty(CSSPropertyWebkitMarqueeStyle, attr->value());
    106         else
    107             removeCSSProperty(CSSPropertyWebkitMarqueeStyle);
     97            style->setProperty(CSSPropertyWebkitMarqueeStyle, attr->value());
    10898    } else if (attr->name() == directionAttr) {
    10999        if (!attr->value().isEmpty())
    110             addCSSProperty(CSSPropertyWebkitMarqueeDirection, attr->value());
    111         else
    112             removeCSSProperty(CSSPropertyWebkitMarqueeDirection);
    113     } else if (attr->name() == truespeedAttr)
     100            style->setProperty(CSSPropertyWebkitMarqueeDirection, attr->value());
     101    } else {
     102        ASSERT(!isRespectedPresentationAttribute(attr));
     103        HTMLElement::collectStyleForAttribute(attr, style);
     104    }
     105}
     106
     107void HTMLMarqueeElement::parseAttribute(Attribute* attr)
     108{
     109    if (isRespectedPresentationAttribute(attr))
     110        setNeedsAttributeStyleUpdate();
     111    else if (attr->name() == truespeedAttr)
    114112        m_minimumDelay = !attr->isEmpty() ? 0 : defaultMinimumDelay;
    115113    else
  • trunk/Source/WebCore/html/HTMLMarqueeElement.h

    r106769 r107484  
    5555
    5656    virtual void parseAttribute(Attribute*) OVERRIDE;
     57    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    5758
    5859    // ActiveDOMObject
  • trunk/Source/WebCore/html/HTMLOListElement.cpp

    r106769 r107484  
    5555}
    5656
    57 void HTMLOListElement::parseAttribute(Attribute* attr)
     57void HTMLOListElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    5858{
    5959    if (attr->name() == typeAttr) {
    6060        if (attr->value() == "a")
    61             addCSSProperty(CSSPropertyListStyleType, CSSValueLowerAlpha);
     61            style->setProperty(CSSPropertyListStyleType, CSSValueLowerAlpha);
    6262        else if (attr->value() == "A")
    63             addCSSProperty(CSSPropertyListStyleType, CSSValueUpperAlpha);
     63            style->setProperty(CSSPropertyListStyleType, CSSValueUpperAlpha);
    6464        else if (attr->value() == "i")
    65             addCSSProperty(CSSPropertyListStyleType, CSSValueLowerRoman);
     65            style->setProperty(CSSPropertyListStyleType, CSSValueLowerRoman);
    6666        else if (attr->value() == "I")
    67             addCSSProperty(CSSPropertyListStyleType, CSSValueUpperRoman);
     67            style->setProperty(CSSPropertyListStyleType, CSSValueUpperRoman);
    6868        else if (attr->value() == "1")
    69             addCSSProperty(CSSPropertyListStyleType, CSSValueDecimal);
    70         else
    71             removeCSSProperty(CSSPropertyListStyleType);
    72     } else if (attr->name() == startAttr) {
     69            style->setProperty(CSSPropertyListStyleType, CSSValueDecimal);
     70    } else
     71        HTMLElement::collectStyleForAttribute(attr, style);
     72}
     73
     74void HTMLOListElement::parseAttribute(Attribute* attr)
     75{
     76    if (attr->name() == typeAttr)
     77        setNeedsAttributeStyleUpdate();
     78    else if (attr->name() == startAttr) {
    7379        int oldStart = start();
    7480        bool canParse;
  • trunk/Source/WebCore/html/HTMLOListElement.h

    r106769 r107484  
    5555
    5656    virtual void parseAttribute(Attribute*) OVERRIDE;
     57    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    5758
    5859    int m_start;
  • trunk/Source/WebCore/html/HTMLObjectElement.cpp

    r107477 r107484  
    7676    document()->updateLayoutIgnorePendingStylesheets();
    7777    return renderPart(); // This will return 0 if the renderer is not a RenderPart.
     78}
     79
     80void HTMLObjectElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     81{
     82    if (attr->name() == borderAttr)
     83        applyBorderAttributeToStyle(attr, style);
     84    else
     85        HTMLPlugInImageElement::collectStyleForAttribute(attr, style);
    7886}
    7987
     
    110118        setAttributeEventListener(eventNames().beforeloadEvent, createAttributeEventListener(this, attr));
    111119    else if (attr->name() == borderAttr)
    112         applyBorderAttribute(attr);
     120        setNeedsAttributeStyleUpdate();
    113121    else
    114122        HTMLPlugInImageElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLObjectElement.h

    r106769 r107484  
    6868
    6969    virtual void parseAttribute(Attribute*) OVERRIDE;
     70    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
     71
    7072    virtual void insertedIntoTree(bool deep);
    7173    virtual void removedFromTree(bool deep);
  • trunk/Source/WebCore/html/HTMLParagraphElement.cpp

    r106769 r107484  
    4545}
    4646
     47void HTMLParagraphElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     48{
     49    if (attr->name() == alignAttr) {
     50        if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
     51            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
     52        else if (equalIgnoringCase(attr->value(), "left"))
     53            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
     54        else if (equalIgnoringCase(attr->value(), "right"))
     55            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
     56        else
     57            style->setProperty(CSSPropertyTextAlign, attr->value());
     58    } else
     59        HTMLElement::collectStyleForAttribute(attr, style);
     60}
     61
    4762void HTMLParagraphElement::parseAttribute(Attribute* attr)
    4863{
    49     if (attr->name() == alignAttr) {
    50         if (attr->value().isNull())
    51             removeCSSProperty(CSSPropertyTextAlign);
    52         else if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
    53             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
    54         else if (equalIgnoringCase(attr->value(), "left"))
    55             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
    56         else if (equalIgnoringCase(attr->value(), "right"))
    57             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
    58         else
    59             addCSSProperty(CSSPropertyTextAlign, attr->value());
    60     } else
     64    if (attr->name() == alignAttr)
     65        setNeedsAttributeStyleUpdate();
     66    else
    6167        HTMLElement::parseAttribute(attr);
    6268}
  • trunk/Source/WebCore/html/HTMLParagraphElement.h

    r106769 r107484  
    3636
    3737    virtual void parseAttribute(Attribute*) OVERRIDE;
     38    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3839};
    3940
  • trunk/Source/WebCore/html/HTMLPlugInElement.cpp

    r107118 r107484  
    141141}
    142142
     143static inline bool isRespectedPresentationAttribute(Attribute* attr)
     144{
     145    return attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == alignAttr;
     146}
     147
     148void HTMLPlugInElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     149{
     150    if (attr->name() == widthAttr)
     151        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     152    else if (attr->name() == heightAttr)
     153        addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     154    else if (attr->name() == vspaceAttr) {
     155        addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
     156        addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     157    } else if (attr->name() == hspaceAttr) {
     158        addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
     159        addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     160    } else if (attr->name() == alignAttr)
     161        applyAlignmentAttributeToStyle(attr, style);
     162    else {
     163        ASSERT(!isRespectedPresentationAttribute(attr));
     164        HTMLFrameOwnerElement::collectStyleForAttribute(attr, style);
     165    }
     166}
     167
    143168void HTMLPlugInElement::parseAttribute(Attribute* attr)
    144169{
    145     if (attr->name() == widthAttr)
    146         if (attr->isNull())
    147             removeCSSProperty(CSSPropertyWidth);
    148         else
    149             addCSSLength(CSSPropertyWidth, attr->value());
    150     else if (attr->name() == heightAttr)
    151         if (attr->isNull())
    152             removeCSSProperty(CSSPropertyHeight);
    153         else
    154             addCSSLength(CSSPropertyHeight, attr->value());
    155     else if (attr->name() == vspaceAttr) {
    156         if (attr->isNull())
    157             removeCSSProperties(CSSPropertyMarginTop, CSSPropertyMarginBottom);
    158         else {
    159             addCSSLength(CSSPropertyMarginTop, attr->value());
    160             addCSSLength(CSSPropertyMarginBottom, attr->value());
    161         }
    162     } else if (attr->name() == hspaceAttr) {
    163         if (attr->isNull())
    164             removeCSSProperties(CSSPropertyMarginLeft, CSSPropertyMarginRight);
    165         else {
    166             addCSSLength(CSSPropertyMarginLeft, attr->value());
    167             addCSSLength(CSSPropertyMarginRight, attr->value());
    168         }
    169     } else if (attr->name() == alignAttr)
    170         addHTMLAlignment(attr);
     170    if (isRespectedPresentationAttribute(attr))
     171        setNeedsAttributeStyleUpdate();
    171172    else
    172173        HTMLFrameOwnerElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLPlugInElement.h

    r106769 r107484  
    6060    virtual void removedFromDocument();
    6161    virtual void parseAttribute(Attribute*) OVERRIDE;
     62    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    6263
    6364    bool m_inBeforeLoadEventHandler;
  • trunk/Source/WebCore/html/HTMLPreElement.cpp

    r106769 r107484  
    4343}
    4444
     45void HTMLPreElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     46{
     47    if (attr->name() == wrapAttr)
     48        style->setProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
     49    else
     50        HTMLElement::collectStyleForAttribute(attr, style);
     51}
     52
    4553void HTMLPreElement::parseAttribute(Attribute* attr)
    4654{
     
    5058        // multiply by the value of the attribute and then set that as the width CSS
    5159        // property.
    52     } else if (attr->name() == wrapAttr) {
    53         if (attr->value().isNull())
    54             removeCSSProperty(CSSPropertyWhiteSpace);
    55         else
    56             addCSSProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
    57     } else
     60    } else if (attr->name() == wrapAttr)
     61        setNeedsAttributeStyleUpdate();
     62    else
    5863        return HTMLElement::parseAttribute(attr);
    5964}
  • trunk/Source/WebCore/html/HTMLPreElement.h

    r106769 r107484  
    3636
    3737    virtual void parseAttribute(Attribute*) OVERRIDE;
     38    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3839};
    3940
  • trunk/Source/WebCore/html/HTMLTableCaptionElement.cpp

    r106769 r107484  
    4545}
    4646
     47void HTMLTableCaptionElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     48{
     49    if (attr->name() == alignAttr) {
     50        if (!attr->isEmpty())
     51            style->setProperty(CSSPropertyCaptionSide, attr->value());
     52    } else
     53        HTMLElement::collectStyleForAttribute(attr, style); // Note that we are bypassing HTMLTablePartElement here.
     54}
     55
    4756void HTMLTableCaptionElement::parseAttribute(Attribute* attr)
    4857{
    49     if (attr->name() == alignAttr) {
    50         if (!attr->value().isEmpty())
    51             addCSSProperty(CSSPropertyCaptionSide, attr->value());
    52         else
    53             removeCSSProperty(CSSPropertyCaptionSide);
    54     } else
    55         HTMLElement::parseAttribute(attr);
     58    if (attr->name() == alignAttr)
     59        setNeedsAttributeStyleUpdate();
     60    else
     61        HTMLElement::parseAttribute(attr); // Note that we are bypassing HTMLTablePartElement here.
    5662}
    5763
  • trunk/Source/WebCore/html/HTMLTableCaptionElement.h

    r106769 r107484  
    3939
    4040    virtual void parseAttribute(Attribute*) OVERRIDE;
     41    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4142};
    4243
  • trunk/Source/WebCore/html/HTMLTableCellElement.cpp

    r107478 r107484  
    7676}
    7777
     78static inline bool isRespectedPresentationAttribute(Attribute* attr)
     79{
     80    return attr->name() == nowrapAttr || attr->name() == widthAttr || attr->name() == heightAttr;
     81}
     82
     83void HTMLTableCellElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     84{
     85    if (attr->name() == nowrapAttr) {
     86        style->setProperty(CSSPropertyWhiteSpace, CSSValueWebkitNowrap);
     87    } else if (attr->name() == widthAttr) {
     88        if (!attr->value().isEmpty()) {
     89            int widthInt = attr->value().toInt();
     90            if (widthInt > 0) // width="0" is ignored for compatibility with WinIE.
     91                addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     92        }
     93    } else if (attr->name() == heightAttr) {
     94        if (!attr->value().isEmpty()) {
     95            int heightInt = attr->value().toInt();
     96            if (heightInt > 0) // height="0" is ignored for compatibility with WinIE.
     97                addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     98        }
     99    } else {
     100        ASSERT(!isRespectedPresentationAttribute(attr));
     101        HTMLTablePartElement::collectStyleForAttribute(attr, style);
     102    }
     103}
     104
    78105void HTMLTableCellElement::parseAttribute(Attribute* attr)
    79106{
    80     if (attr->name() == rowspanAttr) {
     107    if (isRespectedPresentationAttribute(attr))
     108        setNeedsAttributeStyleUpdate();
     109    else if (attr->name() == rowspanAttr) {
    81110        if (renderer() && renderer()->isTableCell())
    82111            toRenderTableCell(renderer())->colSpanOrRowSpanChanged();
     
    84113        if (renderer() && renderer()->isTableCell())
    85114            toRenderTableCell(renderer())->colSpanOrRowSpanChanged();
    86     } else if (attr->name() == nowrapAttr) {
    87         if (attr->isNull())
    88             removeCSSProperty(CSSPropertyWhiteSpace);
    89         else
    90             addCSSProperty(CSSPropertyWhiteSpace, CSSValueWebkitNowrap);
    91 
    92     } else if (attr->name() == widthAttr) {
    93         if (!attr->value().isEmpty()) {
    94             int widthInt = attr->value().toInt();
    95             if (widthInt > 0) // width="0" is ignored for compatibility with WinIE.
    96                 addCSSLength(CSSPropertyWidth, attr->value());
    97         } else
    98             removeCSSProperty(CSSPropertyWidth);
    99     } else if (attr->name() == heightAttr) {
    100         if (!attr->value().isEmpty()) {
    101             int heightInt = attr->value().toInt();
    102             if (heightInt > 0) // height="0" is ignored for compatibility with WinIE.
    103                 addCSSLength(CSSPropertyHeight, attr->value());
    104         } else
    105             removeCSSProperty(CSSPropertyHeight);
    106115    } else
    107116        HTMLTablePartElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLTableCellElement.h

    r107185 r107484  
    5555
    5656    virtual void parseAttribute(Attribute*) OVERRIDE;
     57    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    5758
    5859    virtual StylePropertySet* additionalAttributeStyle() OVERRIDE;
  • trunk/Source/WebCore/html/HTMLTableColElement.cpp

    r107478 r107484  
    4848}
    4949
     50void HTMLTableColElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     51{
     52    if (attr->name() == widthAttr)
     53        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     54    else
     55        HTMLTablePartElement::collectStyleForAttribute(attr, style);
     56}
     57
    5058void HTMLTableColElement::parseAttribute(Attribute* attr)
    5159{
     
    5563            renderer()->updateFromElement();
    5664    } else if (attr->name() == widthAttr) {
     65        setNeedsAttributeStyleUpdate();
    5766        if (!attr->value().isEmpty()) {
    58             addCSSLength(CSSPropertyWidth, attr->value());
    5967            if (renderer() && renderer()->isTableCol()) {
    6068                RenderTableCol* col = toRenderTableCol(renderer());
     
    6371                    col->setNeedsLayoutAndPrefWidthsRecalc();
    6472            }
    65         } else
    66             removeCSSProperty(CSSPropertyWidth);
     73        }
    6774    } else
    6875        HTMLTablePartElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLTableColElement.h

    r107185 r107484  
    4444
    4545    virtual void parseAttribute(Attribute*) OVERRIDE;
     46    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4647    virtual StylePropertySet* additionalAttributeStyle() OVERRIDE;
    4748
  • trunk/Source/WebCore/html/HTMLTableElement.cpp

    r107185 r107484  
    2727
    2828#include "Attribute.h"
     29#include "CSSImageValue.h"
    2930#include "CSSPropertyNames.h"
    3031#include "CSSStyleSheet.h"
     
    267268}
    268269
     270static bool getBordersFromFrameAttributeValue(const AtomicString& value, bool& borderTop, bool& borderRight, bool& borderBottom, bool& borderLeft)
     271{
     272    borderTop = false;
     273    borderRight = false;
     274    borderBottom = false;
     275    borderLeft = false;
     276
     277    if (equalIgnoringCase(value, "above"))
     278        borderTop = true;
     279    else if (equalIgnoringCase(value, "below"))
     280        borderBottom = true;
     281    else if (equalIgnoringCase(value, "hsides"))
     282        borderTop = borderBottom = true;
     283    else if (equalIgnoringCase(value, "vsides"))
     284        borderLeft = borderRight = true;
     285    else if (equalIgnoringCase(value, "lhs"))
     286        borderLeft = true;
     287    else if (equalIgnoringCase(value, "rhs"))
     288        borderRight = true;
     289    else if (equalIgnoringCase(value, "box") || equalIgnoringCase(value, "border"))
     290        borderTop = borderBottom = borderLeft = borderRight = true;
     291    else if (!equalIgnoringCase(value, "void"))
     292        return false;
     293    return true;
     294}
     295
     296void HTMLTableElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     297{
     298    if (attr->name() == widthAttr)
     299        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     300    else if (attr->name() == heightAttr)
     301        addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     302    else if (attr->name() == borderAttr) {
     303        int border = attr->isEmpty() ? 1 : attr->value().toInt();
     304        addHTMLLengthToStyle(style, CSSPropertyBorderWidth, String::number(border)); // FIXME: Pass as integer.
     305    } else if (attr->name() == bordercolorAttr) {
     306        if (!attr->isEmpty())
     307            addHTMLColorToStyle(style, CSSPropertyBorderColor, attr->value());
     308    } else if (attr->name() == bgcolorAttr)
     309        addHTMLColorToStyle(style, CSSPropertyBackgroundColor, attr->value());
     310    else if (attr->name() == backgroundAttr) {
     311        String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
     312        if (!url.isEmpty())
     313            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document()->completeURL(url).string())));
     314    } else if (attr->name() == valignAttr) {
     315        if (!attr->isEmpty())
     316            style->setProperty(CSSPropertyVerticalAlign, attr->value());
     317    } else if (attr->name() == cellspacingAttr) {
     318        if (!attr->isEmpty())
     319            addHTMLLengthToStyle(style, CSSPropertyBorderSpacing, attr->value());
     320    } else if (attr->name() == vspaceAttr) {
     321        addHTMLLengthToStyle(style, CSSPropertyMarginTop, attr->value());
     322        addHTMLLengthToStyle(style, CSSPropertyMarginBottom, attr->value());
     323    } else if (attr->name() == hspaceAttr) {
     324        addHTMLLengthToStyle(style, CSSPropertyMarginLeft, attr->value());
     325        addHTMLLengthToStyle(style, CSSPropertyMarginRight, attr->value());
     326    } else if (attr->name() == alignAttr) {
     327        if (!attr->value().isEmpty()) {
     328            if (equalIgnoringCase(attr->value(), "center")) {
     329                style->setProperty(CSSPropertyWebkitMarginStart, CSSValueAuto);
     330                style->setProperty(CSSPropertyWebkitMarginEnd, CSSValueAuto);
     331            } else
     332                style->setProperty(CSSPropertyFloat, attr->value());
     333        }
     334    } else if (attr->name() == rulesAttr) {
     335        // The presence of a valid rules attribute causes border collapsing to be enabled.
     336        if (m_rulesAttr != UnsetRules)
     337            style->setProperty(CSSPropertyBorderCollapse, CSSValueCollapse);
     338    } else if (attr->name() == frameAttr) {
     339        bool borderTop;
     340        bool borderRight;
     341        bool borderBottom;
     342        bool borderLeft;
     343        if (getBordersFromFrameAttributeValue(attr->value(), borderTop, borderRight, borderBottom, borderLeft)) {
     344            style->setProperty(CSSPropertyBorderTopWidth, CSSValueThin);
     345            style->setProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
     346            style->setProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
     347            style->setProperty(CSSPropertyBorderRightWidth, CSSValueThin);
     348            style->setProperty(CSSPropertyBorderTopStyle, borderTop ? CSSValueSolid : CSSValueHidden);
     349            style->setProperty(CSSPropertyBorderBottomStyle, borderBottom ? CSSValueSolid : CSSValueHidden);
     350            style->setProperty(CSSPropertyBorderLeftStyle, borderLeft ? CSSValueSolid : CSSValueHidden);
     351            style->setProperty(CSSPropertyBorderRightStyle, borderRight ? CSSValueSolid : CSSValueHidden);
     352        }
     353    } else
     354        HTMLElement::collectStyleForAttribute(attr, style);
     355}
     356
    269357void HTMLTableElement::parseAttribute(Attribute* attr)
    270358{
     
    272360    unsigned short oldPadding = m_padding;
    273361
    274     if (attr->name() == widthAttr)
    275         if (attr->isNull())
    276             removeCSSProperty(CSSPropertyWidth);
    277         else
    278             addCSSLength(CSSPropertyWidth, attr->value());
    279     else if (attr->name() == heightAttr)
    280         if (attr->isNull())
    281             removeCSSProperty(CSSPropertyHeight);
    282         else
    283             addCSSLength(CSSPropertyHeight, attr->value());
     362    if (attr->name() == widthAttr || attr->name() == heightAttr || attr->name() == bgcolorAttr || attr->name() == backgroundAttr || attr->name() == valignAttr || attr->name() == vspaceAttr || attr->name() == hspaceAttr || attr->name() == alignAttr || attr->name() == cellspacingAttr)
     363        setNeedsAttributeStyleUpdate();
    284364    else if (attr->name() == borderAttr)  {
     365        // FIXME: This attribute is a mess.
    285366        m_borderAttr = true;
    286 
    287         if (attr->isNull())
    288             removeCSSProperty(CSSPropertyBorderWidth);
    289         else {
    290             int border = 0;
    291             if (attr->isEmpty())
    292                 border = 1;
    293             else
    294                 border = attr->value().toInt();
     367        if (!attr->isNull()) {
     368            int border = attr->isEmpty() ? 1 : attr->value().toInt();
    295369            m_borderAttr = border;
    296             addCSSLength(CSSPropertyBorderWidth, String::number(border));
    297370        }
    298     } else if (attr->name() == bgcolorAttr)
    299         if (attr->isNull())
    300             removeCSSProperty(CSSPropertyBackgroundColor);
    301         else
    302             addCSSColor(CSSPropertyBackgroundColor, attr->value());
    303     else if (attr->name() == bordercolorAttr) {
     371        setNeedsAttributeStyleUpdate();
     372    } else if (attr->name() == bordercolorAttr) {
    304373        m_borderColorAttr = !attr->isEmpty();
    305         if (!attr->isEmpty())
    306             addCSSColor(CSSPropertyBorderColor, attr->value());
    307         else
    308             removeCSSProperty(CSSPropertyBorderColor);
    309     } else if (attr->name() == backgroundAttr) {
    310         String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
    311         if (!url.isEmpty())
    312             addCSSImageProperty(CSSPropertyBackgroundImage, document()->completeURL(url).string());
    313         else
    314             removeCSSProperty(CSSPropertyBackgroundImage);
     374        setNeedsAttributeStyleUpdate();
    315375    } else if (attr->name() == frameAttr) {
    316         // Cache the value of "frame" so that the table can examine it later.
    317         m_frameAttr = false;
    318        
    319         // Whether or not to hide the top/right/bottom/left borders.
    320         const int cTop = 0;
    321         const int cRight = 1;
    322         const int cBottom = 2;
    323         const int cLeft = 3;
    324         bool borders[4] = { false, false, false, false };
    325        
    326         // void, above, below, hsides, vsides, lhs, rhs, box, border
    327         if (equalIgnoringCase(attr->value(), "void"))
    328             m_frameAttr = true;
    329         else if (equalIgnoringCase(attr->value(), "above")) {
    330             m_frameAttr = true;
    331             borders[cTop] = true;
    332         } else if (equalIgnoringCase(attr->value(), "below")) {
    333             m_frameAttr = true;
    334             borders[cBottom] = true;
    335         } else if (equalIgnoringCase(attr->value(), "hsides")) {
    336             m_frameAttr = true;
    337             borders[cTop] = borders[cBottom] = true;
    338         } else if (equalIgnoringCase(attr->value(), "vsides")) {
    339             m_frameAttr = true;
    340             borders[cLeft] = borders[cRight] = true;
    341         } else if (equalIgnoringCase(attr->value(), "lhs")) {
    342             m_frameAttr = true;
    343             borders[cLeft] = true;
    344         } else if (equalIgnoringCase(attr->value(), "rhs")) {
    345             m_frameAttr = true;
    346             borders[cRight] = true;
    347         } else if (equalIgnoringCase(attr->value(), "box") ||
    348                    equalIgnoringCase(attr->value(), "border")) {
    349             m_frameAttr = true;
    350             borders[cTop] = borders[cBottom] = borders[cLeft] = borders[cRight] = true;
    351         }
    352        
    353         // Now map in the border styles of solid and hidden respectively.
    354         if (m_frameAttr) {
    355             addCSSProperty(CSSPropertyBorderTopWidth, CSSValueThin);
    356             addCSSProperty(CSSPropertyBorderBottomWidth, CSSValueThin);
    357             addCSSProperty(CSSPropertyBorderLeftWidth, CSSValueThin);
    358             addCSSProperty(CSSPropertyBorderRightWidth, CSSValueThin);
    359             addCSSProperty(CSSPropertyBorderTopStyle, borders[cTop] ? CSSValueSolid : CSSValueHidden);
    360             addCSSProperty(CSSPropertyBorderBottomStyle, borders[cBottom] ? CSSValueSolid : CSSValueHidden);
    361             addCSSProperty(CSSPropertyBorderLeftStyle, borders[cLeft] ? CSSValueSolid : CSSValueHidden);
    362             addCSSProperty(CSSPropertyBorderRightStyle, borders[cRight] ? CSSValueSolid : CSSValueHidden);
    363         } else
    364             removeCSSProperties(CSSPropertyBorderTopWidth, CSSPropertyBorderBottomWidth, CSSPropertyBorderLeftWidth, CSSPropertyBorderRightWidth, CSSPropertyBorderTopStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle, CSSPropertyBorderRightStyle);
     376        // FIXME: This attribute is a mess.
     377        bool borderTop;
     378        bool borderRight;
     379        bool borderBottom;
     380        bool borderLeft;
     381        m_frameAttr = getBordersFromFrameAttributeValue(attr->value(), borderTop, borderRight, borderBottom, borderLeft);
     382        setNeedsAttributeStyleUpdate();
    365383    } else if (attr->name() == rulesAttr) {
    366384        m_rulesAttr = UnsetRules;
     
    375393        if (equalIgnoringCase(attr->value(), "all"))
    376394            m_rulesAttr = AllRules;
    377        
    378         // The presence of a valid rules attribute causes border collapsing to be enabled.
    379         if (m_rulesAttr != UnsetRules)
    380             addCSSProperty(CSSPropertyBorderCollapse, CSSValueCollapse);
    381         else
    382             removeCSSProperty(CSSPropertyBorderCollapse);
    383     } else if (attr->name() == cellspacingAttr) {
    384         if (!attr->value().isEmpty())
    385             addCSSLength(CSSPropertyBorderSpacing, attr->value());
    386         else
    387             removeCSSProperty(CSSPropertyBorderSpacing);
     395
     396        setNeedsAttributeStyleUpdate();
    388397    } else if (attr->name() == cellpaddingAttr) {
    389398        if (!attr->value().isEmpty())
     
    393402    } else if (attr->name() == colsAttr) {
    394403        // ###
    395     } else if (attr->name() == vspaceAttr) {
    396         if (attr->isNull())
    397             removeCSSProperties(CSSPropertyMarginTop, CSSPropertyMarginBottom);
    398         else {
    399             addCSSLength(CSSPropertyMarginTop, attr->value());
    400             addCSSLength(CSSPropertyMarginBottom, attr->value());
    401         }
    402     } else if (attr->name() == hspaceAttr) {
    403         if (attr->isNull())
    404             removeCSSProperties(CSSPropertyMarginLeft, CSSPropertyMarginRight);
    405         else {
    406             addCSSLength(CSSPropertyMarginLeft, attr->value());
    407             addCSSLength(CSSPropertyMarginRight, attr->value());
    408         }
    409     } else if (attr->name() == alignAttr) {
    410         if (!attr->value().isEmpty()) {
    411             if (equalIgnoringCase(attr->value(), "center")) {
    412                 addCSSProperty(CSSPropertyWebkitMarginStart, CSSValueAuto);
    413                 addCSSProperty(CSSPropertyWebkitMarginEnd, CSSValueAuto);
    414             } else
    415                 addCSSProperty(CSSPropertyFloat, attr->value());
    416         } else
    417             removeCSSProperties(CSSPropertyWebkitMarginStart, CSSPropertyWebkitMarginEnd, CSSPropertyFloat);
    418     } else if (attr->name() == valignAttr) {
    419         if (!attr->value().isEmpty())
    420             addCSSProperty(CSSPropertyVerticalAlign, attr->value());
    421         else
    422             removeCSSProperty(CSSPropertyVerticalAlign);
    423404    } else
    424405        HTMLElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLTableElement.h

    r107185 r107484  
    7474
    7575    virtual void parseAttribute(Attribute*) OVERRIDE;
     76    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    7677    virtual bool isURLAttribute(Attribute*) const;
    7778
  • trunk/Source/WebCore/html/HTMLTablePartElement.cpp

    r107478 r107484  
    2727
    2828#include "Attribute.h"
     29#include "CSSImageValue.h"
    2930#include "CSSPropertyNames.h"
    3031#include "CSSValueKeywords.h"
     
    3839using namespace HTMLNames;
    3940
    40 void HTMLTablePartElement::parseAttribute(Attribute* attr)
     41static inline bool isRespectedPresentationAttribute(Attribute* attr)
     42{
     43    return attr->name() == bgcolorAttr || attr->name() == backgroundAttr || attr->name() == bordercolorAttr || attr->name() == valignAttr || attr->name() == alignAttr || attr->name() == heightAttr;
     44}
     45
     46void HTMLTablePartElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    4147{
    4248    if (attr->name() == bgcolorAttr)
    43         if (attr->value().isNull())
    44             removeCSSProperty(CSSPropertyBackgroundColor);
    45         else
    46             addCSSColor(CSSPropertyBackgroundColor, attr->value());
     49        addHTMLColorToStyle(style, CSSPropertyBackgroundColor, attr->value());
    4750    else if (attr->name() == backgroundAttr) {
    4851        String url = stripLeadingAndTrailingHTMLSpaces(attr->value());
    4952        if (!url.isEmpty())
    50             addCSSImageProperty(CSSPropertyBackgroundImage, document()->completeURL(url).string());
    51         else
    52             removeCSSProperty(CSSPropertyBackgroundImage);
     53            style->setProperty(CSSProperty(CSSPropertyBackgroundImage, CSSImageValue::create(document()->completeURL(url).string())));
    5354    } else if (attr->name() == bordercolorAttr) {
    5455        if (!attr->value().isEmpty()) {
    55             addCSSColor(CSSPropertyBorderColor, attr->value());
    56             addCSSProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
    57             addCSSProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
    58             addCSSProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
    59             addCSSProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
    60         } else
    61             removeCSSProperties(CSSPropertyBorderColor, CSSPropertyBorderTopStyle, CSSPropertyBorderBottomStyle, CSSPropertyBorderLeftStyle, CSSPropertyBorderRightStyle);
     56            addHTMLColorToStyle(style, CSSPropertyBorderColor, attr->value());
     57            style->setProperty(CSSPropertyBorderTopStyle, CSSValueSolid);
     58            style->setProperty(CSSPropertyBorderBottomStyle, CSSValueSolid);
     59            style->setProperty(CSSPropertyBorderLeftStyle, CSSValueSolid);
     60            style->setProperty(CSSPropertyBorderRightStyle, CSSValueSolid);
     61        }
    6262    } else if (attr->name() == valignAttr) {
    6363        if (!attr->value().isEmpty())
    64             addCSSProperty(CSSPropertyVerticalAlign, attr->value());
     64            style->setProperty(CSSPropertyVerticalAlign, attr->value());
     65    } else if (attr->name() == alignAttr) {
     66        if (equalIgnoringCase(attr->value(), "middle") || equalIgnoringCase(attr->value(), "center"))
     67            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
     68        else if (equalIgnoringCase(attr->value(), "absmiddle"))
     69            style->setProperty(CSSPropertyTextAlign, CSSValueCenter);
     70        else if (equalIgnoringCase(attr->value(), "left"))
     71            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
     72        else if (equalIgnoringCase(attr->value(), "right"))
     73            style->setProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
    6574        else
    66             removeCSSProperty(CSSPropertyVerticalAlign);
    67     } else if (attr->name() == alignAttr) {
    68         const AtomicString& v = attr->value();
    69         if (v.isNull())
    70             removeCSSProperty(CSSPropertyTextAlign);
    71         else if (equalIgnoringCase(v, "middle") || equalIgnoringCase(v, "center"))
    72             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitCenter);
    73         else if (equalIgnoringCase(v, "absmiddle"))
    74             addCSSProperty(CSSPropertyTextAlign, CSSValueCenter);
    75         else if (equalIgnoringCase(v, "left"))
    76             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitLeft);
    77         else if (equalIgnoringCase(v, "right"))
    78             addCSSProperty(CSSPropertyTextAlign, CSSValueWebkitRight);
    79         else
    80             addCSSProperty(CSSPropertyTextAlign, v);
     75            style->setProperty(CSSPropertyTextAlign, attr->value());
    8176    } else if (attr->name() == heightAttr) {
    8277        if (!attr->value().isEmpty())
    83             addCSSLength(CSSPropertyHeight, attr->value());
    84         else
    85             removeCSSProperty(CSSPropertyHeight);
    86     } else
     78            addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     79    } else {
     80        ASSERT(!isRespectedPresentationAttribute(attr));
     81        HTMLElement::collectStyleForAttribute(attr, style);
     82    }
     83}
     84
     85void HTMLTablePartElement::parseAttribute(Attribute* attr)
     86{
     87    if (isRespectedPresentationAttribute(attr))
     88        setNeedsAttributeStyleUpdate();
     89    else
    8790        HTMLElement::parseAttribute(attr);
    8891}
  • trunk/Source/WebCore/html/HTMLTablePartElement.h

    r107478 r107484  
    3939    {
    4040    }
    41 
    4241    virtual void parseAttribute(Attribute*) OVERRIDE;
     42    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4343
    4444    HTMLTableElement* findParentTable() const;
  • trunk/Source/WebCore/html/HTMLTextAreaElement.cpp

    r107202 r107484  
    118118    HTMLElement::childrenChanged(changedByParser, beforeChange, afterChange, childCountDelta);
    119119}
    120    
     120
     121void HTMLTextAreaElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     122{
     123    if (attr->name() == wrapAttr) {
     124        if (shouldWrapText()) {
     125            style->setProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
     126            style->setProperty(CSSPropertyWordWrap, CSSValueBreakWord);
     127        } else {
     128            style->setProperty(CSSPropertyWhiteSpace, CSSValuePre);
     129            style->setProperty(CSSPropertyWordWrap, CSSValueNormal);
     130        }
     131    } else
     132        HTMLTextFormControlElement::collectStyleForAttribute(attr, style);
     133}
     134
    121135void HTMLTextAreaElement::parseAttribute(Attribute* attr)
    122136{
     
    151165        if (wrap != m_wrap) {
    152166            m_wrap = wrap;
    153 
    154             if (shouldWrapText()) {
    155                 addCSSProperty(CSSPropertyWhiteSpace, CSSValuePreWrap);
    156                 addCSSProperty(CSSPropertyWordWrap, CSSValueBreakWord);
    157             } else {
    158                 addCSSProperty(CSSPropertyWhiteSpace, CSSValuePre);
    159                 addCSSProperty(CSSPropertyWordWrap, CSSValueNormal);
    160             }
     167            setNeedsAttributeStyleUpdate();
    161168
    162169            if (renderer())
  • trunk/Source/WebCore/html/HTMLTextAreaElement.h

    r106769 r107484  
    9595    virtual void childrenChanged(bool changedByParser = false, Node* beforeChange = 0, Node* afterChange = 0, int childCountDelta = 0);
    9696    virtual void parseAttribute(Attribute*) OVERRIDE;
     97    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    9798    virtual RenderObject* createRenderer(RenderArena*, RenderStyle*);
    9899    virtual bool appendFormData(FormDataList&, bool);
  • trunk/Source/WebCore/html/HTMLUListElement.cpp

    r106769 r107484  
    4848}
    4949
     50void HTMLUListElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     51{
     52    if (attr->name() == typeAttr)
     53        style->setProperty(CSSPropertyListStyleType, attr->value());
     54    else
     55        HTMLElement::collectStyleForAttribute(attr, style);
     56}
     57
    5058void HTMLUListElement::parseAttribute(Attribute* attr)
    5159{
    5260    if (attr->name() == typeAttr)
    53         if (attr->value().isNull())
    54             removeCSSProperty(CSSPropertyListStyleType);
    55         else
    56             addCSSProperty(CSSPropertyListStyleType, attr->value());
     61        setNeedsAttributeStyleUpdate();
    5762    else
    5863        HTMLElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLUListElement.h

    r106769 r107484  
    3737
    3838    virtual void parseAttribute(Attribute*) OVERRIDE;
     39    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    3940};
    4041
  • trunk/Source/WebCore/html/HTMLVideoElement.cpp

    r107239 r107484  
    9696}
    9797
     98void HTMLVideoElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     99{
     100    if (attr->name() == widthAttr)
     101        addHTMLLengthToStyle(style, CSSPropertyWidth, attr->value());
     102    else if (attr->name() == heightAttr)
     103        addHTMLLengthToStyle(style, CSSPropertyHeight, attr->value());
     104    else
     105        HTMLMediaElement::collectStyleForAttribute(attr, style);
     106}
     107
    98108void HTMLVideoElement::parseAttribute(Attribute* attr)
    99109{
     
    116126        }
    117127#endif
    118     } else if (attrName == widthAttr)
    119         if (attr->value().isNull())
    120             removeCSSProperty(CSSPropertyWidth);
    121         else
    122             addCSSLength(CSSPropertyWidth, attr->value());
    123     else if (attrName == heightAttr)
    124         if (attr->value().isNull())
    125             removeCSSProperty(CSSPropertyHeight);
    126         else
    127             addCSSLength(CSSPropertyHeight, attr->value());
     128    } else if (attrName == widthAttr || attrName == heightAttr)
     129        setNeedsAttributeStyleUpdate();
    128130    else
    129131        HTMLMediaElement::parseAttribute(attr);
  • trunk/Source/WebCore/html/HTMLVideoElement.h

    r106769 r107484  
    7777    virtual void detach();
    7878    virtual void parseAttribute(Attribute*) OVERRIDE;
     79    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    7980    virtual bool isVideo() const { return true; }
    8081    virtual bool hasVideo() const { return player() && player()->hasVideo(); }
  • trunk/Source/WebCore/mathml/MathMLElement.cpp

    r106769 r107484  
    4949}
    5050
    51 void MathMLElement::parseAttribute(Attribute* attr)
     51static inline bool isRespectedPresentationAttribute(Attribute* attr)
     52{
     53    return attr->name() == mathbackgroundAttr || attr->name() == mathsizeAttr || attr->name() == mathcolorAttr || attr->name() == fontsizeAttr || attr->name() == backgroundAttr || attr->name() == colorAttr || attr->name() == fontstyleAttr || attr->name() == fontweightAttr || attr->name() == fontfamilyAttr;
     54}
     55
     56void MathMLElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
    5257{
    5358    if (attr->name() == mathbackgroundAttr)
    54         addCSSProperty(CSSPropertyBackgroundColor, attr->value());
     59        style->setProperty(CSSPropertyBackgroundColor, attr->value());
    5560    else if (attr->name() == mathsizeAttr) {
    5661        // The following three values of mathsize are handled in WebCore/css/mathml.css
    5762        if (attr->value() != "normal" && attr->value() != "small" && attr->value() != "big")
    58             addCSSProperty(CSSPropertyFontSize, attr->value());
     63            style->setProperty(CSSPropertyFontSize, attr->value());
    5964    } else if (attr->name() == mathcolorAttr)
    60         addCSSProperty(CSSPropertyColor, attr->value());
     65        style->setProperty(CSSPropertyColor, attr->value());
    6166    // FIXME: deprecated attributes that should loose in a conflict with a non deprecated attribute
    6267    else if (attr->name() == fontsizeAttr)
    63         addCSSProperty(CSSPropertyFontSize, attr->value());
     68        style->setProperty(CSSPropertyFontSize, attr->value());
    6469    else if (attr->name() == backgroundAttr)
    65         addCSSProperty(CSSPropertyBackgroundColor, attr->value());
     70        style->setProperty(CSSPropertyBackgroundColor, attr->value());
    6671    else if (attr->name() == colorAttr)
    67         addCSSProperty(CSSPropertyColor, attr->value());
     72        style->setProperty(CSSPropertyColor, attr->value());
    6873    else if (attr->name() == fontstyleAttr)
    69         addCSSProperty(CSSPropertyFontStyle, attr->value());
     74        style->setProperty(CSSPropertyFontStyle, attr->value());
    7075    else if (attr->name() == fontweightAttr)
    71         addCSSProperty(CSSPropertyFontWeight, attr->value());
     76        style->setProperty(CSSPropertyFontWeight, attr->value());
    7277    else if (attr->name() == fontfamilyAttr)
    73         addCSSProperty(CSSPropertyFontFamily, attr->value());
     78        style->setProperty(CSSPropertyFontFamily, attr->value());
     79    else {
     80        ASSERT(!isRespectedPresentationAttribute(attr));
     81        StyledElement::collectStyleForAttribute(attr, style);
     82    }
     83}
     84
     85void MathMLElement::parseAttribute(Attribute* attr)
     86{
     87    if (isRespectedPresentationAttribute(attr))
     88        setNeedsAttributeStyleUpdate();
    7489    else
    7590        StyledElement::parseAttribute(attr);
  • trunk/Source/WebCore/mathml/MathMLElement.h

    r106769 r107484  
    4444    virtual bool isMathMLElement() const { return true; }
    4545    virtual void parseAttribute(Attribute*) OVERRIDE;
     46    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    4647};
    4748   
  • trunk/Source/WebCore/svg/SVGImageElement.cpp

    r106769 r107484  
    9292}
    9393
     94void SVGImageElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     95{
     96    if (!isSupportedAttribute(attr->name()))
     97        SVGStyledTransformableElement::collectStyleForAttribute(attr, style);
     98    else if (attr->name() == SVGNames::widthAttr)
     99        style->setProperty(CSSPropertyWidth, attr->value());
     100    else if (attr->name() == SVGNames::heightAttr)
     101        style->setProperty(CSSPropertyHeight, attr->value());
     102}
     103
    94104void SVGImageElement::parseAttribute(Attribute* attr)
    95105{
     
    106116    else if (attr->name() == SVGNames::widthAttr) {
    107117        setWidthBaseValue(SVGLength::construct(LengthModeWidth, attr->value(), parseError, ForbidNegativeLengths));
    108         addCSSProperty(CSSPropertyWidth, attr->value());
     118        setNeedsAttributeStyleUpdate();
    109119    } else if (attr->name() == SVGNames::heightAttr) {
    110120        setHeightBaseValue(SVGLength::construct(LengthModeHeight, attr->value(), parseError, ForbidNegativeLengths));
    111         addCSSProperty(CSSPropertyHeight, attr->value());
     121        setNeedsAttributeStyleUpdate();
    112122    } else if (SVGTests::parseAttribute(attr)
    113123             || SVGLangSpace::parseAttribute(attr)
  • trunk/Source/WebCore/svg/SVGImageElement.h

    r106769 r107484  
    5151    bool isSupportedAttribute(const QualifiedName&);
    5252    virtual void parseAttribute(Attribute*) OVERRIDE;
     53    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    5354    virtual void svgAttributeChanged(const QualifiedName&);
    5455
  • trunk/Source/WebCore/svg/SVGStyledElement.cpp

    r107057 r107484  
    293293}
    294294
     295void SVGStyledElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     296{
     297    int propertyID = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name());
     298    if (propertyID > 0)
     299        style->setProperty(propertyID, attr->value());
     300}
     301
    295302void SVGStyledElement::parseAttribute(Attribute* attr)
    296303{
    297     int propId = SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name());
    298     if (propId > 0) {
    299         addCSSProperty(propId, attr->value());
    300         setNeedsStyleRecalc();
     304    if (SVGStyledElement::cssPropertyIdForSVGAttributeName(attr->name()) > 0) {
     305        setNeedsAttributeStyleUpdate();
    301306        return;
    302307    }
  • trunk/Source/WebCore/svg/SVGStyledElement.h

    r106769 r107484  
    6767
    6868    virtual void parseAttribute(Attribute*) OVERRIDE;
     69    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    6970    virtual void svgAttributeChanged(const QualifiedName&);
    7071
  • trunk/Source/WebCore/svg/SVGTextContentElement.cpp

    r106769 r107484  
    229229}
    230230
     231void SVGTextContentElement::collectStyleForAttribute(Attribute* attr, StylePropertySet* style)
     232{
     233    if (!isSupportedAttribute(attr->name()))
     234        SVGStyledElement::collectStyleForAttribute(attr, style);
     235    else if (attr->name().matches(XMLNames::spaceAttr)) {
     236        DEFINE_STATIC_LOCAL(const AtomicString, preserveString, ("preserve"));
     237
     238        if (attr->value() == preserveString)
     239            style->setProperty(CSSPropertyWhiteSpace, CSSValuePre);
     240        else
     241            style->setProperty(CSSPropertyWhiteSpace, CSSValueNowrap);
     242    }
     243}
     244
    231245void SVGTextContentElement::parseAttribute(Attribute* attr)
    232246{
     
    244258               || SVGExternalResourcesRequired::parseAttribute(attr)) {
    245259    } else if (SVGLangSpace::parseAttribute(attr)) {
    246         if (attr->name().matches(XMLNames::spaceAttr)) {
    247             DEFINE_STATIC_LOCAL(const AtomicString, preserveString, ("preserve"));
    248 
    249             if (attr->value() == preserveString)
    250                 addCSSProperty(CSSPropertyWhiteSpace, CSSValuePre);
    251             else
    252                 addCSSProperty(CSSPropertyWhiteSpace, CSSValueNowrap);
    253         }
     260        if (attr->name().matches(XMLNames::spaceAttr))
     261            setNeedsAttributeStyleUpdate();
    254262    } else
    255263        ASSERT_NOT_REACHED();
  • trunk/Source/WebCore/svg/SVGTextContentElement.h

    r106769 r107484  
    105105    bool isSupportedAttribute(const QualifiedName&);
    106106    virtual void parseAttribute(Attribute*) OVERRIDE;
     107    virtual void collectStyleForAttribute(Attribute*, StylePropertySet*) OVERRIDE;
    107108    virtual void svgAttributeChanged(const QualifiedName&);
    108109
Note: See TracChangeset for help on using the changeset viewer.