mirror of
https://github.com/servo/servo.git
synced 2025-08-05 13:40:08 +01:00
script: Upgrade node_ids
to pipeline_to_node_ids
to track the owner pipeline of the node
Signed-off-by: Euclid Ye <yezhizhenjiakang@gmail.com>
This commit is contained in:
parent
568d24d4e3
commit
bce3684645
4 changed files with 61 additions and 37 deletions
|
@ -132,7 +132,7 @@ fn find_node_by_unique_id(
|
||||||
document
|
document
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.traverse_preorder(ShadowIncluding::Yes)
|
.traverse_preorder(ShadowIncluding::Yes)
|
||||||
.find(|candidate| candidate.unique_id() == node_id)
|
.find(|candidate| candidate.unique_id(pipeline) == node_id)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1261,13 +1261,13 @@ impl Node {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn unique_id(&self) -> String {
|
pub(crate) fn unique_id(&self, pipeline: PipelineId) -> String {
|
||||||
let mut rare_data = self.ensure_rare_data();
|
let mut rare_data = self.ensure_rare_data();
|
||||||
|
|
||||||
if rare_data.unique_id.is_none() {
|
if rare_data.unique_id.is_none() {
|
||||||
let id = UniqueId::new();
|
let node_id = UniqueId::new();
|
||||||
ScriptThread::save_node_id(id.borrow().simple().to_string());
|
ScriptThread::save_node_id(pipeline, node_id.borrow().simple().to_string());
|
||||||
rare_data.unique_id = Some(id);
|
rare_data.unique_id = Some(node_id);
|
||||||
}
|
}
|
||||||
rare_data
|
rare_data
|
||||||
.unique_id
|
.unique_id
|
||||||
|
@ -1281,6 +1281,7 @@ impl Node {
|
||||||
pub(crate) fn summarize(&self, can_gc: CanGc) -> NodeInfo {
|
pub(crate) fn summarize(&self, can_gc: CanGc) -> NodeInfo {
|
||||||
let USVString(base_uri) = self.BaseURI();
|
let USVString(base_uri) = self.BaseURI();
|
||||||
let node_type = self.NodeType();
|
let node_type = self.NodeType();
|
||||||
|
let pipeline = self.owner_document().window().pipeline_id();
|
||||||
|
|
||||||
let maybe_shadow_root = self.downcast::<ShadowRoot>();
|
let maybe_shadow_root = self.downcast::<ShadowRoot>();
|
||||||
let shadow_root_mode = maybe_shadow_root
|
let shadow_root_mode = maybe_shadow_root
|
||||||
|
@ -1288,7 +1289,7 @@ impl Node {
|
||||||
.map(ShadowRootMode::convert);
|
.map(ShadowRootMode::convert);
|
||||||
let host = maybe_shadow_root
|
let host = maybe_shadow_root
|
||||||
.map(ShadowRoot::Host)
|
.map(ShadowRoot::Host)
|
||||||
.map(|host| host.upcast::<Node>().unique_id());
|
.map(|host| host.upcast::<Node>().unique_id(pipeline));
|
||||||
let is_shadow_host = self.downcast::<Element>().is_some_and(|potential_host| {
|
let is_shadow_host = self.downcast::<Element>().is_some_and(|potential_host| {
|
||||||
let Some(root) = potential_host.shadow_root() else {
|
let Some(root) = potential_host.shadow_root() else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -1310,12 +1311,12 @@ impl Node {
|
||||||
.map(|style| style.Display().into());
|
.map(|style| style.Display().into());
|
||||||
|
|
||||||
NodeInfo {
|
NodeInfo {
|
||||||
unique_id: self.unique_id(),
|
unique_id: self.unique_id(pipeline),
|
||||||
host,
|
host,
|
||||||
base_uri,
|
base_uri,
|
||||||
parent: self
|
parent: self
|
||||||
.GetParentNode()
|
.GetParentNode()
|
||||||
.map_or("".to_owned(), |node| node.unique_id()),
|
.map_or("".to_owned(), |node| node.unique_id(pipeline)),
|
||||||
node_type,
|
node_type,
|
||||||
is_top_level_document: node_type == NodeConstants::DOCUMENT_NODE,
|
is_top_level_document: node_type == NodeConstants::DOCUMENT_NODE,
|
||||||
node_name: String::from(self.NodeName()),
|
node_name: String::from(self.NodeName()),
|
||||||
|
|
|
@ -194,6 +194,8 @@ pub(crate) struct IncompleteParserContexts(RefCell<Vec<(PipelineId, ParserContex
|
||||||
|
|
||||||
unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>);
|
unsafe_no_jsmanaged_fields!(TaskQueue<MainThreadScriptMsg>);
|
||||||
|
|
||||||
|
type NodeIdSet = HashSet<String>;
|
||||||
|
|
||||||
#[derive(JSTraceable)]
|
#[derive(JSTraceable)]
|
||||||
// ScriptThread instances are rooted on creation, so this is okay
|
// ScriptThread instances are rooted on creation, so this is okay
|
||||||
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
#[cfg_attr(crown, allow(crown::unrooted_must_root))]
|
||||||
|
@ -315,8 +317,9 @@ pub struct ScriptThread {
|
||||||
#[no_trace]
|
#[no_trace]
|
||||||
player_context: WindowGLContext,
|
player_context: WindowGLContext,
|
||||||
|
|
||||||
/// A set of all nodes ever created in this script thread
|
/// A map from pipelines to all owned nodes ever created in this script thread
|
||||||
node_ids: DomRefCell<HashSet<String>>,
|
#[no_trace]
|
||||||
|
pipeline_to_node_ids: DomRefCell<HashMap<PipelineId, NodeIdSet>>,
|
||||||
|
|
||||||
/// Code is running as a consequence of a user interaction
|
/// Code is running as a consequence of a user interaction
|
||||||
is_user_interacting: Cell<bool>,
|
is_user_interacting: Cell<bool>,
|
||||||
|
@ -818,14 +821,25 @@ impl ScriptThread {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn save_node_id(node_id: String) {
|
pub(crate) fn save_node_id(pipeline: PipelineId, node_id: String) {
|
||||||
with_script_thread(|script_thread| {
|
with_script_thread(|script_thread| {
|
||||||
script_thread.node_ids.borrow_mut().insert(node_id);
|
script_thread
|
||||||
|
.pipeline_to_node_ids
|
||||||
|
.borrow_mut()
|
||||||
|
.entry(pipeline)
|
||||||
|
.or_insert_with(HashSet::new)
|
||||||
|
.insert(node_id);
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn has_node_id(node_id: &str) -> bool {
|
pub(crate) fn has_node_id(pipeline: PipelineId, node_id: &str) -> bool {
|
||||||
with_script_thread(|script_thread| script_thread.node_ids.borrow().contains(node_id))
|
with_script_thread(|script_thread| {
|
||||||
|
script_thread
|
||||||
|
.pipeline_to_node_ids
|
||||||
|
.borrow()
|
||||||
|
.get(&pipeline)
|
||||||
|
.is_some_and(|node_ids| node_ids.contains(node_id))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Creates a new script thread.
|
/// Creates a new script thread.
|
||||||
|
@ -945,7 +959,7 @@ impl ScriptThread {
|
||||||
unminify_css: opts.unminify_css,
|
unminify_css: opts.unminify_css,
|
||||||
user_content_manager: state.user_content_manager,
|
user_content_manager: state.user_content_manager,
|
||||||
player_context: state.player_context,
|
player_context: state.player_context,
|
||||||
node_ids: Default::default(),
|
pipeline_to_node_ids: Default::default(),
|
||||||
is_user_interacting: Cell::new(false),
|
is_user_interacting: Cell::new(false),
|
||||||
#[cfg(feature = "webgpu")]
|
#[cfg(feature = "webgpu")]
|
||||||
gpu_id_hub: Arc::new(IdentityHub::default()),
|
gpu_id_hub: Arc::new(IdentityHub::default()),
|
||||||
|
|
|
@ -81,7 +81,7 @@ fn find_node_by_unique_id(
|
||||||
match documents.find_document(pipeline) {
|
match documents.find_document(pipeline) {
|
||||||
Some(doc) => find_node_by_unique_id_in_document(&doc, node_id),
|
Some(doc) => find_node_by_unique_id_in_document(&doc, node_id),
|
||||||
None => {
|
None => {
|
||||||
if ScriptThread::has_node_id(&node_id) {
|
if ScriptThread::has_node_id(pipeline, &node_id) {
|
||||||
Err(ErrorStatus::StaleElementReference)
|
Err(ErrorStatus::StaleElementReference)
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorStatus::NoSuchElement)
|
Err(ErrorStatus::NoSuchElement)
|
||||||
|
@ -94,14 +94,15 @@ pub(crate) fn find_node_by_unique_id_in_document(
|
||||||
document: &Document,
|
document: &Document,
|
||||||
node_id: String,
|
node_id: String,
|
||||||
) -> Result<DomRoot<Node>, ErrorStatus> {
|
) -> Result<DomRoot<Node>, ErrorStatus> {
|
||||||
|
let pipeline = document.window().pipeline_id();
|
||||||
match document
|
match document
|
||||||
.upcast::<Node>()
|
.upcast::<Node>()
|
||||||
.traverse_preorder(ShadowIncluding::Yes)
|
.traverse_preorder(ShadowIncluding::Yes)
|
||||||
.find(|node| node.unique_id() == node_id)
|
.find(|node| node.unique_id(pipeline) == node_id)
|
||||||
{
|
{
|
||||||
Some(node) => Ok(node),
|
Some(node) => Ok(node),
|
||||||
None => {
|
None => {
|
||||||
if ScriptThread::has_node_id(&node_id) {
|
if ScriptThread::has_node_id(pipeline, &node_id) {
|
||||||
Err(ErrorStatus::StaleElementReference)
|
Err(ErrorStatus::StaleElementReference)
|
||||||
} else {
|
} else {
|
||||||
Err(ErrorStatus::NoSuchElement)
|
Err(ErrorStatus::NoSuchElement)
|
||||||
|
@ -129,7 +130,10 @@ fn matching_links(
|
||||||
content == link_text
|
content == link_text
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.map(|node| node.upcast::<Node>().unique_id())
|
.map(|node| {
|
||||||
|
node.upcast::<Node>()
|
||||||
|
.unique_id(node.owner_doc().window().pipeline_id())
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn all_matching_links(
|
fn all_matching_links(
|
||||||
|
@ -329,21 +333,26 @@ unsafe fn jsval_to_webdriver_inner(
|
||||||
Ok(WebDriverJSValue::ArrayLike(result))
|
Ok(WebDriverJSValue::ArrayLike(result))
|
||||||
} else if let Ok(element) = root_from_object::<Element>(*object, cx) {
|
} else if let Ok(element) = root_from_object::<Element>(*object, cx) {
|
||||||
Ok(WebDriverJSValue::Element(WebElement(
|
Ok(WebDriverJSValue::Element(WebElement(
|
||||||
element.upcast::<Node>().unique_id(),
|
element
|
||||||
|
.upcast::<Node>()
|
||||||
|
.unique_id(element.owner_document().window().pipeline_id()),
|
||||||
)))
|
)))
|
||||||
} else if let Ok(window) = root_from_object::<Window>(*object, cx) {
|
} else if let Ok(window) = root_from_object::<Window>(*object, cx) {
|
||||||
let window_proxy = window.window_proxy();
|
let window_proxy = window.window_proxy();
|
||||||
if window_proxy.is_browsing_context_discarded() {
|
if window_proxy.is_browsing_context_discarded() {
|
||||||
return Err(WebDriverJSError::StaleElementReference);
|
return Err(WebDriverJSError::StaleElementReference);
|
||||||
} else if window_proxy.browsing_context_id() == window_proxy.webview_id() {
|
} else {
|
||||||
|
let pipeline = window.pipeline_id();
|
||||||
|
if window_proxy.browsing_context_id() == window_proxy.webview_id() {
|
||||||
Ok(WebDriverJSValue::Window(WebWindow(
|
Ok(WebDriverJSValue::Window(WebWindow(
|
||||||
window.Document().upcast::<Node>().unique_id(),
|
window.Document().upcast::<Node>().unique_id(pipeline),
|
||||||
)))
|
)))
|
||||||
} else {
|
} else {
|
||||||
Ok(WebDriverJSValue::Frame(WebFrame(
|
Ok(WebDriverJSValue::Frame(WebFrame(
|
||||||
window.Document().upcast::<Node>().unique_id(),
|
window.Document().upcast::<Node>().unique_id(pipeline),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
}
|
||||||
} else if object_has_to_json_property(cx, global_scope, object.handle()) {
|
} else if object_has_to_json_property(cx, global_scope, object.handle()) {
|
||||||
let name = CString::new("toJSON").unwrap();
|
let name = CString::new("toJSON").unwrap();
|
||||||
rooted!(in(cx) let mut value = UndefinedValue());
|
rooted!(in(cx) let mut value = UndefinedValue());
|
||||||
|
@ -598,7 +607,7 @@ pub(crate) fn handle_find_element_css(
|
||||||
.QuerySelector(DOMString::from(selector))
|
.QuerySelector(DOMString::from(selector))
|
||||||
.map_err(|_| ErrorStatus::InvalidSelector)
|
.map_err(|_| ErrorStatus::InvalidSelector)
|
||||||
})
|
})
|
||||||
.map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
|
.map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -640,7 +649,7 @@ pub(crate) fn handle_find_element_tag_name(
|
||||||
.elements_iter()
|
.elements_iter()
|
||||||
.next()
|
.next()
|
||||||
})
|
})
|
||||||
.map(|node| node.map(|x| x.upcast::<Node>().unique_id())),
|
.map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline))),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -664,7 +673,7 @@ pub(crate) fn handle_find_elements_css(
|
||||||
.map(|nodes| {
|
.map(|nodes| {
|
||||||
nodes
|
nodes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.upcast::<Node>().unique_id())
|
.map(|x| x.upcast::<Node>().unique_id(pipeline))
|
||||||
.collect()
|
.collect()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -706,7 +715,7 @@ pub(crate) fn handle_find_elements_tag_name(
|
||||||
.map(|nodes| {
|
.map(|nodes| {
|
||||||
nodes
|
nodes
|
||||||
.elements_iter()
|
.elements_iter()
|
||||||
.map(|x| x.upcast::<Node>().unique_id())
|
.map(|x| x.upcast::<Node>().unique_id(pipeline))
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -725,7 +734,7 @@ pub(crate) fn handle_find_element_element_css(
|
||||||
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
|
find_node_by_unique_id(documents, pipeline, element_id).and_then(|node| {
|
||||||
node.query_selector(DOMString::from(selector))
|
node.query_selector(DOMString::from(selector))
|
||||||
.map_err(|_| ErrorStatus::InvalidSelector)
|
.map_err(|_| ErrorStatus::InvalidSelector)
|
||||||
.map(|node| node.map(|x| x.upcast::<Node>().unique_id()))
|
.map(|node| node.map(|x| x.upcast::<Node>().unique_id(pipeline)))
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
@ -764,7 +773,7 @@ pub(crate) fn handle_find_element_element_tag_name(
|
||||||
.GetElementsByTagName(DOMString::from(selector), can_gc)
|
.GetElementsByTagName(DOMString::from(selector), can_gc)
|
||||||
.elements_iter()
|
.elements_iter()
|
||||||
.next()
|
.next()
|
||||||
.map(|x| x.upcast::<Node>().unique_id())),
|
.map(|x| x.upcast::<Node>().unique_id(pipeline))),
|
||||||
None => Err(ErrorStatus::UnknownError),
|
None => Err(ErrorStatus::UnknownError),
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
@ -786,7 +795,7 @@ pub(crate) fn handle_find_element_elements_css(
|
||||||
.map(|nodes| {
|
.map(|nodes| {
|
||||||
nodes
|
nodes
|
||||||
.iter()
|
.iter()
|
||||||
.map(|x| x.upcast::<Node>().unique_id())
|
.map(|x| x.upcast::<Node>().unique_id(pipeline))
|
||||||
.collect()
|
.collect()
|
||||||
})
|
})
|
||||||
}),
|
}),
|
||||||
|
@ -826,7 +835,7 @@ pub(crate) fn handle_find_element_elements_tag_name(
|
||||||
Some(element) => Ok(element
|
Some(element) => Ok(element
|
||||||
.GetElementsByTagName(DOMString::from(selector), can_gc)
|
.GetElementsByTagName(DOMString::from(selector), can_gc)
|
||||||
.elements_iter()
|
.elements_iter()
|
||||||
.map(|x| x.upcast::<Node>().unique_id())
|
.map(|x| x.upcast::<Node>().unique_id(pipeline))
|
||||||
.collect::<Vec<String>>()),
|
.collect::<Vec<String>>()),
|
||||||
None => Err(ErrorStatus::UnknownError),
|
None => Err(ErrorStatus::UnknownError),
|
||||||
}),
|
}),
|
||||||
|
@ -867,7 +876,7 @@ pub(crate) fn handle_get_active_element(
|
||||||
documents
|
documents
|
||||||
.find_document(pipeline)
|
.find_document(pipeline)
|
||||||
.and_then(|document| document.GetActiveElement())
|
.and_then(|document| document.GetActiveElement())
|
||||||
.map(|element| element.upcast::<Node>().unique_id()),
|
.map(|element| element.upcast::<Node>().unique_id(pipeline)),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
@ -1395,7 +1404,7 @@ pub(crate) fn handle_element_click(
|
||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
},
|
},
|
||||||
None => Ok(Some(node.unique_id())),
|
None => Ok(Some(node.unique_id(pipeline))),
|
||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue