const jsdom = require('jsdom');
const requestAnimationFrame = require('raf');
const { JSDOM } = jsdom;
const { template } = require('./libs/template');
let dom;

async function render(html, port, webpackAssets) {
  return new Promise(async (resolve, reject) => {
    /*
     ** 1. 1 line patch (workaround that sets the IE8 check to always be false) via patch-package
     */
    dom = new JSDOM(`${template(html, port, webpackAssets)}`, {
      runScripts: 'dangerously',
      resources: 'usable',
      url: `http://localhost:${port}`,
      beforeParse(window) {
        global.window = window;
        global.document = window.document;
        global.requestAnimationFrame = requestAnimationFrame;
        require('mutationobserver-shim');
        require('document-register-element/build/document-register-element.max.js'); /* [1] */
        window.requestAnimationFrame = requestAnimationFrame;
      },
    });

    dom.window.document.onload = async () => {
      // @todo: work out a way to get these web component tag names to be dynamically added
      const undefinedElements = dom.window.document.querySelectorAll([
        'bolt-button',
        'bolt-text',
        'bolt-icon',
      ]);

      const promises = [...undefinedElements].map(element =>
        dom.window.customElements.whenDefined(element.localName),
      );

      await Promise.all(promises);

      function stripScripts(s) {
        var div = dom.window.document.createElement('div');
        div.innerHTML = s;
        var scripts = div.getElementsByTagName('script');
        var i = scripts.length;
        while (i--) {
          scripts[i].parentNode.removeChild(scripts[i]);
        }
        return div.innerHTML;
      }

      const code = dom.window.document.body.innerHTML;

      // strip out any lit-html comments in the rendered HTML before returning
      resolve(stripScripts(code).replace(/<!---->/g, ''));
    };
  });
}

module.exports = {
  render,
};

@@ -21,24 +21,60 @@
 e('jsdom');%0A
+const resolve = require('resolve');%0A
 const reques
@@ -132,16 +132,42 @@
  jsdom;%0A
+const fs = require('fs');%0A
 const %7B 
@@ -221,126 +221,141 @@
 m;%0A%0A
-async function render(html, port, webpackAssets) %7B%0A  return new Promise(async (resolve, reject) =%3E %7B%0A    /*%0A     ** 1.
+const mutationObserverShim = fs.readFileSync(%0A  resolve.sync('mutationobserver-shim'),%0A  %7B encoding: 'utf-8' %7D,%0A);%0A%0A/**%0A * contains a
  1 l
@@ -364,17 +364,16 @@
 e patch 
-(
 workarou
@@ -422,13 +422,20 @@
 lse)
+%0A *
  via 
+the 
 patc
@@ -447,16 +447,290 @@
 kage
-%0A     */
+ NPM library%0A */%0Aconst customElementShim = fs.readFileSync(%0A  resolve.sync(%0A    'document-register-element/build/document-register-element.max.js',%0A  ),%0A  %7B encoding: 'utf-8' %7D,%0A);%0A%0Aasync function render(html, port, webpackAssets) %7B%0A  return new Promise(async (resolve, reject) =%3E %7B
 %0A   
@@ -929,89 +929,14 @@
     
-global.window = window;%0A        global.document = window.document;%0A        global
+window
 .req
@@ -989,215 +989,187 @@
     
-  require('mutationobserver-shim'
+%7D,%0A    %7D
 );%0A
+%0A
     
-    require('document-register-element/build/document-register-element.max.js'); /* %5B1%5D */
+// add these to our JSOM instance to messing with the global Node.js env
 %0A    
-    
+dom.
 window.
-requestAnimationFrame = requestAnimationFrame;%0A      %7D,%0A    %7D
+eval(%60$%7BmutationObserverShim%7D%60);%0A    dom.window.eval(%60$%7BcustomElementShim%7D%60
 );%0A%0A

update JSDOM renderer to not add shims to the global Node.js env