@epa-wg/custom-element 0.0.20 → 0.0.22

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/demo/s.xslt CHANGED
@@ -1,32 +1,53 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dce="urn:schemas-epa-wg:dce" xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="exsl">
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"
3
+ xmlns:dce="urn:schemas-epa-wg:dce" xmlns:exsl="http://exslt.org/common" version="1.0"
4
+ exclude-result-prefixes="exsl">
3
5
  <xsl:template match="ignore">
4
6
  <xsl:choose>
5
- <xsl:when test="//attr"><xsl:value-of select="//attr"/></xsl:when>
6
- <xsl:otherwise><xsl:value-of select="def"/></xsl:otherwise>
7
+ <xsl:when test="//attr">
8
+ <xsl:value-of select="//attr"/>
9
+ </xsl:when>
10
+ <xsl:otherwise>
11
+ <xsl:value-of select="def"/>
12
+ </xsl:otherwise>
7
13
  </xsl:choose>
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"><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="&#10; 'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',')&#10; .map( k=&gt; localStorage.setItem(k, typesinput.value) )&#10; " 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>
14
+ <xsl:value-of select="."/>
15
+ </xsl:template>
16
+ <xsl:template mode="payload" match="attributes">
17
+ <dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1">
18
+ <u xmlns="" data-dce-id="2">
19
+ <dce-text data-dce-id="3">
20
+ <xsl:call-template name="slot">
21
+ <xsl:with-param name="slotname" select="''"/>
22
+ <xsl:with-param name="defaultvalue">
23
+ <dce-text xmlns="" data-dce-id="4">is green</dce-text>
24
+ </xsl:with-param>
25
+ </xsl:call-template>
26
+ </dce-text>
27
+ </u>
28
+ </dce-root>
29
+ </xsl:template>
18
30
  <xsl:template match="/">
19
31
  <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
20
32
  </xsl:template>
33
+
34
+ <xsl:template match="@*|node()" mode="copy-html">
35
+ <xsl:copy><xsl:apply-templates select="@*|node()" mode="copy-html"/></xsl:copy>
36
+ </xsl:template>
37
+ <xsl:template match="node()[starts-with(name(),'xhtml:')]" mode="copy-html">
38
+ <xsl:element name="{local-name()}"><xsl:apply-templates select="@*|node()" mode="copy-html"/></xsl:element>
39
+ </xsl:template>
40
+
41
+
21
42
  <xsl:template name="slot">
22
43
  <xsl:param name="slotname"/>
23
44
  <xsl:param name="defaultvalue"/>
24
45
  <xsl:choose>
25
46
  <xsl:when test="//payload/*[@slot=$slotname]">
26
- <xsl:copy-of select="//payload/*[@slot=$slotname]"/>
47
+ <xsl:apply-templates mode="copy-html" select="//payload/*[@slot=$slotname]"/>
27
48
  </xsl:when>
28
49
  <xsl:otherwise>
29
- <xsl:copy-of select="$defaultvalue"/>
50
+ <xsl:apply-templates mode="copy-html" select="$defaultvalue"/>
30
51
  </xsl:otherwise>
31
52
  </xsl:choose>
32
53
  </xsl:template>
@@ -36,4 +57,4 @@
36
57
  <xsl:with-param name="defaultvalue"/>
37
58
  </xsl:call-template>
