Line data Source code
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 : #include "nsTreeStyleCache.h"
7 : #include "nsStyleSet.h"
8 : #include "mozilla/dom/Element.h"
9 : #include "mozilla/StyleSetHandle.h"
10 : #include "mozilla/StyleSetHandleInlines.h"
11 :
12 0 : nsTreeStyleCache::Transition::Transition(DFAState aState, nsIAtom* aSymbol)
13 0 : : mState(aState), mInputSymbol(aSymbol)
14 : {
15 0 : }
16 :
17 : bool
18 0 : nsTreeStyleCache::Transition::operator==(const Transition& aOther) const
19 : {
20 0 : return aOther.mState == mState && aOther.mInputSymbol == mInputSymbol;
21 : }
22 :
23 : uint32_t
24 0 : nsTreeStyleCache::Transition::Hash() const
25 : {
26 : // Make a 32-bit integer that combines the low-order 16 bits of the state and the input symbol.
27 0 : uint32_t hb = mState << 16;
28 0 : uint32_t lb = (NS_PTR_TO_UINT32(mInputSymbol.get()) << 16) >> 16;
29 0 : return hb+lb;
30 : }
31 :
32 :
33 : // The style context cache impl
34 : nsStyleContext*
35 0 : nsTreeStyleCache::GetStyleContext(nsICSSPseudoComparator* aComparator,
36 : nsPresContext* aPresContext,
37 : nsIContent* aContent,
38 : nsStyleContext* aContext,
39 : nsICSSAnonBoxPseudo* aPseudoElement,
40 : const AtomArray & aInputWord)
41 : {
42 0 : MOZ_ASSERT(nsCSSAnonBoxes::IsTreePseudoElement(aPseudoElement));
43 :
44 0 : uint32_t count = aInputWord.Length();
45 :
46 : // Go ahead and init the transition table.
47 0 : if (!mTransitionTable) {
48 : // Automatic miss. Build the table
49 0 : mTransitionTable = new TransitionTable();
50 : }
51 :
52 : // 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 :
56 0 : if (!currState) {
57 : // 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 : }
62 :
63 0 : for (uint32_t i = 0; i < count; i++) {
64 0 : Transition transition(currState, aInputWord[i]);
65 0 : currState = mTransitionTable->Get(transition);
66 :
67 0 : if (!currState) {
68 : // 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 : }
73 : }
74 :
75 : // We're in a final state.
76 : // Look up our style context for this state.
77 0 : nsStyleContext* result = nullptr;
78 0 : if (mCache) {
79 0 : result = mCache->GetWeak(currState);
80 : }
81 0 : if (!result) {
82 : // We missed the cache. Resolve this pseudo-style.
83 : // XXXheycam ServoStyleSets do not support XUL tree styles.
84 0 : RefPtr<nsStyleContext> newResult;
85 0 : if (aPresContext->StyleSet()->IsServo()) {
86 0 : NS_ERROR("stylo: ServoStyleSets should not support XUL tree styles yet");
87 0 : newResult = aPresContext->StyleSet()->
88 0 : ResolveStyleForPlaceholder();
89 : } else {
90 0 : newResult = aPresContext->StyleSet()->AsGecko()->
91 0 : ResolveXULTreePseudoStyle(aContent->AsElement(), aPseudoElement,
92 0 : aContext, aComparator);
93 : }
94 :
95 : // Put the style context in our table, transferring the owning reference to the table.
96 0 : if (!mCache) {
97 0 : mCache = new StyleContextCache();
98 : }
99 0 : result = newResult.get();
100 0 : mCache->Put(currState, newResult.forget());
101 : }
102 :
103 0 : return result;
104 : }
105 :
|