@epa-wg/custom-element 0.0.12 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -78,6 +78,10 @@ generates HTML
78
78
  </pokemon-tile>
79
79
  ```
80
80
 
81
+ [![responsive hex grid demo][hex-grid-image] responsive hex-grid demo][hex-grid-url]
82
+ , look into sources for samples of CSS encapsulation and external template use.
83
+
84
+
81
85
  # Implementation notes
82
86
  ## Life cycle
83
87
  ### `custom-element` declaration
@@ -126,6 +130,44 @@ allows to refer the template withing external document
126
130
 
127
131
 
128
132
  # template syntax
133
+ [Scoped CSS][css-demo-url] live demo
134
+ ## styles encapsulation
135
+ DCE can have the own styles which would be scoped to the instances.
136
+ In order to prevent the style leaking, it has to be defined withing `template` tag:
137
+ ```html
138
+ <custom-element>
139
+ <template>
140
+ <style>
141
+ color:green;
142
+ button{ color: blue; }
143
+ </style>
144
+ <label> green <button>blue</button> </label>
145
+ </template>
146
+ </custom-element>
147
+ ```
148
+ <fieldset>
149
+ <label style="color: green"> green <button style="color: blue">blue</button> </label>
150
+ </fieldset>
151
+
152
+ ### override style for instance
153
+ In same way as in DCE itself:
154
+ ```html
155
+ <custom-element tag="dce-2">
156
+ <template><!-- template needed to avoid styles leaking into global HTML -->
157
+ <style>
158
+ button{ border: 0.2rem dashed blue; }
159
+ </style>
160
+ <button><slot>Blue borders</slot></button>
161
+ </template>
162
+ </custom-element>
163
+ <dce-2>dashed blue</dce-2>
164
+ <dce-2>
165
+ <template> <!-- template needed to avoid styles leaking into global HTML -->
166
+ <style>button{border-color:red;}</style>
167
+ Red border
168
+ </template>
169
+ </dce-2>
170
+ ```
129
171
  ## Attributes
130
172
  curly braces `{}` in attributes implemented as [attribute value template](https://www.w3.org/TR/xslt20/#attribute-value-templates)
131
173
 
@@ -219,15 +261,18 @@ within template
219
261
  [git-url]: https://github.com/EPA-WG/custom-element
220
262
  [git-test-url]: https://github.com/EPA-WG/custom-element-test
221
263
  [demo-url]: https://unpkg.com/@epa-wg/custom-element@0.0/index.html
264
+ [css-demo-url]: https://unpkg.com/@epa-wg/custom-element@0.0/demo/scoped-css.html
265
+ [hex-grid-url]: https://unpkg.com/@epa-wg/custom-element@0.0/demo/hex-grid.html
266
+ [hex-grid-image]: demo/hex-grid-transform.png
222
267
  [local-storage-demo]: https://unpkg.com/@epa-wg/custom-element@0.0/demo/local-storage.html
223
268
  [http-request-demo]: https://unpkg.com/@epa-wg/custom-element@0.0/demo/http-request.html
224
269
  [location-demo]: https://unpkg.com/@epa-wg/custom-element@0.0/demo/location.html
225
270
  [github-image]: https://cdnjs.cloudflare.com/ajax/libs/octicons/8.5.0/svg/mark-github.svg
226
271
  [npm-image]: https://img.shields.io/npm/v/@epa-wg/custom-element.svg
227
272
  [npm-url]: https://npmjs.org/package/@epa-wg/custom-element
228
- [coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.12/coverage/coverage.svg
229
- [coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.12/coverage/lcov-report/index.html
230
- [storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.12/storybook-static/index.html?path=/story/welcome--introduction
273
+ [coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.14/coverage/coverage.svg
274
+ [coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.14/coverage/lcov-report/index.html
275
+ [storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.14/storybook-static/index.html?path=/story/welcome--introduction
231
276
  [sandbox-url]: https://stackblitz.com/github/EPA-WG/custom-element?file=index.html
232
277
  [webcomponents-url]: https://www.webcomponents.org/element/@epa-wg/custom-element
233
278
  [webcomponents-img]: https://img.shields.io/badge/webcomponents.org-published-blue.svg
package/custom-element.js CHANGED
@@ -19,12 +19,12 @@ ASSERT(x)
19
19
  // if(!x)
20
20
  // debugger
21
21
  }
22
- function
22
+ export function
23
23
  xml2dom( xmlString )
24
24
  {
25
25
  return new DOMParser().parseFromString( xmlString, "application/xml" )
26
26
  }
27
- function
27
+ export function
28
28
  xmlString(doc){ return new XMLSerializer().serializeToString( doc ) }
29
29
 
30
30
  function
@@ -95,7 +95,7 @@ tagUid( node )
95
95
  [...m].forEach(t=>
96
96
  { if( t.index > l )
97
97
  tt.push( txt( t.input.substring( l, t.index ) ))
98
- const v = e.ownerDocument.createElement('xsl:value-of');
98
+ const v = node.querySelector('value-of').cloneNode();
99
99
  v.setAttribute('select', t[1] );
100
100
  tt.push(v);
101
101
  l = t.index+t[0].length;
@@ -124,7 +124,7 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
124
124
  return tagUid(templateNode)
125
125
  const sanitizeXsl = xml2dom(`<xsl:stylesheet version="1.0" xmlns:xsl="${ XSL_NS_URL }" xmlns:xhtml="${ HTML_NS_URL }" xmlns:exsl="${EXSL_NS_URL}" exclude-result-prefixes="exsl" >
126
126
  <xsl:output method="xml" />
127
- <xsl:template match="/"><dce-root><xsl:apply-templates select="*"/></dce-root></xsl:template>
127
+ <xsl:template match="/"><dce-root xmlns="${ HTML_NS_URL }"><xsl:apply-templates select="*"/></dce-root></xsl:template>
128
128
  <xsl:template match="*[name()='template']"><xsl:apply-templates mode="sanitize" select="*|text()"/></xsl:template>
129
129
  <xsl:template match="*"><xsl:apply-templates mode="sanitize" select="*|text()"/></xsl:template>
130
130
  <xsl:template match="*[name()='svg']|*[name()='math']"><xsl:apply-templates mode="sanitize" select="."/></xsl:template>
