Fix for bug 17301. CSS media queries need to use the correct viewport
authorhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Feb 2008 00:14:47 +0000 (00:14 +0000)
committerhyatt@apple.com <hyatt@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Fri, 22 Feb 2008 00:14:47 +0000 (00:14 +0000)
        when contained in documents inside iframes (rather than always using the
        top-level document's viewport).  CSS media queries based on the viewport
        also needed to be dynamic and update as you resize the window (this is
        a HOT feature). :)

        This patch gets Acid3 up to 86/100 with 3 colored boxes filled in.

        Reviewed by olliej

        Added fast/media/viewport-media-query.html

        * css/CSSStyleSelector.cpp:
        (WebCore::CSSStyleSelector::CSSStyleSelector):
        (WebCore::CSSStyleSelector::addViewportDependentMediaQueryResult):
        (WebCore::CSSStyleSelector::affectedByViewportChange):
        * css/CSSStyleSelector.h:
        (WebCore::MediaQueryResult::MediaQueryResult):
        * css/MediaQueryEvaluator.cpp:
        (WebCore::MediaQueryEvaluator::MediaQueryEvaluator):
        (WebCore::MediaQueryEvaluator):
        (WebCore::MediaQueryEvaluator::eval):
        (WebCore::colorMediaFeatureEval):
        (WebCore::monochromeMediaFeatureEval):
        (WebCore::device_aspect_ratioMediaFeatureEval):
        (WebCore::device_pixel_ratioMediaFeatureEval):
        (WebCore::gridMediaFeatureEval):
        (WebCore::device_heightMediaFeatureEval):
        (WebCore::device_widthMediaFeatureEval):
        (WebCore::heightMediaFeatureEval):
        (WebCore::widthMediaFeatureEval):
        (WebCore::min_colorMediaFeatureEval):
        (WebCore::max_colorMediaFeatureEval):
        (WebCore::min_monochromeMediaFeatureEval):
        (WebCore::max_monochromeMediaFeatureEval):
        (WebCore::min_device_aspect_ratioMediaFeatureEval):
        (WebCore::max_device_aspect_ratioMediaFeatureEval):
        (WebCore::min_device_pixel_ratioMediaFeatureEval):
        (WebCore::max_device_pixel_ratioMediaFeatureEval):
        (WebCore::min_heightMediaFeatureEval):
        (WebCore::max_heightMediaFeatureEval):
        (WebCore::min_widthMediaFeatureEval):
        (WebCore::max_widthMediaFeatureEval):
        (WebCore::min_device_heightMediaFeatureEval):
        (WebCore::max_device_heightMediaFeatureEval):
        (WebCore::min_device_widthMediaFeatureEval):
        (WebCore::max_device_widthMediaFeatureEval):
        * css/MediaQueryEvaluator.h:
        * css/MediaQueryExp.cpp:
        (WebCore::MediaQueryExp::~MediaQueryExp):
        * css/MediaQueryExp.h:
        (WebCore::MediaQueryExp::value):
        (WebCore::MediaQueryExp::isViewportDependent):
        * html/HTMLMediaElement.cpp:
        (WebCore::HTMLMediaElement::pickMedia):
        * page/FrameView.cpp:
        (WebCore::FrameView::layout):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@30466 268f45cc-cd09-0410-ab3c-d52691b4dbfc

WebCore/ChangeLog
WebCore/css/CSSStyleSelector.cpp
WebCore/css/CSSStyleSelector.h
WebCore/css/MediaQueryEvaluator.cpp
WebCore/css/MediaQueryEvaluator.h
WebCore/css/MediaQueryExp.cpp
WebCore/css/MediaQueryExp.h
WebCore/html/HTMLMediaElement.cpp
WebCore/page/FrameView.cpp

