Bug 1025267 - Make some -moz- prefixed pseudo-classes chrome-only. r=bz
authorMats Palmgren <mats@mozilla.com>
Fri, 01 Apr 2016 02:08:15 +0200
changeset 291129 cb55f73763cd7838760ab747510d12e7f039f108
parent 291128 cbeaca0a84e90dc8df4e5a30a262744c512f7030
child 291130 5ba4fe816a3980fd20f3e3ffc92f6e714ce91d88
push id19656
push usergwagner@mozilla.com
push dateMon, 04 Apr 2016 13:43:23 +0000
treeherderb2g-inbound@e99061fde28a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersbz
bugs1025267
milestone48.0a1
Bug 1025267 - Make some -moz- prefixed pseudo-classes chrome-only. r=bz
browser/base/content/nsContextMenu.js
layout/style/nsCSSParser.cpp
layout/style/nsCSSPseudoClassList.h
layout/style/nsCSSPseudoClasses.h
layout/style/test/test_selectors.html
--- a/browser/base/content/nsContextMenu.js
+++ b/browser/base/content/nsContextMenu.js
@@ -1,8 +1,9 @@
+/* -*- tab-width: 2; indent-tabs-mode: nil; js-indent-level: 2 -*- */
 /* vim: set ts=2 sw=2 sts=2 et tw=80: */
 # 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/.
 
 Components.utils.import("resource://gre/modules/PrivateBrowsingUtils.jsm");
 Components.utils.import("resource://gre/modules/InlineSpellChecker.jsm");
 Components.utils.import("resource://gre/modules/LoginManagerContextMenu.jsm");
@@ -772,17 +773,18 @@ nsContextMenu.prototype = {
             this.bgImageURL = makeURLAbsolute(bodyElt.baseURI,
                                               computedURL);
           }
         }
       }
       else if ((this.target instanceof HTMLEmbedElement ||
                 this.target instanceof HTMLObjectElement ||
                 this.target instanceof HTMLAppletElement) &&
-               this.target.matches(":-moz-handler-clicktoplay")) {
+               this.target.displayedType == HTMLObjectElement.TYPE_NULL &&
+               this.target.pluginFallbackType == HTMLObjectElement.PLUGIN_CLICK_TO_PLAY) {
         this.onCTPPlugin = true;
       }
 
       this.canSpellCheck = this._isSpellCheckEnabled(this.target);
     }
     else if (this.target.nodeType == Node.TEXT_NODE) {
       // For text nodes, look at the parent node to determine the spellcheck attribute.
       this.canSpellCheck = this.target.parentNode &&
--- a/layout/style/nsCSSParser.cpp
+++ b/layout/style/nsCSSParser.cpp
@@ -342,16 +342,19 @@ public:
                                            nsIPrincipal* aDocPrincipal,
                                            CSSStyleSheet* aSheet,
                                            uint32_t aLineNumber,
                                            uint32_t aLineOffset);
 
   bool AgentRulesEnabled() const {
     return mParsingMode == css::eAgentSheetFeatures;
   }
