Html desktop notification with Addon Builder Firefox - firefox

I found how to show desktop notification with addon builder for firefox. Like in the below code, but how to show HTML custom notification, google chrome extension can show custom Html notification. Is that possible for Firefox, how?
Here's a typical example. When the message is clicked, a string is logged to the console.
var notifications = require("notifications");
notifications.notify({
title: "Jabberwocky",
text: "'Twas brillig, and the slithy toves",
data: "did gyre and gimble in the wabe",
onClick: function (data) {
console.log(data);
// console.log(this.data) would produce the same result.
}
});
This one displays an icon that's stored in the add-on's data directory. (See the self module documentation for more information.)
var notifications = require("notifications");
var self = require("self");
var myIconURL = self.data.url("myIcon.png");
notifications.notify({
text: "I have an icon!",
iconURL: myIconURL
});

It looks like you've found the current documentation:
https://addons.mozilla.org/en-US/developers/docs/sdk/latest/modules/sdk/notifications.html
As stated there, (sorry) HTML content in notifications is not supported in the Add-on SDK.

Related

Firefox WebExtension notifications API: How to call a function when the notification is clicked

I'm trying to develop a Firefox add on using WebExtensions. What I'm trying to do is open a new Firefox tab or window when the user clicks the notification. But it doesn't work.
When I click the notification, nothing happens.
I'm creating notifications like:
var q = chrome.notifications.create({
"type": "basic",
"iconUrl": chrome.extension.getURL("128-128q.png"),
"title": 'title',
"message": 'content'
});
chrome.notifications.onClicked.addListener(function(notificationId) {
window.open('http://www.google.com');
});
browser.notifications.onClicked.addListener(function(notificationId) {
window.open('http://www.google.com');
});
q.onClicked.addListener(function(notificationId) {
window.open('http://www.google.com');
});
var audio = new Audio('message.mp3');
audio.play();
How can I make this work?
It appears that the problem is that you are attempting to open a new URL in a way that does not work.
The following should work, using chrome.tabs.create():
var q = chrome.notifications.create("MyExtensionNotificationId", {
"type": "basic",
"iconUrl": chrome.extension.getURL("128-128q.png"),
"title": 'title',
"message": 'content'
});
chrome.notifications.onClicked.addListener(function(notificationId) {
chrome.tabs.create({url:"http://www.google.com"});
});
However, you need to be testing this in Firefox 47.0+ as support for chrome.notifications.onClicked() was only added recently. My statement of Firefox 47.0+ is based on the compatibility table. However, the compatibility table has at least one definite error. Thus, a higher version of Firefox may be required. The code I tested worked in Firefox Nightly, version 50.0a1, but did not work properly in Firefox Developer Edition, version 48.0a2. In general, given that the WebExtensions API is in active development, you should be testing against Firefox Nightly if you have questions/issues which are not functioning as you expect. You can also check the source code for the API to see what really is implemented and when it was added.
Note: this works with either chrome.notifications.onClicked or browser.notifications.onClicked. However, don't use both to add two separate anonymous functions which do the same thing as doing so will result in whatever you are doing happening twice.
I did not actually test it with your code, but I did test it with a modified version of the notify-link-clicks-i18n WebExtensions example. I modified the background-script.js file from that example to be:
/*
Log that we received the message.
Then display a notification. The notification contains the URL,
which we read from the message.
*/
function notify(message) {
console.log("notify-link-clicks-i18n: background script received message");
var title = chrome.i18n.getMessage("notificationTitle");
var content = chrome.i18n.getMessage("notificationContent", message.url);
let id = "notify-link-clicks-i18n::" + title + "::" + message.url;
chrome.notifications.create(id,{
"type": "basic",
"iconUrl": chrome.extension.getURL("icons/link-48.png"),
"title": title,
"message": content
});
}
/*
Assign `notify()` as a listener to messages from the content script.
*/
chrome.runtime.onMessage.addListener(notify);
//Add the listener for clicks on a notification:
chrome.notifications.onClicked.addListener(function(notificationId) {
console.log("Caught notification onClicked with ID:" + notificationId);
//Open a new tab with the desired URL:
browser.tabs.create({url:"http://www.google.com"});
});
My preference for something like this where a unique ID is possible is to provide a unique ID, that both identifies that the notification was displayed by my add-on and what the notification was. This allows the listener function to choose to only act on notifications which were displayed by my add-on and/or only a subset of those I display, or have different actions based on why I displayed the notification.
The reason you had trouble here in figuring out what was not working is probably because you did not reduce the issue to the minimum necessary to demonstrate the issue. In other words, it would have been a good idea to just try opening a new URL separately from the notifications onClicked listener and just try a console.log() within the listener.

