@epa-wg/custom-element-dist 0.0.32 → 0.0.33

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 (219) hide show
  1. package/.storybook/main.ts +3 -7
  2. package/.storybook/preview.ts +4 -6
  3. package/README.md +4 -4
  4. package/coverage/coverage-final.json +7 -18
  5. package/coverage/index.html +30 -30
  6. package/coverage/src/custom-element/coverage.svg +1 -1
  7. package/coverage/src/custom-element/custom-element.js/coverage.svg +1 -1
  8. package/coverage/src/custom-element/custom-element.js.html +579 -429
  9. package/coverage/src/custom-element/http-request.js/coverage.svg +1 -1
  10. package/coverage/src/custom-element/http-request.js.html +13 -13
  11. package/coverage/src/custom-element/index.html +29 -29
  12. package/coverage/src/custom-element/local-storage.js.html +1 -1
  13. package/coverage/src/custom-element/location-element.js.html +31 -31
  14. package/coverage/src/custom-element/module-url.js/coverage.svg +1 -1
  15. package/coverage/src/custom-element/module-url.js.html +20 -20
  16. package/coverage/src/index.html +1 -1
  17. package/coverage/src/mocks/handlers.ts.html +1 -1
  18. package/coverage/src/mocks/index.html +1 -1
  19. package/coverage/src/stories/coverage.svg +1 -1
  20. package/coverage/src/stories/{local-storage.test.stories.ts → frame.canvas.ts}/coverage.svg +1 -1
  21. package/coverage/src/stories/frame.canvas.ts.html +175 -0
  22. package/coverage/src/stories/http-request.stories.ts.html +1 -1
  23. package/coverage/src/stories/index.html +14 -179
  24. package/coverage/src/stories/testStoryBook.ts.html +8 -8
  25. package/coverage/src/sum.ts.html +1 -1
  26. package/dist/custom-element-6slVaFEs.cjs +97 -0
  27. package/dist/custom-element-WnOqmEOe.js +609 -0
  28. package/dist/custom-element-bundle.cjs +1 -1
  29. package/dist/custom-element-bundle.js +2 -2
  30. package/dist/demo/attributes.html +153 -0
  31. package/dist/demo/external-templates-sb-6.html +42 -0
  32. package/dist/demo/external-templates-sb-7.html +42 -0
  33. package/dist/demo/html-template.html +1 -1
  34. package/dist/demo/module-url-sb-2.html +46 -0
  35. package/dist/demo/module-url-sb-4.html +48 -0
  36. package/dist/demo/module-url-sb-5.html +53 -0
  37. package/dist/demo/s.xml +71 -8
  38. package/dist/demo/s.xslt +55 -31
  39. package/dist/demo/ss.html +13 -4
  40. package/dist/mockServiceWorker.js +31 -8
  41. package/package.json +25 -26
  42. package/public/demo/attributes.html +153 -0
  43. package/public/demo/external-templates-sb-6.html +42 -0
  44. package/public/demo/external-templates-sb-7.html +42 -0
  45. package/public/demo/html-template.html +1 -1
  46. package/public/demo/module-url-sb-2.html +46 -0
  47. package/public/demo/module-url-sb-4.html +48 -0
  48. package/public/demo/module-url-sb-5.html +53 -0
  49. package/public/demo/s.xml +71 -8
  50. package/public/demo/s.xslt +55 -31
  51. package/public/demo/ss.html +13 -4
  52. package/public/mockServiceWorker.js +31 -8
  53. package/src/custom-element/custom-element.d.ts +4 -0
  54. package/src/custom-element/custom-element.js +91 -41
  55. package/src/custom-element/demo/attributes.html +153 -0
  56. package/src/custom-element/demo/html-template.html +1 -1
  57. package/src/custom-element/demo/s.xml +71 -8
  58. package/src/custom-element/demo/s.xslt +55 -31
  59. package/src/custom-element/demo/ss.html +13 -4
  60. package/src/custom-element/ide/web-types-dce.json +1 -1
  61. package/src/custom-element/ide/web-types-xsl.json +1 -1
  62. package/src/custom-element/index.html +1 -1
  63. package/src/material/components/badge.html +240 -0
  64. package/src/material/components/dropdown.html +7 -12
  65. package/src/material/components/icon-link.html +1 -0
  66. package/src/material/components/icon.html +253 -0
  67. package/src/material/components/input.html +290 -82
  68. package/src/material/components/menu.html +7 -5
  69. package/src/material/components.html +48 -11
  70. package/src/material/theme/semantic.css +20 -1
  71. package/src/mocks/versions.mock.ts +1 -1
  72. package/src/stories/__screenshots__/attributes.test.stories.ts +1 -0
  73. package/src/stories/__screenshots__/external-template.test.stories.ts +1 -0
  74. package/src/stories/__screenshots__/module-url.test.stories.ts +1 -0
  75. package/src/stories/__screenshots__/stories.test.ts/attributes-Attributes-definition-1.png +0 -0
  76. package/src/stories/__screenshots__/stories.test.ts/attributes-Attributes-runtime-change-1.png +0 -0
  77. package/src/stories/__screenshots__/stories.test.ts/attributes-Instance-Attributes-1.png +0 -0
  78. package/src/stories/__screenshots__/stories.test.ts/attributes-Instance-Attributes-2.png +0 -0
  79. package/src/stories/__screenshots__/stories.test.ts/attributes-cloneAs-el-newTag--1.png +0 -0
  80. package/src/stories/__screenshots__/stories.test.ts/attributes-mergeAttr--from--to---1.png +0 -0
  81. package/src/stories/__screenshots__/stories.test.ts/attributes-mergeAttr--from--to---2.png +0 -0
  82. package/src/stories/__screenshots__/stories.test.ts/attributes-mergeAttr--from--to---3.png +0 -0
  83. package/src/stories/__screenshots__/stories.test.ts/attributes-mix-to-from--1.png +0 -0
  84. package/src/stories/__screenshots__/stories.test.ts/http-request-Attributes-definition-1.png +0 -0
  85. package/src/stories/__screenshots__/stories.test.ts/http-request-Attributes-runtime-change-1.png +0 -0
  86. package/src/stories/__screenshots__/stories.test.ts/http-request-Instance-Attributes-1.png +0 -0
  87. package/src/stories/__screenshots__/stories.test.ts/http-request-Instance-Attributes-2.png +0 -0
  88. package/src/stories/__screenshots__/stories.test.ts/http-request-cloneAs-el-newTag--1.png +0 -0
  89. package/src/stories/__screenshots__/stories.test.ts/http-request-http-request-headers-and-response-status-and-headers-1.png +0 -0
  90. package/src/stories/__screenshots__/stories.test.ts/http-request-http-request-with-delayed--5-seconds-response-1.png +0 -0
  91. package/src/stories/__screenshots__/stories.test.ts/http-request-http-request-with-error-1.png +0 -0
  92. package/src/stories/__screenshots__/stories.test.ts/http-request-mergeAttr--from--to---1.png +0 -0
  93. package/src/stories/__screenshots__/stories.test.ts/http-request-mergeAttr--from--to---2.png +0 -0
  94. package/src/stories/__screenshots__/stories.test.ts/http-request-mergeAttr--from--to---3.png +0 -0
  95. package/src/stories/__screenshots__/stories.test.ts/http-request-mix-to-from--1.png +0 -0
  96. package/src/stories/__screenshots__/stories.test.ts/http-request-url-and-slice-1.png +0 -0
  97. package/src/stories/__screenshots__/stories.test.ts/http-request-url-change-1.png +0 -0
  98. package/src/stories/attributes.test.stories.ts +83 -17
  99. package/src/stories/external-template.test.stories.ts +16 -14
  100. package/src/stories/frame.canvas.ts +31 -0
  101. package/src/stories/module-url.test.stories.ts +29 -61
  102. package/storybook-static/assets/Color-F6OSRLHC-Cbp293x2.js +1 -0
  103. package/storybook-static/assets/Configure-BrFr4SLE.js +165 -0
  104. package/storybook-static/assets/DocsRenderer-CFRXHY34-DhHzJiIO.js +2 -0
  105. package/storybook-static/assets/attributes.test.stories-CzWkKw0e.js +1 -0
  106. package/storybook-static/assets/{attributes.test.stories-D1X6EBrd.js → attributes.test.stories-Gg9LQTEK.js} +109 -38
  107. package/storybook-static/assets/{css.test.stories-Cp_g2hE1.js → css.test.stories-B_3ltOrx.js} +1 -1
  108. package/storybook-static/assets/custom-element-CPnvJnn8.js +97 -0
  109. package/storybook-static/assets/{dom-merge.test.stories-hbpdCka0.js → dom-merge.test.stories-nQxcgLoM.js} +1 -1
  110. package/storybook-static/assets/entry-preview-docs-Dwczwtsc.js +2 -0
  111. package/storybook-static/assets/external-template.test.stories-BivZqBTp.js +1 -0
  112. package/storybook-static/assets/{external-template.test.stories-BK89h6sk.js → external-template.test.stories-DZ-rjnfd.js} +38 -40
  113. package/storybook-static/assets/{form.test.stories-BfoLe_rw.js → form.test.stories-DQhPYtMj.js} +1 -1
  114. package/storybook-static/assets/frame.canvas-ClTqYyMN.js +1 -0
  115. package/storybook-static/assets/{handlers-yVPwH_Nz.js → handlers-CLkps6Nz.js} +17 -14
  116. package/storybook-static/assets/{http-request.stories-CBFJS2Ws.js → http-request.stories-jo0f73nw.js} +1 -1
  117. package/storybook-static/assets/iframe-CZwRpnn9.js +199 -0
  118. package/storybook-static/assets/index-B68YUdzy.js +621 -0
  119. package/storybook-static/assets/index-BwkS7JH_.js +8 -0
  120. package/storybook-static/assets/index-CJQtnF9V.js +1 -0
  121. package/storybook-static/assets/index-Dr4PwNfd.js +240 -0
  122. package/storybook-static/assets/{local-storage.test.stories-C0Yzy6Am.js → local-storage.test.stories-uA5EKRPf.js} +1 -1
  123. package/storybook-static/assets/{location-element.test.stories-DNFrEu5A.js → location-element.test.stories-Cu-6Elcg.js} +1 -1
  124. package/storybook-static/assets/module-url.test.stories-CD_wusXQ.js +142 -0
  125. package/storybook-static/assets/module-url.test.stories-CTjUAk3J.js +1 -0
  126. package/storybook-static/assets/preview-1xJJ3sKE.js +1 -0
  127. package/storybook-static/assets/preview-BFlNN3Wj.js +1 -0
  128. package/storybook-static/assets/preview-CTOeX_lO.js +1 -0
  129. package/storybook-static/assets/preview-Cm4PPhHS.js +50 -0
  130. package/storybook-static/assets/preview-CuCH40jj.js +2 -0
  131. package/storybook-static/assets/preview-DfTudP20.js +1 -0
  132. package/storybook-static/assets/{set-url.test.stories-BBfLxv2u.js → set-url.test.stories-CY7B9BVZ.js} +1 -1
  133. package/storybook-static/assets/{slice-events.test.stories-HcXF8XQI.js → slice-events.test.stories-BVnPXm6e.js} +1 -1
  134. package/storybook-static/assets/{slots.test.stories-i6mnIFM2.js → slots.test.stories-Dxsa9KdA.js} +1 -1
  135. package/storybook-static/assets/{version-select.test.stories-BsUFH6Va.js → version-select.test.stories-Buga1PAa.js} +1 -1
  136. package/storybook-static/demo/attributes.html +153 -0
  137. package/storybook-static/demo/external-templates-sb-6.html +42 -0
  138. package/storybook-static/demo/external-templates-sb-7.html +42 -0
  139. package/storybook-static/demo/html-template.html +1 -1
  140. package/storybook-static/demo/module-url-sb-2.html +46 -0
  141. package/storybook-static/demo/module-url-sb-4.html +48 -0
  142. package/storybook-static/demo/module-url-sb-5.html +53 -0
  143. package/storybook-static/demo/s.xml +71 -8
  144. package/storybook-static/demo/s.xslt +55 -31
  145. package/storybook-static/demo/ss.html +13 -4
  146. package/storybook-static/iframe.html +1 -1
  147. package/storybook-static/index.html +6 -10
  148. package/storybook-static/index.json +1 -1
  149. package/storybook-static/mockServiceWorker.js +31 -8
  150. package/storybook-static/project.json +1 -1
  151. package/storybook-static/sb-addons/essentials-actions-2/manager-bundle.js +3 -0
  152. package/storybook-static/sb-addons/essentials-backgrounds-4/manager-bundle.js +8 -8
  153. package/storybook-static/sb-addons/essentials-controls-1/manager-bundle.js +391 -0
  154. package/storybook-static/sb-addons/essentials-docs-3/manager-bundle.js +230 -0
  155. package/storybook-static/sb-addons/essentials-measure-7/manager-bundle.js +1 -1
  156. package/storybook-static/sb-addons/essentials-outline-8/manager-bundle.js +1 -1
  157. package/storybook-static/sb-addons/essentials-toolbars-6/manager-bundle.js +1 -1
  158. package/storybook-static/sb-addons/essentials-viewport-5/manager-bundle.js +1 -1
  159. package/storybook-static/sb-addons/interactions-9/manager-bundle.js +58 -58
  160. package/storybook-static/sb-manager/globals-module-info.js +9 -0
  161. package/storybook-static/sb-manager/globals-runtime.js +10719 -10473
  162. package/storybook-static/sb-manager/runtime.js +4944 -6321
  163. package/coverage/src/stories/attributes.test.stories.ts/coverage.svg +0 -10
  164. package/coverage/src/stories/attributes.test.stories.ts.html +0 -814
  165. package/coverage/src/stories/css.test.stories.ts/coverage.svg +0 -10
  166. package/coverage/src/stories/css.test.stories.ts.html +0 -460
  167. package/coverage/src/stories/dom-merge.test.stories.ts/coverage.svg +0 -10
  168. package/coverage/src/stories/dom-merge.test.stories.ts.html +0 -706
  169. package/coverage/src/stories/external-template.test.stories.ts/coverage.svg +0 -10
  170. package/coverage/src/stories/external-template.test.stories.ts.html +0 -865
  171. package/coverage/src/stories/form.test.stories.ts/coverage.svg +0 -10
  172. package/coverage/src/stories/form.test.stories.ts.html +0 -661
  173. package/coverage/src/stories/local-storage.test.stories.ts.html +0 -1315
  174. package/coverage/src/stories/location-element.test.stories.ts/coverage.svg +0 -10
  175. package/coverage/src/stories/location-element.test.stories.ts.html +0 -523
  176. package/coverage/src/stories/module-url.test.stories.ts/coverage.svg +0 -10
  177. package/coverage/src/stories/module-url.test.stories.ts.html +0 -640
  178. package/coverage/src/stories/set-url.test.stories.ts/coverage.svg +0 -10
  179. package/coverage/src/stories/set-url.test.stories.ts.html +0 -433
  180. package/coverage/src/stories/slice-events.test.stories.ts/coverage.svg +0 -10
  181. package/coverage/src/stories/slice-events.test.stories.ts.html +0 -952
  182. package/coverage/src/stories/slots.test.stories.ts/coverage.svg +0 -10
  183. package/coverage/src/stories/slots.test.stories.ts.html +0 -742
  184. package/coverage/src/stories/version-select.test.stories.ts/coverage.svg +0 -10
  185. package/coverage/src/stories/version-select.test.stories.ts.html +0 -397
  186. package/dist/custom-element-D2wf_rqP.js +0 -576
  187. package/dist/custom-element-Dtzhbjkc.cjs +0 -97
  188. package/storybook-static/assets/Color-F6OSRLHC-BU3iy8jH.js +0 -1
  189. package/storybook-static/assets/Configure-DN6ifayP.js +0 -165
  190. package/storybook-static/assets/DocsRenderer-CFRXHY34-BaVEufDj.js +0 -2
  191. package/storybook-static/assets/custom-element-uuAtIYWS.js +0 -97
  192. package/storybook-static/assets/entry-preview-docs-BbcIMweR.js +0 -2
  193. package/storybook-static/assets/iframe-CJEL_4Nu.js +0 -2
  194. package/storybook-static/assets/index-BcZLpTeD.js +0 -8
  195. package/storybook-static/assets/index-CxRwF5Or.js +0 -234
  196. package/storybook-static/assets/index-D-8MO0q_.js +0 -1
  197. package/storybook-static/assets/index-D5fBh-7N.js +0 -1
  198. package/storybook-static/assets/index-DM-KBPdl.js +0 -1
  199. package/storybook-static/assets/index-RSFf30w1.js +0 -1
  200. package/storybook-static/assets/index-SnjB5uV8.js +0 -769
  201. package/storybook-static/assets/module-url.test.stories-CXibF5Ta.js +0 -208
  202. package/storybook-static/assets/preview-BhhEZcNS.js +0 -1
  203. package/storybook-static/assets/preview-Bnd0XhaF.js +0 -52
  204. package/storybook-static/assets/preview-CNKoaWES.js +0 -1
  205. package/storybook-static/assets/preview-DAeyCMnM.js +0 -1
  206. package/storybook-static/assets/preview-DHPc-V4N.js +0 -1
  207. package/storybook-static/assets/preview-DJMlNTk8.js +0 -2
  208. package/storybook-static/assets/preview-DYzi3Z2p.js +0 -1
  209. package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js +0 -333
  210. package/storybook-static/sb-addons/chromatic-com-storybook-10/manager-bundle.js.LEGAL.txt +0 -40
  211. package/storybook-static/sb-addons/essentials-actions-3/manager-bundle.js +0 -3
  212. package/storybook-static/sb-addons/essentials-controls-2/manager-bundle.js +0 -391
  213. package/storybook-static/sb-addons/links-1/manager-bundle.js +0 -3
  214. package/storybook-static/sb-preview/globals.js +0 -33
  215. package/storybook-static/sb-preview/runtime.js +0 -7174
  216. package/test-runner-jest.config.js +0 -15
  217. /package/storybook-static/sb-addons/{essentials-actions-3 → essentials-actions-2}/manager-bundle.js.LEGAL.txt +0 -0
  218. /package/storybook-static/sb-addons/{essentials-controls-2 → essentials-controls-1}/manager-bundle.js.LEGAL.txt +0 -0
  219. /package/storybook-static/sb-addons/{links-1 → essentials-docs-3}/manager-bundle.js.LEGAL.txt +0 -0
