Close/clear a chrome extension notification while notification panel is open - javascript

References: https://developer.chrome.com/apps/notifications
I am using the chrome.notifications.create(string id, object options, function callback); to create a chrome notification.
var id = 'list';
var options = {};
options.title = 'test';
options.iconUrl = 'notification_icon.png';
options.type = 'list';
options.message = "test";
options.buttons = [{title: 'test'}];
options.items = [{title: 'test', message:'test'}];
var createCallback = function(notificationId) { console.log(notificationId); };
chrome.notifications.create(id, options, createCallback); // returns 'list';
This creates a notification as expected. All working correctly.
I then call chrome.notification.clear(string id, function callback);
var id = 'list';
var clearCallback= function(wasCleared) { console.log(wasCleared); };
chrome.notification.clear(id, clearCallback); // returns true;
This does clear the notification. All working correctly.
EXCEPT it does not clear the notification out if the notification panel is open. This is not a major problem 99% of the time. Until I implemented the button code within the notification.
Using chrome.notifications.onButtonClicked.addListener(function callback); On click I am calling the clear notification panel code, and it reports back as it has been cleared.
var onButtonClickedCallback = function (notificationId, buttonIndex) {
console.log(notificationId, buttonIndex);
if ( notificationId == 'list' ) {
chrome.notification.clear(id, clearCallback); // returns true;
}
}
chrome.notifications.onButtonClicked.addListener(onButtonClickedCallback); // onClick it returns 'list', 0
But I am looking right at it.. Once the notification panel closes and opens again, I can confirm it has actually gone. But obviously since I am clicking a button on the notification, the panel is open, but it does not clear away as I would have liked.
All this is running in an extension background without the persistence: false property (so the script is always loaded, and since I can see the output, I know the functions are being called).
Have I overlooked something? I do not see any functions that deal with closing the notification panel. So as far as I can tell, I am clearing the notification but the panel is not updating it's display.
I am using Chrome 37.0.2019.0 canary on Win8
If anyone can suggest something I may have missed, I would be greatful. My google searches reveal people having problems with the HTML notification.

This is a known bug, or rather an old design decision, with little progress.
Star the issue to raise its priority. I also suffer from the same.

Here's the workaround solution I've been using for several months now:
// open a window to take focus away from notification and there it will close automatically
function openTemporaryWindowToRemoveFocus() {
var win = window.open("about:blank", "emptyWindow", "width=1, height=1, top=-500, left=-500");
win.close();
}
chrome.notifications.clear("", function(wasCleared) {
openTemporaryWindowToRemoveFocus()
});

Related

Do we have to create new popup every time there is an update on google crome?

Do we have to create new popup if google crome updated or we can continue with the older one.
No one is sure what you're asking, but I'm going to take a stab at it. I believe you're asking if you have to use a new popup every time an advertisement is changed? If that is the case, the answer is no, you don't always have to have a new popup. HOWEVER, if the window was closed by the user, a new popup will have to be created. The following code will bring a named window to the front:
function GetAdWindow() {
// Change the window.open parameters to your liking
var AdWindow = window.open("", "AdWindow", "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=no,width=500,height=500");
return AdWindow;
}
After that, you have to determine if the page is blank, or already has an advertisement on it.
function UpdateAd(){
var AdWindow = GetAdWindow();
// If the AdWindow wasn't populated (meaning it was closed)
if (AdWindow.location.href === "about:blank") {
AdWindow.location = /*ADVERTISEMENT URL*/
} else {
// DO WHATEVER YOU WANT IF THE WINDOW HAD CONTENT
}
}
If you asking if your popup will go away if Chrome has an update, the answer is yes. Chrome as a whole will shot down and close all of the windows, then start back up clean.

chrome.notifications.update() or create()