Firefox ToolBar Button When Click Changes DOM?

New to firefox development and trying my best to figure this out.
Say I want to call a function in tap_browser.js that will modify the DOM when the user clicks on the toolbar widget, how would I do this?
This is the code I have so far
require("toolbarwidget").ToolbarWidget({
toolbarID: "nav-bar", // <-- Place widget on Navigation bar
id: "tap-icon",
label: "Tap",
contentURL: data.url("favicon.png"),
contentScriptFile: [data.url("tap_browser.js")]
});
I'm currently using a library to create the toolbar widget here: https://github.com/Rob--W/toolbarwidget-jplib
I don't know too much SDK but I helped someone with something that does. Check this out:
var my_wid = widgets.Widget({
id: "my-widget",
label: "CLIIIICK",
content: "CLICK ME",
width: 100,
onClick: function()
{
require('sdk/window/utils').getMostRecentBrowserWindow().gBrowser.contentDocument.documentElement.innerHTML = 'hi';
}
});
what this does is it shows a panel with 0 width and height, you can put stuff in there, and when it shows it executes the onShow function to change the html of the current document. its not recommended to use innerHTML, addons arent accepted. Im just showing you a quick and dirty copy paste example. One that is different from the sdk doc page "Modifying the Page Hosted by a Tab"

Can't import the nsIDOMGeoGeolocation XPCOM Interface

Using the addon-sdk of firefox I'm following a tutorial about creating reusable modules, the example uses the geolocation API built into Firefox, so the code is simple:
function getCurrentPosition(callback){
var xpcomGeolocation = Cc["#mozilla.org/geolocation;1"].getService(Ci.nsIDOMGeoGeolocation);
xpcomGeolocation.getCurrentPosition(callback);
}
var widget = require("sdk/widget").Widget({
id: "whereami",
label: "Where Am I?",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(){
console.log("clicked!");
getCurrentPosition(function(position){
console.log("latitude: " + position.coords.latitude);
console.log("longitude: " + position.coords.longitude);
});
}
});
When running firefox with the plugin on, clicking the widget give this error:
Message: [Exception... "Component returned failure code: 0x80570018 (NS_ERROR_XPC_BAD_IID) [nsIJSCID.getService]" nsresult: "0x80570018 (NS_ERROR_XPC_BAD_IID)" location: "JS frame :: resource://gre/modules/XPIProvider.jsm -> jar:file:///tmp/tmpTFowYc.mozrunner/extensions/jid1-LIBIfbK6zvWAiQ#jetpack.xpi!/bootstrap.js -> resource://gre/modules/commonjs/toolkit/loader.js -> resource://jid1-libifbk6zvwaiq-at-jetpack/whereami/lib/main.js :: getCurrentPosition :: line 7" data: no]
According to docs, it's possible to get an error when importing nsIDGeoGeolocation so you must use Cc["#mozilla.org/geolocation;1"].getService(Ci.nsISupports); instead. Also, you must ask for permission to access geolocation, please see section Prompting for permission in
Using geolocation
reference.
By the way, as an advice, I think it will be simpler to use navigator.geolocation.getCurrentPosition(successCallback, errorCallback) since it handles prompting for permission for you, but I don't know what are you trying to do beyond this. Just to explain it a little, you could have an addon page data/index.html where you tell the user you are going to prompt him for his geolocation. Besides this, you must have a PageMod that runs a data/script.js for that addon page page, which has access to navigator.geolocation. That content script may communicate with your lib/main.js file so it has access to the user geo location. Somethings like this:
data/index.html:
<html>
<body>
<h1>Hello user!</h1>
</body>
</html>
data/script.js:
var successCallback = function(position) {
/* this way this script will talk to the pagemod in lib/main.js the user's position */
self.port.emit("gotGeolocation", position.coords.latitude, position.coords.longitude);
};
navigator.geolocation.getCurrentPosition(successCallback, errorCallback);
lib/main.js:
var data = require("sdk/self").data;
var pageMod = require("sdk/page-mod");
var tabs = require("sdk/tabs");
pageMod.PageMod({
/* attach the contentScriptFile to this html page */
include: data.url("index.html"),
contentScriptFile: data.url("script.js"),
onAttach: function(worker) {
/* listen to the script.js worker "gotGeolocation" message */
worker.port.on("gotGeolocation", function(latitude, longitude) {
console.log("latitude:", latitude);
console.log("longitude:", longitude);
});
}
});
/* this will open the index.jtml page and promt the user to access his geo position */
tabs.open(data.url("index.html"));
All this code it's only to better describe the idea, it hasn't been tested and in fact there are some indefinded objects. But I hope to give you an idea of how you can acces navigator.geolocation and pass its coords to the main.js script.
I think that you just forgot this at the top:
var { Cc, Ci } = require('chrome');
Also there a third party module for geolocation https://github.com/ZER0/geolocation

