1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/xul/tree/nsTreeStyleCache.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,92 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +#include "nsTreeStyleCache.h" 1.10 +#include "nsStyleSet.h" 1.11 +#include "mozilla/dom/Element.h" 1.12 + 1.13 +// The style context cache impl 1.14 +nsStyleContext* 1.15 +nsTreeStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator, 1.16 + nsPresContext* aPresContext, 1.17 + nsIContent* aContent, 1.18 + nsStyleContext* aContext, 1.19 + nsIAtom* aPseudoElement, 1.20 + const AtomArray & aInputWord) 1.21 +{ 1.22 + uint32_t count = aInputWord.Length(); 1.23 + nsDFAState startState(0); 1.24 + nsDFAState* currState = &startState; 1.25 + 1.26 + // Go ahead and init the transition table. 1.27 + if (!mTransitionTable) { 1.28 + // Automatic miss. Build the table 1.29 + mTransitionTable = 1.30 + new nsObjectHashtable(nullptr, nullptr, DeleteDFAState, nullptr); 1.31 + } 1.32 + 1.33 + // The first transition is always made off the supplied pseudo-element. 1.34 + nsTransitionKey key(currState->GetStateID(), aPseudoElement); 1.35 + currState = static_cast<nsDFAState*>(mTransitionTable->Get(&key)); 1.36 + 1.37 + if (!currState) { 1.38 + // We had a miss. Make a new state and add it to our hash. 1.39 + currState = new nsDFAState(mNextState); 1.40 + mNextState++; 1.41 + mTransitionTable->Put(&key, currState); 1.42 + } 1.43 + 1.44 + for (uint32_t i = 0; i < count; i++) { 1.45 + nsTransitionKey key(currState->GetStateID(), aInputWord[i]); 1.46 + currState = static_cast<nsDFAState*>(mTransitionTable->Get(&key)); 1.47 + 1.48 + if (!currState) { 1.49 + // We had a miss. Make a new state and add it to our hash. 1.50 + currState = new nsDFAState(mNextState); 1.51 + mNextState++; 1.52 + mTransitionTable->Put(&key, currState); 1.53 + } 1.54 + } 1.55 + 1.56 + // We're in a final state. 1.57 + // Look up our style context for this state. 1.58 + nsStyleContext* result = nullptr; 1.59 + if (mCache) 1.60 + result = static_cast<nsStyleContext*>(mCache->Get(currState)); 1.61 + if (!result) { 1.62 + // We missed the cache. Resolve this pseudo-style. 1.63 + result = aPresContext->StyleSet()-> 1.64 + ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement, 1.65 + aContext, aComparator).take(); 1.66 + 1.67 + // Put the style context in our table, transferring the owning reference to the table. 1.68 + if (!mCache) { 1.69 + mCache = new nsObjectHashtable(nullptr, nullptr, ReleaseStyleContext, nullptr); 1.70 + } 1.71 + mCache->Put(currState, result); 1.72 + } 1.73 + 1.74 + return result; 1.75 +} 1.76 + 1.77 +bool 1.78 +nsTreeStyleCache::DeleteDFAState(nsHashKey *aKey, 1.79 + void *aData, 1.80 + void *closure) 1.81 +{ 1.82 + nsDFAState* entry = static_cast<nsDFAState*>(aData); 1.83 + delete entry; 1.84 + return true; 1.85 +} 1.86 + 1.87 +bool 1.88 +nsTreeStyleCache::ReleaseStyleContext(nsHashKey *aKey, 1.89 + void *aData, 1.90 + void *closure) 1.91 +{ 1.92 + nsStyleContext* context = static_cast<nsStyleContext*>(aData); 1.93 + context->Release(); 1.94 + return true; 1.95 +}