@webqit/oohtml 3.2.0 → 4.0.0

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
@@ -19,7 +19,7 @@ Building Single Page Applications? OOHTML is a special love letter! Writing Web
19
19
 
20
20
  ## Polyfill
21
21
 
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.
22
+ 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
23
 
24
24
  <details><summary>Load from a CDN<br>
25
25
  └───────── <a href="https://bundlephobia.com/result?p=@webqit/oohtml"><img align="right" src="https://img.shields.io/badge/21.8%20kB-black"></a></summary>
@@ -114,12 +114,12 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
114
114
 
115
115
  ...still gives the `window` object in the console.
116
116
 
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:
117
+ + **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
118
 
119
119
  ```html
120
120
  <head>
121
121
  <!-- Configurations come before the polyfil -->
122
- <meta name="data-binding" content="attr.expr=expr;">
122
+ <meta name="data-binding" content="attr.render=render;">
123
123
  <meta name="namespaced-html" content="attr.id=id;">
124
124
  <meta name="html-imports" content="attr.def=def; attr.ref=ref;">
125
125
  <script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
@@ -143,16 +143,16 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
143
143
  + `document.bindings` now becomes: `document.wqBindings`,
144
144
  + etc.
145
145
 
146
- The following is the full syntax table.
146
+ <details><summary>Show the full syntax table</summary>
147
147
 
148
- Spec: **data-binding**
148
+ **Spec: `<meta name="data-binding">`**
149
149
 
150
150
  | Config | Default Syntax | Description |
151
151
  | :----- | :------------- | :---------- |
152
- | `attr.expr` | `expr` | The "expr" attribute for inline data binding. ([Docs](#inline-data-binding)) |
152
+ | `attr.render` | `render` | The "render" attribute for inline data binding. ([Docs](#inline-data-binding)) |
153
153
  | `attr.itemIndex` | `data-index` | The "item index" attribute for assigning indexes to list items. ([Docs](#inline-data-binding)) |
154
154
 
155
- Spec: **bindings-api**
155
+ **Spec: `<meta name="bindings-api">`**
156
156
 
157
157
  | Config | Default Syntax | Description |
158
158
  | :----- | :------------- | :---------- |
@@ -160,14 +160,14 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
160
160
  | `api.bind` | `bind` | The `document.bind()` and `Element.prototype.bind()` methods. ([Docs](#the-bindings-api)) |
161
161
  | `api.bindings` | `bindings` | The `document.bindings` and `Element.prototype.bindings` object properties. ([Docs](#the-bindings-api)) |
162
162
 
163
- Spec: **context-api**
163
+ **Spec: `<meta name="context-api">`**
164
164
 
165
165
  | Config | Default Syntax | Description |
166
166
  | :----- | :------------- | :---------- |
167
167
  | `attr.contextname` | `contextname` | The "context name" attribute on arbitrary elements. ([Docs](#the-context-api)) |
168
168
  | `api.contexts` | `contexts` | The `document.contexts` and `Element.prototype.contexts` object properties. ([Docs](#the-context-api)) |
169
169
 
170
- Spec: **html-imports**
170
+ **Spec: `<meta name="html-imports">`**
171
171
 
172
172
  | Config | Default Syntax | Description |
173
173
  | :----- | :------------- | :---------- |
@@ -182,7 +182,8 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
182
182
  | `api.defs` | `defs` | The readonly object property for accessing a `<template>`'s list of definitions. ([Docs](#module-definition)) |
183
183
  | `api.import` | `import` | The `document.import()` and `Element.prototype.import()` methods. ([Docs](#imperative-module-imports)) |
184
184
 
185
- Spec: **namespaced-html**
185
+
186
+ **Spec: `<meta name="namespaced-html">`**
186
187
 
187
188
  | Config | Default Syntax | Description |
188
189
  | :----- | :------------- | :---------- |
@@ -190,9 +191,11 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
190
191
  | `attr.id` | `id` | The "id" attribute on arbitrary elements. ([Docs](#namespacing)) |
191
192
  | `api.namespace` | `namespace` | The "namespace" object property on arbitrary elements. ([Docs](#namespacing)) |
192
193
 
193
- Spec: **scoped-css** (TODO)
194
+ **Spec: `<meta name="scoped-css">`** (TODO)
195
+
196
+ **Spec: `<meta name="scoped-js">`** (TODO)
194
197
 
195
- Spec: **scoped-js** (TODO)
198
+ </details>
196
199
 
197
200
  </details>
198
201
 
@@ -202,7 +205,7 @@ If you'll be going ahead to build a real app with OOHTML, you may want to consid
202
205
 
203
206
  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
207
 
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!
208
+ "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
209
 
207
210
  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
211
 
@@ -219,7 +222,7 @@ OOHTML is effectively different from Web Components (and from the related Declar
219
222
 
220
223
  ## Modular HTML
221
224
 
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!
225
+ The modern UI is best approached with a modular architecture (think UI component frameworks) wherein we are able to author the bits and pieces as self-contained objects - enabling us *encapsulate* structure, styling and logic!
223
226
 
224
227
  OOHTML makes this possible by introducing "namespacing" and style and script scoping!
225
228
 
@@ -227,7 +230,23 @@ OOHTML makes this possible by introducing "namespacing" and style and script sco
227
230
 
228
231
  Naming things is hard! That's especially so where you have one global namespace and a miriad of potentially conflicting identifiers to coordinate!
229
232
 
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:
233
+ <details><summary>Learn more</summary>
234
+
235
+ You want to see how IDs are, in fact, by default, exposed as global variables:
236
+
237
+ ```html
238
+ <div id="foo"><div>
239
+ ```
240
+
241
+ ```js
242
+ console.log(window.foo); // div
243
+ ```
244
+
245
+ [Read more](https://stackoverflow.com/questions/6381425/is-there-a-spec-that-the-id-of-elements-should-be-made-global-variable)
246
+
247
+ </details>
248
+
249
+ 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
250
 
232
251
  ```html
