Commit 02658864 authored by Emilio Cobos Álvarez's avatar Emilio Cobos Álvarez Committed by Chromium LUCI CQ

[css-pseudo] Implement the file-selector-button pseudo.

I2S: https://groups.google.com/a/chromium.org/g/blink-dev/c/d4UdwpPDXJM/m/J-o_C_kqAwAJ

Fixed: 1086855
Change-Id: Ib37d2d8bf4a983ce93445ca0efdf765d3f98935f
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2584810
Commit-Queue: Emilio Cobos Álvarez <emilio@chromium.org>
Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Auto-Submit: Emilio Cobos Álvarez <emilio@chromium.org>
Cr-Commit-Position: refs/heads/master@{#837061}
parent f12990b8
...@@ -281,6 +281,7 @@ PseudoId CSSSelector::GetPseudoId(PseudoType type) { ...@@ -281,6 +281,7 @@ PseudoId CSSSelector::GetPseudoId(PseudoType type) {
case kPseudoOptional: case kPseudoOptional:
case kPseudoPlaceholder: case kPseudoPlaceholder:
case kPseudoPlaceholderShown: case kPseudoPlaceholderShown:
case kPseudoFileSelectorButton:
case kPseudoRequired: case kPseudoRequired:
case kPseudoReadOnly: case kPseudoReadOnly:
case kPseudoReadWrite: case kPseudoReadWrite:
...@@ -403,6 +404,7 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = { ...@@ -403,6 +404,7 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
{"empty", CSSSelector::kPseudoEmpty}, {"empty", CSSSelector::kPseudoEmpty},
{"enabled", CSSSelector::kPseudoEnabled}, {"enabled", CSSSelector::kPseudoEnabled},
{"end", CSSSelector::kPseudoEnd}, {"end", CSSSelector::kPseudoEnd},
{"file-selector-button", CSSSelector::kPseudoFileSelectorButton},
{"first", CSSSelector::kPseudoFirstPage}, {"first", CSSSelector::kPseudoFirstPage},
{"first-child", CSSSelector::kPseudoFirstChild}, {"first-child", CSSSelector::kPseudoFirstChild},
{"first-letter", CSSSelector::kPseudoFirstLetter}, {"first-letter", CSSSelector::kPseudoFirstLetter},
...@@ -622,6 +624,7 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value, ...@@ -622,6 +624,7 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value,
case kPseudoMarker: case kPseudoMarker:
case kPseudoPart: case kPseudoPart:
case kPseudoPlaceholder: case kPseudoPlaceholder:
case kPseudoFileSelectorButton:
case kPseudoResizer: case kPseudoResizer:
case kPseudoScrollbar: case kPseudoScrollbar:
case kPseudoScrollbarCorner: case kPseudoScrollbarCorner:
...@@ -1118,7 +1121,8 @@ bool CSSSelector::IsTreeAbidingPseudoElement() const { ...@@ -1118,7 +1121,8 @@ bool CSSSelector::IsTreeAbidingPseudoElement() const {
return Match() == CSSSelector::kPseudoElement && return Match() == CSSSelector::kPseudoElement &&
(GetPseudoType() == kPseudoBefore || GetPseudoType() == kPseudoAfter || (GetPseudoType() == kPseudoBefore || GetPseudoType() == kPseudoAfter ||
GetPseudoType() == kPseudoMarker || GetPseudoType() == kPseudoMarker ||
GetPseudoType() == kPseudoPlaceholder); GetPseudoType() == kPseudoPlaceholder ||
GetPseudoType() == kPseudoFileSelectorButton);
} }
bool CSSSelector::IsAllowedAfterPart() const { bool CSSSelector::IsAllowedAfterPart() const {
...@@ -1131,6 +1135,7 @@ bool CSSSelector::IsAllowedAfterPart() const { ...@@ -1131,6 +1135,7 @@ bool CSSSelector::IsAllowedAfterPart() const {
case kPseudoBefore: case kPseudoBefore:
case kPseudoAfter: case kPseudoAfter:
case kPseudoPlaceholder: case kPseudoPlaceholder:
case kPseudoFileSelectorButton:
case kPseudoFirstLine: case kPseudoFirstLine:
case kPseudoFirstLetter: case kPseudoFirstLetter:
case kPseudoSelection: case kPseudoSelection:
......
...@@ -214,6 +214,7 @@ class CORE_EXPORT CSSSelector { ...@@ -214,6 +214,7 @@ class CORE_EXPORT CSSSelector {
kPseudoLang, kPseudoLang,
kPseudoNot, kPseudoNot,
kPseudoPlaceholder, kPseudoPlaceholder,
kPseudoFileSelectorButton,
kPseudoResizer, kPseudoResizer,
kPseudoRoot, kPseudoRoot,
kPseudoScope, kPseudoScope,
......
...@@ -96,6 +96,7 @@ RelationType CSSParserSelector::GetImplicitShadowCombinatorForMatching() const { ...@@ -96,6 +96,7 @@ RelationType CSSParserSelector::GetImplicitShadowCombinatorForMatching() const {
case PseudoType::kPseudoBlinkInternalElement: case PseudoType::kPseudoBlinkInternalElement:
case PseudoType::kPseudoCue: case PseudoType::kPseudoCue:
case PseudoType::kPseudoPlaceholder: case PseudoType::kPseudoPlaceholder:
case PseudoType::kPseudoFileSelectorButton:
case PseudoType::kPseudoShadow: case PseudoType::kPseudoShadow:
return RelationType::kShadowPseudo; return RelationType::kShadowPseudo;
case PseudoType::kPseudoPart: case PseudoType::kPseudoPart:
......
...@@ -452,8 +452,11 @@ static void MatchElementScopeRules(const Element& element, ...@@ -452,8 +452,11 @@ static void MatchElementScopeRules(const Element& element,
void StyleResolver::MatchPseudoPartRulesForUAHost( void StyleResolver::MatchPseudoPartRulesForUAHost(
const Element& element, const Element& element,
ElementRuleCollector& collector) { ElementRuleCollector& collector) {
if (element.ShadowPseudoId() != shadow_element_names::kPseudoInputPlaceholder) const AtomicString& pseudo_id = element.ShadowPseudoId();
if (pseudo_id != shadow_element_names::kPseudoInputPlaceholder &&
pseudo_id != shadow_element_names::kPseudoFileUploadButton) {
return; return;
}
// We allow ::placeholder pseudo element after ::part(). See // We allow ::placeholder pseudo element after ::part(). See
// MatchSlottedRulesForUAHost for a more detailed explanation. // MatchSlottedRulesForUAHost for a more detailed explanation.
......
...@@ -131,6 +131,7 @@ bool SupportsInvalidation(CSSSelector::PseudoType type) { ...@@ -131,6 +131,7 @@ bool SupportsInvalidation(CSSSelector::PseudoType type) {
case CSSSelector::kPseudoDir: case CSSSelector::kPseudoDir:
case CSSSelector::kPseudoNot: case CSSSelector::kPseudoNot:
case CSSSelector::kPseudoPlaceholder: case CSSSelector::kPseudoPlaceholder:
case CSSSelector::kPseudoFileSelectorButton:
case CSSSelector::kPseudoResizer: case CSSSelector::kPseudoResizer:
case CSSSelector::kPseudoRoot: case CSSSelector::kPseudoRoot:
case CSSSelector::kPseudoScope: case CSSSelector::kPseudoScope:
......
...@@ -172,6 +172,7 @@ static void ExtractSelectorValues(const CSSSelector* selector, ...@@ -172,6 +172,7 @@ static void ExtractSelectorValues(const CSSSelector* selector,
case CSSSelector::kPseudoAnyLink: case CSSSelector::kPseudoAnyLink:
case CSSSelector::kPseudoFocus: case CSSSelector::kPseudoFocus:
case CSSSelector::kPseudoPlaceholder: case CSSSelector::kPseudoPlaceholder:
case CSSSelector::kPseudoFileSelectorButton:
case CSSSelector::kPseudoHost: case CSSSelector::kPseudoHost:
case CSSSelector::kPseudoHostContext: case CSSSelector::kPseudoHostContext:
case CSSSelector::kPseudoSpatialNavigationInterest: case CSSSelector::kPseudoSpatialNavigationInterest:
...@@ -262,11 +263,14 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component, ...@@ -262,11 +263,14 @@ bool RuleSet::FindBestRuleSetAndAdd(const CSSSelector& component,
focus_pseudo_class_rules_.push_back(rule_data); focus_pseudo_class_rules_.push_back(rule_data);
return true; return true;
case CSSSelector::kPseudoPlaceholder: case CSSSelector::kPseudoPlaceholder:
case CSSSelector::kPseudoFileSelectorButton:
if (it->FollowsPart()) { if (it->FollowsPart()) {
part_pseudo_rules_.push_back(rule_data); part_pseudo_rules_.push_back(rule_data);
} else { } else {
AddToRuleSet(shadow_element_names::kPseudoInputPlaceholder, const auto& name = pseudo_type == CSSSelector::kPseudoFileSelectorButton
EnsurePendingRules()->shadow_pseudo_element_rules, ? shadow_element_names::kPseudoFileUploadButton
: shadow_element_names::kPseudoInputPlaceholder;
AddToRuleSet(name, EnsurePendingRules()->shadow_pseudo_element_rules,
rule_data); rule_data);
} }
return true; return true;
......
...@@ -1206,6 +1206,11 @@ bool SelectorChecker::CheckPseudoClass(const SelectorCheckingContext& context, ...@@ -1206,6 +1206,11 @@ bool SelectorChecker::CheckPseudoClass(const SelectorCheckingContext& context,
return false; return false;
} }
static bool MatchesUAShadowElement(Element& element, const AtomicString& id) {
ShadowRoot* root = element.ContainingShadowRoot();
return root && root->IsUserAgent() && element.ShadowPseudoId() == id;
}
bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context, bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context,
MatchResult& result) const { MatchResult& result) const {
const CSSSelector& selector = *context.selector; const CSSSelector& selector = *context.selector;
...@@ -1234,29 +1239,17 @@ bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context, ...@@ -1234,29 +1239,17 @@ bool SelectorChecker::CheckPseudoElement(const SelectorCheckingContext& context,
return false; return false;
} }
return true; return true;
case CSSSelector::kPseudoFileSelectorButton:
return MatchesUAShadowElement(
element, shadow_element_names::kPseudoFileUploadButton);
case CSSSelector::kPseudoPlaceholder: case CSSSelector::kPseudoPlaceholder:
if (ShadowRoot* root = element.ContainingShadowRoot()) { return MatchesUAShadowElement(
return root->IsUserAgent() && element, shadow_element_names::kPseudoInputPlaceholder);
element.ShadowPseudoId() == case CSSSelector::kPseudoWebKitCustomElement:
shadow_element_names::kPseudoInputPlaceholder; return MatchesUAShadowElement(element, selector.Value());
}
return false;
case CSSSelector::kPseudoWebKitCustomElement: {
if (ShadowRoot* root = element.ContainingShadowRoot()) {
if (!root->IsUserAgent())
return false;
if (element.ShadowPseudoId() != selector.Value())
return false;
return true;
}
return false;
}
case CSSSelector::kPseudoBlinkInternalElement: case CSSSelector::kPseudoBlinkInternalElement:
DCHECK(is_ua_rule_); DCHECK(is_ua_rule_);
if (ShadowRoot* root = element.ContainingShadowRoot()) return MatchesUAShadowElement(element, selector.Value());
return root->IsUserAgent() &&
element.ShadowPseudoId() == selector.Value();
return false;
case CSSSelector::kPseudoSlotted: { case CSSSelector::kPseudoSlotted: {
SelectorCheckingContext sub_context(context); SelectorCheckingContext sub_context(context);
sub_context.is_sub_selector = true; sub_context.is_sub_selector = true;
......
...@@ -89,6 +89,10 @@ ...@@ -89,6 +89,10 @@
name: "-webkit-input-placeholder", name: "-webkit-input-placeholder",
Symbol: "kPseudoInputPlaceholder", Symbol: "kPseudoInputPlaceholder",
}, },
{
name: "-webkit-file-upload-button",
Symbol: "kPseudoFileUploadButton",
},
{ {
name: "-internal-input-suggested", name: "-internal-input-suggested",
Symbol: "kPseudoInternalInputSuggested", Symbol: "kPseudoInternalInputSuggested",
......
...@@ -317,6 +317,7 @@ const char* PseudoTypeToString(CSSSelector::PseudoType pseudo_type) { ...@@ -317,6 +317,7 @@ const char* PseudoTypeToString(CSSSelector::PseudoType pseudo_type) {
DEFINE_STRING_MAPPING(PseudoLang) DEFINE_STRING_MAPPING(PseudoLang)
DEFINE_STRING_MAPPING(PseudoNot) DEFINE_STRING_MAPPING(PseudoNot)
DEFINE_STRING_MAPPING(PseudoPlaceholder) DEFINE_STRING_MAPPING(PseudoPlaceholder)
DEFINE_STRING_MAPPING(PseudoFileSelectorButton)
DEFINE_STRING_MAPPING(PseudoResizer) DEFINE_STRING_MAPPING(PseudoResizer)
DEFINE_STRING_MAPPING(PseudoRoot) DEFINE_STRING_MAPPING(PseudoRoot)
DEFINE_STRING_MAPPING(PseudoScope) DEFINE_STRING_MAPPING(PseudoScope)
......
...@@ -2394,7 +2394,6 @@ crbug.com/1074547 external/wpt/css/css-transitions/transitioncancel-002.html [ T ...@@ -2394,7 +2394,6 @@ crbug.com/1074547 external/wpt/css/css-transitions/transitioncancel-002.html [ T
crbug.com/1078474 external/wpt/css/css-pseudo/cascade-highlight-001.html [ Failure ] crbug.com/1078474 external/wpt/css/css-pseudo/cascade-highlight-001.html [ Failure ]
crbug.com/1078474 external/wpt/css/css-pseudo/cascade-highlight-002.html [ Failure ] crbug.com/1078474 external/wpt/css/css-pseudo/cascade-highlight-002.html [ Failure ]
crbug.com/1024156 external/wpt/css/css-pseudo/cascade-highlight-004.html [ Failure ] crbug.com/1024156 external/wpt/css/css-pseudo/cascade-highlight-004.html [ Failure ]
crbug.com/1086855 external/wpt/css/css-pseudo/file-selector-button-001.html [ Failure ]
crbug.com/1113004 external/wpt/css/css-pseudo/active-selection-043.html [ Failure ] crbug.com/1113004 external/wpt/css/css-pseudo/active-selection-043.html [ Failure ]
crbug.com/1100119 [ Mac ] external/wpt/css/css-pseudo/active-selection-051.html [ Failure ] crbug.com/1100119 [ Mac ] external/wpt/css/css-pseudo/active-selection-051.html [ Failure ]
crbug.com/1100119 [ Mac ] external/wpt/css/css-pseudo/active-selection-052.html [ Failure ] crbug.com/1100119 [ Mac ] external/wpt/css/css-pseudo/active-selection-052.html [ Failure ]
......
<!doctype html>
<title>::file-selector-button allows to customize the button in &lt;input type=file&gt;</title>
<link rel="help" href="https://github.com/w3c/csswg-drafts/issues/5049">
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#file-selector-button-pseudo">
<link rel="mismatch" href="file-selector-button-001-notref.html">
<style>
#host::part(file-input)::file-selector-button {
border: 1px solid green;
}
</style>
<div id="host"></div>
<script>
document.getElementById("host").attachShadow({ mode: "open" }).innerHTML = `
<input type=file part=file-input>
`;
</script>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment