wc-compiler 0.2.2 → 0.4.0
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 +34 -43
- package/dist/wcc.dist.js +14121 -0
- package/package.json +15 -4
- package/src/dom-shim.js +15 -10
- package/src/wcc.js +24 -23
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "wc-compiler",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "Experimental native Web Components compiler.",
|
|
5
5
|
"main": "src/wcc.js",
|
|
6
6
|
"type": "module",
|
|
@@ -10,12 +10,14 @@
|
|
|
10
10
|
"node": ">=14"
|
|
11
11
|
},
|
|
12
12
|
"files": [
|
|
13
|
-
"src/"
|
|
13
|
+
"src/",
|
|
14
|
+
"dist/wcc.dist.js"
|
|
14
15
|
],
|
|
15
16
|
"publishConfig": {
|
|
16
17
|
"access": "public"
|
|
17
18
|
},
|
|
18
19
|
"scripts": {
|
|
20
|
+
"clean": "rimraf ./dist",
|
|
19
21
|
"lint": "eslint \"*.*js\" \"./src/**/**/*.js\" \"./test/**/**/*.js\"",
|
|
20
22
|
"develop": "concurrently \"nodemon --watch src --watch docs -e js,md,css,html ./build.js\" \"http-server ./dist --open\"",
|
|
21
23
|
"build": "node ./build.js",
|
|
@@ -24,7 +26,9 @@
|
|
|
24
26
|
"example:ssr": "node ./examples/ssr.js",
|
|
25
27
|
"start": "npm run develop",
|
|
26
28
|
"test": "c8 mocha --parallel",
|
|
27
|
-
"test:tdd": "npm run test --watch"
|
|
29
|
+
"test:tdd": "npm run test --watch",
|
|
30
|
+
"dist": "rollup -c rollup.config.js",
|
|
31
|
+
"prepublishOnly": "npm run clean && npm run dist"
|
|
28
32
|
},
|
|
29
33
|
"dependencies": {
|
|
30
34
|
"acorn": "^8.7.0",
|
|
@@ -33,6 +37,8 @@
|
|
|
33
37
|
},
|
|
34
38
|
"devDependencies": {
|
|
35
39
|
"@mapbox/rehype-prism": "^0.8.0",
|
|
40
|
+
"@rollup/plugin-commonjs": "^22.0.0",
|
|
41
|
+
"@rollup/plugin-node-resolve": "^13.3.0",
|
|
36
42
|
"c8": "^7.11.2",
|
|
37
43
|
"chai": "^4.3.6",
|
|
38
44
|
"concurrently": "^7.1.0",
|
|
@@ -42,11 +48,16 @@
|
|
|
42
48
|
"mocha": "^9.2.2",
|
|
43
49
|
"nodemon": "^2.0.15",
|
|
44
50
|
"prismjs": "^1.28.0",
|
|
45
|
-
"
|
|
51
|
+
"rehype-autolink-headings": "^6.1.1",
|
|
46
52
|
"rehype-raw": "^6.1.1",
|
|
53
|
+
"rehype-slug": "^5.0.1",
|
|
47
54
|
"rehype-stringify": "^9.0.3",
|
|
48
55
|
"remark-parse": "^10.0.1",
|
|
49
56
|
"remark-rehype": "^10.1.0",
|
|
57
|
+
"remark-toc": "^8.0.1",
|
|
58
|
+
"rimraf": "^3.0.2",
|
|
59
|
+
"rollup": "^2.75.7",
|
|
60
|
+
"simple.css": "^0.1.3",
|
|
50
61
|
"unified": "^10.1.2"
|
|
51
62
|
}
|
|
52
63
|
}
|
package/src/dom-shim.js
CHANGED
|
@@ -3,6 +3,7 @@ class EventTarget { }
|
|
|
3
3
|
|
|
4
4
|
// https://developer.mozilla.org/en-US/docs/Web/API/Node
|
|
5
5
|
// EventTarget <- Node
|
|
6
|
+
// TODO should be an interface?
|
|
6
7
|
class Node extends EventTarget {
|
|
7
8
|
constructor() {
|
|
8
9
|
super();
|
|
@@ -15,7 +16,7 @@ class Node extends EventTarget {
|
|
|
15
16
|
}
|
|
16
17
|
|
|
17
18
|
appendChild(node) {
|
|
18
|
-
this.innerHTML = this.innerHTML ? this.innerHTML += node.
|
|
19
|
+
this.innerHTML = this.innerHTML ? this.innerHTML += node.innerHTML : node.innerHTML;
|
|
19
20
|
}
|
|
20
21
|
}
|
|
21
22
|
|
|
@@ -63,14 +64,9 @@ class HTMLElement extends Element {
|
|
|
63
64
|
}
|
|
64
65
|
|
|
65
66
|
// https://github.com/mfreed7/declarative-shadow-dom/blob/master/README.md#serialization
|
|
67
|
+
// eslint-disable-next-line
|
|
66
68
|
getInnerHTML(options = {}) {
|
|
67
|
-
return
|
|
68
|
-
? `
|
|
69
|
-
<template shadowroot="${this.shadowRoot.mode}">
|
|
70
|
-
${this.shadowRoot.innerHTML}
|
|
71
|
-
</template>
|
|
72
|
-
`
|
|
73
|
-
: this.shadowRoot.innerHTML;
|
|
69
|
+
return this.shadowRoot.innerHTML;
|
|
74
70
|
}
|
|
75
71
|
}
|
|
76
72
|
|
|
@@ -101,11 +97,20 @@ class HTMLTemplateElement extends HTMLElement {
|
|
|
101
97
|
super();
|
|
102
98
|
// console.debug('HTMLTemplateElement constructor');
|
|
103
99
|
|
|
104
|
-
this.content = new DocumentFragment(
|
|
100
|
+
this.content = new DocumentFragment();
|
|
105
101
|
}
|
|
106
102
|
|
|
103
|
+
// TODO open vs closed shadow root
|
|
107
104
|
set innerHTML(html) {
|
|
108
|
-
this.content.
|
|
105
|
+
this.content.innerHTML = `
|
|
106
|
+
<template shadowroot="open">
|
|
107
|
+
${html}
|
|
108
|
+
</template>
|
|
109
|
+
`;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
get innerHTML() {
|
|
113
|
+
return this.content && this.content.innerHTML ? this.content.innerHTML : undefined;
|
|
109
114
|
}
|
|
110
115
|
}
|
|
111
116
|
|
package/src/wcc.js
CHANGED
|
@@ -4,8 +4,7 @@ import './dom-shim.js';
|
|
|
4
4
|
import * as acorn from 'acorn';
|
|
5
5
|
import * as walk from 'acorn-walk';
|
|
6
6
|
import { parse, parseFragment, serialize } from 'parse5';
|
|
7
|
-
|
|
8
|
-
import fs from 'node:fs/promises';
|
|
7
|
+
import fs from 'fs/promises';
|
|
9
8
|
|
|
10
9
|
let definitions;
|
|
11
10
|
|
|
@@ -23,26 +22,29 @@ function isCustomElementDefinitionNode(node) {
|
|
|
23
22
|
&& expression.callee.property.name === 'define';
|
|
24
23
|
}
|
|
25
24
|
|
|
26
|
-
async function renderComponentRoots(tree
|
|
25
|
+
async function renderComponentRoots(tree) {
|
|
27
26
|
for (const node of tree.childNodes) {
|
|
28
27
|
if (node.tagName && node.tagName.indexOf('-') > 0) {
|
|
29
28
|
const { tagName } = node;
|
|
30
29
|
const { moduleURL } = definitions[tagName];
|
|
31
30
|
const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs);
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
const elementHtml = elementInstance.shadowRoot
|
|
32
|
+
? elementInstance.getInnerHTML({ includeShadowRoots: true })
|
|
33
|
+
: elementInstance.innerHTML;
|
|
34
|
+
const elementTree = parseFragment(elementHtml);
|
|
35
|
+
|
|
36
|
+
node.childNodes = node.childNodes.length === 0
|
|
37
|
+
? elementTree.childNodes
|
|
38
|
+
: [...elementTree.childNodes, ...node.childNodes];
|
|
37
39
|
}
|
|
38
40
|
|
|
39
41
|
if (node.childNodes && node.childNodes.length > 0) {
|
|
40
|
-
await renderComponentRoots(node
|
|
42
|
+
await renderComponentRoots(node);
|
|
41
43
|
}
|
|
42
44
|
|
|
43
45
|
// does this only apply to `<template>` tags?
|
|
44
46
|
if (node.content && node.content.childNodes && node.content.childNodes.length > 0) {
|
|
45
|
-
await renderComponentRoots(node.content
|
|
47
|
+
await renderComponentRoots(node.content);
|
|
46
48
|
}
|
|
47
49
|
}
|
|
48
50
|
|
|
@@ -102,10 +104,12 @@ async function getTagName(moduleURL) {
|
|
|
102
104
|
async function initializeCustomElement(elementURL, tagName, attrs = []) {
|
|
103
105
|
await registerDependencies(elementURL);
|
|
104
106
|
|
|
107
|
+
// https://github.com/ProjectEvergreen/wcc/pull/67/files#r902061804
|
|
108
|
+
const { pathname } = elementURL;
|
|
105
109
|
const element = tagName
|
|
106
110
|
? customElements.get(tagName)
|
|
107
|
-
: (await import(
|
|
108
|
-
const dataLoader = (await import(
|
|
111
|
+
: (await import(pathname)).default;
|
|
112
|
+
const dataLoader = (await import(pathname)).getData;
|
|
109
113
|
const data = dataLoader ? await dataLoader() : {};
|
|
110
114
|
const elementInstance = new element(data); // eslint-disable-line new-cap
|
|
111
115
|
|
|
@@ -122,18 +126,18 @@ async function initializeCustomElement(elementURL, tagName, attrs = []) {
|
|
|
122
126
|
return elementInstance;
|
|
123
127
|
}
|
|
124
128
|
|
|
125
|
-
async function renderToString(elementURL
|
|
129
|
+
async function renderToString(elementURL) {
|
|
126
130
|
definitions = [];
|
|
127
131
|
|
|
128
|
-
const { lightMode = false } = options;
|
|
129
|
-
const includeShadowRoots = !lightMode;
|
|
130
132
|
const elementTagName = await getTagName(elementURL);
|
|
131
133
|
const elementInstance = await initializeCustomElement(elementURL);
|
|
132
134
|
|
|
133
|
-
const elementHtml = elementInstance.
|
|
135
|
+
const elementHtml = elementInstance.shadowRoot
|
|
136
|
+
? elementInstance.getInnerHTML({ includeShadowRoots: true })
|
|
137
|
+
: elementInstance.innerHTML;
|
|
134
138
|
const elementTree = getParse(elementHtml)(elementHtml);
|
|
135
|
-
const finalTree = await renderComponentRoots(elementTree
|
|
136
|
-
const html =
|
|
139
|
+
const finalTree = await renderComponentRoots(elementTree);
|
|
140
|
+
const html = elementTagName ? `
|
|
137
141
|
<${elementTagName}>
|
|
138
142
|
${serialize(finalTree)}
|
|
139
143
|
</${elementTagName}>
|
|
@@ -146,18 +150,15 @@ async function renderToString(elementURL, options = {}) {
|
|
|
146
150
|
};
|
|
147
151
|
}
|
|
148
152
|
|
|
149
|
-
async function renderFromHTML(html, elements = []
|
|
153
|
+
async function renderFromHTML(html, elements = []) {
|
|
150
154
|
definitions = [];
|
|
151
155
|
|
|
152
|
-
const { lightMode = false } = options;
|
|
153
|
-
const includeShadowRoots = !lightMode;
|
|
154
|
-
|
|
155
156
|
for (const url of elements) {
|
|
156
157
|
await initializeCustomElement(url);
|
|
157
158
|
}
|
|
158
159
|
|
|
159
160
|
const elementTree = getParse(html)(html);
|
|
160
|
-
const finalTree = await renderComponentRoots(elementTree
|
|
161
|
+
const finalTree = await renderComponentRoots(elementTree);
|
|
161
162
|
|
|
162
163
|
return {
|
|
163
164
|
html: serialize(finalTree),
|