@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
@@ -0,0 +1,53 @@
1
+ "use strict";const F="http://www.w3.org/1999/XSL/Transform",q="http://www.w3.org/1999/xhtml",ye="http://exslt.org/common",x=(e,l)=>e.getAttribute?.(l),K=e=>e.nodeType===3,be=e=>typeof e=="string",ge=e=>e&&typeof e.nodeType=="number",S=(e,l)=>(e.ownerDocument||e).createTextNode(l),ee=e=>{for(;e.firstChild;)e.firstChild.remove();return e},H=e=>(e.getAttributeNames().map(l=>e.removeAttribute(l)),ee(e)),te=e=>(e?.setAttribute("xmlns:xsl",F),e),se=e=>(e?.setAttribute("xmlns:xhtml",q),te(e)),le=e=>/^[_a-zA-Z][-_:a-zA-Z0-9]*$/.test(e),A=(e,l="",t=document)=>{const s=a=>(o=>(l&&o.append(S(t.ownerDocument||t,l)),o))((t.ownerDocument||t).createElement(a));if(le(e))return s(e);const n=s("dce-object");return n.setAttribute("dce-object-name",e),n},Q=(e,l)=>{const t=e.ownerDocument.createElementNS(e.namespaceURI,l);for(let s of e.attributes)t.setAttribute(s.name,s.value);for(;e.firstChild;)t.append(e.firstChild);return t};function $(e){return new DOMParser().parseFromString(e,"application/xml")}function I(e){return new XMLSerializer().serializeToString(e)}function U(e,l,t,s){const n=h=>e.ownerDocument.createElement(h),o=((h,p,m)=>(p.append(m=n(h)),m))(l,e);return[...t].forEach(h=>o.append(s(h))),o}function ve(e){return e.slot||(e.setAttribute||(e=A("span",e.textContent.replaceAll(`
2
+ `,""))),e.setAttribute("slot","")),e}function C(e,l,t){const s=typeof e;if(s==="string")return A(l,e,t);if(s==="number")return A(l,""+e,t);if(e instanceof Array){const a=A("array","",t);return e.map(o=>a.append(C(o,l,t))),a}if(e instanceof FormData){const a=A("form-data","",t);for(const o of e)a.append(C(o[1],o[0],t));return a}const n=A(l,"",t);for(let a in e)ge(e[a])||typeof e[a]=="function"||e[a]instanceof Window||(typeof e[a]!="object"&&le(a)?n.setAttribute(a,e[a]):n.append(C(e[a],a,t)));return n}function W(e){if(D(e,"*",l=>[...l.childNodes].filter(t=>t.nodeType===3&&t.parentNode.localName!=="style"&&t.data).forEach(t=>{const s=t.data,n=s.matchAll(/{([^}]*)}/g);if(n){let a=0,o=p=>S(t,p),h=[];if([...n].forEach(p=>{p.index>a&&h.push(o(p.input.substring(a,p.index)));const m=e.querySelector("value-of").cloneNode();m.setAttribute("select",p[1]),h.push(m),a=p.index+p[0].length}),a<s.length&&h.push(o(s.substring(a,s.length))),h.length){for(let p of h)l.insertBefore(p,t);l.removeChild(t)}}})),"all"in e){let l=1;for(let t of e.all)t.setAttribute&&!t.tagName.startsWith("xsl:")&&t.setAttribute("data-dce-id",""+l++)}return e}function ne(e,l="xsl:stylesheet"){if(e.tagName===l||e.documentElement?.tagName===l)return W(e);const t=$(`<xsl:stylesheet version="1.0" xmlns:xsl="${F}" xmlns:xhtml="${q}" xmlns:exsl="${ye}" exclude-result-prefixes="exsl" >
3
+ <xsl:output method="xml" />
4
+ <xsl:template match="/"><dce-root xmlns="${q}"><xsl:apply-templates select="*"/></dce-root></xsl:template>
5
+ <xsl:template match="*[name()='template']"><xsl:apply-templates mode="sanitize" select="*|text()"/></xsl:template>
6
+ <xsl:template match="*"><xsl:apply-templates mode="sanitize" select="*|text()"/></xsl:template>
7
+ <xsl:template match="*[name()='svg']|*[name()='math']"><xsl:apply-templates mode="sanitize" select="."/></xsl:template>
8
+ <xsl:template mode="sanitize" match="*[count(text())=1 and count(*)=0]"><xsl:copy><xsl:apply-templates mode="sanitize" select="@*"/><xsl:value-of select="text()"></xsl:value-of></xsl:copy></xsl:template>
9
+ <xsl:template mode="sanitize" match="xhtml:*[count(text())=1 and count(*)=0]"><xsl:element name="{local-name()}"><xsl:apply-templates mode="sanitize" select="@*"/><xsl:value-of select="text()"></xsl:value-of></xsl:element></xsl:template>
10
+ <xsl:template mode="sanitize" match="*|@*"><xsl:copy><xsl:apply-templates mode="sanitize" select="*|@*|text()"/></xsl:copy></xsl:template>
11
+ <xsl:template mode="sanitize" match="text()[normalize-space(.) = '']"/>
12
+ <xsl:template mode="sanitize" match="text()"><dce-text><xsl:copy/></dce-text></xsl:template>
13
+ <xsl:template mode="sanitize" match="xsl:value-of|*[name()='slot']"><dce-text><xsl:copy><xsl:apply-templates mode="sanitize" select="*|@*|text()"/></xsl:copy></dce-text></xsl:template>
14
+ <xsl:template mode="sanitize" match="xhtml:*"><xsl:element name="{local-name()}"><xsl:apply-templates mode="sanitize" select="*|@*|text()"/></xsl:element></xsl:template>
15
+ </xsl:stylesheet>`),s=new XSLTProcessor,n=(i=>{D(i,"script",b=>b.remove());const c=i.content??i.firstElementChild?.content??i.body??i;pe.forEach(b=>D(c,b,g=>fe(g,c)));const E=i.firstElementChild?.content||i.content,v=b=>{const g=$("<xhtml/>"),z=g.importNode(b,!0);return g.replaceChild(z,g.documentElement),se(z)};if(E){const b=A("div");return[...E.childNodes].map(g=>b.append(g.cloneNode(!0))),v(b)}return v(i.documentElement||i.body||i)})(e),a=$(`<xsl:stylesheet version="1.0"
16
+ xmlns:xsl="${F}"
17
+ xmlns:xhtml="${q}"
18
+ xmlns:dce="urn:schemas-epa-wg:dce"
19
+ xmlns:exsl="http://exslt.org/common"
20
+ exclude-result-prefixes="exsl"
21
+ >
22
+ <xsl:template match="ignore">
23
+ <xsl:choose>
24
+ <xsl:when test="//attr">{//attr}</xsl:when>
25
+ <xsl:otherwise>{def}</xsl:otherwise>
26
+ </xsl:choose><xsl:value-of select="."></xsl:value-of></xsl:template>
27
+ <xsl:template mode="payload" match="attributes"></xsl:template>
28
+ <xsl:template match="/">
29
+ <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
30
+ </xsl:template>
31
+ <xsl:template name="slot" >
32
+ <xsl:param name="slotname" />
33
+ <xsl:param name="defaultvalue" />
34
+ <xsl:choose>
35
+ <xsl:when test="//payload/*[@slot=$slotname]">
36
+ <xsl:copy-of select="//payload/*[@slot=$slotname]"/>
37
+ </xsl:when>
38
+ <xsl:otherwise>
39
+ <xsl:copy-of select="$defaultvalue"/>
40
+ </xsl:otherwise>
41
+ </xsl:choose>
42
+ </xsl:template>
43
+ <xsl:variable name="js-injected-body">
44
+ <xsl:call-template name="slot" >
45
+ <xsl:with-param name="slotname" select="''"/>
46
+ <xsl:with-param name="defaultvalue"/>
47
+ </xsl:call-template>
48
+ </xsl:variable>
49
+ </xsl:stylesheet>`);s.importStylesheet(t);const o=s.transformToFragment(n,document),h=(i,c)=>i.querySelector(c),p=h(a,'template[mode="payload"]');if(!o)return console.error("transformation error",{xml:n.outerHTML,xsl:I(t)});const m=[];[...o.querySelectorAll("dce-root>attribute")].forEach(i=>{const c=Q(i,"xsl:param"),E=x(i,"name");p.append(c);let v=x(c,"select")?.split("??");v||(v=["//"+E,`'${c.textContent}'`],H(c),c.setAttribute("name",E));let b;if(v?.length>1){c.removeAttribute("select");const g=h(a,'template[match="ignore"]>choose').cloneNode(!0);H(g.firstElementChild).append(S(g,"{"+v[0]+"}")),H(g.lastElementChild).append(S(g,"{"+v[1]+"}")),g.firstElementChild.setAttribute("test",v[0]),c.append(g),b=g.cloneNode(!0)}else b=Q(i,"xsl:value-of");b.removeAttribute("name"),i.append(b),i.removeAttribute("select"),m.push(c)}),[...o.querySelectorAll("[value]")].filter(i=>i.getAttribute("value").match(/\{(.*)\?\?(.*)\}/g)).forEach(i=>{const c=x(i,"value");c&&i.setAttribute("value",de(c))});for(const i of o.childNodes)p.append(a.importNode(i,!0));[...p.querySelectorAll("template")].forEach(i=>p.ownerDocument.documentElement.append(i));const M=h(a,'call-template[name="slot"]'),d=i=>{const c=M.cloneNode(!0),E=x(i,"name");E&&c.firstElementChild.setAttribute("select",`'${E}'`);for(let v of i.childNodes)c.lastElementChild.append(v);return c};D(p,"slot",i=>i.parentNode.replaceChild(d(i),i));const u=W(a);return u.params=m,u}async function ae(e){return await new Promise((t,s)=>{const n=new XMLHttpRequest;n.open("GET",e),n.responseType="document",n.onload=()=>{n.readyState===n.DONE&&n.status===200&&t(n.responseXML||A("div",n.responseText)),s(n.statusText)},n.addEventListener("error",a=>s(a)),n.send()})}function ie(e,l,t=!1){if(e===l)return!0;if(typeof e!="object"||e===null||typeof l!="object"||l===null||Object.keys(e).length!==Object.keys(l).length)return t;for(let s in e)if(!(s in l)||!ie(e[s],l[s]))return t;return!0}const re=e=>e.split("|").map(l=>l.trim()).filter(l=>l),oe=(e,l)=>re(l).map(t=>{let s=e.ownerDocument,n=a=>(e.append(a),a);if(t.includes("/")){const a=[],o=s.evaluate(t,e);for(let h;h=o.iterateNext();)a.push(h);return a}return[...e.childNodes].find(a=>a.localName===t)||n(A(t,"",s))}).flat();function Y(e,l,t,s){if(!t.sliceProcessed)return t.sliceProcessed=1,oe(e,l??"").map(n=>{const a=e.ownerDocument,o=t.sliceEventSource,h=t.sliceElement,p=()=>[...n.childNodes].filter(m=>m.nodeType===3||m.localName==="value"||m.localName==="form-data").map(m=>m.remove());if(o.getAttributeNames().map(m=>n.setAttribute(m,x(o,m))),[...n.childNodes].filter(m=>m.localName==="event").map(m=>m.remove()),"validationMessage"in o&&n.setAttribute("validation-message",o.validationMessage),t.type==="init"&&p(),n.append(C(t,"event",a)),h.hasAttribute("slice-value")){o.value===void 0?n.removeAttribute("value"):n.setAttribute("value",o.value);const m=L(x(h,"slice-value"),n);p(),n.append(S(a,m))}else{if("elements"in o)return p(),n.append(C(new FormData(o),"value",n.ownerDocument)),n;const m=o.value??x(h,"value");p(),m==null?[...n.childNodes].filter(w=>w.localName!=="event").map(w=>w.remove()):be(m)?n.append(S(a,m)):n.append(C(m,"value",n.ownerDocument))}return n})}function D(e,l,t){e.querySelectorAll&&[...e.querySelectorAll(l)].forEach(t)}const Ee=async(e,l)=>{if(!e||!e.trim())return[l];if(e.startsWith("#"))return(t=>{if(!t)return[];const s=t.querySelectorAll(e);if(s.length)return[...s];const n=t.getRootNode();return n===t?[]:getByHashId(n)})(l.parentElement);try{const t=await ae(e),s=new URL(e,location).hash;if(s){const n=t.querySelectorAll(s);return n.length?[...n]:[l]}return[t]}catch{return[l]}};function ce(e,l){for(let t of e.attributes)t.namespaceURI?l.setAttributeNS(t.namespaceURI,t.name,t.value):l.setAttribute(t.name,t.value),t.name==="value"&&(l.value=t.value)}function G(e,l=0){const t={};for(const s of e.childNodes){const n=x(s,"data-dce-id")||s.dceId||0;if(!t[n])n?t[n]=1:(t[n]=s.dceId=++l,s.setAttribute&&s.setAttribute("data-dce-id",s.dceId));else{const a=s.dceId=n+"-"+t[n]++;s.setAttribute&&s.setAttribute("data-dce-id",a)}s.childNodes.length&&G(s)}}function me(e,l,t){t=1*t;for(let s of e.childNodes)if((s.dceId??s.getAttribute("data-dce-id")*1)>t)return e.insertBefore(l,s);e.append(l)}function Z(e,l){if(!l.length)return ee(e);const t={};for(let s of e.childNodes)t[s.dceId],K(s)?(s.data.trim(),t[s.dceId||0]=s):t[x(s,"data-dce-id")||0]=s;for(let s of[...l]){const n=x(s,"data-dce-id")||s.dceId,a=t[n];a?(K(s)?a.nodeValue!==s.nodeValue&&(a.nodeValue=s.nodeValue):(ce(s,a),(a.childNodes.length||s.childNodes.length)&&Z(a,s.childNodes)),delete t[n]):me(e,s,n)}for(let s of Object.values(t))s.remove()}function ue(e,l){return e.hasAttribute(l)||e.setAttribute(l,crypto.randomUUID()),e.getAttribute(l)}const de=e=>[...e?.matchAll(/([^{}]*)(\{)([^}]+)}([^{}]*)/g)].map(t=>`${t[1]}{${V(t[3])}}${t[4]}`).join(""),V=e=>{if(!e.trim())return e;const l=e.split("??"),t=l.shift(),s=V(l.join("??"));return l.length?`concat( ${t} , substring( ${s} , (1+string-length( ${s} )) * string-length( ${t} ) ) )`:e},L=(e,l)=>{const t=e.split("??");if(t.length>1)return L(t[0],l)||L(t[1],l);e=V(e);const s=l.ownerDocument.evaluate(e,l);switch(s.resultType){case XPathResult.NUMBER_TYPE:return s.numberValue;case XPathResult.STRING_TYPE:return s.stringValue;case XPathResult.BOOLEAN_TYPE:return s.booleanValue}let n="";for(let a;a=s.iterateNext();)n+=a.textContent;return n},pe="stylesheet,transform,import,include,strip-space,preserve-space,output,key,decimal-format,namespace-alias,template,value-of,copy-of,number,apply-templates,apply-imports,for-each,sort,if,choose,when,otherwise,attribute-set,call-template,with-param,variable,param,text,processing-instruction,element,attribute,comment,copy,message,fallback".split(","),fe=(e,l)=>{const t=A("xsl:"+e.localName);for(let s of e.attributes)t.setAttribute(s.name,s.value);for(;e.firstChild;)t.append(e.firstChild);if(e.parentElement)e.parentElement.replaceChild(t,e);else{const s=e.parentElement||l,n=[...s.childNodes];n.forEach((a,o)=>{a===e&&(n[o]=t)}),s.replaceChildren(...n)}};class he extends HTMLElement{static observedAttributes=["src","tag","hidden"];async connectedCallback(){const l=await Ee(x(this,"src"),this),t=x(this,"tag"),s=t||"dce-"+crypto.randomUUID();for(const d of l)D(d.templateNode||d.content||d,"style",u=>{const i=u.closest("slot"),c=i?`slot[name="${i.name}"]`:"";u.innerHTML=`${s} ${c}{${u.innerHTML}}`,this.append(u)});const n=l.map(d=>ne(d)),a=n.map((d,u)=>(u=new XSLTProcessor,u.importStylesheet(d),u));Object.defineProperty(this,"xsltString",{get:()=>n.map(d=>I(d)).join(`
50
+ `)});const o=this,h=[...this.templateNode.querySelectorAll("[slice]")],p=h.map(d=>x(d,"slice")).filter(d=>!d.includes("/")).filter((d,u,i)=>i.indexOf(d)===u).map(re).flat(),m=n.reduce((d,u)=>(u.params&&d.push(...u.params),d),[]);class w extends HTMLElement{static get observedAttributes(){return m.map(u=>x(u,"name"))}#e=0;connectedCallback(){let u=this.childNodes;if(this.firstElementChild?.tagName==="TEMPLATE"){this.firstElementChild!==this.lastElementChild&&console.error("payload should have TEMPLATE as only child",this.outerHTML);const f=this.firstElementChild;f.remove(),u=f.content.childNodes;for(const r of[...f.content.childNodes])if(r.localName==="style"){const y=ue(this,"data-dce-style");r.innerHTML=`${s}[data-dce-style="${y}"]{${r.innerHTML}}`,f.insertAdjacentElement("beforebegin",r)}else r.nodeType===1?f.insertAdjacentElement("beforebegin",r):r.nodeType===3&&f.insertAdjacentText("beforebegin",r.data)}const i=$("<datadom/>").documentElement,c=(f,r="")=>(y=>(r&&y.append(S(i,r)),y))(i.ownerDocument.createElement(f)),E=U(i,"payload",u,ve);te(E),se(E),this.innerHTML="";const v=U(i,"attributes",this.attributes,f=>c(f.nodeName,f.value));U(i,"dataset",Object.keys(this.dataset),f=>c(f,this.dataset[f]));const b=U(i,"slice",p,f=>c(f,"")),g=f=>L(f,b);this.xml=i;const z=[],J=()=>{const f={};for(let r;r=z.pop();){const y=x(r.sliceElement,"slice");f[y]||(Y(b,y,r),f[y]=r)}Object.keys(f).length!==0&&R()};let O;this.onSlice=f=>{z.push(f),O||(O=setTimeout(()=>{J(),O=0},1))};const R=this.transform=()=>{if(this.#e)debugger;this.#e=1,a.map((r,y)=>{const X=r.transformToFragment(i.ownerDocument,document);return X||console.error(`XSLT transformation error. xsl:
51
+ `,I(n[y]),`
52
+ xml:
53
+ `,I(i)),X}).map(r=>{r&&(G(r),Z(this,r.childNodes))}),w.observedAttributes.map(r=>{let y=x(this.firstElementChild,r);y!==x(this,r)&&(this.setAttribute(r,y),this.#t(r,y))}),D(this,"[slice],[slice-event]",r=>{if(!r.dceInitialized){r.dceInitialized=1;let y=x(r,"slice-event");r.hasAttribute("custom-validity")&&(y+=" change submit"),[...new Set((y||"change").split(" "))].forEach(X=>(r.localName==="slice"?r.parentElement:r).addEventListener(X,N=>{N.sliceElement=r,N.sliceEventSource=N.currentTarget||N.target;const xe=Y(b,x(N.sliceElement,"slice"),N);D(this,"[custom-validity]",j=>{if(!j.setCustomValidity)return;const B=x(j,"custom-validity");try{const P=B&&L(B,v);j.setCustomValidity(P===!0?"":P===!1?"invalid":P)}catch(P){console.error(P,"xPath",B)}});const _=x(r,"custom-validity"),T=_&&L(_,v),k=T===!0?"":T;if(_){if(r.setCustomValidity?r.setCustomValidity(k):r.validationMessage=k,xe.map(j=>j.setAttribute("validation-message",k)),N.type==="submit")return T===!0?void 0:(setTimeout(R,1),!!T===T?(T||N.preventDefault(),T):T?(N.preventDefault(),!1):void 0);setTimeout(R,1)}this.onSlice(N)})),(!y||y.includes("init"))&&(r.hasAttribute("slice-value")||r.hasAttribute("value")||r.value?this.onSlice({type:"init",target:r,sliceElement:r,sliceEventSource:r}):r.value=g(x(r,"slice")))}}),this.#e=0};R(),J()}#t(u,i){let c=this.xml.querySelector(`attributes>${u}`);c?H(c).append(S(c,i)):(c=A(u,i,this.xml),this.xml.querySelector("attributes").append(c))}attributeChangedCallback(u,i,c){!this.xml||this.#e||(this.#t(u,c),this.transform())}get dce(){return o}}const M=d=>{window.customElements.get(d)!==w&&window.customElements.define(d,w)};if(t)M(t);else{const d=s;this.setAttribute("tag",d),M(d);const u=document.createElement(d);this.getAttributeNames().forEach(i=>u.setAttribute(i,this.getAttribute(i))),u.append(...[...this.childNodes].filter(i=>i.localName!=="style")),this.append(u)}}get templateNode(){return this.firstElementChild?.tagName==="TEMPLATE"?this.firstElementChild.content:this}get dce(){return this}get xslt(){return $(this.xsltString)}}window.customElements.define("custom-element",he);exports.CustomElement=he;exports.appendByDceId=me;exports.assureSlices=oe;exports.assureUID=ue;exports.assureUnique=G;exports.createXsltFromDom=ne;exports.deepEqual=ie;exports.evalCurly=de;exports.event2slice=Y;exports.merge=Z;exports.mergeAttr=ce;exports.obj2node=C;exports.tagUid=W;exports.toXsl=fe;exports.xPath=L;exports.xPathDefaults=V;exports.xhrTemplate=ae;exports.xml2dom=$;exports.xmlString=I;exports.xslTags=pe;
@@ -1 +1 @@
1
- "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./custom-element-BDK7dcJN.cjs"),l=require("./http-request-DPrY7mGh.cjs"),t=require("./local-storage-Boafngui.cjs"),a=require("./location-element-2m0gWq_d.cjs");exports.CustomElement=e.CustomElement;exports.appendByDceId=e.appendByDceId;exports.assureSlices=e.assureSlices;exports.assureUID=e.assureUID;exports.assureUnique=e.assureUnique;exports.createXsltFromDom=e.createXsltFromDom;exports.deepEqual=e.deepEqual;exports.default=e.CustomElement;exports.evalCurly=e.evalCurly;exports.event2slice=e.event2slice;exports.merge=e.merge;exports.mergeAttr=e.mergeAttr;exports.obj2node=e.obj2node;exports.tagUid=e.tagUid;exports.toXsl=e.toXsl;exports.xPath=e.xPath;exports.xPathDefaults=e.xPathDefaults;exports.xhrTemplate=e.xhrTemplate;exports.xml2dom=e.xml2dom;exports.xmlString=e.xmlString;exports.xslTags=e.xslTags;exports.HttpRequestElement=l.HttpRequestElement;exports.LocalStorageElement=t.LocalStorageElement;exports.localStorageSetItem=t.localStorageSetItem;exports.LocationElement=a.LocationElement;
1
+ "use strict";Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});const e=require("./custom-element-DZvvhscI.cjs"),l=require("./http-request-DPrY7mGh.cjs"),t=require("./local-storage-Boafngui.cjs"),a=require("./location-element-DRB7hCwA.cjs");exports.CustomElement=e.CustomElement;exports.appendByDceId=e.appendByDceId;exports.assureSlices=e.assureSlices;exports.assureUID=e.assureUID;exports.assureUnique=e.assureUnique;exports.createXsltFromDom=e.createXsltFromDom;exports.deepEqual=e.deepEqual;exports.default=e.CustomElement;exports.evalCurly=e.evalCurly;exports.event2slice=e.event2slice;exports.merge=e.merge;exports.mergeAttr=e.mergeAttr;exports.obj2node=e.obj2node;exports.tagUid=e.tagUid;exports.toXsl=e.toXsl;exports.xPath=e.xPath;exports.xPathDefaults=e.xPathDefaults;exports.xhrTemplate=e.xhrTemplate;exports.xml2dom=e.xml2dom;exports.xmlString=e.xmlString;exports.xslTags=e.xslTags;exports.HttpRequestElement=l.HttpRequestElement;exports.LocalStorageElement=t.LocalStorageElement;exports.localStorageSetItem=t.localStorageSetItem;exports.LocationElement=a.LocationElement;
@@ -1,8 +1,8 @@
1
- import { C as e } from "./custom-element-DqtzLkTG.js";
2
- import { h as o, e as r, j as l, g as m, c as p, d as x, k as n, f as u, i as c, m as d, o as f, t as g, q as i, n as E, l as S, b as h, x as q, a as D, p as L } from "./custom-element-DqtzLkTG.js";
1
+ import { C as e } from "./custom-element-DAe7uvIt.js";
2
+ import { h as o, e as r, j as l, g as m, c as p, d as x, k as n, f as u, i as c, m as d, o as f, t as g, q as i, n as E, l as S, b as h, x as q, a as D, p as L } from "./custom-element-DAe7uvIt.js";
3
3
  import { H as I } from "./http-request-BOvP4KTl.js";
4
4
  import { L as b, l as j } from "./local-storage-BqDEu2kF.js";
5
- import { L as y } from "./location-element-nA_wsqBt.js";
5
+ import { L as y } from "./location-element-FJlONi2n.js";
6
6
  export {
7
7
  e as CustomElement,
8
8
  I as HttpRequestElement,
@@ -0,0 +1 @@
1
+ "use strict";const u=(t,e)=>t.getAttribute(e);let c;function f(){c||(c={},"back,forward,go,pushState,replaceState".split(",").forEach(t=>{c[t]=history[t],history[t]=function(...e){c[t].apply(history,e),window.dispatchEvent(new CustomEvent("dce-location",{detail:{k:t}}))}}))}const d={"location.href":t=>window.location.href=t,"location.hash":t=>window.location.hash=t,"location.assign":t=>window.location.assign(t),"location.replace":t=>window.location.replace(t),"history.pushState":t=>window.history.pushState({},"",t),"history.replaceState":t=>window.history.replaceState({},"",t)};class w extends HTMLElement{static observedAttributes=["value","slice","href","type","live","src","method"];constructor(){super();const e={},n=()=>setTimeout(r,1),r=()=>{const a=u(this,"href");a||f();const i=a?new URL(a,window.location):window.location,o={},l=new URLSearchParams(i.search);for(const s of l.keys())o[s]=l.getAll(s);const h={params:o};for(const s in i)typeof i[s]=="string"&&(h[s]=i[s]);this.value=h,this.dispatchEvent(new Event("change"))};this.sliceInit=a=>{if(this.hasAttribute("method")){const i=this.getAttribute("method"),o=this.getAttribute("src");i&&o&&(i==="location.hash"?o!==window.location.hash&&d[i]?.(o):window.location.href!==new URL(o,window.location).href&&d[i]?.(o))}return!e.listener&&this.hasAttribute("live")&&(e.listener=1,window.navigation?.addEventListener("navigate",n),window.addEventListener("popstate",n),window.addEventListener("hashchange",n),window.addEventListener("dce-location",n)),r(),a||{}},this._destroy=()=>{window.removeEventListener("popstate",n),window.removeEventListener("hashchange",n),window.removeEventListener("dce-location",n),delete e.listener}}attributeChangedCallback(e,n,r){e!=="href"&&e!=="method"&&!["method","src","href"].includes(e)||this.sliceInit&&this.sliceInit()}connectedCallback(){this.sliceInit()}disconnectedCallback(){this._destroy()}}window.customElements.define("location-element",w);exports.LocationElement=w;
@@ -0,0 +1,65 @@
1
+ const w = (t, e) => t.getAttribute(e);
2
+ let r;
3
+ function f() {
4
+ r || (r = {}, "back,forward,go,pushState,replaceState".split(",").forEach((t) => {
5
+ r[t] = history[t], history[t] = function(...e) {
6
+ r[t].apply(history, e), window.dispatchEvent(new CustomEvent("dce-location", { detail: { k: t } }));
7
+ };
8
+ }));
9
+ }
10
+ const d = {
11
+ "location.href": (t) => window.location.href = t,
12
+ "location.hash": (t) => window.location.hash = t,
13
+ "location.assign": (t) => window.location.assign(t),
14
+ "location.replace": (t) => window.location.replace(t),
15
+ "history.pushState": (t) => window.history.pushState({}, "", t),
16
+ "history.replaceState": (t) => window.history.replaceState({}, "", t)
17
+ };
18
+ class u extends HTMLElement {
19
+ static observedAttributes = [
20
+ "value",
21
+ "slice",
22
+ "href",
23
+ "type",
24
+ "live",
25
+ "src",
26
+ "method"
27
+ // when defined, changes URL by one of predefined methods.
28
+ ];
29
+ constructor() {
30
+ super();
31
+ const e = {}, o = () => setTimeout(c, 1), c = () => {
32
+ const a = w(this, "href");
33
+ a || f();
34
+ const i = a ? new URL(a, window.location) : window.location, n = {}, l = new URLSearchParams(i.search);
35
+ for (const s of l.keys())
36
+ n[s] = l.getAll(s);
37
+ const h = { params: n };
38
+ for (const s in i)
39
+ typeof i[s] == "string" && (h[s] = i[s]);
40
+ this.value = h, this.dispatchEvent(new Event("change"));
41
+ };
42
+ this.sliceInit = (a) => {
43
+ if (this.hasAttribute("method")) {
44
+ const i = this.getAttribute("method"), n = this.getAttribute("src");
45
+ i && n && (i === "location.hash" ? n !== window.location.hash && d[i]?.(n) : window.location.href !== new URL(n, window.location).href && d[i]?.(n));
46
+ }
47
+ return !e.listener && this.hasAttribute("live") && (e.listener = 1, window.navigation?.addEventListener("navigate", o), window.addEventListener("popstate", o), window.addEventListener("hashchange", o), window.addEventListener("dce-location", o)), c(), a || {};
48
+ }, this._destroy = () => {
49
+ window.removeEventListener("popstate", o), window.removeEventListener("hashchange", o), window.removeEventListener("dce-location", o), delete e.listener;
50
+ };
51
+ }
52
+ attributeChangedCallback(e, o, c) {
53
+ e !== "href" && e !== "method" && !["method", "src", "href"].includes(e) || this.sliceInit && this.sliceInit();
54
+ }
55
+ connectedCallback() {
56
+ this.sliceInit();
57
+ }
58
+ disconnectedCallback() {
59
+ this._destroy();
60
+ }
61
+ }
62
+ window.customElements.define("location-element", u);
63
+ export {
64
+ u as L
65
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epa-wg/custom-element-dist",
3
- "version": "0.0.24",
3
+ "version": "0.0.25",
4
4
  "type": "module",
5
5
  "scripts": {
6
6
  "dev": "vite",
@@ -17,7 +17,7 @@
17
17
  "t": "vitest --no-file-parallelism --watch --browser.headless=false src/stories/attributes.test.stories.ts"
18
18
  },
19
19
  "dependencies": {
20
- "@epa-wg/custom-element": "0.0.24"
20
+ "@epa-wg/custom-element": "0.0.25"
21
21
  },
22
22
  "devDependencies": {
23
23
  "@chromatic-com/storybook": "^1.3.3",
@@ -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>
@@ -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>
@@ -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>