|
1 /* |
|
2 * CSS Media Query Evaluator |
|
3 * |
|
4 * Copyright (C) 2006 Kimmo Kinnunen <kimmo.t.kinnunen@nokia.com>. |
|
5 * |
|
6 * Redistribution and use in source and binary forms, with or without |
|
7 * modification, are permitted provided that the following conditions |
|
8 * are met: |
|
9 * 1. Redistributions of source code must retain the above copyright |
|
10 * notice, this list of conditions and the following disclaimer. |
|
11 * 2. Redistributions in binary form must reproduce the above copyright |
|
12 * notice, this list of conditions and the following disclaimer in the |
|
13 * documentation and/or other materials provided with the distribution. |
|
14 * |
|
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY |
|
16 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
|
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
18 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR |
|
19 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, |
|
20 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, |
|
21 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR |
|
22 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY |
|
23 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
|
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
|
25 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
|
26 */ |
|
27 |
|
28 #include "config.h" |
|
29 #include "MediaQueryEvaluator.h" |
|
30 |
|
31 #include "Chrome.h" |
|
32 #include "ChromeClient.h" |
|
33 #include "CSSPrimitiveValue.h" |
|
34 #include "CSSStyleSelector.h" |
|
35 #include "CSSValueList.h" |
|
36 #include "FloatRect.h" |
|
37 #include "Frame.h" |
|
38 #include "FrameView.h" |
|
39 #include "IntRect.h" |
|
40 #include "MediaFeatureNames.h" |
|
41 #include "MediaList.h" |
|
42 #include "MediaQuery.h" |
|
43 #include "MediaQueryExp.h" |
|
44 #include "NodeRenderStyle.h" |
|
45 #include "Page.h" |
|
46 #include "RenderView.h" |
|
47 #include "RenderStyle.h" |
|
48 #include "PlatformScreen.h" |
|
49 #include <wtf/HashMap.h> |
|
50 |
|
51 #if ENABLE(3D_RENDERING) && USE(ACCELERATED_COMPOSITING) |
|
52 #include "RenderLayerCompositor.h" |
|
53 #endif |
|
54 |
|
55 namespace WebCore { |
|
56 |
|
57 using namespace MediaFeatureNames; |
|
58 |
|
59 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix }; |
|
60 |
|
61 typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*, MediaFeaturePrefix); |
|
62 typedef HashMap<AtomicStringImpl*, EvalFunc> FunctionMap; |
|
63 static FunctionMap* gFunctionMap; |
|
64 |
|
65 /* |
|
66 * FIXME: following media features are not implemented: color_index, scan, resolution |
|
67 * |
|
68 * color_index, min-color-index, max_color_index: It's unknown how to retrieve |
|
69 * the information if the display mode is indexed |
|
70 * scan: The "scan" media feature describes the scanning process of |
|
71 * tv output devices. It's unknown how to retrieve this information from |
|
72 * the platform |
|
73 * resolution, min-resolution, max-resolution: css parser doesn't seem to |
|
74 * support CSS_DIMENSION |
|
75 */ |
|
76 |
|
77 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult) |
|
78 : m_frame(0) |
|
79 , m_style(0) |
|
80 , m_expResult(mediaFeatureResult) |
|
81 { |
|
82 } |
|
83 |
|
84 MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult) |
|
85 : m_mediaType(acceptedMediaType) |
|
86 , m_frame(0) |
|
87 , m_style(0) |
|
88 , m_expResult(mediaFeatureResult) |
|
89 { |
|
90 } |
|
91 |
|
92 MediaQueryEvaluator:: MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult) |
|
93 : m_mediaType(acceptedMediaType) |
|
94 , m_frame(0) |
|
95 , m_style(0) |
|
96 , m_expResult(mediaFeatureResult) |
|
97 { |
|
98 } |
|
99 |
|
100 MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, Frame* frame, RenderStyle* style) |
|
101 : m_mediaType(acceptedMediaType) |
|
102 , m_frame(frame) |
|
103 , m_style(style) |
|
104 , m_expResult(false) // doesn't matter when we have m_frame and m_style |
|
105 { |
|
106 } |
|
107 |
|
108 MediaQueryEvaluator::~MediaQueryEvaluator() |
|
109 { |
|
110 } |
|
111 |
|
112 bool MediaQueryEvaluator::mediaTypeMatch(const String& mediaTypeToMatch) const |
|
113 { |
|
114 return mediaTypeToMatch.isEmpty() |
|
115 || equalIgnoringCase(mediaTypeToMatch, "all") |
|
116 || equalIgnoringCase(mediaTypeToMatch, m_mediaType); |
|
117 } |
|
118 |
|
119 bool MediaQueryEvaluator::mediaTypeMatchSpecific(const char* mediaTypeToMatch) const |
|
120 { |
|
121 // Like mediaTypeMatch, but without the special cases for "" and "all". |
|
122 ASSERT(mediaTypeToMatch); |
|
123 ASSERT(mediaTypeToMatch[0] != '\0'); |
|
124 ASSERT(!equalIgnoringCase(mediaTypeToMatch, String("all"))); |
|
125 return equalIgnoringCase(mediaTypeToMatch, m_mediaType); |
|
126 } |
|
127 |
|
128 static bool applyRestrictor(MediaQuery::Restrictor r, bool value) |
|
129 { |
|
130 return r == MediaQuery::Not ? !value : value; |
|
131 } |
|
132 |
|
133 bool MediaQueryEvaluator::eval(const MediaList* mediaList, CSSStyleSelector* styleSelector) const |
|
134 { |
|
135 if (!mediaList) |
|
136 return true; |
|
137 |
|
138 const Vector<MediaQuery*>& queries = mediaList->mediaQueries(); |
|
139 if (!queries.size()) |
|
140 return true; // empty query list evaluates to true |
|
141 |
|
142 // iterate over queries, stop if any of them eval to true (OR semantics) |
|
143 bool result = false; |
|
144 for (size_t i = 0; i < queries.size() && !result; ++i) { |
|
145 MediaQuery* query = queries.at(i); |
|
146 |
|
147 if (query->ignored()) |
|
148 continue; |
|
149 |
|
150 if (mediaTypeMatch(query->mediaType())) { |
|
151 const Vector<MediaQueryExp*>* exps = query->expressions(); |
|
152 // iterate through expressions, stop if any of them eval to false |
|
153 // (AND semantics) |
|
154 size_t j = 0; |
|
155 for (; j < exps->size(); ++j) { |
|
156 bool exprResult = eval(exps->at(j)); |
|
157 if (styleSelector && exps->at(j)->isViewportDependent()) |
|
158 styleSelector->addViewportDependentMediaQueryResult(exps->at(j), exprResult); |
|
159 if (!exprResult) |
|
160 break; |
|
161 } |
|
162 |
|
163 // assume true if we are at the end of the list, |
|
164 // otherwise assume false |
|
165 result = applyRestrictor(query->restrictor(), exps->size() == j); |
|
166 } else |
|
167 result = applyRestrictor(query->restrictor(), false); |
|
168 } |
|
169 |
|
170 return result; |
|
171 } |
|
172 |
|
173 static bool parseAspectRatio(CSSValue* value, int& h, int& v) |
|
174 { |
|
175 if (value->isValueList()) { |
|
176 CSSValueList* valueList = static_cast<CSSValueList*>(value); |
|
177 if (valueList->length() == 3) { |
|
178 CSSValue* i0 = valueList->itemWithoutBoundsCheck(0); |
|
179 CSSValue* i1 = valueList->itemWithoutBoundsCheck(1); |
|
180 CSSValue* i2 = valueList->itemWithoutBoundsCheck(2); |
|
181 if (i0->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i0)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER |
|
182 && i1->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i1)->primitiveType() == CSSPrimitiveValue::CSS_STRING |
|
183 && i2->isPrimitiveValue() && static_cast<CSSPrimitiveValue*>(i2)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) { |
|
184 String str = static_cast<CSSPrimitiveValue*>(i1)->getStringValue(); |
|
185 if (!str.isNull() && str.length() == 1 && str[0] == '/') { |
|
186 h = static_cast<CSSPrimitiveValue*>(i0)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); |
|
187 v = static_cast<CSSPrimitiveValue*>(i2)->getIntValue(CSSPrimitiveValue::CSS_NUMBER); |
|
188 return true; |
|
189 } |
|
190 } |
|
191 } |
|
192 } |
|
193 return false; |
|
194 } |
|
195 |
|
196 template<typename T> |
|
197 bool compareValue(T a, T b, MediaFeaturePrefix op) |
|
198 { |
|
199 switch (op) { |
|
200 case MinPrefix: |
|
201 return a >= b; |
|
202 case MaxPrefix: |
|
203 return a <= b; |
|
204 case NoPrefix: |
|
205 return a == b; |
|
206 } |
|
207 return false; |
|
208 } |
|
209 |
|
210 static bool numberValue(CSSValue* value, float& result) |
|
211 { |
|
212 if (value->isPrimitiveValue() |
|
213 && static_cast<CSSPrimitiveValue*>(value)->primitiveType() == CSSPrimitiveValue::CSS_NUMBER) { |
|
214 result = static_cast<CSSPrimitiveValue*>(value)->getFloatValue(CSSPrimitiveValue::CSS_NUMBER); |
|
215 return true; |
|
216 } |
|
217 return false; |
|
218 } |
|
219 |
|
220 static bool colorMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
221 { |
|
222 int bitsPerComponent = screenDepthPerComponent(frame->page()->mainFrame()->view()); |
|
223 float number; |
|
224 if (value) |
|
225 return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op); |
|
226 |
|
227 return bitsPerComponent != 0; |
|
228 } |
|
229 |
|
230 static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) |
|
231 { |
|
232 if (!screenIsMonochrome(frame->page()->mainFrame()->view())) { |
|
233 if (value) { |
|
234 float number; |
|
235 return numberValue(value, number) && compareValue(0, static_cast<int>(number), op); |
|
236 } |
|
237 return false; |
|
238 } |
|
239 |
|
240 return colorMediaFeatureEval(value, style, frame, op); |
|
241 } |
|
242 |
|
243 static bool orientationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix) |
|
244 { |
|
245 // A missing parameter should fail |
|
246 if (!value) |
|
247 return false; |
|
248 |
|
249 FrameView* view = frame->view(); |
|
250 int width = view->layoutWidth(); |
|
251 int height = view->layoutHeight(); |
|
252 if (width > height) // Square viewport is portrait |
|
253 return "landscape" == static_cast<CSSPrimitiveValue*>(value)->getStringValue(); |
|
254 return "portrait" == static_cast<CSSPrimitiveValue*>(value)->getStringValue(); |
|
255 } |
|
256 |
|
257 static bool aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
258 { |
|
259 if (value) { |
|
260 FrameView* view = frame->view(); |
|
261 int width = view->layoutWidth(); |
|
262 int height = view->layoutHeight(); |
|
263 int h = 0; |
|
264 int v = 0; |
|
265 if (parseAspectRatio(value, h, v)) |
|
266 return v != 0 && compareValue(width * v, height * h, op); |
|
267 return false; |
|
268 } |
|
269 |
|
270 // ({,min-,max-}aspect-ratio) |
|
271 // assume if we have a device, its aspect ratio is non-zero |
|
272 return true; |
|
273 } |
|
274 |
|
275 static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
276 { |
|
277 if (value) { |
|
278 FloatRect sg = screenRect(frame->page()->mainFrame()->view()); |
|
279 int h = 0; |
|
280 int v = 0; |
|
281 if (parseAspectRatio(value, h, v)) |
|
282 return v != 0 && compareValue(static_cast<int>(sg.width()) * v, static_cast<int>(sg.height()) * h, op); |
|
283 return false; |
|
284 } |
|
285 |
|
286 // ({,min-,max-}device-aspect-ratio) |
|
287 // assume if we have a device, its aspect ratio is non-zero |
|
288 return true; |
|
289 } |
|
290 |
|
291 static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
292 { |
|
293 if (value) |
|
294 return value->isPrimitiveValue() && compareValue(frame->page()->chrome()->scaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op); |
|
295 |
|
296 return frame->page()->chrome()->scaleFactor() != 0; |
|
297 } |
|
298 |
|
299 static bool gridMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op) |
|
300 { |
|
301 // if output device is bitmap, grid: 0 == true |
|
302 // assume we have bitmap device |
|
303 float number; |
|
304 if (value && numberValue(value, number)) |
|
305 return compareValue(static_cast<int>(number), 0, op); |
|
306 return false; |
|
307 } |
|
308 |
|
309 static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) |
|
310 { |
|
311 if (value) { |
|
312 FloatRect sg = screenRect(frame->page()->mainFrame()->view()); |
|
313 RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle(); |
|
314 return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.height()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op); |
|
315 } |
|
316 // ({,min-,max-}device-height) |
|
317 // assume if we have a device, assume non-zero |
|
318 return true; |
|
319 } |
|
320 |
|
321 static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) |
|
322 { |
|
323 if (value) { |
|
324 FloatRect sg = screenRect(frame->page()->mainFrame()->view()); |
|
325 RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle(); |
|
326 return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.width()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op); |
|
327 } |
|
328 // ({,min-,max-}device-width) |
|
329 // assume if we have a device, assume non-zero |
|
330 return true; |
|
331 } |
|
332 |
|
333 static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) |
|
334 { |
|
335 FrameView* view = frame->view(); |
|
336 RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle(); |
|
337 |
|
338 if (value) |
|
339 return value->isPrimitiveValue() && compareValue(view->layoutHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op); |
|
340 |
|
341 return view->layoutHeight() != 0; |
|
342 } |
|
343 |
|
344 static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op) |
|
345 { |
|
346 FrameView* view = frame->view(); |
|
347 RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle(); |
|
348 |
|
349 if (value) |
|
350 return value->isPrimitiveValue() && compareValue(view->layoutWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style, rootStyle), op); |
|
351 |
|
352 return view->layoutWidth() != 0; |
|
353 } |
|
354 |
|
355 // rest of the functions are trampolines which set the prefix according to the media feature expression used |
|
356 |
|
357 static bool min_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
358 { |
|
359 return colorMediaFeatureEval(value, style, frame, MinPrefix); |
|
360 } |
|
361 |
|
362 static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
363 { |
|
364 return colorMediaFeatureEval(value, style, frame, MaxPrefix); |
|
365 } |
|
366 |
|
367 static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
368 { |
|
369 return monochromeMediaFeatureEval(value, style, frame, MinPrefix); |
|
370 } |
|
371 |
|
372 static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
373 { |
|
374 return monochromeMediaFeatureEval(value, style, frame, MaxPrefix); |
|
375 } |
|
376 |
|
377 static bool min_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
378 { |
|
379 return aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix); |
|
380 } |
|
381 |
|
382 static bool max_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
383 { |
|
384 return aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix); |
|
385 } |
|
386 |
|
387 static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
388 { |
|
389 return device_aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix); |
|
390 } |
|
391 |
|
392 static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
393 { |
|
394 return device_aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix); |
|
395 } |
|
396 |
|
397 static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
398 { |
|
399 return device_pixel_ratioMediaFeatureEval(value, style, frame, MinPrefix); |
|
400 } |
|
401 |
|
402 static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
403 { |
|
404 return device_pixel_ratioMediaFeatureEval(value, style, frame, MaxPrefix); |
|
405 } |
|
406 |
|
407 static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
408 { |
|
409 return heightMediaFeatureEval(value, style, frame, MinPrefix); |
|
410 } |
|
411 |
|
412 static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
413 { |
|
414 return heightMediaFeatureEval(value, style, frame, MaxPrefix); |
|
415 } |
|
416 |
|
417 static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
418 { |
|
419 return widthMediaFeatureEval(value, style, frame, MinPrefix); |
|
420 } |
|
421 |
|
422 static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
423 { |
|
424 return widthMediaFeatureEval(value, style, frame, MaxPrefix); |
|
425 } |
|
426 |
|
427 static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
428 { |
|
429 return device_heightMediaFeatureEval(value, style, frame, MinPrefix); |
|
430 } |
|
431 |
|
432 static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
433 { |
|
434 return device_heightMediaFeatureEval(value, style, frame, MaxPrefix); |
|
435 } |
|
436 |
|
437 static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
438 { |
|
439 return device_widthMediaFeatureEval(value, style, frame, MinPrefix); |
|
440 } |
|
441 |
|
442 static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame, MediaFeaturePrefix) |
|
443 { |
|
444 return device_widthMediaFeatureEval(value, style, frame, MaxPrefix); |
|
445 } |
|
446 |
|
447 static bool animationMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op) |
|
448 { |
|
449 if (value) { |
|
450 float number; |
|
451 return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); |
|
452 } |
|
453 return true; |
|
454 } |
|
455 |
|
456 static bool transitionMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op) |
|
457 { |
|
458 if (value) { |
|
459 float number; |
|
460 return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); |
|
461 } |
|
462 return true; |
|
463 } |
|
464 |
|
465 static bool transform_2dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame*, MediaFeaturePrefix op) |
|
466 { |
|
467 if (value) { |
|
468 float number; |
|
469 return numberValue(value, number) && compareValue(1, static_cast<int>(number), op); |
|
470 } |
|
471 return true; |
|
472 } |
|
473 |
|
474 static bool transform_3dMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
475 { |
|
476 bool returnValueIfNoParameter; |
|
477 int have3dRendering; |
|
478 |
|
479 #if ENABLE(3D_RENDERING) |
|
480 bool threeDEnabled = false; |
|
481 #if USE(ACCELERATED_COMPOSITING) |
|
482 if (RenderView* view = frame->contentRenderer()) |
|
483 threeDEnabled = view->compositor()->hasAcceleratedCompositing(); |
|
484 #endif |
|
485 |
|
486 returnValueIfNoParameter = threeDEnabled; |
|
487 have3dRendering = threeDEnabled ? 1 : 0; |
|
488 #else |
|
489 UNUSED_PARAM(frame); |
|
490 returnValueIfNoParameter = false; |
|
491 have3dRendering = 0; |
|
492 #endif |
|
493 |
|
494 if (value) { |
|
495 float number; |
|
496 return numberValue(value, number) && compareValue(have3dRendering, static_cast<int>(number), op); |
|
497 } |
|
498 return returnValueIfNoParameter; |
|
499 } |
|
500 |
|
501 #if ENABLE(WIDGETS_10_SUPPORT) |
|
502 static bool view_modeMediaFeatureEval(CSSValue* value, RenderStyle*, Frame* frame, MediaFeaturePrefix op) |
|
503 { |
|
504 if (value) { |
|
505 String mode = static_cast<CSSPrimitiveValue*>(value)->getStringValue(); |
|
506 if (ChromeClient* client = frame->page()->chrome()->client()) { |
|
507 if (mode == "windowed" && client->isWindowed()) |
|
508 return true; |
|
509 if (mode == "floating" && client->isFloating()) |
|
510 return true; |
|
511 if (mode == "fullscreen" && client->isFullscreen()) |
|
512 return true; |
|
513 if (mode == "maximized" && client->isMaximized()) |
|
514 return true; |
|
515 if (mode == "minimized" && client->isMinimized()) |
|
516 return true; |
|
517 return false; |
|
518 } |
|
519 } |
|
520 return true; |
|
521 } |
|
522 #endif |
|
523 |
|
524 static void createFunctionMap() |
|
525 { |
|
526 // Create the table. |
|
527 gFunctionMap = new FunctionMap; |
|
528 #define ADD_TO_FUNCTIONMAP(name, str) \ |
|
529 gFunctionMap->set(name##MediaFeature.impl(), name##MediaFeatureEval); |
|
530 CSS_MEDIAQUERY_NAMES_FOR_EACH_MEDIAFEATURE(ADD_TO_FUNCTIONMAP); |
|
531 #undef ADD_TO_FUNCTIONMAP |
|
532 } |
|
533 |
|
534 bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const |
|
535 { |
|
536 if (!m_frame || !m_style) |
|
537 return m_expResult; |
|
538 |
|
539 if (!expr->isValid()) |
|
540 return false; |
|
541 |
|
542 if (!gFunctionMap) |
|
543 createFunctionMap(); |
|
544 |
|
545 // call the media feature evaluation function. Assume no prefix |
|
546 // and let trampoline functions override the prefix if prefix is |
|
547 // used |
|
548 EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl()); |
|
549 if (func) |
|
550 return func(expr->value(), m_style, m_frame, NoPrefix); |
|
551 |
|
552 return false; |
|
553 } |
|
554 |
|
555 } // namespace |