diff options
author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:09:45 +0100 |
---|---|---|
committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-22 09:10:13 +0100 |
commit | 470286ecfe79d59df14944e5b5d34630fc739391 (patch) | |
tree | 43983212872e06cebefd2ae474418fa2908ca54c /Source/WebCore/dom/StyledElement.cpp | |
parent | 23037105e948c2065da5a937d3a2396b0ff45c1e (diff) | |
download | qtwebkit-470286ecfe79d59df14944e5b5d34630fc739391.tar.gz |
Imported WebKit commit e89504fa9195b2063b2530961d4b73dd08de3242 (http://svn.webkit.org/repository/webkit/trunk@135485)
Change-Id: I03774e5ac79721c13ffa30d152537a74d0b12e66
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/WebCore/dom/StyledElement.cpp')
-rw-r--r-- | Source/WebCore/dom/StyledElement.cpp | 126 |
1 files changed, 80 insertions, 46 deletions
diff --git a/Source/WebCore/dom/StyledElement.cpp b/Source/WebCore/dom/StyledElement.cpp index c4c86ecfd..27c314a2a 100644 --- a/Source/WebCore/dom/StyledElement.cpp +++ b/Source/WebCore/dom/StyledElement.cpp @@ -26,6 +26,7 @@ #include "Attribute.h" #include "CSSImageValue.h" +#include "CSSParser.h" #include "CSSPropertyNames.h" #include "CSSStyleSheet.h" #include "CSSValueKeywords.h" @@ -37,6 +38,7 @@ #include "Document.h" #include "HTMLNames.h" #include "HTMLParserIdioms.h" +#include "PropertySetCSSStyleDeclaration.h" #include "ScriptableDocumentParser.h" #include "StylePropertySet.h" #include "StyleResolver.h" @@ -126,86 +128,118 @@ static PresentationAttributeCacheCleaner& presentationAttributeCacheCleaner() void StyledElement::updateStyleAttribute() const { - ASSERT(!isStyleAttributeValid()); - setIsStyleAttributeValid(); + ASSERT(attributeData()); + ASSERT(attributeData()->m_styleAttributeIsDirty); + attributeData()->m_styleAttributeIsDirty = false; if (const StylePropertySet* inlineStyle = this->inlineStyle()) const_cast<StyledElement*>(this)->setSynchronizedLazyAttribute(styleAttr, inlineStyle->asText()); } -StyledElement::StyledElement(const QualifiedName& name, Document* document, ConstructionType type) - : Element(name, document, type) +StyledElement::~StyledElement() { + if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper()) + cssomWrapper->clearParentElement(); } -StyledElement::~StyledElement() +CSSStyleDeclaration* StyledElement::style() { - if (attributeData() && attributeData()->isMutable()) - mutableAttributeData()->detachCSSOMWrapperIfNeeded(this); + return ensureMutableInlineStyle()->ensureInlineCSSStyleDeclaration(this); } -CSSStyleDeclaration* StyledElement::style() +StylePropertySet* StyledElement::ensureMutableInlineStyle() { - return ensureInlineStyle()->ensureInlineCSSStyleDeclaration(this); + RefPtr<StylePropertySet>& inlineStyle = mutableAttributeData()->m_inlineStyle; + if (!inlineStyle) + inlineStyle = StylePropertySet::create(strictToCSSParserMode(isHTMLElement() && !document()->inQuirksMode())); + else if (!inlineStyle->isMutable()) + inlineStyle = inlineStyle->copy(); + return inlineStyle.get(); } void StyledElement::attributeChanged(const QualifiedName& name, const AtomicString& newValue) { - if (isPresentationAttribute(name)) { - setAttributeStyleDirty(); + if (name == styleAttr) + styleAttributeChanged(newValue); + else if (isPresentationAttribute(name)) { + attributeData()->m_presentationAttributeStyleIsDirty = true; setNeedsStyleRecalc(InlineStyleChange); } Element::attributeChanged(name, newValue); } -void StyledElement::styleAttributeChanged(const AtomicString& newStyleString, ShouldReparseStyleAttribute shouldReparse) +PropertySetCSSStyleDeclaration* StyledElement::inlineStyleCSSOMWrapper() { - if (shouldReparse) { - WTF::OrdinalNumber startLineNumber = WTF::OrdinalNumber::beforeFirst(); - if (document() && document()->scriptableDocumentParser() && !document()->isInDocumentWrite()) - startLineNumber = document()->scriptableDocumentParser()->lineNumber(); - if (newStyleString.isNull() && attributeData()) - mutableAttributeData()->destroyInlineStyle(this); - else if (document()->contentSecurityPolicy()->allowInlineStyle(document()->url(), startLineNumber)) - ensureAttributeData()->updateInlineStyleAvoidingMutation(this, newStyleString); - setIsStyleAttributeValid(); - } - setNeedsStyleRecalc(); - InspectorInstrumentation::didInvalidateStyleAttr(document(), this); + if (!inlineStyle() || !inlineStyle()->hasCSSOMWrapper()) + return 0; + PropertySetCSSStyleDeclaration* cssomWrapper = mutableAttributeData()->m_inlineStyle->cssStyleDeclaration(); + ASSERT(cssomWrapper && cssomWrapper->parentElement() == this); + return cssomWrapper; } -void StyledElement::parseAttribute(const Attribute& attribute) +inline void StyledElement::setInlineStyleFromString(const AtomicString& newStyleString) { - if (attribute.name() == styleAttr) - styleAttributeChanged(attribute.value()); + RefPtr<StylePropertySet>& inlineStyle = attributeData()->m_inlineStyle; + + // Avoid redundant work if we're using shared attribute data with already parsed inline style. + if (inlineStyle && !attributeData()->isMutable()) + return; + + // We reconstruct the property set instead of mutating if there is no CSSOM wrapper. + // This makes wrapperless property sets immutable and so cacheable. + if (inlineStyle && !inlineStyle->isMutable()) + inlineStyle.clear(); + + if (!inlineStyle) + inlineStyle = CSSParser::parseInlineStyleDeclaration(newStyleString, this); else - Element::parseAttribute(attribute); + inlineStyle->parseDeclaration(newStyleString, document()->elementSheet()->contents()); +} + +void StyledElement::styleAttributeChanged(const AtomicString& newStyleString) +{ + WTF::OrdinalNumber startLineNumber = WTF::OrdinalNumber::beforeFirst(); + if (document() && document()->scriptableDocumentParser() && !document()->isInDocumentWrite()) + startLineNumber = document()->scriptableDocumentParser()->lineNumber(); + + if (newStyleString.isNull()) { + if (PropertySetCSSStyleDeclaration* cssomWrapper = inlineStyleCSSOMWrapper()) + cssomWrapper->clearParentElement(); + mutableAttributeData()->m_inlineStyle.clear(); + } else if (document()->contentSecurityPolicy()->allowInlineStyle(document()->url(), startLineNumber)) + setInlineStyleFromString(newStyleString); + + attributeData()->m_styleAttributeIsDirty = false; + + setNeedsStyleRecalc(InlineStyleChange); + InspectorInstrumentation::didInvalidateStyleAttr(document(), this); } void StyledElement::inlineStyleChanged() { setNeedsStyleRecalc(InlineStyleChange); - setIsStyleAttributeValid(false); + ASSERT(attributeData()); + attributeData()->m_styleAttributeIsDirty = true; InspectorInstrumentation::didInvalidateStyleAttr(document(), this); } bool StyledElement::setInlineStyleProperty(CSSPropertyID propertyID, int identifier, bool important) { - ensureInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important); + ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier), important); inlineStyleChanged(); return true; } bool StyledElement::setInlineStyleProperty(CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit, bool important) { - ensureInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important); + ensureMutableInlineStyle()->setProperty(propertyID, cssValuePool().createValue(value, unit), important); inlineStyleChanged(); return true; } bool StyledElement::setInlineStyleProperty(CSSPropertyID propertyID, const String& value, bool important) { - bool changes = ensureInlineStyle()->setProperty(propertyID, value, important, document()->elementSheet()->contents()); + bool changes = ensureMutableInlineStyle()->setProperty(propertyID, value, important, document()->elementSheet()->contents()); if (changes) inlineStyleChanged(); return changes; @@ -213,9 +247,9 @@ bool StyledElement::setInlineStyleProperty(CSSPropertyID propertyID, const Strin bool StyledElement::removeInlineStyleProperty(CSSPropertyID propertyID) { - if (!attributeData() || !attributeData()->inlineStyle()) + if (!inlineStyle()) return false; - bool changes = ensureInlineStyle()->removeProperty(propertyID); + bool changes = ensureMutableInlineStyle()->removeProperty(propertyID); if (changes) inlineStyleChanged(); return changes; @@ -223,12 +257,9 @@ bool StyledElement::removeInlineStyleProperty(CSSPropertyID propertyID) void StyledElement::removeAllInlineStyleProperties() { - if (!attributeData() || !attributeData()->inlineStyle()) + if (!inlineStyle() || inlineStyle()->isEmpty()) return; - StylePropertySet* inlineStylePropertySet = ensureInlineStyle(); - if (inlineStylePropertySet->isEmpty()) - return; - inlineStylePropertySet->clear(); + ensureMutableInlineStyle()->clear(); inlineStyleChanged(); } @@ -281,7 +312,7 @@ static unsigned computePresentationAttributeCacheHash(const PresentationAttribut return WTF::pairIntHash(key.tagName->existingHash(), attributeHash); } -void StyledElement::updateAttributeStyle() +void StyledElement::rebuildPresentationAttributeStyle() { PresentationAttributeCacheKey cacheKey; makePresentationAttributeCacheKey(cacheKey); @@ -305,12 +336,15 @@ void StyledElement::updateAttributeStyle() unsigned size = attributeCount(); for (unsigned i = 0; i < size; ++i) { const Attribute* attribute = attributeItem(i); - collectStyleForAttribute(*attribute, style.get()); + collectStyleForPresentationAttribute(*attribute, style.get()); } } - clearAttributeStyleDirty(); - attributeData()->setAttributeStyle(style->isEmpty() ? 0 : style); + // ImmutableElementAttributeData doesn't store presentation attribute style, so make sure we have a MutableElementAttributeData. + ElementAttributeData* attributeData = mutableAttributeData(); + + attributeData->m_presentationAttributeStyleIsDirty = false; + attributeData->setPresentationAttributeStyle(style->isEmpty() ? 0 : style); if (!cacheHash || cacheIterator->value) return; @@ -328,17 +362,17 @@ void StyledElement::updateAttributeStyle() cacheIterator->value = newEntry.release(); } -void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, int identifier) +void StyledElement::addPropertyToPresentationAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, int identifier) { style->setProperty(propertyID, cssValuePool().createIdentifierValue(identifier)); } -void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit) +void StyledElement::addPropertyToPresentationAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, double value, CSSPrimitiveValue::UnitTypes unit) { style->setProperty(propertyID, cssValuePool().createValue(value, unit)); } -void StyledElement::addPropertyToAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, const String& value) +void StyledElement::addPropertyToPresentationAttributeStyle(StylePropertySet* style, CSSPropertyID propertyID, const String& value) { style->setProperty(propertyID, value, false, document()->elementSheet()->contents()); } |