firefox extensions, make notification box appear in all tabs - firefox-addon

Firefox has a native notification box system:
https://developer.mozilla.org/en/Code_snippets/Alerts_and_Notifications#Using_notification_box
I'd like to use this system in a way that it appears in all opened tabs when it is supposed to appear. The code I have only warns you in the currently opened tab.
var mainWindow = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIWebNavigation).QueryInterface(Components.interfaces.nsIDocShellTreeItem).rootTreeItem.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindow);
var nb = mainWindow.gBrowser.getNotificationBox();
//...
outdatedNotification = nb.appendNotification("Your information outdated",
'outdate-warn',
'chrome://checksistem/skin/checksistem.png',
priority, buttons);

Each tab has it's own notification box. You just need to loop over all the browsers and add the notification to each one. One thing you should know is the gBrowser.getNotificationBox can take a browser element:
http://mxr.mozilla.org/mozilla-central/source/browser/base/content/tabbrowser.xml#337
If you don't pass a browser, the code returns the notification box for the active tab.
Try this:
var browsers = mainWindow.gBrowser.browsers;
for (var i=0; i<browsers.length; i++) {
var nb = mainWindow.gBrowser.getNotificationBox(browsers[i]);
outdatedNotification = nb.appendNotification("Your information outdated",
'outdate-warn',
'chrome://checksistem/skin/checksistem.png',
priority, buttons);
}

Related

PrinterToPrint without showing the print job Progress dialog

I am using iOs default PrinterToPrint in Xamarin to print without showing dialog to choose printer but then also it's showing one dialog which says printing to [PRINTER NAME]. Is there anyway to hide the dialog as well. Like complete silent print functionality?
I am not its possible but I have seen some apps which do that and I am not sure whether they are using the same function or not.
Thanks in advance.
Update:
UIPrinterPickerController comes from UIKit and as such there is no way to push the "printing" process to the background and off the main UI thread.
In the current UIPrintInteractionController.PrintToPrinter implementation (currently up to iOS 10.3 B4) there is no exposed way to disable the print progress (Connecting, Preparing, etc...) alart/dialog (w/ Cancel button) or to modify its appearance.
This interface is high level wrapper using AirPrint and thus Internet Print Protocol (IPP) at a lower level to preform the actual printing, job queue monitoring on the printer, etc... IPP is not currently exposed as a publicly available framework within iOS...
Programs that allow background printing are not using UIPrintInteractionController to do the printing. Most do use UIPrinterPickerController to obtain a UIPrinter selection from the user, but then use the UIPrinter.Url.AbsoluteUrl to "talk" directly to the printer via HTTP/HTTPS Post/Get. Depending upon the printers used, TCP-based sockets are also an option vs. IPP and even USB/serial for direct connected printers.
Re: https://en.wikipedia.org/wiki/Internet_Printing_Protocol
Original:
Pick a Printer:
if (allowUserToSelectDifferentPrinter || printerUrl == null)
{
UIPrinter uiPrinter = printerUrl != null ? null as UIPrinter : UIPrinter.FromUrl(new NSUrl(printerUrl));
var uiPrinterPickerController = UIPrinterPickerController.FromPrinter(uiPrinter);
uiPrinterPickerController.Present(true, (printerPickerController, userDidSelect, error) =>
{
if (userDidSelect)
{
uiPrinter = uiPrinterPickerController?.SelectedPrinter;
printerUrl = uiPrinter.Url.AbsoluteUrl.ToString();
Console.WriteLine($"Save this UIPrinter's Url string for later use: {printerUrl}");
}
});
}
Print using UIPrintInteractionController with an existing UIPrinter:
if (printerUrl != null)
{
// re-create a UIPrinter from a saved NSUrl string
var uiPrinter = UIPrinter.FromUrl(new NSUrl(printerUrl));
var printer = UIPrintInteractionController.SharedPrintController;
printer.ShowsPageRange = false;
printer.ShowsNumberOfCopies = false;
printer.ShowsPaperSelectionForLoadedPapers = false;
var printInfo = UIPrintInfo.PrintInfo;
printInfo.OutputType = UIPrintInfoOutputType.General;
printInfo.JobName = "StackOverflow Print Job";
var textFormatter = new UISimpleTextPrintFormatter("StackOverflow Rocks")
{
StartPage = 0,
ContentInsets = new UIEdgeInsets(72, 72, 72, 72),
MaximumContentWidth = 6 * 72,
};
printer.Delegate = new PrintInteractionControllerDelegate();
printer.PrintFormatter = textFormatter;
printer.PrintToPrinter(uiPrinter, (printInteractionController, completed, error) =>
{
if ((completed && error != null))
{
Console.WriteLine($"Print Error: {error.Code}:{error.Description}");
PresentViewController(
UIAlertController.Create("Print Error", "Code: {error.Code} Description: {error.Description}", UIAlertControllerStyle.ActionSheet),
true, () => { });
}
printInfo?.Dispose();
uiPrinter?.Dispose();
uiPrinter.
});
}
else
{
Console.WriteLine("User has not selected a printer...printing disabled");
}
I know this is a somewhat old thread but I had been struggling with implementing a silent printing in iOS for one of my customers and I finally came across an acceptable solution that is very easy to implement.
As mentioned in the accepted answer there is no way to get rid of the popup that displays printing progress. Yet there is a way of hiding it. You can simply change the UIWindowLevel of your key window to UIWindowLevel.Alert + 100. This will guarantee your current window will display above ANY alert view.
Be careful though, as I mentioned, it will be displayed over ANY alert view after the level has been changed. Luckily you can just switch this level back to "Normal" to get the original behavior.
So to recap my solution. I use UIPrintInteractionController.PrintToPrinter in order to print directly to a printer object I created using UIPrinter.FromUrl (this is Xamarin.iOS code btw). Before doing so, I adjust my window level to alert + 100 and once printing is complete I reset my window level to "Normal". Now my printing happens without any visual feedback to my user.
Hope this helps somebody!