233
252
  <form>
@@ -240,7 +259,7 @@ Here, we get a modular naming convention using the `namespace` attribute. This a
240
259
 
241
260
  <label for="~city">City</label>
242
261
  <input id="city">
243
- <fieldset>
262
+ <fieldset>
244
263
 
245
264
  <fieldset namespace>
246
265
  <legend>Delivery Address</legend>
@@ -250,14 +269,21 @@ Here, we get a modular naming convention using the `namespace` attribute. This a
250
269
 
251
270
  <label for="~city">City</label>
252
271
  <input id="city">
253
- <fieldset>
272
+ <fieldset>
254
273
 
255
274
  </form>
256
275
  ```
257
276
 
258
- This lets us have repeating structures with identical but non-conflicting identifiers and `IDREFS`.
277
+ 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.
259
278
 
260
- And this also translates well to an object model:
279
+ Local `IDREFS` are resolved within the namespace where they're used (not globally; not deeply):
280
+
281
+ ```js
282
+ // Matches "#city" within the fieldset's namespace; not super namespace, not sub namespace
283
+ const city = fieldset.querySelector('#~city');
284
+ ```
285
+
286
+ 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
287
 
262
288
  ```html
263
289
  <div id="user" namespace>
@@ -268,6 +294,29 @@ And this also translates well to an object model:
268
294
  </div>
269
295
  ```
270
296
 
297
+ ```js
298
+ // Namespace aware ID selectors
299
+ console.log(document.querySelector('#user')); // div#user
300
+ console.log(document.querySelector('#~user')); // div#user
301
+
302
+ console.log(document.getElementById('user')); // div#user
303
+ console.log(document.getElementById('~user')); // div#user
304
+
305
+ console.log(document.querySelector('#url')); // a#url
306
+ console.log(document.querySelector('#~url')); // null... not directly in the "document" namespace
307
+
308
+ console.log(document.getElementById('url')); // a#url
309
+ console.log(document.getElementById('~url')); // null... not directly in the "document" namespace
310
+ ```
311
+
312
+ And these also play well as navigation targets, with additional support for path expressions given a hierarchy of namespaces:
313
+
314
+ ```html
315
+ <a href="#~user/email">Jump to Email</a>
316
+ ```
317
+
318
+ And JavaScript applications are able to consume namespace structures as an object model:
319
+
271
320
  ```html
272
321
  user
273
322
  ├── url
@@ -275,8 +324,6 @@ user
275
324
  └── email
276
325
  ```
277
326
 
278
- with a complementary API that exposes said structure to JavaScript applications:
279
-
280
327
  ```js
281
328
  // The document.namespace API
282
329
  let { user } = document.namespace;
@@ -313,27 +360,55 @@ function changeCallback(changes) {
313
360
  }