38
59
  </xsl:variable>
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>
60
+ </xsl:stylesheet>
package/demo/s1.xslt ADDED
@@ -0,0 +1,60 @@
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"
3
+ xmlns:dce="urn:schemas-epa-wg:dce" xmlns:exsl="http://exslt.org/common" version="1.0"
4
+ exclude-result-prefixes="exsl">
5
+ <xsl:template match="ignore">
6
+ <xsl:choose>
7
+ <xsl:when test="//attr">
8
+ <xsl:value-of select="//attr"/>
9
+ </xsl:when>
10
+ <xsl:otherwise>
11
+ <xsl:value-of select="def"/>
12
+ </xsl:otherwise>
13
+ </xsl:choose>
14
+ <xsl:value-of select="."/>
15
+ </xsl:template>
16
+ <xsl:template mode="payload" match="attributes">
17
+ <dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1">
18
+ <u xmlns="" data-dce-id="2">
19
+ <dce-text data-dce-id="3">
20
+ <xsl:call-template name="slot">
21
+ <xsl:with-param name="slotname" select="''"/>
22
+ <xsl:with-param name="defaultvalue">
23
+ <dce-text xmlns="" data-dce-id="4">is green</dce-text>
24
+ </xsl:with-param>
25
+ </xsl:call-template>
26
+ </dce-text>
27
+ </u>
28
+ </dce-root>
29
+ </xsl:template>
30
+ <xsl:template match="/">
31
+ <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
32
+ </xsl:template>
33
+
34
+ <xsl:template match="@*|node()" mode="copy-html">
35
+ <xsl:copy><xsl:apply-templates select="@*|node()" mode="copy-html"/></xsl:copy>
36
+ </xsl:template>
37
+ <xsl:template match="node()[starts-with(name(),'xhtml:')]" mode="copy-html">
38
+ <xsl:element name="{local-name()}"><xsl:apply-templates select="@*|node()" mode="copy-html"/></xsl:element>
39
+ </xsl:template>
40
+
41
+
42
+ <xsl:template name="slot">
43
+ <xsl:param name="slotname"/>
44
+ <xsl:param name="defaultvalue"/>
45
+ <xsl:choose>
46
+ <xsl:when test="//payload/*[@slot=$slotname]">
47
+ <xsl:apply-templates mode="copy-html" select="//payload/*[@slot=$slotname]"/>
48
+ </xsl:when>
49
+ <xsl:otherwise>
50
+ <xsl:apply-templates mode="copy-html" select="$defaultvalue"/>
51
+ </xsl:otherwise>
52
+ </xsl:choose>
53
+ </xsl:template>
54
+ <xsl:variable name="js-injected-body">
55
+ <xsl:call-template name="slot">
56
+ <xsl:with-param name="slotname" select="''"/>
57
+ <xsl:with-param name="defaultvalue"/>
58
+ </xsl:call-template>
59
+ </xsl:variable>
60
+ </xsl:stylesheet>
@@ -6,7 +6,6 @@
6
6
  <link rel="icon" href="./wc-square.svg"/>
7
7
 
8
8
  <script type="module" src="../http-request.js"></script>
9
- <script type="module" src="../input-text.js"></script>
10
9
  <script type="module" src="../custom-element.js"></script>
11
10
  <style>
12
11
  @import "./demo.css";
package/demo/ss.html CHANGED
@@ -1,52 +1,57 @@
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="&#10; 'dateKey,timeKey,localDateTimeKey,numberKey,jsonKey'.split(',')&#10; .map( k=&gt; localStorage.setItem(k, typesinput.value) )&#10; "
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="">
27
-
28
-
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>
1
+ <dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dce="urn:schemas-epa-wg:dce" data-dce-id="1"><http-request xmlns="" url="/reflect" slice="page" data-dce-id="2"></http-request><p xmlns="" data-dce-id="3">Pokemon Count: 6</p>
2
+ <ul xmlns="" data-dce-id="6">
3
+ <var data-testid="request-section" data-dce-id="7"><dce-text data-dce-id="8">request</dce-text></var><div data-dce-id="9">
4
+ <var data-dce-id="10">@url</var><dce-text data-dce-id="11">
5
+ =
6
+ </dce-text><code data-testid="attr-url" data-dce-id="12">/reflect</code>
7
+ </div>
8
+ <div data-dce-id="9-1">
9
+ <var data-dce-id="10">@data-dce-id</var><dce-text data-dce-id="11">
10
+ =
11
+ </dce-text><code data-testid="attr-data-dce-id" data-dce-id="12">2</code>
12
+ </div>
13
+ </ul>
14
+ <ul xmlns="" data-dce-id="6-1">
15
+ <var data-testid="request-section" data-dce-id="7"><dce-text data-dce-id="8">response</dce-text></var><div data-dce-id="9">
16
+ <var data-dce-id="10">@ok</var><dce-text data-dce-id="11">
17
+ =
18
+ </dce-text><code data-testid="attr-ok" data-dce-id="12">true</code>
19
+ </div>
20
+ <div data-dce-id="9-1">
21
+ <var data-dce-id="10">@status</var><dce-text data-dce-id="11">
22
+ =
23
+ </dce-text><code data-testid="attr-status" data-dce-id="12">200</code>
24
+ </div>
25
+ <div data-dce-id="9-2">
26
+ <var data-dce-id="10">@statusText</var><dce-text data-dce-id="11">
27
+ =
28
+ </dce-text><code data-testid="attr-statusText" data-dce-id="12">OK</code>
29
+ </div>
30
+ <div data-dce-id="9-3">
31
+ <var data-dce-id="10">@type</var><dce-text data-dce-id="11">
32
+ =
33
+ </dce-text><code data-testid="attr-type" data-dce-id="12">basic</code>
34
+ </div>
35
+ <div data-dce-id="9-4">
36
+ <var data-dce-id="10">@url</var><dce-text data-dce-id="11">
37
+ =
38
+ </dce-text><code data-testid="attr-url" data-dce-id="12">http://localhost:5173/reflect</code>
39
+ </div>
40
+ <div data-dce-id="9-5">
41
+ <var data-dce-id="10">@redirected</var><dce-text data-dce-id="11">
42
+ =
43
+ </dce-text><code data-testid="attr-redirected" data-dce-id="12">false</code>
44
+ </div>
45
+ </ul><button xmlns="" data-dce-id="5">bulbasaur</button><button xmlns="" data-dce-id="5-1">ivysaur</button><button xmlns="" data-dce-id="5-2">venusaur</button><button xmlns="" data-dce-id="5-3">charmander</button><button xmlns="" data-dce-id="5-4">charmeleon</button><button xmlns="" data-dce-id="5-5">charizard</button>
46
+ <ul xmlns="" data-dce-id="6-2">
47
+ <var data-testid="request-section" data-dce-id="7"><dce-text data-dce-id="8">data</dce-text></var><div data-dce-id="9">
48
+ <var data-dce-id="10">@count</var><dce-text data-dce-id="11">
49
+ =
50
+ </dce-text><code data-testid="attr-count" data-dce-id="12">1279</code>
51
+ </div>
52
+ <div data-dce-id="9-1">
53
+ <var data-dce-id="10">@next</var><dce-text data-dce-id="11">
54
+ =
55
+ </dce-text><code data-testid="attr-next" data-dce-id="12">https://pokeapi.co/api/v2/pokemon?offset=6&amp;limit=6</code>
56
+ </div>
57
+ </ul></dce-root>
package/http-request.js CHANGED
@@ -33,7 +33,7 @@ export class HttpRequestElement extends HTMLElement
33
33
 
