@webqit/oohtml 3.0.1-3 → 3.0.1-5
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 +113 -122
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -690,9 +690,9 @@ Generated item elements are automatically assigned a corresponding index with a
|
|
|
690
690
|
|
|
691
691
|
### Quantum Scripts
|
|
692
692
|
|
|
693
|
-
We often still need to write more serious reactive logic on the UI than a declarative data-binding language can provide. But we shouldn't need to reach for special tooling or some "serious" programming paradigm on top of JavaScript.
|
|
693
|
+
We often still need to write more serious reactive logic on the UI than a declarative data-binding language can provide for. But we shouldn't need to reach for special tooling or some "serious" programming paradigm on top of JavaScript.
|
|
694
694
|
|
|
695
|
-
Here, from the same `<script>` element we write
|
|
695
|
+
Here, from the same `<script>` element we already write, we get a direct upgrade path to reactive programming in just an attribute: `quantum`:
|
|
696
696
|
|
|
697
697
|
```html
|
|
698
698
|
<script quantum>
|
|
@@ -789,9 +789,17 @@ It's Imperative Reactive Programming ([IRP](https://en.wikipedia.org/wiki/Reacti
|
|
|
789
789
|
|
|
790
790
|
Here, the runtime executes your code in a special execution mode that gets literal JavaScript expressions to statically reflect changes. This makes a lot of things possible on the UI! The [Quantum JS](https://github.com/webqit/quantum-js) documentation has a detailed run down.
|
|
791
791
|
|
|
792
|
-
Now, in each case above, reactivity terminates on script's removal from the DOM.
|
|
792
|
+
Now, in each case above, reactivity terminates on script's removal from the DOM. And a programmatic termination is sill possible:
|
|
793
793
|
|
|
794
|
-
|
|
794
|
+
```js
|
|
795
|
+
const script = document.querySelector('script[quantum]');
|
|
796
|
+
// const script = document.querySelector('main').scripts[0];
|
|
797
|
+
script.abort();
|
|
798
|
+
```
|
|
799
|
+
|
|
800
|
+
But while that is automatic, DOM event handlers bound via `addEventListener()` would still need to be terminated in their own way.
|
|
801
|
+
|
|
802
|
+
</details>
|
|
795
803
|
|
|
796
804
|
## Data Plumbing
|
|
797
805
|
|
|
@@ -913,9 +921,8 @@ OOHTML is being developed as something to be used today - via a polyfill.
|
|
|
913
921
|
|
|
914
922
|
</details>
|
|
915
923
|
|
|
916
|
-
<details><summary>
|
|
917
|
-
|
|
918
|
-
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 `@webqit/oohtml` with the DOM instance:
|
|
924
|
+
<details><summary>Install from NPM<br>
|
|
925
|
+
└───────── <a href="https://npmjs.com/package/@webqit/oohtml"><img align="right" src="https://img.shields.io/npm/v/@webqit/oohtml?style=flat&label=&colorB=black"></a></summary>
|
|
919
926
|
|
|
920
927
|
```bash
|
|
921
928
|
npm i @webqit/oohtml
|
|
@@ -929,9 +936,15 @@ import init from '@webqit/oohtml';
|
|
|
929
936
|
init.call( window[, options = {} ]);
|
|
930
937
|
```
|
|
931
938
|
|
|
932
|
-
|
|
939
|
+
└ 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 `@webqit/oohtml` with the DOM instance as above.
|
|
940
|
+
|
|
941
|
+
└ But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
|
|
933
942
|
|
|
934
|
-
|
|
943
|
+
</details>
|
|
944
|
+
|
|
945
|
+
<details><summary>Extended usage concepts</summary>
|
|
946
|
+
|
|
947
|
+
If you'll be going ahead to build a real app to see OOHTML in action, you may want to consider also using:
|
|
935
948
|
|
|
936
949
|
+ the [`@webqit/oohtml-cli`](https://github.com/webqit/oohtml-cli) package for operating a file-based templating system.
|
|
937
950
|
|
|
@@ -969,7 +982,7 @@ Also, if you'll be going ahead to build a real app to see OOHTML in action, you
|
|
|
969
982
|
|
|
970
983
|
...still gives the `window` object in the console.
|
|
971
984
|
|
|
972
|
-
+ **Scoped/Quantum Scripts**. This feature is an extension of [Quantum JS](https://github.com/webqit/quantum-js)
|
|
985
|
+
+ **Scoped/Quantum Scripts**. This feature is an extension of [Quantum JS](https://github.com/webqit/quantum-js) and the default OOHTML build is based on the [Quantum JS Lite APIs](https://github.com/webqit/quantum-js#quantum-js-lite). Now, while Quantum JS Lite yields faster load times, it also means that `<script quantum></script>` and `<script scoped></script>` elements are parsed "asynchronously", in the same timing as `<script type="module"></script>`!
|
|
973
986
|
|
|
974
987
|
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'd need to use the *realtime* OOHTML build:
|
|
975
988
|
|
|
@@ -1029,81 +1042,70 @@ Also, if you'll be going ahead to build a real app to see OOHTML in action, you
|
|
|
1029
1042
|
|
|
1030
1043
|
Here are a few examples in the wide range of use cases these features cover.
|
|
1031
1044
|
|
|
1032
|
-
|
|
1033
|
-
|
|
1034
|
-
+ [Example 3: *Dynamic Shadow DOM*](#example-3-dynamic-shadow-dom)
|
|
1035
|
-
+ [Example 4: *Declarative Lists*](#example-4-declarative-lists)
|
|
1036
|
-
+ [Example 5: *Imperative Lists*](#example-4-imperative-lists)
|
|
1037
|
-
|
|
1038
|
-
### Example 1: *Single Page Application*
|
|
1045
|
+
<details><summary>Example 1: <i>Single Page Application</i><br>
|
|
1046
|
+
└───────── </summary>
|
|
1039
1047
|
|
|
1040
1048
|
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:
|
|
1041
1049
|
|
|
1042
|
-
|
|
1050
|
+
**-->** *First, two components that are themselves analogous to a Single File Component ([SFC](https://vuejs.org/guide/scaling-up/sfc.html))*:
|
|
1043
1051
|
|
|
1044
|
-
|
|
1052
|
+
```html
|
|
1053
|
+
<template def="pages">
|
|
1045
1054
|
|
|
1046
|
-
|
|
1047
|
-
<
|
|
1048
|
-
|
|
1049
|
-
|
|
1050
|
-
<header def="header"></header>
|
|
1051
|
-
<footer def="footer"></footer>
|
|
1052
|
-
</template>
|
|
1053
|
-
|
|
1054
|
-
<!-- Home Page -->
|
|
1055
|
-
<template def="home" extends="layout">
|
|
1056
|
-
<main def="main" namespace>
|
|
1057
|
-
<h1 id="banner">Home Page</h1>
|
|
1058
|
-
<a id="cta" href="#/products">Go to Products</a>
|
|
1059
|
-
<template scoped></template>
|
|
1060
|
-
<style scoped></style>
|
|
1061
|
-
<script scoped></script>
|
|
1062
|
-
</main>
|
|
1063
|
-
</template>
|
|
1064
|
-
|
|
1065
|
-
<!-- Products Page -->
|
|
1066
|
-
<template def="products" extends="layout">
|
|
1067
|
-
<main def="main" namespace>
|
|
1068
|
-
<h1 id="banner">Products Page</h1>
|
|
1069
|
-
<a id="cta" href="#/home">Go to Home</a>
|
|
1070
|
-
<template scoped></template>
|
|
1071
|
-
<style scoped></style>
|
|
1072
|
-
<script scoped></script>
|
|
1073
|
-
</main>
|
|
1074
|
-
</template>
|
|
1055
|
+
<template def="layout">
|
|
1056
|
+
<header def="header"></header>
|
|
1057
|
+
<footer def="footer"></footer>
|
|
1058
|
+
</template>
|
|
1075
1059
|
|
|
1076
|
-
|
|
1077
|
-
|
|
1060
|
+
<!-- Home Page -->
|
|
1061
|
+
<template def="home" extends="layout">
|
|
1062
|
+
<main def="main" namespace>
|
|
1063
|
+
<h1 id="banner">Home Page</h1>
|
|
1064
|
+
<a id="cta" href="#/products">Go to Products</a>
|
|
1065
|
+
<template scoped></template>
|
|
1066
|
+
<style scoped></style>
|
|
1067
|
+
<script scoped></script>
|
|
1068
|
+
</main>
|
|
1069
|
+
</template>
|
|
1078
1070
|
|
|
1079
|
-
|
|
1071
|
+
<!-- Products Page -->
|
|
1072
|
+
<template def="products" extends="layout">
|
|
1073
|
+
<main def="main" namespace>
|
|
1074
|
+
<h1 id="banner">Products Page</h1>
|
|
1075
|
+
<a id="cta" href="#/home">Go to Home</a>
|
|
1076
|
+
<template scoped></template>
|
|
1077
|
+
<style scoped></style>
|
|
1078
|
+
<script scoped></script>
|
|
1079
|
+
</main>
|
|
1080
|
+
</template>
|
|
1080
1081
|
|
|
1081
|
-
|
|
1082
|
+
</template>
|
|
1083
|
+
```
|
|
1082
1084
|
|
|
1083
|
-
|
|
1085
|
+
**-->** *Then a 2-line router that alternates the view based on the URL hash*:
|
|
1084
1086
|
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1088
|
-
|
|
1089
|
-
|
|
1090
|
-
|
|
1091
|
-
|
|
1092
|
-
|
|
1093
|
-
|
|
1094
|
-
|
|
1095
|
-
|
|
1096
|
-
|
|
1097
|
-
|
|
1098
|
-
|
|
1087
|
+
```html
|
|
1088
|
+
<body importscontext="/pages/home">
|
|
1089
|
+
|
|
1090
|
+
<import ref="#header"></import>
|
|
1091
|
+
<import ref="#main"></import>
|
|
1092
|
+
<import ref="#footer"></import>
|
|
1093
|
+
|
|
1094
|
+
<script>
|
|
1095
|
+
const route = () => { document.body.setAttribute('importscontext', '/pages' + location.hash.substring(1)); };
|
|
1096
|
+
window.addEventListener('hashchange', route);
|
|
1097
|
+
</script>
|
|
1098
|
+
|
|
1099
|
+
</body>
|
|
1100
|
+
```
|
|
1099
1101
|
|
|
1100
|
-
|
|
1102
|
+
</details>
|
|
1101
1103
|
|
|
1102
|
-
|
|
1104
|
+
<details><summary>Example 2: <i>Multi-Level Namespacing</i><br>
|
|
1105
|
+
└───────── </summary>
|
|
1103
1106
|
|
|
1104
|
-
The following is a Listbox component lifted directly from the [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.
|
|
1105
1107
|
|
|
1106
|
-
|
|
1108
|
+
The following is a Listbox component lifted directly from the [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.
|
|
1107
1109
|
|
|
1108
1110
|
```html
|
|
1109
1111
|
<div namespace class="listbox-area">
|
|
@@ -1170,75 +1172,65 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
|
|
|
1170
1172
|
|
|
1171
1173
|
</details>
|
|
1172
1174
|
|
|
1173
|
-
|
|
1175
|
+
<details><summary>Example 3: <i>Dynamic Shadow DOM</i><br>
|
|
1176
|
+
└───────── </summary>
|
|
1174
1177
|
|
|
1175
1178
|
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!
|
|
1176
1179
|
|
|
1177
|
-
|
|
1178
|
-
|
|
1179
|
-
<details><summary>Code</summary>
|
|
1180
|
+
**-->** *First, two layout options defined for the Shadow DOM*:
|
|
1180
1181
|
|
|
1181
|
-
|
|
1182
|
-
|
|
1183
|
-
|
|
1184
|
-
<template def="components-layout1">
|
|
1185
|
-
<template def="magic-button">
|
|
1186
|
-
<span id="icon"></span> <span id="text"></span>
|
|
1187
|
-
</template>
|
|
1188
|
-
</template>
|
|
1189
|
-
|
|
1190
|
-
<template def="components-layout2">
|
|
1191
|
-
<template def="magic-button">
|
|
1192
|
-
<span id="text"></span> <span id="icon"></span>
|
|
1193
|
-
</template>
|
|
1194
|
-
</template>
|
|
1182
|
+
```html
|
|
1183
|
+
<template def="vendor1">
|
|
1195
1184
|
|
|
1185
|
+
<template def="components-layout1">
|
|
1186
|
+
<template def="magic-button">
|
|
1187
|
+
<span id="icon"></span> <span id="text"></span>
|
|
1196
1188
|
</template>
|
|
1197
|
-
|
|
1189
|
+
</template>
|
|
1198
1190
|
|
|
1199
|
-
|
|
1191
|
+
<template def="components-layout2">
|
|
1192
|
+
<template def="magic-button">
|
|
1193
|
+
<span id="text"></span> <span id="icon"></span>
|
|
1194
|
+
</template>
|
|
1195
|
+
</template>
|
|
1200
1196
|
|
|
1201
|
-
|
|
1197
|
+
</template>
|
|
1198
|
+
```
|
|
1202
1199
|
|
|
1203
|
-
|
|
1200
|
+
**-->** *Next, the Shadow DOM creation that imports its layout from context*:
|
|
1204
1201
|
|
|
1205
|
-
|
|
1206
|
-
|
|
1207
|
-
|
|
1208
|
-
|
|
1209
|
-
|
|
1210
|
-
|
|
1211
|
-
});
|
|
1212
|
-
}
|
|
1202
|
+
```js
|
|
1203
|
+
customElements.define('magic-button', class extends HTMLElement {
|
|
1204
|
+
connectedCallback() {
|
|
1205
|
+
const shadowRoot = this.attachShadow({ mode: 'open' });
|
|
1206
|
+
this.import('@vendor1/magic-button', template => {
|
|
1207
|
+
shadowRoot.appendChild( template.content.cloneNode(true) );
|
|
1213
1208
|
});
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
+ *Then, the part where we just drop the component in "layout" contexts*:
|
|
1209
|
+
}
|
|
1210
|
+
});
|
|
1211
|
+
```
|
|
1219
1212
|
|
|
1220
|
-
|
|
1213
|
+
**-->** *Then, the part where we just drop the component in "layout" contexts*:
|
|
1221
1214
|
|
|
1222
|
-
|
|
1223
|
-
|
|
1215
|
+
```html
|
|
1216
|
+
<div contextname="vendor1" importscontext="/vendor1/components-layout1">
|
|
1224
1217
|
|
|
1225
|
-
|
|
1218
|
+
<magic-button></magic-button>
|
|
1226
1219
|
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1220
|
+
<aside contextname="vendor1" importscontext="/vendor1/components-layout2">
|
|
1221
|
+
<magic-button></magic-button>
|
|
1222
|
+
</aside>
|
|
1230
1223
|
|
|
1231
|
-
|
|
1232
|
-
|
|
1224
|
+
</div>
|
|
1225
|
+
```
|
|
1233
1226
|
|
|
1234
|
-
|
|
1227
|
+
</details>
|
|
1235
1228
|
|
|
1236
|
-
|
|
1229
|
+
<details><summary>Example 4: <i>Declarative Lists</i><br>
|
|
1230
|
+
└───────── </summary>
|
|
1237
1231
|
|
|
1238
1232
|
The following is a hypothetical list page!
|
|
1239
1233
|
|
|
1240
|
-
<details><summary>Code</summary>
|
|
1241
|
-
|
|
1242
1234
|
```html
|
|
1243
1235
|
<section>
|
|
1244
1236
|
|
|
@@ -1255,12 +1247,11 @@ The following is a hypothetical list page!
|
|
|
1255
1247
|
|
|
1256
1248
|
</details>
|
|
1257
1249
|
|
|
1258
|
-
|
|
1250
|
+
<details><summary>Example 5: <i>Imperative Lists</i><br>
|
|
1251
|
+
└───────── </summary>
|
|
1259
1252
|
|
|
1260
1253
|
The following is much like the above, but imperative. Additions and removals on the data items are also statically reflected!
|
|
1261
1254
|
|
|
1262
|
-
<details><summary>Code</summary>
|
|
1263
|
-
|
|
1264
1255
|
```html
|
|
1265
1256
|
<section namespace>
|
|
1266
1257
|
|