Skip to content

Commit 931905a

Browse files
committed
Support command and search history in 'per-window private mode'
In non-private mode commands and searches are stored in global 'history-command' and 'history-search' stores respectively. Since Firefox 20 the private browsing mode is on per window basis. To support command and search history in per-window private mode: - Save command and search entries for each private (incognito) window opened in 'private-XXX-history-command' or 'private-XXX-history-search' store, where XXX is the private window's unique id. - When the last private window is closed or Firefox itself is closed delete all existing 'private-XXX-*' private stores. - Note: There's no reliable way of detecting when a private window is being closed, Firefox only notifies addons when the last private window is being closed. This is a reason why the private stores are only deleted when the 'last private window close' event is caught. Fixes #137
1 parent f634f10 commit 931905a

File tree

5 files changed

+48
-15
lines changed

5 files changed

+48
-15
lines changed

common/content/commandline.js

Lines changed: 26 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,29 +19,42 @@ const CommandLine = Module("commandline", {
1919

2020
this._callbacks = {};
2121

22-
storage.newArray("history-search", { store: true, privateData: true });
23-
storage.newArray("history-command", { store: true, privateData: true });
22+
["search", "command"].forEach(function (mode) {
23+
let isPrivate = liberator.isPrivateWindow();
24+
storage.newArray(liberator.storeName(mode, isPrivate), { store: !isPrivate});
25+
}, this);
2426

2527
// Really inideal.
2628
let services = modules.services; // Storage objects are global to all windows, 'modules' isn't.
2729
storage.newObject("sanitize", function () {
2830
({
2931
CLEAR: "browser:purge-session-history",
3032
QUIT: "quit-application",
33+
PRIVATE_END: "last-pb-context-exited",
34+
3135
init: function () {
3236
services.get("obs").addObserver(this, this.CLEAR, false);
3337
services.get("obs").addObserver(this, this.QUIT, false);
38+
services.get("obs").addObserver(this, this.PRIVATE_END, false);
3439
},
3540
observe: function (subject, topic, data) {
3641
switch (topic) {
3742
case this.CLEAR:
3843
["search", "command"].forEach(function (mode) {
39-
CommandLine.History(null, mode).sanitize();
40-
});
44+
CommandLine.History(null, mode, liberator.isPrivateWindow()).sanitize();
45+
}, this);
46+
break;
47+
case this.PRIVATE_END:
48+
for (let [key, obj] in Iterator(storage)) {
49+
if (key.match(/^private-[0-9]/)) {
50+
delete storage[key];
51+
}
52+
}
4153
break;
4254
case this.QUIT:
4355
services.get("obs").removeObserver(this, this.CLEAR);
4456
services.get("obs").removeObserver(this, this.QUIT);
57+
services.get("obs").removeObserver(this, this.PRIVATE_END);
4558
break;
4659
}
4760
}
@@ -471,7 +484,9 @@ const CommandLine = Module("commandline", {
471484

472485
this.show();
473486

474-
this._history = CommandLine.History(this._commandWidget.inputField, (modes.extended == modes.EX) ? "command" : "search");
487+
this._history = CommandLine.History(this._commandWidget.inputField,
488+
(modes.extended == modes.EX) ? "command" : "search",
489+
liberator.isPrivateWindow());
475490
this._completions = CommandLine.Completions(this._commandWidget.inputField);
476491

477492
// open the completion list automatically if wanted
@@ -662,7 +677,9 @@ const CommandLine = Module("commandline", {
662677
this.show();
663678
this._commandWidget.focus();
664679

665-
this._history = CommandLine.History(this._commandWidget.inputField, (modes.extended == modes.EX) ? "command" : "search");
680+
this._history = CommandLine.History(this._commandWidget.inputField,
681+
(modes.extended == modes.EX) ? "command" : "search",
682+
liberator.isPrivateWindow());
666683
this._completions = CommandLine.Completions(this._commandWidget.inputField);
667684
},
668685

@@ -1032,10 +1049,11 @@ const CommandLine = Module("commandline", {
10321049
* @param {string} mode The mode for which we need history.
10331050
*/
10341051
History: Class("History", {
1035-
init: function (inputField, mode) {
1052+
init: function (inputField, mode, privateBrowsing) {
10361053
this.mode = mode;
10371054
this.input = inputField;
1038-
this.store = storage["history-" + mode];
1055+
this.storeName = liberator.storeName(mode, privateBrowsing);
1056+
this.store = storage[this.storeName];
10391057
this.reset();
10401058
},
10411059
/**

common/content/liberator.js

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -254,6 +254,25 @@ const Liberator = Module("liberator", {
254254
window.dump(msg.replace(/^./gm, ("config" in modules && config.name.toLowerCase()) + ": $&"));
255255
},
256256

257+
isPrivateWindow: function () {
258+
return window.QueryInterface(Ci.nsIInterfaceRequestor)
259+
.getInterface(Ci.nsIWebNavigation)
260+
.QueryInterface(Ci.nsILoadContext)
261+
.usePrivateBrowsing;
262+
},
263+
264+
windowID: function() {
265+
return window.QueryInterface(Components.interfaces.nsIInterfaceRequestor)
266+
.getInterface(Components.interfaces.nsIDOMWindowUtils)
267+
.outerWindowID;
268+
269+
},
270+
271+
storeName: function(mode, isPrivate) {
272+
let prefix = isPrivate ? "private-" + this.windowID() + "-" : "";
273+
return prefix + "history-" + mode ;
274+
},
275+
257276
/**
258277
* Outputs a plain message to the command line.
259278
*
@@ -1171,10 +1190,7 @@ const Liberator = Module("liberator", {
11711190
win.setAttribute("titlemodifier_normal", value);
11721191
win.setAttribute("titlemodifier_privatebrowsing", value + suffix);
11731192

1174-
if (window.QueryInterface(Ci.nsIInterfaceRequestor)
1175-
.getInterface(Ci.nsIWebNavigation)
1176-
.QueryInterface(Ci.nsILoadContext)
1177-
.usePrivateBrowsing) {
1193+
if (liberator.isPrivateWindow()) {
11781194
win.setAttribute("titlemodifier", value + suffix);
11791195
}
11801196
else

common/content/sanitizer.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ const Sanitizer = Module("sanitizer", {
7474
commands.add(["sa[nitize]"],
7575
"Clear private data",
7676
function (args) {
77-
liberator.assert(!options['private'], "Cannot sanitize items in private mode");
77+
liberator.assert(!liberator.isPrivateWindow(), "Cannot sanitize items in private mode");
7878

7979
let timespan = args["-timespan"] == undefined ? options["sanitizetimespan"] : args["-timespan"];
8080

common/modules/storage.jsm

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,6 @@ function loadPref(name, store, type) {
151151
}
152152

153153
function savePref(obj) {
154-
if (obj.privateData)
155-
return;
156154
if (obj.store && storage.infoPath)
157155
writeFile(getFile(obj.name), obj.serial);
158156
}

vimperator/NEWS

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Make <Ctrl-[> key always behave like <Esc> key (was missing from the command line handler)
77
* Add support for :set hintmatching=fuzzy as a new, alternative way for hintmatching.
88
* Don't display help message in command line for a normal click.
9+
* Keep search history and command line history private in 'Private Browsing' mode.
910

1011
2014-11-09
1112
* Version 3.8.3

0 commit comments

Comments
 (0)