/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* vim: set ts=8 sts=2 et sw=2 tw=80: */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /* * structs that contain the data provided by ComputedStyle, the * internal API for computed style data for an element */ #ifndef nsStyleStruct_h___ #define nsStyleStruct_h___ #include "mozilla/Assertions.h" #include "mozilla/Attributes.h" #include "mozilla/Likely.h" #include "mozilla/Maybe.h" #include "mozilla/UniquePtr.h" #include "mozilla/WindowButtonType.h" #include "nsColor.h" #include "nsCoord.h" #include "nsMargin.h" #include "nsFont.h" #include "nsStyleAutoArray.h" #include "nsStyleConsts.h" #include "nsChangeHint.h" #include "nsTArray.h" #include "imgIContainer.h" #include "imgRequestProxy.h" #include "CounterStyleManager.h" #include // offsetof() #include "X11UndefineNone.h" class nsIFrame; class nsIURI; class nsTextFrame; struct nsStyleDisplay; struct nsStyleVisibility; namespace mozilla { class ComputedStyle; struct IntrinsicSize; } // namespace mozilla namespace mozilla::dom { enum class CompositeOperation : uint8_t; } // namespace mozilla::dom namespace mozilla { using Position = StylePosition; template <> inline bool StylePosition::HasPercent() const { return horizontal.HasPercent() || vertical.HasPercent(); } /** * True if the effective background image position described by this depends on * the size of the corresponding frame. */ template <> inline bool StylePosition::DependsOnPositioningAreaSize() const { return HasPercent(); } template <> inline Position Position::FromPercentage(float aPercent) { return {LengthPercentage::FromPercentage(aPercent), LengthPercentage::FromPercentage(aPercent)}; } /** * Convenience struct for querying if a given box has size-containment in * either axis. */ struct ContainSizeAxes { ContainSizeAxes(bool aIContained, bool aBContained) : mIContained(aIContained), mBContained(aBContained) {} bool IsBoth() const { return mIContained && mBContained; } bool IsAny() const { return mIContained || mBContained; } /** * Return a contained size from an uncontained size. */ nsSize ContainSize(const nsSize& aUncontainedSize, const nsIFrame& aFrame) const; IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize, const nsIFrame& aFrame) const; Maybe ContainIntrinsicBSize(const nsIFrame& aFrame, nscoord aNoneValue = 0) const; Maybe ContainIntrinsicISize(const nsIFrame& aFrame, nscoord aNoneValue = 0) const; const bool mIContained; const bool mBContained; }; } // namespace mozilla struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont { nsStyleFont(const nsStyleFont&); explicit nsStyleFont(const mozilla::dom::Document&); MOZ_COUNTED_DTOR(nsStyleFont) static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStyleFont& aNewData) const; /** * Return a given size multiplied by the current text zoom factor (in * aPresContext). * * The size is allowed to be negative, but the caller is expected to deal with * negative results. */ static mozilla::Length ZoomText(const mozilla::dom::Document&, mozilla::Length); nsAtom* GetFontPaletteAtom() const { return mFontPalette._0.AsAtom(); } nsFont mFont; // Our "computed size". Can be different from mFont.size which is our "actual // size" and is enforced to be >= the user's preferred min-size. mFont.size // should be used for display purposes while mSize is the value to return in // getComputedStyle() for example. mozilla::NonNegativeLength mSize; // In stylo these three track whether the size is keyword-derived // and if so if it has been modified by a factor/offset float mFontSizeFactor; mozilla::Length mFontSizeOffset; mozilla::StyleFontSizeKeyword mFontSizeKeyword; mozilla::StyleFontPalette mFontPalette; // math-depth support (used for MathML scriptlevel) int8_t mMathDepth; // MathML mathvariant support mozilla::StyleMathVariant mMathVariant; // math-style support (used for MathML displaystyle) mozilla::StyleMathStyle mMathStyle; // allow different min font-size for certain cases uint8_t mMinFontSizeRatio = 100; // percent * 100 // Was mLanguage set based on a lang attribute in the document? bool mExplicitLanguage = false; mozilla::StyleXTextScale mXTextScale; bool MinFontSizeEnabled() const { return mXTextScale == mozilla::StyleXTextScale::All; } // The value mSize would have had if scriptminsize had never been applied mozilla::NonNegativeLength mScriptUnconstrainedSize; mozilla::Length mScriptMinSize; float mScriptSizeMultiplier; RefPtr mLanguage; }; struct nsStyleImageLayers { enum class LayerType : uint8_t { Background = 0, Mask }; explicit nsStyleImageLayers(LayerType aType); nsStyleImageLayers(const nsStyleImageLayers& aSource); MOZ_COUNTED_DTOR(nsStyleImageLayers) struct Repeat { mozilla::StyleImageLayerRepeat mXRepeat, mYRepeat; // Initialize nothing Repeat() = default; bool IsInitialValue() const { return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat && mYRepeat == mozilla::StyleImageLayerRepeat::Repeat; } bool DependsOnPositioningAreaSize() const { return mXRepeat == mozilla::StyleImageLayerRepeat::Space || mYRepeat == mozilla::StyleImageLayerRepeat::Space; } // Initialize to initial values void SetInitialValues() { mXRepeat = mozilla::StyleImageLayerRepeat::Repeat; mYRepeat = mozilla::StyleImageLayerRepeat::Repeat; } bool operator==(const Repeat& aOther) const { return mXRepeat == aOther.mXRepeat && mYRepeat == aOther.mYRepeat; } bool operator!=(const Repeat& aOther) const { return !(*this == aOther); } }; struct Layer { typedef mozilla::StyleGeometryBox StyleGeometryBox; typedef mozilla::StyleImageLayerAttachment StyleImageLayerAttachment; typedef mozilla::StyleBackgroundSize StyleBackgroundSize; mozilla::StyleImage mImage; mozilla::Position mPosition; StyleBackgroundSize mSize; StyleGeometryBox mClip; MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin; // This property is used for background layer only. // For a mask layer, it should always be the initial value, which is // StyleImageLayerAttachment::Scroll. StyleImageLayerAttachment mAttachment; // This property is used for background layer only. // For a mask layer, it should always be the initial value, which is // StyleBlend::Normal. mozilla::StyleBlend mBlendMode; // This property is used for mask layer only. // For a background layer, it should always be the initial value, which is // StyleMaskComposite::Add. mozilla::StyleMaskComposite mComposite; // mask-only property. This property is used for mask layer only. For a // background layer, it should always be the initial value, which is // StyleMaskMode::MatchSource. mozilla::StyleMaskMode mMaskMode; Repeat mRepeat; // This constructor does not initialize mRepeat or mOrigin and Initialize() // must be called to do that. Layer(); ~Layer(); // Initialize mRepeat and mOrigin by specified layer type void Initialize(LayerType aType); void ResolveImage(mozilla::dom::Document& aDocument, const Layer* aOldLayer) { mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr); } // True if the rendering of this layer might change when the size // of the background positioning area changes. This is true for any // non-solid-color background whose position or size depends on // the size of the positioning area. It's also true for SVG images // whose root node has a viewBox. bool RenderingMightDependOnPositioningAreaSizeChange() const; // Compute the change hint required by changes in just this layer. nsChangeHint CalcDifference(const Layer& aNewLayer) const; // An equality operator that compares the images using URL-equality // rather than pointer-equality. bool operator==(const Layer& aOther) const; bool operator!=(const Layer& aOther) const { return !(*this == aOther); } }; // The (positive) number of computed values of each property, since // the lengths of the lists are independent. uint32_t mAttachmentCount; uint32_t mClipCount; uint32_t mOriginCount; uint32_t mRepeatCount; uint32_t mPositionXCount; uint32_t mPositionYCount; uint32_t mImageCount; uint32_t mSizeCount; uint32_t mMaskModeCount; uint32_t mBlendModeCount; uint32_t mCompositeCount; // Layers are stored in an array, matching the top-to-bottom order in // which they are specified in CSS. The number of layers to be used // should come from the background-image property. We create // additional |Layer| objects for *any* property, not just // background-image. This means that the bottommost layer that // callers in layout care about (which is also the one whose // background-clip applies to the background-color) may not be last // layer. In layers below the bottom layer, properties will be // uninitialized unless their count, above, indicates that they are // present. nsStyleAutoArray mLayers; const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; } void ResolveImages(mozilla::dom::Document& aDocument, const nsStyleImageLayers* aOldLayers) { for (uint32_t i = 0; i < mImageCount; ++i) { const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i) ? &aOldLayers->mLayers[i] : nullptr; mLayers[i].ResolveImage(aDocument, oldLayer); } } // Fill unspecified layers by cycling through their values // till they all are of length aMaxItemCount void FillAllLayers(uint32_t aMaxItemCount); nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers, nsStyleImageLayers::LayerType aType) const; nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther); nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default; bool operator==(const nsStyleImageLayers& aOther) const; static const nsCSSPropertyID kBackgroundLayerTable[]; static const nsCSSPropertyID kMaskLayerTable[]; #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \ for (uint32_t var_ = (layers_).mImageCount; var_-- != 0;) #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_, \ start_, count_) \ NS_ASSERTION( \ (int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount, \ "Invalid layer start!"); \ NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1, \ "Invalid layer range!"); \ for (uint32_t var_ = (start_) + 1; \ var_-- != (uint32_t)((start_) + 1 - (count_));) }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground { explicit nsStyleBackground(const mozilla::dom::Document&); nsStyleBackground(const nsStyleBackground& aOther); ~nsStyleBackground(); // Resolves and tracks the images in mImage. Only called with a Servo-backed // style system, where those images must be resolved later than the OMT // nsStyleBackground constructor call. void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*); static constexpr bool kHasTriggerImageLoads = true; nsChangeHint CalcDifference(const nsStyleBackground& aNewData) const; // Return the background color as nscolor. nscolor BackgroundColor(const nsIFrame* aFrame) const; nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const; // True if this background is completely transparent. bool IsTransparent(const nsIFrame* aFrame) const; bool IsTransparent(const mozilla::ComputedStyle* aStyle) const; // We have to take slower codepaths for fixed background attachment, // but we don't want to do that when there's no image. // Not inline because it uses an nsCOMPtr // FIXME: Should be in nsStyleStructInlines.h. bool HasFixedBackground(nsIFrame* aFrame) const; // Checks to see if this has a non-empty image with "local" attachment. // This is defined in nsStyleStructInlines.h. inline bool HasLocalBackground() const; const nsStyleImageLayers::Layer& BottomLayer() const { return mImage.BottomLayer(); } nsStyleImageLayers mImage; mozilla::StyleColor mBackgroundColor; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin { explicit nsStyleMargin(const mozilla::dom::Document&); nsStyleMargin(const nsStyleMargin& aMargin); MOZ_COUNTED_DTOR(nsStyleMargin) static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStyleMargin& aNewData) const; bool GetMargin(nsMargin& aMargin) const { bool convertsToLength = mMargin.All( [](const auto& aLength) { return aLength.ConvertsToLength(); }); if (!convertsToLength) { return false; } for (const auto side : mozilla::AllPhysicalSides()) { aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength(); } return true; } nsMargin GetScrollMargin() const { return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(), mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(), mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(), mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits()); } // Return true if either the start or end side in the axis is 'auto'. // (defined in WritingModes.h since we need the full WritingMode type) inline bool HasBlockAxisAuto(mozilla::WritingMode aWM) const; inline bool HasInlineAxisAuto(mozilla::WritingMode aWM) const; inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode) const; mozilla::StyleRect mMargin; mozilla::StyleRect mScrollMargin; // TODO: Add support for overflow-clip-margin: and maybe // per-axis/side clipping, see https://github.com/w3c/csswg-drafts/issues/7245 mozilla::StyleLength mOverflowClipMargin; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding { explicit nsStylePadding(const mozilla::dom::Document&); nsStylePadding(const nsStylePadding& aPadding); MOZ_COUNTED_DTOR(nsStylePadding) static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStylePadding& aNewData) const; mozilla::StyleRect mPadding; mozilla::StyleRect mScrollPadding; inline bool IsWidthDependent() const { return !mPadding.All( [](const auto& aLength) { return aLength.ConvertsToLength(); }); } bool GetPadding(nsMargin& aPadding) const { if (IsWidthDependent()) { return false; } for (const auto side : mozilla::AllPhysicalSides()) { // Clamp negative calc() to 0. aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0); } return true; } }; // 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. #define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \ ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp)) // Returns if the given border style type is visible or not static bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) { return (aStyle != mozilla::StyleBorderStyle::None && aStyle != mozilla::StyleBorderStyle::Hidden); } struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder { explicit nsStyleBorder(const mozilla::dom::Document&); nsStyleBorder(const nsStyleBorder& aBorder); ~nsStyleBorder(); // Resolves and tracks mBorderImageSource. Only called with a Servo-backed // style system, where those images must be resolved later than the OMT // nsStyleBorder constructor call. void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*); static constexpr bool kHasTriggerImageLoads = true; nsChangeHint CalcDifference(const nsStyleBorder& aNewData) const; // Return whether aStyle is a visible style. Invisible styles cause // the relevant computed border width to be 0. // Note that this does *not* consider the effects of 'border-image': // if border-style is none, but there is a loaded border image, // HasVisibleStyle will be false even though there *is* a border. bool HasVisibleStyle(mozilla::Side aSide) const { return IsVisibleBorderStyle(mBorderStyle[aSide]); } // aBorderWidth is in twips void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth, nscoord aAppUnitsPerDevPixel) { nscoord roundedWidth = NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, aAppUnitsPerDevPixel); mBorder.Side(aSide) = roundedWidth; if (HasVisibleStyle(aSide)) { mComputedBorder.Side(aSide) = roundedWidth; } } // Get the computed border (plus rounding). This does consider the // effects of 'border-style: none', but does not consider // 'border-image'. const nsMargin& GetComputedBorder() const { return mComputedBorder; } bool HasBorder() const { return mComputedBorder != nsMargin(0, 0, 0, 0) || !mBorderImageSource.IsNone(); } // Get the actual border width for a particular side, in appunits. Note that // this is zero if and only if there is no border to be painted for this // side. That is, this value takes into account the border style and the // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS. nscoord GetComputedBorderWidth(mozilla::Side aSide) const { return GetComputedBorder().Side(aSide); } mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const { NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side"); return mBorderStyle[aSide]; } void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) { NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side"); mBorderStyle[aSide] = aStyle; mComputedBorder.Side(aSide) = (HasVisibleStyle(aSide) ? mBorder.Side(aSide) : 0); } inline bool IsBorderImageSizeAvailable() const { return mBorderImageSource.IsSizeAvailable(); } nsMargin GetImageOutset() const; imgIRequest* GetBorderImageRequest() const { return mBorderImageSource.GetImageRequest(); } public: mozilla::StyleBorderRadius mBorderRadius; // coord, percent mozilla::StyleImage mBorderImageSource; mozilla::StyleBorderImageWidth mBorderImageWidth; mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset; mozilla::StyleBorderImageSlice mBorderImageSlice; // factor, percent mozilla::StyleBorderImageRepeat mBorderImageRepeatH; mozilla::StyleBorderImageRepeat mBorderImageRepeatV; mozilla::StyleFloatEdge mFloatEdge; mozilla::StyleBoxDecorationBreak mBoxDecorationBreak; protected: mozilla::StyleBorderStyle mBorderStyle[4]; // StyleBorderStyle::* public: // the colors to use for a simple border. // not used for -moz-border-colors mozilla::StyleColor mBorderTopColor; mozilla::StyleColor mBorderRightColor; mozilla::StyleColor mBorderBottomColor; mozilla::StyleColor mBorderLeftColor; mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) { switch (aSide) { case mozilla::eSideTop: return mBorderTopColor; case mozilla::eSideRight: return mBorderRightColor; case mozilla::eSideBottom: return mBorderBottomColor; case mozilla::eSideLeft: return mBorderLeftColor; } MOZ_ASSERT_UNREACHABLE("Unknown side"); return mBorderTopColor; } const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const { switch (aSide) { case mozilla::eSideTop: return mBorderTopColor; case mozilla::eSideRight: return mBorderRightColor; case mozilla::eSideBottom: return mBorderBottomColor; case mozilla::eSideLeft: return mBorderLeftColor; } MOZ_ASSERT_UNREACHABLE("Unknown side"); return mBorderTopColor; } static mozilla::StyleColor nsStyleBorder::*BorderColorFieldFor( mozilla::Side aSide) { switch (aSide) { case mozilla::eSideTop: return &nsStyleBorder::mBorderTopColor; case mozilla::eSideRight: return &nsStyleBorder::mBorderRightColor; case mozilla::eSideBottom: return &nsStyleBorder::mBorderBottomColor; case mozilla::eSideLeft: return &nsStyleBorder::mBorderLeftColor; } MOZ_ASSERT_UNREACHABLE("Unknown side"); return nullptr; } protected: // mComputedBorder holds the CSS2.1 computed border-width values. // In particular, these widths take into account the border-style // for the relevant side, and the values are rounded to the nearest // device pixel (which is not part of the definition of computed // values). The presence or absence of a border-image does not // affect border-width values. nsMargin mComputedBorder; // mBorder holds the nscoord values for the border widths as they // would be if all the border-style values were visible (not hidden // or none). This member exists so that when we create structs // using the copy constructor during style resolution the new // structs will know what the specified values of the border were in // case they have more specific rules setting the border style. // // Note that this isn't quite the CSS specified value, since this // has had the enumerated border widths converted to lengths, and // all lengths converted to twips. But it's not quite the computed // value either. The values are rounded to the nearest device pixel. nsMargin mBorder; private: nsStyleBorder& operator=(const nsStyleBorder& aOther) = delete; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline { explicit nsStyleOutline(const mozilla::dom::Document&); nsStyleOutline(const nsStyleOutline& aOutline); MOZ_COUNTED_DTOR(nsStyleOutline) static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStyleOutline& aNewData) const; // This is the specified value of outline-width, but with length values // computed to absolute. mActualOutlineWidth stores the outline-width // value used by layout. (We must store mOutlineWidth for the same // style struct resolution reasons that we do nsStyleBorder::mBorder; // see that field's comment.) nscoord mOutlineWidth; mozilla::Length mOutlineOffset; mozilla::StyleColor mOutlineColor; mozilla::StyleOutlineStyle mOutlineStyle; nscoord GetOutlineWidth() const { return mActualOutlineWidth; } bool ShouldPaintOutline() const { if (mOutlineStyle.IsAuto()) { return true; } if (GetOutlineWidth() > 0) { MOZ_ASSERT( mOutlineStyle.AsBorderStyle() != mozilla::StyleBorderStyle::None, "outline-style: none implies outline-width of zero"); return true; } return false; } protected: // The actual value of outline-width is the computed value (an absolute // length, forced to zero when outline-style is none) rounded to device // pixels. This is the value used by layout. nscoord mActualOutlineWidth; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList { explicit nsStyleList(const mozilla::dom::Document&); nsStyleList(const nsStyleList& aStyleList); ~nsStyleList(); private: nsStyleList& operator=(const nsStyleList& aOther) = delete; public: void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*); static constexpr bool kHasTriggerImageLoads = true; nsChangeHint CalcDifference(const nsStyleList& aNewData, const nsStyleDisplay& aOldDisplay) const; already_AddRefed GetListStyleImageURI() const; mozilla::StyleListStylePosition mListStylePosition; mozilla::CounterStylePtr mCounterStyle; mozilla::StyleQuotes mQuotes; mozilla::StyleImage mListStyleImage; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePage { using StylePageOrientation = mozilla::StylePageOrientation; using StylePageSize = mozilla::StylePageSize; using StylePageName = mozilla::StylePageName; nsStylePage(const nsStylePage& aOther) = default; nsStylePage& operator=(const nsStylePage& aOther) = default; explicit nsStylePage(const mozilla::dom::Document&) : mSize(StylePageSize::Auto()), mPage(StylePageName::Auto()), mPageOrientation(StylePageOrientation::Upright) {} static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStylePage& aNewData) const; // page-size property. StylePageSize mSize; // page-name property. StylePageName mPage; // page-orientation property. StylePageOrientation mPageOrientation; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition { using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto; using Position = mozilla::Position; template using StyleRect = mozilla::StyleRect; using StyleSize = mozilla::StyleSize; using StyleMaxSize = mozilla::StyleMaxSize; using WritingMode = mozilla::WritingMode; using LogicalAxis = mozilla::LogicalAxis; using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks; using ComputedStyle = mozilla::ComputedStyle; using StyleAlignSelf = mozilla::StyleAlignSelf; using StyleJustifySelf = mozilla::StyleJustifySelf; explicit nsStylePosition(const mozilla::dom::Document&); nsStylePosition(const nsStylePosition& aOther); ~nsStylePosition(); static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference( const nsStylePosition& aNewData, const nsStyleVisibility& aOldStyleVisibility) const; // Returns whether we need to compute an hypothetical position if we were // absolutely positioned. bool NeedsHypotheticalPositionIfAbsPos() const { return (mOffset.Get(mozilla::eSideRight).IsAuto() && mOffset.Get(mozilla::eSideLeft).IsAuto()) || (mOffset.Get(mozilla::eSideTop).IsAuto() && mOffset.Get(mozilla::eSideBottom).IsAuto()); } const mozilla::StyleContainIntrinsicSize& ContainIntrinsicBSize( const WritingMode& aWM) const; const mozilla::StyleContainIntrinsicSize& ContainIntrinsicISize( const WritingMode& aWM) const; /** * Return the used value for 'align-self' given our parent ComputedStyle * (or null for the root). */ StyleAlignSelf UsedAlignSelf(const ComputedStyle*) const; /** * Return the used value for 'justify-self' given our parent ComputedStyle * aParent (or null for the root). */ StyleJustifySelf UsedJustifySelf(const ComputedStyle*) const; /** * Return the used value for 'justify/align-self' in aAxis given our parent * ComputedStyle aParent (or null for the root). * (defined in WritingModes.h since we need the full WritingMode type) */ inline mozilla::StyleAlignFlags UsedSelfAlignment( LogicalAxis aAxis, const mozilla::ComputedStyle* aParent) const; /** * Return the used value for 'justify/align-content' in aAxis. * (defined in WritingModes.h since we need the full WritingMode type) */ inline mozilla::StyleContentDistribution UsedContentAlignment( LogicalAxis aAxis) const; /** * Return the used value for 'align-tracks'/'justify-tracks' for a track * in the given axis. * (defined in WritingModes.h since we need the full LogicalAxis type) */ inline mozilla::StyleContentDistribution UsedTracksAlignment( LogicalAxis aAxis, uint32_t aIndex) const; // Each entry has the same encoding as *-content, see below. mozilla::StyleAlignTracks mAlignTracks; mozilla::StyleJustifyTracks mJustifyTracks; Position mObjectPosition; StyleRect mOffset; StyleSize mWidth; StyleSize mMinWidth; StyleMaxSize mMaxWidth; StyleSize mHeight; StyleSize mMinHeight; StyleMaxSize mMaxHeight; mozilla::StyleFlexBasis mFlexBasis; StyleImplicitGridTracks mGridAutoColumns; StyleImplicitGridTracks mGridAutoRows; mozilla::StyleAspectRatio mAspectRatio; mozilla::StyleGridAutoFlow mGridAutoFlow; mozilla::StyleMasonryAutoFlow mMasonryAutoFlow; mozilla::StyleAlignContent mAlignContent; mozilla::StyleAlignItems mAlignItems; mozilla::StyleAlignSelf mAlignSelf; mozilla::StyleJustifyContent mJustifyContent; mozilla::StyleComputedJustifyItems mJustifyItems; mozilla::StyleJustifySelf mJustifySelf; mozilla::StyleFlexDirection mFlexDirection; mozilla::StyleFlexWrap mFlexWrap; mozilla::StyleObjectFit mObjectFit; mozilla::StyleBoxSizing mBoxSizing; int32_t mOrder; float mFlexGrow; float mFlexShrink; mozilla::StyleZIndex mZIndex; mozilla::StyleGridTemplateComponent mGridTemplateColumns; mozilla::StyleGridTemplateComponent mGridTemplateRows; mozilla::StyleGridTemplateAreas mGridTemplateAreas; mozilla::StyleGridLine mGridColumnStart; mozilla::StyleGridLine mGridColumnEnd; mozilla::StyleGridLine mGridRowStart; mozilla::StyleGridLine mGridRowEnd; mozilla::NonNegativeLengthPercentageOrNormal mColumnGap; mozilla::NonNegativeLengthPercentageOrNormal mRowGap; mozilla::StyleContainIntrinsicSize mContainIntrinsicWidth; mozilla::StyleContainIntrinsicSize mContainIntrinsicHeight; // Logical-coordinate accessors for width and height properties, // given a WritingMode value. The definitions of these methods are // found in WritingModes.h (after the WritingMode class is fully // declared). inline const StyleSize& ISize(WritingMode) const; inline const StyleSize& MinISize(WritingMode) const; inline const StyleMaxSize& MaxISize(WritingMode) const; inline const StyleSize& BSize(WritingMode) const; inline const StyleSize& MinBSize(WritingMode) const; inline const StyleMaxSize& MaxBSize(WritingMode) const; inline const StyleSize& Size(LogicalAxis, WritingMode) const; inline const StyleSize& MinSize(LogicalAxis, WritingMode) const; inline const StyleMaxSize& MaxSize(LogicalAxis, WritingMode) const; inline bool ISizeDependsOnContainer(WritingMode) const; inline bool MinISizeDependsOnContainer(WritingMode) const; inline bool MaxISizeDependsOnContainer(WritingMode) const; inline bool BSizeDependsOnContainer(WritingMode) const; inline bool MinBSizeDependsOnContainer(WritingMode) const; inline bool MaxBSizeDependsOnContainer(WritingMode) const; private: template static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) { if (aCoord.IsLengthPercentage()) { return aCoord.AsLengthPercentage().HasPercent(); } return aCoord.IsFitContent() || aCoord.IsMozAvailable(); } template static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) { return aCoord.IsLengthPercentage() && aCoord.AsLengthPercentage().HasPercent(); } }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset { explicit nsStyleTextReset(const mozilla::dom::Document&); nsStyleTextReset(const nsStyleTextReset& aOther); ~nsStyleTextReset(); static constexpr bool kHasTriggerImageLoads = false; // Note the difference between this and // ComputedStyle::HasTextDecorationLines. bool HasTextDecorationLines() const { return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE && mTextDecorationLine != mozilla::StyleTextDecorationLine::COLOR_OVERRIDE; } nsChangeHint CalcDifference(const nsStyleTextReset& aNewData) const; mozilla::StyleTextOverflow mTextOverflow; mozilla::StyleTextDecorationLine mTextDecorationLine; mozilla::StyleTextDecorationStyle mTextDecorationStyle; mozilla::StyleUnicodeBidi mUnicodeBidi; nscoord mInitialLetterSink; // 0 means normal float mInitialLetterSize; // 0.0f means normal mozilla::StyleColor mTextDecorationColor; mozilla::StyleTextDecorationLength mTextDecorationThickness; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText { explicit nsStyleText(const mozilla::dom::Document&); nsStyleText(const nsStyleText& aOther); ~nsStyleText(); static constexpr bool kHasTriggerImageLoads = false; nsChangeHint CalcDifference(const nsStyleText& aNewData) const; mozilla::StyleAbsoluteColor mColor; mozilla::StyleForcedColorAdjust mForcedColorAdjust; mozilla::StyleTextTransform mTextTransform; mozilla::StyleTextAlign mTextAlign; mozilla::StyleTextAlignLast mTextAlignLast; mozilla::StyleTextJustify mTextJustify; mozilla::StyleWhiteSpace mWhiteSpace; mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto; private: mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal; mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal; public: mozilla::StyleHyphens mHyphens; mozilla::StyleRubyAlign mRubyAlign; mozilla::StyleRubyPosition mRubyPosition; mozilla::StyleTextSizeAdjust mTextSizeAdjust; mozilla::StyleTextCombineUpright mTextCombineUpright; mozilla::StyleMozControlCharacterVisibility mMozControlCharacterVisibility; mozilla::StyleTextEmphasisPosition mTextEmphasisPosition; mozilla::StyleTextRendering mTextRendering; mozilla::StyleColor mTextEmphasisColor; mozilla::StyleColor mWebkitTextFillColor; mozilla::StyleColor mWebkitTextStrokeColor; mozilla::StyleNonNegativeLengthOrNumber mTabSize; mozilla::LengthPercentage mWordSpacing; mozilla::StyleLetterSpacing mLetterSpacing; mozilla::StyleLineHeight mLineHeight; mozilla::LengthPercentage mTextIndent; mozilla::LengthPercentageOrAuto mTextUnderlineOffset; mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk; mozilla::StyleTextUnderlinePosition mTextUnderlinePosition; mozilla::StyleAu mWebkitTextStrokeWidth; mozilla::StyleArcSlice mTextShadow; mozilla::StyleTextEmphasisStyle mTextEmphasisStyle; mozilla::StyleHyphenateCharacter mHyphenateCharacter = mozilla::StyleHyphenateCharacter::Auto(); mozilla::StyleTextSecurity mWebkitTextSecurity = mozilla::StyleTextSecurity::None; char16_t TextSecurityMaskChar() const { switch (mWebkitTextSecurity) { case mozilla::StyleTextSecurity::None: return 0; case mozilla::StyleTextSecurity::Circle: return 0x25E6; case mozilla::StyleTextSecurity::Disc: return 0x2022; case mozilla::StyleTextSecurity::Square: return 0x25A0; default: MOZ_ASSERT_UNREACHABLE("unknown StyleTextSecurity value!"); return 0; } } mozilla::StyleWordBreak EffectiveWordBreak() const { if (mWordBreak == mozilla::StyleWordBreak::BreakWord) { return mozilla::StyleWordBreak::Normal; } return mWordBreak; } mozilla::StyleOverflowWrap EffectiveOverflowWrap() const { if (mWordBreak == mozilla::StyleWordBreak::BreakWord) { return mozilla::StyleOverflowWrap::Anywhere; } return mOverflowWrap; } bool WhiteSpaceIsSignificant() const { return mWhiteSpace == mozilla::StyleWhiteSpace::Pre || mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap || mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces || mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace; } bool WhiteSpaceCanHangOrVisuallyCollapse() const { // This was originally expressed in nsTextFrame in terms of: // mWhiteSpace != StyleWhiteSpace::BreakSpaces && // WhiteSpaceCanWrapStyle() && // WhiteSpaceIsSignificant() // which simplifies to: return mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap; } bool NewlineIsSignificantStyle() const { return mWhiteSpace == mozilla::StyleWhiteSpace::Pre || mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap || mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces || mWhiteSpace == mozilla::StyleWhiteSpace::PreLine; } bool WhiteSpaceOrNewlineIsSignificant() const { return mWhiteSpace == mozilla::StyleWhiteSpace::Pre || mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap || mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces || mWhiteSpace == mozilla::StyleWhiteSpace::PreLine || mWhiteSpace == mozilla::StyleWhiteSpace::PreSpace; } bool TabIsSignificant() const { return mWhiteSpace == mozilla::StyleWhiteSpace::Pre || mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap || mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces; } bool WhiteSpaceCanWrapStyle() const { return mWhiteSpace == mozilla::StyleWhiteSpace::Normal || mWhiteSpace == mozilla::StyleWhiteSpace::PreWrap || mWhiteSpace == mozilla::StyleWhiteSpace::BreakSpaces || mWhiteSpace == mozilla::StyleWhiteSpace::PreLine; } bool WordCanWrapStyle() const { if (!WhiteSpaceCanWrapStyle()) { return false; } auto owrap = EffectiveOverflowWrap(); return owrap == mozilla::StyleOverflowWrap::BreakWord || owrap == mozilla::StyleOverflowWrap::Anywhere; } bool HasEffectiveTextEmphasis() const { if (mTextEmphasisStyle.IsNone()) { return false; } if (mTextEmphasisStyle.IsString() && mTextEmphasisStyle.AsString().AsString().IsEmpty()) { return false; } return true; } mozilla::StyleTextAlign TextAlignForLastLine() const { switch (mTextAlignLast) { case mozilla::StyleTextAlignLast::Auto: // 'text-align-last: auto' is equivalent to the value of the // 'text-align' property except when 'text-align' is set to 'justify', // in which case it is 'justify' when 'text-justify' is 'distribute' and // 'start' otherwise. // // XXX: the code below will have to change when we implement // text-justify if (mTextAlign == mozilla::StyleTextAlign::Justify) { return mozilla::StyleTextAlign::Start; } return mTextAlign; case mozilla::StyleTextAlignLast::Center: return mozilla::StyleTextAlign::Center; case mozilla::StyleTextAlignLast::Start: return mozilla::StyleTextAlign::Start; case mozilla::StyleTextAlignLast::End: return mozilla::StyleTextAlign::End; case mozilla::StyleTextAlignLast::Left: return mozilla::StyleTextAlign::Left; case mozilla::StyleTextAlignLast::Right: return mozilla::StyleTextAlign::Right; case mozilla::StyleTextAlignLast::Justify: return mozilla::StyleTextAlign::Justify; } return mozilla::StyleTextAlign::Start; } bool HasWebkitTextStroke() const { return mWebkitTextStrokeWidth > 0; } bool HasTextShadow() const { return !mTextShadow.IsEmpty(); } // The aContextFrame argument on each of these is the frame this // style struct is for. If the frame is for SVG text or inside ruby, // the return value will be massaged to be something that makes sense // for those cases. inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const; inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const; inline bool WordCanWrap(const nsIFrame* aContextFrame) const; mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM) const; }; struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility { explicit nsStyleVisibility(const mozilla::dom::Document&); nsStyleVisibility(const nsStyleVisibility& aVisibility); MOZ_COUNTED_DTOR(nsStyleVisibility) nsChangeHint CalcDifference(const nsStyleVisibility& aNewData) const; bool IsVisible() const { return mVisible == mozilla::StyleVisibility::Visible; } bool IsCollapse() const { return mVisible == mozilla::StyleVisibility::Collapse; } bool IsVisibleOrCollapsed() const { return mVisible == mozilla::StyleVisibility::Visible || mVisible == mozilla::StyleVisibility::Collapse; } bool UseLegacyCollapseBehavior() const { return mMozBoxCollapse == mozilla::StyleMozBoxCollapse::Legacy; } /** * Given an image request, returns the orientation that should be used * on the image. The returned orientation may differ from the style * struct's orientation member value, if the image request is not of the * same origin. * * @param aRequest The image request used to determine if same origin. */ mozilla::StyleImageOrientation UsedImageOrientation( imgIRequest* aRequest) const { return UsedImageOrientation(aRequest, mImageOrientation); } /** * Given an image request and an orientation, returns the orientation * that should be used on the image. The returned orientation may differ * from the input orientation if the image request is not of the same * origin. * * @param aRequest The image request used to determine if same origin. * @param aOrientation The input orientation. */ static mozilla::StyleImageOrientation UsedImageOrientation( imgIRequest* aRequest, mozilla::StyleImageOrientation aOrientation); static constexpr bool kHasTriggerImageLoads = false; mozilla::StyleDirection mDirection; mozilla::StyleVisibility mVisible; mozilla::StyleImageRendering mImageRendering; mozilla::StyleWritingModeProperty mWritingMode; mozilla::StyleTextOrientation mTextOrientation; mozilla::StyleMozBoxCollapse mMozBoxCollapse; mozilla::StylePrintColorAdjust mPrintColorAdjust; private: mozilla::StyleImageOrientation mImageOrientation; }; namespace mozilla { inline StyleTextTransform StyleTextTransform::None() { return StyleTextTransform{StyleTextTransformCase::None, StyleTextTransformOther()}; } inline bool StyleTextTransform::IsNone() const { return *this == None(); } // Note that IsAuto() does not exclude the possibility that `left` or `right` // is set; it refers only to behavior in horizontal typographic mode. inline bool StyleTextUnderlinePosition::IsAuto() const { return !(*this & (StyleTextUnderlinePosition::FROM_FONT | StyleTextUnderlinePosition::UNDER)); } inline bool StyleTextUnderlinePosition::IsFromFont() const { return bool(*this & StyleTextUnderlinePosition::FROM_FONT); } inline bool StyleTextUnderlinePosition::IsUnder() const { return bool(*this & StyleTextUnderlinePosition::UNDER); } inline bool StyleTextUnderlinePosition::IsLeft() const { return bool(*this & StyleTextUnderlinePosition::LEFT); } inline bool StyleTextUnderlinePosition::IsRight() const { return bool(*this & StyleTextUnderlinePosition::RIGHT); } struct StyleTransition { StyleTransition() = default; explicit StyleTransition(const StyleTransition& aCopy); void SetInitialValues(); // Delay and Duration are in milliseconds const StyleComputedTimingFunction& GetTimingFunction() const { return mTimingFunction; } const mozilla::StyleTime& GetDelay() const { return mDelay; } const mozilla::StyleTime& GetDuration() const { return mDuration; } nsCSSPropertyID GetProperty() const { return mProperty; } nsAtom* GetUnknownProperty() const { return mUnknownProperty; } bool operator==(const StyleTransition& aOther) const; bool operator!=(const StyleTransition& aOther) const { return !(*this == aOther); } private: StyleComputedTimingFunction mTimingFunction{ StyleComputedTimingFunction::LinearKeyword()}; mozilla::StyleTime mDuration{0.0}; mozilla::StyleTime mDelay{0.0}; nsCSSPropertyID mProperty; RefPtr mUnknownProperty; // used when mProperty is // eCSSProperty_UNKNOWN or // eCSSPropertyExtra_variable }; struct StyleAnimation { StyleAnimation() = default; explicit StyleAnimation(const StyleAnimation& aCopy); void SetInitialValues(); // Delay and Duration are in milliseconds const StyleComputedTimingFunction& GetTimingFunction() const { return mTimingFunction; } const mozilla::StyleTime& GetDelay() const { return mDelay; } const mozilla::StyleTime& GetDuration() const { return mDuration; } nsAtom* GetName() const { return mName; } dom::PlaybackDirection GetDirection() const { return mDirection; } dom::FillMode GetFillMode() const { return mFillMode; } StyleAnimationPlayState GetPlayState() const { return mPlayState; } float GetIterationCount() const { return mIterationCount._0; } dom::CompositeOperation GetComposition() const { return mComposition; } const StyleAnimationTimeline& GetTimeline() const { return mTimeline; } void SetName(already_AddRefed aName) { mName = aName; } void SetName(nsAtom* aName) { mName = aName; } bool operator==(const StyleAnimation& aOther) const; bool operator!=(const StyleAnimation& aOther) const { return !(*this == aOther); } private: StyleComputedTimingFunction mTimingFunction{ StyleComputedTimingFunction::LinearKeyword()}; StyleTime mDuration{0.0f}; StyleTime mDelay{0.0f}; RefPtr mName; // nsGkAtoms::_empty for 'none' dom::PlaybackDirection mDirection; dom::FillMode mFillMode; StyleAnimationPlayState mPlayState; StyleAnimationIterationCount mIterationCount; dom::CompositeOperation mComposition; StyleAnimationTimeline mTimeline{StyleAnimationTimeline::Auto()}; }; struct StyleScrollTimeline { StyleScrollTimeline() = default; explicit StyleScrollTimeline(const StyleScrollTimeline& aCopy) = default; // SetInitialValues() are called when ensuring the array length. So basically // we can rely on the default constructor to handle the new constructed // elements. void SetInitialValues() {} const nsAtom* GetName() const { return mName._0.AsAtom(); } StyleScrollAxis GetAxis() const { return mAxis; } bool operator==(const StyleScrollTimeline& aOther) const { return mName == aOther.mName && mAxis == aOther.mAxis; } bool operator!=(const StyleScrollTimeline& aOther) const { return !(*this == aOther); } private: StyleScrollTimelineName mName; StyleScrollAxis mAxis = StyleScrollAxis::Block; }; struct StyleViewTimeline { StyleViewTimeline() = default; explicit StyleViewTimeline(const StyleViewTimeline& aCopy) = default; // SetInitialValues() are called when ensuring the array length. So basically // we can rely on the default constructor to handle the new constructed // elements. void SetInitialValues() {} const nsAtom* GetName() const { return mName._0.AsAtom(); } StyleScrollAxis GetAxis() const { return mAxis; } const StyleViewTimelineInset& GetInset() const { return mInset; } bool operator==(const StyleViewTimeline& aOther) const { return mName == aOther.mName && mAxis == aOther.mAxis && mInset == aOther.mInset; } bool operator!=(const StyleViewTimeline& aOther) const { return !(*this == aOther); } private: StyleScrollTimelineName mName; StyleScrollAxis mAxis = StyleScrollAxis::Block; StyleViewTimelineInset mInset; }; } // namespace mozilla struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay { private: using StyleContain = mozilla::StyleContain; using StyleContentVisibility = mozilla::StyleContentVisibility; public: explicit nsStyleDisplay(const mozilla::dom::Document&); nsStyleDisplay(const nsStyleDisplay& aOther); ~nsStyleDisplay(); void TriggerImageLoads(mozilla::dom::Document&, const nsStyleDisplay*); static constexpr bool kHasTriggerImageLoads = true; nsChangeHint CalcDifference(const nsStyleDisplay& aNewData, const nsStylePosition& aOldPosition) const; nsChangeHint CalcTransformPropertyDifference( const nsStyleDisplay& aNewData) const; mozilla::StyleDisplay mDisplay; // Saved mDisplay for position:absolute/fixed and float:left/right; otherwise // equal to mDisplay. mozilla::StyleDisplay mOriginalDisplay; // Equal to mContain plus any implicit containment from mContentVisibility and // mContainerType. mozilla::StyleContentVisibility mContentVisibility; mozilla::StyleContainerType mContainerType; private: mozilla::StyleAppearance mAppearance; mozilla::StyleContain mContain; // Equal to mContain plus any implicit containment from mContentVisibility and // mContainerType. mozilla::StyleContain mEffectiveContainment; public: mozilla::StyleAppearance mDefaultAppearance; mozilla::StylePositionProperty mPosition; mozilla::StyleFloat mFloat; mozilla::StyleClear mClear; mozilla::StyleBreakWithin mBreakInside; mozilla::StyleBreakBetween mBreakBefore; mozilla::StyleBreakBetween mBreakAfter; mozilla::StyleOverflow mOverflowX; mozilla::StyleOverflow mOverflowY; mozilla::StyleOverflowClipBox mOverflowClipBoxBlock; mozilla::StyleOverflowClipBox mOverflowClipBoxInline; mozilla::StyleScrollbarGutter mScrollbarGutter; mozilla::StyleResize mResize; mozilla::StyleOrient mOrient; mozilla::StyleIsolation mIsolation; mozilla::StyleTopLayer mTopLayer; mozilla::StyleTouchAction mTouchAction; mozilla::StyleScrollBehavior mScrollBehavior; mozilla::StyleOverscrollBehavior mOverscrollBehaviorX; mozilla::StyleOverscrollBehavior mOverscrollBehaviorY; mozilla::StyleOverflowAnchor mOverflowAnchor; mozilla::StyleScrollSnapAlign mScrollSnapAlign; mozilla::StyleScrollSnapStop mScrollSnapStop; mozilla::StyleScrollSnapType mScrollSnapType; mozilla::StyleBackfaceVisibility mBackfaceVisibility; mozilla::StyleTransformStyle mTransformStyle; mozilla::StyleGeometryBox mTransformBox; mozilla::StyleTransform mTransform; mozilla::StyleRotate mRotate; mozilla::StyleTranslate mTranslate; mozilla::StyleScale mScale; mozilla::StyleContainerName mContainerName; mozilla::StyleWillChange mWillChange; mozilla::StyleOffsetPath mOffsetPath; mozilla::LengthPercentage mOffsetDistance; mozilla::StyleOffsetRotate mOffsetRotate; mozilla::StylePositionOrAuto mOffsetAnchor; mozilla::StyleOffsetPosition mOffsetPosition; mozilla::StyleTransformOrigin mTransformOrigin; mozilla::StylePerspective mChildPerspective; mozilla::Position mPerspectiveOrigin; mozilla::StyleVerticalAlign mVerticalAlign; mozilla::StyleBaselineSource mBaselineSource; mozilla::StyleLineClamp mWebkitLineClamp; // The threshold used for extracting a shape from shape-outside: . float mShapeImageThreshold = 0.0f; // The margin around a shape-outside: . mozilla::NonNegativeLengthPercentage mShapeMargin; mozilla::StyleShapeOutside mShapeOutside; mozilla::Maybe GetWindowButtonType() const { if (MOZ_LIKELY(mDefaultAppearance == mozilla::StyleAppearance::None)) { return mozilla::Nothing(); } switch (mDefaultAppearance) { case mozilla::StyleAppearance::MozWindowButtonMaximize: case mozilla::StyleAppearance::MozWindowButtonRestore: return Some(mozilla::WindowButtonType::Maximize); case mozilla::StyleAppearance::MozWindowButtonMinimize: return Some(mozilla::WindowButtonType::Minimize); case mozilla::StyleAppearance::MozWindowButtonClose: return Some(mozilla::WindowButtonType::Close); default: return mozilla::Nothing(); } } bool HasAppearance() const { return EffectiveAppearance() != mozilla::StyleAppearance::None; } mozilla::StyleAppearance EffectiveAppearance() const { if (MOZ_LIKELY(mAppearance == mozilla::StyleAppearance::None)) { return mAppearance; } switch (mAppearance) { case mozilla::StyleAppearance::Auto: case mozilla::StyleAppearance::Button: case mozilla::StyleAppearance::Searchfield: case mozilla::StyleAppearance::Textarea: case mozilla::StyleAppearance::Checkbox: case mozilla::StyleAppearance::Radio: case mozilla::StyleAppearance::Menulist: case mozilla::StyleAppearance::Listbox: case mozilla::StyleAppearance::Meter: case mozilla::StyleAppearance::ProgressBar: // These are all the values that behave like `auto`. return mDefaultAppearance; case mozilla::StyleAppearance::Textfield: // `appearance: textfield` should behave like `auto` on all elements // except
*/ struct nsPoint_Simple { nscoord x, y; }; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y); /** *
*/ struct nsMargin_Simple { nscoord top, right, bottom, left; }; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left); /** *
*/ struct nsRect_Simple { nscoord x, y, width, height; }; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height); /** *
*/ struct nsSize_Simple { nscoord width, height; }; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width); STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height); /** *
* * TODO(Emilio): This is a workaround and we should be able to get rid of this * one. */ template struct UniquePtr_Simple { T* mPtr; }; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(mozilla::UniquePtr, UniquePtr_Simple); /** *
*/ template class nsTArray_Simple { protected: T* mBuffer; public: ~nsTArray_Simple() { // The existence of a user-provided, and therefore non-trivial, destructor // here prevents bindgen from deriving the Clone trait via a simple memory // copy. } }; /** *
*/ template class CopyableTArray_Simple : public nsTArray_Simple {}; STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray, nsTArray_Simple); STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray, nsTArray_Simple); STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray, nsTArray_Simple); STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsTArray, nsTArray_Simple); #endif /* nsStyleStruct_h___ */