Styling option should not override option:checked UA style

This adds !important to option:checked styles, so that styling option won't override the selected appearance.
This adds -internal-listbox which applies to listbox mode select elements.
We need it because we can't remove the !important styles for select[size=0], select[size=1]

BUG=398417

Review URL: https://codereview.chromium.org/450623002

git-svn-id: svn://svn.chromium.org/blink/trunk@179782 bbb929c8-8fbe-4397-9dbb-9b2b20218538
diff --git a/Source/core/css/CSSSelector.cpp b/Source/core/css/CSSSelector.cpp
index b8295a0..2dceb9c 100644
--- a/Source/core/css/CSSSelector.cpp
+++ b/Source/core/css/CSSSelector.cpp
@@ -258,6 +258,7 @@
     case PseudoFullScreenDocument:
     case PseudoFullScreenAncestor:
     case PseudoSpatialNavigationFocus:
+    case PseudoListBox:
         return NOPSEUDO;
     case PseudoNotParsed:
         ASSERT_NOT_REACHED();
@@ -278,6 +279,7 @@
 
 // This table should be kept sorted.
 const static NameToPseudoStruct pseudoTypeMap[] = {
+{"-internal-list-box",            CSSSelector::PseudoListBox},
 {"-internal-spatial-navigation-focus", CSSSelector::PseudoSpatialNavigationFocus},
 {"-webkit-any(",                  CSSSelector::PseudoAny},
 {"-webkit-any-link",              CSSSelector::PseudoAnyLink},
@@ -532,6 +534,7 @@
     case PseudoHostContext:
     case PseudoUnresolved:
     case PseudoSpatialNavigationFocus:
+    case PseudoListBox:
         break;
     case PseudoFirstPage:
     case PseudoLeftPage:
@@ -784,6 +787,7 @@
     case CSSSelector::PseudoHostContext:
     case CSSSelector::PseudoNot:
     case CSSSelector::PseudoSpatialNavigationFocus:
+    case CSSSelector::PseudoListBox:
         return true;
     default:
         return false;
diff --git a/Source/core/css/CSSSelector.h b/Source/core/css/CSSSelector.h
index cb95158..0a2ec6e 100644
--- a/Source/core/css/CSSSelector.h
+++ b/Source/core/css/CSSSelector.h
@@ -217,7 +217,8 @@
             PseudoHost,
             PseudoHostContext,
             PseudoShadow,
-            PseudoSpatialNavigationFocus
+            PseudoSpatialNavigationFocus,
+            PseudoListBox
         };
 
         enum MarginBoxType {
diff --git a/Source/core/css/RuleFeature.cpp b/Source/core/css/RuleFeature.cpp
index 51f4966..8b1d9b8 100644
--- a/Source/core/css/RuleFeature.cpp
+++ b/Source/core/css/RuleFeature.cpp
@@ -98,6 +98,7 @@
     case CSSSelector::PseudoInRange:
     case CSSSelector::PseudoOutOfRange:
     case CSSSelector::PseudoUnresolved:
+    case CSSSelector::PseudoListBox:
         return true;
     default:
         return false;
diff --git a/Source/core/css/SelectorChecker.cpp b/Source/core/css/SelectorChecker.cpp
index 6fefb1d..d95fca3 100644
--- a/Source/core/css/SelectorChecker.cpp
+++ b/Source/core/css/SelectorChecker.cpp
@@ -45,6 +45,7 @@
 #include "core/html/HTMLFrameElementBase.h"
 #include "core/html/HTMLInputElement.h"
 #include "core/html/HTMLOptionElement.h"
+#include "core/html/HTMLSelectElement.h"
 #include "core/html/parser/HTMLParserIdioms.h"
 #include "core/html/track/vtt/VTTElement.h"
 #include "core/inspector/InspectorInstrumentation.h"
@@ -952,6 +953,8 @@
             break;
         case CSSSelector::PseudoSpatialNavigationFocus:
             return context.isUARule && matchesSpatialNavigationFocusPseudoClass(element);
+        case CSSSelector::PseudoListBox:
+            return context.isUARule && matchesListBoxPseudoClass(element);
 
         case CSSSelector::PseudoHorizontal:
         case CSSSelector::PseudoVertical:
@@ -1129,6 +1132,11 @@
     return isHTMLOptionElement(element) && toHTMLOptionElement(element).spatialNavigationFocused() && isFrameFocused(element);
 }
 
