How to launch uwp webview app in full screen mode by default - javascript

We have created a full fledged UWP webview app (WinJs) with help of Visual Studio 2017. Recently going through microsoft documentation and stackoverflow threads, we found out that the uwp app can be launched full screen with title bar removed.
Following code needed to inserted into App.Xaml.Cs file
ApplicationView view = ApplicationView.GetForCurrentView();
view.TryEnterFullScreenMode();
But the problem here is that, we are unable to locate this file to insert this. May be its because of WinJS template i have chosen, i don't know.
Other notables files include main.js | packageapp.manifest file. I do not know whether this code could be integrated with either of this file.
Edit:
With roy's help, the main js file is modified according to the sample given in windows universal sample github, but still full screen does not seem to open up.
The main.js file code is as given below
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var isFirstActivation = true;
var ViewManagement = Windows.UI.ViewManagement;
var ApplicationViewWindowingMode = ViewManagement.ApplicationViewWindowingMode;
var ApplicationView = ViewManagement.ApplicationView;
function onLaunchInFullScreenModeChanged() {
ApplicationView.preferredLaunchWindowingMode = launchInFullScreenMode.checked ? ApplicationViewWindowingMode.fullScreen : ApplicationViewWindowingMode.auto;
}
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.voiceCommand) {
// TODO: Handle relevant ActivationKinds. For example, if your app can be started by voice commands,
// this is a good place to decide whether to populate an input field or choose a different initial view.
}
else if (args.detail.kind === activation.ActivationKind.launch) {
launchInFullScreenMode.addEventListener("click", onLaunchInFullScreenModeChanged);
launchInFullScreenMode.checked = ApplicationView.preferredLaunchWindowingMode == ApplicationViewWindowingMode.fullScreen;
// A Launch activation happens when the user launches your app via the tile
// or invokes a toast notification by clicking or tapping on the body.
if (args.detail.arguments) {
// TODO: If the app supports toasts, use this value from the toast payload to determine where in the app
// to take the user in response to them invoking a toast notification.
}
else if (args.detail.previousExecutionState === activation.ApplicationExecutionState.terminated) {
// TODO: This application had been suspended and was then terminated to reclaim memory.
// To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
// Note: You may want to record the time when the app was last suspended and only restore state if they've returned after a short period.
}
}
if (!args.detail.prelaunchActivated) {
// TODO: If prelaunchActivated were true, it would mean the app was prelaunched in the background as an optimization.
// In that case it would be suspended shortly thereafter.
// Any long-running operations (like expensive network or disk I/O) or changes to user state which occur at launch
// should be done here (to avoid doing them in the prelaunch case).
// Alternatively, this work can be done in a resume or visibilitychanged handler.
}
if (isFirstActivation) {
// TODO: The app was activated and had not been running. Do general startup initialization here.
document.addEventListener("visibilitychange", onVisibilityChanged);
args.setPromise(WinJS.UI.processAll();
launchInFullScreenMode.addEventListener("click", onLaunchInFullScreenModeChanged);
launchInFullScreenMode.checked = ApplicationView.preferredLaunchWindowingMode == ApplicationViewWindowingMode.fullScreen;
}
isFirstActivation = false;
};
function onVisibilityChanged(args) {
if (!document.hidden) {
// TODO: The app just became visible. This may be a good time to refresh the view.
}
}
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
// You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
// If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
};
app.start();
})();
Any suggestions on how to solve this problem.

You could put the code in a JS file that will be referenced by the HTML that you are showing.
There used to be a JS UWP FullScreenMode Sample here: FullScreenMode JS. Although it is archived, you could still take a look at scenario2-launch.js and scenario1-basic.js. It shows how to these APIs are used in JavaScript.

Related

Are all these multiple checks really required to handle a new service worker update?

