<html>
<script type="text/javascript" charset="utf-8">
  function timeout(ms) {
    return new Promise((resolve) => {
      setTimeout(resolve, ms)
    })
  }
  async function invokeGc () {
    // it seems calling window.gc once does not guarantee garbage will be
    // collected, so we repeat 10 times with interval of 100 ms
    for (let i = 0; i < 10; i++) {
      window.gc()
      await timeout(100)
    }
  }

  const [,test] = window.location.href.split('?')
  if (window.opener && test !== 'reload-remote') {
    window.callback = () => {
      opener.require('electron').ipcRenderer.send('answer', document.body.innerHTML)
    }
  } else {
    const tests = {
      'reload-remote-child': () => {
        open(`${location.protocol}//${location.pathname}?reload-remote`)
      },
      'reload-remote': async () => {
        const {ipcRenderer, remote} = require('electron')
        const p = ipcRenderer.sendSync('get-remote-module-path')
        const Hello = remote.require(p)
        if (!ipcRenderer.sendSync('reloaded')) {
          ipcRenderer.send('reload')
          return
        }
        await invokeGc()
        ipcRenderer.send('answer', new Hello().say())
      },
      'webcontents-stop': () => {
        stop()
      },
      'webcontents-events': () => {
        addEventListener('load', () => {
          location.hash = 'in-page-navigate'
          setTimeout(() => {
            location.reload()
          }, 50)
        })
      },
      'exit-event': () => {
        const {ipcRenderer} = require('electron')
        const currentLocation = location.href.slice();
        process.on('exit', () => {
          ipcRenderer.send('answer', currentLocation)
        })
        location.assign('http://www.google.com')
      },
      'window-open': () => {
        addEventListener('load', () => {
          const popup = open(window.location.href, 'popup!', 'top=60,left=50,width=500,height=600')
          popup.addEventListener('DOMContentLoaded', () => {
            popup.document.write('<h1>scripting from opener</h1>')
            popup.callback()
          }, false)
        })
      },
      'window-open-external': () => {
        const {ipcRenderer} = require('electron')
        addEventListener('load', () => {
          ipcRenderer.once('open-the-popup', (event, url) => {
            popup = open(url, '', 'top=65,left=55,width=505,height=605')
          })
          ipcRenderer.once('touch-the-popup', () => {
            let errorMessage = null
            try {
              const childDoc = popup.document
            } catch (error) {
              errorMessage = error.message
            }
            ipcRenderer.send('answer', errorMessage)
          })
          ipcRenderer.send('opener-loaded')
        })
      },
      'verify-ipc-sender': () => {
        const {ipcRenderer} = require('electron')
        const popup = open()
        ipcRenderer.once('verified', () => {
          ipcRenderer.send('parent-answer')
        })
        popup.ipcRenderer.once('verified', () => {
          popup.ipcRenderer.send('child-answer')
        })
        ipcRenderer.send('parent-ready')
        popup.ipcRenderer.send('child-ready')
      }
    }

    addEventListener('unload', () => {
      if (window.popup)
        popup.close()
    }, false)

    if (tests.hasOwnProperty(test))
      tests[test]()
  }
</script>
</html>