Set timeout for notifications.notify FireFox Addon SDK

Please help me with Notification in my Firefox add-on.
var notifications = require("sdk/notifications");
function showNotifcation(title, text) {
notifications.notify({
iconURL: data.url("img/icon.png"),
title: title,
text: text
});
setTimeout(notifications.close(), 1000);
}
Not work.
Without more information from you it is not possible to be sure as to what your problem/issue is.
However, a brief look at the sdk/notifications documentation, and source code, indicates that you are attempting to use a non-existent method: notifications.close(). There is no such method in sdk/notifications.
One possible reason for your attempt to use this method is that you are conflating the Web Notification API, more detail, with the Add-on SDK sdk/notifications.
The Add-on SDK, sdk/notifications, has no way for you to programmatically close the notification from your code. Thus, there is no way for you to set a timeout for the notification using this interface. However, in some operating systems/windowing systems there is already a default timeout for these notifications.
You will need to either display a panel on your own, or use the chrome interfaces described in User Notifications and Alerts.
In addition, it would be unusual for you to be able to just call setTimeout(). That will, under most contexts, not be defined. You would normally need to use sdk/timers with:
var { setTimeout } = require("sdk/timers");
In some contexts, you might be able to use window.setTimeout(), when window is appropriately defined (which you will probably have to set yourself).
Modifying the code from my answer to Prevent XUL notificationBox from closing when button is hit (if you want buttons, that answer will show you how to do it), and other answers of mine: Something along the lines of what I believe you desire would be (code for the timeout is at the bottom):
function showNotificationBox(text) {
//Create some common variables if they do not exist.
if (window === null || typeof window !== "object") {
// Add/remove a "/" to comment/un-comment the code appropriate for your add-on:
//* Add-on SDK:
var window = require('sdk/window/utils').getMostRecentBrowserWindow();
//*/
/* Overlay and bootstrap (from almost any context/scope):
var window=Components.classes["#mozilla.org/appshell/window-mediator;1"]
.getService(Components.interfaces.nsIWindowMediator)
.getMostRecentWindow("navigator:browser");
//*/
}
if (typeof gBrowser === "undefined") {
var gBrowser = window.gBrowser;
}
let notifyBox = gBrowser.getNotificationBox();
//appendNotification( label , value , image (URL) , priority , buttons, eventCallback )
let theNotification = notifyBox.appendNotification(text, "Test notification unique ID",
"chrome://browser/content/aboutRobots-icon.png",
notifyBox.PRIORITY_INFO_HIGH, [], null);
//* Add-on SDK:
var { setTimeout } = require("sdk/timers");
setTimeout(theNotification.close(), 10000);
//*/
/* Overlay and bootstrap:
let timerCallback = {
notify:function notify() {theNotification.close(); }
}
let closeNotificationTimer = Components.classes["#mozilla.org/timer;1"]
.createInstance(Components.interfaces.nsITimer);
closeNotificationTimer.initWithCallback(timerCallback,10000,
Components.interfaces.nsITimer.TYPE_ONE_SHOT);
//*/
}
Note: I changed the timeout to 10 seconds from the 1 second which is in the code in your question. One second is a unreasonable amount of time to expect to show anything which you actually desire the user to see and understand.
The above implements the user notification in a notificationBox. As such it shows up within the Firefox window:
It is also possible to use the nsIAlertsService which is what sdk/notifications uses. This will normally display an alert box in the bottom right of the screen, potentially outside of the Firefox window (see image on nsIAlertsService for example). The notification may show up elsewhere depending on how you have your windowing system set up (this is OS dependent). However, the documentation did not have a method to clear the notification, or set a timeout. However, the interface definition does show that a closeAlert() method does exist. The source code for the sdk/notifications does not expose this to the Add-on SDK. Thus, you would need to use the chrome interfaces. I have updated the documentation to show closeAlert().
Such as (some code taken and modified from nsIAlertsService):
//* Add-on SDK:
var {Cc, Ci} = require("chrome");
//*/
/* Overlay and bootstrap:
const Cc = Components.classes;
const Ci = Components.interfaces;
//*/
function showNotifcation(title, text) {
var alertsService = Cc["#mozilla.org/alerts-service;1"].getService(Ci.nsIAlertsService);
try {
//The second use of title is the alert name.
alertsService.showAlertNotification(icon, title, text, false, "", null, title);
} catch (e) {
// This can fail on Mac OS X
}
//* Add-on SDK:
var { setTimeout } = require("sdk/timers");
setTimeout(alertsService.closeAlert(title), 10000);
//*/
/* Overlay and bootstrap:
let alertTimerCallback = {
notify:function notify() {alertsService.closeAlert(title); }
}
let closeAlertTimer = Cc["#mozilla.org/timer;1"].createInstance(Components.interfaces
.nsITimer);
closeAlertTimer.initWithCallback(alertTimerCallback,10000,Ci.nsITimer.TYPE_ONE_SHOT);
//*/
}
I have only tested the above code with a bootstrapped/restartless Firefox add-on. Thus, the Add-on SDK code may be slightly off.

