Line data Source code
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 : /* CSS Custom Property assignments for a Declaration at a given priority */
8 :
9 : #include "CSSVariableDeclarations.h"
10 :
11 : #include "CSSVariableResolver.h"
12 : #include "nsCSSScanner.h"
13 : #include "nsRuleData.h"
14 :
15 : // These three special string values are used to represent specified values of
16 : // 'initial', 'inherit' and 'unset'. (Note that none of these are valid
17 : // variable values.)
18 : #define INITIAL_VALUE "!"
19 : #define INHERIT_VALUE ";"
20 : #define UNSET_VALUE ")"
21 :
22 : namespace mozilla {
23 :
24 31 : CSSVariableDeclarations::CSSVariableDeclarations()
25 : {
26 31 : MOZ_COUNT_CTOR(CSSVariableDeclarations);
27 31 : }
28 :
29 12 : CSSVariableDeclarations::CSSVariableDeclarations(const CSSVariableDeclarations& aOther)
30 : {
31 12 : MOZ_COUNT_CTOR(CSSVariableDeclarations);
32 12 : CopyVariablesFrom(aOther);
33 12 : }
34 :
35 : #ifdef DEBUG
36 24 : CSSVariableDeclarations::~CSSVariableDeclarations()
37 : {
38 12 : MOZ_COUNT_DTOR(CSSVariableDeclarations);
39 12 : }
40 : #endif
41 :
42 : CSSVariableDeclarations&
43 0 : CSSVariableDeclarations::operator=(const CSSVariableDeclarations& aOther)
44 : {
45 0 : if (this == &aOther) {
46 0 : return *this;
47 : }
48 :
49 0 : mVariables.Clear();
50 0 : CopyVariablesFrom(aOther);
51 0 : return *this;
52 : }
53 :
54 : void
55 12 : CSSVariableDeclarations::CopyVariablesFrom(const CSSVariableDeclarations& aOther)
56 : {
57 34 : for (auto iter = aOther.mVariables.ConstIter(); !iter.Done(); iter.Next()) {
58 22 : mVariables.Put(iter.Key(), iter.UserData());
59 : }
60 12 : }
61 :
62 : bool
63 0 : CSSVariableDeclarations::Has(const nsAString& aName) const
64 : {
65 0 : nsString value;
66 0 : return mVariables.Get(aName, &value);
67 : }
68 :
69 : bool
70 0 : CSSVariableDeclarations::Get(const nsAString& aName,
71 : Type& aType,
72 : nsString& aTokenStream) const
73 : {
74 0 : nsString value;
75 0 : if (!mVariables.Get(aName, &value)) {
76 0 : return false;
77 : }
78 0 : if (value.EqualsLiteral(INITIAL_VALUE)) {
79 0 : aType = eInitial;
80 0 : aTokenStream.Truncate();
81 0 : } else if (value.EqualsLiteral(INHERIT_VALUE)) {
82 0 : aType = eInherit;
83 0 : aTokenStream.Truncate();
84 0 : } else if (value.EqualsLiteral(UNSET_VALUE)) {
85 0 : aType = eUnset;
86 0 : aTokenStream.Truncate();
87 : } else {
88 0 : aType = eTokenStream;
89 0 : aTokenStream = value;
90 : }
91 0 : return true;
92 : }
93 :
94 : void
95 74 : CSSVariableDeclarations::PutTokenStream(const nsAString& aName,
96 : const nsString& aTokenStream)
97 : {
98 74 : MOZ_ASSERT(!aTokenStream.EqualsLiteral(INITIAL_VALUE) &&
99 : !aTokenStream.EqualsLiteral(INHERIT_VALUE) &&
100 : !aTokenStream.EqualsLiteral(UNSET_VALUE));
101 74 : mVariables.Put(aName, aTokenStream);
102 74 : }
103 :
104 : void
105 0 : CSSVariableDeclarations::PutInitial(const nsAString& aName)
106 : {
107 0 : mVariables.Put(aName, NS_LITERAL_STRING(INITIAL_VALUE));
108 0 : }
109 :
110 : void
111 0 : CSSVariableDeclarations::PutInherit(const nsAString& aName)
112 : {
113 0 : mVariables.Put(aName, NS_LITERAL_STRING(INHERIT_VALUE));
114 0 : }
115 :
116 : void
117 0 : CSSVariableDeclarations::PutUnset(const nsAString& aName)
118 : {
119 0 : mVariables.Put(aName, NS_LITERAL_STRING(UNSET_VALUE));
120 0 : }
121 :
122 : void
123 0 : CSSVariableDeclarations::Remove(const nsAString& aName)
124 : {
125 0 : mVariables.Remove(aName);
126 0 : }
127 :
128 : void
129 735 : CSSVariableDeclarations::MapRuleInfoInto(nsRuleData* aRuleData)
130 : {
131 735 : if (!(aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Variables))) {
132 694 : return;
133 : }
134 :
135 41 : if (!aRuleData->mVariables) {
136 12 : aRuleData->mVariables = new CSSVariableDeclarations(*this);
137 : } else {
138 149 : for (auto iter = mVariables.Iter(); !iter.Done(); iter.Next()) {
139 : nsDataHashtable<nsStringHashKey, nsString>& variables =
140 120 : aRuleData->mVariables->mVariables;
141 120 : const nsAString& aName = iter.Key();
142 240 : variables.LookupForAdd(aName).OrInsert(
143 359 : [&iter] () { return iter.UserData(); });
144 : }
145 : }
146 : }
147 :
148 : void
149 12 : CSSVariableDeclarations::AddVariablesToResolver(
150 : CSSVariableResolver* aResolver) const
151 : {
152 153 : for (auto iter = mVariables.ConstIter(); !iter.Done(); iter.Next()) {
153 141 : const nsAString& name = iter.Key();
154 282 : nsString value = iter.UserData();
155 141 : if (value.EqualsLiteral(INITIAL_VALUE)) {
156 : // Values of 'initial' are treated the same as an invalid value in the
157 : // variable resolver.
158 0 : aResolver->Put(name, EmptyString(),
159 : eCSSTokenSerialization_Nothing,
160 : eCSSTokenSerialization_Nothing,
161 0 : false);
162 282 : } else if (value.EqualsLiteral(INHERIT_VALUE) ||
163 141 : value.EqualsLiteral(UNSET_VALUE)) {
164 : // Values of 'inherit' and 'unset' don't need any handling, since it means
165 : // we just need to keep whatever value is currently in the resolver. This
166 : // is because the specified variable declarations already have only the
167 : // winning declaration for the variable and no longer have any of the
168 : // others.
169 : } else {
170 : // At this point, we don't know what token types are at the start and end
171 : // of the specified variable value. These will be determined later during
172 : // the resolving process.
173 282 : aResolver->Put(name, value,
174 : eCSSTokenSerialization_Nothing,
175 : eCSSTokenSerialization_Nothing,
176 141 : false);
177 : }
178 : }
179 12 : }
180 :
181 : size_t
182 0 : CSSVariableDeclarations::SizeOfIncludingThis(
183 : mozilla::MallocSizeOf aMallocSizeOf) const
184 : {
185 0 : size_t n = aMallocSizeOf(this);
186 0 : n += mVariables.ShallowSizeOfExcludingThis(aMallocSizeOf);
187 0 : for (auto iter = mVariables.ConstIter(); !iter.Done(); iter.Next()) {
188 0 : n += iter.Key().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
189 0 : n += iter.Data().SizeOfExcludingThisIfUnshared(aMallocSizeOf);
190 : }
191 0 : return n;
192 : }
193 :
194 : } // namespace mozilla
|