diff --git a/components/script/dom/document.rs b/components/script/dom/document.rs index 2756152f190..ddcee472674 100644 --- a/components/script/dom/document.rs +++ b/components/script/dom/document.rs @@ -1556,12 +1556,12 @@ impl Document { return; } - // For a node within a text input UA shadow DOM, redirect the focus target into its shadow host. + // For a node within a text input UA shadow DOM, delegate the focus target into its shadow host. + // TODO: This focus delegation should be done with shadow DOM delegateFocus attribute. let target_el = el.find_focusable_shadow_host_if_necessary(); self.begin_focus_transaction(); // Try to focus `el`. If it's not focusable, focus the document - // instead. self.request_focus(None, FocusInitiator::Local, can_gc); self.request_focus(target_el.as_deref(), FocusInitiator::Local, can_gc); } diff --git a/components/script/dom/htmlinputelement.rs b/components/script/dom/htmlinputelement.rs index 95748a185ce..8999d7d9e4f 100644 --- a/components/script/dom/htmlinputelement.rs +++ b/components/script/dom/htmlinputelement.rs @@ -116,7 +116,7 @@ const DEFAULT_FILE_INPUT_VALUE: &str = "No file chosen"; /// /// ``` // TODO(stevennovaryo): We are trying to use CSS to mimic Chrome and Firefox's layout for the element. -// But this does have some discrepencies. For example, they would try to vertically align +// But this does have some discrepancies. For example, they would try to vertically align // text baseline with the baseline of other TextNode within an inline flow. struct InputTypeTextShadowTree { text_container: Dom, @@ -135,7 +135,7 @@ struct InputTypeColorShadowTree { // FIXME: These styles should be inside UA stylesheet, but it is not possible without internal pseudo element support. const TEXT_TREE_STYLE: &str = " -#input-editor::selection, #input-placeholder::selection { +#input-editor::selection { background: rgba(176, 214, 255, 1.0); color: black; } @@ -144,14 +144,14 @@ const TEXT_TREE_STYLE: &str = " visibility: hidden !important } -#input-container { - position: relative !important; - height: 100% !important; - pointer-events: none !important; +#input-editor { + pointer-events: auto; } -#input-editor { - pointer-events: auto !important; +#input-container { + position: relative; + height: 100%; + pointer-events: none; } #input-editor, #input-placeholder { @@ -1131,7 +1131,7 @@ impl HTMLInputElement { ShadowRootMode::Closed, false, false, - false, + true, SlotAssignmentMode::Manual, can_gc, ) @@ -1309,11 +1309,6 @@ impl HTMLInputElement { true => "\u{200B}".into(), }; - // TODO(stevennovaryo): Introduce caching to prevent costly update. - text_shadow_tree - .placeholder_container - .upcast::() - .SetTextContent(Some(self.placeholder.to_owned().take()), can_gc); text_shadow_tree .text_container .upcast::() @@ -2909,11 +2904,21 @@ impl VirtualMethods for HTMLInputElement { local_name!("placeholder") => { { let mut placeholder = self.placeholder.borrow_mut(); + let old_placeholder = placeholder.clone(); placeholder.clear(); if let AttributeMutation::Set(_) = mutation { placeholder .extend(attr.value().chars().filter(|&c| c != '\n' && c != '\r')); } + + // If old placeholder is not the same as the new one, + // we need to update the shadow tree. + if old_placeholder != *placeholder { + self.text_shadow_tree(can_gc) + .placeholder_container + .upcast::() + .SetTextContent(Some(placeholder.clone()), can_gc); + } } self.update_placeholder_shown_state(); }, diff --git a/components/script/dom/node.rs b/components/script/dom/node.rs index 5f9a955f4ab..0d66a80afee 100644 --- a/components/script/dom/node.rs +++ b/components/script/dom/node.rs @@ -233,7 +233,7 @@ bitflags! { /// Whether this node has a serve as the text container for editable content of /// or