Web Inspector: Implement screen resolution emulation backend
authorapavlov@chromium.org <apavlov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 16:39:55 +0000 (16:39 +0000)
committerapavlov@chromium.org <apavlov@chromium.org@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Thu, 19 Jan 2012 16:39:55 +0000 (16:39 +0000)
https://bugs.webkit.org/show_bug.cgi?id=76532

Reviewed by Pavel Feldman.

Source/WebCore:

The emulation affects [min-|max-]device-(width|height) media queries, window.screen.(width|height),
and window.inner(Width|Height).

Test: inspector/styles/override-screen-size.html

* css/MediaQueryEvaluator.cpp:
(WebCore::device_heightMediaFeatureEval): Apply device-height override if necessary.
(WebCore::device_widthMediaFeatureEval): Apply device-width override if necessary.
* inspector/Inspector.json:
* inspector/InspectorCSSAgent.cpp:
(WebCore::InspectorCSSAgent::InspectorCSSAgent):
(WebCore::InspectorCSSAgent::startSelectorProfiler):
(WebCore::InspectorCSSAgent::stopSelectorProfilerImpl):
(WebCore::InspectorCSSAgent::willMatchRule):
(WebCore::InspectorCSSAgent::didMatchRule):
(WebCore::InspectorCSSAgent::willProcessRule):
(WebCore::InspectorCSSAgent::didProcessRule):
* inspector/InspectorInstrumentation.cpp:
(WebCore::InspectorInstrumentation::applyScreenWidthOverrideImpl):
(WebCore::InspectorInstrumentation::applyScreenHeightOverrideImpl):
* inspector/InspectorInstrumentation.h:
(WebCore::InspectorInstrumentation::applyScreenWidthOverride):
(WebCore::InspectorInstrumentation::applyScreenHeightOverride):
* inspector/InspectorPageAgent.cpp:
(WebCore::InspectorPageAgent::InspectorPageAgent):
(WebCore::InspectorPageAgent::restore):
(WebCore::InspectorPageAgent::disable):
(WebCore::InspectorPageAgent::setScreenSizeOverride):
(WebCore::InspectorPageAgent::applyScreenWidthOverride):
(WebCore::InspectorPageAgent::applyScreenHeightOverride):
(WebCore::InspectorPageAgent::updateFrameViewFixedLayout):
(WebCore::InspectorPageAgent::clearFrameViewFixedLayout):
(WebCore::InspectorPageAgent::setFrameViewFixedLayout):
* inspector/InspectorPageAgent.h:
* page/DOMWindow.cpp:
(WebCore::DOMWindow::innerHeight): Apply height override if necessary.
(WebCore::DOMWindow::innerWidth): Apply width override if necessary.
* page/Screen.cpp:
(WebCore::Screen::height): Apply height override if necessary.
(WebCore::Screen::width): Apply width override if necessary.

LayoutTests:

* inspector/styles/override-screen-size-expected.txt: Added.
* inspector/styles/override-screen-size.html: Added.

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

13 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/styles/override-screen-size-expected.txt [new file with mode: 0644]
LayoutTests/inspector/styles/override-screen-size.html [new file with mode: 0644]
Source/WebCore/ChangeLog
Source/WebCore/css/MediaQueryEvaluator.cpp
Source/WebCore/inspector/Inspector.json
Source/WebCore/inspector/InspectorCSSAgent.cpp
Source/WebCore/inspector/InspectorInstrumentation.cpp
Source/WebCore/inspector/InspectorInstrumentation.h
Source/WebCore/inspector/InspectorPageAgent.cpp
Source/WebCore/inspector/InspectorPageAgent.h
Source/WebCore/page/DOMWindow.cpp
Source/WebCore/page/Screen.cpp

index 599846c..f658fa8 100644 (file)
@@ -1,3 +1,13 @@
+2012-01-18  Alexander Pavlov  <apavlov@chromium.org>
+
+        Web Inspector: Implement screen resolution emulation backend
+        https://bugs.webkit.org/show_bug.cgi?id=76532
+
+        Reviewed by Pavel Feldman.
+
+        * inspector/styles/override-screen-size-expected.txt: Added.
+        * inspector/styles/override-screen-size.html: Added.
+
 2012-01-19  Philippe Normand  <pnormand@igalia.com>
 
         Unreviewed, GTK test_expectations update for a new failing test.
