tor-browser

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

nsCSSProps.cpp (8577B)


      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 #include "nsCSSProps.h"
     13 
     14 #include "gfxPlatform.h"
     15 #include "mozilla/ClearOnShutdown.h"
     16 #include "mozilla/LookAndFeel.h"  // for system colors
     17 #include "mozilla/Preferences.h"
     18 #include "mozilla/StaticPrefs_layout.h"
     19 #include "mozilla/StaticPtr.h"
     20 #include "mozilla/dom/Animation.h"
     21 #include "mozilla/dom/AnimationEffectBinding.h"  // for PlaybackDirection
     22 #include "mozilla/gfx/gfxVarReceiver.h"
     23 #include "mozilla/gfx/gfxVars.h"  // for UseWebRender
     24 #include "nsIWidget.h"
     25 #include "nsLayoutUtils.h"
     26 #include "nsStaticNameTable.h"
     27 #include "nsString.h"
     28 #include "nsStyleConsts.h"  // For system widget appearance types
     29 
     30 using namespace mozilla;
     31 
     32 static StaticAutoPtr<nsStaticCaseInsensitiveNameTable> gFontDescTable;
     33 static StaticAutoPtr<nsStaticCaseInsensitiveNameTable> gCounterDescTable;
     34 static StaticAutoPtr<nsTHashMap<nsCStringHashKey, NonCustomCSSPropertyId>>
     35    gPropertyIDLNameTable;
     36 
     37 static constexpr const char* const kCSSRawFontDescs[] = {
     38 #define CSS_FONT_DESC(name_, method_) #name_,
     39 #include "nsCSSFontDescList.h"
     40 #undef CSS_FONT_DESC
     41 };
     42 
     43 static constexpr const char* const kCSSRawCounterDescs[] = {
     44 #define CSS_COUNTER_DESC(name_, method_) #name_,
     45 #include "nsCSSCounterDescList.h"
     46 #undef CSS_COUNTER_DESC
     47 };
     48 
     49 static constexpr CSSPropFlags kFlagsTable[eCSSProperty_COUNT_with_aliases] = {
     50 #define CSS_PROP_LONGHAND(name_, id_, method_, flags_, ...) flags_,
     51 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, ...) flags_,
     52 #define CSS_PROP_ALIAS(name_, aliasid_, id_, method_, flags_, ...) flags_,
     53 #include "mozilla/ServoCSSPropList.h"
     54 #undef CSS_PROP_ALIAS
     55 #undef CSS_PROP_SHORTHAND
     56 #undef CSS_PROP_LONGHAND
     57 };
     58 
     59 static nsStaticCaseInsensitiveNameTable* CreateStaticTable(
     60    const char* const aRawTable[], int32_t aLength) {
     61  auto* table = new nsStaticCaseInsensitiveNameTable(aRawTable, aLength);
     62 #ifdef DEBUG
     63  // Partially verify the entries.
     64  for (int32_t index = 0; index < aLength; ++index) {
     65    nsAutoCString temp(aRawTable[index]);
     66    MOZ_ASSERT(-1 == temp.FindChar('_'),
     67               "underscore char in case insensitive name table");
     68  }
     69 #endif
     70  return table;
     71 }
     72 
     73 void nsCSSProps::RecomputeEnabledState(const char* aPref, void*) {
     74  MOZ_RELEASE_ASSERT(NS_IsMainThread());
     75  DebugOnly<bool> foundPref = false;
     76  for (const PropertyPref* pref = kPropertyPrefTable;
     77       pref->mPropId != eCSSProperty_UNKNOWN; pref++) {
     78    if (!aPref || !strcmp(aPref, pref->mPref)) {
     79      foundPref = true;
     80      gPropertyEnabled[pref->mPropId] = Preferences::GetBool(pref->mPref);
     81      if (pref->mPropId == eCSSProperty_backdrop_filter) {
     82        gPropertyEnabled[pref->mPropId] &=
     83            gfx::gfxVars::GetAllowBackdropFilterOrDefault();
     84      }
     85 #ifdef FUZZING
     86      // In fuzzing builds we want to enable all properties unconditionally.
     87      gPropertyEnabled[pref->mPropId] = true;
     88 #endif
     89    }
     90  }
     91  MOZ_ASSERT(foundPref);
     92 }
     93 
     94 void nsCSSProps::Init() {
     95  MOZ_ASSERT(!gFontDescTable, "pre existing array!");
     96  MOZ_ASSERT(!gCounterDescTable, "pre existing array!");
     97  MOZ_ASSERT(!gPropertyIDLNameTable, "pre existing array!");
     98 
     99  gFontDescTable = CreateStaticTable(kCSSRawFontDescs, eCSSFontDesc_COUNT);
    100  gCounterDescTable =
    101      CreateStaticTable(kCSSRawCounterDescs, eCSSCounterDesc_COUNT);
    102 
    103  gPropertyIDLNameTable =
    104      new nsTHashMap<nsCStringHashKey, NonCustomCSSPropertyId>;
    105  for (NonCustomCSSPropertyId p = NonCustomCSSPropertyId(0);
    106       size_t(p) < std::size(kIDLNameTable);
    107       p = NonCustomCSSPropertyId(p + 1)) {
    108    if (kIDLNameTable[p]) {
    109      gPropertyIDLNameTable->InsertOrUpdate(
    110          nsDependentCString(kIDLNameTable[p]), p);
    111    }
    112  }
    113 
    114  ClearOnShutdown(&gFontDescTable);
    115  ClearOnShutdown(&gCounterDescTable);
    116  ClearOnShutdown(&gPropertyIDLNameTable);
    117 
    118  for (const PropertyPref* pref = kPropertyPrefTable;
    119       pref->mPropId != eCSSProperty_UNKNOWN; pref++) {
    120    // https://bugzilla.mozilla.org/show_bug.cgi?id=1472523
    121    // We need to use nsCString instead of substring because the preference
    122    // callback code stores them. Using AssignLiteral prevents any
    123    // unnecessary allocations.
    124    nsCString prefName;
    125    prefName.AssignLiteral(pref->mPref, strlen(pref->mPref));
    126    Preferences::RegisterCallback(nsCSSProps::RecomputeEnabledState, prefName);
    127  }
    128  RecomputeEnabledState(/* aPrefName = */ nullptr);
    129 }
    130 
    131 /* static */
    132 bool nsCSSProps::IsCustomPropertyName(const nsACString& aProperty) {
    133  return aProperty.Length() >= CSS_CUSTOM_NAME_PREFIX_LENGTH &&
    134         StringBeginsWith(aProperty, "--"_ns);
    135 }
    136 
    137 NonCustomCSSPropertyId nsCSSProps::LookupPropertyByIDLName(
    138    const nsACString& aPropertyIDLName, EnabledState aEnabled) {
    139  MOZ_ASSERT(gPropertyIDLNameTable, "no lookup table, needs addref");
    140  NonCustomCSSPropertyId res;
    141  if (!gPropertyIDLNameTable->Get(aPropertyIDLName, &res)) {
    142    return eCSSProperty_UNKNOWN;
    143  }
    144  MOZ_ASSERT(res < eCSSProperty_COUNT);
    145  if (!IsEnabled(res, aEnabled)) {
    146    return eCSSProperty_UNKNOWN;
    147  }
    148  return res;
    149 }
    150 
    151 nsCSSFontDesc nsCSSProps::LookupFontDesc(const nsACString& aFontDesc) {
    152  MOZ_ASSERT(gFontDescTable, "no lookup table, needs addref");
    153  nsCSSFontDesc which = nsCSSFontDesc(gFontDescTable->Lookup(aFontDesc));
    154 
    155  return which;
    156 }
    157 
    158 static constexpr auto sDescNullStr = ""_ns;
    159 
    160 const nsCString& nsCSSProps::GetStringValue(nsCSSFontDesc aFontDescID) {
    161  MOZ_ASSERT(gFontDescTable, "no lookup table, needs addref");
    162  if (gFontDescTable) {
    163    return gFontDescTable->GetStringValue(int32_t(aFontDescID));
    164  }
    165  return sDescNullStr;
    166 }
    167 
    168 const nsCString& nsCSSProps::GetStringValue(nsCSSCounterDesc aCounterDescID) {
    169  MOZ_ASSERT(gCounterDescTable, "no lookup table, needs addref");
    170  if (gCounterDescTable) {
    171    return gCounterDescTable->GetStringValue(int32_t(aCounterDescID));
    172  }
    173  return sDescNullStr;
    174 }
    175 
    176 CSSPropFlags nsCSSProps::PropFlags(NonCustomCSSPropertyId aProperty) {
    177  MOZ_ASSERT(aProperty != eCSSProperty_UNKNOWN &&
    178                 aProperty < eCSSProperty_COUNT_with_aliases,
    179             "out of range");
    180  return kFlagsTable[aProperty];
    181 }
    182 
    183 /* static */
    184 bool nsCSSProps::gPropertyEnabled[eCSSProperty_COUNT_with_aliases] = {
    185 // If the property has any "ENABLED_IN" flag set, it is disabled by
    186 // default. Note that, if a property has pref, whatever its default
    187 // value is, it will later be changed in nsCSSProps::AddRefTable().
    188 // If the property has "ENABLED_IN" flags but doesn't have a pref,
    189 // it is an internal property which is disabled elsewhere.
    190 #define IS_ENABLED_BY_DEFAULT(flags_) \
    191  (!((flags_) & (CSSPropFlags::EnabledMask | CSSPropFlags::Inaccessible)))
    192 
    193 #define CSS_PROP_LONGHAND(name_, id_, method_, flags_, ...) \
    194  IS_ENABLED_BY_DEFAULT(flags_),
    195 #define CSS_PROP_SHORTHAND(name_, id_, method_, flags_, ...) \
    196  IS_ENABLED_BY_DEFAULT(flags_),
    197 #define CSS_PROP_ALIAS(name_, aliasid_, id_, method_, flags_, ...) \
    198  IS_ENABLED_BY_DEFAULT(flags_),
    199 #include "mozilla/ServoCSSPropList.h"
    200 #undef CSS_PROP_ALIAS
    201 #undef CSS_PROP_SHORTHAND
    202 #undef CSS_PROP_LONGHAND
    203 
    204 #undef IS_ENABLED_BY_DEFAULT
    205 };
    206 
    207 /**
    208 * A singleton class to register as a receiver for gfxVars.
    209 * Updates the state of backdrop-filter's pref if the gfx
    210 * backdrop filter var changes state.
    211 */
    212 class nsCSSPropsGfxVarReceiver final : public gfx::gfxVarReceiver {
    213  constexpr nsCSSPropsGfxVarReceiver() = default;
    214 
    215  // Backdrop filter's last known enabled state.
    216  static bool sLastKnownAllowBackdropFilter;
    217  static nsCSSPropsGfxVarReceiver sInstance;
    218 
    219 public:
    220  static gfx::gfxVarReceiver& GetInstance() { return sInstance; }
    221 
    222  void OnVarChanged(const nsTArray<gfx::GfxVarUpdate>&) override {
    223    bool enabled = gfx::gfxVars::AllowBackdropFilter();
    224    if (sLastKnownAllowBackdropFilter != enabled) {
    225      sLastKnownAllowBackdropFilter = enabled;
    226      nsCSSProps::RecomputeEnabledState(
    227          StaticPrefs::GetPrefName_layout_css_backdrop_filter_enabled());
    228    }
    229  }
    230 };
    231 
    232 /* static */
    233 nsCSSPropsGfxVarReceiver nsCSSPropsGfxVarReceiver::sInstance =
    234    nsCSSPropsGfxVarReceiver();
    235 
    236 /* static */
    237 bool nsCSSPropsGfxVarReceiver::sLastKnownAllowBackdropFilter = true;
    238 
    239 /* static */
    240 gfx::gfxVarReceiver& nsCSSProps::GfxVarReceiver() {
    241  return nsCSSPropsGfxVarReceiver::GetInstance();
    242 }
    243 
    244 #include "nsCSSPropsGenerated.inc"