index a6f7f16e243cd80c20e8963d551a01c58b1c76a8..faaacb0b5c5507e0a5b8cd03cc7e2587ea39ecdb 100644 (file)
@@ -1,3 +1,63 @@
+2008-02-21  David Hyatt  <hyatt@apple.com>
+
+        Fix for bug 17301.  CSS media queries need to use the correct viewport
+        when contained in documents inside iframes (rather than always using the
+        top-level document's viewport).  CSS media queries based on the viewport
+        also needed to be dynamic and update as you resize the window (this is
+        a HOT feature). :)
+
+        This patch gets Acid3 up to 86/100 with 3 colored boxes filled in.
+
+        Reviewed by olliej
+
+        Added fast/media/viewport-media-query.html
+
+        * css/CSSStyleSelector.cpp:
+        (WebCore::CSSStyleSelector::CSSStyleSelector):
+        (WebCore::CSSStyleSelector::addViewportDependentMediaQueryResult):
+        (WebCore::CSSStyleSelector::affectedByViewportChange):
+        * css/CSSStyleSelector.h:
+        (WebCore::MediaQueryResult::MediaQueryResult):
+        * css/MediaQueryEvaluator.cpp:
+        (WebCore::MediaQueryEvaluator::MediaQueryEvaluator):
+        (WebCore::MediaQueryEvaluator):
+        (WebCore::MediaQueryEvaluator::eval):
+        (WebCore::colorMediaFeatureEval):
+        (WebCore::monochromeMediaFeatureEval):
+        (WebCore::device_aspect_ratioMediaFeatureEval):
+        (WebCore::device_pixel_ratioMediaFeatureEval):
+        (WebCore::gridMediaFeatureEval):
+        (WebCore::device_heightMediaFeatureEval):
+        (WebCore::device_widthMediaFeatureEval):
+        (WebCore::heightMediaFeatureEval):
+        (WebCore::widthMediaFeatureEval):
+        (WebCore::min_colorMediaFeatureEval):
+        (WebCore::max_colorMediaFeatureEval):
+        (WebCore::min_monochromeMediaFeatureEval):
+        (WebCore::max_monochromeMediaFeatureEval):
+        (WebCore::min_device_aspect_ratioMediaFeatureEval):
+        (WebCore::max_device_aspect_ratioMediaFeatureEval):
+        (WebCore::min_device_pixel_ratioMediaFeatureEval):
+        (WebCore::max_device_pixel_ratioMediaFeatureEval):
+        (WebCore::min_heightMediaFeatureEval):
+        (WebCore::max_heightMediaFeatureEval):
+        (WebCore::min_widthMediaFeatureEval):
+        (WebCore::max_widthMediaFeatureEval):
+        (WebCore::min_device_heightMediaFeatureEval):
+        (WebCore::max_device_heightMediaFeatureEval):
+        (WebCore::min_device_widthMediaFeatureEval):
+        (WebCore::max_device_widthMediaFeatureEval):
+        * css/MediaQueryEvaluator.h:
+        * css/MediaQueryExp.cpp:
+        (WebCore::MediaQueryExp::~MediaQueryExp):
+        * css/MediaQueryExp.h:
+        (WebCore::MediaQueryExp::value):
+        (WebCore::MediaQueryExp::isViewportDependent):
+        * html/HTMLMediaElement.cpp:
+        (WebCore::HTMLMediaElement::pickMedia):
+        * page/FrameView.cpp:
+        (WebCore::FrameView::layout):
+
 2008-02-21  Anders Carlsson  <andersca@apple.com>
 
         Reviewed by Sam.
index a9a7407d4592d005b02df7a6e59f8926843ddb54..e39299d7584e8ea06d0648f6bdfc7b0556a7a975 100644 (file)
@@ -281,7 +281,7 @@ CSSStyleSelector::CSSStyleSelector(Document* doc, const String& userStyleSheet,
 
     if (m_rootDefaultStyle && view) {
         delete m_medium;
-        m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame()->page(), m_rootDefaultStyle);
+        m_medium = new MediaQueryEvaluator(view->mediaType(), view->frame(), m_rootDefaultStyle);
     }
 
     // FIXME: This sucks! The user sheet is reparsed every time!
@@ -5180,4 +5180,19 @@ bool CSSStyleSelector::hasSelectorForAttribute(const AtomicString &attrname)
     return m_selectorAttrs.contains(attrname.impl());
 }
 
