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

Side by Side Diff: third_party/WebKit/Source/core/dom/LayoutTreeBuilderTraversal.cpp

Issue 2450093005: Support display: contents for elements, first-line and first-letter pseudos. (Closed)
Patch Set: Support display: contents for elements, first-line and first-letter pseudos. Created 4 years, 1 month 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 unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Neither the name of Google Inc. nor the names of its 10 * * Neither the name of Google Inc. nor the names of its
(...skipping 17 matching lines...) Expand all
28 28
29 #include "core/HTMLNames.h" 29 #include "core/HTMLNames.h"
30 #include "core/dom/PseudoElement.h" 30 #include "core/dom/PseudoElement.h"
31 #include "core/dom/shadow/FlatTreeTraversal.h" 31 #include "core/dom/shadow/FlatTreeTraversal.h"
32 #include "core/layout/LayoutObject.h" 32 #include "core/layout/LayoutObject.h"
33 33
34 namespace blink { 34 namespace blink {
35 35
36 namespace LayoutTreeBuilderTraversal { 36 namespace LayoutTreeBuilderTraversal {
37 37
38 inline static bool hasDisplayContentsStyle(const Node& node) {
39 return node.isElementNode() && toElement(node).displayContentsStyle();
40 }
41
38 static bool isLayoutObjectReparented(const LayoutObject* layoutObject) { 42 static bool isLayoutObjectReparented(const LayoutObject* layoutObject) {
39 if (!layoutObject->node()->isElementNode()) 43 if (!layoutObject->node()->isElementNode())
40 return false; 44 return false;
41 if (toElement(layoutObject->node())->isInTopLayer()) 45 if (toElement(layoutObject->node())->isInTopLayer())
42 return true; 46 return true;
47
48 // NB: We intentionally ignore display:contents children here, since we aim to
49 // find them in the traversal.
rune 2016/11/08 13:09:20 I think you can just remove this comment. The repa
emilio 2016/11/08 15:43:01 Oh, ok, I see, will do.
50
43 return false; 51 return false;
44 } 52 }
45 53
46 void ParentDetails::didTraverseInsertionPoint( 54 void ParentDetails::didTraverseInsertionPoint(
47 const InsertionPoint* insertionPoint) { 55 const InsertionPoint* insertionPoint) {
48 if (!m_insertionPoint) { 56 if (!m_insertionPoint) {
49 m_insertionPoint = insertionPoint; 57 m_insertionPoint = insertionPoint;
50 } 58 }
51 } 59 }
52 60
53 inline static void assertPseudoElementParent( 61 inline static void assertPseudoElementParent(
54 const PseudoElement& pseudoElement) { 62 const PseudoElement& pseudoElement) {
55 DCHECK(pseudoElement.parentNode()); 63 DCHECK(pseudoElement.parentNode());
56 DCHECK(pseudoElement.parentNode()->canParticipateInFlatTree()); 64 DCHECK(pseudoElement.parentNode()->canParticipateInFlatTree());
57 } 65 }
58 66
59 ContainerNode* parent(const Node& node, ParentDetails* details) { 67 ContainerNode* parent(const Node& node, ParentDetails* details) {
60 // TODO(hayato): Uncomment this once we can be sure 68 // TODO(hayato): Uncomment this once we can be sure
61 // LayoutTreeBuilderTraversal::parent() is used only for a node which is 69 // LayoutTreeBuilderTraversal::parent() is used only for a node which is
62 // connected. 70 // connected.
63 // DCHECK(node.isConnected()); 71 // DCHECK(node.isConnected());
64 if (node.isPseudoElement()) { 72 if (node.isPseudoElement()) {
65 assertPseudoElementParent(toPseudoElement(node)); 73 assertPseudoElementParent(toPseudoElement(node));
66 return node.parentNode(); 74 return node.parentNode();
67 } 75 }
68 return FlatTreeTraversal::parent(node, details); 76 return FlatTreeTraversal::parent(node, details);
69 } 77 }
70 78
79 LayoutObject* parentLayoutObject(const Node& node) {
80 ContainerNode* parent = LayoutTreeBuilderTraversal::parent(node);
81
82 while (parent && hasDisplayContentsStyle(*parent)) {
83 parent = LayoutTreeBuilderTraversal::parent(*parent);
84 }
85
86 return parent ? parent->layoutObject() : nullptr;
87 }
88
71 Node* nextSibling(const Node& node) { 89 Node* nextSibling(const Node& node) {
72 if (node.isBeforePseudoElement()) { 90 if (node.isBeforePseudoElement()) {
73 assertPseudoElementParent(toPseudoElement(node)); 91 assertPseudoElementParent(toPseudoElement(node));
74 if (Node* next = FlatTreeTraversal::firstChild(*node.parentNode())) 92 if (Node* next = FlatTreeTraversal::firstChild(*node.parentNode()))
75 return next; 93 return next;
76 } else { 94 } else {
77 if (node.isAfterPseudoElement()) 95 if (node.isAfterPseudoElement())
78 return nullptr; 96 return nullptr;
79 if (Node* next = FlatTreeTraversal::nextSibling(node)) 97 if (Node* next = FlatTreeTraversal::nextSibling(node))
80 return next; 98 return next;
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
207 return nextNode; 225 return nextNode;
208 return nextAncestorSibling(node, stayWithin); 226 return nextAncestorSibling(node, stayWithin);
209 } 227 }
210 228
211 Node* next(const Node& node, const Node* stayWithin) { 229 Node* next(const Node& node, const Node* stayWithin) {
212 if (Node* child = pseudoAwareFirstChild(node)) 230 if (Node* child = pseudoAwareFirstChild(node))
213 return child; 231 return child;
214 return nextSkippingChildren(node, stayWithin); 232 return nextSkippingChildren(node, stayWithin);
215 } 233 }
216 234
235 static LayoutObject* nextSiblingLayoutObjectInternal(Node* node,
236 int32_t& limit) {
237 for (Node* sibling = node; sibling && limit-- != 0;
238 sibling = LayoutTreeBuilderTraversal::nextSibling(*sibling)) {
239 LayoutObject* layoutObject = sibling->layoutObject();
240
241 #if DCHECK_IS_ON()
242 if (hasDisplayContentsStyle(*sibling))
243 DCHECK(!layoutObject);
244 #endif
245
246 if (!layoutObject && hasDisplayContentsStyle(*sibling)) {
247 layoutObject = nextSiblingLayoutObjectInternal(
248 pseudoAwareFirstChild(*sibling), limit);
249 if (layoutObject)
250 return layoutObject;
251 if (!limit)
252 return nullptr;
253 }
254
255 if (layoutObject && !isLayoutObjectReparented(layoutObject))
256 return layoutObject;
257 }
258
259 return nullptr;
260 }
261
217 LayoutObject* nextSiblingLayoutObject(const Node& node, int32_t limit) { 262 LayoutObject* nextSiblingLayoutObject(const Node& node, int32_t limit) {
218 DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit; 263 DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit;
219 for (Node* sibling = LayoutTreeBuilderTraversal::nextSibling(node); 264 if (LayoutObject* foundLayoutObject = nextSiblingLayoutObjectInternal(
220 sibling && limit-- != 0; 265 LayoutTreeBuilderTraversal::nextSibling(node), limit))
221 sibling = LayoutTreeBuilderTraversal::nextSibling(*sibling)) { 266 return foundLayoutObject;
267
268 Node* maybeDisplayContentsParent = LayoutTreeBuilderTraversal::parent(node);
269 while (limit && maybeDisplayContentsParent &&
270 hasDisplayContentsStyle(*maybeDisplayContentsParent)) {
271 Node* displayContentsSibling =
272 LayoutTreeBuilderTraversal::nextSibling(*maybeDisplayContentsParent);
273 if (LayoutObject* siblingLayoutObject =
274 nextSiblingLayoutObjectInternal(displayContentsSibling, limit))
275 return siblingLayoutObject;
276 maybeDisplayContentsParent =
277 LayoutTreeBuilderTraversal::parent(*maybeDisplayContentsParent);
278 }
279
280 return nullptr;
281 }
282
283 static LayoutObject* previousSiblingLayoutObjectInternal(Node* node,
284 int32_t& limit) {
285 for (Node* sibling = node; sibling && limit-- != 0;
286 sibling = LayoutTreeBuilderTraversal::previousSibling(*sibling)) {
222 LayoutObject* layoutObject = sibling->layoutObject(); 287 LayoutObject* layoutObject = sibling->layoutObject();
288
289 #if DCHECK_IS_ON()
290 if (hasDisplayContentsStyle(*sibling))
291 DCHECK(!layoutObject);
292 #endif
293
294 if (!layoutObject && hasDisplayContentsStyle(*sibling)) {
295 layoutObject = nextSiblingLayoutObjectInternal(
296 pseudoAwareFirstChild(*sibling), limit);
297 if (layoutObject)
298 return layoutObject;
299 if (!limit)
300 return nullptr;
301 }
302
223 if (layoutObject && !isLayoutObjectReparented(layoutObject)) 303 if (layoutObject && !isLayoutObjectReparented(layoutObject))
224 return layoutObject; 304 return layoutObject;
225 } 305 }
226 return 0; 306
307 return nullptr;
227 } 308 }
228 309
229 LayoutObject* previousSiblingLayoutObject(const Node& node, int32_t limit) { 310 LayoutObject* previousSiblingLayoutObject(const Node& node, int32_t limit) {
230 DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit; 311 DCHECK(limit == kTraverseAllSiblings || limit >= 0) << limit;
231 for (Node* sibling = LayoutTreeBuilderTraversal::previousSibling(node); 312 if (LayoutObject* foundLayoutObject = previousSiblingLayoutObjectInternal(
232 sibling && limit-- != 0; 313 LayoutTreeBuilderTraversal::previousSibling(node), limit))
233 sibling = LayoutTreeBuilderTraversal::previousSibling(*sibling)) { 314 return foundLayoutObject;
234 LayoutObject* layoutObject = sibling->layoutObject(); 315
235 if (layoutObject && !isLayoutObjectReparented(layoutObject)) 316 Node* maybeDisplayContentsParent = LayoutTreeBuilderTraversal::parent(node);
236 return layoutObject; 317 while (limit && maybeDisplayContentsParent &&
318 hasDisplayContentsStyle(*maybeDisplayContentsParent)) {
319 Node* displayContentsSibling = LayoutTreeBuilderTraversal::previousSibling(
320 *maybeDisplayContentsParent);
321 if (LayoutObject* siblingLayoutObject =
322 previousSiblingLayoutObjectInternal(displayContentsSibling, limit))
323 return siblingLayoutObject;
324 maybeDisplayContentsParent =
325 LayoutTreeBuilderTraversal::parent(*maybeDisplayContentsParent);
237 } 326 }
238 return 0; 327
328 return nullptr;
239 } 329 }
240 330
241 LayoutObject* nextInTopLayer(const Element& element) { 331 LayoutObject* nextInTopLayer(const Element& element) {
242 if (!element.isInTopLayer()) 332 if (!element.isInTopLayer())
243 return 0; 333 return 0;
244 const HeapVector<Member<Element>>& topLayerElements = 334 const HeapVector<Member<Element>>& topLayerElements =
245 element.document().topLayerElements(); 335 element.document().topLayerElements();
246 size_t position = topLayerElements.find(&element); 336 size_t position = topLayerElements.find(&element);
247 DCHECK_NE(position, kNotFound); 337 DCHECK_NE(position, kNotFound);
248 for (size_t i = position + 1; i < topLayerElements.size(); ++i) { 338 for (size_t i = position + 1; i < topLayerElements.size(); ++i) {
249 if (LayoutObject* layoutObject = topLayerElements[i]->layoutObject()) 339 if (LayoutObject* layoutObject = topLayerElements[i]->layoutObject())
250 return layoutObject; 340 return layoutObject;
251 } 341 }
252 return 0; 342 return 0;
253 } 343 }
254 344
255 } // namespace LayoutTreeBuilderTraversal 345 } // namespace LayoutTreeBuilderTraversal
256 346
257 } // namespace blink 347 } // namespace blink
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698