@webqit/oohtml 3.0.1-0 → 3.0.1-10

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.
Files changed (2) hide show
  1. package/README.md +292 -132
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -38,13 +38,13 @@ This project pursues an object-oriented approach to HTML and implicitly revisits
38
38
 
39
39
  ## Modular HTML
40
40
 
41
- Modular HTML is a markup pattern that lets us write arbitrary markup as self-contained objects - with each *encapsulating* its own structure, styling and logic - as against the regular idea of having everything converge and conflict on one global scope!
41
+ 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!
42
42
 
43
43
  OOHTML makes this possible in just simple conventions - via two new attributes: `namespace` and `scoped`!
44
44
 
45
45
  ### Namespacing
46
46
 
47
- Naming things is hard! That's especially so where there's one global namespace and a miriad of potential conflicts - as is the case with HTML!
47
+ Naming things is hard! That's especially so where you have one global namespace and a miriad of potentially conflicting names to coordinate!
48
48
 
49
49
  Here, we get the `namespace` attribute for designating an element as own naming context for identifiers instead of the global namespace:
50
50
 
@@ -148,9 +148,18 @@ Here, we get the `scoped` attribute for *scoping* said element-specific styleshe
148
148
  let { styleSheets, scripts } = user; // APIs that are analogous to the document.styleSheets, document.scripts properties
149
149
  ```
150
150
 
151
+ <details><summary>Learn more</summary>
152
+
153
+ The `scoped` has two effects on the `<script>` element:
154
+
155
+ + The `this` keyword is a reference to the script's host element
156
+ + The `<script>` element is executed again on each re-insertion to the DOM
157
+
158
+ </details>
159
+
151
160
  ## HTML Imports
152
161
 
153
- HTML Imports is a realtime module system for HTML written in HTML! 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.
162
+ HTML Imports is a realtime module system for HTML that speaks HTML! 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.
154
163
 
155
164
  OOHTML makes this possible in just simple conventions - via a new `def` attribute and a complementary new `<import>` element!
156
165
 
@@ -366,7 +375,7 @@ setTimeout(() => abortController.abort(), 1000);
366
375
 
367
376
  We can defer module loading until we really need them.
368
377
 
369
- Here, we get the `loading="lazy"` directive for that; and loading is only then triggered on the first attempt to import its contents:
378
+ Here, we get the `loading="lazy"` directive for that; and loading is only then triggered on the first attempt to import their contents:
370
379
 
371
380
  ```html
372
381
  <!-- Loading doesn't happen until the first time this is being accessed -->
@@ -570,7 +579,7 @@ console.log(localOrGlobalImport2); // { value: div }
570
579
 
571
580
  ## Data Binding
572
581
 
573
- Data binding is the concept of having a mechanism that declaratively drives the UI from application data, ensuring that the relevant parts of the UI are *automatically* updated as application state changes.
582
+ Data binding is about declaratively binding the UI to application data, ensuring that the relevant parts of the UI are *automatically* updated as application state changes.
574
583
 
575
584
  OOHTML makes this possible in just simple conventions - via a new comment-based data-binding syntax `<?{ }?>` and a complementary new `binding` attribute! And there's one more: Quantum Scripts which brings the most advanced form of reactivity to HTML!
576
585
 
@@ -584,12 +593,42 @@ Here, we get a comment-based data-binding tag `<?{ }?>` which works like regular
584
593
  <title><?{ app.title }?></title>
585
594
  </head>
586
595
  <body>
587
- Hi, I'm <?{ app.name ?? 'Default name' }?>!
588
- and here's another way to write the same comment: <!--?{ app.cool }?-->
596
+ Hi, I'm <?{ name ?? 'Default name' }?>!
597
+ and here's another way to write the same comment: <!--?{ cool }?-->
589
598
  </body>
590
599
  </html>
