NW.js open a new window and close it on event - javascript

I'm migrating my NW.js v0.12.3 to the new NW.js v0.17.3.
In my old app, I used to open a window to show an incoming call notification. And if the user answered the call or hangs up I closed the window based in a special event listener.
This is my code which works with no problems in v0.12.3:
var notificationWin;
window.onload = function () {
var messageHandler = function(event) {
if(event.data.key == 'incomingCall'){
win.requestAttention(1);
notificationWin = gui.Window.open('notification.html', {
frame: false,
toolbar: false,
focus: true,
icon: "app/imgs/traywinaz.png",
title:"Incoming Call"
});
notificationWin.on ('loaded', function(){
....
});
}else if(event.data.key == 'callRejected' || event.data.key == 'callAnswered' || event.data.key == 'callCanceled' ){
notificationWin.close();
}
}
window.addEventListener('message', messageHandler, false);
}
But in the new version I cant close the window in the call rejected or answered events. I can't get the notification window to close it.
My new code looks like this:
var messageHandler = function(event) {
if(event.data.key == 'incomingCall'){
win.requestAttention(1);
nw.Window.open('app/notification.html', {
frame: false,
focus: true,
icon: "app/imgs/traywinaz.png",
id: "callNotification"
}, function(new_notification) {
new_notification.setAlwaysOnTop(true);
new_notification.setVisibleOnAllWorkspaces(true);
new_notification.on ('loaded', function(){
....
});
});
}else if(event.data.key == 'callRejected' || event.data.key == 'callAnswered' || event.data.key == 'callCanceled' ){
try{
notificationWin = nw.Window.get('app/notification.html');
notificationWin.close();
}catch(e){
console.log(e);
}
}
};
I can only get the window inside the callback so I also tried to do something like this inside the callback:
notificationWin = new_notification;
but this closes my main window.
Any ideas of what I am doing wrong or how can I achieve this?
The documentation http://docs.nwjs.io/en/latest/References/Window/#windowgetwindow_object says Window.get([window_object]) but no idea how to get the [window_object] parameter in the new version.

Coming back to this, I resolved it by saving the reference inside de callback : "notificationWin = new_notification;" and then just calling notificationWin.close();
The first time I tried this it closed my main window but now works : )

Related

How to get Chrome to throw exception when changing url if it fails

I have a reference to a new window opened with js
var theNewTab="";
theNewTab = window.open(theURL, 'winRef');
then I change the url in the as the user clicks on another link in the parent window using
theNewTab.location.href = targetLink;
theNewTab.focus();
The problem i'm having with chrome that id doesn't throw exception if the the window doesn't exist anymore "closed" unlink FF & IE which im using to open the window again.
try {
theNewTab.location.href = targetLink;
theNewTab.focus();
}catch(err) {
theNewTab = window.open(theURL, 'winRef');
theNewTab.focus();
}
PS: I tried to use "window.open" every time but if the window already open, id does not reload the page or it does but it doesn't re-execute the script I have in document ready I think.
I'm not sure what you need.
<script type="text/javascript">
var theNewTab = null;
function openNewTab(theURL) {
if (theNewTab == null || theNewTab.closed == true) {
theNewTab = window.open(theURL);
} else {
theNewTab.location.href = theURL;
}
theNewTab.focus();
};
// use the function when you need it
$('a').click(function() {
openNewTab($(this).attr('href'));
});
</script>
Is this example helpful for you?

Firefox WebExtension : check if extension already exists

