electron-prompt
Advanced tools
Comparing version 0.5.0 to 1.0.0
137
lib/index.js
const electron = require('electron'); | ||
const BrowserWindow = electron.BrowserWindow || electron.remote.BrowserWindow; | ||
@@ -8,82 +9,86 @@ const ipcMain = electron.ipcMain || electron.remote.ipcMain; | ||
function electronPrompt(options, parentWindow) { | ||
return new Promise((resolve, reject) => { | ||
const id = `${new Date().getTime()}-${Math.random()}`; | ||
return new Promise((resolve, reject) => { | ||
const id = `${new Date().getTime()}-${Math.random()}`; | ||
const opts = Object.assign({ | ||
title: 'Prompt', | ||
label: 'Please input a value:', | ||
alwaysOnTop: false, | ||
value: null, | ||
type: 'input', | ||
selectOptions: null | ||
}, options || {}); | ||
const opts = Object.assign({ | ||
width: 370, | ||
height: 130, | ||
resizable: false, | ||
title: 'Prompt', | ||
label: 'Please input a value:', | ||
alwaysOnTop: false, | ||
value: null, | ||
type: 'input', | ||
selectOptions: null | ||
}, options || {}); | ||
if(opts.type == 'select' && (opts.selectOptions === null || typeof(opts.selectOptions) !== 'object')) { | ||
return reject(new Error('"selectOptions" must be an object')); | ||
} | ||
if (opts.type === 'select' && (opts.selectOptions === null || typeof (opts.selectOptions) !== 'object')) { | ||
return reject(new Error('"selectOptions" must be an object')); | ||
} | ||
let promptWindow = new BrowserWindow({ | ||
width: 370, height: 130, | ||
resizable: false, | ||
parent: parentWindow ? (parentWindow instanceof BrowserWindow) : null, | ||
skipTaskbar: true, | ||
alwaysOnTop: opts.alwaysOnTop, | ||
useContentSize: true, | ||
modal: parentWindow ? true : false, | ||
title : opts.title | ||
}); | ||
let promptWindow = new BrowserWindow({ | ||
width: opts.width, | ||
height: opts.height, | ||
resizable: opts.resizable, | ||
parent: parentWindow ? (parentWindow instanceof BrowserWindow) : null, | ||
skipTaskbar: true, | ||
alwaysOnTop: opts.alwaysOnTop, | ||
useContentSize: true, | ||
modal: Boolean(parentWindow), | ||
title: opts.title | ||
}); | ||
promptWindow.setMenu(null); | ||
promptWindow.setMenu(null); | ||
const getOptionsListener = (event) => { | ||
event.returnValue = JSON.stringify(opts); | ||
}; | ||
const getOptionsListener = event => { | ||
event.returnValue = JSON.stringify(opts); | ||
}; | ||
const postDataListener = (event, value) => { | ||
resolve(value); | ||
event.returnValue = null; | ||
cleanup(); | ||
}; | ||
const cleanup = () => { | ||
if (promptWindow) { | ||
promptWindow.close(); | ||
promptWindow = null; | ||
} | ||
}; | ||
const unresponsiveListener = () => { | ||
reject(new Error('Window was unresponsive')); | ||
cleanup(); | ||
}; | ||
const postDataListener = (event, value) => { | ||
resolve(value); | ||
event.returnValue = null; | ||
cleanup(); | ||
}; | ||
const errorListener = (event, message) => { | ||
reject(new Error(message)); | ||
event.returnValue = null; | ||
cleanup(); | ||
}; | ||
const unresponsiveListener = () => { | ||
reject(new Error('Window was unresponsive')); | ||
cleanup(); | ||
}; | ||
const cleanup = () => { | ||
if (promptWindow) { | ||
promptWindow.close(); | ||
promptWindow = null; | ||
} | ||
}; | ||
const errorListener = (event, message) => { | ||
reject(new Error(message)); | ||
event.returnValue = null; | ||
cleanup(); | ||
}; | ||
ipcMain.on('prompt-get-options:' + id, getOptionsListener); | ||
ipcMain.on('prompt-post-data:' + id, postDataListener); | ||
ipcMain.on('prompt-error:' + id, errorListener); | ||
promptWindow.on('unresponsive', unresponsiveListener); | ||
ipcMain.on('prompt-get-options:' + id, getOptionsListener); | ||
ipcMain.on('prompt-post-data:' + id, postDataListener); | ||
ipcMain.on('prompt-error:' + id, errorListener); | ||
promptWindow.on('unresponsive', unresponsiveListener); | ||
promptWindow.on('closed', () => { | ||
ipcMain.removeListener('prompt-get-options:' + id, getOptionsListener); | ||
ipcMain.removeListener('prompt-post-data:' + id, postDataListener); | ||
ipcMain.removeListener('prompt-error:' + id, postDataListener); | ||
resolve(null); | ||
}); | ||
promptWindow.on('closed', () => { | ||
ipcMain.removeListener('prompt-get-options:' + id, getOptionsListener); | ||
ipcMain.removeListener('prompt-post-data:' + id, postDataListener); | ||
ipcMain.removeListener('prompt-error:' + id, postDataListener); | ||
resolve(null); | ||
}); | ||
const promptUrl = url.format({ | ||
protocol: 'file', | ||
slashes: true, | ||
pathname: path.join(__dirname, 'page', 'prompt.html'), | ||
hash: id | ||
}); | ||
const promptUrl = url.format({ | ||
protocol: 'file', | ||
slashes: true, | ||
pathname: path.join(__dirname, 'page', 'prompt.html'), | ||
hash: id | ||
}); | ||
promptWindow.loadURL(promptUrl); | ||
}); | ||
promptWindow.loadURL(promptUrl); | ||
}); | ||
} | ||
module.exports = electronPrompt; | ||
module.exports = electronPrompt; |
@@ -1,99 +0,105 @@ | ||
const { ipcRenderer } = require('electron'); | ||
const {ipcRenderer} = require('electron'); | ||
const docReady = require('doc-ready'); | ||
let promptId, promptOptions; | ||
window.onerror = (error) => { | ||
if(promptId) { | ||
promptError("An error has occured on the prompt window: \n"+error); | ||
} | ||
let promptId = null; | ||
let promptOptions = null; | ||
const promptError = e => { | ||
if (e instanceof Error) { | ||
e = e.message; | ||
} | ||
ipcRenderer.sendSync('prompt-error:' + promptId, e); | ||
}; | ||
const promptError = (e) => { | ||
if(e instanceof Error) { | ||
e = e.message; | ||
} | ||
ipcRenderer.sendSync('prompt-error:'+promptId, e); | ||
} | ||
const promptCancel = () => { | ||
ipcRenderer.sendSync('prompt-post-data:'+promptId, null); | ||
} | ||
ipcRenderer.sendSync('prompt-post-data:' + promptId, null); | ||
}; | ||
const promptSubmit = () => { | ||
const dataEl = document.getElementById('data'); | ||
let data = null; | ||
const dataEl = document.getElementById('data'); | ||
let data = null; | ||
if(promptOptions.type === 'input') { | ||
data = dataEl.value | ||
} else if(promptOptions.type === 'select') { | ||
if(promptOptions.selectMultiple) { | ||
data = dataEl.querySelectorAll('option[selected]').map((o) => o.getAttribute('value')); | ||
} else { | ||
data = dataEl.value; | ||
} | ||
} | ||
ipcRenderer.sendSync('prompt-post-data:'+promptId, data); | ||
} | ||
if (promptOptions.type === 'input') { | ||
data = dataEl.value; | ||
} else if (promptOptions.type === 'select') { | ||
if (promptOptions.selectMultiple) { | ||
data = dataEl.querySelectorAll('option[selected]').map(o => o.getAttribute('value')); | ||
} else { | ||
data = dataEl.value; | ||
} | ||
} | ||
ipcRenderer.sendSync('prompt-post-data:' + promptId, data); | ||
}; | ||
window.addEventListener('error', error => { | ||
if (promptId) { | ||
promptError('An error has occured on the prompt window: \n' + error); | ||
} | ||
}); | ||
docReady(() => { | ||
promptId = document.location.hash.replace('#',''); | ||
promptId = document.location.hash.replace('#', ''); | ||
try { | ||
promptOptions = JSON.parse(ipcRenderer.sendSync('prompt-get-options:'+promptId)); | ||
} catch(e) { | ||
return promptError(e); | ||
} | ||
try { | ||
promptOptions = JSON.parse(ipcRenderer.sendSync('prompt-get-options:' + promptId)); | ||
} catch (e) { | ||
return promptError(e); | ||
} | ||
document.getElementById("label").textContent = promptOptions.label; | ||
document.getElementById("ok").addEventListener('click', () => promptSubmit()); | ||
document.getElementById("cancel").addEventListener('click', () => promptCancel()); | ||
document.getElementById('label').textContent = promptOptions.label; | ||
document.getElementById('ok').addEventListener('click', () => promptSubmit()); | ||
document.getElementById('cancel').addEventListener('click', () => promptCancel()); | ||
const dataContainerEl = document.getElementById('data-container'); | ||
const dataContainerEl = document.getElementById('data-container'); | ||
let dataEl; | ||
if(promptOptions.type === 'input') { | ||
dataEl = document.createElement('input'); | ||
dataEl.setAttribute('type', 'text'); | ||
let dataEl; | ||
if (promptOptions.type === 'input') { | ||
dataEl = document.createElement('input'); | ||
dataEl.setAttribute('type', 'text'); | ||
if(promptOptions.value) { | ||
dataEl.value = promptOptions.value; | ||
} else { | ||
dataEl.value = ''; | ||
} | ||
if(promptOptions.inputAttrs && typeof(promptOptions.inputAttrs) === 'object') { | ||
for(let k in promptOptions.inputAttrs) { | ||
if(!promptOptions.inputAttrs.hasOwnProperty(k)) continue; | ||
if (promptOptions.value) { | ||
dataEl.value = promptOptions.value; | ||
} else { | ||
dataEl.value = ''; | ||
} | ||
dataEl.setAttribute(k, promptOptions.inputAttrs[k]); | ||
} | ||
} | ||
if (promptOptions.inputAttrs && typeof (promptOptions.inputAttrs) === 'object') { | ||
for (const k in promptOptions.inputAttrs) { | ||
if (!Object.prototype.hasOwnProperty.call(promptOptions.inputAttrs, k)) { | ||
continue; | ||
} | ||
dataEl.addEventListener('keyup', (e) => { | ||
e.which = e.which || e.keyCode; | ||
if(e.which == 13) { | ||
promptSubmit(); | ||
} | ||
}); | ||
} else if(promptOptions.type === 'select') { | ||
dataEl = document.createElement('select'); | ||
let optionEl; | ||
dataEl.setAttribute(k, promptOptions.inputAttrs[k]); | ||
} | ||
} | ||
for(let k in promptOptions.selectOptions) { | ||
if(!promptOptions.selectOptions.hasOwnProperty(k)) continue; | ||
optionEl = document.createElement('option'); | ||
optionEl.setAttribute('value', k); | ||
optionEl.textContent = promptOptions.selectOptions[k]; | ||
if(k === promptOptions.value) { | ||
optionEl.setAttribute('selected', 'selected'); | ||
} | ||
dataEl.appendChild(optionEl); | ||
} | ||
} | ||
dataEl.addEventListener('keyup', e => { | ||
e.which = e.which || e.keyCode; | ||
if (e.which === 13) { | ||
promptSubmit(); | ||
} | ||
}); | ||
} else if (promptOptions.type === 'select') { | ||
dataEl = document.createElement('select'); | ||
let optionEl; | ||
dataContainerEl.appendChild(dataEl); | ||
dataEl.setAttribute('id', 'data'); | ||
for (const k in promptOptions.selectOptions) { | ||
if (!Object.prototype.hasOwnProperty.call(promptOptions.selectOptions, k)) { | ||
continue; | ||
} | ||
dataEl.focus(); | ||
optionEl = document.createElement('option'); | ||
optionEl.setAttribute('value', k); | ||
optionEl.textContent = promptOptions.selectOptions[k]; | ||
if (k === promptOptions.value) { | ||
optionEl.setAttribute('selected', 'selected'); | ||
} | ||
dataEl.appendChild(optionEl); | ||
} | ||
} | ||
dataContainerEl.appendChild(dataEl); | ||
dataEl.setAttribute('id', 'data'); | ||
dataEl.focus(); | ||
}); |
{ | ||
"name": "electron-prompt", | ||
"version": "0.5.0", | ||
"version": "1.0.0", | ||
"description": "Electron helper to prompt for a value via input or select", | ||
"main": "lib/index.js", | ||
"keywords": [ | ||
@@ -21,5 +20,18 @@ "electron", | ||
"license": "MIT", | ||
"main": "lib/index.js", | ||
"scripts": { | ||
"lint": "xo", | ||
"lint:fix": "xo --fix", | ||
"test": "npm run lint" | ||
}, | ||
"xo": { | ||
"esnext": true, | ||
"env": ["node", "browser"] | ||
}, | ||
"dependencies": { | ||
"doc-ready": "^1.0.4" | ||
}, | ||
"devDependencies": { | ||
"xo": "^0.21.1" | ||
} | ||
} |
@@ -5,5 +5,7 @@ # electron-prompt | ||
[![Build Status](https://travis-ci.com/sperrichon/electron-prompt.svg?branch=master)](https://travis-ci.com/sperrichon/electron-prompt) [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg)](https://github.com/xojs/xo) | ||
## Usage | ||
``` | ||
```sh | ||
npm install electron-prompt --save | ||
@@ -25,16 +27,43 @@ ``` | ||
value: 'http://example.org', | ||
inputAttrs: { // attrs to be set if using 'input' | ||
inputAttrs: { | ||
type: 'url' | ||
}, | ||
type: 'select', // 'select' or 'input, defaults to 'input' | ||
selectOptions: { // select options if using 'select' type | ||
'value 1': 'Display Option 1', | ||
'value 2': 'Display Option 2', | ||
'value 3': 'Display Option 3' | ||
} | ||
type: 'select' | ||
}) | ||
.then((r) => { | ||
console.log('result', r); // null if window was closed, or user clicked Cancel | ||
if(r === null) { | ||
console.log('user cancelled'); | ||
} else { | ||
console.log('result', r); | ||
} | ||
}) | ||
.catch(console.error); | ||
``` | ||
## Documentation | ||
Primary method: | ||
```js | ||
prompt([options, parentBrowserWindow]).then(...).catch(...) | ||
``` | ||
### Options object (optional) | ||
| Key | Explaination | | ||
| ------------- | ------------- | | ||
| width | (optional, integer) The width of the prompt window. Defaults to 370. | | ||
| height | (optional, integer) The height of the prompt window. Defaults to 130. | | ||
| resizable | (optional, boolean) Whether the prompt window can be resized or not. Defaults to false. | | ||
| title | (optional, string) The title of the prompt window. Defaults to 'Prompt'. | | ||
| label | (optional, string) The label which appears on the prompt for the input field. Defaults to 'Please input a value:'. | | ||
| value | (optional, string) The default value for the input field. Defaults to null.| | ||
| type | (optional, string) The type of input field, either 'input' for a standard text input field or 'select' for a dropdown type input. Defaults to 'input'.| | ||
| inputAttrs | (optional, object) The attributes of the input field, analagous to the HTML attributes: `{type: 'text', required: true}` -> `<input type="text" required>`. Used if the type is 'input' | | ||
| selectOptions | (optional, object) The items for the select dropdown if using te 'select' type in the format 'value': 'display text', where the value is what will be given to the then block and the display text is what the user will see. | | ||
If not supplied, it uses the defaults listed in the table above. | ||
### parentBrowserWindow | ||
(optional) The window in which to display the prompt on. If not supplied, the parent window of the prompt will be null. |
Sorry, the diff of this file is not supported yet
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
10188
8
223
1
68
1