@epa-wg/custom-element 0.0.24 → 0.0.25

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 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-dist@0.0.24/coverage/src/custom-element/coverage.svg
352
- [coverage-url]: https://unpkg.com/@epa-wg/custom-element-dist@0.0.24/coverage/src/custom-element/index.html
353
- [storybook-url]: https://unpkg.com/@epa-wg/custom-element-dist@0.0.24/storybook-static/index.html?path=/story/welcome--introduction
351
+ [coverage-image]: https://unpkg.com/@epa-wg/custom-element-dist@0.0.25/coverage/src/custom-element/coverage.svg
352
+ [coverage-url]: https://unpkg.com/@epa-wg/custom-element-dist@0.0.25/coverage/src/custom-element/index.html
353
+ [storybook-url]: https://unpkg.com/@epa-wg/custom-element-dist@0.0.25/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
@@ -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.24",
119
+ "version": "0.0.25",
120
120
  "js-types-syntax": "typescript",
121
121
  "description-markup": "markdown",
122
122
  "contributions": {
package/custom-element.js CHANGED
@@ -9,12 +9,22 @@ const attr = (el, attr)=> el.getAttribute?.(attr)
9
9
  , isText = e => e.nodeType === 3
10
10
  , isString = s => typeof s === 'string'
11
11
  , isNode = e => e && typeof e.nodeType === 'number'
12
- , create = ( tag, t = '', d=document ) => ( e => ((t && e.append(createText(d.ownerDocument||d, t))),e) )((d.ownerDocument || d ).createElement( tag ))
13
12
  , createText = ( d, t) => (d.ownerDocument || d ).createTextNode( t )
14
13
  , removeChildren = n => { while(n.firstChild) n.firstChild.remove(); return n; }
15
14
  , emptyNode = n => { n.getAttributeNames().map( a => n.removeAttribute(a) ); return removeChildren(n); }
16
15
  , xslNs = x => ( x?.setAttribute('xmlns:xsl', XSL_NS_URL ), x )
17
16
  , xslHtmlNs = x => ( x?.setAttribute('xmlns:xhtml', HTML_NS_URL ), xslNs(x) )
17
+ , isValidTagName = tag=> ( /^[_a-zA-Z][-_:a-zA-Z0-9]*$/ .test(tag) )
18
+ , create = ( tag, t = '', d=document ) =>
19
+ {
20
+ const create = tag => ( e => ((t && e.append(createText(d.ownerDocument||d, t))),e) )((d.ownerDocument || d ).createElement( tag ))
21
+
22
+ if( isValidTagName(tag) )
23
+ return create(tag)
24
+ const e = create('dce-object');
25
+ e.setAttribute('dce-object-name',tag)
26
+ return e;
27
+ }
18
28
  , cloneAs = (p,tag) =>
19
29
  { const px = p.ownerDocument.createElementNS(p.namespaceURI,tag);
20
30
  for( let a of p.attributes)
@@ -86,7 +96,7 @@ obj2node( o, tag, doc )
86
96
  if( isNode(o[k]) || typeof o[k] ==='function' || o[k] instanceof Window )
87
97
  continue
88
98
  else
89
- if( typeof o[k] !== "object" )
99
+ if( typeof o[k] !== "object" && isValidTagName(k) )
90
100
  ret.setAttribute(k, o[k] );
91
101
  else
92
102
  ret.append(obj2node(o[k], k, doc))
@@ -594,7 +604,9 @@ CustomElement extends HTMLElement
594
604
  e.append( createText( x, t ))
595
605
  return e;
596
606
  })(x.ownerDocument.createElement( tag ))
597
- injectData( x, 'payload' , payload , assureSlot );
607
+ const payloadNode = injectData( x, 'payload' , payload , assureSlot );
608
+ xslNs(payloadNode);
609
+ xslHtmlNs(payloadNode);
598
610
  this.innerHTML='';
599
611
  const attrsRoot = injectData( x, 'attributes' , this.attributes, e => createXmlNode( e.nodeName, e.value ) );
600
612
  injectData( x, 'dataset', Object.keys( this.dataset ), k => createXmlNode( k, this.dataset[ k ] ) );
