Repository: ProjectEvergreen/wcc (js)

Issue:
assumed methods and members of custom element classes break the compiler
## Type of Change

<!-- Delete what does not apply -->

- Bug

## Summary
Through the compiler, we are assuming methods like `connectedCallback` and `attachShadow` which means any custom element that does not define these will break.
```js
async function initializeCustomElement(elementURL, tagName, attrs = []) {
  ...
  
  await elementInstance.connectedCallback(); // what if the element does not define this method???

  return elementInstance;
}
```

## Details
Basically, something like this "should" work just fine
```js
export default class Empty extends HTMLElement { }

customElements.define('x-empty', Empty)
```

 But the compiler will give errors instead
 ```sh
 # missing `attachShadow`
<template shadowroot="${this.shadowRoot.mode}">
                                                ^
TypeError: Cannot read property 'mode' of null
    at Footer.getInnerHTML (file:///Users/owenbuckley/Workspace/github/repos/wcc/lib/dom-shim.js:68:49)
    at renderComponentRoots (file:///Users/owenbuckley/Workspace/github/repos/wcc/lib/wcc.js:24:48)
    at async renderToString (file:///Users/owenbuckley/Workspace/github/repos/wcc/lib/wcc.js:101:21)
    at async file:///Users/owenbuckley/Workspace/github/repos/wcc/ssg.js:16:28
error Command failed with exit code 1.
```

----

I'm not sure what the exact behavior should be or what can be assumed, but at the very least we should be able to handle gracefully, similar to #78 .

Pull request description:
empty component should not break compiler
<!--
## Submitting a Pull Request
We love contributions and appreciate any help you can offer!
-->

## Related Issue
resolves #4 

## Summary of Changes
1. Handle empty component compilation and test case

For reference, Chrome returns `''` for the custom element when running in the browser, so presuming this is per "the spec".
<img width="1202" alt="Screen Shot 2022-08-04 at 2 01 22 PM" src="https://user-images.githubusercontent.com/895923/183255445-6a8d9042-122e-4250-8e72-ae84597e4db5.png">

> _Just through the way inheritance works I guess but setting innerHTML in the `Element.constructor` triggers the setter, hence the guard to ensure the presence of content for `HTMLTemplateElement`_

Patch:
diff --git a/src/dom-shim.js b/src/dom-shim.js
index 3fc2956..78ed71c 100644
--- a/src/dom-shim.js
+++ b/src/dom-shim.js
@@ -27,7 +27,7 @@ class Element extends Node {
   constructor() {
     super();
     this.shadowRoot = null;
-    this.innerHTML;
+    this.innerHTML = '';
     this.attributes = {};
   }
 
@@ -106,11 +106,13 @@ class HTMLTemplateElement extends HTMLElement {
 
   // TODO open vs closed shadow root
   set innerHTML(html) {
-    this.content.innerHTML = `
-      <template shadowroot="open">
-        ${html}
-      </template>
-    `;
+    if (this.content) {
+      this.content.innerHTML = `
+        <template shadowroot="open">
+          ${html}
+        </template>
+      `;
+    }
   }
 
   get innerHTML() {


Test patch:
diff --git a/test/cases/empty/empty.spec.js b/test/cases/empty/empty.spec.js
new file mode 100644
index 0000000..634642a
--- /dev/null
+++ b/test/cases/empty/empty.spec.js
@@ -0,0 +1,34 @@
+/*
+ * Use Case
+ * Run wcc against a single custom element using with no internal definitions
+ *
+ * User Result
+ * Should run without any errors from the DOM shim.
+ *
+ * User Workspace
+ * src/
+ *   empty.js
+ */
+
+import chai from 'chai';
+import { renderToString } from '../../../src/wcc.js';
+
+const expect = chai.expect;
+
+describe('Run WCC For ', function() {
+  const LABEL = 'Single Custom Element with an empty class definition';
+  let rawHtml;
+
+  before(async function() {
+    const { html } = await renderToString(new URL('./src/empty.js', import.meta.url));
+
+    rawHtml = html;
+  });
+
+  describe(LABEL, function() {
+    it('should be an empty string', function() {
+      expect(rawHtml).to.equal('');
+    });
+  });
+
+});
\ No newline at end of file
diff --git a/test/cases/empty/src/empty.js b/test/cases/empty/src/empty.js
new file mode 100644
index 0000000..4e3ceba
--- /dev/null
+++ b/test/cases/empty/src/empty.js
@@ -0,0 +1,3 @@
+export default class EmptyComponent extends HTMLElement {
+  
+}
\ No newline at end of file