@@ -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">
@@ -14,54 +13,79 @@
14
13
  <xsl:value-of select="."/>
15
14
  </xsl:template>
16
15
  <xsl:template mode="payload" match="attributes">
17
- <xsl:param name="p1" select="/datadom/attributes/p1">default_P1</xsl:param>
18
- <xsl:param name="p2" select="'always_p2'"/>
19
- <xsl:param name="p3">
16
+ <xsl:param name="v">
20
17
  <xsl:choose>
21
- <xsl:when test="string-length(//p3)>0 ">RRRR
22
- <xsl:value-of select="count(//p3)"/>
23
- +<xsl:value-of select="//p3 "/>=
18
+ <xsl:when test="//s[//s/event] ">
19
+ <xsl:value-of select="//s[//s/event] "/>
24
20
  </xsl:when>
25
- <xsl:otherwise>OOO
26
- <xsl:value-of select=" 'def_P3' "/>
21
+ <xsl:when test=" //attributes/@v ">
22
+ <xsl:value-of select=" //attributes/@v "/>
23
+ </xsl:when>
24
+ <xsl:otherwise>
25
+ <xsl:value-of select=" 'def' "/>
27
26
  </xsl:otherwise>
28
27
  </xsl:choose>
29
28
  </xsl:param>
30
29
  <dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1">