@@ -654,7 +666,7 @@ CustomElement extends HTMLElement
654
666
  { if( !el.dceInitialized )
655
667
  { el.dceInitialized = 1;
656
668
  let evs = attr(el,'slice-event');
657
- if( attr(el,'custom-validity') )
669
+ if( el.hasAttribute('custom-validity') )
658
670
  evs += ' change submit';
659
671
 
660
672
  [...new Set((evs || 'change') .split(' '))]
@@ -22,7 +22,19 @@
22
22
  <nav>
23
23
  <a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
24
24
  </nav>
25
- <html-demo-element legend="Change window URL">
25
+ <main>
26
+ <h3>How to get the page URL by location-element?</h3>
27
+ Answer: by defining following attributes:
28
+ <ol>
29
+ <li><code>slice</code> to one of values provided bellow</li>
30
+ <li><code>src</code> optionally with URL, If omitted, it would match the <code>window.location.href</code> </li>
31
+ </ol>
32
+ URL properties would be a part of slice data.
33
+ <p><a href="./set-url.html">Set page URL demo</a> </p>
34
+ </main>
35
+ <html-demo-element legend="Change window URL"
36
+ description="use browser URL bar or those controls to change the page URL"
37
+ >
26
38
  <template>
27
39
  <a href="#dce2">#dce2</a>
28
40
  <form method="get">
@@ -40,7 +52,8 @@
40
52
 
41
53
 
42
54
  <html-demo-element legend="1. window.location live update"
43
- description="In the page beginning change the window URL via link or by history change"
55
+ description="Change the window URL via link or history change by controls in #1.
56
+ Observe the changes detected by location-element slice."
44
57
  id="dce2"
45
58
  >
46
59
  <p>Has to produce URL properties</p>
@@ -48,7 +61,7 @@
48
61
  <custom-element tag="dce-2" hidden>
49
62
  <template>
50
63
 
51
- <location-element slice="window-url" live></location-element>
64
+ <location-element slice="window-url" live method="" src=""></location-element>
52
65
 
53
66
  <xhtml:table>
54
67
  <xhtml:tbody>
@@ -121,7 +134,7 @@
121
134
  <custom-element tag="dce-3" hidden>
122
135
  <template>
123
136
 
124
- <location-element slice="href-url" href="https://my.example?a=1&b=2#3"></location-element>
137
+ <location-element slice="href-url" href="https://my.example?a=1&b=2#3" ></location-element>
125
138
 
126
139
  <xhtml:table>
127
140
  <xhtml:tbody>
package/demo/s.xml CHANGED
@@ -1,11 +1,36 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
2
  <datadom>
3
+ <payload xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
4
+ <span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
5
+ <button xmlns="http://www.w3.org/1999/xhtml" value="#dce4" slice="set-button" slice-event="click" slot="">set
6
+ </button>
7
+ <span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
8
+ <xsl:if xmlns="http://www.w3.org/1999/xhtml" test="//form-data/url" slot="">
9
+ <location-element method="{$selected-method}" src="{//form-data/url}"></location-element>
10
+ {$selected-method} - {//form-data/url}
11
+ </xsl:if>
12
+ <span xmlns="http://www.w3.org/1999/xhtml" slot=""></span>
13
+ </payload>
14
+ <attributes>
15
+ <tag>dce-9d95a532-8e54-414a-9077-08799530a637</tag>
16
+ </attributes>
17
+ <dataset/>
3
18
  <slice>
4
- <signin-form>
5
- <form-data>
6
- <username>QWE</username>
7
- <password>ASD</password>
8
- </form-data>
9
- </signin-form>
19
+ <set-button xmlns="" value="#dce4" slice="set-button" slice-event="click" data-dce-id="2" validation-message="">
20
+ <event isTrusted="true" sliceProcessed="1" pointerId="1" width="1" height="1" pressure="0" tiltX="0"
21
+ tiltY="0" azimuthAngle="0" altitudeAngle="1.5707963267948966" tangentialPressure="0" twist="0"
22
+ pointerType="mouse" isPrimary="false" screenX="47" screenY="538" clientX="47" clientY="451"
23
+ ctrlKey="false" shiftKey="false" altKey="false" metaKey="false" button="0" buttons="0" pageX="47"
24
+ pageY="451" x="47" y="451" offsetX="20" offsetY="8" movementX="0" movementY="0" layerX="47"
25
+ layerY="451" detail="1" which="1" type="click" eventPhase="2" bubbles="true" cancelable="true"
26
+ defaultPrevented="false" composed="true" timeStamp="11628.100000143051" returnValue="true"
27
+ cancelBubble="false" NONE="0" CAPTURING_PHASE="1" AT_TARGET="2" BUBBLING_PHASE="3">
28
+ <relatedTarget/>
29
+ <fromElement/>
30
+ <toElement/>
31
+ <sourceCapabilities firesTouchEvents="false"/>
32
+ </event>
33
+ #dce4
34
+ </set-button>
10
35
  </slice>
11
36
  </datadom>
package/demo/s.xslt CHANGED
@@ -1,4 +1,3 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
1
  <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml"
3
2
  xmlns:dce="urn:schemas-epa-wg:dce" xmlns:exsl="http://exslt.org/common" version="1.0"
4
3
  exclude-result-prefixes="exsl">
@@ -15,39 +14,77 @@
15
14
  </xsl:template>
16
15
  <xsl:template mode="payload" match="attributes">
17
16
  <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>
17
+ <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="methods">
18
+ <a xmlns="" href="https://developer.mozilla.org/en-US/docs/Web/API/Location/href" data-dce-id="2">
19
+ location.href
20
+ </a>
21
+ <a xmlns="" href="https://developer.mozilla.org/en-US/docs/Web/API/Location/hash" data-dce-id="3">
22
+ location.hash
23
+ </a>
24
+ <a xmlns="" href="https://developer.mozilla.org/en-US/docs/Web/API/Location/assign" data-dce-id="4">
25
+ location.assign
26
+ </a>
27
+ </xsl:variable>
28
+ <fieldset xmlns="" data-dce-id="5">
29
+ <legend data-dce-id="6">
30
+ <b data-dce-id="7">set-by</b>
31
+ </legend>
32
+ <xsl:for-each xmlns:xsl="http://www.w3.org/1999/XSL/Transform" select="$methods">
33
+ <p data-dce-id="8">
34
+ <label data-dce-id="9">
35
+ <input type="radio" name="method" value="{.}" data-dce-id="10"/>
36
+ <dce-text data-dce-id="11">
37
+ <xsl:value-of select="."/>
38
+ </dce-text>
39
+ </label>
40
+ <a class="infolink" href="https://developer.mozilla.org/en-US/docs/Web/API/Location/assign"
41
+ data-dce-id="12">mdn
42
+ </a>
43
+ </p>
44
+ </xsl:for-each>
45
+ <label data-dce-id="13">
46
+ <input type="radio" name="method" value="location.href" data-dce-id="14"/>
47
+ <dce-text data-dce-id="15">location.href</dce-text>
48
+ </label>
49
+ <label data-dce-id="16">
50
+ <input type="radio" name="method" value="location" data-dce-id="17"/>
51
+ <dce-text data-dce-id="18">location</dce-text>
52
+ </label>
53
+ <label data-dce-id="19">
54
+ <input type="radio" name="method" value="location.replace" data-dce-id="20"/>
55
+ <dce-text data-dce-id="21">location.replace</dce-text>
56
+ </label>
57
+ <label data-dce-id="22">
58
+ <input type="radio" name="method" value="location.assign" data-dce-id="23"/>
59
+ <dce-text data-dce-id="24">location.assign</dce-text>
60
+ </label>
61
+ <label data-dce-id="25">
62
+ <input type="radio" name="method" value="location.hash" data-dce-id="26"/>
63
+ <dce-text data-dce-id="27">location.hash</dce-text>
64
+ </label>
65
+ <label data-dce-id="28">
66
+ <input type="radio" name="method" value="history.pushState" data-dce-id="29"/>
67
+ <dce-text data-dce-id="30">history.pushState</dce-text>
68
+ </label>
69
+ <label data-dce-id="31">
70
+ <input type="radio" name="method" value="history.replaceState" data-dce-id="32"/>
71
+ <dce-text data-dce-id="33">history.replaceState</dce-text>
72
+ </label>
73
+ </fieldset>
28
74
  </dce-root>
29
75
  </xsl:template>
30
76
  <xsl:template match="/">
31
77
  <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
32
78
  </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
79
  <xsl:template name="slot">
43
80
  <xsl:param name="slotname"/>
44
81
  <xsl:param name="defaultvalue"/>
45
82
  <xsl:choose>
46
83
  <xsl:when test="//payload/*[@slot=$slotname]">
47
- <xsl:apply-templates mode="copy-html" select="//payload/*[@slot=$slotname]"/>
84
+ <xsl:copy-of select="//payload/*[@slot=$slotname]"/>
48
85
  </xsl:when>
49
86
  <xsl:otherwise>
50
- <xsl:apply-templates mode="copy-html" select="$defaultvalue"/>
87
+ <xsl:copy-of select="$defaultvalue"/>
51
88
  </xsl:otherwise>
52
89
  </xsl:choose>
53
90
  </xsl:template>
@@ -0,0 +1,141 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
3
+ xmlns:xhtml="http://www.w3.org/1999/xhtml">
4
+ <head>
5
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
6
+ <title>custom-element Declarative Custom Element implementation demo</title>
7
+ <link rel="icon" href="./wc-square.svg"/>
8
+ <script type="module" src="../location-element.js"></script>
9
+ <script type="module" src="../custom-element.js"></script>
10
+ <style>
11
+ @import "./demo.css";
12
+ input[type="text"]{ min-width: 30rem; }
13
+
14
+ .infolink {
15
+ &:before {
16
+ content: '❔';
17
+ display: inline-block;
18
+ border-radius: 1.2em;
19
+ }
20
+
21
+ &:hover:before {
22
+ background: blue;
23
+ }
24
+ }
25
+ </style>
26
+ </head>
27
+ <body>
28
+ <nav>
29
+ <a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
30
+ </nav>
31
+ <main>
32
+ <h3>How to set the page URL by location-element?</h3>
33
+ Answer: by defining following attributes:
34
+ <ol>
35
+ <li><code>method</code> to one of values provided bellow</li>
36
+ <li><code>src</code> with URL </li>
37
+ </ol>
38
+ <p> &lt;location-element&gt; is safe to be used unconditionally as long as `src` is missing or same as page URL.
39
+ Otherwise it can be injected by event driven condition as in sample <a href="#dce3">#3</a> </p>
40
+ </main>
41
+ <html-demo-element legend="1. Set the page URL by location.hash"
42
+ description="click on 'set' button and observe hash value change in url"
43
+ id="dce1">
44
+ <template>
45
+ <custom-element>
46
+ <template>
47
+ <button value="#dce1" slice="set-button" slice-event="click">#dce1</button>
48
+ <button value="#dce2" slice="set-button" slice-event="click">#dce2</button>
49
+ <location-element method="location.href" src="{//set-button/@value}"></location-element>
50
+ </template>
51
+ </custom-element>
52
+ </template>
53
+ </html-demo-element>
54
+
55
+ <html-demo-element legend="2. Set the page URL by method"
56
+ description="click on 'set' button and observe hash value change in url"
57
+ id="dce2">
58
+ <template>
59
+ <custom-element>
60
+ <template>
61
+ <style>
62
+ button{ display: block; width: 100%; }
63
+ </style>
64
+ <button value="location.href" slice="set-button" slice-event="click"> location.href </button>
65
+ <button value="location.hash" slice="set-button" slice-event="click"> location.hash </button>
66
+ <button value="location.assign" slice="set-button" slice-event="click"> location.assign </button>
67
+ <button value="location.replace" slice="set-button" slice-event="click"> location.replace </button>
68
+ <button value="history.pushState" slice="set-button" slice-event="click"> history.pushState </button>
69
+ <button value="history.replaceState" slice="set-button" slice-event="click"> history.replaceState </button>
70
+ <location-element method="{//set-button/@value}" src="#dce2"></location-element>
71
+ </template>
72
+ </custom-element>
73
+ </template>
74
+ </html-demo-element>
75
+
76
+ <html-demo-element legend="3. Set the page URL by location.href in conditionally injected location-element"
77
+ description="click on 'set' button and observe in url #dce3"
78
+ id="dce3">
79
+ <p>Has to produce URL properties</p>
80
+ <template>
81
+ <custom-element>
82
+ <template>
83
+ <button value="#dce3" slice="set-button" slice-event="click">set</button>
84
+ <if test="//set-button/@slice-event">
85
+ <location-element method="location.href" src="#dce3"></location-element>
86
+ look for <b>#dce3</b> in URL which is set by <code>location-element</code>
87
+ </if>
88
+ </template>
89
+ </custom-element>
90
+ </template>
91
+ </html-demo-element>
92
+
93
+ <html-demo-element legend="4. Set page URL methods"
94
+ description="To define the URL, fill input field or click the radio button, then 'set' button. "
95
+ id="dce4">
96
+ <template>
97
+ <custom-element>
98
+ <template>
99
+ <xsl:variable name="methods">
100
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/Location/href"
101
+ title="./set-url.html?a=A">location.href</a>
102
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/Location/hash"
103
+ title="#dec4">location.hash</a>
104
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/Location/assign"
105
+ title="./set-url.html?assign=1">location.assign</a>
106
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/Location/replace"
107
+ title="./set-url.html?replace=location">location.replace</a>
108
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/History/pushState"
109
+ title="./set-url.html?history=pushState">history.pushState</a>
110
+ <a href="https://developer.mozilla.org/en-US/docs/Web/API/History/replaceState"
111
+ title="./set-url.html?history=replaceState">history.replaceState</a>
112
+ </xsl:variable>
113
+ <form slice="url-form" custom-validity="'invalid'" method="post">
114
+ <fieldset>
115
+ <legend><b>set-by</b></legend>
116
+ <for-each select="exsl:node-set($methods)/*">
117
+ <p><label><input type="radio" name="method" value="{.}"/> {.} </label>
118
+ <a class="infolink" href="{@href}">mdn</a>
119
+ </p>
120
+ </for-each>
121
+ </fieldset>
122
+ <variable name="selected-method" select="//form-data/method/text()"></variable>
123
+ <variable name="selected-url"
124
+ select="exsl:node-set($methods)/*[text() = $selected-method ]/@title"></variable>
125
+
126
+ <label><input name="url" value="{//url ?? $selected-url }" type="text"/></label>
127
+ <button name="submit-btn" value="by-submit" type="submit">set</button>
128
+ <if test="//form-data/url">
129
+ <location-element method="{$selected-method}" src="{//form-data/url}"></location-element>
130
+ {$selected-method} = {//form-data/url}
131
+ </if>
132
+ </form>
133
+ </template>
134
+ </custom-element>
135
+ </template>
136
+ </html-demo-element>
137
+
138
+ <script type="module" src="https://unpkg.com/html-demo-element@1/html-demo-element.js"></script>
139
+
140
+ </body>
141
+ </html>
@@ -120,6 +120,62 @@
120
120
  "url": "https://github.com/EPA-WG/custom-element/tree/develop?tab=readme-ov-file#interactivity-via-data-slice-triggered-by-events"
121
121
  }
122
122
  ]
123
+ },
124
+ {
125
+ "name": "location-element",
126
+ "description": "get/set window URL parts or from SRC URL",
127
+ "attributes": [
128
+ {
129
+ "name": "href",
130
+ "description": "url to be parsed. When omitted window.location is used.",
131
+ "type": "string",
132
+ "references": [
133
+ {
134
+ "name": "MDN docs",
135
+ "url": "https://developer.mozilla.org/en-US/docs/Web/API/Location/href"
136
+ }
137
+ ]
138
+ },
139
+ {
140
+ "name": "live",
141
+ "description": "monitors history change, applicable only when href is omitted.",
142
+ "type": "string",
143
+ "references": [
144
+ {
145
+ "name": "docs",
146
+ "url": "https://unpkg.com/@epa-wg/custom-element@0/demo/location-element.html"
147
+ }
148
+ ]
149
+ },
150
+ {
151
+ "name": "src",
152
+ "description": "sets the window URL",
153
+ "type": "string",
154
+ "references": [
155
+ {
156
+ "name": "docs",
157
+ "url": "https://unpkg.com/@epa-wg/custom-element@0/demo/set-url.html"
158
+ }
159
+ ]
160
+ },
161
+ {
162
+ "name": "method",
163
+ "description": "when defined, changes URL by one of predefined methods.",
164
+ "type": "string",
165
+ "references": [
166
+ {
167
+ "name": "docs",
168
+ "url": "https://unpkg.com/@epa-wg/custom-element@0/demo/set-url.html"
169
+ }
170
+ ]
171
+ }
172
+ ],
173
+ "references": [
174
+ {
175
+ "name": "docs",
176
+ "url": "https://github.com/EPA-WG/custom-element"
177
+ }
178
+ ]
123
179
  }
124
180
  ]