314
361
  ```
315
362
 
316
- </details>
363
+ </details>
317
364
 
318
- <details><summary>Learn more</summary>
365
+ <details><summary>Implementation details</summary>
319
366
 
320
- You want to see how IDs are otherwise exposed as global variables:
367
+ 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
368
 
322
369
  ```html
323
- <div id="foo"><div>
370
+ <!-- Original -->
371
+ <label for="~real-id">Question 1:</label>
372
+ <input id="real-id">
373
+ ```
374
+
375
+ ```html
376
+ <!-- Transformed -->
377
+ <label for="~hg3j:real-id">Question 1:</label>
378
+ <input id="~hg3j:real-id">
324
379
  ```
325
380
 
381
+ the values your application sees are the unprefixed IDs and IDREFs:
382
+
326
383
  ```js
327
- console.log(window.foo); // div
384
+ console.log(label.htmlFor); // ~real-id
385
+ console.log(input.id); // real-id
386
+
387
+ console.log(label.getAttribute('for')); // ~real-id
388
+ console.log(input.attributes[0].value); // real-id
328
389
  ```
329
390
 
330
- [Read more](https://stackoverflow.com/questions/6381425/is-there-a-spec-that-the-id-of-elements-should-be-made-global-variable)
391
+ 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:
392
+
393
+ ```css
394
+ .\:target {
395
+ background-color: whitesmoke;
396
+ }
397
+ ```
398
+
399
+ or, to be more complete:
400
+
401
+ ```css
402
+ :target, .\:target {
403
+ background-color: whitesmoke;
404
+ }
405
+ ```
331
406
 
332
407
  </details>
333
408
 
334
409
  ### Style and Script Scoping
335
410
 
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.**
411
+ 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
412
 
338
413
  Here, we get a new `scoped` attribute that lets us do just that:
339
414
 
@@ -351,7 +426,22 @@ Here, we get a new `scoped` attribute that lets us do just that:
351
426
  </div>
352
427
  ```
353
428
 
354
- **-->** *with a complementary low-level API that exposes said assets to tools*:
429
+ And the special namespace-aware ID selector is supported from within scoped style sheets:
430
+
431
+ ```html
432
+ <div namespace>
433
+ <a id="url" href="https://example.org">
434
+ <span id="name">Joe Bloggs</span>
435
+ </a>
436
+ <a id="email" href="mailto:joebloggs@example.com" >joebloggs@example.com</a>
437
+
438
+ <style scoped>
439
+ #\~name { color: red }
440
+ </style>
441
+ </div>
442
+ ```
443
+
444
+ And everything comes with a complementary low-level API that exposes said assets to tools:
355
445
 
356
446
  ```js
357
447
  let { styleSheets, scripts } = user; // APIs that are analogous to the document.styleSheets, document.scripts properties
@@ -362,15 +452,15 @@ let { styleSheets, scripts } = user; // APIs that are analogous to the document.
362
452
  Here, the `scoped` attribute has two effects on the `<script>` element:
363
453
 
364
454
  + 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
455
+ + The `<script>` element is (re)executed on each re-insertion into the DOM
366
456
 
367
457
  </details>
368
458
 
369
459
  ## HTML Imports
370
460
 
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.**
461
+ 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
462
 
373
- Here, we get a way to both define and use a snippet within *same* document:
463
+ Here, we get a way to both define and reuse a snippet out of *same* document:
374
464
 
375
465
  ```html
376
466
  <head>
@@ -387,7 +477,7 @@ Here, we get a way to both define and use a snippet within *same* document:
387
477
  </body>
388
478
  ```
389
479
 
390
- ...and optionally support remote documents without a change in paradigm:
480
+ ...while optionally supporting remote content without a change in paradigm:
391
481
 
392
482
  ```html
393
483
  <head>
@@ -443,7 +533,7 @@ Here, we get the `def` attribute for defining those - both at the `<template>` e
443
533
 
444
534
  We shouldn't need a different mechanism to work with remote content.
445
535
 
446
- Here, OOHTML introduces an `src` attribute that lets us have self-loading `<template>` elements:
536
+ Here, OOHTML extends the `<template>` with an `src` attribute that lets us have self-loading `<template>` elements:
447
537
 
448
538
  ```html
449
539
  <template def="foo" src="/foo.html"></template>
@@ -597,7 +687,7 @@ setTimeout(() => {
597
687
  }, 1000);
598
688
  ```
599
689
 
600
- <details><summary>Extended Imports concepts</summary>
690
+ <!--<details><summary>Extended Imports concepts</summary>-->
601
691
 
