From 32f92d18a8d022417eacbc79066538f4c9b8c957 Mon Sep 17 00:00:00 2001 From: Alexander Surkov Date: Sun, 26 Jul 2020 21:30:56 +0000 Subject: [PATCH] style: implement -moz-inert CSS property. -moz-inert CSS property reflects inert subtrees concept and can be used to implement HTML:dialog element and HTML:inert attribute Differential Revision: https://phabricator.services.mozilla.com/D81701 --- components/style/element_state.rs | 3 ++ .../style/gecko/non_ts_pseudo_class_list.rs | 1 + components/style/gecko/wrapper.rs | 1 + .../properties/longhands/inherited_ui.mako.rs | 11 ++++ components/style/servo/selector_parser.rs | 2 + components/style/style_adjuster.rs | 51 +++++++++++++++++++ 6 files changed, 69 insertions(+) diff --git a/components/style/element_state.rs b/components/style/element_state.rs index 027ebc839b4..da44186b44b 100644 --- a/components/style/element_state.rs +++ b/components/style/element_state.rs @@ -145,6 +145,9 @@ bitflags! { /// /// https://html.spec.whatwg.org/multipage/#centered-alignment const IN_MODAL_DIALOG_STATE = 1 << 53; + + /// https://html.spec.whatwg.org/multipage/interaction.html#inert-subtrees + const IN_MOZINERT_STATE = 1 << 54; } } diff --git a/components/style/gecko/non_ts_pseudo_class_list.rs b/components/style/gecko/non_ts_pseudo_class_list.rs index 034ce0694ad..bdd994c7095 100644 --- a/components/style/gecko/non_ts_pseudo_class_list.rs +++ b/components/style/gecko/non_ts_pseudo_class_list.rs @@ -48,6 +48,7 @@ macro_rules! apply_non_ts_list { ("-moz-drag-over", MozDragOver, IN_DRAGOVER_STATE, _), ("target", Target, IN_TARGET_STATE, _), ("indeterminate", Indeterminate, IN_INDETERMINATE_STATE, _), + ("-moz-inert", MozInert, IN_MOZINERT_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-devtools-highlighted", MozDevtoolsHighlighted, IN_DEVTOOLS_HIGHLIGHTED_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("-moz-styleeditor-transitioning", MozStyleeditorTransitioning, IN_STYLEEDITOR_TRANSITIONING_STATE, PSEUDO_CLASS_ENABLED_IN_UA_SHEETS), ("fullscreen", Fullscreen, IN_FULLSCREEN_STATE, _), diff --git a/components/style/gecko/wrapper.rs b/components/style/gecko/wrapper.rs index 7e984dc3ae1..3d4f186fcc3 100644 --- a/components/style/gecko/wrapper.rs +++ b/components/style/gecko/wrapper.rs @@ -2022,6 +2022,7 @@ impl<'le> ::selectors::Element for GeckoElement<'le> { NonTSPseudoClass::Checked | NonTSPseudoClass::Fullscreen | NonTSPseudoClass::Indeterminate | + NonTSPseudoClass::MozInert | NonTSPseudoClass::PlaceholderShown | NonTSPseudoClass::Target | NonTSPseudoClass::Valid | diff --git a/components/style/properties/longhands/inherited_ui.mako.rs b/components/style/properties/longhands/inherited_ui.mako.rs index bbe34209647..cb48acaa1fe 100644 --- a/components/style/properties/longhands/inherited_ui.mako.rs +++ b/components/style/properties/longhands/inherited_ui.mako.rs @@ -29,6 +29,17 @@ ${helpers.single_keyword( gecko_enum_prefix="StylePointerEvents", )} +${helpers.single_keyword( + "-moz-inert", + "none inert", + engines="gecko", + gecko_ffi_name="mInert", + gecko_enum_prefix="StyleInert", + animation_value_type="discrete", + enabled_in="ua", + spec="Nonstandard (https://html.spec.whatwg.org/multipage/interaction.html#inert-subtrees)", +)} + ${helpers.single_keyword( "-moz-user-input", "auto none", diff --git a/components/style/servo/selector_parser.rs b/components/style/servo/selector_parser.rs index 66e87b339d4..b11751fbec0 100644 --- a/components/style/servo/selector_parser.rs +++ b/components/style/servo/selector_parser.rs @@ -349,6 +349,7 @@ impl ToCss for NonTSPseudoClass { Fullscreen => ":fullscreen", Hover => ":hover", Indeterminate => ":indeterminate", + MozInert => ":-moz-inert", Link => ":link", PlaceholderShown => ":placeholder-shown", ReadWrite => ":read-write", @@ -438,6 +439,7 @@ impl<'a, 'i> ::selectors::Parser<'i> for SelectorParser<'a> { "fullscreen" => Fullscreen, "hover" => Hover, "indeterminate" => Indeterminate, + "-moz-inert" => MozInert, "link" => Link, "placeholder-shown" => PlaceholderShown, "read-write" => ReadWrite, diff --git a/components/style/style_adjuster.rs b/components/style/style_adjuster.rs index 8ab4aea3d21..fb5fae96bd0 100644 --- a/components/style/style_adjuster.rs +++ b/components/style/style_adjuster.rs @@ -153,6 +153,56 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { } } + /// https://html.spec.whatwg.org/multipage/interaction.html#inert-subtrees + /// + /// If -moz-inert is applied then add: + /// -moz-user-focus: none; + /// -moz-user-input: none; + /// -moz-user-modify: read-only; + /// user-select: none; + /// pointer-events: none; + /// cursor: default; + fn adjust_for_inert(&mut self) { + use properties::longhands::_moz_inert::computed_value::T as Inert; + use properties::longhands::_moz_user_focus::computed_value::T as UserFocus; + use properties::longhands::_moz_user_input::computed_value::T as UserInput; + use properties::longhands::_moz_user_modify::computed_value::T as UserModify; + use properties::longhands::pointer_events::computed_value::T as PointerEvents; + use properties::longhands::cursor::computed_value::T as Cursor; + use crate::values::specified::ui::CursorKind; + use crate::values::specified::ui::UserSelect; + + let needs_update = { + let ui = self.style.get_inherited_ui(); + if ui.clone__moz_inert() == Inert::None { + return; + } + + ui.clone__moz_user_focus() != UserFocus::None || + ui.clone__moz_user_input() != UserInput::None || + ui.clone__moz_user_modify() != UserModify::ReadOnly || + ui.clone_pointer_events() != PointerEvents::None || + ui.clone_cursor().keyword != CursorKind::Default || + ui.clone_cursor().images != Default::default() + }; + + if needs_update { + let ui = self.style.mutate_inherited_ui(); + ui.set__moz_user_focus(UserFocus::None); + ui.set__moz_user_input(UserInput::None); + ui.set__moz_user_modify(UserModify::ReadOnly); + ui.set_pointer_events(PointerEvents::None); + ui.set_cursor(Cursor { + images: Default::default(), + keyword: CursorKind::Default, + }); + } + + if self.style.get_ui().clone_user_select() != UserSelect::None { + self.style.mutate_ui().set_user_select(UserSelect::None); + } + } + /// Whether we should skip any item-based display property blockification on /// this element. fn skip_item_display_fixup(&self, element: Option) -> bool @@ -855,6 +905,7 @@ impl<'a, 'b: 'a> StyleAdjuster<'a, 'b> { #[cfg(feature = "gecko")] { self.adjust_for_appearance(element); + self.adjust_for_inert(); } self.set_bits(); }