how to use localstorage in electron - electron

In an electron app, I use window.loadURL('http://example.com') to load my website, this website uses localStorage to save user data. My question is how to use the localStorage with Electron API?
Here is my code :
{
label:'test',
click:()=>{
let object = mainWindow.webContents.executeJavaScript('localStorage.length');
console.log("localstorage.length:"+JSON.stringify(object));
}
}
But it will print localstorage.length:{}

executeJavaScript is an asynchronous function and returns a Promise. You need to either use async/await or chain .then() to access the value returned by the function.
// inside an async function
const object = await mainWindow.webContents.executeJavaScript('localStorage.length');
console.log(`Localstorage length: ${object}`);
or
mainWindow.webContents.executeJavaScript('localStorage.length')
.then(object => console.log(`Localstorage length: ${object}`));
Check out this example openable in Electron Fiddle. Swap out loadFile for loadURL with your website, and you should be set.

Related

HTMLIFrameElement.contentWindow.print() from GoogleSheets is not opening print preview

I am using GoogleSheets to print a png/image file using HTMLService. I created a temporary Iframe element with an img tag in the modalDialog and call IFrame element's contentWindow.print() function after IFrame element and its image are loaded. (I have not set visibility:hidden attribute of IFrame element to check if image is getting loaded.)
However, I only see the printer dialog without any print preview. I am testing on Firefox. Am I missing anything?
[Updated] - I am using Googles Apps script. performPrint() is in printJsSource.html and openUrl() is in Code.gs.
Inside printJsSource.html
function performPrint(iframeElement, params) {
try {
iframeElement.focus()
// If Edge or IE, try catch with execCommand
if (Browser.isEdge() || Browser.isIE()) {
try {
iframeElement.contentWindow.document.execCommand('print', false, null)
} catch (e) {
iframeElement.contentWindow.print()
}
} else {
// Other browsers
iframeElement.contentWindow.print() // as I am using Firefox, it is coming here
}
} catch (error) {
params.onError(error)
} finally {
//cleanUp(params)
}
}
Inside Code.gs
function openUrl() {
var html = HtmlService.createHtmlOutputFromFile("printJsSource");
html.setWidth(500).setHeight(500);
var ui = SpreadsheetApp.getUi().showModalDialog(html, "Opening ..." );
}
I think there is some general confusion about the concept
First of all, function performPrint() seems to be a client-side Javascript funciton, while function openUrl() is a server-side Apps Script function.
While you did not specify either you use Google Apps Script - if you do so, function openUrl()belongs into the code.gs file and function performPrint() into printJsSource.html file
function openUrl() allows you to open a modal dialog which can show some data on the UI, e.g. your image
Do not confuse this behavior with actual printing (preview)!
It is NOT possible to trigger the opening of a Google Sheets printing preview programamticaly!
The Javascript method you are using iframeElement.contentWindow.print() might trigger the printing of the whole content of a browser window (different from the Google Sheets printing dialog, also depends on the browser), but if you try to incorporate it into the client-side coe of an Apps Script project, you will most likely run into restrictions due to the scopes of modal diloags and usage of iframes.
While from your code it is hard to say either you implemented the funcitons in the correct files of the Apps Script project, keep in mind that to work with iframes you need to specify in function openUrl()
html.setXFrameOptionsMode(HtmlService.XFrameOptionsMode.ALLOWALL);

How to access url params in sapper outside of preload function?

In Sapper, AFAIK from documentation. The only way to access URL params are through preload() function, from which params are available inside params object.
The thing is that I want to access these params ouside of preload() function. From an eagle eye view of documentation. I don't / can't see the solution to my problem / requirement.
I have tried setting a property for url param inside data(). But it seems preload() has no access to data whether getting wise or setting wise. It is not meant for those things.
<script>
import { stores } from "#sapper/app";
const { page } = stores();
const { slug } = $page.params;
</script>
https://sapper.svelte.dev/docs/#Stores
If you are using v3 Svelte and latest alpha of Sapper, import page which is now provided as a store.
import { page } from '#sapper/app';
const {slug} = $page.params;

Phonegap Build and WKWebView: What we have here is a failure to communicate

