diff options
Diffstat (limited to 'layout/xul/tree/nsTreeStyleCache.cpp')
-rw-r--r-- | layout/xul/tree/nsTreeStyleCache.cpp | 99 |
1 files changed, 99 insertions, 0 deletions
diff --git a/layout/xul/tree/nsTreeStyleCache.cpp b/layout/xul/tree/nsTreeStyleCache.cpp new file mode 100644 index 0000000000..74b8a89c47 --- /dev/null +++ b/layout/xul/tree/nsTreeStyleCache.cpp @@ -0,0 +1,99 @@ +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +#include "nsTreeStyleCache.h" +#include "nsStyleSet.h" +#include "mozilla/dom/Element.h" +#include "mozilla/StyleSetHandle.h" +#include "mozilla/StyleSetHandleInlines.h" + +nsTreeStyleCache::Transition::Transition(DFAState aState, nsIAtom* aSymbol) + : mState(aState), mInputSymbol(aSymbol) +{ +} + +bool +nsTreeStyleCache::Transition::operator==(const Transition& aOther) const +{ + return aOther.mState == mState && aOther.mInputSymbol == mInputSymbol; +} + +uint32_t +nsTreeStyleCache::Transition::Hash() const +{ + // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol. + uint32_t hb = mState << 16; + uint32_t lb = (NS_PTR_TO_UINT32(mInputSymbol.get()) << 16) >> 16; + return hb+lb; +} + + +// The style context cache impl +nsStyleContext* +nsTreeStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator, + nsPresContext* aPresContext, + nsIContent* aContent, + nsStyleContext* aContext, + nsIAtom* aPseudoElement, + const AtomArray & aInputWord) +{ + uint32_t count = aInputWord.Length(); + + // Go ahead and init the transition table. + if (!mTransitionTable) { + // Automatic miss. Build the table + mTransitionTable = new TransitionTable(); + } + + // The first transition is always made off the supplied pseudo-element. + Transition transition(0, aPseudoElement); + DFAState currState = mTransitionTable->Get(transition); + + if (!currState) { + // We had a miss. Make a new state and add it to our hash. + currState = mNextState; + mNextState++; + mTransitionTable->Put(transition, currState); + } + + for (uint32_t i = 0; i < count; i++) { + Transition transition(currState, aInputWord[i]); + currState = mTransitionTable->Get(transition); + + if (!currState) { + // We had a miss. Make a new state and add it to our hash. + currState = mNextState; + mNextState++; + mTransitionTable->Put(transition, currState); + } + } + + // We're in a final state. + // Look up our style context for this state. + nsStyleContext* result = nullptr; + if (mCache) { + result = mCache->GetWeak(currState); + } + if (!result) { + // We missed the cache. Resolve this pseudo-style. + // XXXheycam ServoStyleSets do not support XUL tree styles. + if (aPresContext->StyleSet()->IsServo()) { + MOZ_CRASH("stylo: ServoStyleSets should not support XUL tree styles yet"); + } + RefPtr<nsStyleContext> newResult = aPresContext->StyleSet()->AsGecko()-> + ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement, + aContext, aComparator); + + // Put the style context in our table, transferring the owning reference to the table. + if (!mCache) { + mCache = new StyleContextCache(); + } + result = newResult.get(); + mCache->Put(currState, newResult.forget()); + } + + return result; +} + |