Use a 1-byte enum class for TextDirection
[WebKit-https.git] / Source / WebCore / dom / ConstantPropertyMap.cpp
1 /*
2  * Copyright (C) 2017 Apple Inc. All Rights Reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions
6  * are met:
7  * 1. Redistributions of source code must retain the above copyright
8  *    notice, this list of conditions and the following disclaimer.
9  * 2. Redistributions in binary form must reproduce the above copyright
10  *    notice, this list of conditions and the following disclaimer in the
11  *    documentation and/or other materials provided with the distribution.
12  *
13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
17  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
24  *
25  */
26
27 #include "config.h"
28 #include "ConstantPropertyMap.h"
29
30 #include "CSSCustomPropertyValue.h"
31 #include "CSSParserTokenRange.h"
32 #include "CSSVariableData.h"
33 #include "Document.h"
34 #include "Page.h"
35 #include <wtf/NeverDestroyed.h>
36
37 namespace WebCore {
38
39 ConstantPropertyMap::ConstantPropertyMap(Document& document)
40     : m_document(document)
41 {
42 }
43
44 const ConstantPropertyMap::Values& ConstantPropertyMap::values() const
45 {
46     if (!m_values)
47         const_cast<ConstantPropertyMap&>(*this).buildValues();
48     return *m_values;
49 }
50
51 const AtomicString& ConstantPropertyMap::nameForProperty(ConstantProperty property) const
52 {
53     static NeverDestroyed<AtomicString> safeAreaInsetTopName("safe-area-inset-top", AtomicString::ConstructFromLiteral);
54     static NeverDestroyed<AtomicString> safeAreaInsetRightName("safe-area-inset-right", AtomicString::ConstructFromLiteral);
55     static NeverDestroyed<AtomicString> safeAreaInsetBottomName("safe-area-inset-bottom", AtomicString::ConstructFromLiteral);
56     static NeverDestroyed<AtomicString> safeAreaInsetLeftName("safe-area-inset-left", AtomicString::ConstructFromLiteral);
57     static NeverDestroyed<AtomicString> fullscreenInsetTopName("fullscreen-inset-top", AtomicString::ConstructFromLiteral);
58     static NeverDestroyed<AtomicString> fullscreenInsetLeftName("fullscreen-inset-left", AtomicString::ConstructFromLiteral);
59     static NeverDestroyed<AtomicString> fullscreenInsetBottomName("fullscreen-inset-bottom", AtomicString::ConstructFromLiteral);
60     static NeverDestroyed<AtomicString> fullscreenInsetRightName("fullscreen-inset-right", AtomicString::ConstructFromLiteral);
61     static NeverDestroyed<AtomicString> fullscreenAutoHideDurationName("fullscreen-auto-hide-duration", AtomicString::ConstructFromLiteral);
62
63     switch (property) {
64     case ConstantProperty::SafeAreaInsetTop:
65         return safeAreaInsetTopName;
66     case ConstantProperty::SafeAreaInsetRight:
67         return safeAreaInsetRightName;
68     case ConstantProperty::SafeAreaInsetBottom:
69         return safeAreaInsetBottomName;
70     case ConstantProperty::SafeAreaInsetLeft:
71         return safeAreaInsetLeftName;
72     case ConstantProperty::FullscreenInsetTop:
73         return fullscreenInsetTopName;
74     case ConstantProperty::FullscreenInsetLeft:
75         return fullscreenInsetLeftName;
76     case ConstantProperty::FullscreenInsetBottom:
77         return fullscreenInsetBottomName;
78     case ConstantProperty::FullscreenInsetRight:
79         return fullscreenInsetRightName;
80     case ConstantProperty::FullscreenAutoHideDuration:
81         return fullscreenAutoHideDurationName;
82     }
83
84     return nullAtom();
85 }
86
87 void ConstantPropertyMap::setValueForProperty(ConstantProperty property, Ref<CSSVariableData>&& data)
88 {
89     if (!m_values)
90         buildValues();
91
92     auto& name = nameForProperty(property);
93     m_values->set(name, CSSCustomPropertyValue::createWithVariableData(name, WTFMove(data)));
94 }
95
96 void ConstantPropertyMap::buildValues()
97 {
98     m_values = Values { };
99
100     updateConstantsForSafeAreaInsets();
101     updateConstantsForFullscreen();
102 }
103
104 static Ref<CSSVariableData> variableDataForPositivePixelLength(float lengthInPx)
105 {
106     ASSERT(lengthInPx >= 0);
107
108     CSSParserToken token(NumberToken, lengthInPx, NumberValueType, NoSign);
109     token.convertToDimensionWithUnit("px");
110
111     Vector<CSSParserToken> tokens { token };
112     CSSParserTokenRange tokenRange(tokens);
113     return CSSVariableData::create(tokenRange, false);
114 }
115
116 static Ref<CSSVariableData> variableDataForPositiveDuration(Seconds durationInSeconds)
117 {
118     ASSERT(durationInSeconds >= 0_s);
119
120     CSSParserToken token(NumberToken, durationInSeconds.value(), NumberValueType, NoSign);
121     token.convertToDimensionWithUnit("s");
122
123     Vector<CSSParserToken> tokens { token };
124     CSSParserTokenRange tokenRange(tokens);
125     return CSSVariableData::create(tokenRange, false);
126 }
127
128 void ConstantPropertyMap::updateConstantsForSafeAreaInsets()
129 {
130     FloatBoxExtent unobscuredSafeAreaInsets = m_document.page() ? m_document.page()->unobscuredSafeAreaInsets() : FloatBoxExtent();
131     setValueForProperty(ConstantProperty::SafeAreaInsetTop, variableDataForPositivePixelLength(unobscuredSafeAreaInsets.top()));
132     setValueForProperty(ConstantProperty::SafeAreaInsetRight, variableDataForPositivePixelLength(unobscuredSafeAreaInsets.right()));
133     setValueForProperty(ConstantProperty::SafeAreaInsetBottom, variableDataForPositivePixelLength(unobscuredSafeAreaInsets.bottom()));
134     setValueForProperty(ConstantProperty::SafeAreaInsetLeft, variableDataForPositivePixelLength(unobscuredSafeAreaInsets.left()));
135 }
136
137 void ConstantPropertyMap::didChangeSafeAreaInsets()
138 {
139     updateConstantsForSafeAreaInsets();
140     m_document.invalidateMatchedPropertiesCacheAndForceStyleRecalc();
141 }
142
143 void ConstantPropertyMap::updateConstantsForFullscreen()
144 {
145     FloatBoxExtent fullscreenInsets = m_document.page() ? m_document.page()->fullscreenInsets() : FloatBoxExtent();
146     setValueForProperty(ConstantProperty::FullscreenInsetTop, variableDataForPositivePixelLength(fullscreenInsets.top()));
147     setValueForProperty(ConstantProperty::FullscreenInsetRight, variableDataForPositivePixelLength(fullscreenInsets.right()));
148     setValueForProperty(ConstantProperty::FullscreenInsetBottom, variableDataForPositivePixelLength(fullscreenInsets.bottom()));
149     setValueForProperty(ConstantProperty::FullscreenInsetLeft, variableDataForPositivePixelLength(fullscreenInsets.left()));
150
151     Seconds fullscreenAutoHideDuration = m_document.page() ? m_document.page()->fullscreenAutoHideDuration() : 0_s;
152     setValueForProperty(ConstantProperty::FullscreenAutoHideDuration, variableDataForPositiveDuration(fullscreenAutoHideDuration));
153 }
154
155 void ConstantPropertyMap::didChangeFullscreenInsets()
156 {
157     updateConstantsForFullscreen();
158     m_document.invalidateMatchedPropertiesCacheAndForceStyleRecalc();
159 }
160
161 void ConstantPropertyMap::setFullscreenAutoHideDuration(Seconds duration)
162 {
163     setValueForProperty(ConstantProperty::FullscreenAutoHideDuration, variableDataForPositiveDuration(duration));
164     m_document.invalidateMatchedPropertiesCacheAndForceStyleRecalc();
165 }
166
167 }