Bug 1265639 - Support pseudo element aliases.
The idea is to support parsing both pseudo-element and the alias, but
given both of them the same pseudo-element type via
nsCSSPseudoElements::GetPseudoType().
MozReview-Commit-ID: EfXG6FkqUXg
--- a/layout/generic/nsTextFrame.cpp
+++ b/layout/generic/nsTextFrame.cpp
@@ -3748,17 +3748,17 @@ nsTextPaintStyle::InitSelectionColorsAnd
Element* selectionElement =
FindElementAncestorForMozSelection(nonGeneratedAncestor->GetContent());
if (selectionElement &&
selectionStatus == nsISelectionController::SELECTION_ON) {
RefPtr<nsStyleContext> sc = nullptr;
sc = mPresContext->StyleSet()->
ProbePseudoElementStyle(selectionElement,
- CSSPseudoElementType::mozSelection,
+ CSSPseudoElementType::selection,
mFrame->StyleContext());
// Use -moz-selection pseudo class.
if (sc) {
mSelectionBGColor =
sc->GetVisitedDependentColor(eCSSProperty_background_color);
mSelectionTextColor = sc->GetVisitedDependentColor(sc->GetTextFillColorProp());
mHasSelectionShadow =
nsRuleNode::HasAuthorSpecifiedRules(sc,
--- a/layout/style/moz.build
+++ b/layout/style/moz.build
@@ -44,16 +44,17 @@ EXPORTS += [
'nsCSSPropAliasList.h',
'nsCSSProperty.h',
'nsCSSPropertySet.h',
'nsCSSPropList.h',
'nsCSSPropLogicalGroupList.h',
'nsCSSProps.h',
'nsCSSPseudoClasses.h',
'nsCSSPseudoClassList.h',
+ 'nsCSSPseudoElementAliasList.h',
'nsCSSPseudoElementList.h',
'nsCSSPseudoElements.h',
'nsCSSRuleProcessor.h',
'nsCSSScanner.h',
'nsCSSValue.h',
'nsDOMCSSAttrDeclaration.h',
'nsDOMCSSDeclaration.h',
'nsDOMCSSRGBColor.h',
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5909,16 +5909,17 @@ CSSParserImpl::ParsePseudoSelector(int32
nsAutoString buffer;
buffer.Append(char16_t(':'));
buffer.Append(mToken.mIdent);
nsContentUtils::ASCIIToLower(buffer);
nsCOMPtr<nsIAtom> pseudo = NS_Atomize(buffer);
// stash away some info about this pseudo so we only have to get it once.
bool isTreePseudo = false;
+ // Pseudo-element aliases will get their original types.
CSSPseudoElementType pseudoElementType =
nsCSSPseudoElements::GetPseudoType(pseudo);
CSSPseudoClassType pseudoClassType =
nsCSSPseudoClasses::GetPseudoType(pseudo, AgentRulesEnabled(),
ChromeRulesEnabled());
bool pseudoClassIsUserAction =
nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType);
new file mode 100644
--- /dev/null
+++ b/layout/style/nsCSSPseudoElementAliasList.h
@@ -0,0 +1,21 @@
+/* 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/. */
+
+// Alias atom list for CSS pseudo-elements. An aliased pseudo-element won't have
+// an associated enum in CSSPseudoElementType. Its type is the same as the
+// original one.
+
+// Code include this file MUST define CSS_PSEUDO_ELEMENT_ALIAS, which takes
+// three parameters:
+//
+// name_ : The C++ identifier used for the alias atom.
+//
+// value_ : The pseudo-element as a string, with single-colon syntax, used as
+// the string value of the alias atom.
+//
+// aliasname_ : The same C++ identifier name as the name_ field in
+// nsCSSPseudoElementsList.h for the identifier that name_ is being aliased to.
+//
+
+CSS_PSEUDO_ELEMENT_ALIAS(mozSelection, ":-moz-selection", selection)
--- a/layout/style/nsCSSPseudoElementList.h
+++ b/layout/style/nsCSSPseudoElementList.h
@@ -32,17 +32,17 @@ CSS_PSEUDO_ELEMENT(backdrop, ":backdrop"
CSS_PSEUDO_ELEMENT(firstLetter, ":first-letter",
CSS_PSEUDO_ELEMENT_IS_CSS2 |
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
CSS_PSEUDO_ELEMENT(firstLine, ":first-line",
CSS_PSEUDO_ELEMENT_IS_CSS2 |
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
-CSS_PSEUDO_ELEMENT(mozSelection, ":-moz-selection",
+CSS_PSEUDO_ELEMENT(selection, ":selection",
CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS)
// XXXbz should we really allow random content to style these? Maybe
// use our flags to prevent that?
CSS_PSEUDO_ELEMENT(mozFocusInner, ":-moz-focus-inner", 0)
CSS_PSEUDO_ELEMENT(mozFocusOuter, ":-moz-focus-outer", 0)
// XXXbz should we really allow random content to style these? Maybe
--- a/layout/style/nsCSSPseudoElements.cpp
+++ b/layout/style/nsCSSPseudoElements.cpp
@@ -15,48 +15,76 @@
using namespace mozilla;
// define storage for all atoms
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
nsICSSPseudoElement* nsCSSPseudoElements::name_;
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
+#define CSS_PSEUDO_ELEMENT_ALIAS(name_, value_, aliasname_) \
+ nsICSSPseudoElement* nsCSSPseudoElements::name_;
+#include "nsCSSPseudoElementAliasList.h"
+#undef CSS_PSEUDO_ELEMENT_ALIAS
+
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
NS_STATIC_ATOM_BUFFER(name_##_pseudo_element_buffer, value_)
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
+#define CSS_PSEUDO_ELEMENT_ALIAS(name_, value_, aliasname_) \
+ NS_STATIC_ATOM_BUFFER(name_##_pseudo_element_buffer, value_)
+#include "nsCSSPseudoElementAliasList.h"
+#undef CSS_PSEUDO_ELEMENT_ALIAS
+
// Array of nsStaticAtom for each of the pseudo-elements.
static const nsStaticAtom CSSPseudoElements_info[] = {
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
NS_STATIC_ATOM(name_##_pseudo_element_buffer, (nsIAtom**)&nsCSSPseudoElements::name_),
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
};
+static const nsStaticAtom CSSPseudoElementAliases_info[] = {
+#define CSS_PSEUDO_ELEMENT_ALIAS(name_, value_, aliasname_) \
+ NS_STATIC_ATOM(name_##_pseudo_element_buffer, (nsIAtom**)&nsCSSPseudoElements::name_),
+#include "nsCSSPseudoElementAliasList.h"
+#undef CSS_PSEUDO_ELEMENT_ALIAS
+};
+
// Flags data for each of the pseudo-elements, which must be separate
// from the previous array since there's no place for it in
// nsStaticAtom.
static const uint32_t CSSPseudoElements_flags[] = {
#define CSS_PSEUDO_ELEMENT(name_, value_, flags_) \
flags_,
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
};
+// Array of the pseudo-elements for each of the alias.
+static nsICSSPseudoElement** const CSSPseudoElementAliases_name[] = {
+#define CSS_PSEUDO_ELEMENT_ALIAS(name_, value_, aliasname_) \
+ &nsCSSPseudoElements::aliasname_,
+#include "nsCSSPseudoElementAliasList.h"
+#undef CSS_PSEUDO_ELEMENT_ALIAS
+};
+
void nsCSSPseudoElements::AddRefAtoms()
{
NS_RegisterStaticAtoms(CSSPseudoElements_info);
+ NS_RegisterStaticAtoms(CSSPseudoElementAliases_info);
}
bool nsCSSPseudoElements::IsPseudoElement(nsIAtom *aAtom)
{
return nsAtomListUtils::IsMember(aAtom, CSSPseudoElements_info,
- ArrayLength(CSSPseudoElements_info));
+ ArrayLength(CSSPseudoElements_info)) ||
+ nsAtomListUtils::IsMember(aAtom, CSSPseudoElementAliases_info,
+ ArrayLength(CSSPseudoElementAliases_info));
}
/* static */ bool
nsCSSPseudoElements::IsCSS2PseudoElement(nsIAtom *aAtom)
{
// We don't implement this using PseudoElementHasFlags because callers
// want to pass things that could be anon boxes.
NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aAtom) ||
@@ -71,16 +99,26 @@ nsCSSPseudoElements::IsCSS2PseudoElement
CSS_PSEUDO_ELEMENT_IS_CSS2),
"result doesn't match flags");
return result;
}
/* static */ CSSPseudoElementType
nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom)
{
+ // Mapping the alias atom to the original pseudo-element atom.
+ for (CSSPseudoElementTypeBase i = 0;
+ i < ArrayLength(CSSPseudoElementAliases_info);
+ ++i) {
+ if (*CSSPseudoElementAliases_info[i].mAtom == aAtom) {
+ aAtom = *CSSPseudoElementAliases_name[i];
+ break;
+ }
+ }
+
for (CSSPseudoElementTypeBase i = 0;
i < ArrayLength(CSSPseudoElements_info);
++i) {
if (*CSSPseudoElements_info[i].mAtom == aAtom) {
return static_cast<Type>(i);
}
}
--- a/layout/style/nsCSSPseudoElements.h
+++ b/layout/style/nsCSSPseudoElements.h
@@ -73,16 +73,21 @@ public:
static bool IsCSS2PseudoElement(nsIAtom *aAtom);
#define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \
static nsICSSPseudoElement* _name;
#include "nsCSSPseudoElementList.h"
#undef CSS_PSEUDO_ELEMENT
+#define CSS_PSEUDO_ELEMENT_ALIAS(_name, _value, _aliasname) \
+ static nsICSSPseudoElement* _name;
+#include "nsCSSPseudoElementAliasList.h"
+#undef CSS_PSEUDO_ELEMENT_ALIAS
+
static Type GetPseudoType(nsIAtom* aAtom);
// Get the atom for a given Type. aType must be < CSSPseudoElementType::Count
static nsIAtom* GetPseudoAtom(Type aType);
static bool PseudoElementContainsElements(const Type aType) {
return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_CONTAINS_ELEMENTS);
}