Last active
September 5, 2018 19:57
-
-
Save jkleinsc/7eb20129c41f6fc95999404d507fe438 to your computer and use it in GitHub Desktop.
Electron Fiddle Gist
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html> | |
<link rel="icon" type="image/png" href="/favicon.png"/> | |
<link rel="icon" type="image/png" href="http://test.com/favicon.png"/> | |
<meta http-equiv="content-security-policy" content="script-src 'self' 'unsafe-inline'" /> | |
<body> | |
<script type="text/javascript" charset="utf-8"> | |
console.log('a'); | |
document.title = "test" | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* @fileoverview A set of helper functions to make it easier to work | |
* with events in async/await manner. | |
*/ | |
/** | |
* @param {!EventTarget} target | |
* @param {string} eventName | |
* @return {!Promise<!Event>} | |
*/ | |
const waitForEvent = (target, eventName) => { | |
return new Promise(resolve => { | |
target.addEventListener(eventName, resolve, {once: true}) | |
}) | |
} | |
/** | |
* @param {!EventEmitter} emitter | |
* @param {string} eventName | |
* @return {!Promise<!Array>} With Event as the first item. | |
*/ | |
const emittedOnce = (emitter, eventName) => { | |
return new Promise(resolve => { | |
emitter.once(eventName, (...args) => resolve(args)) | |
}) | |
} | |
exports.emittedOnce = emittedOnce | |
exports.waitForEvent = waitForEvent |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!DOCTYPE html> | |
<html> | |
<head> | |
<meta charset="UTF-8"> | |
<title>Hello World!</title> | |
</head> | |
<body> | |
<h1>Hello World!</h1> | |
<!-- All of the Node.js APIs are available in this renderer process. --> | |
We are using Node.js <script>document.write(process.versions.node)</script>, | |
Chromium <script>document.write(process.versions.chrome)</script>, | |
and Electron <script>document.write(process.versions.electron)</script>. | |
<script> | |
// You can also require other files to run in this process | |
require('./renderer.js') | |
</script> | |
</body> | |
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Modules to control application life and create native browser window | |
const fs = require('fs') | |
const path = require('path') | |
const os = require('os') | |
const qs = require('querystring') | |
const http = require('http') | |
const {closeWindow} = require('./window-helpers') | |
const {emittedOnce} = require('./events-helpers') | |
const {app, BrowserWindow, BrowserView, protocol, session, webContents} = require('electron') | |
const features = process.atomBinding('features') | |
// Keep a global reference of the window object, if you don't, the window will | |
// be closed automatically when the JavaScript object is garbage collected. | |
let mainWindow | |
let w = null | |
let iw = null | |
let ws = null | |
let server | |
let postData | |
const defaultOptions = { | |
show: false, | |
width: 400, | |
height: 400, | |
webPreferences: { | |
backgroundThrottling: false | |
} | |
} | |
const openTheWindow = async (options = defaultOptions) => { | |
// The `afterEach` hook isn't called if a test fails, | |
// we should make sure that the window is closed ourselves. | |
await closeTheWindow() | |
w = new BrowserWindow(options) | |
return w | |
} | |
const closeTheWindow = function () { | |
return closeWindow(w).then(() => { w = null }) | |
} | |
function runFirst(done) { | |
const filePath = path.join(__dirname, 'a.html') | |
const fileStats = fs.statSync(filePath) | |
postData = [ | |
{ | |
type: 'rawData', | |
bytes: Buffer.from('username=test&file=') | |
}, | |
{ | |
type: 'file', | |
filePath: filePath, | |
offset: 0, | |
length: fileStats.size, | |
modificationTime: fileStats.mtime.getTime() / 1000 | |
} | |
] | |
server = http.createServer((req, res) => { | |
function respond () { | |
if (req.method === 'POST') { | |
let body = '' | |
req.on('data', (data) => { | |
if (data) body += data | |
}) | |
req.on('end', () => { | |
let parsedData = qs.parse(body) | |
fs.readFile(filePath, (err, data) => { | |
if (err) return | |
if (parsedData.username === 'test' && | |
parsedData.file === data.toString()) { | |
res.end() | |
} | |
}) | |
}) | |
} else { | |
res.end() | |
} | |
} | |
setTimeout(respond, req.url.includes('slow') ? 200 : 0) | |
}) | |
server.listen(0, '127.0.0.1', () => { | |
server.url = `http://127.0.0.1:${server.address().port}` | |
console.log('run first done') | |
done() | |
}) | |
} | |
function runLast() { | |
console.log('Run last running') | |
server.close() | |
server = null | |
} | |
async function createWindow () { | |
console.log('READY, kicking it off') | |
runFirst(async () => { | |
console.log('runfirst done; about to open window') | |
await openTheWindow() | |
console.log('finished opening window') | |
testIt(async () => { | |
console.log('finished testIt') | |
await closeTheWindow() | |
console.log('finished closing window') | |
await openTheWindow() | |
console.log('finished opening window for second test') | |
testModal(async () => { | |
console.log('Done test modal') | |
await closeTheWindow() | |
runLast() | |
}) | |
}) | |
}) | |
} | |
let c = null | |
function before(args) { | |
if (c != null) c.destroy() | |
c = new BrowserWindow(args) | |
} | |
function after() { | |
if (c != null) c.destroy() | |
c = null | |
} | |
function testIt(done) { | |
let winArgs = {show: false, parent: w} | |
before(winArgs) | |
if(c.getParentWindow() == w) { | |
console.log('DOES set parent window') | |
} else { | |
console.log('DOES NOT set parent window') | |
} | |
after() | |
before(winArgs) | |
let childWindows = w.getChildWindows() | |
if (childWindows.length == 1 && childWindows[0] == c) { | |
console.log('it adds window to child windows of parent') | |
} else { | |
console.log('it DOES NOT adds window to child windows of parent') | |
} | |
console.log('About to cleanup') | |
after() | |
console.log('Done cleanup;open new') | |
before(winArgs) | |
console.log('Should have new window, ') | |
c.once('closed', () => { | |
console.log('now closed') | |
if (childWindows.length == 0) { | |
console.log('it removes from child windows of parent when window is closed') | |
} else { | |
console.log('it DOES NOT removes from child windows of parent when window is closed') | |
} | |
console.log('done now call after') | |
after() | |
console.log('new test calling before') | |
before(winArgs) | |
if (!c.isVisible() && !c.getParentWindow().isVisible()) { | |
console.log('it should not affect the show option') | |
} else { | |
console.log('it should not affect the show option') | |
} | |
after() | |
console.log('Calling done') | |
done() | |
}) | |
console.log('Closing') | |
c.close() | |
} | |
function checkEnabled(prefix) { | |
if (w.isEnabled()) { | |
console.log(prefix + ' Parent window enabled') | |
} else { | |
console.log(prefix + ' Parent window disabled') | |
} | |
} | |
function testModal(done) { | |
let winArgs = {show: false, parent: w, modal: true} | |
before(winArgs) | |
checkEnabled('') | |
c.show() | |
checkEnabled('After show') | |
after() | |
before(winArgs) | |
c.once('closed', () => { | |
checkEnabled('After close') | |
after() | |
before(winArgs) | |
let c2 = new BrowserWindow({show: false, parent: w, modal: true}) | |
c.show() | |
checkEnabled('After c show') | |
c2.show() | |
checkEnabled('After c2 show') | |
c.destroy() | |
checkEnabled('After c destroy') | |
c2.destroy() | |
checkEnabled('After c2 destroy') | |
done() | |
}) | |
c.show() | |
c.close() | |
} | |
// This method will be called when Electron has finished | |
// initialization and is ready to create browser windows. | |
// Some APIs can only be used after this event occurs. | |
app.on('ready', createWindow) | |
// Quit when all windows are closed. | |
app.on('window-all-closed', function () { | |
// On OS X it is common for applications and their menu bar | |
// to stay active until the user quits explicitly with Cmd + Q | |
if (process.platform !== 'darwin') { | |
app.quit() | |
} | |
}) | |
app.on('activate', function () { | |
// On OS X it's common to re-create a window in the app when the | |
// dock icon is clicked and there are no other windows open. | |
if (mainWindow === null) { | |
createWindow() | |
} | |
}) | |
// In this file you can include the rest of your app's specific main process | |
// code. You can also put them in separate files and require them here. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// This file is required by the index.html file and will | |
// be executed in the renderer process for that window. | |
// All of the Node.js APIs are available in this process. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
const {BrowserWindow} = require('electron') | |
const {emittedOnce} = require('./events-helpers') | |
exports.closeWindow = async (window = null, | |
{assertSingleWindow} = {assertSingleWindow: true}) => { | |
const windowExists = (window !== null) && !window.isDestroyed() | |
if (windowExists) { | |
const isClosed = emittedOnce(window, 'closed') | |
window.setClosable(true) | |
window.close() | |
await isClosed | |
} | |
if (assertSingleWindow) { | |
if (BrowserWindow.getAllWindows().length == 0) { | |
console.log('SUCCESS no window') | |
} else { | |
console.log(`FAIL have ${BrowserWindow.getAllWindows().length} windows`) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment