[GTK] Menu list button doesn't use the text color from the theme
[WebKit-https.git] / Source / WebCore / rendering / LogicalSelectionOffsetCaches.h
1 /*
2  * Copyright (C) 2013 Apple Inc. All rights reserved.
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Library General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Library General Public License for more details.
13  *
14  * You should have received a copy of the GNU Library General Public License
15  * along with this library; see the file COPYING.LIB.  If not, write to
16  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  *
19  */
20
21 #ifndef LogicalSelectionOffsetCaches_h
22 #define LogicalSelectionOffsetCaches_h
23
24 #include "RenderBlock.h"
25
26 namespace WebCore {
27
28 class LogicalSelectionOffsetCaches {
29 public:
30     class ContainingBlockInfo {
31     public:
32         ContainingBlockInfo()
33             : m_hasFloatsOrFlowThreads(false)
34             , m_cachedLogicalLeftSelectionOffset(false)
35             , m_cachedLogicalRightSelectionOffset(false)
36         { }
37
38         void setBlock(RenderBlock* block, const LogicalSelectionOffsetCaches* cache, bool parentCacheHasFloatsOrFlowThreads = false)
39         {
40             m_block = block;
41             m_hasFloatsOrFlowThreads = parentCacheHasFloatsOrFlowThreads || m_hasFloatsOrFlowThreads || m_block->containsFloats() || m_block->flowThreadContainingBlock();
42             m_cache = cache;
43             m_cachedLogicalLeftSelectionOffset = false;
44             m_cachedLogicalRightSelectionOffset = false;
45         }
46
47         LayoutUnit logicalLeftSelectionOffset(RenderBlock& rootBlock, LayoutUnit position) const
48         {
49             ASSERT(m_cache);
50             if (m_hasFloatsOrFlowThreads || !m_cachedLogicalLeftSelectionOffset) {
51                 m_cachedLogicalLeftSelectionOffset = true;
52                 m_logicalLeftSelectionOffset = m_block->logicalLeftSelectionOffset(rootBlock, position, *m_cache);
53             } else
54                 ASSERT(m_logicalLeftSelectionOffset == m_block->logicalLeftSelectionOffset(rootBlock, position, *m_cache));
55             return m_logicalLeftSelectionOffset;
56         }
57
58         LayoutUnit logicalRightSelectionOffset(RenderBlock& rootBlock, LayoutUnit position) const
59         {
60             ASSERT(m_cache);
61             if (m_hasFloatsOrFlowThreads || !m_cachedLogicalRightSelectionOffset) {
62                 m_cachedLogicalRightSelectionOffset = true;
63                 m_logicalRightSelectionOffset = m_block->logicalRightSelectionOffset(rootBlock, position, *m_cache);
64             } else
65                 ASSERT(m_logicalRightSelectionOffset == m_block->logicalRightSelectionOffset(rootBlock, position, *m_cache));
66             return m_logicalRightSelectionOffset;
67         }
68
69         RenderBlock* block() const { return m_block; }
70         const LogicalSelectionOffsetCaches* cache() const { return m_cache; }
71         bool hasFloatsOrFlowThreads() const { return m_hasFloatsOrFlowThreads; }
72
73     private:
74         RenderBlock* m_block { nullptr };
75         const LogicalSelectionOffsetCaches* m_cache { nullptr };
76         bool m_hasFloatsOrFlowThreads : 1;
77         mutable bool m_cachedLogicalLeftSelectionOffset : 1;
78         mutable bool m_cachedLogicalRightSelectionOffset : 1;
79         mutable LayoutUnit m_logicalLeftSelectionOffset;
80         mutable LayoutUnit m_logicalRightSelectionOffset;
81         
82     };
83
84     explicit LogicalSelectionOffsetCaches(RenderBlock& rootBlock)
85     {
86 #if ENABLE(TEXT_SELECTION)
87         // FIXME: We should either move this assertion to the caller (if applicable) or structure the code
88         // such that we can remove this assertion.
89         ASSERT(rootBlock.isSelectionRoot());
90 #endif
91         auto parent = rootBlock.parent();
92
93         // LogicalSelectionOffsetCaches should not be used on an orphaned tree.
94         m_containingBlockForFixedPosition.setBlock(containingBlockForFixedPosition(parent), nullptr);
95         m_containingBlockForAbsolutePosition.setBlock(containingBlockForAbsolutePosition(parent), nullptr);
96         m_containingBlockForInflowPosition.setBlock(containingBlockForObjectInFlow(parent), nullptr);
97     }
98
99     LogicalSelectionOffsetCaches(RenderBlock& block, const LogicalSelectionOffsetCaches& cache)
100         : m_containingBlockForFixedPosition(cache.m_containingBlockForFixedPosition)
101         , m_containingBlockForAbsolutePosition(cache.m_containingBlockForAbsolutePosition)
102     {
103         if (block.canContainFixedPositionObjects())
104             m_containingBlockForFixedPosition.setBlock(&block, &cache, cache.m_containingBlockForFixedPosition.hasFloatsOrFlowThreads());
105
106         if (block.canContainAbsolutelyPositionedObjects() && !block.isRenderInline() && !block.isAnonymousBlock())
107             m_containingBlockForAbsolutePosition.setBlock(&block, &cache, cache.m_containingBlockForAbsolutePosition.hasFloatsOrFlowThreads());
108
109         m_containingBlockForInflowPosition.setBlock(&block, &cache, cache.m_containingBlockForInflowPosition.hasFloatsOrFlowThreads());
110     }
111
112     const ContainingBlockInfo& containingBlockInfo(RenderBlock& block) const
113     {
114         EPosition position = block.style().position();
115         if (position == FixedPosition) {
116             ASSERT(block.containingBlock() == m_containingBlockForFixedPosition.block());
117             return m_containingBlockForFixedPosition;
118         }
119         if (position == AbsolutePosition) {
120             ASSERT(block.containingBlock() == m_containingBlockForAbsolutePosition.block());
121             return m_containingBlockForAbsolutePosition;
122         }
123         ASSERT(block.containingBlock() == m_containingBlockForInflowPosition.block());
124         return m_containingBlockForInflowPosition;
125     }
126
127 private:
128     ContainingBlockInfo m_containingBlockForFixedPosition;
129     ContainingBlockInfo m_containingBlockForAbsolutePosition;
130     ContainingBlockInfo m_containingBlockForInflowPosition;
131 };
132
133 } // namespace WebCore
134
135 #endif // LogicalSelectionOffsetCaches_h