Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1234)

Unified Diff: third_party/WebKit/Source/core/layout/LayoutCounter.cpp

Issue 1519123003: Implement Style Containment (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fix for shadow DOM Created 4 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: third_party/WebKit/Source/core/layout/LayoutCounter.cpp
diff --git a/third_party/WebKit/Source/core/layout/LayoutCounter.cpp b/third_party/WebKit/Source/core/layout/LayoutCounter.cpp
index 14a2c72c93c37bddc8ff09c57047d028387e4308..542a70ff669aaf7f9d21a57097770e60df841719 100644
--- a/third_party/WebKit/Source/core/layout/LayoutCounter.cpp
+++ b/third_party/WebKit/Source/core/layout/LayoutCounter.cpp
@@ -43,7 +43,7 @@ using namespace HTMLNames;
typedef HashMap<AtomicString, RefPtr<CounterNode>> CounterMap;
typedef HashMap<const LayoutObject*, OwnPtr<CounterMap>> CounterMaps;
-static CounterNode* makeCounterNode(LayoutObject&, const AtomicString& identifier, bool alwaysCreateCounter);
+static CounterNode* makeCounterNodeIfNeeded(LayoutObject&, const AtomicString& identifier, bool alwaysCreateCounter);
// See class definition as to why we have this map.
static CounterMaps& counterMaps()
@@ -52,21 +52,43 @@ static CounterMaps& counterMaps()
return staticCounterMaps;
}
+Element* ancestorStyleContainmentObject(const Element& element)
+{
+ for (Element* ancestor = FlatTreeTraversal::parentElement(element); ancestor; ancestor = FlatTreeTraversal::parentElement(*ancestor)) {
+ if (ancestor->layoutObject() && ancestor->layoutObject()->style()->containsStyle())
+ return ancestor;
+ }
+ return nullptr;
+}
+
// This function processes the layoutObject tree in the order of the DOM tree
-// including pseudo elements as defined in CSS 2.1.
-static LayoutObject* previousInPreOrder(const LayoutObject& object)
+// including pseudo elements as defined in CSS 2.1. This method will always return
+// either a previous object within the same contain: style scope or nullptr.
+static LayoutObject* previousInPreOrderRespectingContainment(const LayoutObject& object)
{
Element* self = toElement(object.node());
ASSERT(self);
Element* previous = ElementTraversal::previousIncludingPseudo(*self);
- while (previous && !previous->layoutObject())
- previous = ElementTraversal::previousIncludingPseudo(*previous);
- return previous ? previous->layoutObject() : 0;
+ Element* styleContainAncestor = ancestorStyleContainmentObject(*self);
+
+ while (1) {
+ while (previous && !previous->layoutObject())
+ previous = ElementTraversal::previousIncludingPseudo(*previous);
+ if (!previous)
+ return nullptr;
+ Element* previousStyleContainAncestor = ancestorStyleContainmentObject(*previous);
+ if (previousStyleContainAncestor == styleContainAncestor)
+ return previous->layoutObject();
+ if (!previousStyleContainAncestor)
+ return nullptr;
+ previous = previousStyleContainAncestor;
+ }
}
// This function processes the layoutObject tree in the order of the DOM tree
-// including pseudo elements as defined in CSS 2.1.
-static LayoutObject* previousSiblingOrParent(const LayoutObject& object)
+// including pseudo elements as defined in CSS 2.1. This method avoids crossing
+// contain: style boundaries.
+static LayoutObject* previousSiblingOrParentRespectingContainment(const LayoutObject& object)
{
Element* self = toElement(object.node());
ASSERT(self);
@@ -76,7 +98,7 @@ static LayoutObject* previousSiblingOrParent(const LayoutObject& object)
if (previous)
return previous->layoutObject();
previous = self->parentElement();
- return previous ? previous->layoutObject() : 0;
+ return previous && previous->layoutObject() && !(previous->layoutObject()->style()->contain() & ContainsStyle) ? previous->layoutObject() : nullptr;
}
static inline Element* parentElement(LayoutObject& object)
@@ -98,7 +120,7 @@ static LayoutObject* nextInPreOrder(const LayoutObject& object, const Element* s
Element* next = skipDescendants ? ElementTraversal::nextIncludingPseudoSkippingChildren(*self, stayWithin) : ElementTraversal::nextIncludingPseudo(*self, stayWithin);
while (next && !next->layoutObject())
next = skipDescendants ? ElementTraversal::nextIncludingPseudoSkippingChildren(*next, stayWithin) : ElementTraversal::nextIncludingPseudo(*next, stayWithin);
- return next ? next->layoutObject() : 0;
+ return next ? next->layoutObject() : nullptr;
}
static bool planCounter(LayoutObject& object, const AtomicString& identifier, bool& isReset, int& value)
@@ -182,16 +204,16 @@ static bool findPlaceForCounter(LayoutObject& counterOwner, const AtomicString&
{
// We cannot stop searching for counters with the same identifier before we also
// check this layoutObject, because it may affect the positioning in the tree of our counter.
- LayoutObject* searchEndLayoutObject = previousSiblingOrParent(counterOwner);
+ LayoutObject* searchEndLayoutObject = previousSiblingOrParentRespectingContainment(counterOwner);
// We check layoutObjects in preOrder from the layoutObject that our counter is attached to
// towards the beginning of the document for counters with the same identifier as the one
// we are trying to find a place for. This is the next layoutObject to be checked.
- LayoutObject* currentLayoutObject = previousInPreOrder(counterOwner);
+ LayoutObject* currentLayoutObject = previousInPreOrderRespectingContainment(counterOwner);
previousSibling = nullptr;
RefPtr<CounterNode> previousSiblingProtector = nullptr;
while (currentLayoutObject) {
- CounterNode* currentCounter = makeCounterNode(*currentLayoutObject, identifier, false);
+ CounterNode* currentCounter = makeCounterNodeIfNeeded(*currentLayoutObject, identifier, false);
if (searchEndLayoutObject == currentLayoutObject) {
// We may be at the end of our search.
if (currentCounter) {
@@ -204,7 +226,7 @@ static bool findPlaceForCounter(LayoutObject& counterOwner, const AtomicString&
// hence we are the next sibling of that counter if that reset is not a root or
// we are a root node if that reset is a root.
parent = currentCounter->parent();
- previousSibling = parent ? currentCounter : 0;
+ previousSibling = parent ? currentCounter : nullptr;
return parent;
}
// We are not a reset node or the previous reset must be on an ancestor of our owner layoutObject
@@ -257,7 +279,7 @@ static bool findPlaceForCounter(LayoutObject& counterOwner, const AtomicString&
// good counter, or we are a reset node and the counter on the previous sibling
// of our owner layoutObject was not a reset counter.
// Set a new goal for the end of the search.
- searchEndLayoutObject = previousSiblingOrParent(*currentLayoutObject);
+ searchEndLayoutObject = previousSiblingOrParentRespectingContainment(*currentLayoutObject);
} else {
// We are searching descendants of a previous sibling of the layoutObject that the
// counter being placed is attached to.
@@ -277,7 +299,7 @@ static bool findPlaceForCounter(LayoutObject& counterOwner, const AtomicString&
} else {
previousSiblingProtector = currentCounter;
}
- currentLayoutObject = previousSiblingOrParent(*currentLayoutObject);
+ currentLayoutObject = previousSiblingOrParentRespectingContainment(*currentLayoutObject);
continue;
}
}
@@ -286,14 +308,14 @@ static bool findPlaceForCounter(LayoutObject& counterOwner, const AtomicString&
// performance improvement would create more code duplication than is worthwhile in my opinion and may further
// impede the readability of this already complex algorithm.
if (previousSiblingProtector)
- currentLayoutObject = previousSiblingOrParent(*currentLayoutObject);
+ currentLayoutObject = previousSiblingOrParentRespectingContainment(*currentLayoutObject);
else
- currentLayoutObject = previousInPreOrder(*currentLayoutObject);
+ currentLayoutObject = previousInPreOrderRespectingContainment(*currentLayoutObject);
}
return false;
}
-static CounterNode* makeCounterNode(LayoutObject& object, const AtomicString& identifier, bool alwaysCreateCounter)
+static CounterNode* makeCounterNodeIfNeeded(LayoutObject& object, const AtomicString& identifier, bool alwaysCreateCounter)
{
if (object.hasCounterNodeMap()) {
if (CounterMap* nodeMap = counterMaps().get(&object)) {
@@ -383,7 +405,7 @@ PassRefPtr<StringImpl> LayoutCounter::originalText() const
break;
beforeAfterContainer = beforeAfterContainer->parent();
}
- makeCounterNode(*beforeAfterContainer, m_counter.identifier(), true)->addLayoutObject(const_cast<LayoutCounter*>(this));
+ makeCounterNodeIfNeeded(*beforeAfterContainer, m_counter.identifier(), true)->addLayoutObject(const_cast<LayoutCounter*>(this));
ASSERT(m_counterNode);
}
CounterNode* child = m_counterNode;
@@ -496,7 +518,7 @@ static void updateCounters(LayoutObject& layoutObject)
CounterDirectiveMap::const_iterator end = directiveMap->end();
if (!layoutObject.hasCounterNodeMap()) {
for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it)
- makeCounterNode(layoutObject, it->key, false);
+ makeCounterNodeIfNeeded(layoutObject, it->key, false);
return;
}
CounterMap* counterMap = counterMaps().get(&layoutObject);
@@ -504,7 +526,7 @@ static void updateCounters(LayoutObject& layoutObject)
for (CounterDirectiveMap::const_iterator it = directiveMap->begin(); it != end; ++it) {
RefPtr<CounterNode> node = counterMap->get(it->key);
if (!node) {
- makeCounterNode(layoutObject, it->key, false);
+ makeCounterNodeIfNeeded(layoutObject, it->key, false);
continue;
}
RefPtr<CounterNode> newParent = nullptr;
@@ -560,7 +582,7 @@ void LayoutCounter::layoutObjectStyleChanged(LayoutObject& layoutObject, const C
// We must create this node here, because the changed node may be a node with no display such as
// as those created by the increment or reset directives and the re-layout that will happen will
// not catch the change if the node had no children.
- makeCounterNode(layoutObject, it->key, false);
+ makeCounterNodeIfNeeded(layoutObject, it->key, false);
}
// Destroying old counters that do not exist in the new counterDirective map.
for (CounterDirectiveMap::const_iterator it = oldCounterDirectives->begin(); it !=oldMapEnd; ++it) {
@@ -579,7 +601,7 @@ void LayoutCounter::layoutObjectStyleChanged(LayoutObject& layoutObject, const C
// We must create this node here, because the added node may be a node with no display such as
// as those created by the increment or reset directives and the re-layout that will happen will
// not catch the change if the node had no children.
- makeCounterNode(layoutObject, it->key, false);
+ makeCounterNodeIfNeeded(layoutObject, it->key, false);
}
}
}

Powered by Google App Engine
This is Rietveld 408576698