Bug 819871 - Make ":-moz-placeholder" parsable but without any effect on styling. r=dbaron,bz a=akeybl
authorMounir Lamouri <mounir.lamouri@gmail.com>
Mon, 28 Jan 2013 15:17:50 +0000
changeset 127329 2ea3931eae6cb55a0eff971438163b853a32cbba
parent 127328 caf86701e0fddaeac5823b23ec4d9de6cec9f4d3
child 127330 43bae1b558444206809b3327154339da857439ed
push id2151
push userlsblakk@mozilla.com
push dateTue, 19 Feb 2013 18:06:57 +0000
treeherdermozilla-beta@4952e88741ec [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersdbaron, bz, akeybl
bugs819871
milestone20.0a2
Bug 819871 - Make ":-moz-placeholder" parsable but without any effect on styling. r=dbaron,bz a=akeybl
content/events/public/nsEventStates.h
layout/reftests/css-placeholder/ignore-pseudo-class-ref.html
layout/reftests/css-placeholder/ignore-pseudo-class.html
layout/reftests/css-placeholder/reftest.list
layout/style/nsCSSParser.cpp
layout/style/nsCSSPseudoClassList.h
layout/style/test/test_selectors.html
--- a/content/events/public/nsEventStates.h
+++ b/content/events/public/nsEventStates.h
@@ -248,16 +248,19 @@ private:
 #define NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM NS_DEFINE_EVENT_STATE_MACRO(41)
 // Element is ltr (for :dir pseudo-class)
 #define NS_EVENT_STATE_LTR NS_DEFINE_EVENT_STATE_MACRO(42)
 // Element is rtl (for :dir pseudo-class)
 #define NS_EVENT_STATE_RTL NS_DEFINE_EVENT_STATE_MACRO(43)
 // Handler for play preview plugin
 #define NS_EVENT_STATE_TYPE_PLAY_PREVIEW NS_DEFINE_EVENT_STATE_MACRO(44)
 
+// Event state that is used for values that need to be parsed but do nothing.
+#define NS_EVENT_STATE_IGNORE NS_DEFINE_EVENT_STATE_MACRO(63)
+
 /**
  * NOTE: do not go over 63 without updating nsEventStates::InternalType!
  */
 
 #define DIRECTION_STATES (NS_EVENT_STATE_LTR | NS_EVENT_STATE_RTL)
 
 #define ESM_MANAGED_STATES (NS_EVENT_STATE_ACTIVE | NS_EVENT_STATE_FOCUS |     \
                             NS_EVENT_STATE_HOVER | NS_EVENT_STATE_DRAGOVER |   \
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-placeholder/ignore-pseudo-class-ref.html
@@ -0,0 +1,7 @@
+<!DOCTYPE html>
+<html>
+<body>
+  <input placeholder='foobar'>
+  <textarea placeholder='foobar'></textarea>
+</body>
+</html>
new file mode 100644
--- /dev/null
+++ b/layout/reftests/css-placeholder/ignore-pseudo-class.html
@@ -0,0 +1,12 @@
+<!DOCTYPE html>
+<html>
+<style>
+  :-moz-placeholder {
+    color: red;
+  }
+</style>
+<body>
+  <input placeholder='foobar'>
+  <textarea placeholder='foobar'></textarea>
+</body>
+</html>
--- a/layout/reftests/css-placeholder/reftest.list
+++ b/layout/reftests/css-placeholder/reftest.list
@@ -1,6 +1,7 @@
 include input/reftest.list
 include textarea/reftest.list
 
 == css-restrictions.html css-restrictions-ref.html
 == css-simple-styling.html css-simple-styling-ref.html
 != css-background.html css-background-ref.html
+== ignore-pseudo-class.html ignore-pseudo-class-ref.html
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -3485,16 +3485,30 @@ CSSParserImpl::ParsePseudoSelector(int32
   if (!pseudo) {
     NS_RUNTIMEABORT("do_GetAtom failed - out of memory?");
   }
 
   // stash away some info about this pseudo so we only have to get it once.
   bool isTreePseudo = false;
   nsCSSPseudoElements::Type pseudoElementType =
     nsCSSPseudoElements::GetPseudoType(pseudo);
+  nsCSSPseudoClasses::Type pseudoClassType =
+    nsCSSPseudoClasses::GetPseudoType(pseudo);
+
+  // We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
+  // be a bit stricter regarding the pseudo-element parsing rules.
+  if (pseudoElementType == nsCSSPseudoElements::ePseudo_mozPlaceholder &&
+      pseudoClassType == nsCSSPseudoClasses::ePseudoClass_mozPlaceholder) {
+    if (parsingPseudoElement) {
+      pseudoClassType = nsCSSPseudoClasses::ePseudoClass_NotPseudoClass;
+    } else {
+      pseudoElementType = nsCSSPseudoElements::ePseudo_NotPseudoElement;
+    }
+  }
+
 #ifdef MOZ_XUL
   isTreePseudo = (pseudoElementType == nsCSSPseudoElements::ePseudo_XULTree);
   // If a tree pseudo-element is using the function syntax, it will
   // get isTree set here and will pass the check below that only
   // allows functions if they are in our list of things allowed to be
   // functions.  If it is _not_ using the function syntax, isTree will
   // be false, and it will still pass that check.  So the tree
   // pseudo-elements are allowed to be either functions or not, as
@@ -3503,18 +3517,16 @@ CSSParserImpl::ParsePseudoSelector(int32
 #endif
   bool isPseudoElement =
     (pseudoElementType < nsCSSPseudoElements::ePseudo_PseudoElementCount);
   // anonymous boxes are only allowed if they're the tree boxes or we have
   // enabled unsafe rules
   bool isAnonBox = isTreePseudo ||
     (pseudoElementType == nsCSSPseudoElements::ePseudo_AnonBox &&
      mUnsafeRulesEnabled);
-  nsCSSPseudoClasses::Type pseudoClassType =
-    nsCSSPseudoClasses::GetPseudoType(pseudo);
   bool isPseudoClass =
     (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass);
 
   NS_ASSERTION(!isPseudoClass ||
                pseudoElementType == nsCSSPseudoElements::ePseudo_NotPseudoElement,
                "Why is this atom both a pseudo-class and a pseudo-element?");
   NS_ASSERTION(isPseudoClass + isPseudoElement + isAnonBox <= 1,
                "Shouldn't be more than one of these");
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -198,16 +198,19 @@ CSS_STATE_PSEUDO_CLASS(mozUIValid, ":-mo
                        NS_EVENT_STATE_MOZ_UI_VALID)
 CSS_STATE_PSEUDO_CLASS(mozMeterOptimum, ":-moz-meter-optimum", "",
                        NS_EVENT_STATE_OPTIMUM)
 CSS_STATE_PSEUDO_CLASS(mozMeterSubOptimum, ":-moz-meter-sub-optimum", "",
                        NS_EVENT_STATE_SUB_OPTIMUM)
 CSS_STATE_PSEUDO_CLASS(mozMeterSubSubOptimum, ":-moz-meter-sub-sub-optimum", "",
                        NS_EVENT_STATE_SUB_SUB_OPTIMUM)
 
+// Those values should be parsed but do nothing.
+CSS_STATE_PSEUDO_CLASS(mozPlaceholder, ":-moz-placeholder", "", NS_EVENT_STATE_IGNORE)
+
 #ifdef DEFINED_CSS_STATE_PSEUDO_CLASS
 #undef DEFINED_CSS_STATE_PSEUDO_CLASS
 #undef CSS_STATE_PSEUDO_CLASS
 #endif
 
 #ifdef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
 #undef DEFINED_CSS_STATE_DEPENDENT_PSEUDO_CLASS
 #undef CSS_STATE_DEPENDENT_PSEUDO_CLASS
--- a/layout/style/test/test_selectors.html
+++ b/layout/style/test/test_selectors.html
@@ -975,16 +975,19 @@ function run() {
 
     // Test that newline escapes are only supported in strings.
     test_balanced_unparseable("di\\\nv");
     test_balanced_unparseable("div \\\n p");
     test_balanced_unparseable("div\\\n p");
     test_balanced_unparseable("div \\\np");
     test_balanced_unparseable("div\\\np");
 
+    // Test that :-moz-placeholder is parsable.
+    test_parseable(":-moz-placeholder");
+
     run_deferred_tests();
 }
 
 var deferred_tests = [];
 
 function defer_clonedoc_tests(docurl, onloadfunc)
 {
     deferred_tests.push( { docurl: docurl, onloadfunc: onloadfunc } );