diff options
author | Andriy Sultanov <53952748+last-genius@users.noreply.github.com> | 2024-09-09 23:38:01 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-09-09 22:38:01 +0000 |
commit | e5150dbda1f89ff07294dbd1ca4e8f4f08cf4874 (patch) | |
tree | e77fae25f33905e1c8c626cf532e7222f521335c /components/script/dom/servoparser | |
parent | 10e5bb72d9e16655b625b8971e346ff479b17fd2 (diff) | |
download | servo-e5150dbda1f89ff07294dbd1ca4e8f4f08cf4874.tar.gz servo-e5150dbda1f89ff07294dbd1ca4e8f4f08cf4874.zip |
Propagate `CanGc` from `Document::new()` (#33386)
* Add canGc as a parameter to autogenerated trait methods
Signed-off-by: Andriy Sultanov <sultanovandriy@gmail.com>
* Propagate CanGc from Document::new()
Signed-off-by: Andriy Sultanov <sultanovandriy@gmail.com>
---------
Signed-off-by: Andriy Sultanov <sultanovandriy@gmail.com>
Diffstat (limited to 'components/script/dom/servoparser')
-rw-r--r-- | components/script/dom/servoparser/async_html.rs | 38 | ||||
-rw-r--r-- | components/script/dom/servoparser/html.rs | 3 | ||||
-rw-r--r-- | components/script/dom/servoparser/mod.rs | 126 |
3 files changed, 107 insertions, 60 deletions
diff --git a/components/script/dom/servoparser/async_html.rs b/components/script/dom/servoparser/async_html.rs index 551692af1f8..be8adb01e09 100644 --- a/components/script/dom/servoparser/async_html.rs +++ b/components/script/dom/servoparser/async_html.rs @@ -41,6 +41,7 @@ use crate::dom::node::Node; use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::servoparser::{create_element_for_token, ElementAttribute, ParsingAlgorithm}; use crate::dom::virtualmethods::vtable_for; +use crate::script_runtime::CanGc; type ParseNodeId = usize; @@ -283,7 +284,11 @@ impl Tokenizer { tokenizer } - pub fn feed(&self, input: &BufferQueue) -> TokenizerResult<DomRoot<HTMLScriptElement>> { + pub fn feed( + &self, + input: &BufferQueue, + _can_gc: CanGc, + ) -> TokenizerResult<DomRoot<HTMLScriptElement>> { let mut send_tendrils = VecDeque::new(); while let Some(str) = input.pop_front() { send_tendrils.push_back(SendTendril::from(str)); @@ -303,7 +308,9 @@ impl Tokenizer { .recv() .expect("Unexpected channel panic in main thread.") { - ToTokenizerMsg::ProcessOperation(parse_op) => self.process_operation(parse_op), + ToTokenizerMsg::ProcessOperation(parse_op) => { + self.process_operation(parse_op, CanGc::note()) + }, ToTokenizerMsg::TokenizerResultDone { updated_input } => { let buffer_queue = create_buffer_queue(updated_input); input.replace_with(buffer_queue); @@ -323,7 +330,7 @@ impl Tokenizer { } } - pub fn end(&self) { + pub fn end(&self, _can_gc: CanGc) { self.html_tokenizer_sender .send(ToHtmlTokenizerMsg::End) .unwrap(); @@ -333,7 +340,9 @@ impl Tokenizer { .recv() .expect("Unexpected channel panic in main thread.") { - ToTokenizerMsg::ProcessOperation(parse_op) => self.process_operation(parse_op), + ToTokenizerMsg::ProcessOperation(parse_op) => { + self.process_operation(parse_op, CanGc::note()) + }, ToTokenizerMsg::TokenizerResultDone { updated_input: _ } | ToTokenizerMsg::TokenizerResultScript { script: _, @@ -364,7 +373,7 @@ impl Tokenizer { }) } - fn append_before_sibling(&self, sibling: ParseNodeId, node: NodeOrText) { + fn append_before_sibling(&self, sibling: ParseNodeId, node: NodeOrText, can_gc: CanGc) { let node = match node { NodeOrText::Node(n) => { HtmlNodeOrText::AppendNode(Dom::from_ref(&**self.get_node(&n.id))) @@ -376,10 +385,10 @@ impl Tokenizer { .GetParentNode() .expect("append_before_sibling called on node without parent"); - super::insert(parent, Some(sibling), node, self.parsing_algorithm); + super::insert(parent, Some(sibling), node, self.parsing_algorithm, can_gc); } - fn append(&self, parent: ParseNodeId, node: NodeOrText) { + fn append(&self, parent: ParseNodeId, node: NodeOrText, can_gc: CanGc) { let node = match node { NodeOrText::Node(n) => { HtmlNodeOrText::AppendNode(Dom::from_ref(&**self.get_node(&n.id))) @@ -388,7 +397,7 @@ impl Tokenizer { }; let parent = &**self.get_node(&parent); - super::insert(parent, None, node, self.parsing_algorithm); + super::insert(parent, None, node, self.parsing_algorithm, can_gc); } fn has_parent_node(&self, node: ParseNodeId) -> bool { @@ -404,7 +413,7 @@ impl Tokenizer { x.is_in_same_home_subtree(y) } - fn process_operation(&self, op: ParseOperation) { + fn process_operation(&self, op: ParseOperation, can_gc: CanGc) { let document = DomRoot::from_ref(&**self.get_node(&0)); let document = document .downcast::<Document>() @@ -415,7 +424,7 @@ impl Tokenizer { let template = target .downcast::<HTMLTemplateElement>() .expect("Tried to extract contents from non-template element while parsing"); - self.insert_node(contents, Dom::from_ref(template.Content().upcast())); + self.insert_node(contents, Dom::from_ref(template.Content(can_gc).upcast())); }, ParseOperation::CreateElement { node, @@ -433,6 +442,7 @@ impl Tokenizer { &self.document, ElementCreator::ParserCreated(current_line), ParsingAlgorithm::Normal, + can_gc, ); self.insert_node(node, Dom::from_ref(element.upcast())); }, @@ -441,10 +451,10 @@ impl Tokenizer { self.insert_node(node, Dom::from_ref(comment.upcast())); }, ParseOperation::AppendBeforeSibling { sibling, node } => { - self.append_before_sibling(sibling, node); + self.append_before_sibling(sibling, node, can_gc); }, ParseOperation::Append { parent, node } => { - self.append(parent, node); + self.append(parent, node, can_gc); }, ParseOperation::AppendBasedOnParentNode { element, @@ -452,9 +462,9 @@ impl Tokenizer { node, } => { if self.has_parent_node(element) { - self.append_before_sibling(element, node); + self.append_before_sibling(element, node, can_gc); } else { - self.append(prev_element, node); + self.append(prev_element, node, can_gc); } }, ParseOperation::AppendDoctypeToDocument { diff --git a/components/script/dom/servoparser/html.rs b/components/script/dom/servoparser/html.rs index b3184923609..a2ef2a323fd 100644 --- a/components/script/dom/servoparser/html.rs +++ b/components/script/dom/servoparser/html.rs @@ -30,6 +30,7 @@ use crate::dom::htmltemplateelement::HTMLTemplateElement; use crate::dom::node::Node; use crate::dom::processinginstruction::ProcessingInstruction; use crate::dom::servoparser::{ParsingAlgorithm, Sink}; +use crate::script_runtime::CanGc; #[derive(JSTraceable, MallocSizeOf)] #[crown::unrooted_must_root_lint::must_root] @@ -163,7 +164,7 @@ fn rev_children_iter(n: &Node) -> impl Iterator<Item = DomRoot<Node>> { } match n.downcast::<HTMLTemplateElement>() { - Some(t) => t.Content().upcast::<Node>().rev_children(), + Some(t) => t.Content(CanGc::note()).upcast::<Node>().rev_children(), None => n.rev_children(), } } diff --git a/components/script/dom/servoparser/mod.rs b/components/script/dom/servoparser/mod.rs index f6c7af85838..958b2bbf3db 100644 --- a/components/script/dom/servoparser/mod.rs +++ b/components/script/dom/servoparser/mod.rs @@ -67,6 +67,7 @@ use crate::dom::text::Text; use crate::dom::virtualmethods::vtable_for; use crate::network_listener::PreInvoke; use crate::realms::enter_realm; +use crate::script_runtime::CanGc; use crate::script_thread::ScriptThread; mod async_html; @@ -150,7 +151,12 @@ impl ServoParser { self.can_write() } - pub fn parse_html_document(document: &Document, input: Option<DOMString>, url: ServoUrl) { + pub fn parse_html_document( + document: &Document, + input: Option<DOMString>, + url: ServoUrl, + can_gc: CanGc, + ) { let parser = if pref!(dom.servoparser.async_html_tokenizer.enabled) { ServoParser::new( document, @@ -172,7 +178,7 @@ impl ServoParser { // Set as the document's current parser and initialize with `input`, if given. if let Some(input) = input { - parser.parse_complete_string_chunk(String::from(input)); + parser.parse_complete_string_chunk(String::from(input), can_gc); } else { parser.document.set_current_parser(Some(&parser)); } @@ -182,6 +188,7 @@ impl ServoParser { pub fn parse_html_fragment( context: &Element, input: DOMString, + can_gc: CanGc, ) -> impl Iterator<Item = DomRoot<Node>> { let context_node = context.upcast::<Node>(); let context_document = context_node.owner_doc(); @@ -208,6 +215,7 @@ impl ServoParser { None, None, Default::default(), + can_gc, ); // Step 2. @@ -233,7 +241,7 @@ impl ServoParser { )), ParserKind::Normal, ); - parser.parse_complete_string_chunk(String::from(input)); + parser.parse_complete_string_chunk(String::from(input), CanGc::note()); // Step 14. let root_element = document.GetDocumentElement().expect("no document element"); @@ -257,7 +265,12 @@ impl ServoParser { document.set_current_parser(Some(&parser)); } - pub fn parse_xml_document(document: &Document, input: Option<DOMString>, url: ServoUrl) { + pub fn parse_xml_document( + document: &Document, + input: Option<DOMString>, + url: ServoUrl, + can_gc: CanGc, + ) { let parser = ServoParser::new( document, Tokenizer::Xml(self::xml::Tokenizer::new(document, url)), @@ -266,7 +279,7 @@ impl ServoParser { // Set as the document's current parser and initialize with `input`, if given. if let Some(input) = input { - parser.parse_complete_string_chunk(String::from(input)); + parser.parse_complete_string_chunk(String::from(input), can_gc); } else { parser.document.set_current_parser(Some(&parser)); } @@ -298,6 +311,7 @@ impl ServoParser { &self, script: &HTMLScriptElement, result: ScriptResult, + can_gc: CanGc, ) { assert!(self.suspended.get()); self.suspended.set(false); @@ -315,7 +329,7 @@ impl ServoParser { self.script_nesting_level.set(script_nesting_level); if !self.suspended.get() && !self.aborted.get() { - self.parse_sync(); + self.parse_sync(can_gc); } } @@ -324,7 +338,7 @@ impl ServoParser { } /// Steps 6-8 of <https://html.spec.whatwg.org/multipage/#document.write()> - pub fn write(&self, text: Vec<DOMString>) { + pub fn write(&self, text: Vec<DOMString>, _can_gc: CanGc) { assert!(self.can_write()); if self.document.has_pending_parsing_blocking_script() { @@ -347,7 +361,7 @@ impl ServoParser { input.push_back(String::from(chunk).into()); } - self.tokenize(|tokenizer| tokenizer.feed(&input)); + self.tokenize(|tokenizer| tokenizer.feed(&input, CanGc::note())); if self.suspended.get() { // Parser got suspended, insert remaining input at end of @@ -363,7 +377,7 @@ impl ServoParser { } // Steps 4-6 of https://html.spec.whatwg.org/multipage/#dom-document-close - pub fn close(&self) { + pub fn close(&self, can_gc: CanGc) { assert!(self.script_created_parser); // Step 4. @@ -375,11 +389,11 @@ impl ServoParser { } // Step 6. - self.parse_sync(); + self.parse_sync(can_gc); } // https://html.spec.whatwg.org/multipage/#abort-a-parser - pub fn abort(&self) { + pub fn abort(&self, can_gc: CanGc) { assert!(!self.aborted.get()); self.aborted.set(true); @@ -392,7 +406,7 @@ impl ServoParser { .set_ready_state(DocumentReadyState::Interactive); // Step 3. - self.tokenizer.end(); + self.tokenizer.end(can_gc); self.document.set_current_parser(None); // Step 4. @@ -499,7 +513,7 @@ impl ServoParser { self.push_tendril_input_chunk(chunk); } - fn parse_sync(&self) { + fn parse_sync(&self, can_gc: CanGc) { let metadata = TimerMetadata { url: self.document.url().as_str().into(), iframe: TimerMetadataFrameType::RootWindow, @@ -514,11 +528,11 @@ impl ServoParser { .upcast::<GlobalScope>() .time_profiler_chan() .clone(), - || self.do_parse_sync(), + || self.do_parse_sync(can_gc), ) } - fn do_parse_sync(&self) { + fn do_parse_sync(&self, _can_gc: CanGc) { assert!(self.script_input.is_empty()); // This parser will continue to parse while there is either pending input or @@ -532,7 +546,7 @@ impl ServoParser { } } } - self.tokenize(|tokenizer| tokenizer.feed(&self.network_input)); + self.tokenize(|tokenizer| tokenizer.feed(&self.network_input, CanGc::note())); if self.suspended.get() { return; @@ -541,24 +555,24 @@ impl ServoParser { assert!(self.network_input.is_empty()); if self.last_chunk_received.get() { - self.finish(); + self.finish(CanGc::note()); } } - fn parse_complete_string_chunk(&self, input: String) { + fn parse_complete_string_chunk(&self, input: String, can_gc: CanGc) { self.document.set_current_parser(Some(self)); self.push_string_input_chunk(input); self.last_chunk_received.set(true); if !self.suspended.get() { - self.parse_sync(); + self.parse_sync(can_gc); } } - fn parse_bytes_chunk(&self, input: Vec<u8>) { + fn parse_bytes_chunk(&self, input: Vec<u8>, can_gc: CanGc) { self.document.set_current_parser(Some(self)); self.push_bytes_input_chunk(input); if !self.suspended.get() { - self.parse_sync(); + self.parse_sync(can_gc); } } @@ -586,7 +600,7 @@ impl ServoParser { self.document .window() .upcast::<GlobalScope>() - .perform_a_microtask_checkpoint(); + .perform_a_microtask_checkpoint(CanGc::note()); } let script_nesting_level = self.script_nesting_level.get(); @@ -606,7 +620,7 @@ impl ServoParser { } // https://html.spec.whatwg.org/multipage/#the-end - fn finish(&self) { + fn finish(&self, can_gc: CanGc) { assert!(!self.suspended.get()); assert!(self.last_chunk_received.get()); assert!(self.script_input.is_empty()); @@ -618,12 +632,13 @@ impl ServoParser { .set_ready_state(DocumentReadyState::Interactive); // Step 2. - self.tokenizer.end(); + self.tokenizer.end(can_gc); self.document.set_current_parser(None); // Steps 3-12 are in another castle, namely finish_load. let url = self.tokenizer.url().clone(); - self.document.finish_load(LoadType::PageSource(url)); + self.document + .finish_load(LoadType::PageSource(url), CanGc::note()); } } @@ -666,18 +681,22 @@ enum Tokenizer { } impl Tokenizer { - fn feed(&self, input: &BufferQueue) -> TokenizerResult<DomRoot<HTMLScriptElement>> { + fn feed( + &self, + input: &BufferQueue, + can_gc: CanGc, + ) -> TokenizerResult<DomRoot<HTMLScriptElement>> { match *self { Tokenizer::Html(ref tokenizer) => tokenizer.feed(input), - Tokenizer::AsyncHtml(ref tokenizer) => tokenizer.feed(input), + Tokenizer::AsyncHtml(ref tokenizer) => tokenizer.feed(input, can_gc), Tokenizer::Xml(ref tokenizer) => tokenizer.feed(input), } } - fn end(&self) { + fn end(&self, can_gc: CanGc) { match *self { Tokenizer::Html(ref tokenizer) => tokenizer.end(), - Tokenizer::AsyncHtml(ref tokenizer) => tokenizer.end(), + Tokenizer::AsyncHtml(ref tokenizer) => tokenizer.end(can_gc), Tokenizer::Xml(ref tokenizer) => tokenizer.end(), } } @@ -797,7 +816,7 @@ impl FetchResponseListener for ParserContext { Some(csp_list) }); - let parser = match ScriptThread::page_headers_available(&self.id, metadata) { + let parser = match ScriptThread::page_headers_available(&self.id, metadata, CanGc::note()) { Some(parser) => parser, None => return, }; @@ -829,7 +848,7 @@ impl FetchResponseListener for ParserContext { self.is_synthesized_document = true; let page = "<html><body></body></html>".into(); parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); let doc = &parser.document; let doc_body = DomRoot::upcast::<Node>(doc.GetBody().unwrap()); @@ -843,7 +862,7 @@ impl FetchResponseListener for ParserContext { // https://html.spec.whatwg.org/multipage/#read-text let page = "<pre>\n".into(); parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); parser.tokenizer.set_plaintext_state(); }, (mime::TEXT, mime::HTML, _) => match error { @@ -856,21 +875,21 @@ impl FetchResponseListener for ParserContext { let page = page.replace("${secret}", &net_traits::PRIVILEGED_SECRET.to_string()); parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); }, Some(NetworkError::Internal(reason)) => { self.is_synthesized_document = true; let page = resources::read_string(Resource::NetErrorHTML); let page = page.replace("${reason}", &reason); parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); }, Some(NetworkError::Crash(details)) => { self.is_synthesized_document = true; let page = resources::read_string(Resource::CrashHTML); let page = page.replace("${details}", &details); parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); }, Some(_) => {}, None => {}, @@ -888,7 +907,7 @@ impl FetchResponseListener for ParserContext { ); self.is_synthesized_document = true; parser.push_string_input_chunk(page); - parser.parse_sync(); + parser.parse_sync(CanGc::note()); }, } } @@ -905,7 +924,7 @@ impl FetchResponseListener for ParserContext { return; } let _realm = enter_realm(&*parser); - parser.parse_bytes_chunk(payload); + parser.parse_bytes_chunk(payload, CanGc::note()); } // This method is called via script_thread::handle_fetch_eof, so we must call @@ -935,7 +954,7 @@ impl FetchResponseListener for ParserContext { parser.last_chunk_received.set(true); if !parser.suspended.get() { - parser.parse_sync(); + parser.parse_sync(CanGc::note()); } // TODO: Only update if this is the current document resource. @@ -1000,6 +1019,7 @@ fn insert( reference_child: Option<&Node>, child: NodeOrText<Dom<Node>>, parsing_algorithm: ParsingAlgorithm, + can_gc: CanGc, ) { match child { NodeOrText::AppendNode(n) => { @@ -1013,7 +1033,7 @@ fn insert( } parent.InsertBefore(&n, reference_child).unwrap(); if element_in_non_fragment { - ScriptThread::pop_current_element_queue(); + ScriptThread::pop_current_element_queue(can_gc); } }, NodeOrText::AppendText(t) => { @@ -1076,7 +1096,7 @@ impl TreeSink for Sink { let template = target .downcast::<HTMLTemplateElement>() .expect("tried to get template contents of non-HTMLTemplateElement in HTML parsing"); - Dom::from_ref(template.Content().upcast()) + Dom::from_ref(template.Content(CanGc::note()).upcast()) } fn same_node(&self, x: &Dom<Node>, y: &Dom<Node>) -> bool { @@ -1110,6 +1130,7 @@ impl TreeSink for Sink { &self.document, ElementCreator::ParserCreated(self.current_line.get()), self.parsing_algorithm, + CanGc::note(), ); Dom::from_ref(element.upcast()) } @@ -1167,7 +1188,13 @@ impl TreeSink for Sink { .GetParentNode() .expect("append_before_sibling called on node without parent"); - insert(&parent, Some(sibling), new_node, self.parsing_algorithm); + insert( + &parent, + Some(sibling), + new_node, + self.parsing_algorithm, + CanGc::note(), + ); } fn parse_error(&self, msg: Cow<'static, str>) { @@ -1185,7 +1212,7 @@ impl TreeSink for Sink { #[allow(crown::unrooted_must_root)] fn append(&self, parent: &Dom<Node>, child: NodeOrText<Dom<Node>>) { - insert(parent, None, child, self.parsing_algorithm); + insert(parent, None, child, self.parsing_algorithm, CanGc::note()); } #[allow(crown::unrooted_must_root)] @@ -1289,6 +1316,7 @@ fn create_element_for_token( document: &Document, creator: ElementCreator, parsing_algorithm: ParsingAlgorithm, + can_gc: CanGc, ) -> DomRoot<Element> { // Step 3. let is = attrs @@ -1312,7 +1340,7 @@ fn create_element_for_token( document .window() .upcast::<GlobalScope>() - .perform_a_microtask_checkpoint(); + .perform_a_microtask_checkpoint(can_gc); } // Step 6.3 ScriptThread::push_new_element_queue() @@ -1325,7 +1353,15 @@ fn create_element_for_token( CustomElementCreationMode::Asynchronous }; - let element = Element::create(name, is, document, creator, creation_mode, None); + let element = Element::create( + name, + is, + document, + creator, + creation_mode, + None, + CanGc::note(), + ); // https://html.spec.whatwg.org/multipage#the-input-element:value-sanitization-algorithm-3 // says to invoke sanitization "when an input element is first created"; @@ -1353,7 +1389,7 @@ fn create_element_for_token( // Step 9. if will_execute_script { // Steps 9.1 - 9.2. - ScriptThread::pop_current_element_queue(); + ScriptThread::pop_current_element_queue(CanGc::note()); // Step 9.3. document.decrement_throw_on_dynamic_markup_insertion_counter(); } |