Line data Source code
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 :
6 : /* atom list for CSS pseudo-classes */
7 :
8 : #include "mozilla/ArrayUtils.h"
9 :
10 : #include "nsCSSPseudoClasses.h"
11 : #include "nsCSSPseudoElements.h"
12 : #include "nsStaticAtom.h"
13 : #include "mozilla/Preferences.h"
14 : #include "mozilla/dom/Element.h"
15 : #include "nsString.h"
16 : #include "nsAttrValueInlines.h"
17 : #include "nsIMozBrowserFrame.h"
18 :
19 : using namespace mozilla;
20 :
21 : // define storage for all atoms
22 : #define CSS_PSEUDO_CLASS(_name, _value, _flags, _pref) \
23 : static nsIAtom* sPseudoClass_##_name;
24 : #include "nsCSSPseudoClassList.h"
25 : #undef CSS_PSEUDO_CLASS
26 :
27 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
28 : NS_STATIC_ATOM_BUFFER(name_##_pseudo_class_buffer, value_)
29 : #include "nsCSSPseudoClassList.h"
30 : #undef CSS_PSEUDO_CLASS
31 :
32 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
33 : static_assert(!((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_CHROME) || \
34 : ((flags_) & CSS_PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), \
35 : "Pseudo-class '" #name_ "' is enabled in chrome, so it " \
36 : "should also be enabled in UA sheets");
37 : #include "nsCSSPseudoClassList.h"
38 : #undef CSS_PSEUDO_CLASS
39 :
40 : // Array of nsStaticAtom for each of the pseudo-classes.
41 : static const nsStaticAtom CSSPseudoClasses_info[] = {
42 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
43 : NS_STATIC_ATOM(name_##_pseudo_class_buffer, &sPseudoClass_##name_),
44 : #include "nsCSSPseudoClassList.h"
45 : #undef CSS_PSEUDO_CLASS
46 : };
47 :
48 : // Flags data for each of the pseudo-classes, which must be separate
49 : // from the previous array since there's no place for it in
50 : // nsStaticAtom.
51 : /* static */ const uint32_t
52 : nsCSSPseudoClasses::kPseudoClassFlags[] = {
53 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
54 : flags_,
55 : #include "nsCSSPseudoClassList.h"
56 : #undef CSS_PSEUDO_CLASS
57 : };
58 :
59 : /* static */ bool
60 : nsCSSPseudoClasses::sPseudoClassEnabled[] = {
61 : // If the pseudo class has any "ENABLED_IN" flag set, it is disabled by
62 : // default. Note that, if a pseudo class has pref, whatever its default
63 : // value is, it'll later be changed in nsCSSPseudoClasses::AddRefAtoms()
64 : // If the pseudo class has "ENABLED_IN" flags but doesn't have a pref,
65 : // it is an internal pseudo class which is disabled elsewhere.
66 : #define IS_ENABLED_BY_DEFAULT(flags_) \
67 : (!((flags_) & CSS_PSEUDO_CLASS_ENABLED_MASK))
68 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
69 : IS_ENABLED_BY_DEFAULT(flags_),
70 : #include "nsCSSPseudoClassList.h"
71 : #undef CSS_PSEUDO_CLASS
72 : #undef IS_ENABLED_BY_DEFAULT
73 : };
74 :
75 3 : void nsCSSPseudoClasses::AddRefAtoms()
76 : {
77 3 : NS_RegisterStaticAtoms(CSSPseudoClasses_info);
78 :
79 : #define CSS_PSEUDO_CLASS(name_, value_, flags_, pref_) \
80 : if (pref_[0]) { \
81 : auto idx = static_cast<CSSPseudoElementTypeBase>(Type::name_); \
82 : Preferences::AddBoolVarCache(&sPseudoClassEnabled[idx], pref_); \
83 : }
84 : #include "nsCSSPseudoClassList.h"
85 : #undef CSS_PSEUDO_CLASS
86 3 : }
87 :
88 : bool
89 5121 : nsCSSPseudoClasses::HasStringArg(Type aType)
90 : {
91 5097 : return aType == Type::lang ||
92 5085 : aType == Type::mozEmptyExceptChildrenWithLocalname ||
93 4879 : aType == Type::mozSystemMetric ||
94 9000 : aType == Type::mozLocaleDir ||
95 5121 : aType == Type::dir;
96 : }
97 :
98 : bool
99 3814 : nsCSSPseudoClasses::HasNthPairArg(Type aType)
100 : {
101 3811 : return aType == Type::nthChild ||
102 3811 : aType == Type::nthLastChild ||
103 7625 : aType == Type::nthOfType ||
104 3814 : aType == Type::nthLastOfType;
105 : }
106 :
107 : void
108 0 : nsCSSPseudoClasses::PseudoTypeToString(Type aType, nsAString& aString)
109 : {
110 0 : MOZ_ASSERT(aType < Type::Count, "Unexpected type");
111 0 : auto idx = static_cast<CSSPseudoClassTypeBase>(aType);
112 0 : (*CSSPseudoClasses_info[idx].mAtom)->ToString(aString);
113 0 : }
114 :
115 : /* static */ CSSPseudoClassType
116 2857 : nsCSSPseudoClasses::GetPseudoType(nsIAtom* aAtom, EnabledState aEnabledState)
117 : {
118 95993 : for (uint32_t i = 0; i < ArrayLength(CSSPseudoClasses_info); ++i) {
119 95637 : if (*CSSPseudoClasses_info[i].mAtom == aAtom) {
120 2501 : Type type = Type(i);
121 2501 : return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
122 : }
123 : }
124 356 : return Type::NotPseudo;
125 : }
126 :
127 : /* static */ bool
128 2857 : nsCSSPseudoClasses::IsUserActionPseudoClass(Type aType)
129 : {
130 : // See http://dev.w3.org/csswg/selectors4/#useraction-pseudos
131 2601 : return aType == Type::hover ||
132 5301 : aType == Type::active ||
133 2857 : aType == Type::focus;
134 : }
135 :
136 : /* static */ Maybe<bool>
137 47009 : nsCSSPseudoClasses::MatchesElement(Type aType, const dom::Element* aElement)
138 : {
139 47009 : switch (aType) {
140 : case CSSPseudoClassType::mozNativeAnonymous:
141 4 : return Some(aElement->IsInNativeAnonymousSubtree());
142 : case CSSPseudoClassType::mozUseShadowTreeRoot:
143 0 : return Some(aElement->IsRootOfUseElementShadowTree());
144 : case CSSPseudoClassType::mozTableBorderNonzero: {
145 0 : if (!aElement->IsHTMLElement(nsGkAtoms::table)) {
146 0 : return Some(false);
147 : }
148 0 : const nsAttrValue *val = aElement->GetParsedAttr(nsGkAtoms::border);
149 0 : return Some(val && (val->Type() != nsAttrValue::eInteger ||
150 0 : val->GetIntegerValue() != 0));
151 : }
152 : case CSSPseudoClassType::mozBrowserFrame: {
153 : nsIMozBrowserFrame* browserFrame =
154 0 : const_cast<Element*>(aElement)->GetAsMozBrowserFrame();
155 0 : return Some(browserFrame && browserFrame->GetReallyIsBrowser());
156 : }
157 : default:
158 47005 : return Nothing();
159 : }
160 9 : }
|