@webqit/oohtml 3.2.0 → 4.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -13,13 +13,19 @@ Building Single Page Applications? OOHTML is a special love letter! Writing Web
13
13
 
14
14
  <details><summary>Versions</summary>
15
15
 
16
- *This is documentation for `OOHTML@3`. (Looking for [`OOHTML@1`](https://github.com/webqit/oohtml/tree/v1.10.4)?)*
16
+ *This is documentation for `OOHTML@4`. (Looking for [`OOHTML@1`](https://github.com/webqit/oohtml/tree/v1.10.4)?)*
17
17
 
18
18
  </details>
19
19
 
20
+ ## Status
21
+
22
+ + Working implementation via a polyfill
23
+ + Actively developed
24
+ + Open to contributions
25
+
20
26
  ## Polyfill
21
27
 
22
- OOHTML is being developed as something to be used today. This implementation adheres closely to the spec and evolves the proposal through a practice-driven process.
28
+ OOHTML is being developed as something to be used today. This implementation adheres closely to the spec and helps evolve the proposal through a practice-driven process.
23
29
 
24
30
  <details><summary>Load from a CDN<br>
25
31
  └───────── <a href="https://bundlephobia.com/result?p=@webqit/oohtml"><img align="right" src="https://img.shields.io/badge/21.8%20kB-black"></a></summary>
@@ -30,13 +36,19 @@ OOHTML is being developed as something to be used today. This implementation adh
30
36
 
31
37
  └ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!
32
38
 
33
- > For `@webqit/oohtml@3.1` and below, you would need an external polyfill - like the [samthor/scoped](https://github.com/samthor/scoped) polyfill - for the Scoped Styles feature:
34
- >
35
- > ```html
36
- > <head>
37
- > <script src="https://unpkg.com/style-scoped/scoped.min.js"></script>
38
- > </head>
39
- > ```
39
+ For `@webqit/oohtml@3.1` and below, you would need an external polyfill - like the [samthor/scoped](https://github.com/samthor/scoped) polyfill - for the Scoped Styles feature:
40
+
41
+ ```html
42
+ <head>
43
+ <script src="https://unpkg.com/style-scoped/scoped.min.js"></script>
44
+ </head>
45
+ ```
46
+
47
+ └ Being an integral part of OOHTML, the Observer and Quantum JS APIs are also accessible on loading the OOHTML polyfill:
48
+
49
+ ```js
50
+ const { QuantumFunction, QuantumAsyncFunction, QuantumScript, QuantumModule, QuantumAsyncScript, State, Observer } = window.webqit;
51
+ ```
40
52
 
41
53
  </details>
42
54
 
@@ -50,12 +62,18 @@ npm i @webqit/oohtml @webqit/quantum-js
50
62
  ```js
51
63
  // Import
52
64
  import * as Quantum from '@webqit/quantum-js/lite'; // Or from '@webqit/quantum-js'; See implementation notes below
53
- import init from '@webqit/oohtml';
65
+ import init from '@webqit/oohtml/src/init.js';
54
66
 
55
67
  // Initialize the lib
56
68
  init.call(window, Quantum[, options = {}]);
57
69
  ```
58
70
 
71
+ └ Being an integral part of OOHTML, the Observer API, in addition to the Quantum JS APIs, is also available from the OOHTML installation:
72
+
73
+ ```js
74
+ import * as Observer from '@webqit/observer';
75
+ ```
76
+
59
77
  └ To use the polyfill on server-side DOM instances as made possible by libraries like [jsdom](https://github.com/jsdom/jsdom), simply install and initialize the library with the DOM instance as above.
60
78
 
61
79
  └ But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
@@ -92,7 +110,7 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
92
110
 
93
111
  ```html
94
112
  <head>
95
- <meta name="scoped-js" content="script.mimeType=some-mime">
113
+ <meta name="scoped-js" content="script.mimeTypes=module|text/javascript|application/javascript|some-mime">
96
114
  <script async src="https://unpkg.com/@webqit/oohtml/dist/main.lite.js"></script>
97
115
  </head>
98
116
  <body>
@@ -114,12 +132,12 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
114
132
 
115
133
  ...still gives the `window` object in the console.
116
134
 
117
- + **Syntax**. The syntax for attribute names and API names across features - e.g. the `def` and `ref` attributes, the `expr` attribute - isn't finalized, and may change on subsequent iterations, albeit with same principle of operation. But the polyfill is designed to be configurable via meta tags, and to honour any such "overrides". Here's an example:
135
+ + **Syntax**. The syntax for attribute names and API names across features - e.g. the `def` and `ref` attributes, the `render` attribute - isn't finalized, and may change on subsequent iterations, albeit with same principle of operation. But the polyfill is designed to be configurable via meta tags, and to honour any such "overrides". Here's an example:
118
136
 
119
137
  ```html
120
138
  <head>
121
139
  <!-- Configurations come before the polyfil -->
122
- <meta name="data-binding" content="attr.expr=expr;">
140
+ <meta name="data-binding" content="attr.render=render;">
123
141
  <meta name="namespaced-html" content="attr.id=id;">
124
142
  <meta name="html-imports" content="attr.def=def; attr.ref=ref;">
125
143
  <script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
@@ -143,16 +161,16 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
143
161
  + `document.bindings` now becomes: `document.wqBindings`,
144
162
  + etc.
145
163
 
146
- The following is the full syntax table.
164
+ <details><summary>Show the full syntax table</summary>
147
165
 
148
- Spec: **data-binding**
166
+ **Spec: `<meta name="data-binding">`**
149
167
 
150
168
  | Config | Default Syntax | Description |
151
169
  | :----- | :------------- | :---------- |
152
- | `attr.expr` | `expr` | The "expr" attribute for inline data binding. ([Docs](#inline-data-binding)) |
170
+ | `attr.render` | `render` | The "render" attribute for inline data binding. ([Docs](#inline-data-binding)) |
153
171
  | `attr.itemIndex` | `data-index` | The "item index" attribute for assigning indexes to list items. ([Docs](#inline-data-binding)) |
154
172
 
155
- Spec: **bindings-api**
173
+ **Spec: `<meta name="bindings-api">`**
156
174
 
157
175
  | Config | Default Syntax | Description |
158
176
  | :----- | :------------- | :---------- |
@@ -160,14 +178,14 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
160
178
  | `api.bind` | `bind` | The `document.bind()` and `Element.prototype.bind()` methods. ([Docs](#the-bindings-api)) |
161
179
  | `api.bindings` | `bindings` | The `document.bindings` and `Element.prototype.bindings` object properties. ([Docs](#the-bindings-api)) |
162
180
 
163
- Spec: **context-api**
181
+ **Spec: `<meta name="context-api">`**
164
182
 
165
183
  | Config | Default Syntax | Description |
166
184
  | :----- | :------------- | :---------- |
167
185
  | `attr.contextname` | `contextname` | The "context name" attribute on arbitrary elements. ([Docs](#the-context-api)) |
168
186
  | `api.contexts` | `contexts` | The `document.contexts` and `Element.prototype.contexts` object properties. ([Docs](#the-context-api)) |
169
187
 
170
- Spec: **html-imports**
188
+ **Spec: `<meta name="html-imports">`**
171
189
 
172
190
  | Config | Default Syntax | Description |
173
191
  | :----- | :------------- | :---------- |
@@ -182,7 +200,8 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
182
200
  | `api.defs` | `defs` | The readonly object property for accessing a `<template>`'s list of definitions. ([Docs](#module-definition)) |
183
201
  | `api.import` | `import` | The `document.import()` and `Element.prototype.import()` methods. ([Docs](#imperative-module-imports)) |
184
202
 
185
- Spec: **namespaced-html**
203
+
204
+ **Spec: `<meta name="namespaced-html">`**
186
205
 
187
206
  | Config | Default Syntax | Description |
188
207
  | :----- | :------------- | :---------- |
@@ -190,9 +209,11 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
190
209
  | `attr.id` | `id` | The "id" attribute on arbitrary elements. ([Docs](#namespacing)) |
191
210
  | `api.namespace` | `namespace` | The "namespace" object property on arbitrary elements. ([Docs](#namespacing)) |
192
211
 
193
- Spec: **scoped-css** (TODO)
212
+ **Spec: `<meta name="scoped-css">`** (TODO)
213
+
214
+ **Spec: `<meta name="scoped-js">`** (TODO)
194
215
 
195
- Spec: **scoped-js** (TODO)
216
+ </details>
196
217
 
197
218
  </details>
198
219
 
@@ -202,7 +223,7 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
202
223
 
203
224
  Amidst a multitude of approaches, vanilla HTML remains an attractive option for the UI author! But the current authoring experience still leaves much to be desired in how the language lacks modularity, reusability, and certain modern paradigms like data binding! Authors still have to rely on tools - and, for the most part, have to do half of the work in HTML and half in JS - to express even basic concepts!
204
225
 
205
- "As an author, I want to be able to do 'x' *declaratively* instead of *imperatively* in JavaScript or by means of a special Custom Element!" "As a Web Component author, I want to be able to leverage *conventions* that keep my component logic *concise*!" All such "user stories" represent important developer intuitions that has yet to be met in HTML; much of which belong under a broad subject: an object-oriented markup language! This subject is what we explore with OOHTML!
226
+ "As an author, I want to be able to do 'x' *declaratively* in HTML instead of *imperatively* in JavaScript or by means of a special Custom Element!" "As a Web Component author, I want to be able to leverage *conventions* that keep my component logic *concise*!" All such "user stories" represent important developer intuitions that has yet to be met in HTML; much of which belong under a broad subject: an object-oriented markup language! This subject is what we explore with OOHTML!
206
227
 
207
228
  OOHTML comes, not as a specific technology, but as a conceptual "framework" of features that solves for HTML as an object-oriented language - whether that means re-aligning existing features or introducing new ones! While features may be discussed or explored individually, the one agenda "Object-Oriented HTML" helps us stay aligned with the original problem! Each of these features has been introduced below with a small explainer.
208
229
 
@@ -219,7 +240,7 @@ OOHTML is effectively different from Web Components (and from the related Declar
219
240
 
220
241
  ## Modular HTML
221
242
 
222
- Modular HTML is a markup pattern that lets us write arbitrary markup as self-contained objects - with each *encapsulating* their own structure, styling and logic!
243
+ The modern UI is best approached with a modular architecture (think UI component frameworks) wherein we are able to author in bits and pieces while having each piece *encapsulate* their structure, styling and logic!
223
244
 
224
245
  OOHTML makes this possible by introducing "namespacing" and style and script scoping!
225
246
 
@@ -227,7 +248,23 @@ OOHTML makes this possible by introducing "namespacing" and style and script sco
227
248
 
228
249
  Naming things is hard! That's especially so where you have one global namespace and a miriad of potentially conflicting identifiers to coordinate!
229
250
 
230
- Here, we get a modular naming convention using the `namespace` attribute. This attribute let's us create a naming context for identifiers in a given subtree:
251
+ <details><summary>Learn more</summary>
252
+
253
+ You want to see how IDs are, in fact, by default, exposed as global variables:
254
+
255
+ ```html
256
+ <div id="foo"><div>
257
+ ```
258
+
259
+ ```js
260
+ console.log(window.foo); // div
261
+ ```
262
+
263
+ [Read more](https://stackoverflow.com/questions/6381425/is-there-a-spec-that-the-id-of-elements-should-be-made-global-variable)
264
+
265
+ </details>
266
+
267
+ Here, we get a modular naming convention that let's us create a naming context for identifiers in a given subtree - by means of a new `namespace` attribute:
231
268
 
232
269
  ```html
233
270
  <form>
@@ -240,7 +277,7 @@ Here, we get a modular naming convention using the `namespace` attribute. This a
240
277
 
241
278
  <label for="~city">City</label>
242
279
  <input id="city">
243
- <fieldset>
280
+ <fieldset>
244
281
 
245
282
  <fieldset namespace>
246
283
  <legend>Delivery Address</legend>
@@ -250,14 +287,21 @@ Here, we get a modular naming convention using the `namespace` attribute. This a
250
287
 
251
288
  <label for="~city">City</label>
252
289
  <input id="city">
253
- <fieldset>
290
+ <fieldset>
254
291
 
255
292
  </form>
256
293
  ```
257
294
 
258
- This lets us have repeating structures with identical but non-conflicting identifiers and `IDREFS`.
295
+ This lets us have repeating structures with identical but non-conflicting identifiers. These identifiers are then referenced locally using "local `IDREFS`" - denoted by the `~` prefix.
296
+
297
+ Local `IDREFS` are resolved within the namespace where they're used (not globally; not deeply):
298
+
299
+ ```js
300
+ // Matches "#city" within the fieldset's namespace; not super namespace, not sub namespace
301
+ const city = fieldset.querySelector('#~city');
302
+ ```
259
303
 
260
- And this also translates well to an object model:
304
+ And when used from the document context, these are resolved against top-level IDs; i.e. IDs in the document namespace itself (not deeply):
261
305
 
262
306
  ```html
263
307
  <div id="user" namespace>
@@ -268,6 +312,29 @@ And this also translates well to an object model:
268
312
  </div>
269
313
  ```
270
314
 
315
+ ```js
316
+ // Namespace aware ID selectors
317
+ console.log(document.querySelector('#user')); // div#user
318
+ console.log(document.querySelector('#~user')); // div#user
319
+
320
+ console.log(document.getElementById('user')); // div#user
321
+ console.log(document.getElementById('~user')); // div#user
322
+
323
+ console.log(document.querySelector('#url')); // a#url
324
+ console.log(document.querySelector('#~url')); // null... not directly in the "document" namespace
325
+
326
+ console.log(document.getElementById('url')); // a#url
327
+ console.log(document.getElementById('~url')); // null... not directly in the "document" namespace
328
+ ```
329
+
330
+ And these also play well as navigation targets, with additional support for path expressions given a hierarchy of namespaces:
331
+
332
+ ```html
333
+ <a href="#~user/email">Jump to Email</a>
334
+ ```
335
+
336
+ And JavaScript applications are able to consume namespace structures as an object model:
337
+
271
338
  ```html
272
339
  user
273
340
  ├── url
@@ -275,8 +342,6 @@ user
275
342
  └── email
276
343
  ```
277
344
 
278
- with a complementary API that exposes said structure to JavaScript applications:
279
-
280
345
  ```js
281
346
  // The document.namespace API
282
347
  let { user } = document.namespace;
@@ -313,27 +378,55 @@ function changeCallback(changes) {
313
378
  }
314
379
  ```
315
380
 
316
- </details>
381
+ </details>
317
382
 
318
- <details><summary>Learn more</summary>
383
+ <details><summary>Implementation details</summary>
319
384
 
320
- You want to see how IDs are otherwise exposed as global variables:
385
+ In the current implementation, a small random string is automatically prepended to each ID and IDREF token in the DOM to give the browser something "unique" to work with, but without that implementation detail leaking into your application. So, while an element may be seen in the browser console as having a random hash prepended to their ID or IDREF:
321
386
 
322
387
  ```html
323
- <div id="foo"><div>
388
+ <!-- Original -->
389
+ <label for="~real-id">Question 1:</label>
390
+ <input id="real-id">
324
391
  ```
325
392
 
393
+ ```html
394
+ <!-- Transformed -->
395
+ <label for="~hg3j:real-id">Question 1:</label>
396
+ <input id="~hg3j:real-id">
397
+ ```
398
+
399
+ the values your application sees are the unprefixed IDs and IDREFs:
400
+
326
401
  ```js
327
- console.log(window.foo); // div
402
+ console.log(label.htmlFor); // ~real-id
403
+ console.log(input.id); // real-id
404
+
405
+ console.log(label.getAttribute('for')); // ~real-id
406
+ console.log(input.attributes[0].value); // real-id
328
407
  ```
329
408
 
330
- [Read more](https://stackoverflow.com/questions/6381425/is-there-a-spec-that-the-id-of-elements-should-be-made-global-variable)
409
+ Now, for URL targets, e.g. `#~user/email`, the "target" element is given a custom `:target` class while it matches the URL fragment, and this may be accessed in CSS as:
410
+
411
+ ```css
412
+ .\:target {
413
+ background-color: whitesmoke;
414
+ }
415
+ ```
416
+
417
+ or, to be more complete:
418
+
419
+ ```css
420
+ :target, .\:target {
421
+ background-color: whitesmoke;
422
+ }
423
+ ```
331
424
 
332
425
  </details>
333
426
 
334
427
  ### Style and Script Scoping
335
428
 
336
- We often need a way to keep component-specific stylesheets and scripts [scoped to a component](https://vuejs.org/guide/scaling-up/sfc.html). **This is especially crucial to "page components" in an SPA architecture.**
429
+ We often need a way to keep component-specific style sheets and scripts [scoped to a component](https://vuejs.org/guide/scaling-up/sfc.html). **This is especially crucial to "page components" in an SPA architecture.**
337
430
 
338
431
  Here, we get a new `scoped` attribute that lets us do just that:
339
432
 
@@ -351,7 +444,22 @@ Here, we get a new `scoped` attribute that lets us do just that:
351
444
  </div>
352
445
  ```
353
446
 
354
- **-->** *with a complementary low-level API that exposes said assets to tools*:
447
+ And the special namespace-aware ID selector is supported from within scoped style sheets:
448
+
449
+ ```html
450
+ <div namespace>
451
+ <a id="url" href="https://example.org">
452
+ <span id="name">Joe Bloggs</span>
453
+ </a>
454
+ <a id="email" href="mailto:joebloggs@example.com" >joebloggs@example.com</a>
455
+
456
+ <style scoped>
457
+ #\~name { color: red }
458
+ </style>
459
+ </div>
460
+ ```
461
+
462
+ And everything comes with a complementary low-level API that exposes said assets to tools:
355
463
 
356
464
  ```js
357
465
  let { styleSheets, scripts } = user; // APIs that are analogous to the document.styleSheets, document.scripts properties
@@ -362,15 +470,15 @@ let { styleSheets, scripts } = user; // APIs that are analogous to the document.
362
470
  Here, the `scoped` attribute has two effects on the `<script>` element:
363
471
 
364
472
  + The `this` keyword is implicitly bound to the script's host element
365
- + The `<script>` element is executed again on each re-insertion into the DOM
473
+ + The `<script>` element is (re)executed on each re-insertion into the DOM
366
474
 
367
475
  </details>
368
476
 
369
477
  ## HTML Imports
370
478
 
371
- HTML Imports is a realtime *import* system for HTML that's drawn entirely on HTML - and that's worlds apart from [the abandoned `<link type="import">` feature](https://www.w3.org/TR/html-imports/) and the [HTML Modules proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md)! **Something like it is the [`<defs>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs) and [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) system in SVG.**
479
+ HTML Imports is a realtime *import* system for HTML that's drawn entirely on HTML - and which addresses a different pain point in comparison to [the abandoned `<link type="import">` feature](https://www.w3.org/TR/html-imports/) and the [HTML Modules proposal](https://github.com/WICG/webcomponents/blob/gh-pages/proposals/html-modules-explainer.md)! **Something like it is the [`<defs>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/defs) and [`<use>`](https://developer.mozilla.org/en-US/docs/Web/SVG/Element/use) system in SVG.**
372
480
 
373
- Here, we get a way to both define and use a snippet within *same* document:
481
+ Here, we get a way to both define and reuse a snippet out of *same* document:
374
482
 
375
483
  ```html
376
484
  <head>
@@ -387,7 +495,7 @@ Here, we get a way to both define and use a snippet within *same* document:
387
495
  </body>
388
496
  ```
389
497
 
390
- ...and optionally support remote documents without a change in paradigm:
498
+ ...while optionally supporting remote content without a change in paradigm:
391
499
 
392
500
  ```html
393
501
  <head>
@@ -443,7 +551,7 @@ Here, we get the `def` attribute for defining those - both at the `<template>` e
443
551
 
444
552
  We shouldn't need a different mechanism to work with remote content.
445
553
 
446
- Here, OOHTML introduces an `src` attribute that lets us have self-loading `<template>` elements:
554
+ Here, OOHTML extends the `<template>` with an `src` attribute that lets us have self-loading `<template>` elements:
447
555
 
448
556
  ```html
449
557
  <template def="foo" src="/foo.html"></template>
@@ -597,7 +705,7 @@ setTimeout(() => {
597
705
  }, 1000);
598
706
  ```
599
707
 
600
- <details><summary>Extended Imports concepts</summary>
708
+ <!--<details><summary>Extended Imports concepts</summary>-->
601
709
 
602
710
  ### Lazy-Loading Modules
603
711
 
@@ -829,19 +937,19 @@ const contextElement = document.querySelector('div');
829
937
  const result = contextElement.import('foo#fragment2'); // the local module: foo#fragment2, and if not found, the inherited module: /bar/nested#fragment2
830
938
  ```
831
939
 
832
- </details>
940
+ <!--</details>-->
833
941
 
834
942
  ## Data Binding
835
943
 
836
- Data binding is a declarative approach to binding the UI to application data, wherein the relevant parts of the UI *automatically* update as application state changes.
944
+ Data binding is the idea of declaratively binding the UI to application data, wherein the relevant parts of the UI *automatically* update as application state changes.
837
945
 
838
- OOHTML makes this possible in just simple conventions - via a new comment-based data-binding syntax `<?{ }?>` and a complementary new `expr` attribute!
946
+ OOHTML makes this possible in just simple conventions - via a new comment-based data-binding syntax `<?{ }?>` and a complementary new `render` attribute!
839
947
 
840
- And for when we need to write extended reactive logic on the UI, a perfect answer: Quantum Scripts!
948
+ And for when we need to write extensive reactive logic on the UI, a perfect answer: Quantum Scripts!
841
949
 
842
950
  ### Discrete Data-Binding
843
951
 
844
- Here, we get a comment-based data-binding tag `<?{ }?>` (or `<!--?{ }?-->`), **which goes as a regular HTML comment** but also an insertion point for application data:
952
+ Here, we get a comment-based data-binding syntax `<?{ }?>` (or `<!--?{ }?-->`), **which works as a regular HTML comment** but also as an insertion point for application data:
845
953
 
846
954
  ```js
847
955
  <html>
@@ -906,10 +1014,12 @@ Now, on getting to the client, that extra bit of information gets decoded, and o
906
1014
 
907
1015
  ### Inline Data-Binding
908
1016
 
909
- For attribute-based data binding, OOHTML deviates from the usual (and problematic) idea of bringing markup-style bindings into attribute texts: `title="Hello { titleValue }"`, **as though attributes had the same semantics as markup**. Instead, we get a dedicated "expressions" attribute - `expr` - for a nifty, key/value data-binding language:
1017
+ For attribute-based data binding, OOHTML deviates from the usual (and problematic) idea of bringing markup-style bindings into attribute texts: `title="Hello { titleValue }"`, **as though attributes had the same semantics as markup**. Instead, we get a dedicated "render" attribute - `render` - for a nifty, key/value data-binding language:
1018
+
1019
+ > Note that in OOHTML <= v3 the `render` attribute was `expr`.
910
1020
 
911
1021
  ```html
912
- <div expr="<directive> <param>: <arg>;"></div>
1022
+ <div render="<directive> <param>: <arg>;"></div>
913
1023
  ```
914
1024
 
915
1025
  **-->** *where*:
@@ -921,36 +1031,36 @@ For attribute-based data binding, OOHTML deviates from the usual (and problemati
921
1031
  **-->** *which would give us the following for a CSS property*:
922
1032
 
923
1033
  ```html
924
- <div expr="& color:someColor; & backgroundColor:'red'"></div>
1034
+ <div render="& color:someColor; & backgroundColor:'red'"></div>
925
1035
  ```
926
1036
 
927
1037
  **-->** *without being space-sensitive*:
928
1038
 
929
1039
  ```html
930
- <div expr="& color:someColor; &backgroundColor: 'red'"></div>
1040
+ <div render="& color:someColor; &backgroundColor: 'red'"></div>
931
1041
  ```
932
1042
 
933
1043
  **-->** *the rest of which can be seen below*:
934
1044
 
935
1045
  | Directive | Type | Usage |
936
1046
  | :---- | :---- | :---- |
937
- | `&` | CSS Property | `<div expr="& color:someColor; & backgroundColor:someBgColor;"></div>` |
938
- | `%` | Class Name | `<div expr="% active:app.isActive; % expanded:app.isExpanded;"></div>` |
939
- | `~` | Attribute Name | `<a expr="~ href:person.profileUrl+'#bio'; ~ title:'Click me';"></a>` |
940
- | | Boolean Attribute | `<a expr="~ ?required:formField.required; ~ ?aria-checked: formField.checked"></a>` |
1047
+ | `&` | CSS Property | `<div render="& color:someColor; & backgroundColor:someBgColor;"></div>` |
1048
+ | `%` | Class Name | `<div render="% active:app.isActive; % expanded:app.isExpanded;"></div>` |
1049
+ | `~` | Attribute Name | `<a render="~ href:person.profileUrl+'#bio'; ~ title:'Click me';"></a>` |
1050
+ | | Boolean Attribute | `<a render="~ ?required:formField.required; ~ ?aria-checked: formField.checked"></a>` |
941
1051
  | `@` | Structural Directive: | *See below* |
942
- | `@text` | Plain text content | `<span expr="@text:firstName+' '+lastName;"></span>` |
943
- | `@html` | Markup content | `<span expr="@html: '<i>'+firstName+'</i>';"></span>` |
1052
+ | `@text` | Plain text content | `<span render="@text:firstName+' '+lastName;"></span>` |
1053
+ | `@html` | Markup content | `<span render="@html: '<i>'+firstName+'</i>';"></span>` |
944
1054
  | `@items` | A list, of the following format | `<declaration> <of\|in> <iterable> / <importRef>`<br>*See next two tables* |
945
1055
 
946
1056
  <details><summary><code>For ... Of</code> Loops</summary>
947
1057
 
948
1058
  | Idea | Usage |
949
1059
  | :---- | :---- |
950
- | A `for...of` loop over an array/iterable | `<ul expr="@items: value of [1,2,3] / 'foo#fragment';"></ul>` |
951
- | Same as above but with a `key` declaration | `<ul expr="@items: (value,key) of [1,2,3] / 'foo#fragment';"></ul>` |
952
- | Same as above but with different variable names | `<ul expr="@items: (product,id) of store.products / 'foo#fragment';"></ul>` |
953
- | Same as above but with a dynamic `importRef` | `<ul expr="@items: (product,id) of store.products / store.importRef;"></ul>` |
1060
+ | A `for...of` loop over an array/iterable | `<ul render="@items: value of [1,2,3] / 'foo#fragment';"></ul>` |
1061
+ | Same as above but with a `key` declaration | `<ul render="@items: (value,key) of [1,2,3] / 'foo#fragment';"></ul>` |
1062
+ | Same as above but with different variable names | `<ul render="@items: (product,id) of store.products / 'foo#fragment';"></ul>` |
1063
+ | Same as above but with a dynamic `importRef` | `<ul render="@items: (product,id) of store.products / store.importRef;"></ul>` |
954
1064
 
955
1065
  </details>
956
1066
 
@@ -958,8 +1068,8 @@ For attribute-based data binding, OOHTML deviates from the usual (and problemati
958
1068
 
959
1069
  | Idea | Usage |
960
1070
  | :---- | :---- |
961
- | A `for...in` loop over an object | `<ul expr="@items: key in {a:1,b:2} / 'foo#fragment';"></ul>` |
962
- | Same as above but with a `value` and `index` declaration | `<ul expr="@items: (key,value,index) in {a:1, b:2} / 'foo#fragment';"></ul>` |
1071
+ | A `for...in` loop over an object | `<ul render="@items: key in {a:1,b:2} / 'foo#fragment';"></ul>` |
1072
+ | Same as above but with a `value` and `index` declaration | `<ul render="@items: (key,value,index) in {a:1, b:2} / 'foo#fragment';"></ul>` |
963
1073
 
964
1074
  </details>
965
1075
 
@@ -1111,10 +1221,11 @@ Now, in each case above, reactivity terminates on script's removal from the DOM
1111
1221
  ```js
1112
1222
  const script = document.querySelector('script[quantum]');
1113
1223
  // const script = document.querySelector('main').scripts[0];
1114
- script.abort();
1224
+ script.state.dispose();
1225
+ // which also happens on doing script.remove()
1115
1226
  ```
1116
1227
 
1117
- But while that is automatic, DOM event handlers bound via `addEventListener()` would still need to be terminated in their own way.
1228
+ But note that while said termination is automatic on script's removal, DOM event handlers bound via `addEventListener()` would still need to be terminated in their own way.
1118
1229
 
1119
1230
  </details>
1120
1231
 
@@ -1170,7 +1281,7 @@ node.bindings.style = 'tall-dark';
1170
1281
  node.bindings.normalize = true;
1171
1282
  ```
1172
1283
 
1173
- **-->** *with a complementary `bind()` method that lets us make mutations in batch*:
1284
+ **-->** *with a complementary `bind()` method that lets us make multiple mutations in one batch*:
1174
1285
 
1175
1286
  ```js
1176
1287
  // ------------
@@ -1223,7 +1334,7 @@ const node = document.querySelector('my-element');
1223
1334
  node.bindings.style = 'tall-dark';
1224
1335
  ```
1225
1336
 
1226
- <details><summary>Details</summary>
1337
+ <details><summary>Implementation details</summary>
1227
1338
 
1228
1339
  In the current OOHTML implementation, the `document.bindings` and `Element.prototype.bindings` APIs are implemented as proxies over their actual bindings interface to enable some interface-level reactivity. This lets us have reactivity over literal property assignments and deletions on these interfaces:
1229
1340
 
@@ -1243,9 +1354,9 @@ Observer.deleteProperty(document.bindings.app, 'title');
1243
1354
 
1244
1355
  ### The Context API
1245
1356
 
1246
- Component trees on the typical UI often call for more than the normal top-down flow of data that the Bindings API facilitates. A child may require the ability to look up the component tree to directly access specific data, or in other words, get data from "context". This is where a Context API comes in.
1357
+ Component trees on the typical UI often call for more than the normal "top-down" flow of data that the Bindings API facilitates. We still often require the ability to "look up" the component tree to directly access specific data, or in other words, get data from "context". This is where a Context API comes in.
1247
1358
 
1248
- Interestingly, the Context API is the underlying resolution mechanism behind HTML Imports and Data Binding in OOHTML!
1359
+ Interestingly, the Context API is the underlying "resolution" infrastructure for the Namespace API and the Data Binding and HTML Imports features in OOHTML!
1249
1360
 
1250
1361
  Here, we simply leverage the DOM's existing event system to fire a "request" event and let an arbitrary "provider" in context fulfill the request. This becomes very simple with the Context API which is exposed on the document object and on element instances as a readonly `contexts` property.
1251
1362
 
@@ -1574,8 +1685,8 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1574
1685
  <div id="ss_elem_list"
1575
1686
  tabindex="0"
1576
1687
  role="listbox"
1577
- aria-labelledby="ss_elem">
1578
- <ul role="group" aria-labelledby="cat" namespace>
1688
+ aria-labelledby="~ss_elem">
1689
+ <ul role="group" namespace aria-labelledby="~cat">
1579
1690
  <li role="presentation" id="cat">
1580
1691
  Land
1581
1692
  </li>
@@ -1595,7 +1706,7 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1595
1706
  Raccoon
1596
1707
  </li>
1597
1708
  </ul>
1598
- <ul role="group" aria-labelledby="cat" namespace>
1709
+ <ul role="group" namespace aria-labelledby="~cat">
1599
1710
  <li role="presentation" id="cat">
1600
1711
  Water
1601
1712
  </li>
@@ -1609,7 +1720,7 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1609
1720
  Eel
1610
1721
  </li>
1611
1722
  </ul>
1612
- <ul role="group" aria-labelledby="cat" namespace>
1723
+ <ul role="group" namespace aria-labelledby="~cat">
1613
1724
  <li role="presentation" id="cat">
1614
1725
  Air
1615
1726
  </li>
@@ -1694,11 +1805,11 @@ The following is a hypothetical list page!
1694
1805
 
1695
1806
  <!-- The "items" template -->
1696
1807
  <template def="item" scoped>
1697
- <li><a expr="~href: '/animals#'+name;"><?{ index+': '+name }?></a></li>
1808
+ <li><a render="~href: '/animals#'+name;"><?{ index+': '+name }?></a></li>
1698
1809
  </template>
1699
1810
 
1700
1811
  <!-- The loop -->
1701
- <ul expr="@items: (name,index) of ['dog','cat','ram'] / 'item';"></ul>
1812
+ <ul render="@items: (name,index) of ['dog','cat','ram'] / 'item';"></ul>
1702
1813
 
1703
1814
  </section>
1704
1815
  ```