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-elements */
7 :
8 : #ifndef nsCSSPseudoElements_h___
9 : #define nsCSSPseudoElements_h___
10 :
11 : #include "nsIAtom.h"
12 : #include "mozilla/CSSEnabledState.h"
13 : #include "mozilla/Compiler.h"
14 :
15 : // Is this pseudo-element a CSS2 pseudo-element that can be specified
16 : // with the single colon syntax (in addition to the double-colon syntax,
17 : // which can be used for all pseudo-elements)?
18 : #define CSS_PSEUDO_ELEMENT_IS_CSS2 (1<<0)
19 : // Is this pseudo-element a pseudo-element that can contain other
20 : // elements?
21 : // (Currently pseudo-elements are either leaves of the tree (relative to
22 : // real elements) or they contain other elements in a non-tree-like
23 : // manner (i.e., like incorrectly-nested start and end tags). It's
24 : // possible that in the future there might be container pseudo-elements
25 : // that form a properly nested tree structure. If that happens, we
26 : // should probably split this flag into two.)
27 : #define CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS (1<<1)
28 : // Flag to add the ability to take into account style attribute set for the
29 : // pseudo element (by default it's ignored).
30 : #define CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE (1<<2)
31 : // Flag that indicate the pseudo-element supports a user action pseudo-class
32 : // following it, such as :active or :hover. This would normally correspond
33 : // to whether the pseudo-element is tree-like, but we don't support these
34 : // pseudo-classes on ::before and ::after generated content yet. See
35 : // http://dev.w3.org/csswg/selectors4/#pseudo-elements.
36 : #define CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE (1<<3)
37 : // Is content prevented from parsing selectors containing this pseudo-element?
38 : #define CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY (1<<4)
39 : // Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" })
40 : // API for creating pseudo-implementing native anonymous content in JS with this
41 : // pseudo-element?
42 : #define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1<<5)
43 : // Does this pseudo-element act like an item for containers (such as flex and
44 : // grid containers) and thus needs parent display-based style fixup?
45 : #define CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM (1<<6)
46 :
47 : namespace mozilla {
48 :
49 : // The total count of CSSPseudoElement is less than 256,
50 : // so use uint8_t as its underlying type.
51 : typedef uint8_t CSSPseudoElementTypeBase;
52 : enum class CSSPseudoElementType : CSSPseudoElementTypeBase {
53 : // If the actual pseudo-elements stop being first here, change
54 : // GetPseudoType.
55 : #define CSS_PSEUDO_ELEMENT(_name, _value_, _flags) \
56 : _name,
57 : #include "nsCSSPseudoElementList.h"
58 : #undef CSS_PSEUDO_ELEMENT
59 : Count,
60 : InheritingAnonBox = Count, // pseudo from nsCSSAnonBoxes,
61 : // IsNonInheritingAnonBox false.
62 : NonInheritingAnonBox, // from nsCSSAnonBoxes, IsNonInheritingAnonBox true.
63 : #ifdef MOZ_XUL
64 : XULTree,
65 : #endif
66 : NotPseudo,
67 : MAX
68 : };
69 :
70 : } // namespace mozilla
71 :
72 : // Empty class derived from nsIAtom so that function signatures can
73 : // require an atom from this atom list.
74 : class nsICSSPseudoElement : public nsIAtom {};
75 :
76 : class nsCSSPseudoElements
77 : {
78 : typedef mozilla::CSSPseudoElementType Type;
79 : typedef mozilla::CSSEnabledState EnabledState;
80 :
81 : public:
82 : static void AddRefAtoms();
83 :
84 : static bool IsPseudoElement(nsIAtom *aAtom);
85 :
86 : static bool IsCSS2PseudoElement(nsIAtom *aAtom);
87 :
88 : #define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \
89 : static nsICSSPseudoElement* _name;
90 : #include "nsCSSPseudoElementList.h"
91 : #undef CSS_PSEUDO_ELEMENT
92 :
93 : static Type GetPseudoType(nsIAtom* aAtom, EnabledState aEnabledState);
94 :
95 : // Get the atom for a given Type. aType must be < CSSPseudoElementType::Count
96 : static nsIAtom* GetPseudoAtom(Type aType);
97 :
98 : // Get the atom for a given nsAString. (e.g. "::before")
99 : static nsIAtom* GetPseudoAtom(const nsAString& aPseudoElement);
100 :
101 0 : static bool PseudoElementContainsElements(const Type aType) {
102 0 : return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS);
103 : }
104 :
105 1292 : static bool PseudoElementSupportsStyleAttribute(const Type aType) {
106 1292 : MOZ_ASSERT(aType < Type::Count);
107 : return PseudoElementHasFlags(aType,
108 1292 : CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE);
109 : }
110 :
111 : static bool PseudoElementSupportsUserActionState(const Type aType);
112 :
113 10 : static bool PseudoElementIsJSCreatedNAC(Type aType)
114 : {
115 10 : return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC);
116 : }
117 :
118 53 : static bool PseudoElementIsFlexOrGridItem(const Type aType)
119 : {
120 : return PseudoElementHasFlags(aType,
121 53 : CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM);
122 : }
123 :
124 259 : static bool IsEnabled(Type aType, EnabledState aEnabledState)
125 : {
126 279 : return !PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY) ||
127 279 : (aEnabledState & EnabledState::eInUASheets);
128 : }
129 :
130 : private:
131 : // Does the given pseudo-element have all of the flags given?
132 :
133 : // Work around https://gcc.gnu.org/bugzilla/show_bug.cgi?id=64037 ,
134 : // which is a general gcc bug that we seem to have hit only on Android/x86.
135 : #if defined(ANDROID) && defined(__i386__) && defined(__GNUC__) && \
136 : !defined(__clang__)
137 : #if (MOZ_GCC_VERSION_AT_LEAST(4,8,0) && MOZ_GCC_VERSION_AT_MOST(4,8,4)) || \
138 : (MOZ_GCC_VERSION_AT_LEAST(4,9,0) && MOZ_GCC_VERSION_AT_MOST(4,9,2))
139 : __attribute__((noinline))
140 : #endif
141 : #endif
142 2326 : static bool PseudoElementHasFlags(const Type aType, uint32_t aFlags)
143 : {
144 2326 : MOZ_ASSERT(aType < Type::Count);
145 2326 : return (kPseudoElementFlags[size_t(aType)] & aFlags) == aFlags;
146 : }
147 :
148 : static const uint32_t kPseudoElementFlags[size_t(Type::Count)];
149 : };
150 :
151 : #endif /* nsCSSPseudoElements_h___ */
|