31
- <xsl:attribute name="p1">default_P1</xsl:attribute>
32
- <xsl:attribute name="p2">
33
- <xsl:value-of select="'always_p2'"/>
34
- </xsl:attribute>
35
- <xsl:attribute name="p3">
30
+ <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="has-input"
31
+ select="count(//s/*) &gt; 0"/>
32
+ <xsl:attribute name="v">
36
33
  <xsl:choose>
37
- <xsl:when test="//p3 ">
38
- <xsl:value-of select="//p3 "/>
34
+ <xsl:when test="//s[//s/event] ">
35
+ <xsl:value-of select="//s[//s/event] "/>
36
+ </xsl:when>
37
+ <xsl:when test=" //attributes/@v ">
38
+ <xsl:value-of select=" //attributes/@v "/>
39
39
  </xsl:when>
40
40
  <xsl:otherwise>
41
- <xsl:value-of select=" 'def_P3' "/>
41
+ <xsl:value-of select=" 'def' "/>
42
42
  </xsl:otherwise>
43
43
  </xsl:choose>
44
44
  </xsl:attribute>
45
45
  <dce-text xmlns="" data-dce-id="2">
46
- p1:
46
+
47
+ //attributes/v='<xsl:value-of select="//attributes/v"/>'
47
48
  </dce-text>
