I'm implementing a web browser using react + electron. Here, I'm using electron webview tag to display the guest page, for example, http://google.com. Here, when I take my mouse over a hyperlink or anchor tag, I want to get that information to my to react app. I implemented it in the following way, but it is not working as expected. Very much appreciate if one can show why is it not working.
This is how I create the Browser window using electron.
const { app, BrowserWindow, dialog } = require('electron');
const path = require('path');
const serve = require('electron-serve');
const loadURL = serve({ directory: 'build' });
let mainWindow;
function isDev() {
return !app.isPackaged;
}
function createWindow() {
mainWindow = new BrowserWindow({
width: 1366,
height: 768,
frame: false,
webPreferences: {
nodeIntegration: true,
enableRemoteModule: true,
webviewTag: true
},
icon: isDev() ? path.join(process.cwd(), 'public/logo.png') : path.join(__dirname, 'build/logo.png'),
show: false
});
if (isDev()) {
mainWindow.loadURL('http://localhost:3000/');
} else {
loadURL(mainWindow);
}
mainWindow.on('closed', function () {
mainWindow = null
});
mainWindow.once('ready-to-show', () => {
mainWindow.show()
});
}
app.on('ready', createWindow);
app.on('window-all-closed', function () {
if (process.platform !== 'darwin') app.quit()
});
app.on('activate', function () {
if (mainWindow === null) createWindow()
});
Then in the react index.js (render), I added the following code to create the ipc-message
event.
const webviewEvents = {
'load-commit': 'onLoadCommit',
'did-start-loading': 'onDidStartLoading',
'did-stop-loading': 'onDidStopLoading',
'did-finish-load': 'onDidFinishLoading',
'did-fail-load': 'onDidFailLoad',
'did-get-response-details': 'onDidGetResponseDetails',
'did-get-redirect-request': 'onDidGetRedirectRequest',
'dom-ready': 'onDomReady',
'page-title-set': 'onPageTitleSet',
'close': 'onClose',
'destroyed': 'onDestroyed',
'ipc-message': 'onIpcMessage',
'console-message': 'onConsoleMessage'
};
function webviewHandler (self, fnName) {
return function (e) {
if (self.props[fnName])
self.props[fnName](e, self.props.page, self.props.pageIndex);
};
}
class BrowserPage extends React.Component {
componentDidMount() {
...
// attach webview events
for (var k in webviewEvents)
ReactDOM.findDOMNode(this.refs.webview).addEventListener(k, webviewHandler(this, webviewEvents[k]));
}
So, now I'm having ipc-message
function as below.
onIpcMessage: function (e, page, pageIndex) {
alert(e.args[0]);
}
I'm having preload.js file to inject Javascript code to the webview.
const {ipcRenderer} = window.require('electron');
function setStatus (status) {
ipcRenderer.sendToHost('status', status);
}
window.addEventListener('mouseover', function (e) {
var el = e.target;
while (el) {
if (el.tagName == 'A') {
// set to title or href
if (el.getAttribute('title'))
setStatus(el.getAttribute('title'));
else if (el.href)
setStatus(el.href);
return
}
el = el.parentNode;
}
setStatus(false);
});
This preload file is imported to index.js through import and added to the webview as below.
import preload from './preload.js';
...
render() {
return <div id="browser-page" className={this.props.isActive ? 'visible' : 'hidden'}>
<BrowserPageSearch isActive={this.props.page.isSearching} onPageSearch={this.onPageSearch} />
<webview ref="webview" preload={preload} onContextMenu={this.props.onContextMenu} />
<BrowserPageStatus page={this.props.page} />
</div>;
}
Can anyone tell why my code is not working as expected?
Thanks.
question from:
https://stackoverflow.com/questions/65843570/how-to-get-mouse-events-from-electron-webview-to-a-react-app