tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsStyleStruct.h (87694B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 /*
      8 * structs that contain the data provided by ComputedStyle, the
      9 * internal API for computed style data for an element
     10 */
     11 
     12 #ifndef nsStyleStruct_h___
     13 #define nsStyleStruct_h___
     14 
     15 #include <cstddef>  // offsetof()
     16 
     17 #include "CounterStyleManager.h"
     18 #include "UniqueOrNonOwningPtr.h"
     19 #include "X11UndefineNone.h"
     20 #include "imgIContainer.h"
     21 #include "imgRequestProxy.h"
     22 #include "mozilla/Assertions.h"
     23 #include "mozilla/Attributes.h"
     24 #include "mozilla/Likely.h"
     25 #include "mozilla/Maybe.h"
     26 #include "mozilla/WindowButtonType.h"
     27 #include "nsChangeHint.h"
     28 #include "nsColor.h"
     29 #include "nsCoord.h"
     30 #include "nsFont.h"
     31 #include "nsMargin.h"
     32 #include "nsStyleAutoArray.h"
     33 #include "nsStyleConsts.h"
     34 #include "nsTArray.h"
     35 
     36 class nsIFrame;
     37 class nsIURI;
     38 class nsTextFrame;
     39 struct nsStyleDisplay;
     40 struct nsStyleVisibility;
     41 class nsComputedDOMStyle;
     42 namespace mozilla {
     43 class ComputedStyle;
     44 struct AnchorPosResolutionCache;
     45 class AnchorPosReferenceData;
     46 struct IntrinsicSize;
     47 struct SizeComputationInput;
     48 
     49 }  // namespace mozilla
     50 
     51 namespace mozilla::dom {
     52 enum class CompositeOperation : uint8_t;
     53 }  // namespace mozilla::dom
     54 
     55 namespace mozilla {
     56 
     57 using Position = StylePosition;
     58 
     59 template <>
     60 inline bool StylePosition::HasPercent() const {
     61  return horizontal.HasPercent() || vertical.HasPercent();
     62 }
     63 
     64 /**
     65 * True if the effective background image position described by this depends on
     66 * the size of the corresponding frame.
     67 */
     68 template <>
     69 inline bool StylePosition::DependsOnPositioningAreaSize() const {
     70  return HasPercent();
     71 }
     72 
     73 template <>
     74 inline Position Position::FromPercentage(float aPercent) {
     75  return {LengthPercentage::FromPercentage(aPercent),
     76          LengthPercentage::FromPercentage(aPercent)};
     77 }
     78 
     79 /**
     80 * Convenience struct for querying if a given box has size-containment in
     81 * either axis.
     82 */
     83 struct ContainSizeAxes {
     84  ContainSizeAxes(bool aIContained, bool aBContained)
     85      : mIContained(aIContained), mBContained(aBContained) {}
     86 
     87  bool IsBoth() const { return mIContained && mBContained; }
     88  bool IsAny() const { return mIContained || mBContained; }
     89 
     90  bool operator==(const ContainSizeAxes&) const = default;
     91 
     92  /**
     93   * Return a contained size from an uncontained size.
     94   */
     95  nsSize ContainSize(const nsSize& aUncontainedSize,
     96                     const nsIFrame& aFrame) const;
     97  IntrinsicSize ContainIntrinsicSize(const IntrinsicSize& aUncontainedSize,
     98                                     const nsIFrame& aFrame) const;
     99  Maybe<nscoord> ContainIntrinsicBSize(const nsIFrame& aFrame,
    100                                       nscoord aNoneValue = 0) const;
    101  Maybe<nscoord> ContainIntrinsicISize(const nsIFrame& aFrame,
    102                                       nscoord aNoneValue = 0) const;
    103 
    104  const bool mIContained;
    105  const bool mBContained;
    106 };
    107 
    108 // Used value for the CSS 'float' property (logical 'inline-*' in the computed
    109 // value will have been resolved to 'left' or 'right').
    110 enum class UsedFloat : uint8_t {
    111  None,
    112  Left,
    113  Right,
    114 };
    115 
    116 // Used value for the CSS 'clear' property (logical 'inline-*' in the computed
    117 // value will have been resolved to 'left' or 'right').
    118 enum class UsedClear : uint8_t {
    119  None,
    120  Left,
    121  Right,
    122  Both,
    123 };
    124 
    125 }  // namespace mozilla
    126 
    127 #define STYLE_STRUCT(name_)                          \
    128  name_(const name_&);                               \
    129  MOZ_COUNTED_DTOR(name_);                           \
    130  void MarkLeaked() const { MOZ_COUNT_DTOR(name_); } \
    131  nsChangeHint CalcDifference(const name_&) const;
    132 
    133 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleFont {
    134  STYLE_STRUCT(nsStyleFont)
    135  explicit nsStyleFont(const mozilla::dom::Document&);
    136 
    137  /**
    138   * Return a given size multiplied by the current text zoom factor (in
    139   * aPresContext).
    140   *
    141   * The size is allowed to be negative, but the caller is expected to deal with
    142   * negative results.
    143   */
    144  static mozilla::Length ZoomText(const mozilla::dom::Document&,
    145                                  mozilla::Length);
    146 
    147  nsAtom* GetFontPaletteAtom() const { return mFontPalette._0.AsAtom(); }
    148 
    149  nsFont mFont;
    150 
    151  // Our "computed size". Can be different from mFont.size which is our "actual
    152  // size" and is enforced to be >= the user's preferred min-size.  mFont.size
    153  // should be used for display purposes while mSize is the value to return in
    154  // getComputedStyle() for example.
    155  mozilla::NonNegativeLength mSize;
    156 
    157  // In stylo these three track whether the size is keyword-derived
    158  // and if so if it has been modified by a factor/offset
    159  float mFontSizeFactor;
    160  mozilla::Length mFontSizeOffset;
    161  mozilla::StyleFontSizeKeyword mFontSizeKeyword;
    162  mozilla::StyleFontPalette mFontPalette;
    163  // math-depth support (used for MathML scriptlevel)
    164  int8_t mMathDepth;
    165  mozilla::StyleLineHeight mLineHeight;
    166  // allow different min font-size for certain cases
    167  mozilla::StylePercentage mMinFontSizeRatio{1.0f};
    168  // MathML  mathvariant support
    169  mozilla::StyleMathVariant mMathVariant;
    170  // math-style support (used for MathML displaystyle)
    171  mozilla::StyleMathStyle mMathStyle;
    172  // math-shift support (used for MathML cramped mode)
    173  mozilla::StyleMathShift mMathShift;
    174 
    175  // Was mLanguage set based on a lang attribute in the document?
    176  bool mExplicitLanguage = false;
    177 
    178  mozilla::StyleXTextScale mXTextScale;
    179 
    180  bool MinFontSizeEnabled() const {
    181    return mXTextScale == mozilla::StyleXTextScale::All;
    182  }
    183 
    184  // The value mSize would have had if scriptminsize had never been applied
    185  mozilla::NonNegativeLength mScriptUnconstrainedSize;
    186  mozilla::Length mScriptMinSize;
    187  RefPtr<nsAtom> mLanguage;
    188 };
    189 
    190 struct nsStyleImageLayers {
    191  enum class LayerType : uint8_t { Background = 0, Mask };
    192 
    193  explicit nsStyleImageLayers(LayerType aType);
    194  nsStyleImageLayers(const nsStyleImageLayers& aSource);
    195 
    196  struct Repeat {
    197    mozilla::StyleImageLayerRepeat mXRepeat =
    198        mozilla::StyleImageLayerRepeat::Repeat;
    199    mozilla::StyleImageLayerRepeat mYRepeat =
    200        mozilla::StyleImageLayerRepeat::Repeat;
    201 
    202    // Initialize nothing
    203    Repeat() = default;
    204 
    205    bool IsInitialValue() const {
    206      return mXRepeat == mozilla::StyleImageLayerRepeat::Repeat &&
    207             mYRepeat == mozilla::StyleImageLayerRepeat::Repeat;
    208    }
    209 
    210    bool DependsOnPositioningAreaSize() const {
    211      return mXRepeat == mozilla::StyleImageLayerRepeat::Space ||
    212             mYRepeat == mozilla::StyleImageLayerRepeat::Space;
    213    }
    214 
    215    bool operator==(const Repeat& aOther) const = default;
    216    bool operator!=(const Repeat& aOther) const = default;
    217  };
    218 
    219  struct Layer {
    220    using StyleGeometryBox = mozilla::StyleGeometryBox;
    221    using StyleImageLayerAttachment = mozilla::StyleImageLayerAttachment;
    222    using StyleBackgroundSize = mozilla::StyleBackgroundSize;
    223 
    224    mozilla::StyleImage mImage;
    225    mozilla::Position mPosition;
    226    StyleBackgroundSize mSize;
    227    StyleGeometryBox mClip;
    228    MOZ_INIT_OUTSIDE_CTOR StyleGeometryBox mOrigin;
    229 
    230    // This property is used for background layer only.
    231    // For a mask layer, it should always be the initial value, which is
    232    // StyleImageLayerAttachment::Scroll.
    233    StyleImageLayerAttachment mAttachment;
    234 
    235    // This property is used for background layer only.
    236    // For a mask layer, it should always be the initial value, which is
    237    // StyleBlend::Normal.
    238    mozilla::StyleBlend mBlendMode;
    239 
    240    // This property is used for mask layer only.
    241    // For a background layer, it should always be the initial value, which is
    242    // StyleMaskComposite::Add.
    243    mozilla::StyleMaskComposite mComposite;
    244 
    245    // mask-only property. This property is used for mask layer only. For a
    246    // background layer, it should always be the initial value, which is
    247    // StyleMaskMode::MatchSource.
    248    mozilla::StyleMaskMode mMaskMode;
    249 
    250    Repeat mRepeat;
    251 
    252    // This constructor does not initialize mRepeat or mOrigin and Initialize()
    253    // must be called to do that.
    254    Layer();
    255    ~Layer();
    256 
    257    // Initialize mRepeat and mOrigin by specified layer type
    258    void Initialize(LayerType aType);
    259 
    260    void ResolveImage(mozilla::dom::Document& aDocument,
    261                      const Layer* aOldLayer) {
    262      mImage.ResolveImage(aDocument, aOldLayer ? &aOldLayer->mImage : nullptr);
    263    }
    264 
    265    // True if the rendering of this layer might change when the size
    266    // of the background positioning area changes.  This is true for any
    267    // non-solid-color background whose position or size depends on
    268    // the size of the positioning area.  It's also true for SVG images
    269    // whose root <svg> node has a viewBox.
    270    bool RenderingMightDependOnPositioningAreaSizeChange() const;
    271 
    272    // Compute the change hint required by changes in just this layer.
    273    nsChangeHint CalcDifference(const Layer& aNewLayer) const;
    274 
    275    // An equality operator that compares the images using URL-equality
    276    // rather than pointer-equality.
    277    bool operator==(const Layer& aOther) const;
    278    bool operator!=(const Layer& aOther) const = default;
    279  };
    280 
    281  // The (positive) number of computed values of each property, since
    282  // the lengths of the lists are independent.
    283  uint32_t mAttachmentCount;
    284  uint32_t mClipCount;
    285  uint32_t mOriginCount;
    286  uint32_t mRepeatCount;
    287  uint32_t mPositionXCount;
    288  uint32_t mPositionYCount;
    289  uint32_t mImageCount;
    290  uint32_t mSizeCount;
    291  uint32_t mMaskModeCount;
    292  uint32_t mBlendModeCount;
    293  uint32_t mCompositeCount;
    294 
    295  // Layers are stored in an array, matching the top-to-bottom order in
    296  // which they are specified in CSS.  The number of layers to be used
    297  // should come from the background-image property.  We create
    298  // additional |Layer| objects for *any* property, not just
    299  // background-image.  This means that the bottommost layer that
    300  // callers in layout care about (which is also the one whose
    301  // background-clip applies to the background-color) may not be last
    302  // layer.  In layers below the bottom layer, properties will be
    303  // uninitialized unless their count, above, indicates that they are
    304  // present.
    305  nsStyleAutoArray<Layer> mLayers;
    306 
    307  const Layer& BottomLayer() const { return mLayers[mImageCount - 1]; }
    308 
    309  void ResolveImages(mozilla::dom::Document& aDocument,
    310                     const nsStyleImageLayers* aOldLayers) {
    311    for (uint32_t i = 0; i < mImageCount; ++i) {
    312      const Layer* oldLayer = (aOldLayers && aOldLayers->mLayers.Length() > i)
    313                                  ? &aOldLayers->mLayers[i]
    314                                  : nullptr;
    315      mLayers[i].ResolveImage(aDocument, oldLayer);
    316    }
    317  }
    318 
    319  // Fill unspecified layers by cycling through their values
    320  // till they all are of length aMaxItemCount
    321  void FillAllLayers(uint32_t aMaxItemCount);
    322 
    323  nsChangeHint CalcDifference(const nsStyleImageLayers& aNewLayers,
    324                              nsStyleImageLayers::LayerType aType) const;
    325 
    326  nsStyleImageLayers& operator=(const nsStyleImageLayers& aOther);
    327  nsStyleImageLayers& operator=(nsStyleImageLayers&& aOther) = default;
    328  bool operator==(const nsStyleImageLayers& aOther) const;
    329 
    330  static const NonCustomCSSPropertyId kBackgroundLayerTable[];
    331  static const NonCustomCSSPropertyId kMaskLayerTable[];
    332 
    333 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT(var_, layers_) \
    334  for (uint32_t var_ = (layers_).mImageCount; (var_)-- != 0;)
    335 #define NS_FOR_VISIBLE_IMAGE_LAYERS_BACK_TO_FRONT_WITH_RANGE(var_, layers_,  \
    336                                                             start_, count_) \
    337  NS_ASSERTION(                                                              \
    338      (int32_t)(start_) >= 0 && (uint32_t)(start_) < (layers_).mImageCount,  \
    339      "Invalid layer start!");                                               \
    340  NS_ASSERTION((count_) > 0 && (count_) <= (start_) + 1,                     \
    341               "Invalid layer range!");                                      \
    342  for (uint32_t var_ = (start_) + 1;                                         \
    343       (var_)-- != (uint32_t)((start_) + 1 - (count_));)
    344 };
    345 
    346 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBackground {
    347  STYLE_STRUCT(nsStyleBackground)
    348  nsStyleBackground();
    349  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBackground*);
    350 
    351  // Return the background color as nscolor.
    352  nscolor BackgroundColor(const nsIFrame* aFrame) const;
    353  nscolor BackgroundColor(const mozilla::ComputedStyle* aStyle) const;
    354 
    355  // True if this background is completely transparent.
    356  bool IsTransparent(const nsIFrame* aFrame) const;
    357  bool IsTransparent(const mozilla::ComputedStyle* aStyle) const;
    358 
    359  // We have to take slower codepaths for fixed background attachment,
    360  // but we don't want to do that when there's no image.
    361  // Not inline because it uses an nsCOMPtr<imgIRequest>
    362  // FIXME: Should be in nsStyleStructInlines.h.
    363  bool HasFixedBackground(nsIFrame* aFrame) const;
    364 
    365  // Checks to see if this has a non-empty image with "local" attachment.
    366  // This is defined in nsStyleStructInlines.h.
    367  inline bool HasLocalBackground() const;
    368 
    369  const nsStyleImageLayers::Layer& BottomLayer() const {
    370    return mImage.BottomLayer();
    371  }
    372 
    373  nsStyleImageLayers mImage;
    374  mozilla::StyleColor mBackgroundColor;
    375 };
    376 
    377 using AnchorResolvedMargin =
    378    mozilla::UniqueOrNonOwningPtr<const mozilla::StyleMargin>;
    379 
    380 // Base set of parameters required to resolve a reference to an anchor.
    381 struct AnchorPosResolutionParams {
    382  struct AutoResolutionOverrideParams {
    383    // Whether anchor-center is being used on the horizontal axis.
    384    bool mHAnchorCenter = false;
    385    // Whether anchor-center is being used on the vertical axis.
    386    bool mVAnchorCenter = false;
    387    // Whether position-area is being used.
    388    bool mPositionAreaInUse = false;
    389 
    390    AutoResolutionOverrideParams() = default;
    391    AutoResolutionOverrideParams(
    392        const nsIFrame* aFrame,
    393        const mozilla::AnchorPosResolutionCache* aCache);
    394    explicit AutoResolutionOverrideParams(const nsIFrame* aFrame);
    395 
    396    bool OverriddenToZero(mozilla::StylePhysicalAxis aAxis) const;
    397  };
    398  // Frame of the anchor positioned element.
    399  // If nullptr, skips anchor lookup and returns invalid, resolving fallbacks.
    400  const nsIFrame* mFrame;
    401  // Position property of the element in question.
    402  mozilla::StylePositionProperty mPosition;
    403  // Cache data used for anchor resolution.
    404  mozilla::AnchorPosResolutionCache* const mCache;
    405  // Set of parameters that override `auto` values to 0, if the default
    406  // anchor is valid.
    407  AutoResolutionOverrideParams mAutoResolutionOverrideParams;
    408 
    409  // Helper functions for creating anchor resolution parameters.
    410  // Defined in corresponding header files.
    411  static inline AnchorPosResolutionParams From(
    412      const nsIFrame* aFrame,
    413      mozilla::AnchorPosResolutionCache* aAnchorPosResolutionCache = nullptr);
    414  static AnchorPosResolutionParams From(
    415      const mozilla::SizeComputationInput* aSizingInput,
    416      bool aIgnorePositionArea = false);
    417  static inline AnchorPosResolutionParams From(
    418      const nsComputedDOMStyle* aComputedDOMStyle);
    419 };
    420 
    421 struct AnchorResolvedMarginHelper {
    422  static const mozilla::StyleMargin& ZeroValue() {
    423    static const auto value = mozilla::StyleMargin::LengthPercentage(
    424        mozilla::StyleLengthPercentage::Zero());
    425    return value;
    426  }
    427 
    428  static AnchorResolvedMargin FromUnresolved(
    429      const mozilla::StyleMargin& aValue, mozilla::StylePhysicalAxis aAxis,
    430      const AnchorPosResolutionParams& aParams) {
    431    auto resolved = [&]() {
    432      if (aValue.HasAnchorPositioningFunction()) {
    433        return ResolveAnchor(aValue, aAxis, aParams);
    434      }
    435      return AnchorResolvedMargin::NonOwning(&aValue);
    436    }();
    437    if (resolved->IsAuto() &&
    438        aParams.mAutoResolutionOverrideParams.OverriddenToZero(aAxis)) {
    439      return Zero();
    440    }
    441    return resolved;
    442  }
    443 
    444 private:
    445  static AnchorResolvedMargin Zero() {
    446    return AnchorResolvedMargin::NonOwning(&ZeroValue());
    447  }
    448 
    449  static AnchorResolvedMargin ResolveAnchor(
    450      const mozilla::StyleMargin& aValue, mozilla::StylePhysicalAxis aAxis,
    451      const AnchorPosResolutionParams& aParams);
    452 };
    453 
    454 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleMargin {
    455  STYLE_STRUCT(nsStyleMargin)
    456  nsStyleMargin();
    457 
    458  // Returns false if any margin is layout-dependent in any way.
    459  // Percentage values and/or `anchor-size()` will do this.
    460  bool GetMargin(nsMargin& aMargin) const {
    461    bool convertsToLength = mMargin.All(
    462        [](const auto& aLength) { return aLength.ConvertsToLength(); });
    463 
    464    if (!convertsToLength) {
    465      return false;
    466    }
    467 
    468    for (const auto side : mozilla::AllPhysicalSides()) {
    469      aMargin.Side(side) = mMargin.Get(side).AsLengthPercentage().ToLength();
    470    }
    471    return true;
    472  }
    473 
    474  nsMargin GetScrollMargin() const {
    475    return nsMargin(mScrollMargin.Get(mozilla::eSideTop).ToAppUnits(),
    476                    mScrollMargin.Get(mozilla::eSideRight).ToAppUnits(),
    477                    mScrollMargin.Get(mozilla::eSideBottom).ToAppUnits(),
    478                    mScrollMargin.Get(mozilla::eSideLeft).ToAppUnits());
    479  }
    480 
    481  // Return true if either the start or end side in the axis is 'auto'.
    482  // (defined in WritingModes.h since we need the full WritingMode type)
    483  inline bool HasBlockAxisAuto(mozilla::WritingMode aWM,
    484                               const AnchorPosResolutionParams& aParams) const;
    485  inline bool HasInlineAxisAuto(mozilla::WritingMode aWM,
    486                                const AnchorPosResolutionParams& aParams) const;
    487  inline bool HasAuto(mozilla::LogicalAxis, mozilla::WritingMode,
    488                      const AnchorPosResolutionParams& aParams) const;
    489 
    490  // Attempt to return the resolved margin, resolving anchor functions, and
    491  // using a dummy percentage basis. If the resulting value returns true for
    492  // `HasPercent`, percentage value needs to be resolved with a proper basis at
    493  // a later point.
    494  AnchorResolvedMargin GetMargin(
    495      mozilla::Side aSide, const AnchorPosResolutionParams& aParams) const {
    496    return AnchorResolvedMarginHelper::FromUnresolved(
    497        mMargin.Get(aSide), mozilla::ToStylePhysicalAxis(aSide), aParams);
    498  }
    499 
    500  bool MarginEquals(const nsStyleMargin& aOther) const {
    501    for (const auto side : mozilla::AllPhysicalSides()) {
    502      if (mMargin.Get(side) != aOther.mMargin.Get(side)) {
    503        return false;
    504      }
    505    }
    506    return true;
    507  }
    508 
    509  // As with other logical-coordinate accessors, definitions for these
    510  // are found in WritingModes.h.
    511  inline AnchorResolvedMargin GetMargin(
    512      mozilla::LogicalSide aSide, mozilla::WritingMode aWM,
    513      const AnchorPosResolutionParams& aParams) const;
    514 
    515  mozilla::StyleRect<mozilla::StyleMargin> mMargin;
    516  mozilla::StyleRect<mozilla::StyleLength> mScrollMargin;
    517  // TODO: Add support per-axis/side clipping, see
    518  // https://github.com/w3c/csswg-drafts/issues/7245
    519  mozilla::StyleOverflowClipMargin mOverflowClipMargin;
    520 };
    521 
    522 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePadding {
    523  STYLE_STRUCT(nsStylePadding)
    524  nsStylePadding();
    525 
    526  mozilla::StyleRect<mozilla::NonNegativeLengthPercentage> mPadding;
    527  mozilla::StyleRect<mozilla::NonNegativeLengthPercentageOrAuto> mScrollPadding;
    528 
    529  inline bool IsWidthDependent() const {
    530    return !mPadding.All(
    531        [](const auto& aLength) { return aLength.ConvertsToLength(); });
    532  }
    533 
    534  bool GetPadding(nsMargin& aPadding) const {
    535    if (IsWidthDependent()) {
    536      return false;
    537    }
    538 
    539    for (const auto side : mozilla::AllPhysicalSides()) {
    540      // Clamp negative calc() to 0.
    541      aPadding.Side(side) = std::max(mPadding.Get(side).ToLength(), 0);
    542    }
    543    return true;
    544  }
    545 };
    546 
    547 // Border widths are rounded to the nearest-below integer number of pixels,
    548 // but values between zero and one device pixels are always rounded up to
    549 // one device pixel.
    550 #define NS_ROUND_BORDER_TO_PIXELS(l, tpp) \
    551  ((l) == 0) ? 0 : std::max((tpp), (l) / (tpp) * (tpp))
    552 
    553 // Returns if the given border style type is visible or not
    554 static inline bool IsVisibleBorderStyle(mozilla::StyleBorderStyle aStyle) {
    555  return aStyle != mozilla::StyleBorderStyle::None &&
    556         aStyle != mozilla::StyleBorderStyle::Hidden;
    557 }
    558 
    559 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleBorder {
    560  STYLE_STRUCT(nsStyleBorder)
    561  nsStyleBorder();
    562  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleBorder*);
    563 
    564  // Return whether aStyle is a visible style.  Invisible styles cause
    565  // the relevant computed border width to be 0.
    566  // Note that this does *not* consider the effects of 'border-image':
    567  // if border-style is none, but there is a loaded border image,
    568  // HasVisibleStyle will be false even though there *is* a border.
    569  bool HasVisibleStyle(mozilla::Side aSide) const {
    570    return IsVisibleBorderStyle(mBorderStyle.Get(aSide));
    571  }
    572 
    573  // aBorderWidth is in twips
    574  void SetBorderWidth(mozilla::Side aSide, nscoord aBorderWidth,
    575                      nscoord aAppUnitsPerDevPixel) {
    576    mBorder.Get(aSide) =
    577        NS_ROUND_BORDER_TO_PIXELS(aBorderWidth, aAppUnitsPerDevPixel);
    578  }
    579 
    580  // Get the computed border (plus rounding).
    581  nsMargin GetComputedBorder() const {
    582    nsMargin border(mBorder._0, mBorder._1, mBorder._2, mBorder._3);
    583    for (auto side : mozilla::AllPhysicalSides()) {
    584      if (!HasVisibleStyle(side)) {
    585        border.Side(side) = 0;
    586      }
    587    }
    588    return border;
    589  }
    590 
    591  bool HasBorder() const {
    592    for (auto side : mozilla::AllPhysicalSides()) {
    593      if (mBorder.Get(side) && HasVisibleStyle(side)) {
    594        return true;
    595      }
    596    }
    597    return !mBorderImageSource.IsNone();
    598  }
    599 
    600  // Get the actual border width for a particular side, in appunits.  Note that
    601  // this is zero if and only if there is no border to be painted for this
    602  // side.  That is, this value takes into account the border style and the
    603  // value is rounded to the nearest device pixel by NS_ROUND_BORDER_TO_PIXELS.
    604  nscoord GetComputedBorderWidth(mozilla::Side aSide) const {
    605    if (!HasVisibleStyle(aSide)) {
    606      return 0;
    607    }
    608    return mBorder.Get(aSide);
    609  }
    610 
    611  mozilla::StyleBorderStyle GetBorderStyle(mozilla::Side aSide) const {
    612    NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
    613    return mBorderStyle.Get(aSide);
    614  }
    615 
    616  void SetBorderStyle(mozilla::Side aSide, mozilla::StyleBorderStyle aStyle) {
    617    NS_ASSERTION(aSide <= mozilla::eSideLeft, "bad side");
    618    mBorderStyle.Get(aSide) = aStyle;
    619  }
    620 
    621  inline bool IsBorderImageSizeAvailable() const {
    622    return mBorderImageSource.IsSizeAvailable();
    623  }
    624 
    625  nsMargin GetImageOutset() const;
    626 
    627  imgIRequest* GetBorderImageRequest() const {
    628    return mBorderImageSource.GetImageRequest();
    629  }
    630 
    631 public:
    632  mozilla::StyleBorderRadius mBorderRadius;  // coord, percent
    633  mozilla::StyleImage mBorderImageSource;
    634  mozilla::StyleBorderImageWidth mBorderImageWidth;
    635  mozilla::StyleNonNegativeLengthOrNumberRect mBorderImageOutset;
    636  mozilla::StyleBorderImageSlice mBorderImageSlice;  // factor, percent
    637  mozilla::StyleBorderImageRepeat mBorderImageRepeat;
    638  mozilla::StyleFloatEdge mFloatEdge;
    639  mozilla::StyleBoxDecorationBreak mBoxDecorationBreak;
    640 
    641 protected:
    642  mozilla::StyleRect<mozilla::StyleBorderStyle> mBorderStyle;
    643  mozilla::StyleRect<mozilla::StyleBorderSideWidth> mBorder;
    644 
    645 public:
    646  // the colors to use for a simple border.
    647  // not used for -moz-border-colors
    648  mozilla::StyleColor mBorderTopColor;
    649  mozilla::StyleColor mBorderRightColor;
    650  mozilla::StyleColor mBorderBottomColor;
    651  mozilla::StyleColor mBorderLeftColor;
    652 
    653  mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) {
    654    switch (aSide) {
    655      case mozilla::eSideTop:
    656        return mBorderTopColor;
    657      case mozilla::eSideRight:
    658        return mBorderRightColor;
    659      case mozilla::eSideBottom:
    660        return mBorderBottomColor;
    661      case mozilla::eSideLeft:
    662        return mBorderLeftColor;
    663    }
    664    MOZ_ASSERT_UNREACHABLE("Unknown side");
    665    return mBorderTopColor;
    666  }
    667 
    668  const mozilla::StyleColor& BorderColorFor(mozilla::Side aSide) const {
    669    switch (aSide) {
    670      case mozilla::eSideTop:
    671        return mBorderTopColor;
    672      case mozilla::eSideRight:
    673        return mBorderRightColor;
    674      case mozilla::eSideBottom:
    675        return mBorderBottomColor;
    676      case mozilla::eSideLeft:
    677        return mBorderLeftColor;
    678    }
    679    MOZ_ASSERT_UNREACHABLE("Unknown side");
    680    return mBorderTopColor;
    681  }
    682 
    683  static mozilla::StyleColor nsStyleBorder::* BorderColorFieldFor(
    684      mozilla::Side aSide) {
    685    switch (aSide) {
    686      case mozilla::eSideTop:
    687        return &nsStyleBorder::mBorderTopColor;
    688      case mozilla::eSideRight:
    689        return &nsStyleBorder::mBorderRightColor;
    690      case mozilla::eSideBottom:
    691        return &nsStyleBorder::mBorderBottomColor;
    692      case mozilla::eSideLeft:
    693        return &nsStyleBorder::mBorderLeftColor;
    694    }
    695    MOZ_ASSERT_UNREACHABLE("Unknown side");
    696    return nullptr;
    697  }
    698 
    699  nsStyleBorder& operator=(const nsStyleBorder&) = delete;
    700 };
    701 
    702 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleOutline {
    703  STYLE_STRUCT(nsStyleOutline)
    704  nsStyleOutline();
    705 
    706  mozilla::StyleBorderSideWidth mOutlineWidth;
    707  mozilla::StyleAu mOutlineOffset;
    708  mozilla::StyleColor mOutlineColor;
    709  mozilla::StyleOutlineStyle mOutlineStyle;
    710 
    711  bool ShouldPaintOutline() const {
    712    if (mOutlineStyle.IsAuto()) {
    713      return true;
    714    }
    715    if (!IsVisibleBorderStyle(mOutlineStyle.AsBorderStyle())) {
    716      return false;
    717    }
    718    return mOutlineWidth > 0;
    719  }
    720 
    721  nsSize EffectiveOffsetFor(const nsRect& aRect) const;
    722 };
    723 
    724 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleList {
    725  STYLE_STRUCT(nsStyleList)
    726  nsStyleList();
    727 
    728  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleList*);
    729 
    730  nsStyleList& operator=(const nsStyleList& aOther) = delete;
    731  nsChangeHint CalcDifference(const nsStyleList& aNewData,
    732                              const mozilla::ComputedStyle& aOldStyle) const;
    733 
    734  mozilla::StyleListStylePosition mListStylePosition;
    735 
    736  mozilla::StyleListStyleType mListStyleType;
    737  mozilla::StyleQuotes mQuotes;
    738  mozilla::StyleImage mListStyleImage;
    739 };
    740 
    741 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePage {
    742  STYLE_STRUCT(nsStylePage)
    743  MOZ_COUNTED_DEFAULT_CTOR(nsStylePage)
    744 
    745  using StylePageOrientation = mozilla::StylePageOrientation;
    746  using StylePageSize = mozilla::StylePageSize;
    747  using StylePageName = mozilla::StylePageName;
    748 
    749  // page-size property.
    750  StylePageSize mSize = StylePageSize::Auto();
    751  // page-name property.
    752  StylePageName mPage = StylePageName::Auto();
    753  // page-orientation property.
    754  StylePageOrientation mPageOrientation = StylePageOrientation::Upright;
    755 };
    756 
    757 using AnchorResolvedInset =
    758    mozilla::UniqueOrNonOwningPtr<const mozilla::StyleInset>;
    759 
    760 // Set of parameters required to resolve the anchor's position offset in a
    761 // containing block.
    762 struct AnchorPosOffsetResolutionParams {
    763  // Size of the containing block for the anchor positioned element.
    764  // This needs to be set only if all of the following conditions are true:
    765  //
    766  //   * The resolution is happening during reflow (i.e. Containing block
    767  //   doesn't have its rect set)
    768  //   * The caller needs the correct size, not just its type (e.g. Just
    769  //     checking `HasPercent()` of the inset resolved value)
    770  const mozilla::LogicalSize* mCBSize;
    771  AnchorPosResolutionParams mBaseParams;
    772 
    773  static AnchorPosOffsetResolutionParams UseCBFrameSize(
    774      const AnchorPosResolutionParams& aBaseParams) {
    775    return {aBaseParams, nullptr};
    776  }
    777 
    778  static AnchorPosOffsetResolutionParams ExplicitCBFrameSize(
    779      const AnchorPosResolutionParams& aBaseParams,
    780      const mozilla::LogicalSize* aCBSize) {
    781    return {aBaseParams, aCBSize};
    782  }
    783 
    784 private:
    785  AnchorPosOffsetResolutionParams(const AnchorPosResolutionParams& aBaseParams,
    786                                  const mozilla::LogicalSize* aCBSize)
    787      : mCBSize{aCBSize}, mBaseParams{aBaseParams} {}
    788 };
    789 
    790 struct AnchorResolvedInsetHelper {
    791  static const mozilla::StyleInset& AutoValue() {
    792    static const auto value = mozilla::StyleInset::Auto();
    793    return value;
    794  }
    795 
    796  static const mozilla::StyleInset& ZeroValue() {
    797    static const auto value = mozilla::StyleInset::LengthPercentage(
    798        mozilla::StyleLengthPercentage::Zero());
    799    return value;
    800  }
    801 
    802  static AnchorResolvedInset FromUnresolved(
    803      const mozilla::StyleInset& aValue, mozilla::Side aSide,
    804      const AnchorPosOffsetResolutionParams& aParams) {
    805    auto resolved = [&]() {
    806      if (aValue.HasAnchorPositioningFunction()) {
    807        return ResolveAnchor(aValue, mozilla::ToStylePhysicalSide(aSide),
    808                             aParams);
    809      }
    810      return AnchorResolvedInset::NonOwning(&aValue);
    811    }();
    812    if (resolved->IsAuto() &&
    813        aParams.mBaseParams.mAutoResolutionOverrideParams.OverriddenToZero(
    814            mozilla::ToStylePhysicalAxis(aSide))) {
    815      return AnchorResolvedInset::NonOwning(&ZeroValue());
    816    }
    817    return resolved;
    818  }
    819 
    820 private:
    821  static AnchorResolvedInset Auto() {
    822    return AnchorResolvedInset::NonOwning(&AutoValue());
    823  }
    824 
    825  static AnchorResolvedInset ResolveAnchor(
    826      const mozilla::StyleInset& aValue, mozilla::StylePhysicalSide aSide,
    827      const AnchorPosOffsetResolutionParams& aParams);
    828 };
    829 
    830 using AnchorResolvedSize =
    831    mozilla::UniqueOrNonOwningPtr<const mozilla::StyleSize>;
    832 
    833 struct AnchorResolvedSizeHelper {
    834  static const mozilla::StyleSize& ZeroValue() {
    835    static const auto value = mozilla::StyleSize::LengthPercentage(
    836        mozilla::StyleLengthPercentage::Zero());
    837    return value;
    838  }
    839 
    840  static const mozilla::StyleSize& MinContentValue() {
    841    static const auto value = mozilla::StyleSize::MinContent();
    842    return value;
    843  }
    844 
    845  static const mozilla::StyleSize& AutoValue() {
    846    static const auto value = mozilla::StyleSize::Auto();
    847    return value;
    848  }
    849 
    850  static AnchorResolvedSize FromUnresolved(
    851      const mozilla::StyleSize& aValue, mozilla::StylePhysicalAxis aAxis,
    852      const AnchorPosResolutionParams& aParams) {
    853    if (aValue.HasAnchorPositioningFunction()) {
    854      return ResolveAnchor(aValue, aAxis, aParams);
    855    }
    856    return AnchorResolvedSize::NonOwning(&aValue);
    857  }
    858 
    859  static AnchorResolvedSize Overridden(const mozilla::StyleSize& aSize) {
    860    return AnchorResolvedSize::NonOwning(&aSize);
    861  }
    862 
    863  static AnchorResolvedSize Zero() {
    864    return AnchorResolvedSize::NonOwning(&ZeroValue());
    865  }
    866 
    867  static AnchorResolvedSize MinContent() {
    868    return AnchorResolvedSize::NonOwning(&MinContentValue());
    869  }
    870 
    871  static AnchorResolvedSize Auto() {
    872    return AnchorResolvedSize::NonOwning(&AutoValue());
    873  }
    874 
    875  static AnchorResolvedSize LengthPercentage(
    876      const mozilla::StyleLengthPercentage& aLP) {
    877    return mozilla::MakeUniqueOfUniqueOrNonOwning<const mozilla::StyleSize>(
    878        aLP);
    879  }
    880 
    881 private:
    882  static AnchorResolvedSize ResolveAnchor(
    883      const mozilla::StyleSize& aValue, mozilla::StylePhysicalAxis aAxis,
    884      const AnchorPosResolutionParams& aParams);
    885 };
    886 
    887 using AnchorResolvedMaxSize =
    888    mozilla::UniqueOrNonOwningPtr<const mozilla::StyleMaxSize>;
    889 
    890 struct AnchorResolvedMaxSizeHelper {
    891  static const mozilla::StyleMaxSize& MaxContentValue() {
    892    static const auto value = mozilla::StyleMaxSize::MaxContent();
    893    return value;
    894  }
    895  static const mozilla::StyleMaxSize& NoneValue() {
    896    static const auto value = mozilla::StyleMaxSize::None();
    897    return value;
    898  }
    899 
    900  static AnchorResolvedMaxSize FromUnresolved(
    901      const mozilla::StyleMaxSize& aValue, mozilla::StylePhysicalAxis aAxis,
    902      const AnchorPosResolutionParams& aParams) {
    903    if (aValue.HasAnchorPositioningFunction()) {
    904      return ResolveAnchor(aValue, aAxis, aParams);
    905    }
    906    return AnchorResolvedMaxSize::NonOwning(&aValue);
    907  }
    908  static AnchorResolvedMaxSize MaxContent() {
    909    return AnchorResolvedMaxSize::NonOwning(&MaxContentValue());
    910  }
    911 
    912  static AnchorResolvedMaxSize None() {
    913    return AnchorResolvedMaxSize::NonOwning(&NoneValue());
    914  }
    915 
    916 private:
    917  static AnchorResolvedMaxSize ResolveAnchor(
    918      const mozilla::StyleMaxSize& aValue, mozilla::StylePhysicalAxis aAxis,
    919      const AnchorPosResolutionParams& aParams);
    920 };
    921 
    922 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStylePosition {
    923  STYLE_STRUCT(nsStylePosition)
    924  nsStylePosition();
    925 
    926  using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
    927  using Position = mozilla::Position;
    928  template <typename T>
    929  using StyleRect = mozilla::StyleRect<T>;
    930  using StyleSize = mozilla::StyleSize;
    931  using StyleMaxSize = mozilla::StyleMaxSize;
    932  using WritingMode = mozilla::WritingMode;
    933  using LogicalAxis = mozilla::LogicalAxis;
    934  using StyleImplicitGridTracks = mozilla::StyleImplicitGridTracks;
    935  using ComputedStyle = mozilla::ComputedStyle;
    936  using StyleSelfAlignment = mozilla::StyleSelfAlignment;
    937 
    938  nsChangeHint CalcDifference(const nsStylePosition& aNewData,
    939                              const ComputedStyle& aOldStyle) const;
    940 
    941  // Returns whether we need to compute an hypothetical position if we were
    942  // absolutely positioned.
    943  bool NeedsHypotheticalPositionIfAbsPos() const {
    944    // NOTE(dshin): By passing in nullptr for frames, we're guaranteeing that
    945    // no anchor is found, instead considering fallbacks or anchor-invalid
    946    // values. Since anchor resolved value can never be auto, this is
    947    // guaranteed to be correct, if not pessimistic.
    948    // TODO(dshin): Probably nicer if we try to resolve. Two tricky parts:
    949    //   * `CalcDifference`: Need to pass in the changing frame somehow.
    950    //   * Reflow cases where containing block is not yet set (Mainly when
    951    //     `nsBlockFrame` is about to run another reflow for clearance)
    952    const auto anchorResolutionParams =
    953        AnchorPosOffsetResolutionParams::UseCBFrameSize(
    954            {nullptr, mozilla::StylePositionProperty::Absolute});
    955    return (GetAnchorResolvedInset(mozilla::eSideRight, anchorResolutionParams)
    956                ->IsAuto() &&
    957            GetAnchorResolvedInset(mozilla::eSideLeft, anchorResolutionParams)
    958                ->IsAuto()) ||
    959           (GetAnchorResolvedInset(mozilla::eSideTop, anchorResolutionParams)
    960                ->IsAuto() &&
    961            GetAnchorResolvedInset(mozilla::eSideBottom, anchorResolutionParams)
    962                ->IsAuto());
    963  }
    964 
    965  const mozilla::StyleContainIntrinsicSize& ContainIntrinsicBSize(
    966      const WritingMode& aWM) const;
    967  const mozilla::StyleContainIntrinsicSize& ContainIntrinsicISize(
    968      const WritingMode& aWM) const;
    969 
    970  /**
    971   * Return the used value for 'align-self' given our parent ComputedStyle
    972   * (or null for the root).
    973   */
    974  StyleSelfAlignment UsedAlignSelf(const ComputedStyle*) const;
    975 
    976  /**
    977   * Return the used value for 'justify-self' given our parent ComputedStyle
    978   * aParent (or null for the root).
    979   */
    980  StyleSelfAlignment UsedJustifySelf(const ComputedStyle*) const;
    981 
    982  /**
    983   * Return the used value for 'justify/align-self' for the axis in the
    984   * alignment container's writing mode.
    985   *
    986   * @param aAlignContainerStyle the computed style of the alignment container,
    987   *        or null for the root.
    988   *
    989   * (defined in WritingModes.h since we need the full WritingMode type)
    990   */
    991  inline mozilla::StyleAlignFlags UsedSelfAlignment(
    992      LogicalAxis aAlignContainerAxis,
    993      const mozilla::ComputedStyle* aAlignContainerStyle) const;
    994 
    995  /**
    996   * Return the used value for 'justify/align-self' for the axis in the
    997   * alignment subject's writing mode.
    998   *
    999   * @param aAlignSubjectAxis the axis in aAlignSubjectWM.
   1000   * @param aAlignContainerStyle the computed style of the alignment container,
   1001   *        or null for the root.
   1002   *
   1003   * (defined in WritingModes.h since we need the full WritingMode type)
   1004   */
   1005  inline mozilla::StyleAlignFlags UsedSelfAlignment(
   1006      WritingMode aAlignSubjectWM, LogicalAxis aAlignSubjectAxis,
   1007      WritingMode aAlignContainerWM,
   1008      const ComputedStyle* aAlignContainerStyle) const;
   1009 
   1010  /**
   1011   * Return the used value for 'justify/align-content' in aAxis.
   1012   * (defined in WritingModes.h since we need the full WritingMode type)
   1013   */
   1014  inline mozilla::StyleContentDistribution UsedContentAlignment(
   1015      LogicalAxis aAxis) const;
   1016 
   1017  Position mObjectPosition;
   1018  StyleRect<mozilla::StyleInset> mOffset;
   1019  StyleSize mWidth;
   1020  StyleSize mMinWidth;
   1021  StyleMaxSize mMaxWidth;
   1022  StyleSize mHeight;
   1023  StyleSize mMinHeight;
   1024  StyleMaxSize mMaxHeight;
   1025 
   1026  // 'auto' or a `<dashed-ident>` referencing an anchor positioning anchor
   1027  // element.
   1028  mozilla::StylePositionAnchor mPositionAnchor;
   1029  mozilla::StylePositionArea mPositionArea;
   1030  mozilla::StylePositionVisibility mPositionVisibility;
   1031  mozilla::StylePositionTryFallbacks mPositionTryFallbacks;
   1032  mozilla::StylePositionTryOrder mPositionTryOrder;
   1033 
   1034  mozilla::StyleFlexBasis mFlexBasis;
   1035  StyleImplicitGridTracks mGridAutoColumns;
   1036  StyleImplicitGridTracks mGridAutoRows;
   1037  mozilla::StyleAspectRatio mAspectRatio;
   1038  mozilla::StyleGridAutoFlow mGridAutoFlow;
   1039  mozilla::StyleMasonryAutoFlow mMasonryAutoFlow;
   1040 
   1041  mozilla::StyleContentDistribution mAlignContent;
   1042  mozilla::StyleItemPlacement mAlignItems;
   1043  mozilla::StyleSelfAlignment mAlignSelf;
   1044  mozilla::StyleContentDistribution mJustifyContent;
   1045  mozilla::StyleComputedJustifyItems mJustifyItems;
   1046  mozilla::StyleSelfAlignment mJustifySelf;
   1047  mozilla::StyleFlexDirection mFlexDirection;
   1048  mozilla::StyleFlexWrap mFlexWrap;
   1049  mozilla::StyleObjectFit mObjectFit;
   1050  mozilla::StyleBoxSizing mBoxSizing;
   1051  int32_t mOrder;
   1052  float mFlexGrow;
   1053  float mFlexShrink;
   1054  mozilla::StyleZIndex mZIndex;
   1055 
   1056  mozilla::StyleGridTemplateComponent mGridTemplateColumns;
   1057  mozilla::StyleGridTemplateComponent mGridTemplateRows;
   1058  mozilla::StyleGridTemplateAreas mGridTemplateAreas;
   1059 
   1060  mozilla::StyleGridLine mGridColumnStart;
   1061  mozilla::StyleGridLine mGridColumnEnd;
   1062  mozilla::StyleGridLine mGridRowStart;
   1063  mozilla::StyleGridLine mGridRowEnd;
   1064  mozilla::NonNegativeLengthPercentageOrNormal mColumnGap;
   1065  mozilla::NonNegativeLengthPercentageOrNormal mRowGap;
   1066 
   1067  mozilla::StyleContainIntrinsicSize mContainIntrinsicWidth;
   1068  mozilla::StyleContainIntrinsicSize mContainIntrinsicHeight;
   1069 
   1070  // Logical-coordinate accessors for width and height properties,
   1071  // given a WritingMode value. The definitions of these methods are
   1072  // found in WritingModes.h (after the WritingMode class is fully
   1073  // declared).
   1074  inline AnchorResolvedSize ISize(WritingMode,
   1075                                  const AnchorPosResolutionParams&) const;
   1076  inline AnchorResolvedSize MinISize(WritingMode,
   1077                                     const AnchorPosResolutionParams&) const;
   1078  inline AnchorResolvedMaxSize MaxISize(WritingMode,
   1079                                        const AnchorPosResolutionParams&) const;
   1080  inline AnchorResolvedSize BSize(WritingMode,
   1081                                  const AnchorPosResolutionParams&) const;
   1082  inline AnchorResolvedSize MinBSize(WritingMode,
   1083                                     const AnchorPosResolutionParams&) const;
   1084  inline AnchorResolvedMaxSize MaxBSize(WritingMode,
   1085                                        const AnchorPosResolutionParams&) const;
   1086  inline AnchorResolvedSize Size(LogicalAxis, WritingMode,
   1087                                 const AnchorPosResolutionParams&) const;
   1088  inline AnchorResolvedSize MinSize(LogicalAxis, WritingMode,
   1089                                    const AnchorPosResolutionParams&) const;
   1090  inline AnchorResolvedMaxSize MaxSize(LogicalAxis, WritingMode,
   1091                                       const AnchorPosResolutionParams&) const;
   1092  static inline bool ISizeDependsOnContainer(const AnchorResolvedSize&);
   1093  static inline bool MinISizeDependsOnContainer(const AnchorResolvedSize&);
   1094  static inline bool MaxISizeDependsOnContainer(const AnchorResolvedMaxSize&);
   1095  static inline bool BSizeDependsOnContainer(const AnchorResolvedSize&);
   1096  static inline bool MinBSizeDependsOnContainer(const AnchorResolvedSize&);
   1097  static inline bool MaxBSizeDependsOnContainer(const AnchorResolvedMaxSize&);
   1098 
   1099  // TODO(dshin): These inset getters are to be removed when
   1100  // interleaving computation is implemented.
   1101  AnchorResolvedInset GetAnchorResolvedInset(
   1102      mozilla::Side aSide,
   1103      const AnchorPosOffsetResolutionParams& aParams) const {
   1104    return AnchorResolvedInsetHelper::FromUnresolved(mOffset.Get(aSide), aSide,
   1105                                                     aParams);
   1106  }
   1107 
   1108  inline AnchorResolvedInset GetAnchorResolvedInset(
   1109      mozilla::LogicalSide aSide, WritingMode aWM,
   1110      const AnchorPosOffsetResolutionParams& aParams) const;
   1111 
   1112  // Returns the side with an auto inset if exactly one inset in the given
   1113  // physical axis is auto. Otherwise returns Nothing().
   1114  mozilla::Maybe<mozilla::Side> GetSingleAutoInsetInAxis(
   1115      mozilla::StylePhysicalAxis aAxis,
   1116      const AnchorPosOffsetResolutionParams& aParams) const {
   1117    const mozilla::Side startSide =
   1118        aAxis == mozilla::StylePhysicalAxis::Horizontal ? mozilla::eSideLeft
   1119                                                        : mozilla::eSideTop;
   1120    const mozilla::Side endSide =
   1121        aAxis == mozilla::StylePhysicalAxis::Horizontal ? mozilla::eSideRight
   1122                                                        : mozilla::eSideBottom;
   1123 
   1124    const bool startInsetIsAuto =
   1125        AnchorResolvedInsetHelper::FromUnresolved(mOffset.Get(startSide),
   1126                                                  startSide, aParams)
   1127            ->IsAuto();
   1128    const bool endInsetIsAuto = AnchorResolvedInsetHelper::FromUnresolved(
   1129                                    mOffset.Get(endSide), endSide, aParams)
   1130                                    ->IsAuto();
   1131 
   1132    if (startInsetIsAuto && !endInsetIsAuto) {
   1133      return mozilla::Some(startSide);
   1134    }
   1135    if (!startInsetIsAuto && endInsetIsAuto) {
   1136      return mozilla::Some(endSide);
   1137    }
   1138    return mozilla::Nothing();
   1139  }
   1140 
   1141  // Logical-axis version, defined in WritingModes.h
   1142  inline mozilla::Maybe<mozilla::Side> GetSingleAutoInsetInAxis(
   1143      LogicalAxis aAxis, WritingMode aWM,
   1144      const AnchorPosOffsetResolutionParams& aParams) const;
   1145 
   1146  AnchorResolvedSize GetWidth(const AnchorPosResolutionParams& aParams) const {
   1147    return AnchorResolvedSizeHelper::FromUnresolved(
   1148        mWidth, mozilla::StylePhysicalAxis::Horizontal, aParams);
   1149  }
   1150 
   1151  AnchorResolvedSize GetHeight(const AnchorPosResolutionParams& aParams) const {
   1152    return AnchorResolvedSizeHelper::FromUnresolved(
   1153        mHeight, mozilla::StylePhysicalAxis::Vertical, aParams);
   1154  }
   1155 
   1156  AnchorResolvedSize GetMinWidth(
   1157      const AnchorPosResolutionParams& aParams) const {
   1158    return AnchorResolvedSizeHelper::FromUnresolved(
   1159        mMinWidth, mozilla::StylePhysicalAxis::Horizontal, aParams);
   1160  }
   1161 
   1162  AnchorResolvedSize GetMinHeight(
   1163      const AnchorPosResolutionParams& aParams) const {
   1164    return AnchorResolvedSizeHelper::FromUnresolved(
   1165        mMinHeight, mozilla::StylePhysicalAxis::Vertical, aParams);
   1166  }
   1167 
   1168  AnchorResolvedMaxSize GetMaxWidth(
   1169      const AnchorPosResolutionParams& aParams) const {
   1170    return AnchorResolvedMaxSizeHelper::FromUnresolved(
   1171        mMaxWidth, mozilla::StylePhysicalAxis::Horizontal, aParams);
   1172  }
   1173 
   1174  AnchorResolvedMaxSize GetMaxHeight(
   1175      const AnchorPosResolutionParams& aParams) const {
   1176    return AnchorResolvedMaxSizeHelper::FromUnresolved(
   1177        mMaxHeight, mozilla::StylePhysicalAxis::Vertical, aParams);
   1178  }
   1179 
   1180 private:
   1181  template <typename SizeOrMaxSize>
   1182  static bool ISizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
   1183    if (aCoord.IsLengthPercentage()) {
   1184      return aCoord.AsLengthPercentage().HasPercent();
   1185    }
   1186    return aCoord.IsFitContent() || aCoord.BehavesLikeStretchOnInlineAxis();
   1187  }
   1188 
   1189  template <typename SizeOrMaxSize>
   1190  static bool BSizeCoordDependsOnContainer(const SizeOrMaxSize& aCoord) {
   1191    if (aCoord.IsLengthPercentage()) {
   1192      return aCoord.AsLengthPercentage().HasPercent();
   1193    }
   1194    return aCoord.BehavesLikeStretchOnBlockAxis();
   1195  }
   1196 };
   1197 
   1198 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTextReset {
   1199  STYLE_STRUCT(nsStyleTextReset)
   1200  nsStyleTextReset();
   1201 
   1202  // Note the difference between this and
   1203  // ComputedStyle::HasTextDecorationLines.
   1204  bool HasTextDecorationLines() const {
   1205    return mTextDecorationLine != mozilla::StyleTextDecorationLine::NONE &&
   1206           mTextDecorationLine !=
   1207               mozilla::StyleTextDecorationLine::COLOR_OVERRIDE;
   1208  }
   1209 
   1210  mozilla::StyleTextOverflow mTextOverflow;
   1211 
   1212  mozilla::StyleTextDecorationLine mTextDecorationLine;
   1213  mozilla::StyleTextDecorationStyle mTextDecorationStyle;
   1214  mozilla::StyleUnicodeBidi mUnicodeBidi;
   1215  mozilla::StyleInitialLetter mInitialLetter;
   1216  mozilla::StyleColor mTextDecorationColor;
   1217  mozilla::StyleTextDecorationLength mTextDecorationThickness;
   1218  mozilla::StyleTextDecorationInset mTextDecorationInset;
   1219 };
   1220 
   1221 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleText {
   1222  STYLE_STRUCT(nsStyleText)
   1223  explicit nsStyleText(const mozilla::dom::Document&);
   1224 
   1225  mozilla::StyleAbsoluteColor mColor;
   1226  mozilla::StyleForcedColorAdjust mForcedColorAdjust;
   1227  mozilla::StyleTextTransform mTextTransform;
   1228  mozilla::StyleTextAlign mTextAlign;
   1229  mozilla::StyleTextAlignLast mTextAlignLast;
   1230  mozilla::StyleTextJustify mTextJustify;
   1231  mozilla::StyleWhiteSpaceCollapse mWhiteSpaceCollapse =
   1232      mozilla::StyleWhiteSpaceCollapse::Collapse;
   1233  mozilla::StyleTextWrapMode mTextWrapMode = mozilla::StyleTextWrapMode::Wrap;
   1234  mozilla::StyleLineBreak mLineBreak = mozilla::StyleLineBreak::Auto;
   1235 
   1236 private:
   1237  mozilla::StyleWordBreak mWordBreak = mozilla::StyleWordBreak::Normal;
   1238  mozilla::StyleOverflowWrap mOverflowWrap = mozilla::StyleOverflowWrap::Normal;
   1239  mozilla::StyleTextAutospace mTextAutospace =
   1240      mozilla::StyleTextAutospace::NO_AUTOSPACE;
   1241 
   1242 public:
   1243  mozilla::StyleHyphens mHyphens;
   1244  mozilla::StyleRubyAlign mRubyAlign;
   1245  mozilla::StyleRubyPosition mRubyPosition;
   1246  mozilla::StyleTextSizeAdjust mTextSizeAdjust;
   1247  mozilla::StyleTextCombineUpright mTextCombineUpright;
   1248  mozilla::StyleMozControlCharacterVisibility mMozControlCharacterVisibility;
   1249  mozilla::StyleTextEmphasisPosition mTextEmphasisPosition;
   1250  mozilla::StyleTextRendering mTextRendering;
   1251  mozilla::StyleColor mTextEmphasisColor;
   1252  mozilla::StyleColor mWebkitTextFillColor;
   1253  mozilla::StyleColor mWebkitTextStrokeColor;
   1254 
   1255  mozilla::StyleNonNegativeLengthOrNumber mTabSize;
   1256  mozilla::LengthPercentage mWordSpacing;
   1257  mozilla::StyleLetterSpacing mLetterSpacing;
   1258  mozilla::StyleTextIndent mTextIndent;
   1259 
   1260  mozilla::LengthPercentageOrAuto mTextUnderlineOffset;
   1261  mozilla::StyleTextDecorationSkipInk mTextDecorationSkipInk;
   1262  mozilla::StyleTextUnderlinePosition mTextUnderlinePosition;
   1263 
   1264  mozilla::StyleAu mWebkitTextStrokeWidth;
   1265 
   1266  mozilla::StyleArcSlice<mozilla::StyleSimpleShadow> mTextShadow;
   1267  mozilla::StyleTextEmphasisStyle mTextEmphasisStyle;
   1268 
   1269  mozilla::StyleHyphenateCharacter mHyphenateCharacter =
   1270      mozilla::StyleHyphenateCharacter::Auto();
   1271  mozilla::StyleHyphenateLimitChars mHyphenateLimitChars =
   1272      mozilla::StyleHyphenateLimitChars::Auto();
   1273 
   1274  mozilla::StyleTextSecurity mWebkitTextSecurity =
   1275      mozilla::StyleTextSecurity::None;
   1276 
   1277  mozilla::StyleTextWrapStyle mTextWrapStyle =
   1278      mozilla::StyleTextWrapStyle::Auto;
   1279 
   1280  char16_t TextSecurityMaskChar() const {
   1281    switch (mWebkitTextSecurity) {
   1282      case mozilla::StyleTextSecurity::None:
   1283        return 0;
   1284      case mozilla::StyleTextSecurity::Circle:
   1285        return 0x25E6;
   1286      case mozilla::StyleTextSecurity::Disc:
   1287        return 0x2022;
   1288      case mozilla::StyleTextSecurity::Square:
   1289        return 0x25A0;
   1290      default:
   1291        MOZ_ASSERT_UNREACHABLE("unknown StyleTextSecurity value!");
   1292        return 0;
   1293    }
   1294  }
   1295 
   1296  mozilla::StyleWordBreak EffectiveWordBreak() const {
   1297    if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
   1298      return mozilla::StyleWordBreak::Normal;
   1299    }
   1300    return mWordBreak;
   1301  }
   1302 
   1303  mozilla::StyleOverflowWrap EffectiveOverflowWrap() const {
   1304    if (mWordBreak == mozilla::StyleWordBreak::BreakWord) {
   1305      return mozilla::StyleOverflowWrap::Anywhere;
   1306    }
   1307    return mOverflowWrap;
   1308  }
   1309 
   1310  mozilla::StyleTextAutospace EffectiveTextAutospace() const {
   1311    if (!mozilla::StaticPrefs::layout_css_text_autospace_enabled()) {
   1312      return mozilla::StyleTextAutospace::NO_AUTOSPACE;
   1313    }
   1314    return mTextAutospace;
   1315  }
   1316 
   1317  bool WhiteSpaceIsSignificant() const {
   1318    return mWhiteSpaceCollapse != mozilla::StyleWhiteSpaceCollapse::Collapse &&
   1319           mWhiteSpaceCollapse !=
   1320               mozilla::StyleWhiteSpaceCollapse::PreserveBreaks;
   1321  }
   1322 
   1323  bool WhiteSpaceCanHangOrVisuallyCollapse() const {
   1324    // This was originally expressed in nsTextFrame in terms of:
   1325    //   mWhiteSpace != StyleWhiteSpace::BreakSpaces &&
   1326    //       WhiteSpaceCanWrapStyle() &&
   1327    //       WhiteSpaceIsSignificant()
   1328    // which simplifies to:
   1329    return mTextWrapMode == mozilla::StyleTextWrapMode::Wrap &&
   1330           mWhiteSpaceCollapse != mozilla::StyleWhiteSpaceCollapse::BreakSpaces;
   1331  }
   1332 
   1333  bool NewlineIsSignificantStyle() const {
   1334    return mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::Preserve ||
   1335           mWhiteSpaceCollapse ==
   1336               mozilla::StyleWhiteSpaceCollapse::PreserveBreaks ||
   1337           mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::BreakSpaces;
   1338  }
   1339 
   1340  bool WhiteSpaceOrNewlineIsSignificant() const {
   1341    return NewlineIsSignificantStyle() || WhiteSpaceIsSignificant();
   1342  }
   1343 
   1344  bool TabIsSignificant() const {
   1345    return mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::Preserve ||
   1346           mWhiteSpaceCollapse == mozilla::StyleWhiteSpaceCollapse::BreakSpaces;
   1347  }
   1348 
   1349  bool WhiteSpaceCanWrapStyle() const {
   1350    return mTextWrapMode == mozilla::StyleTextWrapMode::Wrap;
   1351  }
   1352 
   1353  bool WordCanWrapStyle() const {
   1354    if (!WhiteSpaceCanWrapStyle()) {
   1355      return false;
   1356    }
   1357    auto owrap = EffectiveOverflowWrap();
   1358    return owrap == mozilla::StyleOverflowWrap::BreakWord ||
   1359           owrap == mozilla::StyleOverflowWrap::Anywhere;
   1360  }
   1361 
   1362  bool HasEffectiveTextEmphasis() const {
   1363    if (mTextEmphasisStyle.IsNone()) {
   1364      return false;
   1365    }
   1366    if (mTextEmphasisStyle.IsString() &&
   1367        mTextEmphasisStyle.AsString().AsString().IsEmpty()) {
   1368      return false;
   1369    }
   1370    return true;
   1371  }
   1372 
   1373  mozilla::StyleTextAlign TextAlignForLastLine() const {
   1374    switch (mTextAlignLast) {
   1375      case mozilla::StyleTextAlignLast::Auto:
   1376        // 'text-align-last: auto' is equivalent to the value of the
   1377        // 'text-align' property except when 'text-align' is set to 'justify',
   1378        // in which case it is 'justify' when 'text-justify' is 'distribute' and
   1379        // 'start' otherwise.
   1380        //
   1381        // XXX: the code below will have to change when we implement
   1382        // text-justify
   1383        if (mTextAlign == mozilla::StyleTextAlign::Justify) {
   1384          return mozilla::StyleTextAlign::Start;
   1385        }
   1386        return mTextAlign;
   1387      case mozilla::StyleTextAlignLast::Center:
   1388        return mozilla::StyleTextAlign::Center;
   1389      case mozilla::StyleTextAlignLast::Start:
   1390        return mozilla::StyleTextAlign::Start;
   1391      case mozilla::StyleTextAlignLast::End:
   1392        return mozilla::StyleTextAlign::End;
   1393      case mozilla::StyleTextAlignLast::Left:
   1394        return mozilla::StyleTextAlign::Left;
   1395      case mozilla::StyleTextAlignLast::Right:
   1396        return mozilla::StyleTextAlign::Right;
   1397      case mozilla::StyleTextAlignLast::Justify:
   1398        return mozilla::StyleTextAlign::Justify;
   1399    }
   1400    return mozilla::StyleTextAlign::Start;
   1401  }
   1402 
   1403  bool HasWebkitTextStroke() const { return mWebkitTextStrokeWidth > 0; }
   1404 
   1405  bool HasTextShadow() const { return !mTextShadow.IsEmpty(); }
   1406 
   1407  // The aContextFrame argument on each of these is the frame this
   1408  // style struct is for.  If the frame is for SVG text or inside ruby,
   1409  // the return value will be massaged to be something that makes sense
   1410  // for those cases.
   1411  inline bool NewlineIsSignificant(const nsTextFrame* aContextFrame) const;
   1412  inline bool WhiteSpaceCanWrap(const nsIFrame* aContextFrame) const;
   1413  inline bool WordCanWrap(const nsIFrame* aContextFrame) const;
   1414 
   1415  mozilla::LogicalSide TextEmphasisSide(mozilla::WritingMode aWM,
   1416                                        const nsAtom* aLanguage) const;
   1417 };
   1418 
   1419 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleVisibility {
   1420  STYLE_STRUCT(nsStyleVisibility)
   1421  explicit nsStyleVisibility(const mozilla::dom::Document&);
   1422 
   1423  bool IsVisible() const {
   1424    return mVisible == mozilla::StyleVisibility::Visible;
   1425  }
   1426 
   1427  bool IsCollapse() const {
   1428    return mVisible == mozilla::StyleVisibility::Collapse;
   1429  }
   1430 
   1431  bool IsVisibleOrCollapsed() const {
   1432    return mVisible == mozilla::StyleVisibility::Visible ||
   1433           mVisible == mozilla::StyleVisibility::Collapse;
   1434  }
   1435 
   1436  bool UseLegacyCollapseBehavior() const {
   1437    return mMozBoxCollapse == mozilla::StyleMozBoxCollapse::Legacy;
   1438  }
   1439 
   1440  /**
   1441   * Given an image request, returns the orientation that should be used
   1442   * on the image. The returned orientation may differ from the style
   1443   * struct's orientation member value, if the image request is not of the
   1444   * same origin.
   1445   *
   1446   * @param aRequest     The image request used to determine if same origin.
   1447   */
   1448  mozilla::StyleImageOrientation UsedImageOrientation(
   1449      imgIRequest* aRequest) const {
   1450    return UsedImageOrientation(aRequest, mImageOrientation);
   1451  }
   1452 
   1453  /**
   1454   * Given an image request and an orientation, returns the orientation
   1455   * that should be used on the image. The returned orientation may differ
   1456   * from the input orientation if the image request is not of the same
   1457   * origin.
   1458   *
   1459   * @param aRequest     The image request used to determine if same origin.
   1460   * @param aOrientation The input orientation.
   1461   */
   1462  static mozilla::StyleImageOrientation UsedImageOrientation(
   1463      imgIRequest* aRequest, mozilla::StyleImageOrientation aOrientation);
   1464 
   1465  mozilla::StyleDirection mDirection;
   1466  mozilla::StyleVisibility mVisible;
   1467  mozilla::StyleImageRendering mImageRendering;
   1468  mozilla::StyleWritingModeProperty mWritingMode;
   1469  mozilla::StyleTextOrientation mTextOrientation;
   1470  mozilla::StyleMozBoxCollapse mMozBoxCollapse;
   1471  mozilla::StylePrintColorAdjust mPrintColorAdjust;
   1472 
   1473 private:
   1474  mozilla::StyleImageOrientation mImageOrientation;
   1475 };
   1476 
   1477 namespace mozilla {
   1478 
   1479 // Note that IsAuto() does not exclude the possibility that `left` or `right`
   1480 // is set; it refers only to behavior in horizontal typographic mode.
   1481 inline bool StyleTextUnderlinePosition::IsAuto() const {
   1482  return !(*this & (StyleTextUnderlinePosition::FROM_FONT |
   1483                    StyleTextUnderlinePosition::UNDER));
   1484 }
   1485 inline bool StyleTextUnderlinePosition::IsFromFont() const {
   1486  return bool(*this & StyleTextUnderlinePosition::FROM_FONT);
   1487 }
   1488 inline bool StyleTextUnderlinePosition::IsUnder() const {
   1489  return bool(*this & StyleTextUnderlinePosition::UNDER);
   1490 }
   1491 inline bool StyleTextUnderlinePosition::IsLeft() const {
   1492  return bool(*this & StyleTextUnderlinePosition::LEFT);
   1493 }
   1494 inline bool StyleTextUnderlinePosition::IsRight() const {
   1495  return bool(*this & StyleTextUnderlinePosition::RIGHT);
   1496 }
   1497 
   1498 struct StyleTransition {
   1499  StyleTransition() = default;
   1500  explicit StyleTransition(const StyleTransition& aCopy);
   1501  const StyleComputedTimingFunction& GetTimingFunction() const {
   1502    return mTimingFunction;
   1503  }
   1504  const StyleTime& GetDelay() const { return mDelay; }
   1505  const StyleTime& GetDuration() const { return mDuration; }
   1506  const StyleTransitionProperty& GetProperty() const { return mProperty; }
   1507  StyleTransitionBehavior GetBehavior() const { return mBehavior; }
   1508 
   1509  bool operator==(const StyleTransition& aOther) const;
   1510  bool operator!=(const StyleTransition&) const = default;
   1511 
   1512 private:
   1513  StyleComputedTimingFunction mTimingFunction{
   1514      StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease)};
   1515  StyleTime mDuration{0.0};
   1516  StyleTime mDelay{0.0};
   1517  StyleTransitionProperty mProperty{StyleTransitionProperty::NonCustom(
   1518      StyleNonCustomPropertyId{uint16_t(eCSSProperty_all)})};
   1519  StyleTransitionBehavior mBehavior = StyleTransitionBehavior::Normal;
   1520 };
   1521 
   1522 struct StyleAnimation {
   1523  StyleAnimation() = default;
   1524  explicit StyleAnimation(const StyleAnimation& aCopy);
   1525 
   1526  const StyleComputedTimingFunction& GetTimingFunction() const {
   1527    return mTimingFunction;
   1528  }
   1529  const StyleTime& GetDelay() const { return mDelay; }
   1530  const StyleAnimationDuration& GetDuration() const { return mDuration; }
   1531  nsAtom* GetName() const { return mName._0.AsAtom(); }
   1532  StyleAnimationDirection GetDirection() const { return mDirection; }
   1533  StyleAnimationFillMode GetFillMode() const { return mFillMode; }
   1534  StyleAnimationPlayState GetPlayState() const { return mPlayState; }
   1535  float GetIterationCount() const { return mIterationCount._0; }
   1536  StyleAnimationComposition GetComposition() const { return mComposition; }
   1537  const StyleAnimationTimeline& GetTimeline() const { return mTimeline; }
   1538 
   1539  bool operator==(const StyleAnimation& aOther) const;
   1540  bool operator!=(const StyleAnimation&) const = default;
   1541 
   1542 private:
   1543  StyleComputedTimingFunction mTimingFunction{
   1544      StyleComputedTimingFunction::Keyword(StyleTimingKeyword::Ease)};
   1545  StyleAnimationDuration mDuration = StyleAnimationDuration::Auto();
   1546  StyleTime mDelay{0.0f};
   1547  StyleAnimationName mName;
   1548  StyleAnimationDirection mDirection = StyleAnimationDirection::Normal;
   1549  StyleAnimationFillMode mFillMode = StyleAnimationFillMode::None;
   1550  StyleAnimationPlayState mPlayState = StyleAnimationPlayState::Running;
   1551  StyleAnimationIterationCount mIterationCount{1.0f};
   1552  StyleAnimationComposition mComposition = StyleAnimationComposition::Replace;
   1553  StyleAnimationTimeline mTimeline = StyleAnimationTimeline::Auto();
   1554 };
   1555 
   1556 struct StyleScrollTimeline {
   1557  StyleScrollTimeline() = default;
   1558  explicit StyleScrollTimeline(const StyleScrollTimeline& aCopy) = default;
   1559 
   1560  nsAtom* GetName() const { return mName.AsAtom(); }
   1561  StyleScrollAxis GetAxis() const { return mAxis; }
   1562 
   1563  bool operator==(const StyleScrollTimeline&) const = default;
   1564  bool operator!=(const StyleScrollTimeline&) const = default;
   1565 
   1566 private:
   1567  StyleTimelineName mName;
   1568  StyleScrollAxis mAxis = StyleScrollAxis::Block;
   1569 };
   1570 
   1571 struct StyleViewTimeline {
   1572  StyleViewTimeline() = default;
   1573  explicit StyleViewTimeline(const StyleViewTimeline& aCopy) = default;
   1574 
   1575  nsAtom* GetName() const { return mName.AsAtom(); }
   1576  StyleScrollAxis GetAxis() const { return mAxis; }
   1577  const StyleViewTimelineInset& GetInset() const { return mInset; }
   1578 
   1579  bool operator==(const StyleViewTimeline&) const = default;
   1580  bool operator!=(const StyleViewTimeline&) const = default;
   1581 
   1582 private:
   1583  StyleTimelineName mName;
   1584  StyleScrollAxis mAxis = StyleScrollAxis::Block;
   1585  StyleViewTimelineInset mInset;
   1586 };
   1587 
   1588 }  // namespace mozilla
   1589 
   1590 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleDisplay {
   1591  STYLE_STRUCT(nsStyleDisplay)
   1592  nsStyleDisplay();
   1593  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleDisplay*);
   1594 
   1595  using StyleContain = mozilla::StyleContain;
   1596  using StyleContentVisibility = mozilla::StyleContentVisibility;
   1597 
   1598  nsChangeHint CalcDifference(const nsStyleDisplay& aNewData,
   1599                              const mozilla::ComputedStyle& aOldStyle) const;
   1600 
   1601  nsChangeHint CalcTransformPropertyDifference(
   1602      const nsStyleDisplay& aNewData) const;
   1603 
   1604  mozilla::StyleDisplay mDisplay;
   1605  // Saved mDisplay for position:absolute/fixed and float:left/right; otherwise
   1606  // equal to mDisplay.
   1607  mozilla::StyleDisplay mOriginalDisplay;
   1608  // Equal to mContain plus any implicit containment from mContentVisibility and
   1609  // mContainerType.
   1610  mozilla::StyleContentVisibility mContentVisibility;
   1611  mozilla::StyleContainerType mContainerType;
   1612 
   1613  bool IsQueryContainer() const {
   1614    return mContainerType != mozilla::StyleContainerType::NORMAL;
   1615  }
   1616 
   1617  // See WritingModes.h for the implementations.
   1618  inline mozilla::UsedFloat UsedFloat(mozilla::WritingMode aWM) const;
   1619  inline mozilla::UsedClear UsedClear(mozilla::WritingMode aWM) const;
   1620 
   1621 private:
   1622  mozilla::StyleAppearance mAppearance;
   1623  mozilla::StyleContain mContain;
   1624  // Equal to mContain plus any implicit containment from mContentVisibility and
   1625  // mContainerType.
   1626  mozilla::StyleContain mEffectiveContainment;
   1627 
   1628 public:
   1629  mozilla::StyleAppearance mDefaultAppearance;
   1630  mozilla::StylePositionProperty mPosition;
   1631 
   1632  mozilla::StyleFloat mFloat;
   1633  mozilla::StyleClear mClear;
   1634  mozilla::StyleBreakWithin mBreakInside;
   1635  mozilla::StyleBreakBetween mBreakBefore;
   1636  mozilla::StyleBreakBetween mBreakAfter;
   1637  mozilla::StyleOverflow mOverflowX;
   1638  mozilla::StyleOverflow mOverflowY;
   1639  mozilla::StyleScrollbarGutter mScrollbarGutter;
   1640  mozilla::StyleResize mResize;
   1641  mozilla::StyleOrient mOrient;
   1642  mozilla::StyleIsolation mIsolation;
   1643  mozilla::StyleTopLayer mTopLayer;
   1644 
   1645  mozilla::StyleTouchAction mTouchAction;
   1646  mozilla::StyleScrollBehavior mScrollBehavior;
   1647  mozilla::StyleOverscrollBehavior mOverscrollBehaviorX;
   1648  mozilla::StyleOverscrollBehavior mOverscrollBehaviorY;
   1649  mozilla::StyleOverflowAnchor mOverflowAnchor;
   1650  mozilla::StyleScrollSnapAlign mScrollSnapAlign;
   1651  mozilla::StyleScrollSnapStop mScrollSnapStop;
   1652  mozilla::StyleScrollSnapType mScrollSnapType;
   1653 
   1654  mozilla::StyleBackfaceVisibility mBackfaceVisibility;
   1655  mozilla::StyleTransformStyle mTransformStyle;
   1656  mozilla::StyleTransformBox mTransformBox;
   1657 
   1658  mozilla::StyleTransform mTransform;
   1659  mozilla::StyleRotate mRotate;
   1660 
   1661  mozilla::StyleTranslate mTranslate;
   1662  mozilla::StyleScale mScale;
   1663 
   1664  mozilla::StyleContainerName mContainerName;
   1665  mozilla::StyleWillChange mWillChange;
   1666 
   1667  mozilla::StyleOffsetPath mOffsetPath;
   1668  mozilla::LengthPercentage mOffsetDistance;
   1669  mozilla::StyleOffsetRotate mOffsetRotate;
   1670  mozilla::StylePositionOrAuto mOffsetAnchor;
   1671  mozilla::StyleOffsetPosition mOffsetPosition;
   1672 
   1673  mozilla::StyleTransformOrigin mTransformOrigin;
   1674  mozilla::StylePerspective mChildPerspective;
   1675  mozilla::Position mPerspectiveOrigin;
   1676 
   1677  mozilla::StyleVerticalAlign mVerticalAlign;
   1678  mozilla::StyleBaselineSource mBaselineSource;
   1679 
   1680  mozilla::StyleLineClamp mWebkitLineClamp;
   1681 
   1682  // The threshold used for extracting a shape from shape-outside: <image>.
   1683  float mShapeImageThreshold = 0.0f;
   1684 
   1685  mozilla::StyleZoom mZoom = mozilla::StyleZoom::ONE;
   1686 
   1687  // The margin around a shape-outside: <image>.
   1688  mozilla::NonNegativeLengthPercentage mShapeMargin;
   1689 
   1690  mozilla::StyleShapeOutside mShapeOutside;
   1691 
   1692  // 'none', 'all', or a list of one or more `<dashed-ident>` identifiers that
   1693  // anchor positioned elements may reference.
   1694  mozilla::StyleAnchorName mAnchorName;
   1695 
   1696  // 'none', 'all', or a list of one or more `<dashed-ident>` identifiers that
   1697  // may identify anchor positioning anchor elements.
   1698  mozilla::StyleAnchorScope mAnchorScope;
   1699 
   1700  mozilla::Maybe<mozilla::WindowButtonType> GetWindowButtonType() const {
   1701    if (MOZ_LIKELY(mDefaultAppearance == mozilla::StyleAppearance::None)) {
   1702      return mozilla::Nothing();
   1703    }
   1704    switch (mDefaultAppearance) {
   1705      case mozilla::StyleAppearance::MozWindowButtonMaximize:
   1706      case mozilla::StyleAppearance::MozWindowButtonRestore:
   1707        return Some(mozilla::WindowButtonType::Maximize);
   1708      case mozilla::StyleAppearance::MozWindowButtonMinimize:
   1709        return Some(mozilla::WindowButtonType::Minimize);
   1710      case mozilla::StyleAppearance::MozWindowButtonClose:
   1711        return Some(mozilla::WindowButtonType::Close);
   1712      default:
   1713        return mozilla::Nothing();
   1714    }
   1715  }
   1716 
   1717  bool HasAppearance() const {
   1718    return EffectiveAppearance() != mozilla::StyleAppearance::None;
   1719  }
   1720 
   1721  mozilla::StyleAppearance EffectiveAppearance() const {
   1722    if (MOZ_LIKELY(mAppearance == mozilla::StyleAppearance::None)) {
   1723      return mAppearance;
   1724    }
   1725    switch (mAppearance) {
   1726      case mozilla::StyleAppearance::Auto:
   1727      case mozilla::StyleAppearance::Button:
   1728      case mozilla::StyleAppearance::Searchfield:
   1729      case mozilla::StyleAppearance::Textarea:
   1730      case mozilla::StyleAppearance::Checkbox:
   1731      case mozilla::StyleAppearance::Radio:
   1732      case mozilla::StyleAppearance::Menulist:
   1733      case mozilla::StyleAppearance::Listbox:
   1734      case mozilla::StyleAppearance::Meter:
   1735      case mozilla::StyleAppearance::ProgressBar:
   1736        // These are all the values that behave like `auto`.
   1737        return mDefaultAppearance;
   1738      case mozilla::StyleAppearance::Textfield:
   1739        // `appearance: textfield` should behave like `auto` on all elements
   1740        // except <input type=search/number/password> elements, which we
   1741        // identify using the internal -moz-default-appearance property.
   1742        if (mDefaultAppearance == mozilla::StyleAppearance::NumberInput ||
   1743            mDefaultAppearance == mozilla::StyleAppearance::PasswordInput) {
   1744          return mAppearance;
   1745        }
   1746        return mDefaultAppearance;
   1747      case mozilla::StyleAppearance::MenulistButton:
   1748        // `appearance: menulist-button` should behave like `auto` on all
   1749        // elements except for drop down selects.
   1750        if (mDefaultAppearance == mozilla::StyleAppearance::Menulist) {
   1751          return mAppearance;
   1752        }
   1753        return mDefaultAppearance;
   1754      default:
   1755        return mAppearance;
   1756    }
   1757  }
   1758 
   1759  mozilla::StyleDisplayOutside DisplayOutside() const {
   1760    return mDisplay.Outside();
   1761  }
   1762  mozilla::StyleDisplayInside DisplayInside() const {
   1763    return mDisplay.Inside();
   1764  }
   1765  bool IsListItem() const { return mDisplay.IsListItem(); }
   1766  bool IsInlineFlow() const { return mDisplay.IsInlineFlow(); }
   1767 
   1768  bool IsInlineInsideStyle() const { return mDisplay.IsInlineInside(); }
   1769 
   1770  bool IsBlockOutsideStyle() const {
   1771    return DisplayOutside() == mozilla::StyleDisplayOutside::Block;
   1772  }
   1773 
   1774  bool IsInlineOutsideStyle() const { return mDisplay.IsInlineOutside(); }
   1775 
   1776  bool IsOriginalDisplayInlineOutside() const {
   1777    return mOriginalDisplay.IsInlineOutside();
   1778  }
   1779 
   1780  bool IsInnerTableStyle() const { return mDisplay.IsInternalTable(); }
   1781 
   1782  bool IsInternalTableStyleExceptCell() const {
   1783    return mDisplay.IsInternalTableExceptCell();
   1784  }
   1785 
   1786  bool IsFloatingStyle() const { return mozilla::StyleFloat::None != mFloat; }
   1787 
   1788  bool IsPositionedStyle() const {
   1789    return mPosition != mozilla::StylePositionProperty::Static ||
   1790           (mWillChange.bits & mozilla::StyleWillChangeBits::POSITION);
   1791  }
   1792 
   1793  bool IsAbsolutelyPositionedStyle() const {
   1794    return mozilla::StylePositionProperty::Absolute == mPosition ||
   1795           mozilla::StylePositionProperty::Fixed == mPosition;
   1796  }
   1797 
   1798  bool IsRelativelyOrStickyPositionedStyle() const {
   1799    return mozilla::StylePositionProperty::Relative == mPosition ||
   1800           mozilla::StylePositionProperty::Sticky == mPosition;
   1801  }
   1802  bool IsRelativelyPositionedStyle() const {
   1803    return mozilla::StylePositionProperty::Relative == mPosition;
   1804  }
   1805  bool IsStickyPositionedStyle() const {
   1806    return mozilla::StylePositionProperty::Sticky == mPosition;
   1807  }
   1808  bool IsPositionForcingStackingContext() const {
   1809    return mozilla::StylePositionProperty::Sticky == mPosition ||
   1810           mozilla::StylePositionProperty::Fixed == mPosition;
   1811  }
   1812 
   1813  bool HasAnchorName() const { return !mAnchorName.IsEmpty(); }
   1814 
   1815  bool IsRubyDisplayType() const { return mDisplay.IsRuby(); }
   1816 
   1817  bool IsInternalRubyDisplayType() const { return mDisplay.IsInternalRuby(); }
   1818 
   1819  bool IsOutOfFlowStyle() const {
   1820    return (IsAbsolutelyPositionedStyle() || IsFloatingStyle());
   1821  }
   1822 
   1823  bool IsScrollableOverflow() const {
   1824    // Visible and Clip can be combined but not with other values,
   1825    // so checking mOverflowX is enough.
   1826    return mOverflowX != mozilla::StyleOverflow::Visible &&
   1827           mOverflowX != mozilla::StyleOverflow::Clip;
   1828  }
   1829 
   1830  bool OverflowIsVisibleInBothAxis() const {
   1831    return mOverflowX == mozilla::StyleOverflow::Visible &&
   1832           mOverflowY == mozilla::StyleOverflow::Visible;
   1833  }
   1834 
   1835  bool IsContainPaint() const {
   1836    // Short circuit for no containment whatsoever
   1837    if (!mEffectiveContainment) {
   1838      return false;
   1839    }
   1840    return (mEffectiveContainment & StyleContain::PAINT) &&
   1841           !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
   1842  }
   1843 
   1844  bool IsContainLayout() const {
   1845    // Short circuit for no containment whatsoever
   1846    if (!mEffectiveContainment) {
   1847      return false;
   1848    }
   1849    // Note: The spec for layout containment says it should
   1850    // have no effect on non-atomic, inline-level boxes. We
   1851    // don't check for these here because we don't know
   1852    // what type of element is involved. Callers are
   1853    // responsible for checking if the box in question is
   1854    // non-atomic and inline-level, and creating an
   1855    // exemption as necessary.
   1856    return (mEffectiveContainment & StyleContain::LAYOUT) &&
   1857           !IsInternalRubyDisplayType() && !IsInternalTableStyleExceptCell();
   1858  }
   1859 
   1860  bool IsContainStyle() const {
   1861    return !!(mEffectiveContainment & StyleContain::STYLE);
   1862  }
   1863 
   1864  bool IsContainAny() const { return !!mEffectiveContainment; }
   1865 
   1866  // This is similar to PrecludesSizeContainmentOrContentVisibility, but also
   1867  // takes into account whether or not the given frame is a non-atomic,
   1868  // inline-level box.
   1869  bool PrecludesSizeContainmentOrContentVisibilityWithFrame(
   1870      const nsIFrame&) const;
   1871 
   1872  StyleContentVisibility ContentVisibility(const nsIFrame&) const;
   1873 
   1874  /* Returns whether the element has the transform property or a related
   1875   * property. */
   1876  bool HasTransformStyle() const {
   1877    return HasTransformProperty() || HasIndividualTransform() ||
   1878           mTransformStyle == mozilla::StyleTransformStyle::Preserve3d ||
   1879           (mWillChange.bits & mozilla::StyleWillChangeBits::TRANSFORM) ||
   1880           !mOffsetPath.IsNone();
   1881  }
   1882 
   1883  bool HasTransformProperty() const { return !mTransform._0.IsEmpty(); }
   1884 
   1885  bool HasIndividualTransform() const {
   1886    return !mRotate.IsNone() || !mTranslate.IsNone() || !mScale.IsNone();
   1887  }
   1888 
   1889  bool HasPerspectiveStyle() const { return !mChildPerspective.IsNone(); }
   1890 
   1891  bool BackfaceIsHidden() const {
   1892    return mBackfaceVisibility == mozilla::StyleBackfaceVisibility::Hidden;
   1893  }
   1894 
   1895  // FIXME(emilio): This should be more fine-grained on each caller to
   1896  // BreakBefore() / BreakAfter().
   1897  static bool ShouldBreak(mozilla::StyleBreakBetween aBreak) {
   1898    switch (aBreak) {
   1899      case mozilla::StyleBreakBetween::Left:
   1900      case mozilla::StyleBreakBetween::Right:
   1901      case mozilla::StyleBreakBetween::Page:
   1902      case mozilla::StyleBreakBetween::Always:
   1903        return true;
   1904      case mozilla::StyleBreakBetween::Auto:
   1905      case mozilla::StyleBreakBetween::Avoid:
   1906        return false;
   1907      default:
   1908        MOZ_ASSERT_UNREACHABLE("Unknown break kind");
   1909        return false;
   1910    }
   1911  }
   1912 
   1913  // These two methods are deprecated since they do not differentiate paginated
   1914  // context and multi-column context. Use nsIFrame::ShouldBreakBefore() /
   1915  // nsIFrame::ShouldBreakAfter() instead.
   1916  bool BreakBefore() const { return ShouldBreak(mBreakBefore); }
   1917  bool BreakAfter() const { return ShouldBreak(mBreakAfter); }
   1918 
   1919  // These are defined in nsStyleStructInlines.h.
   1920 
   1921  // The aContextFrame argument on each of these is the frame this
   1922  // style struct is for.  If the frame is for SVG text, the return
   1923  // value will be massaged to be something that makes sense for
   1924  // SVG text.
   1925  inline bool IsBlockOutside(const nsIFrame* aContextFrame) const;
   1926  inline bool IsInlineOutside(const nsIFrame* aContextFrame) const;
   1927  inline mozilla::StyleDisplay GetDisplay(const nsIFrame* aContextFrame) const;
   1928  inline bool IsFloating(const nsIFrame* aContextFrame) const;
   1929  inline bool IsRelativelyOrStickyPositioned(
   1930      const nsIFrame* aContextFrame) const;
   1931 
   1932  // Note: In general, you'd want to call IsRelativelyOrStickyPositioned()
   1933  // unless you want to deal with "position:relative" and "position:sticky"
   1934  // differently.
   1935  inline bool IsRelativelyPositioned(const nsIFrame* aContextFrame) const;
   1936  inline bool IsStickyPositioned(const nsIFrame* aContextFrame) const;
   1937 
   1938  inline bool IsAbsolutelyPositioned(const nsIFrame* aContextFrame) const;
   1939 
   1940  // These methods are defined in nsStyleStructInlines.h.
   1941 
   1942  /**
   1943   * Returns true when the element has the transform property
   1944   * or a related property, and supports CSS transforms.
   1945   * aContextFrame is the frame for which this is the nsStyleDisplay.
   1946   */
   1947  inline bool HasTransform(const nsIFrame* aContextFrame) const;
   1948 
   1949  /**
   1950   * Returns true when the element has the perspective property,
   1951   * and supports CSS transforms. aContextFrame is the frame for
   1952   * which this is the nsStyleDisplay.
   1953   */
   1954  inline bool HasPerspective(const nsIFrame* aContextFrame) const;
   1955 
   1956  inline bool
   1957  IsFixedPosContainingBlockForContainLayoutAndPaintSupportingFrames() const;
   1958  inline bool IsFixedPosContainingBlockForTransformSupportingFrames() const;
   1959 
   1960  mozilla::ContainSizeAxes GetContainSizeAxes(const nsIFrame& aFrame) const;
   1961 };
   1962 
   1963 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTable {
   1964  STYLE_STRUCT(nsStyleTable)
   1965  nsStyleTable();
   1966 
   1967  mozilla::StyleTableLayout mLayoutStrategy;
   1968  int32_t mXSpan;  // The number of columns spanned by a colgroup or col
   1969 };
   1970 
   1971 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleTableBorder {
   1972  STYLE_STRUCT(nsStyleTableBorder)
   1973  nsStyleTableBorder();
   1974 
   1975  mozilla::StyleBorderSpacing mBorderSpacing;
   1976  mozilla::StyleBorderCollapse mBorderCollapse;
   1977  mozilla::StyleCaptionSide mCaptionSide;
   1978  mozilla::StyleEmptyCells mEmptyCells;
   1979 };
   1980 
   1981 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleContent {
   1982  STYLE_STRUCT(nsStyleContent)
   1983  nsStyleContent();
   1984  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleContent*);
   1985 
   1986  using CounterPair = mozilla::StyleGenericCounterPair<int32_t>;
   1987 
   1988  /// Returns the content items that aren't alternative content.
   1989  mozilla::Span<const mozilla::StyleContentItem> NonAltContentItems() const {
   1990    if (!mContent.IsItems()) {
   1991      return {};
   1992    }
   1993    const auto& items = mContent.AsItems();
   1994    return mozilla::Span(items.items).To(items.alt_start);
   1995  }
   1996 
   1997  /// Returns the content items that /are/ alternative content.
   1998  mozilla::Span<const mozilla::StyleContentItem> AltContentItems() const {
   1999    if (!mContent.IsItems()) {
   2000      return {};
   2001    }
   2002    const auto& items = mContent.AsItems();
   2003    return mozilla::Span(items.items).From(items.alt_start);
   2004  }
   2005 
   2006  mozilla::StyleContent mContent;
   2007  mozilla::StyleCounterIncrement mCounterIncrement;
   2008  mozilla::StyleCounterReset mCounterReset;
   2009  mozilla::StyleCounterSet mCounterSet;
   2010 };
   2011 
   2012 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUIReset {
   2013  STYLE_STRUCT(nsStyleUIReset)
   2014  nsStyleUIReset();
   2015 
   2016 private:
   2017  mozilla::StyleUserSelect mUserSelect;  // Use ComputedStyle::UserSelect()
   2018  mozilla::StyleScrollbarWidth mScrollbarWidth;  // Use ScrollbarWidth()
   2019 
   2020 public:
   2021  mozilla::StyleUserSelect ComputedUserSelect() const { return mUserSelect; }
   2022 
   2023  mozilla::StyleScrollbarWidth ScrollbarWidth() const;
   2024 
   2025  const mozilla::StyleTransitionProperty& GetTransitionProperty(
   2026      uint32_t aIndex) const {
   2027    return mTransitions[aIndex % mTransitionPropertyCount].GetProperty();
   2028  }
   2029  const mozilla::StyleTime& GetTransitionDelay(uint32_t aIndex) const {
   2030    return mTransitions[aIndex % mTransitionDelayCount].GetDelay();
   2031  }
   2032  const mozilla::StyleTime& GetTransitionDuration(uint32_t aIndex) const {
   2033    return mTransitions[aIndex % mTransitionDurationCount].GetDuration();
   2034  }
   2035  const mozilla::StyleComputedTimingFunction& GetTransitionTimingFunction(
   2036      uint32_t aIndex) const {
   2037    return mTransitions[aIndex % mTransitionTimingFunctionCount]
   2038        .GetTimingFunction();
   2039  }
   2040  mozilla::StyleTransitionBehavior GetTransitionBehavior(
   2041      uint32_t aIndex) const {
   2042    return mTransitions[aIndex % mTransitionBehaviorCount].GetBehavior();
   2043  }
   2044  mozilla::StyleTime GetTransitionCombinedDuration(uint32_t aIndex) const {
   2045    // https://drafts.csswg.org/css-transitions/#transition-combined-duration
   2046    return {std::max(GetTransitionDuration(aIndex).seconds, 0.0f) +
   2047            GetTransitionDelay(aIndex).seconds};
   2048  }
   2049 
   2050  nsAtom* GetAnimationName(uint32_t aIndex) const {
   2051    return mAnimations[aIndex % mAnimationNameCount].GetName();
   2052  }
   2053  const mozilla::StyleTime& GetAnimationDelay(uint32_t aIndex) const {
   2054    return mAnimations[aIndex % mAnimationDelayCount].GetDelay();
   2055  }
   2056  const mozilla::StyleAnimationDuration& GetAnimationDuration(
   2057      uint32_t aIndex) const {
   2058    return mAnimations[aIndex % mAnimationDurationCount].GetDuration();
   2059  }
   2060  mozilla::StyleAnimationDirection GetAnimationDirection(
   2061      uint32_t aIndex) const {
   2062    return mAnimations[aIndex % mAnimationDirectionCount].GetDirection();
   2063  }
   2064  mozilla::StyleAnimationFillMode GetAnimationFillMode(uint32_t aIndex) const {
   2065    return mAnimations[aIndex % mAnimationFillModeCount].GetFillMode();
   2066  }
   2067  mozilla::StyleAnimationPlayState GetAnimationPlayState(
   2068      uint32_t aIndex) const {
   2069    return mAnimations[aIndex % mAnimationPlayStateCount].GetPlayState();
   2070  }
   2071  float GetAnimationIterationCount(uint32_t aIndex) const {
   2072    return mAnimations[aIndex % mAnimationIterationCountCount]
   2073        .GetIterationCount();
   2074  }
   2075  const mozilla::StyleComputedTimingFunction& GetAnimationTimingFunction(
   2076      uint32_t aIndex) const {
   2077    return mAnimations[aIndex % mAnimationTimingFunctionCount]
   2078        .GetTimingFunction();
   2079  }
   2080  mozilla::StyleAnimationComposition GetAnimationComposition(
   2081      uint32_t aIndex) const {
   2082    return mAnimations[aIndex % mAnimationCompositionCount].GetComposition();
   2083  }
   2084  const mozilla::StyleAnimationTimeline& GetTimeline(uint32_t aIndex) const {
   2085    return mAnimations[aIndex % mAnimationTimelineCount].GetTimeline();
   2086  }
   2087 
   2088  mozilla::StyleBoolInteger mMozForceBrokenImageIcon;
   2089  mozilla::StyleBoolInteger mMozSubtreeHiddenOnlyVisually;
   2090  mozilla::StyleImeMode mIMEMode;
   2091  mozilla::StyleWindowDragging mWindowDragging;
   2092  mozilla::StyleWindowShadow mWindowShadow;
   2093  float mWindowOpacity;
   2094  // The margin of the window region that should be transparent to events.
   2095  mozilla::StyleLength mMozWindowInputRegionMargin;
   2096  mozilla::StyleTransform mMozWindowTransform;
   2097 
   2098  nsStyleAutoArray<mozilla::StyleTransition> mTransitions;
   2099  // The number of elements in mTransitions that are not from repeating
   2100  // a list due to another property being longer.
   2101  uint32_t mTransitionTimingFunctionCount;
   2102  uint32_t mTransitionDurationCount;
   2103  uint32_t mTransitionDelayCount;
   2104  uint32_t mTransitionPropertyCount;
   2105  uint32_t mTransitionBehaviorCount;
   2106  nsStyleAutoArray<mozilla::StyleAnimation> mAnimations;
   2107  // The number of elements in mAnimations that are not from repeating
   2108  // a list due to another property being longer.
   2109  uint32_t mAnimationTimingFunctionCount;
   2110  uint32_t mAnimationDurationCount;
   2111  uint32_t mAnimationDelayCount;
   2112  uint32_t mAnimationNameCount;
   2113  uint32_t mAnimationDirectionCount;
   2114  uint32_t mAnimationFillModeCount;
   2115  uint32_t mAnimationPlayStateCount;
   2116  uint32_t mAnimationIterationCountCount;
   2117  uint32_t mAnimationCompositionCount;
   2118  uint32_t mAnimationTimelineCount;
   2119 
   2120  nsStyleAutoArray<mozilla::StyleScrollTimeline> mScrollTimelines;
   2121  uint32_t mScrollTimelineNameCount;
   2122  uint32_t mScrollTimelineAxisCount;
   2123 
   2124  nsStyleAutoArray<mozilla::StyleViewTimeline> mViewTimelines;
   2125  uint32_t mViewTimelineNameCount;
   2126  uint32_t mViewTimelineAxisCount;
   2127  uint32_t mViewTimelineInsetCount;
   2128 
   2129  mozilla::StyleFieldSizing mFieldSizing;
   2130 
   2131  bool HasViewTransitionName() const { return !mViewTransitionName.IsNone(); }
   2132 
   2133  mozilla::StyleViewTransitionName mViewTransitionName;
   2134  mozilla::StyleViewTransitionClass mViewTransitionClass;
   2135 };
   2136 
   2137 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleUI {
   2138  STYLE_STRUCT(nsStyleUI)
   2139  nsStyleUI();
   2140  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleUI*);
   2141 
   2142  mozilla::StyleInert mInert;
   2143  mozilla::StyleMozTheme mMozTheme;
   2144 
   2145 private:
   2146  mozilla::StyleUserFocus mUserFocus;
   2147  mozilla::StylePointerEvents mPointerEvents;
   2148  mozilla::StyleCursor mCursor;
   2149 
   2150 public:
   2151  bool IsInert() const { return mInert == mozilla::StyleInert::Inert; }
   2152 
   2153  mozilla::StyleUserFocus UserFocus() const {
   2154    return IsInert() ? mozilla::StyleUserFocus::None : mUserFocus;
   2155  }
   2156 
   2157  // This is likely not the getter you want (you probably want
   2158  // ComputedStyle::PointerEvents().
   2159  mozilla::StylePointerEvents ComputedPointerEvents() const {
   2160    return mPointerEvents;
   2161  }
   2162 
   2163  const mozilla::StyleCursor& Cursor() const {
   2164    static mozilla::StyleCursor sAuto{{}, mozilla::StyleCursorKind::Auto};
   2165    return IsInert() ? sAuto : mCursor;
   2166  }
   2167 
   2168  mozilla::StyleColorOrAuto mAccentColor;
   2169  mozilla::StyleCaretColor mCaretColor;
   2170  mozilla::StyleScrollbarColor mScrollbarColor;
   2171  mozilla::StyleColorScheme mColorScheme;
   2172 
   2173  bool HasCustomScrollbars() const { return !mScrollbarColor.IsAuto(); }
   2174 };
   2175 
   2176 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleXUL {
   2177  STYLE_STRUCT(nsStyleXUL)
   2178  nsStyleXUL();
   2179 
   2180  float mBoxFlex;
   2181  int32_t mBoxOrdinal;
   2182  mozilla::StyleBoxAlign mBoxAlign;
   2183  mozilla::StyleBoxDirection mBoxDirection;
   2184  mozilla::StyleBoxOrient mBoxOrient;
   2185  mozilla::StyleBoxPack mBoxPack;
   2186 };
   2187 
   2188 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleColumn {
   2189  STYLE_STRUCT(nsStyleColumn)
   2190  nsStyleColumn();
   2191 
   2192  mozilla::StyleColumnCount mColumnCount = mozilla::StyleColumnCount::Auto();
   2193  mozilla::NonNegativeLengthOrAuto mColumnWidth;
   2194 
   2195  mozilla::StyleColor mColumnRuleColor;
   2196  mozilla::StyleBorderStyle mColumnRuleStyle;
   2197  mozilla::StyleColumnFill mColumnFill = mozilla::StyleColumnFill::Balance;
   2198  mozilla::StyleColumnSpan mColumnSpan = mozilla::StyleColumnSpan::None;
   2199 
   2200  nscoord GetColumnRuleWidth() const {
   2201    if (!IsVisibleBorderStyle(mColumnRuleStyle)) {
   2202      return 0;
   2203    }
   2204    return mColumnRuleWidth;
   2205  }
   2206 
   2207  bool IsColumnContainerStyle() const {
   2208    return !mColumnCount.IsAuto() || !mColumnWidth.IsAuto();
   2209  }
   2210 
   2211  bool IsColumnSpanStyle() const {
   2212    return mColumnSpan == mozilla::StyleColumnSpan::All;
   2213  }
   2214 
   2215 protected:
   2216  mozilla::StyleBorderSideWidth mColumnRuleWidth;
   2217 };
   2218 
   2219 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVG {
   2220  STYLE_STRUCT(nsStyleSVG)
   2221  nsStyleSVG();
   2222 
   2223  mozilla::StyleSVGPaint mFill;
   2224  mozilla::StyleSVGPaint mStroke;
   2225  mozilla::StyleUrlOrNone mMarkerEnd;
   2226  mozilla::StyleUrlOrNone mMarkerMid;
   2227  mozilla::StyleUrlOrNone mMarkerStart;
   2228  mozilla::StyleMozContextProperties mMozContextProperties;
   2229 
   2230  mozilla::StyleSVGStrokeDashArray mStrokeDasharray;
   2231  mozilla::StyleSVGLength mStrokeDashoffset;
   2232  mozilla::StyleSVGWidth mStrokeWidth;
   2233 
   2234  mozilla::StyleSVGOpacity mFillOpacity;
   2235  float mStrokeMiterlimit;
   2236  mozilla::StyleSVGOpacity mStrokeOpacity;
   2237 
   2238  mozilla::StyleFillRule mClipRule;
   2239  mozilla::StyleColorInterpolation mColorInterpolation;
   2240  mozilla::StyleColorInterpolation mColorInterpolationFilters;
   2241  mozilla::StyleFillRule mFillRule;
   2242  mozilla::StyleSVGPaintOrder mPaintOrder;
   2243  mozilla::StyleShapeRendering mShapeRendering;
   2244  mozilla::StyleStrokeLinecap mStrokeLinecap;
   2245  mozilla::StyleStrokeLinejoin mStrokeLinejoin;
   2246  mozilla::StyleDominantBaseline mDominantBaseline;
   2247  mozilla::StyleTextAnchor mTextAnchor;
   2248 
   2249  /// Returns true if style has been set to expose the computed values of
   2250  /// certain properties (such as 'fill') to the contents of any linked images.
   2251  bool ExposesContextProperties() const {
   2252    return bool(mMozContextProperties.bits);
   2253  }
   2254 
   2255  bool HasMarker() const {
   2256    return mMarkerStart.IsUrl() || mMarkerMid.IsUrl() || mMarkerEnd.IsUrl();
   2257  }
   2258 
   2259  /**
   2260   * Returns true if the stroke is not "none" and the stroke-opacity is greater
   2261   * than zero (or a context-dependent value).
   2262   *
   2263   * This ignores stroke-widths as that depends on the context.
   2264   */
   2265  bool HasStroke() const {
   2266    if (mStroke.kind.IsNone()) {
   2267      return false;
   2268    }
   2269    return !mStrokeOpacity.IsOpacity() || mStrokeOpacity.AsOpacity() > 0;
   2270  }
   2271 
   2272  /**
   2273   * Returns true if the fill is not "none" and the fill-opacity is greater
   2274   * than zero (or a context-dependent value).
   2275   */
   2276  bool HasFill() const {
   2277    if (mFill.kind.IsNone()) {
   2278      return false;
   2279    }
   2280    return !mFillOpacity.IsOpacity() || mFillOpacity.AsOpacity() > 0;
   2281  }
   2282 };
   2283 
   2284 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleSVGReset {
   2285  STYLE_STRUCT(nsStyleSVGReset)
   2286  nsStyleSVGReset();
   2287  void TriggerImageLoads(mozilla::dom::Document&, const nsStyleSVGReset*);
   2288 
   2289  bool HasClipPath() const { return !mClipPath.IsNone(); }
   2290 
   2291  bool HasMask() const;
   2292 
   2293  bool HasNonScalingStroke() const {
   2294    return mVectorEffect.HasNonScalingStroke();
   2295  }
   2296 
   2297  // geometry properties
   2298  mozilla::LengthPercentage mX;
   2299  mozilla::LengthPercentage mY;
   2300  mozilla::LengthPercentage mCx;
   2301  mozilla::LengthPercentage mCy;
   2302  mozilla::NonNegativeLengthPercentageOrAuto mRx;
   2303  mozilla::NonNegativeLengthPercentageOrAuto mRy;
   2304  mozilla::NonNegativeLengthPercentage mR;
   2305 
   2306  nsStyleImageLayers mMask;
   2307  mozilla::StyleClipPath mClipPath;
   2308  mozilla::StyleColor mStopColor;
   2309  mozilla::StyleColor mFloodColor;
   2310  mozilla::StyleColor mLightingColor;
   2311 
   2312  float mStopOpacity;
   2313  float mFloodOpacity;
   2314 
   2315  mozilla::StyleVectorEffect mVectorEffect;
   2316  mozilla::StyleMaskType mMaskType;
   2317 
   2318  mozilla::StyleDProperty mD;
   2319 };
   2320 
   2321 struct MOZ_NEEDS_MEMMOVABLE_MEMBERS nsStyleEffects {
   2322  STYLE_STRUCT(nsStyleEffects)
   2323  nsStyleEffects();
   2324 
   2325  bool HasFilters() const { return !mFilters.IsEmpty(); }
   2326 
   2327  bool HasBackdropFilters() const { return !mBackdropFilters.IsEmpty(); }
   2328 
   2329  bool HasBoxShadowWithInset(bool aInset) const {
   2330    for (const auto& shadow : mBoxShadow.AsSpan()) {
   2331      if (shadow.inset == aInset) {
   2332        return true;
   2333      }
   2334    }
   2335    return false;
   2336  }
   2337 
   2338  bool HasMixBlendMode() const {
   2339    return mMixBlendMode != mozilla::StyleBlend::Normal;
   2340  }
   2341 
   2342  bool IsOpaque() const { return mOpacity >= 1.0f; }
   2343 
   2344  bool IsTransparent() const { return mOpacity == 0.0f; }
   2345 
   2346  mozilla::StyleOwnedSlice<mozilla::StyleFilter> mFilters;
   2347  mozilla::StyleOwnedSlice<mozilla::StyleBoxShadow> mBoxShadow;
   2348  mozilla::StyleOwnedSlice<mozilla::StyleFilter> mBackdropFilters;
   2349  mozilla::StyleClipRectOrAuto mClip;  // offsets from UL border edge
   2350  float mOpacity;
   2351  mozilla::StyleBlend mMixBlendMode;
   2352 };
   2353 
   2354 #undef STYLE_STRUCT
   2355 
   2356 #define STATIC_ASSERT_TYPE_LAYOUTS_MATCH(T1, T2)           \
   2357  static_assert(sizeof(T1) == sizeof(T2),                  \
   2358                "Size mismatch between " #T1 " and " #T2); \
   2359  static_assert(alignof(T1) == alignof(T2),                \
   2360                "Align mismatch between " #T1 " and " #T2);
   2361 
   2362 #define STATIC_ASSERT_FIELD_OFFSET_MATCHES(T1, T2, field)          \
   2363  static_assert(offsetof(T1, field) == offsetof(T2, field),        \
   2364                "Field offset mismatch of " #field " between " #T1 \
   2365                " and " #T2);
   2366 
   2367 /**
   2368 * These *_Simple types are used to map Gecko types to layout-equivalent but
   2369 * simpler Rust types, to aid Rust binding generation.
   2370 *
   2371 * If something in this types or the assertions below needs to change, ask
   2372 * bholley, heycam or emilio before!
   2373 *
   2374 * <div rustbindgen="true" replaces="nsPoint">
   2375 */
   2376 struct nsPoint_Simple {
   2377  nscoord x, y;
   2378 };
   2379 
   2380 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsPoint, nsPoint_Simple);
   2381 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, x);
   2382 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsPoint, nsPoint_Simple, y);
   2383 
   2384 /**
   2385 * <div rustbindgen="true" replaces="nsMargin">
   2386 */
   2387 struct nsMargin_Simple {
   2388  nscoord top, right, bottom, left;
   2389 };
   2390 
   2391 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsMargin, nsMargin_Simple);
   2392 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, top);
   2393 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, right);
   2394 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, bottom);
   2395 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsMargin, nsMargin_Simple, left);
   2396 
   2397 /**
   2398 * <div rustbindgen="true" replaces="nsRect">
   2399 */
   2400 struct nsRect_Simple {
   2401  nscoord x, y, width, height;
   2402 };
   2403 
   2404 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsRect, nsRect_Simple);
   2405 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, x);
   2406 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, y);
   2407 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, width);
   2408 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsRect, nsRect_Simple, height);
   2409 
   2410 /**
   2411 * <div rustbindgen="true" replaces="nsSize">
   2412 */
   2413 struct nsSize_Simple {
   2414  nscoord width, height;
   2415 };
   2416 
   2417 STATIC_ASSERT_TYPE_LAYOUTS_MATCH(nsSize, nsSize_Simple);
   2418 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, width);
   2419 STATIC_ASSERT_FIELD_OFFSET_MATCHES(nsSize, nsSize_Simple, height);
   2420 
   2421 #endif /* nsStyleStruct_h___ */