WKWebview and Phonegap Build: Is communication between index.js and WKWebView even possible?
I'm using Phonegap Build to generate my mobile device executables. I'm opening a webview and loading a page off our website. While using UIWebView I had no problem coding index.js on the mobile device to listen for a loadstop event and call executescript to execute javascript on the web page in the webview and return the results to index.js where I could do whatever I needed.
But UIWebView is dog-slow, so for iOS I've been trying to get WKWebView to work via the cordova-plugin-wkwebview-engine plug-in.
I can get the WKWebview to open my URL, and it is blazing fast compared to UIWebView, but after days of searching (every page containing 'WKWebView' and 'Phonegap' that Google knows of) and experimentation I have been unable to find any way to detect loadstop (or equivalent), nor have I found any way to execute a script in WKWebView from index.js.
I would probably be happy with ANY method to communicate between index.js and WKWebView. Is there a process similar to executescript after loadstop event, even if it is async? Is there some type of messaging capability?
I'd love to see some code examples for index.js.
I'm beginning to think that I'm going to have to break down and resort to learning native code in xcode to make this happen. I sure hope not because Phonegap Build has worked fine for me thus far.
Has anyone had any luck with this?
Here is the code that works under UIWebView. It works well enough under WKWebView to open the URL, but loadstop does not trigger and there is no execution of the script.
launchBrowserWindow: function (url) {
var ref;
try {
ref = window.open(url, '_self', 'location=no,toolbar=no');
} catch (e) {
console.log("McMApp catch window.open fail: " + url + " err: " + e.message);
}
try {
ref.addEventListener("loadstop", function () {
ref.executeScript(
{ code: 'window.location.search' },
function (value) {
var requestString = value[0];
console.log("McMApp loadstop request string: " + requestString);
});
});
} catch (e) {
console.log("McMApp FAIL ref.addeventlistener loadstop");
}
},
50 hard-boiled eggs to anyone that can help me get this working.
InAppBrowser is a fickle beast, so happy to help! For reference, I have an app now that uses InAppBrowser and WKWebView and both work using the following:
"LoadStop" not firing:
Self vs _blank:
I typically open the Browser via "_blank" instead of "self". Try that.
Newer versions of InAppBrowser should still be automatically aliased to 'window.open' but in the docs they mention this will go away soon. You can do that in the deviceready event like so:
window.open = cordova.InAppBrowser.open;
Or, and probably the safer option, just use "cordova.InAppBrowser.open".
Here's code I use. Try printing out or "alert"-ing the URLs that are coming through. They may not be what you expect, especially if there are multiple redirects.
var inAppBrowserRef = cordova.InAppBrowser.open("www.google.com", '_blank', 'location=no,toolbar=yes');
inAppBrowserRef.addEventListener('loadstop', function(event) {
console.log("loadstop: " + event.url);
alert("loadstop: " + event.url);
// run execute script code
}
});
Also, make sure any use of InAppBrowser is within/after the 'deviceready' event fires.
Execute Script Issue
I believe here the problem is that your code isn't firing. See here, wrap it into a function and call it immediately:
ref.executeScript(
{ code: 'var runCode = function() { window.location.search; } runCode();' },
function (value) {
var requestString = value[0];
console.log("McMApp loadstop request string: " + requestString);
});
I'm not totally sure, but according to MDN, shouldn't you be passing a parameter to the location search function too?
// Append "someData" as url parameter query
window.location.search = "someData";
Last, note that WKWebView does have lots of known issues currently. Always check first for known issues on GitHub or official Apache Cordova site, etc, because as you wrote, you can burn many hours getting nowhere. I'm currently using this fork of the WKWebView - this team is moving much faster than the "official" plugin fixing bugs so you might try that.

PointerLock with dart

Is there a way to lock the cursor with dart that works on Firefox and Chrome?
I tried:
void lock(event)
{
var canvas = document.querySelector('canvas');
canvas.requestPointerLock();
}
in a mousedown-event listener
document.addEventListener('mousedown', lock, false);
I also tried
renderer.canvas.requestPointerLock();
where renderer is a WebGLRenderer from the three.dart package.
The problem is this works only in Chromium.
I looked up the following crossbrowser-solution for js, but this doesn't work in dart.
canvas.requestPointerLock = canvas.requestPointerLock ||
canvas.mozRequestPointerLock ||
canvas.webkitRequestPointerLock;
Is there a way to do the pointer lock in dart, or do I need to find a way to execute the javascript above from dart?
There is an open issue for this https://dartbug.com/4463
I think the problem in your code code using prefixes is that canvas.requestPointerLock, canvas.mozRequestPointerLock, canvas.webkitRequestPointerLock don't return false if they don't exist (or true if it does). You have to get the current browser by other means and then call the prefixed method.

Override web page's javascript function using firefox addon sdk

I'm trying to override a JS function named replaceMe in the web page from my add-on's content script, but I see that the original function implementation always gets executed.
Original HTML contains the following function definition:
function replaceMe()
{
alert('original');
}
I'm trying to override it my add-on like (main.js):
tabs.activeTab.attach({
contentScriptFile: self.data.url("replacerContent.js")
});
Here's what my replacerContent.js looks like:
this.replaceMe = function()
{
alert('overridden');
}
However, when I run my addon, I always see the text original being alerted, meaning the redefinition in replacerContent.js never took effect. Can you let me know why? replaceMe not being a privileged method, I should be allowed to override, eh?
This is because there is an intentional security between web content and content scripts. If you want to communicate between web content and you have control over the web page as well, you should use postMessage.
If you don't have control over the web page, there is a hacky workaround. In your content script you can access the window object of the page directly via the global variable unsafeWindow:
var aliased = unsafeWindow.somefunction;
unsafeWindow.somefunction = function(args) {
// do stuff
aliased(args);
}
There are two main caveats to this:
this is unsafe, so you should never trust data that comes from the page.
we have never considered the unsafeWindow hack and have plans to remove it and replace it with a safer api.
Rather than relying on unsafeWindow hack, consider using the DOM.
You can create a page script from a content script:
var script = 'rwt=function()();';
document.addEventListener('DOMContentLoaded', function() {
var scriptEl = document.createElement('script');
scriptEl.textContent = script;
document.head.appendChild(scriptEl);
});
The benefit of this approach is that you can use it in environments without unsafeWindow, e. g. chrome extensions.
You can then use postMessage or DOM events to communicate between the page script and the content script.

Resources