OLD | NEW |
1 /* | 1 /* |
2 * CSS Media Query Evaluator | 2 * CSS Media Query Evaluator |
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) 2013 Apple Inc. All rights reserved. | 5 * Copyright (C) 2013 Apple Inc. All rights reserved. |
6 * Copyright (C) 2013 Intel Corporation. All rights reserved. | 6 * Copyright (C) 2013 Intel Corporation. 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 28 matching lines...) Expand all Loading... |
39 #include "core/css/CSSPrimitiveValue.h" | 39 #include "core/css/CSSPrimitiveValue.h" |
40 #include "core/css/CSSToLengthConversionData.h" | 40 #include "core/css/CSSToLengthConversionData.h" |
41 #include "core/css/MediaList.h" | 41 #include "core/css/MediaList.h" |
42 #include "core/css/MediaQuery.h" | 42 #include "core/css/MediaQuery.h" |
43 #include "core/css/resolver/MediaQueryResult.h" | 43 #include "core/css/resolver/MediaQueryResult.h" |
44 #include "core/dom/NodeRenderStyle.h" | 44 #include "core/dom/NodeRenderStyle.h" |
45 #include "core/frame/FrameHost.h" | 45 #include "core/frame/FrameHost.h" |
46 #include "core/frame/FrameView.h" | 46 #include "core/frame/FrameView.h" |
47 #include "core/frame/LocalFrame.h" | 47 #include "core/frame/LocalFrame.h" |
48 #include "core/frame/Settings.h" | 48 #include "core/frame/Settings.h" |
| 49 #include "core/html/imports/HTMLImport.h" |
49 #include "core/inspector/InspectorInstrumentation.h" | 50 #include "core/inspector/InspectorInstrumentation.h" |
50 #include "core/rendering/RenderView.h" | 51 #include "core/rendering/RenderView.h" |
51 #include "core/rendering/compositing/RenderLayerCompositor.h" | 52 #include "core/rendering/compositing/RenderLayerCompositor.h" |
52 #include "core/rendering/style/RenderStyle.h" | 53 #include "core/rendering/style/RenderStyle.h" |
53 #include "platform/PlatformScreen.h" | 54 #include "platform/PlatformScreen.h" |
54 #include "platform/geometry/FloatRect.h" | 55 #include "platform/geometry/FloatRect.h" |
55 #include "wtf/HashMap.h" | 56 #include "wtf/HashMap.h" |
56 | 57 |
57 namespace WebCore { | 58 namespace WebCore { |
58 | 59 |
59 using namespace MediaFeatureNames; | 60 using namespace MediaFeatureNames; |
60 | 61 |
61 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix }; | 62 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix }; |
62 | 63 |
63 typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, LocalFrame*, MediaFeaturePrefi
x); | 64 typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, LocalFrame*, MediaFeaturePrefi
x, MediaValues*, bool); |
64 typedef HashMap<StringImpl*, EvalFunc> FunctionMap; | 65 typedef HashMap<StringImpl*, EvalFunc> FunctionMap; |
65 static FunctionMap* gFunctionMap; | 66 static FunctionMap* gFunctionMap; |
66 | 67 |
67 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult) | 68 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult) |
68 : m_frame(0) | 69 : m_frame(0) |
69 , m_style(nullptr) | 70 , m_style(nullptr) |
70 , m_expResult(mediaFeatureResult) | 71 , m_expResult(mediaFeatureResult) |
| 72 , m_mediaValues(nullptr) |
71 { | 73 { |
72 } | 74 } |
73 | 75 |
74 MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, bool m
ediaFeatureResult) | 76 MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, bool m
ediaFeatureResult) |
75 : m_mediaType(acceptedMediaType) | 77 : m_mediaType(acceptedMediaType) |
76 , m_frame(0) | 78 , m_frame(0) |
77 , m_style(nullptr) | 79 , m_style(nullptr) |
78 , m_expResult(mediaFeatureResult) | 80 , m_expResult(mediaFeatureResult) |
| 81 , m_mediaValues(nullptr) |
79 { | 82 { |
80 } | 83 } |
81 | 84 |
82 MediaQueryEvaluator::MediaQueryEvaluator(const char* acceptedMediaType, bool med
iaFeatureResult) | 85 MediaQueryEvaluator::MediaQueryEvaluator(const char* acceptedMediaType, bool med
iaFeatureResult) |
83 : m_mediaType(acceptedMediaType) | 86 : m_mediaType(acceptedMediaType) |
84 , m_frame(0) | 87 , m_frame(0) |
85 , m_style(nullptr) | 88 , m_style(nullptr) |
86 , m_expResult(mediaFeatureResult) | 89 , m_expResult(mediaFeatureResult) |
| 90 , m_mediaValues(nullptr) |
87 { | 91 { |
88 } | 92 } |
89 | 93 |
90 MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, LocalF
rame* frame, RenderStyle* style) | 94 MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, LocalF
rame* frame, RenderStyle* style) |
91 : m_mediaType(acceptedMediaType) | 95 : m_mediaType(acceptedMediaType) |
92 , m_frame(frame) | 96 , m_frame(frame) |
93 , m_style(style) | 97 , m_style(style) |
94 , m_expResult(false) // Doesn't matter when we have m_frame and m_style. | 98 , m_expResult(false) // Doesn't matter when we have m_frame and m_style. |
| 99 , m_mediaValues(nullptr) |
95 { | 100 { |
96 } | 101 } |
97 | 102 |
| 103 MediaQueryEvaluator::MediaQueryEvaluator(const String& acceptedMediaType, const
MediaValues* mediaValues, bool mediaFeatureResult) |
| 104 : m_mediaType(acceptedMediaType) |
| 105 , m_frame(0) |
| 106 , m_style(nullptr) |
| 107 , m_expResult(mediaFeatureResult) |
| 108 , m_mediaValues(MediaValues::copy(mediaValues)) |
| 109 { |
| 110 } |
| 111 |
98 MediaQueryEvaluator::~MediaQueryEvaluator() | 112 MediaQueryEvaluator::~MediaQueryEvaluator() |
99 { | 113 { |
100 } | 114 } |
101 | 115 |
102 bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const | 116 bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const |
103 { | 117 { |
104 return mediaTypeToMatch.isEmpty() | 118 return mediaTypeToMatch.isEmpty() |
105 || equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all) | 119 || equalIgnoringCase(mediaTypeToMatch, MediaTypeNames::all) |
106 || equalIgnoringCase(mediaTypeToMatch, m_mediaType); | 120 || equalIgnoringCase(mediaTypeToMatch, m_mediaType); |
107 } | 121 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 for (; j < expressions.size(); ++j) { | 155 for (; j < expressions.size(); ++j) { |
142 bool exprResult = eval(expressions.at(j).get()); | 156 bool exprResult = eval(expressions.at(j).get()); |
143 if (viewportDependentMediaQueryResults && expressions.at(j)->isV
iewportDependent()) | 157 if (viewportDependentMediaQueryResults && expressions.at(j)->isV
iewportDependent()) |
144 viewportDependentMediaQueryResults->append(adoptRefWillBeNoo
p(new MediaQueryResult(*expressions.at(j), exprResult))); | 158 viewportDependentMediaQueryResults->append(adoptRefWillBeNoo
p(new MediaQueryResult(*expressions.at(j), exprResult))); |
145 if (!exprResult) | 159 if (!exprResult) |
146 break; | 160 break; |
147 } | 161 } |
148 | 162 |
149 // Assume true if we are at the end of the list, otherwise assume fa
lse. | 163 // Assume true if we are at the end of the list, otherwise assume fa
lse. |
150 result = applyRestrictor(query->restrictor(), expressions.size() ==
j); | 164 result = applyRestrictor(query->restrictor(), expressions.size() ==
j); |
151 } else | 165 } else { |
152 result = applyRestrictor(query->restrictor(), false); | 166 result = applyRestrictor(query->restrictor(), false); |
| 167 } |
153 } | 168 } |
154 | 169 |
155 return result; | 170 return result; |
156 } | 171 } |
157 | 172 |
158 template<typename T> | 173 template<typename T> |
159 bool compareValue(T a, T b, MediaFeaturePrefix op) | 174 bool compareValue(T a, T b, MediaFeaturePrefix op) |
160 { | 175 { |
161 switch (op) { | 176 switch (op) { |
162 case MinPrefix: | 177 case MinPrefix: |
(...skipping 19 matching lines...) Expand all Loading... |
182 static bool numberValue(CSSValue* value, float& result) | 197 static bool numberValue(CSSValue* value, float& result) |
183 { | 198 { |
184 if (value->isPrimitiveValue() | 199 if (value->isPrimitiveValue() |
185 && toCSSPrimitiveValue(value)->isNumber()) { | 200 && toCSSPrimitiveValue(value)->isNumber()) { |
186 result = toCSSPrimitiveValue(value)->getFloatValue(CSSPrimitiveValue::CS
S_NUMBER); | 201 result = toCSSPrimitiveValue(value)->getFloatValue(CSSPrimitiveValue::CS
S_NUMBER); |
187 return true; | 202 return true; |
188 } | 203 } |
189 return false; | 204 return false; |
190 } | 205 } |
191 | 206 |
192 static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fra
me, MediaFeaturePrefix op) | 207 static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fra
me, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedValue) |
193 { | 208 { |
194 int bitsPerComponent = screenDepthPerComponent(frame->view()); | 209 if (!frame && !mediaValues) |
| 210 return expectedValue; |
| 211 |
| 212 int bitsPerComponent; |
| 213 if (frame) |
| 214 bitsPerComponent = screenDepthPerComponent(frame->view()); |
| 215 else |
| 216 bitsPerComponent = mediaValues->getColorBitsPerComponent(); |
| 217 |
195 float number; | 218 float number; |
196 if (value) | 219 if (value) |
197 return numberValue(value, number) && compareValue(bitsPerComponent, stat
ic_cast<int>(number), op); | 220 return numberValue(value, number) && compareValue(bitsPerComponent, stat
ic_cast<int>(number), op); |
198 | 221 |
199 return bitsPerComponent != 0; | 222 return bitsPerComponent != 0; |
200 } | 223 } |
201 | 224 |
202 static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame
*, MediaFeaturePrefix op) | 225 static bool colorIndexMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame
*, MediaFeaturePrefix op, MediaValues*, bool) |
203 { | 226 { |
204 // FIXME: We currently assume that we do not support indexed displays, as it
is unknown | 227 // FIXME: We currently assume that we do not support indexed displays, as it
is unknown |
205 // how to retrieve the information if the display mode is indexed. This matc
hes Firefox. | 228 // how to retrieve the information if the display mode is indexed. This matc
hes Firefox. |
206 if (!value) | 229 if (!value) |
207 return false; | 230 return false; |
208 | 231 |
209 // Acording to spec, if the device does not use a color lookup table, the va
lue is zero. | 232 // Acording to spec, if the device does not use a color lookup table, the va
lue is zero. |
210 float number; | 233 float number; |
211 return numberValue(value, number) && compareValue(0, static_cast<int>(number
), op); | 234 return numberValue(value, number) && compareValue(0, static_cast<int>(number
), op); |
212 } | 235 } |
213 | 236 |
214 static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Loca
lFrame* frame, MediaFeaturePrefix op) | 237 static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Loca
lFrame* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedVal
ue) |
215 { | 238 { |
216 if (!screenIsMonochrome(frame->view())) { | 239 if ((!frame || !style) && !mediaValues) |
| 240 return expectedValue; |
| 241 |
| 242 bool isMonochrome; |
| 243 if (frame) |
| 244 isMonochrome = screenIsMonochrome(frame->view()); |
| 245 else |
| 246 isMonochrome = (mediaValues->getMonochromeBitsPerComponent() > 0); |
| 247 |
| 248 if (!isMonochrome) { |
217 if (value) { | 249 if (value) { |
218 float number; | 250 float number; |
219 return numberValue(value, number) && compareValue(0, static_cast<int
>(number), op); | 251 return numberValue(value, number) && compareValue(0, static_cast<int
>(number), op); |
220 } | 252 } |
221 return false; | 253 return false; |
222 } | 254 } |
223 | 255 |
224 return colorMediaFeatureEval(value, style, frame, op); | 256 return colorMediaFeatureEval(value, style, frame, op, mediaValues, expectedV
alue); |
225 } | 257 } |
226 | 258 |
227 static IntSize viewportSize(FrameView* view) | 259 static IntSize viewportSize(FrameView* view) |
228 { | 260 { |
229 return view->layoutSize(IncludeScrollbars); | 261 return view->layoutSize(IncludeScrollbars); |
230 } | 262 } |
231 | 263 |
232 static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix) | 264 static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
233 { | 265 { |
234 FrameView* view = frame->view(); | 266 if (!frame && !mediaValues) |
235 int width = viewportSize(view).width(); | 267 return expectedValue; |
236 int height = viewportSize(view).height(); | 268 |
| 269 int width; |
| 270 int height; |
| 271 if (frame) { |
| 272 FrameView* view = frame->view(); |
| 273 width = viewportSize(view).width(); |
| 274 height = viewportSize(view).height(); |
| 275 } else { |
| 276 width = mediaValues->getViewportWidth(); |
| 277 height = mediaValues->getViewportHeight(); |
| 278 } |
| 279 |
237 if (value && value->isPrimitiveValue()) { | 280 if (value && value->isPrimitiveValue()) { |
238 const CSSValueID id = toCSSPrimitiveValue(value)->getValueID(); | 281 const CSSValueID id = toCSSPrimitiveValue(value)->getValueID(); |
239 if (width > height) // Square viewport is portrait. | 282 if (width > height) // Square viewport is portrait. |
240 return CSSValueLandscape == id; | 283 return CSSValueLandscape == id; |
241 return CSSValuePortrait == id; | 284 return CSSValuePortrait == id; |
242 } | 285 } |
243 | 286 |
244 // Expression (orientation) evaluates to true if width and height >= 0. | 287 // Expression (orientation) evaluates to true if width and height >= 0. |
245 return height >= 0 && width >= 0; | 288 return height >= 0 && width >= 0; |
246 } | 289 } |
247 | 290 |
248 static bool aspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op) | 291 static bool aspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedValue) |
249 { | 292 { |
| 293 if (!frame && !mediaValues) |
| 294 return expectedValue; |
| 295 |
250 if (value) { | 296 if (value) { |
251 FrameView* view = frame->view(); | 297 int width; |
252 return compareAspectRatioValue(value, viewportSize(view).width(), viewpo
rtSize(view).height(), op); | 298 int height; |
| 299 if (frame) { |
| 300 FrameView* view = frame->view(); |
| 301 width = viewportSize(view).width(); |
| 302 height = viewportSize(view).height(); |
| 303 } else { |
| 304 width = mediaValues->getViewportWidth(); |
| 305 height = mediaValues->getViewportHeight(); |
| 306 } |
| 307 |
| 308 return compareAspectRatioValue(value, width, height, op); |
253 } | 309 } |
254 | 310 |
255 // ({,min-,max-}aspect-ratio) | 311 // ({,min-,max-}aspect-ratio) |
256 // assume if we have a device, its aspect ratio is non-zero. | 312 // assume if we have a device, its aspect ratio is non-zero. |
257 return true; | 313 return true; |
258 } | 314 } |
259 | 315 |
260 static bool deviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Loc
alFrame* frame, MediaFeaturePrefix op) | 316 static bool deviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle*, Loc
alFrame* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedVa
lue) |
261 { | 317 { |
| 318 if (!frame && !mediaValues) |
| 319 return expectedValue; |
| 320 |
262 if (value) { | 321 if (value) { |
263 FloatRect sg = screenRect(frame->view()); | 322 int width; |
264 return compareAspectRatioValue(value, static_cast<int>(sg.width()), stat
ic_cast<int>(sg.height()), op); | 323 int height; |
| 324 if (frame) { |
| 325 FloatRect sg = screenRect(frame->view()); |
| 326 width = static_cast<int>(sg.width()); |
| 327 height = static_cast<int>(sg.height()); |
| 328 } else { |
| 329 width = mediaValues->getDeviceWidth(); |
| 330 height = mediaValues->getDeviceHeight(); |
| 331 } |
| 332 |
| 333 return compareAspectRatioValue(value, width, height, op); |
265 } | 334 } |
266 | 335 |
267 // ({,min-,max-}device-aspect-ratio) | 336 // ({,min-,max-}device-aspect-ratio) |
268 // assume if we have a device, its aspect ratio is non-zero. | 337 // assume if we have a device, its aspect ratio is non-zero. |
269 return true; | 338 return true; |
270 } | 339 } |
271 | 340 |
272 static bool evalResolution(CSSValue* value, LocalFrame* frame, MediaFeaturePrefi
x op) | 341 static bool evalResolution(CSSValue* value, LocalFrame* frame, MediaFeaturePrefi
x op, MediaValues* mediaValues, bool expectedValue) |
273 { | 342 { |
| 343 if (!frame && !mediaValues) |
| 344 return expectedValue; |
| 345 |
274 // According to MQ4, only 'screen', 'print' and 'speech' may match. | 346 // According to MQ4, only 'screen', 'print' and 'speech' may match. |
275 // FIXME: What should speech match? https://www.w3.org/Style/CSS/Tracker/iss
ues/348 | 347 // FIXME: What should speech match? https://www.w3.org/Style/CSS/Tracker/iss
ues/348 |
276 float actualResolution = 0; | 348 float actualResolution = 0; |
277 | 349 |
278 // This checks the actual media type applied to the document, and we know | 350 // This checks the actual media type applied to the document, and we know |
279 // this method only got called if this media type matches the one defined | 351 // this method only got called if this media type matches the one defined |
280 // in the query. Thus, if if the document's media type is "print", the | 352 // in the query. Thus, if if the document's media type is "print", the |
281 // media type of the query will either be "print" or "all". | 353 // media type of the query will either be "print" or "all". |
282 String mediaType = frame->view()->mediaType(); | 354 if (frame) { |
283 if (equalIgnoringCase(mediaType, "screen")) | 355 String mediaType = frame->view()->mediaType(); |
284 actualResolution = clampTo<float>(frame->devicePixelRatio()); | 356 if (equalIgnoringCase(mediaType, "screen")) { |
285 else if (equalIgnoringCase(mediaType, "print")) { | 357 actualResolution = clampTo<float>(frame->devicePixelRatio()); |
286 // The resolution of images while printing should not depend on the DPI | 358 } else if (equalIgnoringCase(mediaType, "print")) { |
287 // of the screen. Until we support proper ways of querying this info | 359 // The resolution of images while printing should not depend on the
DPI |
288 // we use 300px which is considered minimum for current printers. | 360 // of the screen. Until we support proper ways of querying this info |
289 actualResolution = 300 / cssPixelsPerInch; | 361 // we use 300px which is considered minimum for current printers. |
| 362 actualResolution = 300 / cssPixelsPerInch; |
| 363 } |
| 364 } else { |
| 365 actualResolution = mediaValues->getPixelRatio(); |
290 } | 366 } |
291 | 367 |
292 if (!value) | 368 if (!value) |
293 return !!actualResolution; | 369 return !!actualResolution; |
294 | 370 |
295 if (!value->isPrimitiveValue()) | 371 if (!value->isPrimitiveValue()) |
296 return false; | 372 return false; |
297 | 373 |
298 CSSPrimitiveValue* resolution = toCSSPrimitiveValue(value); | 374 CSSPrimitiveValue* resolution = toCSSPrimitiveValue(value); |
299 | 375 |
(...skipping 10 matching lines...) Expand all Loading... |
310 // approximates the reference pixel". With that in mind, allowing 2 deci
mal | 386 // approximates the reference pixel". With that in mind, allowing 2 deci
mal |
311 // point precision seems appropriate. | 387 // point precision seems appropriate. |
312 return compareValue( | 388 return compareValue( |
313 floorf(0.5 + 100 * actualResolution) / 100, | 389 floorf(0.5 + 100 * actualResolution) / 100, |
314 floorf(0.5 + 100 * resolution->getFloatValue(CSSPrimitiveValue::CSS_
DPPX)) / 100, op); | 390 floorf(0.5 + 100 * resolution->getFloatValue(CSSPrimitiveValue::CSS_
DPPX)) / 100, op); |
315 } | 391 } |
316 | 392 |
317 return compareValue(actualResolution, resolution->getFloatValue(CSSPrimitive
Value::CSS_DPPX), op); | 393 return compareValue(actualResolution, resolution->getFloatValue(CSSPrimitive
Value::CSS_DPPX), op); |
318 } | 394 } |
319 | 395 |
320 static bool devicePixelRatioMediaFeatureEval(CSSValue *value, RenderStyle*, Loca
lFrame* frame, MediaFeaturePrefix op) | 396 static bool devicePixelRatioMediaFeatureEval(CSSValue *value, RenderStyle*, Loca
lFrame* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedVal
ue) |
321 { | 397 { |
322 UseCounter::count(frame->document(), UseCounter::PrefixedDevicePixelRatioMed
iaFeature); | 398 UseCounter::count(frame->document(), UseCounter::PrefixedDevicePixelRatioMed
iaFeature); |
323 | 399 |
324 return (!value || toCSSPrimitiveValue(value)->isNumber()) && evalResolution(
value, frame, op); | 400 return (!value || toCSSPrimitiveValue(value)->isNumber()) && evalResolution(
value, frame, op, mediaValues, expectedValue); |
325 } | 401 } |
326 | 402 |
327 static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame
* frame, MediaFeaturePrefix op) | 403 static bool resolutionMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame
* frame, MediaFeaturePrefix op, MediaValues* MediaValues, bool expectedValue) |
328 { | 404 { |
329 return (!value || toCSSPrimitiveValue(value)->isResolution()) && evalResolut
ion(value, frame, op); | 405 return (!value || toCSSPrimitiveValue(value)->isResolution()) && evalResolut
ion(value, frame, op, MediaValues, expectedValue); |
330 } | 406 } |
331 | 407 |
332 static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*, Med
iaFeaturePrefix op) | 408 static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*, Med
iaFeaturePrefix op, MediaValues*, bool) |
333 { | 409 { |
334 // if output device is bitmap, grid: 0 == true | 410 // if output device is bitmap, grid: 0 == true |
335 // assume we have bitmap device | 411 // assume we have bitmap device |
336 float number; | 412 float number; |
337 if (value && numberValue(value, number)) | 413 if (value && numberValue(value, number)) |
338 return compareValue(static_cast<int>(number), 0, op); | 414 return compareValue(static_cast<int>(number), 0, op); |
339 return false; | 415 return false; |
340 } | 416 } |
341 | 417 |
342 static bool computeLength(CSSValue* value, bool strict, RenderStyle* initialStyl
e, int& result) | 418 static bool computeLength(CSSValue* value, bool strict, RenderStyle* initialStyl
e, int defaultFontSize, int& result) |
343 { | 419 { |
344 if (!value->isPrimitiveValue()) | 420 if (!value->isPrimitiveValue()) |
345 return false; | 421 return false; |
346 | 422 |
347 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); | 423 CSSPrimitiveValue* primitiveValue = toCSSPrimitiveValue(value); |
348 | 424 |
349 if (primitiveValue->isNumber()) { | 425 if (primitiveValue->isNumber()) { |
350 result = primitiveValue->getIntValue(); | 426 result = primitiveValue->getIntValue(); |
351 return !strict || !result; | 427 return !strict || !result; |
352 } | 428 } |
353 | 429 |
354 if (primitiveValue->isLength()) { | 430 if (primitiveValue->isLength()) { |
355 // Relative (like EM) and root relative (like REM) units are always reso
lved against | 431 if (initialStyle) { |
356 // the initial values for media queries, hence the two initialStyle para
meters. | 432 // Relative (like EM) and root relative (like REM) units are always
resolved against |
357 // FIXME: We need to plumb viewport unit support down to here. | 433 // the initial values for media queries, hence the two initialStyle
parameters. |
358 result = primitiveValue->computeLength<int>(CSSToLengthConversionData(in
itialStyle, initialStyle, 0, 1.0 /* zoom */, true /* computingFontSize */)); | 434 // FIXME: We need to plumb viewport unit support down to here. |
| 435 result = primitiveValue->computeLength<int>(CSSToLengthConversionDat
a(initialStyle, initialStyle, 0, 1.0 /* zoom */, true /* computingFontSize */)); |
| 436 } else { |
| 437 unsigned short type = primitiveValue->primitiveType(); |
| 438 int factor = 0; |
| 439 if (type == CSSPrimitiveValue::CSS_EMS || type == CSSPrimitiveValue:
:CSS_REMS) { |
| 440 if (defaultFontSize > 0) |
| 441 factor = defaultFontSize; |
| 442 else |
| 443 return false; |
| 444 } else if (type == CSSPrimitiveValue::CSS_PX) { |
| 445 factor = 1; |
| 446 } else { |
| 447 return false; |
| 448 } |
| 449 result = roundForImpreciseConversion<int>(primitiveValue->getDoubleV
alue()*factor); |
| 450 } |
359 return true; | 451 return true; |
360 } | 452 } |
361 | 453 |
362 return false; | 454 return false; |
363 } | 455 } |
364 | 456 |
365 static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Lo
calFrame* frame, MediaFeaturePrefix op) | 457 static bool deviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Lo
calFrame* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedV
alue) |
366 { | 458 { |
| 459 if ((!frame || !style) && !mediaValues) |
| 460 return expectedValue; |
| 461 int fontSize = 0; |
| 462 if (mediaValues) |
| 463 fontSize = mediaValues->getDefaultFontSize(); |
| 464 |
367 if (value) { | 465 if (value) { |
| 466 int height; |
368 int length; | 467 int length; |
369 if (!computeLength(value, !frame->document()->inQuirksMode(), style, len
gth)) | 468 bool inStrictMode = true; |
370 return false; | 469 if (frame) { |
371 int height = static_cast<int>(screenRect(frame->view()).height()); | 470 height = static_cast<int>(screenRect(frame->view()).height()); |
372 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk()) | 471 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk()) |
373 height = lroundf(height * frame->host()->deviceScaleFactor()); | 472 height = lroundf(height * frame->host()->deviceScaleFactor()); |
374 return compareValue(height, length, op); | 473 inStrictMode = !frame->document()->inQuirksMode(); |
| 474 } else { |
| 475 height = mediaValues->getDeviceHeight(); |
| 476 } |
| 477 return computeLength(value, inStrictMode, style, fontSize, length) && co
mpareValue(static_cast<int>(height), length, op); |
375 } | 478 } |
376 // ({,min-,max-}device-height) | 479 // ({,min-,max-}device-height) |
377 // assume if we have a device, assume non-zero | 480 // assume if we have a device, assume non-zero |
378 return true; | 481 return true; |
379 } | 482 } |
380 | 483 |
381 static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Loc
alFrame* frame, MediaFeaturePrefix op) | 484 static bool deviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, Loc
alFrame* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedVa
lue) |
382 { | 485 { |
| 486 if ((!frame || !style) && !mediaValues) |
| 487 return expectedValue; |
| 488 int fontSize = 0; |
| 489 if (mediaValues) |
| 490 fontSize = mediaValues->getDefaultFontSize(); |
| 491 |
383 if (value) { | 492 if (value) { |
| 493 int width; |
384 int length; | 494 int length; |
385 if (!computeLength(value, !frame->document()->inQuirksMode(), style, len
gth)) | 495 bool inStrictMode = true; |
386 return false; | 496 if (frame) { |
387 int width = static_cast<int>(screenRect(frame->view()).width()); | 497 width = static_cast<int>(screenRect(frame->view()).width()); |
388 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk()) | 498 if (frame->settings()->reportScreenSizeInPhysicalPixelsQuirk()) |
389 width = lroundf(width * frame->host()->deviceScaleFactor()); | 499 width = lroundf(width * frame->host()->deviceScaleFactor()); |
390 return compareValue(width, length, op); | 500 inStrictMode = !frame->document()->inQuirksMode(); |
| 501 } else { |
| 502 width = mediaValues->getDeviceWidth(); |
| 503 } |
| 504 return computeLength(value, inStrictMode, style, fontSize, length) && co
mpareValue(static_cast<int>(width), length, op); |
391 } | 505 } |
392 // ({,min-,max-}device-width) | 506 // ({,min-,max-}device-width) |
393 // assume if we have a device, assume non-zero | 507 // assume if we have a device, assume non-zero |
394 return true; | 508 return true; |
395 } | 509 } |
396 | 510 |
397 static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFra
me* frame, MediaFeaturePrefix op) | 511 static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFra
me* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedValue) |
398 { | 512 { |
| 513 if ((!frame || !style) && !mediaValues) |
| 514 return expectedValue; |
| 515 int fontSize = 0; |
| 516 if (mediaValues) |
| 517 fontSize = mediaValues->getDefaultFontSize(); |
| 518 |
399 FrameView* view = frame->view(); | 519 FrameView* view = frame->view(); |
400 | 520 |
401 int height = viewportSize(view).height(); | 521 int height = viewportSize(view).height(); |
402 if (value) { | 522 if (value) { |
403 if (RenderView* renderView = frame->document()->renderView()) | 523 RenderView* renderView = 0; |
404 height = adjustForAbsoluteZoom(height, renderView); | 524 bool inStrictMode = true; |
| 525 if (frame) { |
| 526 if ((renderView = frame->document()->renderView())) |
| 527 height = adjustForAbsoluteZoom(height, renderView); |
| 528 inStrictMode = !frame->document()->inQuirksMode(); |
| 529 } |
405 int length; | 530 int length; |
406 return computeLength(value, !frame->document()->inQuirksMode(), style, l
ength) && compareValue(height, length, op); | 531 return computeLength(value, inStrictMode, style, fontSize, length) && co
mpareValue(height, length, op); |
407 } | 532 } |
408 | 533 |
409 return height; | 534 return height; |
410 } | 535 } |
411 | 536 |
412 static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFram
e* frame, MediaFeaturePrefix op) | 537 static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalFram
e* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedValue) |
413 { | 538 { |
414 FrameView* view = frame->view(); | 539 if ((!frame || !style) && !mediaValues) |
| 540 return expectedValue; |
| 541 int fontSize = 0; |
| 542 int width; |
| 543 if (mediaValues) |
| 544 fontSize = mediaValues->getDefaultFontSize(); |
415 | 545 |
416 int width = viewportSize(view).width(); | 546 if (frame) { |
| 547 FrameView* view = frame->view(); |
| 548 width = viewportSize(view).width(); |
| 549 } else { |
| 550 width = mediaValues->getViewportWidth(); |
| 551 } |
| 552 |
417 if (value) { | 553 if (value) { |
418 if (RenderView* renderView = frame->document()->renderView()) | 554 RenderView* renderView = 0; |
419 width = adjustForAbsoluteZoom(width, renderView); | 555 bool inStrictMode = true; |
| 556 if (frame) { |
| 557 if ((renderView = frame->document()->renderView())) |
| 558 width = adjustForAbsoluteZoom(width, renderView); |
| 559 inStrictMode = !frame->document()->inQuirksMode(); |
| 560 } |
420 int length; | 561 int length; |
421 return computeLength(value, !frame->document()->inQuirksMode(), style, l
ength) && compareValue(width, length, op); | 562 return computeLength(value, inStrictMode, style, fontSize, length) && co
mpareValue(width, length, op); |
422 } | 563 } |
423 | 564 |
424 return width; | 565 return width; |
425 } | 566 } |
426 | 567 |
427 // Rest of the functions are trampolines which set the prefix according to the m
edia feature expression used. | 568 // Rest of the functions are trampolines which set the prefix according to the m
edia feature expression used. |
428 | 569 |
429 static bool minColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix) | 570 static bool minColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
430 { | 571 { |
431 return colorMediaFeatureEval(value, style, frame, MinPrefix); | 572 return colorMediaFeatureEval(value, style, frame, MinPrefix, mediaValues, ex
pectedValue); |
432 } | 573 } |
433 | 574 |
434 static bool maxColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix) | 575 static bool maxColorMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
435 { | 576 { |
436 return colorMediaFeatureEval(value, style, frame, MaxPrefix); | 577 return colorMediaFeatureEval(value, style, frame, MaxPrefix, mediaValues, ex
pectedValue); |
437 } | 578 } |
438 | 579 |
439 static bool minColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 580 static bool minColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues*, bool expectedValue) |
440 { | 581 { |
441 return colorIndexMediaFeatureEval(value, style, frame, MinPrefix); | 582 return colorIndexMediaFeatureEval(value, style, frame, MinPrefix, 0, expecte
dValue); |
442 } | 583 } |
443 | 584 |
444 static bool maxColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 585 static bool maxColorIndexMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues*, bool expectedValue) |
445 { | 586 { |
446 return colorIndexMediaFeatureEval(value, style, frame, MaxPrefix); | 587 return colorIndexMediaFeatureEval(value, style, frame, MaxPrefix, 0, expecte
dValue); |
447 } | 588 } |
448 | 589 |
449 static bool minMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 590 static bool minMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVal
ue) |
450 { | 591 { |
451 return monochromeMediaFeatureEval(value, style, frame, MinPrefix); | 592 return monochromeMediaFeatureEval(value, style, frame, MinPrefix, mediaValue
s, expectedValue); |
452 } | 593 } |
453 | 594 |
454 static bool maxMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 595 static bool maxMonochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVal
ue) |
455 { | 596 { |
456 return monochromeMediaFeatureEval(value, style, frame, MaxPrefix); | 597 return monochromeMediaFeatureEval(value, style, frame, MaxPrefix, mediaValue
s, expectedValue); |
457 } | 598 } |
458 | 599 |
459 static bool minAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 600 static bool minAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVa
lue) |
460 { | 601 { |
461 return aspectRatioMediaFeatureEval(value, style, frame, MinPrefix); | 602 return aspectRatioMediaFeatureEval(value, style, frame, MinPrefix, mediaValu
es, expectedValue); |
462 } | 603 } |
463 | 604 |
464 static bool maxAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 605 static bool maxAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVa
lue) |
465 { | 606 { |
466 return aspectRatioMediaFeatureEval(value, style, frame, MaxPrefix); | 607 return aspectRatioMediaFeatureEval(value, style, frame, MaxPrefix, mediaValu
es, expectedValue); |
467 } | 608 } |
468 | 609 |
469 static bool minDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* s
tyle, LocalFrame* frame, MediaFeaturePrefix) | 610 static bool minDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* s
tyle, LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expe
ctedValue) |
470 { | 611 { |
471 return deviceAspectRatioMediaFeatureEval(value, style, frame, MinPrefix); | 612 return deviceAspectRatioMediaFeatureEval(value, style, frame, MinPrefix, med
iaValues, expectedValue); |
472 } | 613 } |
473 | 614 |
474 static bool maxDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* s
tyle, LocalFrame* frame, MediaFeaturePrefix) | 615 static bool maxDeviceAspectRatioMediaFeatureEval(CSSValue* value, RenderStyle* s
tyle, LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expe
ctedValue) |
475 { | 616 { |
476 return deviceAspectRatioMediaFeatureEval(value, style, frame, MaxPrefix); | 617 return deviceAspectRatioMediaFeatureEval(value, style, frame, MaxPrefix, med
iaValues, expectedValue); |
477 } | 618 } |
478 | 619 |
479 static bool minDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* st
yle, LocalFrame* frame, MediaFeaturePrefix) | 620 static bool minDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* st
yle, LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expec
tedValue) |
480 { | 621 { |
481 UseCounter::count(frame->document(), UseCounter::PrefixedMinDevicePixelRatio
MediaFeature); | 622 UseCounter::count(frame->document(), UseCounter::PrefixedMinDevicePixelRatio
MediaFeature); |
482 | 623 |
483 return devicePixelRatioMediaFeatureEval(value, style, frame, MinPrefix); | 624 return devicePixelRatioMediaFeatureEval(value, style, frame, MinPrefix, medi
aValues, expectedValue); |
484 } | 625 } |
485 | 626 |
486 static bool maxDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* st
yle, LocalFrame* frame, MediaFeaturePrefix) | 627 static bool maxDevicePixelRatioMediaFeatureEval(CSSValue* value, RenderStyle* st
yle, LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expec
tedValue) |
487 { | 628 { |
488 UseCounter::count(frame->document(), UseCounter::PrefixedMaxDevicePixelRatio
MediaFeature); | 629 UseCounter::count(frame->document(), UseCounter::PrefixedMaxDevicePixelRatio
MediaFeature); |
489 | 630 |
490 return devicePixelRatioMediaFeatureEval(value, style, frame, MaxPrefix); | 631 return devicePixelRatioMediaFeatureEval(value, style, frame, MaxPrefix, medi
aValues, expectedValue); |
491 } | 632 } |
492 | 633 |
493 static bool minHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Local
Frame* frame, MediaFeaturePrefix) | 634 static bool minHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Local
Frame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
494 { | 635 { |
495 return heightMediaFeatureEval(value, style, frame, MinPrefix); | 636 return heightMediaFeatureEval(value, style, frame, MinPrefix, mediaValues, e
xpectedValue); |
496 } | 637 } |
497 | 638 |
498 static bool maxHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Local
Frame* frame, MediaFeaturePrefix) | 639 static bool maxHeightMediaFeatureEval(CSSValue* value, RenderStyle* style, Local
Frame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
499 { | 640 { |
500 return heightMediaFeatureEval(value, style, frame, MaxPrefix); | 641 return heightMediaFeatureEval(value, style, frame, MaxPrefix, mediaValues, e
xpectedValue); |
501 } | 642 } |
502 | 643 |
503 static bool minWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix) | 644 static bool minWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
504 { | 645 { |
505 return widthMediaFeatureEval(value, style, frame, MinPrefix); | 646 return widthMediaFeatureEval(value, style, frame, MinPrefix, mediaValues, ex
pectedValue); |
506 } | 647 } |
507 | 648 |
508 static bool maxWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix) | 649 static bool maxWidthMediaFeatureEval(CSSValue* value, RenderStyle* style, LocalF
rame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
509 { | 650 { |
510 return widthMediaFeatureEval(value, style, frame, MaxPrefix); | 651 return widthMediaFeatureEval(value, style, frame, MaxPrefix, mediaValues, ex
pectedValue); |
511 } | 652 } |
512 | 653 |
513 static bool minDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 654 static bool minDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedV
alue) |
514 { | 655 { |
515 return deviceHeightMediaFeatureEval(value, style, frame, MinPrefix); | 656 return deviceHeightMediaFeatureEval(value, style, frame, MinPrefix, mediaVal
ues, expectedValue); |
516 } | 657 } |
517 | 658 |
518 static bool maxDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 659 static bool maxDeviceHeightMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedV
alue) |
519 { | 660 { |
520 return deviceHeightMediaFeatureEval(value, style, frame, MaxPrefix); | 661 return deviceHeightMediaFeatureEval(value, style, frame, MaxPrefix, mediaVal
ues, expectedValue); |
521 } | 662 } |
522 | 663 |
523 static bool minDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 664 static bool minDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVa
lue) |
524 { | 665 { |
525 return deviceWidthMediaFeatureEval(value, style, frame, MinPrefix); | 666 return deviceWidthMediaFeatureEval(value, style, frame, MinPrefix, mediaValu
es, expectedValue); |
526 } | 667 } |
527 | 668 |
528 static bool maxDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix) | 669 static bool maxDeviceWidthMediaFeatureEval(CSSValue* value, RenderStyle* style,
LocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVa
lue) |
529 { | 670 { |
530 return deviceWidthMediaFeatureEval(value, style, frame, MaxPrefix); | 671 return deviceWidthMediaFeatureEval(value, style, frame, MaxPrefix, mediaValu
es, expectedValue); |
531 } | 672 } |
532 | 673 |
533 static bool minResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 674 static bool minResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVal
ue) |
534 { | 675 { |
535 return resolutionMediaFeatureEval(value, style, frame, MinPrefix); | 676 return resolutionMediaFeatureEval(value, style, frame, MinPrefix, mediaValue
s, expectedValue); |
536 } | 677 } |
537 | 678 |
538 static bool maxResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix) | 679 static bool maxResolutionMediaFeatureEval(CSSValue* value, RenderStyle* style, L
ocalFrame* frame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedVal
ue) |
539 { | 680 { |
540 return resolutionMediaFeatureEval(value, style, frame, MaxPrefix); | 681 return resolutionMediaFeatureEval(value, style, frame, MaxPrefix, mediaValue
s, expectedValue); |
541 } | 682 } |
542 | 683 |
543 static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*
frame, MediaFeaturePrefix op) | 684 static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*
frame, MediaFeaturePrefix op, MediaValues*, bool) |
544 { | 685 { |
545 UseCounter::count(frame->document(), UseCounter::PrefixedAnimationMediaFeatu
re); | 686 UseCounter::count(frame->document(), UseCounter::PrefixedAnimationMediaFeatu
re); |
546 | 687 |
547 if (value) { | 688 if (value) { |
548 float number; | 689 float number; |
549 return numberValue(value, number) && compareValue(1, static_cast<int>(nu
mber), op); | 690 return numberValue(value, number) && compareValue(1, static_cast<int>(nu
mber), op); |
550 } | 691 } |
551 return true; | 692 return true; |
552 } | 693 } |
553 | 694 |
554 static bool transform2dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op) | 695 static bool transform2dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op, MediaValues*, bool) |
555 { | 696 { |
556 UseCounter::count(frame->document(), UseCounter::PrefixedTransform2dMediaFea
ture); | 697 UseCounter::count(frame->document(), UseCounter::PrefixedTransform2dMediaFea
ture); |
557 | 698 |
558 if (value) { | 699 if (value) { |
559 float number; | 700 float number; |
560 return numberValue(value, number) && compareValue(1, static_cast<int>(nu
mber), op); | 701 return numberValue(value, number) && compareValue(1, static_cast<int>(nu
mber), op); |
561 } | 702 } |
562 return true; | 703 return true; |
563 } | 704 } |
564 | 705 |
565 static bool transform3dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op) | 706 static bool transform3dMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFram
e* frame, MediaFeaturePrefix op, MediaValues* mediaValues, bool expectedValue) |
566 { | 707 { |
567 UseCounter::count(frame->document(), UseCounter::PrefixedTransform3dMediaFea
ture); | 708 UseCounter::count(frame->document(), UseCounter::PrefixedTransform3dMediaFea
ture); |
568 | 709 |
| 710 // TODO: Not implementing mediaValues yet |
| 711 |
| 712 if (!frame && !mediaValues) |
| 713 return expectedValue; |
| 714 |
569 bool returnValueIfNoParameter; | 715 bool returnValueIfNoParameter; |
570 int have3dRendering; | 716 int have3dRendering; |
571 | 717 |
572 bool threeDEnabled = false; | 718 bool threeDEnabled = false; |
573 if (RenderView* view = frame->contentRenderer()) | 719 if (frame) { |
574 threeDEnabled = view->compositor()->canRender3DTransforms(); | 720 if (RenderView* view = frame->contentRenderer()) |
| 721 threeDEnabled = view->compositor()->canRender3DTransforms(); |
| 722 } else { |
| 723 threeDEnabled = mediaValues->getThreeDEnabled(); |
| 724 } |
575 | 725 |
576 returnValueIfNoParameter = threeDEnabled; | 726 returnValueIfNoParameter = threeDEnabled; |
577 have3dRendering = threeDEnabled ? 1 : 0; | 727 have3dRendering = threeDEnabled ? 1 : 0; |
578 | 728 |
579 if (value) { | 729 if (value) { |
580 float number; | 730 float number; |
581 return numberValue(value, number) && compareValue(have3dRendering, stati
c_cast<int>(number), op); | 731 return numberValue(value, number) && compareValue(have3dRendering, stati
c_cast<int>(number), op); |
582 } | 732 } |
583 return returnValueIfNoParameter; | 733 return returnValueIfNoParameter; |
584 } | 734 } |
585 | 735 |
586 static bool viewModeMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*
frame, MediaFeaturePrefix) | 736 static bool viewModeMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame*
frame, MediaFeaturePrefix, MediaValues*, bool) |
587 { | 737 { |
588 UseCounter::count(frame->document(), UseCounter::PrefixedViewModeMediaFeatur
e); | 738 UseCounter::count(frame->document(), UseCounter::PrefixedViewModeMediaFeatur
e); |
589 | 739 |
590 if (!value) | 740 if (!value) |
591 return true; | 741 return true; |
592 | 742 |
593 return toCSSPrimitiveValue(value)->getValueID() == CSSValueWindowed; | 743 return toCSSPrimitiveValue(value)->getValueID() == CSSValueWindowed; |
594 } | 744 } |
595 | 745 |
596 enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer }
; | 746 enum PointerDeviceType { TouchPointer, MousePointer, NoPointer, UnknownPointer }
; |
597 | 747 |
598 static PointerDeviceType leastCapablePrimaryPointerDeviceType(LocalFrame* frame) | 748 static PointerDeviceType leastCapablePrimaryPointerDeviceType(LocalFrame* frame) |
599 { | 749 { |
600 if (frame->settings()->deviceSupportsTouch()) | 750 if (frame->settings()->deviceSupportsTouch()) |
601 return TouchPointer; | 751 return TouchPointer; |
602 | 752 |
603 // FIXME: We should also try to determine if we know we have a mouse. | 753 // FIXME: We should also try to determine if we know we have a mouse. |
604 // When we do this, we'll also need to differentiate between known not to | 754 // When we do this, we'll also need to differentiate between known not to |
605 // have mouse or touch screen (NoPointer) and unknown (UnknownPointer). | 755 // have mouse or touch screen (NoPointer) and unknown (UnknownPointer). |
606 // We could also take into account other preferences like accessibility | 756 // We could also take into account other preferences like accessibility |
607 // settings to decide which of the available pointers should be considered | 757 // settings to decide which of the available pointers should be considered |
608 // "primary". | 758 // "primary". |
609 | 759 |
610 return UnknownPointer; | 760 return UnknownPointer; |
611 } | 761 } |
612 | 762 |
613 static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fra
me, MediaFeaturePrefix) | 763 static bool hoverMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fra
me, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
614 { | 764 { |
615 PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame); | 765 if (!frame && !mediaValues) |
| 766 return expectedValue; |
| 767 |
| 768 PointerDeviceType pointer; |
| 769 if (frame) |
| 770 pointer = leastCapablePrimaryPointerDeviceType(frame); |
| 771 else |
| 772 pointer = static_cast<PointerDeviceType>(mediaValues->getPointer()); |
616 | 773 |
617 // If we're on a port that hasn't explicitly opted into providing pointer de
vice information | 774 // If we're on a port that hasn't explicitly opted into providing pointer de
vice information |
618 // (or otherwise can't be confident in the pointer hardware available), then
behave exactly | 775 // (or otherwise can't be confident in the pointer hardware available), then
behave exactly |
619 // as if this feature feature isn't supported. | 776 // as if this feature feature isn't supported. |
620 if (pointer == UnknownPointer) | 777 if (pointer == UnknownPointer) |
621 return false; | 778 return false; |
622 | 779 |
623 float number = 1; | 780 float number = 1; |
624 if (value) { | 781 if (value) { |
625 if (!numberValue(value, number)) | 782 if (!numberValue(value, number)) |
626 return false; | 783 return false; |
627 } | 784 } |
628 | 785 |
629 return (pointer == NoPointer && !number) | 786 return (pointer == NoPointer && !number) |
630 || (pointer == TouchPointer && !number) | 787 || (pointer == TouchPointer && !number) |
631 || (pointer == MousePointer && number == 1); | 788 || (pointer == MousePointer && number == 1); |
632 } | 789 } |
633 | 790 |
634 static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* f
rame, MediaFeaturePrefix) | 791 static bool pointerMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* f
rame, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
635 { | 792 { |
636 PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame); | 793 if (!frame && !mediaValues) |
| 794 return expectedValue; |
| 795 |
| 796 PointerDeviceType pointer; |
| 797 if (frame) |
| 798 pointer = leastCapablePrimaryPointerDeviceType(frame); |
| 799 else |
| 800 pointer = static_cast<PointerDeviceType>(mediaValues->getPointer()); |
637 | 801 |
638 // If we're on a port that hasn't explicitly opted into providing pointer de
vice information | 802 // If we're on a port that hasn't explicitly opted into providing pointer de
vice information |
639 // (or otherwise can't be confident in the pointer hardware available), then
behave exactly | 803 // (or otherwise can't be confident in the pointer hardware available), then
behave exactly |
640 // as if this feature feature isn't supported. | 804 // as if this feature feature isn't supported. |
641 if (pointer == UnknownPointer) | 805 if (pointer == UnknownPointer) |
642 return false; | 806 return false; |
643 | 807 |
644 if (!value) | 808 if (!value) |
645 return pointer != NoPointer; | 809 return pointer != NoPointer; |
646 | 810 |
647 if (!value->isPrimitiveValue()) | 811 if (!value->isPrimitiveValue()) |
648 return false; | 812 return false; |
649 | 813 |
650 const CSSValueID id = toCSSPrimitiveValue(value)->getValueID(); | 814 const CSSValueID id = toCSSPrimitiveValue(value)->getValueID(); |
651 return (pointer == NoPointer && id == CSSValueNone) | 815 return (pointer == NoPointer && id == CSSValueNone) |
652 || (pointer == TouchPointer && id == CSSValueCoarse) | 816 || (pointer == TouchPointer && id == CSSValueCoarse) |
653 || (pointer == MousePointer && id == CSSValueFine); | 817 || (pointer == MousePointer && id == CSSValueFine); |
654 } | 818 } |
655 | 819 |
656 static bool scanMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fram
e, MediaFeaturePrefix) | 820 static bool scanMediaFeatureEval(CSSValue* value, RenderStyle*, LocalFrame* fram
e, MediaFeaturePrefix, MediaValues* mediaValues, bool expectedValue) |
657 { | 821 { |
| 822 if (!frame && !mediaValues) |
| 823 return expectedValue; |
| 824 |
658 // Scan only applies to 'tv' media. | 825 // Scan only applies to 'tv' media. |
| 826 String mediaType; |
| 827 if (frame) |
| 828 mediaType = frame->view()->mediaType(); |
| 829 else |
| 830 mediaType = mediaValues->getMediaType(); |
| 831 |
659 if (!equalIgnoringCase(frame->view()->mediaType(), "tv")) | 832 if (!equalIgnoringCase(frame->view()->mediaType(), "tv")) |
660 return false; | 833 return false; |
661 | 834 |
662 if (!value) | 835 if (!value) |
663 return true; | 836 return true; |
664 | 837 |
665 if (!value->isPrimitiveValue()) | 838 if (!value->isPrimitiveValue()) |
666 return false; | 839 return false; |
667 | 840 |
668 // If a platform interface supplies progressive/interlace info for TVs in th
e | 841 // If a platform interface supplies progressive/interlace info for TVs in th
e |
669 // future, it needs to be handled here. For now, assume a modern TV with | 842 // future, it needs to be handled here. For now, assume a modern TV with |
670 // progressive display. | 843 // progressive display. |
671 return toCSSPrimitiveValue(value)->getValueID() == CSSValueProgressive; | 844 return toCSSPrimitiveValue(value)->getValueID() == CSSValueProgressive; |
672 } | 845 } |
673 | 846 |
674 static void createFunctionMap() | 847 static void createFunctionMap() |
675 { | 848 { |
676 // Create the table. | 849 // Create the table. |
677 gFunctionMap = new FunctionMap; | 850 gFunctionMap = new FunctionMap; |
678 #define ADD_TO_FUNCTIONMAP(name) \ | 851 #define ADD_TO_FUNCTIONMAP(name) \ |
679 gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval); | 852 gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval); |
680 CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP); | 853 CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP); |
681 #undef ADD_TO_FUNCTIONMAP | 854 #undef ADD_TO_FUNCTIONMAP |
682 } | 855 } |
683 | 856 |
684 bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const | 857 bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const |
685 { | 858 { |
686 if (!m_frame || !m_style) | 859 if (!m_mediaValues && (!m_frame || !m_style)) |
687 return m_expResult; | 860 return m_expResult; |
688 | 861 |
689 if (!gFunctionMap) | 862 if (!gFunctionMap) |
690 createFunctionMap(); | 863 createFunctionMap(); |
691 | 864 |
692 // Call the media feature evaluation function. Assume no prefix and let | 865 // Call the media feature evaluation function. Assume no prefix and let |
693 // trampoline functions override the prefix if prefix is used. | 866 // trampoline functions override the prefix if prefix is used. |
694 EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl()); | 867 EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl()); |
695 if (func) | 868 if (func) |
696 return func(expr->value(), m_style.get(), m_frame, NoPrefix); | 869 return func(expr->value(), m_style.get(), m_frame, NoPrefix, m_mediaValu
es.get(), m_expResult); |
697 | 870 |
698 return false; | 871 return false; |
699 } | 872 } |
700 | 873 |
| 874 PassRefPtr<MediaValues> MediaValues::create(Document* document) |
| 875 { |
| 876 Document* executingDocument = document->import() ? document->import()->maste
r() : document; |
| 877 ASSERT(executingDocument->frame()); |
| 878 ASSERT(executingDocument->renderer()); |
| 879 ASSERT(executingDocument->renderer()->style()); |
| 880 LocalFrame* frame = executingDocument->frame(); |
| 881 RenderStyle* style = executingDocument->renderer()->style(); |
| 882 |
| 883 // get the values from Frame and Style |
| 884 FrameView* view = frame->view(); |
| 885 RenderView* renderView = frame->document()->renderView(); |
| 886 int viewportWidth = viewportSize(view).width(); |
| 887 int viewportHeight = viewportSize(view).height(); |
| 888 FloatRect sg = screenRect(frame->page()->mainFrame()->view()); |
| 889 int deviceWidth = static_cast<int>(sg.width()); |
| 890 int deviceHeight = static_cast<int>(sg.height()); |
| 891 float pixelRatio = frame->page()->deviceScaleFactor(); |
| 892 int bitsPerComponent = screenDepthPerComponent(frame->page()->mainFrame()->v
iew()); |
| 893 int colorBitsPerComponent = 0; |
| 894 int monochromeBitsPerComponent = 0; |
| 895 int defaultFontSize = style->fontDescription().specifiedSize(); |
| 896 bool threeDEnabled = false; |
| 897 String mediaType = frame->view()->mediaType(); |
| 898 if (renderView) { |
| 899 viewportWidth = adjustForAbsoluteZoom(viewportWidth, renderView); |
| 900 viewportHeight = adjustForAbsoluteZoom(viewportHeight, renderView); |
| 901 } |
| 902 if (RenderView* view = frame->contentRenderer()) |
| 903 threeDEnabled = view->compositor()->canRender3DTransforms(); |
| 904 if (screenIsMonochrome(frame->page()->mainFrame()->view())) |
| 905 monochromeBitsPerComponent = bitsPerComponent; |
| 906 else |
| 907 colorBitsPerComponent = bitsPerComponent; |
| 908 PointerDeviceType pointer = leastCapablePrimaryPointerDeviceType(frame); |
| 909 |
| 910 return adoptRefWillBeRefCountedGarbageCollected(new MediaValues(viewportWidt
h, |
| 911 viewportHeight, |
| 912 deviceWidth, |
| 913 deviceHeight, |
| 914 pixelRatio, |
| 915 colorBitsPerComponent, |
| 916 monochromeBitsPerComponent, |
| 917 pointer, |
| 918 defaultFontSize, |
| 919 threeDEnabled, |
| 920 mediaType)); |
| 921 } |
| 922 |
| 923 PassRefPtr<MediaValues> MediaValues::copy(const MediaValues* mediaValues) |
| 924 { |
| 925 return adoptRefWillBeRefCountedGarbageCollected(new MediaValues(mediaValues-
>m_viewportWidth, |
| 926 mediaValues->m_viewportHeight, |
| 927 mediaValues->m_deviceWidth, |
| 928 mediaValues->m_deviceHeight, |
| 929 mediaValues->m_pixelRatio, |
| 930 mediaValues->m_colorBitsPerComponent, |
| 931 mediaValues->m_monochromeBitsPerComponent, |
| 932 mediaValues->m_pointer, |
| 933 mediaValues->m_defaultFontSize, |
| 934 mediaValues->m_threeDEnabled, |
| 935 mediaValues->m_mediaType)); |
| 936 } |
| 937 |
701 } // namespace | 938 } // namespace |
OLD | NEW |