591
600
  ```
592
601
 
602
+ <details><summary>Details</summary>
603
+
604
+ Here, JavaScript references are resolved from the closest node up the document hierarchy that exposes a corresponding *binding* on its Bindings API ([discussed below](#bindings-api)). Thus, the above markup could have an underlying data structure like the below:
605
+
606
+ ```js
607
+ document.bind({ name: 'James Boye', cool: '100%', app: { title: 'Demo App' } });
608
+ document.body.bind({ name: 'John Doe' });
609
+ ```
610
+
611
+ ```js
612
+ document: { name: 'James Boye', cool: '100%', app: { title: 'Demo App' } }
613
+ └── html
614
+ ├── head
615
+ └── body: { name: 'John Doe' }
616
+ ```
617
+
618
+ Now, the `name` reference remains bound to the `name` *binding* on the `<body>` element until the meaning of "closest node" changes again:
619
+
620
+ ```js
621
+ delete document.body.bindings.name;
622
+ ```
623
+
624
+ While the `cool` reference remains bound to the `cool` *binding* on the `document` node until the meaning of "closest node" changes again:
625
+
626
+ ```js
627
+ document.body.bindings.cool = '200%';
628
+ ```
629
+
630
+ </details>
631
+
593
632
  <details><summary>With SSR Support</summary>
594
633
 
595
634
  On the server, these data-binding tags would retain their place in the DOM while having their output rendered to their right in a text node.
@@ -638,11 +677,11 @@ Here, we get the `binding` attribute for a declarative and neat, key/value data-
638
677
 
639
678
  | Directive | Type | Usage |
640
679
  | :---- | :---- | :---- |
641
- | `&` | CSS Property | `<div binding="& color:someColor; & backgroundColor:someColor;"></div>` |
680
+ | `&` | CSS Property | `<div binding="& color:someColor; & backgroundColor:someBgColor;"></div>` |
642
681
  | `%` | Class Name | `<div binding="% active:app.isActive; % expanded:app.isExpanded;"></div>` |
643
682
  | `~` | Attribute Name | `<a binding="~ href:person.profileUrl+'#bio'; ~ title:'Click me';"></a>` |
644
683
  | | Boolean Attribute | `<a binding="~ ?required:formField.required; ~ ?aria-checked: formField.checked"></a>` |
645
- | `@` | Structural Directive: | *See next table* |
684
+ | `@` | Structural Directive: | *See below* |
646
685
  | `@text` | Plain text content | `<span binding="@text:firstName+' '+lastName;"></span>` |
647
686
  | `@html` | Markup content | `<span binding="@html: '<i>'+firstName+'</i>';"></span>` |
648
687
  | `@items` | A list, with argument in the following format:<br>`<declaration> <of\|in> <iterable> / <importRef>` | *See next two tables* |
@@ -667,21 +706,160 @@ Here, we get the `binding` attribute for a declarative and neat, key/value data-
667
706
 
668
707
  </details>
669
708
 
709
+ <details><summary>Details</summary>
710
+
711
+ Here, JavaScript references are resolved from the closest node up the document hierarchy that exposes a corresponding *binding* on its Bindings API ([discussed below](#bindings-api)). Thus, the above CSS example code could have an underlying data structure like the below:
712
+
713
+ ```js
714
+ document.bind({ someColor: 'green', someBgColor: 'yellow' });
715
+ document.body.bind({ someBgColor: 'silver' });
716
+ ```
717
+
718
+ ```js
719
+ document: { someColor: 'green', someBgColor: 'yellow' }
720
+ └── html
721
+ ├── head
722
+ └── body: { someBgColor: 'silver' }
723
+ ```
724
+
725
+ Now, the `someBgColor` reference remains bound to the `someBgColor` *binding* on the `<body>` element until the meaning of "closest node" changes again:
726
+
727
+ ```js
728
+ delete document.body.bindings.someBgColor;
729
+ ```
730
+
731
+ While the `someColor` reference remains bound to the `someColor` *binding* on the `document` node until the meaning of "closest node" changes again:
732
+
733
+ ```js
734
+ document.body.bindings.someColor = 'brown';
735
+ ```
736
+
737
+ </details>
738
+
670
739
  <details><summary>All in realtime</summary>
671
740
 
672
- Lists are rendered in realtime, which means that in-place mutations - additions and removals - on the *iteratee* will be automatically reflected on the UI!
741
+ Bindings are resolved in realtime! And in fact, for lists, in-place mutations - additions and removals - on the *iteratee* are automatically reflected on the UI!
673
742
 
674
743
  </details>
675
744
 
676
745
  <details><summary>With SSR Support</summary>
677
746
 
678
- Generated item elements are automatically assigned a corresponding index with a `data-index` attribute! This helps in remapping generated item nodes to their respective entry in *iteratee* - universally.
747
+ For lists, generated item elements are automatically assigned a corresponding index with a `data-index` attribute! This helps in remapping generated item nodes to their respective entry in *iteratee* - universally.
679
748
 
680
749
  </details>
681
750
 
682
751
  ### Quantum Scripts
683
752
 
684
- *[TODO]*
753
+ 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.
754
+
755
+ Here, from the same `<script>` element we already write, we get a direct upgrade path to reactive programming in just an attribute: `quantum`:
756
+
757
+ ```html
758
+ <script quantum>
759
+ // Code here
760
+ console.log(this); // window
761
+ </script>
762
+ ```
763
+
764
+ ```html
765
+ <script type="module" quantum>
766
+ // Code here
767
+ console.log(this); // undefined
768
+ </script>
769
+ ```
770
+
771
+ **-->** *which adds up really well with the idea of scoping*:
772
+
773
+ ```html
774
+ <main>
775
+
776
+ <script scoped quantum>
777
+ // Code here
778
+ console.log(this); // main
779
+ </script>
780
+
781
+ </main>
782
+ ```
783
+
784
+ ```html
785
+ <main>
786
+
787
+ <script type="module" scoped quantum>
788
+ // Code here
789
+ console.log(this); // main
790
+ </script>
791
+
792
+ </main>
793
+ ```
794
+
795
+ **-->** *with content being whatever you normally would write in a `<script>` element, but without the "manual" work for reactivity*:
796
+
797
+ ```html
798
+ <main>
799
+
800
+ <script type="module" scoped quantum>
801
+ import { someAPI } from 'some-module';
802
+
803
+ let clickCount = 0;
804
+ console.log(clickCount);
805
+ someAPI(clickCount);
806
+
807
+ this.addEventListener('click', e => clickCount++);
808
+ </script>
809
+
810
+ </main>
811
+ ```
812
+
813
+ **-->** *within which other "live" APIs, like the Namespace API above, fit seamlessly*:
814
+
815
+ ```html
816
+ <main namespace>
817
+
818
+ <script scoped quantum>
819
+ if (this.namespace.specialButton) {
820
+ console.log('specialButton present!');
821
+ } else {
822
+ console.log('specialButton not present!');
823
+ }
824
+ let specialButton = this.namespace.specialButton;
825
+ console.log(specialButton);
826
+ </script>
827
+
828
+ </main>
829
+ ```
830
+
831
+ ```js
832
+ const main = document.querySelector('main');
833
+ const button = document.createElement('button');
834
+ button.id = 'specialButton';
835
+
836
+ const addButton = () => {
837
+ main.appendChild(button);
838
+ setTimeout(removeButton, 5000);
839
+ };
840
+ const removeButton = () => {
841
+ button.remove();
842
+ setTimeout(addButton, 5000);
843
+ };
844
+ ```
845
+
846
+ <details><summary>Details</summary>
847
+
848
+ It's Imperative Reactive Programming ([IRP](https://en.wikipedia.org/wiki/Reactive_programming#Imperative)) right there and it's the [Quantum](https://github.com/webqit/quantum-js) runtime extension to JavaScript!
849
+
850
+ 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.
851
+
852
+ Now, in each case above, reactivity terminates on script's removal from the DOM. And a programmatic termination is sill possible:
853
+
854
+ ```js
855
+ const script = document.querySelector('script[quantum]');
856
+ // const script = document.querySelector('main').scripts[0];
857
+ script.abort();
858
+ ```
859
+
860
+ But while that is automatic, DOM event handlers bound via `addEventListener()` would still need to be terminated in their own way.
861
+
862
+ </details>
685
863
 
686
864
  ## Data Plumbing
687
865
 
@@ -782,7 +960,7 @@ Observer.set(element, 'liveProperty'); // Live expressions rerun
782
960
 
783
961
  ## Polyfill
784
962
 
785
- OOHTML is being developed as something to be used today - via a polyfill.
963
+ OOHTML is being developed as something to be used todayvia a polyfill. This is an active and intentional effort that continues to ensure that the project evolves through a practice-driven process.
786
964
 
787
965
  <details><summary>Load from a CDN<br>
788
966
  └───────── <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></summary>
@@ -803,9 +981,8 @@ OOHTML is being developed as something to be used today - via a polyfill.
803
981
 
804
982
  </details>
805
983
 
806
- <details><summary>Extended usage concepts</summary>
807
-
808
- 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:
984
+ <details><summary>Install from NPM<br>
985
+ └───────── <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>
809
986
 
810
987
  ```bash
