Compare commits
33 Commits
Author | SHA1 | Date | |
---|---|---|---|
1cafe3fd25 | |||
3a1ce635b1 | |||
506f675664 | |||
822fd90f6d | |||
953da8a8e2 | |||
ee146800ee | |||
8ef76f4ebb | |||
348846f5d3 | |||
e42e60276b | |||
235bbda10b | |||
ced728b0f4 | |||
015fa2166b | |||
637ff45592 | |||
78959d60c7 | |||
00283bde24 | |||
2c0666dcf2 | |||
b06dded801 | |||
4bed82f527 | |||
ed36de6cae | |||
676c2348d8 | |||
e7d888c776 | |||
6adb55d048 | |||
4a680de5a2 | |||
79a32618f8 | |||
8d249f4831 | |||
67ed95fc25 | |||
5b6504a11d | |||
832c79f4b5 | |||
988047ec4e | |||
6fa1736321 | |||
890438ffe9 | |||
ebf6f2577a | |||
c19ea1d76c |
@ -99,7 +99,7 @@ var AboutI2pListener = {
|
||||
|
||||
onLocaleChange: function(aLocale) {
|
||||
|
||||
// Display the Tor Browser product name and version.
|
||||
// Display the I2P Browser product name and version.
|
||||
try {
|
||||
const kBrandBundle = "chrome://branding/locale/brand.properties";
|
||||
let brandBundle = Cc["@mozilla.org/intl/stringbundle;1"]
|
||||
|
@ -33,9 +33,12 @@ window.addEventListener("pageshow", function() {
|
||||
<div class='content'>
|
||||
<div class='section-header'>
|
||||
<h1>&aboutI2p.browser_name;</h1>
|
||||
</div>
|
||||
</div>
|
||||
<div id="i2pbrowser-version"></div>
|
||||
<p>
|
||||
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description;
|
||||
&aboutI2p.browser_name; ( &aboutI2p.browser_short_name; ) &aboutI2p.browser_description; <br />
|
||||
&aboutI2p.startup; <a href="&aboutI2p.routerconsole;">&aboutI2p.rc;</a> &aboutI2p.startup_b;
|
||||
|
||||
<h3>&aboutI2p.links;</h3>
|
||||
<p>
|
||||
<ul>
|
||||
|
@ -21,6 +21,7 @@ var m_ib_window_height = window.outerHeight
|
||||
var m_ib_window_width = window.outerWidth
|
||||
|
||||
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
let routerCtrl = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
|
||||
function checkI2P(callback,proxyCallback) {
|
||||
let req = checkSvc.createCheckConsoleRequest(true);
|
||||
@ -50,10 +51,40 @@ function i2pbutton_i2p_check_ok()
|
||||
// It's important to check both if failed and if it's initialised to not report wrong to the end user
|
||||
return (checkSvc.isConsoleWorking && checkSvc.isProxyWorking && checkSvc.kCheckNotInitiated != checkSvc.statusOfI2PCheck)
|
||||
}
|
||||
function i2pbutton_i2p_console_check_ok()
|
||||
function i2pbutton_i2p_console_check_ok() {
|
||||
// This check will now test if the router subprocess is running
|
||||
if (routerCtrl.mI2PProcess != null) {
|
||||
if (routerCtrl.mI2PProcess.isRunning) {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
var i2pbutton_window_pref_observer =
|
||||
{
|
||||
// It's important to check both if failed and if it's initialised to not report wrong to the end user
|
||||
return (checkSvc.isConsoleWorking && checkSvc.kCheckNotInitiated != checkSvc.statusOfI2PCheck)
|
||||
register: function()
|
||||
{
|
||||
m_ib_prefs.addObserver("extensions.i2pbutton", this, false);
|
||||
},
|
||||
|
||||
unregister: function()
|
||||
{
|
||||
m_ib_prefs.removeObserver("extensions.i2pbutton", this);
|
||||
},
|
||||
|
||||
// topic: what event occurred
|
||||
// subject: what nsIPrefBranch we're observing
|
||||
// data: which pref has been changed (relative to subject)
|
||||
observe: function(subject, topic, data)
|
||||
{
|
||||
if (topic != "nsPref:changed") return;
|
||||
switch (data) {
|
||||
case k_ib_browser_update_needed_pref:
|
||||
torbutton_notify_if_update_needed();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var i2pbutton_unique_pref_observer =
|
||||
@ -195,14 +226,82 @@ function i2pbutton_is_mobile() {
|
||||
return false;
|
||||
}
|
||||
|
||||
function i2pbutton_update_is_needed() {
|
||||
var updateNeeded = false
|
||||
try {
|
||||
updateNeeded = m_ib_prefs.getBoolPref(k_ib_browser_update_needed_pref)
|
||||
} catch (e) {}
|
||||
|
||||
return updateNeeded
|
||||
}
|
||||
|
||||
function i2pbutton_notify_if_update_needed() {
|
||||
function setOrClearAttribute(aElement, aAttrName, aValue)
|
||||
{
|
||||
if (!aElement || !aAttrName)
|
||||
return
|
||||
|
||||
if (aValue)
|
||||
aElement.setAttribute(aAttrName, aValue)
|
||||
else
|
||||
aElement.removeAttribute(aAttrName)
|
||||
}
|
||||
|
||||
let updateNeeded = i2pbutton_update_is_needed()
|
||||
|
||||
// Change look of toolbar item (enable/disable animated update icon).
|
||||
var btn = i2pbutton_get_toolbutton()
|
||||
setOrClearAttribute(btn, "ibUpdateNeeded", updateNeeded)
|
||||
|
||||
// Make the "check for update" menu item bold if an update is needed.
|
||||
var item = document.getElementById("i2pbutton-checkForUpdate")
|
||||
setOrClearAttribute(item, "ibUpdateNeeded", updateNeeded)
|
||||
}
|
||||
|
||||
function i2pbutton_check_for_update() {
|
||||
// Open the update prompt in the correct mode. The update state
|
||||
// checks used here were adapted from isPending() and isApplied() in
|
||||
// Mozilla's browser/base/content/aboutDialog.js code.
|
||||
let updateMgr = Cc["@mozilla.org/updates/update-manager;1"]
|
||||
.getService(Ci.nsIUpdateManager)
|
||||
let update = updateMgr.activeUpdate
|
||||
let updateState = (update) ? update.state : undefined
|
||||
let pendingStates = [ "pending", "pending-service",
|
||||
"applied", "applied-service" ]
|
||||
let isPending = (updateState && (pendingStates.indexOf(updateState) >= 0))
|
||||
|
||||
let prompter = Cc["@mozilla.org/updates/update-prompt;1"]
|
||||
.createInstance(Ci.nsIUpdatePrompt)
|
||||
if (isPending)
|
||||
prompter.showUpdateDownloaded(update, false)
|
||||
else
|
||||
prompter.checkForUpdates()
|
||||
}
|
||||
|
||||
function i2pbutton_get_toolbutton() {
|
||||
var o_toolbutton = false;
|
||||
|
||||
i2pbutton_log(1, 'get_toolbutton(): looking for button element');
|
||||
if (document.getElementById("i2pbutton-button")) {
|
||||
o_toolbutton = document.getElementById("i2pbutton-button");
|
||||
} else if (document.getElementById("i2pbutton-button-ib")) {
|
||||
o_toolbutton = document.getElementById("i2pbutton-button-ib");
|
||||
} else if (document.getElementById("i2pbutton-button-ib-msg")) {
|
||||
o_toolbutton = document.getElementById("i2pbutton-button-ib-msg");
|
||||
} else {
|
||||
i2pbutton_log(3, 'get_toolbutton(): did not find i2pbutton-button');
|
||||
}
|
||||
|
||||
return o_toolbutton;
|
||||
}
|
||||
|
||||
|
||||
// This function closes all XUL browser windows except this one. For this
|
||||
// window, it closes all existing tabs and creates one about:blank tab.
|
||||
function i2pbutton_close_tabs_on_new_identity() {
|
||||
if (!m_ib_prefs.getBoolPref("extensions.i2pbutton.close_newnym", true)) {
|
||||
i2pbutton_log(3, "Not closing tabs");
|
||||
return;
|
||||
i2pbutton_log(3, "Not closing tabs")
|
||||
return
|
||||
}
|
||||
|
||||
// TODO: muck around with browser.tabs.warnOnClose.. maybe..
|
||||
@ -450,6 +549,28 @@ function i2pbutton_new_identity() {
|
||||
}
|
||||
}
|
||||
|
||||
/* The "New Identity" implementation does the following:
|
||||
* 1. Disables Javascript and plugins on all tabs
|
||||
* 2. Clears state:
|
||||
* a. OCSP
|
||||
* b. Cache + image cache
|
||||
* c. Site-specific zoom
|
||||
* d. Cookies+DOM Storage+safe browsing key
|
||||
* e. google wifi geolocation token
|
||||
* f. http auth
|
||||
* g. SSL Session IDs
|
||||
* h. last open location url
|
||||
* i. clear content prefs
|
||||
* j. permissions
|
||||
* k. site security settings (e.g. HSTS)
|
||||
* l. IndexedDB and asmjscache storage
|
||||
* 3. Sends tor the NEWNYM signal to get a new circuit
|
||||
* 4. Opens a new window with the default homepage
|
||||
* 5. Closes this window
|
||||
*
|
||||
* XXX: intermediate SSL certificates are not cleared.
|
||||
*/
|
||||
|
||||
function i2pbutton_do_new_identity() {
|
||||
var obsSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
// This is todo.
|
||||
@ -1000,7 +1121,7 @@ var i2pbutton_resizelistener =
|
||||
// in XUL that should be in an XPCOM component
|
||||
function i2pbutton_close_window(event) {
|
||||
i2pbutton_window_pref_observer.unregister();
|
||||
i2pbutton_tor_check_observer.unregister();
|
||||
i2pbutton_i2p_check_observer.unregister();
|
||||
|
||||
window.removeEventListener("sizemodechange", m_ib_resize_handler,
|
||||
false);
|
||||
|
@ -12,6 +12,8 @@ function i2pbutton_log(nLevel, sMsg) {
|
||||
return true;
|
||||
}
|
||||
|
||||
function i2pbutton_init_security_ui() {}
|
||||
|
||||
// get a preferences branch object
|
||||
// FIXME: this is lame.
|
||||
function i2pbutton_get_prefbranch(branch_name) {
|
||||
|
@ -20,18 +20,17 @@
|
||||
accesskey="&i2pbutton.context_menu.new_identity_key;"
|
||||
insertafter="context-stop"
|
||||
oncommand="i2pbutton_new_identity()"/>
|
||||
<menuseparator/>
|
||||
<menuitem id="i2pbutton-cookie-protector"
|
||||
label="&i2pbutton.context_menu.cookieProtections;"
|
||||
accesskey="&i2pbutton.context_menu.cookieProtections.key;"
|
||||
insertafter="context-stop"
|
||||
insertafter="i2pbutton-new-identity"
|
||||
hidden="true"
|
||||
oncommand="i2pbutton_open_cookie_dialog()"/>
|
||||
<menuseparator id="i2pbutton-checkForUpdateSeparator"/>
|
||||
<menuitem id="i2pbutton-checkForUpdate"
|
||||
label="&i2pbutton.context_menu.downloadUpdate;"
|
||||
accesskey="&i2pbutton.context_menu.downloadUpdate.key;"
|
||||
insertafter="context-stop"
|
||||
insertafter="i2pbutton-cookie-protector"
|
||||
oncommand="i2pbutton_check_for_update()"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
212
src/chrome/content/progress.js
Normal file
212
src/chrome/content/progress.js
Normal file
@ -0,0 +1,212 @@
|
||||
const Cc = Components.classes
|
||||
const Ci = Components.interfaces
|
||||
const Cu = Components.utils
|
||||
|
||||
const kI2PProcessExitedTopic = "I2PProcessExited"
|
||||
const kBootstrapStatusTopic = "I2PBootstrapStatus"
|
||||
const kI2PBootstrapErrorTopic = "I2PBootstrapError"
|
||||
const kI2PLogHasWarnOrErrTopic = "I2PLogHasWarnOrErr"
|
||||
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
|
||||
|
||||
|
||||
const I2PLauncherLogger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
const gI2PProcessService = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
|
||||
var gObsSvc
|
||||
var gOpenerCallbackFunc // Set when opened from network settings.
|
||||
|
||||
|
||||
function initDialog()
|
||||
{
|
||||
// If i2p bootstrap has already finished, just close the progress dialog.
|
||||
// This situation can occur if bootstrapping is very fast and/or if this
|
||||
// window opens s vlowly (observed with Adblock Plus installed).
|
||||
try
|
||||
{
|
||||
let processSvc = Cc["@geti2p.net/i2pbutton-process-service;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
if (processSvc.I2PIsBootstrapDone || processSvc.I2PBootstrapErrorOccurred)
|
||||
{
|
||||
closeThisWindow(processSvc.I2PIsBootstrapDone)
|
||||
return
|
||||
}
|
||||
}
|
||||
catch (e) { dump(e + "\n") }
|
||||
|
||||
try
|
||||
{
|
||||
gObsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
|
||||
gObsSvc.addObserver(gObserver, kI2PProcessExitedTopic, false)
|
||||
gObsSvc.addObserver(gObserver, kBootstrapStatusTopic, false)
|
||||
gObsSvc.addObserver(gObserver, kI2PBootstrapErrorTopic, false)
|
||||
gObsSvc.addObserver(gObserver, kI2PLogHasWarnOrErrTopic, false)
|
||||
}
|
||||
catch (e) {}
|
||||
|
||||
var isBrowserStartup = false
|
||||
if (window.arguments)
|
||||
{
|
||||
isBrowserStartup = window.arguments[0]
|
||||
|
||||
if (window.arguments.length > 1)
|
||||
gOpenerCallbackFunc = window.arguments[1]
|
||||
}
|
||||
|
||||
if (gOpenerCallbackFunc)
|
||||
{
|
||||
// Dialog was opened from network settings: hide Open Settings button.
|
||||
var extraBtn = document.documentElement.getButton("extra2")
|
||||
extraBtn.setAttribute("hidden", true)
|
||||
}
|
||||
else
|
||||
{
|
||||
// Dialog was not opened from network settings: change Cancel to Quit.
|
||||
var cancelBtn = document.documentElement.getButton("cancel")
|
||||
var quitKey = (LauncherUtil.isWindows) ? "quit_win" : "quit"
|
||||
cancelBtn.label = 'Cancel'//LauncherUtil.getLocalizedString(quitKey)
|
||||
}
|
||||
|
||||
// If opened during browser startup, display the "please wait" message.
|
||||
if (isBrowserStartup)
|
||||
{
|
||||
var pleaseWait = document.getElementById("progressPleaseWait")
|
||||
if (pleaseWait)
|
||||
pleaseWait.removeAttribute("hidden")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function cleanup()
|
||||
{
|
||||
if (gObsSvc)
|
||||
{
|
||||
gObsSvc.removeObserver(gObserver, kI2PProcessExitedTopic)
|
||||
gObsSvc.removeObserver(gObserver, kBootstrapStatusTopic)
|
||||
gObsSvc.removeObserver(gObserver, kI2PBootstrapErrorTopic)
|
||||
gObsSvc.removeObserver(gObserver, kI2PLogHasWarnOrErrTopic)
|
||||
}
|
||||
}
|
||||
|
||||
function onOpenSettings()
|
||||
{
|
||||
//stopI2PBootstrap()
|
||||
//cleanup()
|
||||
window.close()
|
||||
}
|
||||
|
||||
|
||||
function stopI2PBootstrap()
|
||||
{
|
||||
// Tell i2p to disable use of the network; this should stop the bootstrap
|
||||
// process.
|
||||
const kErrorPrefix = "Setting DisableNetwork=1 failed: ";
|
||||
try
|
||||
{
|
||||
var svc = Cc["@torproject.org/torlauncher-protocol-service;1"]
|
||||
.getService(Ci.nsISupports);
|
||||
svc = svc.wrappedJSObject;
|
||||
var settings = {};
|
||||
settings["DisableNetwork"] = true;
|
||||
var errObj = {};
|
||||
if (!svc.I2PSetConfWithReply(settings, errObj))
|
||||
I2PLauncherLogger.log(5, kErrorPrefix + errObj.details);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
I2PLauncherLogger.log(5, kErrorPrefix + e);
|
||||
}
|
||||
}
|
||||
|
||||
// Fake it for now. The main goal is to could say with more confidence that
|
||||
// the router has had time to start before the user can start using the browser
|
||||
// as any other browser.
|
||||
|
||||
setTimeout(() => {
|
||||
var meter = document.getElementById("progressMeter")
|
||||
if (meter)
|
||||
meter.value = meter.value + 15
|
||||
}, 5000)
|
||||
|
||||
setTimeout(() => {
|
||||
var meter = document.getElementById("progressMeter")
|
||||
if (meter)
|
||||
meter.value = meter.value + 15
|
||||
}, 10000)
|
||||
|
||||
setTimeout(() => {
|
||||
var meter = document.getElementById("progressMeter")
|
||||
if (meter)
|
||||
meter.value = meter.value + 15
|
||||
}, 15000)
|
||||
|
||||
setTimeout(() => {
|
||||
window.close()
|
||||
}, 25000)
|
||||
|
||||
|
||||
var gObserver = {
|
||||
// nsIObserver implementation.
|
||||
observe: function(aSubject, aTopic, aParam)
|
||||
{
|
||||
if ((kI2PProcessExitedTopic == aTopic) ||
|
||||
(kI2PBootstrapErrorTopic == aTopic))
|
||||
{
|
||||
// In these cases, an error alert will be displayed elsewhere so it is
|
||||
// best to close this window.
|
||||
// TODO: provide a way to access tor log e.g., leave this dialog open
|
||||
// and display the open settings button or provide a way to do
|
||||
// that from our error alerts.
|
||||
if (kI2PBootstrapErrorTopic == aTopic)
|
||||
stopI2PBootstrap();
|
||||
cleanup();
|
||||
window.close();
|
||||
}
|
||||
else if (kBootstrapStatusTopic == aTopic)
|
||||
{
|
||||
var statusObj = aSubject.wrappedJSObject
|
||||
var labelText = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "TAG")
|
||||
var percentComplete = (statusObj.PROGRESS) ? statusObj.PROGRESS : 0
|
||||
|
||||
var meter = document.getElementById("progressMeter")
|
||||
if (meter)
|
||||
meter.value = percentComplete
|
||||
|
||||
var bootstrapDidComplete = (percentComplete >= 100)
|
||||
if (percentComplete >= 100)
|
||||
{
|
||||
// To ensure that 100% progress is displayed, wait a short while
|
||||
// before closing this window.
|
||||
window.setTimeout(function() { closeThisWindow(true) }, 250)
|
||||
}
|
||||
else if (statusObj._errorOccurred)
|
||||
{
|
||||
var s = LauncherUtil.getLocalizedBootstrapStatus(statusObj, "REASON");
|
||||
if (s)
|
||||
labelText = s;
|
||||
|
||||
if (meter)
|
||||
meter.setAttribute("hidden", true);
|
||||
|
||||
var pleaseWait = document.getElementById("progressPleaseWait");
|
||||
if (pleaseWait)
|
||||
pleaseWait.setAttribute("hidden", true);
|
||||
}
|
||||
|
||||
var desc = document.getElementById("progressDesc");
|
||||
if (labelText && desc)
|
||||
desc.textContent = labelText;
|
||||
}
|
||||
else if (kI2PLogHasWarnOrErrTopic == aTopic)
|
||||
{
|
||||
var extra2Btn = document.documentElement.getButton("extra2");
|
||||
var clz = extra2Btn.getAttribute("class");
|
||||
extra2Btn.setAttribute("class", clz ? clz + " i2pWarning" : "i2pWarning");
|
||||
|
||||
// TODO: show error / warning message in this dialog?
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
44
src/chrome/content/progress.xul
Normal file
44
src/chrome/content/progress.xul
Normal file
@ -0,0 +1,44 @@
|
||||
<?xml version="1.0"?>
|
||||
<!--
|
||||
- Copyright (c) 2019, The Invisible Internet Project.
|
||||
- See LICENSE for licensing information.
|
||||
- vim: set sw=2 sts=2 ts=8 et syntax=xml:
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://i2pbutton/skin/progress.css"
|
||||
type="text/css"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://i2pbutton/locale/progress.dtd">
|
||||
|
||||
<dialog id="I2PProgress"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&i2pprogress.dialog.title;"
|
||||
windowtype="I2PLauncher:Progress"
|
||||
persist="screenX screenY"
|
||||
buttons="cancel"
|
||||
buttonlabelextra2="&i2pprogress.openSettings;"
|
||||
ondialogcancel="return onCancel();"
|
||||
ondialogextra2="onOpenSettings();"
|
||||
onload="initDialog();"> <!-- extra2 was removed from buttons for now. -->
|
||||
|
||||
<script type="application/x-javascript"
|
||||
src="chrome://i2pbutton/content/progress.js"/>
|
||||
<vbox>
|
||||
<hbox>
|
||||
<vbox>
|
||||
<spacer flex="1" />
|
||||
<image id="ibb-icon" />
|
||||
<spacer flex="1" />
|
||||
</vbox>
|
||||
<separator orient="vertical" />
|
||||
<vbox flex="1">
|
||||
<label id="progressHeading" value="&i2pprogress.heading;" />
|
||||
<description id="progressDesc" />
|
||||
</vbox>
|
||||
</hbox>
|
||||
<progressmeter id="progressMeter" mode="determined" value="0" max="100" />
|
||||
<description id="progressPleaseWait"
|
||||
hidden="true">&i2pprogress.pleaseWait;</description>
|
||||
</vbox>
|
||||
</dialog>
|
@ -31,6 +31,10 @@
|
||||
<!ENTITY aboutI2p.refresh_link "Refresh">
|
||||
|
||||
<!ENTITY aboutI2p.site "http://i2p-projekt.i2p/en">
|
||||
<!ENTITY aboutI2p.routerconsole "http://localhost:7657">
|
||||
<!ENTITY aboutI2p.routerconsole "http://localhost:17657">
|
||||
<!ENTITY aboutI2p.github "https://github.com/mikalv">
|
||||
<!ENTITY aboutI2p.trac "http://trac.i2p2.i2p">
|
||||
|
||||
<!ENTITY aboutI2p.startup "Sometimes it takes a minute or two for I2P to get started for the first time. While you wait, visit the">
|
||||
<!ENTITY aboutI2p.startup_b "to get acquainted with all the capabilities of I2P.">
|
||||
<!ENTITY aboutI2p.rc "Router Console">
|
||||
|
4
src/chrome/locale/en-US/progress.dtd
Normal file
4
src/chrome/locale/en-US/progress.dtd
Normal file
@ -0,0 +1,4 @@
|
||||
<!ENTITY i2pprogress.dialog.title "Starting the I2P router">
|
||||
<!ENTITY i2pprogress.openSettings "Settings">
|
||||
<!ENTITY i2pprogress.heading "I2P Browser">
|
||||
<!ENTITY i2pprogress.pleaseWait "Please wait while the router establish a connection to the I2P network. This may take several minutes">
|
BIN
src/chrome/skin/default48.png
Normal file
BIN
src/chrome/skin/default48.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 3.0 KiB |
44
src/chrome/skin/progress.css
Normal file
44
src/chrome/skin/progress.css
Normal file
@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2019, The Invisible Internet Project.
|
||||
* See LICENSE for licensing information.
|
||||
*
|
||||
* vim: set sw=2 sts=2 ts=8 et syntax=css:
|
||||
*/
|
||||
|
||||
dialog {
|
||||
width: 400px;
|
||||
}
|
||||
|
||||
#progressHeading {
|
||||
font-size: 110%;
|
||||
margin: 8px 0px 8px 0px;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
#progressPleaseWait {
|
||||
font-size: 110%;
|
||||
margin-bottom: 15px;
|
||||
}
|
||||
|
||||
#ibb-icon {
|
||||
list-style-image: url("chrome://i2pbutton/skin/default48.png");
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
#progressDesc {
|
||||
height: 48px;
|
||||
}
|
||||
|
||||
#progressMeter {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
|
||||
.i2pWarning {
|
||||
list-style-image: url("chrome://i2pbutton/skin/warning.png");
|
||||
}
|
||||
|
||||
/* Ensure that our caution icon is always shown on GTK-based platforms. */
|
||||
.i2pWarning .button-icon {
|
||||
display: inline !important;
|
||||
}
|
BIN
src/chrome/skin/warning.png
Normal file
BIN
src/chrome/skin/warning.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.1 KiB |
@ -35,13 +35,15 @@ IBI2PCheckService.prototype =
|
||||
|
||||
isConsoleWorking: false,
|
||||
isProxyWorking: false,
|
||||
isInProgressOfTestingConsole: false,
|
||||
isInProgressOfTestingProxy: false,
|
||||
|
||||
wrappedJSObject: null,
|
||||
_logger: null,
|
||||
_statusOfI2PCheck: 0, // this.kCheckNotInitiated,
|
||||
|
||||
// make this an nsIClassInfo object
|
||||
flags: Ci.nsIClassInfo.DOM_OBJECT,
|
||||
// make this an singleton object
|
||||
flags: Ci.nsIClassInfo.SINGLETON,
|
||||
|
||||
// method of nsIClassInfo
|
||||
classDescription: kMODULE_NAME,
|
||||
@ -71,17 +73,21 @@ IBI2PCheckService.prototype =
|
||||
|
||||
init: function () {
|
||||
let self = this
|
||||
this.isInProgressOfTestingConsole = true
|
||||
let req = this.createCheckConsoleRequest(true)
|
||||
req.onreadystatechange = function (event) {
|
||||
if (req.readyState === 4) {
|
||||
self.parseCheckConsoleResponse(req)
|
||||
self.isInProgressOfTestingConsole = false
|
||||
}
|
||||
}
|
||||
req.send(null)
|
||||
this.isInProgressOfTestingProxy = true
|
||||
let proxyReq = this.createCheckProxyRequest(true)
|
||||
proxyReq.onreadystatechange = function (event) {
|
||||
if (proxyReq.readyState === 4) {
|
||||
self.parseCheckProxyResponse(proxyReq)
|
||||
self.isInProgressOfTestingConsole = false
|
||||
}
|
||||
}
|
||||
proxyReq.send(null)
|
||||
|
@ -8,11 +8,29 @@ const Cu = Components.utils
|
||||
// ctypes can be disabled at build time
|
||||
try { Cu.import("resource://gre/modules/ctypes.jsm") } catch(e) {}
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
|
||||
|
||||
//let observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
|
||||
|
||||
const timer = Cc["@mozilla.org/timer;1"].createInstance(Components.interfaces.nsITimer)
|
||||
|
||||
let routerStateLoglines = [
|
||||
'Router state change from STARTING_1 to STARTING_2',
|
||||
'Router state change from STARTING_2 to STARTING_3',
|
||||
'Router state change from STARTING_3 to NETDB_READY',
|
||||
'Router state change from NETDB_READY to RUNNING'
|
||||
]
|
||||
|
||||
function setTimeout(fn, sleep) {
|
||||
let event = {
|
||||
notify: fn
|
||||
}
|
||||
return timer.initWithCallback(event, sleep, Components.interfaces.nsITimer.TYPE_ONE_SHOT)
|
||||
}
|
||||
|
||||
|
||||
function I2PProcessService()
|
||||
{
|
||||
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
@ -94,19 +112,49 @@ I2PProcessService.prototype =
|
||||
|
||||
|
||||
const self = this
|
||||
this._logger.log(3, 'Checking if a console is already up (an router already running)')
|
||||
this._isConsoleRunning(function(res) {
|
||||
//this._logger.log(3, 'Checking if a console is already up (an router already running)')
|
||||
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
|
||||
let shouldShowDelayUserDialog = prefs.getBoolPref("extensions.i2pbutton.delay_user_with_dialog", true)
|
||||
|
||||
try {
|
||||
if (shouldShowDelayUserDialog) {
|
||||
self.openWaitForRouterDialog()
|
||||
setTimeout(() => {
|
||||
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
|
||||
progressmeter.value = progressmeter.value + 35
|
||||
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
|
||||
text.value = 'Waiting for the router to open the console and proxy port.'
|
||||
}, 5000)
|
||||
}
|
||||
} catch (err) {
|
||||
self._logger.log(5, `Unknown error while executing delay user dialog: ${err}`)
|
||||
}
|
||||
|
||||
let canStartPromise = self._config_checker.ensure_config()
|
||||
canStartPromise.then(() => {
|
||||
self._logger.log(3, 'Starting the router')
|
||||
self.I2PStartAndControlI2P(true)
|
||||
|
||||
})
|
||||
|
||||
// After the router process is spawned.
|
||||
/*if (self.mDelayUserDialog) {
|
||||
setTimeout(() => {
|
||||
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
|
||||
progressmeter.value = progressmeter.value + 35
|
||||
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
|
||||
text.value = 'Waiting for the router to open the console and proxy port.'
|
||||
}, 5000)
|
||||
}*/
|
||||
/*this._isConsoleRunning(function(res) {
|
||||
if (res!=4) {
|
||||
// Yes, 4 is success
|
||||
let canStartPromise = this._config_checker.ensure_config()
|
||||
canStartPromise.then(() => {
|
||||
self._logger.log(3, 'Starting the router')
|
||||
self.I2PStartAndControlI2P(true)
|
||||
})
|
||||
|
||||
} else {
|
||||
self._logger.log(3, 'Already found a router, won\'t launch.')
|
||||
}
|
||||
})
|
||||
})*/
|
||||
}
|
||||
else if ("quit-application-granted" == aTopic)
|
||||
{
|
||||
@ -119,8 +167,8 @@ I2PProcessService.prototype =
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
|
||||
let shouldKillRouter = prefs.getBoolPref("extensions.i2pbutton.kill_router_on_exit", true)
|
||||
if (shouldKillRouter) this.mI2PProcess.kill()
|
||||
this._logger.log(4, "Disconnecting from i2p process (pid " + this.mI2PProcess.pid + ")");
|
||||
this.mI2PProcess = null;
|
||||
this._logger.log(4, "Disconnecting from i2p process (pid " + this.mI2PProcess.pid + ")")
|
||||
this.mI2PProcess = null
|
||||
}
|
||||
}
|
||||
else if (("process-failed" == aTopic) || ("process-finished" == aTopic))
|
||||
@ -135,11 +183,11 @@ I2PProcessService.prototype =
|
||||
this.mI2PProcessStatus = this.kStatusExited;
|
||||
this.mIsBootstrapDone = false;
|
||||
|
||||
this.mObsSvc.notifyObservers(null, "I2PProcessExited", null);
|
||||
this.mObsSvc.notifyObservers(null, "I2PProcessExited", null)
|
||||
|
||||
if (this.mIsQuitting)
|
||||
{
|
||||
LauncherUtil.cleanupTempDirectories();
|
||||
LauncherUtil.cleanupTempDirectories()
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -147,9 +195,9 @@ I2PProcessService.prototype =
|
||||
var cancelBtnLabel = "OK";
|
||||
try
|
||||
{
|
||||
const kSysBundleURI = "chrome://global/locale/commonDialogs.properties";
|
||||
var sysBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kSysBundleURI);
|
||||
cancelBtnLabel = sysBundle.GetStringFromName(cancelBtnLabel);
|
||||
const kSysBundleURI = "chrome://global/locale/commonDialogs.properties"
|
||||
var sysBundle = Cc["@mozilla.org/intl/stringbundle;1"].getService(Ci.nsIStringBundleService).createBundle(kSysBundleURI)
|
||||
cancelBtnLabel = sysBundle.GetStringFromName(cancelBtnLabel)
|
||||
} catch(e) {}
|
||||
|
||||
this._logger.log(3, 'The router stopped..')
|
||||
@ -167,9 +215,9 @@ I2PProcessService.prototype =
|
||||
this.mObsSvc.notifyObservers(null, "I2PProcessIsReady", null)
|
||||
}
|
||||
} else if (kBootstrapStatusTopic == aTopic) {
|
||||
//this._processBootstrapStatus(aSubject.wrappedJSObject);
|
||||
this._processBootstrapStatus(aSubject.wrappedJSObject)
|
||||
} else if (kUserQuitTopic == aTopic) {
|
||||
this.mQuitSoon = true;
|
||||
this.mQuitSoon = true
|
||||
}
|
||||
},
|
||||
|
||||
@ -227,6 +275,40 @@ I2PProcessService.prototype =
|
||||
|
||||
},
|
||||
|
||||
openWaitForRouterDialog: function() {
|
||||
const self = this
|
||||
//var win = ww.openWindow(null, "chrome://i2pbutton/content/progress.xul", "wizard", "chrome,dialog=no,modal,centerscreen", {blabla:0})
|
||||
const ww = Components.classes["@mozilla.org/embedcomp/window-watcher;1"].getService(Components.interfaces.nsIWindowWatcher)
|
||||
|
||||
self.mDelayUserDialog = ww.openWindow(null, "chrome://i2pbutton/content/progress.xul", "startingrouter", "chrome,dialog=no,modal,centerscreen", {blabla:0})
|
||||
|
||||
setTimeout(() => {
|
||||
let progressmeter = self.mDelayUserDialog.document.getElementById('progressMeter')
|
||||
progressmeter.value = progressmeter.value + 15
|
||||
|
||||
var text = self.mDelayUserDialog.document.getElementById('progressPleaseWait')
|
||||
text.hidden = false
|
||||
}, 1000)
|
||||
return self.mDelayUserDialog
|
||||
},
|
||||
|
||||
getWrapperLog: function() {
|
||||
let wrapperLogFile = LauncherUtil.dataDirectoryObject
|
||||
wrapperLogFile.append('I2P')
|
||||
wrapperLogFile.append('wrapper.log')
|
||||
return this._getFileAsString(wrapperLogFile)
|
||||
},
|
||||
|
||||
getLogsLogTxt: function() {
|
||||
let logTxtFile = LauncherUtil.dataDirectoryObject
|
||||
logTxtFile.append('I2P')
|
||||
logTxtFile.append('logs')
|
||||
logTxtFile.append('log-0.txt')
|
||||
return this._getFileAsString(logTxtFile)
|
||||
},
|
||||
|
||||
retrieveBootstrapStatus: function() {},
|
||||
|
||||
I2PStartAndControlI2P: function()
|
||||
{
|
||||
this._startI2P()
|
||||
@ -256,8 +338,22 @@ I2PProcessService.prototype =
|
||||
mLastI2PWarningPhase: null,
|
||||
mLastI2PWarningReason: null,
|
||||
mDefaultPreferencesAreLoaded: false,
|
||||
mDelayUserDialog: null,
|
||||
|
||||
// Private Methods /////////////////////////////////////////////////////////
|
||||
|
||||
_resetLogFiles: function() {
|
||||
let wrapperLogFile = LauncherUtil.dataDirectoryObject
|
||||
wrapperLogFile.append('I2P')
|
||||
wrapperLogFile.append('wrapper.log')
|
||||
if (wrapperLogFile.exists()) wrapperLogFile.remove(false)
|
||||
let logTxtFile = LauncherUtil.dataDirectoryObject
|
||||
logTxtFile.append('I2P')
|
||||
logTxtFile.append('logs')
|
||||
logTxtFile.append('log-0.txt')
|
||||
if (logTxtFile.exists()) logTxtFile.remove(false)
|
||||
},
|
||||
|
||||
_startI2P: function()
|
||||
{
|
||||
this.mI2PProcessStatus = this.kStatusUnknown;
|
||||
@ -270,13 +366,13 @@ I2PProcessService.prototype =
|
||||
try
|
||||
{
|
||||
// Ideally, we would cd to the Firefox application directory before
|
||||
// starting tor (but we don't know how to do that). Instead, we
|
||||
// rely on the TBB launcher to start Firefox from the right place.
|
||||
// starting i2p (but we don't know how to do that). Instead, we
|
||||
// rely on the IBB launcher to start Firefox from the right place.
|
||||
|
||||
// Get the I2P data directory first so it is created before we try to
|
||||
// construct paths to files that will be inside it.
|
||||
let dataDir = LauncherUtil.getI2PConfigPath(true)
|
||||
let exeFile = LauncherUtil.getI2PFile("i2p", false)
|
||||
let exeFile = LauncherUtil.getI2PBinary()
|
||||
this._logger.log(3, `Datadir => ${dataDir.path}\nExeFile => ${exeFile.path}`)
|
||||
|
||||
var detailsKey;
|
||||
@ -294,11 +390,11 @@ I2PProcessService.prototype =
|
||||
return;
|
||||
}
|
||||
|
||||
this._resetLogFiles()
|
||||
|
||||
let args = LauncherUtil.getRouterDefaultArgs()
|
||||
|
||||
// Set an environment variable that points to the I2P data directory.
|
||||
// This is used by meek-client-torbrowser to find the location for
|
||||
// the meek browser profile.
|
||||
let env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment)
|
||||
env.set("I2P_BROWSER_I2P_DATA_DIR", dataDir.path)
|
||||
|
||||
@ -336,42 +432,92 @@ I2PProcessService.prototype =
|
||||
{
|
||||
this.mI2PProcessStatus = this.kStatusExited
|
||||
//var s = LauncherUtil.getLocalizedString("i2p_failed_to_start");
|
||||
//this._notifyUserOfError(s, null, this.kI2PProcessDidNotStartTopic);
|
||||
this._notifyUserOfError('Failed to start the I2P router', null, this.kI2PProcessDidNotStartTopic);
|
||||
this._logger.log(4, "_startI2P error: ", e)
|
||||
}
|
||||
}, // _startI2P()
|
||||
|
||||
_isConsoleRunning: function(callback) {
|
||||
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
let req = checkSvc.createCheckConsoleRequest(true);
|
||||
let obsSvc = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService)
|
||||
let req = checkSvc.createCheckConsoleRequest(true)
|
||||
const self = this
|
||||
req.onreadystatechange = function(event) {
|
||||
if (req.readyState === 4) {
|
||||
// Done
|
||||
let result = checkSvc.parseCheckConsoleResponse(req)
|
||||
self.mIsBootstrapDone = true
|
||||
self.mI2PProcessStatus = self.kStatusRunning
|
||||
self._processBootstrapStatus({ PROGRESS: 100, message: 'The router has succcessfully started.' })
|
||||
|
||||
var statusObj = { bootstrap: 'done', success: true }
|
||||
statusObj.wrappedJSObject = statusObj
|
||||
obsSvc.notifyObservers(statusObj, "I2PBootstrapStatus", null)
|
||||
callback(result)
|
||||
}
|
||||
}
|
||||
req.send(null)
|
||||
},
|
||||
|
||||
_processBootstrapStatus: function(aStatusObj)
|
||||
{
|
||||
if (!aStatusObj)
|
||||
return
|
||||
|
||||
if (100 == aStatusObj.PROGRESS)
|
||||
{
|
||||
this.mIsBootstrapDone = true
|
||||
this.mBootstrapErrorOccurred = false
|
||||
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, false)
|
||||
}
|
||||
else
|
||||
{
|
||||
this.mIsBootstrapDone = false
|
||||
|
||||
if (aStatusObj._errorOccurred)
|
||||
{
|
||||
this.mBootstrapErrorOccurred = true
|
||||
LauncherUtil.setBoolPref(this.kPrefPromptAtStartup, true)
|
||||
let phase = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj,
|
||||
"TAG")
|
||||
let reason = LauncherUtil.getLocalizedBootstrapStatus(aStatusObj,
|
||||
"REASON")
|
||||
let details = LauncherUtil.getFormattedLocalizedString(
|
||||
"i2p_bootstrap_failed_details", [phase, reason], 2)
|
||||
I2PLauncherLogger.log(5, "I2P bootstrap error: [" + aStatusObj.TAG +
|
||||
"/" + aStatusObj.REASON + "] " + details);
|
||||
|
||||
if ((aStatusObj.TAG != this.mLastI2PWarningPhase) ||
|
||||
(aStatusObj.REASON != this.mLastI2PWarningReason))
|
||||
{
|
||||
this.mLastI2PWarningPhase = aStatusObj.TAG
|
||||
this.mLastI2PWarningReason = aStatusObj.REASON
|
||||
|
||||
let msg = LauncherUtil.getLocalizedString("i2p_bootstrap_failed")
|
||||
this._notifyUserOfError(msg, details, this.kI2PBootstrapErrorTopic)
|
||||
}
|
||||
}
|
||||
}
|
||||
}, // _processBootstrapStatus()
|
||||
|
||||
_controlI2P: function(aIsRunningI2P)
|
||||
{
|
||||
|
||||
try
|
||||
{
|
||||
if (aIsRunningI2P)
|
||||
this._monitorI2PProcessStartup();
|
||||
this._monitorI2PProcessStartup()
|
||||
|
||||
// If the user pressed "Quit" within settings/progress, exit.
|
||||
if (this.mQuitSoon)
|
||||
this._quitApp();
|
||||
this._quitApp()
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
this.mI2PProcessStatus = this.kStatusExited;
|
||||
var s = LauncherUtil.getLocalizedString("i2p_control_failed");
|
||||
this._notifyUserOfError(s, null, null);
|
||||
this._logger.log(4, "_controlI2P error: ", e);
|
||||
this.mI2PProcessStatus = this.kStatusExited
|
||||
var s = LauncherUtil.getLocalizedString("i2p_control_failed")
|
||||
this._notifyUserOfError(s, null, null)
|
||||
this._logger.log(4, "_controlI2P error: ", e)
|
||||
}
|
||||
}, // controlI2P()
|
||||
|
||||
@ -384,8 +530,8 @@ I2PProcessService.prototype =
|
||||
this.mI2PProcess.kill()
|
||||
}
|
||||
|
||||
var asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
|
||||
var flags = asSvc.eAttemptQuit;
|
||||
let asSvc = Cc["@mozilla.org/toolkit/app-startup;1"].getService(Ci.nsIAppStartup);
|
||||
let flags = asSvc.eAttemptQuit;
|
||||
asSvc.quit(flags);
|
||||
}
|
||||
catch (e)
|
||||
@ -403,25 +549,25 @@ I2PProcessService.prototype =
|
||||
|
||||
_notifyUserOfError: function(aMessage, aDetails, aNotifyTopic)
|
||||
{
|
||||
let errorObj = { handled: false, message: aMessage };
|
||||
let errorObj = { handled: false, message: aMessage }
|
||||
if (aDetails)
|
||||
errorObj.details = aDetails;
|
||||
errorObj.details = aDetails
|
||||
|
||||
if (aNotifyTopic)
|
||||
{
|
||||
// Give other code an opportunity to handle this error, e.g., if the
|
||||
// network settings window is open, errors are displayed using an
|
||||
// overlaid XUL element.
|
||||
errorObj.wrappedJSObject = errorObj;
|
||||
this.mObsSvc.notifyObservers(errorObj, aNotifyTopic, null);
|
||||
errorObj.wrappedJSObject = errorObj
|
||||
this.mObsSvc.notifyObservers(errorObj, aNotifyTopic, null)
|
||||
}
|
||||
|
||||
if (!errorObj.handled)
|
||||
{
|
||||
let msg = aMessage;
|
||||
let msg = aMessage
|
||||
if (aDetails)
|
||||
msg += "\n\n" + aDetails;
|
||||
I2PLauncherUtil.showAlert(null, msg);
|
||||
msg += "\n\n" + aDetails
|
||||
LauncherUtil.showAlert(null, msg)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -11,6 +11,7 @@ const Cu = Components.utils
|
||||
|
||||
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import("resource://gre/modules/Log.jsm")
|
||||
|
||||
let console = (Cu.import("resource://gre/modules/Console.jsm", {})).console
|
||||
|
||||
@ -107,32 +108,32 @@ I2pbuttonLogger.prototype =
|
||||
},
|
||||
|
||||
safe_log: function(level, str, scrub) {
|
||||
if (this.loglevel < 4) {
|
||||
this.eclog(level, str+scrub);
|
||||
} else {
|
||||
this.eclog(level, str+" [scrubbed]");
|
||||
}
|
||||
if (this.loglevel < 4) {
|
||||
this.eclog(level, str+scrub);
|
||||
} else {
|
||||
this.eclog(level, str+" [scrubbed]");
|
||||
}
|
||||
},
|
||||
|
||||
log: function(level, str) {
|
||||
switch(this.logmethod) {
|
||||
case 2: // debuglogger
|
||||
if(this._debuglog) {
|
||||
this._debuglog.log((6-level), this.formatLog(str,level));
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 0: // stderr
|
||||
if(this.loglevel <= level)
|
||||
dump(this.formatLog(str,level)+"\n");
|
||||
break;
|
||||
default:
|
||||
dump("Bad log method: "+this.logmethod);
|
||||
case 1: // errorconsole
|
||||
if(this.loglevel <= level)
|
||||
this._console.logStringMessage(this.formatLog(str,level));
|
||||
break;
|
||||
}
|
||||
switch(this.logmethod) {
|
||||
case 2: // debuglogger
|
||||
if(this._debuglog) {
|
||||
this._debuglog.log((6-level), this.formatLog(str,level));
|
||||
break;
|
||||
}
|
||||
// fallthrough
|
||||
case 0: // stderr
|
||||
if(this.loglevel <= level)
|
||||
dump(this.formatLog(str,level)+"\n");
|
||||
break;
|
||||
default:
|
||||
dump("Bad log method: "+this.logmethod);
|
||||
case 1: // errorconsole
|
||||
if(this.loglevel <= level)
|
||||
this._console.logStringMessage(this.formatLog(str,level));
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
error: function(str) { this.log(6, str) },
|
||||
@ -149,25 +150,25 @@ I2pbuttonLogger.prototype =
|
||||
// data: which pref has been changed (relative to subject)
|
||||
observe: function(subject, topic, data)
|
||||
{
|
||||
if (topic != "nsPref:changed") return;
|
||||
switch (data) {
|
||||
case "extensions.i2pbutton.logmethod":
|
||||
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
|
||||
if (this.logmethod === 0) {
|
||||
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
|
||||
true);
|
||||
} else if (Services.prefs.
|
||||
getIntPref("extensions.i2plauncher.logmethod", 3) !== 0) {
|
||||
// If Tor Launcher is not available or its log method is not 0
|
||||
// then let's reset the dump pref.
|
||||
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case "extensions.i2pbutton.loglevel":
|
||||
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
|
||||
break;
|
||||
}
|
||||
if (topic != "nsPref:changed") return;
|
||||
switch (data) {
|
||||
case "extensions.i2pbutton.logmethod":
|
||||
this.logmethod = Services.prefs.getIntPref("extensions.i2pbutton.logmethod");
|
||||
if (this.logmethod === 0) {
|
||||
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
|
||||
true);
|
||||
} else if (Services.prefs.
|
||||
getIntPref("extensions.i2plauncher.logmethod", 3) !== 0) {
|
||||
// If I2P Launcher is not available or its log method is not 0
|
||||
// then let's reset the dump pref.
|
||||
Services.prefs.setBoolPref("browser.dom.window.dump.enabled",
|
||||
false);
|
||||
}
|
||||
break;
|
||||
case "extensions.i2pbutton.loglevel":
|
||||
this.loglevel = Services.prefs.getIntPref("extensions.i2pbutton.loglevel");
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -25,6 +25,12 @@ XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/mo
|
||||
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 17657)
|
||||
let httpProxyPort = Services.prefs.getIntPref("network.proxy.http_port", 14444)
|
||||
|
||||
const defaultWebappsConfig = `# Autogenerated by I2P Browser
|
||||
webapps.jsonrpc.startOnLoad=true
|
||||
webapps.routerconsole.startOnLoad=true
|
||||
webapps.i2ptunnel.startOnLoad=true
|
||||
`
|
||||
|
||||
const defaultProxyTunnels = `# Autogenerated by I2P Browser
|
||||
tunnel.0.description=HTTP proxy for browsing eepsites and the web
|
||||
tunnel.0.interface=127.0.0.1
|
||||
@ -125,6 +131,10 @@ i2p.reseedURL=https://download.xxlspeed.com/,https://i2p.mooo.com/netDb/,https:/
|
||||
router.outboundPool.quantity=7
|
||||
router.inboundPool.quantity=7
|
||||
router.sharePercentage=50
|
||||
i2cp.hostname=127.0.0.1
|
||||
i2cp.port=17654
|
||||
router.startup.jetty9.migrated=true
|
||||
routerconsole.welcomeWizardComplete=true
|
||||
`
|
||||
|
||||
|
||||
@ -149,6 +159,7 @@ RouterConfigManager.prototype = {
|
||||
mDoesRouterConfigExists: false,
|
||||
mDoesClientsConfigExists: false,
|
||||
mDoesTunnelConfigExists: false,
|
||||
mDoesWebappsConfigExists: false,
|
||||
mHasChecksStarted: false,
|
||||
mIsChecksDone: false,
|
||||
|
||||
@ -161,23 +172,60 @@ RouterConfigManager.prototype = {
|
||||
},
|
||||
|
||||
|
||||
_write_router_config: function(configfile,onComplete) {
|
||||
_write_config: function(configfile, content, onComplete) {
|
||||
const self = this
|
||||
LauncherUtil.writeFileWithData(configfile, defaultRouterConfig, file => { onComplete(file) }, (err) => {
|
||||
this._logger.log(6,`Can't write router config file :( - path was ${configfile.path}`)
|
||||
LauncherUtil.writeFileWithData(configfile, content, file => { onComplete(file) }, (err) => {
|
||||
this._logger.log(6,`Can't write config file :( - path was ${configfile.path}, error: ${err}`)
|
||||
})
|
||||
},
|
||||
_write_tunnel_config: function(configfile,onComplete) {
|
||||
const self = this
|
||||
LauncherUtil.writeFileWithData(configfile, defaultProxyTunnels, file => { onComplete(file) }, (err) => {
|
||||
this._logger.log(6,`Can't write tunnel proxy config file :( - path was ${configfile.path}`)
|
||||
})
|
||||
|
||||
copy_recursive: async function(sourceDir, destDir) {
|
||||
let items = sourceDir.directoryEntries
|
||||
while (items.hasMoreElements()) {
|
||||
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
|
||||
if (item.isFile()) {
|
||||
item.copyTo(destDir, "")
|
||||
this._logger.log(3, `Copied ${item.path}`)
|
||||
} else if (item.isDirectory()) {
|
||||
let newDir = destDir.clone()
|
||||
newDir.append(item.leafName)
|
||||
newDir.create(newDir.DIRECTORY_TYPE, 0o700)
|
||||
this._logger.log(3, `Recursively copying ${item.path}`)
|
||||
this.copy_recursive(item, newDir)
|
||||
}
|
||||
}
|
||||
},
|
||||
_write_clients_config: function(configfile,onComplete) {
|
||||
const self = this
|
||||
LauncherUtil.writeFileWithData(configfile, defaultClientsConfig, file => { onComplete(file) }, (err) => {
|
||||
this._logger.log(6,`Can't write clients config file :( - path was ${configfile.path}`)
|
||||
})
|
||||
|
||||
ensure_docs: async function() {
|
||||
let configDirectory = LauncherUtil.getI2PConfigPath(true)
|
||||
let destDocsDir = configDirectory.clone()
|
||||
let distDocsDir = LauncherUtil.getI2PBinary()
|
||||
distDocsDir = distDocsDir.parent.parent
|
||||
distDocsDir.append('docs')
|
||||
destDocsDir.append('docs')
|
||||
if (!destDocsDir.exists()) {
|
||||
this.copy_recursive(distDocsDir, destDocsDir)
|
||||
}
|
||||
},
|
||||
|
||||
ensure_webapps: async function() {
|
||||
let configDirectory = LauncherUtil.getI2PConfigPath(true)
|
||||
let destWebappDir = configDirectory.clone()
|
||||
let distWebppDir = LauncherUtil.getI2PBinary()
|
||||
distWebppDir = distWebppDir.parent.parent
|
||||
distWebppDir.append('webapps')
|
||||
destWebappDir.append('webapps')
|
||||
if (!destWebappDir.exists()) {
|
||||
destWebappDir.create(destWebappDir.DIRECTORY_TYPE, 0o700)
|
||||
let items = distWebppDir.directoryEntries
|
||||
while (items.hasMoreElements()) {
|
||||
let item = items.getNext().QueryInterface(Components.interfaces.nsIFile)
|
||||
if (item.isFile()) {
|
||||
item.copyTo(destWebappDir, "")
|
||||
this._logger.log(3, `Copied ${item.path}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@ -191,6 +239,18 @@ RouterConfigManager.prototype = {
|
||||
tunnelConfigFile.append('i2ptunnel.config')
|
||||
let clientsConfigFile = configDirectory.clone()
|
||||
clientsConfigFile.append('clients.config')
|
||||
let webappsConfigFile = configDirectory.clone()
|
||||
webappsConfigFile.append('webapps.config')
|
||||
|
||||
let hoststxtFile = configDirectory.clone()
|
||||
hoststxtFile.append('hosts.txt')
|
||||
|
||||
if (!hoststxtFile.exists()) {
|
||||
let distFile = LauncherUtil.getI2PBinary().parent.parent
|
||||
distFile.append('hosts.txt')
|
||||
distFile.copyTo(hoststxtFile.parent, "")
|
||||
this._logger.log(3, `Copied hosts.txt file`)
|
||||
}
|
||||
|
||||
// Ensure they exists
|
||||
const self = this
|
||||
@ -198,7 +258,7 @@ RouterConfigManager.prototype = {
|
||||
this.ensureRouterConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!routerConfigFile.exists()) {
|
||||
self._write_router_config(routerConfigFile, file => {
|
||||
self._write_config(routerConfigFile, defaultRouterConfig, file => {
|
||||
self.mDoesRouterConfigExists = true
|
||||
self._logger.log(3, 'Wrote router.config')
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(file)
|
||||
@ -215,7 +275,7 @@ RouterConfigManager.prototype = {
|
||||
this.ensureTunnelConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!tunnelConfigFile.exists()) {
|
||||
self._write_tunnel_config(tunnelConfigFile, tfile => {
|
||||
self._write_config(tunnelConfigFile, defaultProxyTunnels, tfile => {
|
||||
self._logger.log(3, 'Wrote i2ptunnel.config')
|
||||
self.mDoesTunnelConfigExists = true
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
@ -232,7 +292,7 @@ RouterConfigManager.prototype = {
|
||||
this.ensureClientsConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!clientsConfigFile.exists()) {
|
||||
self._write_tunnel_config(tunnelConfigFile, tfile => {
|
||||
self._write_config(clientsConfigFile, defaultClientsConfig, tfile => {
|
||||
self._logger.log(3, 'Wrote clients.config')
|
||||
self.mDoesClientsConfigExists = true
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
@ -246,12 +306,30 @@ RouterConfigManager.prototype = {
|
||||
})
|
||||
}
|
||||
|
||||
this.ensureWebappsConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!webappsConfigFile.exists()) {
|
||||
self._write_config(webappsConfigFile, defaultWebappsConfig, tfile => {
|
||||
self._logger.log(3, 'Wrote webapps.config')
|
||||
self.mDoesWebappsConfigExists = true
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
resolve(webappsConfigFile)
|
||||
})
|
||||
} else {
|
||||
self._logger.log(3, 'Found webapps.config from earlier')
|
||||
self.mDoesWebappsConfigExists = true
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
// Promises are not done but at least done here.
|
||||
this.mIsChecksDone = true
|
||||
return Promise.all([
|
||||
this.ensureRouterConfigPromise(),
|
||||
this.ensureTunnelConfigPromise(),
|
||||
this.ensureClientsConfigPromise(),
|
||||
this.ensureWebappsConfigPromise(),
|
||||
])
|
||||
},
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
<em:name>I2pbutton</em:name>
|
||||
<em:creator>Meeh, Mikal Villa</em:creator>
|
||||
<em:id>i2pbutton@geti2p.net</em:id>
|
||||
<em:version>0.3.1</em:version>
|
||||
<em:version>0.3.6</em:version>
|
||||
<em:multiprocessCompatible>true</em:multiprocessCompatible>
|
||||
<em:homepageURL>https://geti2p.net/en/download/lab</em:homepageURL>
|
||||
<em:iconURL>chrome://i2pbutton/skin/i2p.png</em:iconURL>
|
||||
|
@ -49,7 +49,7 @@ const LauncherUtil = {
|
||||
{
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
|
||||
let browserWindow = wm.getMostRecentWindow("navigator:browser")
|
||||
if (TLUtilInternal._isWindowVisible(browserWindow))
|
||||
if (LauncherUtilInternal._isWindowVisible(browserWindow))
|
||||
aParentWindow = browserWindow;
|
||||
}
|
||||
|
||||
@ -85,32 +85,31 @@ const LauncherUtil = {
|
||||
|
||||
get _networkSettingsWindow()
|
||||
{
|
||||
var wm = Cc["@mozilla.org/appshell/window-mediator;1"]
|
||||
.getService(Ci.nsIWindowMediator);
|
||||
return wm.getMostRecentWindow("I2PLauncher:NetworkSettings");
|
||||
let wm = Cc["@mozilla.org/appshell/window-mediator;1"].getService(Ci.nsIWindowMediator)
|
||||
return wm.getMostRecentWindow("I2PLauncher:NetworkSettings")
|
||||
},
|
||||
|
||||
_openNetworkSettings: function(aIsInitialBootstrap, aStartAtWizardPanel)
|
||||
{
|
||||
var win = this._networkSettingsWindow;
|
||||
var win = this._networkSettingsWindow
|
||||
if (win)
|
||||
{
|
||||
// Return to "Starting i2p" panel if being asked to open & dlog already exists.
|
||||
//win.showStartingTorPanel();
|
||||
win.focus();
|
||||
//win.showStartingI2PPanel()
|
||||
win.focus()
|
||||
return;
|
||||
}
|
||||
|
||||
const kSettingsURL = "chrome://i2pbutton/content/network-settings.xul";
|
||||
const kWizardURL = "chrome://i2pbutton/content/network-settings-wizard.xul";
|
||||
const kSettingsURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg.xul"
|
||||
const kWizardURL = "chrome://i2pbutton/chrome/content/i2pstartup-confdlg-wizard.xul"
|
||||
|
||||
var wwSvc = Cc["@mozilla.org/embedcomp/window-watcher;1"]
|
||||
.getService(Ci.nsIWindowWatcher);
|
||||
var winFeatures = "chrome,dialog=yes,modal,all";
|
||||
var argsArray = this._createOpenWindowArgsArray(aIsInitialBootstrap,
|
||||
aStartAtWizardPanel);
|
||||
let isProgress = (this.kWizardProgressPageID == aStartAtWizardPanel);
|
||||
let url = (aIsInitialBootstrap || isProgress) ? kWizardURL : kSettingsURL;
|
||||
wwSvc.openWindow(null, url, "_blank", winFeatures, argsArray);
|
||||
.getService(Ci.nsIWindowWatcher)
|
||||
var winFeatures = "chrome,dialog=no,modal,all"
|
||||
var argsArray = this._createOpenWindowArgsArray(aIsInitialBootstrap,aStartAtWizardPanel)
|
||||
let isProgress = (this.kWizardProgressPageID == aStartAtWizardPanel)
|
||||
//let url = (aIsInitialBootstrap || isProgress) ? kWizardURL : kSettingsURL
|
||||
wwSvc.openWindow(null, kWizardURL, "_blank", winFeatures, argsArray)
|
||||
},
|
||||
|
||||
// Returns true if user confirms; false if not.
|
||||
@ -147,8 +146,8 @@ const LauncherUtil = {
|
||||
{
|
||||
try
|
||||
{
|
||||
let dirPath = this.getCharPref(TLUtilInternal.kIPCDirPrefName);
|
||||
this.clearUserPref(TLUtilInternal.kIPCDirPrefName);
|
||||
let dirPath = this.getCharPref(LauncherUtilInternal.kIPCDirPrefName);
|
||||
this.clearUserPref(LauncherUtilInternal.kIPCDirPrefName);
|
||||
if (dirPath)
|
||||
{
|
||||
let f = Cc['@mozilla.org/file/local;1'].createInstance(Ci.nsIFile);
|
||||
@ -168,31 +167,34 @@ const LauncherUtil = {
|
||||
let dataDir = this.getI2PConfigPath(true)
|
||||
let exeFile = this.getI2PBinary()
|
||||
let libDir = dataDir.clone()
|
||||
let i2pDir = libDir.clone()
|
||||
let i2pDir = exeFile.parent.parent.clone()
|
||||
libDir.append('lib')
|
||||
let args = []
|
||||
// NOTE: Don't mind spaces as nsIProcess escapes them.
|
||||
args.push(`-Di2p.dir.base=${i2pDir.path}`)
|
||||
logger.log(2, `Path for base is => ${i2pDir.path}`)
|
||||
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
|
||||
let logFile = dataDir.clone()
|
||||
logFile.append('wrapper.log')
|
||||
args.push(`-Dwrapper.logfile=${logFile.path}`)
|
||||
args.push(`-Djetty.home=${i2pDir.path}`)
|
||||
args.push(`-Di2p.dir.config=${dataDir.path}`)
|
||||
args.push(`-Di2p.dir.router=${dataDir.path}`)
|
||||
args.push(`-Di2p.dir.app=${dataDir.path}`)
|
||||
let nativeLib = libDir.clone()
|
||||
nativeLib.append('jbigi.jar')
|
||||
let clientConfigFile = dataDir.clone()
|
||||
clientConfigFile.append('clients.config')
|
||||
let routerCofigFile = dataDir.clone()
|
||||
routerCofigFile.append('router.config')
|
||||
logger.log(2, `Path for base is => ${i2pDir.path}`)
|
||||
// NOTE: Don't mind spaces as nsIProcess escapes them.
|
||||
args.push(`-Di2p.dir.base=${i2pDir.path}`)
|
||||
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
|
||||
args.push(`-Dwrapper.logfile=${logFile.path}`)
|
||||
args.push(`-Djetty.home=${i2pDir.path}`)
|
||||
args.push(`-Djava.library.path=${libDir.path}`)
|
||||
args.push(`-Di2p.dir.config=${dataDir.path}`)
|
||||
args.push(`-Di2p.dir.router=${dataDir.path}`)
|
||||
args.push(`-Di2p.dir.app=${dataDir.path}`)
|
||||
args.push(`-Drouter.clientConfigFile=${clientConfigFile.path}`)
|
||||
args.push(`-Drouter.configLocation=${routerCofigFile.path}`)
|
||||
args.push('-Di2p.dir.portableMode=false')
|
||||
args.push('-Dwrapper.name=i2pbrowser')
|
||||
args.push('-Dwrapper.displayname=I2PBrowser')
|
||||
args.push('-cp')
|
||||
args.push(`${i2pDir.path}:${libDir.path}:${dataDir.path}`)
|
||||
args.push(`${i2pDir.path}:${nativeLib.path}:${libDir.path}:${dataDir.path}`)
|
||||
args.push("-Djava.awt.headless=true")
|
||||
args.push("-Dwrapper.console.loglevel=DEBUG")
|
||||
// Main class to execute
|
||||
@ -250,7 +252,7 @@ const LauncherUtil = {
|
||||
let dataDir = profDir.parent.parent.clone()
|
||||
dataDir.append('I2P')
|
||||
if (!dataDir.exists() && create) {
|
||||
dataDir.create(dataDir.DIRECTORY_TYPE, 0o775)
|
||||
dataDir.create(dataDir.DIRECTORY_TYPE, 0o700)
|
||||
}
|
||||
|
||||
return dataDir
|
||||
@ -290,18 +292,17 @@ const LauncherUtil = {
|
||||
}
|
||||
}
|
||||
|
||||
i2pFile = LauncherUtilInternal._appDir.clone()
|
||||
try {
|
||||
|
||||
// Turn 'path' into an absolute path.
|
||||
i2pFile = LauncherUtilInternal._appDir.clone()
|
||||
if (this.isMac) {
|
||||
i2pFile.append("I2PBrowser")
|
||||
} else {
|
||||
if (!this.isMac) {
|
||||
let lnxpath = i2pFile.clone()
|
||||
lnxpath.append(path)
|
||||
return lnxpath
|
||||
}
|
||||
//i2pFile.appendRelativePath(path)
|
||||
logger.log(2, `getI2PFile - Path before append: ${i2pFile.path}`)
|
||||
i2pFile.appendRelativePath(path)
|
||||
logger.log(2, `getI2PFile - Gonna try path ${i2pFile.path}`)
|
||||
|
||||
@ -311,7 +312,7 @@ const LauncherUtil = {
|
||||
return i2pFile
|
||||
} else {
|
||||
logger.log(4, aI2PFileType + " file not found: "+ i2pFile.path)
|
||||
return ''
|
||||
return null
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
@ -320,22 +321,27 @@ const LauncherUtil = {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
get internal() {
|
||||
return LauncherUtilInternal
|
||||
},
|
||||
|
||||
get dataDirectoryObject() {
|
||||
let dataDir = LauncherUtilInternal._dataDir
|
||||
try { dataDir.normalize() } catch(e) {}
|
||||
logger.log(3, `Decided to use file ${dataDir.path}`)
|
||||
return dataDir.clone()
|
||||
},
|
||||
|
||||
get appDirectoryObject() {
|
||||
return LauncherUtilInternal._appDir.clone()
|
||||
},
|
||||
|
||||
flushLocalizedStringCache: function()
|
||||
{
|
||||
LauncherUtilInternal.mStringBundle = undefined
|
||||
},
|
||||
|
||||
// "i2pbutton." is prepended to aStringName.
|
||||
getLocalizedString: function(aStringName)
|
||||
{
|
||||
@ -345,7 +351,7 @@ const LauncherUtil = {
|
||||
try
|
||||
{
|
||||
var key = kPropNamePrefix + aStringName;
|
||||
return TLUtilInternal._stringBundle.GetStringFromName(key);
|
||||
return LauncherUtilInternal._stringBundle.GetStringFromName(key);
|
||||
} catch(e) {}
|
||||
|
||||
return aStringName;
|
||||
@ -360,7 +366,7 @@ const LauncherUtil = {
|
||||
try
|
||||
{
|
||||
var key = kPropNamePrefix + aStringName;
|
||||
return TLUtilInternal._stringBundle.formatStringFromName(key, aArray, aLen)
|
||||
return LauncherUtilInternal._stringBundle.formatStringFromName(key, aArray, aLen)
|
||||
} catch(e) {}
|
||||
|
||||
return aStringName;
|
||||
@ -415,6 +421,7 @@ let LauncherUtilInternal = {
|
||||
|
||||
return this.mOS
|
||||
},
|
||||
|
||||
get _stringBundle()
|
||||
{
|
||||
if (!this.mStringBundle)
|
||||
|
@ -8,12 +8,50 @@ const { utils: Cu } = Components;
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
const { LegacyExtensionContext } =
|
||||
Cu.import("resource://gre/modules/LegacyExtensionsUtils.jsm", {});
|
||||
const { bindPref } =
|
||||
Cu.import("resource://i2pbutton/modules/utils.js", {});
|
||||
let logger = Components.classes["@geti2p.net/i2pbutton-logger;1"]
|
||||
.getService(Components.interfaces.nsISupports).wrappedJSObject;
|
||||
let log = (level, msg) => logger.log(level, msg);
|
||||
|
||||
|
||||
// __prefs__. A shortcut to Mozilla Services.prefs.
|
||||
let prefs = Services.prefs;
|
||||
|
||||
// __getPrefValue(prefName)__
|
||||
// Returns the current value of a preference, regardless of its type.
|
||||
var getPrefValue = function (prefName) {
|
||||
switch(prefs.getPrefType(prefName)) {
|
||||
case prefs.PREF_BOOL: return prefs.getBoolPref(prefName);
|
||||
case prefs.PREF_INT: return prefs.getIntPref(prefName);
|
||||
case prefs.PREF_STRING: return prefs.getCharPref(prefName);
|
||||
default: return null;
|
||||
}
|
||||
};
|
||||
|
||||
// __bindPref(prefName, prefHandler, init)__
|
||||
// Applies prefHandler whenever the value of the pref changes.
|
||||
// If init is true, applies prefHandler to the current value.
|
||||
// Returns a zero-arg function that unbinds the pref.
|
||||
var bindPref = function (prefName, prefHandler, init = false) {
|
||||
let update = () => { prefHandler(getPrefValue(prefName)); },
|
||||
observer = { observe : function (subject, topic, data) {
|
||||
if (data === prefName) {
|
||||
update();
|
||||
}
|
||||
} };
|
||||
prefs.addObserver(prefName, observer, false);
|
||||
if (init) {
|
||||
update();
|
||||
}
|
||||
return () => { prefs.removeObserver(prefName, observer); };
|
||||
};
|
||||
|
||||
// __bindPrefAndInit(prefName, prefHandler)__
|
||||
// Applies prefHandler to the current value of pref specified by prefName.
|
||||
// Re-applies prefHandler whenever the value of the pref changes.
|
||||
// Returns a zero-arg function that unbinds the pref.
|
||||
var bindPrefAndInit = (prefName, prefHandler) =>
|
||||
bindPref(prefName, prefHandler, true);
|
||||
|
||||
// ## NoScript settings
|
||||
|
||||
// Minimum and maximum capability states as controlled by NoScript.
|
||||
|
@ -77,7 +77,7 @@ const getProfileDir = function() {
|
||||
getService(Ci.nsIProperties)
|
||||
// this is a reference to the profile dir (ProfD) now.
|
||||
let localDir = directoryService.get("ProfD", Ci.nsIFile)
|
||||
return localDir.path
|
||||
return localDir
|
||||
}
|
||||
|
||||
function openFile(path, mode) {
|
||||
@ -112,6 +112,22 @@ function array_to_hexdigits(array) {
|
||||
}).join('');
|
||||
}
|
||||
|
||||
function listExtensions(callbackFn) {
|
||||
AddonManager.getAddonsByTypes(["extension"], function(addons) {
|
||||
var addonData = [];
|
||||
|
||||
for (let i in addons) {
|
||||
let cur = addons[i];
|
||||
addonData.push({
|
||||
id: cur.id.toString(),
|
||||
name: cur.name,
|
||||
});
|
||||
};
|
||||
console.log(JSON.stringify(addonData, null, ' '));
|
||||
callbackFn(addonData)
|
||||
});
|
||||
}
|
||||
|
||||
//window.open("chrome://browser/content/browser.xul", "bmarks", "chrome,width=600,height=300")
|
||||
|
||||
// __prefs__. A shortcut to Mozilla Services.prefs.
|
||||
@ -135,10 +151,10 @@ var getPrefValue = function (prefName) {
|
||||
var bindPref = function (prefName, prefHandler, init = false) {
|
||||
let update = () => { prefHandler(getPrefValue(prefName)); },
|
||||
observer = { observe : function (subject, topic, data) {
|
||||
if (data === prefName) {
|
||||
update();
|
||||
}
|
||||
} };
|
||||
if (data === prefName) {
|
||||
update();
|
||||
}
|
||||
} };
|
||||
prefs.addObserver(prefName, observer, false);
|
||||
if (init) {
|
||||
update();
|
||||
@ -200,14 +216,14 @@ let dialogsByName = {};
|
||||
// Like window.openDialog, but if the window is already
|
||||
// open, just focuses it instead of opening a new one.
|
||||
var showDialog = function (parent, url, name, features) {
|
||||
let existingDialog = dialogsByName[name];
|
||||
let existingDialog = dialogsByName[name]
|
||||
if (existingDialog && !existingDialog.closed) {
|
||||
existingDialog.focus();
|
||||
return existingDialog;
|
||||
existingDialog.focus()
|
||||
return existingDialog
|
||||
} else {
|
||||
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1));
|
||||
dialogsByName[name] = newDialog;
|
||||
return newDialog;
|
||||
let newDialog = parent.openDialog.apply(parent, Array.slice(arguments, 1))
|
||||
dialogsByName[name] = newDialog
|
||||
return newDialog
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user