48
- <code xmlns="" data-testid="p1" data-dce-id="3">
49
- <xsl:value-of select="$p1"/>
50
- </code>
51
- <br xmlns="" data-dce-id="4"/>
52
- <dce-text xmlns="" data-dce-id="5">
53
- p2:
49
+ <br xmlns="" data-dce-id="3"/>
50
+ <dce-text xmlns="" data-dce-id="4">
51
+ //attributes/@v='<xsl:value-of select="//attributes/@v"/>'
52
+ </dce-text>
53
+ <br xmlns="" data-dce-id="5"/>
54
+ <dce-text xmlns="" data-dce-id="6">
55
+ $v='<xsl:value-of select="$v"/>'
54
56
  </dce-text>
55
- <code xmlns="" data-testid="p2" data-dce-id="6">
56
- <xsl:value-of select="$p2"/>
57
- </code>
58
57
  <br xmlns="" data-dce-id="7"/>
59
58
  <dce-text xmlns="" data-dce-id="8">
60
- p3:
59
+ //s='<xsl:value-of select="//s"/>'
60
+ </dce-text>
61
+ <br xmlns="" data-dce-id="9"/>
62
+ <dce-text xmlns="" data-dce-id="10">
63
+ A='<xsl:value-of select="//s[//s/event] | //attributes/v[not(//s/event)]"/>'
64
+ </dce-text>
65
+ <br xmlns="" data-dce-id="11"/>
66
+ <dce-text xmlns="" data-dce-id="12">
67
+ has-input =<xsl:value-of select=" $has-input "/>
68
+ </dce-text>
69
+ <br xmlns="" data-dce-id="13"/>
70
+ <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="in-value">
71
+ <xsl:choose>
72
+ <xsl:when test="//s/event">
73
+ <xsl:value-of select="//s">
74
+ </xsl:value-of>
75
+ </xsl:when>
76
+ <xsl:when test="//attributes/@v">
77
+ <xsl:value-of select="//attributes/@v">
78
+ </xsl:value-of>
79
+ </xsl:when>
80
+ <xsl:otherwise>def</xsl:otherwise>
81
+ </xsl:choose>
82
+ </xsl:variable>
83
+ <xsl:variable xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="xx"
84
+ select="//s[//s/event] ?? //attributes/@v ?? 'def' "/>
85
+ <input xmlns="" slice="s" slice-event="input" value="{$in-value}" data-dce-id="14"/>
86
+ <dce-text xmlns="" data-dce-id="15">$in-value:<xsl:value-of select="$in-value"/> | $xx:<xsl:value-of
87
+ select="$xx"/>
61
88
  </dce-text>
62
- <code xmlns="" data-testid="p3" data-dce-id="9">
63
- <xsl:value-of select="$p3"/>
64
- </code>
65
89
  </dce-root>
66
90
  </xsl:template>
67
91
  <xsl:template match="/">
