forked from mirrors/gecko-dev
Bug 1904228: Don't consider :scope selectors to be featureless outside of @scope. r=emilio, a=dmeehan
Differential Revision: https://phabricator.services.mozilla.com/D214678
This commit is contained in:
parent
4b1e713247
commit
07c77d3ecd
3 changed files with 74 additions and 5 deletions
|
|
@ -596,6 +596,43 @@ impl From<StyleRuleInclusion> for RuleInclusion {
|
|||
}
|
||||
}
|
||||
|
||||
/// `:scope` selector, depending on the use case, can match a shadow host.
|
||||
/// If used outside of `@scope`, it cannot possibly match the host.
|
||||
/// Even when inside of `@scope`, it's conditional if the selector will
|
||||
/// match the shadow host.
|
||||
#[derive(Clone, Copy, Eq, PartialEq)]
|
||||
enum ScopeMatchesShadowHost {
|
||||
NotApplicable,
|
||||
No,
|
||||
Yes,
|
||||
}
|
||||
|
||||
impl Default for ScopeMatchesShadowHost {
|
||||
fn default() -> Self {
|
||||
Self::NotApplicable
|
||||
}
|
||||
}
|
||||
|
||||
impl ScopeMatchesShadowHost {
|
||||
fn nest_for_scope(&mut self, matches_shadow_host: bool) {
|
||||
match *self {
|
||||
Self::NotApplicable => {
|
||||
// We're at the outermost `@scope`.
|
||||
*self = if matches_shadow_host {
|
||||
Self::Yes
|
||||
} else {
|
||||
Self::No
|
||||
};
|
||||
},
|
||||
Self::Yes if !matches_shadow_host => {
|
||||
// Inner `@scope` will not be able to match the shadow host.
|
||||
*self = Self::No;
|
||||
},
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// A struct containing state from ancestor rules like @layer / @import /
|
||||
/// @container / nesting / @scope.
|
||||
struct ContainingRuleState {
|
||||
|
|
@ -604,7 +641,7 @@ struct ContainingRuleState {
|
|||
container_condition_id: ContainerConditionId,
|
||||
in_starting_style: bool,
|
||||
scope_condition_id: ScopeConditionId,
|
||||
scope_matches_shadow_host: bool,
|
||||
scope_matches_shadow_host: ScopeMatchesShadowHost,
|
||||
ancestor_selector_lists: SmallVec<[SelectorList<SelectorImpl>; 2]>,
|
||||
}
|
||||
|
||||
|
|
@ -617,7 +654,7 @@ impl Default for ContainingRuleState {
|
|||
in_starting_style: false,
|
||||
ancestor_selector_lists: Default::default(),
|
||||
scope_condition_id: ScopeConditionId::none(),
|
||||
scope_matches_shadow_host: true,
|
||||
scope_matches_shadow_host: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -629,7 +666,7 @@ struct SavedContainingRuleState {
|
|||
container_condition_id: ContainerConditionId,
|
||||
in_starting_style: bool,
|
||||
scope_condition_id: ScopeConditionId,
|
||||
scope_matches_shadow_host: bool,
|
||||
scope_matches_shadow_host: ScopeMatchesShadowHost,
|
||||
}
|
||||
|
||||
impl ContainingRuleState {
|
||||
|
|
@ -3204,7 +3241,8 @@ impl CascadeData {
|
|||
} else if potentially_matches_featureless_host
|
||||
.intersects(FeaturelessHostMatches::FOR_SCOPE)
|
||||
{
|
||||
containing_rule_state.scope_matches_shadow_host
|
||||
containing_rule_state.scope_matches_shadow_host ==
|
||||
ScopeMatchesShadowHost::Yes
|
||||
} else {
|
||||
false
|
||||
};
|
||||
|
|
@ -3484,7 +3522,9 @@ impl CascadeData {
|
|||
condition: Some(replaced),
|
||||
implicit_scope_root,
|
||||
});
|
||||
containing_rule_state.scope_matches_shadow_host &= matches_shadow_host;
|
||||
containing_rule_state
|
||||
.scope_matches_shadow_host
|
||||
.nest_for_scope(matches_shadow_host);
|
||||
containing_rule_state.scope_condition_id = id;
|
||||
},
|
||||
// We don't care about any other rule.
|
||||
|
|
|
|||
|
|
@ -0,0 +1,9 @@
|
|||
<!DOCTYPE html>
|
||||
<title>Reference - :scope Selector Cannot be Featureless Outside of @scope</title>
|
||||
<style>
|
||||
:root {
|
||||
background: white;
|
||||
color: black;
|
||||
}
|
||||
</style>
|
||||
<div id="dut">Test</div>
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<!DOCTYPE html>
|
||||
<title>:scope Selector Cannot be Featureless Outside of @scope</title>
|
||||
<link rel="help" href="https://drafts.csswg.org/css-cascade-6/#scoped-styles">
|
||||
<link rel="help" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1904228">
|
||||
<link rel="match" href="scope-featureless-ref.html">
|
||||
<style>
|
||||
:root {
|
||||
background: white;
|
||||
color: white;
|
||||
}
|
||||
|
||||
:scope {
|
||||
--font-color: black;
|
||||
}
|
||||
|
||||
#dut {
|
||||
color: var(--font-color);
|
||||
}
|
||||
</style>
|
||||
<div id="dut">Test</div>
|
||||
Loading…
Reference in a new issue