Bug 1269976 part 2 - Add nsCSSPseudoElements::IsEnabled() and make GetPseudoType take CSSEnabledState. r?heycam draft
authorXidorn Quan <quanxunzhen@gmail.com>
Thu, 05 May 2016 14:16:15 +1000
changeset 364716 f1ced8cda86ceab01c4e770d7fa15498852c51dc
parent 364715 0bb39430699c0af285372e3a65caa4c2f7181535
child 364721 401f5ea802fecd020d0bb042027c6b54595319f6
push id17555
push userxquan@mozilla.com
push dateMon, 09 May 2016 07:00:07 +0000
reviewersheycam
bugs1269976
milestone49.0a1
Bug 1269976 part 2 - Add nsCSSPseudoElements::IsEnabled() and make GetPseudoType take CSSEnabledState. r?heycam MozReview-Commit-ID: K3uFwojy6FZ
layout/inspector/inDOMUtils.cpp
layout/style/nsCSSParser.cpp
layout/style/nsCSSPseudoElements.cpp
layout/style/nsCSSPseudoElements.h
layout/style/nsComputedDOMStyle.cpp
layout/style/nsStyleSet.cpp
--- a/layout/inspector/inDOMUtils.cpp
+++ b/layout/inspector/inDOMUtils.cpp
@@ -454,18 +454,18 @@ inDOMUtils::SelectorMatchesElement(nsIDO
     *aMatches = false;
     return NS_OK;
   }
 
   if (!aPseudo.IsEmpty()) {
     // We need to make sure that the requested pseudo element type
     // matches the selector pseudo element type before proceeding.
     nsCOMPtr<nsIAtom> pseudoElt = NS_Atomize(aPseudo);
-    if (sel->mSelectors->PseudoType() !=
-        nsCSSPseudoElements::GetPseudoType(pseudoElt)) {
+    if (sel->mSelectors->PseudoType() != nsCSSPseudoElements::
+          GetPseudoType(pseudoElt, CSSEnabledState::eIgnoreEnabledState)) {
       *aMatches = false;
       return NS_OK;
     }
 
     // We have a matching pseudo element, now remove it so we can compare
     // directly against |element| when proceeding into SelectorListMatches.
     // It's OK to do this - we just cloned sel and nothing else is using it.
     sel->RemoveRightmostSelector();
@@ -1228,17 +1228,17 @@ NS_IMETHODIMP
 inDOMUtils::GetCSSPseudoElementNames(uint32_t* aLength, char16_t*** aNames)
 {
   nsTArray<nsIAtom*> array;
 
   const CSSPseudoElementTypeBase pseudoCount =
     static_cast<CSSPseudoElementTypeBase>(CSSPseudoElementType::Count);
   for (CSSPseudoElementTypeBase i = 0; i < pseudoCount; ++i) {
     CSSPseudoElementType type = static_cast<CSSPseudoElementType>(i);
-    if (!nsCSSPseudoElements::PseudoElementIsUASheetOnly(type)) {
+    if (nsCSSPseudoElements::IsEnabled(type, CSSEnabledState::eForAllContent)) {
       nsIAtom* atom = nsCSSPseudoElements::GetPseudoAtom(type);
       array.AppendElement(atom);
     }
   }
 
   *aLength = array.Length();
   char16_t** ret =
     static_cast<char16_t**>(moz_xmalloc(*aLength * sizeof(char16_t*)));
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -5911,30 +5911,22 @@ CSSParserImpl::ParsePseudoSelector(int32
   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;
   CSSEnabledState enabledState = EnabledState();
   CSSPseudoElementType pseudoElementType =
-    nsCSSPseudoElements::GetPseudoType(pseudo);
+    nsCSSPseudoElements::GetPseudoType(pseudo, enabledState);
   CSSPseudoClassType pseudoClassType =
     nsCSSPseudoClasses::GetPseudoType(pseudo, enabledState);
   bool pseudoClassIsUserAction =
     nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType);
 
-  if (pseudoElementType < CSSPseudoElementType::Count && !AgentRulesEnabled() &&
-      nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) {
-    // This pseudo-element is not exposed to content.
-    REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
-    UngetToken();
-    return eSelectorParsingStatus_Error;
-  }
-
   if (nsCSSAnonBoxes::IsNonElement(pseudo)) {
     // Non-element anonymous boxes should not match any rule.
     REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
     UngetToken();
     return eSelectorParsingStatus_Error;
   }
 
   // We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
--- a/layout/style/nsCSSPseudoElements.cpp
+++ b/layout/style/nsCSSPseudoElements.cpp
@@ -63,30 +63,32 @@ nsCSSPseudoElements::IsCSS2PseudoElement
   NS_ASSERTION(nsCSSPseudoElements::IsPseudoElement(aAtom) ||
                nsCSSAnonBoxes::IsAnonBox(aAtom),
                "must be pseudo element or anon box");
   bool result = aAtom == nsCSSPseudoElements::after ||
                   aAtom == nsCSSPseudoElements::before ||
                   aAtom == nsCSSPseudoElements::firstLetter ||
                   aAtom == nsCSSPseudoElements::firstLine;
   NS_ASSERTION(nsCSSAnonBoxes::IsAnonBox(aAtom) ||
-               result == PseudoElementHasFlags(GetPseudoType(aAtom),
-                                               CSS_PSEUDO_ELEMENT_IS_CSS2),
+               result == PseudoElementHasFlags(
+                   GetPseudoType(aAtom, EnabledState::eIgnoreEnabledState),
+                   CSS_PSEUDO_ELEMENT_IS_CSS2),
                "result doesn't match flags");
   return result;
 }
 
 /* static */ CSSPseudoElementType
-nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom)
+nsCSSPseudoElements::GetPseudoType(nsIAtom *aAtom, EnabledState aEnabledState)
 {
   for (CSSPseudoElementTypeBase i = 0;
        i < ArrayLength(CSSPseudoElements_info);
        ++i) {
     if (*CSSPseudoElements_info[i].mAtom == aAtom) {
-      return static_cast<Type>(i);
+      auto type = static_cast<Type>(i);
+      return IsEnabled(type, aEnabledState) ? type : Type::NotPseudo;
     }
   }
 
   if (nsCSSAnonBoxes::IsAnonBox(aAtom)) {
 #ifdef MOZ_XUL
     if (nsCSSAnonBoxes::IsTreePseudoElement(aAtom)) {
       return Type::XULTree;
     }
--- a/layout/style/nsCSSPseudoElements.h
+++ b/layout/style/nsCSSPseudoElements.h
@@ -4,16 +4,17 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 /* atom list for CSS pseudo-elements */
 
 #ifndef nsCSSPseudoElements_h___
 #define nsCSSPseudoElements_h___
 
 #include "nsIAtom.h"
+#include "mozilla/CSSEnabledState.h"
 
 // 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)?
 #define CSS_PSEUDO_ELEMENT_IS_CSS2                     (1<<0)
 // Is this pseudo-element a pseudo-element that can contain other
 // elements?
 // (Currently pseudo-elements are either leaves of the tree (relative to
@@ -60,49 +61,51 @@ enum class CSSPseudoElementType : CSSPse
 
 // Empty class derived from nsIAtom so that function signatures can
 // require an atom from this atom list.
 class nsICSSPseudoElement : public nsIAtom {};
 
 class nsCSSPseudoElements
 {
   typedef mozilla::CSSPseudoElementType Type;
+  typedef mozilla::CSSEnabledState EnabledState;
 
 public:
   static void AddRefAtoms();
 
   static bool IsPseudoElement(nsIAtom *aAtom);
 
   static bool IsCSS2PseudoElement(nsIAtom *aAtom);
 
 #define CSS_PSEUDO_ELEMENT(_name, _value, _flags) \
   static nsICSSPseudoElement* _name;
 #include "nsCSSPseudoElementList.h"
 #undef CSS_PSEUDO_ELEMENT
 
-  static Type GetPseudoType(nsIAtom* aAtom);
+  static Type GetPseudoType(nsIAtom* aAtom, EnabledState aEnabledState);
 
   // 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);
   }
 
   static bool PseudoElementSupportsStyleAttribute(const Type aType) {
     MOZ_ASSERT(aType < Type::Count);
     return PseudoElementHasFlags(aType,
                                  CSS_PSEUDO_ELEMENT_SUPPORTS_STYLE_ATTRIBUTE);
   }
 
   static bool PseudoElementSupportsUserActionState(const Type aType);
 
-  static bool PseudoElementIsUASheetOnly(const Type aType) {
-    MOZ_ASSERT(aType < Type::Count);
-    return PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY);
+  static bool IsEnabled(Type aType, EnabledState aEnabledState)
+  {
+    return !PseudoElementHasFlags(aType, CSS_PSEUDO_ELEMENT_UA_SHEET_ONLY) ||
+           (aEnabledState & EnabledState::eInUASheets);
   }
 
 private:
   // Does the given pseudo-element have all of the flags given?
   static bool PseudoElementHasFlags(const Type aType, uint32_t aFlags)
   {
     MOZ_ASSERT(aType < Type::Count);
     return (kPseudoElementFlags[size_t(aType)] & aFlags) == aFlags;
--- a/layout/style/nsComputedDOMStyle.cpp
+++ b/layout/style/nsComputedDOMStyle.cpp
@@ -483,17 +483,18 @@ nsComputedDOMStyle::GetStyleContextForEl
   nsPresContext *presContext = presShell->GetPresContext();
   if (!presContext)
     return nullptr;
 
   StyleSetHandle styleSet = presShell->StyleSet();
 
   RefPtr<nsStyleContext> sc;
   if (aPseudo) {
-    CSSPseudoElementType type = nsCSSPseudoElements::GetPseudoType(aPseudo);
+    CSSPseudoElementType type = nsCSSPseudoElements::
+      GetPseudoType(aPseudo, CSSEnabledState::eIgnoreEnabledState);
     if (type >= CSSPseudoElementType::Count) {
       return nullptr;
     }
     nsIFrame* frame = nsLayoutUtils::GetStyleFrame(aElement);
     Element* pseudoElement =
       frame && inDocWithShell ? frame->GetPseudoElement(type) : nullptr;
     sc = styleSet->ResolvePseudoElementStyle(aElement, type, parentContext,
                                              pseudoElement);
--- a/layout/style/nsStyleSet.cpp
+++ b/layout/style/nsStyleSet.cpp
@@ -860,18 +860,19 @@ nsStyleSet::GetContext(nsStyleContext* a
                        CSSPseudoElementType aPseudoType,
                        Element* aElementForAnimation,
                        uint32_t aFlags)
 {
   NS_PRECONDITION((!aPseudoTag &&
                    aPseudoType ==
                      CSSPseudoElementType::NotPseudo) ||
                   (aPseudoTag &&
-                   nsCSSPseudoElements::GetPseudoType(aPseudoTag) ==
-                     aPseudoType),
+                   nsCSSPseudoElements::GetPseudoType(
+                     aPseudoTag, CSSEnabledState::eIgnoreEnabledState) ==
+                   aPseudoType),
                   "Pseudo mismatch");
 
   if (aVisitedRuleNode == aRuleNode) {
     // No need to force creation of a visited style in this case.
     aVisitedRuleNode = nullptr;
   }
 
   // Ensure |aVisitedRuleNode != nullptr| corresponds to the need to