1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/layout/style/CSSVariableDeclarations.cpp Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,228 @@ 1.4 +/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ 1.5 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.8 + 1.9 +/* CSS Custom Property assignments for a Declaration at a given priority */ 1.10 + 1.11 +#include "CSSVariableDeclarations.h" 1.12 + 1.13 +#include "CSSVariableResolver.h" 1.14 +#include "nsCSSScanner.h" 1.15 +#include "nsRuleData.h" 1.16 + 1.17 +// These three special string values are used to represent specified values of 1.18 +// 'initial', 'inherit' and 'unset'. (Note that none of these are valid 1.19 +// variable values.) 1.20 +#define INITIAL_VALUE "!" 1.21 +#define INHERIT_VALUE ";" 1.22 +#define UNSET_VALUE ")" 1.23 + 1.24 +namespace mozilla { 1.25 + 1.26 +CSSVariableDeclarations::CSSVariableDeclarations() 1.27 +{ 1.28 + MOZ_COUNT_CTOR(CSSVariableDeclarations); 1.29 +} 1.30 + 1.31 +CSSVariableDeclarations::CSSVariableDeclarations(const CSSVariableDeclarations& aOther) 1.32 +{ 1.33 + MOZ_COUNT_CTOR(CSSVariableDeclarations); 1.34 + CopyVariablesFrom(aOther); 1.35 +} 1.36 + 1.37 +#ifdef DEBUG 1.38 +CSSVariableDeclarations::~CSSVariableDeclarations() 1.39 +{ 1.40 + MOZ_COUNT_DTOR(CSSVariableDeclarations); 1.41 +} 1.42 +#endif 1.43 + 1.44 +CSSVariableDeclarations& 1.45 +CSSVariableDeclarations::operator=(const CSSVariableDeclarations& aOther) 1.46 +{ 1.47 + if (this == &aOther) { 1.48 + return *this; 1.49 + } 1.50 + 1.51 + mVariables.Clear(); 1.52 + CopyVariablesFrom(aOther); 1.53 + return *this; 1.54 +} 1.55 + 1.56 +/* static */ PLDHashOperator 1.57 +CSSVariableDeclarations::EnumerateVariableForCopy(const nsAString& aName, 1.58 + nsString aValue, 1.59 + void* aData) 1.60 +{ 1.61 + CSSVariableDeclarations* variables = static_cast<CSSVariableDeclarations*>(aData); 1.62 + variables->mVariables.Put(aName, aValue); 1.63 + return PL_DHASH_NEXT; 1.64 +} 1.65 + 1.66 +void 1.67 +CSSVariableDeclarations::CopyVariablesFrom(const CSSVariableDeclarations& aOther) 1.68 +{ 1.69 + aOther.mVariables.EnumerateRead(EnumerateVariableForCopy, this); 1.70 +} 1.71 + 1.72 +bool 1.73 +CSSVariableDeclarations::Has(const nsAString& aName) const 1.74 +{ 1.75 + nsString value; 1.76 + return mVariables.Get(aName, &value); 1.77 +} 1.78 + 1.79 +bool 1.80 +CSSVariableDeclarations::Get(const nsAString& aName, 1.81 + Type& aType, 1.82 + nsString& aTokenStream) const 1.83 +{ 1.84 + nsString value; 1.85 + if (!mVariables.Get(aName, &value)) { 1.86 + return false; 1.87 + } 1.88 + if (value.EqualsLiteral(INITIAL_VALUE)) { 1.89 + aType = eInitial; 1.90 + aTokenStream.Truncate(); 1.91 + } else if (value.EqualsLiteral(INHERIT_VALUE)) { 1.92 + aType = eInitial; 1.93 + aTokenStream.Truncate(); 1.94 + } else if (value.EqualsLiteral(UNSET_VALUE)) { 1.95 + aType = eUnset; 1.96 + aTokenStream.Truncate(); 1.97 + } else { 1.98 + aType = eTokenStream; 1.99 + aTokenStream = value; 1.100 + } 1.101 + return true; 1.102 +} 1.103 + 1.104 +void 1.105 +CSSVariableDeclarations::PutTokenStream(const nsAString& aName, 1.106 + const nsString& aTokenStream) 1.107 +{ 1.108 + MOZ_ASSERT(!aTokenStream.EqualsLiteral(INITIAL_VALUE) && 1.109 + !aTokenStream.EqualsLiteral(INHERIT_VALUE) && 1.110 + !aTokenStream.EqualsLiteral(UNSET_VALUE)); 1.111 + mVariables.Put(aName, aTokenStream); 1.112 +} 1.113 + 1.114 +void 1.115 +CSSVariableDeclarations::PutInitial(const nsAString& aName) 1.116 +{ 1.117 + mVariables.Put(aName, NS_LITERAL_STRING(INITIAL_VALUE)); 1.118 +} 1.119 + 1.120 +void 1.121 +CSSVariableDeclarations::PutInherit(const nsAString& aName) 1.122 +{ 1.123 + mVariables.Put(aName, NS_LITERAL_STRING(INHERIT_VALUE)); 1.124 +} 1.125 + 1.126 +void 1.127 +CSSVariableDeclarations::PutUnset(const nsAString& aName) 1.128 +{ 1.129 + mVariables.Put(aName, NS_LITERAL_STRING(UNSET_VALUE)); 1.130 +} 1.131 + 1.132 +void 1.133 +CSSVariableDeclarations::Remove(const nsAString& aName) 1.134 +{ 1.135 + mVariables.Remove(aName); 1.136 +} 1.137 + 1.138 +/* static */ PLDHashOperator 1.139 +CSSVariableDeclarations::EnumerateVariableForMapRuleInfoInto( 1.140 + const nsAString& aName, 1.141 + nsString aValue, 1.142 + void* aData) 1.143 +{ 1.144 + nsDataHashtable<nsStringHashKey, nsString>* variables = 1.145 + static_cast<nsDataHashtable<nsStringHashKey, nsString>*>(aData); 1.146 + if (!variables->Contains(aName)) { 1.147 + variables->Put(aName, aValue); 1.148 + } 1.149 + return PL_DHASH_NEXT; 1.150 +} 1.151 + 1.152 +void 1.153 +CSSVariableDeclarations::MapRuleInfoInto(nsRuleData* aRuleData) 1.154 +{ 1.155 + if (!(aRuleData->mSIDs & NS_STYLE_INHERIT_BIT(Variables))) { 1.156 + return; 1.157 + } 1.158 + 1.159 + if (!aRuleData->mVariables) { 1.160 + aRuleData->mVariables = new CSSVariableDeclarations(*this); 1.161 + } else { 1.162 + mVariables.EnumerateRead(EnumerateVariableForMapRuleInfoInto, 1.163 + aRuleData->mVariables.get()); 1.164 + } 1.165 +} 1.166 + 1.167 +/* static */ PLDHashOperator 1.168 +CSSVariableDeclarations::EnumerateVariableForAddVariablesToResolver( 1.169 + const nsAString& aName, 1.170 + nsString aValue, 1.171 + void* aData) 1.172 +{ 1.173 + CSSVariableResolver* resolver = static_cast<CSSVariableResolver*>(aData); 1.174 + if (aValue.EqualsLiteral(INITIAL_VALUE)) { 1.175 + // Values of 'initial' are treated the same as an invalid value in the 1.176 + // variable resolver. 1.177 + resolver->Put(aName, EmptyString(), 1.178 + eCSSTokenSerialization_Nothing, 1.179 + eCSSTokenSerialization_Nothing, 1.180 + false); 1.181 + } else if (aValue.EqualsLiteral(INHERIT_VALUE) || 1.182 + aValue.EqualsLiteral(UNSET_VALUE)) { 1.183 + // Values of 'inherit' and 'unset' don't need any handling, since it means 1.184 + // we just need to keep whatever value is currently in the resolver. 1.185 + // Values of 'inherit' and 'unset' don't need any handling, since it means 1.186 + // we just need to keep whatever value is currently in the resolver. This 1.187 + // is because the specified variable declarations already have only the 1.188 + // winning declaration for the variable and no longer have any of the 1.189 + // others. 1.190 + } else { 1.191 + // At this point, we don't know what token types are at the start and end 1.192 + // of the specified variable value. These will be determined later during 1.193 + // the resolving process. 1.194 + resolver->Put(aName, aValue, 1.195 + eCSSTokenSerialization_Nothing, 1.196 + eCSSTokenSerialization_Nothing, 1.197 + false); 1.198 + } 1.199 + return PL_DHASH_NEXT; 1.200 +} 1.201 + 1.202 +void 1.203 +CSSVariableDeclarations::AddVariablesToResolver( 1.204 + CSSVariableResolver* aResolver) const 1.205 +{ 1.206 + mVariables.EnumerateRead(EnumerateVariableForAddVariablesToResolver, 1.207 + aResolver); 1.208 +} 1.209 + 1.210 +static size_t 1.211 +SizeOfTableEntry(const nsAString& aKey, 1.212 + const nsString& aValue, 1.213 + MallocSizeOf aMallocSizeOf, 1.214 + void* aUserArg) 1.215 +{ 1.216 + size_t n = 0; 1.217 + n += aKey.SizeOfExcludingThisIfUnshared(aMallocSizeOf); 1.218 + n += aValue.SizeOfExcludingThisIfUnshared(aMallocSizeOf); 1.219 + return n; 1.220 +} 1.221 + 1.222 +size_t 1.223 +CSSVariableDeclarations::SizeOfIncludingThis( 1.224 + mozilla::MallocSizeOf aMallocSizeOf) const 1.225 +{ 1.226 + size_t n = aMallocSizeOf(this); 1.227 + n += mVariables.SizeOfExcludingThis(SizeOfTableEntry, aMallocSizeOf); 1.228 + return n; 1.229 +} 1.230 + 1.231 +} // namespace mozilla