@webqit/oohtml 2.0.2 → 2.1.1
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/dist/html-imports.js +1 -1
- package/dist/html-imports.js.map +2 -2
- package/dist/html-modules.js +1 -1
- package/dist/html-modules.js.map +2 -2
- package/dist/main.js +2 -2
- package/dist/main.js.map +2 -2
- package/package.json +1 -1
- package/src/context-api/HTMLContext.js +3 -3
- package/src/html-imports/_HTMLImportElement.js +3 -3
- package/src/html-modules/HTMLExportsManager.js +36 -28
- package/src/html-modules/_HTMLImportsContext.js +1 -1
- package/src/html-modules/index.js +2 -2
- package/test/imports.test.js +40 -12
- package/test/test.html +6 -6
package/package.json
CHANGED
|
@@ -107,13 +107,13 @@ export default class HTMLContext {
|
|
|
107
107
|
* @handleEvent()
|
|
108
108
|
*/
|
|
109
109
|
handleEvent( event ) {
|
|
110
|
-
if ( this.disposed || ( event.target === this.host &&
|
|
110
|
+
if ( this.disposed || ( event.target === this.host && event.request?.superContextOnly )
|
|
111
111
|
|| !event.request || typeof event.callback !== 'function' || !this.constructor.matchRequest( this.id, event.request ) ) return;
|
|
112
112
|
event.stopPropagation();
|
|
113
113
|
if ( event.type === 'contextclaim' ) {
|
|
114
114
|
const claims = new Set;
|
|
115
115
|
this.subscriptions.forEach( subscriptionEvent => {
|
|
116
|
-
if ( !event.target.contains( subscriptionEvent.request.
|
|
116
|
+
if ( !event.target.contains( subscriptionEvent.request.superContextOnly ? subscriptionEvent.target.parentNode : subscriptionEvent.target )
|
|
117
117
|
|| !this.constructor.matchRequest( event.request/*provider ID*/, subscriptionEvent.request/*request ID*/ ) ) return;
|
|
118
118
|
this.subscriptions.delete( subscriptionEvent );
|
|
119
119
|
claims.add( subscriptionEvent );
|
|
@@ -133,7 +133,7 @@ export default class HTMLContext {
|
|
|
133
133
|
this.disposed = false;
|
|
134
134
|
host.addEventListener( 'contextrequest', this );
|
|
135
135
|
host.addEventListener( 'contextclaim', this );
|
|
136
|
-
HTMLContextManager.instance( host ).ask( this.id, claims => claims.forEach( subscriptionEvent => {
|
|
136
|
+
HTMLContextManager.instance( host ).ask( { ...this.id, superContextOnly: true }, claims => claims.forEach( subscriptionEvent => {
|
|
137
137
|
this.subscribe( subscriptionEvent );
|
|
138
138
|
this.handle( subscriptionEvent );
|
|
139
139
|
} ), { type: 'contextclaim' } );
|
|
@@ -53,7 +53,7 @@ export default function( params ) {
|
|
|
53
53
|
|
|
54
54
|
priv.importRequest = ( callback, signal = null ) => {
|
|
55
55
|
const detail = priv.moduleRef && !priv.moduleRef.includes( '#' ) ? `${ priv.moduleRef }#default` : priv.moduleRef;
|
|
56
|
-
const request = _HTMLImportsContext.createRequest( { detail, live: signal && true, signal
|
|
56
|
+
const request = _HTMLImportsContext.createRequest( { detail, live: signal && true, signal } );
|
|
57
57
|
HTMLContextManager.instance( this.el.isConnected ? this.el.parentNode : priv.anchorNode.parentNode ).ask( request, response => {
|
|
58
58
|
callback( ( response instanceof Set ? new Set( response ) : response ) || [] );
|
|
59
59
|
} );
|
|
@@ -73,9 +73,9 @@ export default function( params ) {
|
|
|
73
73
|
priv.hydrationImportRequest = new AbortController;
|
|
74
74
|
priv.importRequest( modules => {
|
|
75
75
|
if ( priv.originalsRemapped ) { return this.fill( modules ); }
|
|
76
|
-
const identifiersMap = [ ...modules ].map( module => ( { el: module, exportId: module.getAttribute( params.export.attr.exportid ) || 'default', tagName: module.tagName, } ) );
|
|
76
|
+
const identifiersMap = [ ...modules ].map( module => ( { el: module, exportId: module.getAttribute( params.export.attr.exportid ) || '#default', tagName: module.tagName, } ) );
|
|
77
77
|
slottedElements.forEach( slottedElement => {
|
|
78
|
-
const tagName = slottedElement.tagName, exportId = slottedElement.getAttribute( params.export.attr.exportid ) || 'default';
|
|
78
|
+
const tagName = slottedElement.tagName, exportId = slottedElement.getAttribute( params.export.attr.exportid ) || '#default';
|
|
79
79
|
const originalsMatch = identifiersMap.filter( moduleIdentifiers => tagName === moduleIdentifiers.tagName && exportId === moduleIdentifiers.exportId );
|
|
80
80
|
if ( originalsMatch.length !== 1 ) return;
|
|
81
81
|
_( slottedElement ).set( 'original@imports', originalsMatch[ 0 ].el );
|
|
@@ -71,32 +71,32 @@ export default class HTMLExportsManager {
|
|
|
71
71
|
const fragmentsExports = new Map;
|
|
72
72
|
entries.forEach( entry => {
|
|
73
73
|
if ( entry.nodeType !== 1 ) return;
|
|
74
|
-
|
|
74
|
+
const exportId = ( entry.getAttribute( this.params.export.attr.exportid ) || '' ).trim() || '#default';
|
|
75
|
+
const isPackage = entry.matches( this.params.templateSelector );
|
|
76
|
+
if ( exportId.startsWith( '#' ) ) {
|
|
77
|
+
this.validateExportId( exportId.substring( 1 ) );
|
|
78
|
+
if ( !fragmentsExports.has( exportId ) ) { fragmentsExports.set( exportId, [] ); }
|
|
79
|
+
fragmentsExports.get( exportId ).push( entry );
|
|
80
|
+
} else {
|
|
75
81
|
if ( isConnected ) {
|
|
76
|
-
|
|
77
|
-
|
|
82
|
+
if ( isPackage ) { new HTMLExportsManager( entry, this.params, this.host, this.level + 1 ); }
|
|
83
|
+
Observer.set( this.modules, exportId, entry );
|
|
78
84
|
} else {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
moduleExport.dispose();
|
|
85
|
+
if ( isPackage ) { HTMLModulesGraph.instance( entry, this.params ).dispose(); }
|
|
86
|
+
Observer.deleteProperty( this.modules, exportId );
|
|
82
87
|
}
|
|
83
|
-
} else {
|
|
84
|
-
const exportId = ( entry.getAttribute( this.params.export.attr.exportid ) || '' ).trim() || 'default';
|
|
85
|
-
this.validateExportId( exportId );
|
|
86
|
-
if ( !fragmentsExports.has( exportId ) ) { fragmentsExports.set( exportId, [] ); }
|
|
87
|
-
fragmentsExports.get( exportId ).push( entry );
|
|
88
88
|
}
|
|
89
89
|
} );
|
|
90
90
|
// ----------------
|
|
91
91
|
fragmentsExports.forEach( ( fragments, exportId ) => {
|
|
92
|
-
let existingFragments = Observer.get( this.modules,
|
|
92
|
+
let existingFragments = Observer.get( this.modules, exportId );
|
|
93
93
|
if ( isConnected ) {
|
|
94
94
|
existingFragments = new Set( ( existingFragments ? [ ...existingFragments ] : [] ).concat( fragments ) );
|
|
95
95
|
} else if ( existingFragments ) {
|
|
96
96
|
fragments.forEach( el => existingFragments.delete( el ) );
|
|
97
97
|
}
|
|
98
|
-
if ( !isConnected && !existingFragments.size ) { Observer.deleteProperty( this.modules,
|
|
99
|
-
else { Observer.set( this.modules,
|
|
98
|
+
if ( !isConnected && !existingFragments.size ) { Observer.deleteProperty( this.modules, exportId ); }
|
|
99
|
+
else { Observer.set( this.modules, exportId, existingFragments ) }
|
|
100
100
|
} );
|
|
101
101
|
}
|
|
102
102
|
|
|
@@ -158,20 +158,28 @@ export default class HTMLExportsManager {
|
|
|
158
158
|
* @returns Void|AbortController
|
|
159
159
|
*/
|
|
160
160
|
evalInheritance( ) {
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
161
|
+
if ( !this.parent ) return [];
|
|
162
|
+
let extendedId = ( this.host.getAttribute( this.params.template.attr.extends ) || '' ).trim();
|
|
163
|
+
let inheritedIds = ( this.host.getAttribute( this.params.template.attr.inherits ) || '' ).trim();
|
|
164
|
+
const handleInherited = records => {
|
|
165
|
+
records.forEach( record => {
|
|
166
|
+
if ( Observer.get( this.modules, record.key ) !== record.oldValue ) return;
|
|
167
|
+
if ( [ 'get'/*initial get*/, 'set', 'defineProperty' ].includes( record.type ) ) {
|
|
168
|
+
Observer[ record.type.replace( 'get', 'set' ) ]( this.modules, record.key, record.value );
|
|
169
|
+
} else if ( record.type === 'deleteProperty' ) {
|
|
170
|
+
Observer.deleteProperty( this.modules, record.key );
|
|
171
|
+
}
|
|
172
|
+
} );
|
|
173
|
+
};
|
|
174
|
+
const realtimes = [];
|
|
175
|
+
const parentExportsObj = getModulesObject( this.parent );
|
|
176
|
+
if ( extendedId ) {
|
|
177
|
+
realtimes.push( Observer.deep( parentExportsObj, [ extendedId, this.params.template.api.modules, Infinity ], Observer.get, handleInherited, { live: true } ) );
|
|
178
|
+
}
|
|
179
|
+
if ( ( inheritedIds = inheritedIds.split( ' ' ).map( id => id.trim() ).filter( x => x ) ).length ) {
|
|
180
|
+
realtimes.push( Observer.get( parentExportsObj, inheritedIds, handleInherited, { live: true } ) );
|
|
174
181
|
}
|
|
182
|
+
return realtimes;
|
|
175
183
|
}
|
|
176
184
|
|
|
177
185
|
/**
|
|
@@ -182,7 +190,7 @@ export default class HTMLExportsManager {
|
|
|
182
190
|
dispose() {
|
|
183
191
|
this.realtimeA.disconnect();
|
|
184
192
|
this.realtimeB.disconnect();
|
|
185
|
-
this.realtimeC
|
|
193
|
+
this.realtimeC.forEach( r => r.abort() );
|
|
186
194
|
Object.entries( this.modules ).forEach( ( [ key, entry ] ) => {
|
|
187
195
|
if ( key.startsWith( '#' ) ) return;
|
|
188
196
|
HTMLExportsManager.instance( entry ).dispose();
|
|
@@ -82,7 +82,7 @@ export default class _HTMLImportsContext extends HTMLContext {
|
|
|
82
82
|
return update();
|
|
83
83
|
}
|
|
84
84
|
// This superModules contextrequest is automatically aborted by the injected signal below
|
|
85
|
-
const request = this.constructor.createRequest( { detail: record.value.trim(), live: true, signal } );
|
|
85
|
+
const request = this.constructor.createRequest( { detail: record.value.trim(), live: true, signal, superContextOnly: true } );
|
|
86
86
|
HTMLContextManager.instance( this.host ).ask( request, response => {
|
|
87
87
|
this.altModules = !( response && Object.getPrototypeOf( response ) ) ? response : getModulesObject( response );
|
|
88
88
|
update();
|
|
@@ -19,7 +19,7 @@ export default function init( $params = {} ) {
|
|
|
19
19
|
const window = this, dom = wqDom.call( window );
|
|
20
20
|
// -------
|
|
21
21
|
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
22
|
-
template: { attr: { exportid: 'exportid', inherits: 'inherits' }, api: { modules: 'modules', exportid: 'exportid' }, },
|
|
22
|
+
template: { attr: { exportid: 'exportid', extends: 'extends', inherits: 'inherits' }, api: { modules: 'modules', exportid: 'exportid' }, },
|
|
23
23
|
context: { attr: { importscontext: 'importscontext', contextname: 'contextname' }, api: { modules: 'modules' }, },
|
|
24
24
|
export: { attr: { exportid: 'exportid' }, },
|
|
25
25
|
staticsensitivity: true,
|
|
@@ -49,7 +49,7 @@ export function getModulesObject( node, autoCreate = true ) {
|
|
|
49
49
|
if ( !_( node ).has( 'modules' ) && autoCreate ) {
|
|
50
50
|
const modulesObj = Object.create( null );
|
|
51
51
|
Observer.intercept( modulesObj, 'set', ( event, receiver, next ) => {
|
|
52
|
-
if ( !event.key.startsWith( '#' ) || event.value instanceof Set ) return next();
|
|
52
|
+
if ( !event.value || !event.key.startsWith( '#' ) || event.value instanceof Set ) return next();
|
|
53
53
|
if ( !Array.isArray( event.value ) ) { event.value = [ event.value ]; }
|
|
54
54
|
event.value = new Set( event.value );
|
|
55
55
|
return next();
|
package/test/imports.test.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
5
|
import { expect } from 'chai';
|
|
6
|
-
import { delay, createDocument, mockRemoteFetch,
|
|
6
|
+
import { delay, createDocument, mockRemoteFetch, _ } from './index.js';
|
|
7
7
|
|
|
8
8
|
describe(`HTML Imports`, function() {
|
|
9
9
|
|
|
@@ -41,15 +41,37 @@ describe(`HTML Imports`, function() {
|
|
|
41
41
|
|
|
42
42
|
const head = `
|
|
43
43
|
<template exportid="temp0">
|
|
44
|
+
<!-- ------- -->
|
|
44
45
|
<p>Hello world Export</p>
|
|
45
46
|
<p>Hellort</p>
|
|
46
|
-
<input exportid="input" />
|
|
47
|
+
<input exportid="#input" />
|
|
47
48
|
<template exportid="temp1">
|
|
48
|
-
<textarea exportid="input"></textarea>
|
|
49
|
+
<textarea exportid="#input"></textarea>
|
|
49
50
|
<template exportid="temp2">
|
|
50
|
-
<select exportid="input"></select>
|
|
51
|
+
<select exportid="#input"></select>
|
|
51
52
|
</template>
|
|
52
53
|
</template>
|
|
54
|
+
<!-- ------- -->
|
|
55
|
+
<template exportid="_landing1">
|
|
56
|
+
<div exportid="#main.html">a</div>
|
|
57
|
+
<template exportid="_landing2">
|
|
58
|
+
<div exportid="#main.html">b</div>
|
|
59
|
+
<template exportid="_docs">
|
|
60
|
+
<div exportid="#main.html">c</div>
|
|
61
|
+
</template>
|
|
62
|
+
</template>
|
|
63
|
+
</template>
|
|
64
|
+
<!-- ------- -->
|
|
65
|
+
<template exportid="landing1" extends="_landing1">
|
|
66
|
+
<div exportid="#README.md">1</div>
|
|
67
|
+
<template exportid="landing2" extends="_landing2">
|
|
68
|
+
<div exportid="#README.md">2</div>
|
|
69
|
+
<template exportid="docs" extends="_docs">
|
|
70
|
+
<div exportid="#README.md">3</div>
|
|
71
|
+
</template>
|
|
72
|
+
</template>
|
|
73
|
+
</template>
|
|
74
|
+
<!-- ------- -->
|
|
53
75
|
</template>`;
|
|
54
76
|
const body = `
|
|
55
77
|
<import module="temp0/uuu"></import>`;
|
|
@@ -86,6 +108,12 @@ describe(`HTML Imports`, function() {
|
|
|
86
108
|
document.body.querySelector( 'input' ).remove();
|
|
87
109
|
expect( document.body.firstElementChild.nodeName ).to.eq( 'IMPORT' );
|
|
88
110
|
} );
|
|
111
|
+
|
|
112
|
+
/*
|
|
113
|
+
it ( ``, async function() {
|
|
114
|
+
console.log('"""""""""""""""""""""""""""""""""""""""""""""', document.modules.temp0.modules.landing1.modules.landing2.modules.docs.modules);
|
|
115
|
+
} );
|
|
116
|
+
*/
|
|
89
117
|
|
|
90
118
|
} );
|
|
91
119
|
|
|
@@ -131,17 +159,17 @@ describe(`HTML Imports`, function() {
|
|
|
131
159
|
|
|
132
160
|
const head = `
|
|
133
161
|
<template exportid="temp0">
|
|
134
|
-
<input exportid="input" />
|
|
162
|
+
<input exportid="#input" />
|
|
135
163
|
<template exportid="temp1">
|
|
136
|
-
<textarea exportid="input"></textarea>
|
|
164
|
+
<textarea exportid="#input"></textarea>
|
|
137
165
|
<template exportid="temp2">
|
|
138
|
-
<select exportid="input"></select>
|
|
166
|
+
<select exportid="#input"></select>
|
|
139
167
|
</template>
|
|
140
168
|
</template>
|
|
141
169
|
</template>`;
|
|
142
170
|
const body = `
|
|
143
171
|
<div importscontext="temp0/temp1">
|
|
144
|
-
<textarea exportid="input"></textarea>
|
|
172
|
+
<textarea exportid="#input"></textarea>
|
|
145
173
|
<!--<import module="#input"></import>-->
|
|
146
174
|
</div>`;
|
|
147
175
|
const { document } = createDocument( head, body );
|
|
@@ -163,17 +191,17 @@ describe(`HTML Imports`, function() {
|
|
|
163
191
|
|
|
164
192
|
const head = `
|
|
165
193
|
<template exportid="temp0">
|
|
166
|
-
<input exportid="input" />
|
|
194
|
+
<input exportid="#input" />
|
|
167
195
|
<template exportid="temp1">
|
|
168
|
-
<textarea exportid="input"></textarea>
|
|
196
|
+
<textarea exportid="#input"></textarea>
|
|
169
197
|
<template exportid="temp2">
|
|
170
|
-
<select exportid="input"></select>
|
|
198
|
+
<select exportid="#input"></select>
|
|
171
199
|
</template>
|
|
172
200
|
</template>
|
|
173
201
|
</template>`;
|
|
174
202
|
const body = `
|
|
175
203
|
<div importscontext="temp0/temp1">
|
|
176
|
-
<textarea exportid="input"></textarea>
|
|
204
|
+
<textarea exportid="#input"></textarea>
|
|
177
205
|
<!--<import module="#input"></import>-->
|
|
178
206
|
</div>`;
|
|
179
207
|
const { document } = createDocument( head, body );
|
package/test/test.html
CHANGED
|
@@ -2,21 +2,21 @@
|
|
|
2
2
|
<html>
|
|
3
3
|
<head>
|
|
4
4
|
<meta name="oohtml" content="script.retention=hidden" />
|
|
5
|
-
<script src="
|
|
5
|
+
<script src="/oohtml/dist/main.js"></script>
|
|
6
6
|
<script>
|
|
7
7
|
window.extVar = 'External variable initial value.';
|
|
8
8
|
window.Observer = wq.Observer;
|
|
9
9
|
</script>
|
|
10
10
|
<template exportid="temp0">
|
|
11
|
-
<input exportid="input" />
|
|
11
|
+
<input exportid="#input" />
|
|
12
12
|
<template exportid="temp1">
|
|
13
|
-
<textarea exportid="input"></textarea>
|
|
13
|
+
<textarea exportid="#input" placeholder="This is to be rendered"></textarea>
|
|
14
14
|
<template exportid="temp2">
|
|
15
|
-
<select exportid="input"></select>
|
|
15
|
+
<select exportid="#input"></select>
|
|
16
16
|
</template>
|
|
17
17
|
<template exportid="temp2b" inherits="#input"></template>
|
|
18
18
|
<template exportid="temp2c">
|
|
19
|
-
<textarea exportid="input"></textarea>
|
|
19
|
+
<textarea exportid="#input"></textarea>
|
|
20
20
|
</template>
|
|
21
21
|
</template>
|
|
22
22
|
</template>
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
<body>
|
|
25
25
|
|
|
26
26
|
<div importscontext="temp0/temp1">
|
|
27
|
-
<textarea exportid="input"></textarea>
|
|
27
|
+
<textarea exportid="#input" placeholder="This is server-rendered"></textarea>
|
|
28
28
|
<!--<import module="#input"></import>-->
|
|
29
29
|
</div>
|
|
30
30
|
|