/src/mozilla-central/layout/xul/tree/nsTreeStyleCache.cpp
Line | Count | Source (jump to first uncovered line) |
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 | | #include "mozilla/dom/Element.h" |
9 | | #include "mozilla/ServoStyleSet.h" |
10 | | |
11 | | using namespace mozilla; |
12 | | |
13 | | nsTreeStyleCache::Transition::Transition(DFAState aState, nsAtom* aSymbol) |
14 | | : mState(aState), mInputSymbol(aSymbol) |
15 | 0 | { |
16 | 0 | } |
17 | | |
18 | | bool |
19 | | nsTreeStyleCache::Transition::operator==(const Transition& aOther) const |
20 | 0 | { |
21 | 0 | return aOther.mState == mState && aOther.mInputSymbol == mInputSymbol; |
22 | 0 | } |
23 | | |
24 | | uint32_t |
25 | | nsTreeStyleCache::Transition::Hash() const |
26 | 0 | { |
27 | 0 | // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol. |
28 | 0 | uint32_t hb = mState << 16; |
29 | 0 | uint32_t lb = (NS_PTR_TO_UINT32(mInputSymbol.get()) << 16) >> 16; |
30 | 0 | return hb+lb; |
31 | 0 | } |
32 | | |
33 | | |
34 | | // The ComputedStyle cache impl |
35 | | ComputedStyle* |
36 | | nsTreeStyleCache::GetComputedStyle(nsPresContext* aPresContext, |
37 | | nsIContent* aContent, |
38 | | ComputedStyle* aStyle, |
39 | | nsICSSAnonBoxPseudo* aPseudoElement, |
40 | | const AtomArray & aInputWord) |
41 | 0 | { |
42 | 0 | MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoElement)); |
43 | 0 |
|
44 | 0 | uint32_t count = aInputWord.Length(); |
45 | 0 |
|
46 | 0 | // Go ahead and init the transition table. |
47 | 0 | if (!mTransitionTable) { |
48 | 0 | // Automatic miss. Build the table |
49 | 0 | mTransitionTable = new TransitionTable(); |
50 | 0 | } |
51 | 0 |
|
52 | 0 | // The first transition is always made off the supplied pseudo-element. |
53 | 0 | Transition transition(0, aPseudoElement); |
54 | 0 | DFAState currState = mTransitionTable->Get(transition); |
55 | 0 |
|
56 | 0 | if (!currState) { |
57 | 0 | // We had a miss. Make a new state and add it to our hash. |
58 | 0 | currState = mNextState; |
59 | 0 | mNextState++; |
60 | 0 | mTransitionTable->Put(transition, currState); |
61 | 0 | } |
62 | 0 |
|
63 | 0 | for (uint32_t i = 0; i < count; i++) { |
64 | 0 | Transition transition(currState, aInputWord[i]); |
65 | 0 | currState = mTransitionTable->Get(transition); |
66 | 0 |
|
67 | 0 | if (!currState) { |
68 | 0 | // We had a miss. Make a new state and add it to our hash. |
69 | 0 | currState = mNextState; |
70 | 0 | mNextState++; |
71 | 0 | mTransitionTable->Put(transition, currState); |
72 | 0 | } |
73 | 0 | } |
74 | 0 |
|
75 | 0 | // We're in a final state. |
76 | 0 | // Look up our ComputedStyle for this state. |
77 | 0 | ComputedStyle* result = nullptr; |
78 | 0 | if (mCache) { |
79 | 0 | result = mCache->GetWeak(currState); |
80 | 0 | } |
81 | 0 | if (!result) { |
82 | 0 | // We missed the cache. Resolve this pseudo-style. |
83 | 0 | RefPtr<ComputedStyle> newResult = aPresContext->StyleSet()-> |
84 | 0 | ResolveXULTreePseudoStyle(aContent->AsElement(), |
85 | 0 | aPseudoElement, aStyle, aInputWord); |
86 | 0 |
|
87 | 0 | // Put the ComputedStyle in our table, transferring the owning reference to the table. |
88 | 0 | if (!mCache) { |
89 | 0 | mCache = new ComputedStyleCache(); |
90 | 0 | } |
91 | 0 | result = newResult.get(); |
92 | 0 | mCache->Put(currState, newResult.forget()); |
93 | 0 | } |
94 | 0 |
|
95 | 0 | return result; |
96 | 0 | } |
97 | | |