Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |