diff options
| author | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-29 12:18:48 +0100 |
|---|---|---|
| committer | Simon Hausmann <simon.hausmann@digia.com> | 2012-11-29 12:18:57 +0100 |
| commit | 4c01d0526ba4dd8cff0c0ff22a6f0ab5eb973064 (patch) | |
| tree | bed2fe914fe0f7ec70abfb47d2d84af8a3604d09 /Source/WebCore/dom/Element.cpp | |
| parent | 01485457c9a5da3f1121015afd25bb53af77662e (diff) | |
| download | qtwebkit-4c01d0526ba4dd8cff0c0ff22a6f0ab5eb973064.tar.gz | |
Imported WebKit commit c60cfe0fc09efd257aa0111d7b133b02deb8a63e (http://svn.webkit.org/repository/webkit/trunk@136119)
New snapshot that includes the fix for installing the QtWebProcess into libexec
Change-Id: I01344e079cbdac5678c4cba6ffcc05f4597cf0d7
Reviewed-by: Simon Hausmann <simon.hausmann@digia.com>
Diffstat (limited to 'Source/WebCore/dom/Element.cpp')
| -rw-r--r-- | Source/WebCore/dom/Element.cpp | 325 |
1 files changed, 176 insertions, 149 deletions
diff --git a/Source/WebCore/dom/Element.cpp b/Source/WebCore/dom/Element.cpp index a4f7d72af..b7d0e5993 100644 --- a/Source/WebCore/dom/Element.cpp +++ b/Source/WebCore/dom/Element.cpp @@ -305,18 +305,19 @@ bool Element::hasAttribute(const QualifiedName& name) const const AtomicString& Element::getAttribute(const QualifiedName& name) const { - if (UNLIKELY(name == styleAttr) && attributeData() && attributeData()->m_styleAttributeIsDirty) + if (!attributeData()) + return nullAtom; + + if (UNLIKELY(name == styleAttr && attributeData()->m_styleAttributeIsDirty)) updateStyleAttribute(); #if ENABLE(SVG) - if (UNLIKELY(!areSVGAttributesValid())) + if (UNLIKELY(attributeData()->m_animatedSVGAttributesAreDirty)) updateAnimatedSVGAttribute(name); #endif - if (attributeData()) { - if (const Attribute* attribute = getAttributeItem(name)) - return attribute->value(); - } + if (const Attribute* attribute = getAttributeItem(name)) + return attribute->value(); return nullAtom; } @@ -660,24 +661,24 @@ static inline bool shouldIgnoreAttributeCase(const Element* e) const AtomicString& Element::getAttribute(const AtomicString& name) const { + if (!attributeData()) + return nullAtom; + bool ignoreCase = shouldIgnoreAttributeCase(this); // Update the 'style' attribute if it's invalid and being requested: - if (attributeData() && attributeData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase)) + if (attributeData()->m_styleAttributeIsDirty && equalPossiblyIgnoringCase(name, styleAttr.localName(), ignoreCase)) updateStyleAttribute(); #if ENABLE(SVG) - if (!areSVGAttributesValid()) { + if (attributeData()->m_animatedSVGAttributesAreDirty) { // We're not passing a namespace argument on purpose. SVGNames::*Attr are defined w/o namespaces as well. updateAnimatedSVGAttribute(QualifiedName(nullAtom, name, nullAtom)); } #endif - if (attributeData()) { - if (const Attribute* attribute = attributeData()->getAttributeItem(name, ignoreCase)) - return attribute->value(); - } - + if (const Attribute* attribute = attributeData()->getAttributeItem(name, ignoreCase)) + return attribute->value(); return nullAtom; } @@ -824,49 +825,23 @@ static inline bool classStringHasClassName(const AtomicString& newClassString) return classStringHasClassName(newClassString.characters16(), length); } -struct HasSelectorForClassStyleFunctor { - explicit HasSelectorForClassStyleFunctor(StyleResolver* resolver) - : styleResolver(resolver) - { } - - bool operator()(const AtomicString& className) const - { - return styleResolver->hasSelectorForClass(className); - } - - StyleResolver* styleResolver; -}; - -struct HasSelectorForClassDistributionFunctor { - explicit HasSelectorForClassDistributionFunctor(ElementShadow* elementShadow) - : elementShadow(elementShadow) - { } - - bool operator()(const AtomicString& className) const - { - return elementShadow->selectRuleFeatureSet().hasSelectorForClass(className); - } - - ElementShadow* elementShadow; -}; - -template<typename Functor> -static bool checkFunctorForClassChange(const SpaceSplitString& changedClasses, Functor functor) +template<typename Checker> +static bool checkSelectorForClassChange(const SpaceSplitString& changedClasses, const Checker& checker) { unsigned changedSize = changedClasses.size(); for (unsigned i = 0; i < changedSize; ++i) { - if (functor(changedClasses[i])) + if (checker.hasSelectorForClass(changedClasses[i])) return true; } return false; } -template<typename Functor> -static bool checkFunctorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, Functor functor) +template<typename Checker> +static bool checkSelectorForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, const Checker& checker) { unsigned oldSize = oldClasses.size(); if (!oldSize) - return checkFunctorForClassChange(newClasses, functor); + return checkSelectorForClassChange(newClasses, checker); BitVector remainingClassBits; remainingClassBits.ensureSize(oldSize); // Class vectors tend to be very short. This is faster than using a hash table. @@ -878,39 +853,19 @@ static bool checkFunctorForClassChange(const SpaceSplitString& oldClasses, const continue; } } - if (functor(newClasses[i])) + if (checker.hasSelectorForClass(newClasses[i])) return true; } for (unsigned i = 0; i < oldSize; ++i) { // If the bit is not set the the corresponding class has been removed. if (remainingClassBits.quickGet(i)) continue; - if (functor(oldClasses[i])) + if (checker.hasSelectorForClass(oldClasses[i])) return true; } return false; } -static inline bool checkNeedsStyleInvalidationForClassChange(const SpaceSplitString& changedClasses, StyleResolver* styleResolver) -{ - return checkFunctorForClassChange(changedClasses, HasSelectorForClassStyleFunctor(styleResolver)); -} - -static inline bool checkNeedsStyleInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, StyleResolver* styleResolver) -{ - return checkFunctorForClassChange(oldClasses, newClasses, HasSelectorForClassStyleFunctor(styleResolver)); -} - -static inline bool checkNeedsDistributionInvalidationForClassChange(const SpaceSplitString& changedClasses, ElementShadow* elementShadow) -{ - return checkFunctorForClassChange(changedClasses, HasSelectorForClassDistributionFunctor(elementShadow)); -} - -static inline bool checkNeedsDistributionInvalidationForClassChange(const SpaceSplitString& oldClasses, const SpaceSplitString& newClasses, ElementShadow* elementShadow) -{ - return checkFunctorForClassChange(oldClasses, newClasses, HasSelectorForClassDistributionFunctor(elementShadow)); -} - void Element::classAttributeChanged(const AtomicString& newClassString) { StyleResolver* styleResolver = document()->styleResolverIfExists(); @@ -925,10 +880,10 @@ void Element::classAttributeChanged(const AtomicString& newClassString) attributeData->setClass(newClassString, shouldFoldCase); const SpaceSplitString& newClasses = attributeData->classNames(); - shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForClassChange(oldClasses, newClasses, styleResolver); + shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, newClasses, *styleResolver); } else if (const ElementAttributeData* attributeData = this->attributeData()) { const SpaceSplitString& oldClasses = attributeData->classNames(); - shouldInvalidateStyle = testShouldInvalidateStyle && checkNeedsStyleInvalidationForClassChange(oldClasses, styleResolver); + shouldInvalidateStyle = testShouldInvalidateStyle && checkSelectorForClassChange(oldClasses, *styleResolver); attributeData->clearClass(); } @@ -963,11 +918,11 @@ bool Element::shouldInvalidateDistributionWhenAttributeChanged(ElementShadow* el const bool shouldFoldCase = document()->inQuirksMode(); const SpaceSplitString& oldClasses = attributeData->classNames(); const SpaceSplitString newClasses(newClassString, shouldFoldCase); - if (checkNeedsDistributionInvalidationForClassChange(oldClasses, newClasses, elementShadow)) + if (checkSelectorForClassChange(oldClasses, newClasses, elementShadow->selectRuleFeatureSet())) return true; } else if (const ElementAttributeData* attributeData = this->attributeData()) { const SpaceSplitString& oldClasses = attributeData->classNames(); - if (checkNeedsDistributionInvalidationForClassChange(oldClasses, elementShadow)) + if (checkSelectorForClassChange(oldClasses, elementShadow->selectRuleFeatureSet())) return true; } } @@ -1197,34 +1152,34 @@ void Element::createRendererIfNeeded() void Element::attach() { suspendPostAttachCallbacks(); - WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; - - createRendererIfNeeded(); + { + WidgetHierarchyUpdatesSuspensionScope suspendWidgetHierarchyUpdates; + createRendererIfNeeded(); - StyleResolverParentPusher parentPusher(this); + StyleResolverParentPusher parentPusher(this); - if (parentElement() && parentElement()->isInCanvasSubtree()) - setIsInCanvasSubtree(true); + if (parentElement() && parentElement()->isInCanvasSubtree()) + setIsInCanvasSubtree(true); - // When a shadow root exists, it does the work of attaching the children. - if (ElementShadow* shadow = this->shadow()) { - parentPusher.push(); - shadow->attach(); - } else { - if (firstChild()) + // When a shadow root exists, it does the work of attaching the children. + if (ElementShadow* shadow = this->shadow()) { parentPusher.push(); - } - ContainerNode::attach(); + shadow->attach(); + } else { + if (firstChild()) + parentPusher.push(); + } + ContainerNode::attach(); - if (hasRareData()) { - ElementRareData* data = elementRareData(); - if (data->needsFocusAppearanceUpdateSoonAfterAttach()) { - if (isFocusable() && document()->focusedNode() == this) - document()->updateFocusAppearanceSoon(false /* don't restore selection */); - data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false); + if (hasRareData()) { + ElementRareData* data = elementRareData(); + if (data->needsFocusAppearanceUpdateSoonAfterAttach()) { + if (isFocusable() && document()->focusedNode() == this) + document()->updateFocusAppearanceSoon(false /* don't restore selection */); + data->setNeedsFocusAppearanceUpdateSoonAfterAttach(false); + } } } - resumePostAttachCallbacks(); } @@ -1243,6 +1198,7 @@ void Element::detach() ElementRareData* data = elementRareData(); data->setIsInCanvasSubtree(false); data->resetComputedStyle(); + data->resetDynamicRestyleObservations(); } if (ElementShadow* shadow = this->shadow()) { @@ -1310,15 +1266,12 @@ void Element::recalcStyle(StyleChange change) // Ref currentStyle in case it would otherwise be deleted when setting the new style in the renderer. RefPtr<RenderStyle> currentStyle(renderStyle()); bool hasParentStyle = parentNodeForRenderingAndStyle() ? static_cast<bool>(parentNodeForRenderingAndStyle()->renderStyle()) : false; - bool hasDirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByDirectAdjacentRules(); - bool hasIndirectAdjacentRules = currentStyle && currentStyle->childrenAffectedByForwardPositionalRules(); + bool hasDirectAdjacentRules = childrenAffectedByDirectAdjacentRules(); + bool hasIndirectAdjacentRules = childrenAffectedByForwardPositionalRules(); if ((change > NoChange || needsStyleRecalc())) { - if (hasRareData()) { - ElementRareData* data = elementRareData(); - data->resetComputedStyle(); - data->setStyleAffectedByEmpty(false); - } + if (hasRareData()) + elementRareData()->resetComputedStyle(); } if (hasParentStyle && (change >= Inherit || needsStyleRecalc())) { RefPtr<RenderStyle> newStyle = styleForRenderer(); @@ -1335,27 +1288,6 @@ void Element::recalcStyle(StyleChange change) return; } - if (currentStyle) { - // Preserve "affected by" bits that were propagated to us from descendants in the case where we didn't do a full - // style change (e.g., only inline style changed). - if (currentStyle->affectedByHoverRules()) - newStyle->setAffectedByHoverRules(true); - if (currentStyle->affectedByActiveRules()) - newStyle->setAffectedByActiveRules(true); - if (currentStyle->affectedByDragRules()) - newStyle->setAffectedByDragRules(true); - if (currentStyle->childrenAffectedByForwardPositionalRules()) - newStyle->setChildrenAffectedByForwardPositionalRules(); - if (currentStyle->childrenAffectedByBackwardPositionalRules()) - newStyle->setChildrenAffectedByBackwardPositionalRules(); - if (currentStyle->childrenAffectedByFirstChildRules()) - newStyle->setChildrenAffectedByFirstChildRules(); - if (currentStyle->childrenAffectedByLastChildRules()) - newStyle->setChildrenAffectedByLastChildRules(); - if (currentStyle->childrenAffectedByDirectAdjacentRules()) - newStyle->setChildrenAffectedByDirectAdjacentRules(); - } - if (RenderObject* renderer = this->renderer()) { if (ch != NoChange || pseudoStyleCacheIsInvalid(currentStyle.get(), newStyle.get()) || (change == Force && renderer->requiresForcedStyleRecalcPropagation()) || styleChangeType() == SyntheticStyleChange) renderer->setAnimatableStyle(newStyle.get()); @@ -1483,7 +1415,7 @@ static void checkForEmptyStyleChange(Element* element, RenderStyle* style) if (!style && !element->styleAffectedByEmpty()) return; - if (!style || (style->affectedByEmpty() && (!style->emptyState() || element->hasChildNodes()))) + if (!style || (element->styleAffectedByEmpty() && (!style->emptyState() || element->hasChildNodes()))) element->setNeedsStyleRecalc(); } @@ -1493,13 +1425,13 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin // :empty selector. checkForEmptyStyleChange(e, style); - if (!style || (e->needsStyleRecalc() && style->childrenAffectedByPositionalRules())) + if (!style || (e->needsStyleRecalc() && e->childrenAffectedByPositionalRules())) return; // :first-child. In the parser callback case, we don't have to check anything, since we were right the first time. // In the DOM case, we only need to do something if |afterChange| is not 0. // |afterChange| is 0 in the parser case, so it works out that we'll skip this block. - if (style->childrenAffectedByFirstChildRules() && afterChange) { + if (e->childrenAffectedByFirstChildRules() && afterChange) { // Find our new first child. Node* newFirstChild = 0; for (newFirstChild = e->firstChild(); newFirstChild && !newFirstChild->isElementNode(); newFirstChild = newFirstChild->nextSibling()) {}; @@ -1522,7 +1454,7 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin // :last-child. In the parser callback case, we don't have to check anything, since we were right the first time. // In the DOM case, we only need to do something if |afterChange| is not 0. - if (style->childrenAffectedByLastChildRules() && beforeChange) { + if (e->childrenAffectedByLastChildRules() && beforeChange) { // Find our new last child. Node* newLastChild = 0; for (newLastChild = e->lastChild(); newLastChild && !newLastChild->isElementNode(); newLastChild = newLastChild->previousSibling()) {}; @@ -1545,7 +1477,7 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin // The + selector. We need to invalidate the first element following the insertion point. It is the only possible element // that could be affected by this DOM change. - if (style->childrenAffectedByDirectAdjacentRules() && afterChange) { + if (e->childrenAffectedByDirectAdjacentRules() && afterChange) { Node* firstElementAfterInsertion = 0; for (firstElementAfterInsertion = afterChange; firstElementAfterInsertion && !firstElementAfterInsertion->isElementNode(); @@ -1561,8 +1493,8 @@ static void checkForSiblingStyleChanges(Element* e, RenderStyle* style, bool fin // |afterChange| is 0 in the parser callback case, so we won't do any work for the forward case if we don't have to. // For performance reasons we just mark the parent node as changed, since we don't want to make childrenChanged O(n^2) by crawling all our kids // here. recalcStyle will then force a walk of the children when it sees that this has happened. - if ((style->childrenAffectedByForwardPositionalRules() && afterChange) || - (style->childrenAffectedByBackwardPositionalRules() && beforeChange)) + if ((e->childrenAffectedByForwardPositionalRules() && afterChange) + || (e->childrenAffectedByBackwardPositionalRules() && beforeChange)) e->setNeedsStyleRecalc(); } @@ -1969,9 +1901,115 @@ void Element::setStyleAffectedByEmpty() ensureElementRareData()->setStyleAffectedByEmpty(true); } -bool Element::styleAffectedByEmpty() const +void Element::setChildrenAffectedByHover(bool value) +{ + if (value || hasRareData()) + ensureElementRareData()->setChildrenAffectedByHover(value); +} + +void Element::setChildrenAffectedByActive(bool value) +{ + if (value || hasRareData()) + ensureElementRareData()->setChildrenAffectedByActive(value); +} + +void Element::setChildrenAffectedByDrag(bool value) +{ + if (value || hasRareData()) + ensureElementRareData()->setChildrenAffectedByDrag(value); +} + +void Element::setChildrenAffectedByFirstChildRules() +{ + ensureElementRareData()->setChildrenAffectedByFirstChildRules(true); +} + +void Element::setChildrenAffectedByLastChildRules() +{ + ensureElementRareData()->setChildrenAffectedByLastChildRules(true); +} + +void Element::setChildrenAffectedByDirectAdjacentRules() +{ + ensureElementRareData()->setChildrenAffectedByDirectAdjacentRules(true); +} + +void Element::setChildrenAffectedByForwardPositionalRules() +{ + ensureElementRareData()->setChildrenAffectedByForwardPositionalRules(true); +} + +void Element::setChildrenAffectedByBackwardPositionalRules() +{ + ensureElementRareData()->setChildrenAffectedByBackwardPositionalRules(true); +} + +void Element::setChildIndex(unsigned index) +{ + ElementRareData* rareData = ensureElementRareData(); + if (RenderStyle* style = renderStyle()) + style->setUnique(); + rareData->setChildIndex(index); +} + +bool Element::rareDataStyleAffectedByEmpty() const +{ + ASSERT(hasRareData()); + return elementRareData()->styleAffectedByEmpty(); +} + +bool Element::rareDataChildrenAffectedByHover() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByHover(); +} + +bool Element::rareDataChildrenAffectedByActive() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByActive(); +} + +bool Element::rareDataChildrenAffectedByDrag() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByDrag(); +} + +bool Element::rareDataChildrenAffectedByFirstChildRules() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByFirstChildRules(); +} + +bool Element::rareDataChildrenAffectedByLastChildRules() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByLastChildRules(); +} + +bool Element::rareDataChildrenAffectedByDirectAdjacentRules() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByDirectAdjacentRules(); +} + +bool Element::rareDataChildrenAffectedByForwardPositionalRules() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByForwardPositionalRules(); +} + +bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const +{ + ASSERT(hasRareData()); + return elementRareData()->childrenAffectedByBackwardPositionalRules(); +} + +unsigned Element::rareDataChildIndex() const { - return hasRareData() && elementRareData()->styleAffectedByEmpty(); + ASSERT(hasRareData()); + return elementRareData()->childIndex(); } void Element::setIsInCanvasSubtree(bool isInCanvasSubtree) @@ -2430,41 +2468,30 @@ void Element::updateExtraNamedItemRegistration(const AtomicString& oldId, const PassRefPtr<HTMLCollection> Element::ensureCachedHTMLCollection(CollectionType type) { - return ensureElementRareData()->ensureCachedHTMLCollection(this, type); -} - -PassRefPtr<HTMLCollection> ElementRareData::ensureCachedHTMLCollection(Element* element, CollectionType type) -{ if (HTMLCollection* collection = cachedHTMLCollection(type)) return collection; RefPtr<HTMLCollection> collection; if (type == TableRows) { - ASSERT(element->hasTagName(tableTag)); - return ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(element, type); + ASSERT(hasTagName(tableTag)); + return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLTableRowsCollection>(this, type); } else if (type == SelectOptions) { - ASSERT(element->hasTagName(selectTag)); - return ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(element, type); + ASSERT(hasTagName(selectTag)); + return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLOptionsCollection>(this, type); } else if (type == FormControls) { - ASSERT(element->hasTagName(formTag) || element->hasTagName(fieldsetTag)); - return ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(element, type); + ASSERT(hasTagName(formTag) || hasTagName(fieldsetTag)); + return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLFormControlsCollection>(this, type); #if ENABLE(MICRODATA) } else if (type == ItemProperties) { - return ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(element, type); + return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLPropertiesCollection>(this, type); #endif } - return ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(element, type); + return ensureRareData()->ensureNodeLists()->addCacheWithAtomicName<HTMLCollection>(this, type); } HTMLCollection* Element::cachedHTMLCollection(CollectionType type) { - return hasRareData() ? elementRareData()->cachedHTMLCollection(type) : 0; -} - -void Element::removeCachedHTMLCollection(HTMLCollection* collection, CollectionType type) -{ - ASSERT(hasRareData()); - elementRareData()->removeCachedHTMLCollection(collection, type); + return hasRareData() && rareData()->nodeLists() ? rareData()->nodeLists()->cacheWithAtomicName<HTMLCollection>(type) : 0; } IntSize Element::savedLayerScrollOffset() const |
