How to install a spellchecker in Electron for an external URL - node.js

I'm using a very simple Electron app to load a URL in a frameless window. Here's the app.js:
const {app, BrowserWindow} = require('electron')
let window = null
app.once('ready', () => {
window = new BrowserWindow({
width: 800,
height: 600,
icon: __dirname + '/icon/appIcon.png',
show: false,
webPreferences: {
nodeIntegration: false
}
})
window.loadURL('https://www.notion.so')
window.setMenuBarVisibility(false)
window.once('ready-to-show', () => {
// window.maximize()
window.show()
})
})
As Electron doesn't have all the same utilities as Chrome or Chromium, spell check does not work. I'm trying to install electron-spell-check-provider here but can't figure out how it works for the life of me. It has one snippet it says to paste in the renderer process, what section is that of this code?
I apologize if this is a very basic question, I'm still very new to Electron development and would be very grateful for help on this.

Related

how to connect sqlite3 with electron js

please guide me through a full process, that I connect my electron app with sqlite3.
because I have a lot of issues occurring in my electron js.
Thank you.
Main.js:
const{app,BrowserWindow,ipcMain}=require("electron");
app.on("ready",createWindow);
const si = require("systeminformation");
require("electron-reload")(__dirname);
function createWindow()
{
const window = new BrowserWindow({
width: 800,
height:600,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
}
});
window.webContents.openDevTools();
window.loadFile(__dirname+ "/index.html");
}
ipcMain.on("get-cpu-usage",(events,args)=>{
console.log(args);
});
renderer.js:
const{ipcRender} = require("electron")
const os=require("os");
const cpuName=document.getElementById("cpu-name");
const cpuCores =document.getElementById("cores");
const cpuUsage =document.getElementById("cpu-usage");
const cpus=os.cpus();
cpuName.innerText=`CPU: ${cpus[0].model}`;
cpuCores,innerText=`Cores Available: ${cpus.length}`;
setInterval(() =>{
console.log("sending message to get cpu stats")
ipcRender.send("get-cpu-usage", "Hello sheraz The render process")
},2000)
By far the easiest way to use SQLite with electron is with electron-builder.
First, add a postinstall step in your package.json:
"scripts": {
"postinstall": "install-app-deps"
...
}
and then install the necessary dependencies and build:
npm install --save-dev electron-builder
npm install --save sqlite3
npm run postinstall
electron-builder will build the native module for your platform, with the correct name for the Electron binding; and you can then require it in code as normal.

Problem with electron scrolling with Electron BrowserWindow();

I am having trouble getting my electron app to allow for scrolling. Please can someone give me some help? Here is my code below. Sorry I am still fairly new to electron and trying to get my head around it. The problem shows as the content in the browser window extends past the end of the window and I have no facility to scroll down using ether the trackpad or arrow keys.
function createWindow () {
server.run();
// Create the browser window.
mainWindow = new BrowserWindow({
width: 1024,
height: 768,
scrollBounce: false,
webPreferences: {
nodeIntegration: true,
contextIsolation: false,
zoomFactor: 0.8,
enableRemoteModule: false
},
frame: true,
minWidth: 1024,
minHeight: 768
});
// and load the index.html of the app.
mainWindow.loadURL('http://'+server.host+':'+server.port+'/')
/*
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, 'index.php'),
protocol: 'file:',
slashes: true
}))
*/
const {shell} = require('electron')
shell.showItemInFolder('fullPath')
// Open the DevTools.
// mainWindow.webContents.openDevTools()
// Emitted when the window is closed.
mainWindow.on('closed', function () {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
// PHP SERVER QUIT
server.close();
app.quit();
mainWindow = null;
})
}

Problem with open new browser using router in Vue/Electron. Redirecting to default route