I'm porting my Chrome extension to a Firefox WebExtension, so far so good, I manage to communicate smoothly with my content, background scripts and my executable.
I would like now to check the existence of my extension. This is actually the way I do it :
Browser script
// browser-script.js
var isExtensionHere = false;
$("#is-extension-here").click(function(){
console.log("Check the existence of the extension");
window.postMessage({
direction: "from-page-script",
message: "areYouThere"
}, "*");
});
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "from-content-script") {
if(event.data.message == "OK") {
isExtensionHere = true;
}
}
});
Content Script
// content-script.js
window.addEventListener("message", function(event) {
if (event.source == window &&
event.data.direction &&
event.data.direction == "from-page-script") {
if(event.data.message == "areYouThere") {
window.postMessage({
direction: "from-content-script",
message: "OK"
}, "*");
}
}
});
It works fine when the extension is here. But when it is not, obviously I don't get an answer from my extension. How can I know then how to trigger a popup or a message when the extension is not here ?
You can reverse the logic: make the page listen for a ping from the extension. You need to be mindful of when scripts execute (e.g. depending on run_at parameter) in relation to each other, so that you don't accidentally send a message before the page starts listening.
You can use another method of announcing presence to the page: a content script can add an invisible DOM element with a known ID, and you can check for its presence from the page.
If you want to keep the current approach, you can set a timer for the response to happen. Something like, say, 200ms should be more than enough.
You can implement this as a Promise, since it can only be resolved once:
var isExtensionHere = new Promise((resolve, reject) => {
const listener = (event) => {
if (
event.source == window && event.data.direction
&& event.data.direction == "from-content-script"
&& event.data.message == "OK"
) {
resolve(true);
}
}
setTimeout(() => {
window.removeEventListener("message", listener);
resolve(false); // Will have no effect if already called with true
}, 200);
window.addEventListener("message", listener);
window.postMessage({
direction: "from-page-script",
message: "areYouThere"
}, "*");
});
// Sometime later
isExtensionHere.then((result) => { /* ... */ });
If you want to dynamically re-check, make isExtensionHere a function that returns a new Promise every time.

jquery/jscript Prevent open multiple popups

I open a popup with the click event of a hyperlink... The popup contains records from a server.
The problem is that when I click rapidly, there are multiple popups at once.
There is a way to prevent this? in which can open a single popup
My code:
$('.wrapper_form a.add').click(function(e)
{
e.preventDefault();
if(typeof(currentPopup) == 'undefined' || currentPopup.closed)
{
url = 'server_page.aspx';
currentPopup = window.open(url,'server','height=500,width=800');
if (window.focus) {currentPopup.focus()}
}
else
{
currentPopup.focus();
}
});
Here is one approach. Not the best solution but it should work. What this code will do is protect against clicking the link a bunch of times and have it open a new instance for each click. This code will not allow the window to be opened more than once in a 1/2 interval, of course you can change the timing.
var hopefullyThisIsNotInGlobalScope = false;
$('.wrapper_form a.add').click(function(e)
{
if (hopefullyThisIsNotInGlobalScope)
{
return false;
}
hopefullyThisIsNotInGlobalScope = true;
setTimeout(function () { hopefullyThisIsNotInGlobalScope = false; }, 500);
e.preventDefault();
if(typeof(currentPopup) == 'undefined' || currentPopup.closed)
{
url = 'server_page.aspx';
currentPopup = window.open(url,'server','height=500,width=800');
if (window.focus) {currentPopup.focus()}
}
else
{
currentPopup.focus();
}
});
Assuming the popup is on the same domain as the window launching it you might be able to replace hopefullyThisIsNotInGlobalScope variable with a global var attached to the window. You can then set that variable when the popup launches and alter it using the browser unload event

popup window only 'popping up' once in safari

