diff options
Diffstat (limited to 'layout')
125 files changed, 3610 insertions, 865 deletions
diff --git a/layout/base/RestyleManagerBase.cpp b/layout/base/RestyleManagerBase.cpp index 9a5ce43eb..d96d9dbbb 100644 --- a/layout/base/RestyleManagerBase.cpp +++ b/layout/base/RestyleManagerBase.cpp @@ -154,7 +154,7 @@ RestyleManagerBase::ChangeHintToString(nsChangeHint aHint) "NeutralChange", "InvalidateRenderingObservers", "ReflowChangesSizeOrPosition", "UpdateComputedBSize", "UpdateUsesOpacity", "UpdateBackgroundPosition", - "AddOrRemoveTransform" + "AddOrRemoveTransform", "CSSOverflowChange", }; static_assert(nsChangeHint_AllHints == (1 << ArrayLength(names)) - 1, "Name list doesn't match change hints."); @@ -1070,6 +1070,67 @@ RestyleManagerBase::ProcessRestyledFrames(nsStyleChangeList& aChangeList) FramePropertyTable* propTable = presContext->PropertyTable(); nsCSSFrameConstructor* frameConstructor = presContext->FrameConstructor(); + // Handle nsChangeHint_CSSOverflowChange, by either updating the + // scrollbars on the viewport, or upgrading the change hint to frame-reconstruct. + for (nsStyleChangeData& data : aChangeList) { + if (data.mHint & nsChangeHint_CSSOverflowChange) { + data.mHint &= ~nsChangeHint_CSSOverflowChange; + bool doReconstruct = true; // assume the worst + + // Only bother with this if we're html/body, since: + // (a) It'd be *expensive* to reframe these particular nodes. They're + // at the root, so reframing would mean rebuilding the world. + // (b) It's often *unnecessary* to reframe for "overflow" changes on + // these particular nodes. In general, the only reason we reframe + // for "overflow" changes is so we can construct (or destroy) a + // scrollframe & scrollbars -- and the html/body nodes often don't + // need their own scrollframe/scrollbars because they coopt the ones + // on the viewport (which always exist). So depending on whether + // that's happening, we can skip the reframe for these nodes. + if (data.mContent->IsAnyOfHTMLElements(nsGkAtoms::body, + nsGkAtoms::html)) { + // If the restyled element provided/provides the scrollbar styles for + // the viewport before and/or after this restyle, AND it's not coopting + // that responsibility from some other element (which would need + // reconstruction to make its own scrollframe now), THEN: we don't need + // to reconstruct - we can just reflow, because no scrollframe is being + // added/removed. + nsIContent* prevOverrideNode = + presContext->GetViewportScrollbarStylesOverrideNode(); + nsIContent* newOverrideNode = + presContext->UpdateViewportScrollbarStylesOverride(); + + if (data.mContent == prevOverrideNode || + data.mContent == newOverrideNode) { + // If we get here, the restyled element provided the scrollbar styles + // for viewport before this restyle, OR it will provide them after. + if (!prevOverrideNode || !newOverrideNode || + prevOverrideNode == newOverrideNode) { + // If we get here, the restyled element is NOT replacing (or being + // replaced by) some other element as the viewport's + // scrollbar-styles provider. (If it were, we'd potentially need to + // reframe to create a dedicated scrollframe for whichever element + // is being booted from providing viewport scrollbar styles.) + // + // Under these conditions, we're OK to assume that this "overflow" + // change only impacts the root viewport's scrollframe, which + // already exists, so we can simply reflow instead of reframing. + // When requesting this reflow, we send the exact same change hints + // that "width" and "height" would send (since conceptually, + // adding/removing scrollbars is like changing the available + // space). + data.mHint |= (nsChangeHint_ReflowHintsForISizeChange | + nsChangeHint_ReflowHintsForBSizeChange); + doReconstruct = false; + } + } + } + if (doReconstruct) { + data.mHint |= nsChangeHint_ReconstructFrame; + } + } + } + // Make sure to not rebuild quote or counter lists while we're // processing restyles frameConstructor->BeginUpdate(); diff --git a/layout/base/nsCSSFrameConstructor.cpp b/layout/base/nsCSSFrameConstructor.cpp index a118c38f9..767298b85 100644 --- a/layout/base/nsCSSFrameConstructor.cpp +++ b/layout/base/nsCSSFrameConstructor.cpp @@ -3658,13 +3658,13 @@ nsCSSFrameConstructor::FindInputData(Element* aElement, nsCSSAnonBoxes::buttonContent) }, // TODO: this is temporary until a frame is written: bug 635240. SIMPLE_INT_CREATE(NS_FORM_INPUT_NUMBER, NS_NewNumberControlFrame), - // TODO: this is temporary until a frame is written: bug 888320. - SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame), #if defined(MOZ_WIDGET_ANDROID) || defined(MOZ_WIDGET_GONK) // On Android/B2G, date/time input appears as a normal text box. SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewTextControlFrame), + SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewTextControlFrame), #else SIMPLE_INT_CREATE(NS_FORM_INPUT_TIME, NS_NewDateTimeControlFrame), + SIMPLE_INT_CREATE(NS_FORM_INPUT_DATE, NS_NewDateTimeControlFrame), #endif // TODO: this is temporary until a frame is written: bug 888320 SIMPLE_INT_CREATE(NS_FORM_INPUT_MONTH, NS_NewTextControlFrame), @@ -8246,11 +8246,19 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, *aDestroyedFramesFor = aChild; } + nsPresContext* presContext = mPresShell->GetPresContext(); + MOZ_ASSERT(presContext, "Our presShell should have a valid presContext"); + if (aChild->IsHTMLElement(nsGkAtoms::body) || (!aContainer && aChild->IsElement())) { - // This might be the element we propagated viewport scrollbar - // styles from. Recompute those. - mPresShell->GetPresContext()->UpdateViewportScrollbarStylesOverride(); + // We might be removing the element that we propagated viewport scrollbar + // styles from. Recompute those. (This clause covers two of the three + // possible scrollbar-propagation sources: the <body> [as aChild or a + // descendant] and the root node. The other possible scrollbar-propagation + // source is a fullscreen element, and we have code elsewhere to update + // scrollbars after fullscreen elements are removed -- specifically, it's + // part of the fullscreen cleanup code called by Element::UnbindFromTree.) + presContext->UpdateViewportScrollbarStylesOverride(); } // XXXldb Do we need to re-resolve style to handle the CSS2 + combinator and @@ -8316,7 +8324,6 @@ nsCSSFrameConstructor::ContentRemoved(nsIContent* aContainer, ClearDisplayContentsIn(aChild, aContainer); } - nsPresContext* presContext = mPresShell->GetPresContext(); #ifdef MOZ_XUL if (NotifyListBoxBody(presContext, aContainer, aChild, aOldNextSibling, childFrame, CONTENT_REMOVED)) { diff --git a/layout/base/nsCaret.cpp b/layout/base/nsCaret.cpp index 2f08d156e..8ad435950 100644 --- a/layout/base/nsCaret.cpp +++ b/layout/base/nsCaret.cpp @@ -200,8 +200,8 @@ nsCaret::ComputeMetrics(nsIFrame* aFrame, int32_t aOffset, nscoord aCaretHeight) // between 0 and 1 goes up to 1 so we don't let the caret disappear. int32_t tpp = aFrame->PresContext()->AppUnitsPerDevPixel(); Metrics result; - result.mCaretWidth = NS_ROUND_BORDER_TO_PIXELS(caretWidth, tpp); - result.mBidiIndicatorSize = NS_ROUND_BORDER_TO_PIXELS(bidiIndicatorSize, tpp); + result.mCaretWidth = NS_ROUND_CARET_TO_PIXELS(caretWidth, tpp); + result.mBidiIndicatorSize = NS_ROUND_CARET_TO_PIXELS(bidiIndicatorSize, tpp); return result; } diff --git a/layout/base/nsChangeHint.h b/layout/base/nsChangeHint.h index 318b84840..eb2709de6 100644 --- a/layout/base/nsChangeHint.h +++ b/layout/base/nsChangeHint.h @@ -217,6 +217,16 @@ enum nsChangeHint { */ nsChangeHint_AddOrRemoveTransform = 1 << 27, + /** + * Indicates that the overflow-x and/or overflow-y property changed. + * + * In most cases, this is equivalent to nsChangeHint_ReconstructFrame. But + * in some special cases where the change is really targeting the viewport's + * scrollframe, this is instead equivalent to nsChangeHint_AllReflowHints + * (because the viewport always has an associated scrollframe). + */ + nsChangeHint_CSSOverflowChange = 1 << 28, + // IMPORTANT NOTE: When adding new hints, consider whether you need // to add them to NS_HintsNotHandledForDescendantsIn() below. Please // also add them to RestyleManager::ChangeHintToString and modify @@ -225,7 +235,7 @@ enum nsChangeHint { /** * Dummy hint value for all hints. It exists for compile time check. */ - nsChangeHint_AllHints = (1 << 28) - 1, + nsChangeHint_AllHints = (1 << 29) - 1, }; // Redefine these operators to return nothing. This will catch any use @@ -306,6 +316,7 @@ inline nsChangeHint operator^=(nsChangeHint& aLeft, nsChangeHint aRight) nsChangeHint_UpdatePostTransformOverflow | \ nsChangeHint_UpdateParentOverflow | \ nsChangeHint_ChildrenOnlyTransform | \ + nsChangeHint_CSSOverflowChange | \ nsChangeHint_RecomputePosition | \ nsChangeHint_UpdateContainingBlock | \ nsChangeHint_AddOrRemoveTransform | \ @@ -374,6 +385,48 @@ inline nsChangeHint NS_HintsNotHandledForDescendantsIn(nsChangeHint aChangeHint) nsChangeHint_ClearAncestorIntrinsics | \ nsChangeHint_ClearDescendantIntrinsics | \ nsChangeHint_NeedDirtyReflow) + +// Below are the change hints that we send for ISize & BSize changes. +// Each is similar to nsChangeHint_AllReflowHints with a few changes. + +// * For an ISize change, we send nsChangeHint_AllReflowHints, with two bits +// excluded: nsChangeHint_ClearDescendantIntrinsics (because an ancestor's +// inline-size change can't affect descendant intrinsic sizes), and +// nsChangeHint_NeedDirtyReflow (because ISize changes don't need to *force* +// all descendants to reflow). +#define nsChangeHint_ReflowHintsForISizeChange \ + nsChangeHint(nsChangeHint_AllReflowHints & \ + ~(nsChangeHint_ClearDescendantIntrinsics | \ + nsChangeHint_NeedDirtyReflow)) + +// * For a BSize change, we send almost the same hints as for ISize changes, +// with one extra: nsChangeHint_UpdateComputedBSize. We need this hint because +// BSize changes CAN affect descendant intrinsic sizes, due to replaced +// elements with percentage BSizes in descendants which also have percentage +// BSizes. nsChangeHint_UpdateComputedBSize clears intrinsic sizes for frames +// that have such replaced elements. (We could instead send +// nsChangeHint_ClearDescendantIntrinsics, but that's broader than we need.) +// +// NOTE: You might think that BSize changes could exclude +// nsChangeHint_ClearAncestorIntrinsics (which is inline-axis specific), but we +// do need to send it, to clear cached results from CSS Flex measuring reflows. +#define nsChangeHint_ReflowHintsForBSizeChange \ + nsChangeHint((nsChangeHint_AllReflowHints | \ + nsChangeHint_UpdateComputedBSize) & \ + ~(nsChangeHint_ClearDescendantIntrinsics | \ + nsChangeHint_NeedDirtyReflow)) + +// * For changes to the float area of an already-floated element, we need all +// reflow hints, but not the ones that apply to descendants. +// Our descendants aren't impacted when our float area only changes +// placement but not size/shape. (e.g. if we change which side we float to). +// But our ancestors/siblings are potentially impacted, so we need to send +// the non-descendant reflow hints. +#define nsChangeHint_ReflowHintsForFloatAreaChange \ + nsChangeHint(nsChangeHint_AllReflowHints & \ + ~(nsChangeHint_ClearDescendantIntrinsics | \ + nsChangeHint_NeedDirtyReflow)) + #define NS_STYLE_HINT_REFLOW \ nsChangeHint(NS_STYLE_HINT_VISUAL | nsChangeHint_AllReflowHints) diff --git a/layout/base/nsDocumentViewer.cpp b/layout/base/nsDocumentViewer.cpp index a1105ae52..137efb3cd 100644 --- a/layout/base/nsDocumentViewer.cpp +++ b/layout/base/nsDocumentViewer.cpp @@ -544,6 +544,12 @@ nsDocumentViewer::~nsDocumentViewer() mDocument->Destroy(); } + if (mPrintEngine) { + mPrintEngine->Destroy(); + mPrintEngine = nullptr; + } + + MOZ_RELEASE_ASSERT(mDestroyRefCount == 0); NS_ASSERTION(!mPresShell && !mPresContext, "User did not call nsIContentViewer::Destroy"); if (mPresShell || mPresContext) { @@ -1611,7 +1617,6 @@ nsDocumentViewer::Destroy() // We also keep the viewer from being cached in session history, since // we require all documents there to be sanitized. if (mDestroyRefCount != 0) { - --mDestroyRefCount; return NS_OK; } @@ -4420,6 +4425,12 @@ nsDocumentViewer::IncrementDestroyRefCount() ++mDestroyRefCount; } +void +nsDocumentViewer::DecrementDestroyRefCount() +{ + --mDestroyRefCount; +} + //------------------------------------------------------------ #if defined(NS_PRINTING) && defined(NS_PRINT_PREVIEW) diff --git a/layout/base/nsIDocumentViewerPrint.h b/layout/base/nsIDocumentViewerPrint.h index 8bc2465a1..e3c397f3a 100644 --- a/layout/base/nsIDocumentViewerPrint.h +++ b/layout/base/nsIDocumentViewerPrint.h @@ -41,6 +41,7 @@ public: virtual mozilla::StyleSetHandle CreateStyleSet(nsIDocument* aDocument) = 0; virtual void IncrementDestroyRefCount() = 0; + virtual void DecrementDestroyRefCount() = 0; virtual void ReturnToGalleyPresentation() = 0; @@ -75,6 +76,7 @@ NS_DEFINE_STATIC_IID_ACCESSOR(nsIDocumentViewerPrint, bool GetIsPrintPreview() override; \ mozilla::StyleSetHandle CreateStyleSet(nsIDocument* aDocument) override; \ void IncrementDestroyRefCount() override; \ + void DecrementDestroyRefCount() override; \ void ReturnToGalleyPresentation() override; \ void OnDonePrinting() override; \ bool IsInitializedForPrintPreview() override; \ diff --git a/layout/base/nsIPresShell.h b/layout/base/nsIPresShell.h index cbbae0e8f..5990402ed 100644 --- a/layout/base/nsIPresShell.h +++ b/layout/base/nsIPresShell.h @@ -1298,11 +1298,11 @@ public: } }; - static void DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget); + static void DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const mozilla::WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget); + static PointerCaptureInfo* GetPointerCaptureInfo(uint32_t aPointerId); static void SetPointerCapturingContent(uint32_t aPointerId, nsIContent* aContent); @@ -1311,8 +1311,8 @@ public: // CheckPointerCaptureState checks cases, when got/lostpointercapture events // should be fired. - static void CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary); + static void CheckPointerCaptureState( + const mozilla::WidgetPointerEvent* aPointerEvent); // GetPointerInfo returns true if pointer with aPointerId is situated in // device, false otherwise. diff --git a/layout/base/nsLayoutDebugger.cpp b/layout/base/nsLayoutDebugger.cpp index 22c313c72..6ce629bc9 100644 --- a/layout/base/nsLayoutDebugger.cpp +++ b/layout/base/nsLayoutDebugger.cpp @@ -126,8 +126,10 @@ PrintDisplayItemTo(nsDisplayListBuilder* aBuilder, nsDisplayItem* aItem, contentData.AppendLiteral(" id:"); contentData.Append(tmp); } - if (content->GetClasses()) { - content->GetClasses()->ToString(tmp); + const nsAttrValue* classes = content->IsElement() ? + content->AsElement()->GetClasses() : nullptr; + if (classes) { + classes->ToString(tmp); contentData.AppendLiteral(" class:"); contentData.Append(tmp); } diff --git a/layout/base/nsLayoutUtils.cpp b/layout/base/nsLayoutUtils.cpp index ed34f39ce..c8c91b251 100644 --- a/layout/base/nsLayoutUtils.cpp +++ b/layout/base/nsLayoutUtils.cpp @@ -4637,6 +4637,63 @@ GetPercentBSize(const nsStyleCoord& aStyle, return true; } +// Return true if aStyle can be resolved to a definite value and if so +// return that value in aResult. +static bool +GetDefiniteSize(const nsStyleCoord& aStyle, + nsIFrame* aFrame, + bool aIsInlineAxis, + const Maybe<LogicalSize>& aPercentageBasis, + nscoord* aResult) +{ + switch (aStyle.GetUnit()) { + case eStyleUnit_Coord: + *aResult = aStyle.GetCoordValue(); + return true; + case eStyleUnit_Percent: { + if (aPercentageBasis.isNothing()) { + return false; + } + auto wm = aFrame->GetWritingMode(); + nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) + : aPercentageBasis.value().BSize(wm); + if (pb != NS_UNCONSTRAINEDSIZE) { + nscoord p = NSToCoordFloorClamped(pb * aStyle.GetPercentValue()); + *aResult = std::max(nscoord(0), p); + return true; + } + return false; + } + case eStyleUnit_Calc: { + nsStyleCoord::Calc* calc = aStyle.GetCalcValue(); + if (calc->mPercent != 0.0f) { + if (aPercentageBasis.isNothing()) { + return false; + } + auto wm = aFrame->GetWritingMode(); + nscoord pb = aIsInlineAxis ? aPercentageBasis.value().ISize(wm) + : aPercentageBasis.value().BSize(wm); + if (pb == NS_UNCONSTRAINEDSIZE) { + // XXXmats given that we're calculating an intrinsic size here, + // maybe we should back-compute the calc-size using AddPercents? + return false; + } + *aResult = std::max(0, calc->mLength + + NSToCoordFloorClamped(pb * calc->mPercent)); + } else { + *aResult = std::max(0, calc->mLength); + } + return true; + } + default: + return false; + } +} + +// +// NOTE: this function will be replaced by GetDefiniteSizeTakenByBoxSizing (bug 1363918). +// Please do not add new uses of this function. +// // Get the amount of vertical space taken out of aFrame's content area due to // its borders and paddings given the box-sizing value in aBoxSizing. We don't // get aBoxSizing from the frame because some callers want to compute this for @@ -4681,6 +4738,54 @@ GetBSizeTakenByBoxSizing(StyleBoxSizing aBoxSizing, return bSizeTakenByBoxSizing; } +// Get the amount of space taken out of aFrame's content area due to its +// borders and paddings given the box-sizing value in aBoxSizing. We don't +// get aBoxSizing from the frame because some callers want to compute this for +// specific box-sizing values. +// aIsInlineAxis is true if we're computing for aFrame's inline axis. +// aIgnorePadding is true if padding should be ignored. +static nscoord +GetDefiniteSizeTakenByBoxSizing(StyleBoxSizing aBoxSizing, + nsIFrame* aFrame, + bool aIsInlineAxis, + bool aIgnorePadding, + const Maybe<LogicalSize>& aPercentageBasis) +{ + nscoord sizeTakenByBoxSizing = 0; + if (MOZ_UNLIKELY(aBoxSizing == StyleBoxSizing::Border)) { + const bool isHorizontalAxis = + aIsInlineAxis == !aFrame->GetWritingMode().IsVertical(); + const nsStyleBorder* styleBorder = aFrame->StyleBorder(); + sizeTakenByBoxSizing = + isHorizontalAxis ? styleBorder->GetComputedBorder().LeftRight() + : styleBorder->GetComputedBorder().TopBottom(); + if (!aIgnorePadding) { + const nsStyleSides& stylePadding = aFrame->StylePadding()->mPadding; + const nsStyleCoord& pStart = + stylePadding.Get(isHorizontalAxis ? eSideLeft : eSideTop); + const nsStyleCoord& pEnd = + stylePadding.Get(isHorizontalAxis ? eSideRight : eSideBottom); + nscoord pad; + // XXXbz Calling GetPercentBSize on padding values looks bogus, since + // percent padding is always a percentage of the inline-size of the + // containing block. We should perhaps just treat non-absolute paddings + // here as 0 instead, except that in some cases the width may in fact be + // known. See bug 1231059. + if (GetDefiniteSize(pStart, aFrame, aIsInlineAxis, aPercentageBasis, &pad) || + (aPercentageBasis.isNothing() && + GetPercentBSize(pStart, aFrame, isHorizontalAxis, pad))) { + sizeTakenByBoxSizing += pad; + } + if (GetDefiniteSize(pEnd, aFrame, aIsInlineAxis, aPercentageBasis, &pad) || + (aPercentageBasis.isNothing() && + GetPercentBSize(pEnd, aFrame, isHorizontalAxis, pad))) { + sizeTakenByBoxSizing += pad; + } + } + } + return sizeTakenByBoxSizing; +} + // Handles only -moz-max-content and -moz-min-content, and // -moz-fit-content for min-width and max-width, since the others // (-moz-fit-content for width, and -moz-available) have no effect on @@ -4940,17 +5045,21 @@ AddStateBitToAncestors(nsIFrame* aFrame, nsFrameState aBit) } /* static */ nscoord -nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, - nsRenderingContext* aRenderingContext, - nsIFrame* aFrame, - IntrinsicISizeType aType, - uint32_t aFlags, - nscoord aMarginBoxMinSizeClamp) +nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, + nsRenderingContext* aRenderingContext, + nsIFrame* aFrame, + IntrinsicISizeType aType, + const Maybe<LogicalSize>& aPercentageBasis, + uint32_t aFlags, + nscoord aMarginBoxMinSizeClamp) { NS_PRECONDITION(aFrame, "null frame"); NS_PRECONDITION(aFrame->GetParent(), "IntrinsicForAxis called on frame not in tree"); NS_PRECONDITION(aType == MIN_ISIZE || aType == PREF_ISIZE, "bad type"); + MOZ_ASSERT(aFrame->GetParent()->Type() != LayoutFrameType::GridContainer || + aPercentageBasis.isSome(), + "grid layout should always pass a percentage basis"); const bool horizontalAxis = MOZ_LIKELY(aAxis == eAxisHorizontal); #ifdef DEBUG_INTRINSIC_WIDTH @@ -5014,6 +5123,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, PhysicalAxis ourInlineAxis = aFrame->GetWritingMode().PhysicalAxis(eLogicalAxisInline); + const bool isInlineAxis = aAxis == ourInlineAxis; // If we have a specified width (or a specified 'min-width' greater // than the specified 'max-width', which works out to the same thing), // don't even bother getting the frame's intrinsic width, because in @@ -5043,7 +5153,7 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, // constraint is the max-content contribution which we shouldn't clamp. aMarginBoxMinSizeClamp = NS_MAXSIZE; } - if (MOZ_UNLIKELY(aAxis != ourInlineAxis)) { + if (MOZ_UNLIKELY(!isInlineAxis)) { IntrinsicSize intrinsicSize = aFrame->GetIntrinsicSize(); const nsStyleCoord intrinsicBCoord = horizontalAxis ? intrinsicSize.width : intrinsicSize.height; @@ -5105,21 +5215,23 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, NS_FRAME_DESCENDANT_INTRINSIC_ISIZE_DEPENDS_ON_BSIZE); nscoord bSizeTakenByBoxSizing = - GetBSizeTakenByBoxSizing(boxSizing, aFrame, horizontalAxis, - aFlags & IGNORE_PADDING); - + GetDefiniteSizeTakenByBoxSizing(boxSizing, aFrame, !isInlineAxis, + aFlags & IGNORE_PADDING, + aPercentageBasis); // NOTE: This is only the minContentSize if we've been passed MIN_INTRINSIC_ISIZE // (which is fine, because this should only be used inside a check for that flag). nscoord minContentSize = result; nscoord h; - if (GetAbsoluteCoord(styleBSize, h) || - GetPercentBSize(styleBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); result = NSCoordMulDiv(h, ratioISize, ratioBSize); } - if (GetAbsoluteCoord(styleMaxBSize, h) || - GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleMaxBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleMaxBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord maxISize = NSCoordMulDiv(h, ratioISize, ratioBSize); if (maxISize < result) { @@ -5130,8 +5242,9 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, } } - if (GetAbsoluteCoord(styleMinBSize, h) || - GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h)) { + if (GetDefiniteSize(styleMinBSize, aFrame, !isInlineAxis, aPercentageBasis, &h) || + (aPercentageBasis.isNothing() && + GetPercentBSize(styleMinBSize, aFrame, horizontalAxis, h))) { h = std::max(0, h - bSizeTakenByBoxSizing); nscoord minISize = NSCoordMulDiv(h, ratioISize, ratioBSize); if (minISize > result) { @@ -5158,8 +5271,8 @@ nsLayoutUtils::IntrinsicForAxis(PhysicalAxis aAxis, } nsIFrame::IntrinsicISizeOffsetData offsets = - MOZ_LIKELY(aAxis == ourInlineAxis) ? aFrame->IntrinsicISizeOffsets() - : aFrame->IntrinsicBSizeOffsets(); + MOZ_LIKELY(isInlineAxis) ? aFrame->IntrinsicISizeOffsets() + : aFrame->IntrinsicBSizeOffsets(); nscoord contentBoxSize = result; result = AddIntrinsicSizeOffset(aRenderingContext, aFrame, offsets, aType, boxSizing, result, min, styleISize, @@ -5196,7 +5309,7 @@ nsLayoutUtils::IntrinsicForContainer(nsRenderingContext* aRenderingContext, // We want the size aFrame will contribute to its parent's inline-size. PhysicalAxis axis = aFrame->GetParent()->GetWritingMode().PhysicalAxis(eLogicalAxisInline); - return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, aFlags); + return IntrinsicForAxis(axis, aRenderingContext, aFrame, aType, Nothing(), aFlags); } /* static */ nscoord @@ -7242,9 +7355,11 @@ nsLayoutUtils::SurfaceFromElement(HTMLVideoElement* aElement, (aSurfaceFlags & SFE_PREFER_NO_PREMULTIPLY_ALPHA) == 0, "We can't support non-premultiplied alpha for video!"); +#ifdef MOZ_EME if (aElement->ContainsRestrictedContent()) { return result; } +#endif uint16_t readyState; if (NS_SUCCEEDED(aElement->GetReadyState(&readyState)) && diff --git a/layout/base/nsLayoutUtils.h b/layout/base/nsLayoutUtils.h index d9580a3df..97fc410b0 100644 --- a/layout/base/nsLayoutUtils.h +++ b/layout/base/nsLayoutUtils.h @@ -1378,6 +1378,10 @@ public: * width, its 'width', 'min-width', and 'max-width' properties (or 'height' * variations if that's what matches aAxis) and its padding, border and margin * in the corresponding dimension. + * @param aPercentageBasis an optional percentage basis (in aFrame's WM). + * Pass NS_UNCONSTRAINEDSIZE if the basis is indefinite in either/both axes. + * If you pass Nothing() a percentage basis will be calculated from aFrame's + * ancestors' computed size in the relevant axis, if needed. * @param aMarginBoxMinSizeClamp make the result fit within this margin-box * size by reducing the *content size* (flooring at zero). This is used for: * https://drafts.csswg.org/css-grid/#min-size-auto @@ -1396,6 +1400,7 @@ public: nsRenderingContext* aRenderingContext, nsIFrame* aFrame, IntrinsicISizeType aType, + const mozilla::Maybe<mozilla::LogicalSize>& aPercentageBasis = mozilla::Nothing(), uint32_t aFlags = 0, nscoord aMarginBoxMinSizeClamp = NS_MAXSIZE); /** diff --git a/layout/base/nsPresContext.cpp b/layout/base/nsPresContext.cpp index b27e6d0e3..4a54a8432 100644 --- a/layout/base/nsPresContext.cpp +++ b/layout/base/nsPresContext.cpp @@ -208,6 +208,7 @@ nsPresContext::nsPresContext(nsIDocument* aDocument, nsPresContextType aType) mTextZoom(1.0), mFullZoom(1.0), mOverrideDPPX(0.0), mLastFontInflationScreenSize(gfxSize(-1.0, -1.0)), mPageSize(-1, -1), mPPScale(1.0f), + mViewportScrollbarOverrideNode(nullptr), mViewportStyleScrollbar(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO), mImageAnimationModePref(imgIContainer::kNormalAnimMode), mAllInvalidated(false), @@ -1423,10 +1424,10 @@ nsPresContext::UpdateViewportScrollbarStylesOverride() // Start off with our default styles, and then update them as needed. mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_AUTO, NS_STYLE_OVERFLOW_AUTO); - nsIContent* propagatedFrom = nullptr; + mViewportScrollbarOverrideNode = nullptr; // Don't propagate the scrollbar state in printing or print preview. if (!IsPaginated()) { - propagatedFrom = + mViewportScrollbarOverrideNode = GetPropagatedScrollbarStylesForViewport(this, &mViewportStyleScrollbar); } @@ -1438,13 +1439,13 @@ nsPresContext::UpdateViewportScrollbarStylesOverride() // the styles are from, so that the state of those elements is not // affected across fullscreen change. if (fullscreenElement != document->GetRootElement() && - fullscreenElement != propagatedFrom) { + fullscreenElement != mViewportScrollbarOverrideNode) { mViewportStyleScrollbar = ScrollbarStyles(NS_STYLE_OVERFLOW_HIDDEN, NS_STYLE_OVERFLOW_HIDDEN); } } - return propagatedFrom; + return mViewportScrollbarOverrideNode; } bool @@ -1696,6 +1697,9 @@ nsPresContext::SysColorChangedInternal() sLookAndFeelChanged = false; } + // Invalidate cached '-moz-windows-accent-color-applies' media query: + nsCSSRuleProcessor::FreeSystemMetrics(); + // Reset default background and foreground colors for the document since // they may be using system colors GetDocumentColorPreferences(); diff --git a/layout/base/nsPresContext.h b/layout/base/nsPresContext.h index 4fdc60a2e..d8f876291 100644 --- a/layout/base/nsPresContext.h +++ b/layout/base/nsPresContext.h @@ -719,7 +719,18 @@ public: * it was propagated from. */ nsIContent* UpdateViewportScrollbarStylesOverride(); - const ScrollbarStyles& GetViewportScrollbarStylesOverride() + + /** + * Returns the cached result from the last call to + * UpdateViewportScrollbarStylesOverride() -- i.e. return the node + * whose scrollbar styles we have propagated to the viewport (or nullptr if + * there is no such node). + */ + nsIContent* GetViewportScrollbarStylesOverrideNode() const { + return mViewportScrollbarOverrideNode; + } + + const ScrollbarStyles& GetViewportScrollbarStylesOverride() const { return mViewportStyleScrollbar; } @@ -1310,7 +1321,16 @@ protected: nscolor mBodyTextColor; + // This is a non-owning pointer. May be null. If non-null, it's guaranteed + // to be pointing to a node that's still alive, because we'll reset it in + // UpdateViewportScrollbarStylesOverride() as part of the cleanup code + // when this node is removed from the document. (For <body> and the root node, + // this call happens in nsCSSFrameConstructor::ContentRemoved(). For + // fullscreen elements, it happens in the fullscreen-specific cleanup + // invoked by Element::UnbindFromTree().) + nsIContent* MOZ_NON_OWNING_REF mViewportScrollbarOverrideNode; ScrollbarStyles mViewportStyleScrollbar; + uint8_t mFocusRingWidth; bool mExistThrottledUpdates; diff --git a/layout/base/nsPresShell.cpp b/layout/base/nsPresShell.cpp index 56ac370b9..42b39c860 100644 --- a/layout/base/nsPresShell.cpp +++ b/layout/base/nsPresShell.cpp @@ -6514,10 +6514,11 @@ nsIPresShell::GetPointerCapturingContent(uint32_t aPointerId) } /* static */ void -nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, - uint16_t aPointerType, bool aIsPrimary) +nsIPresShell::CheckPointerCaptureState(const WidgetPointerEvent* aPointerEvent) { - PointerCaptureInfo* captureInfo = GetPointerCaptureInfo(aPointerId); + PointerCaptureInfo* captureInfo = + GetPointerCaptureInfo(aPointerEvent->pointerId); + if (captureInfo && captureInfo->mPendingContent != captureInfo->mOverrideContent) { // cache captureInfo->mPendingContent since it may be changed in the pointer @@ -6525,17 +6526,16 @@ nsIPresShell::CheckPointerCaptureState(uint32_t aPointerId, nsIContent* pendingContent = captureInfo->mPendingContent.get(); if (captureInfo->mOverrideContent) { DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ false, - aPointerId, aPointerType, aIsPrimary, + aPointerEvent, captureInfo->mOverrideContent); } if (pendingContent) { - DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, aPointerId, - aPointerType, aIsPrimary, - pendingContent); + DispatchGotOrLostPointerCaptureEvent(/* aIsGotCapture */ true, + aPointerEvent, pendingContent); } captureInfo->mOverrideContent = pendingContent; if (captureInfo->Empty()) { - sPointerCaptureList->Remove(aPointerId); + sPointerCaptureList->Remove(aPointerEvent->pointerId); } } } @@ -6976,37 +6976,30 @@ DispatchPointerFromMouseOrTouch(PresShell* aShell, return NS_OK; } -class ReleasePointerCaptureCaller +class ReleasePointerCaptureCaller final { public: - ReleasePointerCaptureCaller() : - mPointerId(0), - mPointerType(nsIDOMMouseEvent::MOZ_SOURCE_UNKNOWN), - mIsPrimary(false), - mIsSet(false) + ReleasePointerCaptureCaller() + : mPointerEvent(nullptr) { } ~ReleasePointerCaptureCaller() { - if (mIsSet) { - nsIPresShell::ReleasePointerCapturingContent(mPointerId); - nsIPresShell::CheckPointerCaptureState(mPointerId, mPointerType, - mIsPrimary); + if (mPointerEvent) { + nsIPresShell::ReleasePointerCapturingContent(mPointerEvent->pointerId); + nsIPresShell::CheckPointerCaptureState(mPointerEvent); } } - void SetTarget(uint32_t aPointerId, uint16_t aPointerType, bool aIsPrimary) + + void SetTarget(const WidgetPointerEvent* aPointerEvent) { - mPointerId = aPointerId; - mPointerType = aPointerType; - mIsPrimary = aIsPrimary; - mIsSet = true; + MOZ_ASSERT(aPointerEvent); + mPointerEvent = aPointerEvent; } private: - int32_t mPointerId; - uint16_t mPointerType; - bool mIsPrimary; - bool mIsSet; + // This is synchronously used inside PresShell::HandleEvent. + const WidgetPointerEvent* mPointerEvent; }; static bool @@ -7719,9 +7712,7 @@ PresShell::HandleEvent(nsIFrame* aFrame, nsWeakFrame frameKeeper(frame); // Handle pending pointer capture before any pointer events except // gotpointercapture / lostpointercapture. - CheckPointerCaptureState(pointerEvent->pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + CheckPointerCaptureState(pointerEvent); // Prevent application crashes, in case damaged frame. if (!frameKeeper.IsAlive()) { frame = nullptr; @@ -7742,33 +7733,29 @@ PresShell::HandleEvent(nsIFrame* aFrame, } } - if (aEvent->mClass == ePointerEventClass && - aEvent->mMessage != ePointerDown) { - if (WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent()) { - uint32_t pointerId = pointerEvent->pointerId; + // Mouse events should be fired to the same target as their mapped pointer + // events + if ((aEvent->mClass == ePointerEventClass || + aEvent->mClass == eMouseEventClass) && + aEvent->mMessage != ePointerDown && aEvent->mMessage != eMouseDown) { + if (WidgetMouseEvent* mouseEvent = aEvent->AsMouseEvent()) { + uint32_t pointerId = mouseEvent->pointerId; nsIContent* pointerCapturingContent = GetPointerCapturingContent(pointerId); if (pointerCapturingContent) { if (nsIFrame* capturingFrame = pointerCapturingContent->GetPrimaryFrame()) { - // If pointer capture is set, we should suppress - // pointerover/pointerenter events for all elements except element - // which have pointer capture. (Code in EventStateManager) - pointerEvent->retargetedByPointerCapture = - frame && frame->GetContent() && - !nsContentUtils::ContentIsDescendantOf(frame->GetContent(), - pointerCapturingContent); frame = capturingFrame; } - if (pointerEvent->mMessage == ePointerUp || - pointerEvent->mMessage == ePointerCancel) { + if (aEvent->mMessage == ePointerUp || + aEvent->mMessage == ePointerCancel) { // Implicitly releasing capture for given pointer. // ePointerLostCapture should be send after ePointerUp or // ePointerCancel. - releasePointerCaptureCaller.SetTarget(pointerId, - pointerEvent->inputSource, - pointerEvent->mIsPrimary); + WidgetPointerEvent* pointerEvent = aEvent->AsPointerEvent(); + MOZ_ASSERT(pointerEvent); + releasePointerCaptureCaller.SetTarget(pointerEvent); } } } @@ -8204,6 +8191,8 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, } case eMouseDown: case eMouseUp: + case ePointerDown: + case ePointerUp: isHandlingUserInput = true; break; @@ -8340,35 +8329,44 @@ PresShell::HandleEventInternal(WidgetEvent* aEvent, return rv; } -void -nsIPresShell::DispatchGotOrLostPointerCaptureEvent(bool aIsGotCapture, - uint32_t aPointerId, - uint16_t aPointerType, - bool aIsPrimary, - nsIContent* aCaptureTarget) -{ - PointerEventInit init; - init.mPointerId = aPointerId; - init.mBubbles = true; - ConvertPointerTypeToString(aPointerType, init.mPointerType); - init.mIsPrimary = aIsPrimary; - RefPtr<mozilla::dom::PointerEvent> event; - event = PointerEvent::Constructor(aCaptureTarget, - aIsGotCapture - ? NS_LITERAL_STRING("gotpointercapture") - : NS_LITERAL_STRING("lostpointercapture"), - init); - if (event) { +/* static */ void +nsIPresShell::DispatchGotOrLostPointerCaptureEvent( + bool aIsGotCapture, + const WidgetPointerEvent* aPointerEvent, + nsIContent* aCaptureTarget) +{ + nsIDocument* targetDoc = aCaptureTarget->OwnerDoc(); + nsCOMPtr<nsIPresShell> shell = targetDoc->GetShell(); + NS_ENSURE_TRUE_VOID(shell); + + if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { + // If the capturing element was removed from the DOM tree, fire + // ePointerLostCapture at the document. + PointerEventInit init; + init.mPointerId = aPointerEvent->pointerId; + init.mBubbles = true; + init.mComposed = true; + ConvertPointerTypeToString(aPointerEvent->inputSource, init.mPointerType); + init.mIsPrimary = aPointerEvent->mIsPrimary; + RefPtr<mozilla::dom::PointerEvent> event; + event = PointerEvent::Constructor(aCaptureTarget, + NS_LITERAL_STRING("lostpointercapture"), + init); bool dummy; - // If the capturing element was removed from the DOM tree, - // lostpointercapture event should be fired at the document. - if (!aIsGotCapture && !aCaptureTarget->IsInUncomposedDoc()) { - aCaptureTarget->OwnerDoc()->DispatchEvent(event->InternalDOMEvent(), - &dummy); - } else { - aCaptureTarget->DispatchEvent(event->InternalDOMEvent(), &dummy); - } + targetDoc->DispatchEvent(event->InternalDOMEvent(), &dummy); + return; } + nsEventStatus status = nsEventStatus_eIgnore; + WidgetPointerEvent localEvent(aPointerEvent->IsTrusted(), + aIsGotCapture ? ePointerGotCapture : + ePointerLostCapture, + aPointerEvent->mWidget); + localEvent.AssignPointerEventData(*aPointerEvent, true); + nsresult rv = shell->HandleEventWithTarget( + &localEvent, + aCaptureTarget->GetPrimaryFrame(), + aCaptureTarget, &status); + NS_ENSURE_SUCCESS_VOID(rv); } nsresult diff --git a/layout/base/tests/bug1078327_inner.html b/layout/base/tests/bug1078327_inner.html index 9e32fc996..0cfb9da7f 100644 --- a/layout/base/tests/bug1078327_inner.html +++ b/layout/base/tests/bug1078327_inner.html @@ -24,16 +24,16 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 var test_mediator_move = false; var test_mediator_out = false; var test_listener = false; + var test_lost_capture = false; function TargetHandler(event) { logger("Target receive event: " + event.type + ". Mediator.setPointerCapture()"); mediator.setPointerCapture(event.pointerId); test_target = true; + test_capture = true; } function MediatorHandler(event) { logger("Mediator receive event: " + event.type); - if(event.type == "gotpointercapture") - test_capture = true; if(!test_capture) return; if(event.type == "pointermove") @@ -43,7 +43,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 if(event.type == "pointerout") test_mediator_out++; if(event.type == "lostpointercapture") - test_capture = false; + test_lost_capture = true; } function ListenerHandler(event) { logger("Listener receive event: " + event.type); @@ -86,7 +86,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1078327 } function finishTest() { parent.is(test_target, true, "pointerdown event should be received by target"); - parent.is(test_capture, false, "test_capture should be false at the end of the test"); + parent.is(test_lost_capture, true, "mediator should receive lostpointercapture"); parent.is(test_mediator_over, 1, "mediator should receive pointerover event only once"); parent.is(test_mediator_move, 5, "mediator should receive pointermove event five times"); parent.is(test_mediator_out, 1, "mediator should receive pointerout event only once"); diff --git a/layout/base/tests/bug1162990_inner_1.html b/layout/base/tests/bug1162990_inner_1.html index 4ea5edb5c..0f950df8d 100644 --- a/layout/base/tests/bug1162990_inner_1.html +++ b/layout/base/tests/bug1162990_inner_1.html @@ -111,10 +111,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 } function finishTest() { - parent.is(test_basketLeave, 0, "Part1: basket should not receive pointerleave event after pointer capturing"); + parent.is(test_basketLeave, 1, "Part1: basket should receive pointerleave event after pointer capturing"); parent.is(test_targetGotCapture, 1, "Part1: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part1: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 2, "Part1: target should receive pointerleave event two times"); + parent.is(test_targetLeave, 1, "Part1: target should receive pointerleave event only one time"); parent.is(test_childLeave, 0, "Part1: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerDown, 1, "Part1: listener should receive pointerdown event"); parent.is(test_listenerLeave, 1, "Part1: listener should receive pointerleave event only one time"); diff --git a/layout/base/tests/bug1162990_inner_2.html b/layout/base/tests/bug1162990_inner_2.html index 54aa74ca3..e418927bd 100644 --- a/layout/base/tests/bug1162990_inner_2.html +++ b/layout/base/tests/bug1162990_inner_2.html @@ -116,7 +116,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1162990 parent.is(test_targetDown, 1, "Part2: target should receive pointerdown event"); parent.is(test_targetGotCapture, 1, "Part2: target should receive gotpointercapture event"); parent.is(test_targetLostCapture, 1, "Part2: target should receive lostpointercapture event"); - parent.is(test_targetLeave, 1, "Part2: target should receive pointerleave event"); + parent.is(test_targetLeave, 0, "Part2: target should not receive pointerleave event"); parent.is(test_childLeave, 0, "Part2: child should not receive pointerleave event after pointer capturing"); parent.is(test_listenerLeave, 0, "Part2: listener should not receive pointerleave event after pointer capturing"); logger("finishTest"); diff --git a/layout/base/tests/bug976963_inner.html b/layout/base/tests/bug976963_inner.html deleted file mode 100644 index 2c55fbccd..000000000 --- a/layout/base/tests/bug976963_inner.html +++ /dev/null @@ -1,241 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=976963 ---> -<head> - <meta charset="utf-8"> - <title>Test for Bug 976963</title> - <meta name="author" content="Maksim Lebedev" /> - <script type="application/javascript" src="/tests/SimpleTest/EventUtils.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <style> - div#listener { - background: yellow; - position: absolute; - top: -100px; - } - div#middler { - background: yellow; - margin: 10px; - } - div#target { - background: yellow; - } - </style> - <script type="application/javascript"> - /** Test for Bug 976963 **/ - var All_Pointer_Events = ["pointerover", "pointerenter", - "pointermove", - "pointerdown", "pointerup", - "pointerout", "pointerleave", - "pointercancel", - "gotpointercapture", "lostpointercapture"]; - - function on_event(object, event, callback) { - object.addEventListener(event, callback, false); - } - function ok(check, msg) { - parent.ok(check, msg); - } - function is(a, b, msg) { - parent.is(a, b, msg); - } - - var listener = undefined; - var middler = undefined; - var target = undefined; - - var test_ListenerGotCapture = 0; - var test_ListenerUnwanted = 0; - var test_ListenerLostCapture = 0; - var test_ListenerAfterCapture = 0; - var test_MiddlerGotCapture = 0; - var test_MiddlerOver = 0; - var test_MiddlerLeave = 0; - var test_MiddlerUp = 0; - var test_MiddlerLostCapture = 0; - var test_TargetDown = 0; - var test_TargetUnwanted = 0; - var test_TargetUp = 0; - - var captured_event = undefined; - var f_gotPointerCapture = false; - var f_lostPointerCapture = false; - var f_gotMiddlerPointerCapture = false; - - function listenerEventHandler(event) { - logger("Listener: " + event.type + ". Captured_event: " + captured_event); - if(test_ListenerLostCapture) - test_ListenerAfterCapture++; - if (event.type == "gotpointercapture") { - f_gotPointerCapture = true; - test_ListenerGotCapture++; - } - else if (event.type == "lostpointercapture") { - f_lostPointerCapture = true; - f_gotPointerCapture = false; - test_ListenerLostCapture++; - } - else if (event.type == "pointermove") { - ok(captured_event && captured_event.pointerId == event.pointerId, "Listener: equals pointerId for lostpointercapture event"); - if (f_gotPointerCapture) { - // on first event received for capture, release capture - logger("Listener call release"); - ok(!!listener, "Listener should be live!"); - ok(typeof(listener.releasePointerCapture) == "function", "Listener should have a function releasePointerCapture"); - listener.releasePointerCapture(event.pointerId); - } - else { - logger("Listener.ASSERT: " + event.type); - test_ListenerUnwanted++; - // if any other events are received after releaseCapture, then the test fails - ok(false, event.target.id + "-" + event.type + " should be handled by target element handler"); - } - } - else { - test_ListenerUnwanted++; - logger("Listener.ASSERT: " + event.type); - ok(false, event.type + "should be never handled by listener"); - } - } - - function middlerEventHandler(event) { - logger("Middler: " + event.type + ". Captured_event: " + captured_event); - if (event.type == "gotpointercapture") { - test_MiddlerGotCapture++; - f_gotMiddlerPointerCapture = true; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for gotpointercapture event"); - } - else if (event.type == "pointerover") { - test_MiddlerOver++; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerover event"); - } - else if (event.type == "pointerleave") { - test_MiddlerLeave++; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for pointerleave event"); - ok(!!listener, "Listener should be live!"); - ok(typeof(listener.setPointerCapture) == "function", "Listener should have a function setPointerCapture"); - listener.setPointerCapture(event.pointerId); - } - else if (event.type == "lostpointercapture") { - test_MiddlerLostCapture++; - f_gotMiddlerPointerCapture = false; - ok(captured_event && captured_event.pointerId == event.pointerId, "Middler: equals pointerId for lostpointercapture event"); - } - else if (event.type == "pointerup" ) { - test_MiddlerUp++; - } - } - - function targetEventHandler(event) { - logger("Target: " + event.type + ". Captured_event: " + captured_event); - if (f_gotPointerCapture || f_gotMiddlerPointerCapture) { - if (event.type != "pointerout" && event.type != "pointerleave") { - logger("Target.ASSERT: " + event.type + " " + event.pointerId); - test_TargetUnwanted++; - ok(false, "The Target element should not have received any events while capture is active. Event recieved:" + event.type + ". "); - } - } - if (event.type == "pointerdown") { - logger("Target.pointerdown 1: " + captured_event); - test_TargetDown++; - captured_event = event; - ok(!!middler, "Middler should be live!"); - ok(typeof(middler.setPointerCapture) == "function", "Middler should have a function setPointerCapture"); - middler.setPointerCapture(event.pointerId); - logger("Target.pointerdown 2: " + captured_event); - } - else if (event.type == "pointerup") { - ok(f_lostPointerCapture, "Target should have received pointerup"); - ok(captured_event && captured_event.pointerId == event.pointerId, "Target: equals pointerId for lostpointercapture event"); - test_TargetUp++; // complete test - } - } - - function colorerHandler(event) { - if(event.type == "pointerover") - event.target.style.background = "red"; - else if(event.type == "pointerout") - event.target.style.background = "yellow"; - } - - function setEventHandlers() { - listener = document.getElementById("listener"); - middler = document.getElementById("middler"); - target = document.getElementById("target"); - target.style["touchAction"] = "none"; - - // target and listener - handle all events - for (var i = 0; i < All_Pointer_Events.length; i++) { - on_event(target, All_Pointer_Events[i], targetEventHandler); - on_event(listener, All_Pointer_Events[i], listenerEventHandler); - on_event(middler, All_Pointer_Events[i], middlerEventHandler); - on_event(target, All_Pointer_Events[i], colorerHandler); - on_event(middler, All_Pointer_Events[i], colorerHandler); - } - } - - function prepareTest() { - SpecialPowers.pushPrefEnv({ - "set": [ - ["dom.w3c_pointer_events.enabled", true] - ] - }, executeTest); - } - - function executeTest() - { - logger("executeTest"); - setEventHandlers(); - document.body.offsetLeft; - var rect = target.getBoundingClientRect(); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerdown"}); - synthesizePointer(target, rect.width/3, rect.height/3, {type: "pointermove"}); - synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(middler, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointermove"}); - synthesizePointer(target, rect.width/2, rect.height/2, {type: "pointerup"}); - finishTest(); - } - - function finishTest() { - setTimeout(function() { - is(test_ListenerGotCapture, 1, "Listener should receive gotpointercapture event"); - is(test_ListenerUnwanted, 0, "Listener should not receive any unwanted events"); - is(test_ListenerLostCapture, 1, "Listener should receive lostpointercapture event"); - is(test_ListenerAfterCapture, 0, "Listener should not receive any events after release pointer capture"); - is(test_MiddlerGotCapture, 1, "Middler should receive gotpointercapture event"); - is(test_MiddlerOver, 1, "Middler should receive pointerover event"); - is(test_MiddlerLeave, 1, "Middler should receive pointerleave event"); - is(test_MiddlerUp, 0, "Middler should not receive pointerup event"); - is(test_MiddlerLostCapture, 1, "Middler should receive lostpointercapture event"); - is(test_TargetDown, 1, "Target should receive pointerdown event"); - is(test_TargetUnwanted, 0, "Target should not receive any event while pointer capture is active"); - is(test_TargetUp, 1, "Target should receive pointerup event"); - logger("finishTest"); - parent.finishTest(); - }, 1000); - } - - function logger(message) { - console.log(message); - var log = document.getElementById('log'); - log.innerHTML = message + "<br>" + log.innerHTML; - } - </script> -</head> -<body onload="prepareTest()"> - <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=976963">Mozilla Bug 976963</a> - <p id="display"></p> - <div id="content" style="display: none"> - </div> - <div id="listener">div id=listener</div> - <div id="middler">div id=middler</div> - <div id="target">div id=target</div> - <pre id="log"> - </pre> -</body> -</html> diff --git a/layout/base/tests/bug977003_inner_5.html b/layout/base/tests/bug977003_inner_5.html index 70fc5ba40..81094043c 100644 --- a/layout/base/tests/bug977003_inner_5.html +++ b/layout/base/tests/bug977003_inner_5.html @@ -26,6 +26,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 var test_lost_listener = false; var test_lost_type = ""; var test_move_listener = false; + var test_over_listener = false; var test_listener = false; var test_lost_primary = false; @@ -53,6 +54,10 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 logger("Receive event on Listener: " + event.type); test_move_listener = true; } + function ListenerOverHandler(event) { + logger("Receive event on Listener: " + event.type); + test_over_listener = true; + } function ListenerHandler(event) { logger("Receive event on Listener: " + event.type); test_listener = true; @@ -74,7 +79,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 target.addEventListener("pointerdown", TargetDownHandler, false); listener.addEventListener("gotpointercapture", ListenerGotPCHandler, false); listener.addEventListener("lostpointercapture", ListenerLostPCHandler, false); - listener.addEventListener("pointerover", ListenerHandler, false); + listener.addEventListener("pointerover", ListenerOverHandler, false); listener.addEventListener("pointermove", ListenerMoveHandler, false); listener.addEventListener("pointerup", ListenerHandler, false); listener.addEventListener("pointerout", ListenerHandler, false); @@ -93,6 +98,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1098139 parent.is(test_lost_type, "touch", "Part 5: lostpointercapture event should have pointerType touch"); parent.is(test_lost_primary, true, "Part 5: lostpointercapture event should have isPrimary as true"); parent.is(test_move_listener, true, "Part 5: gotpointercapture should be triggered by pointermove"); + parent.is(test_over_listener, true, "Part 5: listener should receive pointerover when capturing pointer"); parent.is(test_listener, false, "Part 5: listener should not receive any other events"); logger("finishTest"); parent.finishTest(); diff --git a/layout/base/tests/bug977003_inner_6.html b/layout/base/tests/bug977003_inner_6.html index 12424b1f2..b60ca5c31 100644 --- a/layout/base/tests/bug977003_inner_6.html +++ b/layout/base/tests/bug977003_inner_6.html @@ -19,6 +19,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 var listener = undefined; var test_target = false; var test_move = false; + var test_over = false; var test_listener = false; var receive_lostpointercapture = false; @@ -44,6 +45,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 } } else if(event.type == "pointermove") { test_move = true; + } else if(event.type == "pointerover") { + test_over = true; } else { test_listener = true; } @@ -81,7 +84,8 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=1073563 // PE level 2 defines that the pending pointer capture is processed when firing next pointer events. // In this test case, pointer capture release is processed when firing pointermove parent.is(test_move, true, "Part 6: gotpointercapture should be triggered by pointermove"); - parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture"); + parent.is(test_over, true, "Part 6: pointerover should be received when capturing pointer"); + parent.is(test_listener, false, "Part 6: no other pointerevents should be fired before gotpointercapture except pointerover"); logger("finishTest"); parent.finishTest(); } diff --git a/layout/base/tests/mochitest.ini b/layout/base/tests/mochitest.ini index 279b0af8a..405697977 100644 --- a/layout/base/tests/mochitest.ini +++ b/layout/base/tests/mochitest.ini @@ -256,8 +256,6 @@ skip-if = toolkit == 'android' support-files = bug851445_helper.html [test_bug970964.html] support-files = bug970964_inner.html -[test_bug976963.html] -support-files = bug976963_inner.html [test_bug977003.html] support-files = bug977003_inner_1.html diff --git a/layout/base/tests/test_bug976963.html b/layout/base/tests/test_bug976963.html deleted file mode 100644 index 4b8da3a6e..000000000 --- a/layout/base/tests/test_bug976963.html +++ /dev/null @@ -1,35 +0,0 @@ -<!DOCTYPE HTML> -<html> -<!-- -https://bugzilla.mozilla.org/show_bug.cgi?id=976963 ---> - <head> - <meta charset="utf-8"> - <meta name="author" content="Maksim Lebedev" /> - <title>Test for Bug 976963</title> - <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> - <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> - <script type="text/javascript"> - function prepareTest() { - SimpleTest.waitForExplicitFinish(); - SimpleTest.requestFlakyTimeout("untriaged"); - SpecialPowers.pushPrefEnv({ - "set": [ - ["dom.w3c_pointer_events.enabled", true], - ["layout.reflow.synthMouseMove", false] - ] - }, startTest); - } - function startTest() { - var iframe = document.getElementById("testFrame"); - iframe.src = "bug976963_inner.html"; - } - function finishTest() { - SimpleTest.finish(); - } - </script> - </head> - <body onload="prepareTest()"> - <iframe id="testFrame" height="700" width="700"></iframe> - </body> -</html> diff --git a/layout/forms/nsDateTimeControlFrame.cpp b/layout/forms/nsDateTimeControlFrame.cpp index df2e43986..fa22dceba 100644 --- a/layout/forms/nsDateTimeControlFrame.cpp +++ b/layout/forms/nsDateTimeControlFrame.cpp @@ -372,7 +372,8 @@ nsDateTimeControlFrame::AttributeChanged(int32_t aNameSpaceID, auto contentAsInputElem = static_cast<dom::HTMLInputElement*>(mContent); // If script changed the <input>'s type before setting these attributes // then we don't need to do anything since we are going to be reframed. - if (contentAsInputElem->GetType() == NS_FORM_INPUT_TIME) { + if (contentAsInputElem->GetType() == NS_FORM_INPUT_TIME || + contentAsInputElem->GetType() == NS_FORM_INPUT_DATE) { if (aAttribute == nsGkAtoms::value) { nsCOMPtr<nsIDateTimeInputArea> inputAreaContent = do_QueryInterface(mInputAreaContent); diff --git a/layout/forms/nsFieldSetFrame.cpp b/layout/forms/nsFieldSetFrame.cpp index befd41ee2..fc9f0571b 100644 --- a/layout/forms/nsFieldSetFrame.cpp +++ b/layout/forms/nsFieldSetFrame.cpp @@ -5,26 +5,22 @@ #include "nsFieldSetFrame.h" +#include <algorithm> #include "mozilla/gfx/2D.h" +#include "mozilla/Likely.h" +#include "mozilla/Maybe.h" #include "nsCSSAnonBoxes.h" -#include "nsLayoutUtils.h" -#include "nsLegendFrame.h" #include "nsCSSRendering.h" -#include <algorithm> -#include "nsIFrame.h" -#include "nsPresContext.h" -#include "mozilla/RestyleManager.h" -#include "nsGkAtoms.h" -#include "nsStyleConsts.h" #include "nsDisplayList.h" +#include "nsGkAtoms.h" +#include "nsIFrameInlines.h" +#include "nsLayoutUtils.h" +#include "nsLegendFrame.h" #include "nsRenderingContext.h" -#include "nsIScrollableFrame.h" -#include "mozilla/Likely.h" -#include "mozilla/Maybe.h" +#include "nsStyleConsts.h" using namespace mozilla; using namespace mozilla::gfx; -using namespace mozilla::image; using namespace mozilla::layout; nsContainerFrame* @@ -126,7 +122,7 @@ void nsDisplayFieldSetBorderBackground::Paint(nsDisplayListBuilder* aBuilder, nsRenderingContext* aCtx) { - DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)-> + image::DrawResult result = static_cast<nsFieldSetFrame*>(mFrame)-> PaintBorder(aBuilder, *aCtx, ToReferenceFrame(), mVisibleRect); nsDisplayItemGenericImageGeometry::UpdateDrawResult(this, result); @@ -210,7 +206,7 @@ nsFieldSetFrame::BuildDisplayList(nsDisplayListBuilder* aBuilder, contentDisplayItems.MoveTo(aLists); } -DrawResult +image::DrawResult nsFieldSetFrame::PaintBorder( nsDisplayListBuilder* aBuilder, nsRenderingContext& aRenderingContext, @@ -695,9 +691,50 @@ nsFieldSetFrame::AccessibleType() #endif nscoord -nsFieldSetFrame::GetLogicalBaseline(WritingMode aWritingMode) const +nsFieldSetFrame::GetLogicalBaseline(WritingMode aWM) const +{ + switch (StyleDisplay()->mDisplay) { + case mozilla::StyleDisplay::Grid: + case mozilla::StyleDisplay::InlineGrid: + case mozilla::StyleDisplay::Flex: + case mozilla::StyleDisplay::InlineFlex: + return BaselineBOffset(aWM, BaselineSharingGroup::eFirst, + AlignmentContext::eInline); + default: + return BSize(aWM) - BaselineBOffset(aWM, BaselineSharingGroup::eLast, + AlignmentContext::eInline); + } +} + +bool +nsFieldSetFrame::GetVerticalAlignBaseline(WritingMode aWM, + nscoord* aBaseline) const { nsIFrame* inner = GetInner(); - return inner->BStart(aWritingMode, GetParent()->GetSize()) + - inner->GetLogicalBaseline(aWritingMode); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsFieldSetFrame::GetNaturalBaselineBOffset(WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = GetInner(); + MOZ_ASSERT(!inner->GetWritingMode().IsOrthogonalTo(aWM)); + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + return false; + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; } diff --git a/layout/forms/nsFieldSetFrame.h b/layout/forms/nsFieldSetFrame.h index 54eaf678f..5eb67c320 100644 --- a/layout/forms/nsFieldSetFrame.h +++ b/layout/forms/nsFieldSetFrame.h @@ -7,7 +7,7 @@ #define nsFieldSetFrame_h___ #include "mozilla/Attributes.h" -#include "imgIContainer.h" +#include "DrawResult.h" #include "nsContainerFrame.h" class nsFieldSetFrame final : public nsContainerFrame @@ -33,7 +33,6 @@ public: const mozilla::LogicalSize& aBorder, const mozilla::LogicalSize& aPadding, ComputeSizeFlags aFlags) override; - virtual nscoord GetLogicalBaseline(mozilla::WritingMode aWritingMode) const override; /** * The area to paint box-shadows around. It's the border rect except @@ -46,6 +45,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + nscoord GetLogicalBaseline(mozilla::WritingMode aWM) const override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual void BuildDisplayList(nsDisplayListBuilder* aBuilder, const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; diff --git a/layout/forms/nsHTMLButtonControlFrame.cpp b/layout/forms/nsHTMLButtonControlFrame.cpp index ef9459ef2..2e4fa9f67 100644 --- a/layout/forms/nsHTMLButtonControlFrame.cpp +++ b/layout/forms/nsHTMLButtonControlFrame.cpp @@ -418,6 +418,47 @@ nsHTMLButtonControlFrame::ReflowButtonContents(nsPresContext* aPresContext, aButtonDesiredSize.SetOverflowAreasToDesiredBounds(); } +bool +nsHTMLButtonControlFrame::GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetVerticalAlignBaseline(aWM, aBaseline)) { + // <input type=color> has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, BaselineSharingGroup::eFirst); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + *aBaseline += innerBStart; + return true; +} + +bool +nsHTMLButtonControlFrame::GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const +{ + nsIFrame* inner = mFrames.FirstChild(); + if (MOZ_UNLIKELY(inner->GetWritingMode().IsOrthogonalTo(aWM))) { + return false; + } + if (!inner->GetNaturalBaselineBOffset(aWM, aBaselineGroup, aBaseline)) { + // <input type=color> has an empty block frame as inner frame + *aBaseline = inner-> + SynthesizeBaselineBOffsetFromBorderBox(aWM, aBaselineGroup); + } + nscoord innerBStart = inner->BStart(aWM, GetSize()); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline += innerBStart; + } else { + *aBaseline += BSize(aWM) - (innerBStart + inner->BSize(aWM)); + } + return true; +} + nsresult nsHTMLButtonControlFrame::SetFormProperty(nsIAtom* aName, const nsAString& aValue) { if (nsGkAtoms::value == aName) { diff --git a/layout/forms/nsHTMLButtonControlFrame.h b/layout/forms/nsHTMLButtonControlFrame.h index 96ad0f366..432afa12c 100644 --- a/layout/forms/nsHTMLButtonControlFrame.h +++ b/layout/forms/nsHTMLButtonControlFrame.h @@ -39,6 +39,13 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override; + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override; + virtual nsresult HandleEvent(nsPresContext* aPresContext, mozilla::WidgetGUIEvent* aEvent, nsEventStatus* aEventStatus) override; diff --git a/layout/forms/nsLegendFrame.h b/layout/forms/nsLegendFrame.h index 5f5e1e03e..a9e11cbbe 100644 --- a/layout/forms/nsLegendFrame.h +++ b/layout/forms/nsLegendFrame.h @@ -9,7 +9,8 @@ #include "mozilla/Attributes.h" #include "nsBlockFrame.h" -class nsLegendFrame : public nsBlockFrame { +class nsLegendFrame final : public nsBlockFrame +{ public: NS_DECL_QUERYFRAME_TARGET(nsLegendFrame) NS_DECL_QUERYFRAME @@ -30,7 +31,7 @@ public: virtual nsresult GetFrameName(nsAString& aResult) const override; #endif - int32_t GetLogicalAlign(WritingMode aCBWM); + int32_t GetLogicalAlign(mozilla::WritingMode aCBWM); }; diff --git a/layout/forms/nsTextControlFrame.cpp b/layout/forms/nsTextControlFrame.cpp index f85bc2a80..a7f7d40a8 100644 --- a/layout/forms/nsTextControlFrame.cpp +++ b/layout/forms/nsTextControlFrame.cpp @@ -106,6 +106,7 @@ private: nsTextControlFrame::nsTextControlFrame(nsStyleContext* aContext) : nsContainerFrame(aContext) + , mFirstBaseline(NS_INTRINSIC_WIDTH_UNKNOWN) , mEditorHasBeenInitialized(false) , mIsProcessing(false) #ifdef DEBUG @@ -538,20 +539,20 @@ nsTextControlFrame::Reflow(nsPresContext* aPresContext, aReflowInput.ComputedLogicalBorderPadding().BStartEnd(wm)); aDesiredSize.SetSize(wm, finalSize); - // computation of the ascent wrt the input height + // Calculate the baseline and store it in mFirstBaseline. nscoord lineHeight = aReflowInput.ComputedBSize(); float inflation = nsLayoutUtils::FontSizeInflationFor(this); if (!IsSingleLineTextControl()) { lineHeight = ReflowInput::CalcLineHeight(GetContent(), StyleContext(), - NS_AUTOHEIGHT, inflation); + NS_AUTOHEIGHT, inflation); } RefPtr<nsFontMetrics> fontMet = nsLayoutUtils::GetFontMetricsForFrame(this, inflation); - // now adjust for our borders and padding - aDesiredSize.SetBlockStartAscent( + mFirstBaseline = nsLayoutUtils::GetCenteredFontBaseline(fontMet, lineHeight, wm.IsLineInverted()) + - aReflowInput.ComputedLogicalBorderPadding().BStart(wm)); + aReflowInput.ComputedLogicalBorderPadding().BStart(wm); + aDesiredSize.SetBlockStartAscent(mFirstBaseline); // overflow handling aDesiredSize.SetOverflowAreasToDesiredBounds(); diff --git a/layout/forms/nsTextControlFrame.h b/layout/forms/nsTextControlFrame.h index a76cba514..9d4d0b77c 100644 --- a/layout/forms/nsTextControlFrame.h +++ b/layout/forms/nsTextControlFrame.h @@ -62,6 +62,29 @@ public: const ReflowInput& aReflowInput, nsReflowStatus& aStatus) override; + bool GetVerticalAlignBaseline(mozilla::WritingMode aWM, + nscoord* aBaseline) const override + { + return GetNaturalBaselineBOffset(aWM, BaselineSharingGroup::eFirst, aBaseline); + } + + bool GetNaturalBaselineBOffset(mozilla::WritingMode aWM, + BaselineSharingGroup aBaselineGroup, + nscoord* aBaseline) const override + { + if (!IsSingleLineTextControl()) { + return false; + } + NS_ASSERTION(mFirstBaseline != NS_INTRINSIC_WIDTH_UNKNOWN, + "please call Reflow before asking for the baseline"); + if (aBaselineGroup == BaselineSharingGroup::eFirst) { + *aBaseline = mFirstBaseline; + } else { + *aBaseline = BSize(aWM) - mFirstBaseline; + } + return true; + } + virtual nsSize GetXULMinSize(nsBoxLayoutState& aBoxLayoutState) override; virtual bool IsXULCollapsed() override; @@ -87,6 +110,14 @@ public: ~(nsIFrame::eReplaced | nsIFrame::eReplacedContainsBlock)); } +#ifdef DEBUG + void MarkIntrinsicISizesDirty() override + { + // Need another Reflow to have a correct baseline value again. + mFirstBaseline = NS_INTRINSIC_WIDTH_UNKNOWN; + } +#endif + // nsIAnonymousContentCreator virtual nsresult CreateAnonymousContent(nsTArray<ContentInfo>& aElements) override; virtual void AppendAnonymousContentTo(nsTArray<nsIContent*>& aElements, @@ -300,6 +331,10 @@ private: } private: + // Our first baseline, or NS_INTRINSIC_WIDTH_UNKNOWN if we have a pending + // Reflow. + nscoord mFirstBaseline; + // these packed bools could instead use the high order bits on mState, saving 4 bytes bool mEditorHasBeenInitialized; bool mIsProcessing; diff --git a/layout/forms/test/test_bug562447.html b/layout/forms/test/test_bug562447.html index 53f84428e..99f691871 100644 --- a/layout/forms/test/test_bug562447.html +++ b/layout/forms/test/test_bug562447.html @@ -23,7 +23,7 @@ addLoadEvent(function() { setTimeout(function() { // Make sure that we're scrolled by 5000px - is(window.pageYOffset, 5000, "Make sure we're scrolled correctly"); + is(Math.round(window.pageYOffset), 5000, "Make sure we're scrolled correctly"); // Scroll back up, and mess with the input box along the way var input = document.getElementById("WhyDoYouFocusMe"); @@ -38,14 +38,14 @@ addLoadEvent(function() { window.scrollTo(0, 5000); setTimeout(function() { - is(window.pageYOffset, 5000, "Sanity check"); + is(Math.round(window.pageYOffset), 5000, "Sanity check"); window.scrollTo(0, 0); input.focus(); input.blur(); setTimeout(function() { - isnot(window.pageYOffset, 0, "This time we shouldn't be scrolled up"); + isnot(Math.round(window.pageYOffset), 0, "This time we shouldn't be scrolled up"); SimpleTest.finish(); }, 0); diff --git a/layout/forms/test/test_bug564115.html b/layout/forms/test/test_bug564115.html index 5723b55d5..ffd4222ca 100644 --- a/layout/forms/test/test_bug564115.html +++ b/layout/forms/test/test_bug564115.html @@ -30,12 +30,12 @@ addLoadEvent(function() { win.scrollTo(0, 5000); setTimeout(function() { - is(win.pageYOffset, 5000, "Page should be scrolled correctly"); + is(Math.round(win.pageYOffset), 5000, "Page should be scrolled correctly"); // Refocus the window SimpleTest.waitForFocus(function() { SimpleTest.waitForFocus(function() { - is(win.pageYOffset, 5000, + is(Math.round(win.pageYOffset), 5000, "The page's scroll offset should not have been changed"); win.close(); diff --git a/layout/generic/ReflowInput.cpp b/layout/generic/ReflowInput.cpp index 42f4a24b5..a8756cea2 100644 --- a/layout/generic/ReflowInput.cpp +++ b/layout/generic/ReflowInput.cpp @@ -93,6 +93,9 @@ ReflowInput::ReflowInput(nsPresContext* aPresContext, if (aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE) { mFlags.mBClampMarginBoxMinSize = true; } + if (aFlags & I_APPLY_AUTO_MIN_SIZE) { + mFlags.mApplyAutoMinSize = true; + } if (!(aFlags & CALLER_WILL_INIT)) { Init(aPresContext); @@ -242,6 +245,7 @@ ReflowInput::ReflowInput( mFlags.mIOffsetsNeedCSSAlign = mFlags.mBOffsetsNeedCSSAlign = false; mFlags.mIClampMarginBoxMinSize = !!(aFlags & I_CLAMP_MARGIN_BOX_MIN_SIZE); mFlags.mBClampMarginBoxMinSize = !!(aFlags & B_CLAMP_MARGIN_BOX_MIN_SIZE); + mFlags.mApplyAutoMinSize = !!(aFlags & I_APPLY_AUTO_MIN_SIZE); mDiscoveredClearance = nullptr; mPercentBSizeObserver = (aParentReflowInput.mPercentBSizeObserver && @@ -1662,6 +1666,10 @@ ReflowInput::InitAbsoluteConstraints(nsPresContext* aPresContext, computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eBClampMarginBoxMinSize); } + if (mFlags.mApplyAutoMinSize) { + computeSizeFlags = ComputeSizeFlags(computeSizeFlags | + ComputeSizeFlags::eIApplyAutoMinSize); + } if (mFlags.mShrinkWrap) { computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); @@ -2375,6 +2383,10 @@ ReflowInput::InitConstraints(nsPresContext* aPresContext, computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eBClampMarginBoxMinSize); } + if (mFlags.mApplyAutoMinSize) { + computeSizeFlags = ComputeSizeFlags(computeSizeFlags | + ComputeSizeFlags::eIApplyAutoMinSize); + } if (mFlags.mShrinkWrap) { computeSizeFlags = ComputeSizeFlags(computeSizeFlags | ComputeSizeFlags::eShrinkWrap); diff --git a/layout/generic/ReflowInput.h b/layout/generic/ReflowInput.h index e42508646..09c980b72 100644 --- a/layout/generic/ReflowInput.h +++ b/layout/generic/ReflowInput.h @@ -220,6 +220,7 @@ public: uint32_t mStaticPosIsCBOrigin:1; // the STATIC_POS_IS_CB_ORIGIN ctor flag uint32_t mIClampMarginBoxMinSize:1; // the I_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag uint32_t mBClampMarginBoxMinSize:1; // the B_CLAMP_MARGIN_BOX_MIN_SIZE ctor flag + uint32_t mApplyAutoMinSize : 1; // the I_APPLY_AUTO_MIN_SIZE ctor flag // If set, the following two flags indicate that: // (1) this frame is absolutely-positioned (or fixed-positioned). @@ -738,6 +739,9 @@ public: // Pass ComputeSizeFlags::eBClampMarginBoxMinSize to ComputeSize(). B_CLAMP_MARGIN_BOX_MIN_SIZE = (1<<6), + + // Pass ComputeSizeFlags::eIApplyAutoMinSize to ComputeSize(). + I_APPLY_AUTO_MIN_SIZE = (1<<7), }; // This method initializes various data members. It is automatically diff --git a/layout/generic/Selection.h b/layout/generic/Selection.h index 6f94303ca..3d5e334fc 100644 --- a/layout/generic/Selection.h +++ b/layout/generic/Selection.h @@ -179,6 +179,9 @@ public: { return mRanges.Length(); } + + void GetType(nsAString& aOutType) const; + nsRange* GetRangeAt(uint32_t aIndex, mozilla::ErrorResult& aRv); void AddRange(nsRange& aRange, mozilla::ErrorResult& aRv); void RemoveRange(nsRange& aRange, mozilla::ErrorResult& aRv); diff --git a/layout/generic/nsFlexContainerFrame.cpp b/layout/generic/nsFlexContainerFrame.cpp index b61024324..3818d3cb7 100644 --- a/layout/generic/nsFlexContainerFrame.cpp +++ b/layout/generic/nsFlexContainerFrame.cpp @@ -33,6 +33,8 @@ typedef nsFlexContainerFrame::FlexItem FlexItem; typedef nsFlexContainerFrame::FlexLine FlexLine; typedef nsFlexContainerFrame::FlexboxAxisTracker FlexboxAxisTracker; typedef nsFlexContainerFrame::StrutInfo StrutInfo; +typedef nsFlexContainerFrame::CachedMeasuringReflowResult + CachedMeasuringReflowResult; static mozilla::LazyLogModule gFlexContainerLog("nsFlexContainerFrame"); @@ -1756,6 +1758,108 @@ nsFlexContainerFrame:: } } +/** + * A cached result for a measuring reflow. + * + * Right now we only need to cache the available size and the computed height + * for checking that the reflow input is valid, and the height and the ascent + * to be used. This can be extended later if needed. + * + * The assumption here is that a given flex item measurement won't change until + * either the available size or computed height changes, or the flex container + * intrinsic size is marked as dirty (due to a style or DOM change). + * + * In particular the computed height may change between measuring reflows due to + * how the mIsFlexContainerMeasuringReflow flag affects size computation (see + * bug 1336708). + * + * Caching it prevents us from doing exponential reflows in cases of deeply + * nested flex and scroll frames. + * + * We store them in the frame property table for simplicity. + */ +class nsFlexContainerFrame::CachedMeasuringReflowResult +{ + // Members that are part of the cache key: + const LogicalSize mAvailableSize; + const nscoord mComputedHeight; + + // Members that are part of the cache value: + const nscoord mHeight; + const nscoord mAscent; + +public: + CachedMeasuringReflowResult(const ReflowInput& aReflowInput, + const ReflowOutput& aDesiredSize) + : mAvailableSize(aReflowInput.AvailableSize()) + , mComputedHeight(aReflowInput.ComputedHeight()) + , mHeight(aDesiredSize.Height()) + , mAscent(aDesiredSize.BlockStartAscent()) + {} + + bool IsValidFor(const ReflowInput& aReflowInput) const { + return mAvailableSize == aReflowInput.AvailableSize() && + mComputedHeight == aReflowInput.ComputedHeight(); + } + + nscoord Height() const { return mHeight; } + + nscoord Ascent() const { return mAscent; } +}; + +NS_DECLARE_FRAME_PROPERTY_DELETABLE(CachedFlexMeasuringReflow, + CachedMeasuringReflowResult); + +const CachedMeasuringReflowResult& +nsFlexContainerFrame::MeasureAscentAndHeightForFlexItem( + FlexItem& aItem, + nsPresContext* aPresContext, + ReflowInput& aChildReflowInput) +{ + const FrameProperties props = aItem.Frame()->Properties(); + if (const auto* cachedResult = props.Get(CachedFlexMeasuringReflow())) { + if (cachedResult->IsValidFor(aChildReflowInput)) { + return *cachedResult; + } + } + + ReflowOutput childDesiredSize(aChildReflowInput); + nsReflowStatus childReflowStatus; + + const uint32_t flags = NS_FRAME_NO_MOVE_FRAME; + ReflowChild(aItem.Frame(), aPresContext, + childDesiredSize, aChildReflowInput, + 0, 0, flags, childReflowStatus); + aItem.SetHadMeasuringReflow(); + + // XXXdholbert Once we do pagination / splitting, we'll need to actually + // handle incomplete childReflowStatuses. But for now, we give our kids + // unconstrained available height, which means they should always complete. + MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childReflowStatus), + "We gave flex item unconstrained available height, so it " + "should be complete"); + + // Tell the child we're done with its initial reflow. + // (Necessary for e.g. GetBaseline() to work below w/out asserting) + FinishReflowChild(aItem.Frame(), aPresContext, + childDesiredSize, &aChildReflowInput, 0, 0, flags); + + auto result = + new CachedMeasuringReflowResult(aChildReflowInput, childDesiredSize); + + props.Set(CachedFlexMeasuringReflow(), result); + return *result; +} + +/* virtual */ void +nsFlexContainerFrame::MarkIntrinsicISizesDirty() +{ + for (nsIFrame* childFrame : mFrames) { + childFrame->Properties().Delete(CachedFlexMeasuringReflow()); + } + nsContainerFrame::MarkIntrinsicISizesDirty(); +} + nscoord nsFlexContainerFrame:: MeasureFlexItemContentHeight(nsPresContext* aPresContext, @@ -1783,27 +1887,15 @@ nsFlexContainerFrame:: childRIForMeasuringHeight.SetVResize(true); } - ReflowOutput childDesiredSize(childRIForMeasuringHeight); - nsReflowStatus childReflowStatus; - const uint32_t flags = NS_FRAME_NO_MOVE_FRAME; - ReflowChild(aFlexItem.Frame(), aPresContext, - childDesiredSize, childRIForMeasuringHeight, - 0, 0, flags, childReflowStatus); - - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childReflowStatus), - "We gave flex item unconstrained available height, so it " - "should be complete"); - - FinishReflowChild(aFlexItem.Frame(), aPresContext, - childDesiredSize, &childRIForMeasuringHeight, - 0, 0, flags); + const CachedMeasuringReflowResult& reflowResult = + MeasureAscentAndHeightForFlexItem(aFlexItem, aPresContext, + childRIForMeasuringHeight); - aFlexItem.SetHadMeasuringReflow(); - aFlexItem.SetAscent(childDesiredSize.BlockStartAscent()); + aFlexItem.SetAscent(reflowResult.Ascent()); // Subtract border/padding in vertical axis, to get _just_ // the effective computed value of the "height" property. - nscoord childDesiredHeight = childDesiredSize.Height() - + nscoord childDesiredHeight = reflowResult.Height() - childRIForMeasuringHeight.ComputedPhysicalBorderPadding().TopBottom(); return std::max(0, childDesiredHeight); @@ -3959,25 +4051,10 @@ nsFlexContainerFrame::SizeItemInCrossAxis( // whether any of its ancestors are being resized). aChildReflowInput.SetVResize(true); } - ReflowOutput childDesiredSize(aChildReflowInput); - nsReflowStatus childReflowStatus; - const uint32_t flags = NS_FRAME_NO_MOVE_FRAME; - ReflowChild(aItem.Frame(), aPresContext, - childDesiredSize, aChildReflowInput, - 0, 0, flags, childReflowStatus); - aItem.SetHadMeasuringReflow(); - - // XXXdholbert Once we do pagination / splitting, we'll need to actually - // handle incomplete childReflowStatuses. But for now, we give our kids - // unconstrained available height, which means they should always complete. - MOZ_ASSERT(NS_FRAME_IS_COMPLETE(childReflowStatus), - "We gave flex item unconstrained available height, so it " - "should be complete"); - // Tell the child we're done with its initial reflow. - // (Necessary for e.g. GetBaseline() to work below w/out asserting) - FinishReflowChild(aItem.Frame(), aPresContext, - childDesiredSize, &aChildReflowInput, 0, 0, flags); + // Potentially reflow the item, and get the sizing info. + const CachedMeasuringReflowResult& reflowResult = + MeasureAscentAndHeightForFlexItem(aItem, aPresContext, aChildReflowInput); // Save the sizing info that we learned from this reflow // ----------------------------------------------------- @@ -3989,7 +4066,7 @@ nsFlexContainerFrame::SizeItemInCrossAxis( // so we don't bother with making aAxisTracker pick the cross-axis component // for us.) nscoord crossAxisBorderPadding = aItem.GetBorderPadding().TopBottom(); - if (childDesiredSize.Height() < crossAxisBorderPadding) { + if (reflowResult.Height() < crossAxisBorderPadding) { // Child's requested size isn't large enough for its border/padding! // This is OK for the trivial nsFrame::Reflow() impl, but other frame // classes should know better. So, if we get here, the child had better be @@ -4002,10 +4079,10 @@ nsFlexContainerFrame::SizeItemInCrossAxis( aItem.SetCrossSize(0); } else { // (normal case) - aItem.SetCrossSize(childDesiredSize.Height() - crossAxisBorderPadding); + aItem.SetCrossSize(reflowResult.Height() - crossAxisBorderPadding); } - aItem.SetAscent(childDesiredSize.BlockStartAscent()); + aItem.SetAscent(reflowResult.Ascent()); } void @@ -4295,7 +4372,7 @@ nsFlexContainerFrame::DoFlexLayout(nsPresContext* aPresContext, LogicalSize availSize = aReflowInput.ComputedSize(wm); availSize.BSize(wm) = NS_UNCONSTRAINEDSIZE; ReflowInput childReflowInput(aPresContext, aReflowInput, - item->Frame(), availSize); + item->Frame(), availSize); if (!sizeOverride) { // Directly override the computed main-size, by tweaking reflow state: if (aAxisTracker.IsMainAxisHorizontal()) { diff --git a/layout/generic/nsFlexContainerFrame.h b/layout/generic/nsFlexContainerFrame.h index 22b420d85..459ae8e20 100644 --- a/layout/generic/nsFlexContainerFrame.h +++ b/layout/generic/nsFlexContainerFrame.h @@ -56,6 +56,7 @@ public: class FlexLine; class FlexboxAxisTracker; struct StrutInfo; + class CachedMeasuringReflowResult; // nsIFrame overrides void Init(nsIContent* aContent, @@ -66,6 +67,8 @@ public: const nsRect& aDirtyRect, const nsDisplayListSet& aLists) override; + void MarkIntrinsicISizesDirty() override; + virtual void Reflow(nsPresContext* aPresContext, ReflowOutput& aDesiredSize, const ReflowInput& aReflowInput, @@ -195,6 +198,18 @@ protected: const FlexboxAxisTracker& aAxisTracker); /** + * This method gets a cached measuring reflow for a flex item, or does it and + * caches it. + * + * This avoids exponential reflows, see the comment on + * CachedMeasuringReflowResult. + */ + const CachedMeasuringReflowResult& MeasureAscentAndHeightForFlexItem( + FlexItem& aItem, + nsPresContext* aPresContext, + ReflowInput& aChildReflowInput); + + /** * This method performs a "measuring" reflow to get the content height of * aFlexItem.Frame() (treating it as if it had auto-height), & returns the * resulting height. diff --git a/layout/generic/nsFrame.cpp b/layout/generic/nsFrame.cpp index 69791d5c5..418fa16b7 100644 --- a/layout/generic/nsFrame.cpp +++ b/layout/generic/nsFrame.cpp @@ -4781,7 +4781,7 @@ nsFrame::ComputeSize(nsRenderingContext* aRenderingContext, ComputeISizeValue(aRenderingContext, aCBSize.ISize(aWM), boxSizingAdjust.ISize(aWM), boxSizingToMarginEdgeISize, minISizeCoord, aFlags); - } else if (MOZ_UNLIKELY(isGridItem)) { + } else if (MOZ_UNLIKELY(aFlags & eIApplyAutoMinSize)) { // This implements "Implied Minimum Size of Grid Items". // https://drafts.csswg.org/css-grid/#min-size-auto minISize = std::min(maxISize, GetMinISize(aRenderingContext)); diff --git a/layout/generic/nsGridContainerFrame.cpp b/layout/generic/nsGridContainerFrame.cpp index 71d5bba21..8f117b5ab 100644 --- a/layout/generic/nsGridContainerFrame.cpp +++ b/layout/generic/nsGridContainerFrame.cpp @@ -818,8 +818,11 @@ struct nsGridContainerFrame::GridItemInfo // Ditto *-content:[last ]baseline. Mutually exclusive w. eSelfBaseline. eContentBaseline = 0x10, eAllBaselineBits = eIsBaselineAligned | eSelfBaseline | eContentBaseline, + // Should apply Automatic Minimum Size per: + // https://drafts.csswg.org/css-grid/#min-size-auto + eApplyAutoMinSize = 0x20, // Clamp per https://drafts.csswg.org/css-grid/#min-size-auto - eClampMarginBoxMinSize = 0x20, + eClampMarginBoxMinSize = 0x40, }; explicit GridItemInfo(nsIFrame* aFrame, @@ -851,11 +854,11 @@ struct nsGridContainerFrame::GridItemInfo return aAlign; } - // Return true if we should we clamp this item's Automatic Minimum Size. + // Return true if we should apply Automatic Minimum Size to this item. // https://drafts.csswg.org/css-grid/#min-size-auto - bool ShouldClampMinSize(WritingMode aContainerWM, - LogicalAxis aContainerAxis, - nscoord aPercentageBasis) const + bool ShouldApplyAutoMinSize(WritingMode aContainerWM, + LogicalAxis aContainerAxis, + nscoord aPercentageBasis) const { const auto pos = mFrame->StylePosition(); const auto& size = aContainerAxis == eLogicalAxisInline ? @@ -2090,6 +2093,18 @@ struct MOZ_STACK_CLASS nsGridContainerFrame::GridReflowInput SizingConstraint aConstraint); /** + * Return the percentage basis for a grid item in its writing-mode. + * If aAxis is eLogicalAxisInline then we return NS_UNCONSTRAINEDSIZE in + * both axes since we know all track sizes are indefinite at this point + * (we calculate column sizes before row sizes). Otherwise, assert that + * column sizes are known and calculate the size for aGridItem.mArea.mCols + * and use NS_UNCONSTRAINEDSIZE in the other axis. + * @param aAxis the axis we're currently calculating track sizes for + */ + LogicalSize PercentageBasisFor(LogicalAxis aAxis, + const GridItemInfo& aGridItem) const; + + /** * Return the containing block for a grid item occupying aArea. */ LogicalRect ContainingBlockFor(const GridArea& aArea) const; @@ -3731,18 +3746,20 @@ MeasuringReflow(nsIFrame* aChild, * the child's margin-box) in aAxis. */ static nscoord -ContentContribution(const GridItemInfo& aGridItem, - const GridReflowInput& aState, - nsRenderingContext* aRC, - WritingMode aCBWM, - LogicalAxis aAxis, - IntrinsicISizeType aConstraint, - nscoord aMinSizeClamp = NS_MAXSIZE, - uint32_t aFlags = 0) +ContentContribution(const GridItemInfo& aGridItem, + const GridReflowInput& aState, + nsRenderingContext* aRC, + WritingMode aCBWM, + LogicalAxis aAxis, + const Maybe<LogicalSize>& aPercentageBasis, + IntrinsicISizeType aConstraint, + nscoord aMinSizeClamp = NS_MAXSIZE, + uint32_t aFlags = 0) { nsIFrame* child = aGridItem.mFrame; PhysicalAxis axis(aCBWM.PhysicalAxis(aAxis)); nscoord size = nsLayoutUtils::IntrinsicForAxis(axis, aRC, child, aConstraint, + aPercentageBasis, aFlags | nsLayoutUtils::BAIL_IF_REFLOW_NEEDED | nsLayoutUtils::ADD_PERCENTS, aMinSizeClamp); @@ -3812,6 +3829,10 @@ struct CachedIntrinsicSizes Maybe<nscoord> mMinSize; Maybe<nscoord> mMinContentContribution; Maybe<nscoord> mMaxContentContribution; + + // The item's percentage basis for intrinsic sizing purposes. + Maybe<LogicalSize> mPercentageBasis; + // "if the grid item spans only grid tracks that have a fixed max track // sizing function, its automatic minimum size in that dimension is // further clamped to less than or equal to the size necessary to fit its @@ -3832,7 +3853,11 @@ MinContentContribution(const GridItemInfo& aGridItem, if (aCache->mMinContentContribution.isSome()) { return aCache->mMinContentContribution.value(); } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, aCache->mMinSizeClamp); aCache->mMinContentContribution.emplace(s); @@ -3850,7 +3875,11 @@ MaxContentContribution(const GridItemInfo& aGridItem, if (aCache->mMaxContentContribution.isSome()) { return aCache->mMaxContentContribution.value(); } + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } nscoord s = ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::PREF_ISIZE, aCache->mMinSizeClamp); aCache->mMaxContentContribution.emplace(s); @@ -3904,7 +3933,11 @@ MinSize(const GridItemInfo& aGridItem, child->StyleDisplay()->mOverflowX == NS_STYLE_OVERFLOW_VISIBLE)) { // Now calculate the "content size" part and return whichever is smaller. MOZ_ASSERT(unit != eStyleUnit_Enumerated || sz == NS_UNCONSTRAINEDSIZE); + if (aCache->mPercentageBasis.isNothing()) { + aCache->mPercentageBasis.emplace(aState.PercentageBasisFor(aAxis, aGridItem)); + } sz = std::min(sz, ContentContribution(aGridItem, aState, aRC, aCBWM, aAxis, + aCache->mPercentageBasis, nsLayoutUtils::MIN_ISIZE, aCache->mMinSizeClamp, nsLayoutUtils::MIN_INTRINSIC_ISIZE)); @@ -3977,9 +4010,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSizeStep1( WritingMode wm = aState.mWM; // Calculate data for "Automatic Minimum Size" clamping, if needed. bool needed = ((sz.mState & TrackSize::eIntrinsicMinSizing) || - aConstraint == SizingConstraint::eNoConstraint); - if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState) && - aGridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) { + aConstraint == SizingConstraint::eNoConstraint) && + (aGridItem.mState[mAxis] & ItemState::eApplyAutoMinSize); + if (needed && TrackSize::IsDefiniteMaxSizing(sz.mState)) { if (sz.mState & TrackSize::eIntrinsicMinSizing) { auto maxCoord = aFunctions.MaxSizingFor(aRange.mStart); cache.mMinSizeClamp = @@ -4382,6 +4415,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( iter.Reset(); for (; !iter.AtEnd(); iter.Next()) { auto& gridItem = aGridItems[iter.GridItemIndex()]; + + // Check if we need to apply "Automatic Minimum Size" and cache it. + MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize), + "Why is eApplyAutoMinSize set already?"); + if (gridItem.ShouldApplyAutoMinSize(wm, mAxis, aPercentageBasis)) { + gridItem.mState[mAxis] |= ItemState::eApplyAutoMinSize; + } + const GridArea& area = gridItem.mArea; const LineRange& lineRange = area.*aRange; uint32_t span = lineRange.Extent(); @@ -4407,9 +4448,9 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( CachedIntrinsicSizes cache; // Calculate data for "Automatic Minimum Size" clamping, if needed. bool needed = ((state & TrackSize::eIntrinsicMinSizing) || - aConstraint == SizingConstraint::eNoConstraint); - if (needed && TrackSize::IsDefiniteMaxSizing(state) && - gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) { + aConstraint == SizingConstraint::eNoConstraint) && + (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize); + if (needed && TrackSize::IsDefiniteMaxSizing(state)) { nscoord minSizeClamp = 0; for (auto i = lineRange.mStart, end = lineRange.mEnd; i < end; ++i) { auto maxCoord = aFunctions.MaxSizingFor(i); @@ -4445,11 +4486,14 @@ nsGridContainerFrame::Tracks::ResolveIntrinsicSize( gridItem.mState[mAxis] |= ItemState::eIsFlexing; } else if (aConstraint == SizingConstraint::eNoConstraint && TrackSize::IsDefiniteMaxSizing(state) && - gridItem.ShouldClampMinSize(wm, mAxis, aPercentageBasis)) { + (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize)) { gridItem.mState[mAxis] |= ItemState::eClampMarginBoxMinSize; } } } + MOZ_ASSERT(!(gridItem.mState[mAxis] & ItemState::eClampMarginBoxMinSize) || + (gridItem.mState[mAxis] & ItemState::eApplyAutoMinSize), + "clamping only applies to Automatic Minimum Size"); } // Step 2. @@ -4707,7 +4751,8 @@ nsGridContainerFrame::Tracks::FindUsedFlexFraction( const GridItemInfo& item = aGridItems[iter.GridItemIndex()]; if (item.mState[mAxis] & ItemState::eIsFlexing) { // XXX optimize: bug 1194446 - nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, + auto pb = Some(aState.PercentageBasisFor(mAxis, item)); + nscoord spaceToFill = ContentContribution(item, aState, rc, wm, mAxis, pb, nsLayoutUtils::PREF_ISIZE); if (spaceToFill <= 0) { continue; @@ -5038,6 +5083,25 @@ nsGridContainerFrame::LineRange::ToPositionAndLengthForAbsPos( } } +LogicalSize +nsGridContainerFrame::GridReflowInput::PercentageBasisFor( + LogicalAxis aAxis, + const GridItemInfo& aGridItem) const +{ + auto wm = aGridItem.mFrame->GetWritingMode(); + if (aAxis == eLogicalAxisInline) { + return LogicalSize(wm, NS_UNCONSTRAINEDSIZE, NS_UNCONSTRAINEDSIZE); + } + // Note: for now, we only resolve transferred percentages to row sizing. + // We may need to adjust these assertions once we implement bug 1300366. + MOZ_ASSERT(mCols.mCanResolveLineRangeSize); + MOZ_ASSERT(!mRows.mCanResolveLineRangeSize); + nscoord colSize = aGridItem.mArea.mCols.ToLength(mCols.mSizes); + nscoord rowSize = NS_UNCONSTRAINEDSIZE; + return !wm.IsOrthogonalTo(mWM) ? + LogicalSize(wm, colSize, rowSize) : LogicalSize(wm, rowSize, colSize); +} + LogicalRect nsGridContainerFrame::GridReflowInput::ContainingBlockFor(const GridArea& aArea) const { @@ -5231,6 +5295,9 @@ nsGridContainerFrame::ReflowInFlowChild(nsIFrame* aChild, } else { aChild->Properties().Delete(BClampMarginBoxMinSizeProperty()); } + if ((aGridItemInfo->mState[childIAxis] & ItemState::eApplyAutoMinSize)) { + flags |= ReflowInput::I_APPLY_AUTO_MIN_SIZE; + } } if (!isConstrainedBSize) { diff --git a/layout/generic/nsIFrame.h b/layout/generic/nsIFrame.h index 50eb958e0..2acafa882 100644 --- a/layout/generic/nsIFrame.h +++ b/layout/generic/nsIFrame.h @@ -2105,6 +2105,14 @@ public: */ eIClampMarginBoxMinSize = 1 << 2, // clamp in our inline axis eBClampMarginBoxMinSize = 1 << 3, // clamp in our block axis + /** + * The frame is stretching (per CSS Box Alignment) and doesn't have an + * Automatic Minimum Size in the indicated axis. + * (may be used for both flex/grid items, but currently only used for Grid) + * https://drafts.csswg.org/css-grid/#min-size-auto + * https://drafts.csswg.org/css-align-3/#valdef-justify-self-stretch + */ + eIApplyAutoMinSize = 1 << 4, // only has an effect when eShrinkWrap is false }; /** diff --git a/layout/generic/nsSelection.cpp b/layout/generic/nsSelection.cpp index e0d65632e..a2227c39c 100644 --- a/layout/generic/nsSelection.cpp +++ b/layout/generic/nsSelection.cpp @@ -5349,6 +5349,18 @@ Selection::GetRangeCount(int32_t* aRangeCount) return NS_OK; } +void +Selection::GetType(nsAString& aOutType) const +{ + if (!RangeCount()) { + aOutType.AssignLiteral("None"); + } else if (IsCollapsed()) { + aOutType.AssignLiteral("Caret"); + } else { + aOutType.AssignLiteral("Range"); + } +} + NS_IMETHODIMP Selection::GetRangeAt(int32_t aIndex, nsIDOMRange** aReturn) { diff --git a/layout/generic/nsTextFrame.cpp b/layout/generic/nsTextFrame.cpp index b9848bcf1..00c0016fd 100644 --- a/layout/generic/nsTextFrame.cpp +++ b/layout/generic/nsTextFrame.cpp @@ -9751,9 +9751,13 @@ nsTextFrame::GetRenderedText(uint32_t aStartOffset, startOffset = aStartOffset; endOffset = std::min<uint32_t>(INT32_MAX, aEndOffset); } + + // If startOffset and/or endOffset are inside of trimmedOffsets' range, + // then clamp the edges of trimmedOffsets accordingly. + int32_t origTrimmedOffsetsEnd = trimmedOffsets.GetEnd(); trimmedOffsets.mStart = std::max<uint32_t>(trimmedOffsets.mStart, startOffset); - trimmedOffsets.mLength = std::min<uint32_t>(trimmedOffsets.GetEnd(), + trimmedOffsets.mLength = std::min<uint32_t>(origTrimmedOffsetsEnd, endOffset) - trimmedOffsets.mStart; if (trimmedOffsets.mLength <= 0) { offsetInRenderedString = nextOffsetInRenderedString; diff --git a/layout/printing/nsPagePrintTimer.cpp b/layout/printing/nsPagePrintTimer.cpp index b56569a9a..164b0469a 100644 --- a/layout/printing/nsPagePrintTimer.cpp +++ b/layout/printing/nsPagePrintTimer.cpp @@ -14,14 +14,8 @@ NS_IMPL_ISUPPORTS_INHERITED(nsPagePrintTimer, mozilla::Runnable, nsITimerCallbac nsPagePrintTimer::~nsPagePrintTimer() { - // "Destroy" the document viewer; this normally doesn't actually - // destroy it because of the IncrementDestroyRefCount call below - // XXX This is messy; the document viewer should use a single approach - // to keep itself alive during printing - nsCOMPtr<nsIContentViewer> cv(do_QueryInterface(mDocViewerPrint)); - if (cv) { - cv->Destroy(); - } + // This matches the IncrementDestroyRefCount call in the constructor. + mDocViewerPrint->DecrementDestroyRefCount(); } nsresult diff --git a/layout/reftests/bugs/315920-17.html b/layout/reftests/bugs/315920-17.html index 1681754a5..6d9180144 100644 --- a/layout/reftests/bugs/315920-17.html +++ b/layout/reftests/bugs/315920-17.html @@ -1,5 +1,5 @@ <!DOCTYPE html> -<html> +<html class="reftest-wait"> <head> <style> input ~ label {color: red} @@ -8,9 +8,7 @@ input:checked:default + label {color: green} </style> </head> - <body onload='document.getElementById("two").setAttribute("checked", "true"); - document.getElementById("one").setAttribute("checked", "checked"); - document.getElementById("two").removeAttribute("checked");'> + <body> <form> <input type="checkbox" name="group1" id="one" value="1"/> <label for="one">Should be no red</label><br> @@ -19,5 +17,14 @@ <input type="checkbox" name="group1" id="three" value="3"/> <label for="three">Should be no red</label> </form> +<script> +function doTest() { + document.getElementById("two").setAttribute("checked", "true"); + document.getElementById("one").setAttribute("checked", "checked"); + document.getElementById("two").removeAttribute("checked"); + setTimeout(function () { document.documentElement.removeAttribute("class"); }, 0); +} +window.addEventListener("MozReftestInvalidate", doTest); +</script> </body> </html> diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html index fc74cd214..caef8b031 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-min-content-min-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html index c5d8a68ff..36a2d4920 100644 --- a/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-auto-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html new file mode 100644 index 000000000..463bbb4e6 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001-ref.html @@ -0,0 +1,78 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: stretching overflow!=visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px 30px 3px / 7px 80px 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + min-width:0; + min-height:0; + box-sizing: border-box; +} + +.oa, .os, .oh { width:80px; height:30px; } +.m.oa, .m.os, .m.oh { width:70px; height:24px; } +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" " style="width:112px"><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m " style="width:112px"><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" " style="height:112px"><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m " style="height:112px"><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-001.html b/layout/reftests/css-grid/grid-item-overflow-stretch-001.html new file mode 100644 index 000000000..4f6259abe --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-001.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: stretching overflow!=visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-001-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; +} + +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html new file mode 100644 index 000000000..a9690a54e --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002-ref.html @@ -0,0 +1,79 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: stretching overflow!=visible vertical-rl items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px 30px 3px / 7px 80px 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + writing-mode: vertical-rl; + min-width:0; + min-height:0; + box-sizing: border-box; +} + +.oa, .os, .oh { width:80px; height:30px; } +.m.oa, .m.os, .m.oh { width:70px; height:24px; } +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" " style="width:112px"><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m " style="width:112px"><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" " style="height:112px"><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m " style="height:112px"><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-002.html b/layout/reftests/css-grid/grid-item-overflow-stretch-002.html new file mode 100644 index 000000000..520eed911 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-002.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: stretching overflow!=visible vertical-rl items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-002-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + writing-mode: vertical-rl; +} + +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html new file mode 100644 index 000000000..c082e6be4 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003-ref.html @@ -0,0 +1,84 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: margin:auto stretch items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px 30px 3px / 7px 112px 3px; + grid-gap: 5px; + border:1px solid; +} +.c2 { grid-template-columns: 7px 122px 3px; } +.h > .grid { grid: 7px 112px 3px / 7px 80px 3px; } + +.grid > * { + grid-area: 2/2; + border:1px solid; + margin: 0 auto; + justify-self:start; + align-self:start; + height:28px; +} +.c2 > * { height:22px; } +.h .grid > * { + margin: 10px 0 0 10px; + justify-self:center; + align-self:center; + width:5px; + height:110px; +} + +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid c2"><span class="m oa"><x></x></span></div> +<div class="grid c2"><span class="m os"><x></x></span></div> +<div class="grid c2"><span class="m oh"><x></x></span></div> +<div class="grid c2"><span class="m "><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-003.html b/layout/reftests/css-grid/grid-item-overflow-stretch-003.html new file mode 100644 index 000000000..8bcd79d9b --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-003.html @@ -0,0 +1,75 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: margin:auto stretch items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-003-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + margin: 0 auto; +} +.h .grid > * { + margin: auto; +} + +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="oa"><x></x></span></div> +<div class="grid"><span class="os"><x></x></span></div> +<div class="grid"><span class="oh"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m oa"><x></x></span></div> +<div class="grid"><span class="m os"><x></x></span></div> +<div class="grid"><span class="m oh"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html new file mode 100644 index 000000000..71ed28d7c --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004-ref.html @@ -0,0 +1,88 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: stretching items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 90px; + height: 50px; + grid: 7px 30px 3px / 7px 102px 3px; + grid-gap: 5px; + border:1px solid; +} +.c2 { grid: 7px 30x 3px / 7px 112px 3px; grid-gap: 5px;} +.c3 { grid: 7px 30x 3px / 7px 70px 3px; grid-gap: 5px;} + +.grid > * { + grid-area: 2/2; + border:1px solid; + min-width: 0; + max-width: 100px; +} +.h .grid > * { + min-height: 0; + max-height: 100px; + justify-self:center safe; + align-self:center safe; +} +.h > .grid { grid: 7px 102px 3px / 7px 70px 3px; grid-gap: 5px;} +.h > .grid.c2 { grid: 7px 30px 3px / 7px 70px 3px; grid-gap: 5px;} +.h > .grid.c3 { grid: 7px 108px 3px / 7px 70px 3px; grid-gap: 5px;} + +.oa { overflow: auto; } +.p { width: 100%; } +.h .grid > .p { height: 100%; } +.x { width:5px; } +.h .grid > .x { max-height:5px; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="p oa"><x></x></span></div> +<div class="grid"><span class="p "><x></x></span></div> +<div class="grid c2"><span class="p x" style="height:5px; margin-left:31.5px; margin-top:11.5px"><x></x></span></div> +<div class="grid c2"><span class=" " style="width:68px"><x></x></span></div> + +<br> + +<div class="grid c3"><span class="p m oa"><x></x></span></div> +<div class="grid c3"><span class="p m"><x></x></span></div> +<div class="grid c2"><span class="m p x"><x></x></span></div> +<div class="grid c2"><span class="m " style="width:58px"><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="p oa"><x></x></span></div> +<div class="grid"><span class="p "><x></x></span></div> +<div class="grid c2"><span class="p x" style=""><x></x></span></div> +<div class="grid c2"><span class=" " style="height:28px; width:68px;"><x></x></span></div> + +<br> + +<div class="grid c3"><span class="m p oa"><x></x></span></div> +<div class="grid c3"><span class="m p"><x></x></span></div> +<div class="grid c2"><span class="m p x" style="justify-self:start;align-self:start"><x></x></span></div> +<div class="grid c2"><span class="m " style="height:22px; width:58px"><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-004.html b/layout/reftests/css-grid/grid-item-overflow-stretch-004.html new file mode 100644 index 000000000..b983b5184 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-004.html @@ -0,0 +1,82 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: stretching items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-004-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 90px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + min-width: 0; + max-width: 100px; +} +.h .grid > * { + min-height: 0; + max-height: 100px; +} + +.oa { overflow: auto; } +.p { width: 100%; } +.h .grid > .p { height: 100%; } +.x { max-width:5px; margin:auto; } +.h .grid > .x { max-height:5px; } +.m { margin: 1px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class="p oa"><x></x></span></div> +<div class="grid"><span class="p "><x></x></span></div> +<div class="grid"><span class="p x"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="p m oa"><x></x></span></div> +<div class="grid"><span class="p m"><x></x></span></div> +<div class="grid"><span class="m p x"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="p oa"><x></x></span></div> +<div class="grid"><span class="p "><x></x></span></div> +<div class="grid"><span class="p x"><x></x></span></div> +<div class="grid"><span class=" "><x></x></span></div> + +<br> + +<div class="grid"><span class="m p oa"><x></x></span></div> +<div class="grid"><span class="m p"><x></x></span></div> +<div class="grid"><span class="m p x"><x></x></span></div> +<div class="grid"><span class="m "><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html new file mode 100644 index 000000000..e7d353c8b --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005-ref.html @@ -0,0 +1,83 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: stretching overflow!=visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + min-width:0; + min-height:0; + box-sizing: border-box; +} + +.oa, .os, .oh { width:80px; height:30px; } +.m.oa, .m.os, .m.oh { width:70px; height:8px; } +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.ov { justify-self: start; } +.m.ov { align-self: start; } +.m { margin: 17px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><input class="oa"></div> +<div class="grid"><input class="os"></div> +<div class="grid"><input class="oh"></div> +<div class="grid"><input class="ov"></div> + +<br> + +<div class="grid"><input class="m oa"></div> +<div class="grid"><input class="m os"></div> +<div class="grid"><input class="m oh"></div> +<div class="grid"><input class="m ov"></div> + +<br> + +<div class="h"> + +<div class="grid"><input class="oa"></div> +<div class="grid"><input class="os"></div> +<div class="grid"><input class="oh"></div> +<div class="grid"><input class="ov"></div> + +<br> + +<div class="grid"><input class="m oa"></div> +<div class="grid"><input class="m os"></div> +<div class="grid"><input class="m oh"></div> +<div class="grid"><input class="m ov"></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-005.html b/layout/reftests/css-grid/grid-item-overflow-stretch-005.html new file mode 100644 index 000000000..33fe468d7 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-005.html @@ -0,0 +1,77 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: stretching overflow!=visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-005-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px auto 3px / 7px auto 3px; + grid-gap: 5px; + border:1px solid; +} + +.grid > * { + grid-area: 2/2; + border:1px solid; + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; +} + +.oa { overflow: auto; } +.os { overflow: scroll; } +.oh { overflow: hidden; } +.m { margin: 17px 3px 5px 7px; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><input class="oa"></div> +<div class="grid"><input class="os"></div> +<div class="grid"><input class="oh"></div> +<div class="grid"><input class=" "></div> + +<br> + +<div class="grid"><input class="m oa"></div> +<div class="grid"><input class="m os"></div> +<div class="grid"><input class="m oh"></div> +<div class="grid"><input class="m "></div> + +<br> + +<div class="h"> + +<div class="grid"><input class="oa"></div> +<div class="grid"><input class="os"></div> +<div class="grid"><input class="oh"></div> +<div class="grid"><input class=" "></div> + +<br> + +<div class="grid"><input class="m oa"></div> +<div class="grid"><input class="m os"></div> +<div class="grid"><input class="m oh"></div> +<div class="grid"><input class="m "></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html b/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html new file mode 100644 index 000000000..71d4d4f54 --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006-ref.html @@ -0,0 +1,54 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Reference: stretching overflow visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-flex; + width: 90px; + height: 40px; + padding: 7px 3px 3px 7px; + border: 1px solid; +} + +.grid > * { + border: 1px solid; + margin: 5px; +} + +.m { margin: 6px 8px 10px 12px; } +.ma { margin: auto; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class=""><x></x></span></div> +<div class="grid"><span class="m"><x></x></span></div> +<div class="grid"><span class="ma" style="margin-left:5px"><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class="" style="flex:1"><x></x></span></div> +<div class="grid"><span class="m" style="flex:1"><x></x></span></div> +<div class="grid"><span class="ma" style="margin-top:5px"><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-item-overflow-stretch-006.html b/layout/reftests/css-grid/grid-item-overflow-stretch-006.html new file mode 100644 index 000000000..015c50fcc --- /dev/null +++ b/layout/reftests/css-grid/grid-item-overflow-stretch-006.html @@ -0,0 +1,56 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>CSS Grid Test: stretching overflow visible items</title> + <link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1348857"> + <link rel="match" href="grid-item-overflow-stretch-006-ref.html"> + <style type="text/css"> +body,html { color:black; background:white; font:16px/1 monospace; padding:0; margin:0; } + +.grid { + display: inline-grid; + width: 100px; + height: 50px; + grid: 7px minmax(20px, auto) 3px / 7px minmax(20px, auto) 3px; + grid-gap: 5px; + border: 1px solid; +} + +.grid > * { + grid-area: 2/2; + border: 1px solid; +} + +.m { margin: 1px 3px 5px 7px; } +.ma { margin: auto; } + +x { display:block; width:110px; height:5px; background:grey; } +.h .grid x { width:5px; height:110px; } + +br { clear:both; } + </style> +</head> +<body> + +<div class="grid"><span class=""><x></x></span></div> +<div class="grid"><span class="m"><x></x></span></div> +<div class="grid"><span class="ma"><x></x></span></div> + +<br> + +<div class="h"> + +<div class="grid"><span class=""><x></x></span></div> +<div class="grid"><span class="m"><x></x></span></div> +<div class="grid"><span class="ma"><x></x></span></div> + +<br> + +</div> + +</body> +</html> diff --git a/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html b/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html index 5fa60b3b5..04d047b83 100644 --- a/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html +++ b/layout/reftests/css-grid/grid-min-content-min-sizing-transferred-size-004-ref.html @@ -36,7 +36,7 @@ var rowtest = [ "min-width:80%; max-height:20px", "min-width:50%", "margin-left: 50px; width:50%" ]; var results = [ -"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "24px/2px", "20px/2px", "20px/2px", "24px/2px", "24px/52px" +"0/2px", "0/2px", "0/4px", "0/2px", "0/2px", "0/2px", "12px/2px", "20px/2px", "20px/2px", "24px/2px", "312px/52px" ]; var item_height = [ "0", "0", "0", "0", "0", "0", "12px", "20px", "20px", "24px", "312px" diff --git a/layout/reftests/css-grid/reftest.list b/layout/reftests/css-grid/reftest.list index d85eefbd0..093e2faee 100644 --- a/layout/reftests/css-grid/reftest.list +++ b/layout/reftests/css-grid/reftest.list @@ -116,6 +116,12 @@ skip-if(Android) == grid-auto-min-sizing-percent-001.html grid-auto-min-sizing-p == grid-item-auto-min-size-clamp-005.html grid-item-auto-min-size-clamp-005-ref.html == grid-item-auto-min-size-clamp-006.html grid-item-auto-min-size-clamp-006-ref.html == grid-item-auto-min-size-clamp-007.html grid-item-auto-min-size-clamp-007-ref.html +== grid-item-overflow-stretch-001.html grid-item-overflow-stretch-001-ref.html +== grid-item-overflow-stretch-002.html grid-item-overflow-stretch-002-ref.html +== grid-item-overflow-stretch-003.html grid-item-overflow-stretch-003-ref.html +== grid-item-overflow-stretch-004.html grid-item-overflow-stretch-004-ref.html +== grid-item-overflow-stretch-005.html grid-item-overflow-stretch-005-ref.html +== grid-item-overflow-stretch-006.html grid-item-overflow-stretch-006-ref.html == grid-item-canvas-001.html grid-item-canvas-001-ref.html skip-if(Android) == grid-item-button-001.html grid-item-button-001-ref.html == grid-item-table-stretch-001.html grid-item-table-stretch-001-ref.html diff --git a/layout/reftests/forms/display-block-baselines-1-ref.html b/layout/reftests/forms/display-block-baselines-1-ref.html new file mode 100644 index 000000000..d01c086b5 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-1-ref.html @@ -0,0 +1,91 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Testcase #1 for bug 1330962</title> + <style type="text/css"> +@font-face { + src: url(../fonts/Ahem.ttf); + font-family: Ahem; +} +html,body { + color:black; background-color:white; font:16px/1 Ahem; padding:0; margin:0; +} +* { font:16px/1 Ahem; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-grid"> + A<img class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D"> + </div> + B +</div> + +<div> + <div style="display:inline-grid"> + A + <input type="image" class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><input type="text" value="text"></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><input type="text" value="text"></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><input type="text"></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><input class="no-theme" type="text" value="text"></div> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-1.html b/layout/reftests/forms/display-block-baselines-1.html new file mode 100644 index 000000000..96ebdad71 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-1.html @@ -0,0 +1,92 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Testcase #1 for bug 1330962</title> + <style type="text/css"> +@font-face { + src: url(../fonts/Ahem.ttf); + font-family: Ahem; +} +html,body { + color:black; background-color:white; font:16px/1 Ahem; padding:0; margin:0; +} +* { font:16px/1 Ahem; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A + <img class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input type="image" class="block" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAIAAACQkWg2AAAACXBIWXMAAAsTAAALEwEAmpwYAAAAEElEQVQoz2NgGAWjYBTAAAADEAABaJFtwwAAAABJRU5ErkJggg%3D%3D"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input class="block" type="text" value="text"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input class="block scroll" type="text" value="text"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input class="block" type="text"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input class="block no-theme" type="text" value="text"> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-2-ref.html b/layout/reftests/forms/display-block-baselines-2-ref.html new file mode 100644 index 000000000..441a927b4 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-2-ref.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Testcase #2 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; + color: black; + text-align: start; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A<div> + <div style="display:inline-block"><input type="button" value="button"></div></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><button>button</button></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><input class="no-theme" type="button" value="button"></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <button class="no-theme">button-first<div style="font-size:10px">button-last</div></button> + </div> + B + <div class="no-theme" style="display:inline-block">button-first<div style="font-size:10px">button-last</div></div> +</div> + +<div> + <div style="display:inline-block"> + A<br> + <button class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></button> + </div> + B + <div class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></div> +</div> + +<div> + <div style="display:inline-grid"> + A + <input type="checkbox" class="block" checked> + </div> + B +</div> + +<div> + <div style="display:inline-grid"> + A + <input type="radio" class="block" checked> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-2.html b/layout/reftests/forms/display-block-baselines-2.html new file mode 100644 index 000000000..78253fe4c --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-2.html @@ -0,0 +1,100 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Testcase #2 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; + color: black; + text-align: start; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A + <input class="block" type="button" value="button"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <button class="block">button</button> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input class="block no-theme" type="button" value="button"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <button class="block no-theme">button-first<div style="font-size:10px">button-last</div></button> + </div> + B + <button class="no-theme">button-first<div style="font-size:10px">button-last</div></button> +</div> + +<div> + <div style="display:inline-block"> + A + <button class="grid no-theme">button-first<x style="font-size:10px">button-last</x></button> + </div> + B + <button class="no-theme" style="display:inline-grid">button-first<x style="font-size:10px">button-last</x></button> +</div> + +<div> + <div style="display:inline-block"> + A + <input type="checkbox" class="block" checked> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input type="radio" class="block" checked> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-3-ref.html b/layout/reftests/forms/display-block-baselines-3-ref.html new file mode 100644 index 000000000..ce277b50c --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-3-ref.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Testcase #3 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-grid"> + A + <textarea class="block">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-grid"> + A + <textarea class="block no-theme">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-grid"> + A + <textarea class="block no-theme no-scroll">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><fieldset style="display:inline">fieldset-first<br>fieldset-last</fieldset></div> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-3.html b/layout/reftests/forms/display-block-baselines-3.html new file mode 100644 index 000000000..9f3c2b110 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-3.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Testcase #3 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A + <textarea class="block">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <textarea class="block no-theme">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <textarea class="block no-theme no-scroll">textarea</textarea> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <fieldset class="block">fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-4-ref.html b/layout/reftests/forms/display-block-baselines-4-ref.html new file mode 100644 index 000000000..5015d50c4 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-4-ref.html @@ -0,0 +1,73 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Testcase #4 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A<br> + <div style="display:inline-block"><fieldset style="display:inline"><legend>legend</legend> +fieldset-first<br>fieldset-last</fieldset></div> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <fieldset style="display:inline-grid">grid-fieldset-first<x>grid-fieldset-last</x></fieldset> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <fieldset style="display:inline" class="no-theme">fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <fieldset style="display:inline" class="no-theme scroll">fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-4.html b/layout/reftests/forms/display-block-baselines-4.html new file mode 100644 index 000000000..1bfd344b0 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-4.html @@ -0,0 +1,74 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Testcase #4 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A + <fieldset class="block"><legend>legend</legend> +fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <fieldset class="grid"><x style="order:2">grid-fieldset-last</x>grid-fieldset-first</fieldset> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <fieldset class="block no-theme">fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <fieldset class="block no-theme scroll">fieldset-first<br>fieldset-last</fieldset> + </div> + B +</div> + + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-5-ref.html b/layout/reftests/forms/display-block-baselines-5-ref.html new file mode 100644 index 000000000..0dce47f59 --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-5-ref.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Reference: Testcase #5 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A<br> + <input type="color"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <input type="color" class="no-theme"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <select><option>select</select> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A<br> + <select class="no-theme"><option>select</select> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/display-block-baselines-5.html b/layout/reftests/forms/display-block-baselines-5.html new file mode 100644 index 000000000..0359c8a6f --- /dev/null +++ b/layout/reftests/forms/display-block-baselines-5.html @@ -0,0 +1,72 @@ +<!DOCTYPE HTML> +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<html><head> + <meta charset="utf-8"> + <title>Testcase #5 for bug 1330962</title> + <style type="text/css"> +html,body { + color:black; background-color:white; font:16px/1 monospace; padding:0; margin:0; +} +* { font:16px/1 monospace; } + +.block { display: block; } +.grid { display: grid; } + +.no-theme { + -moz-appearance: none; + -webkit-appearance: none; + appearance: none; + padding: 20px 0; + border: none; + background: white; +} + +.scroll { + overflow-y: scroll; +} + +.no-scroll { + overflow: visible; +} + + </style> +</head> +<body> + +<div> + <div style="display:inline-block"> + A + <input type="color" class="block"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <input type="color" class="block no-theme"> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <select class="block"><option>select</select> + </div> + B +</div> + +<div> + <div style="display:inline-block"> + A + <select class="block no-theme"><option>select</select> + </div> + B +</div> + +</body> +</html> diff --git a/layout/reftests/forms/input/datetime/reftest.list b/layout/reftests/forms/input/datetime/reftest.list index 0ce2002bd..a62d56c7c 100644 --- a/layout/reftests/forms/input/datetime/reftest.list +++ b/layout/reftests/forms/input/datetime/reftest.list @@ -11,3 +11,14 @@ skip-if(!Android&&!B2G&&!Mulet) == time-simple-unthemed.html time-simple-untheme # type change skip-if(Android||B2G||Mulet) == to-time-from-other-type-unthemed.html time-simple-unthemed.html skip-if(Android||B2G||Mulet) == from-time-to-other-type-unthemed.html from-time-to-other-type-unthemed-ref.html + +# content should not overflow on small width/height +skip-if(Android) == time-small-width.html time-small-width-ref.html +skip-if(Android) == time-small-height.html time-small-height-ref.html +skip-if(Android) == time-small-width-height.html time-small-width-height-ref.html + +# content (text) should be left aligned +skip-if(Android) == time-content-left-aligned.html time-content-left-aligned-ref.html + +# reset button should be right aligned +skip-if(Android) fails-if(styloVsGecko) == time-reset-button-right-aligned.html time-reset-button-right-aligned-ref.html # bug 1372062 diff --git a/layout/reftests/forms/input/datetime/time-content-left-aligned-ref.html b/layout/reftests/forms/input/datetime/time-content-left-aligned-ref.html new file mode 100644 index 000000000..ad8be9adc --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-content-left-aligned-ref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <body> + <input type="time" style="width: 200px;"> + <!-- div to cover the right area --> + <div style="display:block; position:absolute; background-color:black; + top:0px; left:40px; width:200px; height:100px;"></div> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-content-left-aligned.html b/layout/reftests/forms/input/datetime/time-content-left-aligned.html new file mode 100644 index 000000000..aa910cddf --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-content-left-aligned.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <body> + <input type="time" style="width: 50px;"> + <!-- div to cover the right area --> + <div style="display:block; position:absolute; background-color:black; + top:0px; left:40px; width:200px; height:100px;"></div> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-reset-button-right-aligned-ref.html b/layout/reftests/forms/input/datetime/time-reset-button-right-aligned-ref.html new file mode 100644 index 000000000..3d36f2068 --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-reset-button-right-aligned-ref.html @@ -0,0 +1,9 @@ +<!DOCTYPE html> +<html> + <body> + <input type="time" value="10:00" style="float: right; color: white;"> + <!-- div to cover the left area --> + <div style="display:block; position:absolute; background-color:black; + top:0px; right:30px; width:500px; height:100px;"></div> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-reset-button-right-aligned.html b/layout/reftests/forms/input/datetime/time-reset-button-right-aligned.html new file mode 100644 index 000000000..72d5cc140 --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-reset-button-right-aligned.html @@ -0,0 +1,10 @@ +<!DOCTYPE html> +<html> + <body> + <input type="time" value="10:00" style="width: 150px; float: right; + color: white;"> + <!-- div to cover the left area --> + <div style="display:block; position:absolute; background-color:black; + top:0px; right:30px; width:500px; height:100px;"></div> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-height-ref.html b/layout/reftests/forms/input/datetime/time-small-height-ref.html new file mode 100644 index 000000000..fcda93df9 --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-height-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 200px; + height: 5px; + outline: 1px dotted black; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-height.html b/layout/reftests/forms/input/datetime/time-small-height.html new file mode 100644 index 000000000..3044822fe --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-height.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 200px; + height: 5px; + outline: 1px dotted black; + color: white; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input type="time"> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-width-height-ref.html b/layout/reftests/forms/input/datetime/time-small-width-height-ref.html new file mode 100644 index 000000000..0979243db --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-width-height-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 8px; + height: 8px; + outline: 1px dotted black; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-width-height.html b/layout/reftests/forms/input/datetime/time-small-width-height.html new file mode 100644 index 000000000..a221b2819 --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-width-height.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 8px; + height: 8px; + outline: 1px dotted black; + color: white; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input type="time"> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-width-ref.html b/layout/reftests/forms/input/datetime/time-small-width-ref.html new file mode 100644 index 000000000..2379c7080 --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-width-ref.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 10px; + height: 1.5em; + outline: 1px dotted black; + background: white; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input> + </body> +</html> diff --git a/layout/reftests/forms/input/datetime/time-small-width.html b/layout/reftests/forms/input/datetime/time-small-width.html new file mode 100644 index 000000000..f76f7fdfa --- /dev/null +++ b/layout/reftests/forms/input/datetime/time-small-width.html @@ -0,0 +1,20 @@ +<!DOCTYPE html> +<html> + <head> + <style> +input { + width: 10px; + height: 1.5em; + outline: 1px dotted black; + color: white; + background: white; + /* Disable baseline alignment, so that our y-position isn't influenced by the + * choice of font inside of input: */ + vertical-align: top; +} + </style> + </head> + <body> + <input type="time"> + </body> +</html> diff --git a/layout/reftests/forms/reftest.list b/layout/reftests/forms/reftest.list index d45db276f..c7532077b 100644 --- a/layout/reftests/forms/reftest.list +++ b/layout/reftests/forms/reftest.list @@ -1,4 +1,9 @@ fuzzy-if(skiaContent,1,10) HTTP(..) == text-control-baseline-1.html text-control-baseline-1-ref.html +fuzzy-if(cocoaWidget,16,64) fuzzy-if(Android,52,64) fuzzy-if(/^Windows\x20NT\x206\.1/.test(http.oscpu),104,224) fuzzy-if(/^Windows\x20NT\x206\.2/.test(http.oscpu),57,400) == display-block-baselines-1.html display-block-baselines-1-ref.html # anti-aliasing issues +== display-block-baselines-2.html display-block-baselines-2-ref.html +== display-block-baselines-3.html display-block-baselines-3-ref.html +== display-block-baselines-4.html display-block-baselines-4-ref.html +fuzzy-if(Android,4,8) == display-block-baselines-5.html display-block-baselines-5-ref.html # button element include button/reftest.list diff --git a/layout/reftests/scrolling/propagated-overflow-style-1-ref.html b/layout/reftests/scrolling/propagated-overflow-style-1-ref.html new file mode 100644 index 000000000..7c2b1b315 --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-1-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <title> + Reference case with body and html *independently* scrollable. + </title> + <style> + html { + overflow: scroll; + } + body { + overflow: scroll; + } + </style> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-1a.html b/layout/reftests/scrolling/propagated-overflow-style-1a.html new file mode 100644 index 000000000..b5115d36f --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-1a.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with body and html *independently* scrollable, + with body's "overflow" set dynamically. + </title> + <style> + html { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.body.style.overflow = "scroll"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-1b.html b/layout/reftests/scrolling/propagated-overflow-style-1b.html new file mode 100644 index 000000000..4608b87d6 --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-1b.html @@ -0,0 +1,23 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with body and html *independently* scrollable, + with html's "overflow" set dynamically. + </title> + <style> + body { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.documentElement.style.overflow = "scroll"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-1c.html b/layout/reftests/scrolling/propagated-overflow-style-1c.html new file mode 100644 index 000000000..11809915a --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-1c.html @@ -0,0 +1,19 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with body and html *independently* scrollable, + with both html & body's "overflow" set dynamically. + </title> + <script> + function doTest() { + document.documentElement.style.overflow = "scroll"; + document.body.style.overflow = "scroll"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2-ref.html b/layout/reftests/scrolling/propagated-overflow-style-2-ref.html new file mode 100644 index 000000000..20c3b8ae5 --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2-ref.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title> + Reference case with the root viewport scrollable, via styles on html node. + </title> + <style> + html { + overflow: scroll; + } + </style> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2a.html b/layout/reftests/scrolling/propagated-overflow-style-2a.html new file mode 100644 index 000000000..250bedd6c --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2a.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with only one of [html,body] being scrollable, + after body's "overflow" is reset dynamically. + </title> + <style> + html { + overflow: scroll; + } + body { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.body.style.overflow = "visible"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2b.html b/layout/reftests/scrolling/propagated-overflow-style-2b.html new file mode 100644 index 000000000..c94ddedb2 --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2b.html @@ -0,0 +1,26 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with only one of [html,body] being scrollable, + after html's "overflow" is reset dynamically. + </title> + <style> + html { + overflow: scroll; + } + body { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.documentElement.style.overflow = "visible"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2c.html b/layout/reftests/scrolling/propagated-overflow-style-2c.html new file mode 100644 index 000000000..0ceb1f21a --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2c.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with only one of [html,body] being scrollable, + with their "overflow" styles being dynamically swapped. + </title> + <style> + html { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.documentElement.style.overflow = "visible"; + document.body.style.overflow = "scroll"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2d.html b/layout/reftests/scrolling/propagated-overflow-style-2d.html new file mode 100644 index 000000000..3353a3374 --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2d.html @@ -0,0 +1,24 @@ +<!DOCTYPE html> +<html class="reftest-wait"> +<head> + <title> + Testcase with only one of [html,body] being scrollable, + with their "overflow" styles being dynamically swapped. + </title> + <style> + body { + overflow: scroll; + } + </style> + <script> + function doTest() { + document.documentElement.style.overflow = "scroll"; + document.body.style.overflow = "visible"; + document.documentElement.removeAttribute("class"); + } + window.addEventListener("MozReftestInvalidate", doTest); + </script> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/propagated-overflow-style-2e.html b/layout/reftests/scrolling/propagated-overflow-style-2e.html new file mode 100644 index 000000000..f9105185b --- /dev/null +++ b/layout/reftests/scrolling/propagated-overflow-style-2e.html @@ -0,0 +1,15 @@ +<!DOCTYPE html> +<html> +<head> + <title> + Testcase with the root viewport scrollable, via styles on body node. + </title> + <style> + body { + overflow: scroll; + } + </style> +</head> +<body> +</body> +</html> diff --git a/layout/reftests/scrolling/reftest.list b/layout/reftests/scrolling/reftest.list index db1b81db6..43997ced7 100644 --- a/layout/reftests/scrolling/reftest.list +++ b/layout/reftests/scrolling/reftest.list @@ -85,3 +85,13 @@ fuzzy-if(asyncPan&&!layersGPUAccelerated,102,2420) == frame-scrolling-attr-2.htm == fractional-scroll-area.html?top=0.4&outerBottom=99.6&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999 == fractional-scroll-area.html?top=0.4&outerBottom=100.4&innerBottom=200.4&scrollBefore=999 fractional-scroll-area.html?top=0&outerBottom=100&innerBottom=200&scrollBefore=999 != fractional-scroll-area-invalidation.html about:blank + +# Tests for "overflow" styles that may be propagated to the viewport: +== propagated-overflow-style-1a.html propagated-overflow-style-1-ref.html +== propagated-overflow-style-1b.html propagated-overflow-style-1-ref.html +== propagated-overflow-style-1c.html propagated-overflow-style-1-ref.html +== propagated-overflow-style-2a.html propagated-overflow-style-2-ref.html +== propagated-overflow-style-2b.html propagated-overflow-style-2-ref.html +== propagated-overflow-style-2c.html propagated-overflow-style-2-ref.html +== propagated-overflow-style-2d.html propagated-overflow-style-2-ref.html +== propagated-overflow-style-2e.html propagated-overflow-style-2-ref.html diff --git a/layout/reftests/svg/radialGradient-fr-01.svg b/layout/reftests/svg/radialGradient-fr-01.svg new file mode 100644 index 000000000..2f28d3aba --- /dev/null +++ b/layout/reftests/svg/radialGradient-fr-01.svg @@ -0,0 +1,27 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>Test gradient fr attribute</title> + <defs> + <radialGradient id="grad1" fr="100%"> + <stop offset="0%" stop-color="red" /> + <stop offset="100%" stop-color="lime" /> + </radialGradient> + <radialGradient id="grad2" xlink:href="#grad1"/> + <style> + circle { + stroke-width: 3px; + stroke: lime; + } + </style> + </defs> + <rect width="100%" height="100%" fill="lime"/> + + <circle cx="100" cy="100" r="50" fill="url(#grad1)" /> + + <circle cx="300" cy="100" r="50" fill="url(#grad2)" /> +</svg> + diff --git a/layout/reftests/svg/radialGradient-fr-02-ref.svg b/layout/reftests/svg/radialGradient-fr-02-ref.svg new file mode 100644 index 000000000..c256f72a2 --- /dev/null +++ b/layout/reftests/svg/radialGradient-fr-02-ref.svg @@ -0,0 +1,28 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>Test gradient fr attribute</title> + <defs> + <radialGradient id="grad1"> + <stop offset="0%" stop-color="red" /> + <stop offset="20%" stop-color="red" /> + <stop offset="100%" stop-color="lime" /> + </radialGradient> + <style> + .cover { + stroke-width: 3px; + stroke: lime; + fill: none; + image-rendering: optimizeSpeed; + } + </style> + </defs> + <rect width="100%" height="100%" fill="lime"/> + + <circle cx="100" cy="100" r="50" fill="url(#grad1)" /> + <circle class="cover" cx="100" cy="100" r="50" fill="none"/> +</svg> + diff --git a/layout/reftests/svg/radialGradient-fr-02.svg b/layout/reftests/svg/radialGradient-fr-02.svg new file mode 100644 index 000000000..1933203be --- /dev/null +++ b/layout/reftests/svg/radialGradient-fr-02.svg @@ -0,0 +1,27 @@ +<!-- + Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ +--> +<svg xmlns="http://www.w3.org/2000/svg" + xmlns:xlink="http://www.w3.org/1999/xlink"> + <title>Test gradient fr attribute</title> + <defs> + <radialGradient id="grad1" fr="10%"> + <stop offset="0%" stop-color="red" /> + <stop offset="100%" stop-color="lime" /> + </radialGradient> + <style> + .cover { + stroke-width: 3px; + stroke: lime; + fill: none; + image-rendering: optimizeSpeed; + } + </style> + </defs> + <rect width="100%" height="100%" fill="lime"/> + + <circle cx="100" cy="100" r="50" fill="url(#grad1)" /> + <circle class="cover" cx="100" cy="100" r="50" /> +</svg> + diff --git a/layout/reftests/svg/reftest.list b/layout/reftests/svg/reftest.list index e596feae8..520adc9e6 100644 --- a/layout/reftests/svg/reftest.list +++ b/layout/reftests/svg/reftest.list @@ -290,6 +290,8 @@ fuzzy-if(skiaContent,3,5) == pattern-scale-01c.svg pattern-scale-01-ref.svg == radialGradient-basic-02.svg pass.svg fuzzy-if(cocoaWidget,4,15982) fuzzy-if(winWidget,4,92) fuzzy-if(skiaContent,4,60) == radialGradient-basic-03.svg radialGradient-basic-03-ref.svg == radialGradient-basic-04.svg pass.svg +== radialGradient-fr-01.svg pass.svg +fuzzy(1,3235) fuzzy-if(winWidget,1,6704) == radialGradient-fr-02.svg radialGradient-fr-02-ref.svg fuzzy-if(skiaContent,1,3600) == rect-01.svg pass.svg == rect-02.svg pass.svg == rect-03.svg pass.svg diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001-ref.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001-ref.html new file mode 100644 index 000000000..2473417b8 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001-ref.html @@ -0,0 +1,16 @@ +<!doctype html> +<title>CSS Test Reference</title> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<style> +html, body { margin: 0; padding: 0; } + +.content { + margin-top: 100px; + width: 200px; + height: 200px; + background: blue; +} +</style> +<body> + <div class="content"></div> +</body> diff --git a/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001.html b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001.html new file mode 100644 index 000000000..b6e2fdff0 --- /dev/null +++ b/layout/reftests/w3c-css/submitted/flexbox/flexbox-align-items-center-nested-001.html @@ -0,0 +1,47 @@ +<!doctype html> +<meta charset="utf-8"> +<title>CSS Test: Flexbox nested containers with align-items: center and flexible items</title> +<link rel="match" href="flexbox-align-items-center-nested-001-ref.html"> +<link rel="author" href="mailto:emilio@crisal.io" title="Emilio Cobos Álvarez"> +<link rel="help" href="https://www.w3.org/TR/css-flexbox-1/#align-items-property"> +<style> +html, body { margin: 0; padding: 0; } +body { + height: 400px; + position: relative; +} + +.container-0 { + display: flex; + position: absolute; + height: 100%; + flex-direction: column; +} + +.container-1 { + flex: 1 0 auto; + display: flex; + align-items: center; +} + +.container-2 { + height: 100%; + display: flex; + align-items: center; +} + +.content { + width: 200px; + height: 200px; + background: blue; +} +</style> +<body> + <div class="container-0"> + <div class="container-1"> + <div class="container-2"> + <div class="content"></div> + </div> + </div> + </div> +</body> diff --git a/layout/reftests/w3c-css/submitted/flexbox/reftest.list b/layout/reftests/w3c-css/submitted/flexbox/reftest.list index a623a0b59..fd8bfccc9 100644 --- a/layout/reftests/w3c-css/submitted/flexbox/reftest.list +++ b/layout/reftests/w3c-css/submitted/flexbox/reftest.list @@ -39,6 +39,8 @@ fuzzy-if(Android,158,32) == flexbox-align-self-vert-rtl-001.xhtml flexbox-align == flexbox-align-self-vert-rtl-003.xhtml flexbox-align-self-vert-rtl-003-ref.xhtml == flexbox-align-self-vert-rtl-004.xhtml flexbox-align-self-vert-rtl-004-ref.xhtml +== flexbox-align-items-center-nested-001.html flexbox-align-items-center-nested-001-ref.html + # Tests for computing the baseline of a flex container == flexbox-baseline-align-self-baseline-horiz-001.html flexbox-baseline-align-self-baseline-horiz-001-ref.html == flexbox-baseline-align-self-baseline-vert-001.html flexbox-baseline-align-self-baseline-vert-001-ref.html diff --git a/layout/reftests/xul/css-flex-1-ref.html b/layout/reftests/xul/css-flex-1-ref.html new file mode 100644 index 000000000..a47eb8e9c --- /dev/null +++ b/layout/reftests/xul/css-flex-1-ref.html @@ -0,0 +1,18 @@ +<!DOCTYPE html> +<html> +<head> + <style> + body { margin: 0 } + div.ref { + border: 1px solid black; + box-sizing: border-box; + background: green; + height: 50px; + width: 100px; + } + </style> +</head> +<body> + <div class="ref"></div> +</body> +</html> diff --git a/layout/reftests/xul/css-flex-1.xul b/layout/reftests/xul/css-flex-1.xul new file mode 100644 index 000000000..7955373dd --- /dev/null +++ b/layout/reftests/xul/css-flex-1.xul @@ -0,0 +1,153 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en-US" lang="en-US"> +<head> +<link rel="icon" href="/mozilla-central/static/hgicon.png" type="image/png" /> +<meta name="robots" content="index, nofollow"/> +<link rel="stylesheet" href="/mozilla-central/static/style-gitweb.css" type="text/css" /> + +<style type="text/css"> +div.feed { + float: right; +} +a img { + border-width: 0px; +} +div.log_link { + width: 80px; + background-color: white; +} + +div.log_body { + padding-left: 96px; +} +</style> +<script type="text/javascript" src="/mozilla-central/static/mercurial.js"></script> + +<link rel="stylesheet" href="/mozilla-central/highlightcss" type="text/css" /> +<title>mozilla-central: layout/reftests/xul/css-flex-1.xul@67bbef772796</title> +<link rel="alternate" type="application/atom+xml" + href="/mozilla-central/atom-log" title="Atom feed for mozilla-central"/> +<link rel="alternate" type="application/rss+xml" + href="/mozilla-central/rss-log" title="RSS feed for mozilla-central"/> +</head> +<body> + +<div class="page_header"> +<div class="logo"> <a href="https://developer.mozilla.org/en/docs/Mercurial"> <img src="/mozilla-central/static/moz-logo-bw-rgb.svg" alt="mercurial" /> </a> </div> +<a href="/">Mercurial</a> > <a href="/mozilla-central">mozilla-central</a> / file revision / layout/reftests/xul/css-flex-1.xul@67bbef772796 +</div> + +<div class="page_nav"> +<div> +<a href="/mozilla-central/summary">summary</a> | +<a href="/mozilla-central/shortlog">shortlog</a> | +<a href="/mozilla-central/log">changelog</a> | +<a href="/mozilla-central/pushloghtml">pushlog</a> | +<a href="/mozilla-central/graph">graph</a> | +<a href="/mozilla-central/tags">tags</a> | +<a href="/mozilla-central/bookmarks">bookmarks</a> | +<a href="/mozilla-central/branches">branches</a> | +<a href="/mozilla-central/file/67bbef772796/layout/reftests/xul/">files</a> | +<a href="/mozilla-central/rev/67bbef772796">changeset</a> | +file | +<a href="/mozilla-central/file/tip/layout/reftests/xul/css-flex-1.xul">latest</a> | +<a href="/mozilla-central/log/67bbef772796/layout/reftests/xul/css-flex-1.xul">revisions</a> | +<a href="/mozilla-central/annotate/67bbef772796/layout/reftests/xul/css-flex-1.xul">annotate</a> | +<a href="/mozilla-central/diff/67bbef772796/layout/reftests/xul/css-flex-1.xul">diff</a> | +<a href="/mozilla-central/comparison/67bbef772796/layout/reftests/xul/css-flex-1.xul">comparison</a> | +<a href="/mozilla-central/raw-file/67bbef772796/layout/reftests/xul/css-flex-1.xul">raw</a> | +<a href="/mozilla-central/help">help</a> +</div> + +<div class="search"> +<form id="searchform" action="/mozilla-central/log"> + +<input name="rev" type="text" value="" size="40" /> +<div id="hint">Find changesets by keywords (author, files, the commit message), revision +number or hash, or <a href="/mozilla-central/help/revsets">revset expression</a>.</div> +</form> +</div> +</div> + +<div class="title">layout/reftests/xul/css-flex-1.xul</div> + +<div class="title_text"> +<table cellspacing="0"> +<tr> + <td>author</td> + <td>Daniel Holbert <dholbert@cs.stanford.edu></td> +</tr> +<tr> + <td></td> + <td class="date age">Wed, 08 Feb 2017 23:08:43 -0800</td> +</tr> + +<tr> + <td>changeset 341731</td> + <td style="font-family:monospace"><a class="list" href="/mozilla-central/rev/67bbef772796">67bbef772796</a></td> +</tr> + + +<tr> + <td>permissions</td> + <td style="font-family:monospace">-rw-r--r--</td> +</tr> +</table> +</div> + +<div class="page_path description"><a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1338053">Bug 1338053</a>: Make nsFlexContainerFrame::MarkIntrinsicISizesDirty() also call its parent class's method. r=emilio + +MozReview-Commit-ID: 72oIlunLcVq</div> + +<div class="page_body"> +<pre class="sourcelines stripes" + data-logurl="/mozilla-central/log/67bbef772796/layout/reftests/xul/css-flex-1.xul" + data-selectabletag="SPAN" + data-ishead="1"> + +<a href="#l1"></a><span id="l1"><?xml version="1.0"?></span> +<a href="#l2"></a><span id="l2"><window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"</span> +<a href="#l3"></a><span id="l3"> class="reftest-wait"</span> +<a href="#l4"></a><span id="l4"> onload="tweak()"></span> +<a href="#l5"></a><span id="l5"> <style xmlns="http://www.w3.org/1999/xhtml"></span> +<a href="#l6"></a><span id="l6"> <![CDATA[</span> +<a href="#l7"></a><span id="l7"> panelview {</span> +<a href="#l8"></a><span id="l8"> border: 1px solid black;</span> +<a href="#l9"></a><span id="l9"> background: green;</span> +<a href="#l10"></a><span id="l10"> display: flex;</span> +<a href="#l11"></a><span id="l11"> height: 50px;</span> +<a href="#l12"></a><span id="l12"> }</span> +<a href="#l13"></a><span id="l13"> ]]></span> +<a href="#l14"></a><span id="l14"> </style></span> +<a href="#l15"></a><span id="l15"> <script></span> +<a href="#l16"></a><span id="l16"> <![CDATA[</span> +<a href="#l17"></a><span id="l17"> function tweak() {</span> +<a href="#l18"></a><span id="l18"> var tweakMe = document.getElementById("tweakMe");</span> +<a href="#l19"></a><span id="l19"> tweakMe.style.width = "100px";</span> +<a href="#l20"></a><span id="l20"> document.documentElement.className = "";</span> +<a href="#l21"></a><span id="l21"> }</span> +<a href="#l22"></a><span id="l22"> ]]></span> +<a href="#l23"></a><span id="l23"> </script></span> +<a href="#l24"></a><span id="l24"> <hbox></span> +<a href="#l25"></a><span id="l25"> <panelview id="tweakMe"></panelview></span> +<a href="#l26"></a><span id="l26"> </hbox></span> +<a href="#l27"></a><span id="l27"></window></span> +</pre> +</div> + +<script type="text/javascript" src="/mozilla-central/static/followlines.js"></script> + +<div class="page_footer"> +<div class="page_footer_text">mozilla-central</div> +<div class="page_footer_text" style="padding-left: 10px">Deployed from <a href="https://hg.mozilla.org/hgcustom/version-control-tools/rev/bd13917afa61">bd13917afa61</a> at 2018-04-20T21:06:08Z.</div> +<div class="rss_logo"> +<a href="/mozilla-central/rss-log">RSS</a> +<a href="/mozilla-central/atom-log">Atom</a> +</div> +<br /> + +</div> +</body> +</html> + diff --git a/layout/reftests/xul/reftest.list b/layout/reftests/xul/reftest.list index da09b7c81..35b9f9025 100644 --- a/layout/reftests/xul/reftest.list +++ b/layout/reftests/xul/reftest.list @@ -1,3 +1,5 @@ +== css-flex-1.xul css-flex-1-ref.html + == menuitem-key.xul menuitem-key-ref.xul # these random-if(Android) are due to differences between Android Native & Xul, see bug 732569 random-if(Android) == menulist-shrinkwrap-1.xul menulist-shrinkwrap-1-ref.xul diff --git a/layout/style/FontFaceSet.cpp b/layout/style/FontFaceSet.cpp index 59626fba4..550a7d71a 100644 --- a/layout/style/FontFaceSet.cpp +++ b/layout/style/FontFaceSet.cpp @@ -343,17 +343,7 @@ FontFaceSet::Load(JSContext* aCx, } } - nsIGlobalObject* globalObject = GetParentObject(); - if (!globalObject) { - aRv.Throw(NS_ERROR_FAILURE); - return nullptr; - } - - JS::Rooted<JSObject*> jsGlobal(aCx, globalObject->GetGlobalJSObject()); - GlobalObject global(aCx, jsGlobal); - - RefPtr<Promise> result = Promise::All(global, promises, aRv); - return result.forget(); + return Promise::All(aCx, promises, aRv); } bool diff --git a/layout/style/nsCSSKeywordList.h b/layout/style/nsCSSKeywordList.h index febdd32c6..933ff6e7b 100644 --- a/layout/style/nsCSSKeywordList.h +++ b/layout/style/nsCSSKeywordList.h @@ -742,6 +742,8 @@ CSS_KEY(button-focus, button_focus) CSS_KEY(-moz-win-media-toolbox, _moz_win_media_toolbox) CSS_KEY(-moz-win-communications-toolbox, _moz_win_communications_toolbox) CSS_KEY(-moz-win-browsertabbar-toolbox, _moz_win_browsertabbar_toolbox) +CSS_KEY(-moz-win-accentcolor, _moz_win_accentcolor) +CSS_KEY(-moz-win-accentcolortext, _moz_win_accentcolortext) CSS_KEY(-moz-win-mediatext, _moz_win_mediatext) CSS_KEY(-moz-win-communicationstext, _moz_win_communicationstext) CSS_KEY(-moz-win-glass, _moz_win_glass) diff --git a/layout/style/nsCSSParser.cpp b/layout/style/nsCSSParser.cpp index 1108ce5b5..b361cf0c2 100644 --- a/layout/style/nsCSSParser.cpp +++ b/layout/style/nsCSSParser.cpp @@ -8918,6 +8918,10 @@ CSSParserImpl::ParseGridTrackSize(nsCSSValue& aValue, return CSSParseResult::NotFound; } if (mToken.mIdent.LowerCaseEqualsLiteral("fit-content")) { + if (requireFixedSize) { + UngetToken(); + return CSSParseResult::Error; + } nsCSSValue::Array* func = aValue.InitFunction(eCSSKeyword_fit_content, 1); if (ParseGridTrackBreadth(func->Item(1)) == CSSParseResult::Ok && func->Item(1).IsLengthPercentCalcUnit() && @@ -10400,7 +10404,8 @@ CSSParserImpl::ParseLinearGradient(nsCSSValue& aValue, UngetToken(); // <angle> , - if (ParseSingleTokenVariant(cssGradient->mAngle, VARIANT_ANGLE, nullptr) && + if (ParseSingleTokenVariant(cssGradient->mAngle, + VARIANT_ANGLE_OR_ZERO, nullptr) && !ExpectSymbol(',', true)) { SkipUntil(')'); return false; diff --git a/layout/style/nsCSSProps.cpp b/layout/style/nsCSSProps.cpp index ec28d06f8..f3a7f898d 100644 --- a/layout/style/nsCSSProps.cpp +++ b/layout/style/nsCSSProps.cpp @@ -1174,6 +1174,8 @@ const KTableEntry nsCSSProps::kColorKTable[] = { { eCSSKeyword__moz_oddtreerow, LookAndFeel::eColorID__moz_oddtreerow }, { eCSSKeyword__moz_visitedhyperlinktext, NS_COLOR_MOZ_VISITEDHYPERLINKTEXT }, { eCSSKeyword_currentcolor, NS_COLOR_CURRENTCOLOR }, + { eCSSKeyword__moz_win_accentcolor, LookAndFeel::eColorID__moz_win_accentcolor }, + { eCSSKeyword__moz_win_accentcolortext, LookAndFeel::eColorID__moz_win_accentcolortext }, { eCSSKeyword__moz_win_mediatext, LookAndFeel::eColorID__moz_win_mediatext }, { eCSSKeyword__moz_win_communicationstext, LookAndFeel::eColorID__moz_win_communicationstext }, { eCSSKeyword__moz_nativehyperlinktext, LookAndFeel::eColorID__moz_nativehyperlinktext }, diff --git a/layout/style/nsCSSPseudoElements.h b/layout/style/nsCSSPseudoElements.h index 657ef663e..eaf8d966b 100644 --- a/layout/style/nsCSSPseudoElements.h +++ b/layout/style/nsCSSPseudoElements.h @@ -111,8 +111,7 @@ private: // which is a general gcc bug that we seem to have hit only on Android/x86. #if defined(ANDROID) && defined(__i386__) && defined(__GNUC__) && \ !defined(__clang__) -#if (MOZ_GCC_VERSION_AT_LEAST(4,8,0) && MOZ_GCC_VERSION_AT_MOST(4,8,4)) || \ - (MOZ_GCC_VERSION_AT_LEAST(4,9,0) && MOZ_GCC_VERSION_AT_MOST(4,9,2)) +#if (MOZ_GCC_VERSION_AT_LEAST(4,9,0) && MOZ_GCC_VERSION_AT_MOST(4,9,2)) __attribute__((noinline)) #endif #endif diff --git a/layout/style/nsCSSRuleProcessor.cpp b/layout/style/nsCSSRuleProcessor.cpp index 07a4ef57b..8760a330e 100644 --- a/layout/style/nsCSSRuleProcessor.cpp +++ b/layout/style/nsCSSRuleProcessor.cpp @@ -1127,6 +1127,16 @@ InitSystemMetrics() sSystemMetrics->AppendElement(nsGkAtoms::mac_yosemite_theme); } + rv = LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsAccentColorApplies, &metricResult); + if (NS_SUCCEEDED(rv) && metricResult) { + sSystemMetrics->AppendElement(nsGkAtoms::windows_accent_color_applies); + } + + rv = LookAndFeel::GetInt(LookAndFeel::eIntID_WindowsAccentColorIsDark, &metricResult); + if (NS_SUCCEEDED(rv) && metricResult) { + sSystemMetrics->AppendElement(nsGkAtoms::windows_accent_color_is_dark); + } + rv = LookAndFeel::GetInt(LookAndFeel::eIntID_DWMCompositor, &metricResult); if (NS_SUCCEEDED(rv) && metricResult) { sSystemMetrics->AppendElement(nsGkAtoms::windows_compositor); diff --git a/layout/style/nsLayoutStylesheetCache.cpp b/layout/style/nsLayoutStylesheetCache.cpp index f8aea5541..e8c6d09d7 100644 --- a/layout/style/nsLayoutStylesheetCache.cpp +++ b/layout/style/nsLayoutStylesheetCache.cpp @@ -23,19 +23,6 @@ #include "nsPrintfCString.h" #include "nsXULAppAPI.h" -// Includes for the crash report annotation in ErrorLoadingSheet. -#ifdef MOZ_CRASHREPORTER -#include "mozilla/Omnijar.h" -#include "nsDirectoryService.h" -#include "nsDirectoryServiceDefs.h" -#include "nsExceptionHandler.h" -#include "nsIChromeRegistry.h" -#include "nsISimpleEnumerator.h" -#include "nsISubstitutingProtocolHandler.h" -#include "zlib.h" -#include "nsZipArchive.h" -#endif - using namespace mozilla; using namespace mozilla::css; @@ -463,280 +450,6 @@ nsLayoutStylesheetCache::LoadSheetFile(nsIFile* aFile, LoadSheet(uri, aSheet, aParsingMode, aFailureAction); } -#ifdef MOZ_CRASHREPORTER -static inline nsresult -ComputeCRC32(nsIFile* aFile, uint32_t* aResult) -{ - PRFileDesc* fd; - nsresult rv = aFile->OpenNSPRFileDesc(PR_RDONLY, 0, &fd); - NS_ENSURE_SUCCESS(rv, rv); - - uint32_t crc = crc32(0, nullptr, 0); - - unsigned char buf[512]; - int32_t n; - while ((n = PR_Read(fd, buf, sizeof(buf))) > 0) { - crc = crc32(crc, buf, n); - } - PR_Close(fd); - - if (n < 0) { - return NS_ERROR_FAILURE; - } - - *aResult = crc; - return NS_OK; -} - -static void -ListInterestingFiles(nsString& aAnnotation, nsIFile* aFile, - const nsTArray<nsString>& aInterestingFilenames) -{ - nsString filename; - aFile->GetLeafName(filename); - for (const nsString& interestingFilename : aInterestingFilenames) { - if (interestingFilename == filename) { - nsString path; - aFile->GetPath(path); - aAnnotation.AppendLiteral(" "); - aAnnotation.Append(path); - aAnnotation.AppendLiteral(" ("); - int64_t size; - if (NS_SUCCEEDED(aFile->GetFileSize(&size))) { - aAnnotation.AppendPrintf("%ld", size); - } else { - aAnnotation.AppendLiteral("???"); - } - aAnnotation.AppendLiteral(" bytes, crc32 = "); - uint32_t crc; - nsresult rv = ComputeCRC32(aFile, &crc); - if (NS_SUCCEEDED(rv)) { - aAnnotation.AppendPrintf("0x%08x)\n", crc); - } else { - aAnnotation.AppendPrintf("error 0x%08x)\n", uint32_t(rv)); - } - return; - } - } - - bool isDir = false; - aFile->IsDirectory(&isDir); - - if (!isDir) { - return; - } - - nsCOMPtr<nsISimpleEnumerator> entries; - if (NS_FAILED(aFile->GetDirectoryEntries(getter_AddRefs(entries)))) { - aAnnotation.AppendLiteral(" (failed to enumerated directory)\n"); - return; - } - - for (;;) { - bool hasMore = false; - if (NS_FAILED(entries->HasMoreElements(&hasMore))) { - aAnnotation.AppendLiteral(" (failed during directory enumeration)\n"); - return; - } - if (!hasMore) { - break; - } - - nsCOMPtr<nsISupports> entry; - if (NS_FAILED(entries->GetNext(getter_AddRefs(entry)))) { - aAnnotation.AppendLiteral(" (failed during directory enumeration)\n"); - return; - } - - nsCOMPtr<nsIFile> file = do_QueryInterface(entry); - if (file) { - ListInterestingFiles(aAnnotation, file, aInterestingFilenames); - } - } -} - -// Generate a crash report annotation to help debug issues with style -// sheets failing to load (bug 1194856). -static void -AnnotateCrashReport(nsIURI* aURI) -{ - nsAutoCString spec; - nsAutoCString scheme; - nsDependentCSubstring filename; - if (aURI) { - spec = aURI->GetSpecOrDefault(); - aURI->GetScheme(scheme); - int32_t i = spec.RFindChar('/'); - if (i != -1) { - filename.Rebind(spec, i + 1); - } - } - - nsString annotation; - - // The URL of the sheet that failed to load. - annotation.AppendLiteral("Error loading sheet: "); - annotation.Append(NS_ConvertUTF8toUTF16(spec).get()); - annotation.Append('\n'); - - annotation.AppendLiteral("NS_ERROR_FILE_CORRUPTION reason: "); - if (nsZipArchive::sFileCorruptedReason) { - annotation.Append(NS_ConvertUTF8toUTF16(nsZipArchive::sFileCorruptedReason).get()); - annotation.Append('\n'); - } else { - annotation.AppendLiteral("(none)\n"); - } - - // The jar: or file: URL that the sheet's resource: or chrome: URL - // resolves to. - if (scheme.EqualsLiteral("resource")) { - annotation.AppendLiteral("Real location: "); - nsCOMPtr<nsISubstitutingProtocolHandler> handler; - nsCOMPtr<nsIIOService> io(do_GetIOService()); - if (io) { - nsCOMPtr<nsIProtocolHandler> ph; - io->GetProtocolHandler(scheme.get(), getter_AddRefs(ph)); - if (ph) { - handler = do_QueryInterface(ph); - } - } - if (!handler) { - annotation.AppendLiteral("(ResolveURI failed)\n"); - } else { - nsAutoCString resolvedSpec; - handler->ResolveURI(aURI, resolvedSpec); - annotation.Append(NS_ConvertUTF8toUTF16(resolvedSpec)); - annotation.Append('\n'); - } - } else if (scheme.EqualsLiteral("chrome")) { - annotation.AppendLiteral("Real location: "); - nsCOMPtr<nsIChromeRegistry> reg = - mozilla::services::GetChromeRegistryService(); - if (!reg) { - annotation.AppendLiteral("(no chrome registry)\n"); - } else { - nsCOMPtr<nsIURI> resolvedURI; - reg->ConvertChromeURL(aURI, getter_AddRefs(resolvedURI)); - if (!resolvedURI) { - annotation.AppendLiteral("(ConvertChromeURL failed)\n"); - } else { - annotation.Append( - NS_ConvertUTF8toUTF16(resolvedURI->GetSpecOrDefault())); - annotation.Append('\n'); - } - } - } - - nsTArray<nsString> interestingFiles; - interestingFiles.AppendElement(NS_LITERAL_STRING("chrome.manifest")); - interestingFiles.AppendElement(NS_LITERAL_STRING("omni.ja")); - interestingFiles.AppendElement(NS_ConvertUTF8toUTF16(filename)); - - annotation.AppendLiteral("GRE directory: "); - nsCOMPtr<nsIFile> file; - nsDirectoryService::gService->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), - getter_AddRefs(file)); - if (file) { - // The Firefox installation directory. - nsString path; - file->GetPath(path); - annotation.Append(path); - annotation.Append('\n'); - - // List interesting files -- any chrome.manifest or omni.ja file or any file - // whose name is the sheet's filename -- under the Firefox installation - // directory. - annotation.AppendLiteral("Interesting files in the GRE directory:\n"); - ListInterestingFiles(annotation, file, interestingFiles); - - // If the Firefox installation directory has a chrome.manifest file, let's - // see what's in it. - file->Append(NS_LITERAL_STRING("chrome.manifest")); - bool exists = false; - file->Exists(&exists); - if (exists) { - annotation.AppendLiteral("Contents of chrome.manifest:\n[[[\n"); - PRFileDesc* fd; - if (NS_SUCCEEDED(file->OpenNSPRFileDesc(PR_RDONLY, 0, &fd))) { - nsCString contents; - char buf[512]; - int32_t n; - while ((n = PR_Read(fd, buf, sizeof(buf))) > 0) { - contents.Append(buf, n); - } - if (n < 0) { - annotation.AppendLiteral(" (error while reading)\n"); - } else { - annotation.Append(NS_ConvertUTF8toUTF16(contents)); - } - PR_Close(fd); - } - annotation.AppendLiteral("]]]\n"); - } - } else { - annotation.AppendLiteral("(none)\n"); - } - - // The jar: or file: URL prefix that chrome: and resource: URLs get translated - // to. - annotation.AppendLiteral("GRE omnijar URI string: "); - nsCString uri; - nsresult rv = Omnijar::GetURIString(Omnijar::GRE, uri); - if (NS_FAILED(rv)) { - annotation.AppendLiteral("(failed)\n"); - } else { - annotation.Append(NS_ConvertUTF8toUTF16(uri)); - annotation.Append('\n'); - } - - RefPtr<nsZipArchive> zip = Omnijar::GetReader(Omnijar::GRE); - if (zip) { - // List interesting files in the GRE omnijar. - annotation.AppendLiteral("Interesting files in the GRE omnijar:\n"); - nsZipFind* find; - rv = zip->FindInit(nullptr, &find); - if (NS_FAILED(rv)) { - annotation.AppendPrintf(" (FindInit failed with 0x%08x)\n", rv); - } else if (!find) { - annotation.AppendLiteral(" (FindInit returned null)\n"); - } else { - const char* result; - uint16_t len; - while (NS_SUCCEEDED(find->FindNext(&result, &len))) { - nsCString itemPathname; - nsString itemFilename; - itemPathname.Append(result, len); - int32_t i = itemPathname.RFindChar('/'); - if (i != -1) { - itemFilename = NS_ConvertUTF8toUTF16(Substring(itemPathname, i + 1)); - } - for (const nsString& interestingFile : interestingFiles) { - if (interestingFile == itemFilename) { - annotation.AppendLiteral(" "); - annotation.Append(NS_ConvertUTF8toUTF16(itemPathname)); - nsZipItem* item = zip->GetItem(itemPathname.get()); - if (!item) { - annotation.AppendLiteral(" (GetItem failed)\n"); - } else { - annotation.AppendPrintf(" (%d bytes, crc32 = 0x%08x)\n", - item->RealSize(), - item->CRC32()); - } - break; - } - } - } - delete find; - } - } else { - annotation.AppendLiteral("No GRE omnijar\n"); - } - - CrashReporter::AnnotateCrashReport(NS_LITERAL_CSTRING("SheetLoadFailure"), - NS_ConvertUTF16toUTF8(annotation)); -} -#endif - static void ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction) { @@ -751,9 +464,6 @@ ErrorLoadingSheet(nsIURI* aURI, const char* aMsg, FailureAction aFailureAction) } } -#ifdef MOZ_CRASHREPORTER - AnnotateCrashReport(aURI); -#endif NS_RUNTIMEABORT(errorMessage.get()); } @@ -780,9 +490,6 @@ nsLayoutStylesheetCache::LoadSheet(nsIURI* aURI, } } -#ifdef MOZ_CRASHREPORTER - nsZipArchive::sFileCorruptedReason = nullptr; -#endif nsresult rv = loader->LoadSheetSync(aURI, aParsingMode, true, aSheet); if (NS_FAILED(rv)) { ErrorLoadingSheet(aURI, diff --git a/layout/style/nsMediaFeatures.cpp b/layout/style/nsMediaFeatures.cpp index c07a4123e..5a54d5455 100644 --- a/layout/style/nsMediaFeatures.cpp +++ b/layout/style/nsMediaFeatures.cpp @@ -70,8 +70,6 @@ struct OperatingSystemVersionInfo { // Os version identities used in the -moz-os-version media query. const OperatingSystemVersionInfo osVersionStrings[] = { - { LookAndFeel::eOperatingSystemVersion_WindowsXP, L"windows-xp" }, - { LookAndFeel::eOperatingSystemVersion_WindowsVista, L"windows-vista" }, { LookAndFeel::eOperatingSystemVersion_Windows7, L"windows-win7" }, { LookAndFeel::eOperatingSystemVersion_Windows8, L"windows-win8" }, { LookAndFeel::eOperatingSystemVersion_Windows10, L"windows-win10" } @@ -716,6 +714,22 @@ nsMediaFeatures::features[] = { GetSystemMetric }, { + &nsGkAtoms::_moz_windows_accent_color_applies, + nsMediaFeature::eMinMaxNotAllowed, + nsMediaFeature::eBoolInteger, + nsMediaFeature::eNoRequirements, + { &nsGkAtoms::windows_accent_color_applies }, + GetSystemMetric + }, + { + &nsGkAtoms::_moz_windows_accent_color_is_dark, + nsMediaFeature::eMinMaxNotAllowed, + nsMediaFeature::eBoolInteger, + nsMediaFeature::eNoRequirements, + { &nsGkAtoms::windows_accent_color_is_dark }, + GetSystemMetric + }, + { &nsGkAtoms::_moz_windows_compositor, nsMediaFeature::eMinMaxNotAllowed, nsMediaFeature::eBoolInteger, diff --git a/layout/style/nsRuleNode.cpp b/layout/style/nsRuleNode.cpp index b22002d87..fa29fe0f1 100644 --- a/layout/style/nsRuleNode.cpp +++ b/layout/style/nsRuleNode.cpp @@ -4686,7 +4686,8 @@ nsRuleNode::ComputeTextData(void* aStartStruct, if (font->mSize != 0) { lh = nscoord(float(lh) * float(font->mFont.size) / float(font->mSize)); } else { - lh = minimumFontSize; + // Never shrink line heights as a result of minFontSize + lh = std::max(lh, minimumFontSize); } } text->mLineHeight.SetCoordValue(lh); diff --git a/layout/style/nsStyleStruct.cpp b/layout/style/nsStyleStruct.cpp index 2f12d6201..553239e0e 100644 --- a/layout/style/nsStyleStruct.cpp +++ b/layout/style/nsStyleStruct.cpp @@ -1629,23 +1629,11 @@ nsStylePosition::CalcDifference(const nsStylePosition& aNewData, if (aOldStyleVisibility) { bool isVertical = WritingMode(aOldStyleVisibility).IsVertical(); if (isVertical ? widthChanged : heightChanged) { - // Block-size changes can affect descendant intrinsic sizes due to - // replaced elements with percentage bsizes in descendants which - // also have percentage bsizes. This is handled via - // nsChangeHint_UpdateComputedBSize which clears intrinsic sizes - // for frames that have such replaced elements. - hint |= nsChangeHint_NeedReflow | - nsChangeHint_UpdateComputedBSize | - nsChangeHint_ReflowChangesSizeOrPosition; + hint |= nsChangeHint_ReflowHintsForBSizeChange; } if (isVertical ? heightChanged : widthChanged) { - // None of our inline-size differences can affect descendant - // intrinsic sizes and none of them need to force children to - // reflow. - hint |= nsChangeHint_AllReflowHints & - ~(nsChangeHint_ClearDescendantIntrinsics | - nsChangeHint_NeedDirtyReflow); + hint |= nsChangeHint_ReflowHintsForISizeChange; } } else { if (widthChanged || heightChanged) { @@ -3258,8 +3246,6 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const || mDisplay != aNewData.mDisplay || mContain != aNewData.mContain || (mFloat == StyleFloat::None) != (aNewData.mFloat == StyleFloat::None) - || mOverflowX != aNewData.mOverflowX - || mOverflowY != aNewData.mOverflowY || mScrollBehavior != aNewData.mScrollBehavior || mScrollSnapTypeX != aNewData.mScrollSnapTypeX || mScrollSnapTypeY != aNewData.mScrollSnapTypeY @@ -3271,6 +3257,11 @@ nsStyleDisplay::CalcDifference(const nsStyleDisplay& aNewData) const hint |= nsChangeHint_ReconstructFrame; } + if (mOverflowX != aNewData.mOverflowX + || mOverflowY != aNewData.mOverflowY) { + hint |= nsChangeHint_CSSOverflowChange; + } + /* Note: When mScrollBehavior, mScrollSnapTypeX, mScrollSnapTypeY, * mScrollSnapPointsX, mScrollSnapPointsY, or mScrollSnapDestination are * changed, nsChangeHint_NeutralChange is not sufficient to enter diff --git a/layout/style/nsStyleStruct.h b/layout/style/nsStyleStruct.h index ca5d03056..05a6be91e 100644 --- a/layout/style/nsStyleStruct.h +++ b/layout/style/nsStyleStruct.h @@ -1197,11 +1197,14 @@ private: nsCSSShadowItem mArray[1]; // This MUST be the last item }; -// Border widths are rounded to the nearest-below integer number of pixels, -// but values between zero and one device pixels are always rounded up to -// one device pixel. +// Border widths are rounded to the nearest integer number of pixels, but values +// between zero and one device pixels are always rounded up to one device pixel. #define NS_ROUND_BORDER_TO_PIXELS(l,tpp) \ - ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)) + ((l) == 0) ? 0 : std::max((tpp), ((l) + ((tpp) / 2)) / (tpp) * (tpp)) +// Caret widths are rounded to the nearest-below integer number of pixels, but values +// between zero and one device pixels are always rounded up to one device pixel. +#define NS_ROUND_CARET_TO_PIXELS(l,tpp) \ + ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)) // Outline offset is rounded to the nearest integer number of pixels, but values // between zero and one device pixels are always rounded up to one device pixel. // Note that the offset can be negative. diff --git a/layout/style/res/forms.css b/layout/style/res/forms.css index f045540b1..e7566e183 100644 --- a/layout/style/res/forms.css +++ b/layout/style/res/forms.css @@ -1135,3 +1135,8 @@ input[type="number"] > div > div > div:hover { /* give some indication of hover state for the up/down buttons */ background-color: lightblue; } + +input[type="date"], +input[type="time"] { + overflow: hidden !important; +} diff --git a/layout/style/res/html.css b/layout/style/res/html.css index a779461de..bc3f08210 100644 --- a/layout/style/res/html.css +++ b/layout/style/res/html.css @@ -774,6 +774,11 @@ input[type="time"] > xul|datetimebox { -moz-binding: url("chrome://global/content/bindings/datetimebox.xml#time-input"); } +input[type="date"] > xul|datetimebox { + display: flex; + -moz-binding: url("chrome://global/content/bindings/datetimebox.xml#date-input"); +} + /* details & summary */ /* Need to revert Bug 1259889 Part 2 when removing details preference. */ @supports -moz-bool-pref("dom.details_element.enabled") { diff --git a/layout/style/test/chrome/bug418986-2.js b/layout/style/test/chrome/bug418986-2.js index 4336f4abd..b083f48ee 100644 --- a/layout/style/test/chrome/bug418986-2.js +++ b/layout/style/test/chrome/bug418986-2.js @@ -53,8 +53,6 @@ var suppressed_toggles = [ // Possible values for '-moz-os-version' var windows_versions = [ - "windows-xp", - "windows-vista", "windows-win7", "windows-win8", "windows-win10", diff --git a/layout/style/test/mochitest.ini b/layout/style/test/mochitest.ini index 406c6f901..8182691ca 100644 --- a/layout/style/test/mochitest.ini +++ b/layout/style/test/mochitest.ini @@ -295,6 +295,7 @@ skip-if = toolkit == 'android' [test_variables.html] support-files = support/external-variable-url.css [test_video_object_fit.html] +[test_viewport_scrollbar_causing_reflow.html] [test_viewport_units.html] [test_visited_image_loading.html] skip-if = toolkit == 'android' #TIMED_OUT diff --git a/layout/style/test/property_database.js b/layout/style/test/property_database.js index 9c69e7d10..62d413d98 100644 --- a/layout/style/test/property_database.js +++ b/layout/style/test/property_database.js @@ -132,6 +132,9 @@ var validGradientAndElementValues = [ "linear-gradient(to right bottom, red, 50%, green 50%, 50%, blue)", "linear-gradient(to right bottom, red, 0%, green 50%, 100%, blue)", + /* Unitless 0 is valid as an <angle> */ + "linear-gradient(0, red, blue)", + "-moz-linear-gradient(red, blue)", "-moz-linear-gradient(red, yellow, blue)", "-moz-linear-gradient(red 1px, yellow 20%, blue 24em, green)", @@ -388,10 +391,8 @@ var invalidGradientAndElementValues = [ "-moz-linear-gradient(10 10px -45deg, red, blue) repeat", "-moz-linear-gradient(10px 10 -45deg, red, blue) repeat", "linear-gradient(red -99, yellow, green, blue 120%)", - /* Unitless 0 is invalid as an <angle> */ - "-moz-linear-gradient(top left 0, red, blue)", - "-moz-linear-gradient(5px 5px 0, red, blue)", - "linear-gradient(0, red, blue)", + /* Unitless nonzero numbers are valid as an <angle> */ + "linear-gradient(30, red, blue)", /* Invalid color, calc() or -moz-image-rect() function */ "linear-gradient(red, rgb(0, rubbish, 0) 50%, red)", "linear-gradient(red, red calc(50% + rubbish), red)", @@ -6270,6 +6271,7 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) { "repeat(auto-fill,minmax(1%,auto))", "repeat(auto-fill,minmax(1em,min-content)) minmax(min-content,0)", "repeat(auto-fill,minmax(max-content,1mm))", + "repeat(2, fit-content(1px))", "fit-content(1px) 1fr", "[a] fit-content(calc(1px - 99%)) [b]", "[a] fit-content(10%) [b c] fit-content(1em)", @@ -6314,6 +6316,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) { "repeat(1, repeat(1, 20px))", "repeat(auto-fill, auto)", "repeat(auto-fit,auto)", + "repeat(auto-fill, fit-content(1px))", + "repeat(auto-fit, fit-content(1px))", "repeat(auto-fit,[])", "repeat(auto-fill, 0) repeat(auto-fit, 0) ", "repeat(auto-fit, 0) repeat(auto-fill, 0) ", @@ -6335,6 +6339,8 @@ if (IsCSSPropertyPrefEnabled("layout.css.grid.enabled")) { "fit-content(-1px)", "fit-content(auto)", "fit-content(min-content)", + "fit-content(1px) repeat(auto-fit, 1px)", + "fit-content(1px) repeat(auto-fill, 1px)", ], unbalanced_values: [ "(foo] 40px", diff --git a/layout/style/test/test_dynamic_change_causing_reflow.html b/layout/style/test/test_dynamic_change_causing_reflow.html index a941191f6..a5bb3045c 100644 --- a/layout/style/test/test_dynamic_change_causing_reflow.html +++ b/layout/style/test/test_dynamic_change_causing_reflow.html @@ -95,6 +95,90 @@ const gTestcases = [ expectReflow: true, }, + // * Changing 'overflow' on <body> should cause reflow, + // but not frame reconstruction + { + elem: document.body, + /* beforeStyle: implicitly 'overflow:visible' */ + afterStyle: "overflow: hidden", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + /* beforeStyle: implicitly 'overflow:visible' */ + afterStyle: "overflow: scroll", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + beforeStyle: "overflow: hidden", + afterStyle: "overflow: auto", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + beforeStyle: "overflow: hidden", + afterStyle: "overflow: scroll", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + beforeStyle: "overflow: hidden", + afterStyle: "overflow: visible", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + beforeStyle: "overflow: auto", + afterStyle: "overflow: hidden", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.body, + beforeStyle: "overflow: visible", + afterStyle: "overflow: hidden", + expectConstruction: false, + expectReflow: true, + }, + + // * Changing 'overflow' on <html> should cause reflow, + // but not frame reconstruction + { + elem: document.documentElement, + /* beforeStyle: implicitly 'overflow:visible' */ + afterStyle: "overflow: auto", + expectConstruction: false, + expectReflow: true, + }, + { + elem: document.documentElement, + beforeStyle: "overflow: visible", + afterStyle: "overflow: auto", + expectConstruction: false, + expectReflow: true, + }, + + // * Setting 'overflow' on arbitrary node should cause reflow as well as + // frame reconstruction + { + /* beforeStyle: implicitly 'overflow:visible' */ + afterStyle: "overflow: auto", + expectConstruction: true, + expectReflow: true, + }, + { + beforeStyle: "overflow: auto", + afterStyle: "overflow: visible", + expectConstruction: true, + expectReflow: true, + }, + // * Changing 'display' should cause frame construction and reflow. { beforeStyle: "display: inline", @@ -135,23 +219,34 @@ function runOneTest(aTestcase) return; } + // Figure out which element we'll be tweaking (defaulting to gElem) + let elem = aTestcase.elem ? + aTestcase.elem : gElem; + + // Verify that 'style' attribute is unset (avoid causing ourselves trouble): + if (elem.hasAttribute("style")) { + ok(false, + "test element has 'style' attribute already set! We're going to stomp " + + "on whatever's there when we clean up..."); + } + // Set the "before" style, and compose the first part of the message // to be used in our "is"/"isnot" invocations: let msgPrefix = "Changing style "; if (aTestcase.beforeStyle) { - gElem.setAttribute("style", aTestcase.beforeStyle); + elem.setAttribute("style", aTestcase.beforeStyle); msgPrefix += "from '" + aTestcase.beforeStyle + "' "; } - msgPrefix += "to '" + aTestcase.afterStyle + "' "; + msgPrefix += "on " + elem.nodeName + " "; // Establish initial counts: - let unusedVal = gElem.offsetHeight; // flush layout + let unusedVal = elem.offsetHeight; // flush layout let origFramesConstructed = gUtils.framesConstructed; let origFramesReflowed = gUtils.framesReflowed; // Make the change and flush: - gElem.setAttribute("style", aTestcase.afterStyle); - unusedVal = gElem.offsetHeight; // flush layout + elem.setAttribute("style", aTestcase.afterStyle); + unusedVal = elem.offsetHeight; // flush layout // Make our is/isnot assertions about whether things should have changed: checkFinalCount(gUtils.framesConstructed, origFramesConstructed, @@ -162,7 +257,7 @@ function runOneTest(aTestcase) "reflow"); // Clean up! - gElem.removeAttribute("style"); + elem.removeAttribute("style"); } gTestcases.forEach(runOneTest); diff --git a/layout/style/test/test_media_queries.html b/layout/style/test/test_media_queries.html index 1edac15ae..d503fad0b 100644 --- a/layout/style/test/test_media_queries.html +++ b/layout/style/test/test_media_queries.html @@ -628,6 +628,7 @@ function run() { expression_should_be_parseable("-moz-windows-default-theme"); expression_should_be_parseable("-moz-mac-graphite-theme"); expression_should_be_parseable("-moz-mac-yosemite-theme"); + expression_should_be_parseable("-moz-windows-accent-color-applies"); expression_should_be_parseable("-moz-windows-compositor"); expression_should_be_parseable("-moz-windows-classic"); expression_should_be_parseable("-moz-windows-glass"); @@ -643,6 +644,7 @@ function run() { expression_should_be_parseable("-moz-windows-default-theme: 0"); expression_should_be_parseable("-moz-mac-graphite-theme: 0"); expression_should_be_parseable("-moz-mac-yosemite-theme: 0"); + expression_should_be_parseable("-moz-windows-accent-color-applies: 0"); expression_should_be_parseable("-moz-windows-compositor: 0"); expression_should_be_parseable("-moz-windows-classic: 0"); expression_should_be_parseable("-moz-windows-glass: 0"); @@ -658,6 +660,7 @@ function run() { expression_should_be_parseable("-moz-windows-default-theme: 1"); expression_should_be_parseable("-moz-mac-graphite-theme: 1"); expression_should_be_parseable("-moz-mac-yosemite-theme: 1"); + expression_should_be_parseable("-moz-windows-accent-color-applies: 1"); expression_should_be_parseable("-moz-windows-compositor: 1"); expression_should_be_parseable("-moz-windows-classic: 1"); expression_should_be_parseable("-moz-windows-glass: 1"); @@ -673,6 +676,7 @@ function run() { expression_should_not_be_parseable("-moz-windows-default-theme: -1"); expression_should_not_be_parseable("-moz-mac-graphite-theme: -1"); expression_should_not_be_parseable("-moz-mac-yosemite-theme: -1"); + expression_should_not_be_parseable("-moz-windows-accent-color-applies: -1"); expression_should_not_be_parseable("-moz-windows-compositor: -1"); expression_should_not_be_parseable("-moz-windows-classic: -1"); expression_should_not_be_parseable("-moz-windows-glass: -1"); @@ -688,6 +692,7 @@ function run() { expression_should_not_be_parseable("-moz-windows-default-theme: true"); expression_should_not_be_parseable("-moz-mac-graphite-theme: true"); expression_should_not_be_parseable("-moz-mac-yosemite-theme: true"); + expression_should_not_be_parseable("-moz-windows-accent-color-applies: true"); expression_should_not_be_parseable("-moz-windows-compositor: true"); expression_should_not_be_parseable("-moz-windows-classic: true"); expression_should_not_be_parseable("-moz-windows-glass: true"); @@ -708,8 +713,6 @@ function run() { expression_should_not_be_parseable("-moz-windows-theme: "); // os version media queries (currently windows only) - expression_should_be_parseable("-moz-os-version: windows-xp"); - expression_should_be_parseable("-moz-os-version: windows-vista"); expression_should_be_parseable("-moz-os-version: windows-win7"); expression_should_be_parseable("-moz-os-version: windows-win8"); expression_should_be_parseable("-moz-os-version: windows-win10"); diff --git a/layout/style/test/test_viewport_scrollbar_causing_reflow.html b/layout/style/test/test_viewport_scrollbar_causing_reflow.html new file mode 100644 index 000000000..dfd7ec450 --- /dev/null +++ b/layout/style/test/test_viewport_scrollbar_causing_reflow.html @@ -0,0 +1,125 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=1367568 +--> +<head> + <meta charset="utf-8"> + <title>Test for Bug 1367568</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=">Mozilla Bug 1367568</a> +<div id="content"> + <!-- Some fixed-width divs that we shouldn't have to reflow when the viewport + changes: --> + <div style="width: 100px"> + fixed-width + <div>(child)</div> + </div> + <div style="position: absolute; width: 150px"> + abs-fixed-width + <div>(child)</div> + </div> +</div> +<pre id="test"> +<script type="application/javascript"> +"use strict"; + +/** Test for Bug 1367568 **/ + +/** + * This test verifies that "overflow" changes on the <body> don't cause + * an unnecessarily large amount of reflow. + */ + +// Vars used in setStyleAndMeasure that we really only have to look up once: +const gUtils = SpecialPowers.getDOMWindowUtils(window); + +function setStyleAndMeasure(initialStyle, finalStyle) { + is(document.body.style.length, 0, + "Bug in test - body should start with empty style"); + let unusedVal = document.body.offsetHeight; // flush layout + let constructCount = gUtils.framesConstructed; + + document.body.style = initialStyle; + unusedVal = document.body.offsetHeight; // flush layout + let reflowCountBeforeTweak = gUtils.framesReflowed; + + document.body.style = finalStyle; + unusedVal = document.body.offsetHeight; // flush layout + let reflowCountAfterTweak = gUtils.framesReflowed; + + // Clean up: + document.body.style = ""; + + is(gUtils.framesConstructed, constructCount, + "Style tweak shouldn't have triggered frame construction"); + + // ...and return the delta: + return reflowCountAfterTweak - reflowCountBeforeTweak; +} + +function main() { + // First, we sanity-check that our measurement make sense -- if we leave + // styles unchanged, we should measure no frames being reflowed: + let count = setStyleAndMeasure("width: 50px; height: 80px", + "width: 50px; height: 80px"); + is(count, 0, + "Shouldn't reflow anything when we leave 'width' & 'height' unchanged"); + + // Now: see how many frames are reflowed when the "width" & "height" change. + // We'll use this as the reference when measuring reflow counts for various + // changes to "overflow" below. + count = setStyleAndMeasure("width: 50px; height: 80px", + "width: 90px; height: 60px"); + ok(count > 0, + "Should reflow some frames when 'width' & 'height' change"); + + // Expected maximum number of frames reflowed for "overflow" changes + // (+2 is to allow for reflowing scrollbars themselves): + const expectedMax = count + 2; + + // Shared ending for messages in all ok() checks below: + const messageSuffix = + " shouldn't be greater than count for tweaking width/height on body (" + + expectedMax + ")"; + + // OK, here is where the relevant tests actually begin!! + // See how many frames we reflow for various tweaks to "overflow" on + // the body -- we expect the count to be no larger than |expectedMax|. + count = setStyleAndMeasure("", "overflow: scroll"); + ok(count <= expectedMax, + "Reflow count when setting 'overflow: scroll' on body (" + count + ")" + + messageSuffix); + + count = setStyleAndMeasure("", "overflow: hidden"); + ok(count <= expectedMax, + "Reflow count when setting 'overflow: hidden' on body (" + count + ")" + + messageSuffix); + + // Test removal of "overflow: scroll": + count = setStyleAndMeasure("overflow: scroll", ""); + ok(count <= expectedMax, + "Reflow count when removing 'overflow: scroll' from body (" + count + ")" + + messageSuffix); + + count = setStyleAndMeasure("overflow: hidden", ""); + ok(count <= expectedMax, + "Reflow count when removing 'overflow: hidden' from body (" + count + ")" + + messageSuffix); + + // Test change between two non-'visible' overflow values: + count = setStyleAndMeasure("overflow: scroll", "overflow: hidden"); + ok(count <= expectedMax, + "Reflow count when changing 'overflow' on body (" + count + ")" + + messageSuffix); +} + +main(); + +</script> +</pre> +</body> +</html> diff --git a/layout/svg/SVGTextFrame.cpp b/layout/svg/SVGTextFrame.cpp index e68126068..e5a03333f 100644 --- a/layout/svg/SVGTextFrame.cpp +++ b/layout/svg/SVGTextFrame.cpp @@ -5111,8 +5111,8 @@ SVGTextFrame::DoGlyphPositioning() float actualTextLength = static_cast<float>(presContext->AppUnitsToGfxUnits(frameLength) * factor); - RefPtr<SVGAnimatedEnumeration> lengthAdjustEnum = element->LengthAdjust(); - uint16_t lengthAdjust = lengthAdjustEnum->AnimVal(); + uint16_t lengthAdjust = + element->EnumAttributes()[SVGTextContentElement::LENGTHADJUST].GetAnimValue(); switch (lengthAdjust) { case SVG_LENGTHADJUST_SPACINGANDGLYPHS: // Scale the glyphs and their positions. diff --git a/layout/svg/nsSVGGradientFrame.cpp b/layout/svg/nsSVGGradientFrame.cpp index 217ab8c4a..2d7684f5a 100644 --- a/layout/svg/nsSVGGradientFrame.cpp +++ b/layout/svg/nsSVGGradientFrame.cpp @@ -623,7 +623,7 @@ nsSVGRadialGradientFrame::GradientVectorLengthIsZero() already_AddRefed<gfxPattern> nsSVGRadialGradientFrame::CreateGradient() { - float cx, cy, r, fx, fy; + float cx, cy, r, fx, fy, fr; cx = GetLengthValue(dom::SVGRadialGradientElement::ATTR_CX); cy = GetLengthValue(dom::SVGRadialGradientElement::ATTR_CY); @@ -631,6 +631,7 @@ nsSVGRadialGradientFrame::CreateGradient() // If fx or fy are not set, use cx/cy instead fx = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FX, cx); fy = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FY, cy); + fr = GetLengthValue(dom::SVGRadialGradientElement::ATTR_FR); if (fx != cx || fy != cy) { // The focal point (fFx and fFy) must be clamped to be *inside* - not on - @@ -651,7 +652,7 @@ nsSVGRadialGradientFrame::CreateGradient() } } - RefPtr<gfxPattern> pattern = new gfxPattern(fx, fy, 0, cx, cy, r); + RefPtr<gfxPattern> pattern = new gfxPattern(fx, fy, fr, cx, cy, r); return pattern.forget(); } diff --git a/layout/svg/nsSVGUtils.cpp b/layout/svg/nsSVGUtils.cpp index ff74d5baf..344ebf645 100644 --- a/layout/svg/nsSVGUtils.cpp +++ b/layout/svg/nsSVGUtils.cpp @@ -1127,8 +1127,7 @@ nsSVGUtils::GetBBox(nsIFrame *aFrame, uint32_t aFlags) if (clipPathFrame && isOK) { SVGClipPathElement *clipContent = static_cast<SVGClipPathElement*>(clipPathFrame->GetContent()); - RefPtr<SVGAnimatedEnumeration> units = clipContent->ClipPathUnits(); - if (units->AnimVal() == SVG_UNIT_TYPE_OBJECTBOUNDINGBOX) { + if (clipContent->IsUnitsObjectBoundingBox()) { matrix.Translate(gfxPoint(x, y)); matrix.Scale(width, height); } else if (aFrame->GetType() == nsGkAtoms::svgForeignObjectFrame) { diff --git a/layout/tools/recording/recording-cmdline.js b/layout/tools/recording/recording-cmdline.js index e043aa29c..0f127bbd5 100644 --- a/layout/tools/recording/recording-cmdline.js +++ b/layout/tools/recording/recording-cmdline.js @@ -67,8 +67,8 @@ RecordingCmdLineHandler.prototype = cmdLine.preventDefault = true; }, - helpInfo : " --recording <file> Record drawing for a given URL.\n" + - " --recording-output <file> Specify destination file for a drawing recording.\n" + helpInfo : " --recording <file> Record drawing for a given URL.\n" + + " --recording-output <file> Specify destination file for a drawing recording.\n" }; this.NSGetFactory = XPCOMUtils.generateNSGetFactory([RecordingCmdLineHandler]); |