-
Notifications
You must be signed in to change notification settings - Fork 10
Commit
- Loading branch information
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export default { | ||
prerender: true | ||
}; |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
/* | ||
* Use Case | ||
* Run Greenwood and correctly prerender "HTML" Web Components. | ||
* | ||
* User Result | ||
* Should generate a static Greenwood build with the expected prerender "HTML" Web Components content. | ||
* | ||
* User Command | ||
* greenwood build | ||
* | ||
* User Config | ||
* | ||
* { | ||
* prerender: true, | ||
* } | ||
* | ||
* User Workspace | ||
* src/ | ||
* components/ | ||
* picture-frame.js | ||
* index.html | ||
*/ | ||
import chai from 'chai'; | ||
import fs from 'fs'; | ||
Check failure on line 24 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
import glob from 'glob-promise'; | ||
Check failure on line 25 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
import { JSDOM } from 'jsdom'; | ||
import path from 'path'; | ||
import { runSmokeTest } from '../../../../../test/smoke-test.js'; | ||
import { getSetupFiles, getOutputTeardownFiles } from '../../../../../test/utils.js'; | ||
import { Runner } from 'gallinago'; | ||
import { fileURLToPath, URL } from 'url'; | ||
|
||
const expect = chai.expect; | ||
|
||
describe('Build Greenwood With: ', function() { | ||
const LABEL = 'Prerendering with HTML Web Components'; | ||
const cliPath = path.join(process.cwd(), 'packages/cli/src/index.js'); | ||
const outputPath = fileURLToPath(new URL('.', import.meta.url)); | ||
let runner; | ||
|
||
before(function() { | ||
this.context = { | ||
publicDir: path.join(outputPath, 'public') | ||
}; | ||
runner = new Runner(false, true); | ||
}); | ||
|
||
describe(LABEL, function() { | ||
before(function() { | ||
runner.setup(outputPath, getSetupFiles(outputPath)); | ||
runner.runCommand(cliPath, 'build'); | ||
}); | ||
|
||
runSmokeTest(['public'], LABEL); | ||
|
||
describe('Prerender HTML Web Component', function() { | ||
let dom; | ||
let pictureFrame; | ||
|
||
before(async function() { | ||
dom = await JSDOM.fromFile(path.resolve(this.context.publicDir, './index.html')); | ||
pictureFrame = dom.window.document.querySelectorAll('app-picture-frame'); | ||
}); | ||
|
||
it('should not have any <template> tags within the document', function() { | ||
expect(dom.window.document.querySelectorAll('template').length).to.equal(0); | ||
}); | ||
|
||
Check failure on line 68 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
it('should only have one <app-picture-frame> tag', function() { | ||
expect(pictureFrame.length).to.equal(1); | ||
}); | ||
|
||
Check failure on line 72 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
it('should have the expected title attribute content in the heading of HTML', () => { | ||
const heading = pictureFrame[0].querySelectorAll('.picture-frame .heading'); | ||
|
||
Check failure on line 75 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
expect(heading.length).to.equal(1); | ||
expect(heading[0].textContent).to.equal('Greenwood'); | ||
}); | ||
|
||
Check failure on line 79 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
it('should have the expected image from userland in the HTML', () => { | ||
const img = pictureFrame[0].querySelectorAll('.picture-frame img'); | ||
|
||
Check failure on line 82 in packages/cli/test/cases/loaders-build.html-web-components/loaders-html-webcomponents.spec.js
|
||
expect(img.length).to.equal(1); | ||
expect(img[0].getAttribute('alt')).to.equal('Greenwood logo'); | ||
expect(img[0].getAttribute('src')).to.equal('/assets/greenwood.png'); | ||
}); | ||
}); | ||
}); | ||
|
||
after(function() { | ||
runner.teardown(getOutputTeardownFiles(outputPath)); | ||
}); | ||
|
||
}); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"type": "module" | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
export default class PictureFrame extends HTMLElement { | ||
connectedCallback() { | ||
const title = this.getAttribute('title'); | ||
|
||
this.innerHTML = ` | ||
<div class="picture-frame"> | ||
<h6 class="heading">${title}</h6> | ||
${this.innerHTML} | ||
</div> | ||
`; | ||
} | ||
} | ||
|
||
customElements.define('app-picture-frame', PictureFrame); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<!DOCTYPE html> | ||
<html lang="en" prefix="og:http://ogp.me/ns#"> | ||
|
||
<head> | ||
<script type="module" src="./components/picture-frame.js"></script> | ||
</head> | ||
|
||
<body> | ||
<app-picture-frame title="Greenwood"> | ||
<img src="/assets/greenwood.png" alt="Greenwood logo" /> | ||
</app-picture-frame> | ||
</body> | ||
|
||
</html> |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,90 @@ | ||
diff --git a/node_modules/wc-compiler/src/wcc.js b/node_modules/wc-compiler/src/wcc.js | ||
index 35884d4..e37a4a4 100644 | ||
--- a/node_modules/wc-compiler/src/wcc.js | ||
+++ b/node_modules/wc-compiler/src/wcc.js | ||
@@ -32,16 +32,27 @@ async function renderComponentRoots(tree, definitions) { | ||
const { tagName } = node; | ||
|
||
if (definitions[tagName]) { | ||
+ console.log('renderComponentRoots', { tagName }); | ||
const { moduleURL } = definitions[tagName]; | ||
- const elementInstance = await initializeCustomElement(moduleURL, tagName, node.attrs, definitions); | ||
- const elementHtml = elementInstance.shadowRoot | ||
+ console.log({ node }); | ||
+ const elementInstance = await initializeCustomElement(moduleURL, tagName, node, definitions); | ||
+ const hasShadow = elementInstance.shadowRoot; | ||
+ const elementHtml = hasShadow | ||
? elementInstance.getInnerHTML({ includeShadowRoots: true }) | ||
: elementInstance.innerHTML; | ||
const elementTree = parseFragment(elementHtml); | ||
+ const hasLight = elementTree.childNodes > 0; | ||
|
||
- node.childNodes = node.childNodes.length === 0 | ||
+ console.log('elementHtml', { elementHtml }); | ||
+ console.log('elementTree', { elementTree }); | ||
+ console.log('elementTree.childNodes', elementTree.childNodes); | ||
+ console.log('node.childNodes', node.childNodes); | ||
+ | ||
+ node.childNodes = node.childNodes.length === 0 && hasLight > 0 && !hasShadow | ||
? elementTree.childNodes | ||
- : [...elementTree.childNodes, ...node.childNodes]; | ||
+ : hasShadow | ||
+ ? [...elementTree.childNodes, ...node.childNodes] | ||
+ : elementTree.childNodes; | ||
} else { | ||
console.warn(`WARNING: customElement <${tagName}> is not defined. You may not have imported it yet.`); | ||
} | ||
@@ -138,7 +149,10 @@ async function getTagName(moduleURL) { | ||
return tagName; | ||
} | ||
|
||
-async function initializeCustomElement(elementURL, tagName, attrs = [], definitions = [], isEntry, props = {}) { | ||
+async function initializeCustomElement(elementURL, tagName, node = {}, definitions = [], isEntry, props = {}) { | ||
+ const { attrs = [], childNodes = [] } = node; | ||
+ console.log('initializeCustomElement', { node }); | ||
+ | ||
if (!tagName) { | ||
const depth = isEntry ? 1 : 0; | ||
registerDependencies(elementURL, definitions, depth); | ||
@@ -157,6 +171,41 @@ async function initializeCustomElement(elementURL, tagName, attrs = [], definiti | ||
|
||
if (element) { | ||
const elementInstance = new element(data); // eslint-disable-line new-cap | ||
+ let innerHTML = elementInstance.innerHTML || ''; | ||
+ | ||
+ // TODO | ||
+ // 1. Needs to be recursive | ||
+ // 2. ~~Needs to handle attributes~~ | ||
+ // 3. Needs to handle duplicate content | ||
+ // 4. Needs to handle self closing tags | ||
+ // 5. handle all node types | ||
+ childNodes.forEach((child) => { | ||
+ const { nodeName, attrs = [] } = child; | ||
+ | ||
+ if (nodeName !== '#text') { | ||
+ innerHTML += `<${nodeName}`; | ||
+ | ||
+ if (attrs.length > 0) { | ||
+ attrs.forEach(attr => { | ||
+ innerHTML += ` ${attr.name}="${attr.value}"`; | ||
+ }); | ||
+ } | ||
+ | ||
+ innerHTML += '>'; | ||
+ | ||
+ child.childNodes.forEach((c) => { | ||
+ if (c.nodeName === '#text') { | ||
+ innerHTML += c.value; | ||
+ } | ||
+ }); | ||
+ | ||
+ innerHTML += `</${nodeName}>`; | ||
+ } | ||
+ }); | ||
+ | ||
+ console.log({ innerHTML }); | ||
+ elementInstance.innerHTML = innerHTML; | ||
+ console.log('================='); | ||
|
||
attrs.forEach((attr) => { | ||
elementInstance.setAttribute(attr.name, attr.value); |