@webqit/oohtml 2.1.36 → 2.1.38
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 +105 -33
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -94,8 +94,9 @@ The next set of features covers *templating and reusing objects* - in both *decl
|
|
|
94
94
|
<head>
|
|
95
95
|
|
|
96
96
|
<template as="foo">
|
|
97
|
-
<div as="fragment1"
|
|
98
|
-
<div as="fragment2"
|
|
97
|
+
<div as="fragment1">A module fragment that can be accessed independently</div>
|
|
98
|
+
<div as="fragment2">Another module fragment that can be accessed independently</div>
|
|
99
|
+
<p>An element that isn't explicitly exposed.</p>
|
|
99
100
|
</template>
|
|
100
101
|
|
|
101
102
|
</head>
|
|
@@ -155,17 +156,17 @@ foo.addEventListener('load', loadedCallback);
|
|
|
155
156
|
</body>
|
|
156
157
|
```
|
|
157
158
|
|
|
159
|
+
└ *The HTMLImports API for programmatic module import*:
|
|
160
|
+
|
|
158
161
|
```js
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
console.log(docFragment); // DucmentFragment:/foo#fragment2, received synchronously
|
|
162
|
+
document.import('/foo#fragment1', divElement => {
|
|
163
|
+
console.log(divElement); // module:/foo#fragment2, received synchronously
|
|
162
164
|
});
|
|
163
165
|
```
|
|
164
166
|
|
|
165
167
|
```js
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
console.log(docFragment); // DucmentFragment:/foo/nested#fragment2;
|
|
168
|
+
document.import('/foo/nested#fragment2', divElement => {
|
|
169
|
+
console.log(divElement); // module:/foo/nested#fragment2;
|
|
169
170
|
});
|
|
170
171
|
```
|
|
171
172
|
|
|
@@ -188,15 +189,15 @@ document.import('/foo/nested#fragment2', docFragment => {
|
|
|
188
189
|
|
|
189
190
|
```js
|
|
190
191
|
// Using the HTMLImports API
|
|
191
|
-
document.querySelector('div').import('foo#fragment1',
|
|
192
|
-
console.log(
|
|
192
|
+
document.querySelector('div').import('foo#fragment1', divElement => {
|
|
193
|
+
console.log(divElement); // the local module: foo#fragment1
|
|
193
194
|
});
|
|
194
195
|
```
|
|
195
196
|
|
|
196
197
|
```js
|
|
197
198
|
// Using the HTMLImports API
|
|
198
|
-
document.querySelector('div').import('/foo#fragment1',
|
|
199
|
-
console.log(
|
|
199
|
+
document.querySelector('div').import('/foo#fragment1', divElement => {
|
|
200
|
+
console.log(divElement); // the global module: foo#fragment1
|
|
200
201
|
});
|
|
201
202
|
```
|
|
202
203
|
|
|
@@ -251,24 +252,19 @@ Extended Imports concepts
|
|
|
251
252
|
└ *Remote modules with lazy-loading*:
|
|
252
253
|
|
|
253
254
|
```html
|
|
255
|
+
<!-- Loading doesn't happen until the first time this is being accessed -->
|
|
254
256
|
<template as="foo" src="/foo.html" loading="lazy"></template>
|
|
255
257
|
```
|
|
256
258
|
|
|
257
|
-
```
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
```js
|
|
263
|
-
// On subsequent access, after load
|
|
264
|
-
console.log(foo.modules.m1); // module:m1
|
|
259
|
+
```html
|
|
260
|
+
<body>
|
|
261
|
+
<import ref="/foo#fragment1"></import> <!-- To be resolved after remote module has been loaded -->
|
|
262
|
+
</body>
|
|
265
263
|
```
|
|
266
264
|
|
|
267
265
|
```js
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
document.context.ask(request, response => {
|
|
271
|
-
console.log(response); // module:/foo#m2; module loading triggered on first request and received asynchronously, then synchronously on subsequent requests after loaded
|
|
266
|
+
document.import('/foo#fragment1', divElement => {
|
|
267
|
+
console.log(divElement); // To be received after remote module has been loaded
|
|
272
268
|
});
|
|
273
269
|
```
|
|
274
270
|
|
|
@@ -292,8 +288,8 @@ document.context.ask(request, response => {
|
|
|
292
288
|
|
|
293
289
|
```js
|
|
294
290
|
// Using the HTMLImports API
|
|
295
|
-
document.querySelector('section').import('#fragment2',
|
|
296
|
-
console.log(
|
|
291
|
+
document.querySelector('section').import('#fragment2', divElement => {
|
|
292
|
+
console.log(divElement); // module:/foo/nested#fragment2
|
|
297
293
|
});
|
|
298
294
|
```
|
|
299
295
|
|
|
@@ -316,8 +312,8 @@ document.querySelector('section').import('#fragment2', docFragment => {
|
|
|
316
312
|
|
|
317
313
|
```js
|
|
318
314
|
// Using the HTMLImports API
|
|
319
|
-
document.querySelector('div').import('@context1#fragment2',
|
|
320
|
-
console.log(
|
|
315
|
+
document.querySelector('div').import('@context1#fragment2', divElement => {
|
|
316
|
+
console.log(divElement); // module:/foo/nested#fragment2
|
|
321
317
|
});
|
|
322
318
|
```
|
|
323
319
|
|
|
@@ -358,8 +354,8 @@ document.querySelector('div').import('@context1#fragment2', docFragment => {
|
|
|
358
354
|
|
|
359
355
|
```js
|
|
360
356
|
// Using the HTMLImports API
|
|
361
|
-
document.querySelector('div').import('#fragment2',
|
|
362
|
-
console.log(
|
|
357
|
+
document.querySelector('div').import('#fragment2', divElement => {
|
|
358
|
+
console.log(divElement); // the local module: foo#fragment2, and if not found, resolves from context to the module: /bar/nested#fragment2
|
|
363
359
|
});
|
|
364
360
|
```
|
|
365
361
|
|
|
@@ -482,7 +478,9 @@ Observer.set(element, 'liveProperty'); // Live expressions rerun
|
|
|
482
478
|
|
|
483
479
|
### Put Together
|
|
484
480
|
|
|
485
|
-
All of OOHTML brings to the platform much of the modern UI development paradigms that community-based tools have encoded
|
|
481
|
+
All of OOHTML brings to the platform much of the modern UI development paradigms that community-based tools have long encoded, and that just opens up new ways to leverage the web platform and bank less on abstractions! Here are a few examples in the wide range of use cases these features cover.
|
|
482
|
+
|
|
483
|
+
**--> Example 1:** The following is how something you could call a Single Page Application ([SPA](https://en.wikipedia.org/wiki/Single-page_application)) could be made - with zero tooling:
|
|
486
484
|
|
|
487
485
|
└ *First, two components that are themselves analogous to a Single File Component ([SFC](https://vuejs.org/guide/scaling-up/sfc.html))*:
|
|
488
486
|
|
|
@@ -536,7 +534,7 @@ All of OOHTML brings to the platform much of the modern UI development paradigms
|
|
|
536
534
|
</body>
|
|
537
535
|
```
|
|
538
536
|
|
|
539
|
-
|
|
537
|
+
**--> Example 2:** The following is a Listbox component lifted directively from [ARIA Authoring Practices Guide (APG)](https://www.w3.org/WAI/ARIA/apg/patterns/listbox/examples/listbox-grouped/#sc_label) but with IDs effectively "contained" at different levels within the component using the `namespace` attribute.
|
|
540
538
|
|
|
541
539
|
└ *A Listbox with namespaced IDs*:
|
|
542
540
|
|
|
@@ -603,6 +601,80 @@ As another example - being that a wide range of use cases exists beyond the abov
|
|
|
603
601
|
</div>
|
|
604
602
|
```
|
|
605
603
|
|
|
604
|
+
**--> Example 3:** The following is a custom element that derives its Shadow DOM from an imported `<tenplate>`. The idea is to have different Shadow DOM layouts defined and let the "usage" context decide which variant is imported!
|
|
605
|
+
|
|
606
|
+
└ *First, two layout options defined for the Shadow DOM*:
|
|
607
|
+
|
|
608
|
+
```html
|
|
609
|
+
<template as="vendor1">
|
|
610
|
+
|
|
611
|
+
<template as="components-layout1">
|
|
612
|
+
<template as="magic-button">
|
|
613
|
+
<span id="icon"></span> <span id="text"></span>
|
|
614
|
+
</template>
|
|
615
|
+
</template>
|
|
616
|
+
|
|
617
|
+
<template as="components-layout2">
|
|
618
|
+
<template as="magic-button">
|
|
619
|
+
<span id="text"></span> <span id="icon"></span>
|
|
620
|
+
</template>
|
|
621
|
+
</template>
|
|
622
|
+
|
|
623
|
+
</template>
|
|
624
|
+
```
|
|
625
|
+
|
|
626
|
+
└ *Next, the Shadow DOM creation that let's the context decide what's imported*:
|
|
627
|
+
|
|
628
|
+
```js
|
|
629
|
+
customElements.define('magic-button', class extends HTMLElement {
|
|
630
|
+
connectedCallback() {
|
|
631
|
+
const shadowRoot = this.attachShadow({ mode: 'open' });
|
|
632
|
+
this.import('@vendor1/magic-button', template => {
|
|
633
|
+
shadowRoot.appendChild( template.content.cloneNode(true) );
|
|
634
|
+
});
|
|
635
|
+
}
|
|
636
|
+
});
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
└ *Then, the part where we just drop the component in "layout" contexts*:
|
|
640
|
+
|
|
641
|
+
```html
|
|
642
|
+
<div contextname="vendor1" importscontext="/vendor1/components-layout1">
|
|
643
|
+
|
|
644
|
+
<magic-button></magic-button>
|
|
645
|
+
|
|
646
|
+
<aside contextname="vendor1" importscontext="/vendor1/components-layout2">
|
|
647
|
+
<magic-button></magic-button>
|
|
648
|
+
</aside>
|
|
649
|
+
|
|
650
|
+
</div>
|
|
651
|
+
```
|
|
652
|
+
|
|
653
|
+
**--> Example 4:** The following is a "list" element that derives its list items from a "scoped" `<tenplate>` element. The idea is to have a "self-contained" component that's all markup-based, not class-based!
|
|
654
|
+
|
|
655
|
+
└ *A list component with scoped module system*:
|
|
656
|
+
|
|
657
|
+
```html
|
|
658
|
+
<div namespace>
|
|
659
|
+
|
|
660
|
+
<ul id="list"></ul>
|
|
661
|
+
|
|
662
|
+
<template as="item" scoped>
|
|
663
|
+
<li>
|
|
664
|
+
<a></a>
|
|
665
|
+
</li>
|
|
666
|
+
</template>
|
|
667
|
+
|
|
668
|
+
<script scoped>
|
|
669
|
+
this.import('item', template => {
|
|
670
|
+
const clone = template.content.cloneNode(true);
|
|
671
|
+
this.namespace.list.appendChild(clone);
|
|
672
|
+
});
|
|
673
|
+
</script>
|
|
674
|
+
|
|
675
|
+
</div>
|
|
676
|
+
```
|
|
677
|
+
|
|
606
678
|
## The Polyfill
|
|
607
679
|
|
|
608
680
|
OOHTML is being developed as something to be used today - via a polyfill. This has been helping to facilitate the "release - iterations" loop and its overall evolution.
|
|
@@ -635,7 +707,7 @@ If you must load the script "async", one little trade-off has to be made for `<s
|
|
|
635
707
|
</body>
|
|
636
708
|
```
|
|
637
709
|
|
|
638
|
-
The custom MIME type strategy also comes in as a "fix" for older browsers
|
|
710
|
+
The custom MIME type strategy also comes in as a "fix" for certain runtimes - e.g. older browsers - where the polyfill is not able to intercept `<script scoped>` and `<script contract>` elements ahead of the runtime - e.g. where...
|
|
639
711
|
|
|
640
712
|
```html
|
|
641
713
|
<body>
|