Diff
Modified: trunk/Source/WebCore/ChangeLog (229306 => 229307)
--- trunk/Source/WebCore/ChangeLog 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/ChangeLog 2018-03-06 05:59:08 UTC (rev 229307)
@@ -1,3 +1,66 @@
+2018-03-05 Antti Koivisto <[email protected]>
+
+ Add ChildrenAffectedByForwardPositionalRules bit for nth-child pseudo class marking
+ https://bugs.webkit.org/show_bug.cgi?id=183341
+ <rdar://problem/38151470>
+
+ Reviewed by Zalan Bujtas.
+
+ Use it instead of AffectsNextSibling/AffectedByPreviousSibling bits, similar to ChildrenAffectedByBackwardPositionalRules bit.
+ This is more efficient and requires way less marking.
+
+ * css/SelectorChecker.cpp:
+ (WebCore::countElementsBefore):
+ (WebCore::countElementsOfTypeBefore):
+ (WebCore::SelectorChecker::checkOne const):
+
+ Mark with ChildrenAffectedByForwardPositionalRules.
+
+ * cssjit/SelectorCompiler.cpp:
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChild):
+ (WebCore::SelectorCompiler::SelectorCodeGenerator::generateElementIsNthChildOf):
+
+ Mark with ChildrenAffectedByForwardPositionalRules.
+
+ * dom/Element.cpp:
+ (WebCore::checkForSiblingStyleChanges):
+
+ Invalidate siblings after added/removed element.
+
+ (WebCore::Element::setChildrenAffectedByForwardPositionalRules):
+ (WebCore::Element::hasFlagsSetDuringStylingOfChildren const):
+ (WebCore::Element::rareDataChildrenAffectedByForwardPositionalRules const):
+
+ Add the new marking bit.
+
+ * dom/Element.h:
+ (WebCore::Element::childrenAffectedByForwardPositionalRules const):
+ (WebCore::Element::attributeWithoutSynchronization const):
+
+ Remove assert so we can use this to get the current unresolved lazy value of style attrbute.
+
+ * dom/ElementRareData.h:
+ (WebCore::ElementRareData::childrenAffectedByForwardPositionalRules const):
+ (WebCore::ElementRareData::setChildrenAffectedByForwardPositionalRules):
+ (WebCore::ElementRareData::ElementRareData):
+ (WebCore::ElementRareData::resetStyleRelations):
+
+ Add the new marking bit.
+
+ * dom/StyledElement.cpp:
+ (WebCore::StyledElement::invalidateStyleAttribute):
+
+ In special case where we have attribute selectors for style attribute, synchronize the attribute immediately so we get invalidation right.
+ Tested by fast/css/style-attribute-invalidation-propagates-to-counted-siblings.html
+
+ * style/StyleRelations.cpp:
+ (WebCore::Style::commitRelationsToRenderStyle):
+ (WebCore::Style::commitRelations):
+
+ Commit the new bit.
+
+ * style/StyleRelations.h:
+
2018-03-05 Ryan Haddad <[email protected]>
Unreviewed build fix, remove unused variables.
Modified: trunk/Source/WebCore/css/SelectorChecker.cpp (229306 => 229307)
--- trunk/Source/WebCore/css/SelectorChecker.cpp 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/css/SelectorChecker.cpp 2018-03-06 05:59:08 UTC (rev 229307)
@@ -123,13 +123,10 @@
return true;
}
-static inline int countElementsBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element)
+static inline int countElementsBefore(const Element& element)
{
int count = 0;
for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
-
- addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
unsigned index = sibling->childIndex();
if (index) {
count += index;
@@ -140,12 +137,10 @@
return count;
}
-static inline int countElementsOfTypeBefore(SelectorChecker::CheckingContext& checkingContext, const Element& element, const QualifiedName& type)
+static inline int countElementsOfTypeBefore(const Element& element, const QualifiedName& type)
{
int count = 0;
for (const Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
- addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
if (sibling->hasTagName(type))
++count;
}
@@ -837,7 +832,9 @@
case CSSSelector::PseudoClassNthChild:
if (!selector.parseNth())
break;
- if (element.parentElement()) {
+ if (auto* parentElement = element.parentElement()) {
+ addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
+
if (const CSSSelectorList* selectorList = selector.selectorList()) {
unsigned selectorListSpecificity;
if (!matchSelectorList(checkingContext, context, element, *selectorList, selectorListSpecificity))
@@ -845,19 +842,15 @@
specificity = CSSSelector::addSpecificities(specificity, selectorListSpecificity);
}
- addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
-
int count = 1;
if (const CSSSelectorList* selectorList = selector.selectorList()) {
for (Element* sibling = ElementTraversal::previousSibling(element); sibling; sibling = ElementTraversal::previousSibling(*sibling)) {
- addStyleRelation(checkingContext, *sibling, Style::Relation::AffectsNextSibling);
-
unsigned ignoredSpecificity;
if (matchSelectorList(checkingContext, context, *sibling, *selectorList, ignoredSpecificity))
++count;
}
} else {
- count += countElementsBefore(checkingContext, element);
+ count += countElementsBefore(element);
addStyleRelation(checkingContext, element, Style::Relation::NthChildIndex, count);
}
@@ -869,10 +862,10 @@
if (!selector.parseNth())
break;
- if (element.parentElement()) {
- addStyleRelation(checkingContext, element, Style::Relation::AffectedByPreviousSibling);
+ if (auto* parentElement = element.parentElement()) {
+ addStyleRelation(checkingContext, *parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
- int count = 1 + countElementsOfTypeBefore(checkingContext, element, element.tagQName());
+ int count = 1 + countElementsOfTypeBefore(element, element.tagQName());
if (selector.matchNth(count))
return true;
}
Modified: trunk/Source/WebCore/cssjit/SelectorCompiler.cpp (229306 => 229307)
--- trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/cssjit/SelectorCompiler.cpp 2018-03-06 05:59:08 UTC (rev 229307)
@@ -3490,6 +3490,7 @@
{
LocalRegister parentElement(m_registerAllocator);
generateWalkToParentElement(failureCases, parentElement);
+ generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
}
Vector<std::pair<int, int>, 32> validSubsetFilters;
@@ -3502,9 +3503,6 @@
if (validSubsetFilters.isEmpty())
return;
- if (!isAdjacentRelation(fragment.relationToRightFragment))
- generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
-
// Setup the counter at 1.
LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
m_assembler.move(Assembler::TrustedImm32(1), elementCounter);
@@ -3521,7 +3519,6 @@
Assembler::JumpList noCachedChildIndexCases;
generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
- generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
noCachedChildIndexCases.append(m_assembler.branchTest32(Assembler::Zero, Assembler::Address(previousSibling, Node::nodeFlagsMemoryOffset()), Assembler::TrustedImm32(Node::flagHasRareData())));
{
LocalRegister elementRareData(m_registerAllocator);
@@ -3537,7 +3534,6 @@
Assembler::Label loopStart = m_assembler.label();
generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
- generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
m_assembler.add32(Assembler::TrustedImm32(1), elementCounter);
m_assembler.jump().linkTo(loopStart, &m_assembler);
noMoreSiblingsCases.link(&m_assembler);
@@ -3554,6 +3550,7 @@
{
LocalRegister parentElement(m_registerAllocator);
generateWalkToParentElement(failureCases, parentElement);
+ generateAddStyleRelationIfResolvingStyle(parentElement, Style::Relation::ChildrenAffectedByForwardPositionalRules);
}
// The initial element must match the selector list.
@@ -3569,9 +3566,6 @@
if (validSubsetFilters.isEmpty())
return;
- if (!isAdjacentRelation(fragment.relationToRightFragment))
- generateAddStyleRelationIfResolvingStyle(elementAddressRegister, Style::Relation::AffectedByPreviousSibling);
-
for (const NthChildOfSelectorInfo* nthChildOfSelectorInfo : validSubsetFilters) {
// Setup the counter at 1.
LocalRegisterWithPreference elementCounter(m_registerAllocator, JSC::GPRInfo::argumentGPR1);
@@ -3587,7 +3581,6 @@
Assembler::Label loopStart = m_assembler.label();
generateWalkToPreviousAdjacentElement(noMoreSiblingsCases, previousSibling);
- generateAddStyleRelationIfResolvingStyle(previousSibling, Style::Relation::AffectsNextSibling);
Assembler::JumpList localFailureCases;
generateElementMatchesSelectorList(localFailureCases, previousSibling, nthChildOfSelectorInfo->selectorList);
Modified: trunk/Source/WebCore/dom/Element.cpp (229306 => 229307)
--- trunk/Source/WebCore/dom/Element.cpp 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/Element.cpp 2018-03-06 05:59:08 UTC (rev 229307)
@@ -2073,9 +2073,13 @@
}
}
- // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
// We have to invalidate everything following the insertion point in the forward case, and everything before the insertion point in the
// backward case.
+ if (parent.childrenAffectedByForwardPositionalRules()) {
+ for (auto* next = elementAfterChange; next; next = next->nextElementSibling())
+ next->invalidateStyleForSubtree();
+ }
+ // Backward positional selectors include nth-last-child, nth-last-of-type, last-of-type and only-of-type.
if (parent.childrenAffectedByBackwardPositionalRules()) {
for (auto* previous = elementBeforeChange; previous; previous = previous->previousElementSibling())
previous->invalidateStyleForSubtree();
@@ -2809,6 +2813,11 @@
ensureElementRareData().setChildrenAffectedByDrag(true);
}
+void Element::setChildrenAffectedByForwardPositionalRules()
+{
+ ensureElementRareData().setChildrenAffectedByForwardPositionalRules(true);
+}
+
void Element::setChildrenAffectedByBackwardPositionalRules()
{
ensureElementRareData().setChildrenAffectedByBackwardPositionalRules(true);
@@ -2834,6 +2843,7 @@
return false;
return rareDataStyleAffectedByActive()
|| rareDataChildrenAffectedByDrag()
+ || rareDataChildrenAffectedByForwardPositionalRules()
|| rareDataChildrenAffectedByBackwardPositionalRules()
|| rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules();
}
@@ -2862,6 +2872,12 @@
return elementRareData()->childrenAffectedByDrag();
}
+bool Element::rareDataChildrenAffectedByForwardPositionalRules() const
+{
+ ASSERT(hasRareData());
+ return elementRareData()->childrenAffectedByForwardPositionalRules();
+}
+
bool Element::rareDataChildrenAffectedByBackwardPositionalRules() const
{
ASSERT(hasRareData());
Modified: trunk/Source/WebCore/dom/Element.h (229306 => 229307)
--- trunk/Source/WebCore/dom/Element.h 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/Element.h 2018-03-06 05:59:08 UTC (rev 229307)
@@ -331,6 +331,7 @@
bool childrenAffectedByDrag() const { return hasRareData() && rareDataChildrenAffectedByDrag(); }
bool childrenAffectedByFirstChildRules() const { return getFlag(ChildrenAffectedByFirstChildRulesFlag); }
bool childrenAffectedByLastChildRules() const { return getFlag(ChildrenAffectedByLastChildRulesFlag); }
+ bool childrenAffectedByForwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByForwardPositionalRules(); }
bool childrenAffectedByBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByBackwardPositionalRules(); }
bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return hasRareData() && rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules(); }
bool affectsNextSiblingElementStyle() const { return getFlag(AffectsNextSiblingElementStyle); }
@@ -345,6 +346,7 @@
void setChildrenAffectedByDrag();
void setChildrenAffectedByFirstChildRules() { setFlag(ChildrenAffectedByFirstChildRulesFlag); }
void setChildrenAffectedByLastChildRules() { setFlag(ChildrenAffectedByLastChildRulesFlag); }
+ void setChildrenAffectedByForwardPositionalRules();
void setChildrenAffectedByBackwardPositionalRules();
void setChildrenAffectedByPropertyBasedBackwardPositionalRules();
void setAffectsNextSiblingElementStyle() { setFlag(AffectsNextSiblingElementStyle); }
@@ -648,6 +650,7 @@
bool rareDataStyleAffectedByActive() const;
bool rareDataChildrenAffectedByDrag() const;
bool rareDataChildrenAffectedByLastChildRules() const;
+ bool rareDataChildrenAffectedByForwardPositionalRules() const;
bool rareDataChildrenAffectedByBackwardPositionalRules() const;
bool rareDataChildrenAffectedByPropertyBasedBackwardPositionalRules() const;
unsigned rareDataChildIndex() const;
@@ -706,7 +709,6 @@
inline const AtomicString& Element::attributeWithoutSynchronization(const QualifiedName& name) const
{
- ASSERT(fastAttributeLookupAllowed(name));
if (elementData()) {
if (const Attribute* attribute = findAttributeByName(name))
return attribute->value();
Modified: trunk/Source/WebCore/dom/ElementRareData.h (229306 => 229307)
--- trunk/Source/WebCore/dom/ElementRareData.h 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/ElementRareData.h 2018-03-06 05:59:08 UTC (rev 229307)
@@ -70,6 +70,8 @@
bool childrenAffectedByLastChildRules() const { return m_childrenAffectedByLastChildRules; }
void setChildrenAffectedByLastChildRules(bool value) { m_childrenAffectedByLastChildRules = value; }
+ bool childrenAffectedByForwardPositionalRules() const { return m_childrenAffectedByForwardPositionalRules; }
+ void setChildrenAffectedByForwardPositionalRules(bool value) { m_childrenAffectedByForwardPositionalRules = value; }
bool childrenAffectedByBackwardPositionalRules() const { return m_childrenAffectedByBackwardPositionalRules; }
void setChildrenAffectedByBackwardPositionalRules(bool value) { m_childrenAffectedByBackwardPositionalRules = value; }
bool childrenAffectedByPropertyBasedBackwardPositionalRules() const { return m_childrenAffectedByPropertyBasedBackwardPositionalRules; }
@@ -128,6 +130,7 @@
// We optimize for :first-child and :last-child. The other positional child selectors like nth-child or
// *-child-of-type, we will just give up and re-evaluate whenever children change at all.
unsigned m_childrenAffectedByLastChildRules : 1;
+ unsigned m_childrenAffectedByForwardPositionalRules : 1;
unsigned m_childrenAffectedByBackwardPositionalRules : 1;
unsigned m_childrenAffectedByPropertyBasedBackwardPositionalRules : 1;
@@ -168,6 +171,7 @@
, m_childrenAffectedByHover(false)
, m_childrenAffectedByDrag(false)
, m_childrenAffectedByLastChildRules(false)
+ , m_childrenAffectedByForwardPositionalRules(false)
, m_childrenAffectedByBackwardPositionalRules(false)
, m_childrenAffectedByPropertyBasedBackwardPositionalRules(false)
, m_minimumSizeForResizing(defaultMinimumSizeForResizing())
@@ -206,6 +210,7 @@
setStyleAffectedByActive(false);
setChildrenAffectedByDrag(false);
setChildrenAffectedByLastChildRules(false);
+ setChildrenAffectedByForwardPositionalRules(false);
setChildrenAffectedByBackwardPositionalRules(false);
setChildrenAffectedByPropertyBasedBackwardPositionalRules(false);
}
Modified: trunk/Source/WebCore/dom/StyledElement.cpp (229306 => 229307)
--- trunk/Source/WebCore/dom/StyledElement.cpp 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/dom/StyledElement.cpp 2018-03-06 05:59:08 UTC (rev 229307)
@@ -24,6 +24,7 @@
#include "config.h"
#include "StyledElement.h"
+#include "AttributeChangeInvalidation.h"
#include "CSSImageValue.h"
#include "CSSParser.h"
#include "CSSStyleSheet.h"
@@ -145,6 +146,19 @@
InspectorInstrumentation::didInvalidateStyleAttr(document(), *this);
}
+static bool shouldSynchronizeStyleAttributeImmediatelyForInvalidation(StyledElement& element)
+{
+ // In rare case there is a complex attribute selector targeting style attribute (like "[style] ~ div") we need to synchronize immediately.
+ auto* ruleSets = element.styleResolver().ruleSets().attributeInvalidationRuleSets(styleAttr->localName());
+ if (!ruleSets)
+ return false;
+ for (auto& ruleSet : *ruleSets) {
+ if (ruleSet.matchElement != MatchElement::Subject)
+ return true;
+ }
+ return false;
+}
+
void StyledElement::invalidateStyleAttribute()
{
if (usesStyleBasedEditability(*inlineStyle()))
@@ -152,6 +166,15 @@
elementData()->setStyleAttributeIsDirty(true);
invalidateStyle();
+
+ if (shouldSynchronizeStyleAttributeImmediatelyForInvalidation(*this)) {
+ if (auto* inlineStyle = this->inlineStyle()) {
+ elementData()->setStyleAttributeIsDirty(false);
+ auto newValue = inlineStyle->asText();
+ Style::AttributeChangeInvalidation styleInvalidation(*this, styleAttr, attributeWithoutSynchronization(styleAttr), newValue);
+ setSynchronizedLazyAttribute(styleAttr, newValue);
+ }
+ }
}
void StyledElement::inlineStyleChanged()
Modified: trunk/Source/WebCore/style/StyleRelations.cpp (229306 => 229307)
--- trunk/Source/WebCore/style/StyleRelations.cpp 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/style/StyleRelations.cpp 2018-03-06 05:59:08 UTC (rev 229307)
@@ -76,6 +76,7 @@
case Relation::AffectedByFocusWithin:
case Relation::AffectedByPreviousSibling:
case Relation::AffectsNextSibling:
+ case Relation::ChildrenAffectedByForwardPositionalRules:
case Relation::ChildrenAffectedByBackwardPositionalRules:
case Relation::ChildrenAffectedByFirstChildRules:
case Relation::ChildrenAffectedByPropertyBasedBackwardPositionalRules:
@@ -119,6 +120,9 @@
sibling->setAffectsNextSiblingElementStyle();
break;
}
+ case Relation::ChildrenAffectedByForwardPositionalRules:
+ element.setChildrenAffectedByForwardPositionalRules();
+ break;
case Relation::ChildrenAffectedByBackwardPositionalRules:
element.setChildrenAffectedByBackwardPositionalRules();
break;
Modified: trunk/Source/WebCore/style/StyleRelations.h (229306 => 229307)
--- trunk/Source/WebCore/style/StyleRelations.h 2018-03-06 04:38:40 UTC (rev 229306)
+++ trunk/Source/WebCore/style/StyleRelations.h 2018-03-06 05:59:08 UTC (rev 229307)
@@ -46,6 +46,7 @@
AffectedByPreviousSibling,
// For AffectsNextSibling 'value' tells how many element siblings to mark starting with 'element'.
AffectsNextSibling,
+ ChildrenAffectedByForwardPositionalRules,
ChildrenAffectedByBackwardPositionalRules,
ChildrenAffectedByFirstChildRules,
ChildrenAffectedByPropertyBasedBackwardPositionalRules,