Bug 1519013 - Shrink the content to display size if user has never changed the site resolution. r=botond

elementFromPoint-002.html, elementFromPoint-003.html and dialog-showModal.html
use document.elementFromPoint with a given point which is calculated from the
value returned by getBoundingClientRect() for a 100% width element.  Before
this change, the given point is outside of view because there is no viewport
meta tag in the documents so that elementFromPoint fails.  After this change, the
documents fit to the visual viewport so that elementFromPoint works as expected.

Differential Revision: https://phabricator.services.mozilla.com/D16155

--HG--
extra : moz-landing-system : lando
This commit is contained in:
Hiroyuki Ikezoe 2019-03-28 03:04:59 +00:00
parent dd00e6a022
commit 9db5bc51b8
13 changed files with 213 additions and 22 deletions

View File

@ -390,9 +390,9 @@ void MobileViewportManager::UpdateResolution(
MOZ_ASSERT(aDisplayWidthChangeRatio.isNothing());
// We try to scale down the contents only IF the document has no
// initial-scale AND IF it's the initial paint AND IF it's not restored
// documents.
if (mIsFirstPaint && !mRestoreResolution &&
// initial-scale AND IF it's not restored documents AND IF the resolution
// has never been changed by APZ.
if (!mRestoreResolution && !mPresShell->IsResolutionUpdatedByApz() &&
!aViewportInfo.IsDefaultZoomValid()) {
if (zoom != intrinsicScale) {
newZoom = Some(intrinsicScale);

View File

@ -75,6 +75,13 @@ class MobileViewportManager final : public nsIDOMEventListener,
return mDisplaySize;
};
/*
* Shrink the content to fit it to the display width if no initial-scale is
* specified and if the content is still wider than the display width.
*/
void ShrinkToDisplaySizeIfNeeded(nsViewportInfo& aViewportInfo,
const mozilla::ScreenIntSize& aDisplaySize);
private:
~MobileViewportManager();
@ -133,13 +140,6 @@ class MobileViewportManager final : public nsIDOMEventListener,
mozilla::ScreenIntSize GetCompositionSize(
const mozilla::ScreenIntSize& aDisplaySize) const;
/*
* Shrink the content to fit it to the display width if no initial-scale is
* specified and if the content is still wider than the display width.
*/
void ShrinkToDisplaySizeIfNeeded(nsViewportInfo& aViewportInfo,
const mozilla::ScreenIntSize& aDisplaySize);
RefPtr<mozilla::dom::Document> mDocument;
// raw ref since the presShell owns this
nsIPresShell* MOZ_NON_OWNING_REF mPresShell;

View File

@ -2042,6 +2042,7 @@ ScrollFrameHelper::ScrollFrameHelper(nsContainerFrame* aOuter, bool aIsRoot)
mHasOutOfFlowContentInsideFilter(false),
mSuppressScrollbarRepaints(false),
mIsUsingMinimumScaleSize(false),
mMinimumScaleSizeChanged(false),
mVelocityQueue(aOuter->PresContext()) {
if (LookAndFeel::GetInt(LookAndFeel::eIntID_UseOverlayScrollbars) != 0) {
mScrollbarActivity = new ScrollbarActivity(do_QueryFrame(aOuter));
@ -5573,10 +5574,38 @@ void ScrollFrameHelper::FinishReflowForScrollbar(Element* aElement,
SetCoordAttribute(aElement, nsGkAtoms::increment, aIncrement);
}
class MOZ_RAII AutoMinimumScaleSizeChangeDetector final {
public:
explicit AutoMinimumScaleSizeChangeDetector(
ScrollFrameHelper* aScrollFrameHelper)
: mHelper(aScrollFrameHelper) {
MOZ_ASSERT(mHelper);
MOZ_ASSERT(mHelper->mIsRoot);
mPreviousMinimumScaleSize = aScrollFrameHelper->mMinimumScaleSize;
mPreviousIsUsingMinimumScaleSize =
aScrollFrameHelper->mIsUsingMinimumScaleSize;
}
~AutoMinimumScaleSizeChangeDetector() {
if (mPreviousMinimumScaleSize != mHelper->mMinimumScaleSize ||
mPreviousIsUsingMinimumScaleSize != mHelper->mIsUsingMinimumScaleSize) {
mHelper->mMinimumScaleSizeChanged = true;
}
}
private:
ScrollFrameHelper* mHelper;
nsSize mPreviousMinimumScaleSize;
bool mPreviousIsUsingMinimumScaleSize;
};
void ScrollFrameHelper::UpdateMinimumScaleSize(
const nsRect& aScrollableOverflow, const nsSize& aICBSize) {
MOZ_ASSERT(mIsRoot);
AutoMinimumScaleSizeChangeDetector minimumScaleSizeChangeDetector(this);
mIsUsingMinimumScaleSize = false;
if (!mOuter->PresShell()->GetIsViewportOverridden()) {
@ -5645,6 +5674,25 @@ void ScrollFrameHelper::UpdateMinimumScaleSize(
bool ScrollFrameHelper::ReflowFinished() {
mPostedReflowCallback = false;
if (mIsRoot && mMinimumScaleSizeChanged &&
mOuter->PresShell()->GetIsViewportOverridden() &&
!mOuter->PresShell()->IsResolutionUpdatedByApz()) {
nsIPresShell* presShell = mOuter->PresShell();
RefPtr<MobileViewportManager> manager =
presShell->GetMobileViewportManager();
MOZ_ASSERT(manager);
ScreenIntSize displaySize = ViewAs<ScreenPixel>(
manager->DisplaySize(),
PixelCastJustification::LayoutDeviceIsScreenForBounds);
Document* doc = presShell->GetDocument();
MOZ_ASSERT(doc, "The document should be valid");
nsViewportInfo viewportInfo = doc->GetViewportInfo(displaySize);
manager->ShrinkToDisplaySizeIfNeeded(viewportInfo, displaySize);
mMinimumScaleSizeChanged = false;
}
bool doScroll = true;
if (NS_SUBTREE_DIRTY(mOuter)) {
// We will get another call after the next reflow and scrolling

View File

@ -711,6 +711,9 @@ class ScrollFrameHelper : public nsIReflowCallback {
// True if we are using the minimum scale size instead of ICB for scroll port.
bool mIsUsingMinimumScaleSize : 1;
// True if the minimum scale size has been changed since the last reflow.
bool mMinimumScaleSizeChanged : 1;
mozilla::layout::ScrollVelocityQueue mVelocityQueue;
protected:

View File

@ -0,0 +1,40 @@
<!DOCTYPE html>
<!--
`reftest-snapshot-all` is necessary to take the screenshot for whole canvas
when zoom level is changed.
This is the same as what we do in the case where reftest-async-zoom is
specified.
-->
<html class="reftest-wait reftest-snapshot-all">
<meta name="viewport" content="width=device-width, minimum-scale=0.5">
<style>
html {
overflow-x: hidden;
scrollbar-width: none;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
position: absolute;
}
</style>
<div id="green" style="background: green; width: 100%; height: 100%;"></div>
<div style="background: blue; width: 100%; height: 100%;"></div>
<script>
document.addEventListener('MozReftestInvalidate', () => {
green.style.width = '200%';
requestAnimationFrame(() => {
// At this moment we don't scale down the contents due to bug 1508177.
green.style.height = '200%';
requestAnimationFrame(() => {
// Growing height should make the overflow-x:hidden area visible.
document.documentElement.classList.remove('reftest-wait');
});
});
});
</script>
</html>

View File

@ -0,0 +1,30 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta name="viewport" content="width=device-width, minimum-scale=0.5">
<style>
html {
overflow-x: hidden;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
height: 100%;
position: absolute;
}
</style>
<div id="green" style="background: green; width: 100%;"></div>
<div style="background: blue; width: 100%;"></div>
<script>
document.addEventListener('MozReftestInvalidate', () => {
// Grow width to generate overflow-x:hidden area but the content height is
// 100vh so that we don't scale down the contents (bug 1508177).
green.style.width = '200%';
requestAnimationFrame(() => {
document.documentElement.classList.remove('reftest-wait');
});
});
</script>
</html>

View File

@ -0,0 +1,35 @@
<!DOCTYPE html>
<!--
`reftest-snapshot-all` is necessary to take the screenshot for whole canvas
when zoom level is changed.
This is the same as what we do in the case where reftest-async-zoom is
specified.
-->
<html class="reftest-wait reftest-snapshot-all">
<meta name="viewport" content="width=device-width, minimum-scale=0.5">
<style>
html {
overflow: hidden;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
position: absolute;
}
</style>
<div id="red" style="background: red; width: 100%; height: 300%;"></div>
<div id="green" style="background: green; width: 100%; height: 200%;"></div>
<div style="background: blue; width: 100%; height: 100%;"></div>
<script>
document.addEventListener('MozReftestInvalidate', () => {
green.style.width = '200%';
red.style.width = '300%';
requestAnimationFrame(() => {
document.documentElement.classList.remove('reftest-wait');
});
});
</script>
</html>

View File

@ -22,5 +22,9 @@ skip-if(winWidget||webrender) fails == horizontal-overflow-hidden-region.html ho
skip-if(winWidget||webrender) == vertical-overflow-hidden-region.html about:blank
skip-if(winWidget||webrender) == scroll-to-unreachable-area.html scroll-to-unreachable-area-ref.html
skip-if(winWidget||webrender) == wrapped-text-at-icb.html wrapped-text-at-icb-ref.html
skip-if(winWidget||webrender) == overflow-hidden-region-dynamic-width-change.html overflow-region-ref.html
skip-if(winWidget||webrender) == remove-overflow-hidden-region.html remove-overflow-hidden-region-ref.html
skip-if(winWidget||webrender) fails == dynamic-grow-width.html horizontal-overflow-hidden-region-ref.html # bug 1508177
skip-if(winWidget||webrender) == dynamic-grow-width-and-height.html overflow-region-ref.html
skip-if(winWidget||webrender) == not-able-to-scrollTo.html about:blank
skip-if(winWidget||webrender) == min-scale-aspect-ratio.html about:blank

View File

@ -0,0 +1,18 @@
<!DOCTYPE html>
<html>
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html {
overflow: hidden;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
position: absolute;
}
</style>
<div style="background: blue; width: 100%; height: 100%;"></div>
</html>

View File

@ -0,0 +1,25 @@
<!DOCTYPE html>
<html class="reftest-wait">
<meta name="viewport" content="width=device-width, minimum-scale=0.5">
<style>
html {
overflow: hidden;
}
html, body {
margin: 0;
width: 100%;
height: 100%;
}
div {
position: absolute;
}
</style>
<div id="green" style="background: green; width: 200%; height: 200%;"></div>
<div style="background: blue; width: 100%; height: 100%; height: 100%;"></div>
<script>
document.addEventListener('MozReftestInvalidate', () => {
green.style.width = '100%';
document.documentElement.classList.remove('reftest-wait');
});
</script>
</html>

View File

@ -1,4 +0,0 @@
[elementFromPoint-002.html]
[Checking whether dynamic changes to visibility interact correctly with\n table anonymous boxes]
expected:
if (os == "android"): FAIL

View File

@ -1,4 +0,0 @@
[elementFromPoint-003.html]
[Checking whether dynamic changes to visibility interact correctly with\n table anonymous boxes]
expected:
if (os == "android"): FAIL

View File

@ -12,7 +12,3 @@
[opening dialog with multiple focusable children, one having the autofocus attribute]
expected: FAIL
[when opening multiple dialogs, the most recently opened is rendered on top]
expected:
if (os == "android"): FAIL