@webqit/oohtml 2.1.34 → 2.1.35
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/.gitignore +3 -3
- package/LICENSE +20 -20
- package/README.md +733 -67
- package/dist/bindings-api.js +1 -1
- package/dist/bindings-api.js.map +3 -3
- package/dist/context-api.js +1 -1
- package/dist/context-api.js.map +3 -3
- package/dist/html-imports.js +1 -1
- package/dist/html-imports.js.map +3 -3
- package/dist/main.js +12 -12
- package/dist/main.js.map +3 -3
- package/dist/namespace-api.js +1 -1
- package/dist/namespace-api.js.map +3 -3
- package/dist/scoped-css.js +2 -2
- package/dist/scoped-css.js.map +3 -3
- package/dist/scoped-js.js +7 -7
- package/dist/scoped-js.js.map +3 -3
- package/package.json +76 -76
- package/src/bindings-api/index.js +83 -83
- package/src/bindings-api/targets.browser.js +10 -10
- package/src/context-api/HTMLContext.js +76 -157
- package/src/context-api/HTMLContextProvider.js +158 -0
- package/src/context-api/_ContextRequestEvent.js +25 -25
- package/src/context-api/index.js +51 -51
- package/src/context-api/targets.browser.js +9 -9
- package/src/{html-modules/HTMLExportsManager.js → html-imports/_HTMLExportsManager.js} +185 -199
- package/src/html-imports/_HTMLImportElement.js +211 -213
- package/src/{html-modules/_HTMLImportsContext.js → html-imports/_HTMLImportsProvider.js} +122 -114
- package/src/html-imports/index.js +197 -88
- package/src/html-imports/targets.browser.js +9 -9
- package/src/index.js +30 -32
- package/src/namespace-api/index.js +144 -144
- package/src/namespace-api/targets.browser.js +10 -10
- package/src/scoped-css/index.js +45 -45
- package/src/scoped-css/targets.browser.js +10 -10
- package/src/scoped-js/Compiler.js +297 -297
- package/src/scoped-js/index.js +112 -112
- package/src/scoped-js/targets.browser.js +10 -10
- package/src/targets.browser.js +9 -9
- package/src/util.js +34 -34
- package/test/bindings-api.test.js +42 -42
- package/test/imports.test.js +221 -221
- package/test/index.js +50 -50
- package/test/modules.test.js +200 -200
- package/test/namespace-api.test.js +51 -51
- package/test/scoped-css.test.js +31 -31
- package/test/scoped-js.test.js +29 -29
- package/dist/html-modules.js +0 -2
- package/dist/html-modules.js.map +0 -7
- package/src/context-api/HTMLContextManager.js +0 -77
- package/src/html-modules/index.js +0 -131
- package/src/html-modules/targets.browser.js +0 -10
|
@@ -1,199 +1,185 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import { getModulesObject } from './index.js';
|
|
7
|
-
import { _ } from '../util.js';
|
|
8
|
-
|
|
9
|
-
export default class
|
|
10
|
-
|
|
11
|
-
/**
|
|
12
|
-
* @instance
|
|
13
|
-
*/
|
|
14
|
-
static instance( window, host, config ) {
|
|
15
|
-
return _( host ).get( 'exportsmanager::instance' ) || new this( window, host, config );
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
/**
|
|
19
|
-
* @constructor
|
|
20
|
-
*/
|
|
21
|
-
constructor( window, host, config = {}, parent = null, level = 0 ) {
|
|
22
|
-
_( host ).get( `exportsmanager::instance` )?.dispose();
|
|
23
|
-
_( host ).set( `exportsmanager::instance`, this );
|
|
24
|
-
this.host = host;
|
|
25
|
-
this.window = window;
|
|
26
|
-
this.config = config;
|
|
27
|
-
this.parent = parent;
|
|
28
|
-
this.level = level;
|
|
29
|
-
this.modules = getModulesObject( this.host );
|
|
30
|
-
this.exportId = ( this.host.getAttribute( this.config.template?.attr.exportid ) || '' ).trim();
|
|
31
|
-
this.validateExportId( this.exportId );
|
|
32
|
-
const realdom = this.window.webqit.realdom;
|
|
33
|
-
// ----------
|
|
34
|
-
this.realtimeA = realdom.realtime( this.host.content ).children( record => {
|
|
35
|
-
this.export( record.entrants, true );
|
|
36
|
-
this.export( record.exits, false );
|
|
37
|
-
}, { live: true, timing: 'sync' } );
|
|
38
|
-
// ----------
|
|
39
|
-
this.realtimeB = realdom.realtime( this.host ).attr( [ 'src', 'loading' ], ( ...args ) => this.evaluateLoading( ...args ), {
|
|
40
|
-
live: true,
|
|
41
|
-
atomic: true,
|
|
42
|
-
timing: 'sync',
|
|
43
|
-
lifecycleSignals: true
|
|
44
|
-
} );
|
|
45
|
-
// ----------
|
|
46
|
-
this.realtimeC = this.evalInheritance();
|
|
47
|
-
// ----------
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Validates export ID.
|
|
52
|
-
*
|
|
53
|
-
* @param String exportId
|
|
54
|
-
*
|
|
55
|
-
* @returns Void
|
|
56
|
-
*/
|
|
57
|
-
validateExportId( exportId ) {
|
|
58
|
-
if ( [ '@', '
|
|
59
|
-
throw new Error( `The export ID "${ exportId }" contains an invalid character.` );
|
|
60
|
-
}
|
|
61
|
-
}
|
|
62
|
-
|
|
63
|
-
/**
|
|
64
|
-
* Maps module contents as exports.
|
|
65
|
-
*
|
|
66
|
-
* @param Array entries
|
|
67
|
-
* @param Bool isConnected
|
|
68
|
-
*
|
|
69
|
-
* @returns Void
|
|
70
|
-
*/
|
|
71
|
-
export( entries, isConnected ) {
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
const isPackage = entry.matches( this.config.templateSelector );
|
|
77
|
-
if (
|
|
78
|
-
this.
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
* Disposes the instance and its processes.
|
|
187
|
-
*
|
|
188
|
-
* @returns Void
|
|
189
|
-
*/
|
|
190
|
-
dispose() {
|
|
191
|
-
this.realtimeA.disconnect();
|
|
192
|
-
this.realtimeB.disconnect();
|
|
193
|
-
this.realtimeC.forEach( r => r.abort() );
|
|
194
|
-
Object.entries( this.modules ).forEach( ( [ key, entry ] ) => {
|
|
195
|
-
if ( key.startsWith( '#' ) ) return;
|
|
196
|
-
HTMLExportsManager.instance( this.window, entry ).dispose();
|
|
197
|
-
} );
|
|
198
|
-
}
|
|
199
|
-
}
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import { getModulesObject } from './index.js';
|
|
7
|
+
import { _ } from '../util.js';
|
|
8
|
+
|
|
9
|
+
export default class _HTMLExportsManager {
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @instance
|
|
13
|
+
*/
|
|
14
|
+
static instance( window, host, config ) {
|
|
15
|
+
return _( host ).get( 'exportsmanager::instance' ) || new this( window, host, config );
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* @constructor
|
|
20
|
+
*/
|
|
21
|
+
constructor( window, host, config = {}, parent = null, level = 0 ) {
|
|
22
|
+
_( host ).get( `exportsmanager::instance` )?.dispose();
|
|
23
|
+
_( host ).set( `exportsmanager::instance`, this );
|
|
24
|
+
this.host = host;
|
|
25
|
+
this.window = window;
|
|
26
|
+
this.config = config;
|
|
27
|
+
this.parent = parent;
|
|
28
|
+
this.level = level;
|
|
29
|
+
this.modules = getModulesObject( this.host );
|
|
30
|
+
this.exportId = ( this.host.getAttribute( this.config.template?.attr.exportid ) || '' ).trim();
|
|
31
|
+
this.validateExportId( this.exportId );
|
|
32
|
+
const realdom = this.window.webqit.realdom;
|
|
33
|
+
// ----------
|
|
34
|
+
this.realtimeA = realdom.realtime( this.host.content ).children( record => {
|
|
35
|
+
this.export( record.entrants, true );
|
|
36
|
+
this.export( record.exits, false );
|
|
37
|
+
}, { live: true, timing: 'sync' } );
|
|
38
|
+
// ----------
|
|
39
|
+
this.realtimeB = realdom.realtime( this.host ).attr( [ 'src', 'loading' ], ( ...args ) => this.evaluateLoading( ...args ), {
|
|
40
|
+
live: true,
|
|
41
|
+
atomic: true,
|
|
42
|
+
timing: 'sync',
|
|
43
|
+
lifecycleSignals: true
|
|
44
|
+
} );
|
|
45
|
+
// ----------
|
|
46
|
+
this.realtimeC = this.evalInheritance();
|
|
47
|
+
// ----------
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Validates export ID.
|
|
52
|
+
*
|
|
53
|
+
* @param String exportId
|
|
54
|
+
*
|
|
55
|
+
* @returns Void
|
|
56
|
+
*/
|
|
57
|
+
validateExportId( exportId ) {
|
|
58
|
+
if ( [ '@', '/', '#' ].some( token => exportId.includes( token ) ) ) {
|
|
59
|
+
throw new Error( `The export ID "${ exportId }" contains an invalid character.` );
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
/**
|
|
64
|
+
* Maps module contents as exports.
|
|
65
|
+
*
|
|
66
|
+
* @param Array entries
|
|
67
|
+
* @param Bool isConnected
|
|
68
|
+
*
|
|
69
|
+
* @returns Void
|
|
70
|
+
*/
|
|
71
|
+
export( entries, isConnected ) {
|
|
72
|
+
entries.forEach( entry => {
|
|
73
|
+
if ( entry.nodeType !== 1 ) return;
|
|
74
|
+
const exportId = ( entry.getAttribute( this.config.export.attr.exportid ) || '' ).trim();
|
|
75
|
+
if ( !exportId ) return;
|
|
76
|
+
const isPackage = entry.matches( this.config.templateSelector );
|
|
77
|
+
if ( isConnected ) {
|
|
78
|
+
if ( isPackage ) { new _HTMLExportsManager( this.window, entry, this.config, this.host, this.level + 1 ); }
|
|
79
|
+
Observer.set( this.modules, ( !isPackage && '#' || '' ) + exportId, entry );
|
|
80
|
+
} else {
|
|
81
|
+
if ( isPackage ) { _HTMLExportsManager.instance( this.window, entry ).dispose(); }
|
|
82
|
+
Observer.deleteProperty( this.modules, ( !isPackage && '#' || '' ) + exportId );
|
|
83
|
+
}
|
|
84
|
+
} );
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
/**
|
|
88
|
+
* Evaluates remote content loading.
|
|
89
|
+
*
|
|
90
|
+
* @param AbortSignal signal
|
|
91
|
+
*
|
|
92
|
+
* @returns Void
|
|
93
|
+
*/
|
|
94
|
+
evaluateLoading( [ record1, record2 ], { signal } ) {
|
|
95
|
+
const src = ( record1.value || '' ).trim();
|
|
96
|
+
if ( !src ) return;
|
|
97
|
+
let $loadingPromise, loadingPromise = promise => {
|
|
98
|
+
if ( !promise ) return $loadingPromise; // Get
|
|
99
|
+
$loadingPromise = promise.then( () => interception.remove() ); // Set
|
|
100
|
+
};
|
|
101
|
+
const loading = ( record2.value || '' ).trim();
|
|
102
|
+
const interception = Observer.intercept( this.modules, 'get', async ( descriptor, recieved, next ) => {
|
|
103
|
+
if ( loading === 'lazy' ) { loadingPromise( this.load( src, true ) ); }
|
|
104
|
+
await loadingPromise();
|
|
105
|
+
return next();
|
|
106
|
+
}, { signal } );
|
|
107
|
+
if ( loading !== 'lazy' ) { loadingPromise( this.load( src ) ); }
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Fetches a module's "src".
|
|
112
|
+
*
|
|
113
|
+
* @param String src
|
|
114
|
+
*
|
|
115
|
+
* @return Promise
|
|
116
|
+
*/
|
|
117
|
+
load( src ) {
|
|
118
|
+
if ( this.host.content.children.length ) return Promise.resolve();
|
|
119
|
+
// Ongoing request?
|
|
120
|
+
if ( this.fetchInFlight?.src === src ) return this.fetchInFlight.request;
|
|
121
|
+
this.fetchInFlight?.controller.abort();
|
|
122
|
+
// The promise
|
|
123
|
+
const controller = new AbortController();
|
|
124
|
+
const fire = ( type, detail ) => this.host.dispatchEvent( new this.window.CustomEvent( type, { detail } ) );
|
|
125
|
+
const request = this.window.fetch( src, { signal: controller.signal, element: this.host } ).then( response => {
|
|
126
|
+
return response.ok ? response.text() : Promise.reject( response.statusText );
|
|
127
|
+
}).then( content => {
|
|
128
|
+
this.host.innerHTML = content.trim(); // IMPORTANT: .trim()
|
|
129
|
+
fire( 'load' );
|
|
130
|
+
return this.host;
|
|
131
|
+
} ).catch( e => {
|
|
132
|
+
console.error( `Error fetching the bundle at "${ src }": ${ e.message }` );
|
|
133
|
+
this.fetchInFlight = null;
|
|
134
|
+
fire( 'loaderror' );
|
|
135
|
+
return this.host;
|
|
136
|
+
} );
|
|
137
|
+
this.fetchInFlight = { src, request, controller };
|
|
138
|
+
return request;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/**
|
|
142
|
+
* Evaluates module inheritance.
|
|
143
|
+
*
|
|
144
|
+
* @returns Void|AbortController
|
|
145
|
+
*/
|
|
146
|
+
evalInheritance( ) {
|
|
147
|
+
if ( !this.parent ) return [];
|
|
148
|
+
let extendedId = ( this.host.getAttribute( this.config.template.attr.extends ) || '' ).trim();
|
|
149
|
+
let inheritedIds = ( this.host.getAttribute( this.config.template.attr.inherits ) || '' ).trim();
|
|
150
|
+
const handleInherited = records => {
|
|
151
|
+
records.forEach( record => {
|
|
152
|
+
if ( Observer.get( this.modules, record.key ) !== record.oldValue ) return;
|
|
153
|
+
if ( [ 'get'/*initial get*/, 'set', 'defineProperty' ].includes( record.type ) ) {
|
|
154
|
+
Observer[ record.type.replace( 'get', 'set' ) ]( this.modules, record.key, record.value );
|
|
155
|
+
} else if ( record.type === 'deleteProperty' ) {
|
|
156
|
+
Observer.deleteProperty( this.modules, record.key );
|
|
157
|
+
}
|
|
158
|
+
} );
|
|
159
|
+
};
|
|
160
|
+
const realtimes = [];
|
|
161
|
+
const parentExportsObj = getModulesObject( this.parent );
|
|
162
|
+
if ( extendedId ) {
|
|
163
|
+
realtimes.push( Observer.deep( parentExportsObj, [ extendedId, this.config.template.api.modules, Infinity ], Observer.get, handleInherited, { live: true } ) );
|
|
164
|
+
}
|
|
165
|
+
if ( ( inheritedIds = inheritedIds.split( ' ' ).map( id => id.trim() ).filter( x => x ) ).length ) {
|
|
166
|
+
realtimes.push( Observer.get( parentExportsObj, inheritedIds, handleInherited, { live: true } ) );
|
|
167
|
+
}
|
|
168
|
+
return realtimes;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* Disposes the instance and its processes.
|
|
173
|
+
*
|
|
174
|
+
* @returns Void
|
|
175
|
+
*/
|
|
176
|
+
dispose() {
|
|
177
|
+
this.realtimeA.disconnect();
|
|
178
|
+
this.realtimeB.disconnect();
|
|
179
|
+
this.realtimeC.forEach( r => r.abort() );
|
|
180
|
+
Object.entries( this.modules ).forEach( ( [ key, entry ] ) => {
|
|
181
|
+
if ( key.startsWith( '#' ) ) return;
|
|
182
|
+
_HTMLExportsManager.instance( this.window, entry ).dispose();
|
|
183
|
+
} );
|
|
184
|
+
}
|
|
185
|
+
}
|