I want my chrome extension to take a notification.id, and:
Update an existing notification if it does exist.
OR
Create a new notification if it doesn't exist.
Calling clear() then create() is not ideal, since the animation is visually jarring for both remove() and create() methods, where I want to update without animations. Plus, obviously, calling update() on a disappeared notification doesn't do anything.
Is there an easy way to implement this?
Edit: This approach no longer works on any platform except ChromeOS due to the removal of Chrome's Notification Center.
Possible ideas to work around it include using requireInteraction: true flag on notifications to fully control notification lifetime.
There is a dirty trick for re-showing a notification. If you change a notification's priority to a higher value, it will be re-shown if it exists.
function createOrUpdate(id, options, callback) {
// Try to lower priority to minimal "shown" priority
chrome.notifications.update(id, {priority: 0}, function(existed) {
if(existed) {
var targetPriority = options.priority || 0;
options.priority = 1;
// Update with higher priority
chrome.notifications.update(id, options, function() {
chrome.notifications.update(id, {priority: targetPriority}, function() {
callback(true); // Updated
});
});
} else {
chrome.notifications.create(id, options, function() {
callback(false); // Created
});
}
});
}
Xan's answer no longer works on Windows, MacOS, or Linux. At this point the only way to make sure your notification displays, no matter what, is to create a new notification.
If you want to prevent multiple notifications from being on screen, you'll have to clear the old notification and replace it with a new one. This is demonstrated below.
NOTIFICATION_ID = "some_random_string";
function showNotification ( ... , callback) {
chrome.notifications.clear(NOTIFICATION_ID, function(cleared) {
var options = {
// whatever
};
chrome.notifications.create(NOTIFICATION_ID, options, callback);
});
}
Of course, this results in an animation of existing notification getting dismissed and a new notification immediately taking its place, but unfortunately this is unavoidable.

Why "Prevent this page from creating additional dialogs" appears in the alert box?

In my Rails 3 application I do:
render :js => "alert(\"Error!\\nEmpty message sent.\");" if ...
Sometimes, below this error message (in the same alert box) I see: "Prevent this page from creating additional dialogs" and a checkbox.
What does this mean ?
Is that possible not to display this additional text and checkbox ?
I use Firefox 4.
It's a browser feature to stop websites that show annoying alert boxes over and over again.
As a web developer, you can't disable it.
What does this mean ?
This is a security measure on the browser's end to prevent a page from freezing the browser (or the current page) by showing modal (alert / confirm) messages in an infinite loop. See e.g. here for Firefox.
You can not turn this off. The only way around it is to use custom dialogs like JQuery UI's dialogs.
You can create a custom alert box using java script, below code will override default alert function
window.alert = function(message) { $(document.createElement('div'))
.attr({
title: 'Alert',
'class': 'alert'
})
.html(message)
.dialog({
buttons: {
OK: function() {
$(this).dialog('close');
}
},
close: function() {
$(this).remove();
},
modal: true,
resizable: false,
width: 'auto'
});
};
Using JQuery UI's dialogs is not always a solution. As far as I know alert and confirm is the only way to stop the execution of a script at a certain point. As a workaround we can provide a mechanism to let the user know that an application needs to call alert and confirm. This can be done like this for example (where showError uses a jQuery dialog or some other means to communicate with the user):
var f_confirm;
function setConfirm() {
f_confirm = confirm;
confirm = function(s) {
try {
return f_confirm(s);
} catch(e) {
showError("Please do not check 'Prevent this page from creating additional dialogs'");
}
return false;
};
};
I designed this function to hopefully circumvent the checkbox in my web apps.
It blocks all functionality on the page while executing (assuming fewer than three seconds has passed since the user closed the last dialog), but I prefer it to a recursive or setTimeout function since I don't have to code for the possibility of something else being clicked or triggered while waiting for the dialog to appear.
I require it most when displaying errors/prompts/confirms on reports that are already contained within Modalbox. I could add a div for additional dialogs, but that just seems too messy and unnecessary if built-in dialogs can be used.
Note that this would probably break if dom.successive_dialog_time_limit is changed to a value greater than 3, nor do I know if Chrome has the the same default as Firefox. But at least it's an option.
Also, if anyone can improve upon it, please do!
// note that these should not be in the global namespace
var dlgRslt,
lastTimeDialogClosed = 0;
function dialog(msg) {
var defaultValue,
lenIsThree,
type;
while (lastTimeDialogClosed && new Date() - lastTimeDialogClosed < 3001) {
// timer
}
lenIsThree = 3 === arguments.length;
type = lenIsThree ? arguments[2] : (arguments[1] || alert);
defaultValue = lenIsThree && type === prompt ? arguments[1] : '';
// store result of confirm() or prompt()
dlgRslt = type(msg, defaultValue);
lastTimeDialogClosed = new Date();
}
usage:
dialog('This is an alert.');
dialog( 'This is a prompt', prompt );
dialog('You entered ' + dlgRslt);
dialog( 'Is this a prompt?', 'maybe', prompt );
dialog('You entered ' + dlgRslt);
dialog( 'OK/Cancel?', confirm );
if (dlgRslt) {
// code if true
}
This is a browser feature.
If you could, try to employ http://bootboxjs.com/, whit this library you can do the same of
alert("Empty message sent");
by writing:
bootbox.alert("Empty message sent", function(result) {
// do something whit result
});
You'll get a nice user interface too!

