OLD | NEW |
---|---|
1 /* | 1 /* |
2 * CSS Media Query | 2 * CSS Media Query |
3 * | 3 * |
4 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>. | 4 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>. |
5 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). | 5 * Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). |
6 * Copyright (C) 2013 Apple Inc. All rights reserved. | 6 * Copyright (C) 2013 Apple Inc. All rights reserved. |
7 * | 7 * |
8 * Redistribution and use in source and binary forms, with or without | 8 * Redistribution and use in source and binary forms, with or without |
9 * modification, are permitted provided that the following conditions | 9 * modification, are permitted provided that the following conditions |
10 * are met: | 10 * are met: |
(...skipping 13 matching lines...) Expand all Loading... | |
24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY | 24 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 25 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 26 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 27 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
28 */ | 28 */ |
29 | 29 |
30 #include "config.h" | 30 #include "config.h" |
31 #include "core/css/MediaQueryExp.h" | 31 #include "core/css/MediaQueryExp.h" |
32 | 32 |
33 #include "core/css/CSSPrimitiveValue.h" | 33 #include "core/css/CSSPrimitiveValue.h" |
34 #include "core/css/parser/CSSParserValues.h" | 34 #include "core/css/parser/CSSParserToken.h" |
35 #include "core/html/parser/HTMLParserIdioms.h" | 35 #include "core/html/parser/HTMLParserIdioms.h" |
36 #include "platform/Decimal.h" | 36 #include "platform/Decimal.h" |
37 #include "platform/RuntimeEnabledFeatures.h" | 37 #include "platform/RuntimeEnabledFeatures.h" |
38 #include "wtf/text/StringBuffer.h" | 38 #include "wtf/text/StringBuffer.h" |
39 #include "wtf/text/StringBuilder.h" | 39 #include "wtf/text/StringBuilder.h" |
40 | 40 |
41 namespace blink { | 41 namespace blink { |
42 | 42 |
43 using namespace MediaFeatureNames; | 43 using namespace MediaFeatureNames; |
44 | 44 |
45 static inline bool featureWithCSSValueID(const String& mediaFeature, const CSSPa rserValue* value) | 45 static inline bool featureWithCSSValueID(const String& mediaFeature, const CSSVa lueID& id) |
46 { | 46 { |
47 if (!value->id) | 47 if (!id) |
48 return false; | 48 return false; |
49 | 49 |
50 return mediaFeature == displayModeMediaFeature | 50 return mediaFeature == displayModeMediaFeature |
51 || mediaFeature == orientationMediaFeature | 51 || mediaFeature == orientationMediaFeature |
52 || mediaFeature == pointerMediaFeature | 52 || mediaFeature == pointerMediaFeature |
53 || mediaFeature == anyPointerMediaFeature | 53 || mediaFeature == anyPointerMediaFeature |
54 || mediaFeature == hoverMediaFeature | 54 || mediaFeature == hoverMediaFeature |
55 || mediaFeature == anyHoverMediaFeature | 55 || mediaFeature == anyHoverMediaFeature |
56 || mediaFeature == scanMediaFeature; | 56 || mediaFeature == scanMediaFeature; |
57 } | 57 } |
(...skipping 12 matching lines...) Expand all Loading... | |
70 if (mediaFeature == hoverMediaFeature || mediaFeature == anyHoverMediaFeatur e) | 70 if (mediaFeature == hoverMediaFeature || mediaFeature == anyHoverMediaFeatur e) |
71 return ident == CSSValueNone || ident == CSSValueOnDemand || ident == CS SValueHover; | 71 return ident == CSSValueNone || ident == CSSValueOnDemand || ident == CS SValueHover; |
72 | 72 |
73 if (mediaFeature == scanMediaFeature) | 73 if (mediaFeature == scanMediaFeature) |
74 return ident == CSSValueInterlace || ident == CSSValueProgressive; | 74 return ident == CSSValueInterlace || ident == CSSValueProgressive; |
75 | 75 |
76 ASSERT_NOT_REACHED(); | 76 ASSERT_NOT_REACHED(); |
77 return false; | 77 return false; |
78 } | 78 } |
79 | 79 |
80 static inline bool featureWithValidPositiveLength(const String& mediaFeature, co nst CSSParserValue* value) | 80 static inline bool featureWithValidPositiveLength(const String& mediaFeature, co nst CSSParserToken& token) |
81 { | 81 { |
82 if (!(CSSPrimitiveValue::isLength((CSSPrimitiveValue::UnitType)value->unit) || (value->unit == CSSPrimitiveValue::CSS_NUMBER && value->fValue == 0)) || valu e->fValue < 0) | 82 if (!(CSSPrimitiveValue::isLength(token.unitType()) || (token.unitType() == CSSPrimitiveValue::CSS_NUMBER && token.numericValue() == 0)) || token.numericVal ue() < 0) |
83 return false; | 83 return false; |
84 | 84 |
85 | 85 |
86 return mediaFeature == heightMediaFeature | 86 return mediaFeature == heightMediaFeature |
87 || mediaFeature == maxHeightMediaFeature | 87 || mediaFeature == maxHeightMediaFeature |
88 || mediaFeature == minHeightMediaFeature | 88 || mediaFeature == minHeightMediaFeature |
89 || mediaFeature == widthMediaFeature | 89 || mediaFeature == widthMediaFeature |
90 || mediaFeature == maxWidthMediaFeature | 90 || mediaFeature == maxWidthMediaFeature |
91 || mediaFeature == minWidthMediaFeature | 91 || mediaFeature == minWidthMediaFeature |
92 || mediaFeature == deviceHeightMediaFeature | 92 || mediaFeature == deviceHeightMediaFeature |
93 || mediaFeature == maxDeviceHeightMediaFeature | 93 || mediaFeature == maxDeviceHeightMediaFeature |
94 || mediaFeature == minDeviceHeightMediaFeature | 94 || mediaFeature == minDeviceHeightMediaFeature |
95 || mediaFeature == deviceWidthMediaFeature | 95 || mediaFeature == deviceWidthMediaFeature |
96 || mediaFeature == minDeviceWidthMediaFeature | 96 || mediaFeature == minDeviceWidthMediaFeature |
97 || mediaFeature == maxDeviceWidthMediaFeature; | 97 || mediaFeature == maxDeviceWidthMediaFeature; |
98 } | 98 } |
99 | 99 |
100 static inline bool featureWithValidDensity(const String& mediaFeature, const CSS ParserValue* value) | 100 static inline bool featureWithValidDensity(const String& mediaFeature, const CSS ParserToken& token) |
101 { | 101 { |
102 if ((value->unit != CSSPrimitiveValue::CSS_DPPX && value->unit != CSSPrimiti veValue::CSS_DPI && value->unit != CSSPrimitiveValue::CSS_DPCM) || value->fValue <= 0) | 102 if ((token.unitType() != CSSPrimitiveValue::CSS_DPPX && token.unitType() != CSSPrimitiveValue::CSS_DPI && token.unitType() != CSSPrimitiveValue::CSS_DPCM) | | token.numericValue() <= 0) |
103 return false; | 103 return false; |
104 | 104 |
105 return mediaFeature == resolutionMediaFeature | 105 return mediaFeature == resolutionMediaFeature |
106 || mediaFeature == minResolutionMediaFeature | 106 || mediaFeature == minResolutionMediaFeature |
107 || mediaFeature == maxResolutionMediaFeature; | 107 || mediaFeature == maxResolutionMediaFeature; |
108 } | 108 } |
109 | 109 |
110 static inline bool featureWithPositiveInteger(const String& mediaFeature, const CSSParserValue* value) | 110 static inline bool featureWithPositiveInteger(const String& mediaFeature, const CSSParserToken& token) |
111 { | 111 { |
112 if (!value->isInt || value->fValue < 0) | 112 if (token.numericValueType() != IntegerValueType || token.numericValue() < 0 ) |
113 return false; | 113 return false; |
114 | 114 |
115 return mediaFeature == colorMediaFeature | 115 return mediaFeature == colorMediaFeature |
116 || mediaFeature == maxColorMediaFeature | 116 || mediaFeature == maxColorMediaFeature |
117 || mediaFeature == minColorMediaFeature | 117 || mediaFeature == minColorMediaFeature |
118 || mediaFeature == colorIndexMediaFeature | 118 || mediaFeature == colorIndexMediaFeature |
119 || mediaFeature == maxColorIndexMediaFeature | 119 || mediaFeature == maxColorIndexMediaFeature |
120 || mediaFeature == minColorIndexMediaFeature | 120 || mediaFeature == minColorIndexMediaFeature |
121 || mediaFeature == monochromeMediaFeature | 121 || mediaFeature == monochromeMediaFeature |
122 || mediaFeature == maxMonochromeMediaFeature | 122 || mediaFeature == maxMonochromeMediaFeature |
123 || mediaFeature == minMonochromeMediaFeature; | 123 || mediaFeature == minMonochromeMediaFeature; |
124 } | 124 } |
125 | 125 |
126 static inline bool featureWithPositiveNumber(const String& mediaFeature, const C SSParserValue* value) | 126 static inline bool featureWithPositiveNumber(const String& mediaFeature, const C SSParserToken& token) |
127 { | 127 { |
128 if (value->unit != CSSPrimitiveValue::CSS_NUMBER || value->fValue < 0) | 128 if (token.unitType() != CSSPrimitiveValue::CSS_NUMBER || token.numericValue( ) < 0) |
129 return false; | 129 return false; |
130 | 130 |
131 return mediaFeature == transform3dMediaFeature | 131 return mediaFeature == transform3dMediaFeature |
132 || mediaFeature == devicePixelRatioMediaFeature | 132 || mediaFeature == devicePixelRatioMediaFeature |
133 || mediaFeature == maxDevicePixelRatioMediaFeature | 133 || mediaFeature == maxDevicePixelRatioMediaFeature |
134 || mediaFeature == minDevicePixelRatioMediaFeature; | 134 || mediaFeature == minDevicePixelRatioMediaFeature; |
135 } | 135 } |
136 | 136 |
137 static inline bool featureWithZeroOrOne(const String& mediaFeature, const CSSPar serValue* value) | 137 static inline bool featureWithZeroOrOne(const String& mediaFeature, const CSSPar serToken& token) |
138 { | 138 { |
139 if (!value->isInt || !(value->fValue == 1 || !value->fValue)) | 139 if (token.numericValueType() != IntegerValueType || !(token.numericValue() = = 1 || !token.numericValue())) |
140 return false; | 140 return false; |
141 | 141 |
142 return mediaFeature == gridMediaFeature; | 142 return mediaFeature == gridMediaFeature; |
143 } | 143 } |
144 | 144 |
145 static inline bool featureWithAspectRatio(const String& mediaFeature) | 145 static inline bool featureWithAspectRatio(const String& mediaFeature) |
146 { | 146 { |
147 return mediaFeature == aspectRatioMediaFeature | 147 return mediaFeature == aspectRatioMediaFeature |
148 || mediaFeature == deviceAspectRatioMediaFeature | 148 || mediaFeature == deviceAspectRatioMediaFeature |
149 || mediaFeature == minAspectRatioMediaFeature | 149 || mediaFeature == minAspectRatioMediaFeature |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
197 , m_expValue(other.expValue()) | 197 , m_expValue(other.expValue()) |
198 { | 198 { |
199 } | 199 } |
200 | 200 |
201 MediaQueryExp::MediaQueryExp(const String& mediaFeature, const MediaQueryExpValu e& expValue) | 201 MediaQueryExp::MediaQueryExp(const String& mediaFeature, const MediaQueryExpValu e& expValue) |
202 : m_mediaFeature(mediaFeature) | 202 : m_mediaFeature(mediaFeature) |
203 , m_expValue(expValue) | 203 , m_expValue(expValue) |
204 { | 204 { |
205 } | 205 } |
206 | 206 |
207 PassOwnPtrWillBeRawPtr<MediaQueryExp> MediaQueryExp::createIfValid(const String& mediaFeature, CSSParserValueList* valueList) | 207 CSSValueID cssValueKeywordID(const CSSParserString&); |
208 | |
209 PassOwnPtrWillBeRawPtr<MediaQueryExp> MediaQueryExp::createIfValid(const String& mediaFeature, const Vector<CSSParserToken, 4>& tokenList) | |
208 { | 210 { |
209 ASSERT(!mediaFeature.isNull()); | 211 ASSERT(!mediaFeature.isNull()); |
210 | 212 |
211 MediaQueryExpValue expValue; | 213 MediaQueryExpValue expValue; |
212 bool isValid = false; | 214 bool isValid = false; |
213 String lowerMediaFeature = attemptStaticStringCreation(mediaFeature.lower()) ; | 215 String lowerMediaFeature = attemptStaticStringCreation(mediaFeature.lower()) ; |
214 | 216 |
215 // Create value for media query expression that must have 1 or more values. | 217 // Create value for media query expression that must have 1 or more values. |
216 if (valueList && valueList->size() > 0) { | 218 if (tokenList.size() > 0) { |
217 if (valueList->size() == 1) { | 219 if (tokenList.size() == 1) { |
218 CSSParserValue* value = valueList->current(); | 220 CSSParserToken token = tokenList.at(0); |
219 ASSERT(value); | 221 CSSValueID id = token.type() == IdentToken ? cssValueKeywordID(token .value()) : CSSValueInvalid; |
220 | 222 |
221 if (featureWithCSSValueID(lowerMediaFeature, value) && featureWithVa lidIdent(lowerMediaFeature, value->id)) { | 223 if (featureWithCSSValueID(lowerMediaFeature, id) && featureWithValid Ident(lowerMediaFeature, id)) { |
222 // Media features that use CSSValueIDs. | 224 // Media features that use CSSValueIDs. |
223 expValue.id = value->id; | 225 expValue.id = id; |
224 expValue.unit = CSSPrimitiveValue::CSS_VALUE_ID; | 226 expValue.unit = CSSPrimitiveValue::CSS_VALUE_ID; |
225 expValue.isID = true; | 227 expValue.isID = true; |
226 } else if (featureWithValidDensity(lowerMediaFeature, value) | 228 } else if (token.type() == NumberToken || token.type() == Percentage Token || token.type() == DimensionToken) { |
Yoav Weiss
2015/06/15 21:46:27
Does this add a functional change?
rwlbuis
2015/06/15 22:00:53
I think I need this since calling numericValue() A
| |
227 || featureWithValidPositiveLength(lowerMediaFeature, value)) { | 229 if (featureWithValidDensity(lowerMediaFeature, token) |
228 // Media features that must have non-negative <density>, ie. dpp x, dpi or dpcm, | 230 || featureWithValidPositiveLength(lowerMediaFeature, token)) { |
229 // or Media features that must have non-negative <length> or num ber value. | 231 // Media features that must have non-negative <density>, ie. dppx, dpi or dpcm, |
230 expValue.value = value->fValue; | 232 // or Media features that must have non-negative <length> or number value. |
231 expValue.unit = (CSSPrimitiveValue::UnitType)value->unit; | 233 expValue.value = token.numericValue(); |
232 expValue.isValue = true; | 234 expValue.unit = token.unitType(); |
233 } else if (featureWithPositiveInteger(lowerMediaFeature, value) | 235 expValue.isValue = true; |
234 || featureWithPositiveNumber(lowerMediaFeature, value) | 236 } else if (featureWithPositiveInteger(lowerMediaFeature, token) |
235 || featureWithZeroOrOne(lowerMediaFeature, value)) { | 237 || featureWithPositiveNumber(lowerMediaFeature, token) |
236 // Media features that must have non-negative integer value, | 238 || featureWithZeroOrOne(lowerMediaFeature, token)) { |
237 // or media features that must have non-negative number value, | 239 // Media features that must have non-negative integer value, |
238 // or media features that must have (0|1) value. | 240 // or media features that must have non-negative number valu e, |
239 expValue.value = value->fValue; | 241 // or media features that must have (0|1) value. |
240 expValue.unit = CSSPrimitiveValue::CSS_NUMBER; | 242 expValue.value = token.numericValue(); |
241 expValue.isValue = true; | 243 expValue.unit = CSSPrimitiveValue::CSS_NUMBER; |
244 expValue.isValue = true; | |
245 } | |
242 } | 246 } |
243 | 247 |
244 isValid = (expValue.isID || expValue.isValue); | 248 isValid = (expValue.isID || expValue.isValue); |
245 | 249 |
246 } else if (valueList->size() == 3 && featureWithAspectRatio(lowerMediaFe ature)) { | 250 } else if (tokenList.size() == 3 && featureWithAspectRatio(lowerMediaFea ture)) { |
247 // Create list of values. | 251 // Create list of values. |
248 // Currently accepts only <integer>/<integer>. | 252 // Currently accepts only <integer>/<integer>. |
249 // Applicable to device-aspect-ratio and aspec-ratio. | 253 // Applicable to device-aspect-ratio and aspec-ratio. |
250 isValid = true; | 254 isValid = true; |
251 float numeratorValue = 0; | 255 float numeratorValue = 0; |
252 float denominatorValue = 0; | 256 float denominatorValue = 0; |
253 // The aspect-ratio must be <integer> (whitespace)? / (whitespace)? <integer>. | 257 // The aspect-ratio must be <integer> (whitespace)? / (whitespace)? <integer>. |
254 for (unsigned i = 0; i < 3; ++i, valueList->next()) { | 258 for (unsigned i = 0; i < 3; ++i) { |
255 const CSSParserValue* value = valueList->current(); | 259 const CSSParserToken& token = tokenList.at(i); |
256 if (i != 1 && value->unit == CSSPrimitiveValue::CSS_NUMBER && va lue->fValue > 0 && value->isInt) { | 260 if (i != 1 && token.unitType() == CSSPrimitiveValue::CSS_NUMBER && token.numericValue() > 0 && token.numericValueType() == IntegerValueType) { |
257 if (!i) | 261 if (!i) |
258 numeratorValue = value->fValue; | 262 numeratorValue = token.numericValue(); |
259 else | 263 else |
260 denominatorValue = value->fValue; | 264 denominatorValue = token.numericValue(); |
261 } else if (i == 1 && value->unit == CSSParserValue::Operator && value->iValue == '/') { | 265 } else if (i == 1 && token.type() == DelimiterToken && token.del imiter() == '/') { |
262 continue; | 266 continue; |
263 } else { | 267 } else { |
264 isValid = false; | 268 isValid = false; |
265 break; | 269 break; |
266 } | 270 } |
267 } | 271 } |
268 | 272 |
269 if (isValid) { | 273 if (isValid) { |
270 expValue.numerator = (unsigned)numeratorValue; | 274 expValue.numerator = (unsigned)numeratorValue; |
271 expValue.denominator = (unsigned)denominatorValue; | 275 expValue.denominator = (unsigned)denominatorValue; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
323 output.append('/'); | 327 output.append('/'); |
324 output.append(printNumber(denominator)); | 328 output.append(printNumber(denominator)); |
325 } else if (isID) { | 329 } else if (isID) { |
326 output.append(getValueName(id)); | 330 output.append(getValueName(id)); |
327 } | 331 } |
328 | 332 |
329 return output.toString(); | 333 return output.toString(); |
330 } | 334 } |
331 | 335 |
332 } // namespace | 336 } // namespace |
OLD | NEW |