tor-browser

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

ServoStyleRuleMap.cpp (6366B)


      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 #include "mozilla/ServoStyleRuleMap.h"
      8 
      9 #include "mozilla/IntegerRange.h"
     10 #include "mozilla/ServoBindings.h"
     11 #include "mozilla/ServoStyleSet.h"
     12 #include "mozilla/StyleSheetInlines.h"
     13 #include "mozilla/css/GroupRule.h"
     14 #include "mozilla/dom/CSSImportRule.h"
     15 #include "mozilla/dom/CSSNestedDeclarations.h"
     16 #include "mozilla/dom/CSSPositionTryRule.h"
     17 #include "mozilla/dom/CSSRuleBinding.h"
     18 #include "mozilla/dom/CSSStyleRule.h"
     19 #include "mozilla/dom/Document.h"
     20 #include "mozilla/dom/Element.h"
     21 #include "mozilla/dom/ShadowRoot.h"
     22 
     23 using namespace mozilla::dom;
     24 
     25 namespace mozilla {
     26 
     27 void ServoStyleRuleMap::EnsureTable(ServoStyleSet& aStyleSet) {
     28  if (!IsEmpty()) {
     29    return;
     30  }
     31  aStyleSet.EnumerateStyleSheets(
     32      [&](StyleSheet& aSheet) { FillTableFromStyleSheet(aSheet); });
     33 }
     34 
     35 void ServoStyleRuleMap::EnsureTable(ShadowRoot& aShadowRoot) {
     36  if (!IsEmpty()) {
     37    return;
     38  }
     39  for (auto index : IntegerRange(aShadowRoot.SheetCount())) {
     40    FillTableFromStyleSheet(*aShadowRoot.SheetAt(index));
     41  }
     42  for (const auto& sheet : aShadowRoot.AdoptedStyleSheets()) {
     43    FillTableFromStyleSheet(*sheet);
     44  }
     45 }
     46 
     47 void ServoStyleRuleMap::SheetAdded(StyleSheet& aStyleSheet) {
     48  if (!IsEmpty()) {
     49    FillTableFromStyleSheet(aStyleSheet);
     50  }
     51 }
     52 
     53 void ServoStyleRuleMap::SheetCloned(StyleSheet& aStyleSheet) {
     54  // Invalidate all data inside. We could probably track down all the individual
     55  // rules that changed etc, but it doesn't seem worth it.
     56  //
     57  // TODO: We can't do this until GetCssRulesInternal stops cloning.
     58  // mTable.Clear();
     59 }
     60 
     61 void ServoStyleRuleMap::SheetRemoved(StyleSheet& aStyleSheet) {
     62  // Invalidate all data inside. This isn't strictly necessary since
     63  // we should always get update from document before new queries come.
     64  // But it is probably still safer if we try to avoid having invalid
     65  // pointers inside. Also if the document keep adding and removing
     66  // stylesheets, this would also prevent us from infinitely growing
     67  // memory usage.
     68  mTable.Clear();
     69 }
     70 
     71 void ServoStyleRuleMap::RuleAdded(StyleSheet& aStyleSheet,
     72                                  css::Rule& aStyleRule) {
     73  if (!IsEmpty()) {
     74    FillTableFromRule(aStyleRule);
     75  }
     76 }
     77 
     78 void ServoStyleRuleMap::RuleRemoved(StyleSheet& aStyleSheet,
     79                                    css::Rule& aStyleRule) {
     80  if (IsEmpty()) {
     81    return;
     82  }
     83 
     84  switch (aStyleRule.Type()) {
     85    case StyleCssRuleType::Style:
     86    case StyleCssRuleType::NestedDeclarations:
     87    case StyleCssRuleType::Import:
     88    case StyleCssRuleType::Media:
     89    case StyleCssRuleType::Supports:
     90    case StyleCssRuleType::LayerBlock:
     91    case StyleCssRuleType::Container:
     92    case StyleCssRuleType::Document:
     93    case StyleCssRuleType::Scope:
     94    case StyleCssRuleType::StartingStyle:
     95    case StyleCssRuleType::PositionTry: {
     96      // See the comment in SheetRemoved.
     97      mTable.Clear();
     98      break;
     99    }
    100    case StyleCssRuleType::CustomMedia:
    101    case StyleCssRuleType::LayerStatement:
    102    case StyleCssRuleType::FontFace:
    103    case StyleCssRuleType::Page:
    104    case StyleCssRuleType::Property:
    105    case StyleCssRuleType::Keyframes:
    106    case StyleCssRuleType::Keyframe:
    107    case StyleCssRuleType::Margin:
    108    case StyleCssRuleType::Namespace:
    109    case StyleCssRuleType::CounterStyle:
    110    case StyleCssRuleType::FontFeatureValues:
    111    case StyleCssRuleType::FontPaletteValues:
    112      break;
    113  }
    114 }
    115 
    116 size_t ServoStyleRuleMap::SizeOfIncludingThis(
    117    MallocSizeOf aMallocSizeOf) const {
    118  size_t n = aMallocSizeOf(this);
    119  n += mTable.ShallowSizeOfExcludingThis(aMallocSizeOf);
    120  return n;
    121 }
    122 
    123 void ServoStyleRuleMap::RuleDeclarationsChanged(
    124    css::Rule& aRule, const StyleLockedDeclarationBlock* aOld,
    125    const StyleLockedDeclarationBlock* aNew) {
    126  MOZ_ASSERT(aOld);
    127  MOZ_ASSERT(aNew);
    128  if (IsEmpty()) {
    129    return;
    130  }
    131  auto old = mTable.Extract(aOld);
    132  MOZ_ASSERT(old.valueOr(nullptr) == &aRule,
    133             "We were tracking the wrong rule?");
    134  mTable.InsertOrUpdate(aNew, &aRule);
    135 }
    136 
    137 void ServoStyleRuleMap::FillTableFromRule(css::Rule& aRule) {
    138  switch (aRule.Type()) {
    139    case StyleCssRuleType::NestedDeclarations: {
    140      auto& rule = static_cast<CSSNestedDeclarations&>(aRule);
    141      mTable.InsertOrUpdate(rule.RawStyle(), &rule);
    142      break;
    143    }
    144    case StyleCssRuleType::PositionTry: {
    145      auto& rule = static_cast<CSSPositionTryRule&>(aRule);
    146      mTable.InsertOrUpdate(rule.RawStyle(), &rule);
    147      break;
    148    }
    149    case StyleCssRuleType::Style: {
    150      auto& rule = static_cast<CSSStyleRule&>(aRule);
    151      mTable.InsertOrUpdate(rule.RawStyle(), &rule);
    152      [[fallthrough]];
    153    }
    154    case StyleCssRuleType::LayerBlock:
    155    case StyleCssRuleType::Media:
    156    case StyleCssRuleType::Supports:
    157    case StyleCssRuleType::Container:
    158    case StyleCssRuleType::Document:
    159    case StyleCssRuleType::Scope:
    160    case StyleCssRuleType::StartingStyle: {
    161      auto& rule = static_cast<css::GroupRule&>(aRule);
    162      FillTableFromRuleList(*rule.CssRules());
    163      break;
    164    }
    165    case StyleCssRuleType::Import: {
    166      auto& rule = static_cast<CSSImportRule&>(aRule);
    167      if (auto* sheet = rule.GetStyleSheet()) {
    168        FillTableFromStyleSheet(*sheet);
    169      }
    170      break;
    171    }
    172    case StyleCssRuleType::CustomMedia:
    173    case StyleCssRuleType::LayerStatement:
    174    case StyleCssRuleType::FontFace:
    175    case StyleCssRuleType::Page:
    176    case StyleCssRuleType::Property:
    177    case StyleCssRuleType::Keyframes:
    178    case StyleCssRuleType::Keyframe:
    179    case StyleCssRuleType::Margin:
    180    case StyleCssRuleType::Namespace:
    181    case StyleCssRuleType::CounterStyle:
    182    case StyleCssRuleType::FontFeatureValues:
    183    case StyleCssRuleType::FontPaletteValues:
    184      break;
    185  }
    186 }
    187 
    188 void ServoStyleRuleMap::FillTableFromRuleList(ServoCSSRuleList& aRuleList) {
    189  for (uint32_t i : IntegerRange(aRuleList.Length())) {
    190    FillTableFromRule(*aRuleList.GetRule(i));
    191  }
    192 }
    193 
    194 void ServoStyleRuleMap::FillTableFromStyleSheet(StyleSheet& aSheet) {
    195  if (aSheet.IsComplete()) {
    196    FillTableFromRuleList(*aSheet.GetCssRulesInternal());
    197  }
    198 }
    199 
    200 }  // namespace mozilla