Unify the way html5ever and xml5ever block on script elements (#36284)

Companion PR for https://github.com/servo/html5ever/pull/591

Testing: Covered by WPT
Part of https://github.com/servo/servo/issues/6414,
https://github.com/servo/servo/issues/24898, preparation for
https://github.com/servo/html5ever/pull/590

---------

Signed-off-by: Simon Wülker <simon.wuelker@arcor.de>
This commit is contained in:
Simon Wülker 2025-04-08 18:40:14 +02:00 committed by GitHub
parent ce4ca9ee98
commit 9af9507920
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 53 additions and 54 deletions

View file

@ -84,6 +84,7 @@ libc = { workspace = true }
log = { workspace = true }
malloc_size_of = { workspace = true }
malloc_size_of_derive = { workspace = true }
markup5ever = { workspace = true }
media = { path = "../media" }
metrics = { path = "../metrics" }
mime = { workspace = true }

View file

@ -14,14 +14,14 @@ use crossbeam_channel::{Receiver, Sender, unbounded};
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::fmt::UTF8;
use html5ever::tendril::{SendTendril, StrTendril, Tendril};
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts};
use html5ever::tree_builder::{
ElementFlags, NextParserState, NodeOrText as HtmlNodeOrText, QuirksMode, TreeBuilder,
TreeBuilderOpts, TreeSink,
ElementFlags, NodeOrText as HtmlNodeOrText, QuirksMode, TreeBuilder, TreeBuilderOpts, TreeSink,
};
use html5ever::{
Attribute as HtmlAttribute, ExpandedName, QualName, local_name, namespace_url, ns,
};
use markup5ever::TokenizerResult;
use servo_url::ServoUrl;
use style::context::QuirksMode as ServoQuirksMode;
@ -901,10 +901,6 @@ impl TreeSink for Sink {
self.send_op(ParseOperation::MarkScriptAlreadyStarted { node: node.id });
}
fn complete_script(&self, _: &Self::Handle) -> NextParserState {
panic!("complete_script should not be called here!");
}
fn reparent_children(&self, parent: &Self::Handle, new_parent: &Self::Handle) {
self.send_op(ParseOperation::ReparentChildren {
parent: parent.id,

View file

@ -10,9 +10,10 @@ use std::io;
use html5ever::buffer_queue::BufferQueue;
use html5ever::serialize::TraversalScope::IncludeNode;
use html5ever::serialize::{AttrRef, Serialize, Serializer, TraversalScope};
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts, TokenizerResult};
use html5ever::tokenizer::{Tokenizer as HtmlTokenizer, TokenizerOpts};
use html5ever::tree_builder::{TreeBuilder, TreeBuilderOpts};
use html5ever::{QualName, local_name, namespace_url, ns};
use markup5ever::TokenizerResult;
use script_bindings::trace::CustomTraceable;
use servo_url::ServoUrl;
use xml5ever::LocalName;

View file

@ -16,10 +16,10 @@ use encoding_rs::Encoding;
use html5ever::buffer_queue::BufferQueue;
use html5ever::tendril::fmt::UTF8;
use html5ever::tendril::{ByteTendril, StrTendril, TendrilSink};
use html5ever::tokenizer::TokenizerResult;
use html5ever::tree_builder::{ElementFlags, NextParserState, NodeOrText, QuirksMode, TreeSink};
use html5ever::tree_builder::{ElementFlags, NodeOrText, QuirksMode, TreeSink};
use html5ever::{Attribute, ExpandedName, LocalName, QualName, local_name, namespace_url, ns};
use hyper_serde::Serde;
use markup5ever::TokenizerResult;
use mime::{self, Mime};
use net_traits::request::RequestId;
use net_traits::{
@ -1356,15 +1356,6 @@ impl TreeSink for Sink {
}
}
fn complete_script(&self, node: &Dom<Node>) -> NextParserState {
if let Some(script) = node.downcast() {
self.script.set(Some(script));
NextParserState::Suspend
} else {
NextParserState::Continue
}
}
fn reparent_children(&self, node: &Dom<Node>, new_parent: &Dom<Node>) {
while let Some(ref child) = node.GetFirstChild() {
new_parent.AppendChild(child, CanGc::note()).unwrap();

View file

@ -10,10 +10,11 @@ use content_security_policy::Destination;
use html5ever::buffer_queue::BufferQueue;
use html5ever::tokenizer::states::RawKind;
use html5ever::tokenizer::{
Tag, TagKind, Token, TokenSink, TokenSinkResult, Tokenizer as HtmlTokenizer, TokenizerResult,
Tag, TagKind, Token, TokenSink, TokenSinkResult, Tokenizer as HtmlTokenizer,
};
use html5ever::{Attribute, LocalName, local_name};
use js::jsapi::JSTracer;
use markup5ever::TokenizerResult;
use net_traits::request::{
CorsSettings, CredentialsMode, InsecureRequestsPolicy, ParserMetadata, Referrer,
};

View file

@ -6,13 +6,14 @@
use std::cell::Cell;
use html5ever::tokenizer::TokenizerResult;
use markup5ever::TokenizerResult;
use script_bindings::trace::CustomTraceable;
use servo_url::ServoUrl;
use xml5ever::buffer_queue::BufferQueue;
use xml5ever::tokenizer::XmlTokenizer;
use xml5ever::tree_builder::XmlTreeBuilder;
use crate::dom::bindings::inheritance::Castable;
use crate::dom::bindings::root::{Dom, DomRoot};
use crate::dom::document::Document;
use crate::dom::htmlscriptelement::HTMLScriptElement;
@ -43,10 +44,17 @@ impl Tokenizer {
}
pub(crate) fn feed(&self, input: &BufferQueue) -> TokenizerResult<DomRoot<HTMLScriptElement>> {
self.inner.run(input);
match self.inner.sink.sink.script.take() {
Some(script) => TokenizerResult::Script(script),
None => TokenizerResult::Done,
loop {
match self.inner.run(input) {
TokenizerResult::Done => return TokenizerResult::Done,
TokenizerResult::Script(handle) => {
// Apparently the parser can sometimes create <script> elements without a namespace, resulting
// in them not being HTMLScriptElements.
if let Some(script) = handle.downcast::<HTMLScriptElement>() {
return TokenizerResult::Script(DomRoot::from_ref(script));
}
},
}
}
}