I'm trying to open a new window using Vue/Electron but the new windows is opening on default rounte instead the needed route.
*The route on navigation-drawer is working well.
file: router/index.js
import Process from '#/components/ProcessManager/Process.vue'
export default new Router({
routes: [
{
path: '/',
name: 'home',
component: require('#/components/LandingPage').default
},
{
path: 'process',
name: 'process',
component: Process,
},
{
path: '*',
redirect: '/'
}
]
file:main/index.js
const processURL = process.env.NODE_ENV === 'development'
? `http://localhost:9080/#/process`
: `file://${__dirname}/index.html#process`
function createWindow2 () {
let win = new BrowserWindow({ width: 400, height: 320, webPreferences: {webSecurity: false} })
win.loadURL(processURL)
win.on('closed', () => {
win = null
})
}
It looks like it loads the index.html but does not start the app, and the reason is shown in the error message in the screenshot you supplied.
Looking at the error message, you can read here what's going on.

Ways to detect node environment in electron

I would like to know how can I detect the NODE_ENV variable inside the electron main file.
What I'm trying to do is to set the loadURL to localhost:8080 if my NODE_ENV === 'dev' otherwise to /dist/index.html. Because I want to use some webpack-dev-server features such as the HMR and live reload during the development.
I set my npm script in this way but I'm not sure if it is correct.
package.json
"scripts": {
"start": "electron .",
"start:dev": "NODE_ENV=dev webpack-dev-server --config webpack.dev.js && electron .",
"build": "NODE_ENV=prod webpack --config webpack.prod.js && electron ."
},
Here is my electron main file.
main.js
const electron = require('electron');
const url = require('url');
const path = require('path');
const { app, BrowserWindow } = electron;
let mainWindow = null;
app.on('ready', function() { // eslint-disable-line
mainWindow = new BrowserWindow({
webPreferences: {
nodeIntegration: true,
},
});
// mainWindow.loadURL('http://localhost:8080/');
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, '/dist/index.html'),
protocol: 'file:',
slashes: true,
}));
mainWindow.on('closed', function(){
app.quit();
});
});
I will share some of the code from a project I am working on that deals with this issue and hopefully it will help clarify how you might be able to solve your issue.
Electron considers the environment to always be "development" if you are not loading the app from an executable file after packaging the app with something like electron-builder or electron-packager.
Distinguishing "development" from "production" #7714
This has made it time consuming for me to test other items that behave differently in prod vs. dev, but at least that seems to consistently work.
Once this is understood you can use electron.app.isPackaged to set a variable in your main.js file that can be used to control certain functionality.
Demo below...let me know if you have confusion that is not explained in the commented parts of the code.
Here are the npm scripts I am using in a project running Electron v7.0.1:
"main": "main.js",
"scripts": {
"test": "jest",
"prod": "webpack --mode production --config webpack.build.config.js && electron --noDevServer .",
"start": "webpack-dev-server --hot --host 0.0.0.0 --config=./webpack.dev.config.js --mode development",
"build": "webpack --config webpack.build.config.js --mode production",
"package-mac": "electron-builder build --x64 --mac",
"package-all": "electron-builder build -mwl",
"package-linux": "electron-builder build --linux",
"gh-publish-mac": "electron-builder build --x64 --mac -p always",
"gh-publish": "electron-builder build -mwl -p always",
}
Here is code from the main.js file that is used to manage some functionality based on dev vs prod:
// Keep a reference for dev mode
let dev = false;
// this works if npm run build, followed by npm run package-(any of the scripts),
// and then open from executable file
dev = !app.isPackaged;
function createWindow() {
// Create the new browser window instance. devtools set to false in production
if (!dev) {
mainWindow = new BrowserWindow({
width: 2000,
height: 1000,
minWidth: 1304,
minHeight: 700,
backgroundColor: "-webkit-linear-gradient(top, #3dadc2 0%,#2f4858 100%)",
show: false,
title: "Swell",
allowRunningInsecureContent: true,
webPreferences: {
devTools: false,
nodeIntegration: true,
sandbox: false,
webSecurity: true,
},
icon: `${__dirname}/src/assets/icons/64x64.png`,
});
} else {
mainWindow = new BrowserWindow({
width: 2000,
height: 1000,
minWidth: 1304,
minHeight: 700,
backgroundColor: "-webkit-linear-gradient(top, #3dadc2 0%,#2f4858 100%)",
show: false,
title: "Swell",
allowRunningInsecureContent: true,
webPreferences: {
nodeIntegration: true,
sandbox: false,
webSecurity: true,
},
icon: `${__dirname}/src/assets/icons/64x64.png`,
});
}
if (dev) {
const {
default: installExtension,
REACT_DEVELOPER_TOOLS,
REDUX_DEVTOOLS,
} = require("electron-devtools-installer");
// If we are in developer mode Add React & Redux DevTools to Electon App
installExtension(REACT_DEVELOPER_TOOLS)
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log("An error occurred: ", err));
installExtension(REDUX_DEVTOOLS)
.then((name) => console.log(`Added Extension: ${name}`))
.catch((err) => console.log("An error occurred: ", err));
}
// and load the index.html of the app.
let indexPath;
if (dev && process.argv.indexOf("--noDevServer") === -1) {
// if we are in dev mode load up 'http://localhost:8080/index.html'
indexPath = url.format({
protocol: "http:",
host: "localhost:8080",
pathname: "index.html",
slashes: true,
});
} else {
indexPath = url.format({
// if we are not in dev mode load production build file
protocol: "file:",
pathname: path.join(__dirname, "dist", "index.html"),
slashes: true,
});
}
// our new app window will load content depending on the boolean value of the dev variable
mainWindow.loadURL(indexPath);
// give our new window the earlier created touchbar
mainWindow.setTouchBar(touchBar);
// prevent webpack-dev-server from setting new title
mainWindow.on("page-title-updated", (e) => e.preventDefault());
// Don't show until we are ready and loaded
mainWindow.once("ready-to-show", () => {
mainWindow.show();
// Open the DevTools automatically if developing
if (dev) {
mainWindow.webContents.openDevTools();
}
});
// Emitted when the window is closed.
mainWindow.on("closed", () => {
// Dereference the window object, usually you would store windows
// in an array if your app supports multi windows, this is the time
// when you should delete the corresponding element.
//tldr: Remove the BrowserWindow instance that we created earlier by setting its value to null when we exit Swell
mainWindow = null;
});
//require menu file
require("./menu/mainMenu");
}
// 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", () => {
// createLoadingScreen();
createWindow();
if (!dev) {
autoUpdater.checkForUpdates();
}
});
ipcMain.on("check-for-update", () => {
//listens to ipcRenderer in UpdatePopUpContainer.jsx
if (!dev) autoUpdater.checkForUpdates();
});
Well, some quick solution would be if statement
if(process.env.NODE_ENV === 'dev') {
mainWindow.loadURL('http://localhost:8080/')
} else {
mainWindow.loadURL(url.format({
pathname: path.join(__dirname, '/dist/index.html'),
protocol: 'file:',
slashes: true,
}));
}

