2017-10-27 20:33:53 +03:00
|
|
|
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
|
|
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
|
2012-05-21 15:12:37 +04:00
|
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
2006-03-25 08:47:31 +03:00
|
|
|
|
|
|
|
/* atom list for CSS pseudo-elements */
|
|
|
|
|
2002-11-17 18:37:56 +03:00
|
|
|
#ifndef nsCSSPseudoElements_h___
|
|
|
|
#define nsCSSPseudoElements_h___
|
|
|
|
|
2018-08-15 08:46:00 +03:00
|
|
|
#include "nsGkAtoms.h"
|
2016-05-10 11:44:05 +03:00
|
|
|
#include "mozilla/CSSEnabledState.h"
|
2016-06-05 03:51:30 +03:00
|
|
|
#include "mozilla/Compiler.h"
|
2019-02-19 16:44:33 +03:00
|
|
|
#include "mozilla/PseudoStyleType.h"
|
1998-12-11 05:51:05 +03:00
|
|
|
|
2009-08-11 02:52:29 +04:00
|
|
|
// Is this pseudo-element a CSS2 pseudo-element that can be specified
|
|
|
|
// with the single colon syntax (in addition to the double-colon syntax,
|
|
|
|
// which can be used for all pseudo-elements)?
|
2017-08-06 19:42:55 +03:00
|
|
|
//
|
|
|
|
// Note: We also rely on this for IsEagerlyCascadedInServo.
|
2013-11-28 10:46:38 +04:00
|
|
|
#define CSS_PSEUDO_ELEMENT_IS_CSS2 (1 << 0)
|
2009-08-11 02:52:29 +04:00
|
|
|
// Is this pseudo-element a pseudo-element that can contain other
|
|
|
|
// elements?
|
|
|
|
// (Currently pseudo-elements are either leaves of the tree (relative to
|
|
|
|
// real elements) or they contain other elements in a non-tree-like
|
|
|
|
// manner (i.e., like incorrectly-nested start and end tags). It's
|
|
|
|
// possible that in the future there might be container pseudo-elements
|
|
|
|
// that form a properly nested tree structure. If that happens, we
|
|
|
|
// should probably split this flag into two.)
|
2013-11-28 10:46:38 +04:00
|
|
|
#define CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS (1 << 1)
|
2013-07-10 02:25:27 +04:00
|
|
|
// Flag to add the ability to take into account style attribute set for the
|
|
|
|
// pseudo element (by default it's ignored).
|
2013-11-28 10:46:38 +04:00
|
|
|
#define CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE (1 << 2)
|
|
|
|
// Flag that indicate the pseudo-element supports a user action pseudo-class
|
|
|
|
// following it, such as :active or :hover. This would normally correspond
|
|
|
|
// to whether the pseudo-element is tree-like, but we don't support these
|
|
|
|
// pseudo-classes on ::before and ::after generated content yet. See
|
|
|
|
// http://dev.w3.org/csswg/selectors4/#pseudo-elements.
|
|
|
|
#define CSS_PSEUDO_ELEMENT_SUPPORTS_USER_ACTION_STATE (1 << 3)
|
2018-01-26 16:13:14 +03:00
|
|
|
// Should this pseudo-element be enabled only for UA sheets?
|
|
|
|
#define CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS (1 << 4)
|
|
|
|
// Should this pseudo-element be enabled only for UA sheets and chrome
|
|
|
|
// stylesheets?
|
|
|
|
#define CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME (1 << 5)
|
|
|
|
|
|
|
|
#define CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME \
|
|
|
|
(CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS | \
|
|
|
|
CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME)
|
|
|
|
|
2017-03-17 10:30:34 +03:00
|
|
|
// Can we use the ChromeOnly document.createElement(..., { pseudo: "::foo" })
|
|
|
|
// API for creating pseudo-implementing native anonymous content in JS with this
|
|
|
|
// pseudo-element?
|
2018-01-26 16:13:14 +03:00
|
|
|
#define CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC (1 << 6)
|
2017-07-11 05:38:23 +03:00
|
|
|
// Does this pseudo-element act like an item for containers (such as flex and
|
|
|
|
// grid containers) and thus needs parent display-based style fixup?
|
2018-01-26 16:13:14 +03:00
|
|
|
#define CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM (1 << 7)
|
2009-08-11 02:52:29 +04:00
|
|
|
|
2016-02-17 23:37:00 +03:00
|
|
|
class nsCSSPseudoElements {
|
2019-02-19 16:44:33 +03:00
|
|
|
typedef mozilla::PseudoStyleType Type;
|
2016-05-10 11:44:05 +03:00
|
|
|
typedef mozilla::CSSEnabledState EnabledState;
|
1998-12-11 05:51:05 +03:00
|
|
|
|
2016-02-17 23:37:00 +03:00
|
|
|
public:
|
2017-10-03 01:05:19 +03:00
|
|
|
static bool IsPseudoElement(nsAtom* aAtom);
|
1998-12-11 05:51:05 +03:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
static bool IsCSS2PseudoElement(nsAtom* aAtom);
|
2009-08-11 02:52:29 +04:00
|
|
|
|
2017-08-06 19:42:55 +03:00
|
|
|
static bool IsEagerlyCascadedInServo(const Type aType) {
|
|
|
|
return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_CSS2);
|
|
|
|
}
|
|
|
|
|
2018-08-15 09:14:41 +03:00
|
|
|
public:
|
2018-08-15 08:46:00 +03:00
|
|
|
#ifdef DEBUG
|
|
|
|
static void AssertAtoms();
|
|
|
|
#endif
|
|
|
|
|
2018-10-10 08:49:13 +03:00
|
|
|
// Alias nsCSSPseudoElements::foo() to nsGkAtoms::foo.
|
2018-08-15 08:46:00 +03:00
|
|
|
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
|
2018-10-10 08:49:13 +03:00
|
|
|
static nsCSSPseudoElementStaticAtom* name_() { \
|
|
|
|
return const_cast<nsCSSPseudoElementStaticAtom*>( \
|
|
|
|
static_cast<const nsCSSPseudoElementStaticAtom*>( \
|
2018-10-04 02:16:11 +03:00
|
|
|
nsGkAtoms::PseudoElement_##name_)); \
|
2018-08-15 08:46:00 +03:00
|
|
|
}
|
Bug 1449395 - Remove nsStaticAtomSetup. r=froydnj
Each nsStaticAtomSetup contains a pointer to a static atom, and also a pointer
to the canonical pointer to that static atom. Which is pretty weird! The
notable thing thing about it is that these structs are in an array, and that
gives us the only way to iterate over all static atoms in a single class, for
registration and lookups.
But thanks to various other recent changes to the implementation of static
atoms, we can now put the static atoms themselves into an array, which can be
iterated over. So this patch does that. With that done, nsStaticAtomSetup is no
longer necessary.
According to the `size` utility, on Linux64 this reduces the size of libxul.so
by the following amounts:
> text: 62008 bytes
> data: 20992 bytes
> bss: 21040 bytes
> total: 104040 bytes
- The bss reduction is one word per atom, because the canonical static atom
pointers (e.g. nsGkAtoms::foo) have moved from .bss to .data, because they're
now initialized at compile time instead of runtime.
- The data reduction is one word per atom, because we remove two words per atom
for the nsStaticAtomSetup removal, but gain one word per atom from the
previous bullet point.
- I'm not sure about the text reduction. It's three words per atom. Maybe
because there is one less relocation per atom?
Other notable things in the patch:
- nsICSSAnonBoxPseudo and nsICSSPseudoElement now inherit from nsStaticAtom,
not nsAtom, because that's more precise.
- Each static atoms array now has an enum associated with it, which is used in
various ways.
- In the big comment about the macros at the top of nsStaticAtom.h, the pre-
and post-expansion forms are now shown interleaved. The interleaving reduces
duplication and makes the comment much easier to read and maintain. The
comment also has an introduction that explains the constraints and goals of
the implementation.
- The SUBCLASS macro variations are gone. There are few enough users of these
macros now that always passing the atom type has become simpler.
MozReview-Commit-ID: 1GmfKidLjaU
--HG--
extra : rebase_source : 2352590101fc6693ba388f885ca4714a42963943
2018-03-29 03:48:18 +03:00
|
|
|
#include "nsCSSPseudoElementList.h"
|
|
|
|
#undef CSS_PSEUDO_ELEMENT
|
2009-08-11 02:52:29 +04:00
|
|
|
|
2017-10-03 01:05:19 +03:00
|
|
|
static Type GetPseudoType(nsAtom* aAtom, EnabledState aEnabledState);
|
2009-12-11 10:37:40 +03:00
|
|
|
|
2019-02-19 16:44:33 +03:00
|
|
|
// Get the atom for a given Type. aType must be <
|
|
|
|
// PseudoType::CSSPseudoElementsEnd.
|
2017-08-17 21:37:32 +03:00
|
|
|
// This only ever returns static atoms, so it's fine to return a raw pointer.
|
2017-10-03 01:05:19 +03:00
|
|
|
static nsAtom* GetPseudoAtom(Type aType);
|
2009-12-11 10:37:40 +03:00
|
|
|
|
2017-08-17 21:37:32 +03:00
|
|
|
// Get the atom for a given pseudo-element string (e.g. "::before"). This can
|
|
|
|
// return dynamic atoms, for unrecognized pseudo-elements.
|
2017-10-03 01:05:19 +03:00
|
|
|
static already_AddRefed<nsAtom> GetPseudoAtom(
|
|
|
|
const nsAString& aPseudoElement);
|
2017-04-18 06:15:47 +03:00
|
|
|
|
2013-11-17 22:33:56 +04:00
|
|
|
static bool PseudoElementContainsElements(const Type aType) {
|
|
|
|
return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS);
|
|
|
|
}
|
|
|
|
|
2013-07-10 02:25:27 +04:00
|
|
|
static bool PseudoElementSupportsStyleAttribute(const Type aType) {
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
|
2016-02-17 23:37:00 +03:00
|
|
|
return PseudoElementHasFlags(aType,
|
|
|
|
CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE);
|
2013-07-10 02:25:27 +04:00
|
|
|
}
|
|
|
|
|
2013-11-28 10:46:38 +04:00
|
|
|
static bool PseudoElementSupportsUserActionState(const Type aType);
|
|
|
|
|
2017-03-17 10:30:34 +03:00
|
|
|
static bool PseudoElementIsJSCreatedNAC(Type aType) {
|
|
|
|
return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_IS_JS_CREATED_NAC);
|
|
|
|
}
|
|
|
|
|
2017-07-11 05:38:23 +03:00
|
|
|
static bool PseudoElementIsFlexOrGridItem(const Type aType) {
|
|
|
|
return PseudoElementHasFlags(aType,
|
|
|
|
CSS_PSEUDO_ELEMENT_IS_FLEX_OR_GRID_ITEM);
|
|
|
|
}
|
|
|
|
|
2016-05-10 11:44:05 +03:00
|
|
|
static bool IsEnabled(Type aType, EnabledState aEnabledState) {
|
2018-02-21 21:12:38 +03:00
|
|
|
if (!PseudoElementHasAnyFlag(
|
2018-01-26 16:13:14 +03:00
|
|
|
aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS_AND_CHROME)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-04-26 02:03:04 +03:00
|
|
|
if ((aEnabledState & EnabledState::InUASheets) &&
|
2018-01-26 16:13:14 +03:00
|
|
|
PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_UA_SHEETS)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2019-04-26 02:03:04 +03:00
|
|
|
if ((aEnabledState & EnabledState::InChrome) &&
|
2018-01-26 16:13:14 +03:00
|
|
|
PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_ENABLED_IN_CHROME)) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2013-11-28 11:03:13 +04:00
|
|
|
}
|
|
|
|
|
2018-01-27 15:17:26 +03:00
|
|
|
static nsString PseudoTypeAsString(Type aPseudoType);
|
|
|
|
|
2009-08-11 02:52:29 +04:00
|
|
|
private:
|
|
|
|
// Does the given pseudo-element have all of the flags given?
|
2013-11-17 22:33:56 +04:00
|
|
|
static bool PseudoElementHasFlags(const Type aType, uint32_t aFlags) {
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
|
2016-05-10 11:44:05 +03:00
|
|
|
return (kPseudoElementFlags[size_t(aType)] & aFlags) == aFlags;
|
2009-08-11 02:52:29 +04:00
|
|
|
}
|
2016-05-10 11:44:05 +03:00
|
|
|
|
2018-02-21 21:12:38 +03:00
|
|
|
static bool PseudoElementHasAnyFlag(const Type aType, uint32_t aFlags) {
|
2019-02-19 16:44:33 +03:00
|
|
|
MOZ_ASSERT(aType < Type::CSSPseudoElementsEnd);
|
2018-02-21 21:12:38 +03:00
|
|
|
return (kPseudoElementFlags[size_t(aType)] & aFlags) != 0;
|
|
|
|
}
|
|
|
|
|
2019-03-06 07:41:13 +03:00
|
|
|
static nsStaticAtom* GetAtomBase();
|
|
|
|
|
2019-02-19 16:44:33 +03:00
|
|
|
static const uint32_t kPseudoElementFlags[size_t(Type::CSSPseudoElementsEnd)];
|
2002-11-17 18:37:56 +03:00
|
|
|
};
|
1998-12-11 05:51:05 +03:00
|
|
|
|
2002-11-17 18:37:56 +03:00
|
|
|
#endif /* nsCSSPseudoElements_h___ */
|