@epa-wg/custom-element-dist 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.
Files changed (86) hide show
  1. package/.storybook/main.ts +21 -21
  2. package/README.md +4 -4
  3. package/coverage/coverage-final.json +6 -4
  4. package/coverage/index.html +27 -27
  5. package/coverage/src/custom-element/coverage.svg +1 -1
  6. package/coverage/src/custom-element/custom-element.js/coverage.svg +1 -1
  7. package/coverage/src/custom-element/custom-element.js.html +391 -355
  8. package/coverage/src/custom-element/http-request.js.html +12 -12
  9. package/coverage/src/custom-element/index.html +23 -23
  10. package/coverage/src/custom-element/local-storage.js.html +1 -1
  11. package/coverage/src/custom-element/location-element.js/coverage.svg +1 -1
  12. package/coverage/src/custom-element/location-element.js.html +116 -47
  13. package/coverage/src/index.html +1 -1
  14. package/coverage/src/mocks/handlers.ts.html +1 -1
  15. package/coverage/src/mocks/index.html +1 -1
  16. package/coverage/src/stories/attributes.test.stories.ts.html +1 -1
  17. package/coverage/src/stories/coverage.svg +1 -1
  18. package/coverage/src/stories/css.test.stories.ts.html +1 -1
  19. package/coverage/src/stories/dom-merge.test.stories.ts.html +1 -1
  20. package/coverage/src/stories/external-template.test.stories.ts.html +1 -1
  21. package/coverage/src/stories/form.test.stories.ts.html +1 -1
  22. package/coverage/src/stories/http-request.stories.ts.html +1 -1
  23. package/coverage/src/stories/index.html +38 -8
  24. package/coverage/src/stories/local-storage.test.stories.ts.html +1 -1
  25. package/coverage/src/stories/location-element.test.stories.ts.html +1 -1
  26. package/coverage/src/stories/set-url.test.stories.ts/coverage.svg +10 -0
  27. package/coverage/src/stories/set-url.test.stories.ts.html +427 -0
  28. package/coverage/src/stories/slice-events.test.stories.ts.html +1 -1
  29. package/coverage/src/stories/slots.test.stories.ts.html +1 -1
  30. package/coverage/src/stories/testStoryBook.ts.html +12 -12
  31. package/coverage/src/stories/version-select.test.stories.ts/coverage.svg +10 -0
  32. package/coverage/src/stories/version-select.test.stories.ts.html +313 -0
  33. package/coverage/src/sum.ts.html +1 -1
  34. package/dist/{custom-element-DqtzLkTG.js → custom-element-DAe7uvIt.js} +163 -157
  35. package/dist/custom-element-DZvvhscI.cjs +53 -0
  36. package/dist/custom-element-bundle.cjs +1 -1
  37. package/dist/custom-element-bundle.js +3 -3
  38. package/dist/location-element-DRB7hCwA.cjs +1 -0
  39. package/dist/location-element-FJlONi2n.js +65 -0
  40. package/package.json +2 -2
  41. package/src/custom-element/custom-element.js +16 -4
  42. package/src/custom-element/demo/location-element.html +17 -4
  43. package/src/custom-element/demo/s.xml +31 -6
  44. package/src/custom-element/demo/s.xslt +59 -22
  45. package/src/custom-element/demo/set-url.html +141 -0
  46. package/src/custom-element/ide/customData-dce.json +56 -0
  47. package/src/custom-element/ide/web-types-dce.json +153 -110
  48. package/src/custom-element/ide/web-types-xsl.json +1 -1
  49. package/src/custom-element/index.html +1 -0
  50. package/src/custom-element/location-element.js +25 -2
  51. package/src/custom-element.test.ts +26 -26
  52. package/src/stories/set-url.test.stories.ts +114 -0
  53. package/src/stories/version-select.test.stories.ts +76 -0
  54. package/storybook-static/assets/{Color-PRSJMWNM-y4ZsI1hY.js → Color-PRSJMWNM-CRSv4C7i.js} +1 -1
  55. package/storybook-static/assets/{Configure-CyLVkwlf.js → Configure-D0qG3gR9.js} +1 -1
  56. package/storybook-static/assets/{DocsRenderer-K4EAMTCU-VRGUwRrq.js → DocsRenderer-K4EAMTCU-CG_P5zRZ.js} +2 -2
  57. package/storybook-static/assets/{WithTooltip-KJL26V4Q-xdXH9Ztt.js → WithTooltip-KJL26V4Q-CUqUi5E8.js} +1 -1
  58. package/storybook-static/assets/{attributes.test.stories-BckCcyrF.js → attributes.test.stories-W34tZdUt.js} +1 -1
  59. package/storybook-static/assets/{css.test.stories-B-QcObCF.js → css.test.stories-BZFYx1TQ.js} +1 -1
  60. package/storybook-static/assets/{custom-element-BIxkVg7K.js → custom-element-DpIq8E2p.js} +79 -79
  61. package/storybook-static/assets/{dom-merge.test.stories-CjXhjTQY.js → dom-merge.test.stories-S-7U5N3h.js} +1 -1
  62. package/storybook-static/assets/{external-template.test.stories-BBqyi0az.js → external-template.test.stories-QIO3lAFz.js} +1 -1
  63. package/storybook-static/assets/{form.test.stories-DsIo1B4n.js → form.test.stories-ClYhj9F1.js} +1 -1
  64. package/storybook-static/assets/{formatter-2WMMO6ZP-CThVcQxM.js → formatter-2WMMO6ZP-C-UiBIma.js} +1 -1
  65. package/storybook-static/assets/http-request-DNq59pnj.js +1 -0
  66. package/storybook-static/assets/{http-request.stories-sXA_Y-VM.js → http-request.stories-DCqY5s2i.js} +9 -9
  67. package/storybook-static/assets/iframe-CURpvmVV.js +2 -0
  68. package/storybook-static/assets/{index-VWixWKZ7.js → index-CKw1EbdP.js} +1 -1
  69. package/storybook-static/assets/{index-CUFHd5VD.js → index-DYpTqTNu.js} +1 -1
  70. package/storybook-static/assets/{index-DPPi9iZu.js → index-DsWii_Ep.js} +5 -5
  71. package/storybook-static/assets/{local-storage.test.stories-Cs2v3QTS.js → local-storage.test.stories-BqgYwqr-.js} +1 -1
  72. package/storybook-static/assets/location-element-hKpcXCdn.js +1 -0
  73. package/storybook-static/assets/{location-element.test.stories-WkrQDzJJ.js → location-element.test.stories-DvH1TWK4.js} +9 -9
  74. package/storybook-static/assets/{preview-p-Bwze-K.js → preview-DjDbQHPa.js} +2 -2
  75. package/storybook-static/assets/set-url.test.stories-GlJOh31I.js +81 -0
  76. package/storybook-static/assets/{slice-events.test.stories-BRBBc0JT.js → slice-events.test.stories-VoNjuPCX.js} +1 -1
  77. package/storybook-static/assets/{slots.test.stories-r-i91k3y.js → slots.test.stories-Da2j9YuO.js} +1 -1
  78. package/storybook-static/assets/{syntaxhighlighter-BP7B2CQK-OnioRcs9.js → syntaxhighlighter-BP7B2CQK-CDpEe51g.js} +1 -1
  79. package/storybook-static/assets/version-select.test.stories-DLwf-TPB.js +60 -0
  80. package/storybook-static/iframe.html +1 -1
  81. package/storybook-static/index.json +1 -1
  82. package/storybook-static/project.json +1 -1
  83. package/dist/custom-element-BDK7dcJN.cjs +0 -53
  84. package/dist/location-element-2m0gWq_d.cjs +0 -1
  85. package/dist/location-element-nA_wsqBt.js +0 -49
  86. package/storybook-static/assets/iframe-DcDTQOmA.js +0 -2
