mirror of
https://github.com/servo/servo.git
synced 2025-07-23 07:13:52 +01:00
Implement all trusted sinks in HTMLScriptElement
(#36668)
As a follow-up to the recent introduction of `script.src` as trusted sink, this PR refactors machinery to also support `TrustedScript`. In doing so, all trusted sinks in `HTMLScriptElement` are now covered. Instead of calling the callbacks in `policy.createX`, we now have a `TrustedType` enum that specifies which callback to invoke. Unfortunately we still have the `USVString` vs `DOMString` problem, which is why we need to `.map` twice to retrieve the backing `String` and avoid two different types. Additionally, I saw that `script.text` should have called the "String replace all" algorithm rather than setting the child contents. So that's also now fixed. Part of #36258 Requires servo/html5ever#608 Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com> Signed-off-by: Tim van der Lippe <tvanderlippe@gmail.com>
This commit is contained in:
parent
dd63325f50
commit
4164f76769
20 changed files with 320 additions and 353 deletions
|
@ -32,6 +32,7 @@ use net_traits::{
|
|||
};
|
||||
use servo_config::pref;
|
||||
use servo_url::{ImmutableOrigin, ServoUrl};
|
||||
use style::attr::AttrValue;
|
||||
use style::str::{HTML_SPACE_CHARACTERS, StaticStringVec};
|
||||
use stylo_atoms::Atom;
|
||||
use uuid::Uuid;
|
||||
|
@ -44,7 +45,9 @@ use crate::dom::bindings::codegen::Bindings::DocumentBinding::DocumentMethods;
|
|||
use crate::dom::bindings::codegen::Bindings::HTMLScriptElementBinding::HTMLScriptElementMethods;
|
||||
use crate::dom::bindings::codegen::Bindings::NodeBinding::NodeMethods;
|
||||
use crate::dom::bindings::codegen::GenericBindings::HTMLElementBinding::HTMLElement_Binding::HTMLElementMethods;
|
||||
use crate::dom::bindings::codegen::UnionTypes::TrustedScriptURLOrUSVString;
|
||||
use crate::dom::bindings::codegen::UnionTypes::{
|
||||
TrustedScriptOrString, TrustedScriptURLOrUSVString,
|
||||
};
|
||||
use crate::dom::bindings::error::Fallible;
|
||||
use crate::dom::bindings::inheritance::Castable;
|
||||
use crate::dom::bindings::refcounted::Trusted;
|
||||
|
@ -64,6 +67,8 @@ use crate::dom::globalscope::GlobalScope;
|
|||
use crate::dom::htmlelement::HTMLElement;
|
||||
use crate::dom::node::{ChildrenMutation, CloneChildrenFlag, Node, NodeTraits};
|
||||
use crate::dom::performanceresourcetiming::InitiatorType;
|
||||
use crate::dom::trustedscript::TrustedScript;
|
||||
use crate::dom::trustedscripturl::TrustedScriptURL;
|
||||
use crate::dom::virtualmethods::VirtualMethods;
|
||||
use crate::fetch::create_a_potential_cors_request;
|
||||
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
|
||||
|
@ -667,7 +672,7 @@ impl HTMLScriptElement {
|
|||
|
||||
// Step 5. Let source text be el's child text content.
|
||||
// Step 6. If el has no src attribute, and source text is the empty string, then return.
|
||||
let text = self.Text();
|
||||
let text = self.text();
|
||||
if text.is_empty() && !element.has_attribute(&local_name!("src")) {
|
||||
return;
|
||||
}
|
||||
|
@ -1272,6 +1277,15 @@ impl HTMLScriptElement {
|
|||
let event = Event::new(window.upcast(), type_, bubbles, cancelable, can_gc);
|
||||
event.fire(self.upcast(), can_gc)
|
||||
}
|
||||
|
||||
fn text(&self) -> DOMString {
|
||||
match self.Text() {
|
||||
TrustedScriptOrString::String(value) => value,
|
||||
TrustedScriptOrString::TrustedScript(trusted_script) => {
|
||||
DOMString::from(trusted_script.to_string())
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl VirtualMethods for HTMLScriptElement {
|
||||
|
@ -1286,7 +1300,7 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
if *attr.local_name() == local_name!("src") {
|
||||
if let AttributeMutation::Set(_) = mutation {
|
||||
if !self.parser_inserted.get() && self.upcast::<Node>().is_connected() {
|
||||
self.prepare(CanGc::note());
|
||||
self.prepare(can_gc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1344,10 +1358,25 @@ impl VirtualMethods for HTMLScriptElement {
|
|||
|
||||
impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
||||
// https://html.spec.whatwg.org/multipage/#dom-script-src
|
||||
make_trusted_type_url_getter!(Src, "src");
|
||||
fn Src(&self) -> TrustedScriptURLOrUSVString {
|
||||
let element = self.upcast::<Element>();
|
||||
element.get_trusted_type_url_attribute(&local_name!("src"))
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-script-src
|
||||
make_trusted_type_url_setter!(SetSrc, "src");
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#the-src-idl-attribute>
|
||||
fn SetSrc(&self, value: TrustedScriptURLOrUSVString, can_gc: CanGc) -> Fallible<()> {
|
||||
let element = self.upcast::<Element>();
|
||||
let local_name = &local_name!("src");
|
||||
let value = TrustedScriptURL::get_trusted_script_url_compliant_string(
|
||||
&element.owner_global(),
|
||||
value,
|
||||
"HTMLScriptElement",
|
||||
local_name,
|
||||
can_gc,
|
||||
)?;
|
||||
element.set_attribute(local_name, AttrValue::String(value), can_gc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-script-type
|
||||
make_getter!(Type, "type");
|
||||
|
@ -1416,14 +1445,77 @@ impl HTMLScriptElementMethods<crate::DomTypeHolder> for HTMLScriptElement {
|
|||
// https://html.spec.whatwg.org/multipage/#dom-script-referrerpolicy
|
||||
make_setter!(SetReferrerPolicy, "referrerpolicy");
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-script-text
|
||||
fn Text(&self) -> DOMString {
|
||||
self.upcast::<Node>().child_text_content()
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#dom-htmlscriptelement-innertext>
|
||||
fn InnerText(&self, can_gc: CanGc) -> TrustedScriptOrString {
|
||||
// Step 1: Return the result of running get the text steps with this.
|
||||
TrustedScriptOrString::String(self.upcast::<HTMLElement>().get_inner_outer_text(can_gc))
|
||||
}
|
||||
|
||||
// https://html.spec.whatwg.org/multipage/#dom-script-text
|
||||
fn SetText(&self, value: DOMString, can_gc: CanGc) {
|
||||
self.upcast::<Node>().SetTextContent(Some(value), can_gc)
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#the-innerText-idl-attribute>
|
||||
fn SetInnerText(&self, input: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
|
||||
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||
// this's relevant global object, the given value, HTMLScriptElement innerText, and script.
|
||||
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||
&self.owner_global(),
|
||||
input,
|
||||
"HTMLScriptElement",
|
||||
"innerText",
|
||||
can_gc,
|
||||
)?;
|
||||
// Step 3: Run set the inner text steps with this and value.
|
||||
self.upcast::<HTMLElement>()
|
||||
.set_inner_text(DOMString::from(value), can_gc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// <https://html.spec.whatwg.org/multipage/#dom-script-text>
|
||||
fn Text(&self) -> TrustedScriptOrString {
|
||||
TrustedScriptOrString::String(self.upcast::<Node>().child_text_content())
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#the-text-idl-attribute>
|
||||
fn SetText(&self, value: TrustedScriptOrString, can_gc: CanGc) -> Fallible<()> {
|
||||
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||
// this's relevant global object, the given value, HTMLScriptElement text, and script.
|
||||
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||
&self.owner_global(),
|
||||
value,
|
||||
"HTMLScriptElement",
|
||||
"text",
|
||||
can_gc,
|
||||
)?;
|
||||
// Step 2: Set this's script text value to the given value.
|
||||
// TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
|
||||
// Step 3: String replace all with the given value within this.
|
||||
Node::string_replace_all(DOMString::from(value), self.upcast::<Node>(), can_gc);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
|
||||
fn GetTextContent(&self) -> Option<TrustedScriptOrString> {
|
||||
// Step 1: Return the result of running get text content with this.
|
||||
Some(TrustedScriptOrString::String(
|
||||
self.upcast::<Node>().GetTextContent()?,
|
||||
))
|
||||
}
|
||||
|
||||
/// <https://w3c.github.io/trusted-types/dist/spec/#the-textContent-idl-attribute>
|
||||
fn SetTextContent(&self, value: Option<TrustedScriptOrString>, can_gc: CanGc) -> Fallible<()> {
|
||||
// Step 1: Let value be the result of calling Get Trusted Type compliant string with TrustedScript,
|
||||
// this's relevant global object, the given value, HTMLScriptElement textContent, and script.
|
||||
let value = TrustedScript::get_trusted_script_compliant_string(
|
||||
&self.owner_global(),
|
||||
value.unwrap_or(TrustedScriptOrString::String(DOMString::from(""))),
|
||||
"HTMLScriptElement",
|
||||
"textContent",
|
||||
can_gc,
|
||||
)?;
|
||||
// Step 2: Set this's script text value to value.
|
||||
// TODO: Implement for https://w3c.github.io/trusted-types/dist/spec/#prepare-script-text
|
||||
// Step 3: Run set text content with this and value.
|
||||
self.upcast::<Node>()
|
||||
.SetTextContent(Some(DOMString::from(value)), can_gc);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue