| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "config.h" | 5 #include "config.h" |
| 6 #include "core/editing/iterators/FullyClippedStateStack.h" | 6 #include "core/editing/iterators/FullyClippedStateStack.h" |
| 7 | 7 |
| 8 #include "core/dom/ContainerNode.h" | 8 #include "core/dom/ContainerNode.h" |
| 9 #include "core/dom/Node.h" | 9 #include "core/dom/Node.h" |
| 10 #include "core/layout/LayoutBox.h" | 10 #include "core/layout/LayoutBox.h" |
| 11 #include "core/layout/LayoutObject.h" | 11 #include "core/layout/LayoutObject.h" |
| 12 | 12 |
| 13 namespace blink { | 13 namespace blink { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 inline bool fullyClipsContents(Node* node) | 17 inline bool fullyClipsContents(Node* node) |
| 18 { | 18 { |
| 19 LayoutObject* renderer = node->layoutObject(); | 19 LayoutObject* layoutObject = node->layoutObject(); |
| 20 if (!renderer || !renderer->isBox() || !renderer->hasOverflowClip()) | 20 if (!layoutObject || !layoutObject->isBox() || !layoutObject->hasOverflowCli
p()) |
| 21 return false; | 21 return false; |
| 22 return toLayoutBox(renderer)->size().isEmpty(); | 22 return toLayoutBox(layoutObject)->size().isEmpty(); |
| 23 } | 23 } |
| 24 | 24 |
| 25 inline bool ignoresContainerClip(Node* node) | 25 inline bool ignoresContainerClip(Node* node) |
| 26 { | 26 { |
| 27 LayoutObject* renderer = node->layoutObject(); | 27 LayoutObject* layoutObject = node->layoutObject(); |
| 28 if (!renderer || renderer->isText()) | 28 if (!layoutObject || layoutObject->isText()) |
| 29 return false; | 29 return false; |
| 30 return renderer->style()->hasOutOfFlowPosition(); | 30 return layoutObject->style()->hasOutOfFlowPosition(); |
| 31 } | 31 } |
| 32 | 32 |
| 33 template <typename Strategy> | 33 template <typename Strategy> |
| 34 unsigned depthCrossingShadowBoundaries(const Node& node) | 34 unsigned depthCrossingShadowBoundaries(const Node& node) |
| 35 { | 35 { |
| 36 unsigned depth = 0; | 36 unsigned depth = 0; |
| 37 for (ContainerNode* parent = Strategy::parentOrShadowHostNode(node); parent;
parent = Strategy::parentOrShadowHostNode(*parent)) | 37 for (ContainerNode* parent = Strategy::parentOrShadowHostNode(node); parent;
parent = Strategy::parentOrShadowHostNode(*parent)) |
| 38 ++depth; | 38 ++depth; |
| 39 return depth; | 39 return depth; |
| 40 } | 40 } |
| (...skipping 11 matching lines...) Expand all Loading... |
| 52 } | 52 } |
| 53 | 53 |
| 54 template<typename Strategy> | 54 template<typename Strategy> |
| 55 void FullyClippedStateStackAlgorithm<Strategy>::pushFullyClippedState(Node* node
) | 55 void FullyClippedStateStackAlgorithm<Strategy>::pushFullyClippedState(Node* node
) |
| 56 { | 56 { |
| 57 ASSERT(size() == depthCrossingShadowBoundaries<Strategy>(*node)); | 57 ASSERT(size() == depthCrossingShadowBoundaries<Strategy>(*node)); |
| 58 | 58 |
| 59 // FIXME: m_fullyClippedStack was added in response to <https://bugs.webkit.
org/show_bug.cgi?id=26364> | 59 // FIXME: m_fullyClippedStack was added in response to <https://bugs.webkit.
org/show_bug.cgi?id=26364> |
| 60 // ("Search can find text that's hidden by overflow:hidden"), but the logic
here will not work correctly if | 60 // ("Search can find text that's hidden by overflow:hidden"), but the logic
here will not work correctly if |
| 61 // a shadow tree redistributes nodes. m_fullyClippedStack relies on the assu
mption that DOM node hierarchy matches | 61 // a shadow tree redistributes nodes. m_fullyClippedStack relies on the assu
mption that DOM node hierarchy matches |
| 62 // the render tree, which is not necessarily true if there happens to be sha
dow DOM distribution or other mechanics | 62 // the layout tree, which is not necessarily true if there happens to be sha
dow DOM distribution or other mechanics |
| 63 // that shuffle around the render objects regardless of node tree hierarchy
(like CSS flexbox). | 63 // that shuffle around the layout objects regardless of node tree hierarchy
(like CSS flexbox). |
| 64 // | 64 // |
| 65 // A more appropriate way to handle this situation is to detect overflow:hid
den blocks by using only rendering | 65 // A more appropriate way to handle this situation is to detect overflow:hid
den blocks by using only layout |
| 66 // primitives, not with DOM primitives. | 66 // primitives, not with DOM primitives. |
| 67 | 67 |
| 68 // Push true if this node full clips its contents, or if a parent already ha
s fully | 68 // Push true if this node full clips its contents, or if a parent already ha
s fully |
| 69 // clipped and this is not a node that ignores its container's clip. | 69 // clipped and this is not a node that ignores its container's clip. |
| 70 push(fullyClipsContents(node) || (top() && !ignoresContainerClip(node))); | 70 push(fullyClipsContents(node) || (top() && !ignoresContainerClip(node))); |
| 71 } | 71 } |
| 72 | 72 |
| 73 template<typename Strategy> | 73 template<typename Strategy> |
| 74 void FullyClippedStateStackAlgorithm<Strategy>::setUpFullyClippedStack(Node* nod
e) | 74 void FullyClippedStateStackAlgorithm<Strategy>::setUpFullyClippedStack(Node* nod
e) |
| 75 { | 75 { |
| 76 // Put the nodes in a vector so we can iterate in reverse order. | 76 // Put the nodes in a vector so we can iterate in reverse order. |
| 77 WillBeHeapVector<RawPtrWillBeMember<ContainerNode>, 100> ancestry; | 77 WillBeHeapVector<RawPtrWillBeMember<ContainerNode>, 100> ancestry; |
| 78 for (ContainerNode* parent = Strategy::parentOrShadowHostNode(*node); parent
; parent = Strategy::parentOrShadowHostNode(*parent)) | 78 for (ContainerNode* parent = Strategy::parentOrShadowHostNode(*node); parent
; parent = Strategy::parentOrShadowHostNode(*parent)) |
| 79 ancestry.append(parent); | 79 ancestry.append(parent); |
| 80 | 80 |
| 81 // Call pushFullyClippedState on each node starting with the earliest ancest
or. | 81 // Call pushFullyClippedState on each node starting with the earliest ancest
or. |
| 82 size_t ancestrySize = ancestry.size(); | 82 size_t ancestrySize = ancestry.size(); |
| 83 for (size_t i = 0; i < ancestrySize; ++i) | 83 for (size_t i = 0; i < ancestrySize; ++i) |
| 84 pushFullyClippedState(ancestry[ancestrySize - i - 1]); | 84 pushFullyClippedState(ancestry[ancestrySize - i - 1]); |
| 85 pushFullyClippedState(node); | 85 pushFullyClippedState(node); |
| 86 | 86 |
| 87 ASSERT(size() == 1 + depthCrossingShadowBoundaries<Strategy>(*node)); | 87 ASSERT(size() == 1 + depthCrossingShadowBoundaries<Strategy>(*node)); |
| 88 } | 88 } |
| 89 | 89 |
| 90 template class FullyClippedStateStackAlgorithm<EditingStrategy>; | 90 template class FullyClippedStateStackAlgorithm<EditingStrategy>; |
| 91 template class FullyClippedStateStackAlgorithm<EditingInComposedTreeStrategy>; | 91 template class FullyClippedStateStackAlgorithm<EditingInComposedTreeStrategy>; |
| 92 | 92 |
| 93 } // namespace blink | 93 } // namespace blink |
| OLD | NEW |