CSS Device Adaptation: window.innerWidth returns wrong value if CSS viewport descriptors are applied
https://bugs.webkit.org/show_bug.cgi?id=103737
Patch by Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com> on 2012-12-03
Reviewed by Kenneth Rohde Christiansen.
Source/WebCore:
ViewportStyleResolver used frame view visibleContentRect size as initial viewport size.
This however caused a problem when page enabled/disabled CSS stylesheets, having viewport
descriptors. Viewport descriptors from new stylesheet were applied to the visibleContentRect
affected already by the viewport descriptors from the previous stylesheet.
New 'initialViewportSize' property (http://dev.w3.org/csswg/css-device-adapt/#initial-viewport)
was added to frame view so that viewport descriptors can always be applied to the reliable
viewport size.
Test: css3/device-adapt/viewport-width-check-window-innerwidth-correct.html
* css/ViewportStyleResolver.cpp:
(WebCore::ViewportStyleResolver::ViewportStyleResolver):
(WebCore::ViewportStyleResolver::getViewportArgumentValue):
* css/ViewportStyleResolver.h:
(ViewportStyleResolver):
* dom/Document.cpp:
(WebCore):
(WebCore::Document::initialViewportSize):
* dom/Document.h:
(Document):
* page/FrameView.h:
(FrameView):
(WebCore::FrameView::initialViewportSize):
(WebCore::FrameView::setInitialViewportSize):
Source/WebKit2:
ViewportStyleResolver used frame view visibleContentRect size as initial viewport size.
This however caused a problem when page enabled/disabled CSS stylesheets, having viewport
descriptors. Viewport descriptors from new stylesheet were applied to the visibleContentRect
affected already by the viewport descriptors from the previous stylesheet.
New 'initialViewportSize' property (http://dev.w3.org/csswg/css-device-adapt/#initial-viewport)
was added to frame view so that viewport descriptors can always be applied to the reliable
viewport size.
Both newly added 'initialViewportSize' property and 'fixedVisibleContentRect' property
are assigned appropriately now in WebPage::sendViewportAttributesChanged().
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::sendViewportAttributesChanged):
LayoutTests:
Added new test css3/device-adapt/viewport-width-check-window-innerwidth-correct.html.
* css3/device-adapt/viewport-width-check-window-innerwidth-correct-expected.txt: Added.
* css3/device-adapt/viewport-width-check-window-innerwidth-correct.html: Added.
git-svn-id: http://svn.webkit.org/repository/webkit/trunk@136373 268f45cc-cd09-0410-ab3c-d52691b4dbfc
diff --git a/LayoutTests/ChangeLog b/LayoutTests/ChangeLog
index 8f1d6c7..34ae197 100644
--- a/LayoutTests/ChangeLog
+++ b/LayoutTests/ChangeLog
@@ -1,3 +1,15 @@
+2012-12-03 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+
+ CSS Device Adaptation: window.innerWidth returns wrong value if CSS viewport descriptors are applied
+ https://bugs.webkit.org/show_bug.cgi?id=103737
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ Added new test css3/device-adapt/viewport-width-check-window-innerwidth-correct.html.
+
+ * css3/device-adapt/viewport-width-check-window-innerwidth-correct-expected.txt: Added.
+ * css3/device-adapt/viewport-width-check-window-innerwidth-correct.html: Added.
+
2012-12-03 Alexander Pavlov <apavlov@chromium.org>
Web Inspector: [Styles] Retain selector case as written in the source code
diff --git a/LayoutTests/css3/device-adapt/resources/viewport-width-check-inner-width.html b/LayoutTests/css3/device-adapt/resources/viewport-width-check-inner-width.html
new file mode 100644
index 0000000..711c33e
--- /dev/null
+++ b/LayoutTests/css3/device-adapt/resources/viewport-width-check-inner-width.html
@@ -0,0 +1,24 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <style type="text/css">
+ @-webkit-viewport {
+ width: 300px;
+ }
+ </style>
+ <script type="text/javascript">
+ function load() {
+ var result = document.getElementById("result");
+ result.innerHTML = "window.innerWidth should be equal to 300. Got ";
+ result.innerHTML += window.innerWidth;
+ if (window.testRunner)
+ testRunner.notifyDone();
+ }
+ </script>
+</head>
+<body onload="load()">
+ <div id="result">
+ </p>
+ </div>
+</body>
+</html>
diff --git a/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct-expected.txt b/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct-expected.txt
new file mode 100644
index 0000000..a0418fd
--- /dev/null
+++ b/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct-expected.txt
@@ -0,0 +1 @@
+window.innerWidth should be equal to 300. Got 300
diff --git a/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct.html b/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct.html
new file mode 100644
index 0000000..a3c93d9
--- /dev/null
+++ b/LayoutTests/css3/device-adapt/viewport-width-check-window-innerwidth-correct.html
@@ -0,0 +1,18 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <title>CSS Test: window.innerWidth should return valid value, when CSS viewport descriptors applied.</title>
+ <link rel="author" title="Mikhail Pozdnyakov" href="mailto:mikhail.pozdnyakov@intel.com" />
+ <script type="text/javascript">
+ if (window.testRunner) {
+ testRunner.dumpAsText();
+ testRunner.waitUntilDone();
+ testRunner.setBackingScaleFactor(2, backingScaleFactorCallback);
+ }
+
+ function backingScaleFactorCallback() {
+ window.location = "resources/viewport-width-check-inner-width.html";
+ }
+ </script>
+</head>
+</html>
diff --git a/Source/WebCore/ChangeLog b/Source/WebCore/ChangeLog
index aa99f45..c0b1939 100644
--- a/Source/WebCore/ChangeLog
+++ b/Source/WebCore/ChangeLog
@@ -1,3 +1,36 @@
+2012-12-03 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+
+ CSS Device Adaptation: window.innerWidth returns wrong value if CSS viewport descriptors are applied
+ https://bugs.webkit.org/show_bug.cgi?id=103737
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ ViewportStyleResolver used frame view visibleContentRect size as initial viewport size.
+ This however caused a problem when page enabled/disabled CSS stylesheets, having viewport
+ descriptors. Viewport descriptors from new stylesheet were applied to the visibleContentRect
+ affected already by the viewport descriptors from the previous stylesheet.
+
+ New 'initialViewportSize' property (http://dev.w3.org/csswg/css-device-adapt/#initial-viewport)
+ was added to frame view so that viewport descriptors can always be applied to the reliable
+ viewport size.
+
+ Test: css3/device-adapt/viewport-width-check-window-innerwidth-correct.html
+
+ * css/ViewportStyleResolver.cpp:
+ (WebCore::ViewportStyleResolver::ViewportStyleResolver):
+ (WebCore::ViewportStyleResolver::getViewportArgumentValue):
+ * css/ViewportStyleResolver.h:
+ (ViewportStyleResolver):
+ * dom/Document.cpp:
+ (WebCore):
+ (WebCore::Document::initialViewportSize):
+ * dom/Document.h:
+ (Document):
+ * page/FrameView.h:
+ (FrameView):
+ (WebCore::FrameView::initialViewportSize):
+ (WebCore::FrameView::setInitialViewportSize):
+
2012-12-03 Alexander Pavlov <apavlov@chromium.org>
Web Inspector: [Styles] Retain selector case as written in the source code
diff --git a/Source/WebCore/css/ViewportStyleResolver.cpp b/Source/WebCore/css/ViewportStyleResolver.cpp
index 4148e7c4..4ec98fd 100644
--- a/Source/WebCore/css/ViewportStyleResolver.cpp
+++ b/Source/WebCore/css/ViewportStyleResolver.cpp
@@ -46,9 +46,6 @@
: m_document(document)
{
ASSERT(m_document);
-
- m_initialViewportSize.setWidth(m_document->viewportSize().width());
- m_initialViewportSize.setHeight(m_document->viewportSize().height());
}
void ViewportStyleResolver::addViewportRule(StyleRuleViewport* viewportRule)
@@ -125,10 +122,12 @@
switch (id) {
case CSSPropertyMaxHeight:
case CSSPropertyMinHeight:
- return percentValue * m_initialViewportSize.height();
+ ASSERT(m_document->initialViewportSize().height() > 0);
+ return percentValue * m_document->initialViewportSize().height();
case CSSPropertyMaxWidth:
case CSSPropertyMinWidth:
- return percentValue * m_initialViewportSize.width();
+ ASSERT(m_document->initialViewportSize().width() > 0);
+ return percentValue * m_document->initialViewportSize().width();
case CSSPropertyMaxZoom:
case CSSPropertyMinZoom:
case CSSPropertyZoom:
diff --git a/Source/WebCore/css/ViewportStyleResolver.h b/Source/WebCore/css/ViewportStyleResolver.h
index 0b8ff57..307e238 100644
--- a/Source/WebCore/css/ViewportStyleResolver.h
+++ b/Source/WebCore/css/ViewportStyleResolver.h
@@ -63,8 +63,6 @@
Document* m_document;
RefPtr<StylePropertySet> m_propertySet;
-
- FloatSize m_initialViewportSize;
};
} // namespace WebCore
diff --git a/Source/WebCore/dom/Document.cpp b/Source/WebCore/dom/Document.cpp
index 2604276..14c8c07 100644
--- a/Source/WebCore/dom/Document.cpp
+++ b/Source/WebCore/dom/Document.cpp
@@ -5657,6 +5657,15 @@
return view()->visibleContentRect(/* includeScrollbars */ true).size();
}
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+IntSize Document::initialViewportSize() const
+{
+ if (!view())
+ return IntSize();
+ return view()->initialViewportSize();
+}
+#endif
+
Node* eventTargetNodeForDocument(Document* doc)
{
if (!doc)
diff --git a/Source/WebCore/dom/Document.h b/Source/WebCore/dom/Document.h
index 95e25c5..27ec3cf 100644
--- a/Source/WebCore/dom/Document.h
+++ b/Source/WebCore/dom/Document.h
@@ -1134,6 +1134,10 @@
IntSize viewportSize() const;
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ IntSize initialViewportSize() const;
+#endif
+
#if ENABLE(LINK_PRERENDER)
Prerenderer* prerenderer() { return m_prerenderer.get(); }
#endif
diff --git a/Source/WebCore/page/FrameView.h b/Source/WebCore/page/FrameView.h
index dab46ae..42c4c34 100644
--- a/Source/WebCore/page/FrameView.h
+++ b/Source/WebCore/page/FrameView.h
@@ -373,6 +373,10 @@
void setHasSoftwareFilters(bool hasSoftwareFilters) { m_hasSoftwareFilters = hasSoftwareFilters; }
bool hasSoftwareFilters() const { return m_hasSoftwareFilters; }
#endif
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ IntSize initialViewportSize() const { return m_initialViewportSize; }
+ void setInitialViewportSize(const IntSize& size) { m_initialViewportSize = size; }
+#endif
protected:
virtual bool scrollContentsFastPath(const IntSize& scrollDelta, const IntRect& rectToScroll, const IntRect& clipRect);
@@ -573,6 +577,11 @@
#if ENABLE(CSS_FILTERS)
bool m_hasSoftwareFilters;
#endif
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ // Size of viewport before any UA or author styles have overridden
+ // the viewport given by the window or viewing area of the UA.
+ IntSize m_initialViewportSize;
+#endif
};
inline void FrameView::incrementVisuallyNonEmptyCharacterCount(unsigned count)
diff --git a/Source/WebKit2/ChangeLog b/Source/WebKit2/ChangeLog
index 3145077..3df3428 100644
--- a/Source/WebKit2/ChangeLog
+++ b/Source/WebKit2/ChangeLog
@@ -1,3 +1,25 @@
+2012-12-03 Mikhail Pozdnyakov <mikhail.pozdnyakov@intel.com>
+
+ CSS Device Adaptation: window.innerWidth returns wrong value if CSS viewport descriptors are applied
+ https://bugs.webkit.org/show_bug.cgi?id=103737
+
+ Reviewed by Kenneth Rohde Christiansen.
+
+ ViewportStyleResolver used frame view visibleContentRect size as initial viewport size.
+ This however caused a problem when page enabled/disabled CSS stylesheets, having viewport
+ descriptors. Viewport descriptors from new stylesheet were applied to the visibleContentRect
+ affected already by the viewport descriptors from the previous stylesheet.
+
+ New 'initialViewportSize' property (http://dev.w3.org/csswg/css-device-adapt/#initial-viewport)
+ was added to frame view so that viewport descriptors can always be applied to the reliable
+ viewport size.
+
+ Both newly added 'initialViewportSize' property and 'fixedVisibleContentRect' property
+ are assigned appropriately now in WebPage::sendViewportAttributesChanged().
+
+ * WebProcess/WebPage/WebPage.cpp:
+ (WebKit::WebPage::sendViewportAttributesChanged):
+
2012-12-02 Huang Dongsung <luxtella@company100.net>
Coordinated Graphics: Reorder messages to LayerTreeCoordinatorProxy
diff --git a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
index 441b14d..725b08b 100644
--- a/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
+++ b/Source/WebKit2/WebProcess/WebPage/WebPage.cpp
@@ -1029,7 +1029,6 @@
int deviceHeight = (settings->deviceHeight() > 0) ? settings->deviceHeight() : m_viewportSize.height();
ViewportAttributes attr = computeViewportAttributes(m_page->viewportArguments(), minimumLayoutFallbackWidth, deviceWidth, deviceHeight, m_page->deviceScaleFactor(), m_viewportSize);
- attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
// Keep the current position, update size only.
// For the new loads position is already reset to (0,0).
@@ -1037,12 +1036,21 @@
IntPoint contentFixedOrigin = view->fixedVisibleContentRect().location();
// Put the width and height to the viewport width and height. In css units however.
- // FIXME: This should be in scaled units but this currently affects viewport attributes calculation.
IntSize contentFixedSize = m_viewportSize;
+
contentFixedSize.scale(1 / m_page->deviceScaleFactor());
+#if ENABLE(CSS_DEVICE_ADAPTATION)
+ // CSS viewport descriptors might be applied to already affected viewport size
+ // if the page enables/disables stylesheets, so need to keep initial viewport size.
+ view->setInitialViewportSize(contentFixedSize);
+#endif
+
+ contentFixedSize.scale(1 / attr.initialScale);
setFixedVisibleContentRect(IntRect(contentFixedOrigin, contentFixedSize));
+ attr.initialScale = m_page->viewportArguments().zoom; // Resets auto (-1) if no value was set by user.
+
// This also takes care of the relayout.
setFixedLayoutSize(roundedIntSize(attr.layoutSize));