@@ -1,5 +1,14 @@
1
1
  <?xml version="1.0" encoding="UTF-8"?>
2
- <dce-root data-dce-id="1" value="123"
3
- xmlns="http://www.w3.org/1999/xhtml" xmlns:dce="urn:schemas-epa-wg:dce" xmlns:xhtml="http://www.w3.org/1999/xhtml"><label data-dce-id="2">
4
- <dce-text data-dce-id="3"/>
5
- <input data-dce-id="4" slice="selected" slice-event="input" value="123"/></label></dce-root>
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"><label data-dce-id="2" xmlns=""><input data-dce-id="3"
4
+ slice="disabled-slice"
5
+ type="checkbox"
6
+ value="disabled"/>
7
+ <dce-text data-dce-id="4">disabled</dce-text>
8
+ </label>
9
+ <cem-input data-dce-id="6" value="123"/>
10
+ <button data-dce-id="7">Next</button>
11
+
12
+
13
+ </p></form>
14
+ </dce-root>
@@ -8,8 +8,8 @@
8
8
  * - Please do NOT serve this file on production.
9
9
  */
10
10
 
11
- const PACKAGE_VERSION = '2.4.5'
12
- const INTEGRITY_CHECKSUM = '26357c79639bfa20d64c0efca2a87423'
11
+ const PACKAGE_VERSION = '2.7.0'
12
+ const INTEGRITY_CHECKSUM = '00729d72e3b82faf54ca8b9621dbb96f'
13
13
  const IS_MOCKED_RESPONSE = Symbol('isMockedResponse')
14
14
  const activeClientIds = new Set()
15
15
 
@@ -62,7 +62,12 @@ self.addEventListener('message', async function (event) {
62
62
 
63
63
  sendToClient(client, {
64
64
  type: 'MOCKING_ENABLED',
65
- payload: true,
65
+ payload: {
66
+ client: {
67
+ id: client.id,
68
+ frameType: client.frameType,
69
+ },
70
+ },
66
71
  })
67
72
  break
68
73
  }
@@ -155,6 +160,10 @@ async function handleRequest(event, requestId) {
155
160
  async function resolveMainClient(event) {
156
161
  const client = await self.clients.get(event.clientId)
157
162
 
163
+ if (activeClientIds.has(event.clientId)) {
164
+ return client
165
+ }
166
+
158
167
  if (client?.frameType === 'top-level') {
159
168
  return client
160
169
  }
@@ -183,12 +192,26 @@ async function getResponse(event, client, requestId) {
183
192
  const requestClone = request.clone()
184
193
 
185
194
  function passthrough() {
186
- const headers = Object.fromEntries(requestClone.headers.entries())
195
+ // Cast the request headers to a new Headers instance
196
+ // so the headers can be manipulated with.
197
+ const headers = new Headers(requestClone.headers)
198
+
199
+ // Remove the "accept" header value that marked this request as passthrough.
200
+ // This prevents request alteration and also keeps it compliant with the
201
+ // user-defined CORS policies.
202
+ const acceptHeader = headers.get('accept')
203
+ if (acceptHeader) {
204
+ const values = acceptHeader.split(',').map((value) => value.trim())
205
+ const filteredValues = values.filter(
206
+ (value) => value !== 'msw/passthrough',
207
+ )
187
208
 
188
- // Remove internal MSW request header so the passthrough request
189
- // complies with any potential CORS preflight checks on the server.
190
- // Some servers forbid unknown request headers.
191
- delete headers['x-msw-intention']
209
+ if (filteredValues.length > 0) {
210
+ headers.set('accept', filteredValues.join(', '))
211
+ } else {
212
+ headers.delete('accept')
213
+ }
214
+ }
192
215
 
193
216
  return fetch(requestClone, { headers })
194
217
  }
@@ -1,5 +1,9 @@
1
1
  export function log(x: any): void;
2
2
  export function deepEqual(a: any, b:any): boolean|0;
3
+ export function cloneAs(sourceNode: HTMLElement, tag:string): HTMLElement;
4
+ export function mix(objTo: any, objFrom:any): any;
5
+ export function mergeAttr(fromEl: HTMLElement, toEL:HTMLElement): void;
6
+
3
7
  export function xml2dom(xmlString:string): Document;
4
8
  export function xmlString(doc:Node|Document): string;
5
9
  export function obj2node(o:any, tag:string, doc:Document): HTMLElement;
@@ -5,7 +5,7 @@ const XSL_NS_URL = 'http://www.w3.org/1999/XSL/Transform'
5
5
 
6
6
  // const log = x => console.debug( new XMLSerializer().serializeToString( x ) );
7
7
 
8
- const attr = (el, attr)=> el.getAttribute?.(attr)
8
+ 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'
@@ -234,6 +234,8 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
234
234
  const d = xml2dom( '<xhtml/>' )
235
235
  , n = d.importNode(r, true);
236
236
  d.replaceChild(n,d.documentElement);
237
+ if( n.namespaceURI === HTML_NS_URL && !attr(n,'xmlns'))
238
+ n.setAttribute('xmlns',HTML_NS_URL);
237
239
  return xslHtmlNs(n);
238
240
  };
239
241
  if( e )
@@ -294,6 +296,16 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
294
296
  fr.append(r)
295
297
  }
296
298
 
299
+ [...fr.querySelectorAll('[test]')].forEach( n=>{
300
+ const t = attr(n,'test')
301
+ , r = t.replace(/hasBoolAttribute\((.*?)\)/g,
302
+ (match, p1, p2,p3,p4)=>
303
+ { const a = p1.substring(1);
304
+ return `(not($${a} = \'false\') and ($${a} = '' or $${a} = '${a}' or $${a} = 'true' ))`
305
+ });
306
+ t!== r && n.setAttribute('test',r);
307
+ });
308
+
297
309
  [...fr.querySelectorAll('dce-root>attribute')].forEach( a=>
298
310
  {
299
311
  keepAttributes(a,'namespace,name,select');
@@ -317,10 +329,15 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
317
329
  if( select?.length>1 )
318
330
  { p.removeAttribute('select');
319
331
  const c = $( xslDom, 'template[match="ignore"]>choose').cloneNode(true);
320
- // todo multiple ?? operators
321
332
  emptyNode(c.firstElementChild).append( createText(c,'{'+select[0]+'}'));
322
- emptyNode(c.lastElementChild ).append( createText(c,'{'+select[1]+'}'));
323
- c.firstElementChild.setAttribute('test','string-length('+select[0]+')');
333
+ c.firstElementChild.setAttribute('test',select[0]);
334
+ for( let i=1; i<select.length-1; i++)
335
+ { const when = c.firstElementChild.cloneNode(true);
336
+ emptyNode(when).append( createText(c,'{'+select[i]+'}'));
337
+ when.setAttribute('test',select[i]);
338
+ c.insertBefore(when, c.lastElementChild);
339
+ }
340
+ emptyNode(c.lastElementChild ).append( createText(c,'{'+select[select.length-1]+'}'));
324
341
  p.append(c);
325
342
  val = c.cloneNode(true);
326
343
  }else
@@ -329,8 +346,12 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
329
346
  a.append(val);
330
347
  a.removeAttribute('select');
331
348
  }else
332
- { keepAttributes( p, 'name' );
349
+ {
350
+ keepAttributes( p, 'name' );
333
351
  p.setAttribute('select','/datadom/attributes/'+name)
352
+
353
+ if( !hardcodedAttributes[name] )
354
+ a.remove();
334
355
  }
335
356
  });
336
357
  [...fr.querySelectorAll('[value]')].filter(el=>el.getAttribute('value').match( /\{(.*)\?\?(.*)\}/g )).forEach(el=>
@@ -460,12 +481,15 @@ event2slice( x, sliceNames, ev, dce )
460
481
  const v = notChecked? '' : el.value ?? attr( el, 'value' );
461
482
  cleanSliceValue();
462
483
  if( v === null || v === undefined )
484
+ {
463
485
  [...s.childNodes].filter(n=>n.localName!=='event').map(n=>n.remove());
486
+ s.removeAttribute('value');
487
+ }
464
488
  else
465
- if( isString(v) )
466
- s.append( createText( d, v) );
467
- else
468
- s.append( obj2node(v,'value',s.ownerDocument) )
489
+ { const ve = isString(v) ? createText( d, v) : obj2node(v,'value',s.ownerDocument);
490
+ s.append( ve );
491
+ s.setAttribute('value',v);
492
+ }
469
493
  }
470
494
  return s
471
495
  })
