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 |