602
692
  ### Lazy-Loading Modules
603
693
 
@@ -829,19 +919,19 @@ const contextElement = document.querySelector('div');
829
919
  const result = contextElement.import('foo#fragment2'); // the local module: foo#fragment2, and if not found, the inherited module: /bar/nested#fragment2
830
920
  ```
831
921
 
832
- </details>
922
+ <!--</details>-->
833
923
 
834
924
  ## Data Binding
835
925
 
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.
926
+ 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
927
 
838
- OOHTML makes this possible in just simple conventions - via a new comment-based data-binding syntax `<?{ }?>` and a complementary new `expr` attribute!
928
+ OOHTML makes this possible in just simple conventions - via a new comment-based data-binding syntax `<?{ }?>` and a complementary new `render` attribute!
839
929
 
840
- And for when we need to write extended reactive logic on the UI, a perfect answer: Quantum Scripts!
930
+ And for when we need to write extensive reactive logic on the UI, a perfect answer: Quantum Scripts!
841
931
 
842
932
  ### Discrete Data-Binding
843
933
 
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:
934
+ 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
935
 
846
936
  ```js
847
937
  <html>
@@ -906,10 +996,12 @@ Now, on getting to the client, that extra bit of information gets decoded, and o
906
996
 
907
997
  ### Inline Data-Binding
908
998
 
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:
999
+ 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:
1000
+
1001
+ > Note that in OOHTML <= v3 the `render` attribute was `expr`.
910
1002
 
911
1003
  ```html
912
- <div expr="<directive> <param>: <arg>;"></div>
1004
+ <div render="<directive> <param>: <arg>;"></div>
913
1005
  ```
914
1006
 
915
1007
  **-->** *where*:
