@webqit/oohtml 2.1.53 → 2.1.54
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/README.md +15 -1
- 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-bracelets.js +1 -1
- package/dist/html-bracelets.js.map +3 -3
- package/dist/html-imports.js +1 -1
- package/dist/html-imports.js.map +3 -3
- package/dist/html-namespaces.js +1 -1
- package/dist/html-namespaces.js.map +3 -3
- package/dist/main.js +4 -4
- package/dist/main.js.map +3 -3
- package/dist/scoped-css.js +2 -2
- package/dist/scoped-css.js.map +3 -3
- package/dist/scoped-js.js +4 -4
- package/dist/scoped-js.js.map +3 -3
- package/package.json +3 -6
- package/src/context-api/ContextReturnValue.js +2 -2
- package/src/html-bracelets/AttrBracelet.js +18 -5
- package/src/html-bracelets/Bracelet.js +8 -4
- package/src/html-bracelets/HTMLBracelets.js +14 -13
- package/src/html-bracelets/TextBracelet.js +1 -1
- package/src/html-bracelets/index.js +7 -6
- package/src/html-imports/index.js +8 -4
- package/src/scoped-js/index.js +10 -12
package/package.json
CHANGED
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"wicg-proposal"
|
|
15
15
|
],
|
|
16
16
|
"homepage": "https://webqit.io/tooling/oohtml",
|
|
17
|
-
"version": "2.1.
|
|
17
|
+
"version": "2.1.54",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
@@ -25,9 +25,6 @@
|
|
|
25
25
|
},
|
|
26
26
|
"type": "module",
|
|
27
27
|
"sideEffects": false,
|
|
28
|
-
"browser": {
|
|
29
|
-
"fs": false
|
|
30
|
-
},
|
|
31
28
|
"main": "./src/index.js",
|
|
32
29
|
"scripts": {
|
|
33
30
|
"test": "mocha --extension .test.js --exit",
|
|
@@ -39,8 +36,8 @@
|
|
|
39
36
|
},
|
|
40
37
|
"dependencies": {
|
|
41
38
|
"@webqit/observer": "^2.2.9",
|
|
42
|
-
"@webqit/realdom": "^2.1.17
|
|
43
|
-
"@webqit/stateful-js": "^3.0.
|
|
39
|
+
"@webqit/realdom": "^2.1.17",
|
|
40
|
+
"@webqit/stateful-js": "^3.0.15",
|
|
44
41
|
"@webqit/util": "^0.8.11"
|
|
45
42
|
},
|
|
46
43
|
"devDependencies": {
|
|
@@ -6,8 +6,8 @@ import Observer from "@webqit/observer";
|
|
|
6
6
|
|
|
7
7
|
export default class ContextReturnValue {
|
|
8
8
|
constructor( request, hostElement ) {
|
|
9
|
-
this
|
|
10
|
-
this
|
|
9
|
+
Object.defineProperty( this, 'request', { value: request } );
|
|
10
|
+
Object.defineProperty( this, 'hostElement', { value: hostElement } );
|
|
11
11
|
if ( request.live && !request.signal ) {
|
|
12
12
|
Object.defineProperty( this, 'abortController', { value: new AbortController } );
|
|
13
13
|
request.signal = this.abortController.signal;
|
|
@@ -7,12 +7,12 @@ import Bracelet from './Bracelet.js';
|
|
|
7
7
|
import { _ } from '../util.js';
|
|
8
8
|
|
|
9
9
|
export default class AttrBracelet extends Bracelet {
|
|
10
|
-
static get query() { return
|
|
10
|
+
static get query() { return `@*[${ this.tokens.contains }]`; }
|
|
11
11
|
|
|
12
12
|
static parse( ...attrs ) {
|
|
13
13
|
return attrs.reduce( ( attrs, attr ) => {
|
|
14
14
|
return attrs.concat( [ ...attr.nodeValue.matchAll( new RegExp( this.tokens.regex, 'g' ) ) ].reduce( ( bracelets, match ) => {
|
|
15
|
-
const bracelet = new this( attr, match[ 0 ], match.index, match[ 1 ].trim() );
|
|
15
|
+
const bracelet = new this( attr, match[ 0 ], match.index, match[ 1 ].trim(), attr.nodeName === 'class' || match[ 0 ] === attr.nodeValue.trim() );
|
|
16
16
|
const prev = bracelets.slice( -1 )[ 0 ];
|
|
17
17
|
if ( prev ) { prev._nextSibling = bracelet; }
|
|
18
18
|
return bracelets.concat( bracelet );
|
|
@@ -55,25 +55,31 @@ export default class AttrBracelet extends Bracelet {
|
|
|
55
55
|
}
|
|
56
56
|
}
|
|
57
57
|
|
|
58
|
-
constructor( attr, _value, startIndex, expr ) {
|
|
58
|
+
constructor( attr, _value, startIndex, expr, booleanAble ) {
|
|
59
59
|
super();
|
|
60
60
|
const $refs = [], $expr = this.parseExpr( expr, $refs );
|
|
61
|
+
const ownerElement = attr.ownerElement; // Hard save. Deleted attributes don't retain .ownerElement
|
|
61
62
|
Object.defineProperties( this, {
|
|
62
63
|
type: { get: () => 'attr' },
|
|
63
64
|
expr: { get: () => $expr },
|
|
64
65
|
refs: { get: () => $refs },
|
|
65
66
|
attr: { get: () => attr },
|
|
66
|
-
ownerElement: { get: () =>
|
|
67
|
+
ownerElement: { get: () => ownerElement },
|
|
67
68
|
originalValue: { value: _value },
|
|
68
69
|
_value: { value: _value, writable: true },
|
|
69
70
|
_dirty: { value: false, writable: true },
|
|
70
71
|
_startIndex: { value: undefined, writable: true },
|
|
71
72
|
_endIndex: { value: undefined, writable: true },
|
|
72
73
|
_nextSibling: { value: undefined, writable: true },
|
|
74
|
+
_booleanAble: { value: booleanAble, writable: true },
|
|
73
75
|
_nested: { value: new Set },
|
|
74
76
|
} );
|
|
77
|
+
if ( this.attr.nodeName === 'class' && ( this.expr.length !== 1 || this.expr[ 0 ].type !== 'ref' ) ) {
|
|
78
|
+
throw new Error( `Invalid bracelet for the class attribute: "${ this.originalValue }"` );
|
|
79
|
+
}
|
|
75
80
|
this.startIndex = startIndex;
|
|
76
81
|
}
|
|
82
|
+
get isBoolean() { return this._booleanAble && typeof this._value === 'boolean'; }
|
|
77
83
|
|
|
78
84
|
get startIndex() { return this._startIndex; }
|
|
79
85
|
set startIndex( value ) {
|
|
@@ -97,7 +103,14 @@ export default class AttrBracelet extends Bracelet {
|
|
|
97
103
|
this._nested.forEach( p => p.disconnect() );
|
|
98
104
|
const attrBraceletsRegistry = _( this.ownerElement ).get( 'attr-bracelets' );
|
|
99
105
|
attrBraceletsRegistry.active.unshift( this );
|
|
100
|
-
|
|
106
|
+
if ( this.isBoolean && this.attr.nodeName !== 'class' ) {
|
|
107
|
+
this.ownerElement.toggleAttribute( this.attr.nodeName, value );
|
|
108
|
+
} else {
|
|
109
|
+
if ( this.isBoolean && this.attr.nodeName === 'class' ) {
|
|
110
|
+
value = value ? this.expr[ 0 ].value.join( '' ) : '';
|
|
111
|
+
}
|
|
112
|
+
this.ownerElement.setAttribute( this.attr.nodeName, this.attr.nodeValue.substring( 0, this.startIndex ) + value + this.attr.nodeValue.substring( this.endIndex ) );
|
|
113
|
+
}
|
|
101
114
|
attrBraceletsRegistry.active.shift();
|
|
102
115
|
// Reindex
|
|
103
116
|
const newEndIndex = this.startIndex + value.length;
|
|
@@ -65,13 +65,17 @@ export default class Bracelet {
|
|
|
65
65
|
}
|
|
66
66
|
|
|
67
67
|
render( bindings ) {
|
|
68
|
-
|
|
68
|
+
let value = this.renderExpr( this.expr, bindings );
|
|
69
69
|
if ( typeof value === 'undefined' ) {
|
|
70
|
-
|
|
71
|
-
this.
|
|
70
|
+
value = this.originalValue;
|
|
71
|
+
if ( !this.dirty ) {
|
|
72
|
+
if ( this._booleanAble ) { value = false; }
|
|
73
|
+
else return;
|
|
74
|
+
}
|
|
75
|
+
this.value = value;
|
|
72
76
|
return;
|
|
73
77
|
}
|
|
74
|
-
this.value = value
|
|
78
|
+
this.value = value;
|
|
75
79
|
}
|
|
76
80
|
|
|
77
81
|
disconnect() { this.disconnected = true; }
|
|
@@ -31,17 +31,17 @@ export default class HTMLBracelets extends Set {
|
|
|
31
31
|
if ( !( bracelet instanceof Bracelet ) ) throw new Error( `Argument must be instance of Bracelet.` );
|
|
32
32
|
const returnValue = super.add( bracelet );
|
|
33
33
|
const bindings = this[ '#' ].bindings;
|
|
34
|
-
bracelet.refs.forEach(
|
|
35
|
-
const $
|
|
36
|
-
if ( !( $
|
|
37
|
-
bindings[ $
|
|
38
|
-
const request = _HTMLBindingsProvider.createRequest( { detail:
|
|
34
|
+
bracelet.refs.forEach( path => {
|
|
35
|
+
const $path = path.join( '.' );
|
|
36
|
+
if ( !( $path in bindings ) ) {
|
|
37
|
+
bindings[ $path ] = { subs: new Set, controller: new AbortController };
|
|
38
|
+
const request = _HTMLBindingsProvider.createRequest( { detail: path, live: true, signal: bindings[ $path ].signal } );
|
|
39
39
|
HTMLContext.instance( this[ '#' ].host ).request( request, value => {
|
|
40
|
-
bindings[ $
|
|
41
|
-
bindings[ $
|
|
40
|
+
bindings[ $path ].value = value;
|
|
41
|
+
bindings[ $path ].subs.forEach( bracelet => bracelet.render( bindings ) );
|
|
42
42
|
} );
|
|
43
43
|
}
|
|
44
|
-
bindings[ $
|
|
44
|
+
bindings[ $path ].subs.add( bracelet );
|
|
45
45
|
} );
|
|
46
46
|
bracelet.render( bindings );
|
|
47
47
|
return returnValue;
|
|
@@ -51,11 +51,12 @@ export default class HTMLBracelets extends Set {
|
|
|
51
51
|
if ( !( bracelet instanceof Bracelet ) ) throw new Error( `Argument must be instance of Bracelet.` );
|
|
52
52
|
const returnValue = super.delete( bracelet );
|
|
53
53
|
const bindings = this[ '#' ].bindings;
|
|
54
|
-
bracelet.refs.forEach(
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
54
|
+
bracelet.refs.forEach( path => {
|
|
55
|
+
const $path = path.join( '.' );
|
|
56
|
+
bindings[ $path ].subs.delete( bracelet );
|
|
57
|
+
if ( !bindings[ $path ].subs.size ) {
|
|
58
|
+
bindings[ $path ].controller.abort();
|
|
59
|
+
delete bindings[ $path ];
|
|
59
60
|
}
|
|
60
61
|
} );
|
|
61
62
|
return returnValue;
|
|
@@ -7,7 +7,7 @@ import Bracelet from './Bracelet.js';
|
|
|
7
7
|
import { _ } from '../util.js';
|
|
8
8
|
|
|
9
9
|
export default class TextBracelet extends Bracelet {
|
|
10
|
-
static get query() { return `text()[not(ancestor::script) and ${ this.tokens.contains }]`; }
|
|
10
|
+
static get query() { return `text()[not(ancestor::script) and not(ancestor::style) and ${ this.tokens.contains }]`; }
|
|
11
11
|
|
|
12
12
|
static parse( ...nodes ) {
|
|
13
13
|
return nodes.reduce( ( nodes, node ) => {
|
|
@@ -53,19 +53,20 @@ function exposeAPIs( config ) {
|
|
|
53
53
|
*/
|
|
54
54
|
function realtime( config ) {
|
|
55
55
|
const window = this, { realdom } = window.webqit;
|
|
56
|
-
realdom.realtime( window.document ).
|
|
56
|
+
realdom.realtime( window.document ).subtree( `(${ TextBracelet.query })`, record => {
|
|
57
57
|
TextBracelet.cleanup( ...record.exits );
|
|
58
58
|
TextBracelet.mount( ...TextBracelet.parse( ...record.entrants.filter( node => !_( node ).has( 'text-bracelet' )/** generated text nodes during parse() */ ) ) );
|
|
59
|
-
}, {
|
|
59
|
+
}, { live: true } );
|
|
60
|
+
realdom.realtime( window.document ).subtree( `(${ AttrBracelet.query })`, record => {
|
|
61
|
+
AttrBracelet.cleanup( ...record.exits );
|
|
62
|
+
AttrBracelet.mount( ...AttrBracelet.parse( ...record.entrants ) );
|
|
63
|
+
}, { live: true } );
|
|
60
64
|
realdom.realtime( window.document, 'attr' ).observe( records => {
|
|
61
65
|
for ( const record of records ) {
|
|
62
66
|
if ( _( record.target ).get( 'attr-bracelets' )?.active.some( p => p.attr.nodeName === record.name ) ) continue;
|
|
67
|
+
if ( [ ...( _( record.target ).get( 'attr-bracelets' )?.get( record.name ) || [] ) ].some( p => p.isBoolean ) ) continue;
|
|
63
68
|
if ( record.oldValue ) { AttrBracelet.cleanup( record.value ? record.target.attributes[ record.name ] : { ownerElement: record.target, nodeName: record.name } ); }
|
|
64
69
|
if ( record.value ) { AttrBracelet.mount( ...AttrBracelet.parse( record.target.attributes[ record.name ] ) ); }
|
|
65
70
|
}
|
|
66
71
|
}, { subtree: true, newValue: true, oldValue: true, timing: 'sync' } );
|
|
67
|
-
realdom.realtime( window.document ).observe( `(${ AttrBracelet.query })`, record => {
|
|
68
|
-
AttrBracelet.cleanup( ...record.exits.reduce( ( attrs, node ) => [ ...attrs, ...node.attributes ], [] ) );
|
|
69
|
-
AttrBracelet.mount( ...AttrBracelet.parse( ...record.entrants.reduce( ( attrs, node ) => [ ...attrs, ...node.attributes ], [] ) ) );
|
|
70
|
-
}, { subtree: true } );
|
|
71
72
|
}
|
|
@@ -76,14 +76,18 @@ function exposeAPIs( config ) {
|
|
|
76
76
|
Object.defineProperty( window.HTMLTemplateElement.prototype, config.template.api.moduledef, { get: function() {
|
|
77
77
|
return this.getAttribute( config.template.attr.moduledef );
|
|
78
78
|
} } );
|
|
79
|
-
Object.defineProperty( window.document, config.context.api.import, { value: function( ref, callback = null ) {
|
|
79
|
+
Object.defineProperty( window.document, config.context.api.import, { value: function( ref, live = false, callback = null ) {
|
|
80
80
|
return importRequest( window.document, ...arguments );
|
|
81
81
|
} } );
|
|
82
|
-
Object.defineProperty( window.HTMLElement.prototype, config.context.api.import, { value: function( ref, callback = null ) {
|
|
82
|
+
Object.defineProperty( window.HTMLElement.prototype, config.context.api.import, { value: function( ref, live = false, callback = null ) {
|
|
83
83
|
return importRequest( this, ...arguments );
|
|
84
84
|
} } );
|
|
85
|
-
function importRequest( context, ref, callback = null ) {
|
|
86
|
-
|
|
85
|
+
function importRequest( context, ref, live = false, callback = null ) {
|
|
86
|
+
if ( typeof live === 'function' ) {
|
|
87
|
+
callback = live;
|
|
88
|
+
live = false;
|
|
89
|
+
}
|
|
90
|
+
const request = _HTMLImportsProvider.createRequest( { detail: ref, live } );
|
|
87
91
|
return HTMLContext.instance( context ).request( request, callback );
|
|
88
92
|
}
|
|
89
93
|
}
|
package/src/scoped-js/index.js
CHANGED
|
@@ -2,8 +2,8 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
|
-
import { resolveParams } from '@webqit/stateful-js/
|
|
6
|
-
import { StatefulAsyncFunction, StatefulAsyncScript, StatefulModule, State } from '@webqit/stateful-js/
|
|
5
|
+
import { resolveParams } from '@webqit/stateful-js/params';
|
|
6
|
+
import { StatefulAsyncFunction, StatefulAsyncScript, StatefulModule, State } from '@webqit/stateful-js/async';
|
|
7
7
|
import Observer from '@webqit/observer';
|
|
8
8
|
import Hash from './Hash.js';
|
|
9
9
|
import { _init } from '../util.js';
|
|
@@ -54,16 +54,10 @@ async function execute( config, execHash ) {
|
|
|
54
54
|
}
|
|
55
55
|
// Execute and save state
|
|
56
56
|
const state = ( await compiledScript.bind( thisContext ) ).execute();
|
|
57
|
-
if (
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
// Observe DOM removal
|
|
62
|
-
if ( !( thisContext instanceof window.Node ) ) return script;
|
|
63
|
-
realdom.realtime( window.document ).observe( thisContext, () => {
|
|
64
|
-
thisContext.dispatchEvent( new window.CustomEvent( 'remove' ) );
|
|
65
|
-
state.dispose();
|
|
66
|
-
thisContext.scripts.splice( thisContext.scripts.indexOf( state, 1 ) );
|
|
57
|
+
if ( script.stateful ) { Object.defineProperty( script, 'state', { value: state } ); }
|
|
58
|
+
realdom.realtime( window.document ).observe( script, () => {
|
|
59
|
+
if ( script.stateful ) { state.dispose(); }
|
|
60
|
+
if ( script.scoped ) { thisContext.scripts.splice( thisContext.scripts.indexOf( script, 1 ) ); }
|
|
67
61
|
}, { subtree: true, timing: 'sync', generation: 'exits' } );
|
|
68
62
|
}
|
|
69
63
|
|
|
@@ -102,6 +96,10 @@ function realtime( config ) {
|
|
|
102
96
|
}
|
|
103
97
|
// Run now!!!
|
|
104
98
|
const thisContext = script.scoped ? script.parentNode || record.target : ( script.type === 'module' ? undefined : window );
|
|
99
|
+
if ( script.scoped ) {
|
|
100
|
+
if ( !thisContext.scripts ) { Object.defineProperty( thisContext, 'scripts', { value: [] } ); }
|
|
101
|
+
thisContext.scripts.push( script );
|
|
102
|
+
}
|
|
105
103
|
const execHash = Hash.toHash( { script, compiledScript, thisContext } );
|
|
106
104
|
const manualHandling = record.type === 'query' || ( potentialManualTypes.includes( script.type ) && !window.HTMLScriptElement.supports( script.type ) );
|
|
107
105
|
if ( manualHandling ) { oohtml.Script.execute( execHash ); } else {
|