|
1 /* vim: set shiftwidth=2 tabstop=8 autoindent cindent expandtab: */ |
|
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 /* object that resolves CSS variables using specified and inherited variable |
|
7 * values |
|
8 */ |
|
9 |
|
10 #ifndef mozilla_CSSVariableResolver_h |
|
11 #define mozilla_CSSVariableResolver_h |
|
12 |
|
13 #include "mozilla/DebugOnly.h" |
|
14 #include "nsCSSParser.h" |
|
15 #include "nsCSSScanner.h" |
|
16 #include "nsDataHashtable.h" |
|
17 #include "nsTArray.h" |
|
18 |
|
19 namespace mozilla { |
|
20 |
|
21 class CSSVariableDeclarations; |
|
22 class CSSVariableValues; |
|
23 class EnumerateVariableReferencesData; |
|
24 |
|
25 class CSSVariableResolver |
|
26 { |
|
27 friend class CSSVariableDeclarations; |
|
28 friend class CSSVariableValues; |
|
29 friend class EnumerateVariableReferencesData; |
|
30 public: |
|
31 /** |
|
32 * Creates a new CSSVariableResolver that will output a set of resolved, |
|
33 * computed variables into aOutput. |
|
34 */ |
|
35 CSSVariableResolver(CSSVariableValues* aOutput) |
|
36 : mOutput(aOutput) |
|
37 , mResolved(false) |
|
38 { |
|
39 MOZ_ASSERT(aOutput); |
|
40 } |
|
41 |
|
42 /** |
|
43 * Resolves the set of inherited variables from aInherited and the |
|
44 * set of specified variables from aSpecified. The resoled variables |
|
45 * are written in to mOutput. |
|
46 */ |
|
47 void Resolve(const CSSVariableValues* aInherited, |
|
48 const CSSVariableDeclarations* aSpecified); |
|
49 |
|
50 private: |
|
51 struct Variable |
|
52 { |
|
53 Variable(const nsAString& aVariableName, |
|
54 nsString aValue, |
|
55 nsCSSTokenSerializationType aFirstToken, |
|
56 nsCSSTokenSerializationType aLastToken, |
|
57 bool aWasInherited) |
|
58 : mVariableName(aVariableName) |
|
59 , mValue(aValue) |
|
60 , mFirstToken(aFirstToken) |
|
61 , mLastToken(aLastToken) |
|
62 , mWasInherited(aWasInherited) |
|
63 , mResolved(false) |
|
64 , mReferencesNonExistentVariable(false) |
|
65 , mInStack(false) |
|
66 , mIndex(0) |
|
67 , mLowLink(0) { } |
|
68 |
|
69 nsString mVariableName; |
|
70 nsString mValue; |
|
71 nsCSSTokenSerializationType mFirstToken; |
|
72 nsCSSTokenSerializationType mLastToken; |
|
73 |
|
74 // Whether this variable came from the set of inherited variables. |
|
75 bool mWasInherited; |
|
76 |
|
77 // Whether this variable has been resolved yet. |
|
78 bool mResolved; |
|
79 |
|
80 // Whether this variables includes any references to non-existent variables. |
|
81 bool mReferencesNonExistentVariable; |
|
82 |
|
83 // Bookkeeping for the cycle remover algorithm. |
|
84 bool mInStack; |
|
85 size_t mIndex; |
|
86 size_t mLowLink; |
|
87 }; |
|
88 |
|
89 /** |
|
90 * Adds or modifies an existing entry in the set of variables to be resolved. |
|
91 * This is intended to be called by the AddVariablesToResolver functions on |
|
92 * the CSSVariableDeclarations and CSSVariableValues objects passed in to |
|
93 * Resolve. |
|
94 * |
|
95 * @param aName The variable name (not including any "--" prefix that would |
|
96 * be part of the custom property name) whose value is to be set. |
|
97 * @param aValue The variable value. |
|
98 * @param aFirstToken The type of token at the start of the variable value. |
|
99 * @param aLastToken The type of token at the en of the variable value. |
|
100 * @param aWasInherited Whether this variable came from the set of inherited |
|
101 * variables. |
|
102 */ |
|
103 void Put(const nsAString& aVariableName, |
|
104 nsString aValue, |
|
105 nsCSSTokenSerializationType aFirstToken, |
|
106 nsCSSTokenSerializationType aLastToken, |
|
107 bool aWasInherited); |
|
108 |
|
109 // Helper functions for Resolve. |
|
110 void RemoveCycles(size_t aID); |
|
111 void ResolveVariable(size_t aID); |
|
112 |
|
113 // A mapping of variable names to an ID that indexes into mVariables |
|
114 // and mReferences. |
|
115 nsDataHashtable<nsStringHashKey, size_t> mVariableIDs; |
|
116 |
|
117 // The set of variables. |
|
118 nsTArray<Variable> mVariables; |
|
119 |
|
120 // The list of variables that each variable references. |
|
121 nsTArray<nsTArray<size_t> > mReferences; |
|
122 |
|
123 // The next index to assign to a variable found during the cycle removing |
|
124 // algorithm's traversal of the variable reference graph. |
|
125 size_t mNextIndex; |
|
126 |
|
127 // Stack of variable IDs that we push to as we traverse the variable reference |
|
128 // graph while looking for cycles. Variable::mInStack reflects whether a |
|
129 // given variable has its ID in mStack. |
|
130 nsTArray<size_t> mStack; |
|
131 |
|
132 // CSS parser to use for parsing property values with variable references. |
|
133 nsCSSParser mParser; |
|
134 |
|
135 // The object to output the resolved variables into. |
|
136 CSSVariableValues* mOutput; |
|
137 |
|
138 // Whether Resolve has been called. |
|
139 DebugOnly<bool> mResolved; |
|
140 }; |
|
141 |
|
142 } |
|
143 |
|
144 #endif |