34
34
  async fetch()
35
35
  {
36
- if( !this.closest('custom-element') )
36
+ if( !this.closest('body') )
37
37
  return;
38
38
  const url = attr(this, 'url') || '';
39
39
  if( !url )
@@ -46,7 +46,7 @@ export class HttpRequestElement extends HTMLElement
46
46
 
47
47
  this.#inProgressUrl = url;
48
48
  const controller = new AbortController();
49
- this.#destroy = ()=> controller.abort(this.localName+' disconnected');
49
+ this.#destroy = ()=> { controller.abort(this.localName+' disconnected'); this.#inProgressUrl = ''; }
50
50
 
51
51
  const request = { ...this.requestProps, headers: this.requestHeaders }
52
52
  , slice = { request }
@@ -61,16 +61,24 @@ export class HttpRequestElement extends HTMLElement
61
61
 
62
62
  slice.response = r;
63
63
  update();
64
- slice.data = await response.json();
65
- update();
64
+ if( r.headers['content-type']?.includes('json'))
65
+ try
66
+ { slice.data = await response.json();
67
+ update();
68
+ }catch(_e){}
66
69
  }
67
70
 
68
71
  attributeChangedCallback(name, oldValue, newValue)
69
72
  { if( name === 'url' )
70
- { if( newValue && oldValue !== newValue)
73
+ { if( oldValue !== newValue)
71
74
  {
72
75
  oldValue && this.#destroy?.();
73
- setTimeout(()=>this.fetch(),0)
76
+ if( newValue )
77
+ setTimeout(()=>this.fetch(),10)
78
+ else
79
+ { this.value = {}
80
+ setTimeout(()=>this.dispatchEvent( new Event('change') ),10)
81
+ }
74
82
  }
75
83
  }
76
84
  }
@@ -27,6 +27,19 @@
27
27
  }
28
28
  ]
29
29
  },
30
+ {
31
+ "name": "custom-validity",
32
+ "description": {
33
+ "kind": "markdown",
34
+ "value": "XPath expression to return either boolean or error string to be shown by browser native UI on form validation event. Unless value is true, prevents the form submission."
35
+ },
36
+ "references": [
37
+ {
38
+ "name": "Demo",
39
+ "url": "https://unpkg.com/@epa-wg/custom-element/demo/form.html"
40
+ }
41
+ ]
42
+ },
30
43
  {
31
44
  "name": "slice-value",
32
45
  "description": {
@@ -109,4 +122,4 @@
109
122
  ]
110
123
  }
