@webqit/oohtml 1.10.3 → 2.0.0
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 +399 -396
- package/dist/context-api.js +2 -0
- package/dist/context-api.js.map +7 -0
- package/dist/html-imports.js +1 -2
- package/dist/html-imports.js.map +3 -3
- package/dist/html-modules.js +1 -2
- package/dist/html-modules.js.map +3 -3
- package/dist/main.js +26 -14
- package/dist/main.js.map +3 -3
- package/dist/namespaced-html.js +1 -2
- package/dist/namespaced-html.js.map +3 -3
- package/dist/scoped-js.js +27 -0
- package/dist/scoped-js.js.map +7 -0
- package/dist/state-api.js +1 -2
- package/dist/state-api.js.map +3 -3
- package/package.json +76 -76
- package/src/context-api/HTMLContext.js +158 -0
- package/src/context-api/HTMLContextManager.js +77 -0
- package/src/context-api/_ContextRequestEvent.js +26 -0
- package/src/context-api/index.js +53 -0
- package/src/{namespaced-html/browser-entry.js → context-api/targets.browser.js} +9 -9
- package/src/html-imports/_HTMLImportElement.js +216 -0
- package/src/html-imports/index.js +92 -557
- package/src/{browser-entry.js → html-imports/targets.browser.js} +10 -10
- package/src/html-modules/HTMLExportsManager.js +191 -0
- package/src/html-modules/_HTMLImportsContext.js +114 -0
- package/src/html-modules/index.js +133 -384
- package/src/{html-imports/browser-entry.js → html-modules/targets.browser.js} +9 -9
- package/src/index.js +34 -39
- package/src/namespaced-html/index.js +130 -144
- package/src/namespaced-html/targets.browser.js +10 -0
- package/src/scoped-js/index.js +382 -0
- package/src/scoped-js/targets.browser.js +10 -0
- package/src/state-api/index.js +55 -142
- package/src/state-api/targets.browser.js +10 -0
- package/src/{html-modules/browser-entry.js → targets.browser.js} +10 -10
- package/src/util.js +20 -180
- package/test/imports.test.js +194 -0
- package/test/index.js +119 -0
- package/test/modules.test.js +198 -0
- package/test/namespaced-html.test.js +50 -0
- package/test/scoped-js.js +57 -0
- package/test/state-api.test.js +34 -0
- package/test/test.html +69 -0
- package/dist/subscript.js +0 -15
- package/dist/subscript.js.map +0 -7
- package/src/state-api/browser-entry.js +0 -10
- package/src/subscript/Element.js +0 -103
- package/src/subscript/browser-entry.js +0 -10
- package/src/subscript/index.js +0 -70
- package/test/all.test.js +0 -0
|
@@ -1,144 +1,130 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import Observer from '@webqit/observer';
|
|
6
|
-
import
|
|
7
|
-
import {
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
if (presence) {
|
|
132
|
-
// ONLY if I am not currently the one in place
|
|
133
|
-
if (namespaceObject[scopedId] !== el) {
|
|
134
|
-
Observer.set(namespaceObject, scopedId, el);
|
|
135
|
-
}
|
|
136
|
-
} else {
|
|
137
|
-
// ONLY if I am still the one in place
|
|
138
|
-
if (namespaceObject[scopedId] === el) {
|
|
139
|
-
Observer.deleteProperty(namespaceObject, scopedId);
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
});
|
|
143
|
-
});
|
|
144
|
-
};
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import Observer from '@webqit/observer';
|
|
6
|
+
import wqDom from '@webqit/dom';
|
|
7
|
+
import { _ } from '../util.js';
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @init
|
|
11
|
+
*
|
|
12
|
+
* @param Object $params
|
|
13
|
+
*/
|
|
14
|
+
export default function init( $params = {} ) {
|
|
15
|
+
const window = this, dom = wqDom.call( window );
|
|
16
|
+
// -------
|
|
17
|
+
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
18
|
+
attr: { namespace: 'namespace', id: 'data-id', },
|
|
19
|
+
api: { namespace: 'namespace', },
|
|
20
|
+
staticsensitivity: true,
|
|
21
|
+
eagermode: true,
|
|
22
|
+
} );
|
|
23
|
+
params.idSelector = `[${ window.CSS.escape( params.attr.id ) }]`;
|
|
24
|
+
params.namespaceSelector = `[${ window.CSS.escape( params.attr.namespace ) }]`;
|
|
25
|
+
// -------
|
|
26
|
+
exposeNamespaceObjects.call( this, params );
|
|
27
|
+
realtime.call( this, params );
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Exposes Namespaced HTML with native APIs.
|
|
32
|
+
*
|
|
33
|
+
* @param Object params
|
|
34
|
+
*
|
|
35
|
+
* @return Void
|
|
36
|
+
*/
|
|
37
|
+
function exposeNamespaceObjects( params ) {
|
|
38
|
+
const window = this;
|
|
39
|
+
// Assertions
|
|
40
|
+
if ( params.api.namespace in window.document ) { throw new Error( `document already has a "${ params.api.namespace }" property!` ); }
|
|
41
|
+
if ( params.api.namespace in window.Element.prototype ) { throw new Error( `The "Element" class already has a "${ params.api.namespace }" property!` ); }
|
|
42
|
+
// Definitions
|
|
43
|
+
Object.defineProperty( window.document, params.api.namespace, { get: function() {
|
|
44
|
+
return Observer.proxy( getNamespaceObject.call( window, window.document, params ) );
|
|
45
|
+
} });
|
|
46
|
+
Object.defineProperty( window.Element.prototype, params.api.namespace, { get: function() {
|
|
47
|
+
return Observer.proxy( getNamespaceObject.call( window, this, params ) );
|
|
48
|
+
} } );
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Returns the "namespace" object associated with the given node.
|
|
53
|
+
*
|
|
54
|
+
* @param Element node
|
|
55
|
+
*
|
|
56
|
+
* @return Object
|
|
57
|
+
*/
|
|
58
|
+
function getNamespaceObject( node, params ) {
|
|
59
|
+
const window = this;
|
|
60
|
+
if ( !_( node ).has( 'namespace' ) ) {
|
|
61
|
+
const namespaceObj = Object.create( null );
|
|
62
|
+
Observer.intercept( namespaceObj, 'get', ( event, receiver, next ) => {
|
|
63
|
+
if ( Observer.has( namespaceObj, event.key ) || !params.eagermode ) return next();
|
|
64
|
+
const selector = `[${ window.CSS.escape( params.attr.id ) }="${ event.key }"]`;
|
|
65
|
+
const resultNode = Array.from( node.querySelectorAll( selector ) ).filter( idNode => {
|
|
66
|
+
const ownerRoot = idNode.parentNode.closest( params.namespaceSelector );
|
|
67
|
+
if ( node === window.document ) {
|
|
68
|
+
// Only IDs without a scope actually belong to the document scope
|
|
69
|
+
return !ownerRoot;
|
|
70
|
+
}
|
|
71
|
+
return ownerRoot === node;
|
|
72
|
+
} )[ 0 ];
|
|
73
|
+
if ( resultNode ) Observer.set( namespaceObj, event.key, resultNode );
|
|
74
|
+
return next();
|
|
75
|
+
} );
|
|
76
|
+
_( node ).set( 'namespace', namespaceObj );
|
|
77
|
+
}
|
|
78
|
+
return _( node ).get( 'namespace' );
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
/**
|
|
82
|
+
* Performs realtime capture of elements and builds their relationships.
|
|
83
|
+
*
|
|
84
|
+
* @param Object params
|
|
85
|
+
*
|
|
86
|
+
* @return Void
|
|
87
|
+
*/
|
|
88
|
+
function realtime( params ) {
|
|
89
|
+
const window = this, { dom } = window.wq;
|
|
90
|
+
// ----------------
|
|
91
|
+
const handle = ( target, entry, incoming ) => {
|
|
92
|
+
const identifier = entry.getAttribute( params.attr.id );
|
|
93
|
+
const ownerRoot = target.closest( params.namespaceSelector ) || _( entry ).get( 'ownerNamespace' ) || window.document;
|
|
94
|
+
const namespaceObj = getNamespaceObject.call( window, ownerRoot, params );
|
|
95
|
+
if ( incoming ) {
|
|
96
|
+
if ( Observer.get( namespaceObj, identifier ) !== entry ) {
|
|
97
|
+
_( entry ).set( 'ownerNamespace', ownerRoot );
|
|
98
|
+
Observer.set( namespaceObj, identifier, entry );
|
|
99
|
+
}
|
|
100
|
+
} else if ( Observer.get( namespaceObj, identifier ) === entry ) {
|
|
101
|
+
_( entry ).delete( 'ownerNamespace' );
|
|
102
|
+
Observer.deleteProperty( namespaceObj, identifier );
|
|
103
|
+
}
|
|
104
|
+
};
|
|
105
|
+
dom.realtime( window.document ).observe( params.idSelector, record => {
|
|
106
|
+
record.entrants.forEach( entry => handle( record.target, entry, true ) );
|
|
107
|
+
record.exits.forEach( entry => handle( record.target, entry, false ) );
|
|
108
|
+
}, { subtree: true, timing: 'sync', staticSensitivity: params.staticsensitivity } );
|
|
109
|
+
// ----------------
|
|
110
|
+
if ( params.staticsensitivity ) {
|
|
111
|
+
dom.realtime( window.document, 'attr' ).observe( params.namespaceSelector, record => {
|
|
112
|
+
const ownerRoot = record.target.parentNode?.closest( params.namespaceSelector ) || _( record.target ).get( 'ownerNamespace' ) || window.document;
|
|
113
|
+
const ownerRootNamespaceObj = getNamespaceObject.call( window, ownerRoot, params );
|
|
114
|
+
const namespaceObj = getNamespaceObject.call( window, record.target, params );
|
|
115
|
+
if ( record.target.matches( params.namespaceSelector ) ) {
|
|
116
|
+
for ( const [ key, entry ] of Object.entries( ownerRootNamespaceObj ) ) {
|
|
117
|
+
if ( !record.target.contains( entry.parentNode ) ) continue;
|
|
118
|
+
Observer.deleteProperty( ownerRootNamespaceObj, key );
|
|
119
|
+
Observer.set( namespaceObj, key, entry );
|
|
120
|
+
}
|
|
121
|
+
} else {
|
|
122
|
+
for ( const [ key, entry ] of Object.entries( namespaceObj ) ) {
|
|
123
|
+
Observer.deleteProperty( namespaceObj, key );
|
|
124
|
+
Observer.set( ownerRootNamespaceObj, key, entry );
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}, { subtree: true, timing: 'sync' } );
|
|
128
|
+
}
|
|
129
|
+
// ----------------
|
|
130
|
+
}
|