+void CSSStyleSelector::addViewportDependentMediaQueryResult(const MediaQueryExp* expr, bool result)
+{
+    m_viewportDependentMediaQueryResults.append(new MediaQueryResult(*expr, result));
+}
+
+bool CSSStyleSelector::affectedByViewportChange() const
+{
+    unsigned s = m_viewportDependentMediaQueryResults.size();
+    for (unsigned i = 0; i < s; i++) {
+        if (m_medium->eval(&m_viewportDependentMediaQueryResults[i]->m_expression) != m_viewportDependentMediaQueryResults[i]->m_result)
+            return true;
+    }
+    return false;
+}
+
 } // namespace WebCore
index 98ddb5daa8734b49802b5496a1905faed264e8a8..b5ba49b9109ec3e9cdca8bc0e35f5941b1caf8b4 100644 (file)
@@ -23,6 +23,7 @@
 #define CSSStyleSelector_h
 
 #include "CSSFontSelector.h"
+#include "MediaQueryExp.h"
 #include "RenderStyle.h"
 #include <wtf/HashSet.h>
 #include <wtf/Vector.h>
@@ -55,6 +56,18 @@ class StyleSheet;
 class StyleSheetList;
 class StyledElement;
 
+class MediaQueryResult
+{
+public:
+    MediaQueryResult(const MediaQueryExp& expr, bool result)
+    : m_expression(expr)
+    , m_result(result)
+    {}
+
+    MediaQueryExp m_expression;
+    bool m_result;
+};
+
     /**
      * this class selects a RenderStyle for a given Element based on the
      * collection of styleshets it contains. This is just a vrtual base class
@@ -129,6 +142,9 @@ class StyledElement;
            matches the given Element */
         bool checkSelector(CSSSelector*);
 
+        void addViewportDependentMediaQueryResult(const MediaQueryExp*, bool result);
+        bool affectedByViewportChange() const;
+        
     protected:
         enum SelectorMatch {
             SelectorMatches = 0,
@@ -239,6 +255,8 @@ class StyledElement;
         
         Vector<CSSMutableStyleDeclaration*> m_additionalAttributeStyleDecls;
         
+        Vector<MediaQueryResult*> m_viewportDependentMediaQueryResults;
+
         void applyProperty(int id, CSSValue*);
 
 #if ENABLE(SVG)
index 837e9098103b54dea3e53951c56cc2c4bd2e5c4a..de2b4c47c601d1af77da4160137c44f6543fbd2f 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "Chrome.h"
 #include "CSSPrimitiveValue.h"
+#include "CSSStyleSelector.h"
 #include "CSSValueList.h"
 #include "FloatRect.h"
 #include "Frame.h"
@@ -50,7 +51,7 @@ using namespace MediaFeatureNames;
 
 enum MediaFeaturePrefix { MinPrefix, MaxPrefix, NoPrefix };
 
-typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Page*,  MediaFeaturePrefix);
+typedef bool (*EvalFunc)(CSSValue*, RenderStyle*, Frame*,  MediaFeaturePrefix);
 typedef HashMap<AtomicStringImpl*, EvalFunc> FunctionMap;
 static FunctionMap* gFunctionMap;
 
@@ -67,7 +68,7 @@ static FunctionMap* gFunctionMap;
  */
 
 MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
-    : m_page(0)
+    : m_frame(0)
     , m_style(0)
     , m_expResult(mediaFeatureResult)
 {
@@ -75,7 +76,7 @@ MediaQueryEvaluator::MediaQueryEvaluator(bool mediaFeatureResult)
 
 MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, bool mediaFeatureResult)
     : m_mediaType(acceptedMediaType)
