How to fix "Not allowed to load local resource" Node-JS - node.js

I am making an Electron app that when a button is clicked it creates a new window and loads HTML into it, but for some reason the HTML isn't loaded into it and when I toggle developer tools for the window it shows me in the console this error:
"Not allowed to load local resource". It doesn't tell me a specific line.
const electron = require('electron');
const {ipcRenderer} = electron;
const {BrowserWindow} = electron.remote;
// NewTODO window variable
let newTodoWindow;
// Function to call when "New todo" button is clicked
function NewTodo(){
// Creates a NewTODO window
createTodoWindow();
}
function createTodoWindow(){
newTodoWindow = new BrowserWindow({});
newTodoWindow.loadFile("./newTodoWindow.html");
newTodoWindow.setSize(400 , 400);
}
All it needs to do is that when createTodoWindow function is called(And it is called) it would create a new window and load the HTML to it, but it only creates the window without loading the HTML.
I am not sure why that goes like and I would really appreciate getting help.

So apparently this error occurs when trying to require a file that doesn't exist and that's exactly what I tried doing, For some reason I changed the file I tried requiring and just forgot to require the file with the right name.

Related

#material material-component-web Invalid tab component given as activeTab

firstly let my say that the mdc documentation is difficult for non-pros like me.
I'm using Elixir Phoenix and Brunch.
I import and everything is fine.
import {MDCTab, MDCTabFoundation} from '#material/tabs'; import
{MDCTabBar, MDCTabBarFoundation} from '#material/tabs'; import
{MDCTabBarScroller, MDCTabBarScrollerFoundation} from
'#material/tabs';
I manually instantiate the tab bar in a separate function that I export
export var Tabbable = {
run: function(MDCTabBar, el){
var myDynamicTabBar = window.myDynamicTabBar = new MDCTabBar(document.querySelector('#' + el));
Which is following the documentation like this
const tabBar = new MDCTabBar(document.querySelector('#my-mdc-tab-bar'));
but is slightly different to the documentation's use of the tab bar in their code snippet
var dynamicTabBar = window.dynamicTabBar = new mdc.tabs.MDCTabBar(document.querySelector('#dynamic-tab-bar'));
But, whenever I try to use mdc I get a 'not defined' error. Therefore, I'm not using it :-)
Now, when the user clicks the tab bar I capture that like this:
myDynamicTabBar.listen('MDCTabBar:change', function ({detail: tabs}) {
var nthChildIndex = tabs.activeTabIndex;
updatePanel(nthChildIndex);
});
The subtle difference is that my myDynamicTabBar is MDCTabBar but the documentation's dynamicTabBar is mdc.tabs.MDCTabBar
My tab control works, but it throws an error only visible in the console:
Uncaught Error: Invalid tab component given as activeTab: Tab not
found within this component's tab list
which is likely because I'm not using mdc.tabs? The documentation notes the change event happens on the MDCTabBar.
Therefore, how do I get rid of this annoying error in the console?
And why can I not access the global mdc? I have tried this in my Brunch file
globals: { mdc: "#material"}
But no good.
I'm right behind you on this! I'm frustrated with the docs too :(
You answered your own question in this Elixir thread which is very informative.
I found the real solution in this thread https://github.com/hyperapp/hyperapp/issues/546
MDCTabBar automatically initiates its children. So initiating tabs will result in that error.
The fix is to just initiate MDCTabBar

Electron app installed but doesn't appear in start menu

I've created an app using Electron, and bundled it in an .exe file with electron-builder.
When I run the generated executable, the application starts with the default installation GIF used by electron-builder, as expected.
After the GIF finishes, the app restarts and works properly. It even appears in control panel's programs list.
However, if I look for it in the start menu applications, it isn't there (and searching it by its name only returns the aforementioned .exe installer).
Because of this, once the app is closed, the only way to open it back is running again the installer.
Why does this happen? Is there any way to make it appear with the other programs?
The electron-builder installer (and electron-windows-installer) use Squirrel for handling the installation. Squirrel launches your application on install with arguments that you need to handle. An example can be found on the windows installer github docs
Handling Squirrel Events
Squirrel will spawn your app with command line flags on first run, updates, and uninstalls. it is very important that your app handle these events as early as possible, and quit immediately after handling them. Squirrel will give your app a short amount of time (~15sec) to apply these operations and quit.
The electron-squirrel-startup module will handle the most common events for you, such as managing desktop shortcuts. Just add the following to the top of your main.js and you're good to go:
if (require('electron-squirrel-startup')) return;
You should handle these events in your app's main entry point with something such as:
const app = require('app');
// this should be placed at top of main.js to handle setup events quickly
if (handleSquirrelEvent()) {
// squirrel event handled and app will exit in 1000ms, so don't do anything else
return;
}
function handleSquirrelEvent() {
if (process.argv.length === 1) {
return false;
}
const ChildProcess = require('child_process');
const path = require('path');
const appFolder = path.resolve(process.execPath, '..');
const rootAtomFolder = path.resolve(appFolder, '..');
const updateDotExe = path.resolve(path.join(rootAtomFolder, 'Update.exe'));
const exeName = path.basename(process.execPath);
const spawn = function(command, args) {
let spawnedProcess, error;
try {
spawnedProcess = ChildProcess.spawn(command, args, {detached: true});
} catch (error) {}
return spawnedProcess;
};
const spawnUpdate = function(args) {
return spawn(updateDotExe, args);
};
const squirrelEvent = process.argv[1];
switch (squirrelEvent) {
case '--squirrel-install':
case '--squirrel-updated':
// Optionally do things such as:
// - Add your .exe to the PATH
// - Write to the registry for things like file associations and
// explorer context menus
// Install desktop and start menu shortcuts
spawnUpdate(['--createShortcut', exeName]);
setTimeout(app.quit, 1000);
return true;
case '--squirrel-uninstall':
// Undo anything you did in the --squirrel-install and
// --squirrel-updated handlers
// Remove desktop and start menu shortcuts
spawnUpdate(['--removeShortcut', exeName]);
setTimeout(app.quit, 1000);
return true;
case '--squirrel-obsolete':
// This is called on the outgoing version of your app before
// we update to the new version - it's the opposite of
// --squirrel-updated
app.quit();
return true;
}
};
Notice that the first time the installer launches your app, your app will see a --squirrel-firstrun flag. This allows you to do things like showing up a splash screen or presenting a settings UI. Another thing to be aware of is that, since the app is spawned by squirrel and squirrel acquires a file lock during installation, you won't be able to successfully check for app updates till a few seconds later when squirrel releases the lock.
In this example you can see it run Update.exe (a squirrel executable) with the argument --create-shortcut that adds start menu and desktop shortcuts.
It's 2021 and I am still having a very similar problem.
My app installs correctly and with the script above it also successfully adds a Desktop link to my app. BUT: There is no Shortcut being added to the Windows Start Menu.
With the script above this should also be added to the Start Menu, right?
One comment above says:
// Install desktop and start menu shortcuts
spawnUpdate(['--createShortcut', exeName]);
What am I missing? Any hint highly appreciated...
For me it helped to add icon and setupIcon to the package.json file, where the makers, are configured. Before my app didnt show up in the Start menu, and with the maker config as below, it does. I am not sure why though.
"makers": [
{
"name": "#electron-forge/maker-squirrel",
"config": {
"name": "cellmonitor",
"icon": "favicon.ico",
"setupIcon": "favicon.ico"
}
}
]

Error `window not defined` in Node.js

I know window doesn't exist in Node.js, but I'm using React and the same code on both client and server. Any method I use to check if window exists nets me:
Uncaught ReferenceError: window is not defined
How do I get around the fact that I can't do window && window.scroll(0, 0)?
Sawtaytoes has got it. I would run whatever code you have in componentDidMount() and surround it with:
if (typeof(window) !== 'undefined') {
// code here
}
If the window object is still not being created by the time React renders the component, you can always run your code a fraction of a second after the component renders (and the window object has definitely been created by then) so the user can't tell the difference.
if (typeof(window) !== 'undefined') {
var timer = setTimeout(function() {
// code here
}, 200);
}
I would advise against putting state in the setTimeout.
This will settle that issue for you:
typeof(window) === 'undefined'
Even if a variable isn't defined, you can use typeof() to check for it.
This kind of code shouldn't even be running on the server, it should be inside some componentDidMount (see doc) hook, which is only invoke client side. This is because it doesn't make sense to scroll the window server side.
However, if you have to reference to window in a part of your code that really runs both client and server, use global instead (which represents the global scope - e.g. window on the client).
This is a little older but for ES6 style react component classes you can use this class decorator I created as a drop in solution for defining components that should only render on the client side. I like it better than dropping window checks in everywhere.
import { clientOnly } from 'client-component';
#clientOnly
class ComponentThatAccessesWindowThatIsNotSafeForServerRendering extends Component {
render() {
const currentLocation = window.location;
return (
<div>{currentLocation}</div>
)
};
}
https://github.com/peterlazzarino/client-component
<Router onUpdate={() => window.scrollTo(0, 0)} history= {browserHistory}>
if you need to open new page on top in React JS app, use this code in router.js
Move the window and related code to the mounted() lifecycle hook. This is because mounted() hook is called on the client side only and window is available there.

Unable to open local file using cordova inappbrowser on windows 8.1 platform

I am developing a phone gap application and we've recently added support for the windows 8.1 platform. The application downloads/creates files which are saved to the device using the Cordova FileSystem API.
I have successfully saved a file to the device using a URL which looks like this
ms-appdata:///local/file.png
I have checked on my PC and the file is viewable inside the LocalState folder under the app's root folder. However, when I try to open this file using inAppBrowser nothing happens; no error message is being reported and none of the inAppBrowser default events fire.
function empty() { alert('here'); } //never fires
var absoluteUrl = "ms-appdata:///local/file.png";
cordova.InAppBrowser.open(absoluteURL, "_blank", "location=no", { loadstart: empty, loadstop: empty, loaderror: empty });
I have verified that the url is valid by calling the following built-in javascript on the url
Windows.Storage.StorageFile.getFileFromApplicationUriAsync(uri).done(function (file) {
debugger; //the file object contains the correct path to the file; C:\...etc.
});
Also, adding the url as the src for an img tag works as expected.
I have also tried attaching the inAppBrowser handlers using addEventListener("loadstart") etc. but none of them are firing either. However, when I try to open "http://www.google.com" the events do fire and the inAppBrowser pops up on the screen.
After inspecting the dom I can see that the inAppBrowser element has been added, but it doesn't appear to have a source attribute set
<div class="inAppBrowserWrap">
<x-ms-webview style="border-width: 0px; width: 100%; height: 100%;"></x-ms-webview>
</div>
I have looked at other questions such as this one but to no avail. I have verified that
a) InAppBrowser is installed
b) deviceReady has fired
I have also tried changing the target to "_self" (same issue) and "_system" (popup saying you need a new app to open a file of type msappdata://) and I'm running out of ideas. Has anybody come across similar issues?
I had a similar problem. My cordova app downloads a file and then opens it with native browser (so that images, PDF files and so on are properly handled).
In the end I had to modify InAppBrowserProxy.js class (part of InAppBrowser plugin for Windows platform).
This is the code that opens the file (plain JavaScript):
// This value comes from somewhere, I write it here as an example
var path = 'ms-appdata:///local//myfile.jpg';
// Open file in InAppBrowser
window.open(path, '_system', 'location=no');
Then, I updated InAppBrowserProxy.js file (under platforms\windows\www\plugins\cordova-plugin-inappbrowser\src\windows). I replaced this code fragment:
if (target === "_system") {
url = new Windows.Foundation.Uri(strUrl);
Windows.System.Launcher.launchUriAsync(url);
}
By this:
if (target === "_system") {
if (strUrl.indexOf('ms-appdata:///local//') == 0) {
var fileName = decodeURI(strUrl.substr(String(strUrl).lastIndexOf("/") + 1));
var localFolder = Windows.Storage.ApplicationData.current.localFolder;
localFolder.getFileAsync(fileName).then(function (file) {
Windows.System.Launcher.launchFileAsync(file);
}, function (error) {
console.log("Error getting file '" + fileName + "': " + error);
});
} else {
url = new Windows.Foundation.Uri(strUrl);
Windows.System.Launcher.launchUriAsync(url);
}
}
This is a very ad-hoc hack, but it did the trick for me, and it could be improved, extended, and even standarized.
Anyway, there may be other ways to achieve this, it's just that this worked for me...
After more searching, it seems that the x-ms-webview, which is the underlying component used by PhoneGap for Windows only supports loading HTML content. This Microsoft blog post on the web view control states that
UnviewableContentIdentified – Is fired when a user navigates to
content other than a webpage. The WebView control is only capable of
displaying HTML content. It doesn’t support displaying standalone
images, downloading files, viewing Office documents, etc. This event
is fired so the app can decide how to handle the situation.
This article suggests looking at the Windows.Data.Pdf namespace for providing in-app support for reading PDFs.

Re-inject content scripts after update

I have a chrome extension which injects an iframe into every open tab. I have a chrome.runtime.onInstalled listener in my background.js which manually injects the required scripts as follows (Details of the API here : http://developer.chrome.com/extensions/runtime.html#event-onInstalled ) :
background.js
var injectIframeInAllTabs = function(){
console.log("reinject content scripts into all tabs");
var manifest = chrome.app.getDetails();
chrome.windows.getAll({},function(windows){
for( var win in windows ){
chrome.tabs.getAllInWindow(win.id, function reloadTabs(tabs) {
for (var i in tabs) {
var scripts = manifest.content_scripts[0].js;
console.log("content scripts ", scripts);
var k = 0, s = scripts.length;
for( ; k < s; k++ ) {
chrome.tabs.executeScript(tabs[i].id, {
file: scripts[k]
});
}
}
});
}
});
};
This works fine when I first install the extension. I want to do the same when my extension is updated. If I run the same script on update as well, I do not see a new iframe injected. Not only that, if I try to send a message to my content script AFTER the update, none of the messages go through to the content script. I have seen other people also running into the same issue on SO (Chrome: message content-script on runtime.onInstalled). What is the correct way of removing old content scripts and injecting new ones after chrome extension update?
When the extension is updated Chrome automatically cuts off all the "old" content scripts from talking to the background page and they also throw an exception if the old content script does try to communicate with the runtime. This was the missing piece for me. All I did was, in chrome.runtime.onInstalled in bg.js, I call the same method as posted in the question. That injects another iframe that talks to the correct runtime. At some point in time, the old content scripts tries to talk to the runtime which fails. I catch that exception and just wipeout the old content script. Also note that, each iframe gets injected into its own "isolated world" (Isolated world is explained here: http://www.youtube.com/watch?v=laLudeUmXHM) hence newly injected iframe cannot clear out the old lingering iframe.
Hope this helps someone in future!
There is no way to "remove" old content scripts (Apart from reloading the page in question using window.location.reload, which would be bad)
If you want to be more flexible about what code you execute in your content script, use the "code" parameter in the executeScript function, that lets you pass in a raw string with javascript code. If your content script is just one big function (i.e. content_script_function) which lives in background.js
in background.js:
function content_script_function(relevant_background_script_info) {
// this function will be serialized as a string using .toString()
// and will be called in the context of the content script page
// do your content script stuff here...
}
function execute_script_in_content_page(info) {
chrome.tabs.executeScript(tabid,
{code: "(" + content_script_function.toString() + ")(" +
JSON.stringify(info) + ");"});
}
chrome.tabs.onUpdated.addListener(
execute_script_in_content_page.bind( { reason: 'onUpdated',
otherinfo: chrome.app.getDetails() });
chrome.runtime.onInstalled.addListener(
execute_script_in_content_page.bind( { reason: 'onInstalled',
otherinfo: chrome.app.getDetails() });
)
Where relevant_background_script_info contains information about the background page, i.e. which version it is, whether there was an upgrade event, and why the function is being called. The content script page still maintains all its relevant state. This way you have full control over how to handle an "upgrade" event.

Resources