CSSVariableDeclarations.cpp 5.5 KB

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