Skip to content

Commit 7371b4f

Browse files
committed
Implement run a module script
1 parent 84959b2 commit 7371b4f

File tree

3 files changed

+94
-72
lines changed

3 files changed

+94
-72
lines changed

components/script/dom/document.rs

Lines changed: 0 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ use crate::dom::webglcontextevent::WebGLContextEvent;
100100
use crate::dom::window::{ReflowReason, Window};
101101
use crate::dom::windowproxy::WindowProxy;
102102
use crate::fetch::FetchCanceller;
103-
use crate::script_module::ModuleObject;
104-
use crate::script_module::{execute_module, instantiate_module_tree};
105103
use crate::script_runtime::{CommonScriptMsg, ScriptThreadEventCategory};
106104
use crate::script_thread::{MainThreadScriptMsg, ScriptThread};
107105
use crate::stylesheet_set::StylesheetSetRef;
@@ -2104,25 +2102,6 @@ impl Document {
21042102
self.process_deferred_scripts();
21052103
}
21062104

2107-
#[allow(unsafe_code)]
2108-
pub fn deferred_module_script_loaded(&self, element: &HTMLScriptElement, url: ServoUrl) {
2109-
if self.ready_state.get() != DocumentReadyState::Interactive {
2110-
return;
2111-
}
2112-
2113-
let window = self.window();
2114-
let global = window.upcast::<GlobalScope>();
2115-
2116-
if let Some(module_record) = global.get_module_map().borrow().get(&url) {
2117-
if let ModuleObject::Fetched(Some(record)) = module_record {
2118-
unsafe {
2119-
instantiate_module_tree(global, record.handle());
2120-
execute_module(global, record.handle());
2121-
}
2122-
}
2123-
}
2124-
}
2125-
21262105
/// https://html.spec.whatwg.org/multipage/#the-end step 3.
21272106
fn process_deferred_scripts(&self) {
21282107
if self.ready_state.get() != DocumentReadyState::Interactive {

components/script/dom/htmlscriptelement.rs

Lines changed: 60 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ use crate::dom::bindings::inheritance::Castable;
1212
use crate::dom::bindings::refcounted::Trusted;
1313
use crate::dom::bindings::reflector::DomObject;
1414
use crate::dom::bindings::root::{Dom, DomRoot};
15+
use crate::dom::bindings::settings_stack::AutoEntryScript;
1516
use crate::dom::bindings::str::{DOMString, USVString};
1617
use crate::dom::document::Document;
18+
use crate::dom::domexception::{DOMErrorName, DOMException};
1719
use crate::dom::element::{
1820
cors_setting_for_element, reflect_cross_origin_attribute, set_cross_origin_attribute,
1921
};
@@ -26,7 +28,8 @@ use crate::dom::node::{BindContext, ChildrenMutation, CloneChildrenFlag, Node};
2628
use crate::dom::performanceresourcetiming::InitiatorType;
2729
use crate::dom::virtualmethods::VirtualMethods;
2830
use crate::network_listener::{self, NetworkListener, PreInvoke, ResourceTimingListener};
29-
use crate::script_module::{fetch_module_script_graph, ModuleOwner};
31+
use crate::script_module::{execute_module, instantiate_module_tree};
32+
use crate::script_module::{fetch_module_script_graph, ModuleObject, ModuleOwner};
3033
use dom_struct::dom_struct;
3134
use encoding_rs::Encoding;
3235
use html5ever::{LocalName, Prefix};
@@ -127,7 +130,7 @@ static SCRIPT_JS_MIMES: StaticStringVec = &[
127130
"text/x-javascript",
128131
];
129132

130-
#[derive(JSTraceable, MallocSizeOf)]
133+
#[derive(JSTraceable, MallocSizeOf, PartialEq)]
131134
pub enum ScriptType {
132135
Classic,
133136
Module,
@@ -546,9 +549,9 @@ impl HTMLScriptElement {
546549
);
547550

548551
if r#async {
549-
// doc.add_asap_script(self);
552+
doc.add_asap_script(self);
550553
} else {
551-
// doc.add_deferred_script(self);
554+
doc.add_deferred_script(self);
552555
};
553556
},
554557
};
@@ -628,7 +631,7 @@ impl HTMLScriptElement {
628631
}
629632