811
988
  npm i @webqit/oohtml
@@ -819,9 +996,15 @@ import init from '@webqit/oohtml';
819
996
  init.call( window[, options = {} ]);
820
997
  ```
821
998
 
822
- But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
999
+ 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.
1000
+
1001
+ └ But all things "SSR" for OOHTML are best left to the [`@webqit/oohtml-ssr`](https://github.com/webqit/oohtml-ssr) package!
1002
+
1003
+ </details>
1004
+
1005
+ <details><summary>Extended usage concepts</summary>
823
1006
 
824
- Also, if you'll be going ahead to build a real app to see OOHTML in action, you may want to consider also using:
1007
+ If you'll be going ahead to build a real app to see OOHTML in action, you may want to consider also using:
825
1008
 
826
1009
  + the [`@webqit/oohtml-cli`](https://github.com/webqit/oohtml-cli) package for operating a file-based templating system.
827
1010
 
@@ -859,7 +1042,7 @@ Also, if you'll be going ahead to build a real app to see OOHTML in action, you
859
1042
 
860
1043
  ...still gives the `window` object in the console.
861
1044
 
862
- + **Scoped/Quantum Scripts**. This feature is an extension of [Quantum JS](https://github.com/webqit/quantum-js). The default OOHTML build is based on the [Quantum JS Lite APIs](https://github.com/webqit/quantum-js#quantum-js-lite) and this means that `<script quantum></script>` and `<script scoped></script>` elements are parsed "asynchronously", in the same timing as `<script type="module"></script>`!
1045
+ + **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>`!
863
1046
 