@@ -513,11 +537,24 @@ const loadTemplateRoots = async ( src, dce )=>
513
537
  export function mergeAttr( from, to )
514
538
  { for( let a of from.attributes)
515
539
  try
516
- { a.namespaceURI? to.setAttributeNS( a.namespaceURI, a.name, a.value ) : to.setAttribute( a.name, a.value )
540
+ { const name = a.name;
541
+ if( a.namespaceURI )
542
+ { if( !to.hasAttributeNS(a.namespaceURI, name) || to.getAttributeNS(a.namespaceURI, name) !== a.value )
543
+ to.setAttributeNS( a.namespaceURI, name, a.value )
544
+ }else
545
+ { if( !to.hasAttribute(name) || to.getAttribute(name) !== a.value )
546
+ to.setAttribute( a.name, a.value )
547
+ }
517
548
  if( a.name === 'value')
518
549
  to.value = a.value
519
550
  }catch(e)
520
551
  { console.warn('attribute assignment error',e?.message || e); }
552
+ const ea = to.dceExportedAttributes
553
+ , aa = to.getAttribute('dce-exported-attributes')
554
+ , em = aa ? new Set( aa.split(' ') ) : null;
555
+ for( let a of to.getAttributeNames() )
556
+ if( !from.hasAttribute(a) && !ea?.has(a) && !em?.has(a) )
557
+ to.removeAttribute(a)
521
558
  }
522
559
  export function assureUnique(n, id=0)
523
560
  {
@@ -650,7 +687,7 @@ CustomElement extends HTMLElement
650
687
  async connectedCallback()
651
688
  {
652
689
  if(this.firstElementChild && this.firstElementChild.localName !== 'template')
653
- console.warn('custom-element used without template wrapping content\n', this.outerHTML);
690
+ console.log('custom-element used without template wrapping content\n', this.outerHTML);
654
691
  const templateRoots = await loadTemplateRoots( attr( this, 'src' ), this )
655
692
  , tag = attr( this, 'tag' )
656
693
  , tagName = tag ? tag : 'dce-'+crypto.randomUUID();
@@ -681,11 +718,13 @@ CustomElement extends HTMLElement
681
718
  .map(splitSliceNames).flat();
682
719
 
683
720
  const { declaredAttributes, hardcodedAttributes, exposedAttributes } = templateDocs[0];
721
+ const dceExportedAttributes = new Set([...Object.keys(hardcodedAttributes), ...Object.keys(exposedAttributes)]);
684
722
 
685
723
  class DceElement extends HTMLElement
686
724
  {
687
725
  static get observedAttributes(){ return declaredAttributes; }
688
726
  #inTransform = 0;
727
+ get dceExportedAttributes(){ return dceExportedAttributes; }
689
728
  connectedCallback()
690
729
  { let payload = sanitizeBlankText(this.childNodes);
691
730
  if( this.firstElementChild?.tagName === 'TEMPLATE' )
@@ -719,8 +758,9 @@ CustomElement extends HTMLElement
719
758
  this.innerHTML='';
720
759
  const attrsRoot = injectData( x, 'attributes' , this.attributes, e => createXmlNode( e.nodeName, e.value ) )
721
760
  , inAttrs = a=> this.hasAttribute(a) || [...attrsRoot.children].find(e=>e.localName === a);
761
+ mergeAttr( this, attrsRoot );
722
762
  Object.keys(hardcodedAttributes).map(a=> inAttrs(a) || attrsRoot.append(createXmlNode(a,hardcodedAttributes[a])) );
723
- declaredAttributes.map(a=> inAttrs(a) || attrsRoot.append(createXmlNode(a)) );
763
+ Object.keys(exposedAttributes).map(a=> inAttrs(a) || attrsRoot.append(createXmlNode(a)) );
724
764
 
725
765
  injectData( x, 'dataset', Object.keys( this.dataset ), k => createXmlNode( k, this.dataset[ k ] ) );
726
766
  const sliceRoot = injectData( x, 'slice', sliceNames, k => createXmlNode( k, '' ) )
@@ -753,34 +793,42 @@ CustomElement extends HTMLElement
753
793
  const transform = this.transform = ()=>
754
794
  { if(this.#inTransform){ debugger }
755
795
  this.#inTransform = 1;
756
-
757
- const ff = xp.map( (p,i) =>
758
- { const f = p.transformToFragment(x.ownerDocument, document)
759
- if( !f )
760
- console.error( "XSLT transformation error. xsl:\n", xmlString(templateDocs[i]), '\nxml:\n', xmlString(x) );
761
- return f
762
- });
763
- ff.map( f =>
764
- { if( !f )
765
- return;
766
- assureUnique(f);
767
- merge( this, f.childNodes )
768
- })
769
-
770
- Object.entries(hardcodedAttributes).map(( [a,v] )=>
771
- { if( !this.hasAttribute(a) && v !== attr(this,a) )
772
- { this.setAttribute( a, v );
773
- this.#applyAttribute( a, v );
774
- }
775
- });
776
-
777
- Object.keys(exposedAttributes).map( a =>
778
- { let v = attr(this.firstElementChild,a);
779
- if( v !== attr(this,a) )
780
- { this.setAttribute( a, v );
781
- this.#applyAttribute( a, v );
782
- }
783
- });
796
+ const renderModel = ()=>
797
+ {
798
+ const ff = xp.map( (p,i) =>
799
+ { const f = p.transformToFragment(x.ownerDocument, document)
800
+ if( !f )
801
+ console.error( "XSLT transformation error. xsl:\n", xmlString(templateDocs[i]), '\nxml:\n', xmlString(x) );
802
+ return f
803
+ });
804
+ ff.map( f =>
805
+ { if( !f )
806
+ return;
807
+ assureUnique(f);
808
+ merge( this, f.childNodes )
809
+ })
810
+ let attrChangedCount = 0;
811
+ Object.entries(hardcodedAttributes).map(( [a,v] )=>
812
+ { if( !this.hasAttribute(a) && v !== attr(this,a) )
813
+ { this.setAttribute( a, v );
814
+ this.#applyAttribute( a, v );
815
+ attrChangedCount++;
816
+ }
817
+ });
818
+
819
+ Object.keys(exposedAttributes).map( a =>
820
+ { let v = attr(this.firstElementChild,a);
821
+ if( v !== attr(this,a) )
822
+ { this.setAttribute( a, v );
823
+ this.#applyAttribute( a, v );
824
+ attrChangedCount++;
825
+ }
826
+ });
827
+ return attrChangedCount;
828
+ };
829
+ if( renderModel() )
830
+ if( renderModel() )
831
+ console.warn("model update should not be the result of transform more than once");
784
832
 
785
833
  function getSliceTarget(el)
786
834
  { let r = el;
@@ -868,13 +916,15 @@ CustomElement extends HTMLElement
868
916
  #applyAttribute(name, newValue)
869
917
  { if( 'value' === name )
870
918
  this.value = newValue;
919
+ const attrs = this.xml.querySelector('attributes');
871
920
  let a = this.xml.querySelector(`attributes>${name}`);
872
921
  if( a )
873
922
  emptyNode(a).append( createText(a,newValue) );
874
923
  else
875
924
  { a = create( name, newValue, this.xml );
876
- this.xml.querySelector('attributes').append( a );
925
+ attrs.append( a );
877
926
  }
927
+ this.#inTransform || attrs.setAttribute(name,newValue);
878
928
 
879
929
  this.dispatchEvent(new CustomEvent('change', { bubbles: true,detail: { [name]: newValue }}))
880
930
  }
@@ -0,0 +1,153 @@
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>parameters - 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
+
13
+ button{ background: forestgreen; }
14
+ table{ min-width: 16rem; }
15
+ td{ border-bottom: 1px solid silver; }
16
+ tfoot td{ border-bottom: none; }
17
+ td,th{text-align: right; }
18
+ caption{ padding: 1rem; font-weight: bolder; font-family: sans-serif; }
19
+ </style>
20
+ </head>
21
+ <body>
22
+ <nav>
23
+ <a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
24
+ </nav>
25
+ <main>
26
+ <p><code>attribute</code> is used for DCE attributes declaration and track the attributes changes. It also be used by IDE and validation.</p>
27
+ <p>The attribute can be changed by component itself and used as output to the container.
28
+ Usual case is when <code>value</code> attribute is updated from inside.</p>
29
+ <p>Initial value of attribute is available on the <code>attributes</code> node attribute as in <code>/datadom/attributes/@attr1</code></p>
30
+ <p>The current, i.e. including the changes by component itself, attribute value is a child node of <code>attributes</code> as in <code>/datadom/attributes/attr1</code>.</p>
31
+ <p>To define the attribute which is modified from within, the 3 parts are usually used as in <code>//s[//s/event] ?? //attributes/@v ?? 'def' </code>
32
+ <ol>
33
+ <li><code>//s[//s/event]</code> the slice <code>s</code> with event gives the slice value which was modified by user event like input</li>
34
+ <li><code>//attributes/@v</code> the attribute passed by container</li>
35
+ <li><code>'def' </code> the default value which used when no user input or attribute set by container</li>
36
+ </ol>
37
+ </p>
38
+ </main>
39
+ <html-demo-element legend="attributes definition" >
40
+ <p slot="description">
41
+ <code>attribute</code> is used for DCE attributes declaration and track the attributes changes. It also be used by IDE and validation.
42
+
43
+ </p>
44
+ <template>
45
+ <custom-element tag="dce-link" hidden>
46
+ <attribute name="p1" >default_P1 </attribute>
47
+ <attribute name="p2" select="'always_p2'" ></attribute>
48
+ <attribute name="p3" select="//attributes/@p3 ?? 'def_P3' " ></attribute>
49
+ p1:{$p1} <br/> p2: {$p2} <br/> p3: {$p3}
50
+ </custom-element>
51
+ <dce-link id="dce1" ></dce-link>
52
+ <section>
53
+ <dce-link id="dce2" p1="123" p2="override ignored as select is defined"></dce-link> <br/>
54
+ <div><input id="i1" value="p1" /> <button onclick="dce2.setAttribute('p1',i1.value)"> set p1</button> </div>
55
+ <div><input id="i2" value="p2" /> <button onclick="dce2.setAttribute('p2',i2.value)"> set p2</button> </div>
56
+ <div><input id="i3" value="p3" /> <button onclick="dce2.setAttribute('p3',i3.value)"> set p3</button> </div>
57
+ </section>
58
+ <dce-link id="dce3" p1="123" p3="qwe"></dce-link> |
59
+
60
+ </template>
61
+ </html-demo-element>
62
+
63
+ <html-demo-element legend="attribute from slice">
64
+ <p slot="description">
65
+ When slice value points to attribute, it would be populated on slice change.<br/>
66
+ Type in the input field to see the variable $title change. <br/>
67
+ Hover the mouse to see the title attribute text popup.<br/>
68
+ Inspect DCE node in dev tools to see `title` attribute updated while typing.
69
+
70
+ </p>
71
+
72
+ <template>
73
+ <custom-element>
74
+ <template>
75
+ <attribute name="title" select="//title ?? '😃'" ></attribute>
76
+ <input slice="/datadom/attributes/title" slice-event="keyup"/>
77
+ title attribute: {$title}
78
+ </template>
79
+ </custom-element>
80
+ </template>
81
+ </html-demo-element>
82
+
83
+
84
+ <html-demo-element legend="V attribute matches input value" description="
85
+ Type in the input field and observe in DevTools the V attribute changed.
86
+ ">
87
+ <template>
88
+ <custom-element tag="x-input" >
89
+ <template>
90
+ <attribute name="is-changed" select="count(//s/event) &gt; 0"></attribute>
91
+ <attribute name="v" select="//s[//s/event] ?? //attributes/@v ?? 'def' "></attribute>
92
+ /datadom/attributes/v='{/datadom/attributes/v}'<br/>
93
+ same as v='{v}'<br/>
94
+ same as $v='{$v}'<br/>
95
+ //attributes/@v='{//attributes/@v}'<br/>
96
+ //s='{//s}'<br/>
97
+ is-changed ={ is-changed }<br/>
98
+ <input slice="s" slice-event="input" value="{//attributes/v}"/>
99
+ </template>
100
+ </custom-element>
101
+ <x-input></x-input>
102
+ <x-input v="V1"></x-input>
103
+ </template>
104
+ </html-demo-element>
105
+
106
+ <html-demo-element legend="attribute defaults, from container, and from slice" description="
107
+ Type in the input field and observe in DevTools the V attribute changed.
108
+ ">
109
+ <template>
110
+ <custom-element tag="attr-demo">
111
+ <template>
112
+ <variable name="has-input" select="count(//s/*) &gt; 0"></variable>
113
+ <attribute name="v" select="//s[//s/event] ?? //attributes/@v ?? 'def' "></attribute>
114
+ //attributes/v='{//attributes/v}'<br/>
115
+ //attributes/@v='{//attributes/@v}'<br/>
116
+ $v='{$v}'<br/>
117
+ //s='{//s}'<br/>
118
+ A='{//s[//s/event] | //attributes/v[not(//s/event)]}'<br/>
119
+ has-input ={ $has-input }<br/>
120
+ <input slice="s" slice-event="input" />
121
+ </template>
122
+ </custom-element>
123
+
124
+ <attr-demo></attr-demo>
125
+ <attr-demo v="From Container"></attr-demo>
126
+ </template>
127
+ </html-demo-element>
128
+
129
+ <details>
130
+ <summary>Attributes processing</summary>
131
+ To be available in template, <code>custom-element</code> attributes should be
132
+ defined by <code>attribute</code> markup as shown above.
133
+ The value is taken from attribute text content or from <code>select</code> XPath expression<br/>
134
+
135
+ Declared in such way, attributes are exposed via <code><a
136
+ href="https://developer.mozilla.org/en-US/docs/Web/API/Web_components/Using_custom_elements#responding_to_attribute_changes"
137
+ >observedAttributes</a></code>. <br/>
138
+ The template exposes those attributes as <code>xsl:param</code> which makes the attribute value available as
139
+ xsl variable (as attribute name prefixed with $). <br/>
140
+ After transformation the attributes values are read from CE root and copied into DCE component. <br/>
141
+ The DCE attribute change from outside invokes <code>attributeChangedCallback</code> which triggers DCE re-render.
142
+ <p>
143
+ The <code>value</code> attribute is usual case to be propagated from within of <code>custom-element</code>.
144
+ See the <a href="./form.html#sample-5">using custom-element as form input</a> example.
145
+ </p>
146
+ &bull; <a href="https://github.com/EPA-WG/custom-element/blob/main/docs/attributes.md">Design docs</a>
147
+ </details>
148
+
149
+
150
+ <script type="module" src="https://unpkg.com/html-demo-element@1/html-demo-element.js"></script>
151
+
152
+ </body>
153
+ </html>
@@ -73,7 +73,7 @@
73
73
  <path class="cls-1"
74
74
  d="m184.02,96.93l20.64-11.92c.47-.27.47-.79,0-1.06l-20.65-11.92h0c-4.44-2.57-8.22-2.57-12.67,0l-20.65,11.92c-.47.27-.47.79,0,1.06l20.64,11.92c4.44,2.57,8.22,2.57,12.67,0h0Z"/>
75
75
  </svg>
76
- <math id="sophomores-dream" display="block">
76
+ <math id="sophomores-dream" data-testid="ml-test" display="block">
77
77
  <mrow>
78
78
  <msubsup>
79
79
  <mo>∫</mo>