This question already has an answer here:
after updating chrome(35.0.1916.114 m), webkitNotifications does not work
(1 answer)
Closed 7 years ago.
I have a extension that shows a notifications, and worked fine until chrome updating and doesn't work any more with Chrome.
What I should edit on this code to make it working.
here is my code.
deskNoti=webkitNotifications.createNotification(chrome.app.getDetails().name,'You have '+counter+' new messages');
deskNoti.onclick=function(){openPage();this.cancel()
};
deskNoti.show();
if(timeNoti){window.setTimeout(function(){deskNoti.cancel();},timeNoti);}
webkitNotifications has been removed. The direct replacement is Notifications API.
The code is easy to translate:
// Instead of calling a create function, one calls the "new" operator:
deskNoti = new Notification(
chrome.app.getDetails().name,
// Instead of just message text, the second parameter is now an object
// with multiple properties. Message text should go into "body" parameter:
{ body: 'You have '+counter+' new messages' }
);
// Instead of .cancel(), the function to close the notification is now .close()
deskNoti.onclick = function() { openPage(); this.close() };
// Notifications are now shown automatically; there is no .show() function
//deskNoti.show();
if(timeNoti) {
window.setTimeout(function() { deskNoti.close(); }, timeNoti);
}
Consider using chrome.notifications API instead.
Related
This question already has answers here:
Capturing javascript console.log? [duplicate]
(2 answers)
Closed 4 years ago.
I have been seeing in some questions on Stack Overflow that there is examples, example code or snippets. Such as the one below:
console.log(1, 2, 3)
By running the code snippet above you'll see something like this:
I am currently working with something in node.js that also requires to fetch the output from console.logs. I find it fascinating that Stack Overflow is able to do this, whilst I don't even have a single clue how they did this.
I would be very thankful if someone could send me a link to where I can read and learn about how to fetch data form the console API.
Cheers,
Richard
P.S. If someone could edit this post to display the image, I'd be very thankful.
Edit
The project that I'm working on is an Electron app. It uses both the node.js process and the Electron BrowserWindow.
It uses a logger that I'm working on wich needs to fetch data from console.log
Some of the use cases might look like this:
console.log('%d is cool', User.firstName)
// => "Jason is cool"
or
console.log('User ID:', User._id)
// => A5FFE
or
console.log('%cUser connected!', 'color: #00FF00')
// => User connected!
// In green text.
You can overwrite window.console.log with your own function to achieve such an effect. For example:
const oldConsoleLog = console.log.bind(console);
console.log = (...params) => {
const textToDisplay = params.map(param =>
typeof param === 'object'
? JSON.stringify(param)
: param
);
document.body.appendChild(document.createElement('div'))
.textContent = textToDisplay;
oldConsoleLog(...params);
};
console.log('foo');
console.log('bar baz');
console.log({ prop: 'value' });
.as-console-wrapper {
height: 60%
}
In nodejs, console.log just formats the data you pass to it and then writes it to process.stdout which is a stream that goes to your commandline window. To intercept that, you can just listen for events on that stream:
process.stdout.on("data", chunk => {
// Do what you wanna do
});
This question already has answers here:
How do I return the response from an asynchronous call?
(41 answers)
Closed 6 years ago.
I have a basic function in JavaScript that simply takes some pre-set values and puts them onto the screen by the use of a pre-made function. When I breakpoint the first line of what it is I'm doing, the page loads fine, as expected, but as soon as I remove that breakpoint, none of the information is set. and the page is blank.
this.QuizSelection = function () {
// Fill the ID's with the right info
app.SetBackground('head', this.HeroImage);
console.log('1 ' + this.HeroImage);
app.LoadInnerHTML('breadcrumbs', 'Home / ' + this.Title);
app.LoadInnerHTML('quizSelectionTitle',this.Title);
console.log('2 ' + this.Title);
app.LoadInnerHTML('quizSelectionIntro',this.Introduction);
console.log('3 ' + this.Introduction);
// Show the Quiz Selection and Heading
app.ShowSection('head');
app.ShowSection('quizSelection');
console.log('Quiz Selection');
}.bind(this);
The functions inside that (SetBackground and LoadInnerHTML) are just small one line functions that change the inner html and the set a background image.
// Change Inner HTML
this.LoadInnerHTML = function (id, html) {
var d = document.getElementById(id);
d.innerHTML = html;
}
// Set Background Image
this.SetBackground = function (id, image) {
document.getElementById(id).style.backgroundImage = 'url(image)';
}
I can't understand why it wouldn't work when the breakpoint isn't on. Clearly it does work, because everything is fine with the breakpoint on, but then when it's off the result I get output to the console is:
1
2
3 undefined
Quiz Selection
You have a race condition.
The act of hitting a breakpoint makes your code wait for the async JSON load to complete. Without the breakpoint, the code trying to read the JSON is executing before the JSON has actually loaded.
See How do I return the response from an asynchronous call? for how to fix this issue.
You have console.log statements in your code. When the debugger is not on, console object does not exist (this is true for IE not for Chrome to the best of my knowledge), thus your javascript code execution fails.
My goal is to create a notification with a Chrome extension when a value in firebase changes.
With the code below I receive a notification the first time I'm changing the value, but not the following times.
f.on('child_changed', function (snapshot) {
ignoreInitialData = false;
var options = {
type: 'basic',
iconUrl: '../../icons/green.png',
title: "Availability notifier",
message: snapshot.val(),
contextMessage: "",
eventTime: Date.now(),
isClickable: false,
};
chrome.notifications.create("child_changed", options, function (notificationID) {
console.error(chrome.runtime.lastError);
});
});
Any solutions?
Since you're using a fixed notification ID, it's updated instead of creating a new one.
If the notification is not closed but hidden in the Chrome notification center, it will not be shown again.
Your options include:
Not using a fixed ID (pass "" as ID)
This will cause both the old and the new notifications to remain until dismissed. Probably not what you want.
Closing the old notification just before showing a new one.
This works well, but is visually jarring if your old notification did not yet disappear. However, you may actually want this effect if you want to emphasize "this is new information"
Using a priority change trick to re-show the notification.
This works best, but is "hacky". We can only hope Chrome API will improve to do this natively.
You can also add a timestamp suffix so every notification is different:
var timestamp = new Date().getTime();
var id = 'myid' + timestamp;
This question already has answers here:
chrome.storage.local.get and set [duplicate]
(3 answers)
Closed 8 years ago.
I have a chrome extension that is using storage and I can't get the value from the storage with one enter click.
There is a single input field. After the user enters a value and presses enter, the extension should take the value from storage and add the user's input to this value. The first enter press it doesn't work, but if user clicks Enter for second time, then stored value is seen.
I assume that problem is in the ordering of functions, but I can't understand where exactly.
Code in correct order:
var repo, moduleCodes, url;
// Third process
function getStoredUrl() {
chrome.storage.sync.get(function (item) {
url = item.savedUrl;
});
}
// Fourth process
function setVariables() {
repo = document.getElementById("repo").value.toLowerCase();
moduleCodes = {
admin: "EHEALTHADM"
};
}
// Second process
function openGraph() {
getStoredUrl();
setVariables();
if (moduleCodes[repo] !== undefined) {
// ERROR: field "test" doesn't have value url, but should to have
document.getElementById("test").value = url;
//window.open(url + moduleCodes[repo]);
} else {
returnError("Can't find repo " + repo, "repo");
}
}
var enter = 13;
// First process
function inputRepoListener(e) {
"use strict";
if (e.keyCode === enter) {
openGraph();
}
}
The whole code can be seen on gitHub repo: https://github.com/iriiiina/fisheyeGraph
This is a typical race condition, caused by asynchronous method calls.
The call to storage.sync.get is asynchronous, i.e. the normal program flow continues while the storage values are being retrieved. This means that also the assignment of the (still empty) url variable to the element with id test happens before the storage value retrieval has finished.
Solution: Move everything that should happen after the storage value has been retrieved into the callback of storage.sync.get. If, for example, you assign the url like that, it will work.
chrome.storage.sync.get(function (item) {
url = item.savedUrl;
document.getElementById("test").value = url;
});
So you need to restructure your code in order to meet this criteria.
I am opening a popup window and attaching an onbeforeunload event to it like this:
win = window.open("http://www.google.com", "", "width=300px,height=300px");
win.onbeforeunload = function() {
//do your stuff here
alert("Closed");
};
If I leave the URL empty, the new popup opens with "about:blank" as the address but when I close it, I see the alert.
If I open in as you see it (with an external URL), once it's closed, I cannot see the alert anymore. Any idea why this is happening?
As mentioned, same origin policy prevents Javascript from detecting such events. But there's a quite simple solution which allows you to detect closure of such windows.
Here's the JS code:
var openDialog = function(uri, name, options, closeCallback) {
var win = window.open(uri, name, options);
var interval = window.setInterval(function() {
try {
if (win == null || win.closed) {
window.clearInterval(interval);
closeCallback(win);
}
}
catch (e) {
}
}, 1000);
return win;
};
What it does: it creates new window with provided parameters and then sets the checker function with 1s interval. The function then checks if the window object is present and has its closed property set to false. If either ot these is not true, this means, that the window is (probably) closed and we should fire the 'closeCallback function' callback.
This function should work with all modern browsers. Some time ago Opera caused errors when checking properties from windows on other domains - thus the try..catch block. But I've tested it now and it seems it works quite ok.
We used this technique to create 'facebook-style' login popups for sites which doesn't support them via SDK (ehem... Twitter... ehem). This required a little bit of extra work - we couldn't get any message from Twitter itself, but the Oauth redireced us back to our domain, and then we were able to put some data in popup window object which were accessible from the opener. Then in the close callback function we parsed those data and presented the actual results.
One drawback of this method is that the callback is invoked AFTER the window has been closed. Well, this is the best I was able to achieve with cross domain policies in place.
You could listen to the 'focus' event of the opener window which fires when the user closes the popup.
Unfortunately, you're trying to communicate across domains which is prohibited by JavaScript's same origin policy. You'd have to use a server-side proxy or some other ugly hack to get around it.
You could try creating a page on your site that loads the external website in an iframe. You could then pop open that page and listen for it to unload.
I combined #ThomasZ's answer with this one to set an interval limit (didn't want to use setTimeout).
Example (in Typescript, declared anonymously so as not lose reference to "this"):
private _callMethodWithInterval = (url: string, callback: function, delay: number, repetitions: number) => {
const newWindow = window.open(url, "WIndowName", null, true);
let x = 0;
let intervalID = window.setInterval(() => {
//stops interval if newWindow closed or doesn't exist
try {
if (newWindow == null || newWindow.closed) {
console.info("window closed - interval cleared")
callback();
window.clearInterval(intervalID);
}
}
catch (e) {
console.error(`newWindow never closed or null - ${e}`)
}
//stops interval after number of intervals
if (++x === repetitions) {
console.info("max intervals reached - interval cleared")
window.clearInterval(intervalID);
}
}, delay)
}//end _callMethodWithInterval