-    , m_page(0)
+    , m_frame(0)
     , m_style(0)
     , m_expResult(mediaFeatureResult)
 {
@@ -83,17 +84,17 @@ MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, bool
 
 MediaQueryEvaluator:: MediaQueryEvaluator(const char* acceptedMediaType, bool mediaFeatureResult)
     : m_mediaType(acceptedMediaType)
-    , m_page(0)
+    , m_frame(0)
     , m_style(0)
     , m_expResult(mediaFeatureResult)
 {
 }
 
-MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, Page* page, RenderStyle* style)
+MediaQueryEvaluator:: MediaQueryEvaluator(const String& acceptedMediaType, Frame* frame, RenderStyle* style)
     : m_mediaType(acceptedMediaType.lower())
-    , m_page(page)
+    , m_frame(frame)
     , m_style(style)
-    , m_expResult(false) // doesn't matter when we have m_page and m_style
+    , m_expResult(false) // doesn't matter when we have m_frame and m_style
 {
 }
 
@@ -141,7 +142,13 @@ bool MediaQueryEvaluator::eval(const MediaList* mediaList) const
             // iterate through expressions, stop if any of them eval to false
             // (AND semantics)
             size_t j = 0;
-            for (; j < exps->size() && eval(exps->at(j)); ++j) /* empty*/;
+            for (; j < exps->size(); ++j) {
+                bool exprResult = eval(exps->at(j));
+                if (exps->at(j)->isViewportDependent())
+                    m_frame->document()->styleSelector()->addViewportDependentMediaQueryResult(exps->at(j), exprResult);
+                if (!exprResult)
+                    break;
+            }
 
             // assume true if we are at the end of the list,
             // otherwise assume false
@@ -200,9 +207,9 @@ static bool numberValue(CSSValue* value, float& result)
     return false;
 }
 
-static bool colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
-    int bitsPerComponent = screenDepthPerComponent(page->mainFrame()->view());
+    int bitsPerComponent = screenDepthPerComponent(frame->page()->mainFrame()->view());
     float number;
     if (value)
         return numberValue(value, number) && compareValue(bitsPerComponent, static_cast<int>(number), op);
@@ -210,18 +217,18 @@ static bool colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* pag
     return bitsPerComponent != 0;
 }
 
-static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
-    if (!screenIsMonochrome(page->mainFrame()->view()))
+    if (!screenIsMonochrome(frame->page()->mainFrame()->view()))
         return false;
 
-    return colorMediaFeatureEval(value, style, page, op);
+    return colorMediaFeatureEval(value, style, frame, op);
 }
 
-static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
     if (value) {
-        FloatRect sg = screenRect(page->mainFrame()->view());
+        FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         int h = 0;
         int v = 0;
         if (parseAspectRatio(value, h, v))
@@ -234,15 +241,15 @@ static bool device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* st
     return true;
 }
 
-static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle* style, Page* page, MediaFeaturePrefix op)
+static bool device_pixel_ratioMediaFeatureEval(CSSValue *value, RenderStyle* style, Frame* frame, MediaFeaturePrefix op)
 {
     if (value)
-        return value->isPrimitiveValue() && compareValue(page->chrome()->scaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
+        return value->isPrimitiveValue() && compareValue(frame->page()->chrome()->scaleFactor(), static_cast<CSSPrimitiveValue*>(value)->getFloatValue(), op);
 
-    return page->chrome()->scaleFactor() != 0;
+    return frame->page()->chrome()->scaleFactor() != 0;
 }
 
-static bool gridMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool gridMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
     // if output device is bitmap, grid: 0 == true
     // assume we have bitmap device
@@ -252,10 +259,10 @@ static bool gridMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page
     return false;
 }
 
-static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
     if (value) {
-        FloatRect sg = screenRect(page->mainFrame()->view());
+        FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.height()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
     }
     // ({,min-,max-}device-height)
@@ -263,10 +270,10 @@ static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, P
     return true;
 }
 
-static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
     if (value) {
-        FloatRect sg = screenRect(page->mainFrame()->view());
+        FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         return value->isPrimitiveValue() && compareValue(static_cast<int>(sg.width()), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
     }
     // ({,min-,max-}device-width)
@@ -274,9 +281,9 @@ static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Pa
     return true;
 }
 
