Bug 1265639 - Support pseudo element aliases. draft
authorTing-Yu Lin <tlin@mozilla.com>
Fri, 06 May 2016 12:12:35 +0800
changeset 364186 a8e52a207dfd06a6c34a150f22f0b740c6a36038
parent 363870 e5a10bc7dac4ee2453d8319165c1f6578203eac7
child 520206 820eba4c38023ea2208dc9fd146f54d951c7c04c
push id17381
push usertlin@mozilla.com
push dateFri, 06 May 2016 04:15:53 +0000
bugs1265639
milestone49.0a1
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
layout/generic/nsTextFrame.cpp
layout/style/moz.build
layout/style/nsCSSParser.cpp
layout/style/nsCSSPseudoElementAliasList.h
layout/style/nsCSSPseudoElementList.h
layout/style/nsCSSPseudoElements.cpp
layout/style/nsCSSPseudoElements.h
--- 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);
   }