How to produce a settings dialog (and save the values)

These are my first steps with the Firefox AddOn SDK. What I'm trying to create is a simple 'settings dialogue'. I thought about a html page containing forms for the values and a submit button. Following the first mozilla tutorials I created a widget:
var widget = require('widget').Widget({
label: 'Settings',
id: 'settings',
//panel: text_entry
contentURL: data.url('images/stgfavicon.ico'),
contentScriptFile: data.url('scripts/submit.js'),
onClick: function() {
tabs.open(data.url('forms/settings.html'));
}
});
But since settings.js is not the contentScriptFile I got no communication between settings.html and settings.js. Is it possible to get this done without some (complex looking) messaging system? And how to save the values best? A JSON file?
Some links/examples/API names would help me a lot. :)
That's because you're trying to attach your script to the widget (which is not an HTML file). You need to attach it to the actual html file after the tab opens.
tabs.open({
url: data.url('forms/settings.html'),
onOpen: function onOpen(tab) {
tab.attach({ contentScriptFile: data.url('scripts/submit.js'); });
}
});
I haven't tested that out so there may be an error.
You should also look at the simple-prefs module if these are settings that aren't going to be adjusted frequently.

Firefox Addon: Add some functions and object to the window object

I just started using the FireFox Builder to build a simple addon. I realised that I cannot get direct access to the window object.
What I want to do is to get the window object and pollute it with some classes and functions so I can call them from the page itself.
Below is the current code:
// This is an active module of the ritcoder Add-on
require("widget").Widget({
id: "widgetID1",
label: "My Mozilla Widget",
contentURL: "http://www.mozilla.org/favicon.ico",
onClick: function(evt){
var tabs = require("tabs");
var activeTab = tabs.activeTab;
var notifications = require("notifications");
notifications.notify({
title: "Jabberwocky",
text: "'Twas brillig, and the slithy toves",
data: "did gyre and gimble in the wabe",
onClick: function (data) {
console.log(data);
// console.log(this.data) would produce the same result.
}
});
activeTab.window.a=20; //this fails
context.alert('yesx');
}
});
How do I do this? Inject some code into the active page so that it can be called.
regards,
You need to use tab.attach() to run a content script in the tab's context, and then use unsafeWindow to add properties the page's script can see. (You should also read the introduction to Content Scripts.)
The Addon SDK doesn't provide a direct access (without the content script) to the page from the add-on's code because it tries to be forward compatible with the plans to make web pages run in processes separate from the browser's and the add-on's process.

Resources