Skip to content

Commit 681e367

Browse files
networkExceptionlinusg
authored andcommitted
LibWeb: Implement recent changes to module script fetching
This patch implements all changes to the specification touching the subset of module script fetching we support. Notably it adds parts of the specification for supporting import maps. With this we are also able to get rid of a non standard workaround for a spec issue we discovered while initially implementing module scripts :^)
1 parent 9afea12 commit 681e367

File tree

4 files changed

+252
-88
lines changed

4 files changed

+252
-88
lines changed

Userland/Libraries/LibWeb/Bindings/MainThreadVM.cpp

Lines changed: 29 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -325,53 +325,50 @@ JS::VM& main_thread_vm()
325325
return { "type"sv };
326326
};
327327

328-
// 8.1.5.5.3 HostResolveImportedModule(referencingScriptOrModule, moduleRequest), https://html.spec.whatwg.org/multipage/webappapis.html#hostresolveimportedmodule(referencingscriptormodule,-modulerequest)
328+
// 8.1.6.5.3 HostResolveImportedModule(referencingScriptOrModule, moduleRequest), https://html.spec.whatwg.org/multipage/webappapis.html#hostresolveimportedmodule(referencingscriptormodule,-modulerequest)
329329
vm->host_resolve_imported_module = [](JS::ScriptOrModule const& referencing_string_or_module, JS::ModuleRequest const& module_request) -> JS::ThrowCompletionOr<JS::NonnullGCPtr<JS::Module>> {
330-
// 1. Let settings object be the current settings object.
331-
auto* settings_object = &HTML::current_settings_object();
330+
// 1. Let moduleMap and referencingScript be null.
331+
Optional<HTML::ModuleMap&> module_map;
332+
Optional<HTML::Script&> referencing_script;
332333

333-
// 2. Let base URL be settings object's API base URL.
334-
auto base_url = settings_object->api_base_url();
335-
336-
// 3. If referencingScriptOrModule is not null, then:
334+
// 2. If referencingScriptOrModule is not null, then:
337335
if (!referencing_string_or_module.has<Empty>()) {
338-
// 1. Let referencing script be referencingScriptOrModule.[[HostDefined]].
339-
auto const& referencing_script = verify_cast<HTML::Script>(referencing_string_or_module.has<JS::NonnullGCPtr<JS::Script>>() ? referencing_string_or_module.get<JS::NonnullGCPtr<JS::Script>>()->host_defined() : referencing_string_or_module.get<JS::NonnullGCPtr<JS::Module>>()->host_defined());
340-
341-
// 2. Set settings object to referencing script's settings object.
342-
settings_object = &referencing_script->settings_object();
336+
// 1. Set referencingScript to referencingScriptOrModule.[[HostDefined]].
337+
referencing_script = verify_cast<HTML::Script>(referencing_string_or_module.has<JS::NonnullGCPtr<JS::Script>>() ? *referencing_string_or_module.get<JS::NonnullGCPtr<JS::Script>>()->host_defined() : *referencing_string_or_module.get<JS::NonnullGCPtr<JS::Module>>()->host_defined());
343338

344-
// 3. Set base URL to referencing script's base URL.
345-
base_url = referencing_script->base_url();
346-
347-
// 4. Assert: base URL is not null, as referencing script is a classic script or a JavaScript module script.
348-
VERIFY(base_url.is_valid());
339+
// 2. Set moduleMap to referencingScript's settings object's module map.
340+
module_map = referencing_script->settings_object().module_map();
349341
}
342+
// 3. Otherwise:
343+
else {
344+
// 1. Assert: there is a current settings object.
345+
// NOTE: This is handled by the HTML::current_settings_object() accessor.
350346

351-
// 4. Let moduleMap be settings object's module map.
352-
auto& module_map = settings_object->module_map();
347+
// 2. Set moduleMap to the current settings object's module map.
348+
module_map = HTML::current_settings_object().module_map();
349+
}
353350

354-
// 5. Let url be the result of resolving a module specifier given base URL and moduleRequest.[[Specifier]].
355-
auto url = HTML::resolve_module_specifier(module_request, base_url);
351+
// 4. Let url be the result of resolving a module specifier given referencingScript and moduleRequest.[[Specifier]].
352+
auto url = MUST(HTML::resolve_module_specifier(referencing_script, module_request.module_specifier));
356353

357-
// 6. Assert: url is never failure, because resolving a module specifier must have been previously successful
354+
// 5. Assert: the previous step never throws an exception, because resolving a module specifier must have been previously successful
358355
// with these same two arguments (either while creating the corresponding module script, or in fetch an import() module script graph).
359-
VERIFY(url.is_valid());
356+
// NOTE: Handled by MUST above.
360357

361-
// 7. Let moduleType be the result of running the module type from module request steps given moduleRequest.
358+
// 6. Let moduleType be the result of running the module type from module request steps given moduleRequest.
362359
auto module_type = HTML::module_type_from_module_request(module_request);
363360

364-
// 8. Let resolved module script be moduleMap[(url, moduleType)]. (This entry must exist for us to have gotten to this point.)
365-
auto resolved_module = module_map.get(url, module_type).value();
361+
// 7. Let resolvedModuleScript be moduleMap[(url, moduleType)]. (This entry must exist for us to have gotten to this point.)
362+
auto resolved_module_script = module_map->get(url, module_type).value();
366363

367-
// 9. Assert: resolved module script is a module script (i.e., is not null or "fetching").
368-
VERIFY(resolved_module.type == HTML::ModuleMap::EntryType::ModuleScript);
364+
// 8. Assert: resolvedModuleScript is a module script (i.e., is not null or "fetching").
365+
VERIFY(resolved_module_script.type == HTML::ModuleMap::EntryType::ModuleScript);
369366

370-
// 10. Assert: resolved module script's record is not null.
371-
VERIFY(resolved_module.module_script->record());
367+
// 9. Assert: resolvedModuleScript's record is not null.
368+
VERIFY(resolved_module_script.module_script->record());
372369

373-
// 11. Return resolved module script's record.
374-
return JS::NonnullGCPtr(*resolved_module.module_script->record());
370+
// 10. Return resolvedModuleScript's record.
371+
return JS::NonnullGCPtr(*resolved_module_script.module_script->record());
375372
};
376373

377374
// NOTE: We push a dummy execution context onto the JS execution context stack,

0 commit comments

Comments
 (0)