tor-browser

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

nsComputedDOMStyle.h (15239B)


      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 /* DOM object returned from element.getComputedStyle() */
      8 
      9 #ifndef nsComputedDOMStyle_h__
     10 #define nsComputedDOMStyle_h__
     11 
     12 #include "mozilla/ComputedStyle.h"
     13 #include "mozilla/PseudoStyleType.h"
     14 #include "mozilla/StyleColorInlines.h"
     15 #include "mozilla/WritingModes.h"
     16 #include "mozilla/gfx/Types.h"
     17 #include "nsCOMPtr.h"
     18 #include "nsColor.h"
     19 #include "nsContentUtils.h"
     20 #include "nsCoord.h"
     21 #include "nsDOMCSSDeclaration.h"
     22 #include "nsIWeakReferenceUtils.h"
     23 #include "nsStubMutationObserver.h"
     24 #include "nsStyleStruct.h"
     25 #include "nsStyleStructList.h"
     26 #include "nscore.h"
     27 
     28 // XXX Avoid including this here by moving function bodies to the cpp file
     29 #include "mozilla/dom/Element.h"
     30 
     31 namespace mozilla {
     32 enum class FlushType : uint8_t;
     33 
     34 namespace dom {
     35 class DocGroup;
     36 class Element;
     37 }  // namespace dom
     38 class PresShell;
     39 struct ComputedGridTrackInfo;
     40 }  // namespace mozilla
     41 
     42 struct ComputedStyleMap;
     43 struct nsCSSKTableEntry;
     44 class nsIFrame;
     45 class nsDOMCSSValueList;
     46 struct nsMargin;
     47 class nsROCSSPrimitiveValue;
     48 class nsStyleGradient;
     49 
     50 class nsComputedDOMStyle final : public nsDOMCSSDeclaration,
     51                                 public nsStubMutationObserver {
     52 private:
     53  // Convenience typedefs:
     54  template <typename T>
     55  using Span = mozilla::Span<T>;
     56  using KTableEntry = nsCSSKTableEntry;
     57  using CSSValue = mozilla::dom::CSSValue;
     58  using StyleGeometryBox = mozilla::StyleGeometryBox;
     59  using Element = mozilla::dom::Element;
     60  using Document = mozilla::dom::Document;
     61  using PseudoStyleRequest = mozilla::PseudoStyleRequest;
     62  using LengthPercentage = mozilla::LengthPercentage;
     63  using LengthPercentageOrAuto = mozilla::LengthPercentageOrAuto;
     64  using ComputedStyle = mozilla::ComputedStyle;
     65 
     66 public:
     67  NS_DECL_CYCLE_COLLECTING_ISUPPORTS
     68  NS_DECL_CYCLE_COLLECTION_SKIPPABLE_WRAPPERCACHE_CLASS_AMBIGUOUS(
     69      nsComputedDOMStyle, nsICSSDeclaration)
     70 
     71  NS_DECL_NSIDOMCSSSTYLEDECLARATION_HELPER
     72 
     73  void GetPropertyValue(const NonCustomCSSPropertyId aPropId,
     74                        nsACString& aValue) override;
     75  void SetPropertyValue(const NonCustomCSSPropertyId aPropId,
     76                        const nsACString& aValue,
     77                        nsIPrincipal* aSubjectPrincipal,
     78                        mozilla::ErrorResult& aRv) override;
     79 
     80  void IndexedGetter(uint32_t aIndex, bool& aFound,
     81                     nsACString& aPropName) final;
     82 
     83  enum class StyleType : uint8_t {
     84    DefaultOnly,  // Only includes UA and user sheets
     85    All           // Includes all stylesheets
     86  };
     87 
     88  // In some cases, for legacy reasons, we forcefully return an empty style.
     89  enum class AlwaysReturnEmptyStyle : bool { No, Yes };
     90 
     91  nsComputedDOMStyle(Element*, PseudoStyleRequest&&, Document*, StyleType,
     92                     AlwaysReturnEmptyStyle = AlwaysReturnEmptyStyle::No);
     93 
     94  nsINode* GetAssociatedNode() const override { return mElement; }
     95  nsINode* GetParentObject() const override { return mElement; }
     96 
     97  static already_AddRefed<const ComputedStyle> GetComputedStyle(
     98      Element* aElement, const PseudoStyleRequest& aType = {},
     99      StyleType = StyleType::All);
    100 
    101  static already_AddRefed<const ComputedStyle> GetComputedStyleNoFlush(
    102      const Element* aElement, const PseudoStyleRequest& aPseudo = {},
    103      StyleType aStyleType = StyleType::All) {
    104    return DoGetComputedStyleNoFlush(
    105        aElement, aPseudo, nsContentUtils::GetPresShellForContent(aElement),
    106        aStyleType);
    107  }
    108 
    109  static already_AddRefed<const ComputedStyle>
    110  GetUnanimatedComputedStyleNoFlush(Element*, const PseudoStyleRequest&);
    111 
    112  // Helper for nsDOMWindowUtils::GetVisitedDependentComputedStyle
    113  void SetExposeVisitedStyle(bool aExpose) {
    114    NS_ASSERTION(aExpose != mExposeVisitedStyle, "should always be changing");
    115    mExposeVisitedStyle = aExpose;
    116  }
    117 
    118  float UsedFontSize() final;
    119 
    120  void GetCSSImageURLs(const nsACString& aPropertyName,
    121                       nsTArray<nsCString>& aImageURLs,
    122                       mozilla::ErrorResult& aRv) final;
    123 
    124  // nsDOMCSSDeclaration abstract methods which should never be called
    125  // on a nsComputedDOMStyle object, but must be defined to avoid
    126  // compile errors.
    127  mozilla::DeclarationBlock* GetOrCreateCSSDeclaration(
    128      Operation aOperation, mozilla::DeclarationBlock** aCreated) final;
    129  virtual nsresult SetCSSDeclaration(mozilla::DeclarationBlock*,
    130                                     mozilla::MutationClosureData*) override;
    131  virtual mozilla::dom::Document* DocToUpdate() final;
    132 
    133  nsDOMCSSDeclaration::ParsingEnvironment GetParsingEnvironment(
    134      nsIPrincipal* aSubjectPrincipal) const final;
    135 
    136  static already_AddRefed<nsROCSSPrimitiveValue> MatrixToCSSValue(
    137      const mozilla::gfx::Matrix4x4& aMatrix);
    138 
    139  static void RegisterPrefChangeCallbacks();
    140  static void UnregisterPrefChangeCallbacks();
    141 
    142  // nsIMutationObserver
    143  NS_DECL_NSIMUTATIONOBSERVER_PARENTCHAINCHANGED
    144 
    145 private:
    146  already_AddRefed<nsROCSSPrimitiveValue> AppUnitsToCSSValue(nscoord);
    147  already_AddRefed<nsROCSSPrimitiveValue> PixelsToCSSValue(float);
    148  void SetValueToPixels(nsROCSSPrimitiveValue*, float);
    149 
    150  void GetPropertyValue(const NonCustomCSSPropertyId aPropId,
    151                        const nsACString& aMaybeCustomPropertyNme,
    152                        nsACString& aValue);
    153  using nsDOMCSSDeclaration::GetPropertyValue;
    154 
    155  virtual ~nsComputedDOMStyle();
    156 
    157  void AssertFlushedPendingReflows() {
    158    NS_ASSERTION(mFlushedPendingReflows,
    159                 "property getter should have been marked layout-dependent");
    160  }
    161 
    162  nsMargin GetAdjustedValuesForBoxSizing();
    163 
    164  // This indicates error by leaving mComputedStyle null.
    165  void UpdateCurrentStyleSources(NonCustomCSSPropertyId);
    166  void ClearCurrentStyleSources();
    167 
    168  // Helper functions called by UpdateCurrentStyleSources.
    169  void ClearComputedStyle();
    170  void SetResolvedComputedStyle(RefPtr<const ComputedStyle>,
    171                                uint64_t aGeneration);
    172  void SetFrameComputedStyle(RefPtr<const ComputedStyle>, uint64_t aGeneration);
    173 
    174  static already_AddRefed<const ComputedStyle> DoGetComputedStyleNoFlush(
    175      const Element*, const PseudoStyleRequest&, mozilla::PresShell*,
    176      StyleType);
    177 
    178 #define COMPUTED_STYLE_ACCESSOR(name_)         \
    179  const nsStyle##name_* Style##name_() const { \
    180    return mComputedStyle->Style##name_();     \
    181  }
    182  FOR_EACH_STYLE_STRUCT(COMPUTED_STYLE_ACCESSOR, COMPUTED_STYLE_ACCESSOR)
    183 #undef COMPUTED_STYLE_ACCESSOR
    184 
    185  /**
    186   * A method to get a percentage base for a percentage value.  Returns true
    187   * if a percentage base value was determined, false otherwise.
    188   */
    189  typedef bool (nsComputedDOMStyle::*PercentageBaseGetter)(nscoord&);
    190 
    191  already_AddRefed<CSSValue> GetOffsetWidthFor(mozilla::Side);
    192  already_AddRefed<CSSValue> GetAbsoluteOffset(mozilla::Side);
    193  nscoord GetUsedAbsoluteOffset(mozilla::Side);
    194  already_AddRefed<CSSValue> GetNonStaticPositionOffset(
    195      mozilla::Side aSide, bool aResolveAuto, PercentageBaseGetter aWidthGetter,
    196      PercentageBaseGetter aHeightGetter);
    197 
    198  already_AddRefed<CSSValue> GetStaticOffset(mozilla::Side aSide);
    199 
    200  already_AddRefed<CSSValue> GetPaddingWidthFor(mozilla::Side aSide);
    201 
    202  already_AddRefed<CSSValue> GetMarginFor(mozilla::Side aSide);
    203 
    204  already_AddRefed<CSSValue> GetTransformValue(const mozilla::StyleTransform&);
    205 
    206  already_AddRefed<nsROCSSPrimitiveValue> GetGridTrackSize(
    207      const mozilla::StyleTrackSize&);
    208  already_AddRefed<nsROCSSPrimitiveValue> GetGridTrackBreadth(
    209      const mozilla::StyleTrackBreadth&);
    210  void SetValueToTrackBreadth(nsROCSSPrimitiveValue*,
    211                              const mozilla::StyleTrackBreadth&);
    212  already_AddRefed<CSSValue> GetGridTemplateColumnsRows(
    213      const mozilla::StyleGridTemplateComponent& aTrackList,
    214      const mozilla::ComputedGridTrackInfo& aTrackInfo);
    215 
    216  bool GetLineHeightCoord(nscoord& aCoord);
    217 
    218  bool ShouldHonorMinSizeAutoInAxis(mozilla::PhysicalAxis aAxis);
    219 
    220  /* Properties queryable as CSSValues.
    221   * To avoid a name conflict with nsIDOM*CSS2Properties, these are all
    222   * DoGetXXX instead of GetXXX.
    223   */
    224 
    225  /* Box properties */
    226 
    227  already_AddRefed<CSSValue> DoGetWidth();
    228  already_AddRefed<CSSValue> DoGetHeight();
    229  already_AddRefed<CSSValue> DoGetMaxHeight();
    230  already_AddRefed<CSSValue> DoGetMaxWidth();
    231  already_AddRefed<CSSValue> DoGetMinHeight();
    232  already_AddRefed<CSSValue> DoGetMinWidth();
    233  already_AddRefed<CSSValue> DoGetLeft();
    234  already_AddRefed<CSSValue> DoGetTop();
    235  already_AddRefed<CSSValue> DoGetRight();
    236  already_AddRefed<CSSValue> DoGetBottom();
    237 
    238  /* Font properties */
    239  already_AddRefed<CSSValue> DoGetMozOsxFontSmoothing();
    240 
    241  /* Grid properties */
    242  already_AddRefed<CSSValue> DoGetGridTemplateColumns();
    243  already_AddRefed<CSSValue> DoGetGridTemplateRows();
    244 
    245  /* StyleImageLayer properties */
    246  already_AddRefed<CSSValue> DoGetImageLayerPosition(
    247      const nsStyleImageLayers& aLayers);
    248 
    249  /* Padding properties */
    250  already_AddRefed<CSSValue> DoGetPaddingTop();
    251  already_AddRefed<CSSValue> DoGetPaddingBottom();
    252  already_AddRefed<CSSValue> DoGetPaddingLeft();
    253  already_AddRefed<CSSValue> DoGetPaddingRight();
    254 
    255  /* Margin Properties */
    256  already_AddRefed<CSSValue> DoGetMarginTop();
    257  already_AddRefed<CSSValue> DoGetMarginBottom();
    258  already_AddRefed<CSSValue> DoGetMarginLeft();
    259  already_AddRefed<CSSValue> DoGetMarginRight();
    260 
    261  /* Display properties */
    262  already_AddRefed<CSSValue> DoGetTransform();
    263  already_AddRefed<CSSValue> DoGetTransformOrigin();
    264  already_AddRefed<CSSValue> DoGetPerspectiveOrigin();
    265 
    266  // For working around a MSVC bug. See related comment in
    267  // GenerateComputedDOMStyleGenerated.py.
    268  already_AddRefed<CSSValue> DummyGetter();
    269 
    270  /* Helper functions */
    271  void SetValueToPosition(const mozilla::Position& aPosition,
    272                          nsDOMCSSValueList* aValueList);
    273 
    274  void SetValueFromFitContentFunction(nsROCSSPrimitiveValue* aValue,
    275                                      const mozilla::LengthPercentage&);
    276 
    277  void SetValueToSize(nsROCSSPrimitiveValue* aValue, const AnchorResolvedSize&);
    278 
    279  void SetValueToLengthPercentageOrAuto(nsROCSSPrimitiveValue* aValue,
    280                                        const LengthPercentageOrAuto&,
    281                                        bool aClampNegativeCalc);
    282  void SetValueToMargin(nsROCSSPrimitiveValue* aValue,
    283                        const mozilla::StyleMargin&);
    284 
    285  void SetValueToLengthPercentage(nsROCSSPrimitiveValue* aValue,
    286                                  const LengthPercentage&,
    287                                  bool aClampNegativeCalc);
    288 
    289  void SetValueToMaxSize(nsROCSSPrimitiveValue* aValue,
    290                         const AnchorResolvedMaxSize&);
    291 
    292  bool GetCBContentWidth(nscoord& aWidth);
    293  bool GetCBContentHeight(nscoord& aHeight);
    294  bool GetCBPaddingRectWidth(nscoord& aWidth);
    295  bool GetCBPaddingRectHeight(nscoord& aHeight);
    296  bool GetScrollFrameContentWidth(nscoord& aWidth);
    297  bool GetScrollFrameContentHeight(nscoord& aHeight);
    298  bool GetFrameBorderRectWidth(nscoord& aWidth);
    299  bool GetFrameBorderRectHeight(nscoord& aHeight);
    300 
    301  // Find out if we can safely skip flushing (i.e. pending restyles do not
    302  // affect our element).
    303  bool NeedsToFlushStyle(NonCustomCSSPropertyId) const;
    304  // Find out if we need to flush layout of the document, depending on the
    305  // property that was requested.
    306  bool NeedsToFlushLayout(NonCustomCSSPropertyId) const;
    307  // Find out if we need to flush layout of the document due to container
    308  // query being made before relevant query containers are reflowed at least
    309  // once.
    310  bool NeedsToFlushLayoutForContainerQuery() const;
    311  // Flushes the given document, which must be our document, and potentially the
    312  // mElement's document.
    313  void Flush(Document&, mozilla::FlushType);
    314  nsIFrame* GetOuterFrame() const;
    315 
    316  static ComputedStyleMap* GetComputedStyleMap();
    317 
    318  // We don't really have a good immutable representation of "presentation".
    319  // Given the way GetComputedStyle is currently used, we should just grab the
    320  // presshell, if any, from the document.
    321  mozilla::WeakPtr<mozilla::dom::Document> mDocumentWeak;
    322  RefPtr<Element> mElement;
    323 
    324  /**
    325   * Strong reference to the ComputedStyle we access data from.  This can be
    326   * either a ComputedStyle we resolved ourselves or a ComputedStyle we got
    327   * from our frame.
    328   *
    329   * If we got the ComputedStyle from the frame, we clear out mComputedStyle
    330   * in ClearCurrentStyleSources.  If we resolved one ourselves, then
    331   * ClearCurrentStyleSources leaves it in mComputedStyle for use the next
    332   * time this nsComputedDOMStyle object is queried.  UpdateCurrentStyleSources
    333   * in this case will check that the ComputedStyle is still valid to be used,
    334   * by checking whether flush styles results in any restyles having been
    335   * processed.
    336   */
    337  RefPtr<const ComputedStyle> mComputedStyle;
    338 
    339  /*
    340   * While computing style data, the primary frame for mContent --- named
    341   * "outer" because we should use it to compute positioning data.  Null
    342   * otherwise.
    343   */
    344  nsIFrame* mOuterFrame;
    345  /*
    346   * While computing style data, the "inner frame" for mContent --- the frame
    347   * which we should use to compute margin, border, padding and content data.
    348   * Null otherwise.
    349   */
    350  nsIFrame* mInnerFrame;
    351  /*
    352   * While computing style data, the presshell we're working with.  Null
    353   * otherwise.
    354   */
    355  mozilla::PresShell* mPresShell;
    356 
    357  /*
    358   * The pseudo style request which packs PseudoStyleType and the function
    359   * parameter if any.
    360   */
    361  PseudoStyleRequest mPseudo;
    362 
    363  /* The kind of styles we should be returning. */
    364  StyleType mStyleType;
    365 
    366  /* Whether for legacy reasons we return an empty style (when an unknown
    367   * pseudo-element is specified) */
    368  AlwaysReturnEmptyStyle mAlwaysReturnEmpty;
    369 
    370  /**
    371   * The nsComputedDOMStyle generation at the time we last resolved a style
    372   * context and stored it in mComputedStyle, and the pres shell we got the
    373   * style from. Should only be used together.
    374   */
    375  uint64_t mComputedStyleGeneration = 0;
    376 
    377  uint32_t mPresShellId = 0;
    378 
    379  bool mExposeVisitedStyle = false;
    380 
    381  /**
    382   * Whether we resolved a ComputedStyle last time we called
    383   * UpdateCurrentStyleSources.  Initially false.
    384   */
    385  bool mResolvedComputedStyle = false;
    386 
    387 #ifdef DEBUG
    388  bool mFlushedPendingReflows = false;
    389 #endif
    390 
    391  friend struct ComputedStyleMap;
    392  friend AnchorPosResolutionParams AnchorPosResolutionParams::From(
    393      const nsComputedDOMStyle*);
    394 };
    395 
    396 already_AddRefed<nsComputedDOMStyle> NS_NewComputedDOMStyle(
    397    mozilla::dom::Element*, const nsAString& aPseudoElt,
    398    mozilla::dom::Document*, nsComputedDOMStyle::StyleType,
    399    mozilla::ErrorResult&);
    400 
    401 inline AnchorPosResolutionParams AnchorPosResolutionParams::From(
    402    const nsComputedDOMStyle* aComputedDOMStyle) {
    403  AutoResolutionOverrideParams overrides{aComputedDOMStyle->mOuterFrame};
    404  return {aComputedDOMStyle->mOuterFrame,
    405          aComputedDOMStyle->StyleDisplay()->mPosition, nullptr, overrides};
    406 }
    407 
    408 #endif /* nsComputedDOMStyle_h__ */