BrowserLoader
extends AutoService
in package
implements
EventSubscriberInterface
uses
BasicLoaderTrait
The BrowserLoader leverages the browser's built-in support for ECMAScript Modules (ESM's).
Any ESM's required by CiviCRM or its extensions are rendered like so:
<script type="importmap"> { "import": {"civicrm/": "https://example.com/sites/all/modules/civicrm"}} </script> <script type="module"> import { TableWidget } from "civicrm/TableWidget.js"; const table = new TableWidget(); </script>This should be the simplest and most efficient way to load modules. However, there may be compatibility issues with older browsers or future UFs.
For a fuller description of this mechanism, see the neighboring README.
Tags
Table of Contents
Interfaces
- EventSubscriberInterface
Properties
- $importMap : ImportMap
- $required : bool
- Do we need to send an import-map for the current page-view?
Methods
- getSubscribedEvents() : array<string|int, mixed>
- onRegionRender() : void
- Listen to 'civi.region.render[html-header]'.
- onUseModule() : void
- Receive a notification that an ESM is being used.
- renderModule() : string
- buildImportMap() : array<string|int, mixed>
- renderImportMap() : string
- renderModuleScript() : string
- renderModuleUrl() : string
Properties
$importMap
protected
ImportMap
$importMap
Tags
$required
Do we need to send an import-map for the current page-view?
protected
bool
$required
= FALSE
For the moment, we figure this dynamically -- based on whether any "esm" scripts have been added. During the early stages (where ESMs aren't in widespread use), this seems safer. However, in the future, we might find some kind of race (e.g. where the system renders "
" before it decides on a specific "<script type=module"> to load. If that edge-case happens, then it's probably fair to switch this default ($required=TRUE
).
Methods
getSubscribedEvents()
public
static getSubscribedEvents() : array<string|int, mixed>
Return values
array<string|int, mixed>onRegionRender()
Listen to 'civi.region.render[html-header]'.
public
onRegionRender(CRM_Core_Region $region) : void
If there are any active "module"s on this page, then output the "import-map".
Parameters
- $region : CRM_Core_Region
onUseModule()
Receive a notification that an ESM is being used.
public
onUseModule(array<string|int, mixed> &$snippet) : void
Parameters
- $snippet : array<string|int, mixed>
-
The module resource being rendered, as per "CollectionInterface::add()". Ex: ['type' => 'scriptUrl', 'scriptUrl' => 'https://example.com/foo.js', 'esm' => TRUE, 'region' => 'page-footer']
Tags
renderModule()
public
renderModule(array<string|int, mixed> $snippet) : string
Parameters
- $snippet : array<string|int, mixed>
-
The module resource being rendered, as per "CollectionInterface::add()". Ex: ['type' => 'scriptUrl', 'scriptUrl' => 'https://example.com/foo.js', 'esm' => TRUE]
Tags
Return values
string —HTML
buildImportMap()
protected
buildImportMap() : array<string|int, mixed>
Tags
Return values
array<string|int, mixed> —The import-map, as defined by the browser-vendor or browser-based polyfill. For BasicLoaderTrait, we do a straight-through mapping (read extension-names, generate extension-URLs).
renderImportMap()
protected
renderImportMap(array<string|int, mixed> $importMap) : string
Parameters
- $importMap : array<string|int, mixed>
Tags
Return values
stringrenderModuleScript()
protected
renderModuleScript(array<string|int, mixed> $snippet) : string
Parameters
- $snippet : array<string|int, mixed>
Tags
Return values
stringrenderModuleUrl()
protected
renderModuleUrl(array<string|int, mixed> $snippet) : string
Parameters
- $snippet : array<string|int, mixed>