111
124
  ]
112
- }
125
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json.schemastore.org/web-types",
3
3
  "name": "@epa-wg/custom-element",
4
- "version": "0.0.20",
4
+ "version": "0.0.22",
5
5
  "js-types-syntax": "typescript",
6
6
  "description-markup": "markdown",
7
7
  "contributions": {
@@ -17,6 +17,11 @@
17
17
  "description": "Defines the event name on which `value` would be synchronized with DCE slice\n\nOn: any component with `value` and associated change event",
18
18
  "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/dom-merge.html"
19
19
  },
20
+ {
21
+ "name": "custom-validity",
22
+ "description": "XPath expression to return either boolean or error string to be shown by browser native UI on form validation event. Unless value is true, prevents the form submission.",
23
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/form.html"
24
+ },
20
25
  {
21
26
  "name": "slice-value",
22
27
  "description": "XPath expression to populate into the slice",
@@ -108,4 +113,4 @@
108
113
  ]
109
114
  }
110
115
  }
111
- }
116
+ }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$schema": "http://json.schemastore.org/web-types",
3
3
  "name": "@epa-wg/custom-element",
4
- "version": "0.0.20",
4
+ "version": "0.0.22",
5
5
  "js-types-syntax": "typescript",
6
6
  "description-markup": "markdown",
7
7
  "contributions": {
@@ -864,4 +864,4 @@
864
864
  ]
865
865
  }
866
866
  }
867
- }
867
+ }
package/index.html CHANGED
@@ -35,6 +35,7 @@
35
35
  <a href="./demo/scoped-css.html" >scoped CSS </a> |
36
36
  <a href="./demo/parameters.html" >attributes </a> |
37
37
  <a href="./demo/data-slices.html" >data slices/events </a> |
38
+ <a href="./demo/form.html" >Form validation </a> |
38
39
  <a href="./demo/dom-merge.html" >DOM merge on dynamic update </a>
39
40
  </section>
40
41
  </nav>
package/index.js ADDED
@@ -0,0 +1,7 @@
1
+ import CustomElement from "./custom-element.js";
2
+ export default CustomElement;
3
+
4
+ export * from "./custom-element.js";
5
+ export * from "./http-request.js";
6
+ export * from "./local-storage.js";
7
+ export * from "./location-element.js";
package/local-storage.js CHANGED
@@ -62,7 +62,7 @@ export class LocalStorageElement extends HTMLElement
62
62
  async connectedCallback()
63
63
  {
64
64
  const attr = attr => this.getAttribute(attr)
65
- , fromStorage = ()=>
65
+ , fromStorage = ()=>
66
66
  { this.#value = string2value( attr('type'), localStorage.getItem( attr( 'key' ) ) );
67
67
  this.dispatchEvent( new Event('change') )
68
68
  }
@@ -84,4 +84,4 @@ export class LocalStorageElement extends HTMLElement
84
84
  }
85
85
 
86
86
  window.customElements.define( 'local-storage', LocalStorageElement );
87
- export default LocalStorageElement;
87
+ export default LocalStorageElement;
@@ -1,23 +1,42 @@
1
- const attr = (el, attr)=> el.getAttribute(attr);
1
+ const attr = ( el, attr )=> el.getAttribute( attr );
2
+
3
+ let originalHistory;
4
+
5
+ function ensureTrackLocationChange()
6
+ { if( originalHistory )
7
+ return;
8
+ originalHistory = {};
9
+ 'back,forward,go,pushState,replaceState'.split(',').forEach( k =>
10
+ {
11
+ originalHistory[ k ] = history[ k ];
12
+ history[ k ] = function(...rest )
13
+ {
14
+ originalHistory[k].apply( history, rest );
15
+ window.dispatchEvent( new CustomEvent('dce-location',{detail:{ k }}) );
16
+ }
17
+ });
18
+ }
2
19
 
3
20
  export class LocationElement extends HTMLElement
