@webqit/oohtml 2.1.55 → 2.1.56
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 +120 -122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -491,37 +491,7 @@ OOHTML is being developed as something to be used today - via a polyfill.
|
|
|
491
491
|
|
|
492
492
|
└ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!
|
|
493
493
|
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
If you must load the script "async", one little trade-off has to be made for `<script scoped>` and `<script stateful>` elements to have them ignored by the browser until the polyfill comes picking them up: *employing a custom MIME type in place of the standard `text/javascript` and `module` types*, in which case, a `<meta name="scoped-js">` element is used to configure the polyfill to honor the custom MIME type:
|
|
497
|
-
|
|
498
|
-
```html
|
|
499
|
-
<head>
|
|
500
|
-
<meta name="scoped-js" content="script.mimeType=some-mime">
|
|
501
|
-
<script async src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
502
|
-
</head>
|
|
503
|
-
<body>
|
|
504
|
-
<script type="some-mime" scoped>
|
|
505
|
-
console.log(this); // body
|
|
506
|
-
</script>
|
|
507
|
-
</body>
|
|
508
|
-
```
|
|
509
|
-
|
|
510
|
-
The custom MIME type strategy also comes in as a "fix" for when in a browser or other runtime where the polyfill is not able to intercept `<script scoped>` and `<script stateful>` elements ahead of the runtime - e.g. where...
|
|
511
|
-
|
|
512
|
-
```html
|
|
513
|
-
<body>
|
|
514
|
-
<script scoped>
|
|
515
|
-
console.log(this); // body
|
|
516
|
-
</script>
|
|
517
|
-
</body>
|
|
518
|
-
```
|
|
519
|
-
|
|
520
|
-
...still gives the `window` object in the console.
|
|
521
|
-
|
|
522
|
-
</details>
|
|
523
|
-
|
|
524
|
-
For the Scoped Styles feature, you'd also need something like the [samthor/scoped](https://github.com/samthor/scoped) polyfill (more details below):
|
|
494
|
+
└ For the Scoped Styles feature, you'd also need something like the [samthor/scoped](https://github.com/samthor/scoped) polyfill (more details below):
|
|
525
495
|
|
|
526
496
|
```html
|
|
527
497
|
<head>
|
|
@@ -559,6 +529,34 @@ Also, if you'll be going ahead to build a real app to see OOHTML in action, you
|
|
|
559
529
|
|
|
560
530
|
<details><summary>Implementation Notes</summary>
|
|
561
531
|
|
|
532
|
+
+ **Loading Requirements**. As specified above, the OOHTML script tag is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!
|
|
533
|
+
|
|
534
|
+
If you must load the script "async", one little trade-off has to be made for `<script scoped>` and `<script stateful>` elements to have them ignored by the browser until the polyfill comes picking them up: *employing a custom MIME type in place of the standard `text/javascript` and `module` types*, in which case, a `<meta name="scoped-js">` element is used to configure the polyfill to honor the custom MIME type:
|
|
535
|
+
|
|
536
|
+
```html
|
|
537
|
+
<head>
|
|
538
|
+
<meta name="scoped-js" content="script.mimeType=some-mime">
|
|
539
|
+
<script async src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
540
|
+
</head>
|
|
541
|
+
<body>
|
|
542
|
+
<script type="some-mime" scoped>
|
|
543
|
+
console.log(this); // body
|
|
544
|
+
</script>
|
|
545
|
+
</body>
|
|
546
|
+
```
|
|
547
|
+
|
|
548
|
+
The custom MIME type strategy also comes in as a "fix" for when in a browser or other runtime where the polyfill is not able to intercept `<script scoped>` and `<script stateful>` elements ahead of the runtime - e.g. where...
|
|
549
|
+
|
|
550
|
+
```html
|
|
551
|
+
<body>
|
|
552
|
+
<script scoped>
|
|
553
|
+
console.log(this); // body
|
|
554
|
+
</script>
|
|
555
|
+
</body>
|
|
556
|
+
```
|
|
557
|
+
|
|
558
|
+
...still gives the `window` object in the console.
|
|
559
|
+
|
|
562
560
|
+ **Scoped/Stateful Scripts**. This feature is an extension of [Stateful JS](https://github.com/webqit/stateful-js). The default OOHTML build is based on the [Stateful JS Lite APIs](https://github.com/webqit/stateful-js#stateful-js-lite) and this means that `<script stateful></script>` and `<script scoped></script>` elements are parsed "asynchronously", in the same timing as `<script type="module"></script>`!
|
|
563
561
|
|
|
564
562
|
This timing works perfectly generally, but if you have a requirment to have classic scripts follow their [native synchronous timing](https://html.spec.whatwg.org/multipage/parsing.html#scripts-that-modify-the-page-as-it-is-being-parsed), then you need to the *realtime* OOHTML build:
|
|
@@ -628,65 +626,65 @@ Here are a few examples in the wide range of use cases these features cover.
|
|
|
628
626
|
|
|
629
627
|
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:
|
|
630
628
|
|
|
631
|
-
|
|
629
|
+
+ *First, two components that are themselves analogous to a Single File Component ([SFC](https://vuejs.org/guide/scaling-up/sfc.html))*:
|
|
632
630
|
|
|
633
|
-
<details><summary>Code</summary>
|
|
634
|
-
|
|
635
|
-
```html
|
|
636
|
-
<template def="pages">
|
|
637
|
-
|
|
638
|
-
<template def="layout">
|
|
639
|
-
<header def="header"></header>
|
|
640
|
-
<footer def="footer"></footer>
|
|
641
|
-
</template>
|
|
631
|
+
<details><summary>Code</summary>
|
|
642
632
|
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
<
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
|
|
657
|
-
|
|
658
|
-
|
|
659
|
-
|
|
660
|
-
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
633
|
+
```html
|
|
634
|
+
<template def="pages">
|
|
635
|
+
|
|
636
|
+
<template def="layout">
|
|
637
|
+
<header def="header"></header>
|
|
638
|
+
<footer def="footer"></footer>
|
|
639
|
+
</template>
|
|
640
|
+
|
|
641
|
+
<!-- Home Page -->
|
|
642
|
+
<template def="home" extends="layout">
|
|
643
|
+
<main def="main" namespace>
|
|
644
|
+
<h1 id="banner">Home Page</h1>
|
|
645
|
+
<a id="cta" href="#/products">Go to Products</a>
|
|
646
|
+
<template scoped></template>
|
|
647
|
+
<style scoped></style>
|
|
648
|
+
<script scoped></script>
|
|
649
|
+
</main>
|
|
650
|
+
</template>
|
|
651
|
+
|
|
652
|
+
<!-- Products Page -->
|
|
653
|
+
<template def="products" extends="layout">
|
|
654
|
+
<main def="main" namespace>
|
|
655
|
+
<h1 id="banner">Products Page</h1>
|
|
656
|
+
<a id="cta" href="#/home">Go to Home</a>
|
|
657
|
+
<template scoped></template>
|
|
658
|
+
<style scoped></style>
|
|
659
|
+
<script scoped></script>
|
|
660
|
+
</main>
|
|
661
|
+
</template>
|
|
664
662
|
|
|
665
|
-
</template>
|
|
666
|
-
```
|
|
663
|
+
</template>
|
|
664
|
+
```
|
|
667
665
|
|
|
668
|
-
</details>
|
|
666
|
+
</details>
|
|
669
667
|
|
|
670
|
-
|
|
668
|
+
+ *Then a 2-line router that alternates the view based on the URL hash*:
|
|
671
669
|
|
|
672
|
-
<details><summary>Code</summary>
|
|
670
|
+
<details><summary>Code</summary>
|
|
673
671
|
|
|
674
|
-
```html
|
|
675
|
-
<body importscontext="/pages/home">
|
|
676
|
-
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
682
|
-
|
|
683
|
-
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
</body>
|
|
687
|
-
```
|
|
672
|
+
```html
|
|
673
|
+
<body importscontext="/pages/home">
|
|
674
|
+
|
|
675
|
+
<import ref="#header"></import>
|
|
676
|
+
<import ref="#main"></import>
|
|
677
|
+
<import ref="#footer"></import>
|
|
678
|
+
|
|
679
|
+
<script>
|
|
680
|
+
const route = () => { document.body.setAttribute('importscontext', '/pages' + location.hash.substring(1)); };
|
|
681
|
+
window.addEventListener('hashchange', route);
|
|
682
|
+
</script>
|
|
683
|
+
|
|
684
|
+
</body>
|
|
685
|
+
```
|
|
688
686
|
|
|
689
|
-
</details>
|
|
687
|
+
</details>
|
|
690
688
|
|
|
691
689
|
### Example 2: *Multi-Level Namespacing*
|
|
692
690
|
|
|
@@ -763,64 +761,64 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
|
|
|
763
761
|
|
|
764
762
|
The following is a custom element that derives its Shadow DOM from an imported `<tenplate>` element. The idea is to have different Shadow DOM layouts defined and let the "usage" context decide which variant is imported!
|
|
765
763
|
|
|
766
|
-
|
|
764
|
+
+ *First, two layout options defined for the Shadow DOM*:
|
|
767
765
|
|
|
768
|
-
<details><summary>Code</summary>
|
|
766
|
+
<details><summary>Code</summary>
|
|
769
767
|
|
|
770
|
-
```html
|
|
771
|
-
<template def="vendor1">
|
|
768
|
+
```html
|
|
769
|
+
<template def="vendor1">
|
|
772
770
|
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
771
|
+
<template def="components-layout1">
|
|
772
|
+
<template def="magic-button">
|
|
773
|
+
<span id="icon"></span> <span id="text"></span>
|
|
774
|
+
</template>
|
|
775
|
+
</template>
|
|
778
776
|
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
777
|
+
<template def="components-layout2">
|
|
778
|
+
<template def="magic-button">
|
|
779
|
+
<span id="text"></span> <span id="icon"></span>
|
|
780
|
+
</template>
|
|
781
|
+
</template>
|
|
784
782
|
|
|
785
|
-
</template>
|
|
786
|
-
```
|
|
783
|
+
</template>
|
|
784
|
+
```
|
|
787
785
|
|
|
788
|
-
</details>
|
|
786
|
+
</details>
|
|
789
787
|
|
|
790
|
-
|
|
788
|
+
+ *Next, the Shadow DOM creation that imports its layout from context*:
|
|
791
789
|
|
|
792
|
-
<details><summary>Code</summary>
|
|
790
|
+
<details><summary>Code</summary>
|
|
793
791
|
|
|
794
|
-
```js
|
|
795
|
-
customElements.define('magic-button', class extends HTMLElement {
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
792
|
+
```js
|
|
793
|
+
customElements.define('magic-button', class extends HTMLElement {
|
|
794
|
+
connectedCallback() {
|
|
795
|
+
const shadowRoot = this.attachShadow({ mode: 'open' });
|
|
796
|
+
this.import('@vendor1/magic-button', template => {
|
|
797
|
+
shadowRoot.appendChild( template.content.cloneNode(true) );
|
|
798
|
+
});
|
|
799
|
+
}
|
|
800
800
|
});
|
|
801
|
-
|
|
802
|
-
});
|
|
803
|
-
```
|
|
801
|
+
```
|
|
804
802
|
|
|
805
|
-
</details>
|
|
803
|
+
</details>
|
|
806
804
|
|
|
807
|
-
|
|
805
|
+
+ *Then, the part where we just drop the component in "layout" contexts*:
|
|
808
806
|
|
|
809
|
-
<details><summary>Code</summary>
|
|
807
|
+
<details><summary>Code</summary>
|
|
810
808
|
|
|
811
|
-
```html
|
|
812
|
-
<div contextname="vendor1" importscontext="/vendor1/components-layout1">
|
|
809
|
+
```html
|
|
810
|
+
<div contextname="vendor1" importscontext="/vendor1/components-layout1">
|
|
813
811
|
|
|
814
|
-
|
|
812
|
+
<magic-button></magic-button>
|
|
815
813
|
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
814
|
+
<aside contextname="vendor1" importscontext="/vendor1/components-layout2">
|
|
815
|
+
<magic-button></magic-button>
|
|
816
|
+
</aside>
|
|
819
817
|
|
|
820
|
-
</div>
|
|
821
|
-
```
|
|
818
|
+
</div>
|
|
819
|
+
```
|
|
822
820
|
|
|
823
|
-
</details>
|
|
821
|
+
</details>
|
|
824
822
|
|
|
825
823
|
### Example 4: *List Items*
|
|
826
824
|
|