@webqit/oohtml 2.1.59 → 2.1.60
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/{html-bindings.js → data-binding.js} +4 -4
- package/dist/{html-bindings.js.map → data-binding.js.map} +3 -3
- package/dist/html-imports.js +1 -1
- package/dist/html-imports.js.map +2 -2
- package/dist/main.js +6 -6
- package/dist/main.js.map +3 -3
- package/dist/{html-namespaces.js → namespaced-html.js} +2 -2
- package/dist/{html-namespaces.js.map → namespaced-html.js.map} +2 -2
- package/package.json +4 -4
- package/src/bindings-api/_HTMLBindingsProvider.js +13 -0
- package/src/bindings-api/index.js +19 -8
- package/src/context-api/index.js +1 -0
- package/src/{html-bindings → data-binding}/index.js +17 -17
- package/src/html-imports/_HTMLImportElement.js +1 -1
- package/src/html-imports/index.js +2 -1
- package/src/index.js +9 -9
- package/src/{html-namespaces → namespaced-html}/index.js +1 -1
- package/test/imports.test.js +6 -4
- package/test/index.js +1 -1
- package/test/scoped-js.test.js +2 -2
- /package/src/{html-bindings → data-binding}/targets.browser.js +0 -0
- /package/src/{html-namespaces → namespaced-html}/targets.browser.js +0 -0
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.60",
|
|
18
18
|
"license": "MIT",
|
|
19
19
|
"repository": {
|
|
20
20
|
"type": "git",
|
|
@@ -29,8 +29,8 @@
|
|
|
29
29
|
"scripts": {
|
|
30
30
|
"test": "mocha --extension .test.js --exit",
|
|
31
31
|
"test:coverage": "c8 --reporter=text-lcov npm run test | coveralls",
|
|
32
|
-
"build": "esbuild main=src/targets.browser.js
|
|
33
|
-
"preversion": "npm run build && git add -A dist",
|
|
32
|
+
"build": "esbuild main=src/targets.browser.js namespaced-html=src/namespaced-html/targets.browser.js scoped-css=src/scoped-css/targets.browser.js scoped-js=src/scoped-js/targets.browser.js context-api=src/context-api/targets.browser.js bindings-api=src/bindings-api/targets.browser.js html-imports=src/html-imports/targets.browser.js data-binding=src/data-binding/targets.browser.js --bundle --minify --sourcemap --outdir=dist",
|
|
33
|
+
"preversion": "npm run test && npm run build && git add -A dist",
|
|
34
34
|
"postversion": "npm publish",
|
|
35
35
|
"postpublish": "git push && git push --tags"
|
|
36
36
|
},
|
|
@@ -41,7 +41,7 @@
|
|
|
41
41
|
"@webqit/util": "^0.8.11"
|
|
42
42
|
},
|
|
43
43
|
"devDependencies": {
|
|
44
|
-
"@webqit/oohtml-ssr": "^1.2.
|
|
44
|
+
"@webqit/oohtml-ssr": "^1.2.19",
|
|
45
45
|
"chai": "^4.3.4",
|
|
46
46
|
"coveralls": "^3.1.1",
|
|
47
47
|
"esbuild": "^0.14.43",
|
|
@@ -9,6 +9,19 @@ export default class _HTMLBindingsProvider extends HTMLContextProvider {
|
|
|
9
9
|
|
|
10
10
|
static type = 'bindings';
|
|
11
11
|
|
|
12
|
+
/**
|
|
13
|
+
* @createRequest
|
|
14
|
+
*/
|
|
15
|
+
static createRequest( fields = {} ) {
|
|
16
|
+
const request = super.createRequest( fields );
|
|
17
|
+
if ( request.detail?.startsWith( '@' ) ) {
|
|
18
|
+
const [ contextName, ...detail ] = request.detail.slice( 1 ).split( '.' ).map( s => s.trim() );
|
|
19
|
+
request.contextName = contextName;
|
|
20
|
+
request.detail = detail.join( '.' );
|
|
21
|
+
}
|
|
22
|
+
return request;
|
|
23
|
+
}
|
|
24
|
+
|
|
12
25
|
/**
|
|
13
26
|
* @matchesRequest
|
|
14
27
|
*/
|
|
@@ -15,9 +15,11 @@ export { Observer }
|
|
|
15
15
|
*/
|
|
16
16
|
export default function init( $config = {} ) {
|
|
17
17
|
const { config, window } = _init.call( this, 'bindings-api', $config, {
|
|
18
|
-
context: { attr: {
|
|
18
|
+
context: { attr: { bindingscontext: 'bindings' }, },
|
|
19
19
|
api: { bind: 'bind', bindings: 'bindings', },
|
|
20
20
|
} );
|
|
21
|
+
config.CONTEXT_API = window.webqit.oohtml.configs.CONTEXT_API;
|
|
22
|
+
config.context.attr.contextname = config.CONTEXT_API.attr.contextname; // Inherit this
|
|
21
23
|
window.webqit.HTMLBindingsProvider = class extends _HTMLBindingsProvider {
|
|
22
24
|
static get config() { return config; }
|
|
23
25
|
};
|
|
@@ -31,7 +33,8 @@ export default function init( $config = {} ) {
|
|
|
31
33
|
* The internal bindings object
|
|
32
34
|
* within elements and the document object.
|
|
33
35
|
*/
|
|
34
|
-
function getBindingsObject( node ) {
|
|
36
|
+
function getBindingsObject( config, node ) {
|
|
37
|
+
const window = this;
|
|
35
38
|
if ( !_( node ).has( 'bindings' ) ) {
|
|
36
39
|
const bindingsObj = Object.create( null );
|
|
37
40
|
_( node ).set( 'bindings', bindingsObj );
|
|
@@ -41,6 +44,13 @@ function getBindingsObject( node ) {
|
|
|
41
44
|
detachBindingsContext.call( this, node, mutation.key );
|
|
42
45
|
} else { attachBindingsContext.call( this, node, mutation.key ); }
|
|
43
46
|
}
|
|
47
|
+
const props = Object.keys( bindingsObj );
|
|
48
|
+
const targetNode = node === window.document ? window.document.documentElement : node;
|
|
49
|
+
if ( props.length ) {
|
|
50
|
+
targetNode.setAttribute( config.context.attr.bindingscontext, props.join( ' ') );
|
|
51
|
+
} else {
|
|
52
|
+
targetNode.toggleAttribute( config.context.attr.bindingscontext, false );
|
|
53
|
+
}
|
|
44
54
|
} );
|
|
45
55
|
}
|
|
46
56
|
return _( node ).get( 'bindings' );
|
|
@@ -61,14 +71,15 @@ function detachBindingsContext( host, key ) {
|
|
|
61
71
|
/**
|
|
62
72
|
* Exposes Bindings with native APIs.
|
|
63
73
|
*
|
|
74
|
+
* @param Object config
|
|
64
75
|
* @param document|Element target
|
|
65
76
|
* @param Object bindings
|
|
66
77
|
* @param Object params
|
|
67
78
|
*
|
|
68
79
|
* @return Void
|
|
69
80
|
*/
|
|
70
|
-
function applyBindings( target, bindings, { merge, diff, namespace } = {} ) {
|
|
71
|
-
const bindingsObj = getBindingsObject.call( this, target );
|
|
81
|
+
function applyBindings( config, target, bindings, { merge, diff, namespace } = {} ) {
|
|
82
|
+
const bindingsObj = getBindingsObject.call( this, config, target );
|
|
72
83
|
const $params = { diff, namespace };
|
|
73
84
|
const exitingKeys = merge ? [] : Observer.ownKeys( bindingsObj, $params ).filter( key => !( key in bindings ) );
|
|
74
85
|
return Observer.batch( bindingsObj, () => {
|
|
@@ -93,15 +104,15 @@ function exposeAPIs( config ) {
|
|
|
93
104
|
if ( config.api.bindings in window.Element.prototype ) { throw new Error( `The "Element" class already has a "${ config.api.bindings }" property!` ); }
|
|
94
105
|
// Definitions
|
|
95
106
|
Object.defineProperty( window.document, config.api.bind, { value: function( bindings, config = {} ) {
|
|
96
|
-
return applyBindings.call( window, window.document, bindings
|
|
107
|
+
return applyBindings.call( window, config, window.document, bindings );
|
|
97
108
|
} });
|
|
98
109
|
Object.defineProperty( window.document, config.api.bindings, { get: function() {
|
|
99
|
-
return Observer.proxy( getBindingsObject.call( window, window.document ) );
|
|
110
|
+
return Observer.proxy( getBindingsObject.call( window, config, window.document ) );
|
|
100
111
|
} });
|
|
101
112
|
Object.defineProperty( window.Element.prototype, config.api.bind, { value: function( bindings, config = {} ) {
|
|
102
|
-
return applyBindings.call( window, this, bindings
|
|
113
|
+
return applyBindings.call( window, config, this, bindings );
|
|
103
114
|
} });
|
|
104
115
|
Object.defineProperty( window.Element.prototype, config.api.bindings, { get: function() {
|
|
105
|
-
return Observer.proxy( getBindingsObject.call( window, this ) );
|
|
116
|
+
return Observer.proxy( getBindingsObject.call( window, config, this ) );
|
|
106
117
|
} } );
|
|
107
118
|
}
|
package/src/context-api/index.js
CHANGED
|
@@ -23,6 +23,7 @@ export {
|
|
|
23
23
|
*/
|
|
24
24
|
export default function init( $config = {} ) {
|
|
25
25
|
const { config, window } = _init.call( this, 'context-api', $config, {
|
|
26
|
+
attr: { contextname: 'contextname', },
|
|
26
27
|
api: { context: 'context', },
|
|
27
28
|
} );
|
|
28
29
|
window.webqit.HTMLContextProvider = HTMLContextProvider;
|
|
@@ -16,7 +16,7 @@ import { _, _init } from '../util.js';
|
|
|
16
16
|
*/
|
|
17
17
|
export default function init( $config = {} ) {
|
|
18
18
|
const { config, window } = _init.call( this, 'html-bindings', $config, {
|
|
19
|
-
attr: {
|
|
19
|
+
attr: { binding: 'binding', itemIndex: 'data-index' },
|
|
20
20
|
tokens: { nodeType: 'processing-instruction', tagStart: '?{', tagEnd: '}?', stateStart: '; [=', stateEnd: ']' },
|
|
21
21
|
staticsensitivity: true,
|
|
22
22
|
isomorphic: true,
|
|
@@ -24,7 +24,7 @@ export default function init( $config = {} ) {
|
|
|
24
24
|
config.CONTEXT_API = window.webqit.oohtml.configs.CONTEXT_API;
|
|
25
25
|
config.BINDINGS_API = window.webqit.oohtml.configs.BINDINGS_API;
|
|
26
26
|
config.HTML_IMPORTS = window.webqit.oohtml.configs.HTML_IMPORTS;
|
|
27
|
-
config.attrSelector = `[${ window.CSS.escape( config.attr.
|
|
27
|
+
config.attrSelector = `[${ window.CSS.escape( config.attr.binding ) }]`;
|
|
28
28
|
const discreteBindingsMatch = ( start, end ) => {
|
|
29
29
|
const starting = `starts-with(., "${ start }")`;
|
|
30
30
|
const ending = `substring(., string-length(.) - string-length("${ end }") + 1) = "${ end }"`;
|
|
@@ -56,7 +56,7 @@ function realtime( config ) {
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
function createDynamicScope( config, root ) {
|
|
59
|
-
if ( _( root ).has( '
|
|
59
|
+
if ( _( root ).has( 'data-binding' ) ) return _( root ).get( 'data-binding' );
|
|
60
60
|
const scope = {}, abortController = new AbortController;
|
|
61
61
|
scope.$set__ = function( node, prop, val ) {
|
|
62
62
|
node && ( node[ prop ] = val );
|
|
@@ -73,22 +73,22 @@ function createDynamicScope( config, root ) {
|
|
|
73
73
|
},
|
|
74
74
|
has: ( e, recieved, next ) => { return next( true ); }
|
|
75
75
|
} );
|
|
76
|
-
const instance = { scope, abortController,
|
|
77
|
-
_( root ).set( '
|
|
76
|
+
const instance = { scope, abortController, bindings: new Map };
|
|
77
|
+
_( root ).set( 'data-binding', instance );
|
|
78
78
|
return instance;
|
|
79
79
|
}
|
|
80
80
|
|
|
81
81
|
function cleanup( ...entries ) {
|
|
82
82
|
for ( const node of entries ) {
|
|
83
83
|
const root = node.nodeName === '#text' ? node.parentNode : node;
|
|
84
|
-
const {
|
|
85
|
-
if ( !
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if ( !
|
|
84
|
+
const { bindings, abortController } = _( root ).get( 'data-binding' ) || {};
|
|
85
|
+
if ( !bindings?.has( node ) ) return;
|
|
86
|
+
bindings.get( node ).state.dispose();
|
|
87
|
+
bindings.get( node ).signals.forEach( s => s.abort() );
|
|
88
|
+
bindings.delete( node );
|
|
89
|
+
if ( !bindings.size ) {
|
|
90
90
|
abortController.abort();
|
|
91
|
-
_( root ).delete( '
|
|
91
|
+
_( root ).delete( 'data-binding' );
|
|
92
92
|
}
|
|
93
93
|
}
|
|
94
94
|
}
|
|
@@ -127,24 +127,24 @@ async function mountDiscreteBindings( config, ...entries ) {
|
|
|
127
127
|
}, [] );
|
|
128
128
|
|
|
129
129
|
for ( const { textNode, template, anchorNode } of instances ) {
|
|
130
|
-
const { scope: env,
|
|
130
|
+
const { scope: env, bindings } = createDynamicScope( config, textNode.parentNode );
|
|
131
131
|
let source = '';
|
|
132
132
|
source += `let content = ((${ template.expr }) ?? '') + '';`;
|
|
133
133
|
source += `$set__(this, 'nodeValue', content);`;
|
|
134
134
|
if ( anchorNode ) { source += `$set__($anchorNode__, 'nodeValue', \`${ config.tokens.tagStart }${ template.expr }${ config.tokens.stateStart }\` + content.length + \`${ config.tokens.stateEnd } ${ config.tokens.tagEnd }\`);`; }
|
|
135
135
|
const compiled = new StatefulAsyncFunction( '$signals__', `$anchorNode__`, source, { env } );
|
|
136
136
|
const signals = [];
|
|
137
|
-
|
|
137
|
+
bindings.set( textNode, { compiled, signals, state: await compiled.call( textNode, signals, anchorNode ), } );
|
|
138
138
|
}
|
|
139
139
|
}
|
|
140
140
|
|
|
141
141
|
async function mountInlineBindings( config, ...entries ) {
|
|
142
142
|
for ( const node of entries ) {
|
|
143
|
-
const source = parseInlineBindings( config, node.getAttribute( config.attr.
|
|
144
|
-
const { scope: env,
|
|
143
|
+
const source = parseInlineBindings( config, node.getAttribute( config.attr.binding ) );
|
|
144
|
+
const { scope: env, bindings } = createDynamicScope( config, node );
|
|
145
145
|
const compiled = new StatefulAsyncFunction( '$signals__', source, { env } );
|
|
146
146
|
const signals = [];
|
|
147
|
-
|
|
147
|
+
bindings.set( node, { compiled, signals, state: await compiled.call( node, signals ), } );
|
|
148
148
|
}
|
|
149
149
|
}
|
|
150
150
|
|
|
@@ -87,7 +87,7 @@ export default function( config ) {
|
|
|
87
87
|
priv.autoRestoreRealtime?.disconnect();
|
|
88
88
|
if ( callback ) callback();
|
|
89
89
|
const restore = () => {
|
|
90
|
-
priv.anchorNode
|
|
90
|
+
priv.anchorNode?.replaceWith( this.el );
|
|
91
91
|
priv.anchorNode = null;
|
|
92
92
|
this.el.setAttribute( 'data-nodecount', 0 );
|
|
93
93
|
};
|
|
@@ -18,12 +18,13 @@ import { _, _init } from '../util.js';
|
|
|
18
18
|
export default function init( $config = {} ) {
|
|
19
19
|
const { config, realdom, window } = _init.call( this, 'html-imports', $config, {
|
|
20
20
|
template: { attr: { moduledef: 'def', fragmentdef: 'def', extends: 'extends', inherits: 'inherits' }, api: { modules: 'modules', moduledef: 'def' }, },
|
|
21
|
-
context: { attr: { importscontext: 'importscontext',
|
|
21
|
+
context: { attr: { importscontext: 'importscontext', }, api: { import: 'import' }, },
|
|
22
22
|
import: { tagName: 'import', attr: { moduleref: 'ref' }, },
|
|
23
23
|
staticsensitivity: true,
|
|
24
24
|
isomorphic: true,
|
|
25
25
|
} );
|
|
26
26
|
config.CONTEXT_API = window.webqit.oohtml.configs.CONTEXT_API;
|
|
27
|
+
config.context.attr.contextname = config.CONTEXT_API.attr.contextname; // Inherit this
|
|
27
28
|
config.templateSelector = `template[${ window.CSS.escape( config.template.attr.moduledef ) }]`;
|
|
28
29
|
config.ownerContextSelector = [ config.context.attr.contextname, config.context.attr.importscontext ].map( a => `[${ window.CSS.escape( a ) }]` ).join( ',' );
|
|
29
30
|
config.slottedElementsSelector = `[${ window.CSS.escape( config.template.attr.fragmentdef ) }]`;
|
package/src/index.js
CHANGED
|
@@ -3,13 +3,13 @@
|
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
5
|
import Observer from '@webqit/observer';
|
|
6
|
+
import NamespacedHTML from './namespaced-html/index.js';
|
|
7
|
+
import ScopedCSS from './scoped-css/index.js';
|
|
8
|
+
import ScopedJS from './scoped-js/index.js';
|
|
6
9
|
import ContextAPI from './context-api/index.js';
|
|
7
10
|
import BindingsAPI from './bindings-api/index.js';
|
|
8
11
|
import HTMLImports from './html-imports/index.js';
|
|
9
|
-
import
|
|
10
|
-
import HTMLNamespaces from './html-namespaces/index.js';
|
|
11
|
-
import ScopedCSS from './scoped-css/index.js';
|
|
12
|
-
import ScopedJS from './scoped-js/index.js';
|
|
12
|
+
import DataBinding from './data-binding/index.js';
|
|
13
13
|
|
|
14
14
|
/**
|
|
15
15
|
* @exports
|
|
@@ -22,12 +22,12 @@ export { Observer }
|
|
|
22
22
|
export default function init( configs = {} ) {
|
|
23
23
|
if ( !this.webqit ) { this.webqit = {}; }
|
|
24
24
|
// --------------
|
|
25
|
-
|
|
26
|
-
BindingsAPI.call( this, ( configs.BINDINGS_API || {} ) );
|
|
27
|
-
HTMLImports.call( this, ( configs.HTML_IMPORTS || {} ) ); // Depends ContextAPI
|
|
28
|
-
HTMLBindings.call( this, ( configs.HTML_BRACELETS || {} ) ); // Depends ContextAPI, BindingsAPI, HTMLImports
|
|
29
|
-
HTMLNamespaces.call( this, ( configs.HTML_NAMESPACES || {} ) );
|
|
25
|
+
NamespacedHTML.call( this, ( configs.NAMESPACED_HTML || {} ) );
|
|
30
26
|
ScopedCSS.call( this, ( configs.SCOPED_CSS || {} ) );
|
|
31
27
|
ScopedJS.call( this, ( configs.SCOPED_JS || {} ) );
|
|
28
|
+
ContextAPI.call( this, ( configs.CONTEXT_API || {} ) );
|
|
29
|
+
BindingsAPI.call( this, ( configs.BINDINGS_API || {} ) ); // Depends on ContextAPI
|
|
30
|
+
HTMLImports.call( this, ( configs.HTML_IMPORTS || {} ) ); // Depends on ContextAPI
|
|
31
|
+
DataBinding.call( this, ( configs.DATA_BINDING || {} ) ); // Depends on ContextAPI, BindingsAPI, HTMLImports
|
|
32
32
|
// --------------
|
|
33
33
|
}
|
|
@@ -13,7 +13,7 @@ export { Observer }
|
|
|
13
13
|
* @param Object $config
|
|
14
14
|
*/
|
|
15
15
|
export default function init( $config = {} ) {
|
|
16
|
-
const { config, window } = _init.call( this, 'html
|
|
16
|
+
const { config, window } = _init.call( this, 'namespaced-html', $config, {
|
|
17
17
|
id: { attr: 'id' },
|
|
18
18
|
namespace: { attr: 'namespace', api: 'namespace', },
|
|
19
19
|
target: { attr: ':target', event: ':target', scrolling: true },
|
package/test/imports.test.js
CHANGED
|
@@ -162,9 +162,9 @@ describe(`HTML Imports`, function() {
|
|
|
162
162
|
const body = `
|
|
163
163
|
<div importscontext="temp0/temp1">
|
|
164
164
|
<textarea def="input"></textarea>
|
|
165
|
-
|
|
165
|
+
<!--<import ref="#input" data-nodecount="1"></import>-->
|
|
166
166
|
</div>`;
|
|
167
|
-
const { document } = createDocument( head, body );
|
|
167
|
+
const { document } = createDocument( head, body, window => window.webqit.env = 'client' );
|
|
168
168
|
await delay( 20 );
|
|
169
169
|
|
|
170
170
|
const routingElement = document.body.firstElementChild;
|
|
@@ -195,10 +195,12 @@ describe(`HTML Imports`, function() {
|
|
|
195
195
|
const body = `
|
|
196
196
|
<div importscontext="temp0/temp1">
|
|
197
197
|
<textarea def="input"></textarea>
|
|
198
|
-
|
|
198
|
+
<!--<import ref="#input" data-nodecount="1"></import>-->
|
|
199
199
|
</div>`;
|
|
200
|
-
const { document } = createDocument( head, body );
|
|
200
|
+
const { document } = createDocument( head, body, window => window.webqit.env = 'client' );
|
|
201
|
+
console.log('-----------1');
|
|
201
202
|
await delay( 20 );
|
|
203
|
+
console.log('-----------2');
|
|
202
204
|
|
|
203
205
|
const routingElement = document.body.firstElementChild;
|
|
204
206
|
expect( routingElement.firstElementChild.nodeName ).to.eq( 'TEXTAREA' );
|
package/test/index.js
CHANGED
|
@@ -21,7 +21,7 @@ export function createDocument( head = '', body = '', callback = null, ) {
|
|
|
21
21
|
<!DOCTYPE html>
|
|
22
22
|
<html>
|
|
23
23
|
<head>
|
|
24
|
-
<meta name="
|
|
24
|
+
<meta name="$f-compiler-url" content="../stateful-js/dist/compiler.js">
|
|
25
25
|
<script ssr src="/dist/main.js"></script>
|
|
26
26
|
${ head }
|
|
27
27
|
</head>
|
package/test/scoped-js.test.js
CHANGED
|
@@ -14,12 +14,12 @@ describe(`Test: Scoped JS`, function() {
|
|
|
14
14
|
<h1>Hello World!</h1>
|
|
15
15
|
<script scoped stateful>
|
|
16
16
|
testRecords.push( this );
|
|
17
|
-
console.log('-------scoped JS here.');
|
|
17
|
+
console.log('-------scoped JS here.', this);
|
|
18
18
|
</script>`;
|
|
19
19
|
|
|
20
20
|
const window = createDocument( head, body );
|
|
21
21
|
window.testRecords = [];
|
|
22
|
-
await delay(
|
|
22
|
+
await delay( 300 ); // Takes time to dynamically load Reflex compiler
|
|
23
23
|
|
|
24
24
|
expect( window.testRecords ).to.have.length( 1 );
|
|
25
25
|
expect( window.testRecords[ 0 ] ).to.eql( window.document.body );
|
|
File without changes
|
|
File without changes
|