# HG changeset patch # User Corey Ford # Date 1376017164 25200 # Thu Aug 08 19:59:24 2013 -0700 # Node ID 6c8980cb64f36b014aedce57626c1e3489318bf0 # Parent d5ad4f4a50408190e2298827461d80f4b25aa5f4 Bug 886646 - Part 3: Compute sticky positioning offsets for getComputedStyle(). r=heycam diff --git a/layout/style/nsComputedDOMStyle.cpp b/layout/style/nsComputedDOMStyle.cpp --- a/layout/style/nsComputedDOMStyle.cpp +++ b/layout/style/nsComputedDOMStyle.cpp @@ -3673,16 +3673,18 @@ nsComputedDOMStyle::GetOffsetWidthFor(mo position = NS_STYLE_POSITION_STATIC; } switch (position) { case NS_STYLE_POSITION_STATIC: return GetStaticOffset(aSide); case NS_STYLE_POSITION_RELATIVE: return GetRelativeOffset(aSide); + case NS_STYLE_POSITION_STICKY: + return GetStickyOffset(aSide); case NS_STYLE_POSITION_ABSOLUTE: case NS_STYLE_POSITION_FIXED: return GetAbsoluteOffset(aSide); default: NS_ERROR("Invalid position"); return nullptr; } } @@ -3774,16 +3776,46 @@ nsComputedDOMStyle::GetRelativeOffset(mo baseGetter = &nsComputedDOMStyle::GetCBContentHeight; } val->SetAppUnits(sign * StyleCoordToNSCoord(coord, baseGetter, 0, false)); return val; } CSSValue* +nsComputedDOMStyle::GetStickyOffset(mozilla::css::Side aSide) +{ + nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; + + const nsStylePosition* positionData = StylePosition(); + nsStyleCoord coord = positionData->mOffset.Get(aSide); + + NS_ASSERTION(coord.GetUnit() == eStyleUnit_Coord || + coord.GetUnit() == eStyleUnit_Percent || + coord.GetUnit() == eStyleUnit_Auto || + coord.IsCalcUnit(), + "Unexpected unit"); + + if (coord.GetUnit() == eStyleUnit_Auto) { + val->SetIdent(eCSSKeyword_auto); + return val; + } + PercentageBaseGetter baseGetter; + if (aSide == NS_SIDE_LEFT || aSide == NS_SIDE_RIGHT) { + baseGetter = &nsComputedDOMStyle::GetScrollFrameContentWidth; + } else { + baseGetter = &nsComputedDOMStyle::GetScrollFrameContentHeight; + } + + val->SetAppUnits(StyleCoordToNSCoord(coord, baseGetter, 0, false)); + return val; +} + + +CSSValue* nsComputedDOMStyle::GetStaticOffset(mozilla::css::Side aSide) { nsROCSSPrimitiveValue *val = new nsROCSSPrimitiveValue; SetValueToCoord(val, StylePosition()->mOffset.Get(aSide), false); return val; } @@ -4092,16 +4124,60 @@ nsComputedDOMStyle::GetCBContentHeight(n AssertFlushedPendingReflows(); nsIFrame* container = mOuterFrame->GetContainingBlock(); aHeight = container->GetContentRect().height; return true; } bool +nsComputedDOMStyle::GetScrollFrameContentWidth(nscoord& aWidth) +{ + if (!mOuterFrame) { + return false; + } + + AssertFlushedPendingReflows(); + + nsIScrollableFrame* scrollableFrame = + nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame, + nsLayoutUtils::SCROLLABLE_SAME_DOC | + nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); + + if (!scrollableFrame) { + return false; + } + aWidth = + scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().width; + return true; +} + +bool +nsComputedDOMStyle::GetScrollFrameContentHeight(nscoord& aHeight) +{ + if (!mOuterFrame) { + return false; + } + + AssertFlushedPendingReflows(); + + nsIScrollableFrame* scrollableFrame = + nsLayoutUtils::GetNearestScrollableFrame(mOuterFrame, + nsLayoutUtils::SCROLLABLE_SAME_DOC | + nsLayoutUtils::SCROLLABLE_INCLUDE_HIDDEN); + + if (!scrollableFrame) { + return false; + } + aHeight = + scrollableFrame->GetScrolledFrame()->GetContentRectRelativeToSelf().height; + return true; +} + +bool nsComputedDOMStyle::GetFrameBorderRectWidth(nscoord& aWidth) { if (!mInnerFrame) { return false; } AssertFlushedPendingReflows(); diff --git a/layout/style/nsComputedDOMStyle.h b/layout/style/nsComputedDOMStyle.h --- a/layout/style/nsComputedDOMStyle.h +++ b/layout/style/nsComputedDOMStyle.h @@ -119,16 +119,18 @@ private: bool aIsBorder); // else outline mozilla::dom::CSSValue* GetOffsetWidthFor(mozilla::css::Side aSide); mozilla::dom::CSSValue* GetAbsoluteOffset(mozilla::css::Side aSide); mozilla::dom::CSSValue* GetRelativeOffset(mozilla::css::Side aSide); + mozilla::dom::CSSValue* GetStickyOffset(mozilla::css::Side aSide); + mozilla::dom::CSSValue* GetStaticOffset(mozilla::css::Side aSide); mozilla::dom::CSSValue* GetPaddingWidthFor(mozilla::css::Side aSide); mozilla::dom::CSSValue* GetBorderColorsFor(mozilla::css::Side aSide); mozilla::dom::CSSValue* GetBorderStyleFor(mozilla::css::Side aSide); @@ -483,16 +485,18 @@ private: */ nscoord StyleCoordToNSCoord(const nsStyleCoord& aCoord, PercentageBaseGetter aPercentageBaseGetter, nscoord aDefaultValue, bool aClampNegativeCalc); bool GetCBContentWidth(nscoord& aWidth); bool GetCBContentHeight(nscoord& aWidth); + bool GetScrollFrameContentWidth(nscoord& aWidth); + bool GetScrollFrameContentHeight(nscoord& aHeight); bool GetFrameBoundsWidthForTransform(nscoord &aWidth); bool GetFrameBoundsHeightForTransform(nscoord &aHeight); bool GetFrameBorderRectWidth(nscoord& aWidth); bool GetFrameBorderRectHeight(nscoord& aHeight); /* Helper functions for computing the filter property style. */ void SetCssTextToCoord(nsAString& aCssText, const nsStyleCoord& aCoord); mozilla::dom::CSSValue* CreatePrimitiveValueForStyleFilter( diff --git a/layout/style/test/Makefile.in b/layout/style/test/Makefile.in --- a/layout/style/test/Makefile.in +++ b/layout/style/test/Makefile.in @@ -140,16 +140,18 @@ MOCHITEST_FILES = test_acid3_test46.html test_of_type_selectors.xhtml \ test_parse_eof.html \ test_parse_ident.html \ test_parse_rule.html \ test_parse_url.html \ test_parser_diagnostics_unprintables.html \ test_pixel_lengths.html \ test_pointer-events.html \ + file_position_sticky.html \ + test_position_sticky.html \ test_property_database.html \ test_priority_preservation.html \ test_property_syntax_errors.html \ test_rem_unit.html \ test_rule_insertion.html \ test_rule_serialization.html \ test_rules_out_of_sheets.html \ test_selectors.html \ diff --git a/layout/style/test/file_position_sticky.html b/layout/style/test/file_position_sticky.html new file mode 100644 --- /dev/null +++ b/layout/style/test/file_position_sticky.html @@ -0,0 +1,81 @@ + + + + + + + + + +
+
+
+
+
+
+
+
+
+
+ + diff --git a/layout/style/test/test_position_sticky.html b/layout/style/test/test_position_sticky.html new file mode 100644 --- /dev/null +++ b/layout/style/test/test_position_sticky.html @@ -0,0 +1,42 @@ + + + + + + Test for Bug 886646 + + + + +Mozilla Bug 886646 +
+ +
+
+
+
+ +