Commit f9a46fa7 authored by Delan Azabani's avatar Delan Azabani Committed by Chromium LUCI CQ

Implement style support for ::spelling-error + ::grammar-error

This implements the style support only, behind a flag, based on the
::target-text counterpart in <https://crrev.com/c/2463563>.

The paint code for querying these selectors and paint invalidation,
as well as the changes needed to limit the acceptable properties (à
la <https://crrev.com/c/2489657>), will be written in another CL.

Bug: 1035708
Change-Id: I77e530fbbb78fb20c05325ef75babde91e5ef831
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2606878
Auto-Submit: Delan Azabani <dazabani@igalia.com>
Reviewed-by: default avatarAndrey Kosyakov <caseq@chromium.org>
Reviewed-by: default avatarRune Lillesveen <futhark@chromium.org>
Reviewed-by: default avatarManuel Rego <rego@igalia.com>
Commit-Queue: Delan Azabani <dazabani@igalia.com>
Cr-Commit-Position: refs/heads/master@{#841443}
parent cd7b7fd2
......@@ -1815,6 +1815,8 @@ domain DOM
backdrop
selection
target-text
spelling-error
grammar-error
first-line-inherited
scrollbar
scrollbar-thumb
......
......@@ -245,6 +245,10 @@ PseudoId CSSSelector::GetPseudoId(PseudoType type) {
return kPseudoIdResizer;
case kPseudoTargetText:
return kPseudoIdTargetText;
case kPseudoSpellingError:
return kPseudoIdSpellingError;
case kPseudoGrammarError:
return kPseudoIdGrammarError;
case kPseudoUnknown:
case kPseudoEmpty:
case kPseudoFirstChild:
......@@ -411,6 +415,7 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
{"focus-within", CSSSelector::kPseudoFocusWithin},
{"fullscreen", CSSSelector::kPseudoFullscreen},
{"future", CSSSelector::kPseudoFutureCue},
{"grammar-error", CSSSelector::kPseudoGrammarError},
{"horizontal", CSSSelector::kPseudoHorizontal},
{"host", CSSSelector::kPseudoHost},
{"hover", CSSSelector::kPseudoHover},
......@@ -440,6 +445,7 @@ const static NameToPseudoStruct kPseudoTypeWithoutArgumentsMap[] = {
{"scope", CSSSelector::kPseudoScope},
{"selection", CSSSelector::kPseudoSelection},
{"single-button", CSSSelector::kPseudoSingleButton},
{"spelling-error", CSSSelector::kPseudoSpellingError},
{"start", CSSSelector::kPseudoStart},
{"target", CSSSelector::kPseudoTarget},
{"target-text", CSSSelector::kPseudoTargetText},
......@@ -521,6 +527,12 @@ static CSSSelector::PseudoType NameToPseudoType(const AtomicString& name,
return CSSSelector::kPseudoUnknown;
}
if ((match->type == CSSSelector::kPseudoSpellingError ||
match->type == CSSSelector::kPseudoGrammarError) &&
!RuntimeEnabledFeatures::CSSSpellingGrammarErrorsEnabled()) {
return CSSSelector::kPseudoUnknown;
}
return static_cast<CSSSelector::PseudoType>(match->type);
}
......@@ -630,6 +642,8 @@ void CSSSelector::UpdatePseudoType(const AtomicString& value,
case kPseudoWebKitCustomElement:
case kPseudoSlotted:
case kPseudoTargetText:
case kPseudoSpellingError:
case kPseudoGrammarError:
if (match_ != kPseudoElement)
pseudo_type_ = kPseudoUnknown;
break;
......@@ -1121,6 +1135,8 @@ bool CSSSelector::IsAllowedAfterPart() const {
case kPseudoFirstLetter:
case kPseudoSelection:
case kPseudoTargetText:
case kPseudoSpellingError:
case kPseudoGrammarError:
return true;
default:
return false;
......
......@@ -285,6 +285,8 @@ class CORE_EXPORT CSSSelector {
kPseudoVideoPersistentAncestor,
kPseudoTargetText,
kPseudoDir,
kPseudoSpellingError,
kPseudoGrammarError,
};
enum class AttributeMatchType {
......
......@@ -180,6 +180,8 @@ bool SupportsInvalidation(CSSSelector::PseudoType type) {
case CSSSelector::kPseudoIs:
case CSSSelector::kPseudoWhere:
case CSSSelector::kPseudoTargetText:
case CSSSelector::kPseudoSpellingError:
case CSSSelector::kPseudoGrammarError:
return true;
case CSSSelector::kPseudoUnknown:
case CSSSelector::kPseudoLeftPage:
......
......@@ -180,6 +180,10 @@ protocol::DOM::PseudoType InspectorDOMAgent::ProtocolPseudoElementType(
return protocol::DOM::PseudoTypeEnum::Selection;
case kPseudoIdTargetText:
return protocol::DOM::PseudoTypeEnum::TargetText;
case kPseudoIdSpellingError:
return protocol::DOM::PseudoTypeEnum::SpellingError;
case kPseudoIdGrammarError:
return protocol::DOM::PseudoTypeEnum::GrammarError;
case kPseudoIdFirstLineInherited:
return protocol::DOM::PseudoTypeEnum::FirstLineInherited;
case kPseudoIdScrollbar:
......
......@@ -369,6 +369,8 @@ const char* PseudoTypeToString(CSSSelector::PseudoType pseudo_type) {
DEFINE_STRING_MAPPING(PseudoXrOverlay)
DEFINE_STRING_MAPPING(PseudoTargetText)
DEFINE_STRING_MAPPING(PseudoModal)
DEFINE_STRING_MAPPING(PseudoSpellingError)
DEFINE_STRING_MAPPING(PseudoGrammarError)
#undef DEFINE_STRING_MAPPING
}
......
......@@ -65,6 +65,8 @@ enum PseudoId : uint8_t {
kPseudoIdSelection,
kPseudoIdScrollbar,
kPseudoIdTargetText,
kPseudoIdSpellingError,
kPseudoIdGrammarError,
// Internal IDs follow:
kPseudoIdFirstLineInherited,
kPseudoIdScrollbarThumb,
......
......@@ -228,7 +228,7 @@
{
name: "PseudoBits",
field_template: "primitive",
field_size: 9,
field_size: 11,
default_value: "kPseudoIdNone",
type_name: "unsigned",
custom_copy: true,
......
......@@ -155,12 +155,12 @@ TEST(ComputedStyleTest, FirstPublicPseudoStyle) {
}
TEST(ComputedStyleTest, LastPublicPseudoElementStyle) {
static_assert(kFirstInternalPseudoId - 1 == kPseudoIdTargetText,
static_assert(kFirstInternalPseudoId - 1 == kPseudoIdGrammarError,
"Make sure we are testing the last public pseudo id");
scoped_refptr<ComputedStyle> style = ComputedStyle::Create();
style->SetHasPseudoElementStyle(kPseudoIdTargetText);
EXPECT_TRUE(style->HasPseudoElementStyle(kPseudoIdTargetText));
style->SetHasPseudoElementStyle(kPseudoIdGrammarError);
EXPECT_TRUE(style->HasPseudoElementStyle(kPseudoIdGrammarError));
EXPECT_TRUE(style->HasAnyPseudoElementStyles());
}
......
......@@ -614,6 +614,17 @@
name: "CSSSnapSize",
status: "experimental",
},
{
// Support for CSS ::spelling-error, ::grammar-error, and the
// spelling-error and grammar-error values in text-decoration-line.
//
// https://drafts.csswg.org/css-pseudo-4/#selectordef-spelling-error
// https://drafts.csswg.org/css-pseudo-4/#selectordef-grammar-error
// https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-spelling-error
// https://drafts.csswg.org/css-text-decor-4/#valdef-text-decoration-line-grammar-error
name: "CSSSpellingGrammarErrors",
status: "test",
},
// Make system color keywords compute to themselves.
// https://github.com/w3c/csswg-drafts/issues/3847
{
......
<!doctype html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: highlight selectors getComputedStyle</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-selectors">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#target::selection,
#target::target-text,
#target::spelling-error,
#target::grammar-error {
background-color: green;
color: lime;
}
</style>
<div id="target"></div>
<script>
for (const pseudo of ["::selection", "::target-text", "::spelling-error", "::grammar-error"]) {
test(() => {
let style = getComputedStyle(target, pseudo);
assert_equals(style.backgroundColor, "rgb(0, 128, 0)", "Background color is green.");
assert_equals(style.color, "rgb(0, 255, 0)", "Color is lime.");
}, `getComputedStyle() for ${pseudo}`);
}
</script>
<!doctype html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: highlight selectors parsing</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#highlight-selectors">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
for (const pseudo of ["::selection", "::target-text", "::spelling-error", "::grammar-error"]) {
test_valid_selector(`${pseudo}`);
test_valid_selector(`.a${pseudo}`);
test_valid_selector(`div ${pseudo}`);
test_valid_selector(`::part(my-part)${pseudo}`);
test_invalid_selector(`::before${pseudo}`);
test_invalid_selector(`${pseudo}.a`);
test_invalid_selector(`${pseudo} div`);
test_invalid_selector(`${pseudo}::after`);
test_invalid_selector(`${pseudo}:hover`);
test_invalid_selector(`:not(${pseudo})`);
}
</script>
<!doctype html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: ::target-text parsing</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#selectordef-target-text">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/css/support/parsing-testcommon.js"></script>
<script>
test_valid_selector("::target-text");
test_valid_selector(".a::target-text");
test_valid_selector("div ::target-text");
test_valid_selector("::part(my-part)::target-text");
test_invalid_selector("::before::target-text");
test_invalid_selector("::target-text.a");
test_invalid_selector("::target-text div");
test_invalid_selector("::target-text::after");
test_invalid_selector("::target-text:hover");
test_invalid_selector(":not(::target-text)");
</script>
<!doctype html>
<meta charset="utf-8">
<title>CSS Pseudo-Elements Test: ::target-text getComputedStyle</title>
<link rel="help" href="https://drafts.csswg.org/css-pseudo/#selectordef-target-text">
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<style>
#target::target-text {
background-color: green;
}
#target::target-text {
color: lime;
}
</style>
<div id="target"></div>
<script>
test(() => {
let style = getComputedStyle(target, "::target-text");
assert_equals(style.backgroundColor, "rgb(0, 128, 0)", "Background color is green.");
assert_equals(style.color, "rgb(0, 255, 0)", "Color is lime.");
}, "getComputedStyle() for ::target-text");
</script>
......@@ -39,6 +39,11 @@ element.style { ()
[$#inspected:after$] { (<style>)
content: "AFTER";
======== Pseudo ::grammar-error element ========
[expanded]
#inspected::grammar-error { (<style>)
color: teal;
======== Pseudo ::marker element ========
[expanded]
[$#inspected::marker$] { (<style>)
......@@ -53,6 +58,11 @@ element.style { ()
text-align: start !important;
text-align-last: start !important;
======== Pseudo ::spelling-error element ========
[expanded]
#inspected::spelling-error { (<style>)
color: orange;
======== Pseudo ::target-text element ========
[expanded]
#inspected::target-text { (<style>)
......
......@@ -12,6 +12,14 @@
color: green;
}
#inspected::spelling-error {
color: orange;
}
#inspected::grammar-error {
color: teal;
}
#inspected {
display: list-item;
}
......
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