@webqit/oohtml 2.1.8 → 2.1.10
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 +2 -0
- package/dist/bindings-api.js.map +7 -0
- 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/html-modules.js +1 -1
- package/dist/html-modules.js.map +3 -3
- package/dist/main.js +9 -9
- package/dist/main.js.map +3 -3
- package/dist/namespace-api.js +2 -0
- package/dist/namespace-api.js.map +7 -0
- package/dist/scoped-js.js +7 -7
- package/dist/scoped-js.js.map +3 -3
- package/package.json +6 -6
- package/src/bindings-api/index.js +84 -0
- package/src/context-api/HTMLContext.js +3 -3
- package/src/context-api/index.js +13 -17
- package/src/html-imports/_HTMLImportElement.js +13 -15
- package/src/html-imports/index.js +20 -26
- package/src/html-modules/HTMLExportsManager.js +17 -17
- package/src/html-modules/_HTMLImportsContext.js +6 -6
- package/src/html-modules/index.js +31 -37
- package/src/index.js +9 -11
- package/src/{namespaced-html → namespace-api}/index.js +35 -40
- package/src/scoped-js/Compiler.js +7 -7
- package/src/scoped-js/index.js +19 -24
- package/src/targets.browser.js +2 -2
- package/src/util.js +13 -1
- package/test/bindings-api.test.js +42 -0
- package/test/index.js +11 -9
- package/dist/namespaced-html.js +0 -2
- package/dist/namespaced-html.js.map +0 -7
- package/dist/state-api.js +0 -2
- package/dist/state-api.js.map +0 -7
- package/src/state-api/index.js +0 -59
- package/test/state-api.test.js +0 -34
- /package/src/{namespaced-html → bindings-api}/targets.browser.js +0 -0
- /package/src/{state-api → namespace-api}/targets.browser.js +0 -0
- /package/test/{namespaced-html.test.js → namespace-api.test.js} +0 -0
|
@@ -2,39 +2,33 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
|
-
import wqDom from '@webqit/dom';
|
|
6
5
|
import Observer from '@webqit/observer';
|
|
7
6
|
import _HTMLImportsContext from './_HTMLImportsContext.js';
|
|
8
7
|
import HTMLExportsManager from './HTMLExportsManager.js';
|
|
9
|
-
import { _ } from '../util.js';
|
|
8
|
+
import { _, _init } from '../util.js';
|
|
10
9
|
|
|
11
10
|
/**
|
|
12
11
|
* Initializes HTML Modules.
|
|
13
12
|
*
|
|
14
|
-
* @param Object $
|
|
13
|
+
* @param Object $config
|
|
15
14
|
*
|
|
16
15
|
* @return Void
|
|
17
16
|
*/
|
|
18
|
-
export default function init( $
|
|
19
|
-
const
|
|
20
|
-
if ( !window.wq ) { window.wq = {}; }
|
|
21
|
-
window.wq.Observer = Observer;
|
|
22
|
-
window.wq.HTMLImportsContext = class extends _HTMLImportsContext {
|
|
23
|
-
static get params() { return params; }
|
|
24
|
-
};
|
|
25
|
-
// -------
|
|
26
|
-
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
17
|
+
export default function init( $config = {} ) {
|
|
18
|
+
const { config, window } = _init.call( this, 'html-modules', $config, {
|
|
27
19
|
template: { attr: { exportid: 'exportid', extends: 'extends', inherits: 'inherits' }, api: { modules: 'modules', exportid: 'exportid' }, },
|
|
28
20
|
context: { attr: { importscontext: 'importscontext', contextname: 'contextname' }, api: { modules: 'modules' }, },
|
|
29
21
|
export: { attr: { exportid: 'exportid' }, },
|
|
30
22
|
staticsensitivity: true,
|
|
31
23
|
} );
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
24
|
+
config.templateSelector = `template[${ window.CSS.escape( config.template.attr.exportid ) }]`;
|
|
25
|
+
config.ownerContextSelector = [ config.context.attr.contextname, config.context.attr.importscontext ].map( a => `[${ window.CSS.escape( a ) }]` ).join( ',' );
|
|
26
|
+
window.webqit.HTMLImportsContext = class extends _HTMLImportsContext {
|
|
27
|
+
static get config() { return config; }
|
|
28
|
+
};
|
|
29
|
+
window.webqit.Observer = Observer;
|
|
30
|
+
exposeModulesObjects.call( window, config );
|
|
31
|
+
realtime.call( window, config );
|
|
38
32
|
}
|
|
39
33
|
|
|
40
34
|
export { Observer }
|
|
@@ -64,37 +58,37 @@ export function getModulesObject( node, autoCreate = true ) {
|
|
|
64
58
|
/**
|
|
65
59
|
* Exposes HTML Modules with native APIs.
|
|
66
60
|
*
|
|
67
|
-
* @param Object
|
|
61
|
+
* @param Object config
|
|
68
62
|
*
|
|
69
63
|
* @return Void
|
|
70
64
|
*/
|
|
71
|
-
function exposeModulesObjects(
|
|
65
|
+
function exposeModulesObjects( config ) {
|
|
72
66
|
const window = this;
|
|
73
67
|
// Assertions
|
|
74
|
-
if (
|
|
75
|
-
if (
|
|
76
|
-
if (
|
|
68
|
+
if ( config.context.api.modules in window.document ) { throw new Error( `document already has a "${ config.context.api.modules }" property!` ); }
|
|
69
|
+
if ( config.template.api.modules in window.HTMLElement.prototype ) { throw new Error( `The "HTMLElement" 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!` ); }
|
|
77
71
|
// Definitions
|
|
78
|
-
Object.defineProperty( window.document,
|
|
72
|
+
Object.defineProperty( window.document, config.context.api.modules, { get: function() {
|
|
79
73
|
return getModulesObject( window.document );
|
|
80
74
|
} } );
|
|
81
|
-
Object.defineProperty( window.HTMLElement.prototype,
|
|
75
|
+
Object.defineProperty( window.HTMLElement.prototype, config.template.api.modules, { get: function() {
|
|
82
76
|
return getModulesObject( this );
|
|
83
77
|
} } );
|
|
84
|
-
Object.defineProperty( window.HTMLTemplateElement.prototype,
|
|
85
|
-
return this.
|
|
78
|
+
Object.defineProperty( window.HTMLTemplateElement.prototype, config.template.api.exportid, { get: function() {
|
|
79
|
+
return this.getAttribute( config.template.attr.exportid );
|
|
86
80
|
} } );
|
|
87
81
|
}
|
|
88
82
|
|
|
89
83
|
/**
|
|
90
84
|
* Performs realtime capture of elements and builds their contents graph.
|
|
91
85
|
*
|
|
92
|
-
* @param Object
|
|
86
|
+
* @param Object config
|
|
93
87
|
*
|
|
94
88
|
* @return Void
|
|
95
89
|
*/
|
|
96
|
-
function realtime(
|
|
97
|
-
const window = this, { dom, HTMLImportsContext } = window.
|
|
90
|
+
function realtime( config ) {
|
|
91
|
+
const window = this, { dom, HTMLImportsContext } = window.webqit;
|
|
98
92
|
// ------------
|
|
99
93
|
const attachImportsContext = host => {
|
|
100
94
|
const contextId = HTMLImportsContext.createId( host );
|
|
@@ -103,15 +97,15 @@ function realtime( params ) {
|
|
|
103
97
|
const detachImportsContext = ( host, force ) => {
|
|
104
98
|
const contextId = HTMLImportsContext.createId( host );
|
|
105
99
|
HTMLImportsContext.detachFrom( host, contextId, cx => {
|
|
106
|
-
return force || host.matches && !host.matches(
|
|
100
|
+
return force || host.matches && !host.matches( config.ownerContextSelector ) && !Object.keys( cx.modules ).length;
|
|
107
101
|
} );
|
|
108
102
|
};
|
|
109
103
|
// ------------
|
|
110
|
-
dom.realtime( window.document ).observe( [
|
|
104
|
+
dom.realtime( window.document ).observe( [ config.templateSelector, config.ownerContextSelector ], record => {
|
|
111
105
|
record.entrants.forEach( entry => {
|
|
112
|
-
if ( entry.matches(
|
|
106
|
+
if ( entry.matches( config.templateSelector ) ) {
|
|
113
107
|
Object.defineProperty( entry, 'scoped', { value: entry.hasAttribute( 'scoped' ) } );
|
|
114
|
-
const moduleExport = new HTMLExportsManager( entry,
|
|
108
|
+
const moduleExport = new HTMLExportsManager( window, entry, config );
|
|
115
109
|
moduleExport.ownerContext = entry.scoped ? record.target : window.document;
|
|
116
110
|
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
117
111
|
if ( moduleExport.exportId ) { Observer.set( ownerContextModulesObj, moduleExport.exportId, entry ); }
|
|
@@ -124,8 +118,8 @@ function realtime( params ) {
|
|
|
124
118
|
}
|
|
125
119
|
} );
|
|
126
120
|
record.exits.forEach( entry => {
|
|
127
|
-
if ( entry.matches(
|
|
128
|
-
const moduleExport = HTMLExportsManager.instance( entry,
|
|
121
|
+
if ( entry.matches( config.templateSelector ) ) {
|
|
122
|
+
const moduleExport = HTMLExportsManager.instance( window, entry, config );
|
|
129
123
|
const ownerContextModulesObj = getModulesObject( moduleExport.ownerContext );
|
|
130
124
|
if ( moduleExport.exportId ) { Observer.deleteProperty( ownerContextModulesObj, moduleExport.exportId ); }
|
|
131
125
|
detachImportsContext( moduleExport.ownerContext );
|
|
@@ -133,5 +127,5 @@ function realtime( params ) {
|
|
|
133
127
|
detachImportsContext( entry, true );
|
|
134
128
|
}
|
|
135
129
|
} );
|
|
136
|
-
}, { subtree: true, timing: 'sync', staticSensitivity:
|
|
130
|
+
}, { subtree: true, timing: 'sync', staticSensitivity: config.staticsensitivity } );
|
|
137
131
|
}
|
package/src/index.js
CHANGED
|
@@ -3,27 +3,25 @@
|
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
5
|
import Observer from '@webqit/observer';
|
|
6
|
-
import
|
|
6
|
+
import BindingsAPI from './bindings-api/index.js';
|
|
7
7
|
import ContextAPI from './context-api/index.js';
|
|
8
|
+
import NamespaceAPI from './namespace-api/index.js';
|
|
8
9
|
import HTMLModules from './html-modules/index.js';
|
|
9
10
|
import HTMLImports from './html-imports/index.js';
|
|
10
|
-
import NamespacedHTML from './namespaced-html/index.js';
|
|
11
11
|
import ScopedJS from './scoped-js/index.js';
|
|
12
12
|
|
|
13
13
|
/**
|
|
14
14
|
* @init
|
|
15
15
|
*/
|
|
16
16
|
export default function init( configs = {} ) {
|
|
17
|
-
if ( !this.
|
|
18
|
-
if ( this.wq.oohtml ) return;
|
|
19
|
-
this.wq.oohtml = {};
|
|
17
|
+
if ( !this.webqit ) { this.webqit = {}; }
|
|
20
18
|
// --------------
|
|
21
|
-
|
|
22
|
-
ContextAPI.call( this, ( configs.
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
ScopedJS.call( this, ( configs.
|
|
19
|
+
BindingsAPI.call(this, ( configs.BINDINGS_API || {} ) );
|
|
20
|
+
ContextAPI.call( this, ( configs.CONTEXT_API || {} ) );
|
|
21
|
+
NamespaceAPI.call(this, ( configs.NAMESPACE_API || {} ) );
|
|
22
|
+
HTMLModules.call( this, ( configs.HTML_MODULES || {} ) );
|
|
23
|
+
HTMLImports.call( this, ( configs.HTML_IMPORTS || {} ) );
|
|
24
|
+
ScopedJS.call( this, ( configs.SCOPED_JS || {} ) );
|
|
27
25
|
// --------------
|
|
28
26
|
}
|
|
29
27
|
|
|
@@ -3,30 +3,25 @@
|
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
5
|
import Observer from '@webqit/observer';
|
|
6
|
-
import
|
|
7
|
-
import { _ } from '../util.js';
|
|
6
|
+
import { _, _init } from '../util.js';
|
|
8
7
|
|
|
9
8
|
/**
|
|
10
9
|
* @init
|
|
11
10
|
*
|
|
12
|
-
* @param Object $
|
|
11
|
+
* @param Object $config
|
|
13
12
|
*/
|
|
14
|
-
export default function init( $
|
|
15
|
-
|
|
16
|
-
if ( !window.wq ) { window.wq = {}; }
|
|
17
|
-
window.wq.Observer = Observer;
|
|
18
|
-
// -------
|
|
19
|
-
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
13
|
+
export default function init( $config = {} ) {
|
|
14
|
+
const { config, window } = _init.call( this, 'namespace-api', $config, {
|
|
20
15
|
attr: { namespace: 'namespace', id: ':id', },
|
|
21
16
|
api: { namespace: 'namespace', },
|
|
22
17
|
staticsensitivity: true,
|
|
23
18
|
eagermode: true,
|
|
24
19
|
} );
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
exposeNamespaceObjects.call(
|
|
29
|
-
realtime.call(
|
|
20
|
+
config.idSelector = `[${ window.CSS.escape( config.attr.id ) }]`;
|
|
21
|
+
config.namespaceSelector = `[${ window.CSS.escape( config.attr.namespace ) }]`;
|
|
22
|
+
window.webqit.Observer = Observer;
|
|
23
|
+
exposeNamespaceObjects.call( window, config );
|
|
24
|
+
realtime.call( window, config );
|
|
30
25
|
}
|
|
31
26
|
|
|
32
27
|
export { Observer }
|
|
@@ -34,21 +29,21 @@ export { Observer }
|
|
|
34
29
|
/**
|
|
35
30
|
* Exposes Namespaced HTML with native APIs.
|
|
36
31
|
*
|
|
37
|
-
* @param Object
|
|
32
|
+
* @param Object config
|
|
38
33
|
*
|
|
39
34
|
* @return Void
|
|
40
35
|
*/
|
|
41
|
-
function exposeNamespaceObjects(
|
|
36
|
+
function exposeNamespaceObjects( config ) {
|
|
42
37
|
const window = this;
|
|
43
38
|
// Assertions
|
|
44
|
-
if (
|
|
45
|
-
if (
|
|
39
|
+
if ( config.api.namespace in window.document ) { throw new Error( `document already has a "${ config.api.namespace }" property!` ); }
|
|
40
|
+
if ( config.api.namespace in window.Element.prototype ) { throw new Error( `The "Element" class already has a "${ config.api.namespace }" property!` ); }
|
|
46
41
|
// Definitions
|
|
47
|
-
Object.defineProperty( window.document,
|
|
48
|
-
return Observer.proxy( getNamespaceObject.call( window, window.document,
|
|
42
|
+
Object.defineProperty( window.document, config.api.namespace, { get: function() {
|
|
43
|
+
return Observer.proxy( getNamespaceObject.call( window, window.document, config ) );
|
|
49
44
|
} });
|
|
50
|
-
Object.defineProperty( window.Element.prototype,
|
|
51
|
-
return Observer.proxy( getNamespaceObject.call( window, this,
|
|
45
|
+
Object.defineProperty( window.Element.prototype, config.api.namespace, { get: function() {
|
|
46
|
+
return Observer.proxy( getNamespaceObject.call( window, this, config ) );
|
|
52
47
|
} } );
|
|
53
48
|
}
|
|
54
49
|
|
|
@@ -59,15 +54,15 @@ function exposeNamespaceObjects( params ) {
|
|
|
59
54
|
*
|
|
60
55
|
* @return Object
|
|
61
56
|
*/
|
|
62
|
-
function getNamespaceObject( node,
|
|
57
|
+
function getNamespaceObject( node, config ) {
|
|
63
58
|
const window = this;
|
|
64
59
|
if ( !_( node ).has( 'namespace' ) ) {
|
|
65
60
|
const namespaceObj = Object.create( null );
|
|
66
61
|
Observer.intercept( namespaceObj, 'get', ( event, receiver, next ) => {
|
|
67
|
-
if ( Observer.has( namespaceObj, event.key ) || !
|
|
68
|
-
const selector = `[${ window.CSS.escape(
|
|
62
|
+
if ( Observer.has( namespaceObj, event.key ) || !config.eagermode ) return next();
|
|
63
|
+
const selector = `[${ window.CSS.escape( config.attr.id ) }="${ event.key }"]`;
|
|
69
64
|
const resultNode = Array.from( node.querySelectorAll( selector ) ).filter( idNode => {
|
|
70
|
-
const ownerRoot = idNode.parentNode.closest(
|
|
65
|
+
const ownerRoot = idNode.parentNode.closest( config.namespaceSelector );
|
|
71
66
|
if ( node === window.document ) {
|
|
72
67
|
// Only IDs without a scope actually belong to the document scope
|
|
73
68
|
return !ownerRoot;
|
|
@@ -85,17 +80,17 @@ function getNamespaceObject( node, params ) {
|
|
|
85
80
|
/**
|
|
86
81
|
* Performs realtime capture of elements and builds their relationships.
|
|
87
82
|
*
|
|
88
|
-
* @param Object
|
|
83
|
+
* @param Object config
|
|
89
84
|
*
|
|
90
85
|
* @return Void
|
|
91
86
|
*/
|
|
92
|
-
function realtime(
|
|
93
|
-
const window = this, { dom } = window.
|
|
87
|
+
function realtime( config ) {
|
|
88
|
+
const window = this, { dom } = window.webqit;
|
|
94
89
|
// ----------------
|
|
95
90
|
const handle = ( target, entry, incoming ) => {
|
|
96
|
-
const identifier = entry.getAttribute(
|
|
97
|
-
const ownerRoot = target.closest(
|
|
98
|
-
const namespaceObj = getNamespaceObject.call( window, ownerRoot,
|
|
91
|
+
const identifier = entry.getAttribute( config.attr.id );
|
|
92
|
+
const ownerRoot = target.closest( config.namespaceSelector ) || _( entry ).get( 'ownerNamespace' ) || window.document;
|
|
93
|
+
const namespaceObj = getNamespaceObject.call( window, ownerRoot, config );
|
|
99
94
|
if ( incoming ) {
|
|
100
95
|
if ( Observer.get( namespaceObj, identifier ) !== entry ) {
|
|
101
96
|
_( entry ).set( 'ownerNamespace', ownerRoot );
|
|
@@ -106,17 +101,17 @@ function realtime( params ) {
|
|
|
106
101
|
Observer.deleteProperty( namespaceObj, identifier );
|
|
107
102
|
}
|
|
108
103
|
};
|
|
109
|
-
dom.realtime( window.document ).observe(
|
|
104
|
+
dom.realtime( window.document ).observe( config.idSelector, record => {
|
|
110
105
|
record.entrants.forEach( entry => handle( record.target, entry, true ) );
|
|
111
106
|
record.exits.forEach( entry => handle( record.target, entry, false ) );
|
|
112
|
-
}, { subtree: true, timing: 'sync', staticSensitivity:
|
|
107
|
+
}, { subtree: true, timing: 'sync', staticSensitivity: config.staticsensitivity } );
|
|
113
108
|
// ----------------
|
|
114
|
-
if (
|
|
115
|
-
dom.realtime( window.document, 'attr' ).observe(
|
|
116
|
-
const ownerRoot = record.target.parentNode?.closest(
|
|
117
|
-
const ownerRootNamespaceObj = getNamespaceObject.call( window, ownerRoot,
|
|
118
|
-
const namespaceObj = getNamespaceObject.call( window, record.target,
|
|
119
|
-
if ( record.target.matches(
|
|
109
|
+
if ( config.staticsensitivity ) {
|
|
110
|
+
dom.realtime( window.document, 'attr' ).observe( config.namespaceSelector, record => {
|
|
111
|
+
const ownerRoot = record.target.parentNode?.closest( config.namespaceSelector ) || _( record.target ).get( 'ownerNamespace' ) || window.document;
|
|
112
|
+
const ownerRootNamespaceObj = getNamespaceObject.call( window, ownerRoot, config );
|
|
113
|
+
const namespaceObj = getNamespaceObject.call( window, record.target, config );
|
|
114
|
+
if ( record.target.matches( config.namespaceSelector ) ) {
|
|
120
115
|
for ( const [ key, entry ] of Object.entries( ownerRootNamespaceObj ) ) {
|
|
121
116
|
if ( !record.target.contains( entry.parentNode ) ) continue;
|
|
122
117
|
Observer.deleteProperty( ownerRootNamespaceObj, key );
|
|
@@ -25,11 +25,11 @@ export default class Compiler {
|
|
|
25
25
|
}
|
|
26
26
|
|
|
27
27
|
// Set window property
|
|
28
|
-
constructor( window,
|
|
28
|
+
constructor( window, config, executeCallback ) {
|
|
29
29
|
this.window = window;
|
|
30
|
-
this.
|
|
30
|
+
this.config = config;
|
|
31
31
|
// This is a global function
|
|
32
|
-
window.
|
|
32
|
+
window.webqit.oohtml.Script.run = ( execHash ) => {
|
|
33
33
|
const exec = this.constructor.fromHash( execHash );
|
|
34
34
|
if ( !exec ) throw new Error( `Argument must be a valid exec hash.` );
|
|
35
35
|
const { script, compiledScript, thisContext } = exec;
|
|
@@ -37,7 +37,7 @@ export default class Compiler {
|
|
|
37
37
|
if ( !thisContext.scripts ) { Object.defineProperty( thisContext, 'scripts', { value: new Set } ); }
|
|
38
38
|
thisContext.scripts.add( script );
|
|
39
39
|
}
|
|
40
|
-
switch (
|
|
40
|
+
switch ( config.script.retention ) {
|
|
41
41
|
case 'dispose':
|
|
42
42
|
script.remove();
|
|
43
43
|
break;
|
|
@@ -54,7 +54,7 @@ export default class Compiler {
|
|
|
54
54
|
// Compile scipt
|
|
55
55
|
compile( script, thisContext ) {
|
|
56
56
|
const _static = this.constructor;
|
|
57
|
-
const {
|
|
57
|
+
const { webqit: { oohtml, SubscriptFunction } } = this.window;
|
|
58
58
|
const cache = oohtml.Script.compileCache[ script.contract ? 0 : 1 ];
|
|
59
59
|
const sourceHash = _static.toHash( script.textContent );
|
|
60
60
|
// Script instances are parsed only once
|
|
@@ -72,7 +72,7 @@ export default class Compiler {
|
|
|
72
72
|
}
|
|
73
73
|
}
|
|
74
74
|
// Let's obtain a material functions
|
|
75
|
-
let _Function, { parserParams, compilerParams, runtimeParams } = this.
|
|
75
|
+
let _Function, { parserParams, compilerParams, runtimeParams } = this.config.advanced;
|
|
76
76
|
if ( script.contract ) {
|
|
77
77
|
parserParams = { ...parserParams, allowAwaitOutsideFunction: script.type === 'module' };
|
|
78
78
|
runtimeParams = { ...runtimeParams, async: script.type === 'module' };
|
|
@@ -93,7 +93,7 @@ export default class Compiler {
|
|
|
93
93
|
cache.set( sourceHash, compiledScript );
|
|
94
94
|
}
|
|
95
95
|
const execHash = _static.toHash( { script, compiledScript, thisContext } );
|
|
96
|
-
script.textContent = `
|
|
96
|
+
script.textContent = `webqit.oohtml.Script.run('${ execHash }');`;
|
|
97
97
|
}
|
|
98
98
|
|
|
99
99
|
// Match import statements
|
package/src/scoped-js/index.js
CHANGED
|
@@ -6,35 +6,30 @@ import { resolveParams } from '@webqit/subscript/src/params.js';
|
|
|
6
6
|
import SubscriptFunction from '@webqit/subscript/src/SubscriptFunctionLite.js';
|
|
7
7
|
import Observer from '@webqit/observer';
|
|
8
8
|
import Compiler from './Compiler.js';
|
|
9
|
-
import
|
|
9
|
+
import { _init } from '../util.js';
|
|
10
10
|
|
|
11
11
|
/**
|
|
12
12
|
* @init
|
|
13
13
|
*
|
|
14
|
-
* @param Object $
|
|
14
|
+
* @param Object $config
|
|
15
15
|
*/
|
|
16
|
-
export default function init(
|
|
17
|
-
|
|
18
|
-
if ( !window.wq ) { window.wq = {}; }
|
|
19
|
-
if ( !window.wq.oohtml ) { window.wq.oohtml = {}; }
|
|
20
|
-
window.wq.oohtml.Script = { compileCache: [ new Map, new Map, ] };
|
|
21
|
-
window.wq.SubscriptFunction = $params.SubscriptFunction/* allow for injection, e.g. from test runner */ || SubscriptFunction;
|
|
22
|
-
window.wq.Observer = Observer;
|
|
23
|
-
// -------
|
|
24
|
-
const params = dom.meta( 'oohtml' ).copyWithDefaults( $params, {
|
|
16
|
+
export default function init( { advanced = {}, ...$config } ) {
|
|
17
|
+
const { config, window } = _init.call( this, 'scoped-js', $config, {
|
|
25
18
|
script: { retention: 'retain', mimeType: '' },
|
|
26
|
-
|
|
27
|
-
parserParams: { allowReturnOutsideFunction: false, allowSuperOutsideMethod: false
|
|
28
|
-
compilerParams: { globalsNoObserve: [ 'alert' ]
|
|
29
|
-
runtimeParams: { apiVersion: 2
|
|
19
|
+
advanced: resolveParams( advanced, {
|
|
20
|
+
parserParams: { allowReturnOutsideFunction: false, allowSuperOutsideMethod: false },
|
|
21
|
+
compilerParams: { globalsNoObserve: [ 'alert' ] },
|
|
22
|
+
runtimeParams: { apiVersion: 2 },
|
|
30
23
|
} ),
|
|
31
24
|
} );
|
|
32
|
-
|
|
25
|
+
config.scriptSelector = ( Array.isArray( config.script.mimeType ) ? config.script.mimeType : [ config.script.mimeType ] ).reduce( ( selector, mm ) => {
|
|
33
26
|
const qualifier = mm ? `[type=${ window.CSS.escape( mm ) }]` : '';
|
|
34
27
|
return selector.concat( `script${ qualifier }[scoped],script${ qualifier }[contract]` );
|
|
35
28
|
}, [] ).join( ',' );
|
|
36
|
-
|
|
37
|
-
|
|
29
|
+
window.webqit.oohtml.Script = { compileCache: [ new Map, new Map, ] };
|
|
30
|
+
window.webqit.SubscriptFunction = $config.SubscriptFunction/* allow for injection, e.g. from test runner */ || SubscriptFunction;
|
|
31
|
+
window.webqit.Observer = Observer;
|
|
32
|
+
realtime.call( window, config );
|
|
38
33
|
}
|
|
39
34
|
|
|
40
35
|
export {
|
|
@@ -65,7 +60,7 @@ export function execute( compiledScript, thisContext, script ) {
|
|
|
65
60
|
} );
|
|
66
61
|
} );
|
|
67
62
|
}
|
|
68
|
-
const window = this, { dom } = window.
|
|
63
|
+
const window = this, { dom } = window.webqit;
|
|
69
64
|
dom.realtime( window.document ).observe( thisContext, () => {
|
|
70
65
|
if ( script.contract ) {
|
|
71
66
|
// Rerending processes,,,
|
|
@@ -82,14 +77,14 @@ export function execute( compiledScript, thisContext, script ) {
|
|
|
82
77
|
/**
|
|
83
78
|
* Performs realtime capture of elements and builds their relationships.
|
|
84
79
|
*
|
|
85
|
-
* @param Object
|
|
80
|
+
* @param Object config
|
|
86
81
|
*
|
|
87
82
|
* @return Void
|
|
88
83
|
*/
|
|
89
|
-
function realtime(
|
|
90
|
-
const window = this, { dom } = window.
|
|
91
|
-
const compiler = new Compiler( window,
|
|
92
|
-
dom.realtime( window.document ).observe(
|
|
84
|
+
function realtime( config ) {
|
|
85
|
+
const window = this, { dom } = window.webqit;
|
|
86
|
+
const compiler = new Compiler( window, config, execute ), handled = () => {};
|
|
87
|
+
dom.realtime( window.document ).observe( config.scriptSelector, record => {
|
|
93
88
|
record.entrants.forEach( script => {
|
|
94
89
|
if ( 'contract' in script ) return handled( script );
|
|
95
90
|
Object.defineProperty( script, 'contract', { value: script.hasAttribute( 'contract' ) } );
|
package/src/targets.browser.js
CHANGED
package/src/util.js
CHANGED
|
@@ -2,11 +2,23 @@
|
|
|
2
2
|
/**
|
|
3
3
|
* @imports
|
|
4
4
|
*/
|
|
5
|
+
import webqitDom from '@webqit/dom';
|
|
5
6
|
import { _internals } from '@webqit/util/js/index.js';
|
|
7
|
+
import { _inherit } from '@webqit/util/obj/index.js';
|
|
6
8
|
|
|
7
9
|
export const _ = ( node, ...args ) => _internals( node, 'oohtml', ...args );
|
|
8
10
|
|
|
9
|
-
export
|
|
11
|
+
export function _init( name, $config, $defaults ) {
|
|
12
|
+
const window = this, dom = webqitDom.call( window );
|
|
13
|
+
window.webqit || ( window.webqit = {} );
|
|
14
|
+
window.webqit.oohtml || ( window.webqit.oohtml = {} );
|
|
15
|
+
window.webqit.oohtml.configs || ( window.webqit.oohtml.configs = {} );
|
|
16
|
+
const config = _inherit( 1, dom.meta( name ).json(), $config, $defaults );
|
|
17
|
+
window.webqit.oohtml.configs[ name.toUpperCase().replace( '-', '_' ) ] = config;
|
|
18
|
+
return { config, dom, window };
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function _compare( a, b, depth = 1, objectSizing = false ) {
|
|
10
22
|
if ( depth && typeof a === 'object' && a && typeof b === 'object' && b && ( !objectSizing || Object.keys( a ).length === Object.keys( b ).length ) ) {
|
|
11
23
|
for ( let key in a ) {
|
|
12
24
|
if ( !_compare( a[ key ], b[ key ], depth - 1, objectSizing ) ) return false;
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
|
|
2
|
+
/**
|
|
3
|
+
* @imports
|
|
4
|
+
*/
|
|
5
|
+
import { expect } from 'chai';
|
|
6
|
+
import { createDocument } from './index.js';
|
|
7
|
+
import Observer from '@webqit/observer';
|
|
8
|
+
|
|
9
|
+
describe(`Bindings API`, function() {
|
|
10
|
+
|
|
11
|
+
describe( `Basic...`, function() {
|
|
12
|
+
|
|
13
|
+
const head = ``;
|
|
14
|
+
const body = ``;
|
|
15
|
+
const { document } = createDocument( head, body );
|
|
16
|
+
|
|
17
|
+
it ( `The document object and elements should expose a "bindings" property each...`, async function() {
|
|
18
|
+
expect( document ).to.have.property( 'bindings' );
|
|
19
|
+
expect( document.body ).to.have.property( 'bindings' );
|
|
20
|
+
} );
|
|
21
|
+
|
|
22
|
+
it ( `Bindings objects should be observable...`, async function() {
|
|
23
|
+
let idReceived = null;
|
|
24
|
+
Observer.observe( document.bindings, records => {
|
|
25
|
+
idReceived = records[ 0 ].key;
|
|
26
|
+
} );
|
|
27
|
+
document.bindings.someKey = 'someValue'; // new
|
|
28
|
+
expect( idReceived ).to.eq( 'someKey' );
|
|
29
|
+
// -------------
|
|
30
|
+
let changes = [];
|
|
31
|
+
Observer.observe( document.bindings, records => {
|
|
32
|
+
changes.push( ...records );
|
|
33
|
+
} );
|
|
34
|
+
document.bindings.someKey2 = 'someValue2'; // new
|
|
35
|
+
document.bind( { someKey: 'someValue'/* update */, someKey3: 'someValue3'/* new */ } );
|
|
36
|
+
expect( changes ).to.an( 'array' ).with.length( 4 ); // (1) sets: someKey2, (2) deletes: someKey2, (3) updates: someKey, (4) sets: someKey3;
|
|
37
|
+
} );
|
|
38
|
+
|
|
39
|
+
} );
|
|
40
|
+
|
|
41
|
+
} );
|
|
42
|
+
|
package/test/index.js
CHANGED
|
@@ -7,7 +7,7 @@ import { createContext, compileFunction, runInContext } from 'vm';
|
|
|
7
7
|
import jsdom from 'jsdom';
|
|
8
8
|
import init, { Observer } from '../src/index.js';
|
|
9
9
|
import { SubscriptFunction } from '@webqit/subscript';
|
|
10
|
-
import
|
|
10
|
+
import webqitDom from '@webqit/dom';
|
|
11
11
|
|
|
12
12
|
/**
|
|
13
13
|
* -------
|
|
@@ -35,7 +35,7 @@ export function createDocument( head = '', body = '', callback = null, ) {
|
|
|
35
35
|
url: 'http://localhost',
|
|
36
36
|
beforeParse( window ) {
|
|
37
37
|
init.call( window );
|
|
38
|
-
if ( callback ) callback( window, window.
|
|
38
|
+
if ( callback ) callback( window, window.webqit.dom );
|
|
39
39
|
}
|
|
40
40
|
} );
|
|
41
41
|
return instance.window;
|
|
@@ -55,16 +55,18 @@ export function createDocumentForScopedJS( head = '', body = '', callback = null
|
|
|
55
55
|
window.testRecords = [];
|
|
56
56
|
createContext( window );
|
|
57
57
|
// Running advanced scripts
|
|
58
|
-
init.call( window, {
|
|
58
|
+
init.call( window, { SCOPED_JS: {
|
|
59
59
|
SubscriptFunction,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
60
|
+
advanced: {
|
|
61
|
+
runtimeParams: {
|
|
62
|
+
compileFunction: ( code, parameters ) => compileFunction( code, parameters, {
|
|
63
|
+
parsingContext: window,
|
|
64
|
+
} ),
|
|
65
|
+
}
|
|
64
66
|
}
|
|
65
67
|
} } );
|
|
66
68
|
// Running basic scripts
|
|
67
|
-
const dom =
|
|
69
|
+
const dom = webqitDom.call( window );
|
|
68
70
|
if ( params.runScripts !== 'dangerously' ) {
|
|
69
71
|
dom.realtime( window.document ).observe( 'script', record => {
|
|
70
72
|
record.entrants.forEach( script => {
|
|
@@ -74,7 +76,7 @@ export function createDocumentForScopedJS( head = '', body = '', callback = null
|
|
|
74
76
|
}, { subtree: true } );
|
|
75
77
|
}
|
|
76
78
|
// Sync callback?
|
|
77
|
-
if ( callback ) callback( window, window.
|
|
79
|
+
if ( callback ) callback( window, window.webqit.dom );
|
|
78
80
|
}
|
|
79
81
|
} );
|
|
80
82
|
return instance.window;
|