@webqit/oohtml 4.3.1 → 4.3.3
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/bindings-api.js +1 -1
- package/dist/bindings-api.js.map +2 -2
- package/dist/context-api.js +1 -1
- package/dist/context-api.js.map +2 -2
- package/dist/data-binding.js +7 -7
- package/dist/data-binding.js.map +2 -2
- package/dist/html-imports.js +1 -1
- package/dist/html-imports.js.map +2 -2
- package/dist/main.js +8 -8
- package/dist/main.js.map +2 -2
- package/dist/main.lite.js +20 -20
- package/dist/main.lite.js.map +2 -2
- package/dist/namespaced-html.js +1 -1
- package/dist/namespaced-html.js.map +2 -2
- package/dist/scoped-css.js +2 -2
- package/dist/scoped-css.js.map +2 -2
- package/dist/scoped-js.js +1 -1
- package/dist/scoped-js.js.map +2 -2
- package/package.json +2 -2
- package/src/data-binding/index.js +19 -11
- package/src/html-imports/_HTMLImportElement.js +5 -6
- package/src/html-imports/index.js +4 -3
- package/src/init.js +2 -2
- package/src/namespaced-html/index.js +6 -6
- package/src/scoped-css/index.js +1 -1
- package/src/scoped-js/index.js +11 -11
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"wicg-proposal"
|
|
15
15
|
],
|
|
16
16
|
"homepage": "https://webqit.io/tooling/oohtml",
|
|
17
|
-
"version": "4.3.
|
|
17
|
+
"version": "4.3.3",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
@@ -40,7 +40,7 @@
|
|
|
40
40
|
},
|
|
41
41
|
"dependencies": {
|
|
42
42
|
"@webqit/quantum-js": "^4.5.11",
|
|
43
|
-
"@webqit/realdom": "^2.1.
|
|
43
|
+
"@webqit/realdom": "^2.1.32",
|
|
44
44
|
"@webqit/util": "^0.8.11"
|
|
45
45
|
},
|
|
46
46
|
"devDependencies": {
|
|
@@ -38,14 +38,20 @@ export default function init( $config = {} ) {
|
|
|
38
38
|
function realtime( config ) {
|
|
39
39
|
const window = this, { webqit: { realdom } } = window;
|
|
40
40
|
// ----------------
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
41
|
+
/**
|
|
42
|
+
* For an element, render should happen first
|
|
43
|
+
<div render="">
|
|
44
|
+
<?{ content }?>
|
|
45
|
+
</div>
|
|
46
|
+
*/
|
|
45
47
|
realdom.realtime( window.document ).query( config.attrSelector, record => {
|
|
46
48
|
cleanup.call( this, ...record.exits );
|
|
47
49
|
mountInlineBindings.call( window, config, ...record.entrants );
|
|
48
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync', eventDetails: true, staticSensitivity: true } );
|
|
50
|
+
}, { id: 'data-binding:attr', live: true, subtree: 'cross-roots', timing: 'sync', eventDetails: true, staticSensitivity: true } );
|
|
51
|
+
realdom.realtime( window.document ).query( `(${ config.discreteBindingsSelector })`, record => {
|
|
52
|
+
cleanup.call( this, ...record.exits );
|
|
53
|
+
mountDiscreteBindings.call( window, config, ...record.entrants );
|
|
54
|
+
}, { id: 'data-binding:descrete', live: true, subtree: 'cross-roots', timing: 'sync' } );
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
function createDynamicScope( config, root ) {
|
|
@@ -54,16 +60,17 @@ function createDynamicScope( config, root ) {
|
|
|
54
60
|
const scope = Object.create( null ), abortController = new AbortController;
|
|
55
61
|
scope[ '$exec__' ] = ( target, prop, ...args ) => {
|
|
56
62
|
const exec = () => {
|
|
57
|
-
try { target[ prop ]( ...args ); }
|
|
63
|
+
try { target[ prop ]( ...args ); }
|
|
64
|
+
catch( e ) { console.error( `Error executing "${ prop }": ${ e.message } at ${ e.cause }` ); }
|
|
58
65
|
};
|
|
59
|
-
|
|
66
|
+
exec();
|
|
60
67
|
};
|
|
61
68
|
scope[ '$assign__' ] = ( target, prop, val ) => {
|
|
62
69
|
const exec = () => {
|
|
63
70
|
try { target[ prop ] = val; }
|
|
64
71
|
catch( e ) { console.error( `${ e.message } at ${ e.cause }` ); }
|
|
65
72
|
};
|
|
66
|
-
|
|
73
|
+
exec();
|
|
67
74
|
};
|
|
68
75
|
Observer.intercept( scope, {
|
|
69
76
|
get: ( e, recieved, next ) => {
|
|
@@ -266,11 +273,12 @@ const escDouble = str => str.replace(/"/g, '\\"');
|
|
|
266
273
|
|
|
267
274
|
export function idleCompiler( node ) {
|
|
268
275
|
const window = this, { webqit: { oohtml: { configs: { DATA_BINDING: config } } } } = window;
|
|
276
|
+
// Attr selector must also come first, as in above
|
|
277
|
+
( node?.matches( config.attrSelector ) ? [ node ] : [] ).concat([ ...( node?.querySelectorAll( config.attrSelector ) || [] ) ]).forEach( node => {
|
|
278
|
+
compileInlineBindings.call( window, config, node.getAttribute( config.attr.render ) );
|
|
279
|
+
} );
|
|
269
280
|
xpathQuery( window, node, `(${ config.discreteBindingsSelector })` ).forEach( node => {
|
|
270
281
|
const template = patternMatch( config, node.nodeValue );
|
|
271
282
|
compileDiscreteBindings.call( window, config, template.expr );
|
|
272
283
|
} );
|
|
273
|
-
( node?.matches( config.attrSelector ) ? [ node ] : [] ).concat([ ...( node?.querySelectorAll( config.attrSelector ) || [] ) ]).forEach( node => {
|
|
274
|
-
compileInlineBindings.call( window, config, node.getAttribute( config.attr.render ) );
|
|
275
|
-
} );
|
|
276
284
|
}
|
|
@@ -63,6 +63,7 @@ export default function() {
|
|
|
63
63
|
} );
|
|
64
64
|
}, { live: true, timing: 'sync', lifecycleSignals: true } );
|
|
65
65
|
priv.autoDestroyRealtime = realdom.realtime( window.document ).track( parentNode, () => {
|
|
66
|
+
this.state = null;
|
|
66
67
|
priv.die();
|
|
67
68
|
}, { subtree: 'cross-roots', timing: 'sync', generation: 'exits' } );
|
|
68
69
|
};
|
|
@@ -97,9 +98,8 @@ export default function() {
|
|
|
97
98
|
const restore = () => {
|
|
98
99
|
if (this.el.isConnected) return;
|
|
99
100
|
this.el.setAttribute( 'data-nodecount', 0 );
|
|
100
|
-
this.
|
|
101
|
+
this.state = 'restored';
|
|
101
102
|
priv.anchorNode.replaceWith( this.el );
|
|
102
|
-
this.el.slottingAction = false;
|
|
103
103
|
priv.setAnchorNode( null );
|
|
104
104
|
};
|
|
105
105
|
if ( !priv.slottedElements.size ) return restore();
|
|
@@ -119,12 +119,12 @@ export default function() {
|
|
|
119
119
|
};
|
|
120
120
|
|
|
121
121
|
priv.connectedCallback = () => {
|
|
122
|
-
if ( this.
|
|
122
|
+
if ( this.state === 'restored' ) return;
|
|
123
123
|
priv.live( fragments => this.fill( fragments ) );
|
|
124
124
|
};
|
|
125
125
|
|
|
126
126
|
priv.disconnectedCallback = () => {
|
|
127
|
-
if ( this.
|
|
127
|
+
if ( this.state === 'resolved' ) return;
|
|
128
128
|
priv.die();
|
|
129
129
|
};
|
|
130
130
|
}
|
|
@@ -175,9 +175,8 @@ export default function() {
|
|
|
175
175
|
// not the import element itslef - but all only when we have slottableElements.size
|
|
176
176
|
if ( slottableElements.size && this.el.isConnected ) {
|
|
177
177
|
const newAnchorNode = this[ '#' ].setAnchorNode( this.createAnchorNode() );
|
|
178
|
-
this.
|
|
178
|
+
this.state = 'resolved';
|
|
179
179
|
this.el.replaceWith( newAnchorNode );
|
|
180
|
-
this.el.slottingAction = false;
|
|
181
180
|
}
|
|
182
181
|
// Insert slottables now
|
|
183
182
|
slottableElements.forEach( slottableElement => {
|
|
@@ -154,6 +154,7 @@ function realtime(config) {
|
|
|
154
154
|
record.exits.forEach(entry => {
|
|
155
155
|
if (entry.matches(config.templateSelector)) {
|
|
156
156
|
const htmlModule = HTMLModule.instance(entry);
|
|
157
|
+
//if (!htmlModule.ownerContext) return; // JSDOM sometimes
|
|
157
158
|
const ownerContextModulesObj = getDefs(htmlModule.ownerContext);
|
|
158
159
|
if (htmlModule.defId && htmlModule.ownerContext.isConnected) { Observer.deleteProperty(ownerContextModulesObj, htmlModule.defId); }
|
|
159
160
|
detachImportsContext(htmlModule.ownerContext);
|
|
@@ -161,7 +162,7 @@ function realtime(config) {
|
|
|
161
162
|
detachImportsContext(entry);
|
|
162
163
|
}
|
|
163
164
|
});
|
|
164
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync', staticSensitivity: true, eventDetails: true });
|
|
165
|
+
}, { id: 'imports:template/importscontext', live: true, subtree: 'cross-roots', timing: 'sync', staticSensitivity: true, eventDetails: true });
|
|
165
166
|
|
|
166
167
|
// ------------
|
|
167
168
|
// IMPORTS
|
|
@@ -169,7 +170,7 @@ function realtime(config) {
|
|
|
169
170
|
realdom.realtime(window.document).query(config.elements.import, record => {
|
|
170
171
|
record.entrants.forEach(node => handleRealtime(node, true, record));
|
|
171
172
|
record.exits.forEach(node => handleRealtime(node, false, record));
|
|
172
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync' });
|
|
173
|
+
}, { id: 'imports:import', live: true, subtree: 'cross-roots', timing: 'sync', deferred: true });
|
|
173
174
|
function handleRealtime(entry, connectedState) {
|
|
174
175
|
const elInstance = HTMLImportElement.instance(entry);
|
|
175
176
|
if (connectedState) { elInstance['#'].connectedCallback(); }
|
|
@@ -192,5 +193,5 @@ function realtime(config) {
|
|
|
192
193
|
}
|
|
193
194
|
HTMLImportElement.instance(importEl)['#'].hydrate(anchorNode, slottedElements);
|
|
194
195
|
});
|
|
195
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync' });
|
|
196
|
+
}, { id: 'imports:hydration', live: true, subtree: 'cross-roots', timing: 'sync' });
|
|
196
197
|
}
|
package/src/init.js
CHANGED
|
@@ -19,10 +19,10 @@ export default function init( QuantumJS, configs = {} ) {
|
|
|
19
19
|
// --------------
|
|
20
20
|
ContextAPI.call( this, ( configs.CONTEXT_API || {} ) );
|
|
21
21
|
BindingsAPI.call( this, ( configs.BINDINGS_API || {} ) ); // Depends on ContextAPI
|
|
22
|
-
|
|
22
|
+
// Imports must happen before the rest... structure must be flattened before the other things below which query the DOM
|
|
23
23
|
HTMLImports.call( this, { ...( configs.HTML_IMPORTS || {} ), idleCompilers: [ idleCompiler1, idleCompiler2 ] } ); // Depends on ContextAPI
|
|
24
|
+
NamespacedHTML.call( this, ( configs.NAMESPACED_HTML || {} ) ); // Depends on ContextAPI
|
|
24
25
|
DataBinding.call( this, ( configs.DATA_BINDING || {} ) ); // Depends on ContextAPI, BindingsAPI, HTMLImports
|
|
25
26
|
ScopedCSS.call( this, ( configs.SCOPED_CSS || {} ) ); // Depends on NamespacedHTML
|
|
26
27
|
ScopedJS.call( this, ( configs.SCOPED_JS || {} ) );
|
|
27
|
-
// --------------
|
|
28
28
|
}
|
|
@@ -38,7 +38,7 @@ function lidUtil( config ) {
|
|
|
38
38
|
lidrefPrefix( escapeMode = 0 ) { return escapeMode ? this.escape( lidrefPrefix, escapeMode ) : lidrefPrefix; },
|
|
39
39
|
lidrefSeparator( escapeMode = 0 ) { return escapeMode ? this.escape( lidrefSeparator, escapeMode ) : lidrefSeparator; },
|
|
40
40
|
isUuid( str, escapeMode = 0 ) { return str.startsWith( this.lidrefPrefix( escapeMode ) ) && str.includes( this.lidrefSeparator( escapeMode ) ); },
|
|
41
|
-
isLidref( str, escapeMode = 0 ) { return str.startsWith( this.lidrefPrefix( escapeMode ) ) && !str.includes( this.lidrefSeparator( escapeMode ) ); },
|
|
41
|
+
//isLidref( str, escapeMode = 0 ) { return str.startsWith( this.lidrefPrefix( escapeMode ) ) && !str.includes( this.lidrefSeparator( escapeMode ) ); },
|
|
42
42
|
toUuid( hash, lid, escapeMode = 0 ) { return hash.endsWith( '-root' ) ? lid : `${ this.lidrefPrefix( escapeMode ) }${ hash }${ this.lidrefSeparator( escapeMode ) }${ lid }`; },
|
|
43
43
|
uuidToId( str, escapeMode = 0 ) { return this.isUuid( str ) ? str.split( this.lidrefSeparator( escapeMode ) )[ 1 ] : str; },
|
|
44
44
|
uuidToLidref( str, escapeMode = 0 ) { return this.isUuid( str ) ? `${ this.lidrefPrefix( escapeMode ) }${ str.split( this.lidrefSeparator( escapeMode ) )[ 1 ] }` : str; },
|
|
@@ -278,7 +278,7 @@ function realtime( config ) {
|
|
|
278
278
|
}
|
|
279
279
|
} else {
|
|
280
280
|
_( entry, 'attrOriginals' ).set( attrName, value ); // Save original before rewrite
|
|
281
|
-
const newAttrValue = value.split( ' ' ).map( idref => ( idref = idref.trim() ) &&
|
|
281
|
+
const newAttrValue = value.split( ' ' ).map( idref => ( idref = idref.trim() ) && $lidUtil.isUuid( idref ) ? idref : $lidUtil.toUuid( namespaceUUID, idref ) ).join( ' ' );
|
|
282
282
|
entry.setAttribute( attrName, newAttrValue );
|
|
283
283
|
_( namespaceObj ).set( 'idrefs', _( namespaceObj ).get( 'idrefs' ) || new Set );
|
|
284
284
|
_( namespaceObj ).get( 'idrefs' ).add( entry );
|
|
@@ -296,7 +296,7 @@ function realtime( config ) {
|
|
|
296
296
|
}
|
|
297
297
|
} else {
|
|
298
298
|
const newAttrValue = _( entry, 'attrOriginals' ).get( attrName );// oldValue.split( ' ' ).map( lid => ( lid = lid.trim() ) && $lidUtil.uuidToLidref( lid ) ).join( ' ' );
|
|
299
|
-
entry.setAttribute( attrName, newAttrValue );
|
|
299
|
+
if ( entry.hasAttribute( attrName ) ) entry.setAttribute( attrName, newAttrValue );
|
|
300
300
|
_( namespaceObj ).get( 'idrefs' )?.delete( entry );
|
|
301
301
|
}
|
|
302
302
|
} );
|
|
@@ -338,7 +338,7 @@ function realtime( config ) {
|
|
|
338
338
|
const contextsApi = entry[ configs.CONTEXT_API.api.contexts ];
|
|
339
339
|
if ( !contextsApi.find( DOMNamingContext.kind ) ) { contextsApi.attach( new DOMNamingContext ); }
|
|
340
340
|
} );
|
|
341
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync', staticSensitivity: true, eventDetails: true } );
|
|
341
|
+
}, { id: 'namespace-html:namespace', live: true, subtree: 'cross-roots', timing: 'sync', staticSensitivity: true, eventDetails: true } );
|
|
342
342
|
|
|
343
343
|
// DOM realtime
|
|
344
344
|
realdom.realtime( window.document ).query( `[${ attrList.map( attrName => window.CSS.escape( attrName ) ).join( '],[' ) }]`, record => {
|
|
@@ -365,14 +365,14 @@ function realtime( config ) {
|
|
|
365
365
|
}
|
|
366
366
|
namespaceNodesToTest.forID.clear();
|
|
367
367
|
namespaceNodesToTest.forOther.clear();
|
|
368
|
-
}, { live: true, subtree: 'cross-roots', timing: 'sync' } );
|
|
368
|
+
}, { id: 'namespace-html:attrs', live: true, subtree: 'cross-roots', timing: 'sync' } );
|
|
369
369
|
// Attr realtime
|
|
370
370
|
realdom.realtime( window.document, 'attr' ).observe( attrList, records => {
|
|
371
371
|
for ( const record of records ) {
|
|
372
372
|
if ( record.oldValue ) { cleanupBinding( record.target, record.name, record.oldValue/* Current resolved value as-is */ ); }
|
|
373
373
|
if ( record.value ) { setupBinding( record.target, record.name, record.value/* Raw value (as-is) that will be saved as original */ ); }
|
|
374
374
|
}
|
|
375
|
-
}, { subtree: 'cross-roots', timing: 'sync', newValue: true, oldValue: true } );
|
|
375
|
+
}, { id: 'namespace-html:attr(attrs)', subtree: 'cross-roots', timing: 'sync', newValue: true, oldValue: true } );
|
|
376
376
|
|
|
377
377
|
// ------------
|
|
378
378
|
// TARGETS
|
package/src/scoped-css/index.js
CHANGED
|
@@ -100,7 +100,7 @@ function realtime( config ) {
|
|
|
100
100
|
else { setTimeout( () => { transform(); }, 0 ); }
|
|
101
101
|
}
|
|
102
102
|
} );
|
|
103
|
-
}, { live: true, subtree: 'cross-roots', timing: 'intercept', generation: 'entrants' } );
|
|
103
|
+
}, { id: 'scoped-css', live: true, subtree: 'cross-roots', timing: 'intercept', generation: 'entrants' } );
|
|
104
104
|
// ---
|
|
105
105
|
}
|
|
106
106
|
|
package/src/scoped-js/index.js
CHANGED
|
@@ -16,10 +16,8 @@ export default function init({ advanced = {}, ...$config }) {
|
|
|
16
16
|
api: { scripts: 'scripts' },
|
|
17
17
|
advanced: resolveParams(advanced),
|
|
18
18
|
} );
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
return selector.concat( `script${ qualifier }` );
|
|
22
|
-
}, [] ).join( ',' );
|
|
19
|
+
const customTypes = Array.isArray( config.script.mimeTypes ) ? config.script.mimeTypes : config.script.mimeTypes.split( '|' ).filter( t => t );
|
|
20
|
+
config.scriptSelector = customTypes.map( t => `script[type="${ window.CSS.escape( t ) }"]`).concat(`script:not([type])`).join( ',' );
|
|
23
21
|
window.webqit.oohtml.Script = {
|
|
24
22
|
compileCache: [ new Map, new Map, ],
|
|
25
23
|
execute: execute.bind( window, config ),
|
|
@@ -38,10 +36,12 @@ export default function init({ advanced = {}, ...$config }) {
|
|
|
38
36
|
function exposeAPIs( config ) {
|
|
39
37
|
const window = this, scriptsMap = new Map;
|
|
40
38
|
if ( config.api.scripts in window.Element.prototype ) { throw new Error( `The "Element" class already has a "${ config.api.scripts }" property!` ); }
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
39
|
+
[ window.ShadowRoot.prototype, window.Element.prototype ].forEach( proto => {
|
|
40
|
+
Object.defineProperty( proto, config.api.scripts, { get: function() {
|
|
41
|
+
if ( !scriptsMap.has( this ) ) { scriptsMap.set( this, [] ); }
|
|
42
|
+
return scriptsMap.get( this );
|
|
43
|
+
}, } );
|
|
44
|
+
} );
|
|
45
45
|
Object.defineProperties( window.HTMLScriptElement.prototype, {
|
|
46
46
|
scoped: {
|
|
47
47
|
configurable: true,
|
|
@@ -80,7 +80,7 @@ async function execute( config, execHash ) {
|
|
|
80
80
|
realdom.realtime( window.document ).observe( script, () => {
|
|
81
81
|
if ( script.quantum ) { state.dispose(); }
|
|
82
82
|
if ( thisContext instanceof window.Element ) { thisContext[ config.api.scripts ]?.splice( thisContext[ config.api.scripts ].indexOf( script, 1 ) ); }
|
|
83
|
-
}, { subtree: 'cross-roots', timing: 'sync', generation: 'exits' } );
|
|
83
|
+
}, { id: 'scoped-js:script-exits', subtree: 'cross-roots', timing: 'sync', generation: 'exits' } );
|
|
84
84
|
}
|
|
85
85
|
|
|
86
86
|
/**
|
|
@@ -105,12 +105,12 @@ function realtime( config ) {
|
|
|
105
105
|
const thisContext = script.scoped ? script.parentNode || record.target : ( script.type === 'module' ? undefined : window );
|
|
106
106
|
if ( script.scoped ) { thisContext[ config.api.scripts ].push( script ); }
|
|
107
107
|
const execHash = _toHash( { script, compiledScript, thisContext } );
|
|
108
|
-
const manualHandling = record.type === 'query' || ( script.type && !window.HTMLScriptElement.supports( script.type ) );
|
|
108
|
+
const manualHandling = record.type === 'query' || ( script.type && !window.HTMLScriptElement.supports( script.type ) ) || script.getAttribute('data-handling') === 'manual';
|
|
109
109
|
if ( manualHandling || config.script.timing === 'manual' ) { oohtml.Script.execute( execHash ); } else {
|
|
110
110
|
script.textContent = `webqit.oohtml.Script.execute( '${ execHash }' );`;
|
|
111
111
|
}
|
|
112
112
|
} );
|
|
113
|
-
}, { live: true, subtree: 'cross-roots', timing: 'intercept', generation: 'entrants', eventDetails: true } );
|
|
113
|
+
}, { id: 'scoped-js:script-entries', live: true, subtree: 'cross-roots', timing: 'intercept', generation: 'entrants', eventDetails: true } );
|
|
114
114
|
// ---
|
|
115
115
|
}
|
|
116
116
|
|