@@ -141,7 +141,12 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
141
141
  {
142
142
  forEach$(n,'script', s=> s.remove() );
143
143
  const e = n.firstElementChild?.content || n.content
144
- , asXmlNode = r => xslHtmlNs(xml2dom( '<xhtml/>' ).importNode(r, true));
144
+ , asXmlNode = r => {
145
+ const d = xml2dom( '<xhtml/>' )
146
+ , n = d.importNode(r, true);
147
+ d.replaceChild(n,d.documentElement);
148
+ return xslHtmlNs(n);
149
+ };
145
150
  if( e )
146
151
  { const t = create('div');
147
152
  [ ...e.childNodes ].map( c => t.append(c.cloneNode(true)) )
@@ -152,10 +157,12 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
152
157
  , xslDom = xml2dom(
153
158
  `<xsl:stylesheet version="1.0"
154
159
  xmlns:xsl="${ XSL_NS_URL }"
160
+ xmlns:xhtml="${ HTML_NS_URL }"
155
161
  xmlns:dce="urn:schemas-epa-wg:dce"
156
162
  xmlns:exsl="http://exslt.org/common"
157
163
  exclude-result-prefixes="exsl"
158
164
  >
165
+ <xsl:template match="ignore"><xsl:value-of select="."/></xsl:template>
159
166
  <xsl:template mode="payload" match="attributes"></xsl:template>
160
167
  <xsl:template match="/">
161
168
  <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
@@ -345,25 +352,54 @@ export function merge( parent, fromArr )
345
352
  parent.append( e )
346
353
  }
347
354
  }
348
-
355
+ export function assureUID(n,attr)
356
+ { if( !n.hasAttribute(attr) )
357
+ n.setAttribute(attr, crypto.randomUUID());
358
+ return n.getAttribute(attr)
359
+ }
349
360
  export class
350
361
  CustomElement extends HTMLElement
351
362
  {
352
363
  async connectedCallback()
353
364
  {
354
365
  const templateRoots = await loadTemplateRoots( attr( this, 'src' ), this )
355
- , templateDocs = templateRoots.map( n => createXsltFromDom( n ) )
366
+ , tag = attr( this, 'tag' )
367
+ , tagName = tag ? tag : 'dce-'+crypto.randomUUID();
368
+
369
+ for( const t of templateRoots )
370
+ forEach$(t.templateNode||t.content||t, 'style',s=>{
371
+ const slot = s.closest('slot');
372
+ const sName = slot ? `slot[name="${slot.name}"]`:'';
373
+ s.innerHTML = `${tagName} ${sName}{${s.innerHTML}}`;
374
+ this.append(s);
375
+ })
376
+ const templateDocs = templateRoots.map( n => createXsltFromDom( n ) )
356
377
  , xp = templateDocs.map( (td, p) =>{ p = new XSLTProcessor(); p.importStylesheet( td ); return p })
357
378
 
358
379
  Object.defineProperty( this, "xsltString", { get: ()=>templateDocs.map( td => xmlString(td) ).join('\n') });
359
380
 
360
- const tag = attr( this, 'tag' );
361
381
  const dce = this;
362
382
  const sliceNames = [...this.templateNode.querySelectorAll('[slice]')].map(e=>attr(e,'slice'));
363
383
  class DceElement extends HTMLElement
364
384
  {
365
385
  connectedCallback()
366
- { const x = xml2dom( '<datadom/>' ).documentElement;
386
+ { if( this.firstElementChild?.tagName === 'TEMPLATE' )
387
+ { const t = this.firstElementChild;
388
+ for( const n of [...t.content.childNodes] )
389
+ if( n.localName === 'style' ){
390
+ const id = assureUID(this,'data-dce-style')
391
+ n.innerHTML= `${tagName}[data-dce-style="${id}"]{${n.innerHTML}}`;
392
+ t.insertAdjacentElement('beforebegin',n);
393
+ }else
394
+ if(n.nodeType===1)
395
+ t.insertAdjacentElement('beforebegin',n);
396
+ else if(n.nodeType===3)
397
+ t.insertAdjacentText('beforebegin',n.data);
398
+
399
+ t.remove();
400
+
401
+ }
402
+ const x = xml2dom( '<datadom/>' ).documentElement;
367
403
  const createXmlNode = ( tag, t = '' ) => ( e =>
368
404
  { if( t )
369
405
  e.append( createText( x, t ))
@@ -407,7 +443,7 @@ CustomElement extends HTMLElement
407
443
  const transform = ()=>
408
444
  {
409
445
  const ff = xp.map( (p,i) =>
410
- { const f = p.transformToFragment(x, document)
446
+ { const f = p.transformToFragment(x.ownerDocument, document)
411
447
  if( !f )
412
448
  console.error( "XSLT transformation error. xsl:\n", xmlString(templateDocs[i]), '\nxml:\n', xmlString(x) );
413
449
  return f
@@ -415,7 +451,7 @@ CustomElement extends HTMLElement
415
451
  ff.map( f =>
416
452
  { if( !f )
417
453
  return;
418
- assureUnique(f)
454
+ assureUnique(f);
419
455
  merge( this, f.childNodes )
420
456
  })
421
457
  const changeCb = el=>this.onSlice({ detail: el[attr(el,'slice-prop') || 'value'], target: el })
@@ -438,11 +474,11 @@ CustomElement extends HTMLElement
438
474
  if(tag)
439
475
  window.customElements.define( tag, DceElement);
440
476
  else
441
- { const t = 'dce-'+crypto.randomUUID()
477
+ { const t = tagName;
442
478
  window.customElements.define( t, DceElement);
443
479
  const el = document.createElement(t);
444
480
  this.getAttributeNames().forEach(a=>el.setAttribute(a,this.getAttribute(a)));
445
- el.append(...this.childNodes)
481
+ el.append(...[...this.childNodes].filter(e=>e.localName!=='style'))
446
482
  this.append(el);
447
483
  }
448
484
  }
@@ -93,7 +93,10 @@
93
93
  <custom-element>
94
94
  <form>
95
95
  <label>
96
- <input type="text" value="Type time update" slice="txt" slice-update="keyup"/>
96
+ <input type="text"
97
+ value="Type time update"
98
+ slice="txt"
99
+ slice-update="keyup"/>
97
100
 
98
101
  <span> Character count:
99
102
  <b> {string-length(//slice/txt)} </b>
@@ -0,0 +1,183 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <script type="module" src="../custom-element.js"></script>
6
+
7
+ <style>
8
+ @import url('https://fonts.googleapis.com/css2?family=Roboto:wght@500&display=swap');
9
+ button{ font-family: 'Roboto', sans-serif; color: darkcyan;}
10
+ body{ background-color: #DDE2F1;}
11
+ </style>
12
+ </head>
13
+ <body>
14
+
15
+ <custom-element tag="hex-grid">
16
+ <template id="hex-grid-template">
17
+ <style>
18
+ section{ filter: drop-shadow(0px 2px 3px rgba(50, 50, 0, 0.5)) }
19
+ :root {
20
+ --hex-grid-size: 8rem;
21
+ }
22
+
23
+ nav {
24
+ --hex-grid-size: 8rem;
25
+ display: flex;
26
+ flex-wrap: wrap;
27
+ flex-direction: row;
28
+ justify-content: left;
29
+ margin-right: calc(var(--hex-grid-size)/2);
30
+ padding-bottom: calc(var(--hex-grid-size,8rem));
31
+ gap: 0.1rem;
32
+ section{
33
+ width: var(--hex-grid-size);
34
+ height: calc(1.53 *var(--hex-grid-size))
35
+ }
36
+ button {
37
+ display: flex;
38
+ flex-direction: column; align-items: center;
39
+ justify-content: center;
40
+ border: none;
41
+ width: var(--hex-grid-size,8rem);
42
+ min-width: var(--hex-grid-size,8rem);
43
+ height: var(--hex-grid-size,8rem);
44
+ padding: calc( var(--hex-grid-size,8rem)/8);
45
+ clip-path: polygon(50% 0, 100% 25%,100% 75%, 50% 100%, 0 75%, 0 25%);
46
+ &:hover,&:focus,&.focus{
47
+ transform: scale3d(0.9,0.9,0.9) ;
48
+ background-color: mediumaquamarine;
49
+ color: white;
50
+ }
51
+
52
+ img{ height: calc( var(--hex-grid-size,8rem)/2);}
53
+ }
54
+
55
+
56
+ section:nth-child(even){
57
+ width:0;
58
+ }
59
+ section:nth-child(even){
60
+ position: relative;
61
+ top: 50%;
62
+ button{
63
+ position: absolute;
64
+
65
+ top: calc(0.77*var(--hex-grid-size));
66
+ right: calc( -1* var(--hex-grid-size,8rem)/2);
67
+ }
68
+ }
69
+ }
70
+ </style>
71
+ <nav>
72
+ <xsl:for-each select="/datadom/payload/xhtml:*">
73
+ <xsl:if test="local-name(.) = 'style'">
74
+ <xsl:copy-of select="." />
75
+ </xsl:if>
76
+ <!-- sanitize blank spans -->
77
+ <xsl:if test="local-name(.) != 'style' and (local-name(.) != 'span' or normalize-space(.) != '')">
78
+ <section>
79
+ <button class="action">
80
+ {@alt}
81
+ <xsl:copy-of select="."/>
82
+ </button>
83
+ </section>
84
+ </xsl:if>
85
+ </xsl:for-each>
86
+ </nav>
87
+ </template>
88
+ </custom-element>
89
+
90
+ <!--<hex-grid>-->
91
+ <!-- <img src="wc-square.svg" alt="web component"/>-->
92
+ <!-- <img src="wc-square.svg" alt="123"/>-->
93
+ <!-- <span>Hey!</span>-->
94
+ <!--</hex-grid>-->
95
+ <hex-grid class="grid2x">
96
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
97
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
98
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
99
+ <img src="https://semantic-ui.com/images/logo.png" alt="Semantic UI" href="https://semantic-ui.com/"/>
100
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
101
+ <img src="https://storage.googleapis.com/cms-storage-bucket/4fd0db61df0567c0f352.png" alt="Flutter" href="https://flutter.dev/"/>
102
+ <img src="https://refine.dev/img/refine_favicon.svg" alt="Refine" href="https://refine.dev/"/>
103
+ <img src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo-shadow.png" alt="Bootstrap" href="https://getbootstrap.com/"/>
104
+ <img src="https://upload.wikimedia.org/wikipedia/commons/9/95/Vue.js_Logo_2.svg" alt="Vue.JS" href="https://vuejs.org/"/>
105
+ <img src="https://lit.dev/images/logo.svg#flame" alt="Lit"/>
106
+ <img src="https://redux.js.org/img/redux.svg" alt="Redux"/>
107
+ <img src="https://upload.wikimedia.org/wikipedia/commons/1/1b/Svelte_Logo.svg" alt="Svelte"/>
108
+ <img src="https://www.solidjs.com/img/logo/without-wordmark/logo.svg" alt="SolidJS"/>
109
+ <img src="https://www.svgrepo.com/show/354113/nextjs-icon.svg" alt="NextJS"/>
110
+ <img src="https://global.discourse-cdn.com/standard17/uploads/threejs/original/2X/b/be2f75f72751c11cbe1593c69a99a52900bf12cb.svg" alt="ThreeJS" href="https://threejs.org/"/>
111
+ <img src="https://www.blazejs.org/logo/icon.png" alt="BlazeJS"/>
112
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/tailwindcss.webp" alt="Tailwind CSS"/>
113
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/flowbite.webp" alt="Flowbite"/>
114
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/chakra-ui.webp" alt="Chakra-UI"/>
115
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/graphql.webp" alt="GraphQL"/>
116
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/cloud-icon.png" alt="Meteor" href="https://www.meteor.com/"/>
117
+ <img src="https://www.svgrepo.com/show/508923/jquery.svg" alt="jQuery"/>
118
+ <img src="https://www.svgrepo.com/show/330899/materialui.svg" alt="Material UI"/>
119
+ <img src="https://mithril.js.org/logo.svg" alt="Mithril.js" href="https://mithril.js.org/"/>
120
+ <img src="https://seeklogo.com/images/M/materialize-logo-0FCAD8A6F8-seeklogo.com.png" alt="Materialize"/>
121
+ <img src="https://seeklogo.com/images/P/preact-logo-64E4BF9ABC-seeklogo.com.png" alt="Preact"/>
122
+ <img src="https://seeklogo.com/images/D/dojo-logo-E24E2CA700-seeklogo.com.png" alt="Dojo"/>
123
+ <img src="https://uxwing.com/wp-content/themes/uxwing/download/brands-and-social-media/backbone-js-icon.svg" alt="Backbone.js"/>
124
+ <img src="https://d3js.org/logo.svg" alt="D3.js"/>
125
+ <img src="https://lodash.com/assets/img/lodash.svg" alt="Lodash"/>
126
+ <img src="https://www.chartjs.org/img/chartjs-logo.svg" alt="Chart.JS" href="https://www.chartjs.org/"/>
127
+ <img src="https://glimmerjs.com/images/favicon.png" alt="Glimmer" href="https://glimmerjs.com/"/>
128
+ <img src="https://sarcadass.github.io/granim.js/favicon.ico" alt="Granim.js" href="https://sarcadass.github.io/granim.js/"/>
129
+ <img src="https://leafletjs.com/docs/images/favicon.ico" alt="leaflet.js" href="https://leafletjs.com/"/>
130
+ <img src="https://animejs.com/documentation/assets/img/favicon.png" alt="Anime.JS"/>
131
+ <img src="https://www.algolia.com/algoliaweb-static-favicons/light-mode/apple-touch-icon.png" alt="Algolia"/>
132
+ <img src="https://momentjs.com/static/img/moment-favicon.png" alt="Moment" href="https://momentjs.com"/>
133
+ <img src="https://omniscientjs.github.io/assets/favicon.ico" alt="Omniscient" href="https://omniscientjs.github.io"/>
134
+ <img src="https://aurelia.io/styles/images/aurelia-icon.svg" alt="Aurelia" href="https://aurelia.io"/>
135
+ <img src="https://emberjs.com/favicons/icon.svg" alt="EmberJS" href="https://emberjs.com"/>
136
+ <img src="https://ionicframework.com/apple-icon-57x57.png" alt="Ionic" href="https://ionicframework.com/"/>
137
+ <img src="https://webix.com/assets/favicons/favicon-96x96.png" alt="Webix" href="https://webix.com/"/>
138
+ <img src="https://images.ctfassets.net/vkdbses00qqt/3Id5VwofmvaFbjuSumaOmM/592c2d2e523187bd054a16b358d5a7ec/framework.svg" alt="Gatsby" href="https://www.gatsbyjs.com/"/>
139
+ </hex-grid>
140
+
141
+ <custom-element tag="hex-row">
142
+ <template>
143
+ <style>
144
+ hex-grid {
145
+ nav {
146
+ --hex-grid-size:6rem;
147
+ display: inline-flex;
148
+ padding-bottom: 0;
149
+ margin-right: 0;
150
+ section{ margin-right: 0.2rem; height: var(--hex-grid-size);}
151
+ button:has([selected]){ background-color: #2d4554; color: burlywood; }
152
+ }
153
+ }
154
+ </style>
155
+ <xsl:for-each select="/datadom/payload/xhtml:*">
156
+ <!-- sanitize blank spans -->
157
+ <xsl:if test="local-name(.) != 'span' or normalize-space(.) != ''">
158
+ <hex-grid>
159
+ <xsl:copy-of select="."/>
160
+ </hex-grid>
161
+ </xsl:if>
162
+ </xsl:for-each>
163
+ </template>
164
+ </custom-element>
165
+ <hex-row class="grid2x">
166
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/chakra-ui.webp" alt="Chakra-UI"/>
167
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/integrations/graphql.webp" alt="GraphQL"/>
168
+ <img src="https://dmtgy0px4zdqn.cloudfront.net/images/cloud-icon.png" alt="Meteor"/>
169
+ <img src="https://www.svgrepo.com/show/508923/jquery.svg" alt="jQuery" selected/>
170
+ <img src="https://www.svgrepo.com/show/330899/materialui.svg" alt="Material UI"/>
171
+ <img src="https://mithril.js.org/logo.svg" alt="Mithril.js"/>
172
+ <img src="https://uxwing.com/wp-content/themes/uxwing/download/brands-and-social-media/backbone-js-icon.svg" alt="Backbone.js" href="https://backbonejs.org/"/>
173
+ <img src="https://ionicframework.com/apple-icon-57x57.png" alt="Ionic" href="https://ionicframework.com/"/>
174
+ </hex-row>
175
+
176
+
177
+
178
+ <style>
179
+ .grid2x{--hex-grid-size:16rem; margin-top: 8rem; }
180
+ </style>
181
+
182
+ </body>
183
+ </html>
Binary file
@@ -0,0 +1,66 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <link rel="icon" href="./wc-square.svg"/>
6
+ <script type="module" src="../custom-element.js"></script>
7
+ <style>
8
+ html
9
+ { font-family: -apple-system,BlinkMacSystemFont,Segoe UI,Roboto,Oxygen,Ubuntu,Cantarell,Fira Sans,Droid Sans,Helvetica Neue,sans-serif;
10
+ font-weight: 400; font-style: normal; -webkit-font-smoothing: antialiased;
11
+ }
12
+ #grid1 nav {
13
+ transform: perspective(15cm) rotateX(5deg) rotateY(40deg) translateX(20rem) translateY(6rem);
14
+ }
15
+ #grid2 nav {
16
+ transform: perspective(15cm) rotateX(5deg) rotateY(50deg) translateX(20rem) translateY(10rem);
17
+ }
18
+ </style>
19
+ </head>
20
+ <body>
21
+
22
+ <nav>
23
+ <a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
24
+ <h3>Example of DCE HTML as a library.</h3>
25
+ </nav>
26
+ <p>The template and its own responsive layout behavior demo resides in
27
+ <a href="hex-grid-dce.html">hex-grid-dce.html</a> file.</p>
28
+ <custom-element src="hex-grid-dce.html#hex-grid-template" tag="hex-grid" >
29
+ <template><i>loading hex-grid template from HTML lib file ...</i></template>
30
+ </custom-element>
31
+
32
+ <hex-grid id="grid1">
33
+ <template>
34
+ <style>
35
+ nav{
36
+ --hex-grid-size:5rem;
37
+ button dce-text{ position: absolute; top: 3rem; text-shadow: 0 0 3px white, 0 0 6px blue; }
38
+ }
39
+ </style>
40
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
41
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
42
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
43
+ <img src="https://semantic-ui.com/images/logo.png" alt="Semantic UI" href="https://semantic-ui.com/"/>
44
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
45
+ </template>
46
+ </hex-grid>
47
+ <hex-grid id="grid2">
48
+ <template>
49
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
50
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
51
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
52
+ <img src="https://semantic-ui.com/images/logo.png" alt="Semantic UI" href="https://semantic-ui.com/"/>
53
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
54
+ <img src="https://storage.googleapis.com/cms-storage-bucket/4fd0db61df0567c0f352.png" alt="Flutter" href="https://flutter.dev/"/>
55
+ <img src="https://refine.dev/img/refine_favicon.svg" alt="Refine" href="https://refine.dev/"/>
56
+ <img src="https://getbootstrap.com/docs/5.3/assets/brand/bootstrap-logo-shadow.png" alt="Bootstrap" href="https://getbootstrap.com/"/>
57
+ <img src="https://upload.wikimedia.org/wikipedia/commons/9/95/Vue.js_Logo_2.svg" alt="Vue.JS" href="https://vuejs.org/"/>
58
+ <img src="https://lit.dev/images/logo.svg#flame" alt="Lit"/>
59
+ <img src="https://redux.js.org/img/redux.svg" alt="Redux"/>
60
+ <img src="https://upload.wikimedia.org/wikipedia/commons/1/1b/Svelte_Logo.svg" alt="Svelte"/>
61
+ <img src="https://www.solidjs.com/img/logo/without-wordmark/logo.svg" alt="SolidJS"/>
62
+ <img src="https://www.svgrepo.com/show/354113/nextjs-icon.svg" alt="NextJS"/>
63
+ </template>
64
+ </hex-grid>
65
+ </body>
66
+ </html>
@@ -82,18 +82,19 @@
82
82
  </table>
83
83
  </fieldset>
84
84
  <script type="module">
85
+ import { localStorageSetItem } from '../local-storage.js';
85
86
  import $ from 'https://unpkg.com/css-chain@1/CssChain.js';
86
87
 
87
88
  const basket = {cherries: 12, lemons:1 };
88
- localStorage.setItem( 'basket', JSON.stringify(basket) );
89
+ localStorageSetItem( 'basket', JSON.stringify(basket) );
89
90
 
90
91
  $('button[name]')
91
92
  .forEach( b=> localStorage.setItem( b.name, b.value ) )
92
93
  .addEventListener( 'click', e =>
93
94
  { const k = e.target.name;
94
95
  basket[k] || (basket[k] = 1);
95
- localStorage.setItem( k, basket[k] = 1+1*localStorage[k] )
96
- localStorage.setItem( 'basket', JSON.stringify(basket) );
96
+ localStorageSetItem( k, basket[k] = 1+1*localStorage[k] )
97
+ localStorageSetItem( 'basket', JSON.stringify(basket) );
97
98
  renderStorage();
98
99
  } );
99
100
 
package/demo/s.xml CHANGED
@@ -1 +1 @@
1
- <datadom><payload><i xmlns="http://www.w3.org/1999/xhtml" slot="">loading from HTML file ...</i></payload><attributes><src>/src/demo/html-template.html</src><tag/><data-smile>👼</data-smile><attr-1>a1</attr-1><attr-2>a2</attr-2></attributes><dataset><smile>👼</smile></dataset><slice/></datadom>
1
+ <datadom><payload><i xmlns="http://www.w3.org/1999/xhtml" slot="">🍋</i></payload><attributes/><dataset/><slice/></datadom>
package/demo/s.xslt CHANGED
@@ -1,139 +1,28 @@
1
- <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dce="urn:schemas-epa-wg:dce"
2
- xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="exsl">
1
+ <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:dce="urn:schemas-epa-wg:dce"
2
+ xmlns:exsl="http://exslt.org/common" exclude-result-prefixes="exsl">
3
+ <xsl:template match="ignore">
4
+ <xsl:value-of select="."/>
5
+ </xsl:template>
3
6
  <xsl:template mode="payload" match="attributes">
4
- <dce-root xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1">
5
- <head data-dce-id="2">
6
-
7
- <title data-dce-id="4">template based on HTML file</title>
8
- </head>
9
- <body data-dce-id="5">
10
- <b id="wave" data-dce-id="6">👋</b>
11
- <b id="ok" data-dce-id="7">👌</b>
12
- <svg xmlns="http://www.w3.org/2000/svg" id="dwc-logo" viewBox="0 0 216 209.18" data-dce-id="8">
13
- <defs data-dce-id="9">
14
- <style data-dce-id="10">
15
- .cls-1{fill:#c2e6f1;}.cls-2{fill:#dcf1f7;}.cls-3{fill:#2d4554;}.cls-4{fill:#60cae5;}
16
- </style>
17
- </defs>
18
- <polygon class="cls-3"
19
- points="0 82.47 0 126.71 34.84 146.83 34.84 187.06 73.16 209.18 108 189.07 142.84 209.18 181.16 187.06 181.16 146.83 216 126.71 216 82.47 181.16 62.35 181.16 22.12 142.84 0 108 20.12 73.16 0 34.84 22.12 34.84 62.35 0 82.47"
20
- data-dce-id="11"/>
21
- <path class="cls-2"
22
- d="m114.33,56.69l20.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"
23
- data-dce-id="12"/>
24
- <path class="cls-2"
25
- d="m98.19,62.71h0s-20.64-11.92-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84s0,0,0,0c0,5.13,1.89,8.4,6.33,10.97l20.65,11.92c.47.27.92,0,.92-.54v-23.84c0-5.13-1.89-8.4-6.33-10.97Z"
26
- data-dce-id="13"/>
27
- <path class="cls-1"
28
- d="m48.12,66.01l20.65,11.92c.47.27.92,0,.92-.54v-23.84c0-5.13-1.89-8.4-6.33-10.97h0s-20.64-11.92-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84s0,0,0,0c0,5.13,1.89,8.4,6.33,10.97Z"
29
- data-dce-id="14"/>
30
- <path class="cls-2"
31
- d="m46.18,24.66l20.64,11.92c4.44,2.57,8.22,2.57,12.67,0h0s20.64-11.92,20.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.06Z"
32
- data-dce-id="15"/>
33
- <path class="cls-2"
34
- d="m115.87,24.66l20.64,11.92c4.44,2.57,8.22,2.57,12.67,0h0s20.64-11.92,20.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.06Z"
35
- data-dce-id="16"/>
36
- <path class="cls-2"
37
- d="m152.65,42.59c-4.44,2.56-6.33,5.84-6.33,10.97v23.84c0,.54.45.8.92.54l20.65-11.92c4.44-2.57,6.33-5.84,6.33-10.97h0v-23.84c0-.54-.45-.8-.92-.53l-20.64,11.92h0Z"
38
- data-dce-id="17"/>
39
- <path class="cls-2"
40
- d="m77.55,158.4l20.65-11.92h0c4.44-2.57,6.33-5.84,6.33-10.97v-23.84c0-.54-.45-.8-.92-.53l-20.64,11.92c-4.44,2.57-6.33,5.84-6.33,10.97h0s0,23.84,0,23.84c0,.54.45.8.92.54Z"
41
- data-dce-id="18"/>
42
- <path class="cls-4"
43
- d="m146.31,134.03v23.84c0,.54.45.8.92.54l20.65-11.92c4.44-2.57,6.33-5.84,6.33-10.97h0s0-23.84,0-23.84c0-.54-.45-.8-.92-.53l-20.64,11.92h0c-4.44,2.57-6.33,5.84-6.33,10.97Z"
44
- data-dce-id="19"/>
45
- <path class="cls-4"
46
- d="m63.35,123.06h0s-20.64-11.92-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84s0,0,0,0c0,5.13,1.89,8.4,6.33,10.97l20.65,11.92c.47.27.92,0,.92-.54v-23.84c0-5.13-1.89-8.4-6.33-10.97Z"
47
- data-dce-id="20"/>
48
- <path class="cls-4"
49
- d="m103.61,151.37l-20.64,11.92c-4.44,2.57-6.33,5.84-6.33,10.97h0s0,23.84,0,23.84c0,.54.45.8.92.54l20.65-11.92h0c4.44-2.57,6.33-5.84,6.33-10.97v-23.84c0-.54-.45-.8-.92-.53Z"
50
- data-dce-id="21"/>
51
- <path class="cls-4"
52
- d="m63.35,163.29h0s-20.64-11.92-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84s0,0,0,0c0,5.13,1.89,8.4,6.33,10.97l20.65,11.92c.47.27.92,0,.92-.54v-23.84c0-5.13-1.89-8.4-6.33-10.97Z"
53
- data-dce-id="22"/>
54
- <path class="cls-4"
55
- d="m28.51,102.94h0s-20.64-11.92-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84s0,0,0,0c0,5.13,1.89,8.4,6.33,10.97l20.65,11.92c.47.27.92,0,.92-.54v-23.84c0-5.13-1.89-8.4-6.33-10.97Z"
56
- data-dce-id="23"/>
57
- <path class="cls-4"
58
- d="m133.04,163.29l-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84c0,5.13,1.89,8.4,6.33,10.97h0s20.65,11.92,20.65,11.92c.47.27.92,0,.92-.54v-23.84s0,0,0,0c0-5.13-1.89-8.4-6.33-10.97Z"
59
- data-dce-id="24"/>
60
- <path class="cls-4"
61
- d="m173.29,151.37l-20.64,11.92h0c-4.44,2.57-6.33,5.84-6.33,10.97v23.84c0,.54.45.8.92.54l20.65-11.92c4.44-2.57,6.33-5.84,6.33-10.97h0s0-23.84,0-23.84c0-.54-.45-.8-.92-.53Z"
62
- data-dce-id="25"/>
63
- <path class="cls-4"
64
- d="m209.06,91.55c0-.54-.45-.8-.92-.53l-20.64,11.92h0c-4.44,2.57-6.33,5.84-6.33,10.97v23.84c0,.54.45.8.92.54l20.65-11.92c4.44-2.57,6.33-5.84,6.33-10.97h0v-23.84Z"
65
- data-dce-id="26"/>
66
- <path class="cls-2"
67
- d="m149.18,117.04l20.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"
68
- data-dce-id="27"/>
69
- <path class="cls-1"
70
- d="m112.39,98.05l20.65-11.92c4.44-2.57,6.33-5.84,6.33-10.97h0v-23.84c0-.54-.45-.8-.92-.53l-20.64,11.92h0c-4.44,2.57-6.33,5.84-6.33,10.97v23.84c0,.54.45.8.92.54Z"
71
- data-dce-id="28"/>
72
- <path class="cls-1"
73
- d="m100.13,105.12c.47-.27.47-.79,0-1.06l-20.65-11.92c-4.44-2.57-8.22-2.57-12.67,0h0s-20.65,11.92-20.65,11.92c-.47.27-.47.79,0,1.06l20.64,11.92h0c4.44,2.57,8.22,2.57,12.67,0l20.64-11.92Z"
74
- data-dce-id="29"/>
75
- <path class="cls-2"
76
- d="m65.29,85.01c.47-.27.47-.79,0-1.06l-20.65-11.92c-4.44-2.57-8.22-2.57-12.67,0h0s-20.65,11.92-20.65,11.92c-.47.27-.47.79,0,1.06l20.64,11.92h0c4.44,2.57,8.22,2.57,12.67,0l20.64-11.92Z"
77
- data-dce-id="30"/>
78
- <path class="cls-1"
79
- d="m133.04,123.06l-20.64-11.92c-.47-.27-.92-.01-.92.53v23.84c0,5.13,1.89,8.4,6.33,10.97h0s20.65,11.92,20.65,11.92c.47.27.92,0,.92-.54v-23.84s0,0,0,0c0-5.13-1.89-8.4-6.33-10.97Z"
80
- data-dce-id="31"/>
81
- <path class="cls-1"
82
- 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"
83
- data-dce-id="32"/>
84
- </svg>
85
- <math xmlns="http://www.w3.org/1998/Math/MathML" id="sophomores-dream" display="block" data-dce-id="33">
86
- <mrow data-dce-id="34">
87
- <msubsup data-dce-id="35">
88
- <mo data-dce-id="36">∫</mo>
89
- <mn data-dce-id="37">0</mn>
90
- <mn data-dce-id="38">1</mn>
91
- </msubsup>
92
- <msup data-dce-id="39">
93
- <mi data-dce-id="40">x</mi>
94
- <mi data-dce-id="41">x</mi>
95
- </msup>
96
- <mo rspace="0.22em" data-dce-id="42">⁢</mo>
97
- <mo rspace="0" data-dce-id="43">ⅆ</mo>
98
- <mi data-dce-id="44">x</mi>
99
- <mo data-dce-id="45">=</mo>
100
- <munderover data-dce-id="46">
101
- <mo data-dce-id="47">∑</mo>
102
- <mrow data-dce-id="48">
103
- <mi data-dce-id="49">n</mi>
104
- <mo data-dce-id="50">=</mo>
105
- <mn data-dce-id="51">1</mn>
106
- </mrow>
107
- <mn data-dce-id="52">∞</mn>
108
- </munderover>
109
- <msup data-dce-id="53">
110
- <mrow data-dce-id="54">
111
- <mo data-dce-id="55">(</mo>
112
- <mrow data-dce-id="56">
113
- <mo form="prefix" data-dce-id="57">−</mo>
114
- <mn data-dce-id="58">1</mn>
115
- </mrow>
116
- <mo data-dce-id="59">)</mo>
117
- </mrow>
118
- <mrow data-dce-id="60">
119
- <mi data-dce-id="61">n</mi>
120
- <mo data-dce-id="62">+</mo>
121
- <mn data-dce-id="63">1</mn>
122
- </mrow>
123
- </msup>
124
- <mo data-dce-id="64">⁢</mo>
125
- <msup data-dce-id="65">
126
- <mi data-dce-id="66">n</mi>
127
- <mrow data-dce-id="67">
128
- <mo form="prefix" data-dce-id="68">−</mo>
129
- <mi data-dce-id="69">n</mi>
130
- </mrow>
131
- </msup>
132
- </mrow>
133
- </math>
134
- <script type="module" src="/__web-dev-server__web-socket.js?wds-import-map=0" data-dce-id="70"/>
135
- </body>
136
- </dce-root>
7
+ <nav data-dce-id="1">
8
+ <xsl:for-each select="/datadom/payload/xhtml:*">
9
+ <xsl:if test="local-name(.) = 'style'">
10
+ <xsl:copy-of select=".">
11
+ </xsl:copy-of>
12
+ </xsl:if>
13
+ <xsl:if test="local-name(.) != 'style' and (local-name(.) != 'span' or normalize-space(.) != '')">
14
+ <section data-dce-id="2">
15
+ <button class="action" data-dce-id="3">
16
+ <dce-text data-dce-id="4">
17
+ <xsl:value-of select="@alt"/>
18
+ </dce-text>
19
+ <xsl:copy-of select=".">
20
+ </xsl:copy-of>
21
+ </button>
22
+ </section>
23
+ </xsl:if>
24
+ </xsl:for-each>
25
+ </nav>
137
26
  </xsl:template>
138
27
  <xsl:template match="/">
139
28
  <xsl:apply-templates mode="payload" select="/datadom/attributes"/>
@@ -0,0 +1,170 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>CSS scoping - Declarative Custom Element implementation demo</title>
6
+ <link rel="icon" href="./wc-square.svg"/>
7
+
8
+ <script type="module" src="../http-request.js"></script>
9
+ <script type="module" src="../input-text.js"></script>
10
+ <script type="module" src="../custom-element.js"></script>
11
+ <style>
12
+ @import "./demo.css";
13
+
14
+ button {
15
+ display: inline-flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ flex: auto;
19
+ box-shadow: inset silver 0 0 1rem;
20
+ min-width: 12rem;
21
+ padding: 1rem;
22
+ color: coral;
23
+ text-shadow: 1px 1px silver;
24
+ font-weight: bolder;
25
+ }
26
+
27
+ caption {
28
+ padding: 1rem;
29
+ font-weight: bolder;
30
+ font-family: sans-serif;
31
+ }
32
+
33
+ code {
34
+ text-align: right;
35
+ min-width: 3rem;
36
+ }
37
+
38
+ </style>
39
+ </head>
40
+ <body>
41
+
42
+ <nav>
43
+ <a href="../index.html"><h3><code>custom-element</code> demo</h3></a>
44
+ <h3>DOM merge. DCE dynamic update with focus preservation.</h3>
45
+ </nav>
46
+
47
+ <html-demo-element legend="1. STYLE tag css rules are scoped within element "
48
+ description="Green button borders should not be applied to external button ">
49
+ <template>
50
+ <custom-element>
51
+ <template><!-- template needed to avoid styles leaking into global HTML -->
52
+ <style>
53
+ button{ border: 0.2rem dashed green; }
54
+ </style>
55
+ <button>Green dashed border</button>
56
+ </template>
57
+ </custom-element>
58
+ <button>Default border</button>
59
+ </template>
60
+ </html-demo-element>
61
+
62
+ <html-demo-element legend="2. DCE with tag "
63
+ description="Blue borders only within 2 DCE instances">
64
+ <template>
65
+ <custom-element tag="dce-1">
66
+ <template><!-- template needed to avoid styles leaking into global HTML -->
67
+ <style>
68
+ button{ border: 0.2rem dotted blue; }
69
+ </style>
70
+ <button><slot>Blue borders</slot></button>
71
+ </template>
72
+ </custom-element>
73
+ <button>Default border</button>
74
+ <dce-1>1st</dce-1>
75
+ <dce-1>2nd</dce-1>
76
+ </template>
77
+ </html-demo-element>
78
+
79
+ <html-demo-element legend="3. Override style in DCE payload "
80
+ description="Red borders only for last DCE instance">
81
+ <template>
82
+ <custom-element tag="dce-2">
83
+ <template><!-- template needed to avoid styles leaking into global HTML -->
84
+ <style>
85
+ button{ border: 0.2rem dashed blue; }
86
+ </style>
87
+ <button><slot>Blue borders</slot></button>
88
+ </template>
89
+ </custom-element>
90
+ <button>Default border</button>
91
+ <dce-2>1st</dce-2>
92
+ <dce-2>
93
+ <template> <!-- template needed to avoid styles leaking into global HTML -->
94
+ <style>button{border-color:red;}</style>
95
+ Red border
96
+ <b>2</b>
97
+ 3
98
+ <b>4</b>
99
+ </template>
100
+ </dce-2>
101
+ </template>
102
+ </html-demo-element>
103
+
104
+
105
+ <html-demo-element legend="4. simple internal override "
106
+ description="green label with blue text button ">
107
+ <template>
108
+ <custom-element>
109
+ <template>
110
+ <style>
111
+ color:green;
112
+ b{ color: blue;}
113
+ input:checked+b{ color: darkblue; text-shadow: 0 0 4px springgreen;}
114
+ </style>
115
+ <label>
116
+ green
117
+ <input type="checkbox" value="Glowing Blue" checked/><b>blue</b>
118
+ </label>
119
+ </template>
120
+ </custom-element>
121
+
122
+ </template>
123
+ </html-demo-element>
124
+
125
+
126
+ <html-demo-element legend="5. External template( inline lib )"
127
+ description="green label with blue text button ">
128
+ <template>
129
+ <template id="template-5">
130
+ <style>
131
+ color:green;
132
+ i{ color: blue;}
133
+ </style>
134
+ <p>
135
+ green
136
+ <i>blue</i>
137
+ </p>
138
+ </template>
139
+ <custom-element src="#template-5"></custom-element>
140
+
141
+ </template>
142
+ </html-demo-element>
143
+
144
+ <html-demo-element legend="6. External template( ext lib )"
145
+ description="Grid with 8 hex shaped buttons with text and icon ">
146
+ <template>
147
+ <a href="hex-grid-dce.html">hex-grid-dce.html</a>
148
+ <custom-element src="hex-grid-dce.html#hex-grid-template">
149
+ <template>
150
+ <style>nav{--hex-grid-size: 5rem; margin-left:2rem; }</style>
151
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
152
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
153
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
154
+ <img src="https://www.svgrepo.com/show/508923/jquery.svg" alt="jQuery"/>
155
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
156
+ <img src="https://storage.googleapis.com/cms-storage-bucket/4fd0db61df0567c0f352.png" alt="Flutter" href="https://flutter.dev/"/>
157
+ <img src="https://lit.dev/images/logo.svg#flame" alt="Lit"/>
158
+ <img src="https://redux.js.org/img/redux.svg" alt="Redux"/>
159
+ </template>
160
+ </custom-element>
161
+
162
+ </template>
163
+ </html-demo-element>
164
+
165
+
166
+
167
+ <script type="module" src="https://unpkg.com/html-demo-element@1/html-demo-element.js"></script>
168
+
169
+ </body>
170
+ </html>
package/demo/ss.html ADDED
@@ -0,0 +1,32 @@
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>CSS scoping - Declarative Custom Element implementation demo</title>
6
+ <link rel="icon" href="./wc-square.svg"/>
7
+
8
+ <script type="module" src="../http-request.js"></script>
9
+ <script type="module" src="../input-text.js"></script>
10
+ <script type="module" src="../custom-element.js"></script>
11
+ <style>
12
+ @import "./demo.css";
13
+ </style>
14
+ </head>
15
+ <body>
16
+
17
+
18
+ <custom-element src="hex-grid-dce.html#hex-grid-template">
19
+ <template>
20
+ <style>nav{--hex-grid-size: 4rem;}</style>
21
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
22
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
23
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
24
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
25
+ <img src="https://storage.googleapis.com/cms-storage-bucket/4fd0db61df0567c0f352.png" alt="Flutter" href="https://flutter.dev/"/>
26
+ <img src="https://lit.dev/images/logo.svg#flame" alt="Lit"/>
27
+ <img src="https://redux.js.org/img/redux.svg" alt="Redux"/>
28
+ </template>
29
+ </custom-element>
30
+
31
+ </body>
32
+ </html>
package/demo/z.html CHANGED
@@ -1,42 +1,60 @@
1
- <?xml version="1.0" encoding="UTF-8"?>
2
- <dce-root data-dce-id="1" xmlns:dce="urn:schemas-epa-wg:dce" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
- <table data-dce-id="2">
4
- <tr data-dce-id="3">
5
- <xhtml:th data-dce-id="4">href</xhtml:th>
6
- <xhtml:td data-dce-id="5">http://localhost:63342/custom-element/demo/a.html?_ijt=qca6trk5kne6eo4s4tomq4egmm&amp;_ij_reload=RELOAD_ON_SAVE</xhtml:td>
7
- </tr>
8
- <tr data-dce-id="3">
9
- <xhtml:th data-dce-id="4">origin</xhtml:th>
10
- <xhtml:td data-dce-id="5">http://localhost:63342</xhtml:td>
11
- </tr>
12
- <tr data-dce-id="3">
13
- <xhtml:th data-dce-id="4">protocol</xhtml:th>
14
- <xhtml:td data-dce-id="5">http:</xhtml:td>
15
- </tr>
16
- <tr data-dce-id="3">
17
- <xhtml:th data-dce-id="4">host</xhtml:th>
18
- <xhtml:td data-dce-id="5">localhost:63342</xhtml:td>
19
- </tr>
20
- <tr data-dce-id="3">
21
- <xhtml:th data-dce-id="4">hostname</xhtml:th>
22
- <xhtml:td data-dce-id="5">localhost</xhtml:td>
23
- </tr>
24
- <tr data-dce-id="3">
25
- <xhtml:th data-dce-id="4">port</xhtml:th>
26
- <xhtml:td data-dce-id="5">63342</xhtml:td>
27
- </tr>
28
- <tr data-dce-id="3">
29
- <xhtml:th data-dce-id="4">pathname</xhtml:th>
30
- <xhtml:td data-dce-id="5">/custom-element/demo/a.html</xhtml:td>
31
- </tr>
32
- <tr data-dce-id="3">
33
- <xhtml:th data-dce-id="4">search</xhtml:th>
34
- <xhtml:td data-dce-id="5">?_ijt=qca6trk5kne6eo4s4tomq4egmm&amp;_ij_reload=RELOAD_ON_SAVE</xhtml:td>
35
- </tr>
36
- <tr data-dce-id="3">
37
- <xhtml:th data-dce-id="4">hash</xhtml:th>
38
- <xhtml:td data-dce-id="5"/>
39
- </tr>
40
- </table>
41
- <location-element slice="window-url" data-dce-id="6"/>
42
- </dce-root>
1
+ <!DOCTYPE html>
2
+ <html lang="en" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml">
3
+ <head>
4
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8"/>
5
+ <title>CSS scoping - Declarative Custom Element implementation demo</title>
6
+ <link rel="icon" href="./wc-square.svg"/>
7
+
8
+ <script type="module" src="../http-request.js"></script>
9
+ <script type="module" src="../input-text.js"></script>
10
+ <script type="module" src="../custom-element.js"></script>
11
+ <style>
12
+ @import "./demo.css";
13
+
14
+ button {
15
+ display: inline-flex;
16
+ flex-direction: column;
17
+ align-items: center;
18
+ flex: auto;
19
+ box-shadow: inset silver 0 0 1rem;
20
+ min-width: 12rem;
21
+ padding: 1rem;
22
+ color: coral;
23
+ text-shadow: 1px 1px silver;
24
+ font-weight: bolder;
25
+ }
26
+
27
+ caption {
28
+ padding: 1rem;
29
+ font-weight: bolder;
30
+ font-family: sans-serif;
31
+ }
32
+
33
+ code {
34
+ text-align: right;
35
+ min-width: 3rem;
36
+ }
37
+
38
+ </style>
39
+ </head>
40
+ <body>
41
+ <custom-element src="hex-grid-dce.html#hex-grid-template">
42
+ <template>
43
+ <style>nav{--hex-grid-size: 5rem; margin-left:2rem; }</style>
44
+ <img src="wc-square.svg" alt="DCE" href="https://github.com/EPA-WG/custom-element"/>
45
+ <img src="https://upload.wikimedia.org/wikipedia/commons/a/a7/React-icon.svg" alt="React" href="https://react.dev/"/>
46
+ <img src="https://angularjs.org/favicon.ico" alt="Angular" href="https://angularjs.org/"/>
47
+ <img src="https://www.svgrepo.com/show/508923/jquery.svg" alt="jQuery"/>
48
+ <img src="https://open-wc.org/35ded306.svg" alt="Open WC" href="https://open-wc.org/"/>
49
+ <img src="https://storage.googleapis.com/cms-storage-bucket/4fd0db61df0567c0f352.png" alt="Flutter" href="https://flutter.dev/"/>
50
+ <img src="https://lit.dev/images/logo.svg#flame" alt="Lit"/>
51
+ <img src="https://redux.js.org/img/redux.svg" alt="Redux"/>
52
+ </template>
53
+ </custom-element>
54
+
55
+
56
+
57
+
58
+
59
+ </body>
60
+ </html>
package/index.html CHANGED
@@ -29,7 +29,9 @@
29
29
  <a href="./demo/local-storage.html" >local-storage </a> |
30
30
  <a href="./demo/http-request.html" >http-request </a> |
31
31
  <a href="./demo/location-element.html" >location-element </a> |
32
- <a href="./demo/external-template.html" >external template </a> |
32
+ <a href="./demo/external-template.html" >external template </a> <br/>
33
+ <a href="./demo/hex-grid.html" >hex grid lib </a> |
34
+ <a href="./demo/scoped-css.html" >scoped CSS </a> |
33
35
  <a href="./demo/dom-merge.html" >DOM merge on dynamic update </a>
34
36
  </section>
35
37
  </nav>
package/local-storage.js CHANGED
@@ -9,22 +9,14 @@ const string2value = (type, v) =>
9
9
  return type==='number'? el.valueAsNumber : 'date|time|dateTimeLocal'.includes(type)? el.valueAsDate: el.value;
10
10
  };
11
11
 
12
- let originalSetItem;
13
-
14
- function ensureTrackLocalStorage()
15
- { if( originalSetItem )
16
- return;
17
- originalSetItem = localStorage.setItem;
18
- localStorage.setItem = function( key, value, ...rest )
19
- { originalSetItem.apply(this, [ key, value, ...rest ]);
20
- window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
21
- };
12
+ export function localStorageSetItem(key, value)
13
+ { localStorage.setItem(key, value);
14
+ window.dispatchEvent( new CustomEvent('local-storage',{detail:{key,value}}) );
22
15
  }
23
-
24
16
  export class LocalStorageElement extends HTMLElement
25
17
  {
26
18
  static get observedAttributes() {
27
- return [ 'value' // populated from localStorage, if defined initially, sets the valiue in storage
19
+ return [ 'value' // populated from localStorage, if defined initially, sets the value in storage
28
20
  , 'slice'
29
21
  , 'key'
30
22
  , 'type' // `text|json`, defaults to text, other types are compatible with INPUT field
@@ -41,14 +33,13 @@ export class LocalStorageElement extends HTMLElement
41
33
  }
42
34
  // todo apply type
43
35
  if( this.hasAttribute('value'))
44
- localStorage.setItem( attr( this, 'key' ) )
36
+ localStorageSetItem( attr( this, 'key' ) )
45
37
  else
46
38
  fromStorage()
47
39
 
48
40
  if( this.hasAttribute('live') )
49
41
  { const listener = (e => e.detail.key === attr( 'key' ) && fromStorage());
50
42
  window.addEventListener( 'local-storage', listener );
51
- ensureTrackLocalStorage();
52
43
  this._destroy = ()=> window.removeEventListener('local-storage', listener );
53
44
  }
54
45
  }
@@ -3,7 +3,7 @@ const attr = (el, attr)=> el.getAttribute(attr);
3
3
  export class LocationElement extends HTMLElement
4
4
  {
5
5
  static get observedAttributes()
6
- { return [ 'value' // populated from localStorage, if defined initially, sets the valiue in storage
6
+ { return [ 'value' // populated from localStorage, if defined initially, sets the value in storage
7
7
  , 'slice'
8
8
  , 'live' // monitors location change
9
9
  , 'src' // URL to be parsed, defaults to `window.location`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epa-wg/custom-element",
3
- "version": "0.0.12",
3
+ "version": "0.0.14",
4
4
  "description": "Declarative Custom Element as W3C proposal PoC with native(XSLT) based templating",
5
5
  "browser": "custom-element.js",
6
6
  "module": "custom-element.js",