mirror of
https://github.com/moparisthebest/FireTray
synced 2024-12-22 05:48:49 -05:00
proof of concept version
This commit is contained in:
parent
1366a19410
commit
c842690051
@ -1,6 +1,6 @@
|
|||||||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
|
||||||
Components.utils.import("resource://sce/commons.js");
|
Components.utils.import("resource://mozt/commons.js");
|
||||||
|
|
||||||
const Cc = Components.classes;
|
const Cc = Components.classes;
|
||||||
const Ci = Components.interfaces;
|
const Ci = Components.interfaces;
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||||
<!DOCTYPE prefwindow SYSTEM "chrome://sce/locale/options.dtd">
|
<!DOCTYPE prefwindow SYSTEM "chrome://mozt/locale/options.dtd">
|
||||||
<prefwindow id="sce-preferences"
|
<prefwindow id="mozt-preferences"
|
||||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||||
title="&prefwindow.title;"
|
title="&prefwindow.title;"
|
||||||
onload= "mozt.UIOptions.onLoad()">
|
onload= "mozt.UIOptions.onLoad()">
|
||||||
|
@ -1,63 +1,39 @@
|
|||||||
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
|
||||||
/*
|
Components.utils.import("resource://mozt/commons.js");
|
||||||
* GLOBAL APPROACH:
|
Components.utils.import("resource://mozt/LibGtkStatusIcon.js");
|
||||||
*
|
|
||||||
* since we can't avoid the about:certerr page (1), and can't shortcut the
|
|
||||||
* internal request to about:certerr gracefully (2), we:
|
|
||||||
*
|
|
||||||
* - add the cert exception
|
|
||||||
* - wait for the full load of the about:certerr page (that's the tricky part)
|
|
||||||
* - load the initially requested URL
|
|
||||||
*
|
|
||||||
* (1) certerror is hardly avoidable since it may be displayed whenever a
|
|
||||||
* newsocket is created, see: nsNSSIOLayer.cpp: dialogs->ShowCertError,
|
|
||||||
* nsNSSBadCertHandler, nsSSLIOLayerNewSocket,
|
|
||||||
* ./netwerk/base/src/nsSocketTransport2.cpp
|
|
||||||
*
|
|
||||||
* (2) a raw reload of the requested https page works, but is not very clean
|
|
||||||
* since it shortcuts the internal request to about:certerr, and produces a
|
|
||||||
* harmless *no element found* error (displayed shortly and not too noticeable
|
|
||||||
* though)
|
|
||||||
*/
|
|
||||||
|
|
||||||
Components.utils.import("resource://sce/commons.js");
|
|
||||||
|
|
||||||
mozt.Main = {
|
mozt.Main = {
|
||||||
|
|
||||||
onLoad: function() {
|
onLoad: function() {
|
||||||
// initialization code
|
// initialization code
|
||||||
this.initialized = null;
|
this.initialized = null;
|
||||||
this.strings = document.getElementById("sce-strings");
|
this.strings = document.getElementById("mozt-strings");
|
||||||
this.overrideService = null;
|
|
||||||
this.recentCertsService = null;
|
|
||||||
this.notification = {};
|
|
||||||
this.stash = {};
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// Set up preference change observer
|
// Set up preference change observer
|
||||||
mozt.Utils.prefService.QueryInterface(Ci.nsIPrefBranch2);
|
mozt.Utils.prefService.QueryInterface(Ci.nsIPrefBranch2);
|
||||||
// must stay out of _toggle()
|
// must stay out of _toggle()
|
||||||
mozt.Utils.prefService.addObserver("", this, false);
|
mozt.Utils.prefService.addObserver("", this, false);
|
||||||
|
|
||||||
// Get cert services
|
|
||||||
this.overrideService =
|
|
||||||
Cc["@mozilla.org/security/certoverride;1"]
|
|
||||||
.getService(Components.interfaces.nsICertOverrideService);
|
|
||||||
this.recentCertsService = Cc["@mozilla.org/security/recentbadcerts;1"]
|
|
||||||
.getService(Ci.nsIRecentBadCertsService);
|
|
||||||
}
|
}
|
||||||
catch (ex) {
|
catch (ex) {
|
||||||
Components.utils.reportError(ex);
|
Components.utils.reportError(ex);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var enabled = mozt.Utils.prefService.getBoolPref('enabled');
|
|
||||||
mozt.Debug.dump('enabled: '+enabled);
|
|
||||||
if (enabled)
|
|
||||||
this._toggle(true);
|
|
||||||
|
|
||||||
mozt.Debug.dump('SkipCertError LOADED !');
|
LibGtkStatusIcon.init();
|
||||||
|
/*
|
||||||
|
GtkStatusIcon *tray_icon = gtk_status_icon_new();
|
||||||
|
GdkPixbuf *default_icon = gdk_pixbuf_new_from_xpm_data(firefox_xpm);
|
||||||
|
gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(tray_icon),
|
||||||
|
GDK_PIXBUF(default_icon));
|
||||||
|
*/
|
||||||
|
this.tray_icon = LibGtkStatusIcon.gtk_status_icon_new();
|
||||||
|
// var pixmap = "hi"; // TODO: read pixmap from file
|
||||||
|
// LibGtkStatusIcon.gdk_pixbuf_new_from_xpm_data(pixmap);
|
||||||
|
|
||||||
|
mozt.Debug.dump('Moztray LOADED !');
|
||||||
this.initialized = true;
|
this.initialized = true;
|
||||||
return true;
|
return true;
|
||||||
},
|
},
|
||||||
@ -65,30 +41,12 @@ mozt.Main = {
|
|||||||
onQuit: function() {
|
onQuit: function() {
|
||||||
// Remove observer
|
// Remove observer
|
||||||
mozt.Utils.prefService.removeObserver("", this);
|
mozt.Utils.prefService.removeObserver("", this);
|
||||||
|
LibGtkStatusIcon.shutdown();
|
||||||
this._toogle(false);
|
|
||||||
|
|
||||||
mozt.Debug.dump('SkipCertError UNLOADED !');
|
mozt.Debug.dump('SkipCertError UNLOADED !');
|
||||||
this.initialized = false;
|
this.initialized = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// since we are using a TabsProgressListener, it seems we do not need to keep
|
|
||||||
// track of WebProgressListeners as indicated on
|
|
||||||
// https://developer.mozilla.org/en/XUL_School/Intercepting_Page_Loads#WebProgressListeners
|
|
||||||
_toggle: function (enable) {
|
|
||||||
mozt.Debug.dump('toggle: '+enable);
|
|
||||||
try {
|
|
||||||
if (enable) {
|
|
||||||
gBrowser.addTabsProgressListener(this.TabsProgressListener);
|
|
||||||
} else {
|
|
||||||
gBrowser.removeTabsProgressListener(this.TabsProgressListener);
|
|
||||||
}
|
|
||||||
} catch (ex) {
|
|
||||||
Components.utils.reportError(ex);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
|
|
||||||
observe: function(subject, topic, data) {
|
observe: function(subject, topic, data) {
|
||||||
// Observer for pref changes
|
// Observer for pref changes
|
||||||
if (topic != "nsPref:changed") return;
|
if (topic != "nsPref:changed") return;
|
||||||
@ -102,301 +60,6 @@ mozt.Main = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
_getCertException: function(uri, cert) {
|
|
||||||
var outFlags = {};
|
|
||||||
var outTempException = {};
|
|
||||||
var knownCert = mozt.Main.overrideService.hasMatchingOverride(
|
|
||||||
uri.asciiHost,
|
|
||||||
uri.port,
|
|
||||||
cert,
|
|
||||||
outFlags,
|
|
||||||
outTempException);
|
|
||||||
return knownCert;
|
|
||||||
},
|
|
||||||
|
|
||||||
_addCertException: function(SSLStatus, uri, cert) {
|
|
||||||
var flags = 0;
|
|
||||||
if(SSLStatus.isUntrusted)
|
|
||||||
flags |= mozt.Main.overrideService.ERROR_UNTRUSTED;
|
|
||||||
if(SSLStatus.isDomainMismatch)
|
|
||||||
flags |= mozt.Main.overrideService.ERROR_MISMATCH;
|
|
||||||
if(SSLStatus.isNotValidAtThisTime)
|
|
||||||
flags |= mozt.Main.overrideService.ERROR_TIME;
|
|
||||||
mozt.Main.overrideService.rememberValidityOverride(
|
|
||||||
uri.asciiHost, uri.port,
|
|
||||||
cert,
|
|
||||||
flags,
|
|
||||||
mozt.Utils.prefService.getBoolPref('add_temporary_exceptions'));
|
|
||||||
mozt.Debug.dump("CertEx added");
|
|
||||||
mozt.Main.TabsProgressListener._certExceptionJustAdded = true;
|
|
||||||
mozt.Debug.dump("certEx changed: " + mozt.Main.TabsProgressListener._certExceptionJustAdded);
|
|
||||||
|
|
||||||
mozt.Main.TabsProgressListener._goto = uri.spec; // never reset
|
|
||||||
},
|
|
||||||
|
|
||||||
_parseBadCertFlags: function(flags) {
|
|
||||||
var tag = '';
|
|
||||||
var ns = Ci.nsIX509Cert;
|
|
||||||
|
|
||||||
if (flags & ns.NOT_VERIFIED_UNKNOWN)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('NOT_VERIFIED_UNKNOWN');
|
|
||||||
if (flags & ns.CERT_REVOKED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('CERT_REVOKED');
|
|
||||||
if (flags & ns.CERT_EXPIRED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('CERT_EXPIRED');
|
|
||||||
if (flags & ns.CERT_NOT_TRUSTED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('CERT_NOT_TRUSTED');
|
|
||||||
if (flags & ns.ISSUER_NOT_TRUSTED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('ISSUER_NOT_TRUSTED');
|
|
||||||
if (flags & ns.ISSUER_UNKNOWN)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('ISSUER_UNKNOWN');
|
|
||||||
if (flags & ns.INVALID_CA)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('INVALID_CA');
|
|
||||||
if (flags & ns.USAGE_NOT_ALLOWED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('USAGE_NOT_ALLOWED');
|
|
||||||
if (flags & SCE_CERT_SELF_SIGNED)
|
|
||||||
tag += ', ' + mozt.Main.strings.getString('CERT_SELF_SIGNED');
|
|
||||||
|
|
||||||
if (tag != "") tag = tag.substr(2);
|
|
||||||
|
|
||||||
return tag;
|
|
||||||
},
|
|
||||||
|
|
||||||
notify: function(abrowser) {
|
|
||||||
|
|
||||||
// find the correct tab to display notification on
|
|
||||||
var mainWindow = window
|
|
||||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation)
|
|
||||||
.QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem
|
|
||||||
.QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow);
|
|
||||||
var notificationBox = mainWindow.gBrowser.getNotificationBox(abrowser);
|
|
||||||
mozt.Main.stash.notificationBox = notificationBox; // stash for later use
|
|
||||||
|
|
||||||
// check notification not already here
|
|
||||||
var notificationValue = mozt.Main.notification.type + '_' + mozt.Main.notification.host;
|
|
||||||
if (notificationBox.getNotificationWithValue(notificationValue)) {
|
|
||||||
mozt.Debug.dump("notificationBox already here");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// build notification
|
|
||||||
var temporaryException = mozt.Utils.prefService.getBoolPref('add_temporary_exceptions') ?
|
|
||||||
mozt.Main.strings.getString('temporaryException') : mozt.Main.strings.getString('permanentException');
|
|
||||||
var msgArgs = [];
|
|
||||||
var priority = null; // notificationBox.PRIORITY_INFO_LOW not working ??
|
|
||||||
switch (mozt.Main.notification.type) {
|
|
||||||
case 'exceptionAdded':
|
|
||||||
msgArgs = [temporaryException, mozt.Main.notification.host];
|
|
||||||
priority = 'PRIORITY_INFO_LOW';
|
|
||||||
break;
|
|
||||||
case 'exceptionNotAdded':
|
|
||||||
msgArgs = [mozt.Main.notification.dontBypassFlags];
|
|
||||||
priority = 'PRIORITY_WARNING_LOW';
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var message = mozt.Main.strings.getFormattedString(
|
|
||||||
mozt.Main.notification.type, msgArgs);
|
|
||||||
|
|
||||||
// appendNotification( label , value , image , priority , buttons )
|
|
||||||
var notification = notificationBox.appendNotification(
|
|
||||||
message, notificationValue, null, notificationBox[priority], null);
|
|
||||||
|
|
||||||
// close notificatioBox if needed (will close automatically if reload)
|
|
||||||
var exceptionDialogButton = abrowser.webProgress.DOMWindow
|
|
||||||
.document.getElementById('exceptionDialogButton');
|
|
||||||
exceptionDialogButton.addEventListener(
|
|
||||||
"click", mozt.Main.exceptionDialogButtonOnClick, false);
|
|
||||||
|
|
||||||
mozt.Main.notification = {}; // reset
|
|
||||||
},
|
|
||||||
|
|
||||||
exceptionDialogButtonOnClick: function(event) {
|
|
||||||
mozt.Main._closeNotificationMaybe();
|
|
||||||
event.originalTarget.removeEventListener(
|
|
||||||
"click", mozt.Main.exceptionDialogButtonOnClick, false);
|
|
||||||
},
|
|
||||||
|
|
||||||
_closeNotificationMaybe: function() {
|
|
||||||
if (!mozt.Main.stash.notificationBox)
|
|
||||||
return;
|
|
||||||
mozt.Main.stash.notificationBox.currentNotification.close();
|
|
||||||
mozt.Main.stash.notificationBox = null;
|
|
||||||
},
|
|
||||||
|
|
||||||
|
|
||||||
// a TabProgressListner seems more appropriate than an Observer, which only
|
|
||||||
// gets notified for document requests (not internal requests)
|
|
||||||
TabsProgressListener: {
|
|
||||||
// can't see the necessity of having QueryInterface(aIID) implemented...
|
|
||||||
|
|
||||||
_certExceptionJustAdded: null, // used for communication btw
|
|
||||||
// onSecurityChange, onStateChange, ...
|
|
||||||
_certerrorCount: 0, // certerr seems called more than once...
|
|
||||||
|
|
||||||
// This method will be called on security transitions (eg HTTP -> HTTPS,
|
|
||||||
// HTTPS -> HTTP, FOO -> HTTPS) and *after document load* completion. It
|
|
||||||
// might also be called if an error occurs during network loading.
|
|
||||||
onSecurityChange: function (aBrowser, aWebProgress, aRequest, aState) {
|
|
||||||
var uri = aBrowser.currentURI;
|
|
||||||
mozt.Debug.dump("onSecurityChange: uri=" + uri.prePath);
|
|
||||||
|
|
||||||
if (!uri.schemeIs("https")) return;
|
|
||||||
|
|
||||||
this._certerrorCount = 0; // reset
|
|
||||||
|
|
||||||
// retrieve bad cert from nsIRecentBadCertsService
|
|
||||||
// NOTE: experience shows that nsIRecentBadCertsService will not provide
|
|
||||||
// SSLStatus when cert is known or trusted. That's why we don't try to
|
|
||||||
// get it from aRequest
|
|
||||||
var port = uri.port;
|
|
||||||
if (port == -1) port = 443; // thx http://gitorious.org/perspectives-notary-server/
|
|
||||||
var hostWithPort = uri.host + ":" + port;
|
|
||||||
mozt.Main.notification.host = uri.host;
|
|
||||||
var SSLStatus = mozt.Main.recentCertsService.getRecentBadCert(hostWithPort);
|
|
||||||
|
|
||||||
if (!SSLStatus) {
|
|
||||||
mozt.Debug.dump("no SSLStatus for: " + hostWithPort);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
mozt.Debug.dump("SSLStatus");
|
|
||||||
mozt.Debug.dumpObj(SSLStatus);
|
|
||||||
var cert = SSLStatus.serverCert;
|
|
||||||
mozt.Debug.dump("cert");
|
|
||||||
mozt.Debug.dumpObj(cert);
|
|
||||||
|
|
||||||
// check if cert already known/added
|
|
||||||
var knownCert = mozt.Main._getCertException(uri, cert);
|
|
||||||
if (knownCert) {
|
|
||||||
mozt.Debug.dump("known cert: " + knownCert);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine cert problems
|
|
||||||
var dontBypassFlags = 0;
|
|
||||||
|
|
||||||
// we're only interested in certs with characteristics
|
|
||||||
// defined in options (self-signed, issuer unknown, ...)
|
|
||||||
cert.QueryInterface(Ci.nsIX509Cert3);
|
|
||||||
var isSelfSigned = cert.isSelfSigned;
|
|
||||||
mozt.Debug.dump("isSelfSigned:" + isSelfSigned);
|
|
||||||
if (isSelfSigned
|
|
||||||
&& !mozt.Utils.prefService.getBoolPref("bypass_self_signed"))
|
|
||||||
dontBypassFlags |= SCE_CERT_SELF_SIGNED;
|
|
||||||
// NOTE: isSelfSigned *implies* ISSUER_UNKNOWN (should be handled
|
|
||||||
// correctly in option dialog)
|
|
||||||
|
|
||||||
var verificationResult = cert.verifyForUsage(Ci.nsIX509Cert.CERT_USAGE_SSLServer);
|
|
||||||
switch (verificationResult) {
|
|
||||||
case Ci.nsIX509Cert.ISSUER_NOT_TRUSTED: // including self-signed
|
|
||||||
mozt.Debug.dump("issuer not trusted");
|
|
||||||
case Ci.nsIX509Cert.ISSUER_UNKNOWN:
|
|
||||||
mozt.Debug.dump("issuer unknown");
|
|
||||||
mozt.Debug.dump("bypass_issuer_unknown: " + mozt.Utils.prefService.getBoolPref("bypass_issuer_unknown"));
|
|
||||||
if (!mozt.Utils.prefService.getBoolPref("bypass_issuer_unknown"))
|
|
||||||
dontBypassFlags |= Ci.nsIX509Cert.ISSUER_UNKNOWN;
|
|
||||||
default:
|
|
||||||
mozt.Debug.dump("verificationResult: " + verificationResult);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
var dontBypassTag = mozt.Main._parseBadCertFlags(dontBypassFlags);
|
|
||||||
mozt.Debug.dump("dontBypassFlags=" + dontBypassFlags + ", " + dontBypassTag);
|
|
||||||
|
|
||||||
// trigger notification
|
|
||||||
if (mozt.Utils.prefService.getBoolPref('notify')) {
|
|
||||||
mozt.Main.notification.willNotify = true;
|
|
||||||
mozt.Debug.dump("onSecurityChange: willNotify");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add cert exception (if bypass allowed by options)
|
|
||||||
if (dontBypassFlags == 0) {
|
|
||||||
mozt.Main._addCertException(SSLStatus, uri, cert);
|
|
||||||
mozt.Main.notification.type = 'exceptionAdded';
|
|
||||||
} else {
|
|
||||||
mozt.Main.notification.type = 'exceptionNotAdded';
|
|
||||||
mozt.Main.notification.dontBypassFlags = dontBypassTag;
|
|
||||||
}
|
|
||||||
|
|
||||||
}, // END onSecurityChange
|
|
||||||
|
|
||||||
_getTabIndex: function(abrowser) {
|
|
||||||
var tabbrowser = abrowser.getTabBrowser();
|
|
||||||
var tabContainer = tabbrowser.tabs;
|
|
||||||
|
|
||||||
var tabIndex = null;
|
|
||||||
for (var i = 0; i < tabContainer.length; ++i) {
|
|
||||||
if (abrowser == tabbrowser.getBrowserAtIndex(i)) {
|
|
||||||
tabIndex = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return tabIndex;
|
|
||||||
},
|
|
||||||
|
|
||||||
// "We can't look for this during onLocationChange since at that point the
|
|
||||||
// document URI is not yet the about:-uri of the error page." (browser.js)
|
|
||||||
// Experience shows that the order is as follows: badcert
|
|
||||||
// (onSecurityChange) leading to about:blank, then request of
|
|
||||||
// about:document-onload-blocker, leading to about:certerror (called at
|
|
||||||
// least twice)
|
|
||||||
onStateChange: function (aBrowser, aWebProgress, aRequest, aStateFlags, aStatus) {
|
|
||||||
|
|
||||||
// aProgress.DOMWindow is the tab/window which triggered the change.
|
|
||||||
var originDoc = aWebProgress.DOMWindow.document;
|
|
||||||
var originURI = originDoc.documentURI;
|
|
||||||
mozt.Debug.dump("onStateChange " + this._getTabIndex(aBrowser) + ": originURI=" + originURI);
|
|
||||||
var safeRequestName = mozt.Utils.safeGetName(aRequest);
|
|
||||||
mozt.Debug.dump("safeRequestName: " + safeRequestName);
|
|
||||||
|
|
||||||
// WE JUST CAN'T CANCEL THE REQUEST FOR about:certerr |
|
|
||||||
// about:document-onload-blocker ...SO WE WAIT FOR IT !
|
|
||||||
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP
|
|
||||||
|Ci.nsIWebProgressListener.STATE_IS_REQUEST)) {
|
|
||||||
|
|
||||||
if (/^about:certerr/.test(originURI)) {
|
|
||||||
this._certerrorCount++;
|
|
||||||
mozt.Debug.dump("certerrorCount=" + this._certerrorCount);
|
|
||||||
|
|
||||||
if (this._certerrorCount < 2) {
|
|
||||||
if (aStateFlags & (Ci.nsIWebProgressListener.STATE_STOP
|
|
||||||
|Ci.nsIWebProgressListener.STATE_RESTORING)) {
|
|
||||||
// experienced only one certerr call during sessoin restore
|
|
||||||
mozt.Debug.dump("restoring");
|
|
||||||
} else {
|
|
||||||
mozt.Debug.dump("certerrorCount not sufficient");
|
|
||||||
return; // wait for last (?) call
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (this._certExceptionJustAdded) {
|
|
||||||
this._certExceptionJustAdded = false; // reset
|
|
||||||
mozt.Debug.dump("certEx changed: " + this._certExceptionJustAdded);
|
|
||||||
|
|
||||||
aRequest.cancel(Components.results.NS_BINDING_ABORTED);
|
|
||||||
aBrowser.loadURI(this._goto, null, null);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mozt.Main.notification.willNotify) {
|
|
||||||
mozt.Debug.dump("onStateChange: willNotify");
|
|
||||||
mozt.Main.notify.willNotify = false; // reset
|
|
||||||
mozt.Main.notify(aBrowser);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}, // END onStateChange
|
|
||||||
|
|
||||||
onLocationChange: function() { },
|
|
||||||
onProgressChange: function() { },
|
|
||||||
onStatusChange: function() { },
|
|
||||||
|
|
||||||
}, // END TabsProgressListener
|
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
BIN
src/chrome/skin/icon32.png
Normal file
BIN
src/chrome/skin/icon32.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.5 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.1 KiB |
Binary file not shown.
Before Width: | Height: | Size: 3.5 KiB |
@ -1,22 +1,22 @@
|
|||||||
/* This is just an example. You shouldn't do this. */
|
/* This is just an example. You shouldn't do this. */
|
||||||
#sce-hello
|
#mozt-hello
|
||||||
{
|
{
|
||||||
color: red ! important;
|
color: red ! important;
|
||||||
}
|
}
|
||||||
#sce-toolbar-button
|
#mozt-toolbar-button
|
||||||
{
|
{
|
||||||
list-style-image: url("chrome://sce/skin/toolbar-button.png");
|
list-style-image: url("chrome://mozt/skin/toolbar-button.png");
|
||||||
-moz-image-region: rect(0px 24px 24px 0px);
|
-moz-image-region: rect(0px 24px 24px 0px);
|
||||||
}
|
}
|
||||||
#sce-toolbar-button:hover
|
#mozt-toolbar-button:hover
|
||||||
{
|
{
|
||||||
-moz-image-region: rect(24px 24px 48px 0px);
|
-moz-image-region: rect(24px 24px 48px 0px);
|
||||||
}
|
}
|
||||||
[iconsize="small"] #sce-toolbar-button
|
[iconsize="small"] #mozt-toolbar-button
|
||||||
{
|
{
|
||||||
-moz-image-region: rect( 0px 40px 16px 24px);
|
-moz-image-region: rect( 0px 40px 16px 24px);
|
||||||
}
|
}
|
||||||
[iconsize="small"] #sce-toolbar-button:hover
|
[iconsize="small"] #mozt-toolbar-button:hover
|
||||||
{
|
{
|
||||||
-moz-image-region: rect(24px 40px 40px 24px);
|
-moz-image-region: rect(24px 40px 40px 24px);
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
// https://developer.mozilla.org/en/Localizing_extension_descriptions
|
// https://developer.mozilla.org/en/Localizing_extension_descriptions
|
||||||
pref("extensions.skipcerterror@foudil.fr.description", "chrome://sce/locale/overlay.properties");
|
pref("extensions.skipcerterror@foudil.fr.description", "chrome://mozt/locale/overlay.properties");
|
||||||
|
|
||||||
// Extension prefs
|
// Extension prefs
|
||||||
pref("extensions.mozt.enabled", true);
|
pref("extensions.mozt.enabled", true);
|
||||||
|
@ -1,19 +1,17 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||||
<Description about="urn:mozilla:install-manifest">
|
<Description about="urn:mozilla:install-manifest">
|
||||||
<em:id>skipcerterror@foudil.fr</em:id>
|
<em:id>moztray@foudil.fr</em:id>
|
||||||
<em:unpack>false</em:unpack>
|
<em:unpack>false</em:unpack>
|
||||||
<em:type>2</em:type>
|
<em:type>2</em:type>
|
||||||
<em:name>Mozilla Tray</em:name>
|
<em:name>Mozilla Tray</em:name>
|
||||||
<em:version>0.0.1</em:version>
|
<em:version>0.0.1</em:version>
|
||||||
<em:creator>Foudil BRÉTEL</em:creator>
|
<em:creator>Foudil BRÉTEL</em:creator>
|
||||||
<em:contributor></em:contributor>
|
|
||||||
<em:contributor>Hua Luo, Francesco Solero (Firetray original authors)</em:contributor>
|
<em:contributor>Hua Luo, Francesco Solero (Firetray original authors)</em:contributor>
|
||||||
<em:homepageURL>https://github.com/foudfou/moztray</em:homepageURL>
|
<em:homepageURL>https://github.com/foudfou/moztray</em:homepageURL>
|
||||||
<em:description></em:description>
|
<em:description></em:description>
|
||||||
<em:optionsURL>chrome://mozt/content/options.xul</em:optionsURL>
|
<!-- <em:optionsURL>chrome://mozt/content/options.xul</em:optionsURL> -->
|
||||||
<em:iconURL>chrome://mozt/skin/icon48.png</em:iconURL>
|
<em:iconURL>chrome://mozt/skin/icon32.png</em:iconURL>
|
||||||
<em:icon64URL>chrome://mozt/skin/icon64.png</em:icon64URL>
|
|
||||||
<em:targetApplication>
|
<em:targetApplication>
|
||||||
<Description>
|
<Description>
|
||||||
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
|
<em:id>{ec8030f7-c20a-464f-9b0e-13a3a9e97384}</em:id> <!-- Firefox -->
|
||||||
|
81
src/modules/LibGtkStatusIcon.js
Normal file
81
src/modules/LibGtkStatusIcon.js
Normal file
@ -0,0 +1,81 @@
|
|||||||
|
/* -*- Mode: js2; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||||
|
|
||||||
|
var EXPORTED_SYMBOLS = ["LibGtkStatusIcon"];
|
||||||
|
|
||||||
|
const Cc = Components.classes;
|
||||||
|
const Ci = Components.interfaces;
|
||||||
|
const Cu = Components.utils;
|
||||||
|
|
||||||
|
const LIB_GTK = "libgtk-x11-2.0.so";
|
||||||
|
|
||||||
|
var LibGtkStatusIcon = {
|
||||||
|
|
||||||
|
_lib: null,
|
||||||
|
|
||||||
|
init: function() {
|
||||||
|
// If ctypes doesn't exist, try to get it
|
||||||
|
Cu.import("resource://gre/modules/ctypes.jsm");
|
||||||
|
// If we still don't have ctypes, this isn't going to work...
|
||||||
|
if (typeof(ctypes) == "undefined") {
|
||||||
|
throw ("Could not load JS-Ctypes");
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Try to start up dependencies - if they fail, they'll throw
|
||||||
|
// exceptions. ex: GObjectLib.init();
|
||||||
|
|
||||||
|
this._lib = ctypes.open(LIB_GTK);
|
||||||
|
if (!this._lib)
|
||||||
|
throw ("Could not load " + LIB_GTK);
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
this.shutdown();
|
||||||
|
throw(e);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ok, we got everything - let's declare.
|
||||||
|
this._declare();
|
||||||
|
},
|
||||||
|
|
||||||
|
shutdown: function() {
|
||||||
|
// Close our connection to the library.
|
||||||
|
if (this._lib)
|
||||||
|
this._lib.close();
|
||||||
|
},
|
||||||
|
|
||||||
|
_declare: function() {
|
||||||
|
// Types
|
||||||
|
this.GtkStatusIcon = ctypes.StructType("GtkStatusIcon");
|
||||||
|
this.GtkStatusIconRef = ctypes.PointerType(this.GtkStatusIcon);
|
||||||
|
this.GdkPixbuf = ctypes.StructType("GdkPixbuf");
|
||||||
|
this.GdkPixbufRef = ctypes.PointerType(this.GdkPixbuf);
|
||||||
|
this.Pixbuf = ctypes.PointerType(ctypes.char.ptr);
|
||||||
|
|
||||||
|
// Consts
|
||||||
|
this.INDICATOR_MESSAGES_SERVER_TYPE = "message";
|
||||||
|
|
||||||
|
// Functions
|
||||||
|
|
||||||
|
this.gtk_status_icon_new = this._lib.declare(
|
||||||
|
"gtk_status_icon_new",
|
||||||
|
ctypes.default_abi,
|
||||||
|
this.GtkStatusIconRef
|
||||||
|
);
|
||||||
|
|
||||||
|
this.gdk_pixbuf_new_from_xpm_data = this._lib.declare(
|
||||||
|
"gdk_pixbuf_new_from_xpm_data",
|
||||||
|
ctypes.default_abi,
|
||||||
|
this.GdkPixbufRef,
|
||||||
|
this.Pixbuf
|
||||||
|
);
|
||||||
|
|
||||||
|
this.gtk_status_icon_set_from_pixbuf = this._lib.declare(
|
||||||
|
"gtk_status_icon_set_from_pixbuf",
|
||||||
|
ctypes.default_abi,
|
||||||
|
this.GtkStatusIconRef,
|
||||||
|
this.GdkPixbufRef
|
||||||
|
);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
4
testing/Makefile
Normal file
4
testing/Makefile
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
includes := $(shell pkg-config --libs --cflags gtk+-2.0)
|
||||||
|
|
||||||
|
all:
|
||||||
|
gcc $(includes) -o gtk_icon_example gkt_icon_example.c
|
3096
testing/firefox.xpm
Normal file
3096
testing/firefox.xpm
Normal file
File diff suppressed because it is too large
Load Diff
45
testing/gkt_icon_example.c
Normal file
45
testing/gkt_icon_example.c
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
#include <gtk/gtk.h>
|
||||||
|
#include "firefox.xpm"
|
||||||
|
|
||||||
|
void tray_icon_on_click(GtkStatusIcon *status_icon,
|
||||||
|
gpointer user_data)
|
||||||
|
{
|
||||||
|
printf("Clicked on tray icon\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
void tray_icon_on_menu(GtkStatusIcon *status_icon, guint button,
|
||||||
|
guint activate_time, gpointer user_data)
|
||||||
|
{
|
||||||
|
printf("Popup menu\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
static GtkStatusIcon *create_tray_icon() {
|
||||||
|
GtkStatusIcon *tray_icon;
|
||||||
|
|
||||||
|
tray_icon = gtk_status_icon_new();
|
||||||
|
g_signal_connect(G_OBJECT(tray_icon), "activate",
|
||||||
|
G_CALLBACK(tray_icon_on_click), NULL);
|
||||||
|
g_signal_connect(G_OBJECT(tray_icon),
|
||||||
|
"popup-menu",
|
||||||
|
G_CALLBACK(tray_icon_on_menu), NULL);
|
||||||
|
|
||||||
|
GdkPixbuf *default_icon = gdk_pixbuf_new_from_xpm_data(firefox_xpm);
|
||||||
|
|
||||||
|
gtk_status_icon_set_from_pixbuf(GTK_STATUS_ICON(tray_icon),
|
||||||
|
GDK_PIXBUF(default_icon));
|
||||||
|
gtk_status_icon_set_tooltip(tray_icon,
|
||||||
|
"Example Tray Icon");
|
||||||
|
gtk_status_icon_set_visible(tray_icon, TRUE);
|
||||||
|
|
||||||
|
return tray_icon;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char **argv) {
|
||||||
|
GtkStatusIcon *tray_icon;
|
||||||
|
|
||||||
|
gtk_init(&argc, &argv);
|
||||||
|
tray_icon = create_tray_icon();
|
||||||
|
gtk_main();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
BIN
testing/gtk_icon_example
Executable file
BIN
testing/gtk_icon_example
Executable file
Binary file not shown.
Loading…
Reference in New Issue
Block a user