+bool SelectorChecker::matchesListBoxPseudoClass(const Element& element)
+{
+    return isHTMLSelectElement(element) && !toHTMLSelectElement(element).usesMenuList();
+}
+
 template
 SelectorChecker::Match SelectorChecker::match(const SelectorCheckingContext&, const DOMSiblingTraversalStrategy&, MatchResult*) const;
 
diff --git a/Source/core/css/SelectorChecker.h b/Source/core/css/SelectorChecker.h
index 4d1b27e..d192d48 100644
--- a/Source/core/css/SelectorChecker.h
+++ b/Source/core/css/SelectorChecker.h
@@ -115,6 +115,7 @@
     static bool isCommonPseudoClassSelector(const CSSSelector&);
     static bool matchesFocusPseudoClass(const Element&);
     static bool matchesSpatialNavigationFocusPseudoClass(const Element&);
+    static bool matchesListBoxPseudoClass(const Element&);
     static bool checkExactAttribute(const Element&, const QualifiedName& selectorAttributeName, const StringImpl* value);
 
     enum LinkMatchMask { MatchLink = 1, MatchVisited = 2, MatchAll = MatchLink | MatchVisited };
diff --git a/Source/core/css/html.css b/Source/core/css/html.css
index b1ad9ac..91f074a 100644
--- a/Source/core/css/html.css
+++ b/Source/core/css/html.css
@@ -757,9 +757,7 @@
     cursor: default;
 }
 
-select[size],
-select[multiple],
-select[size][multiple] {
+select:-internal-list-box {
     -webkit-appearance: listbox;
     align-items: flex-start;
     border: 1px inset gray;
@@ -771,21 +769,6 @@
     white-space: nowrap;
 }
 
-select[size="0"],
-select[size="1"] {
-    -webkit-appearance: menulist;
-    align-items: center;
-    border-width: 1px;
-    border-style: solid;
-    border-color: initial;
-    border-radius: 5px;
-    overflow-x: initial;
-    overflow-y: initial;
-    vertical-align: initial;
-    -webkit-user-select: initial;
-    white-space: pre;
-}
-
 optgroup {
     font-weight: bolder;
     display: block;
@@ -799,38 +782,21 @@
     min-height: 1.2em;
 }
 
-select:focus[size] option:checked,
-select:focus[multiple] option:checked,
-select:focus[size][multiple] option:checked {
-    background-color: -internal-active-list-box-selection;
-    color: -internal-active-list-box-selection-text;
+select:-internal-list-box:focus option:checked {
+    background-color: -internal-active-list-box-selection !important;
+    color: -internal-active-list-box-selection-text !important;
 }
 
-select[size] option:checked,
-select[multiple] option:checked,
-select[size][multiple] option:checked {
-    background-color: -internal-inactive-list-box-selection;
-    color: -internal-inactive-list-box-selection-text;
+select:-internal-list-box option:checked {
+    background-color: -internal-inactive-list-box-selection !important;
+    color: -internal-inactive-list-box-selection-text !important;
 }
 
-select[size="0"] option:checked,
-select[size="1"] option:checked,
-select:focus[size="0"] option:checked,
-select:focus[size="1"] option:checked {
-    background-color: initial;
-    color: initial;
+select:-internal-list-box:disabled option:checked,
+select:-internal-list-box option:checked:disabled {
+    color: gray !important;
 }
 
-select:disabled option:checked,
-select:disabled[size] option:checked,
-select:disabled[multiple] option:checked,
-select:disabled[size][multiple] option:checked,
-option:checked:disabled,
-select[size] option:checked:disabled,
-select[multiple] option:checked:disabled,
-select[size][multiple] option:checked:disabled {
-    color: gray;
-}
 
 output {
     display: inline;