You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: ShadowDOM/explainer.md
+39-4Lines changed: 39 additions & 4 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -270,9 +270,9 @@ Earlier versions of this document used the `<script>` tag for declaring CSS Modu
270
270
271
271
User agents allow for disabling JavaScript, and declarative modules should still work with JavaScript disabled. However, the module graph as it exists today only functions with script enabled. Browser engines should confirm whether this is feasible with their current implementations. Chromium has been verified as compatible, but other engines such as WebKit and Gecko have not been verified yet.
272
272
273
-
### Syntactic Sugar For Import Maps with Data URI
273
+
### Syntactic Sugar For Import Maps with Blob URL
274
274
275
-
The simplest approach for Declarative CSS Modules is to treat them as syntactic sugar that generates an Import Map entry containing a specifier and a data URI containing the module contents.
275
+
The simplest approach for Declarative CSS Modules is to treat them as syntactic sugar that generates an Import Map entry containing a specifier and a Blob URL referencing a Blob containing the module contents.
276
276
277
277
For example, a Declarative CSS Module defined as follows:
278
278
```html
@@ -284,10 +284,13 @@ For example, a Declarative CSS Module defined as follows:
@@ -314,6 +317,38 @@ This approach does have a few limitations:
314
317
- The `<style>` definition *must* occur before it is imported, otherwise the import map will not be populated. Based on developer feedback, this is not a major limitation.
315
318
- Since Import Maps have no knowledge of an underlying type for their mappings, declarative modules with the same specifier (e.g. "foo"), but differing types (e.g. one JavaScript module with a specifier of "foo" and one CSS module with a specifier of "foo") would create separate entries in the generated import map, and only the first definition would actually be mapped. See [Open Issues](#open-issues) for some potential solutions to this scenario.
316
319
320
+
Blob URLs are active for the lifetime of the page on which they were created and are revoked via `revokeObjectURL`. A developer could theoretically discover the URL generated from
321
+
a Declarative CSS Module and revoke it, but this doesn't expose any new issues as this scenario is already possible to do imperatively.
322
+
323
+
There are several options for managing the lifetime of the generated Blob object. For instance, it could be revoked when the `<style type="module">` that created it is disconnected. This
324
+
would give developers some options for managing Blob lifetimes, but once revoked, Blob URLs cannot be reused, so re-inserting the `<style type="module">` tag cannot undo it being
325
+
removed. Generating a new Blob URL and adding it to the Import Map will not work either, since Import Maps will ignore subsequent entries with an existing specifier. By default,
326
+
Blob URLs generated with Declarative CSS Modules would be tied to the lifetime of the document, with no options for revoking them. This would result in consistent behaviors for developers,
327
+
at the expense of flexibility with resource management. Not exposing the ability to revoke the Blob URL aligns with how Import Maps behave, so it is the preferred option.
328
+
329
+
Alternatively, a data URI could be used instead of a Blob URL. However, using a Blob URL offers several performance advantages over a data URI, such as avoiding URL-encoding and a much
330
+
smaller Import Map value string stored in memory.
331
+
332
+
Using Data URI's, a Declarative CSS Module defined as follows:
333
+
```html
334
+
<styletype="module"specifier="foo">
335
+
#content { color: red; }
336
+
</style>
337
+
```
338
+
339
+
...would be syntactic sugar for:
340
+
341
+
```html
342
+
<scripttype="importmap">
343
+
{
344
+
"imports": {
345
+
"foo":"data:text/css,%23content { color: red; }"
346
+
}
347
+
}
348
+
</script>
349
+
```
350
+
The data URI must be URL-encoded, because many CSS selectors have special meaning in URLs. One example is the `#` ID selector in CSS, which is a fragment identifier in URLs and can only
351
+
exist once in a URL. Importing via `shadowrootadoptedstylesheets` would work exactly the same as the Blob URL example above.
317
352
318
353
### Detailed Parsing Workflow
319
354
@@ -332,7 +367,7 @@ In the following example:
332
367
</my-element>
333
368
```
334
369
335
-
Upon parsing the `<style>` tag above, an [import map string](https://html.spec.whatwg.org/multipage/webappapis.html#parse-an-import-map-string) is generated with JSON containing a [map](https://infra.spec.whatwg.org/#ordered-map) with a key of "imports". The [value](https://infra.spec.whatwg.org/#map-value) associated with this key is another JSON [map](https://infra.spec.whatwg.org/#ordered-map) with a single entry with a [key](https://infra.spec.whatwg.org/#map-key) containing the value of the `specifier` attribute on the `<style>` tag (in this case, "foo"). The [value](https://infra.spec.whatwg.org/#map-value) associated with this key is a [data URI](https://www.rfc-editor.org/rfc/rfc2397) with a [scheme](https://url.spec.whatwg.org/#concept-url-scheme) of "data", a [media type](https://www.rfc-editor.org/rfc/rfc2397) of "text/css", and [data](https://www.rfc-editor.org/rfc/rfc2397) consisting of a [UTF-8 percent encoded](https://url.spec.whatwg.org/#utf-8-percent-encode) value of the [text content](https://html.spec.whatwg.org/#get-the-text-steps) of the `<style>` tag.
370
+
Upon parsing the `<style>` tag above, an [import map string](https://html.spec.whatwg.org/multipage/webappapis.html#parse-an-import-map-string) is generated with JSON containing a [map](https://infra.spec.whatwg.org/#ordered-map) with a key of "imports". The [value](https://infra.spec.whatwg.org/#map-value) associated with this key is another JSON [map](https://infra.spec.whatwg.org/#ordered-map) with a single entry with a [key](https://infra.spec.whatwg.org/#map-key) containing the value of the `specifier` attribute on the `<style>` tag (in this case, "foo"). The [value](https://infra.spec.whatwg.org/#map-value) associated with this key is a [Blob URI](https://w3c.github.io/FileAPI/#dfn-Blob) with a [media type](https://www.rfc-editor.org/rfc/rfc2397) of "text/css" and a value of the [text content](https://html.spec.whatwg.org/#get-the-text-steps) of the `<style>` tag. Alternatively, the [value](https://infra.spec.whatwg.org/#map-value) associated with the key is a [data URI](https://www.rfc-editor.org/rfc/rfc2397) with a [scheme](https://url.spec.whatwg.org/#concept-url-scheme) of "data", a [media type](https://www.rfc-editor.org/rfc/rfc2397) of "text/css", and [data](https://www.rfc-editor.org/rfc/rfc2397) consisting of a [UTF-8 percent encoded](https://url.spec.whatwg.org/#utf-8-percent-encode) value of the [text content](https://html.spec.whatwg.org/#get-the-text-steps) of the `<style>` tag.
336
371
337
372
Note that unlike a regular `<style>` tag with CSS content, the `sheet` attribute defined in the [LinkStyle interface](https://www.w3.org/TR/cssom-1/#the-linkstyle-interface) would always be empty for Declarative CSS Modules. Similarly, updating the text content of the `<style>` tag would not update the generated [import map string](https://html.spec.whatwg.org/multipage/webappapis.html#parse-an-import-map-string), which is exactly how [import maps](https://html.spec.whatwg.org/multipage/webappapis.html#import-maps) behave when their text content is modified.
0 commit comments