author | Xidorn Quan <quanxunzhen@gmail.com> |
Wed, 30 Sep 2015 10:48:41 +1000 | |
changeset 265095 | df5ce21dade97b0703c742efcf15fbc15fbfd615 |
parent 265094 | de8b305fb6f904932e587882c248f5eed88731cb |
child 265096 | 8b090a69694cb058d9ea438ef68d0c8b1bbbb3fa |
push id | 65839 |
push user | xquan@mozilla.com |
push date | Wed, 30 Sep 2015 00:49:05 +0000 |
treeherder | mozilla-inbound@8b090a69694c [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | roc |
bugs | 1201798 |
milestone | 44.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/base/nsDocument.cpp +++ b/dom/base/nsDocument.cpp @@ -11333,16 +11333,26 @@ LogFullScreenDenied(bool aLogFailure, co false); asyncDispatcher->PostDOMEvent(); nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, NS_LITERAL_CSTRING("DOM"), aDoc, nsContentUtils::eDOM_PROPERTIES, aMessage); } +static void +UpdateViewportScrollbarOverrideForFullscreen(nsIDocument* aDoc) +{ + if (nsIPresShell* presShell = aDoc->GetShell()) { + if (nsPresContext* presContext = presShell->GetPresContext()) { + presContext->UpdateViewportScrollbarStylesOverride(); + } + } +} + void nsDocument::CleanupFullscreenState() { // Iterate the fullscreen stack and clear the fullscreen states. // Since we also need to clear the fullscreen-ancestor state, and // currently fullscreen elements can only be placed in hierarchy // order in the stack, reversely iterating the stack could be more // efficient. NOTE that fullscreen-ancestor state would be removed @@ -11352,29 +11362,31 @@ nsDocument::CleanupFullscreenState() if (nsCOMPtr<Element> element = do_QueryReferent(weakPtr)) { // Remove any VR state properties element->DeleteProperty(nsGkAtoms::vr_state); EventStateManager::SetFullScreenState(element, false); } } mFullScreenStack.Clear(); mFullscreenRoot = nullptr; + UpdateViewportScrollbarOverrideForFullscreen(this); } bool nsDocument::FullScreenStackPush(Element* aElement) { NS_ASSERTION(aElement, "Must pass non-null to FullScreenStackPush()"); Element* top = FullScreenStackTop(); if (top == aElement || !aElement) { return false; } EventStateManager::SetFullScreenState(aElement, true); mFullScreenStack.AppendElement(do_GetWeakReference(aElement)); NS_ASSERTION(GetFullScreenElement() == aElement, "Should match"); + UpdateViewportScrollbarOverrideForFullscreen(this); return true; } void nsDocument::FullScreenStackPop() { if (mFullScreenStack.IsEmpty()) { return; @@ -11404,16 +11416,18 @@ nsDocument::FullScreenStackPop() "Should have already removed full-screen styles"); uint32_t last = mFullScreenStack.Length() - 1; mFullScreenStack.RemoveElementAt(last); } else { // The top element of the stack is now an in-doc element. Return here. break; } } + + UpdateViewportScrollbarOverrideForFullscreen(this); } Element* nsDocument::FullScreenStackTop() { if (mFullScreenStack.IsEmpty()) { return nullptr; }
--- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -2302,22 +2302,22 @@ nsCSSFrameConstructor::ConstructDocEleme // by a new root element style (e.g. a propagated 'direction'). // @see nsStyleContext::ApplyStyleFixups { nsRefPtr<nsStyleContext> sc = mPresShell->StyleSet()-> ResolveAnonymousBoxStyle(nsCSSAnonBoxes::viewport, nullptr); GetRootFrame()->SetStyleContextWithoutNotification(sc); } - // Make sure to call PropagateScrollToViewport before + // Make sure to call UpdateViewportScrollbarStylesOverride before // SetUpDocElementContainingBlock, since it sets up our scrollbar state // properly. DebugOnly<nsIContent*> propagatedScrollFrom; if (nsPresContext* presContext = mPresShell->GetPresContext()) { - propagatedScrollFrom = presContext->PropagateScrollToViewport(); + propagatedScrollFrom = presContext->UpdateViewportScrollbarStylesOverride(); } SetUpDocElementContainingBlock(aDocElement); NS_ASSERTION(mDocElementContainingBlock, "Should have parent by now"); nsFrameConstructorState state(mPresShell, GetAbsoluteContainingBlock(mDocElementContainingBlock, FIXED_POS), @@ -4420,17 +4420,17 @@ nsCSSFrameConstructor::FindDisplayData(c // it might have dynamically changed from scrollable to not scrollable, // and that might need to be propagated. // XXXbz is this the right place to do this? If this code moves, // make this function static. bool propagatedScrollToViewport = false; if (aElement->IsHTMLElement(nsGkAtoms::body)) { if (nsPresContext* presContext = mPresShell->GetPresContext()) { propagatedScrollToViewport = - presContext->PropagateScrollToViewport() == aElement; + presContext->UpdateViewportScrollbarStylesOverride() == aElement; } } NS_ASSERTION(!propagatedScrollToViewport || !mPresShell->GetPresContext()->IsPaginated(), "Shouldn't propagate scroll in paginated contexts"); if (aDisplay->IsBlockInsideStyle()) {
--- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -1570,82 +1570,72 @@ nsPresContext::ScreenSizeInchesForFontIn *aChanged = true; mLastFontInflationScreenSize = deviceSizeInches; } return deviceSizeInches; } static bool -CheckOverflow(nsPresContext* aPresContext, const nsStyleDisplay* aDisplay) +CheckOverflow(const nsStyleDisplay* aDisplay, ScrollbarStyles* aStyles) { if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE && aDisplay->mScrollBehavior == NS_STYLE_SCROLL_BEHAVIOR_AUTO && aDisplay->mScrollSnapTypeX == NS_STYLE_SCROLL_SNAP_TYPE_NONE && aDisplay->mScrollSnapTypeY == NS_STYLE_SCROLL_SNAP_TYPE_NONE && aDisplay->mScrollSnapPointsX == nsStyleCoord(eStyleUnit_None) && aDisplay->mScrollSnapPointsY == nsStyleCoord(eStyleUnit_None) && !aDisplay->mScrollSnapDestination.mXPosition.mHasPercent && !aDisplay->mScrollSnapDestination.mYPosition.mHasPercent && aDisplay->mScrollSnapDestination.mXPosition.mLength == 0 && aDisplay->mScrollSnapDestination.mYPosition.mLength == 0) { return false; } if (aDisplay->mOverflowX == NS_STYLE_OVERFLOW_CLIP) { - aPresContext->SetViewportScrollbarStylesOverride( - ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, - NS_STYLE_OVERFLOW_HIDDEN, - aDisplay)); + *aStyles = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, + NS_STYLE_OVERFLOW_HIDDEN, aDisplay); } else { - aPresContext->SetViewportScrollbarStylesOverride( - ScrollbarStyles(aDisplay)); + *aStyles = ScrollbarStyles(aDisplay); } return true; } -/** - * This checks the root element and the HTML BODY, if any, for an "overflow" property - * that should be applied to the viewport. If one is found then we return the - * element that we took the overflow from (which should then be treated as - * "overflow:visible"), and we store the overflow style in the prescontext. - * @return if scroll was propagated from some content node, the content node it - * was propagated from. - */ -nsIContent* -nsPresContext::PropagateScrollToViewport() +static nsIContent* +GetPropagatedScrollbarStylesForViewport(nsPresContext* aPresContext, + ScrollbarStyles *aStyles) { // Set default - SetViewportScrollbarStylesOverride(ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO, - NS_STYLE_OVERFLOW_AUTO)); + *aStyles = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO); // We never mess with the viewport scroll state // when printing or in print preview - if (IsPaginated()) { + if (aPresContext->IsPaginated()) { return nullptr; } - Element* docElement = mDocument->GetRootElement(); + nsIDocument* document = aPresContext->Document(); + Element* docElement = document->GetRootElement(); // Check the style on the document root element - nsStyleSet *styleSet = mShell->StyleSet(); + nsStyleSet *styleSet = aPresContext->StyleSet(); nsRefPtr<nsStyleContext> rootStyle; rootStyle = styleSet->ResolveStyleFor(docElement, nullptr); - if (CheckOverflow(this, rootStyle->StyleDisplay())) { + if (CheckOverflow(rootStyle->StyleDisplay(), aStyles)) { // tell caller we stole the overflow style from the root element return docElement; } // Don't look in the BODY for non-HTML documents or HTML documents // with non-HTML roots // XXX this should be earlier; we shouldn't even look at the document root // for non-HTML documents. Fix this once we support explicit CSS styling // of the viewport // XXX what about XHTML? - nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(mDocument)); + nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(document)); if (!htmlDoc || !docElement->IsHTMLElement()) { return nullptr; } nsCOMPtr<nsIDOMHTMLElement> body; htmlDoc->GetBody(getter_AddRefs(body)); nsCOMPtr<nsIContent> bodyElement = do_QueryInterface(body); @@ -1653,24 +1643,47 @@ nsPresContext::PropagateScrollToViewport !bodyElement->NodeInfo()->Equals(nsGkAtoms::body)) { // The body is not a <body> tag, it's a <frameset>. return nullptr; } nsRefPtr<nsStyleContext> bodyStyle; bodyStyle = styleSet->ResolveStyleFor(bodyElement->AsElement(), rootStyle); - if (CheckOverflow(this, bodyStyle->StyleDisplay())) { + if (CheckOverflow(bodyStyle->StyleDisplay(), aStyles)) { // tell caller we stole the overflow style from the body element return bodyElement; } return nullptr; } +nsIContent* +nsPresContext::UpdateViewportScrollbarStylesOverride() +{ + nsIContent* propagatedFrom = + GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar); + + nsIDocument* document = Document(); + if (Element* fullscreenElement = document->GetFullScreenElement()) { + // If the document is in fullscreen, but the fullscreen element is + // not the root element, we should explicitly suppress the scrollbar + // here. Note that, we still need to return the original element + // the styles are from, so that the state of those elements is not + // affected across fullscreen change. + if (fullscreenElement != document->GetRootElement() && + fullscreenElement != propagatedFrom) { + mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, + NS_STYLE_OVERFLOW_HIDDEN); + } + } + + return propagatedFrom; +} + void nsPresContext::SetContainer(nsIDocShell* aDocShell) { if (aDocShell) { NS_ASSERTION(!(mContainer && mNeedsPrefUpdate), "Should only need pref update if mContainer is null."); mContainer = static_cast<nsDocShell*>(aDocShell); if (mNeedsPrefUpdate) {
--- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -660,27 +660,32 @@ public: static nscoord CSSPointsToAppUnits(float aPoints) { return NSToCoordRound(aPoints * mozilla::AppUnitsPerCSSInch() / POINTS_PER_INCH_FLOAT); } nscoord RoundAppUnitsToNearestDevPixels(nscoord aAppUnits) const { return DevPixelsToAppUnits(AppUnitsToDevPixels(aAppUnits)); } - void SetViewportScrollbarStylesOverride(const ScrollbarStyles& aScrollbarStyle) - { - mViewportStyleScrollbar = aScrollbarStyle; - } + /** + * This checks the root element and the HTML BODY, if any, for an "overflow" + * property that should be applied to the viewport. If one is found then we + * return the element that we took the overflow from (which should then be + * treated as "overflow: visible"), and we store the overflow style here. + * If the document is in fullscreen, and the fullscreen element is not the + * root, the scrollbar of viewport will be suppressed. + * @return if scroll was propagated from some content node, the content node + * it was propagated from. + */ + nsIContent* UpdateViewportScrollbarStylesOverride(); ScrollbarStyles GetViewportScrollbarStylesOverride() { return mViewportStyleScrollbar; } - nsIContent* PropagateScrollToViewport(); - /** * Set and get methods for controlling the background drawing */ bool GetBackgroundImageDraw() const { return mDrawImageBackground; } void SetBackgroundImageDraw(bool aCanDraw) { mDrawImageBackground = aCanDraw; }
--- a/layout/style/ua.css +++ b/layout/style/ua.css @@ -275,23 +275,16 @@ margin: 0 !important; min-width: 0 !important; max-width: none !important; min-height: 0 !important; max-height: none !important; box-sizing: border-box !important; } -/* If there is a full-screen element that is not the root then - we should hide the viewport scrollbar. We exclude the chrome - document to prevent reframing of contained plugins. */ -:not(xul|*):root:-moz-full-screen-ancestor { - overflow: hidden !important; -} - /* XML parse error reporting */ parsererror|parsererror { display: block; font-family: sans-serif; font-weight: bold; white-space: pre; margin: 1em;