mirror of
https://github.com/servo/servo
synced 2026-04-26 17:45:19 +02:00
A lot (and I mean, really a lot) depends on these constructors. Therefore, this is the one spaghetti ball that I could extract and convert all `can_gc` to `cx`. There are some new introductions of `temp_cx` in the callbacks of the servo parser, but we already had some in other callbacks. Part of #40600 Testing: It compiles Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
78 lines
2.7 KiB
Rust
78 lines
2.7 KiB
Rust
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at https://mozilla.org/MPL/2.0/. */
|
|
|
|
use std::cell::Ref;
|
|
|
|
use js::context::JSContext;
|
|
use script_bindings::codegen::GenericBindings::CharacterDataBinding::CharacterDataMethods;
|
|
use script_bindings::root::Dom;
|
|
|
|
use crate::dom::bindings::cell::DomRefCell;
|
|
use crate::dom::bindings::inheritance::Castable;
|
|
use crate::dom::characterdata::CharacterData;
|
|
use crate::dom::element::Element;
|
|
use crate::dom::htmlinputelement::HTMLInputElement;
|
|
use crate::dom::node::{Node, NodeTraits};
|
|
use crate::dom::text::Text;
|
|
|
|
#[derive(Default, JSTraceable, MallocSizeOf, PartialEq)]
|
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
|
pub(crate) struct TextValueWidget {
|
|
shadow_tree: DomRefCell<Option<TextValueShadowTree>>,
|
|
}
|
|
|
|
impl TextValueWidget {
|
|
/// Get the shadow tree for this [`HTMLInputElement`], if it is created and valid, otherwise
|
|
/// recreate the shadow tree and return it.
|
|
fn get_or_create_shadow_tree(
|
|
&self,
|
|
cx: &mut JSContext,
|
|
input: &HTMLInputElement,
|
|
) -> Ref<'_, TextValueShadowTree> {
|
|
{
|
|
if let Ok(shadow_tree) = Ref::filter_map(self.shadow_tree.borrow(), |shadow_tree| {
|
|
shadow_tree.as_ref()
|
|
}) {
|
|
return shadow_tree;
|
|
}
|
|
}
|
|
|
|
let element = input.upcast::<Element>();
|
|
let shadow_root = element
|
|
.shadow_root()
|
|
.unwrap_or_else(|| element.attach_ua_shadow_root(cx, true));
|
|
let shadow_root = shadow_root.upcast();
|
|
*self.shadow_tree.borrow_mut() = Some(TextValueShadowTree::new(cx, shadow_root));
|
|
self.get_or_create_shadow_tree(cx, input)
|
|
}
|
|
|
|
pub(crate) fn update_shadow_tree(&self, cx: &mut JSContext, input: &HTMLInputElement) {
|
|
self.get_or_create_shadow_tree(cx, input).update(input)
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, JSTraceable, MallocSizeOf, PartialEq)]
|
|
#[cfg_attr(crown, crown::unrooted_must_root_lint::must_root)]
|
|
struct TextValueShadowTree {
|
|
value: Dom<Text>,
|
|
}
|
|
|
|
impl TextValueShadowTree {
|
|
fn new(cx: &mut JSContext, shadow_root: &Node) -> Self {
|
|
let value = Text::new(cx, Default::default(), &shadow_root.owner_document());
|
|
Node::replace_all(cx, Some(value.upcast()), shadow_root);
|
|
Self {
|
|
value: value.as_traced(),
|
|
}
|
|
}
|
|
|
|
fn update(&self, input_element: &HTMLInputElement) {
|
|
let character_data = self.value.upcast::<CharacterData>();
|
|
let value = input_element.value_for_shadow_dom();
|
|
if character_data.Data() != value {
|
|
character_data.SetData(value);
|
|
}
|
|
}
|
|
}
|