-static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
-    FrameView* view = page->mainFrame()->view();
+    FrameView* view = frame->view();
     
     if (value)
         return value->isPrimitiveValue() && compareValue(view->visibleHeight(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
@@ -284,9 +291,9 @@ static bool heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* pa
     return view->visibleHeight() != 0;
 }
 
-static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix op)
+static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix op)
 {
-    FrameView* view = page->mainFrame()->view();
+    FrameView* view = frame->view();
     
     if (value)
         return value->isPrimitiveValue() && compareValue(view->visibleWidth(), static_cast<CSSPrimitiveValue*>(value)->computeLengthInt(style), op);
@@ -296,84 +303,84 @@ static bool widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* pag
 
 // rest of the functions are trampolines which set the prefix according to the media feature expression used
 
-static bool min_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return colorMediaFeatureEval(value, style, page, MinPrefix);
+    return colorMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_colorMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return colorMediaFeatureEval(value, style, page, MaxPrefix);
+    return colorMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return monochromeMediaFeatureEval(value, style, page, MinPrefix);
+    return monochromeMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_monochromeMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return monochromeMediaFeatureEval(value, style, page, MaxPrefix);
+    return monochromeMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_aspect_ratioMediaFeatureEval(value, style, page, MinPrefix);
+    return device_aspect_ratioMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_device_aspect_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_aspect_ratioMediaFeatureEval(value, style, page, MaxPrefix);
+    return device_aspect_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_pixel_ratioMediaFeatureEval(value, style, page, MinPrefix);
+    return device_pixel_ratioMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_device_pixel_ratioMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_pixel_ratioMediaFeatureEval(value, style, page, MaxPrefix);
+    return device_pixel_ratioMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return heightMediaFeatureEval(value, style, page, MinPrefix);
+    return heightMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return heightMediaFeatureEval(value, style, page, MaxPrefix);
+    return heightMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return widthMediaFeatureEval(value, style, page, MinPrefix);
+    return widthMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return widthMediaFeatureEval(value, style, page, MaxPrefix);
+    return widthMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_heightMediaFeatureEval(value, style, page, MinPrefix);
+    return device_heightMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_heightMediaFeatureEval(value, style, page, MaxPrefix);
+    return device_heightMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
-static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool min_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_widthMediaFeatureEval(value, style, page, MinPrefix);
+    return device_widthMediaFeatureEval(value, style, frame, MinPrefix);
 }
 
-static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Page* page,  MediaFeaturePrefix /*op*/)
+static bool max_device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Frame* frame,  MediaFeaturePrefix /*op*/)
 {
-    return device_widthMediaFeatureEval(value, style, page, MaxPrefix);
+    return device_widthMediaFeatureEval(value, style, frame, MaxPrefix);
 }
 
 static void createFunctionMap()
@@ -388,7 +395,7 @@ static void createFunctionMap()
 
 bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
 {
-    if (!m_page || !m_style)
+    if (!m_frame || !m_style)
         return m_expResult;
 
     if (!gFunctionMap)
@@ -399,7 +406,7 @@ bool MediaQueryEvaluator::eval(const MediaQueryExp* expr) const
     // used
     EvalFunc func = gFunctionMap->get(expr->mediaFeature().impl());
     if (func)
-        return func(expr->value(), m_style, m_page, NoPrefix);
+        return func(expr->value(), m_style, m_frame, NoPrefix);
 
     return false;
 }
index 5f4ab50b522d96c928a256ee894012c2917dd6ea..bc389b78f2115e3f68894dcffa20f3142a9fca83 100644 (file)
@@ -31,7 +31,7 @@
 #include "PlatformString.h"
 
 namespace WebCore {
-class Page;
+class Frame;
 class RenderStyle;
 class MediaList;
 class MediaQueryExp;
@@ -66,7 +66,7 @@ public:
 
     /** Creates evaluator which evaluates full media queries
      */
-    MediaQueryEvaluator(const String& acceptedMediaType, Page* page, RenderStyle* style);
+    MediaQueryEvaluator(const String& acceptedMediaType, Frame*, RenderStyle*);
 
     ~MediaQueryEvaluator();
 
@@ -81,7 +81,7 @@ public:
 
 private:
     String m_mediaType;
-    Page* m_page; // not owned
+    Frame* m_frame; // not owned
     RenderStyle* m_style; // not owned
     bool m_expResult;
 };