Windows 7 Gadget Flyout Question

I'm having troubles with my flyout. What happens with my gadget is you double click a component and it will have a corresponding flyout window. If you double click that or any other visual component with a flyout, though, the flyout document is returned as null. I have no idea why this is, and if you make the flyout go away and reopen it or a new one it's ok. It's only when a flyout is already opened this happens. I'm looking for some ideas on why this is.
Double click code:
Blah.prototype.ondblclick = function()
{
var me = this.parent;
if (System.Gadget.Flyout.show)
{
// flyout is already shown, make sure it shows our stuff
System.Gadget.Flyout.file = FLYOUT_FILE;
onFlyoutShow();
}
else
{
System.Gadget.Flyout.file = FLYOUT_FILE;
System.Gadget.Flyout.onShow = onFlyoutShow;
System.Gadget.Flyout.show = true;
}
System.Gadget.Flyout.onHide = onFlyoutHide;
function onFlyoutShow()
{
me.flyoutOpen = true;
me.updateFlyout();
}
function onFlyoutHide()
{
me.flyoutOpen = false;
}
};
Executed code:
Blah.prototype.updateFlyout = function ()
{
var flyoutDoc = System.Gadget.Flyout.document;
//flyoutDoc is null at this point
var info = flyoutDoc.getElementById("info");
info.innerHTML = "info: " + this.information;
//Error thrown: 'null' is null or not an object
}
I don't know a lot about writing gadgets for windows 7, but to me it looks a lot like a timing issue. When the flyout is already there, you change the file property which tells it to load a new file. Without waiting you then call onFlyoutShow which tries to get the document and the document isn't loaded yet.
My first thought is: Doesn't the onShow event fire when you set the file? Probably doesn't or you wouldn't have the if, but worth verifying.
If that doesn't work, calling onFlyoutShow in a timeout. Start with a long timer, like 1000. And then shorten it, hopefully you can get down to 0: setTimeout(onFlyoutShow, 0);

Make browser window blink in task Bar

