@webqit/oohtml 3.1.14 → 3.1.16
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 +248 -217
- package/dist/main.js +18 -22
- package/dist/main.js.map +2 -2
- package/dist/main.lite.js +13 -17
- package/dist/main.lite.js.map +2 -2
- package/dist/namespaced-html.js +1 -1
- package/dist/namespaced-html.js.map +2 -2
- package/dist/scoped-css.js +1 -5
- package/dist/scoped-css.js.map +2 -2
- package/package.json +1 -1
- package/src/namespaced-html/index.js +95 -45
- package/src/scoped-css/index.js +32 -26
package/README.md
CHANGED
|
@@ -17,6 +17,185 @@ Building Single Page Applications? OOHTML is a special love letter! Writing Web
|
|
|
17
17
|
|
|
18
18
|
</details>
|
|
19
19
|
|
|
20
|
+
## Polyfill
|
|
21
|
+
|
|
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
|
+
|
|
24
|
+
<details><summary>Load from a CDN<br>
|
|
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>
|
|
26
|
+
|
|
27
|
+
```html
|
|
28
|
+
<script src="https://unpkg.com/@webqit/oohtml/dist/main.lite.js"></script>
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
└ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!
|
|
32
|
+
|
|
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
|
+
> ```
|
|
40
|
+
|
|
41
|
+
</details>
|
|
42
|
+
|
|
43
|
+
<details><summary>Install from NPM<br>
|
|
44
|
+
└───────── <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>
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
npm i @webqit/oohtml @webqit/quantum-js
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
```js
|
|
51
|
+
// Import
|
|
52
|
+
import * as Quantum from '@webqit/quantum-js/lite'; // Or from '@webqit/quantum-js'; See implementation notes below
|
|
53
|
+
import init from '@webqit/oohtml';
|
|
54
|
+
|
|
55
|
+
// Initialize the lib
|
|
56
|
+
init.call(window, Quantum[, options = {}]);
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
└ 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
|
+
|
|
61
|
+
└ But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
|
|
62
|
+
|
|
63
|
+
</details>
|
|
64
|
+
|
|
65
|
+
<details><summary>Extended usage concepts</summary>
|
|
66
|
+
|
|
67
|
+
If you'll be going ahead to build a real app with OOHTML, you may want to consider also using:
|
|
68
|
+
|
|
69
|
+
+ the [`@webqit/oohtml-cli`](https://github.com/webqit/oohtml-cli) package for operating a file-based templating system.
|
|
70
|
+
|
|
71
|
+
+ the modest, OOHTML-based [Webflo](https://github.com/webqit/webflo) framework to greatly streamline your workflow!
|
|
72
|
+
|
|
73
|
+
</details>
|
|
74
|
+
|
|
75
|
+
<details><summary>Implementation Notes</summary>
|
|
76
|
+
|
|
77
|
+
+ **Scoped/Quantum Scripts**. This feature is an extension of [Quantum JS](https://github.com/webqit/quantum-js). While the main OOHTML build is based on the main Quantum JS APIs, a companion "OOHTML Lite" build is also available based on the [Quantum JS Lite](https://github.com/webqit/quantum-js#quantum-js-lite) edition. The trade-off is in the execution timing of `<script quantum></script>` and `<script scoped></script>` elements: being "synchronous/blocking" with the former, and "asynchronous/non-blocking" with the latter! (See [`async`/`defer`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes).)
|
|
78
|
+
|
|
79
|
+
Of the two, the "OOHTML Lite" edition is the recommend option on web pages (as used above) for faster load times unless there's a requirment to emulate the [native synchronous timing](https://html.spec.whatwg.org/multipage/parsing.html#scripts-that-modify-the-page-as-it-is-being-parsed) of classic scripts, in which case you'd need the main OOHTML build:
|
|
80
|
+
|
|
81
|
+
```html
|
|
82
|
+
<head>
|
|
83
|
+
<script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
84
|
+
</head>
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
└─ <a href="https://bundlephobia.com/result?p=@webqit/oohtml"><img align="right" src="https://img.shields.io/bundlephobia/minzip/@webqit/oohtml?label=&style=flat&colorB=black"></a>
|
|
88
|
+
|
|
89
|
+
+ **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!
|
|
90
|
+
|
|
91
|
+
If you must load the script "async", one little trade-off would have to be made for `<script scoped>` and `<script quantum>` 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:
|
|
92
|
+
|
|
93
|
+
```html
|
|
94
|
+
<head>
|
|
95
|
+
<meta name="scoped-js" content="script.mimeType=some-mime">
|
|
96
|
+
<script async src="https://unpkg.com/@webqit/oohtml/dist/main.lite.js"></script>
|
|
97
|
+
</head>
|
|
98
|
+
<body>
|
|
99
|
+
<script type="some-mime" scoped>
|
|
100
|
+
console.log(this); // body
|
|
101
|
+
</script>
|
|
102
|
+
</body>
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
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 quantum>` elements ahead of the runtime - e.g. where...
|
|
106
|
+
|
|
107
|
+
```html
|
|
108
|
+
<body>
|
|
109
|
+
<script scoped>
|
|
110
|
+
console.log(this); // body
|
|
111
|
+
</script>
|
|
112
|
+
</body>
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
...still gives the `window` object in the console.
|
|
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:
|
|
118
|
+
|
|
119
|
+
```html
|
|
120
|
+
<head>
|
|
121
|
+
<!-- Configurations come before the polyfil -->
|
|
122
|
+
<meta name="data-binding" content="attr.expr=expr;">
|
|
123
|
+
<meta name="namespaced-html" content="attr.id=id;">
|
|
124
|
+
<meta name="html-imports" content="attr.def=def; attr.ref=ref;">
|
|
125
|
+
<script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
126
|
+
<head>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Now, even when the default syntax change, your `def`, `ref`, etc. overrides will keep your implementation intact.
|
|
130
|
+
|
|
131
|
+
Additionally, you could employ a global prefix in your implementation:
|
|
132
|
+
|
|
133
|
+
```html
|
|
134
|
+
<meta name="webqit" content="prefix=wq;">
|
|
135
|
+
```
|
|
136
|
+
|
|
137
|
+
...which automatically applies to all `webqit` attributes and APIs (with the exception of the `scoped`, `quantum`, and `data-*` attributes), such that:
|
|
138
|
+
|
|
139
|
+
+ `<template def="foo"></template>` now becomes: `<template wq-def="foo"></template>`,
|
|
140
|
+
+ `<import ref="foo"></import>` now becomes: `<wq-import wq-ref="foo"></wq-import>`,
|
|
141
|
+
+ `document.import()` now becomes: `document.wqImport()`,
|
|
142
|
+
+ `document.bind()` now becomes: `document.wqBind()`,
|
|
143
|
+
+ `document.bindings` now becomes: `document.wqBindings`,
|
|
144
|
+
+ etc.
|
|
145
|
+
|
|
146
|
+
The following is the full syntax table.
|
|
147
|
+
|
|
148
|
+
Spec: **data-binding**
|
|
149
|
+
|
|
150
|
+
| Config | Default Syntax | Description |
|
|
151
|
+
| :----- | :------------- | :---------- |
|
|
152
|
+
| `attr.expr` | `expr` | The "expr" attribute for inline data binding. ([Docs](#inline-data-binding)) |
|
|
153
|
+
| `attr.itemIndex` | `data-index` | The "item index" attribute for assigning indexes to list items. ([Docs](#inline-data-binding)) |
|
|
154
|
+
|
|
155
|
+
Spec: **bindings-api**
|
|
156
|
+
|
|
157
|
+
| Config | Default Syntax | Description |
|
|
158
|
+
| :----- | :------------- | :---------- |
|
|
159
|
+
| `attr.bindingsreflection` | `bindings` | The attribute for exposing an element's bindings. |
|
|
160
|
+
| `api.bind` | `bind` | The `document.bind()` and `Element.prototype.bind()` methods. ([Docs](#the-bindings-api)) |
|
|
161
|
+
| `api.bindings` | `bindings` | The `document.bindings` and `Element.prototype.bindings` object properties. ([Docs](#the-bindings-api)) |
|
|
162
|
+
|
|
163
|
+
Spec: **context-api**
|
|
164
|
+
|
|
165
|
+
| Config | Default Syntax | Description |
|
|
166
|
+
| :----- | :------------- | :---------- |
|
|
167
|
+
| `attr.contextname` | `contextname` | The "context name" attribute on arbitrary elements. ([Docs](#the-context-api)) |
|
|
168
|
+
| `api.contexts` | `contexts` | The `document.contexts` and `Element.prototype.contexts` object properties. ([Docs](#the-context-api)) |
|
|
169
|
+
|
|
170
|
+
Spec: **html-imports**
|
|
171
|
+
|
|
172
|
+
| Config | Default Syntax | Description |
|
|
173
|
+
| :----- | :------------- | :---------- |
|
|
174
|
+
| `elements.import` | `import` | The tag name for "import" elements. ([Docs](#html-imports)) |
|
|
175
|
+
| `attr.def` | `def` | The "definition" attribute on the `<template>` elements. ([Docs](#module-definition)) |
|
|
176
|
+
| `attr.fragmentdef` | *Inherits the value of `attr.def`* | The "definition" attribute on a `<template>`'s contents. ([Docs](#module-definition)) |
|
|
177
|
+
| `attr.extends` | `extends` | The "extends" attribute for extending definitions. ([Docs](#module-inheritance)) |
|
|
178
|
+
| `attr.inherits` | `inherits` | The "inherits" attribute for inheriting definitions. ([Docs](#module-inheritance)) |
|
|
179
|
+
| `attr.ref` | `ref` | The "import ref" attribute on "import" elements. ([Docs](#declarative-module-imports)) |
|
|
180
|
+
| `attr.importscontext` | `importscontext` | The "importscontext" attribute on arbitrary elements. ([Docs](#imports-contexts)) |
|
|
181
|
+
| `api.def` | `def` | The readonly string property for accessing an element's "def" value. ([Docs](#module-definition)) |
|
|
182
|
+
| `api.defs` | `defs` | The readonly object property for accessing a `<template>`'s list of definitions. ([Docs](#module-definition)) |
|
|
183
|
+
| `api.import` | `import` | The `document.import()` and `Element.prototype.import()` methods. ([Docs](#imperative-module-imports)) |
|
|
184
|
+
|
|
185
|
+
Spec: **namespaced-html**
|
|
186
|
+
|
|
187
|
+
| Config | Default Syntax | Description |
|
|
188
|
+
| :----- | :------------- | :---------- |
|
|
189
|
+
| `attr.namespace` | `namespace` | The "namespace" attribute on arbitrary elements. ([Docs](#namespacing)) |
|
|
190
|
+
| `attr.id` | `id` | The "id" attribute on arbitrary elements. ([Docs](#namespacing)) |
|
|
191
|
+
| `api.namespace` | `namespace` | The "namespace" object property on arbitrary elements. ([Docs](#namespacing)) |
|
|
192
|
+
|
|
193
|
+
Spec: **scoped-css** (TODO)
|
|
194
|
+
|
|
195
|
+
Spec: **scoped-js** (TODO)
|
|
196
|
+
|
|
197
|
+
</details>
|
|
198
|
+
|
|
20
199
|
## Explainer
|
|
21
200
|
|
|
22
201
|
<details><summary>Show</summary>
|
|
@@ -50,6 +229,43 @@ Naming things is hard! That's especially so where you have one global namespace
|
|
|
50
229
|
|
|
51
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:
|
|
52
231
|
|
|
232
|
+
```html
|
|
233
|
+
<form>
|
|
234
|
+
|
|
235
|
+
<fieldset namespace>
|
|
236
|
+
<legend>Home Address</legend>
|
|
237
|
+
|
|
238
|
+
<label for="~address-line">Address</label>
|
|
239
|
+
<input id="address-line">
|
|
240
|
+
|
|
241
|
+
<label for="~city">City</label>
|
|
242
|
+
<input id="city">
|
|
243
|
+
<fieldset>
|
|
244
|
+
|
|
245
|
+
<fieldset namespace>
|
|
246
|
+
<legend>Delivery Address</legend>
|
|
247
|
+
|
|
248
|
+
<label for="~address-line">Address</label>
|
|
249
|
+
<input id="address-line">
|
|
250
|
+
|
|
251
|
+
<label for="~city">City</label>
|
|
252
|
+
<input id="city">
|
|
253
|
+
<fieldset>
|
|
254
|
+
|
|
255
|
+
</form>
|
|
256
|
+
```
|
|
257
|
+
|
|
258
|
+
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
|
+
|
|
260
|
+
More generally, local `IDREFS` are resolved within the namespace where they're used (not globally; not deeply):
|
|
261
|
+
|
|
262
|
+
```js
|
|
263
|
+
// Matches "#city" within the fieldset's namespace; not super namespace, not sub namespace
|
|
264
|
+
const city = fieldset.querySelector('#~city');
|
|
265
|
+
```
|
|
266
|
+
|
|
267
|
+
And when used from the document context, these are resolved against top-level IDs; i.e. IDs in the document namespace itself (not deeply):
|
|
268
|
+
|
|
53
269
|
```html
|
|
54
270
|
<div id="user" namespace>
|
|
55
271
|
<a id="url" href="https://example.org">
|
|
@@ -58,8 +274,22 @@ Here, we get a modular naming convention using the `namespace` attribute. This a
|
|
|
58
274
|
<a id="email" href="mailto:joebloggs@example.com" >joebloggs@example.com</a>
|
|
59
275
|
</div>
|
|
60
276
|
```
|
|
61
|
-
|
|
62
|
-
|
|
277
|
+
|
|
278
|
+
```js
|
|
279
|
+
const user = document.querySelector('#~user');
|
|
280
|
+
```
|
|
281
|
+
|
|
282
|
+
```js
|
|
283
|
+
const user = document.getElementById('~user');
|
|
284
|
+
```
|
|
285
|
+
|
|
286
|
+
And these also play well as URL targets, with additional support for path expressions denoting a hierarchy of namespaces:
|
|
287
|
+
|
|
288
|
+
```html
|
|
289
|
+
<a href="#~user/email">Jump to Email</a>
|
|
290
|
+
```
|
|
291
|
+
|
|
292
|
+
And JavaScript applications are able to consume namespace structures as an object model:
|
|
63
293
|
|
|
64
294
|
```html
|
|
65
295
|
user
|
|
@@ -68,8 +298,6 @@ user
|
|
|
68
298
|
└── email
|
|
69
299
|
```
|
|
70
300
|
|
|
71
|
-
**-->** *with a complementary API that exposes said structure to JavaScript applications*:
|
|
72
|
-
|
|
73
301
|
```js
|
|
74
302
|
// The document.namespace API
|
|
75
303
|
let { user } = document.namespace;
|
|
@@ -144,7 +372,22 @@ Here, we get a new `scoped` attribute that lets us do just that:
|
|
|
144
372
|
</div>
|
|
145
373
|
```
|
|
146
374
|
|
|
147
|
-
|
|
375
|
+
And the special "local ID" selector is supported within a scoped style sheet:
|
|
376
|
+
|
|
377
|
+
```html
|
|
378
|
+
<div namespace>
|
|
379
|
+
<a id="url" href="https://example.org">
|
|
380
|
+
<span id="name">Joe Bloggs</span>
|
|
381
|
+
</a>
|
|
382
|
+
<a id="email" href="mailto:joebloggs@example.com" >joebloggs@example.com</a>
|
|
383
|
+
|
|
384
|
+
<style scoped>
|
|
385
|
+
#\~name { color: red }
|
|
386
|
+
</style>
|
|
387
|
+
</div>
|
|
388
|
+
```
|
|
389
|
+
|
|
390
|
+
And everything comes with a complementary low-level API that exposes said assets to tools:
|
|
148
391
|
|
|
149
392
|
```js
|
|
150
393
|
let { styleSheets, scripts } = user; // APIs that are analogous to the document.styleSheets, document.scripts properties
|
|
@@ -1290,218 +1533,6 @@ const response = myElement.contexts.request(requestParams);
|
|
|
1290
1533
|
console.log(response.value.title);
|
|
1291
1534
|
```
|
|
1292
1535
|
|
|
1293
|
-
## Polyfill
|
|
1294
|
-
|
|
1295
|
-
OOHTML is being developed as something to be used today—via a polyfill. This is an intentional effort that in turn ensures that the proposal evolves through a practice-driven process.
|
|
1296
|
-
|
|
1297
|
-
<details><summary>Load from a CDN<br>
|
|
1298
|
-
└───────── <a href="https://bundlephobia.com/result?p=@webqit/oohtml"><img align="right" src="https://img.shields.io/badge/21.8%20kB-black"></a></summary>
|
|
1299
|
-
|
|
1300
|
-
```html
|
|
1301
|
-
<script src="https://unpkg.com/@webqit/oohtml/dist/main.lite.js"></script>
|
|
1302
|
-
```
|
|
1303
|
-
|
|
1304
|
-
└ This is to be placed early on in the document and should be a classic script without any `defer` or `async` directives!
|
|
1305
|
-
|
|
1306
|
-
└ For the Scoped Styles feature, you'd need an external polyfill like the [samthor/scoped](https://github.com/samthor/scoped) polyfill (more details below):
|
|
1307
|
-
|
|
1308
|
-
```html
|
|
1309
|
-
<head>
|
|
1310
|
-
<script src="https://unpkg.com/style-scoped/scoped.min.js"></script>
|
|
1311
|
-
</head>
|
|
1312
|
-
```
|
|
1313
|
-
|
|
1314
|
-
</details>
|
|
1315
|
-
|
|
1316
|
-
<details><summary>Install from NPM<br>
|
|
1317
|
-
└───────── <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>
|
|
1318
|
-
|
|
1319
|
-
```bash
|
|
1320
|
-
npm i @webqit/oohtml @webqit/quantum-js
|
|
1321
|
-
```
|
|
1322
|
-
|
|
1323
|
-
```js
|
|
1324
|
-
// Import
|
|
1325
|
-
import * as Quantum from '@webqit/quantum-js/lite'; // Or from '@webqit/quantum-js'; See implementation notes below
|
|
1326
|
-
import init from '@webqit/oohtml';
|
|
1327
|
-
|
|
1328
|
-
// Initialize the lib
|
|
1329
|
-
init.call(window, Quantum[, options = {}]);
|
|
1330
|
-
```
|
|
1331
|
-
|
|
1332
|
-
└ 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.
|
|
1333
|
-
|
|
1334
|
-
└ But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
|
|
1335
|
-
|
|
1336
|
-
</details>
|
|
1337
|
-
|
|
1338
|
-
<details><summary>Extended usage concepts</summary>
|
|
1339
|
-
|
|
1340
|
-
If you'll be going ahead to build a real app with OOHTML, you may want to consider also using:
|
|
1341
|
-
|
|
1342
|
-
+ the [`@webqit/oohtml-cli`](https://github.com/webqit/oohtml-cli) package for operating a file-based templating system.
|
|
1343
|
-
|
|
1344
|
-
+ the modest, OOHTML-based [Webflo](https://github.com/webqit/webflo) framework to greatly streamline your workflow!
|
|
1345
|
-
|
|
1346
|
-
</details>
|
|
1347
|
-
|
|
1348
|
-
<details><summary>Implementation Notes</summary>
|
|
1349
|
-
|
|
1350
|
-
+ **Scoped/Quantum Scripts**. This feature is an extension of [Quantum JS](https://github.com/webqit/quantum-js). While the main OOHTML build is based on the main Quantum JS APIs, a companion "OOHTML Lite" build is also available based on the [Quantum JS Lite](https://github.com/webqit/quantum-js#quantum-js-lite) edition. The trade-off is in the execution timing of `<script quantum></script>` and `<script scoped></script>` elements: being "synchronous/blocking" with the former, and "asynchronous/non-blocking" with the latter! (See [`async`/`defer`](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/script#attributes).)
|
|
1351
|
-
|
|
1352
|
-
Of the two, the "OOHTML Lite" edition is the recommend option on web pages (as used above) for faster load times unless there's a requirment to emulate the [native synchronous timing](https://html.spec.whatwg.org/multipage/parsing.html#scripts-that-modify-the-page-as-it-is-being-parsed) of classic scripts, in which case you'd need the main OOHTML build:
|
|
1353
|
-
|
|
1354
|
-
```html
|
|
1355
|
-
<head>
|
|
1356
|
-
<script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
1357
|
-
</head>
|
|
1358
|
-
```
|
|
1359
|
-
|
|
1360
|
-
└─ <a href="https://bundlephobia.com/result?p=@webqit/oohtml"><img align="right" src="https://img.shields.io/bundlephobia/minzip/@webqit/oohtml?label=&style=flat&colorB=black"></a>
|
|
1361
|
-
|
|
1362
|
-
+ **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!
|
|
1363
|
-
|
|
1364
|
-
If you must load the script "async", one little trade-off would have to be made for `<script scoped>` and `<script quantum>` 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:
|
|
1365
|
-
|
|
1366
|
-
```html
|
|
1367
|
-
<head>
|
|
1368
|
-
<meta name="scoped-js" content="script.mimeType=some-mime">
|
|
1369
|
-
<script async src="https://unpkg.com/@webqit/oohtml/dist/main.lite.js"></script>
|
|
1370
|
-
</head>
|
|
1371
|
-
<body>
|
|
1372
|
-
<script type="some-mime" scoped>
|
|
1373
|
-
console.log(this); // body
|
|
1374
|
-
</script>
|
|
1375
|
-
</body>
|
|
1376
|
-
```
|
|
1377
|
-
|
|
1378
|
-
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 quantum>` elements ahead of the runtime - e.g. where...
|
|
1379
|
-
|
|
1380
|
-
```html
|
|
1381
|
-
<body>
|
|
1382
|
-
<script scoped>
|
|
1383
|
-
console.log(this); // body
|
|
1384
|
-
</script>
|
|
1385
|
-
</body>
|
|
1386
|
-
```
|
|
1387
|
-
|
|
1388
|
-
...still gives the `window` object in the console.
|
|
1389
|
-
|
|
1390
|
-
+ **Scoped CSS**. This feature is only in "concept" implementation and doesn't work right now as is. The current implementation simply wraps `<style scoped>` blocks in an `@scope {}` block - which itself isn't supported in any browser *yet*. To try this "concept" implementation, set the `style.strategy` config to `@scope`:
|
|
1391
|
-
|
|
1392
|
-
```html
|
|
1393
|
-
<head>
|
|
1394
|
-
<meta name="scoped-css" content="style.strategy=@scope"> <!-- Must come before the polyfil -->
|
|
1395
|
-
<script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
1396
|
-
<head>
|
|
1397
|
-
```
|
|
1398
|
-
|
|
1399
|
-
Now the following `<style scoped>`...
|
|
1400
|
-
|
|
1401
|
-
```html
|
|
1402
|
-
<style scoped>
|
|
1403
|
-
h2 { color: red; }
|
|
1404
|
-
</style>
|
|
1405
|
-
```
|
|
1406
|
-
|
|
1407
|
-
...will be wrapped to something like:
|
|
1408
|
-
|
|
1409
|
-
```html
|
|
1410
|
-
<style ref="scoped8eff" scoped>
|
|
1411
|
-
@scope from (:has(> style[ref="scoped8eff"])) {
|
|
1412
|
-
h2 { color: red; }
|
|
1413
|
-
}
|
|
1414
|
-
</style>
|
|
1415
|
-
```
|
|
1416
|
-
|
|
1417
|
-
Browser support for `@scope {}` style blocks may be coming soon, but in the meantime, you could try one of the polyfills for `<style scoped>` out there; e.g. [samthor/scoped](https://github.com/samthor/scoped):
|
|
1418
|
-
|
|
1419
|
-
```html
|
|
1420
|
-
<script src="https://unpkg.com/style-scoped/scoped.min.js"></script>
|
|
1421
|
-
```
|
|
1422
|
-
|
|
1423
|
-
+ **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:
|
|
1424
|
-
|
|
1425
|
-
```html
|
|
1426
|
-
<head>
|
|
1427
|
-
<!-- Configurations come before the polyfil -->
|
|
1428
|
-
<meta name="data-binding" content="attr.expr=expr;">
|
|
1429
|
-
<meta name="namespaced-html" content="attr.id=id;">
|
|
1430
|
-
<meta name="html-imports" content="attr.def=def; attr.ref=ref;">
|
|
1431
|
-
<script src="https://unpkg.com/@webqit/oohtml/dist/main.js"></script>
|
|
1432
|
-
<head>
|
|
1433
|
-
```
|
|
1434
|
-
|
|
1435
|
-
Now, even when the default syntax change, your `def`, `ref`, etc. overrides will keep your implementation intact.
|
|
1436
|
-
|
|
1437
|
-
Additionally, you could employ a global prefix in your implementation:
|
|
1438
|
-
|
|
1439
|
-
```html
|
|
1440
|
-
<meta name="webqit" content="prefix=wq;">
|
|
1441
|
-
```
|
|
1442
|
-
|
|
1443
|
-
...which automatically applies to all `webqit` attributes and APIs (with the exception of the `scoped`, `quantum`, and `data-*` attributes), such that:
|
|
1444
|
-
|
|
1445
|
-
+ `<template def="foo"></template>` now becomes: `<template wq-def="foo"></template>`,
|
|
1446
|
-
+ `<import ref="foo"></import>` now becomes: `<wq-import wq-ref="foo"></wq-import>`,
|
|
1447
|
-
+ `document.import()` now becomes: `document.wqImport()`,
|
|
1448
|
-
+ `document.bind()` now becomes: `document.wqBind()`,
|
|
1449
|
-
+ `document.bindings` now becomes: `document.wqBindings`,
|
|
1450
|
-
+ etc.
|
|
1451
|
-
|
|
1452
|
-
The following is the full syntax table.
|
|
1453
|
-
|
|
1454
|
-
Spec: **data-binding**
|
|
1455
|
-
|
|
1456
|
-
| Config | Default Syntax | Description |
|
|
1457
|
-
| :----- | :------------- | :---------- |
|
|
1458
|
-
| `attr.expr` | `expr` | The "expr" attribute for inline data binding. ([Docs](#inline-data-binding)) |
|
|
1459
|
-
| `attr.itemIndex` | `data-index` | The "item index" attribute for assigning indexes to list items. ([Docs](#inline-data-binding)) |
|
|
1460
|
-
|
|
1461
|
-
Spec: **bindings-api**
|
|
1462
|
-
|
|
1463
|
-
| Config | Default Syntax | Description |
|
|
1464
|
-
| :----- | :------------- | :---------- |
|
|
1465
|
-
| `attr.bindingsreflection` | `bindings` | The attribute for exposing an element's bindings. |
|
|
1466
|
-
| `api.bind` | `bind` | The `document.bind()` and `Element.prototype.bind()` methods. ([Docs](#the-bindings-api)) |
|
|
1467
|
-
| `api.bindings` | `bindings` | The `document.bindings` and `Element.prototype.bindings` object properties. ([Docs](#the-bindings-api)) |
|
|
1468
|
-
|
|
1469
|
-
Spec: **context-api**
|
|
1470
|
-
|
|
1471
|
-
| Config | Default Syntax | Description |
|
|
1472
|
-
| :----- | :------------- | :---------- |
|
|
1473
|
-
| `attr.contextname` | `contextname` | The "context name" attribute on arbitrary elements. ([Docs](#the-context-api)) |
|
|
1474
|
-
| `api.contexts` | `contexts` | The `document.contexts` and `Element.prototype.contexts` object properties. ([Docs](#the-context-api)) |
|
|
1475
|
-
|
|
1476
|
-
Spec: **html-imports**
|
|
1477
|
-
|
|
1478
|
-
| Config | Default Syntax | Description |
|
|
1479
|
-
| :----- | :------------- | :---------- |
|
|
1480
|
-
| `elements.import` | `import` | The tag name for "import" elements. ([Docs](#html-imports)) |
|
|
1481
|
-
| `attr.def` | `def` | The "definition" attribute on the `<template>` elements. ([Docs](#module-definition)) |
|
|
1482
|
-
| `attr.fragmentdef` | *Inherits the value of `attr.def`* | The "definition" attribute on a `<template>`'s contents. ([Docs](#module-definition)) |
|
|
1483
|
-
| `attr.extends` | `extends` | The "extends" attribute for extending definitions. ([Docs](#module-inheritance)) |
|
|
1484
|
-
| `attr.inherits` | `inherits` | The "inherits" attribute for inheriting definitions. ([Docs](#module-inheritance)) |
|
|
1485
|
-
| `attr.ref` | `ref` | The "import ref" attribute on "import" elements. ([Docs](#declarative-module-imports)) |
|
|
1486
|
-
| `attr.importscontext` | `importscontext` | The "importscontext" attribute on arbitrary elements. ([Docs](#imports-contexts)) |
|
|
1487
|
-
| `api.def` | `def` | The readonly string property for accessing an element's "def" value. ([Docs](#module-definition)) |
|
|
1488
|
-
| `api.defs` | `defs` | The readonly object property for accessing a `<template>`'s list of definitions. ([Docs](#module-definition)) |
|
|
1489
|
-
| `api.import` | `import` | The `document.import()` and `Element.prototype.import()` methods. ([Docs](#imperative-module-imports)) |
|
|
1490
|
-
|
|
1491
|
-
Spec: **namespaced-html**
|
|
1492
|
-
|
|
1493
|
-
| Config | Default Syntax | Description |
|
|
1494
|
-
| :----- | :------------- | :---------- |
|
|
1495
|
-
| `attr.namespace` | `namespace` | The "namespace" attribute on arbitrary elements. ([Docs](#namespacing)) |
|
|
1496
|
-
| `attr.id` | `id` | The "id" attribute on arbitrary elements. ([Docs](#namespacing)) |
|
|
1497
|
-
| `api.namespace` | `namespace` | The "namespace" object property on arbitrary elements. ([Docs](#namespacing)) |
|
|
1498
|
-
|
|
1499
|
-
Spec: **scoped-css** (TODO)
|
|
1500
|
-
|
|
1501
|
-
Spec: **scoped-js** (TODO)
|
|
1502
|
-
|
|
1503
|
-
</details>
|
|
1504
|
-
|
|
1505
1536
|
## Examples
|
|
1506
1537
|
|
|
1507
1538
|
Here are a few examples in the wide range of use cases these features cover. While we'll demonstrate the most basic form of these scenarios, it takes roughly the same principles to build an intricate form and a highly interactive UI.
|