+  bool ChromeRulesEnabled() const {
+    return mIsChrome;
+  }
   bool UserRulesEnabled() const {
     return mParsingMode == css::eAgentSheetFeatures ||
            mParsingMode == css::eUserSheetFeatures;
   }
 
   nsCSSProps::EnabledState PropertyEnabledState() const {
     static_assert(nsCSSProps::eEnabledForAllContent == 0,
                   "nsCSSProps::eEnabledForAllContent should be zero for "
@@ -5872,17 +5875,20 @@ CSSParserImpl::ParsePseudoSelector(int32
     nsCSSPseudoClasses::GetPseudoType(pseudo);
   bool pseudoClassIsUserAction =
     nsCSSPseudoClasses::IsUserActionPseudoClass(pseudoClassType);
 
   if (!AgentRulesEnabled() &&
       ((pseudoElementType < CSSPseudoElementType::Count &&
         nsCSSPseudoElements::PseudoElementIsUASheetOnly(pseudoElementType)) ||
        (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
-        nsCSSPseudoClasses::PseudoClassIsUASheetOnly(pseudoClassType)))) {
+        nsCSSPseudoClasses::PseudoClassIsUASheetOnly(pseudoClassType)) ||
+       (!ChromeRulesEnabled() &&
+        (pseudoClassType != nsCSSPseudoClasses::ePseudoClass_NotPseudoClass &&
+         nsCSSPseudoClasses::PseudoClassIsUASheetAndChromeOnly(pseudoClassType))))) {
     // This pseudo-element or pseudo-class is not exposed to content.
     REPORT_UNEXPECTED_TOKEN(PEPseudoSelUnknown);
     UngetToken();
     return eSelectorParsingStatus_Error;
   }
 
   // We currently allow :-moz-placeholder and ::-moz-placeholder. We have to
   // be a bit stricter regarding the pseudo-element parsing rules.
--- a/layout/style/nsCSSPseudoClassList.h
+++ b/layout/style/nsCSSPseudoClassList.h
@@ -118,17 +118,18 @@ CSS_PSEUDO_CLASS(mozLWThemeDarkText, ":-
 // Matches anything when the containing window is inactive
 CSS_PSEUDO_CLASS(mozWindowInactive, ":-moz-window-inactive", 0, "")
 
 // Matches any table elements that have a nonzero border attribute,
 // according to HTML integer attribute parsing rules.
 CSS_PSEUDO_CLASS(mozTableBorderNonzero, ":-moz-table-border-nonzero", 0, "")
 
 // Matches HTML frame/iframe elements which are mozbrowser.
-CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz-browser-frame", 0, "")
+CSS_PSEUDO_CLASS(mozBrowserFrame, ":-moz-browser-frame",
+                 CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "")
 
 // Matches whatever the contextual reference elements are for the
 // matching operation.
 CSS_PSEUDO_CLASS(scope, ":scope", 0, "layout.css.scope-pseudo.enabled")
 
 // :not needs to come at the end of the non-bit pseudo-class list, since
 // it doesn't actually get directly matched on in SelectorMatches.
 CSS_PSEUDO_CLASS(notPseudo, ":not", 0, "")
@@ -167,36 +168,47 @@ CSS_STATE_PSEUDO_CLASS(mozFullScreen, ":
 // or an ancestor of a containing frame of the full-screen element.
 CSS_STATE_PSEUDO_CLASS(mozFullScreenAncestor, ":-moz-full-screen-ancestor", 0, "", NS_EVENT_STATE_FULL_SCREEN_ANCESTOR)
 
 // Matches if the element is focused and should show a focus ring
 CSS_STATE_PSEUDO_CLASS(mozFocusRing, ":-moz-focusring", 0, "", NS_EVENT_STATE_FOCUSRING)
 
 // Image, object, etc state pseudo-classes
 CSS_STATE_PSEUDO_CLASS(mozBroken, ":-moz-broken", 0, "", NS_EVENT_STATE_BROKEN)
-CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", 0, "", NS_EVENT_STATE_LOADING)
+
+CSS_STATE_PSEUDO_CLASS(mozUserDisabled, ":-moz-user-disabled",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_USERDISABLED)
-CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozSuppressed, ":-moz-suppressed",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_SUPPRESSED)
-CSS_STATE_PSEUDO_CLASS(mozLoading, ":-moz-loading", 0, "", NS_EVENT_STATE_LOADING)
-CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozTypeUnsupported, ":-moz-type-unsupported",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_TYPE_UNSUPPORTED)
-CSS_STATE_PSEUDO_CLASS(mozTypeUnsupportedPlatform, ":-moz-type-unsupported-platform", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozTypeUnsupportedPlatform, ":-moz-type-unsupported-platform",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_TYPE_UNSUPPORTED_PLATFORM)
-CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerClickToPlay, ":-moz-handler-clicktoplay",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_TYPE_CLICK_TO_PLAY)
-CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableUpdatable, ":-moz-handler-vulnerable-updatable", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableUpdatable, ":-moz-handler-vulnerable-updatable",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_VULNERABLE_UPDATABLE)
-CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableNoUpdate, ":-moz-handler-vulnerable-no-update", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerVulnerableNoUpdate, ":-moz-handler-vulnerable-no-update",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_VULNERABLE_NO_UPDATE)
-CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerDisabled, ":-moz-handler-disabled",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_HANDLER_DISABLED)
-CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerBlocked, ":-moz-handler-blocked",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_HANDLER_BLOCKED)
-CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed", 0, "",
+CSS_STATE_PSEUDO_CLASS(mozHandlerCrashed, ":-moz-handler-crashed",
+                       CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME, "",
                        NS_EVENT_STATE_HANDLER_CRASHED)
 
 CSS_STATE_PSEUDO_CLASS(mozMathIncrementScriptLevel,
                        ":-moz-math-increment-script-level", 0, "",
                        NS_EVENT_STATE_INCREMENT_SCRIPT_LEVEL)
 
 // CSS 3 UI
 // http://www.w3.org/TR/2004/CR-css3-ui-20040511/#pseudo-classes
