Wed, 31 Dec 2014 06:09:35 +0100
Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.
michael@0 | 1 | /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
michael@0 | 2 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 3 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 4 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 5 | |
michael@0 | 6 | #ifndef nsTreeStyleCache_h__ |
michael@0 | 7 | #define nsTreeStyleCache_h__ |
michael@0 | 8 | |
michael@0 | 9 | #include "mozilla/Attributes.h" |
michael@0 | 10 | #include "nsHashtable.h" |
michael@0 | 11 | #include "nsIAtom.h" |
michael@0 | 12 | #include "nsCOMArray.h" |
michael@0 | 13 | #include "nsICSSPseudoComparator.h" |
michael@0 | 14 | #include "nsStyleContext.h" |
michael@0 | 15 | |
michael@0 | 16 | typedef nsCOMArray<nsIAtom> AtomArray; |
michael@0 | 17 | |
michael@0 | 18 | class nsDFAState : public nsHashKey |
michael@0 | 19 | { |
michael@0 | 20 | public: |
michael@0 | 21 | uint32_t mStateID; |
michael@0 | 22 | |
michael@0 | 23 | nsDFAState(uint32_t aID) :mStateID(aID) {} |
michael@0 | 24 | |
michael@0 | 25 | uint32_t GetStateID() { return mStateID; } |
michael@0 | 26 | |
michael@0 | 27 | uint32_t HashCode(void) const MOZ_OVERRIDE { |
michael@0 | 28 | return mStateID; |
michael@0 | 29 | } |
michael@0 | 30 | |
michael@0 | 31 | bool Equals(const nsHashKey *aKey) const MOZ_OVERRIDE { |
michael@0 | 32 | nsDFAState* key = (nsDFAState*)aKey; |
michael@0 | 33 | return key->mStateID == mStateID; |
michael@0 | 34 | } |
michael@0 | 35 | |
michael@0 | 36 | nsHashKey *Clone(void) const MOZ_OVERRIDE { |
michael@0 | 37 | return new nsDFAState(mStateID); |
michael@0 | 38 | } |
michael@0 | 39 | }; |
michael@0 | 40 | |
michael@0 | 41 | class nsTransitionKey : public nsHashKey |
michael@0 | 42 | { |
michael@0 | 43 | public: |
michael@0 | 44 | uint32_t mState; |
michael@0 | 45 | nsCOMPtr<nsIAtom> mInputSymbol; |
michael@0 | 46 | |
michael@0 | 47 | nsTransitionKey(uint32_t aState, nsIAtom* aSymbol) :mState(aState), mInputSymbol(aSymbol) {} |
michael@0 | 48 | |
michael@0 | 49 | uint32_t HashCode(void) const MOZ_OVERRIDE { |
michael@0 | 50 | // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol. |
michael@0 | 51 | int32_t hb = mState << 16; |
michael@0 | 52 | int32_t lb = (NS_PTR_TO_INT32(mInputSymbol.get()) << 16) >> 16; |
michael@0 | 53 | return hb+lb; |
michael@0 | 54 | } |
michael@0 | 55 | |
michael@0 | 56 | bool Equals(const nsHashKey *aKey) const MOZ_OVERRIDE { |
michael@0 | 57 | nsTransitionKey* key = (nsTransitionKey*)aKey; |
michael@0 | 58 | return key->mState == mState && key->mInputSymbol == mInputSymbol; |
michael@0 | 59 | } |
michael@0 | 60 | |
michael@0 | 61 | nsHashKey *Clone(void) const MOZ_OVERRIDE { |
michael@0 | 62 | return new nsTransitionKey(mState, mInputSymbol); |
michael@0 | 63 | } |
michael@0 | 64 | }; |
michael@0 | 65 | |
michael@0 | 66 | class nsTreeStyleCache |
michael@0 | 67 | { |
michael@0 | 68 | public: |
michael@0 | 69 | nsTreeStyleCache() :mTransitionTable(nullptr), mCache(nullptr), mNextState(0) {} |
michael@0 | 70 | ~nsTreeStyleCache() { Clear(); } |
michael@0 | 71 | |
michael@0 | 72 | void Clear() { delete mTransitionTable; mTransitionTable = nullptr; delete mCache; mCache = nullptr; mNextState = 0; } |
michael@0 | 73 | |
michael@0 | 74 | nsStyleContext* GetStyleContext(nsICSSPseudoComparator* aComparator, |
michael@0 | 75 | nsPresContext* aPresContext, |
michael@0 | 76 | nsIContent* aContent, |
michael@0 | 77 | nsStyleContext* aContext, |
michael@0 | 78 | nsIAtom* aPseudoElement, |
michael@0 | 79 | const AtomArray & aInputWord); |
michael@0 | 80 | |
michael@0 | 81 | static bool DeleteDFAState(nsHashKey *aKey, void *aData, void *closure); |
michael@0 | 82 | |
michael@0 | 83 | static bool ReleaseStyleContext(nsHashKey *aKey, void *aData, void *closure); |
michael@0 | 84 | |
michael@0 | 85 | protected: |
michael@0 | 86 | // A transition table for a deterministic finite automaton. The DFA |
michael@0 | 87 | // takes as its input a single pseudoelement and an ordered set of properties. |
michael@0 | 88 | // It transitions on an input word that is the concatenation of the pseudoelement supplied |
michael@0 | 89 | // with the properties in the array. |
michael@0 | 90 | // |
michael@0 | 91 | // It transitions from state to state by looking up entries in the transition table (which is |
michael@0 | 92 | // a mapping from (S,i)->S', where S is the current state, i is the next |
michael@0 | 93 | // property in the input word, and S' is the state to transition to. |
michael@0 | 94 | // |
michael@0 | 95 | // If S' is not found, it is constructed and entered into the hashtable |
michael@0 | 96 | // under the key (S,i). |
michael@0 | 97 | // |
michael@0 | 98 | // Once the entire word has been consumed, the final state is used |
michael@0 | 99 | // to reference the cache table to locate the style context. |
michael@0 | 100 | nsObjectHashtable* mTransitionTable; |
michael@0 | 101 | |
michael@0 | 102 | // The cache of all active style contexts. This is a hash from |
michael@0 | 103 | // a final state in the DFA, Sf, to the resultant style context. |
michael@0 | 104 | nsObjectHashtable* mCache; |
michael@0 | 105 | |
michael@0 | 106 | // An integer counter that is used when we need to make new states in the |
michael@0 | 107 | // DFA. |
michael@0 | 108 | uint32_t mNextState; |
michael@0 | 109 | }; |
michael@0 | 110 | |
michael@0 | 111 | #endif // nsTreeStyleCache_h__ |