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