@epa-wg/custom-element 0.0.17 → 0.0.18
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/.idea/codeStyles/codeStyleConfig.xml +5 -0
- package/.vscode/settings.json +25 -0
- package/README.md +21 -15
- package/bin/xslDtd2Ide.mjs +160 -0
- package/custom-element.d.ts +1 -1
- package/custom-element.js +35 -4
- package/demo/a.html +8 -2
- package/demo/hex-grid-dce.html +13 -13
- package/demo/http-request.html +13 -13
- package/demo/local-storage.html +2 -2
- package/demo/location-element.html +12 -12
- package/demo/parameters.html +3 -3
- package/demo/s.xslt +4 -6
- package/demo/z.html +3 -5
- package/ide/IDE.md +31 -0
- package/ide/customData-dce.json +89 -0
- package/ide/customData-xsl.json +1018 -0
- package/{web-types.json → ide/web-types-dce.json} +29 -1
- package/ide/web-types-xsl.json +867 -0
- package/index.html +5 -4
- package/package.json +4 -2
- package/request.html +2 -2
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"html.customData": [
|
|
3
|
+
"./ide/customData-dce.json",
|
|
4
|
+
"./ide/customData-xsl.json"
|
|
5
|
+
],
|
|
6
|
+
"terminal.integrated.profiles.windows": {
|
|
7
|
+
|
|
8
|
+
"PowerShell": {
|
|
9
|
+
"source": "PowerShell",
|
|
10
|
+
"icon": "terminal-powershell"
|
|
11
|
+
},
|
|
12
|
+
"Command Prompt": {
|
|
13
|
+
"path": [
|
|
14
|
+
"${env:windir}\\Sysnative\\cmd.exe",
|
|
15
|
+
"${env:windir}\\System32\\cmd.exe"
|
|
16
|
+
],
|
|
17
|
+
"args": [],
|
|
18
|
+
"icon": "terminal-cmd"
|
|
19
|
+
},
|
|
20
|
+
"Git Bash": {
|
|
21
|
+
"source": "Git Bash"
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
"terminal.integrated.defaultProfile.windows": "Git Bash"
|
|
25
|
+
}
|
package/README.md
CHANGED
|
@@ -45,6 +45,8 @@ This project is a POC( Proof of Concept ) targeting to become a base for native
|
|
|
45
45
|
</details>
|
|
46
46
|
|
|
47
47
|
# use
|
|
48
|
+
|
|
49
|
+
Use the [bootstrap project](https://github.com/EPA-WG/custom-element-bootstrap) with all pre-configured or
|
|
48
50
|
## install
|
|
49
51
|
use via CDN
|
|
50
52
|
```html
|
|
@@ -56,17 +58,21 @@ npm i -P @epa-wg/custom-element
|
|
|
56
58
|
yarn add @epa-wg/custom-element
|
|
57
59
|
```
|
|
58
60
|
|
|
61
|
+
## [enable IDE support](ide/IDE.md)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
|
|
59
65
|
## [Live demo 🔗][demo-url]
|
|
60
66
|
```html
|
|
61
67
|
<custom-element tag="pokemon-tile" hidden>
|
|
62
68
|
<h3>{title}</h3> <!-- title is an attribute in instance
|
|
63
69
|
mapped into /*/attributes/title -->
|
|
64
|
-
<
|
|
70
|
+
<if test="//smile"> <!-- data-smile DCE instance attribute,
|
|
65
71
|
mapped into /*/dataset/smile
|
|
66
72
|
used in condition -->
|
|
67
73
|
<!-- data-smile DCE instance attribute, used as HTML -->
|
|
68
74
|
<div>Smile as: {//smile} </div>
|
|
69
|
-
</
|
|
75
|
+
</if>
|
|
70
76
|
<!-- image would not be visible in sandbox, see live demo -->
|
|
71
77
|
<img src="https://unpkg.com/pokeapi-sprites@2.0.2/sprites/pokemon/other/dream-world/{pokemon-id}.svg"
|
|
72
78
|
alt="{title} image"/>
|
|
@@ -205,12 +211,12 @@ In same way as in DCE itself:
|
|
|
205
211
|
</dce-2>
|
|
206
212
|
```
|
|
207
213
|
## Attributes
|
|
208
|
-
To be served by IDE and to track the attributes changes, they have to be declared via `
|
|
214
|
+
To be served by IDE and to track the attributes changes, they have to be declared via `attribute`:
|
|
209
215
|
```html
|
|
210
216
|
<custom-element tag="dce-with-attrs" hidden>
|
|
211
|
-
<
|
|
212
|
-
<
|
|
213
|
-
<
|
|
217
|
+
<attribute name="p1" >default_P1 </attribute>
|
|
218
|
+
<attribute name="p2" select="'always_p2'" ></attribute>
|
|
219
|
+
<attribute name="p3" select="//p3 ?? 'def_P3' " ></attribute>
|
|
214
220
|
p1: {$p1} <br/> p2: {$p2} <br/> p3: {$p3}
|
|
215
221
|
</custom-element>
|
|
216
222
|
<dce-with-attrs p1="123" p3="qwe"></dce-with-attrs>
|
|
@@ -229,7 +235,7 @@ i.e. slot `xxx` is matching `<i slot="xxx">...</i>` in payload.
|
|
|
229
235
|
<custom-element tag="with-description" >
|
|
230
236
|
<slot name="description">description is not available</slot>
|
|
231
237
|
<!-- same as
|
|
232
|
-
<
|
|
238
|
+
<value-of select='/*/payload/*[@slot="description"]'/>
|
|
233
239
|
-->
|
|
234
240
|
</custom-element>
|
|
235
241
|
<with-description>
|
|
@@ -238,12 +244,12 @@ i.e. slot `xxx` is matching `<i slot="xxx">...</i>` in payload.
|
|
|
238
244
|
```
|
|
239
245
|
|
|
240
246
|
## loops, variables
|
|
241
|
-
Loop implemented via [
|
|
247
|
+
Loop implemented via [for-each](https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each)
|
|
242
248
|
|
|
243
249
|
[Variables in XSLT](https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/variable)
|
|
244
250
|
|
|
245
251
|
## [XPath](https://developer.mozilla.org/en-US/docs/Web/XSLT/Transforming_XML_with_XSLT/The_Netscape_XSLT_XPath_Reference)
|
|
246
|
-
is available in `{}` in attributes, in `
|
|
252
|
+
is available in `{}` in attributes, in `for-each`, `if`, `value-of`, and other XSL tags.
|
|
247
253
|
|
|
248
254
|
XPath is a selector language to navigate over custom element instance data, attributes, and payload.
|
|
249
255
|
|
|
@@ -262,12 +268,12 @@ in template. In such cases the `xhtml:` prefix in front of troubled tag would so
|
|
|
262
268
|
<local-storage key="basket" slice="basket" live type="json"></local-storage>
|
|
263
269
|
<xhtml:table xmlns:xhtml="http://www.w3.org/1999/xhtml" >
|
|
264
270
|
<xhtml:tbody>
|
|
265
|
-
<
|
|
271
|
+
<for-each select="//basket/@*">
|
|
266
272
|
<xhtml:tr>
|
|
267
273
|
<xhtml:th> {name()} </xhtml:th>
|
|
268
274
|
<xhtml:td> {.} </xhtml:td>
|
|
269
275
|
</xhtml:tr>
|
|
270
|
-
</
|
|
276
|
+
</for-each>
|
|
271
277
|
</xhtml:tbody>
|
|
272
278
|
<xhtml:tfoot>
|
|
273
279
|
<xhtml:tr>
|
|
@@ -302,7 +308,7 @@ run transformation under debugger.
|
|
|
302
308
|
* try to add as attribute you could observe and put the value of node name or text to identify the current location in data
|
|
303
309
|
within template
|
|
304
310
|
```xml
|
|
305
|
-
<b title="{name(*)} : {text()}">xml tag name: <
|
|
311
|
+
<b title="{name(*)} : {text()}">xml tag name: <value-of select='name()'/></b>
|
|
306
312
|
```
|
|
307
313
|
|
|
308
314
|
[git-url]: https://github.com/EPA-WG/custom-element
|
|
@@ -317,9 +323,9 @@ within template
|
|
|
317
323
|
[github-image]: https://cdnjs.cloudflare.com/ajax/libs/octicons/8.5.0/svg/mark-github.svg
|
|
318
324
|
[npm-image]: https://img.shields.io/npm/v/@epa-wg/custom-element.svg
|
|
319
325
|
[npm-url]: https://npmjs.org/package/@epa-wg/custom-element
|
|
320
|
-
[coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
321
|
-
[coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
322
|
-
[storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.
|
|
326
|
+
[coverage-image]: https://unpkg.com/@epa-wg/custom-element-test@0.0.18/coverage/coverage.svg
|
|
327
|
+
[coverage-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.18/coverage/lcov-report/index.html
|
|
328
|
+
[storybook-url]: https://unpkg.com/@epa-wg/custom-element-test@0.0.18/storybook-static/index.html?path=/story/welcome--introduction
|
|
323
329
|
[sandbox-url]: https://stackblitz.com/github/EPA-WG/custom-element?file=index.html
|
|
324
330
|
[webcomponents-url]: https://www.webcomponents.org/element/@epa-wg/custom-element
|
|
325
331
|
[webcomponents-img]: https://img.shields.io/badge/webcomponents.org-published-blue.svg
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* node xslDtd2Ide.cjs
|
|
3
|
+
* would get xsl 1.0 schema and populate IntelliJ and VS Code IDE custom elements definitions
|
|
4
|
+
*
|
|
5
|
+
* This is one time use script as XSLT 1.0 schema is not changing.
|
|
6
|
+
* DTD parsing here is not generic and cobers only particula XSLT 1.0 schema.
|
|
7
|
+
*/
|
|
8
|
+
import { readFileSync, writeFileSync } from 'node:fs';
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
const dtdText = await fetch( 'https://www.w3.org/1999/11/xslt10.dtd' )
|
|
12
|
+
.then( ( response ) => response.text() )
|
|
13
|
+
.then( ( body ) =>
|
|
14
|
+
{
|
|
15
|
+
return body;
|
|
16
|
+
} );
|
|
17
|
+
const matches = dtdText.match( /<([^>]*)>/g );
|
|
18
|
+
|
|
19
|
+
const chopOff = ( s, begin = 1, end = 1 ) => s.substring( begin, s.length - end );
|
|
20
|
+
const trim = s => s?.trim ? s.trim() : s;
|
|
21
|
+
|
|
22
|
+
let lastComment = ''
|
|
23
|
+
const dtdObj = { ENTITY: {}, ELEMENT: {} }
|
|
24
|
+
for( const match of matches ){
|
|
25
|
+
if( match.startsWith( '<!--' ) ) {
|
|
26
|
+
lastComment = match;
|
|
27
|
+
continue;
|
|
28
|
+
}
|
|
29
|
+
const body = chopOff( match, 2 );
|
|
30
|
+
const arr = body.split( /\s/ );
|
|
31
|
+
const name = arr[ 1 ].trim();
|
|
32
|
+
const resolveRef = s => s ? ( s.startsWith ? ( s.startsWith( '%' ) ? dtdObj.ENTITY[ chopOff( s, 1, 0 ).replace( ';',
|
|
33
|
+
'' ) ] : s ) : s ) : s;
|
|
34
|
+
const attrObj = a =>
|
|
35
|
+
{
|
|
36
|
+
if( !a || Array.isArray( a ) || !a.trim )
|
|
37
|
+
return a;
|
|
38
|
+
const as = a.trim();
|
|
39
|
+
if( 'CDATA,#PCDATA,NMTOKEN,NMTOKENS,'.includes( as + ',' ) )
|
|
40
|
+
return as;
|
|
41
|
+
const ar = as.split( ';' )
|
|
42
|
+
const aa = ar[ 0 ].split( ' ' );
|
|
43
|
+
// if( aa[0].includes('select')){debugger;}
|
|
44
|
+
return { name: aa[ 0 ], type: resolveRef( aa[ 1 ] ), defValue: aa[ 1 ], required: (ar[1] || aa[ 2 ])?.trim() }
|
|
45
|
+
};
|
|
46
|
+
switch( arr[ 0 ] ){
|
|
47
|
+
case 'ENTITY':{
|
|
48
|
+
let key = arr[ 2 ];
|
|
49
|
+
let val = body.substring( body.indexOf( key ) + key.length ).trim();
|
|
50
|
+
let ss;
|
|
51
|
+
if( val.startsWith( '"' ) || val.startsWith( "'" ) ) {
|
|
52
|
+
val = chopOff( val );
|
|
53
|
+
if( val.includes( '(#PCDATA' ) ) {
|
|
54
|
+
val = val.replace( '(#PCDATA', '' ).replace( ')*', '' ).trim();
|
|
55
|
+
ss = [ '#PCDATA', ...val.split( '\n' ).map( s => s.trim() ).map( resolveRef ).flat() ];
|
|
56
|
+
} else
|
|
57
|
+
ss = val.split( /[\n]/ ).map( s => s.replace( '|', '' ).trim() ).filter( s => s );
|
|
58
|
+
} else
|
|
59
|
+
ss = val.split( /[|\n]/ );
|
|
60
|
+
|
|
61
|
+
const v = ss.map( trim ).filter( s => s ).map( resolveRef ).map( attrObj ).flat().filter( s => s );
|
|
62
|
+
dtdObj.ENTITY[ key ] = !v.length ? '' : v.length === 1 ? v[ 0 ] : v;
|
|
63
|
+
break;
|
|
64
|
+
}
|
|
65
|
+
case 'ELEMENT':
|
|
66
|
+
dtdObj.ELEMENT[ name ] = { values: arr[ 2 ], attributes: [] };
|
|
67
|
+
break;
|
|
68
|
+
case 'ATTLIST':{
|
|
69
|
+
const attrStr = body.split( name )[ 1 ].trim();
|
|
70
|
+
const attrs = attrStr.split( '\n' ).map( s => s.trim() );
|
|
71
|
+
const elementAttrs = dtdObj.ELEMENT[ name ].attributes;
|
|
72
|
+
for( let a of attrs ){
|
|
73
|
+
if( a.startsWith( '%' ) ) {
|
|
74
|
+
const v = dtdObj.ENTITY[ chopOff( a.split( ';' )[ 0 ], 1, 0 ) ];
|
|
75
|
+
if( !v ) {
|
|
76
|
+
debugger;
|
|
77
|
+
}
|
|
78
|
+
Array.isArray( v )
|
|
79
|
+
? elementAttrs.push( ...v )
|
|
80
|
+
: elementAttrs.push( v );
|
|
81
|
+
} else
|
|
82
|
+
elementAttrs.push( attrObj( a ) );
|
|
83
|
+
}
|
|
84
|
+
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
// replace the tags list in custom-element.js
|
|
91
|
+
|
|
92
|
+
const tagsCsv = Object.keys( dtdObj.ELEMENT ).map( s => s.replace( 'xsl:', '' ) ).join( ',' );
|
|
93
|
+
const jsText = readFileSync( '../custom-element.js', 'utf8' )
|
|
94
|
+
const updatedJs = jsText.replace( /^.*export const xslTags = .*$/mg,
|
|
95
|
+
`export const xslTags = '${ tagsCsv }'.split(',');` );
|
|
96
|
+
writeFileSync( '../custom-element.js', updatedJs );
|
|
97
|
+
|
|
98
|
+
const vsCode = {
|
|
99
|
+
"version": 1.1, tags: Object.keys( dtdObj.ELEMENT ).map( s => (
|
|
100
|
+
{ name : s.replace( 'xsl:', '' )
|
|
101
|
+
, description : `${ s }`
|
|
102
|
+
, attributes : dtdObj.ELEMENT[ s ].attributes.map( a => (
|
|
103
|
+
{ name : a.name
|
|
104
|
+
, description: `${ JSON.stringify( a ) }`
|
|
105
|
+
, type : "string"
|
|
106
|
+
, required : a.required === '#REQUIRED'
|
|
107
|
+
} ) )
|
|
108
|
+
, references : [ { name: "MDN docs"
|
|
109
|
+
, url : `https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/${s.replace( 'xsl:', '' )}`
|
|
110
|
+
}]
|
|
111
|
+
} ) )
|
|
112
|
+
};
|
|
113
|
+
|
|
114
|
+
writeFileSync( '.././ide/customData-xsl.json', JSON.stringify( vsCode, undefined, 4 ) );
|
|
115
|
+
|
|
116
|
+
const intelliJ = {
|
|
117
|
+
"$schema": "http://json.schemastore.org/web-types",
|
|
118
|
+
"name": "@epa-wg/custom-element",
|
|
119
|
+
"version": "0.0.18",
|
|
120
|
+
"js-types-syntax": "typescript",
|
|
121
|
+
"description-markup": "markdown",
|
|
122
|
+
"contributions": {
|
|
123
|
+
"html": {
|
|
124
|
+
"elements": [
|
|
125
|
+
...Object.keys( dtdObj.ELEMENT ).map( s => (
|
|
126
|
+
{ name : s.replace( 'xsl:', '' )
|
|
127
|
+
, description : `${ s }`
|
|
128
|
+
, attributes : dtdObj.ELEMENT[ s ].attributes.map( a => (
|
|
129
|
+
{ name : a.name
|
|
130
|
+
, description : `${ JSON.stringify( a ) }`
|
|
131
|
+
, type : "string"
|
|
132
|
+
, required : a.required === '#REQUIRED'
|
|
133
|
+
} ) )
|
|
134
|
+
, 'doc-url' : `https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/${s.replace( 'xsl:', '' )}`
|
|
135
|
+
} ) ),
|
|
136
|
+
{
|
|
137
|
+
"name": "for-each",
|
|
138
|
+
"description": "The <xsl:for-each> element selects a set of nodes and processes each of them in the same way. It is often used to iterate through a set of nodes or to change the current node. If one or more <xsl:sort> elements appear as the children of this element, sorting occurs before processing. Otherwise, nodes are processed in document order.",
|
|
139
|
+
"doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each",
|
|
140
|
+
"attributes": [
|
|
141
|
+
{
|
|
142
|
+
"name": "select",
|
|
143
|
+
"description": "Uses an XPath expression to select nodes to be processed.",
|
|
144
|
+
"required": true,
|
|
145
|
+
"doc-url": "https://developer.mozilla.org/en-US/docs/Web/XSLT/Element/for-each#select",
|
|
146
|
+
"value": {
|
|
147
|
+
"type": "string"
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
]
|
|
151
|
+
}
|
|
152
|
+
]
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
|
|
158
|
+
writeFileSync( '.././ide/web-types-xsl.json', JSON.stringify( intelliJ, undefined, 4 ) );
|
|
159
|
+
|
|
160
|
+
|
package/custom-element.d.ts
CHANGED
package/custom-element.js
CHANGED
|
@@ -12,7 +12,15 @@ const attr = (el, attr)=> el.getAttribute?.(attr)
|
|
|
12
12
|
, emptyNode = n=> { while(n.firstChild) n.firstChild.remove(); return n; }
|
|
13
13
|
, createNS = ( ns, tag, t = '' ) => ( e => ((e.innerText = t||''),e) )(document.createElementNS( ns, tag ))
|
|
14
14
|
, xslNs = x => ( x?.setAttribute('xmlns:xsl', XSL_NS_URL ), x )
|
|
15
|
-
, xslHtmlNs = x => ( x?.setAttribute('xmlns:xhtml', HTML_NS_URL ), xslNs(x) )
|
|
15
|
+
, xslHtmlNs = x => ( x?.setAttribute('xmlns:xhtml', HTML_NS_URL ), xslNs(x) )
|
|
16
|
+
, cloneAs = (p,tag) =>
|
|
17
|
+
{ const px = p.ownerDocument.createElementNS(p.namespaceURI,tag);
|
|
18
|
+
for( let a of p.attributes)
|
|
19
|
+
px.setAttribute(a.name, a.value);
|
|
20
|
+
while( p.firstChild )
|
|
21
|
+
px.append(p.firstChild);
|
|
22
|
+
return px;
|
|
23
|
+
}
|
|
16
24
|
|
|
17
25
|
function
|
|
18
26
|
ASSERT(x)
|
|
@@ -141,6 +149,8 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
|
|
|
141
149
|
, tc = (n =>
|
|
142
150
|
{
|
|
143
151
|
forEach$(n,'script', s=> s.remove() );
|
|
152
|
+
const xslRoot = n.content ?? n.firstElementChild?.content ?? n.body ?? n;
|
|
153
|
+
xslTags.forEach( tag => forEach$( xslRoot, tag, el=>toXsl(el,xslRoot) ) );
|
|
144
154
|
const e = n.firstElementChild?.content || n.content
|
|
145
155
|
, asXmlNode = r => {
|
|
146
156
|
const d = xml2dom( '<xhtml/>' )
|
|
@@ -202,14 +212,15 @@ createXsltFromDom( templateNode, S = 'xsl:stylesheet' )
|
|
|
202
212
|
if( !fr )
|
|
203
213
|
return console.error("transformation error",{ xml:tc.outerHTML, xsl: xmlString( sanitizeXsl ) });
|
|
204
214
|
const params = [];
|
|
205
|
-
[...fr.querySelectorAll('dce-root>
|
|
206
|
-
{
|
|
215
|
+
[...fr.querySelectorAll('dce-root>attribute')].forEach(p=>
|
|
216
|
+
{ p = cloneAs(p,'xsl:param');
|
|
217
|
+
payload.append(p);
|
|
207
218
|
let select = attr(p,'select')?.split('??')
|
|
208
219
|
if( !select)
|
|
209
220
|
{ select = ['//'+attr(p, 'name'), `'${p.textContent}'`];
|
|
210
221
|
emptyNode(p);
|
|
211
222
|
}
|
|
212
|
-
if( select?.length>1){
|
|
223
|
+
if( select?.length>1 ){
|
|
213
224
|
p.removeAttribute('select');
|
|
214
225
|
const c = $( xslDom, 'template[match="ignore"]>choose').cloneNode(true);
|
|
215
226
|
c.firstElementChild.setAttribute('test',select[0]);
|
|
@@ -383,6 +394,26 @@ export function assureUID(n,attr)
|
|
|
383
394
|
n.setAttribute(attr, crypto.randomUUID());
|
|
384
395
|
return n.getAttribute(attr)
|
|
385
396
|
}
|
|
397
|
+
export const xslTags = '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(',');
|
|
398
|
+
export const toXsl = (el, defParent) => {
|
|
399
|
+
const x = create('xsl:'+el.localName);
|
|
400
|
+
for( let a of el.attributes )
|
|
401
|
+
x.setAttribute( a.name, a.value );
|
|
402
|
+
while(el.firstChild)
|
|
403
|
+
x.append(el.firstChild);
|
|
404
|
+
if( el.parentElement )
|
|
405
|
+
el.parentElement.replaceChild( x, el );
|
|
406
|
+
else
|
|
407
|
+
{ const p = (el.parentElement || defParent)
|
|
408
|
+
, arr = [...p.childNodes];
|
|
409
|
+
arr.forEach((n, i) => {
|
|
410
|
+
if (n === el)
|
|
411
|
+
arr[i] = x;
|
|
412
|
+
});
|
|
413
|
+
p.replaceChildren(...arr);
|
|
414
|
+
}
|
|
415
|
+
};
|
|
416
|
+
|
|
386
417
|
export class
|
|
387
418
|
CustomElement extends HTMLElement
|
|
388
419
|
{
|
package/demo/a.html
CHANGED
|
@@ -20,8 +20,14 @@
|
|
|
20
20
|
</style>
|
|
21
21
|
</head>
|
|
22
22
|
<body>
|
|
23
|
-
|
|
24
|
-
<
|
|
23
|
+
|
|
24
|
+
<custom-element tag="dce-link" hidden>
|
|
25
|
+
<param name="p1" >default_P1 </param>
|
|
26
|
+
<param name="p2" select="'always_p2'" ></param>
|
|
27
|
+
<param name="p3" select="//p3 ?? 'def_P3' " ></param>
|
|
28
|
+
p1:{$p1} <br/> p2: {$p2} <br/> p3: {$p3}
|
|
29
|
+
</custom-element>
|
|
30
|
+
<dce-link id="dce1" ></dce-link>
|
|
25
31
|
|
|
26
32
|
</body>
|
|
27
33
|
</html>
|
package/demo/hex-grid-dce.html
CHANGED
|
@@ -69,20 +69,20 @@
|
|
|
69
69
|
}
|
|
70
70
|
</style>
|
|
71
71
|
<nav>
|
|
72
|
-
<
|
|
73
|
-
<
|
|
74
|
-
<
|
|
75
|
-
</
|
|
72
|
+
<for-each select="/datadom/payload/xhtml:*">
|
|
73
|
+
<if test="local-name(.) = 'style'">
|
|
74
|
+
<copy-of select="." />
|
|
75
|
+
</if>
|
|
76
76
|
<!-- sanitize blank spans -->
|
|
77
|
-
<
|
|
77
|
+
<if test="local-name(.) != 'style' and (local-name(.) != 'span' or normalize-space(.) != '')">
|
|
78
78
|
<section>
|
|
79
79
|
<button class="action">
|
|
80
80
|
{@alt}
|
|
81
|
-
<
|
|
81
|
+
<copy-of select="."/>
|
|
82
82
|
</button>
|
|
83
83
|
</section>
|
|
84
|
-
</
|
|
85
|
-
</
|
|
84
|
+
</if>
|
|
85
|
+
</for-each>
|
|
86
86
|
</nav>
|
|
87
87
|
</template>
|
|
88
88
|
</custom-element>
|
|
@@ -152,14 +152,14 @@
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
</style>
|
|
155
|
-
<
|
|
155
|
+
<for-each select="/datadom/payload/xhtml:*">
|
|
156
156
|
<!-- sanitize blank spans -->
|
|
157
|
-
<
|
|
157
|
+
<if test="local-name(.) != 'span' or normalize-space(.) != ''">
|
|
158
158
|
<hex-grid>
|
|
159
|
-
<
|
|
159
|
+
<copy-of select="."/>
|
|
160
160
|
</hex-grid>
|
|
161
|
-
</
|
|
162
|
-
</
|
|
161
|
+
</if>
|
|
162
|
+
</for-each>
|
|
163
163
|
</template>
|
|
164
164
|
</custom-element>
|
|
165
165
|
<hex-row class="grid2x">
|
package/demo/http-request.html
CHANGED
|
@@ -43,18 +43,18 @@
|
|
|
43
43
|
method="GET"
|
|
44
44
|
header-accept="application/json"
|
|
45
45
|
></http-request>
|
|
46
|
-
<
|
|
47
|
-
>https://unpkg.com/pokeapi-sprites@2.0.2/sprites/pokemon/other/dream-world</
|
|
48
|
-
<
|
|
49
|
-
<
|
|
46
|
+
<variable name="slides-url"
|
|
47
|
+
>https://unpkg.com/pokeapi-sprites@2.0.2/sprites/pokemon/other/dream-world</variable>
|
|
48
|
+
<for-each select="//slice/page/data/results/*">
|
|
49
|
+
<variable name="pokeid"
|
|
50
50
|
select="substring-before( substring-after( @url, 'https://pokeapi.co/api/v2/pokemon/'),'/')"
|
|
51
|
-
></
|
|
51
|
+
></variable>
|
|
52
52
|
<button>
|
|
53
53
|
<img src="{$slides-url}/{$pokeid}.svg"
|
|
54
54
|
alt="{@name}"/>
|
|
55
55
|
{@name}
|
|
56
56
|
</button>
|
|
57
|
-
</
|
|
57
|
+
</for-each>
|
|
58
58
|
</template>
|
|
59
59
|
</custom-element>
|
|
60
60
|
</template>
|
|
@@ -86,22 +86,22 @@
|
|
|
86
86
|
<tr><th> //slice/request_slice/response/@status </th>
|
|
87
87
|
<td>{ //slice/request_slice/response/@status }</td></tr>
|
|
88
88
|
</table>
|
|
89
|
-
<
|
|
90
|
-
<
|
|
89
|
+
<apply-templates mode="display" select="//slice/request_slice/*"></apply-templates>
|
|
90
|
+
<template mode="display" match="*">
|
|
91
91
|
<fieldset>
|
|
92
92
|
<legend> {local-name(.)} </legend>
|
|
93
93
|
<ul>
|
|
94
|
-
<
|
|
94
|
+
<for-each select="@*">
|
|
95
95
|
<li>
|
|
96
96
|
<var data-testid="section-attribute">@{local-name(.)}</var>
|
|
97
97
|
=
|
|
98
|
-
<code><
|
|
98
|
+
<code><value-of select='.'/></code>
|
|
99
99
|
</li>
|
|
100
|
-
</
|
|
100
|
+
</for-each>
|
|
101
101
|
</ul>
|
|
102
|
-
<
|
|
102
|
+
<apply-templates mode="display" select="*"></apply-templates>
|
|
103
103
|
</fieldset>
|
|
104
|
-
</
|
|
104
|
+
</template>
|
|
105
105
|
</template>
|
|
106
106
|
</custom-element>
|
|
107
107
|
</template>
|
package/demo/local-storage.html
CHANGED
|
@@ -45,12 +45,12 @@
|
|
|
45
45
|
<local-storage key="basket" slice="basket" live type="json"></local-storage>
|
|
46
46
|
<xhtml:table xmlns:xhtml="http://www.w3.org/1999/xhtml" >
|
|
47
47
|
<xhtml:tbody>
|
|
48
|
-
<
|
|
48
|
+
<for-each select="//basket/@*">
|
|
49
49
|
<xhtml:tr>
|
|
50
50
|
<xhtml:th> {name()} </xhtml:th>
|
|
51
51
|
<xhtml:td> {.} </xhtml:td>
|
|
52
52
|
</xhtml:tr>
|
|
53
|
-
</
|
|
53
|
+
</for-each>
|
|
54
54
|
</xhtml:tbody>
|
|
55
55
|
<xhtml:tfoot>
|
|
56
56
|
<xhtml:tr>
|
|
@@ -52,18 +52,18 @@
|
|
|
52
52
|
|
|
53
53
|
<xhtml:table>
|
|
54
54
|
<tr><th><h3> URL properties </h3></th></tr>
|
|
55
|
-
<
|
|
55
|
+
<apply-templates mode="attrs" select="//slice/window-url/@*"></apply-templates>
|
|
56
56
|
</xhtml:table>
|
|
57
57
|
<xhtml:table>
|
|
58
58
|
<tr><th><h3> URL parameters </h3></th></tr>
|
|
59
|
-
<
|
|
59
|
+
<apply-templates mode="attrs" select="//slice/window-url/params/*"></apply-templates>
|
|
60
60
|
</xhtml:table>
|
|
61
|
-
<
|
|
61
|
+
<template mode="attrs" match="*|@*">
|
|
62
62
|
<xhtml:tr>
|
|
63
63
|
<xhtml:th>{name()}</xhtml:th>
|
|
64
64
|
<xhtml:td>{.}</xhtml:td>
|
|
65
65
|
</xhtml:tr>
|
|
66
|
-
</
|
|
66
|
+
</template>
|
|
67
67
|
</template>
|
|
68
68
|
</custom-element>
|
|
69
69
|
<dce-2>?</dce-2>
|
|
@@ -84,21 +84,21 @@
|
|
|
84
84
|
<xhtml:table>
|
|
85
85
|
<xhtml:tbody>
|
|
86
86
|
<xhtml:tr><xhtml:th><h3>URL properties</h3></xhtml:th></xhtml:tr>
|
|
87
|
-
<
|
|
87
|
+
<for-each select="//slice/window-url/@*">
|
|
88
88
|
<xhtml:tr>
|
|
89
89
|
<xhtml:th>{name()}</xhtml:th>
|
|
90
90
|
<xhtml:td>{.}</xhtml:td>
|
|
91
91
|
</xhtml:tr>
|
|
92
|
-
</
|
|
92
|
+
</for-each>
|
|
93
93
|
</xhtml:tbody>
|
|
94
94
|
<xhtml:tbody>
|
|
95
95
|
<xhtml:tr><xhtml:th><h3>URL parameters</h3></xhtml:th></xhtml:tr>
|
|
96
|
-
<
|
|
96
|
+
<for-each select="//slice/window-url/params/*">
|
|
97
97
|
<xhtml:tr>
|
|
98
98
|
<xhtml:th>{name()}</xhtml:th>
|
|
99
99
|
<xhtml:td>{.}</xhtml:td>
|
|
100
100
|
</xhtml:tr>
|
|
101
|
-
</
|
|
101
|
+
</for-each>
|
|
102
102
|
</xhtml:tbody>
|
|
103
103
|
</xhtml:table>
|
|
104
104
|
</template>
|
|
@@ -121,21 +121,21 @@
|
|
|
121
121
|
<xhtml:table>
|
|
122
122
|
<xhtml:tbody>
|
|
123
123
|
<xhtml:tr><xhtml:th><h3>URL properties</h3></xhtml:th></xhtml:tr>
|
|
124
|
-
<
|
|
124
|
+
<for-each select="//slice/src-url/@*">
|
|
125
125
|
<xhtml:tr>
|
|
126
126
|
<xhtml:th>{name()}</xhtml:th>
|
|
127
127
|
<xhtml:td>{.}</xhtml:td>
|
|
128
128
|
</xhtml:tr>
|
|
129
|
-
</
|
|
129
|
+
</for-each>
|
|
130
130
|
</xhtml:tbody>
|
|
131
131
|
<xhtml:tbody>
|
|
132
132
|
<xhtml:tr><xhtml:th><h3>URL parameters</h3></xhtml:th></xhtml:tr>
|
|
133
|
-
<
|
|
133
|
+
<for-each select="//slice/src-url/params/*">
|
|
134
134
|
<xhtml:tr>
|
|
135
135
|
<xhtml:th>{name()}</xhtml:th>
|
|
136
136
|
<xhtml:td>{.}</xhtml:td>
|
|
137
137
|
</xhtml:tr>
|
|
138
|
-
</
|
|
138
|
+
</for-each>
|
|
139
139
|
</xhtml:tbody>
|
|
140
140
|
</xhtml:table>
|
|
141
141
|
</template>
|
package/demo/parameters.html
CHANGED
|
@@ -27,9 +27,9 @@ params needed to declare DCE attributes and track the attributes changes. It als
|
|
|
27
27
|
">
|
|
28
28
|
<template>
|
|
29
29
|
<custom-element tag="dce-link" hidden>
|
|
30
|
-
<
|
|
31
|
-
<
|
|
32
|
-
<
|
|
30
|
+
<attribute name="p1" >default_P1 </attribute>
|
|
31
|
+
<attribute name="p2" select="'always_p2'" ></attribute>
|
|
32
|
+
<attribute name="p3" select="//p3 ?? 'def_P3' " ></attribute>
|
|
33
33
|
p1:{$p1} <br/> p2: {$p2} <br/> p3: {$p3}
|
|
34
34
|
</custom-element>
|
|
35
35
|
<dce-link id="dce1" ></dce-link>
|
package/demo/s.xslt
CHANGED
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
<?xml version="1.0" encoding="UTF-8"?>
|
|
2
1
|
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xhtml="http://www.w3.org/1999/xhtml" xmlns:dce="urn:schemas-epa-wg:dce" xmlns:exsl="http://exslt.org/common" version="1.0" exclude-result-prefixes="exsl">
|
|
3
2
|
<xsl:template match="ignore">
|
|
4
3
|
<xsl:choose>
|
|
@@ -10,11 +9,10 @@
|
|
|
10
9
|
<xsl:when test="//p1 "><xsl:value-of select="//p1 "/></xsl:when>
|
|
11
10
|
<xsl:otherwise><xsl:value-of select=" 'def_p1' "/></xsl:otherwise>
|
|
12
11
|
</xsl:choose></xsl:param><xsl:param xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="p2" select="'always_p2'"/><xsl:param xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="p3"><xsl:choose>
|
|
13
|
-
<xsl:when test="p3"><xsl:value-of select="p3"/></xsl:when>
|
|
14
|
-
<xsl:otherwise><xsl:value-of select="default_P3"
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
</dce-text></dce-root></xsl:template>
|
|
12
|
+
<xsl:when test="//p3"><xsl:value-of select="//p3"/></xsl:when>
|
|
13
|
+
<xsl:otherwise><xsl:value-of select="'default_P3 p1:{$p1"/> p2:<xsl:value-of select="$p2"/> p3:<xsl:value-of select="$p3"/>
|
|
14
|
+
'}</xsl:otherwise>
|
|
15
|
+
</xsl:choose></xsl:param><dce-root xmlns="http://www.w3.org/1999/xhtml" xmlns:xhtml="http://www.w3.org/1999/xhtml" data-dce-id="1"><xsl:attribute xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="p1" select="//p1 ?? 'def_p1' "/><xsl:attribute xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="p2" select="'always_p2'"/><xsl:attribute xmlns:xsl="http://www.w3.org/1999/XSL/Transform" name="p3"/></dce-root></xsl:template>
|
|
18
16
|
<xsl:template match="/">
|
|
19
17
|
<xsl:apply-templates mode="payload" select="/datadom/attributes"/>
|
|
20
18
|
</xsl:template>
|