Compare commits
70 Commits
Author | SHA1 | Date | |
---|---|---|---|
a6d97dc00a | |||
92a908907b | |||
b40d5578f8 | |||
199f3b839e | |||
dbf0d53e5c | |||
00f3ac2afb | |||
32bb96b18e | |||
52c3c6a6c2 | |||
301bcf6d33 | |||
b52f7f7510 | |||
116f787d25 | |||
abc0ce454f | |||
b90ed676fd | |||
91b0d0500e | |||
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 | |||
d3b043fc23 | |||
a9e70d19a7 | |||
4e6117faf9 | |||
c19ea1d76c | |||
015e20c06a | |||
96ad84bf2c | |||
45b13ef209 | |||
fbf7ced2c7 | |||
d2403362ba | |||
fe23ea2047 | |||
5b01b19688 | |||
7664b3530d | |||
87faaa3e74 | |||
e66bc441d3 | |||
13eaf1f035 | |||
8106f114ca | |||
e796ce750f | |||
7301cbd7ba | |||
3bb805b40c | |||
4a880b973d | |||
60c455b6af | |||
721a3b9242 | |||
1886a5ffc9 | |||
40d97cd420 |
@ -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,25 +33,36 @@ 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>
|
||||
&aboutI2p.source;: <a href="https://github.com/mikalv/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3">https://github.com/mikalv/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3</a><br />
|
||||
&aboutI2p.bug_tracker;: <a href="https://trac.i2p2.de/">https://trac.i2p2.de/</a><br />
|
||||
&aboutI2p.build_scripts;: <a href="https://github.com/mikalv/i2p-browser-build-scripts">https://github.com/mikalv/i2p-browser-build-scripts</a><br />
|
||||
&aboutI2p.i2pbutton_source;: <a href="https://github.com/mikalv/i2pbutton">https://github.com/mikalv/i2pbutton</a><br />
|
||||
<ul>
|
||||
<li>&aboutI2p.source;: <a href="&aboutI2p.github;/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3">&aboutI2p.github;/test-i2p-browser/tree/i2p-browser-60.7.0esr-9.0-1-build3</a></li>
|
||||
<li>&aboutI2p.design;: <a href="&aboutI2p.github;/i2p-browser-design-docs">&aboutI2p.github;/i2p-browser-design-docs</a></li>
|
||||
<li>&aboutI2p.bug_tracker;: <a href="&aboutI2p.trac;/">&aboutI2p.trac;/</a></li>
|
||||
<li>&aboutI2p.build_scripts;: <a href="&aboutI2p.github;/i2p-browser-build-scripts">&aboutI2p.github;/i2p-browser-build-scripts</a></li>
|
||||
<li>&aboutI2p.i2pbutton_source;: <a href="&aboutI2p.github;/i2pbutton">&aboutI2p.github;/i2pbutton</a></li>
|
||||
<li><em>&aboutI2p.donate;: <a href="&aboutI2p.site;/get-involved/donate">&aboutI2p.supportus;</a></em></li>
|
||||
</ul>
|
||||
</p>
|
||||
|
||||
&aboutI2p.warn_experimental;
|
||||
</p>
|
||||
<p>
|
||||
&aboutI2p.refresh_text; <a href="about:i2p">&aboutI2p.refresh_link;</a>
|
||||
<!--<p class="hideIfI2POn">&aboutI2p.warn_not_running; <a href="about:i2p">&aboutI2p.refresh_text;</a> &aboutI2p.reccommend_not_running;</p>-->
|
||||
<p class="hideIfI2PConsoleOff">&aboutI2p.all_checks_ok;</p>
|
||||
<p class="hideIfI2PConsoleOff">
|
||||
<ul>
|
||||
<li>&aboutI2p.i2ptunnel_visit_msg; <a href="&aboutI2p.routerconsole;/i2ptunnelmgr">&aboutI2p.i2ptunnel;</a></li>
|
||||
<li>&aboutI2p.email_visit_msg; <a href="&aboutI2p.routerconsole;/webmail">&aboutI2p.email;</a></li>
|
||||
<li>&aboutI2p.torrent_visit_msg; <a href="&aboutI2p.routerconsole;/torrents">&aboutI2p.torrent;</a></li>
|
||||
<li>&aboutI2p.console_visit_msg; <a href="&aboutI2p.routerconsole;">&aboutI2p.console;</a></li>
|
||||
</ul>
|
||||
</p>
|
||||
<p class="hideIfI2POn">&aboutI2p.warn_not_running;</p>
|
||||
<p class="hideIfI2POff">&aboutI2p.all_checks_ok;</p>
|
||||
<p class="hideIfI2PConsoleOff">&aboutI2p.console_visit_msg; <a href="http://127.0.0.1:7657">&aboutI2p.console;</a></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -20,9 +20,10 @@ var m_ib_confirming_plugins = false
|
||||
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 checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject;
|
||||
let req = checkSvc.createCheckConsoleRequest(true);
|
||||
req.onreadystatechange = function(event) {
|
||||
if (req.readyState === 4) {
|
||||
@ -47,15 +48,43 @@ function checkI2P(callback,proxyCallback) {
|
||||
|
||||
function i2pbutton_i2p_check_ok()
|
||||
{
|
||||
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
// 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 =
|
||||
{
|
||||
let checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
// 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 =
|
||||
@ -197,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..
|
||||
@ -452,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.
|
||||
@ -1002,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>
|
||||
|
216
src/chrome/content/progress.js
Normal file
216
src/chrome/content/progress.js
Normal file
@ -0,0 +1,216 @@
|
||||
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/Services.jsm")
|
||||
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
|
||||
|
||||
var gObsSvc
|
||||
var gOpenerCallbackFunc // Set when opened from network settings.
|
||||
var gIsInitialBootstrap
|
||||
var gInitialPanelID
|
||||
|
||||
function closeThisWindow(reason) {
|
||||
dump('closeThisWindow\n')
|
||||
window.close()
|
||||
}
|
||||
|
||||
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)
|
||||
|
||||
var isBrowserStartup = false
|
||||
if (window.arguments)
|
||||
{
|
||||
let wargs = window.arguments || window.arguments.wrappedJSObject
|
||||
isBrowserStartup = wargs[0]
|
||||
dump(`window.arguments = ${wargs}\n`)
|
||||
dump(`window.arguments.length = ${wargs.length}\n`)
|
||||
|
||||
if (window.arguments.length > 1)
|
||||
gInitialPanelID = 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")
|
||||
}
|
||||
|
||||
// Test if the i2p console port is open or not
|
||||
|
||||
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
|
||||
LauncherUtil.waitForPortToOpen(consolePort, () => {
|
||||
var meter = document.getElementById("progressMeter")
|
||||
if (meter) {
|
||||
meter.value = meter.value + 30
|
||||
}
|
||||
setTimeout(() => {
|
||||
window.close()
|
||||
}, 5000)
|
||||
})
|
||||
}
|
||||
catch (e) {
|
||||
dump(`Error: ${e}\n`)
|
||||
}
|
||||
dump('initDialog done\n')
|
||||
}
|
||||
|
||||
function onCancel() {
|
||||
//
|
||||
dump('onCancel\n')
|
||||
cleanup()
|
||||
}
|
||||
|
||||
|
||||
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 settings = {};
|
||||
settings["DisableNetwork"] = true;
|
||||
var errObj = {};
|
||||
I2PLauncherLogger.log(5, kErrorPrefix + errObj.details);
|
||||
}
|
||||
catch(e)
|
||||
{
|
||||
I2PLauncherLogger.log(5, kErrorPrefix + e);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
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?
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
|
43
src/chrome/content/progress.xul
Normal file
43
src/chrome/content/progress.xul
Normal file
@ -0,0 +1,43 @@
|
||||
<?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="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>
|
@ -5,21 +5,36 @@
|
||||
|
||||
<!ENTITY aboutI2p.browser_name "The Invisible Internet Browser">
|
||||
<!ENTITY aboutI2p.browser_short_name "I2P Browser">
|
||||
<!ENTITY aboutI2p.browser_description "is preconfigured to search for content on the I2P network. In this release, I2P Browser does not launch its own router and is dependent on having the I2P router pre installed and running. The I2P Browser is preconfigured with default router settings.">
|
||||
<!ENTITY aboutI2p.browser_description "is preconfigured to get your content using the anonymous and private I2P network. In this release, I2P Browser bundles it's own I2P Router, which starts and stops when you open and close the browser application. It does not require an existing I2P router installed.">
|
||||
<!ENTITY aboutI2p.donate "Donate">
|
||||
<!ENTITY aboutI2p.supportus "Support I2P development">
|
||||
|
||||
<!ENTITY aboutI2p.warn_not_running "It currently seems like your router is NOT running :( However, if you just started the router, please try again in two minutes cause it need time to start.">
|
||||
<!ENTITY aboutI2p.warn_not_running "It currently seems like your router is NOT running :(">
|
||||
<!ENTITY aboutI2p.reccommend_not_running "If you just started the router, it may take up to 2 minutes for the router to start the proxy.">
|
||||
<!ENTITY aboutI2p.all_checks_ok "Super! The browser detected I2P running in background! :)">
|
||||
<!ENTITY aboutI2p.warn_experimental "This is a experimental sub-project of I2P.">
|
||||
<!ENTITY aboutI2p.console_visit_msg "It seems like your console is up, click the to visit:">
|
||||
<!ENTITY aboutI2p.warn_experimental "This is a experimental sub-project of I2P. It is currently Beta software.">
|
||||
<!ENTITY aboutI2p.console_visit_msg "It seems like your console is up, click to visit:">
|
||||
<!ENTITY aboutI2p.i2ptunnel_visit_msg "I2P has a web-based interface for configuring .i2p services like web sites, to set up your own web sites, go here:">
|
||||
<!ENTITY aboutI2p.email_visit_msg "I2P also bundles a webmail client which can be used to access in-I2P e-mail. To use it, go here:">
|
||||
<!ENTITY aboutI2p.torrent_visit_msg "I2P is capable of anonymous Peer-to-Peer file sharing, to use the built-in bittorrent client go here:">
|
||||
<!ENTITY aboutI2p.console "Console">
|
||||
<!ENTITY aboutI2p.torrent "Torrents">
|
||||
<!ENTITY aboutI2p.i2ptunnel "Tunnels">
|
||||
<!ENTITY aboutI2p.email "E-Mail">
|
||||
<!ENTITY aboutI2p.i2pbutton_source "I2P Button source">
|
||||
<!ENTITY aboutI2p.build_scripts "Build scripts">
|
||||
<!ENTITY aboutI2p.source "Source">
|
||||
<!ENTITY aboutI2p.bug_tracker "Bugtracker">
|
||||
<!ENTITY aboutI2p.build_scripts "Build scripts to compile from source">
|
||||
<!ENTITY aboutI2p.source "Browse the source code">
|
||||
<!ENTITY aboutI2p.bug_tracker "Submit a Bug Report">
|
||||
<!ENTITY aboutI2p.links "Links">
|
||||
<!ENTITY aboutI2p.refresh_text "Click the link to refresh the page (In case the router is starting up):">
|
||||
<!ENTITY aboutI2p.design "Design Document">
|
||||
<!ENTITY aboutI2p.refresh_text "Try refreshing the page.">
|
||||
<!ENTITY aboutI2p.refresh_link "Refresh">
|
||||
|
||||
<!ENTITY aboutI2p.getInvolved.label "Get Involved »">
|
||||
<!ENTITY aboutI2p.getInvolved.link "https://geti2p.net/en/get-involved">
|
||||
<!ENTITY aboutI2p.site "http://i2p-projekt.i2p/en">
|
||||
<!ENTITY aboutI2p.routerconsole "http://localhost:7647">
|
||||
<!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">
|
||||
|
@ -1,44 +1,53 @@
|
||||
# vim: set sw=2 sts=2 ts=8 et:
|
||||
|
||||
onboarding.tour-i2p-welcome=Welcome
|
||||
onboarding.tour-i2p-welcome.title=You’re ready.
|
||||
onboarding.tour-i2p-welcome.description=I2P Browser offers the highest standard of privacy and security while browsing the web. You’re now protected against tracking, surveillance, and censorship. This quick onboarding will show you how.
|
||||
onboarding.tour-i2p-welcome.title=Welcome to I2P Browser
|
||||
onboarding.tour-i2p-welcome.description=I2P Browser allows you to surf the internet using the private and secure I2P network. When using it, you are protected against tracking, surveillance, and censorship as a first-class participant in the I2P network.
|
||||
# onboarding.tour-i2p-welcome.description-suffix=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser.
|
||||
onboarding.tour-i2p-welcome.next-button=Go to Privacy
|
||||
|
||||
onboarding.tour-i2p-privacy=Privacy
|
||||
onboarding.tour-i2p-privacy.title=Snub trackers and snoopers.
|
||||
onboarding.tour-i2p-privacy.description=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser. Click ‘I2P Network’ to learn how we protect you on the network level.
|
||||
onboarding.tour-i2p-privacy.button=Go to I2P Network
|
||||
onboarding.tour-i2p-privacy.title=Stay in control of your Data
|
||||
onboarding.tour-i2p-privacy.description=I2P Browser isolates cookies and deletes your browser history after your session. These modifications ensure your privacy and security are protected in the browser.
|
||||
onboarding.tour-i2p-privacy.button=Go to Security and Experience
|
||||
|
||||
onboarding.tour-i2p-network=I2P Network
|
||||
# This slide is not currently use in the I2P Browser Onboarding slideshow
|
||||
#onboarding.tour-i2p-network=I2P Network
|
||||
onboarding.tour-i2p-network.title=Travel a decentralized network.
|
||||
onboarding.tour-i2p-network.description=I2P Browser connects you to the I2P network run by thousands of volunteers around the world. Unlike a VPN, there’s no one point of failure or centralized entity you need to trust in order to enjoy the internet privately.
|
||||
onboarding.tour-i2p-network.button=Go to Tunnel Display
|
||||
# End
|
||||
|
||||
# This slide is not currently use in the I2P Browser Onboarding slideshow
|
||||
onboarding.tour-i2p-circuit-display=Tunnel Display
|
||||
onboarding.tour-i2p-circuit-display.title=See your path.
|
||||
onboarding.tour-i2p-circuit-display.description=For each domain you visit, your traffic is relayed and encrypted in a tunnel across three I2P routers around the world. Currently displaying this information is still under development.
|
||||
onboarding.tour-i2p-circuit-display.button=Sorry, come back later.
|
||||
onboarding.tour-i2p-circuit-display.next-button=Go to Security
|
||||
# end
|
||||
|
||||
onboarding.tour-i2p-security=Security
|
||||
onboarding.tour-i2p-security=Security and Experience
|
||||
onboarding.tour-i2p-security.title=Choose your experience.
|
||||
onboarding.tour-i2p-security.description=We also provide you with additional settings for bumping up your browser security. Our Security Settings allow you to block elements that could be used to attack your computer. Click below to see what the different options do.
|
||||
onboarding.tour-i2p-security.description-suffix=Note: By default, NoScript and HTTPS Everywhere are not included on the toolbar, but you can customize your toolbar to add them.
|
||||
onboarding.tour-i2p-security.description=We also provide you with additional settings for bumping up your browser security. Our Security Settings allow you to block elements that could be used to attack your computer. Click below to see what the different options do.\n Note: By default, NoScript and HTTPS Everywhere are not included on the toolbar, but you can customize your toolbar to add them.
|
||||
onboarding.tour-i2p-security.description-suffix=With all the security and privacy features provided by I2P, your experience while browsing the internet may be a little different. Things may be a bit slower, and depending on your security level, some elements may not work or load. You may also be asked to prove you are a human and not a robot.
|
||||
onboarding.tour-i2p-security-level.button=See Your Security Level
|
||||
onboarding.tour-i2p-security-level.next-button=Go to Experience Tips
|
||||
|
||||
onboarding.tour-i2p-expect-differences=Experience Tips
|
||||
onboarding.tour-i2p-expect-differences.title=Expect some differences.
|
||||
onboarding.tour-i2p-expect-differences.description=With all the security and privacy features provided by I2P, your experience while browsing the internet may be a little different. Things may be a bit slower, and depending on your security level, some elements may not work or load. You may also be asked to prove you are a human and not a robot.
|
||||
onboarding.tour-i2p-expect-differences.button=See FAQs
|
||||
onboarding.tour-i2p-expect-differences.next-button=Go to Hidden Services
|
||||
onboarding.tour-i2p-expect-differences.button=Done
|
||||
# onboarding.tour-i2p-expect-differences.button=See FAQs
|
||||
onboarding.tour-i2p-expect-differences.next-button=Done
|
||||
# onboarding.tour-i2p-expect-differences.next-button=Go to Hidden Services
|
||||
|
||||
onboarding.tour-i2p-onion-services=Hidden Services
|
||||
onboarding.tour-i2p-onion-services.title=Be extra protected.
|
||||
onboarding.tour-i2p-onion-services.description=Hidden services are sites that end with a .i2p that provide extra protections to publishers and visitors, including added safeguards against censorship. Onion services allow anyone to provide content and services anonymously.
|
||||
onboarding.tour-i2p-onion-services.button=Visit an Hidden
|
||||
onboarding.tour-i2p-onion-services.next-button=Done
|
||||
# This slide is not currently use in the I2P Browser Onboarding slideshow
|
||||
#onboarding.tour-i2p-onion-services=Hidden Services
|
||||
#onboarding.tour-i2p-onion-services.title=Be extra protected.
|
||||
#onboarding.tour-i2p-onion-services.description=Hidden services are sites that end with a .i2p that provide extra protections to publishers and visitors, including added safeguards against censorship. Onion services allow anyone to provide content and services anonymously.
|
||||
#onboarding.tour-i2p-onion-services.button=Visit an Hidden
|
||||
#onboarding.tour-i2p-onion-services.next-button=Done
|
||||
# End
|
||||
|
||||
onboarding.overlay-icon-tooltip-updated2=See what's new\nin %S
|
||||
onboarding.tour-i2p-update.prefix-new=New
|
||||
|
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">
|
@ -72,3 +72,6 @@ body:not([i2pconsoleon]) .hideIfI2PConsoleOff {
|
||||
display: none;
|
||||
}
|
||||
|
||||
ul {
|
||||
margin-left: 2rem;
|
||||
}
|
||||
|
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 |
@ -12,8 +12,8 @@ function IBI2PCheckService() {
|
||||
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
this._logger.info("I2pbutton I2P Check Service initialized")
|
||||
|
||||
this._statusOfI2PCheck = this.kCheckNotInitiated;
|
||||
this.wrappedJSObject = this;
|
||||
this._statusOfI2PCheck = this.kCheckNotInitiated
|
||||
this.wrappedJSObject = this
|
||||
}
|
||||
|
||||
IBI2PCheckService.prototype =
|
||||
@ -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,42 +73,48 @@ 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)
|
||||
},
|
||||
|
||||
_createRequest: function(url, aAsync, mimetype) {
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"]);
|
||||
let req = new XMLHttpRequest();
|
||||
req.open('GET', url, aAsync);
|
||||
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE;
|
||||
req.overrideMimeType(mimetype);
|
||||
req.timeout = 120000; // Wait at most two minutes for a response.
|
||||
return req;
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"])
|
||||
let req = new XMLHttpRequest()
|
||||
req.open('GET', url, aAsync)
|
||||
req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE
|
||||
req.overrideMimeType(mimetype)
|
||||
req.timeout = 120000 // Wait at most two minutes for a response.
|
||||
return req
|
||||
},
|
||||
|
||||
createCheckConsoleRequest: function(aAsync)
|
||||
{
|
||||
let url = 'http://localhost:7657/netdb?r=.';
|
||||
return this._createRequest(url, aAsync, "text/html");
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
|
||||
let port = prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
|
||||
let url = `http://localhost:${port}/netdb?r=.`
|
||||
return this._createRequest(url, aAsync, "text/html")
|
||||
},
|
||||
|
||||
createCheckProxyRequest: function(aAsync) {
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch);
|
||||
let url = prefs.getCharPref("extensions.i2pbutton.test_url");
|
||||
return this._createRequest(url, aAsync, "application/json");
|
||||
let prefs = Cc["@mozilla.org/preferences-service;1"].getService(Ci.nsIPrefBranch)
|
||||
let url = prefs.getCharPref("extensions.i2pbutton.test_url")
|
||||
return this._createRequest(url, aAsync, "application/json")
|
||||
},
|
||||
|
||||
parseCheckConsoleResponse: function(aReq)
|
||||
@ -181,5 +189,5 @@ IBI2PCheckService.prototype =
|
||||
}
|
||||
};
|
||||
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([IBI2PCheckService]);
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
var NSGetFactory = XPCOMUtils.generateNSGetFactory([IBI2PCheckService])
|
||||
|
@ -8,15 +8,33 @@ 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")
|
||||
//XPCOMUtils.defineLazyModuleGetter(this, "I2PLauncherLogger", "resource://i2pbutton/modules/tl-logger.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
|
||||
this._config_checker = Cc["@geti2p.net/i2pbutton-router-config-mgr;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
this._logger.log(3, "I2pbutton I2P Router Process Service initialized")
|
||||
this.wrappedJSObject = this
|
||||
}
|
||||
@ -34,7 +52,7 @@ I2PProcessService.prototype =
|
||||
|
||||
kInitialControlConnDelayMS: 25,
|
||||
kMaxControlConnRetryMS: 2000, // Retry at least every 2 seconds.
|
||||
kControlConnTimeoutMS: 5*60*1000, // Wait at most 5 minutes for tor to start.
|
||||
kControlConnTimeoutMS: 5*60*1000, // Wait at most 5 minutes for i2p to start.
|
||||
|
||||
kStatusUnknown: 0, // I2P process status.
|
||||
kStatusStarting: 1,
|
||||
@ -94,16 +112,49 @@ I2PProcessService.prototype =
|
||||
|
||||
|
||||
const self = this
|
||||
this._logger.log(3, 'Checking if a console is already up (an router already running)s')
|
||||
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)
|
||||
|
||||
let canStartPromise = self._config_checker.ensure_config()
|
||||
canStartPromise.then(() => {
|
||||
self._logger.log(3, 'Starting the router')
|
||||
self.I2PStartAndControlI2P(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}`)
|
||||
}
|
||||
|
||||
// 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
|
||||
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)
|
||||
{
|
||||
@ -116,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))
|
||||
@ -132,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
|
||||
{
|
||||
@ -144,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..')
|
||||
@ -164,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
|
||||
}
|
||||
},
|
||||
|
||||
@ -224,6 +275,46 @@ 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",
|
||||
[true])
|
||||
this._logger.log(3, 'After open wait for router dialog')
|
||||
|
||||
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()
|
||||
@ -253,8 +344,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;
|
||||
@ -267,14 +372,14 @@ 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)
|
||||
this._logger.log(3, `Datadir: ${dataDir.path} ,,, ExeFile: ${exeFile.path}`)
|
||||
let exeFile = LauncherUtil.getI2PBinary()
|
||||
this._logger.log(3, `Datadir => ${dataDir.path}\nExeFile => ${exeFile.path}`)
|
||||
|
||||
var detailsKey;
|
||||
if (!exeFile)
|
||||
@ -291,13 +396,13 @@ 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)
|
||||
env.set('I2P_BROWSER_I2P_DATA_DIR', dataDir.path)
|
||||
|
||||
// On Windows, prepend the I2P program directory to PATH. This is
|
||||
// needed so that pluggable transports can find OpenSSL DLLs, etc.
|
||||
@ -314,12 +419,16 @@ I2PProcessService.prototype =
|
||||
|
||||
this._logger.log(3, `Trying to start with ${args}`)
|
||||
|
||||
this._logger.log(2, "Starting " + exeFile.path)
|
||||
var p = Cc["@mozilla.org/process/util;1"].createInstance(Ci.nsIProcess)
|
||||
p.init(exeFile)
|
||||
|
||||
this._logger.log(2, "Starting " + exeFile.path)
|
||||
for (var i = 0; i < args.length; ++i)
|
||||
this._logger.log(2, " " + args[i])
|
||||
this._logger.log(2, ` ${args[i]}`)
|
||||
|
||||
// Possible fix for Windows and cmd.exe window spawn.
|
||||
p.startHidden = true
|
||||
p.noShell = true
|
||||
|
||||
p.runwAsync(args, args.length, this, false)
|
||||
this.mI2PProcess = p
|
||||
@ -327,44 +436,92 @@ I2PProcessService.prototype =
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
this.mI2PProcessStatus = this.kStatusExited;
|
||||
this.mI2PProcessStatus = this.kStatusExited
|
||||
//var s = LauncherUtil.getLocalizedString("i2p_failed_to_start");
|
||||
//this._notifyUserOfError(s, null, this.kI2PProcessDidNotStartTopic);
|
||||
this._logger.log(4, "_startI2P error: ", e);
|
||||
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 checkSvc = Cc["@geti2p.net/i2pbutton-i2pCheckService;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
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()
|
||||
|
||||
@ -377,8 +534,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)
|
||||
@ -396,25 +553,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)
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -1,26 +1,19 @@
|
||||
// Bug 1506 P1: This is just a handy logger. If you have a better one, toss
|
||||
// this in the trash.
|
||||
|
||||
/*************************************************************************
|
||||
* TBLogger (JavaScript XPCOM component)
|
||||
*
|
||||
* Allows loglevel-based logging to different logging mechanisms.
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
// TODO: Slowly migrate to firefox's Log module "resource://gre/modules/Log.jsm"
|
||||
// Module specific constants
|
||||
const kMODULE_NAME = "I2pbutton Logger";
|
||||
const kMODULE_CONTRACTID = "@geti2p.net/i2pbutton-logger;1";
|
||||
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7");
|
||||
const kMODULE_NAME = "I2pbutton Logger"
|
||||
const kMODULE_CONTRACTID = "@geti2p.net/i2pbutton-logger;1"
|
||||
const kMODULE_CID = Components.ID("f36d72c9-9718-4134-b550-e109638331d7")
|
||||
|
||||
const Cr = Components.results;
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cu = Components.utils;
|
||||
const Cr = Components.results
|
||||
const Cc = Components.classes
|
||||
const Ci = Components.interfaces
|
||||
const Cu = Components.utils
|
||||
|
||||
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
|
||||
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import("resource://gre/modules/Log.jsm")
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
let console = (Cu.import("resource://gre/modules/Console.jsm", {})).console
|
||||
|
||||
function I2pbuttonLogger() {
|
||||
// Register observer
|
||||
@ -115,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) },
|
||||
@ -157,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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -16,18 +16,25 @@ const nsFile = Components.Constructor(
|
||||
"initWithPath"
|
||||
)
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
|
||||
//XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
|
||||
Cu.import("resource://i2pbutton/modules/launcher-util.jsm")
|
||||
//ChromeUtils.defineModuleGetter(this, "ZipUtils", "resource://gre/modules/ZipUtils.jsm")
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import('resource://gre/modules/osfile.jsm')
|
||||
Cu.import('resource://gre/modules/FileUtils.jsm')
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "LauncherUtil", "resource://i2pbutton/modules/launcher-util.jsm")
|
||||
|
||||
let consolePort = Services.prefs.getIntPref("extensions.i2pbutton.console_port_i2pj", 7647)
|
||||
let httpProxyPort = Services.prefs.getIntPref("network.proxy.http_port", 7644)
|
||||
|
||||
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
|
||||
tunnel.0.listenPort=4444
|
||||
tunnel.0.listenPort=${httpProxyPort}
|
||||
tunnel.0.name=I2P HTTP Proxy
|
||||
tunnel.0.option.i2cp.closeIdleTime=1800000
|
||||
tunnel.0.option.i2cp.closeOnIdle=false
|
||||
@ -67,7 +74,7 @@ tunnel.0.type=httpclient
|
||||
`
|
||||
|
||||
const defaultClientsConfig = `# Autogenerated by I2P Browser
|
||||
clientApp.0.args=7657 ::1,127.0.0.1 ./webapps/
|
||||
clientApp.0.args=${consolePort} ::1,127.0.0.1 ./webapps/
|
||||
clientApp.0.main=net.i2p.router.web.RouterConsoleRunner
|
||||
clientApp.0.name=I2P Router Console
|
||||
clientApp.0.onBoot=true
|
||||
@ -124,12 +131,17 @@ 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
|
||||
`
|
||||
|
||||
let noscript = Cu.import("resource://i2pbutton/modules/noscript-control.js")
|
||||
noscript.initialize()
|
||||
|
||||
function RouterConfigManager() {
|
||||
this.version = '0.1'
|
||||
this.routerCertsZipFile = LauncherUtil.getI2PFile("certszip", false)
|
||||
this._logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
this._logger.log(3, "I2pbutton I2P RouterConfigManager Service initialized")
|
||||
this.wrappedJSObject = this
|
||||
@ -145,56 +157,202 @@ RouterConfigManager.prototype = {
|
||||
_logger: null,
|
||||
state: {},
|
||||
|
||||
// State
|
||||
mDoesRouterConfigExists: false,
|
||||
mDoesClientsConfigExists: false,
|
||||
mDoesTunnelConfigExists: false,
|
||||
mDoesWebappsConfigExists: false,
|
||||
mHasChecksStarted: false,
|
||||
mIsChecksDone: false,
|
||||
|
||||
|
||||
// nsISupports implementation.
|
||||
QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsISupports]),
|
||||
|
||||
|
||||
|
||||
_write_router_config: function(configfile,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}`)
|
||||
})
|
||||
},
|
||||
_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}`)
|
||||
})
|
||||
},
|
||||
_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}`)
|
||||
})
|
||||
canRouterStart: function() {
|
||||
return (this.mDoesRouterConfigExists && this.mDoesClientsConfigExists && this.mDoesTunnelConfigExists)
|
||||
},
|
||||
|
||||
|
||||
ensure_config: function(onCompleteCallback) {
|
||||
_write_config: function(configfile, content, onComplete) {
|
||||
const self = this
|
||||
LauncherUtil.writeFileWithData(configfile, content, file => { onComplete(file) }, (err) => {
|
||||
this._logger.log(6,`Can't write config file :( - path was ${configfile.path}, error: ${err}`)
|
||||
})
|
||||
},
|
||||
|
||||
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)
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
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}`)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
ensure_config: async function(onCompleteCallback) {
|
||||
this.mHasChecksStarted = true
|
||||
|
||||
let configDirectory = LauncherUtil.getI2PConfigPath(true)
|
||||
let routerConfigFile = configDirectory.clone()
|
||||
routerConfigFile.append('router.config')
|
||||
let tunnelConfigFIle = configDirectory.clone()
|
||||
tunnelConfigFIle.append('i2ptunnel.config')
|
||||
let clientsConfigFIle = configDirectory.clone()
|
||||
clientsConfigFIle.append('clients.config')
|
||||
let tunnelConfigFile = configDirectory.clone()
|
||||
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`)
|
||||
}
|
||||
|
||||
// Temporary jetty fix
|
||||
let orgDir = configDirectory.clone()
|
||||
orgDir.append('org')
|
||||
if (!orgDir.exists()) {
|
||||
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
|
||||
orgDir.append('eclipse')
|
||||
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
|
||||
orgDir.append('jetty')
|
||||
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
|
||||
orgDir.append('webapp')
|
||||
orgDir.create(orgDir.DIRECTORY_TYPE, 0o700)
|
||||
let distJettyFile = LauncherUtil.getI2PBinary().parent.parent
|
||||
distJettyFile.append('org')
|
||||
distJettyFile.append('eclipse')
|
||||
distJettyFile.append('jetty')
|
||||
distJettyFile.append('webapp')
|
||||
distJettyFile.append('webdefault.xml')
|
||||
distJettyFile.copyTo(orgDir, '')
|
||||
}
|
||||
|
||||
// Ensure they exists
|
||||
if (!routerConfigFile.exists) {
|
||||
this._write_router_config(routerConfigFile, file => {
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(file)
|
||||
const self = this
|
||||
|
||||
this.ensureRouterConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!routerConfigFile.exists()) {
|
||||
self._write_config(routerConfigFile, defaultRouterConfig, file => {
|
||||
self.mDoesRouterConfigExists = true
|
||||
self._logger.log(3, 'Wrote router.config')
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(file)
|
||||
resolve(routerConfigFile)
|
||||
})
|
||||
} else {
|
||||
self._logger.log(3, 'Found router.config from earlier')
|
||||
self.mDoesRouterConfigExists = true
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!tunnelConfigFIle.exits) {
|
||||
this._write_tunnel_config(tunnelConfigFIle, tfile => {
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
|
||||
this.ensureTunnelConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!tunnelConfigFile.exists()) {
|
||||
self._write_config(tunnelConfigFile, defaultProxyTunnels, tfile => {
|
||||
self._logger.log(3, 'Wrote i2ptunnel.config')
|
||||
self.mDoesTunnelConfigExists = true
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
resolve(tunnelConfigFile)
|
||||
})
|
||||
} else {
|
||||
self._logger.log(3, 'Found i2ptunnel.config from earlier')
|
||||
self.mDoesTunnelConfigExists = true
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
if (!clientsConfigFIle.exits) {
|
||||
this._write_tunnel_config(tunnelConfigFIle, tfile => {
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
|
||||
this.ensureClientsConfigPromise = () => {
|
||||
return new Promise(resolve => {
|
||||
if (!clientsConfigFile.exists()) {
|
||||
self._write_config(clientsConfigFile, defaultClientsConfig, tfile => {
|
||||
self._logger.log(3, 'Wrote clients.config')
|
||||
self.mDoesClientsConfigExists = true
|
||||
if (typeof onCompleteCallback === 'function') onCompleteCallback(tfile)
|
||||
resolve(clientsConfigFile)
|
||||
})
|
||||
} else {
|
||||
self._logger.log(3, 'Found clients.config from earlier')
|
||||
self.mDoesClientsConfigExists = true
|
||||
resolve(null)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
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(),
|
||||
])
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -8,34 +8,34 @@
|
||||
*
|
||||
*************************************************************************/
|
||||
|
||||
const Cc = Components.classes;
|
||||
const Ci = Components.interfaces;
|
||||
const Cr = Components.results;
|
||||
const Cu = Components.utils;
|
||||
const Cc = Components.classes
|
||||
const Ci = Components.interfaces
|
||||
const Cr = Components.results
|
||||
const Cu = Components.utils
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm");
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "FileUtils", "resource://gre/modules/FileUtils.jsm")
|
||||
|
||||
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs();
|
||||
//let NoScriptControl = Cu.import("resource://torbutton/modules/noscript-control.js", {});
|
||||
Cu.import("resource://i2pbutton/modules/default-prefs.js", {}).ensureDefaultPrefs()
|
||||
let NoScriptControl = Cu.import("resource://i2pbutton/modules/noscript-control.js", {})
|
||||
|
||||
// Module specific constants
|
||||
const kMODULE_NAME = "Startup";
|
||||
const kMODULE_CONTRACTID = "@geti2p.net/startup-observer;1";
|
||||
const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629");
|
||||
const kMODULE_NAME = "Startup"
|
||||
const kMODULE_CONTRACTID = "@geti2p.net/startup-observer;1"
|
||||
const kMODULE_CID = Components.ID("06322def-6fde-4c06-aef6-47ae8e799629")
|
||||
|
||||
function StartupObserver() {
|
||||
this.logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject;
|
||||
this._prefs = Services.prefs;
|
||||
this.logger.log(3, "Startup Observer created");
|
||||
this.logger = Cc["@geti2p.net/i2pbutton-logger;1"].getService(Ci.nsISupports).wrappedJSObject
|
||||
this._prefs = Services.prefs
|
||||
this.logger.log(3, "Startup Observer created")
|
||||
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment);
|
||||
var prefName = "browser.startup.homepage";
|
||||
var env = Cc["@mozilla.org/process/environment;1"].getService(Ci.nsIEnvironment)
|
||||
var prefName = "browser.startup.homepage"
|
||||
if (env.exists("I2P_DEFAULT_HOMEPAGE")) {
|
||||
// if the user has set this value in a previous installation, don't override it
|
||||
if (!this._prefs.prefHasUserValue(prefName)) {
|
||||
this._prefs.setCharPref(prefName, env.get("I2P_DEFAULT_HOMEPAGE"));
|
||||
this._prefs.setCharPref(prefName, env.get("I2P_DEFAULT_HOMEPAGE"))
|
||||
}
|
||||
}
|
||||
|
||||
@ -48,20 +48,16 @@ function StartupObserver() {
|
||||
}
|
||||
|
||||
try {
|
||||
// XXX: We're in a race with HTTPS-Everywhere to update our proxy settings
|
||||
// before the initial SSL-Observatory test... If we lose the race, Firefox
|
||||
// caches the old proxy settings for check.tp.o somehwere, and it never loads :(
|
||||
this.setProxySettings();
|
||||
} catch(e) {
|
||||
this.logger.log(4, "Early proxy change failed. Will try again at profile load. Error: "+e);
|
||||
}
|
||||
|
||||
// Arrange for our about:tor handler to be loaded in the default (chrome)
|
||||
// Arrange for our about:i2p handler to be loaded in the default (chrome)
|
||||
// process as well as in each content process.
|
||||
let ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
|
||||
.getService(Ci.nsIProcessScriptLoader);
|
||||
ppmm.loadProcessScript("resource://i2pbutton/components/aboutI2p.js",
|
||||
true);
|
||||
ppmm.loadProcessScript("resource://i2pbutton/components/aboutI2p.js", true)
|
||||
}
|
||||
|
||||
StartupObserver.prototype = {
|
||||
@ -77,12 +73,13 @@ StartupObserver.prototype = {
|
||||
this._prefs.setIntPref("network.proxy.type", 1);
|
||||
this._prefs.setIntPref("network.proxy.socks_port", 0);
|
||||
this._prefs.setCharPref("network.proxy.socks", "");
|
||||
this._prefs.setIntPref("extensions.i2pbutton.console_port_i2pj", 7647);
|
||||
this._prefs.setCharPref("network.proxy.http", "127.0.0.1");
|
||||
this._prefs.setIntPref("network.proxy.http_port", 4444);
|
||||
this._prefs.setIntPref("network.proxy.http_port", 7644);
|
||||
this._prefs.setCharPref("network.proxy.ssl", "127.0.0.1");
|
||||
this._prefs.setIntPref("network.proxy.ssl_port", 4445);
|
||||
this._prefs.setIntPref("network.proxy.ssl_port", 7644);
|
||||
this._prefs.setCharPref("network.proxy.ftp", "127.0.0.1");
|
||||
this._prefs.setIntPref("network.proxy.ftp_port", 4444);
|
||||
this._prefs.setIntPref("network.proxy.ftp_port", 7644);
|
||||
this._prefs.setCharPref("network.proxy.no_proxies_on", "localhost, 127.0.0.1");
|
||||
|
||||
// Force prefs to be synced to disk
|
||||
@ -97,8 +94,8 @@ StartupObserver.prototype = {
|
||||
// but only for hackish reasons.
|
||||
this._prefs.setBoolPref("extensions.i2pbutton.startup", true);
|
||||
|
||||
// We need to listen for NoScript before it starts.
|
||||
//NoScriptControl.initialize();
|
||||
// We need to listen for NoScript before it starts.
|
||||
NoScriptControl.initialize();
|
||||
|
||||
this.setProxySettings();
|
||||
}
|
||||
|
@ -16,6 +16,10 @@ pref("extensions.i2pbutton.local_i2p_check",true);
|
||||
// https://developer.mozilla.org/en/Addons/Working_with_AMO
|
||||
pref("extensions.i2pbutton@geti2p.net.getAddons.cache.enabled", false);
|
||||
|
||||
// I2P router control prefs:
|
||||
pref("extensions.i2pbutton.start_i2p", true);
|
||||
pref("extensions.i2pbutton.kill_router_on_exit", true);
|
||||
|
||||
// State prefs:
|
||||
pref("extensions.i2pbutton.startup",false);
|
||||
pref("extensions.i2pbutton.inserted_button",false);
|
||||
@ -27,9 +31,9 @@ pref("extensions.i2pbutton.cookie_auto_protect",false);
|
||||
pref("extensions.i2pbutton.clear_http_auth",true);
|
||||
pref("extensions.i2pbutton.close_newnym",true);
|
||||
pref("extensions.i2pbutton.resize_new_windows",true);
|
||||
pref("extensions.i2pbutton.startup_state", 2); // 0=non-tor, 1=tor, 2=last
|
||||
pref("extensions.i2pbutton.startup_state", 2); // 0=non-i2p, 1=i2p, 2=last
|
||||
pref("extensions.i2pbutton.i2p_memory_jar",false);
|
||||
pref("extensions.i2pbutton.nontor_memory_jar",false);
|
||||
pref("extensions.i2pbutton.noni2p_memory_jar",false);
|
||||
pref("extensions.i2pbutton.launch_warning",true);
|
||||
|
||||
// Security Slider
|
||||
@ -52,20 +56,9 @@ pref("browser.startup.homepage", "chrome://i2pbutton/content/locale/non-localize
|
||||
pref("extensions.i2pbutton.start_i2p", true);
|
||||
pref("extensions.i2pbutton.kill_router_on_exit", true);
|
||||
pref("extensions.i2pbutton.console_host", "127.0.0.1");
|
||||
pref("extensions.i2pbutton.console_port_i2pj", 7657);
|
||||
pref("extensions.i2pbutton.console_port_i2pd", 7070);
|
||||
pref("extensions.i2pbutton.console_port_i2pj", 7647);
|
||||
pref("extensions.i2pbutton.console_port_i2pd", 17070);
|
||||
|
||||
// I2P Implementation
|
||||
pref("extensions.i2pbutton.i2pimpl_driver", "i2pj");
|
||||
|
||||
// The i2p_path is relative to the application directory. On Linux and
|
||||
// Windows this is the Browser/ directory that contains the firefox
|
||||
// executables, and on Mac OS it is the I2PBrowser.app directory.
|
||||
pref("extensions.i2pbutton.i2p_path", "");
|
||||
|
||||
// The i2pdatadir_path are relative to the data directory,
|
||||
// which is I2PBrowser-Data/ if it exists as a sibling of the application
|
||||
// directory. If I2PBrowser-Data/ does not exist, these paths are relative
|
||||
// to the I2PBrowser/ directory within the application directory.
|
||||
pref("extensions.i2pbutton.i2pdatadir_path", "");
|
||||
|
||||
|
@ -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.0</em:version>
|
||||
<em:version>0.3.8</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>
|
||||
|
93
src/modules/jsonrpc-client.jsm
Normal file
93
src/modules/jsonrpc-client.jsm
Normal file
@ -0,0 +1,93 @@
|
||||
const EXPORTED_SYMBOLS = ['JsonPrcClient']
|
||||
// vim: set sw=2 sts=2 ts=8 et syntax=javascript:
|
||||
|
||||
const Cc = Components.classes
|
||||
const Ci = Components.interfaces
|
||||
const Cr = Components.results
|
||||
const Cu = Components.utils
|
||||
|
||||
Cu.import("resource://gre/modules/Services.jsm")
|
||||
Cu.import("resource://gre/modules/XPCOMUtils.jsm")
|
||||
Cu.import("resource://gre/modules/Log.jsm")
|
||||
Cu.import("resource://i2pbutton/modules/http.jsm")
|
||||
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"])
|
||||
|
||||
var log = Log.repository.getLogger("i2pbutton.jsonrpc-client")
|
||||
log.level = Log.Level.Debug
|
||||
// A console appender logs to the browser console.
|
||||
log.addAppender(new Log.ConsoleAppender(new Log.BasicFormatter()))
|
||||
|
||||
class JsonRpcClient {
|
||||
constructor(url) {
|
||||
this.serverUrl = url
|
||||
this.mReqIdSequence = 0
|
||||
this.responses = new Array()
|
||||
this.token = ''
|
||||
}
|
||||
|
||||
_createTemplateData(method, params, id) {
|
||||
this.mReqIdSequence++
|
||||
return JSON.stringify({
|
||||
'id': id || this.mReqIdSequence,
|
||||
'method': method,
|
||||
'params': params || {},
|
||||
'jsonrpc': '2.0'
|
||||
})
|
||||
}
|
||||
|
||||
_onload(method, callback) {
|
||||
const self = this
|
||||
return () => {
|
||||
console.log('done', method)
|
||||
switch (method) {
|
||||
case 'Authenticate':
|
||||
let jData = JSON.parse(self.xhr.response)
|
||||
let token = jData.result.Token
|
||||
self.token = token
|
||||
break
|
||||
case 'RouterManager':
|
||||
break
|
||||
default:
|
||||
console.log('Unknown method')
|
||||
}
|
||||
if('function' === typeof callback) {
|
||||
callback(self.xhr)
|
||||
}
|
||||
self.responses.push(self.xhr.response)
|
||||
console.log(self.xhr.responseText)
|
||||
}
|
||||
}
|
||||
|
||||
makeRequest(method, params, callback) {
|
||||
this.xhr = new XMLHttpRequest()
|
||||
this.xhr.open('POST', this.serverUrl)
|
||||
let data = this._createTemplateData(method, params)
|
||||
this.xhr.onload = this._onload(method, callback)
|
||||
this.xhr.setRequestHeader('Content-Length', `${data.length}`)
|
||||
this.xhr.setRequestHeader('Content-Type', 'application/json')
|
||||
this.xhr.send(data)
|
||||
}
|
||||
}
|
||||
|
||||
class I2PControlClient extends JsonRpcClient {
|
||||
constructor() {
|
||||
super('http://127.0.0.1:7647/jsonrpc/')
|
||||
}
|
||||
|
||||
authenticate(password, callback) {
|
||||
this.makeRequest('Authenticate', {'API':1, 'Password':password}, callback)
|
||||
}
|
||||
|
||||
shutdownRouter(callback) {
|
||||
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Shutdown': true}, callback)
|
||||
}
|
||||
|
||||
reseedRouter(callback) {
|
||||
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Reseed': true}, callback)
|
||||
}
|
||||
|
||||
restartRouter(callback) {
|
||||
this.makeRequest('RouterManager', {'API':1,'Token':this.token, 'Restart': true}, callback)
|
||||
}
|
||||
}
|
@ -5,6 +5,8 @@ const Ci = Components.interfaces
|
||||
const Cu = Components.utils
|
||||
const Cr = Components.results
|
||||
|
||||
Cu.importGlobalProperties(["XMLHttpRequest"])
|
||||
|
||||
const kPropBundleURI = "chrome://i2pbutton/locale/i2pbutton.properties"
|
||||
const kPropNamePrefix = "i2pbutton."
|
||||
|
||||
@ -19,6 +21,38 @@ let logger = {
|
||||
}
|
||||
}
|
||||
|
||||
const Timer = Components.Constructor("@mozilla.org/timer;1", "nsITimer", "initWithCallback");
|
||||
|
||||
function delay(timeout, func) {
|
||||
let timer = new Timer(function () {
|
||||
// Remove the reference so that it can be reaped.
|
||||
delete delay.timers[idx];
|
||||
|
||||
func();
|
||||
}, timeout, Ci.nsITimer.TYPE_ONE_SHOT);
|
||||
|
||||
// Store a reference to the timer so that it's not reaped before it fires.
|
||||
let idx = delay.timers.push(timer) - 1;
|
||||
return idx
|
||||
}
|
||||
delay.timers = []
|
||||
|
||||
function repeat(timeout, func) {
|
||||
let timer = new Timer(function () {
|
||||
func();
|
||||
}, timeout, Ci.nsITimer.TYPE_REPEATING_SLACK);
|
||||
|
||||
// Store a reference to the timer so that it's not reaped before it fires.
|
||||
let idx = delay.timers.push(timer) - 1;
|
||||
return idx
|
||||
}
|
||||
repeat.timers = []
|
||||
|
||||
// Wrapper since window.setTimeout isn't always available in context/scope.
|
||||
function setTimeout(func, interval) {
|
||||
delay(interval, func)
|
||||
}
|
||||
|
||||
|
||||
const LauncherUtil = {
|
||||
get isMac()
|
||||
@ -49,7 +83,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;
|
||||
}
|
||||
|
||||
@ -83,34 +117,40 @@ const LauncherUtil = {
|
||||
return argsArray;
|
||||
},
|
||||
|
||||
setTimeout: (func, interval) => {
|
||||
delay(interval, func)
|
||||
},
|
||||
setInterval: (func, interval) => {
|
||||
repeat(interval, func)
|
||||
},
|
||||
|
||||
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 +187,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);
|
||||
@ -164,29 +204,65 @@ const LauncherUtil = {
|
||||
asSvc.quit(0x12) // eAttemptQuit (0x02) + eRestart (0x10)
|
||||
},
|
||||
|
||||
|
||||
|
||||
waitForPortToOpen: function(portNum, doneCallback, interval) {
|
||||
interval = interval || 3000
|
||||
let portOpen = false
|
||||
let testPort = () => {
|
||||
var xhr = new XMLHttpRequest()
|
||||
xhr.open('GET', `http://127.0.0.1:${portNum}`)
|
||||
xhr.onerror = () => {
|
||||
console.log(`Still waiting for ${portNum} to open`)
|
||||
if (!portOpen) {
|
||||
setTimeout(testPort, interval)
|
||||
}
|
||||
}
|
||||
xhr.onload = () => {
|
||||
console.log(`Port ${portNum} seem open now finally`)
|
||||
portOpen = true
|
||||
if ('function' === typeof doneCallback) {
|
||||
doneCallback(portNum)
|
||||
}
|
||||
}
|
||||
xhr.send()
|
||||
}
|
||||
testPort()
|
||||
},
|
||||
//waitForPortToOpen(7647, () => { console.log('ALL DONE') })
|
||||
|
||||
getRouterDefaultArgs: function() {
|
||||
let dataDir = this.getI2PConfigPath(true)
|
||||
let exeFile = this.getI2PBinary()
|
||||
let libDir = exeFile.parent.parent.clone()
|
||||
let i2pDir = libDir.clone()
|
||||
let libDir = dataDir.clone()
|
||||
let i2pDir = exeFile.parent.parent.clone()
|
||||
libDir.append('lib')
|
||||
let args = []
|
||||
let logFile = dataDir.clone()
|
||||
logFile.append('wrapper.log')
|
||||
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}`)
|
||||
logger.log(2, `Path for base is => ${i2pDir.path}`)
|
||||
args.push(`-Duser.dir=${dataDir.path}`) // make PWD equal dataDir
|
||||
args.push(`-Dwrapper.logfile=${dataDir.path}/wrapper.log`)
|
||||
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=${dataDir.path}/clients.config`)
|
||||
args.push(`-Drouter.configLocation=${dataDir.path}/router.config`)
|
||||
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}/lib`)
|
||||
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
|
||||
@ -235,83 +311,68 @@ const LauncherUtil = {
|
||||
},
|
||||
|
||||
getI2PPath: (aI2PFileType, aCreate) => {
|
||||
return this.getI2PFile(aI2PFileType, aCreate)
|
||||
return this.getI2PFile(aI2PFileType, aCreate).clone()
|
||||
},
|
||||
|
||||
getI2PConfigPath: (create) => {
|
||||
// Going backwards from profile works on all OS.
|
||||
let profDir = Services.dirsvc.get("ProfD", Ci.nsIFile)
|
||||
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.clone()
|
||||
|
||||
return dataDir
|
||||
},
|
||||
|
||||
getI2PFile: function(aI2PFileType, aCreate) {
|
||||
if (!aI2PFileType) {
|
||||
return false
|
||||
aI2PFileType = 'i2p'
|
||||
}
|
||||
let i2pFile
|
||||
let path = ''
|
||||
let useAppDir = false
|
||||
let isRelativePath = true
|
||||
let isUserData = (aI2PFileType != 'i2p')
|
||||
let isUserData = false
|
||||
let appBaseDir = this.appDirectoryObject.clone()
|
||||
|
||||
logger.log(2, `appBaseDir => ${appBaseDir.path}`)
|
||||
|
||||
if (this.isWindows) {
|
||||
//
|
||||
if ("i2p" == aI2PFileType) {
|
||||
path = "I2PBrowser\\I2P\\bin\\java"
|
||||
useAppDir = true
|
||||
} else if ("i2pdatadir" == aI2PFileType) {
|
||||
path = "I2P"
|
||||
} else if ("certszip" == aI2PFileType) {
|
||||
path = "I2PBrowser\\I2P\\certs.zip"
|
||||
appBaseDir.append('I2P')
|
||||
appBaseDir.append('bin')
|
||||
appBaseDir.append('java.exe')
|
||||
return appBaseDir
|
||||
}
|
||||
} else if (this.isMac) {
|
||||
//
|
||||
if ("i2p" == aI2PFileType) {
|
||||
path = "Contents/Resources/I2PBrowser/I2P/bin/java"
|
||||
} else if ("i2pdatadir" == aI2PFileType) {
|
||||
path = "I2P"
|
||||
} else if ("certszip" == aI2PFileType) {
|
||||
path = "Contents/Resources/I2PBrowser/I2P/certs.zip"
|
||||
}
|
||||
} else {
|
||||
if ("i2p" == aI2PFileType) {
|
||||
path = "I2PBrowser/I2P/bin/java"
|
||||
} else if ("i2pdatadir" == aI2PFileType) {
|
||||
path = "I2P"
|
||||
} else if ("certszip" == aI2PFileType) {
|
||||
path = "I2PBrowser/I2P/certs.zip"
|
||||
appBaseDir.append('I2P')
|
||||
appBaseDir.append('bin')
|
||||
appBaseDir.append('java')
|
||||
return appBaseDir
|
||||
}
|
||||
}
|
||||
|
||||
logger.log(2, `getI2PFile - Gonna try path ${path}`)
|
||||
try {
|
||||
if (path == '' && !useAppDir) {
|
||||
throw Error('Fatal error: Can\'t resolve directories!')
|
||||
}
|
||||
if (useAppDir)
|
||||
{
|
||||
i2pFile = LauncherUtilInternal._appDir.clone()
|
||||
}
|
||||
|
||||
// Turn 'path' into an absolute path.
|
||||
if (LauncherUtilInternal._isUserDataOutsideOfAppDir)
|
||||
{
|
||||
let baseDir = isUserData ? LauncherUtilInternal._dataDir : LauncherUtilInternal._appDir
|
||||
i2pFile = baseDir.clone()
|
||||
} else {
|
||||
i2pFile = LauncherUtilInternal._appDir.clone()
|
||||
i2pFile.append("I2PBrowser")
|
||||
i2pFile = LauncherUtilInternal._appDir.clone()
|
||||
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)
|
||||
|
||||
if (!i2pFile.exists() && aCreate === true) {
|
||||
logger.log(3, `Requested datadir ${i2pFile.path}, but it wasn't created so we create it now.`)
|
||||
i2pFile.create(i2pFile.DIRECTORY_TYPE, 0o700)
|
||||
}
|
||||
logger.log(2, `getI2PFile - Gonna try path ${i2pFile.path}`)
|
||||
|
||||
if (i2pFile.exists()) {
|
||||
try { i2pFile.normalize() } catch(e) {}
|
||||
@ -319,7 +380,7 @@ const LauncherUtil = {
|
||||
return i2pFile
|
||||
} else {
|
||||
logger.log(4, aI2PFileType + " file not found: "+ i2pFile.path)
|
||||
return ''
|
||||
return null
|
||||
}
|
||||
|
||||
} catch(e) {
|
||||
@ -328,19 +389,27 @@ const LauncherUtil = {
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
get internal() {
|
||||
return LauncherUtilInternal
|
||||
},
|
||||
|
||||
get dataDirectoryObject() {
|
||||
return LauncherUtilInternal._dataDir
|
||||
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
|
||||
return LauncherUtilInternal._appDir.clone()
|
||||
},
|
||||
|
||||
flushLocalizedStringCache: function()
|
||||
{
|
||||
LauncherUtilInternal.mStringBundle = undefined
|
||||
},
|
||||
|
||||
// "i2pbutton." is prepended to aStringName.
|
||||
getLocalizedString: function(aStringName)
|
||||
{
|
||||
@ -350,7 +419,7 @@ const LauncherUtil = {
|
||||
try
|
||||
{
|
||||
var key = kPropNamePrefix + aStringName;
|
||||
return TLUtilInternal._stringBundle.GetStringFromName(key);
|
||||
return LauncherUtilInternal._stringBundle.GetStringFromName(key);
|
||||
} catch(e) {}
|
||||
|
||||
return aStringName;
|
||||
@ -365,7 +434,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;
|
||||
@ -420,6 +489,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.
|
||||
@ -78,7 +116,7 @@ let noscriptSettings = safetyLevel => (
|
||||
"enforced": true,
|
||||
"autoAllowTop": false
|
||||
},
|
||||
"isTorBrowser": true,
|
||||
"isI2PBrowser": true,
|
||||
"tabId": -1
|
||||
});
|
||||
|
||||
|
@ -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