tor-browser

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

nsCSSProps.h (9062B)


      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 * methods for dealing with CSS properties and tables of the keyword
      9 * values they accept
     10 */
     11 
     12 #ifndef nsCSSProps_h___
     13 #define nsCSSProps_h___
     14 
     15 #include <ostream>
     16 
     17 #include "NonCustomCSSPropertyId.h"
     18 #include "mozilla/CSSEnabledState.h"
     19 #include "mozilla/CSSPropFlags.h"
     20 #include "mozilla/Preferences.h"
     21 #include "mozilla/UseCounter.h"
     22 #include "nsString.h"
     23 #include "nsStyleStructFwd.h"
     24 
     25 // Length of the "--" prefix on custom names (such as custom property names,
     26 // and, in the future, custom media query names).
     27 #define CSS_CUSTOM_NAME_PREFIX_LENGTH 2
     28 
     29 namespace mozilla {
     30 class ComputedStyle;
     31 namespace gfx {
     32 class gfxVarReceiver;
     33 }
     34 }  // namespace mozilla
     35 
     36 extern "C" {
     37 NonCustomCSSPropertyId Servo_ResolveLogicalProperty(
     38    NonCustomCSSPropertyId, const mozilla::ComputedStyle*);
     39 NonCustomCSSPropertyId Servo_Property_LookupEnabledForAllContent(
     40    const nsACString*);
     41 const uint8_t* Servo_Property_GetName(NonCustomCSSPropertyId,
     42                                      uint32_t* aLength);
     43 }
     44 
     45 class nsCSSProps {
     46 public:
     47  using EnabledState = mozilla::CSSEnabledState;
     48  using Flags = mozilla::CSSPropFlags;
     49 
     50  static void Init();
     51 
     52  // Looks up the property with name aProperty and returns its corresponding
     53  // NonCustomCSSPropertyId value.  If aProperty is the name of a custom
     54  // property, then eCSSPropertyExtra_variable will be returned.
     55  //
     56  // This only returns properties enabled for all content, and resolves aliases
     57  // to return the aliased property.
     58  static NonCustomCSSPropertyId LookupProperty(const nsACString& aProperty) {
     59    return Servo_Property_LookupEnabledForAllContent(&aProperty);
     60  }
     61 
     62  // As above, but looked up using a property's IDL name.
     63  // eCSSPropertyExtra_variable won't be returned from this method.
     64  static NonCustomCSSPropertyId LookupPropertyByIDLName(
     65      const nsACString& aPropertyIDLName, EnabledState aEnabled);
     66 
     67  // Returns whether aProperty is a custom property name, i.e. begins with
     68  // "--".  This assumes that the CSS Variables pref has been enabled.
     69  static bool IsCustomPropertyName(const nsACString& aProperty);
     70 
     71  static bool IsShorthand(NonCustomCSSPropertyId aProperty) {
     72    if (aProperty == eCSSPropertyExtra_variable) {
     73      return false;
     74    }
     75    MOZ_ASSERT(
     76        aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT,
     77        "out of range");
     78    return aProperty >= eCSSProperty_COUNT_no_shorthands;
     79  }
     80 
     81  // Same but for @font-face descriptors
     82  static nsCSSFontDesc LookupFontDesc(const nsACString&);
     83 
     84  // The relevant invariants are asserted in Document.cpp
     85  static mozilla::UseCounter UseCounterFor(NonCustomCSSPropertyId aProperty) {
     86    MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN &&
     87                   aProperty < eCSSProperty_COUNT_with_aliases,
     88               "out of range");
     89    return mozilla::UseCounter(size_t(mozilla::eUseCounter_FirstCSSProperty) +
     90                               size_t(aProperty));
     91  }
     92 
     93  // Given a property enum, get the string value
     94  //
     95  // This string is static.
     96  static nsDependentCSubstring GetStringValue(
     97      NonCustomCSSPropertyId aProperty) {
     98    uint32_t len;
     99    const uint8_t* chars = Servo_Property_GetName(aProperty, &len);
    100    return nsDependentCSubstring(reinterpret_cast<const char*>(chars), len);
    101  }
    102 
    103  static const nsCString& GetStringValue(nsCSSFontDesc aFontDesc);
    104  static const nsCString& GetStringValue(nsCSSCounterDesc aCounterDesc);
    105 
    106  static Flags PropFlags(NonCustomCSSPropertyId);
    107  static bool PropHasFlags(NonCustomCSSPropertyId aProperty, Flags aFlags) {
    108    return (PropFlags(aProperty) & aFlags) == aFlags;
    109  }
    110 
    111  static NonCustomCSSPropertyId Physicalize(
    112      NonCustomCSSPropertyId aProperty, const mozilla::ComputedStyle& aStyle) {
    113    MOZ_ASSERT(!IsShorthand(aProperty));
    114    if (PropHasFlags(aProperty, Flags::IsLogical)) {
    115      return Servo_ResolveLogicalProperty(aProperty, &aStyle);
    116    }
    117    return aProperty;
    118  }
    119 
    120 private:
    121  // A table for shorthand properties.  The appropriate index is the
    122  // property id minus eCSSProperty_COUNT_no_shorthands.
    123  static const NonCustomCSSPropertyId* const
    124      kSubpropertyTable[eCSSProperty_COUNT - eCSSProperty_COUNT_no_shorthands];
    125 
    126 public:
    127  /**
    128   * Returns true if the backdrop-filter pref and the gfx blocklist are enabled.
    129   */
    130  static bool IsBackdropFilterAvailable(JSContext*, JSObject*) {
    131    return IsEnabled(eCSSProperty_backdrop_filter, EnabledState::ForAllContent);
    132  }
    133 
    134  /**
    135   * Recoumputes the enabled state of a pref. If aPrefName is nullptr,
    136   * recomputes the state of all prefs in gPropertyEnabled.
    137   * aClosure is the pref callback closure data, which is not used.
    138   */
    139  static void RecomputeEnabledState(const char* aPrefName,
    140                                    void* aClosure = nullptr);
    141 
    142  /**
    143   * Retrieve a singleton receiver to register with gfxVars
    144   */
    145  static mozilla::gfx::gfxVarReceiver& GfxVarReceiver();
    146 
    147  static const NonCustomCSSPropertyId* SubpropertyEntryFor(
    148      NonCustomCSSPropertyId aProperty) {
    149    MOZ_ASSERT(eCSSProperty_COUNT_no_shorthands <= aProperty &&
    150                   aProperty < eCSSProperty_COUNT,
    151               "out of range");
    152    return kSubpropertyTable[aProperty - eCSSProperty_COUNT_no_shorthands];
    153  }
    154 
    155 private:
    156  static bool gPropertyEnabled[eCSSProperty_COUNT_with_aliases];
    157  // Defined in the generated nsCSSPropsGenerated.inc.
    158  static const char* const kIDLNameTable[eCSSProperty_COUNT];
    159  static const int32_t kIDLNameSortPositionTable[eCSSProperty_COUNT];
    160 
    161 public:
    162  /**
    163   * Returns the IDL name of the specified property, which must be a
    164   * longhand, logical or shorthand property.  The IDL name is the property
    165   * name with any hyphen-lowercase character pairs replaced by an
    166   * uppercase character:
    167   * https://drafts.csswg.org/cssom/#css-property-to-idl-attribute
    168   *
    169   * As a special case, the string "cssFloat" is returned for the float
    170   * property.  nullptr is returned for internal properties.
    171   */
    172  static const char* PropertyIDLName(NonCustomCSSPropertyId aProperty) {
    173    MOZ_ASSERT(
    174        aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT,
    175        "out of range");
    176    return kIDLNameTable[aProperty];
    177  }
    178 
    179  /**
    180   * Returns the position of the specified property in a list of all
    181   * properties sorted by their IDL name.
    182   */
    183  static int32_t PropertyIDLNameSortPosition(NonCustomCSSPropertyId aProperty) {
    184    MOZ_ASSERT(
    185        aProperty != eCSSProperty_UNKNOWN && aProperty < eCSSProperty_COUNT,
    186        "out of range");
    187    return kIDLNameSortPositionTable[aProperty];
    188  }
    189 
    190  static bool IsEnabled(NonCustomCSSPropertyId aProperty,
    191                        EnabledState aEnabled) {
    192    MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN &&
    193                   aProperty < eCSSProperty_COUNT_with_aliases,
    194               "out of range");
    195    // In the child process, assert that we're not trying to parse stylesheets
    196    // before we've gotten all our prefs.
    197    MOZ_ASSERT_IF(!XRE_IsParentProcess(),
    198                  mozilla::Preferences::ArePrefsInitedInContentProcess());
    199    if (gPropertyEnabled[aProperty]) {
    200      return true;
    201    }
    202    if (aEnabled == EnabledState::IgnoreEnabledState) {
    203      return true;
    204    }
    205    if ((aEnabled & EnabledState::InUASheets) &&
    206        PropHasFlags(aProperty, Flags::EnabledInUASheets)) {
    207      return true;
    208    }
    209    if ((aEnabled & EnabledState::InChrome) &&
    210        PropHasFlags(aProperty, Flags::EnabledInChrome)) {
    211      return true;
    212    }
    213    return false;
    214  }
    215 
    216  struct PropertyPref {
    217    NonCustomCSSPropertyId mPropId;
    218    const char* mPref;
    219  };
    220  static const PropertyPref kPropertyPrefTable[];
    221 
    222 // Storing the enabledstate_ value in an NonCustomCSSPropertyId variable is a
    223 // small hack to avoid needing a separate variable declaration for its real type
    224 // (CSSEnabledState), which would then require using a block and
    225 // therefore a pair of macros by consumers for the start and end of the loop.
    226 #define CSSPROPS_FOR_SHORTHAND_SUBPROPERTIES(it_, prop_, enabledstate_)       \
    227  for (const NonCustomCSSPropertyId *                                         \
    228           it_ = nsCSSProps::SubpropertyEntryFor(prop_),                      \
    229          es_ =                                                               \
    230              (NonCustomCSSPropertyId)((enabledstate_) | CSSEnabledState(0)); \
    231       *it_ != eCSSProperty_UNKNOWN; ++it_)                                   \
    232    if (nsCSSProps::IsEnabled(*it_, (mozilla::CSSEnabledState)es_))
    233 };
    234 
    235 // MOZ_DBG support for NonCustomCSSPropertyId
    236 
    237 inline std::ostream& operator<<(std::ostream& aOut,
    238                                NonCustomCSSPropertyId aProperty) {
    239  return aOut << nsCSSProps::GetStringValue(aProperty);
    240 }
    241 
    242 #endif /* nsCSSProps_h___ */