125
181
  }
@@ -1,116 +1,159 @@
1
1
  {
2
- "$schema": "http://json.schemastore.org/web-types",
3
- "name": "@epa-wg/custom-element",
4
- "version": "0.0.24",
5
- "js-types-syntax": "typescript",
6
- "description-markup": "markdown",
7
- "contributions": {
8
- "html": {
9
- "attributes": [
10
- {
11
- "name": "slice",
12
- "description": "Defines the name of data slice in DCE where the data from `value` will be propagated on `change` or by `slice-event` event\n\nOn: any component with `value` and associated change event",
13
- "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/dom-merge.html"
14
- },
15
- {
16
- "name": "slice-event",
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
- "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/dom-merge.html"
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
- },
25
- {
26
- "name": "slice-value",
27
- "description": "XPath expression to populate into the slice",
28
- "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/data-slices.html"
29
- }
30
- ],
31
- "elements": [
32
- {
33
- "name": "custom-element",
34
- "description": "Declarative Custom Element as W3C proposal PoC with native(XSLT) based templating",
35
- "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#custom-element",
36
- "attributes": [
37
- {
38
- "name": "hidden",
39
- "description": "hides DCE definition to prevent visual appearance of content. Wrap the payload into template tag to prevent applying the inline CSS in global scope.",
40
- "required": false,
41
- "doc-url": "https://developer.mozilla.org/en-US/docs/web/html/global_attributes/hidden",
42
- "value": {
43
- "type": "boolean"
44
- }
45
- },
46
- {
47
- "name": "tag",
48
- "description": "HTML tag for Custom Element. Used for window.customElements.define(). If not set, would be generated and DCE instance rendered inline. ",
49
- "default": "",
50
- "required": false,
51
- "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#tag-attribute",
52
- "value": {
53
- "type": "string"
54
- }
55
- },
56
- {
57
- "name": "src",
58
- "description": "full, relative, or hash URL to DCE template.",
59
- "default": "",
60
- "required": false,
61
- "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#src-attribute",
62
- "value": {
63
- "type": "URL"
64
- }
65
- }
66
- ],
67
- "slots": [],
68
- "js": {
69
- "events": [
70
- {
71
- "name": "value:changed",
72
- "description": "Emitted when data changes. Can be used for state serialization in hydration flow"
73
- }
2
+ "$schema": "http://json.schemastore.org/web-types",
3
+ "name": "@epa-wg/custom-element",
4
+ "version": "0.0.25",
5
+ "js-types-syntax": "typescript",
6
+ "description-markup": "markdown",
7
+ "contributions": {
8
+ "html": {
9
+ "attributes": [
10
+ {
11
+ "name": "slice",
12
+ "description": "Defines the name of data slice in DCE where the data from `value` will be propagated on `change` or by `slice-event` event\n\nOn: any component with `value` and associated change event",
13
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/dom-merge.html"
14
+ },
15
+ {
16
+ "name": "slice-event",
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
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/dom-merge.html"
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
+ },
25
+ {
26
+ "name": "slice-value",
27
+ "description": "XPath expression to populate into the slice",
28
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element/demo/data-slices.html"
29
+ }
74
30
  ],
75
- "properties": [
76
- {
77
- "name": "value",
78
- "type": "string",
79
- "default": "",
80
- "description": "DCE state. Can be used for state serialization in hydration flow. Format TBD, most likely encoded XML string"
81
- }
82
- ]
83
- },
84
- "css": {
85
- "properties": [
86
- ]
87
- }
88
- },
89
- {
90
- "name": "for-each",
91
- "description": "The <xsl:for-each> element selects a set of nodes and processes each of them in the same way. It is often used to iterate through a set of nodes or to change the current node. If one or more <xsl:sort> elements appear as the children of this element, sorting occurs before processing. Otherwise, nodes are processed in document order.",
92
- "doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each",
93
- "attributes": [
94
- {
95
- "name": "select",
96
- "description": "Uses an XPath expression to select nodes to be processed.",
97
- "required": true,
98
- "doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each#select",
99
- "value": {
100
- "type": "string"
101
- }
102
- }
103
- ]
104
- },
105
- {
106
- "name": "slice",
107
- "description": "Synthetic element for defining the slice-attributed when more then one slice/event/value associated with parent element",
108
- "doc-url": "https://github.com/EPA-WG/custom-element/tree/develop?tab=readme-ov-file#interactivity-via-data-slice-triggered-by-events",
109
- "attributes": [
31
+ "elements": [
32
+ {
33
+ "name": "custom-element",
34
+ "description": "Declarative Custom Element as W3C proposal PoC with native(XSLT) based templating",
35
+ "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#custom-element",
36
+ "attributes": [
37
+ {
38
+ "name": "hidden",
39
+ "description": "hides DCE definition to prevent visual appearance of content. Wrap the payload into template tag to prevent applying the inline CSS in global scope.",
40
+ "required": false,
41
+ "doc-url": "https://developer.mozilla.org/en-US/docs/web/html/global_attributes/hidden",
42
+ "value": {
43
+ "type": "boolean"
44
+ }
45
+ },
46
+ {
47
+ "name": "tag",
48
+ "description": "HTML tag for Custom Element. Used for window.customElements.define(). If not set, would be generated and DCE instance rendered inline. ",
49
+ "default": "",
50
+ "required": false,
51
+ "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#tag-attribute",
52
+ "value": {
53
+ "type": "string"
54
+ }
55
+ },
56
+ {
57
+ "name": "src",
58
+ "description": "full, relative, or hash URL to DCE template.",
59
+ "default": "",
60
+ "required": false,
61
+ "doc-url": "https://github.com/EPA-WG/custom-element?tab=readme-ov-file#src-attribute",
62
+ "value": {
63
+ "type": "URL"
64
+ }
65
+ }
66
+ ],
67
+ "slots": [ ],
68
+ "js": {
69
+ "events": [
70
+ {
71
+ "name": "value:changed",
72
+ "description": "Emitted when data changes. Can be used for state serialization in hydration flow"
73
+ }
74
+ ],
75
+ "properties": [
76
+ {
77
+ "name": "value",
78
+ "type": "string",
79
+ "default": "",
80
+ "description": "DCE state. Can be used for state serialization in hydration flow. Format TBD, most likely encoded XML string"
81
+ }
82
+ ]
83
+ },
84
+ "css": {
85
+ "properties": [
86
+ ]
87
+ }
88
+ },
89
+ {
90
+ "name": "for-each",
91
+ "description": "The <xsl:for-each> element selects a set of nodes and processes each of them in the same way. It is often used to iterate through a set of nodes or to change the current node. If one or more <xsl:sort> elements appear as the children of this element, sorting occurs before processing. Otherwise, nodes are processed in document order.",
92
+ "doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each",
93
+ "attributes": [
94
+ {
95
+ "name": "select",
96
+ "description": "Uses an XPath expression to select nodes to be processed.",
97
+ "required": true,
98
+ "doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each#select",
99
+ "value": {
100
+ "type": "string"
101
+ }
102
+ }
103
+ ]
104
+ },
105
+ {
106
+ "name": "location-element",
107
+ "description": "get/set window URL parts or from SRC URL",
108
+ "doc-url": "https://github.com/EPA-WG/custom-element",
109
+ "attributes": [
110
+ {
111
+ "name": "href",
112
+ "description": "url to be parsed. When omitted window.location is used.",
113
+ "required": false,
114
+ "doc-url": "https://developer.mozilla.org/en-US/docs/Web/API/Location/href",
115
+ "value": {
116
+ "type": "string"
117
+ }
118
+ },
119
+ {
120
+ "name": "live",
121
+ "description": "monitors history change, applicable only when href is omitted.",
122
+ "required": false,
123
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element@0/demo/location-element.html",
124
+ "value": {
125
+ "type": "string"
126
+ }
127
+ },
128
+ {
129
+ "name": "src",
130
+ "description": "sets the window URL",
131
+ "required": false,
132
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element@0/demo/set-url.html",
133
+ "value": {
134
+ "type": "string"
135
+ }
136
+ },
137
+ {
138
+ "name": "method",
139
+ "description": "when defined, changes URL by one of predefined methods.",
140
+ "required": false,
141
+ "doc-url": "https://unpkg.com/@epa-wg/custom-element@0/demo/set-url.html",
142
+ "value": {
143
+ "type": "string"
144
+ }
145
+ }
146
+ ]
147
+ },
148
+ {
149
+ "name": "slice",
150
+ "description": "Synthetic element for defining the slice-attributed when more then one slice/event/value associated with parent element",
151
+ "doc-url": "https://github.com/EPA-WG/custom-element/tree/develop?tab=readme-ov-file#interactivity-via-data-slice-triggered-by-events",
152
+ "attributes": [
110
153
 
111
- ]
154
+ ]
155
+ }
156
+ ]
112
157
  }
113
- ]
114
158
  }
115
- }
116
159
  }
@@ -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.24",
4
+ "version": "0.0.25",
5
5
  "js-types-syntax": "typescript",
6
6
  "description-markup": "markdown",
7
7
  "contributions": {
package/index.html CHANGED
@@ -30,6 +30,7 @@
30
30
  <a href="./demo/local-storage.html" >local-storage </a> |
31
31
  <a href="./demo/http-request.html" >http-request </a> |
32
32
  <a href="./demo/location-element.html" >location-element </a> |
33
+ <a href="./demo/set-url.html" >set-url </a> |
33
34
  <a href="./demo/external-template.html" >external template </a> <br/>
34
35
  <a href="./demo/hex-grid.html" >hex grid lib </a> |
35
36
  <a href="./demo/scoped-css.html" >scoped CSS </a> |
@@ -16,6 +16,15 @@ function ensureTrackLocationChange()
16
16
  }
17
17
  });
18
18
  }