diff --git a/LayoutTests/inspector/styles/override-screen-size-expected.txt b/LayoutTests/inspector/styles/override-screen-size-expected.txt
new file mode 100644 (file)
index 0000000..3fe27dc
--- /dev/null
@@ -0,0 +1,46 @@
+Tests that screen dimension overrides affect media rules, body dimensions, and window.screen.
+
+Override: 480x960
+Screen from page: 480x960
+Body from page: 480x960
+Main style:
+[expanded] 
+element.style  { ()
+
+======== Matched CSS Rules ========
+[expanded] 
+media="screen" (override-screen-size.html)
+@media (max-device-height: 960px) and (max-device-width: 480px) (override-screen-size.html:9)
+#main  { (override-screen-size.html:10)
+background: green;
+
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
+
+
+Override: 960x480
+Screen from page: 960x480
+Body from page: 960x480
+Main style:
+[expanded] 
+element.style  { ()
+
+======== Matched CSS Rules ========
+[expanded] 
+div  { (user agent stylesheet)
+display: block;
+
+
+Override: 10000001x960 => ERROR
+Override: -1x960 => ERROR
+Override: 480x10000001 => ERROR
+Override: 480x-1 => ERROR
+Current dimensions:
+Screen from page: 960x480
+Body from page: 960x480
+Disable PageAgent:
+Screen size same as original - OK
+Enable PageAgent:
+Screen size same as original - OK
+
diff --git a/LayoutTests/inspector/styles/override-screen-size.html b/LayoutTests/inspector/styles/override-screen-size.html
new file mode 100644 (file)
index 0000000..224800f
--- /dev/null
@@ -0,0 +1,200 @@
+<html>
+<head>
+
+<style type="text/css" media="screen">
+@media (max-device-width: 478px) and (max-device-height: 959px) {
+    #main { background: red; }
+}
+
+@media (max-device-width: 480px) and (max-device-height: 960px) {
+    #main { background: green; }
+}
+
+@media (min-device-width: 481px) and (min-device-height: 961px) {
+    #main { background: yellow; }
+}
+
+body {
+    position: absolute;
+    top: 0;
+    right: 0;
+    bottom: 0;
+    left: 0;
+    margin: 0;
+}
+
+</style>
+
+<script src="../../http/tests/inspector/inspector-test.js"></script>
+<script src="../../http/tests/inspector/elements-test.js"></script>
+<script>
+
+function getSizes()
+{
+    return JSON.stringify({
+        screen: window.screen.width + "x" + window.screen.height,
+        body: document.body.offsetWidth + "x" + document.body.offsetHeight
+    });
+}
+
+function test()
+{
+    var exceededDimension = 10000001;
+    var originalScreenSize;
+
+    function saveSizeCallback(jsonResult)
+    {
+        var value = JSON.parse(jsonResult.value);
+        originalScreenSize = value.screen;
+        if (!originalScreenSize || originalScreenSize.indexOf("x") === -1)
+            InspectorTest.addResult("Invalid original screen size: " + originalScreenSize + ". Expect runtime failures later on.");
+
+        InspectorTest.selectNodeAndWaitForStyles("main", step0);
+    }
+
+    InspectorTest.evaluateInPage("getSizes()", saveSizeCallback);
+
+
+    function step0()
+    {
+        overrideAndDumpData(480, 960, step1);
+    }
+
+    function step1()
+    {
+        function compareSizeCallback(jsonResult)
+        {
+            // Check that the screen size reported is the same as the original one.
+            var result = JSON.parse(jsonResult.value);
+            if (result.screen !== originalScreenSize)
+                InspectorTest.addResult("Original size " + originalScreenSize + " not restored, found: " + result.screen);
+            step2();
+        }
+
+        function overrideCallback()
+        {
+            InspectorTest.evaluateInPage("getSizes()", compareSizeCallback);
+        }
+
+        // Disable overrides.
+        PageAgent.setScreenSizeOverride(0, 0, overrideCallback);
+    }
+
+    function step2()
+    {
+        overrideAndDumpData(960, 480, step3);
+    }
+
+    function step3()
+    {
+        applyOverride(exceededDimension, 960, step4);
+    }
+
+    function step4()
+    {
+        applyOverride(-1, 960, step5);
+    }
+
+    function step5()
+    {
+        applyOverride(480, exceededDimension, step6);
+    }
+
+    function step6()
+    {
+        function callback()
+        {
+            InspectorTest.addResult("Current dimensions:");
+            getAndDumpSizes(step7);
+        }
+        applyOverride(480, -1, callback);
+    }
+
+    function step7()
+    {
+        function callback(jsonResult)
+        {
+            var value = JSON.parse(jsonResult.value);
+            if (value.screen !== originalScreenSize)
+                InspectorTest.addResult("Screen size not restored, actual: " + value.screen + ", expected: " + originalScreenSize);
+            else
+                InspectorTest.addResult("Screen size same as original - OK");
+            step8();
+        }
+
+        InspectorTest.addResult("Disable PageAgent:");
+        PageAgent.disable();
+        InspectorTest.evaluateInPage("getSizes()", callback);
+    }
+
+    function step8()
+    {
+        function callback(jsonResult)
+        {
+            var value = JSON.parse(jsonResult.value);
+            if (value.screen !== originalScreenSize)
+                InspectorTest.addResult("Screen size not restored, actual: " + value.screen + ", expected: " + originalScreenSize);
+            else
+                InspectorTest.addResult("Screen size same as original - OK");
+            InspectorTest.completeTest();
+        }
+
+        InspectorTest.addResult("Enable PageAgent:");
+        PageAgent.enable();
+        InspectorTest.evaluateInPage("getSizes()", callback);
+
+    }
+
+    function applyOverride(width, height, userCallback)
+    {
+        function callback(error)
+        {
+            if (error)
+                InspectorTest.addResult("Override: " + width + "x" + height + " => ERROR");
+            userCallback();
+        }
+        PageAgent.setScreenSizeOverride(width, height, callback);
+    }
+
+    function overrideAndDumpData(width, height, callback)
+    {
+        function selectCallback()
+        {
+            InspectorTest.addResult("Main style:");
+            InspectorTest.dumpSelectedElementStyles(true, false, true);
+            callback();
+        }
+
+        function applyCallback()
+        {
+            getAndDumpSizes(selectCallback);
+        }
+
+        InspectorTest.addResult("Override: " + width + "x" + height);
+        applyOverride(width, height, applyCallback);
+    }
+
+    function getAndDumpSizes(callback)
+    {
+        function getSizesCallback(jsonResult)
+        {
+            var result = JSON.parse(jsonResult.value);
+            InspectorTest.addResult("Screen from page: " + result.screen);
+            InspectorTest.addResult("Body from page: " + result.body);
+            callback();
+        }
+
+        InspectorTest.evaluateInPage("getSizes()", getSizesCallback);
+    }
+}
+</script>
+</head>
+
+<body onload="runTest()">
+<p>
+Tests that screen dimension overrides affect media rules, body dimensions, and window.screen.
+</p>
+
+<div id="main"></div>
+</body>
+</html>
index 39a2926..55d74a4 100644 (file)
@@ -1,3 +1,51 @@
+2012-01-18  Alexander Pavlov  <apavlov@chromium.org>
+
+        Web Inspector: Implement screen resolution emulation backend
+        https://bugs.webkit.org/show_bug.cgi?id=76532
+
+        Reviewed by Pavel Feldman.
+
+        The emulation affects [min-|max-]device-(width|height) media queries, window.screen.(width|height),
+        and window.inner(Width|Height).
+
+        Test: inspector/styles/override-screen-size.html
+
+        * css/MediaQueryEvaluator.cpp:
+        (WebCore::device_heightMediaFeatureEval): Apply device-height override if necessary.
+        (WebCore::device_widthMediaFeatureEval): Apply device-width override if necessary.
+        * inspector/Inspector.json:
+        * inspector/InspectorCSSAgent.cpp:
+        (WebCore::InspectorCSSAgent::InspectorCSSAgent):
+        (WebCore::InspectorCSSAgent::startSelectorProfiler):
+        (WebCore::InspectorCSSAgent::stopSelectorProfilerImpl):
+        (WebCore::InspectorCSSAgent::willMatchRule):
+        (WebCore::InspectorCSSAgent::didMatchRule):
+        (WebCore::InspectorCSSAgent::willProcessRule):
+        (WebCore::InspectorCSSAgent::didProcessRule):
+        * inspector/InspectorInstrumentation.cpp:
+        (WebCore::InspectorInstrumentation::applyScreenWidthOverrideImpl):
+        (WebCore::InspectorInstrumentation::applyScreenHeightOverrideImpl):
+        * inspector/InspectorInstrumentation.h:
+        (WebCore::InspectorInstrumentation::applyScreenWidthOverride):
+        (WebCore::InspectorInstrumentation::applyScreenHeightOverride):
+        * inspector/InspectorPageAgent.cpp:
+        (WebCore::InspectorPageAgent::InspectorPageAgent):
+        (WebCore::InspectorPageAgent::restore):
+        (WebCore::InspectorPageAgent::disable):
+        (WebCore::InspectorPageAgent::setScreenSizeOverride):
+        (WebCore::InspectorPageAgent::applyScreenWidthOverride):
+        (WebCore::InspectorPageAgent::applyScreenHeightOverride):
+        (WebCore::InspectorPageAgent::updateFrameViewFixedLayout):
+        (WebCore::InspectorPageAgent::clearFrameViewFixedLayout):
+        (WebCore::InspectorPageAgent::setFrameViewFixedLayout):
+        * inspector/InspectorPageAgent.h:
+        * page/DOMWindow.cpp:
+        (WebCore::DOMWindow::innerHeight): Apply height override if necessary.
+        (WebCore::DOMWindow::innerWidth): Apply width override if necessary.
+        * page/Screen.cpp:
+        (WebCore::Screen::height): Apply height override if necessary.
+        (WebCore::Screen::width): Apply width override if necessary.
+
 2012-01-18  Jocelyn Turcotte  <jocelyn.turcotte@nokia.com>
 
         [Qt] Handle the layers visible rect calculation on the web process.
index b6686fd..c4be436 100644 (file)
@@ -332,7 +332,9 @@ static bool device_heightMediaFeatureEval(CSSValue* value, RenderStyle* style, F
         FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
         int length;
-        return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(sg.height()), length, op);
+        long height = sg.height();
+        InspectorInstrumentation::applyScreenHeightOverride(frame, &height);
+        return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(height), length, op);
     }
     // ({,min-,max-}device-height)
     // assume if we have a device, assume non-zero
@@ -345,7 +347,9 @@ static bool device_widthMediaFeatureEval(CSSValue* value, RenderStyle* style, Fr
         FloatRect sg = screenRect(frame->page()->mainFrame()->view());
         RenderStyle* rootStyle = frame->document()->documentElement()->renderStyle();
         int length;
-        return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(sg.width()), length, op);
+        long width = sg.width();
+        InspectorInstrumentation::applyScreenWidthOverride(frame, &width);
+        return computeLength(value, !frame->document()->inQuirksMode(), style, rootStyle, length) && compareValue(static_cast<int>(width), length, op);
     }
     // ({,min-,max-}device-width)
     // assume if we have a device, assume non-zero