I have a JavaScript fired popup window, it's created when hitting the onclick event of a tag:
top.popUp('/bus/popup.asp', '', 'height=457px,width=525px,status=no,scrollbars=no,resizable=yes,location=no,menubar=no,toolbar=no');return false;">
function popUp(url, winName, params, win)
{
var winExists = false;
if (win.handler)
{
if (!(win.handler == "" || win.handler.closed || win.handler.name == undefined))
{
winExists = true;
}
}
if (!winExists)
{
win.handler = window.open(url, winName, params)
}
try
{
win.handler.focus();
}
catch (e)
{
}
return false;
}
I also found these two funky little functions in the main file, fired when the popup window gets unloaded:
// Hack for onUnload and onBeforeUnload
onBeforeUnloadHappened = false;
closeDirectly = false;
function onBeforeUnloadHandler()
{
if (!closeDirectly)
{
openerUnhilightSaveLink();
onBeforeUnloadHappened = true;
}
}
function onUnloadHandler()
{
if (!closeDirectly)
{
if (!onBeforeUnloadHappened)
{
openerUnhilightSaveLink();
}
else
{
onBeforeUnloadHappened = false;
}
}
}
The problem is that in Safari, the window will only popup once, each subsequent click on the link gets you nada, zilch, nothing... how do I correct this?
I did find a couple of articles, Google is my friend, online and they suggested that I add this.close(), which I did to the unload event but it doesn't seem to have solved the problem.
The other thing I find odd is that the onUnloadHandler() doesn't actually happen each time the page is unloaded! Shouldn't this be called each time by the page itself irrespective of what else has happened?!
Thanks
It's my opinion that your popup code isn't written properly. This works in Safari, as I just tested it out. This is what I've done.
// Create a global popup object as you should rarely ever
// have more than one popup open at a time.
window.popUpObj = null;
// The function to call the popup.
function popUp(url, winName, params)
{
// If the window has not been defined or if it has been closes open it.
// Since we defined window.popUpObj to be null we'll expect only 2 conditions.
if(window.popUpObj == null || window.popUpObj.closed)
{
window.popUpObj = window.open(url, winName, params);
}
// Get window focus
window.popUpObj.focus();
// Return false.
// we do this so that when we call it we don't need a ; to return false afterwards
// we just add return before the function call. It's a bit more elegant.
return false;
}
You can call it like this. You should by the way always populate the 2nd parameter with something.
Link
Here's a working HTML doc.
<html>
<head>
<script type="text/javascript">
window.popUpObj = null;
function popUp(url, winName, params)
{
// If the window has not been defined or if it has been closes open it.
if(window.popUpObj == null || window.popUpObj.closed || window.popUpObj.name == undefined)
{
window.popUpObj = window.open(url, winName, params);
}
// Get window focus
window.popUpObj.focus();
// Return false.
return false;
}
</script>
</head>
<body>
Link
close
</body>
</html>

Concurrent call to a simplemodal object

I have to make a function concurrent to multiple open/close modal requests.
For exemple: When i call showAjaxLoading(true), it's showing the modal, and showAjaxLoading(false) it's disposing the modal.
The Problem: When i make a first long request to showing the modal, and another one quick request will close it. I want to be able keeping in a array all the requests and disposing the modal only when the last request is ended.
SimpleModal: The object simplemodal is unique. When you create the modal it return the object itself. But when you have a modal already open, it returns false. url: http://www.ericmmartin.com/projects/simplemodal/
var showAjaxLoading = function (show) {
var ajaxModal;
if (show) {
var aModal = $("#ajaxLoading").modal({ overlayId: 'ajaxloading-overlay', containerId: 'ajaxloading-container', closeClass: 'ajaxloading-close', close: false, escClose: false });
if (aModal !== false) {
ajaxModal = aModal;
};
} else {
if (ajaxModal !== undefined && $.isFunction(ajaxModal.close)) {
ajaxModal.close();
};
};
};
What the is the best solution to solve this problem ?
var modalDialog = {
_requestsInProcess: 0,
showAjaxLoading : function()
{
if ( this._requestsInProcess == 0 )
{
// open overlay here
}
this._requestsInProcess++;
},
hideAjaxLoading : function()
{
this._requestsInProcess--;
if ( this._requestsInProcess == 0 )
{
// hide overlay here
}
}
}
Try something like this/ Now you can call modalDialog.showAjaxLoading() each time you making AJAX request and modalDialog.hideAjaxLoading() each time your request is completed.

Categories