Firefox Addon: Get Sync Device Name

I'm writing a simple Addon for Firefox.
There's an option for user to set up a Device Name in Firefox Sync
How to get that name "My PC" in the Addon code?
It's a really simple extension
main.js
var buttons = require('sdk/ui/button/action');
var tabs = require("sdk/tabs");
var deviceName = what.what?
Probably using weave service but I can't figure it out:
var WeaveService = Cc["#mozilla.org/weave/service;1"].getService(Ci.nsISupports);
// Referencing Weave.Service will implicitly initialize sync, and we don't
// want to force that - so first check if it is ready.
/* WeaveService object holds these:
enabled:true
fxAccountsEnabled:true
ready:true
*/
if (WaveService.ready) {
}
So I cheated and read pref value:
var clientEngineName = Services.prefs.getCharPref('services.sync.client.name');

Xamarin Forms WebView Check When Website Address Changed

I have the following code that sets up a WebView inside my Xamarin.Forms Cross Platform application:
ReportsListWebView = new WebView()
{
VerticalOptions = LayoutOptions.FillAndExpand,
HorizontalOptions = LayoutOptions.FillAndExpand,
BackgroundColor = Xamarin.Forms.Color.Transparent
};
URLReportsListWebView = new UrlWebViewSource
{
Url = "http://192.168.0.96/MyWebsite/App/MiniMyWebsite?ActionType=Listing&Params=Reports"
};
ReportsListWebView.Source = URLReportsListWebView;
grid.Children.Add(ReportsListWebView, 0, 4, 0, 1);
The situation is that there is listing within the website that I am referencing in the WebView. When the user selects an item in the listing on the webpage it has javascript that changes the url of the website (appends #SelectedItem=1 to the url). I just want to be able to recognize this change from within the application.
I've checked the URLReportsListWebView.Url but it doesn't seem to update with the latest changes. Any ideas on how to achieve this?
Thanks
This ended up being a limitation on the xamarin forms webview control. The work around was to create a custom renderer which the Xamarin support provided me a great same showing how to accomplish this at github.com/jgold6/XFormsWebViewCustomRenderer/tree/master
When I've done a few tests against http://www.yahoo.com it appears to be updating the WebView.Source property ok, even with query string attribues.
Are you just updating the location of the current webpage rather than navigating to a new page?
Maybe this could be the reason why its not working for you?
If so, after the change, you will then be able to monitor the .Source property for the newly navigated webpage as there is no event handler or anything to hook into to get notified when a page has been navigated to / fully loaded.
Update 1:-
Try the following that is working for me.
It should produce updates similar to the following:-
http://www.yahoo.com
https://fr.yahoo.com/?p=us
https://fr.news.yahoo.com/syrie-jihadistes-exécutent-160-soldats-43-casques-bleus-050134941.html
http://www.tv3g.bouquettv.mobi/wap/landing/landing2.asp?c=LFYAH_TVGREEN_AAAMMM&IDLanding=16972&tag=0&Alea=7.906741E-02&Al=MM201408290946299694
Code:-
StackLayout objStackLayout = new StackLayout()
{
};
//
WebView objWebView1 = new WebView();
objWebView1.HeightRequest = 300;
objStackLayout.Children.Add(objWebView1);
//
UrlWebViewSource objUrlToNavigateTo = new UrlWebViewSource()
{
Url = "http://www.yahoo.com"
};
objWebView1.Source = objUrlToNavigateTo;
//
//
Button cmdButton1 = new Button();
cmdButton1.Text = "Show Me Current Url";
objStackLayout.Children.Add(cmdButton1);
//
cmdButton1.Clicked += ((o2, e2) =>
{
System.Diagnostics.Debug.WriteLine((objWebView1.Source as UrlWebViewSource).Url);
});
//
//
this.Content = objStackLayout;
If you don't yet have a custom renderer, you'll need to refer to Xamarin documentation to learn how to custom render Xamarin.Forms WebView.
If you already have the custom renderer, inside the CustomRenderer object, you should access the NativeWebview object and assign HandleShouldStartLoad to its ShouldStartLoad event handler. My mistake was that I assigned HandleShouldStartLoad to the event handler of the renderer itself, which won't work.

iPad website fullscreen in Safari

I am trying to get a website that runs fullscreen for all pages, I have looked over here: iPad WebApp Full Screen in Safari and followed that and my index page fills the screen just nicely, but whenever I click a link to another page even though that page is all setup with the meta tags it pulls the chrome bar back in and all the alignment goes out.
There must be a way or is that a limitation of safari that will be fixed in a later revision.
I have written a jQuery plugin for this exact purpose: https://github.com/mrmoses/jQuery.stayInWebApp
Include the plugin somehow , then run it like so:
$(function() {
$.stayInWebApp();
});
By default it will attach to all <a /> elements. You can pass a different selector to attach it to specific links. For example, $.stayInWebApp('a.stay'); will attach to all links that have class="stay"
Because its so small, I usually just copy the minified version into one of my other external javascript files to include it, rather than having to add another external js reference.
Also available on plugins.jquery.com
You can try something like this:
if ((navigator.userAgent.indexOf('iPad') != -1)) {
// for standalone (app) fulscreen mode
if (window.innerHeight == 748 || window.innerHeight == 1004) {
var a = document.getElementsByTagName("a");
for (var i = 0, len = a.length; i < len; i++) {
if (a[i].getAttribute("href");) {
a[i].onclick = function() {
window.location = this.getAttribute("href");
return false;
}
}
}
}
}

Resources