19
+ const methods =
20
+ { 'location.href' : src => window.location.href = src
21
+ , 'location.hash' : src => window.location.hash = src
22
+ , 'location.assign' : src => window.location.assign( src )
23
+ , 'location.replace' : src => window.location.replace( src )
24
+ , 'history.pushState' : src => window.history.pushState( {}, "", src )
25
+ , 'history.replaceState' : src => window.history.replaceState( {}, "", src )
26
+ };
27
+
19
28
 
20
29
  export class LocationElement extends HTMLElement
21
30
  {
@@ -25,6 +34,8 @@ export class LocationElement extends HTMLElement
25
34
  , 'href' // url to be parsed. When omitted window.location is used.
26
35
  , 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
27
36
  , 'live' // monitors history change, applicable only when href is omitted.
37
+ , 'src' // sets the URL
38
+ , 'method' // when defined, changes URL by one of predefined methods.
28
39
  ];
29
40
 
30
41
  constructor()
@@ -53,6 +64,17 @@ export class LocationElement extends HTMLElement
53
64
  };
54
65
  this.sliceInit = s =>
55
66
  {
67
+ if( this.hasAttribute('method') )
68
+ {
69
+ const method = this.getAttribute('method');
70
+ const src = this.getAttribute('src');
71
+ if( method && src )
72
+ if( method === 'location.hash' )
73
+ { if( src !== window.location.hash )
74
+ methods[ method ]?.( src );
75
+ }else if( window.location.href !== new URL(src, window.location).href )
76
+ methods[method]?.(src);
77
+ }
56
78
  if( !state.listener && this.hasAttribute('live') )
57
79
  { state.listener = 1;
58
80
  window.navigation?.addEventListener("navigate", listener );
@@ -74,8 +96,9 @@ export class LocationElement extends HTMLElement
74
96
  }
75
97
  attributeChangedCallback(name, oldValue, newValue)
76
98
  {
77
- if('href'!== name)
78
- return;
99
+ if('href'!== name && 'method' !== name && 'src' )
100
+ if( !['method','src','href'].includes(name) )
101
+ return;
79
102
  this.sliceInit && this.sliceInit();
80
103
  }
81
104
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epa-wg/custom-element",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
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",