@epa-wg/custom-element 0.0.19 → 0.0.20
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 +3 -3
- package/bin/xslDtd2Ide.mjs +1 -1
- package/custom-element.js +25 -11
- package/demo/a.html +28 -16
- package/demo/dom-merge.html +2 -2
- package/demo/http-request.html +27 -0
- package/demo/local-storage.html +106 -1
- package/demo/s.xml +92 -5
- package/demo/s.xslt +10 -8
- package/demo/ss.html +50 -30
- package/http-request.js +53 -25
- package/ide/web-types-dce.json +1 -1
- package/ide/web-types-xsl.json +1 -1
- package/local-storage.js +47 -10
- package/location-element.js +7 -7
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -348,9 +348,9 @@ within template
|
|
|
348
348
|
[github-image]: https://cdnjs.cloudflare.com/ajax/libs/octicons/8.5.0/svg/mark-github.svg
|
|
349
349
|
[npm-image]: https://img.shields.io/npm/v/@epa-wg/custom-element.svg
|
|
350
350
|
[npm-url]: https://npmjs.org/package/@epa-wg/custom-element
|
|
351
|
-
[coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
352
|
-
[coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
353
|
-
[storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
351
|
+
[coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.20/coverage/coverage.svg
|
|
352
|
+
[coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.20/coverage/lcov-report/index.html
|
|
353
|
+
[storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.20/storybook-static/index.html?path=/story/welcome--introduction
|
|
354
354
|
[sandbox-url]: https://stackblitz.com/github/EPA-WG/custom-element?file=index.html
|
|
355
355
|
[webcomponents-url]: https://www.webcomponents.org/element/@epa-wg/custom-element
|
|
356
356
|
[webcomponents-img]: https://img.shields.io/badge/webcomponents.org-published-blue.svg
|
package/bin/xslDtd2Ide.mjs
CHANGED
|
@@ -116,7 +116,7 @@ writeFileSync( '.././ide/customData-xsl.json', JSON.stringify( vsCode, undefined
|
|
|
116
116
|
const intelliJ = {
|
|
117
117
|
"$schema": "http://json.schemastore.org/web-types",
|
|
118
118
|
"name": "@epa-wg/custom-element",
|
|
119
|
-
"version": "0.0.
|
|
119
|
+
"version": "0.0.20",
|
|
120
120
|
"js-types-syntax": "typescript",
|
|
121
121
|
"description-markup": "markdown",
|
|
122
122
|
"contributions": {
|
package/custom-element.js
CHANGED
|
@@ -11,7 +11,8 @@ const attr = (el, attr)=> el.getAttribute?.(attr)
|
|
|
11
11
|
, isNode = e => e && typeof e.nodeType === 'number'
|
|
12
12
|
, create = ( tag, t = '', d=document ) => ( e => ((t && e.append(createText(d.ownerDocument||d, t))),e) )((d.ownerDocument || d ).createElement( tag ))
|
|
13
13
|
, createText = ( d, t) => (d.ownerDocument || d ).createTextNode( t )
|
|
14
|
-
,
|
|
14
|
+
, removeChildren = n => { while(n.firstChild) n.firstChild.remove(); return n; }
|
|
15
|
+
, emptyNode = n => { n.getAttributeNames().map( a => n.removeAttribute(a) ); return removeChildren(n); }
|
|
15
16
|
, createNS = ( ns, tag, t = '' ) => ( e => ((e.innerText = t||''),e) )(document.createElementNS( ns, tag ))
|
|
16
17
|
, xslNs = x => ( x?.setAttribute('xmlns:xsl', XSL_NS_URL ), x )
|
|
17
18
|
, xslHtmlNs = x => ( x?.setAttribute('xmlns:xhtml', HTML_NS_URL ), xslNs(x) )
|
|
@@ -95,10 +96,12 @@ Json2Xml( o, tag )
|
|
|
95
96
|
|
|
96
97
|
export function
|
|
97
98
|
obj2node( o, tag, doc )
|
|
98
|
-
{
|
|
99
|
-
if(
|
|
100
|
-
if(
|
|
99
|
+
{ const t = typeof o;
|
|
100
|
+
if( t === 'function'){debugger}
|
|
101
|
+
if( t === 'string' )
|
|
101
102
|
return create(tag,o,doc);
|
|
103
|
+
if( t === 'number' )
|
|
104
|
+
return create(tag,''+o,doc);
|
|
102
105
|
|
|
103
106
|
if( o instanceof Array )
|
|
104
107
|
{ const ret = create('array');
|
|
@@ -364,17 +367,23 @@ event2slice( x, sliceNames, ev, dce )
|
|
|
364
367
|
ev.type==='init' && cleanSliceValue();
|
|
365
368
|
s.append( obj2node( ev, 'event', d ) );
|
|
366
369
|
if( sel.hasAttribute('slice-value') )
|
|
367
|
-
{
|
|
370
|
+
{ if( el.value === undefined)
|
|
371
|
+
s.removeAttribute('value')
|
|
372
|
+
else
|
|
373
|
+
s.setAttribute('value', el.value );
|
|
368
374
|
const v = xPath( attr( sel, 'slice-value'),s );
|
|
369
375
|
cleanSliceValue();
|
|
370
376
|
s.append( createText( d, v ) );
|
|
371
377
|
}else
|
|
372
|
-
{ const v = el.value
|
|
378
|
+
{ const v = el.value ?? attr( sel, 'value' ) ;
|
|
373
379
|
cleanSliceValue();
|
|
374
|
-
if(
|
|
375
|
-
s.
|
|
380
|
+
if( v === null || v === undefined )
|
|
381
|
+
[...s.childNodes].filter(n=>n.localName!=='event').map(n=>n.remove());
|
|
376
382
|
else
|
|
377
|
-
|
|
383
|
+
if( isString(v) )
|
|
384
|
+
s.append( createText( d, v) );
|
|
385
|
+
else
|
|
386
|
+
s.append( obj2node(v,'value',s.ownerDocument) )
|
|
378
387
|
}
|
|
379
388
|
})
|
|
380
389
|
}
|
|
@@ -445,6 +454,8 @@ export function assureUnique(n, id=0)
|
|
|
445
454
|
}
|
|
446
455
|
export function merge( parent, fromArr )
|
|
447
456
|
{
|
|
457
|
+
if(!fromArr.length)
|
|
458
|
+
return removeChildren(parent);
|
|
448
459
|
const id2old = {};
|
|
449
460
|
for( let c of parent.childNodes)
|
|
450
461
|
{ ASSERT( !id2old[c.dceId] );
|
|
@@ -455,8 +466,8 @@ export function merge( parent, fromArr )
|
|
|
455
466
|
id2old[attr(c, 'data-dce-id') || 0] = c;
|
|
456
467
|
}
|
|
457
468
|
for( let e of [...fromArr] )
|
|
458
|
-
{
|
|
459
|
-
const o = id2old[
|
|
469
|
+
{ const k = attr(e, 'data-dce-id') || e.dceId;
|
|
470
|
+
const o = id2old[ k ];
|
|
460
471
|
if( o )
|
|
461
472
|
{ if( isText(e) )
|
|
462
473
|
{ if( o.nodeValue !== e.nodeValue )
|
|
@@ -466,9 +477,12 @@ export function merge( parent, fromArr )
|
|
|
466
477
|
if( o.childNodes.length || e.childNodes.length )
|
|
467
478
|
merge(o, e.childNodes)
|
|
468
479
|
}
|
|
480
|
+
delete id2old[ k ]
|
|
469
481
|
}else
|
|
470
482
|
parent.append( e )
|
|
471
483
|
}
|
|
484
|
+
for( let v of Object.values(id2old) )
|
|
485
|
+
v.remove();
|
|
472
486
|
}
|
|
473
487
|
export function assureUID(n,attr)
|
|
474
488
|
{ if( !n.hasAttribute(attr) )
|
package/demo/a.html
CHANGED
|
@@ -6,6 +6,7 @@
|
|
|
6
6
|
<title>custom-element Declarative Custom Element implementation demo</title>
|
|
7
7
|
<link rel="icon" href="./wc-square.svg"/>
|
|
8
8
|
<script type="module" src="../http-request.js"></script>
|
|
9
|
+
<script type="module" src="../local-storage.js"></script>
|
|
9
10
|
<script type="module" src="../custom-element.js"></script>
|
|
10
11
|
|
|
11
12
|
<style>
|
|
@@ -40,22 +41,33 @@
|
|
|
40
41
|
</head>
|
|
41
42
|
<body>
|
|
42
43
|
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
44
|
+
<custom-element>
|
|
45
|
+
<template>
|
|
46
|
+
<button slice="url-string" slice-value="'https://pokeapi.co/api/v2/pokemon?limit=6'" slice-event="click"
|
|
47
|
+
>⬇️https://pokeapi.co/api/v2/pokemon?limit=6</button>
|
|
48
|
+
<input slice="url-string" value="{ //url-string ?? '' }" style="width:100%"/>
|
|
49
|
+
<button slice="fetch-url" slice-event="click" slice-value="//url-string"> GET </button>
|
|
50
|
+
<http-request
|
|
51
|
+
url="{//fetch-url}"
|
|
52
|
+
slice="request_slice"
|
|
53
|
+
type="text"
|
|
54
|
+
mode="cors"
|
|
55
|
+
></http-request>
|
|
56
|
+
//fetch-url : <code>{//fetch-url}</code>
|
|
57
|
+
<!-- <for-each select="//slice/request_slice/value/*">-->
|
|
58
|
+
<!-- <ul>-->
|
|
59
|
+
<!-- <var data-testid="request-section"><value-of select='name(.)'/></var>-->
|
|
60
|
+
<!-- <for-each select="@*">-->
|
|
61
|
+
<!-- <div>-->
|
|
62
|
+
<!-- <var data-testid="section-attribute">@<value-of select='local-name(.)'/></var>-->
|
|
63
|
+
<!-- =-->
|
|
64
|
+
<!-- <code><value-of select='.'/></code>-->
|
|
65
|
+
<!-- </div>-->
|
|
66
|
+
<!-- </for-each>-->
|
|
67
|
+
<!-- </ul>-->
|
|
68
|
+
<!-- </for-each>-->
|
|
69
|
+
</template>
|
|
70
|
+
</custom-element>
|
|
59
71
|
|
|
60
72
|
</body>
|
|
61
73
|
</html>
|
package/demo/dom-merge.html
CHANGED
|
@@ -94,9 +94,9 @@
|
|
|
94
94
|
<form>
|
|
95
95
|
<label>
|
|
96
96
|
<input type="text"
|
|
97
|
-
value="Type time update"
|
|
97
|
+
value="{//txt ?? 'Type time update'}"
|
|
98
98
|
slice="txt"
|
|
99
|
-
slice-event="
|
|
99
|
+
slice-event="init input"/>
|
|
100
100
|
|
|
101
101
|
<span> Character count:
|
|
102
102
|
<b> {string-length(//slice/txt)} </b>
|
package/demo/http-request.html
CHANGED
|
@@ -31,6 +31,33 @@
|
|
|
31
31
|
<a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
|
|
32
32
|
</nav>
|
|
33
33
|
|
|
34
|
+
|
|
35
|
+
<html-demo-element legend="0. url from text to http-request "
|
|
36
|
+
description="read data from arbitrary URL">
|
|
37
|
+
<template>
|
|
38
|
+
<custom-element>
|
|
39
|
+
<template>
|
|
40
|
+
|
|
41
|
+
<button slice="url-string" slice-value="'https://pokeapi.co/api/v2/pokemon?limit=6'" slice-event="click">⬇️https://pokeapi.co/api/v2/pokemon?limit=6</button>
|
|
42
|
+
<input slice="url-string" value="{ //url-string ?? '' }" style="width:100%"/>
|
|
43
|
+
<button slice="fetch-url" slice-event="click" slice-value="//url-string"> GET </button>
|
|
44
|
+
<http-request
|
|
45
|
+
url="{//fetch-url}"
|
|
46
|
+
slice="request_slice"
|
|
47
|
+
type="text"
|
|
48
|
+
mode="cors"
|
|
49
|
+
></http-request>
|
|
50
|
+
<code>//fetch-url</code> from <code>{//fetch-url}</code><br/>
|
|
51
|
+
<for-each select="//results">
|
|
52
|
+
<var>
|
|
53
|
+
*{@name}
|
|
54
|
+
</var>
|
|
55
|
+
</for-each>
|
|
56
|
+
</template>
|
|
57
|
+
</custom-element>
|
|
58
|
+
</template>
|
|
59
|
+
</html-demo-element>
|
|
60
|
+
|
|
34
61
|
<html-demo-element legend="1. http-request simplest"
|
|
35
62
|
description="load the list of pokemons">
|
|
36
63
|
<p>Should display 6 image buttons with pokemon name </p>
|
package/demo/local-storage.html
CHANGED
|
@@ -16,14 +16,119 @@
|
|
|
16
16
|
td,th{text-align: right; }
|
|
17
17
|
caption{ padding: 1rem; font-weight: bolder; font-family: sans-serif; }
|
|
18
18
|
</style>
|
|
19
|
+
|
|
20
|
+
<script>
|
|
21
|
+
window.JsonSample = {a:1,b:'B'};
|
|
22
|
+
</script>
|
|
19
23
|
</head>
|
|
20
24
|
<body>
|
|
21
25
|
|
|
22
26
|
<nav>
|
|
23
27
|
<a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
|
|
24
28
|
</nav>
|
|
29
|
+
<main>
|
|
30
|
+
<code>local-storage</code> allows to read and write its value to the key in <code>localStorage</code>.
|
|
31
|
+
The <code>type</code> attribute allows to place the validation constrains to the value: when the value does not
|
|
32
|
+
match the expected type, it would not be assigned, keeping empty <code>value</code> instead.
|
|
33
|
+
</main>
|
|
34
|
+
<html-demo-element legend="0. read localStorage text value"
|
|
35
|
+
description="click should set text-key slice via localStorage change.">
|
|
36
|
+
<template>
|
|
37
|
+
<custom-element>
|
|
38
|
+
<template>
|
|
39
|
+
<local-storage key="textKey" slice="text-key" type="text" live="live"></local-storage>
|
|
40
|
+
<button onclick="localStorage.setItem('textKey','text value')">text value</button>
|
|
41
|
+
<button onclick="localStorage.setItem('textKey','another value')">another value</button>
|
|
42
|
+
//text-key: <code>{//text-key}</code>
|
|
43
|
+
</template>
|
|
44
|
+
</custom-element>
|
|
45
|
+
</template>
|
|
46
|
+
</html-demo-element>
|
|
47
|
+
|
|
48
|
+
<html-demo-element legend="1. always override "
|
|
49
|
+
description="value in localStorage[] should be always reset to ABC. click should set text-key slice via localStorage change.">
|
|
50
|
+
<template>
|
|
51
|
+
<custom-element>
|
|
52
|
+
<template>
|
|
53
|
+
<!-- always reset -->
|
|
54
|
+
<local-storage key="overrideKey" slice="override-key" type="text" value="ABC"></local-storage>
|
|
55
|
+
<button onclick="localStorage.setItem('overrideKey','text value')">text value</button>
|
|
56
|
+
<button onclick="localStorage.removeItem('attrKey')">clear key</button>
|
|
57
|
+
//override-key: <code>{//override-key}</code>
|
|
58
|
+
</template>
|
|
59
|
+
</custom-element>
|
|
60
|
+
</template>
|
|
61
|
+
</html-demo-element>
|
|
62
|
+
|
|
63
|
+
<html-demo-element legend="2. from storage with default "
|
|
64
|
+
description="default overridden by button, refresh should preserve updated value">
|
|
65
|
+
<template>
|
|
66
|
+
<custom-element>
|
|
67
|
+
<template>
|
|
68
|
+
<!-- initially set value to DEF and update by button. On reload the value picked from localStorage -->
|
|
69
|
+
<local-storage key="attr2Key" slice="attr2-key" type="text" live="live" slice-value="@value ?? 'DEF'"></local-storage>
|
|
70
|
+
<button onclick="localStorage.clear()">clear localStorage</button>
|
|
71
|
+
<button onclick="localStorage.removeItem('attr2Key')">clear key</button>
|
|
72
|
+
<button onclick="localStorage.setItem('attr2Key','text value')">updated value</button>
|
|
73
|
+
//attr2-key: <code>{//attr2-key}</code>
|
|
74
|
+
</template>
|
|
75
|
+
</custom-element>
|
|
76
|
+
</template>
|
|
77
|
+
</html-demo-element>
|
|
78
|
+
|
|
79
|
+
<html-demo-element legend="3. localStorage type"
|
|
80
|
+
description="type validation happy path. Invalid for type value in storage would be treated as null">
|
|
81
|
+
<template>
|
|
82
|
+
<custom-element>
|
|
83
|
+
<template>
|
|
84
|
+
<local-storage key="dateKey" slice="date-key" type="date" live="live"></local-storage>
|
|
85
|
+
<local-storage key="timeKey" slice="time-key" type="time" live="live"></local-storage>
|
|
86
|
+
<local-storage key="localDateTimeKey" slice="local-date-time" type="datetime-local" live="live"></local-storage>
|
|
87
|
+
<local-storage key="numberKey" slice="number-key" type="number" live="live"></local-storage>
|
|
88
|
+
<local-storage key="jsonKey" slice="json-key" type="json" live="live"></local-storage>
|
|
89
|
+
<input id="typesinput" placeholder="set value" /><button onclick="
|
|
90
|
+
'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',')
|
|
91
|
+
.map( k=> localStorage.setItem(k, typesinput.value) )
|
|
92
|
+
"> set to all</button><br/>
|
|
93
|
+
<hr/>
|
|
94
|
+
date-key:
|
|
95
|
+
<button onclick="localStorage.setItem('dateKey', '2024-04-20T03:58:42.131Z')" >2024-04-21T03:58:42.131Z </button>
|
|
96
|
+
<button onclick="localStorage.setItem('dateKey', new Date(Date.now()).toISOString())" >now </button>
|
|
97
|
+
<button onclick="localStorage.setItem('dateKey', 'ABC' )" >date ABC - invalid </button>
|
|
98
|
+
<code>{//date-key }</code><br/>
|
|
99
|
+
time-key:
|
|
100
|
+
<button onclick="localStorage.setItem('timeKey', '13:30')" >13:30 </button>
|
|
101
|
+
<code>{//time-key }</code><br/>
|
|
102
|
+
local-date-time:
|
|
103
|
+
<button onclick="localStorage.setItem('localDateTimeKey', '1977-04-01T14:00:30')" >21977-04-01T14:00:30 - local </button>
|
|
104
|
+
<code>{//local-date-time}</code><br/>
|
|
105
|
+
number-key:
|
|
106
|
+
<button onclick="localStorage.setItem('numberKey', '2024' )" >2024 - number </button>
|
|
107
|
+
<button onclick="localStorage.setItem('numberKey', '24' )" >24 - number </button>
|
|
108
|
+
<button onclick="localStorage.setItem('numberKey', '1.23456e+5' )" >1.23456e+5 </button>
|
|
109
|
+
<button onclick="localStorage.setItem('numberKey', '0001' )" >0001 </button>
|
|
110
|
+
<button onclick="localStorage.setItem('numberKey', '000' )" >000 </button>
|
|
111
|
+
<button onclick="localStorage.setItem('numberKey', '0' )" >0 </button>
|
|
112
|
+
<button onclick="localStorage.setItem('numberKey', 'ABC' )" >ABC - invalid, NaN </button>
|
|
113
|
+
<code>{//number-key }</code> <br/>
|
|
114
|
+
<fieldset>
|
|
115
|
+
<legend>json-key: </legend>
|
|
116
|
+
|
|
117
|
+
<button onclick="localStorage.setItem('jsonKey', JSON.stringify('ABC'))" >'ABC' - string </button>
|
|
118
|
+
<button onclick="localStorage.setItem('jsonKey', JSON.stringify(12.345))" >12.345 - number </button>
|
|
119
|
+
<button onclick="localStorage.setItem('jsonKey', JSON.stringify(window.JsonSample) )" >a:1,b:'B' -json </button>
|
|
120
|
+
<button onclick="localStorage.setItem('jsonKey', 'ABC' )" >ABC - invalid </button><br/>
|
|
121
|
+
json-key:<code><xsl:apply-templates select="//json-key/value/@*|//json-key/text()|//json-key/value/text()" mode="json"></xsl:apply-templates></code>
|
|
122
|
+
</fieldset>
|
|
123
|
+
<xsl:template mode="json" match="*|@*">
|
|
124
|
+
<div>{name()} : {.}</div>
|
|
125
|
+
</xsl:template>
|
|
126
|
+
</template>
|
|
127
|
+
</custom-element>
|
|
128
|
+
</template>
|
|
129
|
+
</html-demo-element>
|
|
25
130
|
|
|
26
|
-
<html-demo-element legend="
|
|
131
|
+
<html-demo-element legend="3. localStorage simplest"
|
|
27
132
|
description="local-storage read only during initial and only render, does not track the changes.">
|
|
28
133
|
<p>Has to produce 12🍒</p>
|
|
29
134
|
<template>
|
package/demo/s.xml
CHANGED
|
@@ -1,6 +1,93 @@
|
|
|
1
1
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
-
<datadom
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
2
|
+
<datadom>
|
|
3
|
+
<payload>
|
|
4
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
5
|
+
<button xmlns="http://www.w3.org/1999/xhtml" slice="url-string"
|
|
6
|
+
slice-value="'https://pokeapi.co/api/v2/pokemon?limit=6'" slice-event="click" slot="">
|
|
7
|
+
⬇️https://pokeapi.co/api/v2/pokemon?limit=6
|
|
8
|
+
</button>
|
|
9
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
10
|
+
<input xmlns="http://www.w3.org/1999/xhtml" slice="url-string" value="{ //url-string ?? '' }" style="width:100%"
|
|
11
|
+
slot=""/>
|
|
12
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
13
|
+
<button xmlns="http://www.w3.org/1999/xhtml" slice="fetch-url" slice-event="click" slice-value="//url-string"
|
|
14
|
+
slot="">GET
|
|
15
|
+
</button>
|
|
16
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
17
|
+
<http-request xmlns="http://www.w3.org/1999/xhtml" url="{//fetch-url}" slice="request_slice" type="text"
|
|
18
|
+
mode="cors" slot=""></http-request>
|
|
19
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
20
|
+
<code xmlns="http://www.w3.org/1999/xhtml" slot="">//fetch-url</code>
|
|
21
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot="">from</span>
|
|
22
|
+
<code xmlns="http://www.w3.org/1999/xhtml" slot="">{//fetch-url}</code>
|
|
23
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
24
|
+
<xsl:for-each xmlns="http://www.w3.org/1999/xhtml" select="//slice/request_slice/value/*" slot="">
|
|
25
|
+
<ul>
|
|
26
|
+
<var data-testid="request-section">
|
|
27
|
+
<xsl:value-of select="name(.)"></xsl:value-of>
|
|
28
|
+
</var>
|
|
29
|
+
<xsl:for-each select="@*">
|
|
30
|
+
<div>
|
|
31
|
+
<var data-testid="section-attribute">@
|
|
32
|
+
<xsl:value-of select="local-name(.)"></xsl:value-of>
|
|
33
|
+
</var>
|
|
34
|
+
=
|
|
35
|
+
<code>
|
|
36
|
+
<xsl:value-of select="."></xsl:value-of>
|
|
37
|
+
</code>
|
|
38
|
+
</div>
|
|
39
|
+
</xsl:for-each>
|
|
40
|
+
</ul>
|
|
41
|
+
</xsl:for-each>
|
|
42
|
+
<span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
|
|
43
|
+
</payload>
|
|
44
|
+
<attributes>
|
|
45
|
+
<tag>dce-5dc8d4a0-d545-4498-9de5-eec25c2b232f</tag>
|
|
46
|
+
</attributes>
|
|
47
|
+
<dataset/>
|
|
48
|
+
<slice>
|
|
49
|
+
<url-string xmlns="" slice="url-string" value="" style="width:100%" data-dce-id="2"
|
|
50
|
+
slice-value="'https://pokeapi.co/api/v2/pokemon?limit=6'" slice-event="click">
|
|
51
|
+
<event isTrusted="true" pointerId="1" width="1" height="1" pressure="0" tiltX="0" tiltY="0" azimuthAngle="0"
|
|
52
|
+
altitudeAngle="1.5707963267948966" tangentialPressure="0" twist="0" pointerType="mouse"
|
|
53
|
+
isPrimary="false" screenX="94" screenY="186" clientX="94" clientY="99" ctrlKey="false"
|
|
54
|
+
shiftKey="false" altKey="false" metaKey="false" button="0" buttons="0" pageX="94" pageY="99" x="94"
|
|
55
|
+
y="99" offsetX="60" offsetY="6" movementX="0" movementY="0" layerX="94" layerY="99" detail="1"
|
|
56
|
+
which="1" type="click" eventPhase="0" bubbles="true" cancelable="true" defaultPrevented="false"
|
|
57
|
+
composed="true" timeStamp="5596.5" returnValue="true" cancelBubble="false" NONE="0"
|
|
58
|
+
CAPTURING_PHASE="1" AT_TARGET="2" BUBBLING_PHASE="3">
|
|
59
|
+
<relatedTarget/>
|
|
60
|
+
<fromElement/>
|
|
61
|
+
<toElement/>
|
|
62
|
+
<sourceCapabilities firesTouchEvents="false"/>
|
|
63
|
+
<currentTarget/>
|
|
64
|
+
</event>
|
|
65
|
+
https://pokeapi.co/api/v2/pokemon?limit=6
|
|
66
|
+
</url-string>
|
|
67
|
+
<fetch-url xmlns="" slice="fetch-url" slice-event="click" slice-value="//url-string" data-dce-id="4" value="">
|
|
68
|
+
<event isTrusted="true" pointerId="1" width="1" height="1" pressure="0" tiltX="0" tiltY="0" azimuthAngle="0"
|
|
69
|
+
altitudeAngle="1.5707963267948966" tangentialPressure="0" twist="0" pointerType="mouse"
|
|
70
|
+
isPrimary="false" screenX="56" screenY="232" clientX="56" clientY="145" ctrlKey="false"
|
|
71
|
+
shiftKey="false" altKey="false" metaKey="false" button="0" buttons="0" pageX="56" pageY="145" x="56"
|
|
72
|
+
y="145" offsetX="23" offsetY="8" movementX="0" movementY="0" layerX="56" layerY="145" detail="1"
|
|
73
|
+
which="1" type="click" eventPhase="0" bubbles="true" cancelable="true" defaultPrevented="false"
|
|
74
|
+
composed="true" timeStamp="6699.100000023842" returnValue="true" cancelBubble="false" NONE="0"
|
|
75
|
+
CAPTURING_PHASE="1" AT_TARGET="2" BUBBLING_PHASE="3">
|
|
76
|
+
<relatedTarget/>
|
|
77
|
+
<fromElement/>
|
|
78
|
+
<toElement/>
|
|
79
|
+
<sourceCapabilities firesTouchEvents="false"/>
|
|
80
|
+
<currentTarget/>
|
|
81
|
+
</event>
|
|
82
|
+
https://pokeapi.co/api/v2/pokemon?limit=6
|
|
83
|
+
</fetch-url>
|
|
84
|
+
<request_slice xmlns="" url="" slice="request_slice" type="text" mode="cors" data-dce-id="5">
|
|
85
|
+
<event type="init"/>
|
|
86
|
+
<value>
|
|
87
|
+
<request xmlns="" url="" type="text" mode="cors" data-dce-id="5">
|
|
88
|
+
<headers/>
|
|
89
|
+
</request>
|
|
90
|
+
</value>
|
|
91
|
+
</request_slice>
|
|
92
|
+
</slice>
|
|
93
|
+
</datadom>
|
package/demo/s.xslt
CHANGED
|
@@ -6,13 +6,15 @@
|
|
|
6
6
|
<xsl:otherwise><xsl:value-of select="def"/></xsl:otherwise>
|
|
7
7
|
</xsl:choose>
|
|
8
8
|
<xsl:value-of select="."/></xsl:template>
|
|
9
|
-
<xsl:template mode="payload" match="attributes"><dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1"><
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
9
|
+
<xsl:template mode="payload" match="attributes"><dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1"><local-storage xmlns="" key="dateKey" slice="date-key" type="date" live="live" data-dce-id="2"/><local-storage xmlns="" key="timeKey" slice="time-key" type="time" live="live" data-dce-id="3"/><local-storage xmlns="" key="localDateTimeKey" slice="local-date-time" type="datetime-local" live="live" data-dce-id="4"/><local-storage xmlns="" key="numberKey" slice="number-key" type="number" live="live" data-dce-id="5"/><local-storage xmlns="" key="jsonKey" slice="json-key" type="json" live="live" data-dce-id="6"/><input xmlns="" id="typesinput" placeholder="set value" data-dce-id="7"/><button xmlns="" onclick=" 'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',') .map( k=> localStorage.setItem(k, typesinput.value) ) " data-dce-id="8"> set to all</button><br xmlns="" data-dce-id="9"/><hr xmlns="" data-dce-id="10"/><dce-text xmlns="" data-dce-id="11">
|
|
10
|
+
date-key:
|
|
11
|
+
</dce-text><button xmlns="" onclick="localStorage.setItem('dateKey', '2024-04-20T03:58:42.131Z')" data-dce-id="12">2024-04-21T03:58:42.131Z </button><button xmlns="" onclick="localStorage.setItem('dateKey', new Date(Date.now()).toISOString())" data-dce-id="13">now </button><button xmlns="" onclick="localStorage.setItem('dateKey', 'ABC' )" data-dce-id="14">date ABC - invalid </button><code xmlns="" data-dce-id="15"><xsl:value-of select="//date-key "/></code><br xmlns="" data-dce-id="16"/><dce-text xmlns="" data-dce-id="17">
|
|
12
|
+
time-key:
|
|
13
|
+
</dce-text><button xmlns="" onclick="localStorage.setItem('timeKey', '13:30')" data-dce-id="18">13:30 </button><code xmlns="" data-dce-id="19"><xsl:value-of select="//time-key "/></code><br xmlns="" data-dce-id="20"/><dce-text xmlns="" data-dce-id="21">
|
|
14
|
+
local-date-time:
|
|
15
|
+
</dce-text><button xmlns="" onclick="localStorage.setItem('localDateTimeKey', '1977-04-01T14:00:30')" data-dce-id="22">21977-04-01T14:00:30 - local </button><code xmlns="" data-dce-id="23"><xsl:value-of select="//local-date-time"/></code><br xmlns="" data-dce-id="24"/><dce-text xmlns="" data-dce-id="25">
|
|
16
|
+
number-key:
|
|
17
|
+
</dce-text><button xmlns="" onclick="localStorage.setItem('numberKey', '2024')" data-dce-id="26">2024 - number </button><button xmlns="" onclick="localStorage.setItem('numberKey', '24')" data-dce-id="27">24 - number </button><code xmlns="" data-dce-id="28"><xsl:value-of select="//number-key "/></code><br xmlns="" data-dce-id="29"/><fieldset xmlns="" data-dce-id="30"><legend data-dce-id="31">json-key: </legend><button onclick="localStorage.setItem('jsonKey', jsonStringSample)" data-dce-id="32"> a:1,b:'B' - json </button><xsl:apply-templates xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="//json-key/value/@*" mode="json"/></fieldset></dce-root></xsl:template>
|
|
16
18
|
<xsl:template match="/">
|
|
17
19
|
<xsl:apply-templates mode="payload" select="/datadom/attributes"/>
|
|
18
20
|
</xsl:template>
|
|
@@ -34,4 +36,4 @@
|
|
|
34
36
|
<xsl:with-param name="defaultvalue"/>
|
|
35
37
|
</xsl:call-template>
|
|
36
38
|
</xsl:variable>
|
|
37
|
-
|
|
39
|
+
<xsl:template xmlns:xsl="http://www.w3.org/1999/XSL/Transform" mode="json" match="*|@*"><div xmlns="" data-dce-id="33"><xsl:value-of select="name()"/> : <xsl:value-of select="."/></div></xsl:template></xsl:stylesheet>
|
package/demo/ss.html
CHANGED
|
@@ -1,32 +1,52 @@
|
|
|
1
|
-
|
|
2
|
-
<
|
|
3
|
-
|
|
4
|
-
<
|
|
5
|
-
<
|
|
6
|
-
<
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
|
+
<dce-root data-dce-id="1" xmlns="http://www.w3.org/1999/xhtml" xmlns:dce="urn:schemas-epa-wg:dce"
|
|
3
|
+
xmlns:xhtml="http://www.w3.org/1999/xhtml">
|
|
4
|
+
<local-storage key="dateKey" slice="date-key" type="date" live="live" data-dce-id="2" xmlns=""/>
|
|
5
|
+
<local-storage key="timeKey" slice="time-key" type="time" live="live" data-dce-id="3" xmlns=""/>
|
|
6
|
+
<local-storage key="localDateTimeKey" slice="local-date-time" type="datetime-local" live="live" data-dce-id="4"
|
|
7
|
+
xmlns=""/>
|
|
8
|
+
<local-storage key="numberKey" slice="number-key" type="number" live="live" data-dce-id="5" xmlns=""/>
|
|
9
|
+
<local-storage key="jsonKey" slice="json-key" type="json" live="live" data-dce-id="6" xmlns=""/>
|
|
10
|
+
<input id="typesinput" placeholder="set value" data-dce-id="7" xmlns=""/>
|
|
11
|
+
<button onclick=" 'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',') .map( k=> localStorage.setItem(k, typesinput.value) ) "
|
|
12
|
+
data-dce-id="8" xmlns=""> set to all
|
|
13
|
+
</button>
|
|
14
|
+
<br data-dce-id="9" xmlns=""/>
|
|
15
|
+
<hr data-dce-id="10" xmlns=""/>
|
|
16
|
+
<dce-text data-dce-id="11" xmlns="">
|
|
17
|
+
date-key:
|
|
18
|
+
</dce-text>
|
|
19
|
+
<button onclick="localStorage.setItem('dateKey', '2024-04-20T03:58:42.131Z')" data-dce-id="12" xmlns="">
|
|
20
|
+
2024-04-21T03:58:42.131Z
|
|
21
|
+
</button>
|
|
22
|
+
<button onclick="localStorage.setItem('dateKey', new Date(Date.now()).toISOString())" data-dce-id="13" xmlns="">
|
|
23
|
+
now
|
|
24
|
+
</button>
|
|
25
|
+
<button onclick="localStorage.setItem('dateKey', 'ABC' )" data-dce-id="14" xmlns="">date ABC - invalid</button>
|
|
26
|
+
<code data-dce-id="15" xmlns="">
|
|
7
27
|
|
|
8
|
-
<script type="module" src="../http-request.js"></script>
|
|
9
|
-
<script type="module" src="../input-text.js"></script>
|
|
10
|
-
<script type="module" src="../custom-element.js"></script>
|
|
11
|
-
<style>
|
|
12
|
-
@import "./demo.css";
|
|
13
|
-
</style>
|
|
14
|
-
</head>
|
|
15
|
-
<body>
|
|
16
28
|
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
</
|
|
29
|
+
</code><br data-dce-id="16" xmlns=""/>
|
|
30
|
+
<dce-text data-dce-id="17" xmlns="">
|
|
31
|
+
time-key:
|
|
32
|
+
</dce-text>
|
|
33
|
+
<button onclick="localStorage.setItem('timeKey', '13:30')" data-dce-id="18" xmlns="">13:30</button>
|
|
34
|
+
<code data-dce-id="19" xmlns=""/><br data-dce-id="20" xmlns=""/>
|
|
35
|
+
<dce-text data-dce-id="21" xmlns="">
|
|
36
|
+
local-date-time:
|
|
37
|
+
</dce-text>
|
|
38
|
+
<button onclick="localStorage.setItem('localDateTimeKey', '1977-04-01T14:00:30')" data-dce-id="22" xmlns="">
|
|
39
|
+
21977-04-01T14:00:30 - local
|
|
40
|
+
</button>
|
|
41
|
+
<code data-dce-id="23" xmlns=""/><br data-dce-id="24" xmlns=""/>
|
|
42
|
+
<dce-text data-dce-id="25" xmlns="">
|
|
43
|
+
number-key:
|
|
44
|
+
</dce-text>
|
|
45
|
+
<button onclick="localStorage.setItem('numberKey', '2024')" data-dce-id="26" xmlns="">2024 - number</button>
|
|
46
|
+
<button onclick="localStorage.setItem('numberKey', '24')" data-dce-id="27" xmlns="">24 - number</button>
|
|
47
|
+
<code data-dce-id="28" xmlns=""/><br data-dce-id="29" xmlns=""/>
|
|
48
|
+
<fieldset data-dce-id="30" xmlns="">
|
|
49
|
+
<legend data-dce-id="31">json-key:</legend>
|
|
50
|
+
<button onclick="localStorage.setItem('jsonKey', jsonStringSample)" data-dce-id="32"> a:1,b:'B' - json</button>
|
|
51
|
+
</fieldset>
|
|
52
|
+
</dce-root>
|
package/http-request.js
CHANGED
|
@@ -2,14 +2,13 @@ const attr = (el, attr)=> el.getAttribute(attr);
|
|
|
2
2
|
|
|
3
3
|
export class HttpRequestElement extends HTMLElement
|
|
4
4
|
{
|
|
5
|
-
static
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
}
|
|
5
|
+
static observedAttributes =
|
|
6
|
+
[ 'value' // populated from localStorage, if defined initially, sets the value in storage
|
|
7
|
+
, 'slice'
|
|
8
|
+
, 'url'
|
|
9
|
+
, 'method'
|
|
10
|
+
, 'header-accept'
|
|
11
|
+
];
|
|
13
12
|
|
|
14
13
|
get requestHeaders()
|
|
15
14
|
{ const ret = {};
|
|
@@ -23,30 +22,59 @@ export class HttpRequestElement extends HTMLElement
|
|
|
23
22
|
return ret
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
disconnectedCallback(){ this
|
|
25
|
+
disconnectedCallback(){ this.#destroy?.(); }
|
|
27
26
|
|
|
28
27
|
connectedCallback()
|
|
29
|
-
{
|
|
30
|
-
|
|
28
|
+
{
|
|
29
|
+
setTimeout(()=>this.fetch(),0)
|
|
30
|
+
}
|
|
31
|
+
#inProgressUrl = ''
|
|
32
|
+
#destroy = ()=>{}
|
|
33
|
+
|
|
34
|
+
async fetch()
|
|
35
|
+
{
|
|
36
|
+
if( !this.closest('custom-element') )
|
|
37
|
+
return;
|
|
38
|
+
const url = attr(this, 'url') || '';
|
|
39
|
+
if( !url )
|
|
40
|
+
{ this.#destroy?.();
|
|
41
|
+
return this.value = {};
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
if( this.#inProgressUrl === url )
|
|
45
|
+
return ;
|
|
46
|
+
|
|
47
|
+
this.#inProgressUrl = url;
|
|
48
|
+
const controller = new AbortController();
|
|
49
|
+
this.#destroy = ()=> controller.abort(this.localName+' disconnected');
|
|
31
50
|
|
|
32
|
-
const
|
|
33
|
-
, request = { ...this.requestProps, headers: this.requestHeaders }
|
|
51
|
+
const request = { ...this.requestProps, headers: this.requestHeaders }
|
|
34
52
|
, slice = { request }
|
|
35
53
|
, update = () => this.dispatchEvent( new Event('change') );
|
|
36
54
|
this.value = slice;
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
},0 );
|
|
55
|
+
|
|
56
|
+
update();
|
|
57
|
+
const response = await fetch(url,{ ...this.requestProps, signal: controller.signal, headers: this.requestHeaders })
|
|
58
|
+
, r = {headers: {}};
|
|
59
|
+
[...response.headers].map( ([k,v]) => r.headers[k] = v );
|
|
60
|
+
'ok,status,statusText,type,url,redirected'.split(',').map( k=> r[k] = response[k] )
|
|
61
|
+
|
|
62
|
+
slice.response = r;
|
|
63
|
+
update();
|
|
64
|
+
slice.data = await response.json();
|
|
65
|
+
update();
|
|
49
66
|
}
|
|
67
|
+
|
|
68
|
+
attributeChangedCallback(name, oldValue, newValue)
|
|
69
|
+
{ if( name === 'url' )
|
|
70
|
+
{ if( newValue && oldValue !== newValue)
|
|
71
|
+
{
|
|
72
|
+
oldValue && this.#destroy?.();
|
|
73
|
+
setTimeout(()=>this.fetch(),0)
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
}
|
|
77
|
+
|
|
50
78
|
}
|
|
51
79
|
|
|
52
80
|
window.customElements.define( 'http-request', HttpRequestElement );
|
package/ide/web-types-dce.json
CHANGED
package/ide/web-types-xsl.json
CHANGED
package/local-storage.js
CHANGED
|
@@ -2,44 +2,81 @@ const string2value = (type, v) =>
|
|
|
2
2
|
{ if( type === 'text')
|
|
3
3
|
return v;
|
|
4
4
|
if( type === 'json')
|
|
5
|
-
return JSON.parse( v );
|
|
5
|
+
try{ return JSON.parse( v );}
|
|
6
|
+
catch(err){ return null }
|
|
6
7
|
const el = document.createElement('input');
|
|
7
8
|
el.setAttribute('type',type);
|
|
8
|
-
|
|
9
|
-
|
|
9
|
+
if( 'number' === type )
|
|
10
|
+
{ el.value = v;
|
|
11
|
+
return el.valueAsNumber;
|
|
12
|
+
}
|
|
13
|
+
if( 'date' === type )
|
|
14
|
+
{ if(!v) return null;
|
|
15
|
+
el.valueAsDate = new Date( v );
|
|
16
|
+
return el.value;
|
|
17
|
+
}
|
|
18
|
+
el.value = v;
|
|
19
|
+
return el.value;
|
|
10
20
|
};
|
|
11
21
|
|
|
22
|
+
let originalSetItem,originalRemoveItem,originalClear;
|
|
23
|
+
|
|
24
|
+
function ensureTrackLocalStorage()
|
|
25
|
+
{ if( originalSetItem )
|
|
26
|
+
return;
|
|
27
|
+
originalSetItem = localStorage.setItem;
|
|
28
|
+
localStorage.setItem = function( key, value, ...rest )
|
|
29
|
+
{ originalSetItem.apply(this, [ key, value, ...rest ]);
|
|
30
|
+
window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
|
|
31
|
+
};
|
|
32
|
+
originalRemoveItem = localStorage.removeItem;
|
|
33
|
+
localStorage.removeItem = function( key, ...rest )
|
|
34
|
+
{ originalRemoveItem.apply(this, [ key, ...rest ]);
|
|
35
|
+
window.dispatchEvent( new CustomEvent('local-storage',{detail:{key}}) );
|
|
36
|
+
};
|
|
37
|
+
originalClear = localStorage.clear;
|
|
38
|
+
localStorage.clear = function( ...rest )
|
|
39
|
+
{ originalClear.apply(this, [ ...rest ]);
|
|
40
|
+
window.dispatchEvent( new CustomEvent('local-storage',{detail:{}}) );
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
|
|
12
44
|
export function localStorageSetItem(key, value)
|
|
13
45
|
{ localStorage.setItem(key, value);
|
|
14
46
|
window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
|
|
15
47
|
}
|
|
16
48
|
export class LocalStorageElement extends HTMLElement
|
|
17
49
|
{
|
|
18
|
-
static
|
|
19
|
-
|
|
50
|
+
static observedAttributes=
|
|
51
|
+
[ 'value' // populated from localStorage, if defined initially, sets the value in storage
|
|
20
52
|
, 'slice'
|
|
21
53
|
, 'key'
|
|
22
54
|
, 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
|
|
23
55
|
, 'live' // monitors localStorage change
|
|
24
56
|
];
|
|
25
|
-
|
|
57
|
+
|
|
58
|
+
#value;
|
|
59
|
+
get value(){ return this.#value ===null ? undefined: this.#value }
|
|
60
|
+
set value(o){ return this.#value = o; }
|
|
26
61
|
|
|
27
62
|
async connectedCallback()
|
|
28
63
|
{
|
|
29
64
|
const attr = attr => this.getAttribute(attr)
|
|
30
65
|
, fromStorage = ()=>
|
|
31
|
-
{ this
|
|
66
|
+
{ this.#value = string2value( attr('type'), localStorage.getItem( attr( 'key' ) ) );
|
|
32
67
|
this.dispatchEvent( new Event('change') )
|
|
33
68
|
}
|
|
34
|
-
|
|
69
|
+
this.#value = string2value( attr('type'), localStorage.getItem( attr( 'key' ) ) );
|
|
70
|
+
|
|
35
71
|
if( this.hasAttribute('value'))
|
|
36
|
-
localStorageSetItem( attr(
|
|
72
|
+
localStorageSetItem( attr( 'key' ), this.#value = attr( 'value' ) )
|
|
37
73
|
else
|
|
38
74
|
fromStorage()
|
|
39
75
|
|
|
40
76
|
if( this.hasAttribute('live') )
|
|
41
|
-
{ const listener = (e => e.detail.key === attr( 'key' ) && fromStorage());
|
|
77
|
+
{ const listener = (e => (e.detail.key === attr( 'key' ) || !e.detail.key ) && fromStorage());
|
|
42
78
|
window.addEventListener( 'local-storage', listener );
|
|
79
|
+
ensureTrackLocalStorage();
|
|
43
80
|
this._destroy = ()=> window.removeEventListener('local-storage', listener );
|
|
44
81
|
}
|
|
45
82
|
}
|
package/location-element.js
CHANGED
|
@@ -2,13 +2,13 @@ const attr = (el, attr)=> el.getAttribute(attr);
|
|
|
2
2
|
|
|
3
3
|
export class LocationElement extends HTMLElement
|
|
4
4
|
{
|
|
5
|
-
static
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
5
|
+
static observedAttributes=
|
|
6
|
+
[ 'value' // populated from localStorage, if defined initially, sets the value in storage
|
|
7
|
+
, 'slice'
|
|
8
|
+
, 'key'
|
|
9
|
+
, 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
|
|
10
|
+
, 'live' // monitors localStorage change
|
|
11
|
+
];
|
|
12
12
|
|
|
13
13
|
constructor()
|
|
14
14
|
{
|
package/package.json
CHANGED