зеркало из https://github.com/mozilla/gecko-dev.git
Bug 1531609 part 2 - Implement overflow:clip/visible combinations. r=emilio
Differential Revision: https://phabricator.services.mozilla.com/D73717
This commit is contained in:
Родитель
92b8f0f77a
Коммит
c875610606
|
@ -9,8 +9,34 @@
|
|||
|
||||
namespace mozilla {
|
||||
|
||||
ScrollStyles::ScrollStyles(const nsStyleDisplay& aDisplay)
|
||||
: mHorizontal(aDisplay.mOverflowX), mVertical(aDisplay.mOverflowY) {}
|
||||
// https://drafts.csswg.org/css-overflow/#overflow-propagation
|
||||
// "If `visible` is applied to the viewport, it must be interpreted as `auto`.
|
||||
// If `clip` is applied to the viewport, it must be interpreted as `hidden`."
|
||||
static StyleOverflow MapOverflowValueForViewportPropagation(StyleOverflow aOverflow) {
|
||||
switch (aOverflow) {
|
||||
case StyleOverflow::Visible:
|
||||
return StyleOverflow::Auto;
|
||||
case StyleOverflow::Clip:
|
||||
return StyleOverflow::Hidden;
|
||||
default:
|
||||
return aOverflow;
|
||||
}
|
||||
}
|
||||
|
||||
ScrollStyles::ScrollStyles(StyleOverflow aH, StyleOverflow aV)
|
||||
: mHorizontal(aH), mVertical(aV) {
|
||||
MOZ_ASSERT(mHorizontal == StyleOverflow::Auto ||
|
||||
mHorizontal == StyleOverflow::Hidden ||
|
||||
mHorizontal == StyleOverflow::Scroll);
|
||||
MOZ_ASSERT(mVertical == StyleOverflow::Auto ||
|
||||
mVertical == StyleOverflow::Hidden ||
|
||||
mVertical == StyleOverflow::Scroll);
|
||||
}
|
||||
|
||||
ScrollStyles::ScrollStyles(const nsStyleDisplay& aDisplay,
|
||||
MapOverflowToValidScrollStyleTag)
|
||||
: ScrollStyles(MapOverflowValueForViewportPropagation(aDisplay.mOverflowX),
|
||||
MapOverflowValueForViewportPropagation(aDisplay.mOverflowY)) {}
|
||||
|
||||
bool ScrollStyles::IsHiddenInBothDirections() const {
|
||||
return mHorizontal == StyleOverflow::Hidden &&
|
||||
|
|
|
@ -8,7 +8,6 @@
|
|||
#define mozilla_ScrollStyles_h
|
||||
|
||||
#include <stdint.h>
|
||||
#include "mozilla/dom/WindowBinding.h"
|
||||
|
||||
// Forward declarations
|
||||
struct nsStyleDisplay;
|
||||
|
@ -17,17 +16,20 @@ namespace mozilla {
|
|||
|
||||
enum class StyleOverflow : uint8_t;
|
||||
|
||||
// NOTE: Only styles that are propagated from the <body> should end up in this
|
||||
// class.
|
||||
struct ScrollStyles {
|
||||
// Always one of Scroll, Hidden, or Auto
|
||||
// Always one of Scroll, Hidden, or Auto.
|
||||
StyleOverflow mHorizontal;
|
||||
StyleOverflow mVertical;
|
||||
|
||||
ScrollStyles(StyleOverflow aH, StyleOverflow aV)
|
||||
: mHorizontal(aH), mVertical(aV) {}
|
||||
ScrollStyles(StyleOverflow aH, StyleOverflow aV);
|
||||
|
||||
// NOTE: This ctor maps `visible` to `auto` and `clip` to `hidden`.
|
||||
// It's used for styles that are propagated from the <body> and for
|
||||
// scroll frames (which we create also for overflow:clip/visible in
|
||||
// some cases, e.g. form controls).
|
||||
enum MapOverflowToValidScrollStyleTag { MapOverflowToValidScrollStyle };
|
||||
ScrollStyles(const nsStyleDisplay&, MapOverflowToValidScrollStyleTag);
|
||||
|
||||
explicit ScrollStyles(const nsStyleDisplay&);
|
||||
bool operator==(const ScrollStyles& aStyles) const {
|
||||
return aStyles.mHorizontal == mHorizontal && aStyles.mVertical == mVertical;
|
||||
}
|
||||
|
|
|
@ -1085,16 +1085,12 @@ static bool CheckOverflow(const ComputedStyle* aComputedStyle,
|
|||
return false;
|
||||
}
|
||||
|
||||
if (display->mOverflowX == StyleOverflow::Visible) {
|
||||
MOZ_ASSERT(display->mOverflowY == StyleOverflow::Visible);
|
||||
if (display->mOverflowX == StyleOverflow::Visible &&
|
||||
display->mOverflowY == StyleOverflow::Visible) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (display->mOverflowX == StyleOverflow::Clip) {
|
||||
*aStyles = ScrollStyles(StyleOverflow::Hidden, StyleOverflow::Hidden);
|
||||
} else {
|
||||
*aStyles = ScrollStyles(*display);
|
||||
}
|
||||
*aStyles = ScrollStyles(*display, ScrollStyles::MapOverflowToValidScrollStyle);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,21 @@
|
|||
#ifndef nsPresContext_h___
|
||||
#define nsPresContext_h___
|
||||
|
||||
#include "mozilla/AppUnits.h"
|
||||
#include "mozilla/Attributes.h"
|
||||
#include "mozilla/EnumeratedArray.h"
|
||||
#include "mozilla/MediaEmulationData.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/NotNull.h"
|
||||
#include "mozilla/ScrollStyles.h"
|
||||
#include "mozilla/PreferenceSheet.h"
|
||||
#include "mozilla/PresShellForwards.h"
|
||||
#include "mozilla/ScrollStyles.h"
|
||||
#include "mozilla/ServoStyleSet.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/UniquePtr.h"
|
||||
#include "mozilla/WeakPtr.h"
|
||||
#include "nsColor.h"
|
||||
#include "nsCompatibility.h"
|
||||
#include "nsCoord.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsRect.h"
|
||||
|
@ -32,11 +39,6 @@
|
|||
#include "gfxTypes.h"
|
||||
#include "gfxRect.h"
|
||||
#include "nsTArray.h"
|
||||
#include "mozilla/MemoryReporting.h"
|
||||
#include "mozilla/TimeStamp.h"
|
||||
#include "mozilla/AppUnits.h"
|
||||
#include "mozilla/MediaEmulationData.h"
|
||||
#include "mozilla/PresShellForwards.h"
|
||||
#include "prclist.h"
|
||||
#include "nsThreadUtils.h"
|
||||
#include "Units.h"
|
||||
|
@ -131,6 +133,8 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||
using Encoding = mozilla::Encoding;
|
||||
template <typename T>
|
||||
using NotNull = mozilla::NotNull<T>;
|
||||
template <typename T>
|
||||
using Maybe = mozilla::Maybe<T>;
|
||||
using MediaEmulationData = mozilla::MediaEmulationData;
|
||||
using StylePrefersColorScheme = mozilla::StylePrefersColorScheme;
|
||||
|
||||
|
@ -1220,7 +1224,7 @@ class nsPresContext : public nsISupports, public mozilla::SupportsWeakPtr {
|
|||
|
||||
mozilla::TimeStamp mReflowStartTime;
|
||||
|
||||
mozilla::Maybe<TransactionId> mFirstContentfulPaintTransactionId;
|
||||
Maybe<TransactionId> mFirstContentfulPaintTransactionId;
|
||||
|
||||
mozilla::UniquePtr<mozilla::MediaFeatureChange>
|
||||
mPendingMediaFeatureValuesChange;
|
||||
|
|
|
@ -1254,9 +1254,12 @@ void nsBlockFrame::Reflow(nsPresContext* aPresContext, ReflowOutput& aMetrics,
|
|||
Maybe<ReflowInput> mutableReflowInput;
|
||||
// If we have non-auto block size, we're clipping our kids and we fit,
|
||||
// make sure our kids fit too.
|
||||
const PhysicalAxes physicalBlockAxis =
|
||||
wm.IsVertical() ? PhysicalAxes::Horizontal : PhysicalAxes::Vertical;
|
||||
if (aReflowInput.AvailableBSize() != NS_UNCONSTRAINEDSIZE &&
|
||||
aReflowInput.ComputedBSize() != NS_UNCONSTRAINEDSIZE &&
|
||||
ShouldApplyOverflowClipping(aReflowInput.mStyleDisplay)) {
|
||||
(ShouldApplyOverflowClipping(aReflowInput.mStyleDisplay) &
|
||||
physicalBlockAxis)) {
|
||||
LogicalMargin blockDirExtras = aReflowInput.ComputedLogicalBorderPadding();
|
||||
if (GetLogicalSkipSides().BStart()) {
|
||||
blockDirExtras.BStart(wm) = 0;
|
||||
|
@ -2042,7 +2045,7 @@ void nsBlockFrame::ComputeOverflowAreas(const nsRect& aBounds,
|
|||
// XXX_perf: This can be done incrementally. It is currently one of
|
||||
// the things that makes incremental reflow O(N^2).
|
||||
nsOverflowAreas areas(aBounds, aBounds);
|
||||
if (!ShouldApplyOverflowClipping(aDisplay)) {
|
||||
if (ShouldApplyOverflowClipping(aDisplay) != PhysicalAxes::Both) {
|
||||
for (const auto& line : Lines()) {
|
||||
if (aDisplay->IsContainLayout()) {
|
||||
// If we have layout containment, we should only consider our child's
|
||||
|
|
|
@ -4314,7 +4314,8 @@ ScrollStyles ScrollFrameHelper::GetScrollStylesFromFrame() const {
|
|||
}
|
||||
|
||||
if (!mIsRoot) {
|
||||
return ScrollStyles(*mOuter->StyleDisplay());
|
||||
return ScrollStyles(*mOuter->StyleDisplay(),
|
||||
ScrollStyles::MapOverflowToValidScrollStyle);
|
||||
}
|
||||
|
||||
ScrollStyles result = presContext->GetViewportScrollStylesOverride();
|
||||
|
|
|
@ -854,7 +854,7 @@ class nsHTMLScrollFrame : public nsContainerFrame,
|
|||
return mHelper.GetScrolledFrame()->GetContentInsertionFrame();
|
||||
}
|
||||
|
||||
bool DoesClipChildren() final { return true; }
|
||||
bool DoesClipChildrenInBothAxes() final { return true; }
|
||||
|
||||
nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) final {
|
||||
nsPoint pt = aChild->GetPosition();
|
||||
|
@ -1298,7 +1298,7 @@ class nsXULScrollFrame final : public nsBoxFrame,
|
|||
return mHelper.GetScrolledFrame()->GetContentInsertionFrame();
|
||||
}
|
||||
|
||||
bool DoesClipChildren() final { return true; }
|
||||
bool DoesClipChildrenInBothAxes() final { return true; }
|
||||
|
||||
nsPoint GetPositionOfChildIgnoringScrolling(const nsIFrame* aChild) final {
|
||||
nsPoint pt = aChild->GetPosition();
|
||||
|
|
|
@ -1778,7 +1778,7 @@ bool nsIFrame::Extend3DContext(const nsStyleDisplay* aStyleDisplay,
|
|||
return false;
|
||||
}
|
||||
|
||||
return !ShouldApplyOverflowClipping(disp) &&
|
||||
return ShouldApplyOverflowClipping(disp) == PhysicalAxes::None &&
|
||||
!GetClipPropClipRect(disp, effects, GetSize()) &&
|
||||
!SVGIntegrationUtils::UsingEffectsForFrame(this);
|
||||
}
|
||||
|
@ -2653,17 +2653,18 @@ Maybe<nsRect> nsIFrame::GetClipPropClipRect(const nsStyleDisplay* aDisp,
|
|||
* handled by constructing a dedicated nsHTML/XULScrollFrame, set up clipping
|
||||
* for that overflow in aBuilder->ClipState() to clip all containing-block
|
||||
* descendants.
|
||||
*
|
||||
* Return true if clipping was applied.
|
||||
*/
|
||||
static void ApplyOverflowClipping(
|
||||
nsDisplayListBuilder* aBuilder, const nsIFrame* aFrame,
|
||||
nsIFrame::PhysicalAxes aClipAxes,
|
||||
DisplayListClipState::AutoClipMultiple& aClipState) {
|
||||
// Only 'clip' is handled here (and 'hidden' for table frames, and any
|
||||
// non-'visible' value for blocks in a paginated context).
|
||||
// We allow 'clip' to apply to any kind of frame. This is required by
|
||||
// comboboxes which make their display text (an inline frame) have clipping.
|
||||
MOZ_ASSERT(aFrame->ShouldApplyOverflowClipping(aFrame->StyleDisplay()));
|
||||
MOZ_ASSERT(aClipAxes != nsIFrame::PhysicalAxes::None);
|
||||
MOZ_ASSERT(aFrame->ShouldApplyOverflowClipping(aFrame->StyleDisplay()) ==
|
||||
aClipAxes);
|
||||
|
||||
nsRect clipRect;
|
||||
bool haveRadii = false;
|
||||
|
@ -2689,6 +2690,20 @@ static void ApplyOverflowClipping(
|
|||
bp.ApplySkipSides(aFrame->GetSkipSides());
|
||||
nsRect rect(nsPoint(0, 0), aFrame->GetSize());
|
||||
rect.Deflate(bp);
|
||||
if (MOZ_UNLIKELY(!(aClipAxes & nsIFrame::PhysicalAxes::Horizontal))) {
|
||||
// NOTE(mats) We shouldn't be clipping at all in this dimension really,
|
||||
// but clipping in just one axis isn't supported by our GFX APIs so we
|
||||
// clip to our visual overflow rect instead.
|
||||
nsRect o = aFrame->InkOverflowRect();
|
||||
rect.x = o.x;
|
||||
rect.width = o.width;
|
||||
}
|
||||
if (MOZ_UNLIKELY(!(aClipAxes & nsIFrame::PhysicalAxes::Vertical))) {
|
||||
// See the note above.
|
||||
nsRect o = aFrame->InkOverflowRect();
|
||||
rect.y = o.y;
|
||||
rect.height = o.height;
|
||||
}
|
||||
clipRect = rect + aBuilder->ToReferenceFrame(aFrame);
|
||||
haveRadii = aFrame->GetBoxBorderRadii(radii, bp, false);
|
||||
aClipState.ClipContainingBlockDescendantsExtra(clipRect,
|
||||
|
@ -3989,8 +4004,9 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
placeholder ? placeholder->GetOutOfFlowFrame() : child;
|
||||
|
||||
nsIFrame* parent = childOrOutOfFlow->GetParent();
|
||||
const bool shouldApplyOverflowClip =
|
||||
parent->ShouldApplyOverflowClipping(parent->StyleDisplay());
|
||||
const auto* parentDisplay = parent->StyleDisplay();
|
||||
const auto overflowClipAxes =
|
||||
parent->ShouldApplyOverflowClipping(parentDisplay);
|
||||
|
||||
const bool isPaintingToWindow = aBuilder->IsPaintingToWindow();
|
||||
const bool doingShortcut =
|
||||
|
@ -3999,8 +4015,8 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
// Animations may change the stacking context state.
|
||||
// ShouldApplyOverflowClipping is affected by the parent style, which does
|
||||
// not invalidate the NS_FRAME_SIMPLE_DISPLAYLIST bit.
|
||||
!(shouldApplyOverflowClip || child->MayHaveTransformAnimation() ||
|
||||
child->MayHaveOpacityAnimation());
|
||||
!(overflowClipAxes != PhysicalAxes::None ||
|
||||
child->MayHaveTransformAnimation() || child->MayHaveOpacityAnimation());
|
||||
|
||||
if (aBuilder->IsForPainting()) {
|
||||
aBuilder->ClearWillChangeBudgetStatus(child);
|
||||
|
@ -4180,8 +4196,8 @@ void nsIFrame::BuildDisplayListForChild(nsDisplayListBuilder* aBuilder,
|
|||
// FIXME(emilio): Why can't we handle this more similarly to `clip` (on the
|
||||
// parent, rather than on the children)? Would ClipContentDescendants do what
|
||||
// we want?
|
||||
if (shouldApplyOverflowClip) {
|
||||
ApplyOverflowClipping(aBuilder, parent, clipState);
|
||||
if (overflowClipAxes != PhysicalAxes::None) {
|
||||
ApplyOverflowClipping(aBuilder, parent, overflowClipAxes, clipState);
|
||||
awayFromCommonPath = true;
|
||||
}
|
||||
|
||||
|
@ -7381,7 +7397,7 @@ bool nsIFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) {
|
|||
|
||||
/* virtual */
|
||||
void nsIFrame::UnionChildOverflow(nsOverflowAreas& aOverflowAreas) {
|
||||
if (!DoesClipChildren() &&
|
||||
if (!DoesClipChildrenInBothAxes() &&
|
||||
!(IsXULCollapsed() && (IsXULBoxFrame() || ::IsXULBoxWrapped(this)))) {
|
||||
nsLayoutUtils::UnionChildOverflow(this, aOverflowAreas);
|
||||
}
|
||||
|
@ -9021,7 +9037,8 @@ static nsRect UnionBorderBoxes(
|
|||
}
|
||||
const nsStyleDisplay* disp = aFrame->StyleDisplay();
|
||||
LayoutFrameType fType = aFrame->Type();
|
||||
if (aFrame->ShouldApplyOverflowClipping(disp) ||
|
||||
auto overflowClipAxes = aFrame->ShouldApplyOverflowClipping(disp);
|
||||
if (overflowClipAxes == nsIFrame::PhysicalAxes::Both ||
|
||||
fType == LayoutFrameType::Scroll ||
|
||||
fType == LayoutFrameType::ListControl ||
|
||||
fType == LayoutFrameType::SVGOuterSVG) {
|
||||
|
@ -9092,6 +9109,15 @@ static nsRect UnionBorderBoxes(
|
|||
}
|
||||
}
|
||||
|
||||
if (overflowClipAxes & nsIFrame::PhysicalAxes::Vertical) {
|
||||
u.y = bounds.y;
|
||||
u.height = bounds.height;
|
||||
}
|
||||
if (overflowClipAxes & nsIFrame::PhysicalAxes::Horizontal) {
|
||||
u.x = bounds.x;
|
||||
u.width = bounds.width;
|
||||
}
|
||||
|
||||
return u;
|
||||
}
|
||||
|
||||
|
@ -9237,12 +9263,12 @@ bool nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
|
|||
// changed.
|
||||
SetSize(aNewSize, false);
|
||||
|
||||
const bool applyOverflowClipping = ShouldApplyOverflowClipping(disp);
|
||||
const auto overflowClipAxes = ShouldApplyOverflowClipping(disp);
|
||||
|
||||
if (ChildrenHavePerspective(disp) && sizeChanged) {
|
||||
RecomputePerspectiveChildrenOverflow(this);
|
||||
|
||||
if (!applyOverflowClipping) {
|
||||
if (overflowClipAxes != PhysicalAxes::Both) {
|
||||
aOverflowAreas.SetAllTo(bounds);
|
||||
DebugOnly<bool> ok = ComputeCustomOverflow(aOverflowAreas);
|
||||
|
||||
|
@ -9271,16 +9297,25 @@ bool nsIFrame::FinishAndStoreOverflow(nsOverflowAreas& aOverflowAreas,
|
|||
"Computed overflow area must contain frame bounds");
|
||||
}
|
||||
|
||||
// If we clip our children, clear accumulated overflow area. The
|
||||
// children are actually clipped to the padding-box, but since the
|
||||
// overflow area should include the entire border-box, just set it to
|
||||
// the border-box here.
|
||||
NS_ASSERTION((disp->mOverflowY == StyleOverflow::Clip) ==
|
||||
(disp->mOverflowX == StyleOverflow::Clip),
|
||||
"If one overflow is clip, the other should be too");
|
||||
if (applyOverflowClipping) {
|
||||
// The contents are actually clipped to the padding area
|
||||
aOverflowAreas.SetAllTo(bounds);
|
||||
// If we clip our children, clear accumulated overflow area in the affected
|
||||
// dimension(s). The children are actually clipped to the padding-box, but
|
||||
// since the overflow area should include the entire border-box, just set it
|
||||
// to the border-box size here.
|
||||
if (overflowClipAxes != PhysicalAxes::None) {
|
||||
nsRect& ink = aOverflowAreas.InkOverflow();
|
||||
nsRect& scrollable = aOverflowAreas.ScrollableOverflow();
|
||||
if (overflowClipAxes & PhysicalAxes::Vertical) {
|
||||
ink.y = bounds.y;
|
||||
scrollable.y = bounds.y;
|
||||
ink.height = bounds.height;
|
||||
scrollable.height = bounds.height;
|
||||
}
|
||||
if (overflowClipAxes & PhysicalAxes::Horizontal) {
|
||||
ink.x = bounds.x;
|
||||
scrollable.x = bounds.x;
|
||||
ink.width = bounds.width;
|
||||
scrollable.width = bounds.width;
|
||||
}
|
||||
}
|
||||
|
||||
// Overflow area must always include the frame's top-left and bottom-right,
|
||||
|
@ -11020,7 +11055,8 @@ void nsIFrame::UpdateVisibleDescendantsState() {
|
|||
}
|
||||
}
|
||||
|
||||
bool nsIFrame::ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const {
|
||||
nsIFrame::PhysicalAxes nsIFrame::ShouldApplyOverflowClipping(
|
||||
const nsStyleDisplay* aDisp) const {
|
||||
MOZ_ASSERT(aDisp == StyleDisplay(), "Wrong display struct");
|
||||
|
||||
// 'contain:paint', which we handle as 'overflow:clip' here. Except for
|
||||
|
@ -11030,7 +11066,7 @@ bool nsIFrame::ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const {
|
|||
// (e.g. because it forms a fixed-pos containing block).
|
||||
if (aDisp->IsContainPaint() && !IsScrollFrame() &&
|
||||
IsFrameOfType(eSupportsContainLayoutAndPaint)) {
|
||||
return true;
|
||||
return PhysicalAxes::Both;
|
||||
}
|
||||
|
||||
// and overflow:hidden that we should interpret as clip
|
||||
|
@ -11045,35 +11081,48 @@ bool nsIFrame::ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const {
|
|||
case LayoutFrameType::SVGInnerSVG:
|
||||
case LayoutFrameType::SVGSymbol:
|
||||
case LayoutFrameType::SVGForeignObject:
|
||||
return true;
|
||||
return PhysicalAxes::Both;
|
||||
default:
|
||||
if (IsFrameOfType(nsIFrame::eReplacedContainsBlock)) {
|
||||
// It has an anonymous scroll frame that handles any overflow
|
||||
// except TextInput.
|
||||
return type != LayoutFrameType::TextInput;
|
||||
if (type == mozilla::LayoutFrameType::TextInput) {
|
||||
// It has an anonymous scroll frame that handles any overflow.
|
||||
return PhysicalAxes::None;
|
||||
}
|
||||
return PhysicalAxes::Both;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// clip overflow:clip, except for nsListControlFrame,
|
||||
// which is an nsHTMLScrollFrame.
|
||||
if (MOZ_UNLIKELY(aDisp->mOverflowX == StyleOverflow::Clip &&
|
||||
// clip overflow:clip, except for nsListControlFrame which is
|
||||
// an nsHTMLScrollFrame sub-class.
|
||||
if (MOZ_UNLIKELY((aDisp->mOverflowX == mozilla::StyleOverflow::Clip ||
|
||||
aDisp->mOverflowY == mozilla::StyleOverflow::Clip) &&
|
||||
!IsListControlFrame())) {
|
||||
// FIXME: we could use GetViewportScrollStylesOverrideElement() here instead
|
||||
// if that worked correctly in a print context. (see bug 1654667)
|
||||
const auto* element = Element::FromNodeOrNull(GetContent());
|
||||
if (!element ||
|
||||
!PresContext()->ElementWouldPropagateScrollStyles(*element)) {
|
||||
return true;
|
||||
uint8_t axes = uint8_t(PhysicalAxes::None);
|
||||
if (aDisp->mOverflowX == mozilla::StyleOverflow::Clip) {
|
||||
axes |= uint8_t(PhysicalAxes::Horizontal);
|
||||
}
|
||||
if (aDisp->mOverflowY == mozilla::StyleOverflow::Clip) {
|
||||
axes |= uint8_t(PhysicalAxes::Vertical);
|
||||
}
|
||||
return PhysicalAxes(axes);
|
||||
}
|
||||
}
|
||||
|
||||
if (HasAnyStateBits(NS_FRAME_SVG_LAYOUT)) {
|
||||
return false;
|
||||
return PhysicalAxes::None;
|
||||
}
|
||||
|
||||
// If we're paginated and a block, and have NS_BLOCK_CLIP_PAGINATED_OVERFLOW
|
||||
// set, then we want to clip our overflow.
|
||||
return HasAnyStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW) &&
|
||||
PresContext()->IsPaginated() && IsBlockFrame();
|
||||
bool clip = HasAnyStateBits(NS_BLOCK_CLIP_PAGINATED_OVERFLOW) &&
|
||||
PresContext()->IsPaginated() && IsBlockFrame();
|
||||
return clip ? PhysicalAxes::Both : PhysicalAxes::None;
|
||||
}
|
||||
|
||||
// Box layout debugging
|
||||
|
|
|
@ -2956,10 +2956,18 @@ class nsIFrame : public nsQueryFrame {
|
|||
*/
|
||||
virtual void UnionChildOverflow(nsOverflowAreas& aOverflowAreas);
|
||||
|
||||
// Represents zero or more physical axes.
|
||||
enum class PhysicalAxes : uint8_t {
|
||||
None = 0x0,
|
||||
Horizontal = 0x1,
|
||||
Vertical = 0x2,
|
||||
Both = Horizontal | Vertical,
|
||||
};
|
||||
|
||||
/**
|
||||
* Returns true if this frame should apply overflow clipping.
|
||||
*/
|
||||
bool ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const;
|
||||
PhysicalAxes ShouldApplyOverflowClipping(const nsStyleDisplay* aDisp) const;
|
||||
|
||||
/**
|
||||
* Helper method used by block reflow to identify runs of text so
|
||||
|
@ -4254,7 +4262,7 @@ class nsIFrame : public nsQueryFrame {
|
|||
* Returns true if this box clips its children, e.g., if this box is an
|
||||
* scrollbox.
|
||||
*/
|
||||
virtual bool DoesClipChildren();
|
||||
virtual bool DoesClipChildrenInBothAxes();
|
||||
|
||||
// We compute and store the HTML content's overflow area. So don't
|
||||
// try to compute it in the box code.
|
||||
|
@ -5381,6 +5389,7 @@ class nsIFrame : public nsQueryFrame {
|
|||
#endif
|
||||
};
|
||||
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsIFrame::PhysicalAxes)
|
||||
MOZ_MAKE_ENUM_CLASS_BITWISE_OPERATORS(nsIFrame::ReflowChildFlags)
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
#define nsIScrollFrame_h___
|
||||
|
||||
#include "nsCoord.h"
|
||||
#include "mozilla/dom/WindowBinding.h" // for mozilla::dom::ScrollBehavior
|
||||
#include "mozilla/Maybe.h"
|
||||
#include "mozilla/ScrollOrigin.h"
|
||||
#include "mozilla/ScrollStyles.h"
|
||||
|
|
|
@ -35,11 +35,11 @@
|
|||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
<div class="outer">
|
||||
<div class="clip"><div class="outer">
|
||||
<div class="inner">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="clip"><div class="outer">
|
||||
<div class="inner">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
|
@ -66,11 +66,11 @@
|
|||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
<div class="outer">
|
||||
<div class="clip"><div class="outer">
|
||||
<div class="inner">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
</div></div>
|
||||
<div class="clip"><div class="outer">
|
||||
<div class="inner">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
</div>
|
||||
<div class="outer">
|
||||
<div class="inner" style="overflow-y:clip;">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
<img width="296px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
<div class="outer">
|
||||
|
@ -64,7 +64,7 @@
|
|||
</div>
|
||||
<div class="outer" style="overflow-y:clip;">
|
||||
<div class="inner">
|
||||
<img width="400px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
<img width="296px" height="10px" src="data:image/gif;base64,R0lGODlhAQABAIABAAD/AP///ywAAAAAAQABAAACAkQBADs=">
|
||||
</div>
|
||||
</div>
|
||||
<div class="outer" style="overflow:hidden;">
|
||||
|
|
|
@ -1504,8 +1504,8 @@ struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
|
|||
}
|
||||
|
||||
bool IsScrollableOverflow() const {
|
||||
// mOverflowX and mOverflowY always match when one of them is
|
||||
// Visible or Clip.
|
||||
// Visible and Clip can be combined but not with other values,
|
||||
// so checking mOverflowX is enough.
|
||||
return mOverflowX != mozilla::StyleOverflow::Visible &&
|
||||
mOverflowX != mozilla::StyleOverflow::Clip;
|
||||
}
|
||||
|
|
|
@ -1926,7 +1926,8 @@ void nsTableFrame::Reflow(nsPresContext* aPresContext,
|
|||
// make sure the table overflow area does include the table rect.
|
||||
nsRect tableRect(0, 0, aDesiredSize.Width(), aDesiredSize.Height());
|
||||
|
||||
if (!ShouldApplyOverflowClipping(aReflowInput.mStyleDisplay)) {
|
||||
if (ShouldApplyOverflowClipping(aReflowInput.mStyleDisplay) !=
|
||||
PhysicalAxes::Both) {
|
||||
// collapsed border may leak out
|
||||
LogicalMargin bcMargin = GetExcludedOuterBCBorder(wm);
|
||||
tableRect.Inflate(bcMargin.GetPhysicalMargin(wm));
|
||||
|
@ -2001,7 +2002,7 @@ void nsTableFrame::FixupPositionedTableParts(nsPresContext* aPresContext,
|
|||
bool nsTableFrame::ComputeCustomOverflow(nsOverflowAreas& aOverflowAreas) {
|
||||
// As above in Reflow, make sure the table overflow area includes the table
|
||||
// rect, and check for collapsed borders leaking out.
|
||||
if (!ShouldApplyOverflowClipping(StyleDisplay())) {
|
||||
if (ShouldApplyOverflowClipping(StyleDisplay()) != PhysicalAxes::Both) {
|
||||
nsRect bounds(nsPoint(0, 0), GetSize());
|
||||
WritingMode wm = GetWritingMode();
|
||||
LogicalMargin bcMargin = GetExcludedOuterBCBorder(wm);
|
||||
|
|
|
@ -255,13 +255,10 @@ nsresult nsIFrame::XULLayout(nsBoxLayoutState& aState) {
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
bool nsIFrame::DoesClipChildren() {
|
||||
bool nsIFrame::DoesClipChildrenInBothAxes() {
|
||||
const nsStyleDisplay* display = StyleDisplay();
|
||||
NS_ASSERTION(
|
||||
(display->mOverflowY == StyleOverflow::Clip) ==
|
||||
(display->mOverflowX == StyleOverflow::Clip),
|
||||
"If one overflow is clip, the other should be too");
|
||||
return display->mOverflowX == StyleOverflow::Clip;
|
||||
return display->mOverflowX == StyleOverflow::Clip &&
|
||||
display->mOverflowY == StyleOverflow::Clip;
|
||||
}
|
||||
|
||||
nsresult nsIFrame::SyncXULLayout(nsBoxLayoutState& aBoxLayoutState) {
|
||||
|
@ -290,7 +287,7 @@ nsresult nsIFrame::SyncXULLayout(nsBoxLayoutState& aBoxLayoutState) {
|
|||
} else {
|
||||
nsRect rect(nsPoint(0, 0), GetSize());
|
||||
nsOverflowAreas overflowAreas(rect, rect);
|
||||
if (!DoesClipChildren() && !IsXULCollapsed()) {
|
||||
if (!DoesClipChildrenInBothAxes() && !IsXULCollapsed()) {
|
||||
// See if our child frames caused us to overflow after being laid
|
||||
// out. If so, store the overflow area. This normally can't happen
|
||||
// in XUL, but it can happen with the CSS 'outline' property and
|
||||
|
|
|
@ -97,7 +97,7 @@ class nsScrollbarFrame final : public nsBoxFrame,
|
|||
* scrollframe by setting its height or width to zero, that will
|
||||
* hide the children too.
|
||||
*/
|
||||
virtual bool DoesClipChildren() override { return true; }
|
||||
virtual bool DoesClipChildrenInBothAxes() override { return true; }
|
||||
|
||||
virtual nsresult GetXULMargin(nsMargin& aMargin) override;
|
||||
|
||||
|
|
|
@ -469,48 +469,22 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
/// CSS3 overflow-x and overflow-y require some fixup as well in some
|
||||
/// cases.
|
||||
///
|
||||
/// overflow: clip and overflow: visible are meaningful only when used in
|
||||
/// both dimensions.
|
||||
/// CSS overflow-x and overflow-y require some fixup as well in some cases.
|
||||
/// https://drafts.csswg.org/css-overflow-3/#overflow-properties
|
||||
/// "Computed value: as specified, except with `visible`/`clip` computing to
|
||||
/// `auto`/`hidden` (respectively) if one of `overflow-x` or `overflow-y` is
|
||||
/// neither `visible` nor `clip`."
|
||||
fn adjust_for_overflow(&mut self) {
|
||||
let original_overflow_x = self.style.get_box().clone_overflow_x();
|
||||
let original_overflow_y = self.style.get_box().clone_overflow_y();
|
||||
|
||||
let mut overflow_x = original_overflow_x;
|
||||
let mut overflow_y = original_overflow_y;
|
||||
|
||||
let overflow_x = self.style.get_box().clone_overflow_x();
|
||||
let overflow_y = self.style.get_box().clone_overflow_y();
|
||||
if overflow_x == overflow_y {
|
||||
return;
|
||||
return; // optimization for the common case
|
||||
}
|
||||
|
||||
// If 'visible' is specified but doesn't match the other dimension,
|
||||
// it turns into 'auto'.
|
||||
if overflow_x == Overflow::Visible {
|
||||
overflow_x = Overflow::Auto;
|
||||
}
|
||||
|
||||
if overflow_y == Overflow::Visible {
|
||||
overflow_y = Overflow::Auto;
|
||||
}
|
||||
|
||||
#[cfg(feature = "gecko")]
|
||||
{
|
||||
// overflow: clip is deprecated, so convert to hidden if it's
|
||||
// specified in only one dimension.
|
||||
if overflow_x == Overflow::Clip {
|
||||
overflow_x = Overflow::Hidden;
|
||||
}
|
||||
if overflow_y == Overflow::Clip {
|
||||
overflow_y = Overflow::Hidden;
|
||||
}
|
||||
}
|
||||
|
||||
if overflow_x != original_overflow_x || overflow_y != original_overflow_y {
|
||||
if overflow_x.is_scrollable() != overflow_y.is_scrollable() {
|
||||
let box_style = self.style.mutate_box();
|
||||
box_style.set_overflow_x(overflow_x);
|
||||
box_style.set_overflow_y(overflow_y);
|
||||
box_style.set_overflow_x(overflow_x.to_scrollable());
|
||||
box_style.set_overflow_y(overflow_y.to_scrollable());
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
[clip-003.html]
|
||||
expected:
|
||||
if os == "mac": FAIL # 3rd and 5th grid container fails on macOS 10.14 by rendering scrollbars in both axes. However, the same build succeeds when I load the test locally on a 10.15.3 MacBook
|
|
@ -1,31 +0,0 @@
|
|||
[overflow-computed.html]
|
||||
[Property overflow value 'clip clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'clip auto']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'auto clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'hidden clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'scroll clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'clip hidden']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow-y value 'clip']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow value 'clip scroll']
|
||||
expected: FAIL
|
||||
|
||||
[Property overflow-block value 'clip']
|
||||
expected: FAIL
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
[overflow-valid.html]
|
||||
[e.style['overflow'\] = "clip" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['overflow-y'\] = "clip" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['overflow'\] = "clip clip" should set the property value]
|
||||
expected: FAIL
|
||||
|
||||
[e.style['overflow-block'\] = "clip" should set the property value]
|
||||
expected: FAIL
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: overflow: clip can be combined with overflow: visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<style>
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="width:50px; height:50px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="top:-20px; width:50px"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="left:-40px; height:50px"></div>
|
||||
</div>
|
|
@ -0,0 +1,39 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: overflow:clip can be combined with overflow:visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip">
|
||||
<link rel="match" href="clip-002-ref.html">
|
||||
<style>
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
top: -20px;
|
||||
left: -40px;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer" style="overflow:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer" style="overflow-x:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer" style="overflow-y:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
|
@ -0,0 +1,61 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: overflow:clip can be combined with overflow:visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<style>
|
||||
.wrapper {
|
||||
margin-left: 30px;
|
||||
margin-bottom: 20px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
top: -10px;
|
||||
left: -10px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
background: blue;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no scrollbars -->
|
||||
<div class="wrapper" style="overflow: hidden">
|
||||
<div class="outer">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be no white areas inside the outline -->
|
||||
<div class="wrapper" style="outline: solid">
|
||||
<div class="outer">
|
||||
<div class="inner" style="left:0; width:50px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be a vertical scrollbar, but not a horizontal one -->
|
||||
<div class="wrapper" style="overflow: hidden scroll; margin-top:50px">
|
||||
<div class="outer">
|
||||
<div class="inner" style="width:1px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be no white areas inside the outline -->
|
||||
<div class="wrapper" style="outline: solid">
|
||||
<div class="outer">
|
||||
<div class="inner" style="top:0; height:50px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be horizontal scrollbar, but not a vertical one -->
|
||||
<div class="wrapper" style="overflow: scroll hidden">
|
||||
<div class="outer">
|
||||
<div class="inner" style="height:1px"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,63 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: overflow:clip can be combined with overflow:visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip">
|
||||
<link rel="match" href="clip-003-ref.html">
|
||||
<style>
|
||||
.wrapper {
|
||||
margin-left: 30px;
|
||||
margin-bottom: 20px;
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
}
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
top: -10px;
|
||||
left: -10px;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
background: blue;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no scrollbars -->
|
||||
<div class="wrapper" style="overflow: auto">
|
||||
<div class="outer" style="overflow:clip; outline:solid red">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be no white areas inside the outline -->
|
||||
<div class="wrapper" style="outline: solid">
|
||||
<div class="outer" style="overflow-x:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be a vertical scrollbar, but not a horizontal one -->
|
||||
<div class="wrapper" style="overflow: auto; margin-top:50px">
|
||||
<div class="outer" style="overflow-x:clip">
|
||||
<div class="inner" style="width:1px"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be no white areas inside the outline -->
|
||||
<div class="wrapper" style="outline: solid">
|
||||
<div class="outer" style="overflow-y:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- there should be horizontal scrollbar, but not a vertical one -->
|
||||
<div class="wrapper" style="overflow: auto">
|
||||
<div class="outer" style="overflow-y:clip">
|
||||
<div class="inner" style="height:1px"></div>
|
||||
</div>
|
||||
</div>
|
|
@ -0,0 +1,35 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: overflow: clip can be combined with overflow: visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<style>
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="width:50px; height:50px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="top:-10px; width:50px"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="left:-30px; height:50px"></div>
|
||||
</div>
|
|
@ -0,0 +1,40 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: overflow:clip can be combined with overflow:visible</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip">
|
||||
<link rel="match" href="clip-004-ref.html">
|
||||
<style>
|
||||
.outer {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding: 10px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
top: -20px;
|
||||
left: -40px;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer" style="overflow:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer" style="overflow-x:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer" style="overflow-y:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
|
@ -0,0 +1,36 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>Reference: overflow:clip doesn't affect the box' own outline</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<style>
|
||||
.outer {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
outline: 2px solid grey;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="width:50px; height:50px;"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="top:-10px; width:50px"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer">
|
||||
<div class="inner" style="left:-30px; height:50px"></div>
|
||||
</div>
|
|
@ -0,0 +1,41 @@
|
|||
<!doctype html>
|
||||
<meta charset="utf-8">
|
||||
<title>CSS Test: overflow:clip doesn't affect the box' own outline</title>
|
||||
<link rel="author" title="Mats Palmgren" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1531609">
|
||||
<link rel="help" href="https://drafts.csswg.org/css-overflow/#valdef-overflow-clip">
|
||||
<link rel="match" href="clip-005-ref.html">
|
||||
<style>
|
||||
.outer {
|
||||
width: 30px;
|
||||
height: 30px;
|
||||
padding: 10px;
|
||||
margin-left: 100px;
|
||||
margin-top: 100px;
|
||||
background: black;
|
||||
outline: 2px solid grey;
|
||||
}
|
||||
|
||||
.inner {
|
||||
position: relative;
|
||||
top: -20px;
|
||||
left: -40px;
|
||||
background: blue;
|
||||
height: 100px;
|
||||
width: 100px;
|
||||
opacity: 0.5;
|
||||
}
|
||||
</style>
|
||||
<!-- there should be no overflow -->
|
||||
<div class="outer" style="overflow:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the vertical dimension, but not horizontally -->
|
||||
<div class="outer" style="overflow-x:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
||||
|
||||
<!-- there should be overflow in the horizontal dimension, but not vertically -->
|
||||
<div class="outer" style="overflow-y:clip">
|
||||
<div class="inner"></div>
|
||||
</div>
|
|
@ -25,6 +25,7 @@ test_computed_value("overflow", 'clip auto', 'hidden auto');
|
|||
test_computed_value("overflow", 'clip clip', 'clip');
|
||||
test_computed_value("overflow", 'clip hidden', 'hidden');
|
||||
test_computed_value("overflow", 'clip scroll', 'hidden scroll')
|
||||
test_computed_value("overflow", 'clip visible', 'clip visible')
|
||||
test_computed_value("overflow", 'hidden clip', 'hidden');
|
||||
test_computed_value("overflow", 'hidden visible', 'hidden auto');
|
||||
test_computed_value("overflow", 'scroll auto');
|
||||
|
@ -33,6 +34,7 @@ test_computed_value("overflow", 'scroll visible', 'scroll auto');
|
|||
test_computed_value("overflow", 'visible auto', 'auto');
|
||||
test_computed_value("overflow", 'visible hidden', 'auto hidden');
|
||||
test_computed_value("overflow", 'visible scroll', 'auto scroll');
|
||||
test_computed_value("overflow", 'visible clip', 'visible clip');
|
||||
test_computed_value("overflow", 'visible visible', 'visible');
|
||||
|
||||
|
||||
|
|
Загрузка…
Ссылка в новой задаче