How do I make a user's browser blink/flash/highlight in the task bar using JavaScript? For example, if I make an AJAX request every 10 seconds to see if the user has any new messages on the server, I want the user to know it right away, even if he is using another application at the time.
Edit: These users do want to be distracted when a new message arrives.
this won't make the taskbar button flash in changing colours, but the title will blink on and off until they move the mouse. This should work cross platform, and even if they just have it in a different tab.
newExcitingAlerts = (function () {
var oldTitle = document.title;
var msg = "New!";
var timeoutId;
var blink = function() { document.title = document.title == msg ? ' ' : msg; };
var clear = function() {
clearInterval(timeoutId);
document.title = oldTitle;
window.onmousemove = null;
timeoutId = null;
};
return function () {
if (!timeoutId) {
timeoutId = setInterval(blink, 1000);
window.onmousemove = clear;
}
};
}());
Update: You may want to look at using HTML5 notifications.
I've made a jQuery plugin for the purpose of blinking notification messages in the browser title bar. You can specify different options like blinking interval, duration, if the blinking should stop when the window/tab gets focused, etc. The plugin works in Firefox, Chrome, Safari, IE6, IE7 and IE8.
Here is an example on how to use it:
$.titleAlert("New mail!", {
requireBlur:true,
stopOnFocus:true,
interval:600
});
If you're not using jQuery, you might still want to look at the source code (there are a few quirky bugs and edge cases that you need to work around when doing title blinking if you want to fully support all major browsers).
var oldTitle = document.title;
var msg = "New Popup!";
var timeoutId = false;
var blink = function() {
document.title = document.title == msg ? oldTitle : msg;//Modify Title in case a popup
if(document.hasFocus())//Stop blinking and restore the Application Title
{
document.title = oldTitle;
clearInterval(timeoutId);
}
};
if (!timeoutId) {
timeoutId = setInterval(blink, 500);//Initiate the Blink Call
};//Blink logic
Supposedly you can do this on windows with the growl for windows javascript API:
http://ajaxian.com/archives/growls-for-windows-and-a-web-notification-api
Your users will have to install growl though.
Eventually this is going to be part of google gears, in the form of the NotificationAPI:
http://code.google.com/p/gears/wiki/NotificationAPI
So I would recommend using the growl approach for now, falling back to window title updates if possible, and already engineering in attempts to use the Gears Notification API, for when it eventually becomes available.
My "user interface" response is: Are you sure your users want their browsers flashing, or do you think that's what they want? If I were the one using your software, I know I'd be annoyed if these alerts happened very often and got in my way.
If you're sure you want to do it this way, use a javascript alert box. That's what Google Calendar does for event reminders, and they probably put some thought into it.
A web page really isn't the best medium for need-to-know alerts. If you're designing something along the lines of "ZOMG, the servers are down!" alerts, automated e-mails or SMS messages to the right people might do the trick.
The only way I can think of doing this is by doing something like alert('you have a new message') when the message is received. This will flash the taskbar if the window is minimized, but it will also open a dialog box, which you may not want.
Why not take the approach that GMail uses and show the number of messages in the page title?
Sometimes users don't want to be distracted when a new message arrives.
you could change the title of the web page with each new message to alert the user. I did this for a browser chat client and most users thought it worked well enough.
document.title = "[user] hello world";
You may want to try window.focus() - but it may be annoying if the screen switches around
AFAIK, there is no good way to do this with consistency. I was writing an IE only web-based IM client. We ended up using window.focus(), which works most of the time. Sometimes it will actually cause the window to steal focus from the foreground app, which can be really annoying.
function blinkTab() {
const browserTitle = document.title;
let timeoutId;
let message = 'My New Title';
const stopBlinking = () => {
document.title = browserTitle;
clearInterval(timeoutId);
};
const startBlinking = () => {
document.title = document.title === message ? browserTitle : message;
};
function registerEvents() {
window.addEventListener("focus", function(event) {
stopBlinking();
});
window.addEventListener("blur", function(event) {
const timeoutId = setInterval(startBlinking, 500);
});
};
registerEvents();
};
blinkTab();
These users do want to be distracted when a new message arrives.
It sounds like you're writing an app for an internal company project.
You might want to investigate writing a small windows app in .net which adds a notify icon and can then do fancy popups or balloon popups or whatever, when they get new messages.
This isn't overly hard and I'm sure if you ask SO 'how do I show a tray icon' and 'how do I do pop up notifications' you'll get some great answers :-)
For the record, I'm pretty sure that (other than using an alert/prompt dialog box) you can't flash the taskbar in JS, as this is heavily windows specific, and JS really doesn't work like that. You may be able to use some IE-specific windows activex controls, but then you inflict IE upon your poor users. Don't do that :-(

Categories