4
21
  {
5
22
  static observedAttributes=
6
- [ 'value' // populated from localStorage, if defined initially, sets the value in storage
23
+ [ 'value' // populated from url
7
24
  , 'slice'
8
- , 'key'
25
+ , 'href' // url to be parsed. When omitted window.location is used.
9
26
  , 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
10
- , 'live' // monitors localStorage change
27
+ , 'live' // monitors history change, applicable only when href is omitted.
11
28
  ];
12
29
 
13
30
  constructor()
14
31
  {
15
32
  super();
16
33
  const state = {}
17
- , listener = e=> propagateSlice(e)
34
+ , listener = () => setTimeout( propagateSlice,1 )
18
35
  , propagateSlice = ()=>
19
- { const urlStr = attr(this,'src')
20
- const url = urlStr? new URL(urlStr) : window.location
36
+ { const urlStr = attr(this,'href')
37
+ if(!urlStr)
38
+ ensureTrackLocationChange();
39
+ const url = urlStr? new URL(urlStr, window.location) : window.location;
21
40
 
22
41
  const params= {}
23
42
  const search = new URLSearchParams(url.search);
@@ -36,24 +55,30 @@ export class LocationElement extends HTMLElement
36
55
  {
37
56
  if( !state.listener && this.hasAttribute('live') )
38
57
  { state.listener = 1;
39
- window.addEventListener( 'popstate' , listener );
40
- window.addEventListener( 'hashchange', listener );
58
+ window.navigation?.addEventListener("navigate", listener );
59
+ window.addEventListener( 'popstate' , listener );
60
+ window.addEventListener( 'hashchange' , listener );
61
+ window.addEventListener( 'dce-location' , listener );
41
62
  }
42
63
  propagateSlice();
43
64
  return s || {}
44
65
  }
45
66
  this._destroy = ()=>
46
67
  {
47
- if( !state.listener )
48
- return;
49
- if(state.listener)
50
- { window.removeEventListener('popstate' , listener);
51
- window.removeEventListener('hashchange', listener);
52
- }
68
+ window.removeEventListener('popstate' , listener);
69
+ window.removeEventListener('hashchange' , listener);
70
+ window.removeEventListener('dce-location', listener);
53
71
  delete state.listener;
54
72
  };
55
73
 
56
74
  }
75
+ attributeChangedCallback(name, oldValue, newValue)
76
+ {
77
+ if('href'!== name)
78
+ return;
79
+ this.sliceInit && this.sliceInit();
80
+ }
81
+
57
82
  connectedCallback(){ this.sliceInit() }
58
83
  disconnectedCallback(){ this._destroy() }
59
84
  }
package/package.json CHANGED
@@ -1,11 +1,11 @@
1
1
  {
2
2
  "name": "@epa-wg/custom-element",
3
- "version": "0.0.20",
3
+ "version": "0.0.22",
4
4
  "description": "Declarative Custom Element as W3C proposal PoC with native(XSLT) based templating",
5
5
  "browser": "custom-element.js",
6
6
  "module": "custom-element.js",
7
7
  "exports": {
8
- ".": "./custom-element.js",
8
+ ".": "./index.js",
9
9
  "./package.json": "./package.json",
10
10
  "./CustomElement": "./custom-element.js"
11
11
  },
@@ -16,7 +16,7 @@
16
16
  "dev:help": "echo \"needed for sandbox demo\"",
17
17
  "dev": "bash bin/stackblitz.sh",
18
18
  "start": "npm i --no-save @web/dev-server && web-dev-server --node-resolve",
19
- "test": "echo \"test would reside in https://github.com/EPA-WG/custom-element-test\" && exit 0",
19
+ "test": "echo \"test would reside in https://github.com/EPA-WG/custom-element-dist\" && exit 0",
20
20
  "typings": "npx -p typescript tsc custom-element.js --declaration --allowJs --emitDeclarationOnly "
21
21
  },
22
22
  "type": "module",
package/input-text.js DELETED
@@ -1,17 +0,0 @@
1
- export class InputTextElement extends HTMLElement
2
- {
3
- constructor()
4
- {
5
- super();
6
- const i = this.ownerDocument.createElement('input');
7
- for(let a of this.attributes)
8
- a.namespaceURI ? i.setAttributeNS(a.namespaceURI,a.name,a.value) : i.setAttribute(a.name,a.value)
9
- this.append(i)
10
- }
11
- get value(){ return this.firstChild.value }
12
- set value(v){ return this.firstChild.value = v }
13
- disconnectedCallback(){ }
14
- }
15
-
16
- window.customElements.define( 'input-text', InputTextElement );
17
- export default InputTextElement;