@webqit/oohtml 2.1.57 → 2.1.59
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 +54 -0
- package/dist/html-bindings.js.map +7 -0
- 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 +2 -2
- package/dist/main.js +38 -6
- package/dist/main.js.map +3 -3
- package/dist/scoped-css.js +1 -1
- package/dist/scoped-css.js.map +2 -2
- package/dist/scoped-js.js +4 -4
- package/dist/scoped-js.js.map +3 -3
- package/package.json +5 -5
- package/src/html-bindings/index.js +233 -0
- package/src/html-imports/_HTMLImportElement copy.js +217 -0
- package/src/html-imports/_HTMLImportElement.js +26 -17
- package/src/html-imports/_HTMLImportsProvider.js +2 -2
- package/src/html-imports/index.js +25 -44
- package/src/index.js +4 -4
- package/src/scoped-js/index.js +2 -2
- package/dist/html-bracelets.js +0 -2
- package/dist/html-bracelets.js.map +0 -7
- package/src/html-bracelets/AttrBracelet.js +0 -122
- package/src/html-bracelets/Bracelet.js +0 -82
- package/src/html-bracelets/HTMLBracelets.js +0 -68
- package/src/html-bracelets/TextBracelet.js +0 -69
- package/src/html-bracelets/index.js +0 -72
- /package/src/{html-bracelets → html-bindings}/targets.browser.js +0 -0
|
@@ -1,122 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import HTMLBracelets from './HTMLBracelets.js';
|
|
6
|
-
import Bracelet from './Bracelet.js';
|
|
7
|
-
import { _ } from '../util.js';
|
|
8
|
-
|
|
9
|
-
export default class AttrBracelet extends Bracelet {
|
|
10
|
-
static get query() { return `@*[${ this.tokens.contains }]`; }
|
|
11
|
-
|
|
12
|
-
static parse( ...attrs ) {
|
|
13
|
-
return attrs.reduce( ( attrs, attr ) => {
|
|
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(), attr.nodeName === 'class' || match[ 0 ] === attr.nodeValue.trim() );
|
|
16
|
-
const prev = bracelets.slice( -1 )[ 0 ];
|
|
17
|
-
if ( prev ) { prev._nextSibling = bracelet; }
|
|
18
|
-
return bracelets.concat( bracelet );
|
|
19
|
-
}, [] ) );
|
|
20
|
-
}, [] );
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
static mount( ...bracelets ) {
|
|
24
|
-
for ( const bracelet of bracelets ) {
|
|
25
|
-
// Add to attr-specific registry
|
|
26
|
-
let attrBraceletsRegistry = _( bracelet.ownerElement ).get( 'attr-bracelets' );
|
|
27
|
-
if ( !attrBraceletsRegistry ) {
|
|
28
|
-
attrBraceletsRegistry = new Map;
|
|
29
|
-
attrBraceletsRegistry.active = [];
|
|
30
|
-
_( bracelet.ownerElement ).set( 'attr-bracelets', attrBraceletsRegistry );
|
|
31
|
-
}
|
|
32
|
-
let attrBracelets = attrBraceletsRegistry.get( bracelet.attr.nodeName );
|
|
33
|
-
if ( !attrBracelets ) {
|
|
34
|
-
attrBracelets = new Set;
|
|
35
|
-
attrBraceletsRegistry.set( bracelet.attr.nodeName, attrBracelets );
|
|
36
|
-
}
|
|
37
|
-
attrBracelets.add( bracelet );
|
|
38
|
-
attrBraceletsRegistry.active[ 0 ]?._nested.add( bracelet );
|
|
39
|
-
// Add to general registry
|
|
40
|
-
HTMLBracelets.instance( bracelet.ownerElement ).add( bracelet );
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
static cleanup( ...attrs ) {
|
|
45
|
-
for ( const attr of attrs ) {
|
|
46
|
-
// Remove from attr-specific registry
|
|
47
|
-
const attrBraceletsRegistry = _( attr.ownerElement ).get( 'attr-bracelets' );
|
|
48
|
-
attrBraceletsRegistry?.get( attr.nodeName )?.forEach( bracelet => {
|
|
49
|
-
bracelet.disconnect();
|
|
50
|
-
// Remove from general registry
|
|
51
|
-
HTMLBracelets.instance( bracelet.ownerElement ).delete( bracelet );
|
|
52
|
-
} );
|
|
53
|
-
attrBraceletsRegistry?.delete( attr.nodeName );
|
|
54
|
-
if ( attrBraceletsRegistry && !attrBraceletsRegistry.size ) { _( attr.ownerElement ).delete( 'attr-bracelets' ); }
|
|
55
|
-
}
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
constructor( attr, _value, startIndex, expr, booleanAble ) {
|
|
59
|
-
super();
|
|
60
|
-
const $refs = [], $expr = this.parseExpr( expr, $refs );
|
|
61
|
-
const ownerElement = attr.ownerElement; // Hard save. Deleted attributes don't retain .ownerElement
|
|
62
|
-
Object.defineProperties( this, {
|
|
63
|
-
type: { get: () => 'attr' },
|
|
64
|
-
expr: { get: () => $expr },
|
|
65
|
-
refs: { get: () => $refs },
|
|
66
|
-
attr: { get: () => attr },
|
|
67
|
-
ownerElement: { get: () => ownerElement },
|
|
68
|
-
originalValue: { value: _value },
|
|
69
|
-
_value: { value: _value, writable: true },
|
|
70
|
-
_dirty: { value: false, writable: true },
|
|
71
|
-
_startIndex: { value: undefined, writable: true },
|
|
72
|
-
_endIndex: { value: undefined, writable: true },
|
|
73
|
-
_nextSibling: { value: undefined, writable: true },
|
|
74
|
-
_booleanAble: { value: booleanAble, writable: true },
|
|
75
|
-
_nested: { value: new Set },
|
|
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
|
-
}
|
|
80
|
-
this.startIndex = startIndex;
|
|
81
|
-
}
|
|
82
|
-
get isBoolean() { return this._booleanAble && typeof this._value === 'boolean'; }
|
|
83
|
-
|
|
84
|
-
get startIndex() { return this._startIndex; }
|
|
85
|
-
set startIndex( value ) {
|
|
86
|
-
this._startIndex = value;
|
|
87
|
-
this.endIndex = this._startIndex + this.value.length;
|
|
88
|
-
}
|
|
89
|
-
|
|
90
|
-
get endIndex() { return this._endIndex; }
|
|
91
|
-
set endIndex( value ) {
|
|
92
|
-
if ( value === this._endIndex ) return;
|
|
93
|
-
if ( this.nextSibling ) { this.nextSibling.startIndex += value - this._endIndex; }
|
|
94
|
-
this._endIndex = value;
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
get value() { return this._value; }
|
|
98
|
-
set value( value ) {
|
|
99
|
-
if ( this.disconnected || value === this._value ) return;
|
|
100
|
-
this._value = value;
|
|
101
|
-
this._dirty = true;
|
|
102
|
-
// Set attribute; but first disconnect any "nested"
|
|
103
|
-
this._nested.forEach( p => p.disconnect() );
|
|
104
|
-
const attrBraceletsRegistry = _( this.ownerElement ).get( 'attr-bracelets' );
|
|
105
|
-
attrBraceletsRegistry.active.unshift( this );
|
|
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
|
-
}
|
|
114
|
-
attrBraceletsRegistry.active.shift();
|
|
115
|
-
// Reindex
|
|
116
|
-
const newEndIndex = this.startIndex + value.length;
|
|
117
|
-
if ( newEndIndex !== this.endIndex ) { this.endIndex = newEndIndex; }
|
|
118
|
-
}
|
|
119
|
-
|
|
120
|
-
get nextSibling() { return this._nextSibling; }
|
|
121
|
-
get dirty() { return this._dirty; }
|
|
122
|
-
}
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
export default class Bracelet {
|
|
3
|
-
static tokens = {
|
|
4
|
-
startTag: `{`, endTag: `}`,
|
|
5
|
-
get contains () { return `contains(., "${ this.startTag }") and contains(substring-after(., "${ this.startTag }"), "${ this.endTag }")`; },
|
|
6
|
-
get startsAndEnds() { return `starts-with(., "${ this.startTag }") and substring(., string-length(.) - string-length("${ this.endTag }") + 1) = "${ this.endTag }"`; },
|
|
7
|
-
get regex() {
|
|
8
|
-
const startTag = this.startTag.split( '' ).map( s => '\\' + s );
|
|
9
|
-
const endTag = this.endTag.split( '' ).map( s => '\\' + s );
|
|
10
|
-
return `${ startTag.join( '' ) }([^${ startTag[ 0 ] }]+)${ endTag.join( '' ) }`;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
parseExpr( expr, refs ) {
|
|
15
|
-
const tokens = expr.match( /[\+\-\*\/&|\?\:\=\<\>\%]+|(['"])[^'"]*\1|\[[^\]]*\]|\([^)]*\)|\S+/g ).map( s => s.trim() );
|
|
16
|
-
return tokens.map( s => {
|
|
17
|
-
let meta = {};
|
|
18
|
-
if ( s[ 0 ] === '!' ) { meta = { negation: true }; s = s.slice( 1 ); }
|
|
19
|
-
if ( /^\(.*\)$/.test( s ) ) return { type: 'expr', value: this.parseExpr( s.slice( 1, -1 ), refs ), ...meta }; // must be before the operator test
|
|
20
|
-
if ( [ '"', "'" ].includes( s[ 0 ] ) ) return { type: 'literal', value: /(['"])(.*?)\1/g.exec( s )[ 2 ], ...meta }; // must be before the operator test
|
|
21
|
-
if ( /[\+\-\*\/&|\?\:\=\<\>\%]/.test( s ) ) return { type: 'operator', value: s, ...meta };
|
|
22
|
-
if ( !isNaN( s ) ) return { type: 'literal', value: parseFloat( s ), ...meta };
|
|
23
|
-
const ref = s.match( /[^\.\[\]]+/g );
|
|
24
|
-
refs.push( ref );
|
|
25
|
-
return { type: 'ref', value: ref, ...meta };
|
|
26
|
-
} );
|
|
27
|
-
}
|
|
28
|
-
|
|
29
|
-
renderExpr( expr, bindings ) {
|
|
30
|
-
return expr.reduce( ( [ prev, operator, state ], token ) => {
|
|
31
|
-
// No further evaluations allowed?
|
|
32
|
-
if ( state === 'end' ) return [ prev, null, 'end' ];
|
|
33
|
-
// Mode has been consequent and we've now hit the alternate block?
|
|
34
|
-
if ( state === 'consequent' && token.type === 'operator' && token.value === ':' ) return [ prev, null, 'end' ];
|
|
35
|
-
// Always return operators at this level
|
|
36
|
-
if ( token.type === 'operator' ) return [ prev, token, state ];
|
|
37
|
-
// Still expecting to hit the alternate block?
|
|
38
|
-
if ( state === 'alternate' && operator?.value !== ':' ) return [ null, null, 'alternate' ];
|
|
39
|
-
// Main...
|
|
40
|
-
let value, render = ( token, val ) => token.negation ? !val : val;
|
|
41
|
-
switch ( token.type ) {
|
|
42
|
-
case 'ref': value = render( token, bindings[ token.value.join( '.' ) ].value ); break;
|
|
43
|
-
case 'expr': value = render( token, this.renderExpr( token.value, bindings ) ); break;
|
|
44
|
-
default: value = render( token, token.value );
|
|
45
|
-
}
|
|
46
|
-
switch ( operator?.value ) {
|
|
47
|
-
case '-': return [ prev - value, null, state ];
|
|
48
|
-
case '+': return [ prev + value, null, state ];
|
|
49
|
-
case '/': return [ prev / value, null, state ];
|
|
50
|
-
case '*': return [ prev * value, null, state ];
|
|
51
|
-
case '%': return [ prev % value, null, state ];
|
|
52
|
-
case '===': return [ prev === value, null, state ];
|
|
53
|
-
case '==': return [ render( operator, prev == value ), null, state ];
|
|
54
|
-
case '>=': return [ prev >= value, null, state ];
|
|
55
|
-
case '<=': return [ prev <= value, null, state ];
|
|
56
|
-
case '>': return [ prev > value, null, state ];
|
|
57
|
-
case '<': return [ prev < value, null, state ];
|
|
58
|
-
case '||': return [ prev || value, null, state ];
|
|
59
|
-
case '&&': return [ prev && value, null, state ];
|
|
60
|
-
case '?': return prev ? [ value, null, 'consequent' ] : [ null, null, 'alternate' ];
|
|
61
|
-
case '??': return [ prev ?? value, null, state ];
|
|
62
|
-
default: return [ value ];
|
|
63
|
-
}
|
|
64
|
-
}, [ null, null ] )[ 0 ];
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
render( bindings ) {
|
|
68
|
-
let value = this.renderExpr( this.expr, bindings );
|
|
69
|
-
if ( typeof value === 'undefined' ) {
|
|
70
|
-
value = this.originalValue;
|
|
71
|
-
if ( !this.dirty ) {
|
|
72
|
-
if ( this._booleanAble ) { value = false; }
|
|
73
|
-
else return;
|
|
74
|
-
}
|
|
75
|
-
this.value = value;
|
|
76
|
-
return;
|
|
77
|
-
}
|
|
78
|
-
this.value = value;
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
disconnect() { this.disconnected = true; }
|
|
82
|
-
}
|
|
@@ -1,68 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { HTMLContext } from '../context-api/index.js';
|
|
6
|
-
import _HTMLBindingsProvider from '../bindings-api/_HTMLBindingsProvider.js';
|
|
7
|
-
import Bracelet from './Bracelet.js';
|
|
8
|
-
import { _ } from '../util.js';
|
|
9
|
-
|
|
10
|
-
export default class HTMLBracelets extends Set {
|
|
11
|
-
|
|
12
|
-
/**
|
|
13
|
-
* @instance
|
|
14
|
-
*/
|
|
15
|
-
static instance( host ) {
|
|
16
|
-
return _( host ).get( 'bracelets::instance' ) || new this( host );
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* @constructor
|
|
21
|
-
*/
|
|
22
|
-
constructor( host ) {
|
|
23
|
-
super();
|
|
24
|
-
_( host ).get( `bracelets::instance` )?.dispose();
|
|
25
|
-
_( host ).set( `bracelets::instance`, this );
|
|
26
|
-
const priv = { host, bindings: Object.create( null ) };
|
|
27
|
-
Object.defineProperty( this, '#', { get: () => priv } );
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
add( bracelet ) {
|
|
31
|
-
if ( !( bracelet instanceof Bracelet ) ) throw new Error( `Argument must be instance of Bracelet.` );
|
|
32
|
-
const returnValue = super.add( bracelet );
|
|
33
|
-
const bindings = this[ '#' ].bindings;
|
|
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
|
-
HTMLContext.instance( this[ '#' ].host ).request( request, value => {
|
|
40
|
-
bindings[ $path ].value = value;
|
|
41
|
-
bindings[ $path ].subs.forEach( bracelet => bracelet.render( bindings ) );
|
|
42
|
-
} );
|
|
43
|
-
}
|
|
44
|
-
bindings[ $path ].subs.add( bracelet );
|
|
45
|
-
} );
|
|
46
|
-
bracelet.render( bindings );
|
|
47
|
-
return returnValue;
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
delete( bracelet ) {
|
|
51
|
-
if ( !( bracelet instanceof Bracelet ) ) throw new Error( `Argument must be instance of Bracelet.` );
|
|
52
|
-
const returnValue = super.delete( bracelet );
|
|
53
|
-
const bindings = this[ '#' ].bindings;
|
|
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 ];
|
|
60
|
-
}
|
|
61
|
-
} );
|
|
62
|
-
return returnValue;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
clear() {
|
|
66
|
-
for ( const bracelet of this ) { this.delete( bracelet ); }
|
|
67
|
-
}
|
|
68
|
-
}
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import HTMLBracelets from './HTMLBracelets.js';
|
|
6
|
-
import Bracelet from './Bracelet.js';
|
|
7
|
-
import { _ } from '../util.js';
|
|
8
|
-
|
|
9
|
-
export default class TextBracelet extends Bracelet {
|
|
10
|
-
static get query() { return `text()[not(ancestor::script) and not(ancestor::style) and ${ this.tokens.contains }]`; }
|
|
11
|
-
|
|
12
|
-
static parse( ...nodes ) {
|
|
13
|
-
return nodes.reduce( ( nodes, node ) => {
|
|
14
|
-
let $node = node, $rest = node, startIndex, endIndex;
|
|
15
|
-
while ( $rest && ( startIndex = $rest.nodeValue.indexOf( this.tokens.startTag ) ) > -1 ) {
|
|
16
|
-
if ( startIndex > 0 ) { $node = $rest.splitText( startIndex ); }
|
|
17
|
-
if ( ( endIndex = $node.nodeValue.indexOf( this.tokens.endTag ) + this.tokens.endTag.length ) !== $node.nodeValue.length ) {
|
|
18
|
-
$rest = $node.splitText( endIndex );
|
|
19
|
-
} else { $rest = null; }
|
|
20
|
-
nodes.push( new this( $node ) );
|
|
21
|
-
}
|
|
22
|
-
return nodes;
|
|
23
|
-
}, [] );
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
static mount( ...bracelets ) {
|
|
27
|
-
for ( const bracelet of bracelets ) {
|
|
28
|
-
_( bracelet.node ).set( 'text-bracelet', bracelet );
|
|
29
|
-
HTMLBracelets.instance( bracelet.ownerElement ).add( bracelet );
|
|
30
|
-
}
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
static cleanup( ...nodes ) {
|
|
34
|
-
for ( const node of nodes ) {
|
|
35
|
-
const bracelet = _( node ).get( 'text-bracelet' );
|
|
36
|
-
if ( !bracelet ) continue;
|
|
37
|
-
bracelet.disconnect();
|
|
38
|
-
HTMLBracelets.instance( bracelet.ownerElement ).delete( bracelet );
|
|
39
|
-
_( node ).delete( 'text-bracelet' );
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
constructor( node ) {
|
|
44
|
-
super();
|
|
45
|
-
const expr = [ ...node.nodeValue.match( new RegExp( this.constructor.tokens.regex ) ) ][ 1 ].trim();
|
|
46
|
-
const $refs = [], $expr = this.parseExpr( expr, $refs );
|
|
47
|
-
Object.defineProperties( this, {
|
|
48
|
-
_value: { value: node.nodeValue, writable: true },
|
|
49
|
-
_dirty: { value: false, writable: true },
|
|
50
|
-
type: { get: () => 'text' },
|
|
51
|
-
expr: { get: () => $expr },
|
|
52
|
-
refs: { get: () => $refs },
|
|
53
|
-
node: { get: () => node },
|
|
54
|
-
ownerElement: { get: () => node.parentNode },
|
|
55
|
-
originalValue: { value: node.nodeValue },
|
|
56
|
-
} );
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
get value() { return this._value; }
|
|
60
|
-
set value( value ) {
|
|
61
|
-
if ( this.disconnected || value === this._value ) return;
|
|
62
|
-
this._value = value;
|
|
63
|
-
this._dirty = true;
|
|
64
|
-
this.node.nodeValue = value;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
get nextSibling() { return this.node.nextSibling; }
|
|
68
|
-
get dirty() { return this._dirty; }
|
|
69
|
-
}
|
|
@@ -1,72 +0,0 @@
|
|
|
1
|
-
|
|
2
|
-
/**
|
|
3
|
-
* @imports
|
|
4
|
-
*/
|
|
5
|
-
import { _, _init } from '../util.js';
|
|
6
|
-
import AttrBracelet from './AttrBracelet.js';
|
|
7
|
-
import TextBracelet from './TextBracelet.js';
|
|
8
|
-
import HTMLBracelets from './HTMLBracelets.js';
|
|
9
|
-
|
|
10
|
-
/**
|
|
11
|
-
* Initializes DOM Parts.
|
|
12
|
-
*
|
|
13
|
-
* @param $config Object
|
|
14
|
-
*
|
|
15
|
-
* @return Void
|
|
16
|
-
*/
|
|
17
|
-
export default function init( $config = {} ) {
|
|
18
|
-
const { config, realdom, window } = _init.call( this, 'html-bracelets', $config, {
|
|
19
|
-
api: { bracelets: 'bracelets' },
|
|
20
|
-
isomorphic: true,
|
|
21
|
-
} );
|
|
22
|
-
exposeAPIs.call( window, config );
|
|
23
|
-
realtime.call( window, config );
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/**
|
|
27
|
-
* Exposes DOM Parts with native APIs.
|
|
28
|
-
*
|
|
29
|
-
* @param Object config
|
|
30
|
-
*
|
|
31
|
-
* @return Void
|
|
32
|
-
*/
|
|
33
|
-
function exposeAPIs( config ) {
|
|
34
|
-
const window = this;
|
|
35
|
-
// Assertions
|
|
36
|
-
if ( config.api.bracelets in window.document ) { throw new Error( `document already has a "${ config.api.bracelets }" property!` ); }
|
|
37
|
-
if ( config.api.bracelets in window.HTMLElement.prototype ) { throw new Error( `The "HTMLElement" class already has a "${ config.api.bracelets }" property!` ); }
|
|
38
|
-
// Definitions
|
|
39
|
-
Object.defineProperty( window.document, config.api.bracelets, { get: function() {
|
|
40
|
-
return HTMLBracelets.instance( window.document );
|
|
41
|
-
} } );
|
|
42
|
-
Object.defineProperty( window.HTMLElement.prototype, config.api.bracelets, { get: function() {
|
|
43
|
-
return HTMLBracelets.instance( this );
|
|
44
|
-
} } );
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
/**
|
|
48
|
-
* Performs realtime capture of elements and their attributes
|
|
49
|
-
*
|
|
50
|
-
* @param Object config
|
|
51
|
-
*
|
|
52
|
-
* @return Void
|
|
53
|
-
*/
|
|
54
|
-
function realtime( config ) {
|
|
55
|
-
const window = this, { realdom } = window.webqit;
|
|
56
|
-
realdom.realtime( window.document ).subtree( `(${ TextBracelet.query })`, record => {
|
|
57
|
-
TextBracelet.cleanup( ...record.exits );
|
|
58
|
-
TextBracelet.mount( ...TextBracelet.parse( ...record.entrants.filter( node => !_( node ).has( 'text-bracelet' )/** generated text nodes during parse() */ ) ) );
|
|
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 } );
|
|
64
|
-
realdom.realtime( window.document, 'attr' ).observe( records => {
|
|
65
|
-
for ( const record of records ) {
|
|
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;
|
|
68
|
-
if ( record.oldValue ) { AttrBracelet.cleanup( record.value ? record.target.attributes[ record.name ] : { ownerElement: record.target, nodeName: record.name } ); }
|
|
69
|
-
if ( record.value ) { AttrBracelet.mount( ...AttrBracelet.parse( record.target.attributes[ record.name ] ) ); }
|
|
70
|
-
}
|
|
71
|
-
}, { subtree: true, newValue: true, oldValue: true, timing: 'sync' } );
|
|
72
|
-
}
|
|
File without changes
|