tor-browser

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

nsTreeStyleCache.cpp (3774B)


      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 "nsTreeStyleCache.h"
      8 
      9 #include "mozilla/ComputedStyleInlines.h"
     10 #include "mozilla/ServoStyleSet.h"
     11 #include "mozilla/dom/Element.h"
     12 #include "nsPresContextInlines.h"
     13 
     14 using namespace mozilla;
     15 
     16 nsTreeStyleCache::Transition::Transition(DFAState aState, nsAtom* aSymbol)
     17    : mState(aState), mInputSymbol(aSymbol) {}
     18 
     19 bool nsTreeStyleCache::Transition::operator==(const Transition& aOther) const {
     20  return aOther.mState == mState && aOther.mInputSymbol == mInputSymbol;
     21 }
     22 
     23 uint32_t nsTreeStyleCache::Transition::Hash() const {
     24  // Make a 32-bit integer that combines the low-order 16 bits of the state and
     25  // the input symbol.
     26  uint32_t hb = mState << 16;
     27  uint32_t lb = (NS_PTR_TO_UINT32(mInputSymbol.get()) << 16) >> 16;
     28  return hb + lb;
     29 }
     30 
     31 // The ComputedStyle cache impl
     32 ComputedStyle* nsTreeStyleCache::GetComputedStyle(
     33    nsPresContext* aPresContext, nsIContent* aContent, ComputedStyle* aStyle,
     34    nsCSSAnonBoxPseudoStaticAtom* aPseudoElement, const AtomArray& aInputWord) {
     35  MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoElement));
     36 
     37  uint32_t count = aInputWord.Length();
     38 
     39  // Go ahead and init the transition table.
     40  if (!mTransitionTable) {
     41    // Automatic miss. Build the table
     42    mTransitionTable = MakeUnique<TransitionTable>();
     43  }
     44 
     45  // The first transition is always made off the supplied pseudo-element.
     46  Transition transition(0, aPseudoElement);
     47  DFAState currState = mTransitionTable->Get(transition);
     48 
     49  if (!currState) {
     50    // We had a miss. Make a new state and add it to our hash.
     51    currState = mNextState;
     52    mNextState++;
     53    mTransitionTable->InsertOrUpdate(transition, currState);
     54  }
     55 
     56  for (uint32_t i = 0; i < count; i++) {
     57    Transition transition(currState, aInputWord[i]);
     58    currState = mTransitionTable->Get(transition);
     59 
     60    if (!currState) {
     61      // We had a miss. Make a new state and add it to our hash.
     62      currState = mNextState;
     63      mNextState++;
     64      mTransitionTable->InsertOrUpdate(transition, currState);
     65    }
     66  }
     67 
     68  // We're in a final state.
     69  // Look up our ComputedStyle for this state.
     70  ComputedStyle* result = nullptr;
     71  if (mCache) {
     72    result = mCache->GetWeak(currState);
     73  }
     74  if (!result) {
     75    // We missed the cache. Resolve this pseudo-style.
     76    RefPtr<ComputedStyle> newResult =
     77        aPresContext->StyleSet()->ResolveXULTreePseudoStyle(
     78            aContent->AsElement(), aPseudoElement, aStyle, aInputWord);
     79 
     80    // Normally we rely on nsIFrame::Init / RestyleManager to call this, but
     81    // these are weird and don't use a frame, yet ::-moz-tree-twisty definitely
     82    // pokes at list-style-image.
     83    newResult->StartImageLoads(*aPresContext->Document());
     84 
     85    // Even though xul-tree pseudos are defined in nsCSSAnonBoxList, nothing has
     86    // ever treated them as an anon box, and they don't ever get boxes anyway.
     87    //
     88    // This is really weird, and probably nothing really relies on the result of
     89    // these assert, but it's here just to avoid changing them accidentally.
     90    MOZ_ASSERT(newResult->GetPseudoType() == PseudoStyleType::XULTree);
     91    MOZ_ASSERT(!newResult->IsAnonBox());
     92    MOZ_ASSERT(!newResult->IsPseudoElement());
     93 
     94    // Put the ComputedStyle in our table, transferring the owning reference to
     95    // the table.
     96    if (!mCache) {
     97      mCache = MakeUnique<ComputedStyleCache>();
     98    }
     99    result = newResult.get();
    100    mCache->InsertOrUpdate(currState, std::move(newResult));
    101  }
    102 
    103  return result;
    104 }