Don't use inline scripts and function constructor (#4310)
* Don't use inline scripts and function constructor. This allows a stricter Content-Security-Policy which is required for web extensions. * Load module scripts asynchronously * Extract common code into method * Fix injecting loading script * Append to the file instead of reading and appending to the file string --------- Co-authored-by: Jonathan Kelley <jkelleyrtp@gmail.com> Co-authored-by: Evan Almloff <evanalmloff@gmail.com>
This commit is contained in:
5 files changed
+114
-70
No files matched your search
@@ -1,8 +1,7 @@
|
||||
use dioxus_core::prelude::queue_effect;
|
||||
use dioxus_core::ScopeId;
|
||||
use dioxus_document::{
|
||||
create_element_in_head, Document, Eval, EvalError, Evaluator, LinkProps, MetaProps,
|
||||
ScriptProps, StyleProps,
|
||||
Document, Eval, EvalError, Evaluator, LinkProps, MetaProps, ScriptProps, StyleProps,
|
||||
};
|
||||
use dioxus_history::History;
|
||||
use futures_util::FutureExt;
|
||||
@@ -97,45 +96,60 @@ impl Document for WebDocument {
|
||||
|
||||
/// Create a new meta tag in the head
|
||||
fn create_meta(&self, props: MetaProps) {
|
||||
let myself = self.clone();
|
||||
queue_effect(move || {
|
||||
myself.eval(create_element_in_head("meta", &props.attributes(), None));
|
||||
append_element_to_head("meta", &props.attributes(), None);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a new script tag in the head
|
||||
fn create_script(&self, props: ScriptProps) {
|
||||
let myself = self.clone();
|
||||
queue_effect(move || {
|
||||
myself.eval(create_element_in_head(
|
||||
append_element_to_head(
|
||||
"script",
|
||||
&props.attributes(),
|
||||
props.script_contents().ok(),
|
||||
));
|
||||
props.script_contents().ok().as_deref(),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a new style tag in the head
|
||||
fn create_style(&self, props: StyleProps) {
|
||||
let myself = self.clone();
|
||||
queue_effect(move || {
|
||||
myself.eval(create_element_in_head(
|
||||
append_element_to_head(
|
||||
"style",
|
||||
&props.attributes(),
|
||||
props.style_contents().ok(),
|
||||
));
|
||||
props.style_contents().ok().as_deref(),
|
||||
);
|
||||
});
|
||||
}
|
||||
|
||||
/// Create a new link tag in the head
|
||||
fn create_link(&self, props: LinkProps) {
|
||||
let myself = self.clone();
|
||||
queue_effect(move || {
|
||||
myself.eval(create_element_in_head("link", &props.attributes(), None));
|
||||
append_element_to_head("link", &props.attributes(), None);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
fn append_element_to_head(
|
||||
local_name: &str,
|
||||
attributes: &Vec<(&'static str, String)>,
|
||||
text_content: Option<&str>,
|
||||
) {
|
||||
let window = web_sys::window().expect("no global `window` exists");
|
||||
let document = window.document().expect("should have a document on window");
|
||||
let head = document.head().expect("document should have a head");
|
||||
|
||||
let element = document.create_element(local_name).unwrap();
|
||||
for (name, value) in attributes {
|
||||
element.set_attribute(name, value).unwrap();
|
||||
}
|
||||
if text_content.is_some() {
|
||||
element.set_text_content(text_content);
|
||||
}
|
||||
head.append_child(&element).unwrap();
|
||||
}
|
||||
|
||||
/// Required to avoid blocking the Rust WASM thread.
|
||||
const PROMISE_WRAPPER: &str = r#"
|
||||
return (async function(){
|
||||
|
||||
Reference in new issue
Block a user