I am following a tutorial on service workers on Udacity by Jake Archibald, and this is the solution skeleton of an exercise on "updating" that has confused me:
They give a long solution that is like the code below (they check for three possible cases, as explained in comments):
(async() => {
if ("serviceWorker" in navigator) {
try {
const reg = await navigator.serviceWorker.register("/sw.js");
if (!reg || !navigator.serviceWorker.controller) {
return;
}
// Possible states of new updates:
// - 1. There are no updates yet, a new update may arrive
// - 2. An update is in progress
// - 3. A waiting update exists (already installed)
// 1.
addEventListener("updatefound", () => {
console.log("updatefound");
const sw = reg.installing;
trackInstallation(sw);
});
// 2
const installingSw = reg.installing;
if (installingSw) {
console.log("installingSw");
trackInstallation(installingSw);
return;
}
// 3
if (reg.waiting) {
console.log("reg.waiting");
const sw = reg.waiting;
notifyUpdate();
return;
}
console.log("nothing");
} catch (error) {
console.error("Service worker registration failed.", error);
}
}
})();
function trackInstallation(worker) {
worker.addEventListener("statechange", () => {
if (worker.state === "installed") {
notifyUpdate();
}
});
}
function notifyUpdate() {
alert("There's a new update!");
}
But I tried different scenarios and I can't get these checks except the third one (if (reg.waiting) {) to be triggered. So I wonder if all these checks are really needed?
This is how I trigger the third check:
Install the service worker (register, install, activate) by loading the web page for the first time at localhost:8080
Make a change to the service worker (e.g., add "/tmp.txt" to the array of names of the files that have to be cached)
Refresh the page.
👉 First load none of the checks are triggered.
👉 Second load, reg.waiting runs (the third check is triggered).
which makes sense (I've read and I know how the lifecycle of service workers works), but I don't know in what scenario the other two checks (i.e., the ones on line 14 and 21) would be triggered?
Things to remember:
The service worker isn't for a single page
The service worker runs independently of any page
In your example code, one page installs the service worker, and ensures that the install completes entirely.
That isn't always the case in the real world. Let's say:
You refresh a service-worker-controlled page.
That triggers a service worker update check. Assuming an update is found:
// 1 will happen for all pages in the origin. You might not be seeing it, because your code is addEventListener('updatefound', where it should be navigator.serviceWorker.addEventListener('updatefound'.
If at this point, you reload the page, you might hit // 2, since there's already an install in progress.
For more details on the service worker lifecycle, see https://web.dev/service-worker-lifecycle/

Quitting an electron app after setInterval() from external script file

Edited for more clarity.
I am trying to make a splash screen applet - to start learning nodejs and electron.
I want to create an applet that launches, shows some messages every 10 seconds, and then quits.
I'm basing it off the Discord app and Teams where they have pop up loading screens that have a progress bar, and once completed load the full application.
I want to know how to do it before the "load full app" portion kicks in and how to close the splash screen completely.
Currently I have an index.js, index.html, and a main.js.
index.js is the electron browser window. index.html is the main rendered page, and the main.js is the timer to switch the innerHTML based on the time from:
// main.js
var startTime = 0,
totalTime = 10,
timeBuffer = 2,
totalPercent = 0,
timeCounter = setInterval( progress, 1000 );
function progress() {
if( (startTime += 1) >= (totalTime + timeBuffer + 1) ) {
// quit app (1)
} else {
// show messages here
}
}
At point (1) in the code, I've tried adding in app.close(); but that fails since I haven't added in app. I tried adding it in but that doesn't work either.
I tried adding in:
// main.js
const { ipcRenderer } = require('electron');
ipcRenderer.send('close-me');
//index.js
ipcMain.on( 'close-me', (evt, arg) => {
app.quit();
});
But this didn't work either. I'm still trying to understand the relationship between index.js and the other scripts you might write for the app - but thought quitting the app entirely would be easy.
It seems app.quit() wasn't working in this instance, but app.close(0) was.
Reading through the docs didn't suggest any reasons to why but in case someone else runs into this problem too.
Store your setInterval()as a variable and use JavaScript clearInterval(variable) as a page exit action.

Jquery Not Working Windows Universal App

This is not a duplicate as this has nothing to do with referenced link as this is a windows based application, and has nothing to do with the location of the script as this is not related to a web based app. Please remove duplication.
Maybe I am just putting the code in the wrong location as this is my first time attempting to get started in creating Universal Apps for windows using JS. As per windows developer site Jquery can be used. https://blogs.windows.com/buildingapps/2013/07/10/jquery-and-winjs-working-together-in-windows-store-apps/#IYuzrU7FW7kC0fig.97
so to just test it out I did a standard simple default new project. With some jquery test code.
My Test Jquery Code:
$(".bodytype").on("click", function () {
console.log('Clicked');
$(".bodytype").css("background", "blue");
});
html code in index.html
<div class="bodytype">A Row</div>
The main.js file in the windows app looks like this:
// For an introduction to the Blank template, see the following documentation:
// http://go.microsoft.com/fwlink/?LinkId=232509
(function () {
"use strict";
var app = WinJS.Application;
var activation = Windows.ApplicationModel.Activation;
var isFirstActivation = true;
app.onactivated = function (args) {
if (args.detail.kind === activation.ActivationKind.voiceCommand) {
// TODO: Handle relevant ActivationKinds. For example, if your app can be started by voice commands,
// this is a good place to decide whether to populate an input field or choose a different initial view.
}
else if (args.detail.kind === activation.ActivationKind.launch) {
// A Launch activation happens when the user launches your app via the tile
// or invokes a toast notification by clicking or tapping on the body.
if (args.detail.arguments) {
// TODO: If the app supports toasts, use this value from the toast payload to determine where in the app
// to take the user in response to them invoking a toast notification.
}
else if (args.detail.previousExecutionState === activation.ApplicationExecutionState.terminated) {
// TODO: This application had been suspended and was then terminated to reclaim memory.
// To create a smooth user experience, restore application state here so that it looks like the app never stopped running.
// Note: You may want to record the time when the app was last suspended and only restore state if they've returned after a short period.
}
}
if (!args.detail.prelaunchActivated) {
// TODO: If prelaunchActivated were true, it would mean the app was prelaunched in the background as an optimization.
// In that case it would be suspended shortly thereafter.
// Any long-running operations (like expensive network or disk I/O) or changes to user state which occur at launch
// should be done here (to avoid doing them in the prelaunch case).
// Alternatively, this work can be done in a resume or visibilitychanged handler.
}
if (isFirstActivation) {
// TODO: The app was activated and had not been running. Do general startup initialization here.
document.addEventListener("visibilitychange", onVisibilityChanged);
args.setPromise(WinJS.UI.processAll());
}
isFirstActivation = false;
};
function onVisibilityChanged(args) {
if (!document.hidden) {
// TODO: The app just became visible. This may be a good time to refresh the view.
}
}
app.oncheckpoint = function (args) {
// TODO: This application is about to be suspended. Save any state that needs to persist across suspensions here.
// You might use the WinJS.Application.sessionState object, which is automatically saved and restored across suspension.
// If you need to complete an asynchronous operation before your application is suspended, call args.setPromise().
};
//Code Here
$(".bodytype").on("click", function () {
console.log('Clicked');
$(".bodytype").css("background", "blue");
});
//App Start Code Before
app.start();
})();
index.html full code here:
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>App3</title>
<link href="lib/winjs-4.0.1/css/ui-light.css" rel="stylesheet" />
<script src="lib/winjs-4.0.1/js/base.js"></script>
<script src="lib/winjs-4.0.1/js/ui.js"></script>
<link href="css/default.css" rel="stylesheet" />
<script src="js/jquery-3.1.1.js"></script>
<script src="js/main.js"></script>
</head>
<body class="win-type-body">
<div class="bodytype">A Row</div>
</body>
</html>
can someone help me understand what I am doing wrong? There are no compile errors and the app loads fine, but when I attempt to click the row the background color does not change.
Make sure you already attached your Jquery file in your html page
Goto your main.js and write this
window.onload = function () {
$(".bodytype").on("click", function () {
console.log('Clicked');
$(".bodytype").css("background", "blue");
});
}
`
Worked for me , Fam it will for you too.

How can I access the DOM of a <webview> in Electron?

I'm just getting started with Electron, with prior experience with node-webkit (nw.js).
In nw.js, I was able to create iframes and then access the DOM of said iframe in order to grab things like the title, favicon, &c. When I picked up Electron a few days ago to port my nw.js app to it, I saw advice to use webviews instead of iframes, simply because they were better. Now, the functionality I mentioned above was relatively easy to do in nw.js, but I don't know how to do it in Electron (and examples are slim to none). Can anyone help?
Also, I have back/forward buttons for my webview (and I intend on having more than one). I saw in the documentation that I could call functions for doing so on a webview, but nothing I have tried worked either (and, I haven't found examples of them being used in the wild).
I dunno who voted to close my question, but I'm glad it didn't go through. Other people have this question elsewhere online too. I also explained what I wanted to achieve, but w/e.
I ended up using ipc-message. The documentation could use more examples/explanations for the layperson, but hey, I figured it out. My code is here and here, but I will also post examples below should my code disappear for whatever reason.
This code is in aries.js, and this file is included in the main renderer page, which is index.html.
var ipc = require("ipc");
var webview = document.getElementsByClassName("tabs-pane active")[0];
webview.addEventListener("ipc-message", function (e) {
if (e.channel === "window-data") {
// console.log(e.args[0]);
$(".tab.active .tab-favicon").attr("src", e.args[0].favicon);
$(".tab.active .tab-title").html(e.args[0].title);
$("#url-bar").val(e.args[0].url);
$("#aries-titlebar h1").html("Aries | " + e.args[0].title);
}
// TODO
// Make this better...cancel out setTimeout?
var timer;
if (e.channel === "mouseover-href") {
// console.log(e.args[0]);
$(".linker").html(e.args[0]).stop().addClass("active");
clearTimeout(timer);
timer = setTimeout(function () {
$(".linker").stop().removeClass("active");
}, 1500);
}
});
This next bit of code is in browser.js, and this file gets injected into my <webview>.
var ipc = require("ipc");
document.addEventListener("mouseover", function (e) {
var hoveredEl = e.target;
if (hoveredEl.tagName !== "A") {
return;
}
ipc.sendToHost("mouseover-href", hoveredEl.href);
});
document.addEventListener("DOMContentLoaded", function () {
var data = {
"title": document.title,
"url": window.location.href,
// need to make my own version, can't rely on Google forever
// maybe have this URL fetcher hosted on hikar.io?
"favicon": "https://www.google.com/s2/favicons?domain=" + window.location.href
};
ipc.sendToHost("window-data", data);
});
I haven't found a reliable way to inject jQuery into <webview>s, and I probably shouldn't because the page I would be injecting might already have it (in case you're wondering why my main code is jQuery, but there's also regular JavaScript).
Besides guest to host IPC calls as NetOperatorWibby, it is also very useful to go from host to guest. The only way to do this at present is to use the <webview>.executeJavaScript(code, userGesture). This api is a bit crude but it works.
If you are working with a remote guest, like "extending" a third party web page, you can also utilize webview preload attribute which executes your custom script before any other scripts are run on the page. Just note that the preload api, for security reasons, will nuke any functions that are created in the root namespace of your custom JS file when your custom script finishes, however this custodial process will not nuke any objects you declare in the root. So if you want your custom functions to persist, bundle them into a singleton object and your custom APIs will persist after the page fully loads.
[update] Here is a simple example that I just finished writing: Electron-Webview-Host-to-Guest-RPC-Sample
This relates to previous answer (I am not allowed to comment): Important info regarding ipc module for users of Electron 1.x:
The ipc module was split into two separate modules:
ipcMain for the main process
ipcRenderer for the renderer process
So, the above examples need to be corrected, instead of
// Outdated - doesn't work in 1.x
var ipc = require("ipc");
use:
// In main process.
var ipcMain = require('electron').ipcMain
And:
// In renderer process.
var ipcRenderer = require('electron').ipcRenderer
See: http://electron.atom.io/blog/2015/11/17/electron-api-changes section on 'Splitting the ipc module'

iOS UI Automation wait until web view is ready and rendered

I am creating an iOS UI Automation javascript using Instruments to automate taking a screenshot for my iOS app. The tool I am using to automate taking a screenshot is Snapshot.
I am using a webview for part of my app and I want to take a screenshot of fully rendered webview before proceeding to the rest of the script.
So currently my script looks like:
var target = UIATarget.localTarget();
target.frontMostApp().mainWindow().scrollViews()[0].webViews()[0].links()[0].tap();
// take screen shot here
target.frontMostApp().navigationBar().leftButton().tap();
But when it takes the screen shot, the webview was not fully rendered so it's taking an empty screen and go back to the main screen.
Is there a way to wait until the webview is fully loaded, then take a screen shot and continue rest of the script?
The Illuminator framework (full disclosure, I wrote it) provides a function called waitForChildExistence() in its Extensions.js that allows you to continuously evaluate a reference to an element until it actually appears.
You would do something like this to wait up to 10 seconds for the webview to load:
var webView = target.frontMostApp().mainWindow().scrollViews()[0].webViews()[0];
webView.tap();
webView.waitForChildExistence(10, true, "a specific link in the web view", function(wb) {
// the argument wb will contain the reference to our var webView
return wb.links()["the link you are waiting for"];
});
// take screen shot here
target.frontMostApp().navigationBar().leftButton().tap();
You can use computed style, put some inert style property (I used clip), and you can check with intervals of 1 second (if you use css files better create a class with it and use the class on element).
The function below i user to get the style computed.
function getStyle (el, prop) {
try {
if (getComputedStyle !== undefined) {
return getComputedStyle(el, null).getPropertyValue(prop);
}
else {
return el.currentStyle[prop];
}
} catch (e) {
return el.currentStyle[prop];
}
}
The timer you can try this
Be aware of that computed style may vary by browsers.
Hope it helps...

Categories

Resources