index 126d9ee..8c39e9d 100644 (file)
                     { "name": "html", "type": "string", "description": "HTML content to set."  }
                 ],
                 "hidden": true
+            },
+            {
+                "name": "setScreenSizeOverride",
+                "description": "Overrides the values of window.screen.width, window.screen.height, window.innerWidth, window.innerHeight, and \"device-width\"/\"device-height\"-related CSS media query results",
+                "parameters": [
+                    { "name": "width", "type": "integer", "description": "Overriding width value in pixels (minimum 0, maximum 10000000). 0 disables the override." },
+                    { "name": "height", "type": "integer", "description": "Overriding height value in pixels (minimum 0, maximum 10000000). 0 disables the override." }
+                ],
+                "hidden": true
             }
         ],
         "events": [
index 59601b8..ebe90b5 100644 (file)
@@ -235,6 +235,7 @@ InspectorCSSAgent::InspectorCSSAgent(InstrumentingAgents* instrumentingAgents, I
     , m_lastStyleId(1)
 {
     m_domAgent->setDOMListener(this);
+    m_instrumentingAgents->setInspectorCSSAgent(this);
 }
 
 InspectorCSSAgent::~InspectorCSSAgent()
@@ -524,7 +525,6 @@ void InspectorCSSAgent::getSupportedCSSProperties(ErrorString*, RefPtr<Inspector
 void InspectorCSSAgent::startSelectorProfiler(ErrorString*)
 {
     m_currentSelectorProfile = adoptPtr(new SelectorProfile());
-    m_instrumentingAgents->setInspectorCSSAgent(this);
     m_state->setBoolean(CSSAgentState::isSelectorProfiling, true);
 }
 
@@ -538,7 +538,6 @@ void InspectorCSSAgent::stopSelectorProfilerImpl(ErrorString*, RefPtr<InspectorO
     if (!m_state->getBoolean(CSSAgentState::isSelectorProfiling))
         return;
     m_state->setBoolean(CSSAgentState::isSelectorProfiling, false);
-    m_instrumentingAgents->setInspectorCSSAgent(0);
     if (m_frontend && result)
         *result = m_currentSelectorProfile->toInspectorObject();
     m_currentSelectorProfile.clear();
@@ -546,22 +545,26 @@ void InspectorCSSAgent::stopSelectorProfilerImpl(ErrorString*, RefPtr<InspectorO
 
 void InspectorCSSAgent::willMatchRule(const CSSStyleRule* rule)
 {
-    m_currentSelectorProfile->startSelector(rule);
+    if (m_currentSelectorProfile)
+        m_currentSelectorProfile->startSelector(rule);
 }
 
 void InspectorCSSAgent::didMatchRule(bool matched)
 {
-    m_currentSelectorProfile->commitSelector(matched);
+    if (m_currentSelectorProfile)
+        m_currentSelectorProfile->commitSelector(matched);
 }
 
 void InspectorCSSAgent::willProcessRule(const CSSStyleRule* rule)
 {
-    m_currentSelectorProfile->startSelector(rule);
+    if (m_currentSelectorProfile)
+        m_currentSelectorProfile->startSelector(rule);
 }
 
 void InspectorCSSAgent::didProcessRule()
 {
-    m_currentSelectorProfile->commitSelectorTime();
+    if (m_currentSelectorProfile)
+        m_currentSelectorProfile->commitSelectorTime();
 }
 
 InspectorStyleSheetForInlineStyle* InspectorCSSAgent::asInspectorStyleSheet(Element* element)
index b23c9e5..c501096 100644 (file)
@@ -485,6 +485,18 @@ void InspectorInstrumentation::applyUserAgentOverrideImpl(InstrumentingAgents* i
         resourceAgent->applyUserAgentOverride(userAgent);
 }
 
+void InspectorInstrumentation::applyScreenWidthOverrideImpl(InstrumentingAgents* instrumentingAgents, long* width)
+{
+    if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
+        pageAgent->applyScreenWidthOverride(width);
+}
+
+void InspectorInstrumentation::applyScreenHeightOverrideImpl(InstrumentingAgents* instrumentingAgents, long* height)
+{
+    if (InspectorPageAgent* pageAgent = instrumentingAgents->inspectorPageAgent())
+        pageAgent->applyScreenHeightOverride(height);
+}
+
 void InspectorInstrumentation::willSendRequestImpl(InstrumentingAgents* instrumentingAgents, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
 {
     if (InspectorTimelineAgent* timelineAgent = instrumentingAgents->inspectorTimelineAgent())
index 73989a4..92c4ec7 100644 (file)
@@ -128,6 +128,8 @@ public:
     static void didProcessRule(const InspectorInstrumentationCookie&);
 
     static void applyUserAgentOverride(Frame*, String*);
+    static void applyScreenWidthOverride(Frame*, long*);
+    static void applyScreenHeightOverride(Frame*, long*);
     static void willSendRequest(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
     static void continueAfterPingLoader(Frame*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&);
     static void markResourceAsCached(Page*, unsigned long identifier);
@@ -273,6 +275,8 @@ private:
     static void didProcessRuleImpl(const InspectorInstrumentationCookie&);
 
     static void applyUserAgentOverrideImpl(InstrumentingAgents*, String*);
+    static void applyScreenWidthOverrideImpl(InstrumentingAgents*, long*);
+    static void applyScreenHeightOverrideImpl(InstrumentingAgents*, long*);
     static void willSendRequestImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse& redirectResponse);
     static void continueAfterPingLoaderImpl(InstrumentingAgents*, unsigned long identifier, DocumentLoader*, ResourceRequest&, const ResourceResponse&);
     static void markResourceAsCachedImpl(InstrumentingAgents*, unsigned long identifier);
@@ -779,6 +783,24 @@ inline void InspectorInstrumentation::applyUserAgentOverride(Frame* frame, Strin
 #endif
 }
 
+inline void InspectorInstrumentation::applyScreenWidthOverride(Frame* frame, long* width)
+{
+#if ENABLE(INSPECTOR)
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        applyScreenWidthOverrideImpl(instrumentingAgents, width);
+#endif
+}
+
+inline void InspectorInstrumentation::applyScreenHeightOverride(Frame* frame, long* height)
+{
+#if ENABLE(INSPECTOR)
+    FAST_RETURN_IF_NO_FRONTENDS(void());
+    if (InstrumentingAgents* instrumentingAgents = instrumentingAgentsForFrame(frame))
+        applyScreenHeightOverrideImpl(instrumentingAgents, height);
+#endif
+}
+
 inline void InspectorInstrumentation::willSendRequest(Frame* frame, unsigned long identifier, DocumentLoader* loader, ResourceRequest& request, const ResourceResponse& redirectResponse)
 {
 #if ENABLE(INSPECTOR)
index e68cf8f..c39152e 100644 (file)
 #include "DocumentLoader.h"
 #include "Frame.h"
 #include "FrameLoadRequest.h"
+#include "FrameView.h"
 #include "HTMLFrameOwnerElement.h"
 #include "HTMLNames.h"
 #include "IdentifiersFactory.h"
 #include "InjectedScriptManager.h"
 #include "InspectorFrontend.h"
+#include "InspectorInstrumentation.h"
 #include "InspectorState.h"
 #include "InspectorValues.h"
 #include "InstrumentingAgents.h"
@@ -75,6 +77,8 @@ namespace WebCore {
 namespace PageAgentState {
 static const char pageAgentEnabled[] = "pageAgentEnabled";
 static const char pageAgentScriptsToEvaluateOnLoad[] = "pageAgentScriptsToEvaluateOnLoad";
+static const char pageAgentScreenWidthOverride[] = "pageAgentScreenWidthOverride";
+static const char pageAgentScreenHeightOverride[] = "pageAgentScreenHeightOverride";
 }
 
 static bool decodeSharedBuffer(PassRefPtr<SharedBuffer> buffer, const String& textEncodingName, String* result)
@@ -268,6 +272,7 @@ InspectorPageAgent::InspectorPageAgent(InstrumentingAgents* instrumentingAgents,
     , m_injectedScriptManager(injectedScriptManager)
     , m_frontend(0)
     , m_lastScriptIdentifier(0)
+    , m_originalUseFixedLayout(false)
 {
 }
 
@@ -288,6 +293,11 @@ void InspectorPageAgent::restore()
     if (m_state->getBoolean(PageAgentState::pageAgentEnabled)) {
         ErrorString error;
         enable(&error);
+
+        // When restoring the agent, override values are restored into the FrameView.
+        int width = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
+        int height = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
+        updateFrameViewFixedLayout(width, height);
     }
 }
 
@@ -301,6 +311,11 @@ void InspectorPageAgent::disable(ErrorString*)
 {
     m_state->setBoolean(PageAgentState::pageAgentEnabled, false);
     m_instrumentingAgents->setInspectorPageAgent(0);
+
+    // When disabling the agent, reset the override values.
+    m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, 0);
+    m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, 0);
+    updateFrameViewFixedLayout(0, 0);
 }
 
 void InspectorPageAgent::addScriptToEvaluateOnLoad(ErrorString*, const String& source, String* identifier)
@@ -578,6 +593,28 @@ void InspectorPageAgent::setDocumentContent(ErrorString* errorString, const Stri
     editor.patchDocument(html);
 }
 
+void InspectorPageAgent::setScreenSizeOverride(ErrorString* errorString, const int width, const int height)
+{
+    const static long maxDimension = 10000000;
+
+    if (width < 0 || height < 0 || width > maxDimension || height > maxDimension) {
+        *errorString = makeString("Width and height values must be positive, not greater than ", String::number(maxDimension));
+        return;
+    }
+
+    // These two always fit an int.
+    int currentWidth = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenWidthOverride));
+    int currentHeight = static_cast<int>(m_state->getLong(PageAgentState::pageAgentScreenHeightOverride));
+
+    if (width == currentWidth && height == currentHeight)
+        return;
+
+    m_state->setLong(PageAgentState::pageAgentScreenWidthOverride, width);
+    m_state->setLong(PageAgentState::pageAgentScreenHeightOverride, height);
+
+    updateFrameViewFixedLayout(width, height);
+}
+
 void InspectorPageAgent::didClearWindowObjectInWorld(Frame* frame, DOMWrapperWorld* world)
 {
     if (world != mainThreadNormalWorld())
@@ -693,6 +730,20 @@ void InspectorPageAgent::loaderDetachedFromFrame(DocumentLoader* loader)
         m_loaderToIdentifier.remove(iterator);
 }
 
+void InspectorPageAgent::applyScreenWidthOverride(long* width)
+{
+    long widthOverride = m_state->getLong(PageAgentState::pageAgentScreenWidthOverride);
+    if (widthOverride)
+        *width = widthOverride;
+}
+
+void InspectorPageAgent::applyScreenHeightOverride(long* height)
+{
+    long heightOverride = m_state->getLong(PageAgentState::pageAgentScreenHeightOverride);
+    if (heightOverride)
+        *height = heightOverride;
+}
+
 PassRefPtr<InspectorObject> InspectorPageAgent::buildObjectForFrame(Frame* frame)
 {
     RefPtr<InspectorObject> frameObject = InspectorObject::create();
@@ -743,6 +794,40 @@ PassRefPtr<InspectorObject> InspectorPageAgent::buildObjectForFrameTree(Frame* f
     return result;
 }
 
+void InspectorPageAgent::updateFrameViewFixedLayout(int width, int height)
+{
+    if (!width && !height)
+        clearFrameViewFixedLayout();
+    else
+        setFrameViewFixedLayout(width, height);
+
+    Document* document = mainFrame()->document();
+    document->styleSelectorChanged(RecalcStyleImmediately);
+    InspectorInstrumentation::mediaQueryResultChanged(document);
+}
+
+void InspectorPageAgent::clearFrameViewFixedLayout()
+{
+    if (m_originalFixedLayoutSize) {
+        // Turning off existing overrides (no-op otherwise) - revert the affected FrameView to the remembered fixed layout settings.
+        mainFrame()->view()->setFixedLayoutSize(*m_originalFixedLayoutSize);
+        m_originalFixedLayoutSize.clear();
+        mainFrame()->view()->setUseFixedLayout(m_originalUseFixedLayout);
+    }
+}
+
+void InspectorPageAgent::setFrameViewFixedLayout(int width, int height)
+{
+    if (!m_originalFixedLayoutSize) {
+        // Turning on the overrides (none currently exist) - remember existing fixed layout for the affected FrameView.
+        m_originalFixedLayoutSize = adoptPtr(new IntSize(mainFrame()->view()->fixedLayoutSize()));
+        m_originalUseFixedLayout = mainFrame()->view()->useFixedLayout();
+    }
+
+    mainFrame()->view()->setFixedLayoutSize(IntSize(width, height));
+    mainFrame()->view()->setUseFixedLayout(true);
+}
+
 } // namespace WebCore
 
 #endif // ENABLE(INSPECTOR)
index a67a807..b40d648 100644 (file)
@@ -100,6 +100,7 @@ public:
     void searchInResource(ErrorString*, const String& frameId, const String& url, const String& query, const bool* const optionalCaseSensitive, const bool* const optionalIsRegex, RefPtr<InspectorArray>&);
     void searchInResources(ErrorString*, const String&, const bool* const caseSensitive, const bool* const isRegex, RefPtr<InspectorArray>&);
     void setDocumentContent(ErrorString*, const String& frameId, const String& html);
+    void setScreenSizeOverride(ErrorString*, const int width, const int height);
 
     // InspectorInstrumentation API
     void didClearWindowObjectInWorld(Frame*, DOMWrapperWorld*);
@@ -108,6 +109,8 @@ public:
     void frameNavigated(DocumentLoader*);
     void frameDetached(Frame*);
     void loaderDetachedFromFrame(DocumentLoader*);
+    void applyScreenWidthOverride(long*);
+    void applyScreenHeightOverride(long*);
 
     // Inspector Controller API
     virtual void setFrontend(InspectorFrontend*);
@@ -125,6 +128,9 @@ public:
 
 private:
     InspectorPageAgent(InstrumentingAgents*, Page*, InspectorState*, InjectedScriptManager*);
+    void updateFrameViewFixedLayout(int, int);
+    void setFrameViewFixedLayout(int, int);
+    void clearFrameViewFixedLayout();
 
     PassRefPtr<InspectorObject> buildObjectForFrame(Frame*);
     PassRefPtr<InspectorObject> buildObjectForFrameTree(Frame*);
@@ -137,6 +143,8 @@ private:
     HashMap<Frame*, String> m_frameToIdentifier;
     HashMap<String, Frame*> m_identifierToFrame;
     HashMap<DocumentLoader*, String> m_loaderToIdentifier;
+    OwnPtr<IntSize> m_originalFixedLayoutSize;
+    bool m_originalUseFixedLayout;
 };
 
 
index acb22af..1ab987b 100644 (file)
@@ -1134,7 +1134,9 @@ int DOMWindow::innerHeight() const
     if (!view)
         return 0;
     
-    return static_cast<int>(view->visibleContentRect(/* includeScrollbars */ true).height() / m_frame->pageZoomFactor());
+    long height = view->visibleContentRect(/* includeScrollbars */ true).height();
+    InspectorInstrumentation::applyScreenHeightOverride(m_frame, &height);
+    return static_cast<int>(height / m_frame->pageZoomFactor());
 }
 
 int DOMWindow::innerWidth() const
@@ -1146,7 +1148,9 @@ int DOMWindow::innerWidth() const
     if (!view)
         return 0;
 
-    return static_cast<int>(view->visibleContentRect(/* includeScrollbars */ true).width() / m_frame->pageZoomFactor());
+    long width = view->visibleContentRect(/* includeScrollbars */ true).width();
+    InspectorInstrumentation::applyScreenWidthOverride(m_frame, &width);
+    return static_cast<int>(width / m_frame->pageZoomFactor());
 }
 
 int DOMWindow::screenX() const
index b021e5f..e1e1d11 100644 (file)
@@ -33,6 +33,7 @@
 #include "FloatRect.h"
 #include "Frame.h"
 #include "FrameView.h"
+#include "InspectorInstrumentation.h"
 #include "PlatformScreen.h"
 #include "Widget.h"
 
@@ -61,14 +62,18 @@ unsigned Screen::height() const
 {
     if (!m_frame)
         return 0;
-    return static_cast<unsigned>(screenRect(m_frame->view()).height());
+    long height = static_cast<long>(screenRect(m_frame->view()).height());
+    InspectorInstrumentation::applyScreenHeightOverride(m_frame, &height);
+    return static_cast<unsigned>(height);
 }
 
 unsigned Screen::width() const
 {
     if (!m_frame)
         return 0;
-    return static_cast<unsigned>(screenRect(m_frame->view()).width());
+    long width = static_cast<long>(screenRect(m_frame->view()).width());
+    InspectorInstrumentation::applyScreenWidthOverride(m_frame, &width);
+    return static_cast<unsigned>(width);
 }
 
 unsigned Screen::colorDepth() const