Protractor generates an error when disabling flow control to test an Angular app

I've been struggling with this error for a while and I'm running out of mana. I'm currently trying to test an Angular app with protractor and async/await. According to the doc, I have to disable the control flow by adding the following to my config file:
SELENIUM_PROMISE_MANAGER: false but doing so produces the following error:
UnhandledPromiseRejectionWarning: Error: Error while waiting for Protractor to sync with the page: "both angularJS testability and angular testability are undefined. This could be either because this is a non-angular page or because your test involves client-side navigation, which can interfere with Protractor's bootstrapping. See https://github.com/angular/protractor/issues/2643 for details" I visited the url (https://github.com/angular/protractor/issues/2643) but it didn't turn out very helpful.
At this point I'm not sure if I'm doing something wrong or if it's a bug with protractor itself. For this reason I also opened an issue on GitHub.
Here is my test:
import {
browser,
ExpectedConditions,
$
} from 'protractor';
describe('When user click \"Test\" button', async () => {
beforeAll(async () => {
expect(browser.getCurrentUrl()).toContain('myawesomewebsite');
});
it ("should click the button", async () => {
var button = $(".button");
button.click();
});
});
And here is my full configuration:
exports.config = {
capabilities: {
'browserName': 'chrome'
},
seleniumAddress: 'http://localhost:4444/wd/hub',
framework: 'jasmine',
specs: ['test.spec.ts'],
SELENIUM_PROMISE_MANAGER: false,
jasmineNodeOpts: {
defaultTimeoutInterval: 30000
},
beforeLaunch: function () {
require('ts-node/register')
}
};
You missed await before each protractor api invoking.
describe('When user click \"Test\" button', async () => {
beforeAll(async () => {
expect(await browser.getCurrentUrl()).toContain('myawesomewebsite');
});
it ("should click the button", async () => {
var button = $(".button");
await button.click();
});
});
So, thanks to #CrispusDH on GitHub, I figured out that I could use waitForAngularEnabled in the configuration file and not just in the spec file. Using it in the spec file was not working, but if used in the onPrepare hook of the configuration file, the error goes away.
A lot of resources online were saying to set it to false, but this wasn't working for me as Protractor couldn't find element without waiting for Angular, so I did set it to false in the configuration and file but called browser.waitForAngularEnabled(true); in my specs file (beforeAll hook). Now the error is gone, allowing me to use async/await.
Here is the proper configuration to use:
SELENIUM_PROMISE_MANAGER: false,
onPrepare: async () => {
await browser.waitForAngularEnabled(false);
}
And here is the code to call in spec file:
beforeAll(async () => {
browser.waitForAngularEnabled(true);
});

Resources