--- a/layout/style/nsCSSPseudoClasses.h
+++ b/layout/style/nsCSSPseudoClasses.h
@@ -5,18 +5,20 @@
 
 /* atom list for CSS pseudo-classes */
 
 #ifndef nsCSSPseudoClasses_h___
 #define nsCSSPseudoClasses_h___
 
 #include "nsStringFwd.h"
 
-// This pseudo-element is accepted only in UA style sheets.
+// This pseudo-class is accepted only in UA style sheets.
 #define CSS_PSEUDO_CLASS_UA_SHEET_ONLY                 (1<<0)
+// This pseudo-class is accepted only in UA style sheets and chrome.
+#define CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME           (1<<1)
 
 class nsIAtom;
 
 class nsCSSPseudoClasses {
 public:
 
   static void AddRefAtoms();
 
@@ -36,16 +38,19 @@ public:
   static bool HasSelectorListArg(Type aType) {
     return aType == ePseudoClass_any;
   }
   static bool IsUserActionPseudoClass(Type aType);
 
   static bool PseudoClassIsUASheetOnly(Type aType) {
     return PseudoClassHasFlags(aType, CSS_PSEUDO_CLASS_UA_SHEET_ONLY);
   }
+  static bool PseudoClassIsUASheetAndChromeOnly(Type aType) {
+    return PseudoClassHasFlags(aType, CSS_PSEUDO_CLASS_UA_SHEET_AND_CHROME);
+  }
 
   // Should only be used on types other than Count and NotPseudoClass
   static void PseudoTypeToString(Type aType, nsAString& aString);
 
 private:
   static uint32_t FlagsForPseudoClass(const Type aType);
 
   // Does the given pseudo-class have all of the flags given?
--- a/layout/style/test/test_selectors.html
+++ b/layout/style/test/test_selectors.html
@@ -1024,21 +1024,31 @@ function run() {
     test_parseable("::-moz-tree-twisty(  hover open  )");
     test_balanced_unparseable("::-moz-tree-row(selected {[]} )");
     test_balanced_unparseable(":-moz-tree-twisty(open())");
     test_balanced_unparseable("::-moz-tree-twisty(hover ())");
 
     test_parseable(":-moz-window-inactive");
     test_parseable("div p:-moz-window-inactive:hover span");
 
-    // Plugin pseudoclasses
-    test_parseable(":-moz-type-unsupported");
-    test_parseable(":-moz-handler-disabled");
-    test_parseable(":-moz-handler-blocked");
-    test_parseable(":-moz-handler-crashed");
+    // Chrome-only
+    test_unbalanced_unparseable(":-moz-browser-frame");
+
+    // Plugin pseudoclasses are chrome-only:
+    test_unbalanced_unparseable(":-moz-type-unsupported");
+    test_unbalanced_unparseable(":-moz-user-disabled");
+    test_unbalanced_unparseable(":-moz-suppressed");
+    test_unbalanced_unparseable(":-moz-type-unsupported");
+    test_unbalanced_unparseable(":-moz-type-unsupported-platform");
+    test_unbalanced_unparseable(":-moz-handler-clicktoplay");
+    test_unbalanced_unparseable(":-moz-handler-vulnerable-updatable");
+    test_unbalanced_unparseable(":-moz-handler-vulnerable-no-update");
+    test_unbalanced_unparseable(":-moz-handler-disabled");
+    test_unbalanced_unparseable(":-moz-handler-blocked");
+    test_unbalanced_unparseable(":-moz-handler-crashed");
 
     // We're not in a UA sheet, so this should be invalid.
     test_balanced_unparseable(":-moz-native-anonymous");
 
     // Case sensitivity of tag selectors
     function setup_cased_spans(body) {
       var data = [
         { tag: "span" },