diff --git a/common/content/bookmarks.js b/common/content/bookmarks.js index 42f5d110..747fbe54 100644 --- a/common/content/bookmarks.js +++ b/common/content/bookmarks.js @@ -79,10 +79,10 @@ function Bookmarks() //{{{ ].filter(function (item) item[1])); const storage = modules.storage; - function Cache(name, store, serial) + function Cache(name, store) { const rootFolders = [bookmarksService.toolbarFolder, bookmarksService.bookmarksMenuFolder, bookmarksService.unfiledBookmarksFolder]; - const sleep = liberator.sleep; + const sleep = liberator.sleep; // Storage objects are global to all windows, 'liberator' isn't. let bookmarks = []; let self = this; @@ -1052,7 +1052,7 @@ function QuickMarks() //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - var qmarks = storage.newMap("quickmarks", true); + var qmarks = storage.newMap("quickmarks", true, { privateData: true }); /////////////////////////////////////////////////////////////////////////////}}} ////////////////////// MAPPINGS //////////////////////////////////////////////// diff --git a/common/content/buffer.js b/common/content/buffer.js index a1bb0913..316be720 100644 --- a/common/content/buffer.js +++ b/common/content/buffer.js @@ -1630,8 +1630,8 @@ function Marks() //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - var localMarks = storage.newMap("local-marks", true); - var urlMarks = storage.newMap("url-marks", true); + var localMarks = storage.newMap("local-marks", true, { privateData: true }); + var urlMarks = storage.newMap("url-marks", true, { privateData: true }); var pendingJumps = []; var appContent = document.getElementById("appcontent"); diff --git a/common/content/events.js b/common/content/events.js index 3cc39348..38e0e03e 100644 --- a/common/content/events.js +++ b/common/content/events.js @@ -345,7 +345,7 @@ function Events() //{{{ var lastFocus = null; - var macros = storage.newMap("macros", true); + var macros = storage.newMap("macros", true, { privateData: true }); var currentMacro = ""; var lastMacro = ""; diff --git a/common/content/style.js b/common/content/style.js index 7ffad6ab..0b4c1bca 100644 --- a/common/content/style.js +++ b/common/content/style.js @@ -135,7 +135,7 @@ Highlights.prototype.CSS = */ -function Highlights(name, store, serial) +function Highlights(name, store) { let self = this; let highlight = {}; @@ -247,7 +247,7 @@ function Highlights(name, store, serial) * * @author Kris Maglione */ -function Styles(name, store, serial) +function Styles(name, store) { // Can't reference liberator or Components inside Styles -- // they're members of the window object, which disappear diff --git a/common/content/ui.js b/common/content/ui.js index 84e3126f..0864bcd1 100644 --- a/common/content/ui.js +++ b/common/content/ui.js @@ -40,8 +40,8 @@ function CommandLine() //{{{ ////////////////////// PRIVATE SECTION ///////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////{{{ - storage.newArray("history-search", true); - storage.newArray("history-command", true); + storage.newArray("history-search", true, { privateData: true }); + storage.newArray("history-command", true, { privateData: true }); var messageHistory = { // {{{ _messages: [], diff --git a/common/content/util.js b/common/content/util.js index 994fbf88..fc47a72a 100644 --- a/common/content/util.js +++ b/common/content/util.js @@ -706,16 +706,17 @@ const util = { //{{{ /** * Array utility methods. */ -util.Array = function Array(ary) { +util.Array = function Array_(ary) { var obj = { __proto__: ary, __iterator__: function () this.iteritems(), __noSuchMethod__: function (meth, args) { - let res = util.Array[meth].apply(null, [this.__proto__].concat(args)); + let res = (util.Array[meth] || Array[meth]).apply(null, [this.__proto__].concat(args)); if (util.Array.isinstance(res)) return util.Array(res); return res; - } + }, + map: function() this.__noSuchMethod__("map", Array.slice(arguments)), }; return obj; } diff --git a/common/modules/storage.jsm b/common/modules/storage.jsm index 3d4c7840..bec7f721 100644 --- a/common/modules/storage.jsm +++ b/common/modules/storage.jsm @@ -10,7 +10,6 @@ var EXPORTED_SYMBOLS = ["storage", "Timer"]; const Cc = Components.classes; const Ci = Components.interfaces; -const Cr = Components.results; const Cu = Components.utils; // XXX: does not belong here @@ -154,21 +153,38 @@ function loadPref(name, store, type) function savePref(obj) { + if (obj.privateData && storage.privateMode) + return; if (obj.store && storage.infoPath) writeFile(getFile(obj.name), obj.serial); } var prototype = { + OPTIONS: ["privateData"], fireEvent: function (event, arg) { storage.fireEvent(this.name, event, arg) }, save: function () { savePref(this) }, + init: function (name, store, data, options) + { + this.__defineGetter__("store", function () store); + this.__defineGetter__("name", function () name); + for (let [k, v] in Iterator(options)) + if (this.OPTIONS.indexOf(k) >= 0) + this[k] = v; + this.reload(); + } }; -function ObjectStore(name, store, data) +function ObjectStore(name, store, load, options) { - var object = data || {}; + var object = {}; - this.__defineGetter__("store", function () store); - this.__defineGetter__("name", function () name); + this.reload = function reload() + { + object = load() || {}; + this.fireEvent("change", null); + }; + + this.init.apply(this, arguments); this.__defineGetter__("serial", function () json.encode(object)); this.set = function set(key, val) @@ -201,12 +217,17 @@ function ObjectStore(name, store, data) } ObjectStore.prototype = prototype; -function ArrayStore(name, store, data) +function ArrayStore(name, store, load, options) { - var array = data || []; + var array = []; - this.__defineGetter__("store", function () store); - this.__defineGetter__("name", function () name); + this.reload = function reload() + { + array = load() || []; + this.fireEvent("change", null); + }; + + this.init.apply(this, arguments); this.__defineGetter__("serial", function () json.encode(array)); this.__defineGetter__("length", function () array.length); @@ -266,27 +287,28 @@ var observers = {}; var timers = {}; var storage = { - newObject: function newObject(key, constructor, store, type, reload) + newObject: function newObject(key, constructor, store, type, options, reload) { if (!(key in keys) || reload) { if (key in this && !reload) throw Error; - keys[key] = new constructor(key, store, loadPref(key, store, type || Object)); + let load = function() loadPref(key, store, type || Object); + keys[key] = new constructor(key, store, load, options || {}); timers[key] = new Timer(1000, 10000, function () storage.save(key)); this.__defineGetter__(key, function () keys[key]); } return keys[key]; }, - newMap: function newMap(key, store) + newMap: function newMap(key, store, options) { - return this.newObject(key, ObjectStore, store); + return this.newObject(key, ObjectStore, store, null, options); }, - newArray: function newArray(key, store) + newArray: function newArray(key, store, options) { - return this.newObject(key, ArrayStore, store, Array); + return this.newObject(key, ArrayStore, store, Array, options); }, addObserver: function addObserver(key, callback, ref) @@ -333,6 +355,8 @@ var storage = { fireEvent: function fireEvent(key, event, arg) { + if (!(key in this)) + return; this.removeDeadObservers(); // Safe, since we have our own Array object here. for each (let observer in observers[key]) @@ -340,6 +364,12 @@ var storage = { timers[key].tell(); }, + load: function load(key) + { + if (this[key].store && this[key].reload) + this[key].reload(); + }, + save: function save(key) { savePref(keys[key]); @@ -347,9 +377,19 @@ var storage = { saveAll: function storeAll() { - for each (obj in keys) + for each (let obj in keys) savePref(obj); }, + + _privateMode: false, + get privateMode() this._privateMode, + set privateMode(val) + { + if (!val && this._privateMode) + for (let key in keys) + this.load(key); + return this._privateMode = Boolean(val); + }, }; // vim: set fdm=marker sw=4 sts=4 et ft=javascript: diff --git a/vimperator/NEWS b/vimperator/NEWS index 8305922d..bbb9cb14 100644 --- a/vimperator/NEWS +++ b/vimperator/NEWS @@ -13,9 +13,7 @@ { arg: true, count: true, motion: true, route: true }); * IMPORTANT: shifted key notation now matches Vim's behaviour. E.g. and are equivalent, to map the uppercase character use . - Is this still true, or going to be true? --djk - * add 'private' - enter private browsing mode IMPORTANT: this doesn't - currently cause Vimperator-specific data like command-line history to be - purged. + * add 'private' - enter private browsing mode * add -description option to :command * command-line options are now supported via the host application's -liberator option diff --git a/vimperator/content/config.js b/vimperator/content/config.js index aad75539..b8227f42 100644 --- a/vimperator/content/config.js +++ b/vimperator/content/config.js @@ -478,9 +478,9 @@ const config = { //{{{ }); // only available in FF 3.5 - if (Ci.nsIPrivateBrowsingService) + services.add("privateBrowsing", "@mozilla.org/privatebrowsing;1", Ci.nsIPrivateBrowsingService); + if (services.get("privateBrowsing")) { - services.add("privateBrowsing", "@mozilla.org/privatebrowsing;1", Ci.nsIPrivateBrowsingService); options.add(["private", "pornmode"], "Set the 'private browsing' option", "boolean", false, @@ -494,6 +494,27 @@ const config = { //{{{ return services.get("privateBrowsing").privateBrowsingEnabled; } }); + let services = modules.services; // Storage objects are global to all windows, 'modules' isn't. + storage.newObject("private-mode-observer", function () { + ({ + init: function () { + services.get("observer").addObserver(this, "private-browsing", false); + services.get("observer").addObserver(this, "quit-application", false); + this.private = services.get("privateBrowsing").privateBrowsingEnabled; + }, + observe: function (subject, topic, data) { + if (topic == "private-browsing") { + if (data == "enter") + storage.privateMode = true; + else if (data == "exit") + storage.privateMode = false; + } else if (topic == "quit-application") { + services.get("observer").removeObserver(this, "quit-application"); + services.get("observer").removeObserver(this, "private-browsing"); + } + }, + }).init(); + }, false); } // TODO: merge with Vimperator version and add Muttator version @@ -508,7 +529,7 @@ const config = { //{{{ elem.setAttribute("titlemodifier", value); // TODO: remove this FF3.5 test when we no longer support 3.0 - if (Ci.nsIPrivateBrowsingService) + if (services.get("privateBrowsing")) { elem.setAttribute("titlemodifier_privatebrowsing", value); elem.setAttribute("titlemodifier_normal", value); diff --git a/vimperator/locale/en-US/options.txt b/vimperator/locale/en-US/options.txt index 3f9aabd9..c8e01e13 100644 --- a/vimperator/locale/en-US/options.txt +++ b/vimperator/locale/en-US/options.txt @@ -453,9 +453,6 @@ files, cookies, form data, passwords, and download list entries are available only for the duration of the private browsing session and deleted when returning to normal browsing mode. -Warning: Vimperator specific data like command-line history is not yet purged -when exiting private browsing mode. - Note: this is only available in FF 3.5. ____