summaryrefslogtreecommitdiff
path: root/Source/WebCore/dom/StyledElement.cpp
diff options
context:
space:
mode:
authorSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:09:45 +0100
committerSimon Hausmann <simon.hausmann@digia.com>2012-11-22 09:10:13 +0100
commit470286ecfe79d59df14944e5b5d34630fc739391 (patch)
tree43983212872e06cebefd2ae474418fa2908ca54c /Source/WebCore/dom/StyledElement.cpp
parent23037105e948c2065da5a937d3a2396b0ff45c1e (diff)
downloadqtwebkit-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.cpp126
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());
}