Commit f84c000f authored by Rune Lillesveen's avatar Rune Lillesveen Committed by Commit Bot

Filter highlight pseudo element properties.

The css-pseudo specification lists which properties applies to which
pseudo elements. For ::marker and ::first-letter we were already using
the CascadeFilter. This CL uses the filter for highlight pseudo elements
like ::selection and ::target-text, which share the same set of
properties which apply.

This means we stop retrieving resources for CSS properties which don't
apply to these pseudo elements. Additionally, block all resource
fetching for the ::target-text element since resource fetching can be
used by an external stylesheet in combination with a text fragment url
to detect text content on a page.

Bug: 1136817
Change-Id: I8b19db8535882e6b20f6319cd2a9f5219e7c9538
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2489657
Commit-Queue: Rune Lillesveen <futhark@chromium.org>
Reviewed-by: default avatarAnders Hartvoll Ruud <andruud@chromium.org>
Cr-Commit-Position: refs/heads/master@{#821283}
parent ec6be3dd
......@@ -37,6 +37,8 @@ def validate_property(prop):
'Only longhands can be valid_for_cue [%s]' % name
assert not prop['valid_for_marker'] or prop['is_longhand'], \
'Only longhands can be valid_for_marker [%s]' % name
assert not prop['valid_for_highlight'] or prop['is_longhand'], \
'Only longhands can be valid_for_highlight [%s]' % name
def validate_alias(alias):
......
......@@ -51,6 +51,7 @@ namespace {{namespace}} {
(property.is_border and 'kBorder' or ''),
(property.computed_value_comparable and 'kComputedValueComparable' or ''),
(property.tree_scoped_value and 'kTreeScopedValue' or ''),
(property.valid_for_highlight and 'kValidForHighlight' or ''),
] | reject('==', '') | join(' | ') %}
{% set ctor_args = (not is_alias and [property_id, flags, separator] or []) %}
// {{property.name}}
......
......@@ -479,6 +479,14 @@
valid_type: "bool",
},
// - valid_for_highlight: true
//
// https://drafts.csswg.org/css-pseudo-4/#highlight-styling
valid_for_highlight: {
default: false,
valid_type: "bool",
},
// - is_border
// The property, when used by the author, will disable any native
// appearance on UI elements.
......@@ -714,6 +722,7 @@
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_marker: true,
valid_for_highlight: true,
},
{
name: "direction",
......@@ -969,6 +978,7 @@
keywords: ["auto", "none"],
typedom_types: ["Keyword"],
default_value: "auto",
valid_for_highlight: true,
},
{
name: "-webkit-locale",
......@@ -1201,6 +1211,7 @@
affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
is_background: true,
},
{
......@@ -1742,6 +1753,7 @@
style_builder_custom_functions: ["initial", "inherit", "value"],
keywords: ["auto", "currentcolor"],
typedom_types: ["Keyword"],
valid_for_highlight: true,
},
{
name: "clear",
......@@ -1823,6 +1835,7 @@
type_name: "Vector<AtomicString>",
default_value: "Vector<AtomicString, 0>()",
field_template: "external",
valid_for_highlight: true,
},
{
name: "column-fill",
......@@ -1919,7 +1932,8 @@
],
default_value: "auto",
style_builder_custom_functions: ["initial", "inherit", "value"],
typedom_types: ["Keyword"]
typedom_types: ["Keyword"],
valid_for_highlight: true,
},
{
name: "cx",
......@@ -1988,6 +2002,7 @@
getter: "FillPaint",
converter: "ConvertSVGPaint",
affected_by_forced_colors: true,
valid_for_highlight: true,
},
{
name: "fill-opacity",
......@@ -3474,6 +3489,7 @@
getter: "StrokePaint",
converter: "ConvertSVGPaint",
affected_by_forced_colors: true,
valid_for_highlight: true,
},
{
name: "stroke-dasharray",
......@@ -3542,7 +3558,8 @@
inherited: true,
svg: true,
converter: "ConvertUnzoomedLength",
typedom_types: ["Length", "Percentage"]
typedom_types: ["Length", "Percentage"],
valid_for_highlight: true,
},
{
name: "table-layout",
......@@ -3632,6 +3649,7 @@
affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
computed_value_comparable: true,
},
{
......@@ -3647,6 +3665,7 @@
converter: "ConvertFlags<TextDecoration>",
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
computed_value_comparable: true,
},
{
......@@ -3661,6 +3680,7 @@
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_marker: true,
valid_for_highlight: true,
computed_value_comparable: true,
},
{
......@@ -3673,6 +3693,7 @@
default_value: "solid",
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
computed_value_comparable: true,
},
{
......@@ -3689,6 +3710,7 @@
keywords: ["auto", "from-font"],
typedom_types: ["Keyword", "Length", "Percentage"],
valid_for_first_letter: true,
valid_for_highlight: true,
computed_value_comparable: true,
},
{
......@@ -3744,6 +3766,7 @@
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_marker: true,
valid_for_highlight: true,
},
{
name: "text-size-adjust",
......@@ -4461,6 +4484,7 @@
style_builder_template: "color",
affected_by_forced_colors: true,
valid_for_marker: true,
valid_for_highlight: true,
},
{
name: "-webkit-text-emphasis-position",
......@@ -4493,6 +4517,7 @@
computed_style_custom_functions: ["getter"],
converter: "ConvertStyleColor",
style_builder_template: "color",
valid_for_highlight: true,
},
{
name: "-webkit-text-security",
......@@ -4516,6 +4541,7 @@
computed_style_custom_functions: ["getter"],
converter: "ConvertStyleColor",
style_builder_template: "color",
valid_for_highlight: true,
},
{
name: "-webkit-text-stroke-width",
......@@ -4526,6 +4552,7 @@
default_value: "0",
type_name: "float",
converter: "ConvertTextStrokeWidth",
valid_for_highlight: true,
},
{
name: "-webkit-transform-origin-x",
......@@ -5744,6 +5771,7 @@
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_marker: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-caret-color",
......@@ -5761,6 +5789,7 @@
style_builder_template_args: {
initial_color: "StyleAutoColor::AutoColor",
},
valid_for_highlight: true,
},
{
name: "-internal-visited-column-rule-color",
......@@ -5794,6 +5823,7 @@
affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-border-left-color",
......@@ -5906,6 +5936,7 @@
getter: "FillPaint",
converter: "ConvertSVGPaint",
affected_by_forced_colors: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-outline-color",
......@@ -5933,6 +5964,7 @@
getter: "StrokePaint",
converter: "ConvertSVGPaint",
affected_by_forced_colors: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-text-decoration-color",
......@@ -5949,6 +5981,7 @@
affected_by_forced_colors: true,
valid_for_first_letter: true,
valid_for_cue: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-text-emphasis-color",
......@@ -5964,6 +5997,7 @@
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
affected_by_forced_colors: true,
valid_for_highlight: true,
},
{
name: "-internal-visited-text-fill-color",
......@@ -5978,6 +6012,7 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
valid_for_highlight: true,
},
{
name: "-internal-visited-text-stroke-color",
......@@ -5992,6 +6027,7 @@
computed_style_custom_functions: ["getter", "setter"],
converter: "ConvertStyleColor",
style_builder_template: "visited_color",
valid_for_highlight: true,
},
// Name: -internal-empty-line-height:
......
......@@ -56,6 +56,7 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
bool IsValidForFirstLetter() const { return flags_ & kValidForFirstLetter; }
bool IsValidForCue() const { return flags_ & kValidForCue; }
bool IsValidForMarker() const { return flags_ & kValidForMarker; }
bool IsValidForHighlight() const { return flags_ & kValidForHighlight; }
bool IsSurrogate() const { return flags_ & kSurrogate; }
bool AffectsFont() const { return flags_ & kAffectsFont; }
bool IsBackground() const { return flags_ & kBackground; }
......@@ -152,6 +153,8 @@ class CORE_EXPORT CSSProperty : public CSSUnresolvedProperty {
kComputedValueComparable = 1 << 18,
// Set if the property values are tree-scoped references.
kTreeScopedValue = 1 << 19,
// https://drafts.csswg.org/css-pseudo-4/#highlight-styling
kValidForHighlight = 1 << 20,
};
constexpr CSSProperty(CSSPropertyID property_id,
......
......@@ -35,7 +35,8 @@ class CORE_EXPORT Variable : public Longhand {
protected:
explicit constexpr Variable(CSSProperty::Flags flags)
: Longhand(CSSPropertyID::kVariable,
kProperty | kValidForFirstLetter | kValidForMarker | flags,
kProperty | kValidForFirstLetter | kValidForMarker |
kValidForHighlight | flags,
'\0') {}
};
......
......@@ -24,6 +24,8 @@ CascadeFilter AddValidPropertiesFilter(
return filter.Add(CSSProperty::kValidForFirstLetter, false);
case ValidPropertyFilter::kMarker:
return filter.Add(CSSProperty::kValidForMarker, false);
case ValidPropertyFilter::kHighlight:
return filter.Add(CSSProperty::kValidForHighlight, false);
}
}
......
......@@ -453,6 +453,25 @@ TEST_F(CascadeExpansionTest, FilterMarker) {
EXPECT_TRUE(e.AtEnd());
}
TEST_F(CascadeExpansionTest, FilterHighlight) {
MatchResult result;
result.FinishAddingUARules();
result.FinishAddingUserRules();
result.AddMatchedProperties(
ParseDeclarationBlock("display:block;background-color:lime;"),
CSSSelector::kMatchAll, ValidPropertyFilter::kHighlight);
result.FinishAddingAuthorRulesForTreeScope(GetDocument());
auto e = ExpansionAt(result, 0);
ASSERT_FALSE(e.AtEnd());
EXPECT_EQ(CSSPropertyID::kBackgroundColor, e.Id());
e.Next();
ASSERT_FALSE(e.AtEnd());
EXPECT_EQ(CSSPropertyID::kInternalVisitedBackgroundColor, e.Id());
e.Next();
EXPECT_TRUE(e.AtEnd());
}
TEST_F(CascadeExpansionTest, FilterAllNonInherited) {
MatchResult result;
result.FinishAddingUARules();
......
......@@ -120,12 +120,11 @@ SVGResource* ElementStyleResources::GetSVGResourceFromValue(
return nullptr;
}
void ElementStyleResources::LoadPendingSVGResources(
ComputedStyle* computed_style) {
if (!computed_style->HasFilter())
void ElementStyleResources::LoadPendingSVGResources(ComputedStyle& style) {
if (!style.HasFilter())
return;
FilterOperations::FilterOperationVector& filter_operations =
computed_style->MutableFilter().Operations();
style.MutableFilter().Operations();
for (const auto& filter_operation : filter_operations) {
auto* reference_operation =
DynamicTo<ReferenceFilterOperation>(filter_operation.Get());
......@@ -147,7 +146,7 @@ static bool BackgroundLayerMayBeSprite(const FillLayer& background_layer) {
}
StyleImage* ElementStyleResources::LoadPendingImage(
ComputedStyle* style,
ComputedStyle& style,
StylePendingImage* pending_image,
FetchParameters::ImageRequestBehavior image_request_behavior,
CrossOriginAttributeValue cross_origin) {
......@@ -158,7 +157,7 @@ StyleImage* ElementStyleResources::LoadPendingImage(
if (CSSPaintValue* paint_value = pending_image->CssPaintValue()) {
auto* image = MakeGarbageCollected<StyleGeneratedImage>(*paint_value);
style->AddPaintImage(image);
style.AddPaintImage(image);
return image;
}
......@@ -178,7 +177,7 @@ StyleImage* ElementStyleResources::LoadPendingImage(
return nullptr;
}
void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
void ElementStyleResources::LoadPendingImages(ComputedStyle& style) {
// We must loop over the properties and then look at the style to see if
// a pending image exists, and only load that image. For example:
//
......@@ -200,7 +199,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
for (CSSPropertyID property : pending_image_properties_) {
switch (property) {
case CSSPropertyID::kBackgroundImage: {
for (FillLayer* background_layer = &style->AccessBackgroundLayers();
for (FillLayer* background_layer = &style.AccessBackgroundLayers();
background_layer; background_layer = background_layer->Next()) {
StyleImage* background_image = background_layer->GetImage();
if (background_image && background_image->IsPendingImage()) {
......@@ -228,7 +227,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
}
case CSSPropertyID::kContent: {
for (ContentData* content_data =
const_cast<ContentData*>(style->GetContentData());
const_cast<ContentData*>(style.GetContentData());
content_data; content_data = content_data->Next()) {
if (content_data->IsImage()) {
StyleImage* image = To<ImageContentData>(content_data)->GetImage();
......@@ -243,7 +242,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
break;
}
case CSSPropertyID::kCursor: {
if (CursorList* cursor_list = style->Cursors()) {
if (CursorList* cursor_list = style.Cursors()) {
for (wtf_size_t i = 0; i < cursor_list->size(); ++i) {
CursorData& current_cursor = cursor_list->at(i);
if (StyleImage* image = current_cursor.GetImage()) {
......@@ -258,25 +257,25 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
break;
}
case CSSPropertyID::kListStyleImage: {
if (style->ListStyleImage() &&
style->ListStyleImage()->IsPendingImage()) {
style->SetListStyleImage(LoadPendingImage(
style, To<StylePendingImage>(style->ListStyleImage()),
if (style.ListStyleImage() &&
style.ListStyleImage()->IsPendingImage()) {
style.SetListStyleImage(LoadPendingImage(
style, To<StylePendingImage>(style.ListStyleImage()),
FetchParameters::kNone));
}
break;
}
case CSSPropertyID::kBorderImageSource: {
if (style->BorderImageSource() &&
style->BorderImageSource()->IsPendingImage()) {
style->SetBorderImageSource(LoadPendingImage(
style, To<StylePendingImage>(style->BorderImageSource()),
if (style.BorderImageSource() &&
style.BorderImageSource()->IsPendingImage()) {
style.SetBorderImageSource(LoadPendingImage(
style, To<StylePendingImage>(style.BorderImageSource()),
FetchParameters::kNone));
}
break;
}
case CSSPropertyID::kWebkitBoxReflect: {
if (StyleReflection* reflection = style->BoxReflect()) {
if (StyleReflection* reflection = style.BoxReflect()) {
const NinePieceImage& mask_image = reflection->Mask();
if (mask_image.GetImage() &&
mask_image.GetImage()->IsPendingImage()) {
......@@ -292,16 +291,16 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
break;
}
case CSSPropertyID::kWebkitMaskBoxImageSource: {
if (style->MaskBoxImageSource() &&
style->MaskBoxImageSource()->IsPendingImage()) {
style->SetMaskBoxImageSource(LoadPendingImage(
style, To<StylePendingImage>(style->MaskBoxImageSource()),
if (style.MaskBoxImageSource() &&
style.MaskBoxImageSource()->IsPendingImage()) {
style.SetMaskBoxImageSource(LoadPendingImage(
style, To<StylePendingImage>(style.MaskBoxImageSource()),
FetchParameters::kNone));
}
break;
}
case CSSPropertyID::kWebkitMaskImage: {
for (FillLayer* mask_layer = &style->AccessMaskLayers(); mask_layer;
for (FillLayer* mask_layer = &style.AccessMaskLayers(); mask_layer;
mask_layer = mask_layer->Next()) {
if (mask_layer->GetImage() &&
mask_layer->GetImage()->IsPendingImage()) {
......@@ -313,10 +312,10 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
break;
}
case CSSPropertyID::kShapeOutside:
if (style->ShapeOutside() && style->ShapeOutside()->GetImage() &&
style->ShapeOutside()->GetImage()->IsPendingImage()) {
style->ShapeOutside()->SetImage(LoadPendingImage(
style, To<StylePendingImage>(style->ShapeOutside()->GetImage()),
if (style.ShapeOutside() && style.ShapeOutside()->GetImage() &&
style.ShapeOutside()->GetImage()->IsPendingImage()) {
style.ShapeOutside()->SetImage(LoadPendingImage(
style, To<StylePendingImage>(style.ShapeOutside()->GetImage()),
FetchParameters::kNone, kCrossOriginAttributeAnonymous));
}
break;
......@@ -327,7 +326,7 @@ void ElementStyleResources::LoadPendingImages(ComputedStyle* style) {
}
void ElementStyleResources::LoadPendingResources(
ComputedStyle* computed_style) {
ComputedStyle& computed_style) {
LoadPendingImages(computed_style);
LoadPendingSVGResources(computed_style);
}
......
......@@ -74,17 +74,17 @@ class ElementStyleResources {
const cssvalue::CSSURIValue&,
AllowExternal = kDontAllowExternalResource) const;
void LoadPendingResources(ComputedStyle*);
void LoadPendingResources(ComputedStyle&);
private:
StyleImage* GeneratedOrPendingFromValue(CSSPropertyID,
const CSSImageGeneratorValue&);
void LoadPendingSVGResources(ComputedStyle*);
void LoadPendingImages(ComputedStyle*);
void LoadPendingSVGResources(ComputedStyle&);
void LoadPendingImages(ComputedStyle&);
StyleImage* LoadPendingImage(
ComputedStyle*,
ComputedStyle&,
StylePendingImage*,
FetchParameters::ImageRequestBehavior,
CrossOriginAttributeValue = kCrossOriginAttributeNotSet);
......
......@@ -50,7 +50,7 @@ struct CORE_EXPORT MatchedProperties {
struct Data {
unsigned link_match_type : 2;
unsigned valid_property_filter : 2;
unsigned valid_property_filter : 3;
CascadeOrigin origin;
// This is approximately equivalent to the 'shadow-including tree order'.
// It can be used to evaluate the 'Shadow Tree' criteria. Note that the
......
......@@ -1434,6 +1434,8 @@ bool StyleResolver::ApplyAnimatedStyle(StyleResolverState& state,
filter = filter.Add(CSSProperty::kIsAffectedByForcedColors, true);
if (state.Style()->StyleType() == kPseudoIdMarker)
filter = filter.Add(CSSProperty::kValidForMarker, false);
if (IsHighlightPseudoElement(state.Style()->StyleType()))
filter = filter.Add(CSSProperty::kValidForHighlight, false);
filter = filter.Add(CSSProperty::kAnimation, true);
cascade.Apply(filter);
......
......@@ -155,7 +155,13 @@ void StyleResolverState::LoadPendingResources() {
StyleRef().IsEnsuredOutsideFlatTree())
return;
element_style_resources_.LoadPendingResources(Style());
if (StyleRef().StyleType() == kPseudoIdTargetText) {
// Do not load any resources for ::target-text since that could leak text
// content to external stylesheets.
return;
}
element_style_resources_.LoadPendingResources(StyleRef());
}
const FontDescription& StyleResolverState::ParentFontDescription() const {
......
......@@ -593,6 +593,64 @@ TEST_F(StyleResolverTest, NoFetchForAtPage) {
EXPECT_TRUE(To<CSSImageValue>(bg_img_list->Item(0)).IsCachePending());
}
TEST_F(StyleResolverTest, NoFetchForHighlightPseudoElements) {
ScopedCSSTargetTextPseudoElementForTest scoped_feature(true);
GetDocument().body()->setInnerHTML(R"HTML(
<style>
body::target-text, body::selection {
color: green;
background-image: url(bg-img.png);
cursor: url(cursor.ico), auto;
}
</style>
)HTML");
UpdateAllLifecyclePhasesForTest();
auto* body = GetDocument().body();
ASSERT_TRUE(body);
const auto* element_style = body->GetComputedStyle();
ASSERT_TRUE(element_style);
scoped_refptr<ComputedStyle> target_text_style =
GetDocument().GetStyleResolver().PseudoStyleForElement(
GetDocument().body(), PseudoElementStyleRequest(kPseudoIdTargetText),
element_style, element_style);
ASSERT_TRUE(target_text_style);
scoped_refptr<ComputedStyle> selection_style =
GetDocument().GetStyleResolver().PseudoStyleForElement(
GetDocument().body(), PseudoElementStyleRequest(kPseudoIdSelection),
element_style, element_style);
ASSERT_TRUE(selection_style);
// Check that we don't fetch the cursor url() for ::target-text.
CursorList* cursor_list = target_text_style->Cursors();
ASSERT_TRUE(cursor_list->size());
CursorData& current_cursor = cursor_list->at(0);
StyleImage* image = current_cursor.GetImage();
ASSERT_TRUE(image);
EXPECT_TRUE(image->IsPendingImage());
for (const auto* pseudo_style :
{target_text_style.get(), selection_style.get()}) {
// Check that the color applies.
EXPECT_EQ(Color(0, 128, 0),
pseudo_style->VisitedDependentColor(GetCSSPropertyColor()));
// Check that the background-image does not apply.
const CSSValue* computed_value = ComputedStyleUtils::ComputedPropertyValue(
GetCSSPropertyBackgroundImage(), *pseudo_style);
const CSSValueList* list = DynamicTo<CSSValueList>(computed_value);
ASSERT_TRUE(list);
ASSERT_EQ(1u, list->length());
const auto* keyword = DynamicTo<CSSIdentifierValue>(list->Item(0));
ASSERT_TRUE(keyword);
EXPECT_EQ(CSSValueID::kNone, keyword->GetValueID());
}
}
TEST_F(StyleResolverTest, CSSMarkerPseudoElement) {
GetDocument().body()->setInnerHTML(R"HTML(
<style>
......
......@@ -51,14 +51,23 @@ static inline ValidPropertyFilter DetermineValidPropertyFilter(
const CSSSelector& selector) {
for (const CSSSelector* component = &selector; component;
component = component->TagHistory()) {
if (component->GetPseudoType() == CSSSelector::kPseudoCue ||
(component->Match() == CSSSelector::kPseudoElement &&
component->Value() == TextTrackCue::CueShadowPseudoId()))
if (component->Match() == CSSSelector::kPseudoElement &&
component->Value() == TextTrackCue::CueShadowPseudoId()) {
return ValidPropertyFilter::kCue;
if (component->GetPseudoType() == CSSSelector::kPseudoFirstLetter)
return ValidPropertyFilter::kFirstLetter;
if (component->GetPseudoType() == CSSSelector::kPseudoMarker)
return ValidPropertyFilter::kMarker;
}
switch (component->GetPseudoType()) {
case CSSSelector::kPseudoCue:
return ValidPropertyFilter::kCue;
case CSSSelector::kPseudoFirstLetter:
return ValidPropertyFilter::kFirstLetter;
case CSSSelector::kPseudoMarker:
return ValidPropertyFilter::kMarker;
case CSSSelector::kPseudoSelection:
case CSSSelector::kPseudoTargetText:
return ValidPropertyFilter::kHighlight;
default:
break;
}
}
return ValidPropertyFilter::kNoFilter;
}
......
......@@ -58,6 +58,10 @@ enum class ValidPropertyFilter : unsigned {
// Defined in a ::marker pseudo-element scope. Only properties listed in
// https://drafts.csswg.org/css-pseudo-4/#marker-pseudo are valid.
kMarker,
// Defined in a highlight pseudo-element scope like ::selection and
// ::target-text. Only properties listed in
// https://drafts.csswg.org/css-pseudo-4/#highlight-styling are valid.
kHighlight,
};
class CSSSelector;
......@@ -151,8 +155,8 @@ class CORE_EXPORT RuleData : public GarbageCollected<RuleData> {
unsigned specificity_ : 24;
unsigned link_match_type_ : 2;
unsigned has_document_security_origin_ : 1;
unsigned valid_property_filter_ : 2;
// 29 bits above
unsigned valid_property_filter_ : 3;
// 30 bits above
// Use plain array instead of a Vector to minimize memory overhead.
unsigned descendant_selector_identifier_hashes_[kMaximumIdentifierCount];
};
......
......@@ -80,6 +80,10 @@ enum PseudoId : uint8_t {
kFirstInternalPseudoId = kPseudoIdFirstLineInherited,
};
inline bool IsHighlightPseudoElement(PseudoId pseudo_id) {
return pseudo_id == kPseudoIdSelection || pseudo_id == kPseudoIdTargetText;
}
enum class OutlineIsAuto : bool { kOff = false, kOn = true };
// Random visual rendering model attributes. Not inherited.
......
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