@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,114 +1,122 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import {
|
|
7
|
-
import { getModulesObject } from './index.js';
|
|
8
|
-
import { _ } from '../util.js';
|
|
9
|
-
|
|
10
|
-
export default class
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @
|
|
14
|
-
*/
|
|
15
|
-
static
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
//
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
//
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
event.request.
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import { HTMLContext, HTMLContextProvider } from '../context-api/index.js';
|
|
7
|
+
import { getModulesObject } from './index.js';
|
|
8
|
+
import { _ } from '../util.js';
|
|
9
|
+
|
|
10
|
+
export default class _HTMLImportsProvider extends HTMLContextProvider {
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* @createId
|
|
14
|
+
*/
|
|
15
|
+
static createId( host, fields = {} ) {
|
|
16
|
+
if ( !( 'type' in fields ) ) fields = { type: 'htmlimports', ...fields };
|
|
17
|
+
return super.createId( host, fields );
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
/**
|
|
21
|
+
* @createRequest
|
|
22
|
+
*/
|
|
23
|
+
static createRequest( fields = {} ) {
|
|
24
|
+
const request = { type: 'htmlimports', ...fields };
|
|
25
|
+
if ( !request.contextName && request.detail?.startsWith( '/' ) ) { request.contextName = 'root'; }
|
|
26
|
+
else if ( request.detail?.startsWith( '@' ) ) {
|
|
27
|
+
const [ contextName, ...detail ] = request.detail.slice( 1 ).split( /(?<=\w)(?=\/|#)/ ).map( s => s.trim() );
|
|
28
|
+
request.contextName = contextName;
|
|
29
|
+
request.detail = detail.join( '' );
|
|
30
|
+
}
|
|
31
|
+
return request;
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* @localModules
|
|
36
|
+
*/
|
|
37
|
+
get localModules() {
|
|
38
|
+
return getModulesObject( this.host );
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
/**
|
|
42
|
+
* @handle()
|
|
43
|
+
*/
|
|
44
|
+
handle( event ) {
|
|
45
|
+
// Any existing event.request.controller? Abort!
|
|
46
|
+
event.request.controller?.abort();
|
|
47
|
+
|
|
48
|
+
// Parse and translate detail
|
|
49
|
+
if ( ( event.request.detail || '' ).trim() === '/' ) return event.respondWith( this.localModules );
|
|
50
|
+
const $config = this.constructor.config;
|
|
51
|
+
let path = ( event.request.detail || '' ).split( /\/|(?<=\w)(?=#)/g ).map( x => x.trim() ).filter( x => x );
|
|
52
|
+
if ( path.length ) { path = path.join( `/${ $config.template.api.modules }/` )?.split( '/' ) || []; }
|
|
53
|
+
// No detail?
|
|
54
|
+
if ( !path.length ) return event.respondWith();
|
|
55
|
+
|
|
56
|
+
// We'll now fulfill request
|
|
57
|
+
const options = { live: event.request.live, descripted: true, midwayResults: true };
|
|
58
|
+
// Find a way to resolve request against two sources
|
|
59
|
+
event.request.controller = Observer.deep( this.localModules, path, Observer.get, ( result, { signal } = {} ) => {
|
|
60
|
+
if ( !result.value && this.host.isConnected === false ) return; // Subtree is being disposed
|
|
61
|
+
if ( result.value || !this.contextModules ) return event.respondWith( result.value );
|
|
62
|
+
// This superModules binding is automatically aborted by the injected control.signal; see below
|
|
63
|
+
return Observer.deep( this.contextModules, path, Observer.get, result => {
|
|
64
|
+
return event.respondWith( result.value );
|
|
65
|
+
}, { signal, ...options } );
|
|
66
|
+
}, options );
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* @startRealtime()
|
|
71
|
+
*/
|
|
72
|
+
realtimeSources( host ) {
|
|
73
|
+
this.host = host;
|
|
74
|
+
// ----------------
|
|
75
|
+
const update = () => {
|
|
76
|
+
for ( const subscriptionEvent of this.subscriptions ) {
|
|
77
|
+
this.handle( subscriptionEvent );
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
// ----------------
|
|
81
|
+
const $config = this.constructor.config;
|
|
82
|
+
if ( !this.host.matches || !$config.context.attr.importscontext ) return;
|
|
83
|
+
// Any existing this.refdSourceController? Abort!
|
|
84
|
+
this.refdSourceController?.disconnect();
|
|
85
|
+
const realdom = this.host.ownerDocument.defaultView.webqit.realdom;
|
|
86
|
+
this.refdSourceController = realdom.realtime( this.host ).attr( $config.context.attr.importscontext, ( record, { signal } ) => {
|
|
87
|
+
// No importscontext attr set. But we're still watching
|
|
88
|
+
if ( !record.value ) {
|
|
89
|
+
this.contextModules = undefined;
|
|
90
|
+
return update();
|
|
91
|
+
}
|
|
92
|
+
// This superModules contextrequest is automatically aborted by the injected signal below
|
|
93
|
+
const request = this.constructor.createRequest( { detail: record.value.trim(), live: true, signal, superContextOnly: true } );
|
|
94
|
+
HTMLContext.instance( this.host ).request( request, response => {
|
|
95
|
+
this.contextModules = !( response && Object.getPrototypeOf( response ) ) ? response : getModulesObject( response );
|
|
96
|
+
update();
|
|
97
|
+
} );
|
|
98
|
+
}, { live: true, timing: 'sync', lifecycleSignals: true } );
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* @initialize()
|
|
103
|
+
*/
|
|
104
|
+
initialize( host ) {
|
|
105
|
+
// If host has importscontext attr, compute that
|
|
106
|
+
this.realtimeSources( host );
|
|
107
|
+
// Now, listen for contextrequest and contextclaim events
|
|
108
|
+
// And process own claim
|
|
109
|
+
return super.initialize( host );
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/**
|
|
113
|
+
* @dispose()
|
|
114
|
+
*/
|
|
115
|
+
dispose( host ) {
|
|
116
|
+
// Stop listening for sources
|
|
117
|
+
this.refdSourceController?.disconnect();
|
|
118
|
+
// Now, stop listening for contextrequest and contextclaim events
|
|
119
|
+
// And relinquish own subscribers to owner context
|
|
120
|
+
return super.dispose( host );
|
|
121
|
+
}
|
|
122
|
+
}
|
|
@@ -1,88 +1,197 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import
|
|
6
|
-
import {
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
*
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
}
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
realdom.
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
*
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import { HTMLContext } from '../context-api/index.js';
|
|
7
|
+
import _HTMLExportsManager from './_HTMLExportsManager.js';
|
|
8
|
+
import _HTMLImportElement from './_HTMLImportElement.js';
|
|
9
|
+
import _HTMLImportsProvider from './_HTMLImportsProvider.js';
|
|
10
|
+
import { _, _init } from '../util.js';
|
|
11
|
+
|
|
12
|
+
/**
|
|
13
|
+
* Initializes HTML Modules.
|
|
14
|
+
*
|
|
15
|
+
* @param $config Object
|
|
16
|
+
*
|
|
17
|
+
* @return Void
|
|
18
|
+
*/
|
|
19
|
+
export default function init( $config = {} ) {
|
|
20
|
+
const { config, realdom, window } = _init.call( this, 'html-imports', $config, {
|
|
21
|
+
export: { attr: { exportid: 'as' }, },
|
|
22
|
+
template: { attr: { exportid: 'as', extends: 'extends', inherits: 'inherits' }, api: { modules: 'modules', exportid: 'exportid' }, },
|
|
23
|
+
context: { attr: { importscontext: 'importscontext', contextname: 'contextname' }, api: { modules: 'modules' }, },
|
|
24
|
+
import: { tagName: 'import', attr: { moduleref: 'ref' }, },
|
|
25
|
+
staticsensitivity: true,
|
|
26
|
+
isomorphic: true,
|
|
27
|
+
} );
|
|
28
|
+
config.templateSelector = `template[${ window.CSS.escape( config.template.attr.exportid ) }]`;
|
|
29
|
+
config.ownerContextSelector = [ config.context.attr.contextname, config.context.attr.importscontext ].map( a => `[${ window.CSS.escape( a ) }]` ).join( ',' );
|
|
30
|
+
config.slottedElementsSelector = `[${ window.CSS.escape( config.export.attr.exportid ) }]`;
|
|
31
|
+
window.webqit.HTMLImportElement = _HTMLImportElement.call( window, config );
|
|
32
|
+
window.webqit.HTMLImportsProvider = class extends _HTMLImportsProvider {
|
|
33
|
+
static get config() { return config; }
|
|
34
|
+
};
|
|
35
|
+
window.webqit.Observer = Observer;
|
|
36
|
+
exposeModulesObjects.call( window, config );
|
|
37
|
+
realdom.ready( () => hydration.call( window, config ) );
|
|
38
|
+
realtime.call( window, config );
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export { Observer }
|
|
42
|
+
|
|
43
|
+
/**
|
|
44
|
+
* Returns the "exports" object associated with the given node.
|
|
45
|
+
*
|
|
46
|
+
* @param Element node
|
|
47
|
+
* @param Bool autoCreate
|
|
48
|
+
*
|
|
49
|
+
* @return Object
|
|
50
|
+
*/
|
|
51
|
+
export function getModulesObject( node, autoCreate = true ) {
|
|
52
|
+
if ( !_( node ).has( 'modules' ) && autoCreate ) {
|
|
53
|
+
const modulesObj = Object.create( null );
|
|
54
|
+
_( node ).set( 'modules', modulesObj );
|
|
55
|
+
}
|
|
56
|
+
return _( node ).get( 'modules' );
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
/**
|
|
60
|
+
* Exposes HTML Modules with native APIs.
|
|
61
|
+
*
|
|
62
|
+
* @param Object config
|
|
63
|
+
*
|
|
64
|
+
* @return Void
|
|
65
|
+
*/
|
|
66
|
+
function exposeModulesObjects( config ) {
|
|
67
|
+
const window = this;
|
|
68
|
+
// Assertions
|
|
69
|
+
if ( config.template.api.modules in window.HTMLTemplateElement.prototype ) { throw new Error( `The "HTMLTemplateElement" class already has a "${ config.template.api.modules }" property!` ); }
|
|
70
|
+
if ( config.template.api.exportid in window.HTMLTemplateElement.prototype ) { throw new Error( `The "HTMLTemplateElement" class already has a "${ config.template.api.exportid }" property!` ); }
|
|
71
|
+
if ( config.context.api.import in window.document ) { throw new Error( `document already has a "${ config.context.api.import }" property!` ); }
|
|
72
|
+
if ( config.context.api.import in window.HTMLElement.prototype ) { throw new Error( `The "HTMLElement" class already has a "${ config.context.api.import }" property!` ); }
|
|
73
|
+
// Definitions
|
|
74
|
+
Object.defineProperty( window.HTMLTemplateElement.prototype, config.template.api.modules, { get: function() {
|
|
75
|
+
return getModulesObject( this );
|
|
76
|
+
} } );
|
|
77
|
+
Object.defineProperty( window.HTMLTemplateElement.prototype, config.template.api.exportid, { get: function() {
|
|
78
|
+
return this.getAttribute( config.template.attr.exportid );
|
|
79
|
+
} } );
|
|
80
|
+
Object.defineProperty( window.document, config.context.api.import, { value: function( ref, callback, options = {} ) {
|
|
81
|
+
return importRequest( window.document, ref, callback, options );
|
|
82
|
+
} } );
|
|
83
|
+
Object.defineProperty( window.HTMLElement.prototype, config.context.api.import, { value: function( ref, callback, options = {} ) {
|
|
84
|
+
return importRequest( this, ref, callback, options );
|
|
85
|
+
} } );
|
|
86
|
+
function importRequest( context, ref, callback, options ) {
|
|
87
|
+
const request = _HTMLImportsProvider.createRequest( { detail: ref, ...options } );
|
|
88
|
+
return HTMLContext.instance( context ).request( request, callback );
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Performs realtime capture of elements and their attributes
|
|
94
|
+
* and their module query results; then resolves the respective import elements.
|
|
95
|
+
*
|
|
96
|
+
* @param Object config
|
|
97
|
+
*
|
|
98
|
+
* @return Void
|
|
99
|
+
*/
|
|
100
|
+
function realtime( config ) {
|
|
101
|
+
const window = this, { realdom, HTMLImportElement, HTMLImportsProvider } = window.webqit;
|
|
102
|
+
// ------------
|
|
103
|
+
// MODULES
|
|
104
|
+
// ------------
|
|
105
|
+
const attachImportsContext = host => {
|
|
106
|
+
const contextId = HTMLImportsProvider.createId( host );
|
|
107
|
+
HTMLImportsProvider.attachTo( host, contextId );
|
|
108
|
+
};
|
|
109
|
+
const detachImportsContext = ( host, force ) => {
|
|
110
|
+
const contextId = HTMLImportsProvider.createId( host );
|
|
111
|
+
HTMLImportsProvider.detachFrom( host, contextId, cx => {
|
|
112
|
+
return force || host.matches && !host.matches( config.ownerContextSelector ) && !Object.keys( cx.localModules ).length;
|
|
113
|
+
} );
|
|
114
|
+
};
|
|
115
|
+
// ------------
|
|
116
|
+
realdom.realtime( window.document ).subtree/*instead of observe(); reason: jsdom timing*/( [ config.templateSelector, config.ownerContextSelector ], record => {
|
|
117
|
+
record.entrants.forEach( entry => {
|
|
118
|
+
if ( entry.matches( config.templateSelector ) ) {
|
|
119
|
+
Object.defineProperty( entry, 'scoped', { value: entry.hasAttribute( 'scoped' ) } );
|
|
120
|
+
const moduleExport = new _HTMLExportsManager( window, entry, config );
|
|
121
|
+
moduleExport.ownerContext = entry.scoped ? record.target : window.document;
|
|
122
|
+
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
123
|
+
if ( moduleExport.exportId ) { Observer.set( ownerContextModulesObj, moduleExport.exportId, entry ); }
|
|
124
|
+
// The ownerContext's modulesObj - ownerContextModulesObj - has to be populated
|
|
125
|
+
// Before attaching a context instance to it, to give the just created context something to use for
|
|
126
|
+
// fullfiling reclaimed requests.
|
|
127
|
+
attachImportsContext( moduleExport.ownerContext );
|
|
128
|
+
} else {
|
|
129
|
+
attachImportsContext( entry );
|
|
130
|
+
}
|
|
131
|
+
} );
|
|
132
|
+
record.exits.forEach( entry => {
|
|
133
|
+
if ( entry.matches( config.templateSelector ) ) {
|
|
134
|
+
const moduleExport = _HTMLExportsManager.instance( window, entry, config );
|
|
135
|
+
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
136
|
+
if ( moduleExport.exportId ) { Observer.deleteProperty( ownerContextModulesObj, moduleExport.exportId ); }
|
|
137
|
+
detachImportsContext( moduleExport.ownerContext );
|
|
138
|
+
} else {
|
|
139
|
+
detachImportsContext( entry, true );
|
|
140
|
+
}
|
|
141
|
+
} );
|
|
142
|
+
}, { live: true, timing: 'sync', staticSensitivity: config.staticsensitivity } );
|
|
143
|
+
// ------------
|
|
144
|
+
// IMPORTS
|
|
145
|
+
// ------------
|
|
146
|
+
realdom.realtime( window.document ).subtree/*instead of observe(); reason: jsdom timing*/( config.import.tagName, record => {
|
|
147
|
+
record.entrants.forEach( node => handleRealtime( node, true, record ) );
|
|
148
|
+
record.exits.forEach( node => handleRealtime( node, false, record ) );
|
|
149
|
+
}, { live: true, timing: 'sync' } );
|
|
150
|
+
function handleRealtime( entry, connectedState, record ) {
|
|
151
|
+
const elInstance = HTMLImportElement.instance( entry );
|
|
152
|
+
if ( connectedState ) { elInstance[ '#' ].connectedCallback(); }
|
|
153
|
+
else { elInstance[ '#' ].disconnectedCallback(); }
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Performs hydration for server-slotted elements.
|
|
159
|
+
*
|
|
160
|
+
* @param Object config
|
|
161
|
+
*
|
|
162
|
+
* @return Void
|
|
163
|
+
*/
|
|
164
|
+
function hydration( config ) {
|
|
165
|
+
const window = this, { HTMLImportElement } = window.webqit;
|
|
166
|
+
function scan( context ) {
|
|
167
|
+
const slottedElements = new Set;
|
|
168
|
+
context.childNodes.forEach( node => {
|
|
169
|
+
if ( node.nodeType === 1/** ELEMENT_NODE */ ) {
|
|
170
|
+
if ( !node.matches( config.slottedElementsSelector ) ) return;
|
|
171
|
+
if ( _( node ).get( 'slot@imports' ) ) return;
|
|
172
|
+
slottedElements.add( node );
|
|
173
|
+
} else if ( node.nodeType === 8/** COMMENT_NODE */ ) {
|
|
174
|
+
const nodeValue = node.nodeValue.trim();
|
|
175
|
+
if ( !nodeValue.startsWith( '<' + config.import.tagName ) ) return;
|
|
176
|
+
if ( !nodeValue.endsWith( '</' + config.import.tagName + '>' ) ) return;
|
|
177
|
+
const reviver = window.document.createElement( 'div' );
|
|
178
|
+
reviver.innerHTML = nodeValue;
|
|
179
|
+
const importEl = reviver.firstChild;
|
|
180
|
+
if ( !importEl.matches( config.import.tagName ) ) return;
|
|
181
|
+
HTMLImportElement.instance( importEl )[ '#' ].hydrate(
|
|
182
|
+
node/* the comment node */, slottedElements
|
|
183
|
+
);
|
|
184
|
+
slottedElements.clear();
|
|
185
|
+
}
|
|
186
|
+
} );
|
|
187
|
+
}
|
|
188
|
+
Array.from( window.document.querySelectorAll( config.slottedElementsSelector ) ).forEach( slottedElement => {
|
|
189
|
+
// hydration() might be running AFTER certain <slots> have resolved
|
|
190
|
+
// and slottedElement might be a just-resolved node
|
|
191
|
+
if ( _( slottedElement ).get( 'slot@imports' ) ) return;
|
|
192
|
+
if ( _( slottedElement.parentNode ).get( 'alreadyscanned@imports' ) ) return;
|
|
193
|
+
scan( slottedElement.parentNode );
|
|
194
|
+
// Scanning is once for every parent
|
|
195
|
+
_( slottedElement.parentNode ).set( 'alreadyscanned@imports', true );
|
|
196
|
+
} );
|
|
197
|
+
}
|
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import init from './index.js';
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* @init
|
|
9
|
-
*/
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import init from './index.js';
|
|
6
|
+
|
|
7
|
+
/**
|
|
8
|
+
* @init
|
|
9
|
+
*/
|
|
10
10
|
init.call( window );
|
package/src/index.js
CHANGED
|
@@ -1,33 +1,31 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import BindingsAPI from './bindings-api/index.js';
|
|
7
|
-
import ContextAPI from './context-api/index.js';
|
|
8
|
-
import
|
|
9
|
-
import
|
|
10
|
-
import
|
|
11
|
-
import
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
HTMLImports.call( this, ( configs.HTML_IMPORTS || {} ) );
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
* @exports
|
|
32
|
-
*/
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import BindingsAPI from './bindings-api/index.js';
|
|
7
|
+
import ContextAPI from './context-api/index.js';
|
|
8
|
+
import ScopedCSS from './scoped-css/index.js';
|
|
9
|
+
import ScopedJS from './scoped-js/index.js';
|
|
10
|
+
import NamespaceAPI from './namespace-api/index.js';
|
|
11
|
+
import HTMLImports from './html-imports/index.js';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @init
|
|
15
|
+
*/
|
|
16
|
+
export default function init( configs = {} ) {
|
|
17
|
+
if ( !this.webqit ) { this.webqit = {}; }
|
|
18
|
+
// --------------
|
|
19
|
+
BindingsAPI.call( this, ( configs.BINDINGS_API || {} ) );
|
|
20
|
+
ContextAPI.call( this, ( configs.CONTEXT_API || {} ) );
|
|
21
|
+
ScopedJS.call( this, ( configs.SCOPED_JS || {} ) );
|
|
22
|
+
ScopedCSS.call( this, ( configs.SCOPED_CSS || {} ) );
|
|
23
|
+
NamespaceAPI.call( this, ( configs.NAMESPACE_API || {} ) );
|
|
24
|
+
HTMLImports.call( this, ( configs.HTML_IMPORTS || {} ) );
|
|
25
|
+
// --------------
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
/**
|
|
29
|
+
* @exports
|
|
30
|
+
*/
|
|
33
31
|
export { Observer }
|