630633
/// <https://html.spec.whatwg.org/multipage/#execute-the-script-block>
631-
pub fn execute(&self, result: Result<ScriptOrigin, NetworkError>) {
634+
pub fn execute(&self, result: ScriptResult) {
632635
// Step 1.
633636
let doc = document_from_node(self);
634637
if self.parser_inserted.get() && &*doc != &*self.parser_document {
@@ -646,7 +649,9 @@ impl HTMLScriptElement {
646649
Ok(script) => script,
647650
};
648651

649-
self.unminify_js(&mut script);
652+
if script.type_ == ScriptType::Classic {
653+
self.unminify_js(&mut script);
654+
}
650655

651656
// Step 3.
652657
let neutralized_doc = if script.external {
@@ -662,21 +667,24 @@ impl HTMLScriptElement {
662667
let document = document_from_node(self);
663668
let old_script = document.GetCurrentScript();
664669

665-
// Step 5.a.1.
666-
document.set_current_script(Some(self));
667-
668-
// Step 5.a.2.
669-
self.run_a_classic_script(&script);
670-
671-
// Step 6.
672-
document.set_current_script(old_script.deref());
670+
match script.type_ {
671+
ScriptType::Classic => {
672+
document.set_current_script(Some(self));
673+
self.run_a_classic_script(&script);
674+
document.set_current_script(old_script.deref());
675+
},
676+
ScriptType::Module => {
677+
assert!(old_script.is_none());
678+
self.run_a_module_script(&script, false);
679+
},
680+
}
673681

674-
// Step 7.
682+
// Step 5.
675683
if let Some(doc) = neutralized_doc {
676684
doc.decr_ignore_destructive_writes_counter();
677685
}
678686

679-
// Step 8.
687+
// Step 6.
680688
if script.external {
681689
self.dispatch_load_event();
682690
}
@@ -708,6 +716,42 @@ impl HTMLScriptElement {
708716
);
709717
}
710718

719+
#[allow(unsafe_code)]
720+
/// https://html.spec.whatwg.org/multipage/#run-a-module-script
721+
pub fn run_a_module_script(&self, script: &ScriptOrigin, _rethrow_errors: bool) {
722+
// TODO use a settings object rather than this element's document/window
723+
// Step 2
724+
let document = document_from_node(self);
725+
if !document.is_fully_active() || !document.is_scripting_enabled() {
726+
return;
727+
}
728+
729+
// Step 4
730+
let window = window_from_node(self);
731+
let global = window.upcast::<GlobalScope>();
732+
let _aes = AutoEntryScript::new(&global);
733+
734+
// TODO: Step 6. Check script's error to throw
735+
736+
let module_map = global.get_module_map().borrow();
737+
738+
if let Some(module_record) = module_map.get(&script.url) {
739+
// Step 7-1.
740+
if let ModuleObject::Fetched(Some(record)) = module_record {
741+
unsafe {
742+
// Step 7-2.
743+
let _instantiated = instantiate_module_tree(global, record.handle());
744+
let evaluated = execute_module(global, record.handle());
745+
746+
if evaluated.is_err() {
747+
let _exception =
748+
DOMException::new(&global, DOMErrorName::QuotaExceededError);
749+
}
750+
}
751+
}
752+
}
753+
}
754+
711755
pub fn queue_error_event(&self) {
712756
let window = window_from_node(self);
713757
window

components/script/script_module.rs

Lines changed: 34 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -161,43 +161,42 @@ impl FetchResponseListener for ModuleContext {
161161
)
162162
});
163163

164+
if load.is_err() {
165+
// https://html.spec.whatwg.org/multipage/#fetch-a-single-module-script
166+
// Step 9.
167+
global.set_module_map(self.url.clone(), ModuleObject::Fetched(None));
168+
return;
169+
}
170+
164171
// TODO: HANDLE MIME TYPE CHECKING
165172

166-
match load {
167-
Err(_) => {
168-
// https://html.spec.whatwg.org/multipage/#fetch-a-single-module-script
169-
// Step 9.
170-
global.set_module_map(self.url.clone(), ModuleObject::Fetched(None));
171-
},
172-
Ok(resp_mod_script) => {
173-
let compiled_module =
174-
compile_module_script(resp_mod_script.text(), self.url.clone(), &global);
175-
176-
let compiled = compiled_module.ok().map(|compiled| Heap::boxed(compiled));
177-
178-
global.set_module_map(self.url.clone(), ModuleObject::Fetched(compiled));
179-
180-
match &self.owner {
181-
ModuleOwner::Worker(_) => unimplemented!(),
182-
ModuleOwner::Window(script) => {
183-
let document = document_from_node(&*script.root());
184-
185-
let r#async = script
186-
.root()
187-
.upcast::<Element>()
188-
.has_attribute(&local_name!("async"));
189-
190-
if r#async {
191-
// document.asap_module_script_loaded(script.root(), load);
192-
} else {
193-
document
194-
.deferred_module_script_loaded(&*script.root(), self.url.clone());
195-
}
196-
197-
document.finish_load(LoadType::Script(self.url.clone()));
198-
},
199-
}
200-
},
173+
if let Ok(ref resp_mod_script) = load {
174+
let compiled_module =
175+
compile_module_script(resp_mod_script.text(), self.url.clone(), &global);
176+
177+
let compiled = compiled_module.ok().map(|compiled| Heap::boxed(compiled));
178+
179+
global.set_module_map(self.url.clone(), ModuleObject::Fetched(compiled));
180+
181+
match &self.owner {
182+
ModuleOwner::Worker(_) => unimplemented!(),
183+
ModuleOwner::Window(script) => {
184+
let document = document_from_node(&*script.root());
185+
186+
let r#async = script
187+
.root()
188+
.upcast::<Element>()
189+
.has_attribute(&local_name!("async"));
190+
191+
if r#async {
192+
document.asap_script_loaded(&*script.root(), load);
193+
} else {
194+
document.deferred_script_loaded(&*script.root(), load);
195+
}
196+
197+
document.finish_load(LoadType::Script(self.url.clone()));
198+
},
199+
}
201200
}
202201
}
203202

0 commit comments

Comments
 (0)