@@ -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": {
@@ -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
 
@@ -1,26 +1,26 @@
1
- import {expect, test} from 'vitest'
2
- import {deepEqual, xml2dom, xmlString, obj2node } from './custom-element/custom-element.js'
3
-
4
- test('deepEqual', () =>
5
- {
6
- expect(deepEqual(1, 1)).toBe(true);
7
- expect(deepEqual({}, null)).toBe(false);
8
- expect(deepEqual({a: 1}, {a: 1, b: 2})).toBe(false);
9
- expect(deepEqual({a: 1}, {a: 2})).toBe(false);
10
- expect(deepEqual({a: 1}, {a: 1})).toBe(true);
11
- })
12
- test('xml2dom', () =>
13
- {
14
- const dom = xml2dom('<a/>');
15
- expect(dom.documentElement.localName).to.equal('a');
16
- expect(dom.documentElement.childNodes.length).to.equal(0);
17
- const xStr = xmlString(dom);
18
- expect(xStr).to.include('<a');
19
- })
20
- test('obj2node', () =>
21
- {
22
- expect(obj2node(()=>{} , 'f',document).outerHTML).to.equal('<f></f>' );
23
- expect(obj2node(9 , 'a',document).outerHTML).to.equal('<a>9</a>' );
24
- expect(obj2node('abc' , 's',document).outerHTML).to.equal('<s>abc</s>' );
25
- expect(obj2node({a:1,b:{c:'abc'}} , 's',document).outerHTML).to.equal('<s a="1"><b c="abc"></b></s>');
26
- })
1
+ import {expect, test} from 'vitest'
2
+ import {deepEqual, xml2dom, xmlString, obj2node } from './custom-element/custom-element.js'
3
+
4
+ test('deepEqual', () =>
5
+ {
6
+ expect(deepEqual(1, 1)).toBe(true);
7
+ expect(deepEqual({}, null)).toBe(false);
8
+ expect(deepEqual({a: 1}, {a: 1, b: 2})).toBe(false);
9
+ expect(deepEqual({a: 1}, {a: 2})).toBe(false);
10
+ expect(deepEqual({a: 1}, {a: 1})).toBe(true);
11
+ })
12
+ test('xml2dom', () =>
13
+ {
14
+ const dom = xml2dom('<a/>');
15
+ expect(dom.documentElement.localName).to.equal('a');
16
+ expect(dom.documentElement.childNodes.length).to.equal(0);
17
+ const xStr = xmlString(dom);
18
+ expect(xStr).to.include('<a');
19
+ })
20
+ test('obj2node', () =>
21
+ {
22
+ expect(obj2node(()=>{} , 'f',document).outerHTML).to.equal('<f></f>' );
23
+ expect(obj2node(9 , 'a',document).outerHTML).to.equal('<a>9</a>' );
24
+ expect(obj2node('abc' , 's',document).outerHTML).to.equal('<s>abc</s>' );
25
+ expect(obj2node({a:1,b:{c:'abc'}} , 's',document).outerHTML).to.equal('<s a="1"><b c="abc"></b></s>');
26
+ })
@@ -0,0 +1,114 @@
1
+ // noinspection DuplicatedCode
2
+
3
+ import type {StoryObj} from '@storybook/web-components';
4
+ import {expect, getByTestId, userEvent, within} from '@storybook/test';
5
+
6
+ import '../custom-element/custom-element.js';
7
+ import '../custom-element/location-element.js';
8
+
9
+ type TProps = { title: string; slice: string; href: string; live: string; body: string };
10
+ const defs: TProps =
11
+ {
12
+ title: ''
13
+ , slice: 'url-slice'
14
+ , href: ''
15
+ , live: ''
16
+ , body: ``
17
+ };
18
+ type Story = StoryObj<TProps>;
19
+
20
+ function sleep(ms: number) {
21
+ return new Promise((resolve) => setTimeout(resolve, ms));
22
+ }
23
+
24
+ function render(args: TProps) {
25
+ const {title, body} = {...defs, ...args};
26
+ return `
27
+ <fieldset>
28
+ <legend>${title}</legend>
29
+
30
+ <custom-element>
31
+ <template><!-- wrapping into template to prevent images loading within DCE declaration -->
32
+
33
+ ${body}
34
+
35
+ </template>
36
+ </custom-element>
37
+ </fieldset>
38
+ `;
39
+ }
40
+
41
+ const meta =
42
+ {
43
+ title: 'location-element set URL'
44
+ , render
45
+ };
46
+
47
+ export default meta;
48
+
49
+ export const DynamicSrc: Story =
50
+ {
51
+ args: {
52
+ title: '1. Set the page URL by location.hash', body: `
53
+ <button value="#dce1" slice="set-button" slice-event="click">#dce1</button>
54
+ <button value="#dce2" slice="set-button" slice-event="click">#dce2</button>
55
+ <location-element method="location.href" src="{//set-button/@value}"></location-element>`
56
+ }
57
+ , play: async ({canvasElement}) => {
58
+ const canvas = within(canvasElement);
59
+ await canvas.findByText(DynamicSrc.args!.title as string);
60
+ await userEvent.click(canvas.getByText('#dce1'));
61
+ await sleep(1);
62
+ await expect(window.location.hash).toEqual('#dce1')
63
+ await userEvent.click(canvas.getByText('#dce2'));
64
+ await sleep(1);
65
+ await expect(window.location.hash).toEqual('#dce2')
66
+ },
67
+ };
68
+ export const DynamicMethod: Story =
69
+ {
70
+ args: {
71
+ title: '2. Set the page URL by method', body: `
72
+ <style>
73
+ button{ display: block; width: 100%; }
74
+ </style>
75
+ <button value="location.href" slice="set-button" slice-event="click"> location.href </button>
76
+ <button value="location.hash" slice="set-button" slice-event="click"> location.hash </button>
77
+ <button value="location.assign" slice="set-button" slice-event="click"> location.assign </button>
78
+ <button value="location.replace" slice="set-button" slice-event="click"> location.replace </button>
79
+ <button value="history.pushState" slice="set-button" slice-event="click"> history.pushState </button>
80
+ <button value="history.replaceState" slice="set-button" slice-event="click"> history.replaceState </button>
81
+ <location-element method="{//set-button/@value}" ></location-element>`
82
+ }
83
+ , play: async ({canvasElement}) => {
84
+ const canvas = within(canvasElement);
85
+ const le = canvasElement.querySelector('location-element');
86
+ await canvas.findByText(DynamicMethod.args!.title as string);
87
+
88
+ async function testHash(hash, text) {
89
+ le.setAttribute('method', ''); // to prevent immediate URL change
90
+ le.setAttribute('src', hash);
91
+ await userEvent.click(canvas.getByText(text));
92
+ await sleep(1);
93
+ await expect(window.location.hash).toEqual(hash)
94
+ }
95
+
96
+ await testHash('#byHash', 'location.hash');
97
+ await testHash('#byhref', 'location.href');
98
+ await testHash('#byassign', 'location.assign');
99
+ await testHash('#byreplace', 'location.replace');
100
+ await testHash('#by.history.pushState', 'history.pushState');
101
+ await testHash('#by.history.replaceState', 'history.replaceState');
102
+
103
+ },
104
+ };
105
+
106
+
107
+ /* istanbul ignore else -- @preserve */
108
+ if ('test' === import.meta.env.MODE &&
109
+ !import.meta.url.includes('skiptest')) {
110
+ const mod = await import('./set-url.test.stories.ts?skiptest');
111
+ const {testStoryBook} = await import('./testStoryBook')
112
+ const {describe} = await import('vitest')
113
+ describe(meta.title, () => testStoryBook(mod, meta));
114
+ }
@@ -0,0 +1,76 @@
1
+ // noinspection DuplicatedCode
2
+
3
+ import type { StoryObj } from '@storybook/web-components';
4
+ import {expect, within} from '@storybook/test';
5
+
6
+ import '../custom-element/custom-element.js';
7
+ import '../custom-element/http-request.js';
8
+
9
+ type TProps = { title: string; body:string};
10
+
11
+ type Story = StoryObj<TProps>;
12
+
13
+ function sleep(ms: number) { return new Promise((resolve) => setTimeout(resolve, ms)); }
14
+
15
+ function render(args: TProps)
16
+ {
17
+ const {title, body} = args;
18
+ return `
19
+ <fieldset>
20
+ <legend>${ title }</legend>
21
+ ${ body }
22
+ </fieldset>
23
+ `;
24
+ }
25
+ const meta =
26
+ { title: 'site/VersionSelect'
27
+ // , tags: ['autodocs']
28
+ , render
29
+ };
30
+
31
+ export default meta;
32
+
33
+ export const VersionsSelect:Story =
34
+ { args : {title: 'Versions of custom-element', body:`
35
+ <p>Select the version of custom-element StoryBook.</p>
36
+ <custom-element >
37
+ <template>
38
+ <http-request
39
+ url="https://registry.npmjs.org/@epa-wg/custom-element-dist"
40
+ method="GET"
41
+ header-accept="application/json"
42
+ slice="page" ></http-request>
43
+ <xhtml:select>
44
+ <for-each select="//versions/*">
45
+ <option>
46
+ {./@version}
47
+ </option>
48
+ </for-each>
49
+ </xhtml:select>
50
+ </template>
51
+ </custom-element>
52
+ <dce-link id="dce1"></dce-link>
53
+ `}
54
+ , play: async ({canvasElement}) =>
55
+ {
56
+ const titleText = VersionsSelect.args!.title as string;
57
+ const canvas = within(canvasElement)
58
+ , code = async (id) => (await canvas.findByTestId(id)).textContent.trim();
59
+
60
+ await sleep(20)
61
+ expect( await code('p1') ).toEqual('default_P1' );
62
+ expect( await code('p2') ).toEqual('always_p2' );
63
+ expect( await code('p3') ).toEqual('def_P3' );
64
+ },
65
+ };
66
+
67
+
68
+ /* istanbul ignore else -- @preserve */
69
+ if( 'test' === import.meta.env.MODE &&
70
+ !import.meta.url.includes('skiptest') )
71
+ {
72
+ const mod = await import('./attributes.test.stories.ts?skiptest');
73
+ const { testStoryBook } = await import('./testStoryBook')
74
+ const { describe } = await import('vitest')
75
+ describe(meta.title, () => testStoryBook( mod, meta ) );
76
+ }