Module scripts
Script loading, the event loop and JavaScript workers as the engine needs them (HTML "scripting"): document.write / open / close, the script element's own state, Content-Security-Policy checks of inline code and of eval, ES module graphs (the browser fetches a whole graph, the engine links and runs it), unhandled promise rejections, javascript: URLs, workers whose script is JavaScript and their structured-clone messages. Implemented in src/page/js_load*.odin and js_workers.odin; used by native/js/runtime (load.c, modules.c, handlers.c, load_errors.c, timers.c, workers.c).
Exposed to: Window, Worker. Source: api/js_load.widl.
Odin: import "wren:scripts".
Types
enum InlineScriptKind : i32
What a Content-Security-Policy check of inline code is about: a script element's text, an event handler attribute (script-src-attr), a javascript: URL.
| member | value | |
|---|---|---|
Element | 0 | |
Attribute | 1 | |
Navigation | 2 |
enum ModuleType : i32
The type of a module (import attributes: with {type: "json"}, with {type: "css"}).
| member | value | |
|---|---|---|
JavaScript | 0 | |
Json | 1 | |
Css | 2 |
enum WorkerType : i32
The type of a worker's script (new Worker(url, {type})).
| member | value | |
|---|---|---|
Classic | 0 | |
Module | 1 |
Functions
Document_writeMarkup
void Document_writeMarkup(usvstring markup) raisesdocument.write(markup) (writeln adds the newline): inserted at the parser's insertion point while the document loads (scripts written run before it returns), else the document is opened again first and replaced. Invalid_State for a document that does not accept it now (a custom element constructor, a parser that would have to be aborted).
Raises: returns an Error (see web).
Host: Document_writeMarkup :: proc(c: ^Call, markup: string) -> Api_Error
Document_openStream
void Document_openStream() raisesdocument.open(): the document is emptied and its parser starts again (does nothing while the parser runs a script; the listeners and handlers of its tree and of its Window are erased, the engine's records first through its export wj_document_opening). Invalid_State when the document cannot be opened.
Raises: returns an Error (see web).
Host: Document_openStream :: proc(c: ^Call) -> Api_Error
Document_closeStream
void Document_closeStream() raisesdocument.close(): the parser of a document.open() finishes (DOMContentLoaded, then load).
Raises: returns an Error (see web).
Host: Document_closeStream :: proc(c: ^Call) -> Api_Error
HTMLScriptElement_forceAsync
bool HTMLScriptElement_forceAsync(u64 element)The "force async" flag of a script element (set when a script creates it: dynamic scripts are async unless their async attribute is set to false).
Host: HTMLScriptElement_forceAsync :: proc(c: ^Call, element: u64) -> bool
HTMLScriptElement_setForceAsync
void HTMLScriptElement_setForceAsync(u64 element, bool value)script.async = value: the attribute is set or removed by the caller, this clears the flag.
Host: HTMLScriptElement_setForceAsync :: proc(c: ^Call, element: u64, value: bool)
Script_allowInline
bool Script_allowInline(u64 element, InlineScriptKind kind, usvstring source)May this inline code run (Content-Security-Policy: 'unsafe-inline', nonces, hashes)? A refusal is reported as a
violation. element is the element it comes from (0 for a javascript: URL).
Host: Script_allowInline :: proc(c: ^Call, element: u64, kind: Api_InlineScriptKind, source: string) -> bool
Script_allowEval
bool Script_allowEval(usvstring source)May eval() / new Function / setTimeout(string) compile this ('unsafe-eval')? A refusal is reported.
Host: Script_allowEval :: proc(c: ^Call, source: string) -> bool
Script_javascriptResult
void Script_javascriptResult(usvstring html)The result of a javascript: URL that was a string: it becomes the document (HTML "navigate to a javascript: URL").
Host: Script_javascriptResult :: proc(c: ^Call, html: string)
Script_baseName
string Script_baseName()The URL naming code that has no script of its own in stack traces and as the base of import() (handlers, timer strings): the document's (the worker's script in a worker).
Host: Script_baseName :: proc(c: ^Call) -> string
Module_resolve
string Module_resolve(usvstring specifier, usvstring base) raisesThe URL a module specifier stands for, imported from the module (or script) at base ("" for the root of a
graph, given as a URL already): import maps, then URL parsing. Type: a bare specifier nothing maps, or not a URL.
Raises: returns an Error (see web).
Host: Module_resolve :: proc(c: ^Call, specifier: string, base: string) -> (string, Api_Error)
Module_source
string Module_source(usvstring url) raisesThe source of a module of the page's module map. Not_Found when the browser does not have it.
Raises: returns an Error (see web).
Host: Module_source :: proc(c: ^Call, url: string) -> (string, Api_Error)
Module_request
void Module_request(usvstring module_url, usvstring specifier, ModuleType type) raisesThe module at module_url imports specifier: resolved and fetched if new (part of the module's graph).
Raises: returns an Error (see web).
Host: Module_request :: proc(c: ^Call, module_url: string, specifier: string, type: Api_ModuleType) -> Api_Error
Module_import
void Module_import(i32 id, usvstring specifier, usvstring base, ModuleType type) raisesimport(specifier) from code at base: the browser fetches the graph, then calls the engine's
wj_module_import_done(id, ...) from a task of its own. Type: the specifier cannot be resolved.
Raises: returns an Error (see web).
Host: Module_import :: proc(c: ^Call, id: i32, specifier: string, base: string, type: Api_ModuleType) -> Api_Error
Engine_queueRejectionCheck
void Engine_queueRejectionCheck()Unhandled promise rejections are waiting: run the engine's wj_notify_rejections in a task of its own.
Host: Engine_queueRejectionCheck :: proc(c: ^Call)
Worker_createScript
u64 Worker_createScript(usvstring url, usvstring name, WorkerType type) raisesnew Worker(url, {name, type}) for a JavaScript worker: the Worker object (a handle of module workers). Syntax for an invalid URL, Not_Allowed when the browser refuses (the console says why).
Raises: returns an Error (see web).
Host: Worker_createScript :: proc(c: ^Call, url: string, name: string, type: Api_WorkerType) -> (u64, Api_Error)
Worker_postSerialized
void Worker_postSerialized(u64 worker, bytes data) raisesworker.postMessage(message): the message as structured serialization bytes (native/js/runtime/clone.c).
Raises: returns an Error (see web).
Host: Worker_postSerialized :: proc(c: ^Call, worker: u64, data: []u8) -> Api_Error
DedicatedWorkerGlobalScope_postSerialized
void DedicatedWorkerGlobalScope_postSerialized(bytes data) raisespostMessage(message) in a JavaScript worker.
Raises: returns an Error (see web).
Host: DedicatedWorkerGlobalScope_postSerialized :: proc(c: ^Call, data: []u8) -> Api_Error
WorkerGlobalScope_importScript
string WorkerGlobalScope_importScript(usvstring url) raisesimportScripts(url), one URL: fetched synchronously (same rules as the worker's script). The result is '1' when the script's errors are muted (an opaque response: another origin without CORS) else '0', the response's URL, a NUL byte, then the script. Network when it cannot be fetched or is not JavaScript; Type in a module worker (importScripts is a classic worker's).
Raises: returns an Error (see web).
Host: WorkerGlobalScope_importScript :: proc(c: ^Call, url: string) -> (string, Api_Error)
WorkerGlobalScope_isModule
bool WorkerGlobalScope_isModule()Whether the calling worker's script is a module ({type: "module"}).
Host: WorkerGlobalScope_isModule :: proc(c: ^Call) -> bool
SharedWorker_connect
u64 SharedWorker_connect(usvstring url, usvstring name, WorkerType type, bool extended_lifetime) raisesnew SharedWorker(url, {name, type, extendedLifetime}) from a document: the SharedWorker object (it gets error
events), connected to the shared worker of (the document's storage key, the URL, the name), which starts if none
runs. Its port: SharedWorker_portEnd. Syntax for an invalid URL, Security for a URL of another origin,
Not_Allowed when the browser refuses (shared workers disabled, too many: the console says why).
Raises: returns an Error (see web).
Host: SharedWorker_connect :: proc(c: ^Call, url: string, name: string, type: Api_WorkerType, extended_lifetime: bool) -> (u64, Api_Error)
Worker_createScriptBytes
u64 Worker_createScriptBytes(usvstring url, usvstring name, WorkerType type, bytes script) raisesnew Worker(blobURL) / new SharedWorker(blobURL): the same, with the script the engine read from the Blob the URL stands for (blob: URLs live in the realm that made them, the browser cannot fetch them).
Raises: returns an Error (see web).
Host: Worker_createScriptBytes :: proc(c: ^Call, url: string, name: string, type: Api_WorkerType, script: []u8) -> (u64, Api_Error)
Worker_pendingError
string Worker_pendingError()While wj_worker_error_to_global runs: the worker's uncaught error that its Worker object's error event did not cancel, "message TAB filename" (HTML: it is reported in the owner's global, window.onerror).
Host: Worker_pendingError :: proc(c: ^Call) -> string
SharedWorker_connectBytes
u64 SharedWorker_connectBytes(usvstring url, usvstring name, WorkerType type, bool extended_lifetime, bytes script) raisesRaises: returns an Error (see web).
Host: SharedWorker_connectBytes :: proc(c: ^Call, url: string, name: string, type: Api_WorkerType, extended_lifetime: bool, script: []u8) -> (u64, Api_Error)
SharedWorker_portEnd
u64 SharedWorker_portEnd(u64 worker)The port end of the SharedWorker's port, given once (the caller binds it with Port_bind); 0 afterwards.
Host: SharedWorker_portEnd :: proc(c: ^Call, worker: u64) -> u64
SharedWorkerGlobalScope_takeConnection
u64 SharedWorkerGlobalScope_takeConnection()The end of the port of the next connect event of the calling shared worker (0: none waits).
Host: SharedWorkerGlobalScope_takeConnection :: proc(c: ^Call) -> u64