864
1047
  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:
865
1048
 
@@ -917,84 +1100,72 @@ Also, if you'll be going ahead to build a real app to see OOHTML in action, you
917
1100
 
918
1101
  ## Examples
919
1102
 
920
- Here are a few examples in the wide range of use cases these features cover.
921
-
922
- + [Example 1: *Single Page Application*](#example-1-single-page-application)
923
- + [Example 2: *Multi-Level Namespacing*](#example-2-multi-level-namespacing)
924
- + [Example 3: *Dynamic Shadow DOM*](#example-3-dynamic-shadow-dom)
925
- + [Example 4: *Declarative Lists*](#example-4-declarative-lists)
926
- + [Example 5: *Imperative Lists*](#example-4-imperative-lists)
1103
+ Here are a few examples in the wide range of use cases these features cover. While we'll demonstrate the most basic forms of these scenarios, it takes roughly the same principles to build an intricate form and a highly interactive UI.
927
1104
 
928
- ### Example 1: *Single Page Application*
1105
+ <details><summary>Example 1: <i>Single Page Application</i><br>
1106
+ └───────── </summary>
929
1107
 
930
1108
  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:
931
1109
 
932
- + *First, two components that are themselves analogous to a Single File Component ([SFC](https://vuejs.org/guide/scaling-up/sfc.html))*:
1110
+ **-->** *First, two components that are themselves analogous to a Single File Component ([SFC](https://vuejs.org/guide/scaling-up/sfc.html))*:
933
1111
 
934
- <details><summary>Code</summary>
1112
+ ```html
1113
+ <template def="pages">
935
1114
 
936
- ```html
937
- <template def="pages">
938
-
939
- <template def="layout">
940
- <header def="header"></header>
941
- <footer def="footer"></footer>
942
- </template>
943
-
944
- <!-- Home Page -->
945
- <template def="home" extends="layout">
946
- <main def="main" namespace>
947
- <h1 id="banner">Home Page</h1>
948
- <a id="cta" href="#/products">Go to Products</a>
949
- <template scoped></template>
950
- <style scoped></style>
951
- <script scoped></script>
952
- </main>
953
- </template>
954
-
955
- <!-- Products Page -->
956
- <template def="products" extends="layout">
957
- <main def="main" namespace>
958
- <h1 id="banner">Products Page</h1>
959
- <a id="cta" href="#/home">Go to Home</a>
960
- <template scoped></template>
961
- <style scoped></style>
962
- <script scoped></script>
963
- </main>
964
- </template>
1115
+ <template def="layout">
1116
+ <header def="header"></header>
1117
+ <footer def="footer"></footer>
1118
+ </template>
965
1119
 
966
- </template>
967
- ```
1120
+ <!-- Home Page -->
1121
+ <template def="home" extends="layout">
1122
+ <main def="main" namespace>
1123
+ <h1 id="banner">Home Page</h1>
1124
+ <a id="cta" href="#/products">Go to Products</a>
1125
+ <template scoped></template>
1126
+ <style scoped></style>
1127
+ <script scoped></script>
1128
+ </main>
1129
+ </template>
968
1130
 
969
- </details>
1131
+ <!-- Products Page -->
1132
+ <template def="products" extends="layout">
1133
+ <main def="main" namespace>
1134
+ <h1 id="banner">Products Page</h1>
1135
+ <a id="cta" href="#/home">Go to Home</a>
1136
+ <template scoped></template>
1137
+ <style scoped></style>
1138
+ <script scoped></script>
1139
+ </main>
1140
+ </template>
970
1141
 
971
- + *Then a 2-line router that alternates the view based on the URL hash*:
1142
+ </template>
1143
+ ```
972
1144
 
973
- <details><summary>Code</summary>
1145
+ **-->** *Then a 2-line router that alternates the view based on the URL hash*:
974
1146
 
975
- ```html
976
- <body importscontext="/pages/home">
977
-
978
- <import ref="#header"></import>
979
- <import ref="#main"></import>
980
- <import ref="#footer"></import>
981
-
982
- <script>
983
- const route = () => { document.body.setAttribute('importscontext', '/pages' + location.hash.substring(1)); };
984
- window.addEventListener('hashchange', route);
985
- </script>
986
-
987
- </body>
988
- ```
1147
+ ```html
1148
+ <body importscontext="/pages/home">
1149
+
1150
+ <import ref="#header"></import>
1151
+ <import ref="#main"></import>
1152
+ <import ref="#footer"></import>
1153
+
1154
+ <script>
1155
+ const route = () => { document.body.setAttribute('importscontext', '/pages' + location.hash.substring(1)); };
1156
+ window.addEventListener('hashchange', route);
1157
+ </script>
1158
+
1159
+ </body>
1160
+ ```
989
1161
 
990
- </details>
1162
+ </details>
991
1163
 
992
- ### Example 2: *Multi-Level Namespacing*
1164
+ <details><summary>Example 2: <i>Multi-Level Namespacing</i><br>
1165
+ └───────── </summary>
993
1166
 
994
1167
  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.
995
1168
 
996
- <details><summary>Code</summary>
997
-
998
1169
  ```html
999
1170
  <div namespace class="listbox-area">
1000
1171
  <div>
@@ -1060,75 +1231,65 @@ The following is a Listbox component lifted directly from the [ARIA Authoring Pr
1060
1231
 
1061
1232
  </details>
1062
1233
 
1063
- ### Example 3: *Dynamic Shadow DOM*
1234
+ <details><summary>Example 3: <i>Dynamic Shadow DOM</i><br>
1235
+ └───────── </summary>
1064
1236
 
1065
1237
  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!
1066
1238
 
1067
- + *First, two layout options defined for the Shadow DOM*:
1239
+ **-->** *First, two layout options defined for the Shadow DOM*:
1068
1240
 
1069
- <details><summary>Code</summary>
1070
-
1071
- ```html
1072
- <template def="vendor1">
1073
-
1074
- <template def="components-layout1">
1075
- <template def="magic-button">
1076
- <span id="icon"></span> <span id="text"></span>
1077
- </template>
1078
- </template>
1079
-
1080
- <template def="components-layout2">
1081
- <template def="magic-button">
1082
- <span id="text"></span> <span id="icon"></span>
1083
- </template>
1084
- </template>
1241
+ ```html
1242
+ <template def="vendor1">
1085
1243
 
1244
+ <template def="components-layout1">
1245
+ <template def="magic-button">
1246
+ <span id="icon"></span> <span id="text"></span>
1086
1247
  </template>
1087
- ```
1248
+ </template>
1088
1249
 
1089
- </details>
1250
+ <template def="components-layout2">
1251
+ <template def="magic-button">
1252
+ <span id="text"></span> <span id="icon"></span>
1253
+ </template>
1254
+ </template>
1090
1255
 
1091
- + *Next, the Shadow DOM creation that imports its layout from context*:
1256
+ </template>
1257
+ ```
1092
1258
 
1093
- <details><summary>Code</summary>
1259
+ **-->** *Next, the Shadow DOM creation that imports its layout from context*:
1094
1260
 
1095
- ```js
1096
- customElements.define('magic-button', class extends HTMLElement {
1097
- connectedCallback() {
1098
- const shadowRoot = this.attachShadow({ mode: 'open' });
1099
- this.import('@vendor1/magic-button', template => {
1100
- shadowRoot.appendChild( template.content.cloneNode(true) );
1101
- });
1102
- }
1261
+ ```js
1262
+ customElements.define('magic-button', class extends HTMLElement {
1263
+ connectedCallback() {
1264
+ const shadowRoot = this.attachShadow({ mode: 'open' });
1265
+ this.import('@vendor1/magic-button', template => {
1266
+ shadowRoot.appendChild( template.content.cloneNode(true) );
1103
1267
  });
1104
- ```
1105
-
1106
- </details>
1107
-
1108
- + *Then, the part where we just drop the component in "layout" contexts*:
1268
+ }
1269
+ });
1270
+ ```
1109
1271
 
1110
- <details><summary>Code</summary>
1272
+ **-->** *Then, the part where we just drop the component in "layout" contexts*:
1111
1273
 
1112
- ```html
1113
- <div contextname="vendor1" importscontext="/vendor1/components-layout1">
1274
+ ```html
1275
+ <div contextname="vendor1" importscontext="/vendor1/components-layout1">
1114
1276
 
1115
- <magic-button></magic-button>
1277
+ <magic-button></magic-button>
1116
1278
 
1117
- <aside contextname="vendor1" importscontext="/vendor1/components-layout2">
1118
- <magic-button></magic-button>
1119
- </aside>
1279
+ <aside contextname="vendor1" importscontext="/vendor1/components-layout2">
1280
+ <magic-button></magic-button>
1281
+ </aside>
1120
1282
 
1121
- </div>
1122
- ```
1283
+ </div>
1284
+ ```
1123
1285
 
1124
- </details>
1286
+ </details>
1125
1287
 
1126
- ### Example 4: *Declarative Lists*
1288
+ <details><summary>Example 4: <i>Declarative Lists</i><br>
1289
+ └───────── </summary>
1127
1290
 
1128
1291
  The following is a hypothetical list page!
1129
1292
 
1130
- <details><summary>Code</summary>
1131
-
1132
1293
  ```html
1133
1294
  <section>
1134
1295
 
@@ -1145,12 +1306,11 @@ The following is a hypothetical list page!
1145
1306
 
1146
1307
  </details>
1147
1308
 
1148
- ### Example 4: *Imperative Lists*
1309
+ <details><summary>Example 5: <i>Imperative Lists</i><br>
1310
+ └───────── </summary>
1149
1311
 
1150
1312
  The following is much like the above, but imperative. Additions and removals on the data items are also statically reflected!
1151
1313
 
1152
- <details><summary>Code</summary>
1153
-
1154
1314
  ```html
1155
1315
  <section namespace>
1156
1316
 
package/package.json CHANGED
@@ -14,7 +14,7 @@
14
14
  "wicg-proposal"
15
15
  ],
16
16
  "homepage": "https://webqit.io/tooling/oohtml",
17
- "version": "3.0.1-0",
17
+ "version": "3.0.1-10",
18
18
  "license": "MIT",
19
19
  "repository": {
20
20
  "type": "git",