index 7245b141ee82a5d5318d57f18fa4044e3da13eb1..e6f9ff0574ded4d64b0591871f14d276a6213698 100644 (file)
@@ -80,7 +80,6 @@ MediaQueryExp::MediaQueryExp(const AtomicString& mediaFeature, ValueList* valueL
 
 MediaQueryExp::~MediaQueryExp()
 {
-    delete m_value;
 }
 
 } // namespace
index 25d5c86eb9cc5a4154833c9314dbebc2bf34c96f..14cb123db92ed4f6920848e07b4c726e7cdf7955 100644 (file)
@@ -30,6 +30,8 @@
 
 #include "AtomicString.h"
 #include "CSSValue.h"
+#include "MediaFeatureNames.h"
+#include <wtf/RefPtr.h>
 
 namespace WebCore {
 class ValueList;
@@ -42,7 +44,7 @@ public:
 
     AtomicString mediaFeature() const { return m_mediaFeature; }
 
-    CSSValue* value() const { return m_value; }
+    CSSValue* value() const { return m_value.get(); }
 
     bool operator==(const MediaQueryExp& other) const  {
         return (other.m_mediaFeature == m_mediaFeature)
@@ -50,9 +52,15 @@ public:
                 || (other.m_value && m_value && other.m_value->cssText() == m_value->cssText()));
     }
 
+    bool isViewportDependent() const { return m_mediaFeature == MediaFeatureNames::widthMediaFeature || 
+                                              m_mediaFeature == MediaFeatureNames::heightMediaFeature ||
+                                              m_mediaFeature == MediaFeatureNames::min_widthMediaFeature ||
+                                              m_mediaFeature == MediaFeatureNames::min_heightMediaFeature ||
+                                              m_mediaFeature == MediaFeatureNames::max_widthMediaFeature ||
+                                              m_mediaFeature == MediaFeatureNames::max_heightMediaFeature; }
 private:
     AtomicString m_mediaFeature;
-    CSSValue* m_value;
+    RefPtr<CSSValue> m_value;
 };
 
 } // namespace
index c8c1f10ccd9256c0c7c4d4d45c7207a9d5d0096d..bac3093dbf298389fabb84b477ac03a543e0855a 100644 (file)
@@ -809,7 +809,7 @@ String HTMLMediaElement::pickMedia()
                 if (!source->hasAttribute(srcAttr))
                     continue; 
                 if (source->hasAttribute(mediaAttr)) {
-                    MediaQueryEvaluator screenEval("screen", document()->page(), renderer() ? renderer()->style() : 0);
+                    MediaQueryEvaluator screenEval("screen", document()->frame(), renderer() ? renderer()->style() : 0);
                     RefPtr<MediaList> media = new MediaList((CSSStyleSheet*)0, source->media(), true);
                     if (!screenEval.eval(media.get()))
                         continue;
index 0cc65b405eaae8dfed04094f890273b64f9b3917..d56175a4dd618f2e631392a2959d58577e4a43c2 100644 (file)
@@ -27,6 +27,7 @@
 #include "FrameView.h"
 
 #include "AXObjectCache.h"
+#include "CSSStyleSelector.h"
 #include "EventHandler.h"
 #include "FloatRect.h"
 #include "Frame.h"
@@ -364,6 +365,11 @@ void FrameView::layout(bool allowSubtree)
         performPostLayoutTasks();
     }
 
+    // Viewport-dependent media queries may cause us to need completely different style information.
+    // Check that here.
+    if (document->styleSelector()->affectedByViewportChange())
+        document->updateStyleSelector();
+
     // Always ensure our style info is up-to-date.  This can happen in situations where
     // the layout beats any sort of style recalc update that needs to occur.
     if (m_frame->needsReapplyStyles())