nsCSSPseudoClasses.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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. /* atom list for CSS pseudo-classes */
  6. #include "mozilla/ArrayUtils.h"
  7. #include "nsCSSPseudoClasses.h"
  8. #include "nsStaticAtom.h"
  9. #include "mozilla/Preferences.h"
  10. #include "nsString.h"
  11. using namespace mozilla;
  12. using namespace mozilla::css;
  13. // define storage for all atoms
  14. #define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
  15. static nsIAtom* sPseudoClass_##_name;
  16. #include "nsCSSPseudoClassList.h"
  17. #undef CSS_PSEUDO_CLASS
  18. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  19. NS_STATIC_ATOM_BUFFER(name_##_pseudo_class_buffer, value_)
  20. #include "nsCSSPseudoClassList.h"
  21. #undef CSS_PSEUDO_CLASS
  22. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  23. static_assert(!((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME) || \
  24. ((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), \
  25. "Pseudo-class '" #name_ "' is enabled in chrome, so it " \
  26. "should also be enabled in UA sheets");
  27. #include "nsCSSPseudoClassList.h"
  28. #undef CSS_PSEUDO_CLASS
  29. // Array of nsStaticAtom for each of the pseudo-classes.
  30. static const nsStaticAtom CSSPseudoClasses_info[] = {
  31. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  32. NS_STATIC_ATOM(name_##_pseudo_class_buffer, &sPseudoClass_##name_),
  33. #include "nsCSSPseudoClassList.h"
  34. #undef CSS_PSEUDO_CLASS
  35. };
  36. // Flags data for each of the pseudo-classes, which must be separate
  37. // from the previous array since there's no place for it in
  38. // nsStaticAtom.
  39. /* static */ const uint32_t
  40. nsCSSPseudoClasses::kPseudoClassFlags[] = {
  41. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  42. flags_,
  43. #include "nsCSSPseudoClassList.h"
  44. #undef CSS_PSEUDO_CLASS
  45. };
  46. /* static */ bool
  47. nsCSSPseudoClasses::sPseudoClassEnabled[] = {
  48. // If the pseudo class has any "ENABLED_IN" flag set, it is disabled by
  49. // default. Note that, if a pseudo class has pref, whatever its default
  50. // value is, it'll later be changed in nsCSSPseudoClasses::AddRefAtoms()
  51. // If the pseudo class has "ENABLED_IN" flags but doesn't have a pref,
  52. // it is an internal pseudo class which is disabled elsewhere.
  53. #define IS_ENABLED_BY_DEFAULT(flags_) \
  54. (!((flags_) & CSS_PSEUDO_CLASS_ENABLED_MASK))
  55. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  56. IS_ENABLED_BY_DEFAULT(flags_),
  57. #include "nsCSSPseudoClassList.h"
  58. #undef CSS_PSEUDO_CLASS
  59. #undef IS_ENABLED_BY_DEFAULT
  60. };
  61. void nsCSSPseudoClasses::AddRefAtoms()
  62. {
  63. NS_RegisterStaticAtoms(CSSPseudoClasses_info);
  64. #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
  65. if (pref_[0]) { \
  66. auto idx = static_cast<CSSPseudoElementTypeBase>(Type::name_); \
  67. Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \
  68. }
  69. #include "nsCSSPseudoClassList.h"
  70. #undef CSS_PSEUDO_CLASS
  71. }
  72. bool
  73. nsCSSPseudoClasses::HasStringArg(Type aType)
  74. {
  75. return aType == Type::lang ||
  76. aType == Type::mozEmptyExceptChildrenWithLocalname ||
  77. aType == Type::mozSystemMetric ||
  78. aType == Type::mozLocaleDir ||
  79. aType == Type::mozDir ||
  80. aType == Type::dir;
  81. }
  82. bool
  83. nsCSSPseudoClasses::HasNthPairArg(Type aType)
  84. {
  85. return aType == Type::nthChild ||
  86. aType == Type::nthLastChild ||
  87. aType == Type::nthOfType ||
  88. aType == Type::nthLastOfType;
  89. }
  90. void
  91. nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString)
  92. {
  93. MOZ_ASSERT(aType < Type::Count, "Unexpected type");
  94. auto idx = static_cast<CSSPseudoClassTypeBase>(aType);
  95. (*CSSPseudoClasses_info[idx].mAtom)->ToString(aString);
  96. }
  97. /* static */ CSSPseudoClassType
  98. nsCSSPseudoClasses::GetPseudoType(nsIAtom* aAtom, EnabledState aEnabledState)
  99. {
  100. for (uint32_t i = 0; i < ArrayLength(CSSPseudoClasses_info); ++i) {
  101. if (*CSSPseudoClasses_info[i].mAtom == aAtom) {
  102. Type type = Type(i);
  103. return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
  104. }
  105. }
  106. return Type::NotPseudo;
  107. }
  108. /* static */ bool
  109. nsCSSPseudoClasses::IsUserActionPseudoClass(Type aType)
  110. {
  111. // See http://dev.w3.org/csswg/selectors4/#useraction-pseudos
  112. return aType == Type::hover ||
  113. aType == Type::active ||
  114. aType == Type::focus;
  115. }