@@ -921,36 +1013,36 @@ For attribute-based data binding, OOHTML deviates from the usual (and problemati
921
1013
  **-->** *which would give us the following for a CSS property*:
922
1014
 
923
1015
  ```html
924
- <div expr="& color:someColor; & backgroundColor:'red'"></div>
1016
+ <div render="& color:someColor; & backgroundColor:'red'"></div>
925
1017
  ```
926
1018
 
927
1019
  **-->** *without being space-sensitive*:
928
1020
 
929
1021
  ```html
930
- <div expr="& color:someColor; &backgroundColor: 'red'"></div>
1022
+ <div render="& color:someColor; &backgroundColor: 'red'"></div>
931
1023
  ```
932
1024
 
933
1025
  **-->** *the rest of which can be seen below*:
934
1026
 
935
1027
  | Directive | Type | Usage |
936
1028
  | :---- | :---- | :---- |
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>` |
1029
+ | `&` | CSS Property | `<div render="& color:someColor; & backgroundColor:someBgColor;"></div>` |
1030
+ | `%` | Class Name | `<div render="% active:app.isActive; % expanded:app.isExpanded;"></div>` |
1031
+ | `~` | Attribute Name | `<a render="~ href:person.profileUrl+'#bio'; ~ title:'Click me';"></a>` |
1032
+ | | Boolean Attribute | `<a render="~ ?required:formField.required; ~ ?aria-checked: formField.checked"></a>` |
941
1033
  | `@` | 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>` |
1034
+ | `@text` | Plain text content | `<span render="@text:firstName+' '+lastName;"></span>` |
1035
+ | `@html` | Markup content | `<span render="@html: '<i>'+firstName+'</i>';"></span>` |
944
1036
  | `@items` | A list, of the following format | `<declaration> <of\|in> <iterable> / <importRef>`<br>*See next two tables* |
945
1037
 
946
1038
  <details><summary><code>For ... Of</code> Loops</summary>
947
1039
 
948
1040
  | Idea | Usage |
949
1041
  | :---- | :---- |
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>` |
1042
+ | A `for...of` loop over an array/iterable | `<ul render="@items: value of [1,2,3] / 'foo#fragment';"></ul>` |
1043
+ | Same as above but with a `key` declaration | `<ul render="@items: (value,key) of [1,2,3] / 'foo#fragment';"></ul>` |
1044
+ | Same as above but with different variable names | `<ul render="@items: (product,id) of store.products / 'foo#fragment';"></ul>` |
1045
+ | Same as above but with a dynamic `importRef` | `<ul render="@items: (product,id) of store.products / store.importRef;"></ul>` |
954
1046
 
955
1047
  </details>
956
1048
 
@@ -958,8 +1050,8 @@ For attribute-based data binding, OOHTML deviates from the usual (and problemati
958
1050
 
959
1051
  | Idea | Usage |
960
1052
  | :---- | :---- |
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>` |
1053
+ | A `for...in` loop over an object | `<ul render="@items: key in {a:1,b:2} / 'foo#fragment';"></ul>` |
1054
+ | 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
1055
 
964
1056
  </details>
965
1057
 
@@ -1111,10 +1203,11 @@ Now, in each case above, reactivity terminates on script's removal from the DOM
1111
1203
  ```js
1112
1204
  const script = document.querySelector('script[quantum]');
1113
1205
  // const script = document.querySelector('main').scripts[0];
1114
- script.abort();
1206
+ script.state.dispose();
1207
+ // which also happens on doing script.remove()
1115
1208
  ```
1116
1209
 
1117
- But while that is automatic, DOM event handlers bound via `addEventListener()` would still need to be terminated in their own way.
1210
+ 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
1211
 
1119
1212
  </details>
1120
1213
 
@@ -1170,7 +1263,7 @@ node.bindings.style = 'tall-dark';
1170
1263
  node.bindings.normalize = true;
1171
1264
  ```
1172
1265
 
1173
- **-->** *with a complementary `bind()` method that lets us make mutations in batch*:
1266
+ **-->** *with a complementary `bind()` method that lets us make multiple mutations in one batch*:
1174
1267
 
1175
1268
  ```js
1176
1269
  // ------------
@@ -1223,7 +1316,7 @@ const node = document.querySelector('my-element');
1223
1316
  node.bindings.style = 'tall-dark';
1224
1317
  ```
1225
1318
 
1226
- <details><summary>Details</summary>
1319
+ <details><summary>Implementation details</summary>
1227
1320
 
1228
1321
  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
1322
 
@@ -1243,9 +1336,9 @@ Observer.deleteProperty(document.bindings.app, 'title');
1243
1336
 
1244
1337
  ### The Context API
1245
1338
 
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.
1339
+ 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
1340
 
1248
- Interestingly, the Context API is the underlying resolution mechanism behind HTML Imports and Data Binding in OOHTML!
1341
+ Interestingly, the Context API is the underlying "resolution" infrastructure for the Namespace API and the Data Binding and HTML Imports features in OOHTML!
1249
1342
 
1250
1343
  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
1344
 
@@ -1574,8 +1667,8 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1574
1667
  <div id="ss_elem_list"
1575
1668
  tabindex="0"
1576
1669
  role="listbox"
1577
- aria-labelledby="ss_elem">
1578
- <ul role="group" aria-labelledby="cat" namespace>
1670
+ aria-labelledby="~ss_elem">
1671
+ <ul role="group" namespace aria-labelledby="~cat">
1579
1672
  <li role="presentation" id="cat">
1580
1673
  Land
1581
1674
  </li>
@@ -1595,7 +1688,7 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1595
1688
  Raccoon
1596
1689
  </li>
1597
1690
  </ul>
1598
- <ul role="group" aria-labelledby="cat" namespace>
1691
+ <ul role="group" namespace aria-labelledby="~cat">
1599
1692
  <li role="presentation" id="cat">
1600
1693
  Water
1601
1694
  </li>
@@ -1609,7 +1702,7 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1609
1702
  Eel
1610
1703
  </li>
1611
1704
  </ul>
1612
- <ul role="group" aria-labelledby="cat" namespace>
1705
+ <ul role="group" namespace aria-labelledby="~cat">
1613
1706
  <li role="presentation" id="cat">
1614
1707
  Air
1615
1708
  </li>
@@ -1694,11 +1787,11 @@ The following is a hypothetical list page!
1694
1787
 
1695
1788
  <!-- The "items" template -->
1696
1789
  <template def="item" scoped>
1697
- <li><a expr="~href: '/animals#'+name;"><?{ index+': '+name }?></a></li>
1790
+ <li><a render="~href: '/animals#'+name;"><?{ index+': '+name }?></a></li>
1698
1791
  </template>
1699
1792
 
1700
1793
  <!-- The loop -->
1701
- <ul expr="@items: (name,index) of ['dog','cat','ram'] / 'item';"></ul>
1794
+ <ul render="@items: (name,index) of ['dog','cat','ram'] / 'item';"></ul>
1702
1795
 
1703
1796
  </section>
1704
1797
  ```