-
-
Save PsyGik/c7a896b16d892b31f7817c09abd05ff1 to your computer and use it in GitHub Desktop.
This is an example of how to poll the clipboard for changes in an Electron application. See notes in 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
<!DOCTYPE html> | |
<html lang="en"> | |
<head> | |
<title>My App - Clipboard</title> | |
<meta charset="utf-8"> | |
<meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self' chrome-extension://*;"> | |
</head> | |
<body> | |
<-- | |
This is an example of how to poll the clipboard for changes in an Electron application. | |
In this example I'm monitoring the clipboard for the possibility of the user copying a login token - | |
identified by a prefix - from an email, and then I notify the rest of the app (not shown in this gist) | |
so the token can be pasted automatically into a login form. | |
The clipboard.js code creates a hidden Electron window containing this HTML, which is essentially an empty document. | |
It also does preload injection with preload_clipboard.js, which is what polls the clipboard every 250 ms. | |
The code is run in a separate window like this so it doesn't load the main Electron-Node process. | |
However, you could run the polling code anywhere that you can access the require('electron') object. | |
--> | |
</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
"use strict"; | |
// Import dependencies. | |
let electron = require('electron'); | |
let emitter = require('events').EventEmitter; | |
let path = require('path'); | |
let url = require('url'); | |
// Constants. | |
const LOGIN_TOKEN_PREFIX = 'my-app:login-token#'; | |
/*================================================================================================*/ | |
/*································································································*/ | |
/* | |
Constructor to create a clipboard instance and initialise its data. | |
*/ | |
function Clipboard() | |
{ | |
Object.defineProperty(this, 'window', {value: null, writable: true}); // The clipboard window. | |
// Setup event handlers for IPC messages. | |
electron.ipcMain.on('clipboard_message', this.ipc_message_handler.bind(this)); | |
// Startup the database window. | |
this.create_window(); | |
} | |
// Set the inheritance prototype of the constructor and name it. | |
Clipboard.prototype = Object.create(emitter.prototype, {constructor: {value: Clipboard}}); | |
Clipboard.prototype.name = '<Clipboard>'; | |
/*================================================================================================*/ | |
/*································································································*/ | |
/* | |
Save any data and close window. | |
*/ | |
Clipboard.prototype.shutdown = function shutdown() | |
{ | |
// Close the window. | |
this.window.close(); | |
} | |
/*································································································*/ | |
/* | |
Create the clipboard window. | |
*/ | |
Clipboard.prototype.create_window = function create_window() | |
{ | |
// Create the browser window. | |
this.window = new electron.BrowserWindow( | |
{ | |
width: 0, | |
height: 0, | |
show: false, | |
webPreferences: | |
{ | |
nodeIntegration: false, | |
preload: path.join(__dirname, 'preload_injectors', 'preload_clipboard.js'), | |
contextIsolation: true | |
} | |
} | |
); | |
// Load the base HTML of the application. | |
this.window.loadURL(url.format( | |
{ | |
pathname: path.join(__dirname, 'clipboard', 'clipboard.html'), | |
protocol: 'file:', | |
slashes: true | |
} | |
)); | |
// Open the Chrome Dev Tools. | |
// this.window.webContents.openDevTools(); | |
// Setup window event handlers. | |
this.window.on('closed', this.window_closed.bind(this)); | |
} | |
/*································································································*/ | |
/* | |
Cleanup after the window is closed. | |
*/ | |
Clipboard.prototype.window_closed = function window_closed() | |
{ | |
// Dereference the window object. | |
this.window = null; | |
} | |
/*································································································*/ | |
/* | |
Handle asynchronous clipboard messages coming in. | |
*/ | |
Clipboard.prototype.ipc_message_handler = function ipc_message_handler(event, message) | |
{ | |
switch(message.action) | |
{ | |
case 'clipboard_changed': | |
if(message.value.indexOf(LOGIN_TOKEN_PREFIX) === 0) | |
{ | |
// Notify rest of application that useful clipboard content was found. | |
this.emit('clipboard_login_token', message.value.substr(LOGIN_TOKEN_PREFIX.length)); | |
} | |
break; | |
} | |
} | |
/*================================================================================================*/ | |
module.exports = Clipboard; | |
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
"use strict"; | |
let electron = require('electron'); | |
let last_value = null; | |
/*================================================================================================*/ | |
/*································································································*/ | |
function post_ipc_message(message) | |
{ | |
electron.ipcRenderer.send('clipboard_message', message); | |
} | |
/*································································································*/ | |
/* | |
Normally the listener would take the form: function listener(event, message){}. | |
However, because our windows are sandboxed the event parameter is dropped and all we get | |
is the message parameter, so the listener needs to be: function listener(message){}. | |
*/ | |
function add_ipc_message_listener(listener) | |
{ | |
electron.ipcRenderer.on('ipc_message', listener); | |
} | |
/*································································································*/ | |
function remove_ipc_message_listener(listener) | |
{ | |
electron.ipcRenderer.removeListener('ipc_message', listener); | |
} | |
/*================================================================================================*/ | |
function check_clipboard_for_changes() | |
{ | |
let value = electron.clipboard.readText(); | |
if(last_value !== value)clipboard_changed(value); | |
} | |
function clipboard_changed(value) | |
{ | |
last_value = value; | |
post_ipc_message({action: 'clipboard_changed', value: value}); | |
} | |
// Get the initial value of the clipboard. | |
clipboard_changed(electron.clipboard.readText()); | |
// Check for changes at an interval. | |
setInterval(check_clipboard_for_changes, 250); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment