// Copyright (c) 2009 by Doug Kearns <dougkearns@gmail.com>
-// Copyright (c) 2009-2011 by Kris Maglione <maglione.k at Gmail>
+// Copyright (c) 2009-2014 Kris Maglione <maglione.k at Gmail>
//
// This work is licensed for reuse under an MIT license. Details are
// given in the LICENSE.txt file included with this file.
-/* use strict */
+"use strict";
// TODO:
// - fix Sanitize autocommand
// FIXME:
// - finish 1.9.0 support if we're going to support sanitizing in Melodactyl
-Components.utils.import("resource://dactyl/bootstrap.jsm");
defineModule("sanitizer", {
exports: ["Range", "Sanitizer", "sanitizer"],
require: ["config", "prefs", "services", "util"]
-}, this);
+});
-this.lazyRequire("messages", ["_"]);
-this.lazyRequire("storage", ["storage"]);
-this.lazyRequire("template", ["teplate"]);
+lazyRequire("messages", ["_"]);
+lazyRequire("overlay", ["overlay"]);
+lazyRequire("storage", ["storage"]);
+lazyRequire("template", ["template"]);
-let tmp = {};
+let tmp = Object.create(this);
JSMLoader.loadSubScript("chrome://browser/content/sanitize.js", tmp);
tmp.Sanitizer.prototype.__proto__ = Class.prototype;
util.addObserver(this);
- services.add("contentPrefs", "@mozilla.org/content-pref/service;1", Ci.nsIContentPrefService);
services.add("cookies", "@mozilla.org/cookiemanager;1", [Ci.nsICookieManager, Ci.nsICookieManager2,
Ci.nsICookieService]);
services.add("loginManager", "@mozilla.org/login-manager;1", Ci.nsILoginManager);
},
override: true
});
- if (services.has("privateBrowsing"))
+ try {
+ var { ForgetAboutSite } = Cu.import("resource://gre/modules/ForgetAboutSite.jsm", {});
+ }
+ catch (e) {}
+ if (ForgetAboutSite)
this.addItem("host", {
description: "All data from the given host",
action: function (range, host) {
if (host)
- services.privateBrowsing.removeDataFromDomain(host);
+ ForgetAboutSite.removeDataFromDomain(host);
}
});
this.addItem("sitesettings", {
// "Allow this site to open popups" ...
services.permissions.removeAll();
// Zoom level, ...
- services.contentPrefs.removeGroupedPrefs();
+ services.contentPrefs.removeAllDomains(null);
}
// "Never remember passwords" ...
- for each (let domain in services.loginManager.getAllDisabledHosts())
+ for (let domain of services.loginManager.getAllDisabledHosts())
if (!host || util.isSubdomain(domain, host))
services.loginManager.setLoginSavingEnabled(host, true);
},
];
function prefOverlay(branch, persistent, local) update(Object.create(local), {
- before: array.toObject([
- [branch.substr(Item.PREFIX.length) + "history",
- <preferences xmlns={XUL}>{
- template.map(ourItems(persistent), function (item)
- <preference type="bool" id={branch + item.name} name={branch + item.name}/>)
- }</preferences>.*::*]
- ]),
+ before: [
+ ["preferences", { id: branch.substr(Item.PREFIX.length) + "history",
+ xmlns: "xul" },
+ template.map(ourItems(persistent), item =>
+ ["preference", { type: "bool", id: branch + item.name, name: branch + item.name }])]
+ ],
init: function init(win) {
let pane = win.document.getElementById("SanitizeDialogPane");
for (let [, pref] in iter(pane.preferences))
}
});
- let (branch = Item.PREFIX + Item.SHUTDOWN_BRANCH) {
- util.overlayWindow("chrome://browser/content/preferences/sanitize.xul",
- function (win) prefOverlay(branch, true, {
- append: {
- SanitizeDialogPane:
- <groupbox orient="horizontal" xmlns={XUL}>
- <caption label={config.appName + /*L*/" (see :help privacy)"}/>
- <grid flex="1">
- <columns><column flex="1"/><column flex="1"/></columns>
- <rows>{
- let (items = ourItems(true))
- template.map(util.range(0, Math.ceil(items.length / 2)), function (i)
- <row xmlns={XUL}>{
- template.map(items.slice(i * 2, i * 2 + 2), function (item)
- <checkbox xmlns={XUL} label={item.description} preference={branch + item.name}/>)
- }</row>)
- }</rows>
- </grid>
- </groupbox>
- }
- }));
- }
- let (branch = Item.PREFIX + Item.BRANCH) {
- util.overlayWindow("chrome://browser/content/sanitize.xul",
- function (win) prefOverlay(branch, false, {
- append: {
- itemList: <>
- <listitem xmlns={XUL} label={/*L*/"See :help privacy for the following:"} disabled="true" style="font-style: italic; font-weight: bold;"/>
- {
- template.map(ourItems(), function ([item, desc])
- <listitem xmlns={XUL} type="checkbox"
- label={config.appName + " " + desc}
- preference={branch + item}
- onsyncfrompreference="return gSanitizePromptDialog.onReadGeneric();"/>)
- }
- </>
- },
- ready: function ready(win) {
- let elem = win.document.getElementById("itemList");
- elem.setAttribute("rows", elem.itemCount);
- win.Sanitizer = Class("Sanitizer", win.Sanitizer, {
- sanitize: function sanitize() {
- self.withSavedValues(["sanitizing"], function () {
- self.sanitizing = true;
- sanitize.superapply(this, arguments);
- sanitizer.sanitizeItems([item.name for (item in values(self.itemMap))
- if (item.shouldSanitize(false))],
- Range.fromArray(this.range || []));
- }, this);
- }
- });
- }
- }));
- }
+ util.timeout(function () { // Load order issue...
+
+ let (branch = Item.PREFIX + Item.SHUTDOWN_BRANCH) {
+ overlay.overlayWindow("chrome://browser/content/preferences/sanitize.xul",
+ function (win) prefOverlay(branch, true, {
+ append: {
+ SanitizeDialogPane:
+ ["groupbox", { orient: "horizontal", xmlns: "xul" },
+ ["caption", { label: config.appName + /*L*/" (see :help privacy)" }],
+ ["grid", { flex: "1" },
+ ["columns", {},
+ ["column", { flex: "1" }],
+ ["column", { flex: "1" }]],
+ ["rows", {},
+ let (items = ourItems(true))
+ template.map(util.range(0, Math.ceil(items.length / 2)), i =>
+ ["row", {},
+ template.map(items.slice(i * 2, i * 2 + 2), item =>
+ ["checkbox", { xmlns: XUL, label: item.description, preference: branch + item.name }])])]]]
+ }
+ }));
+ }
+ let (branch = Item.PREFIX + Item.BRANCH) {
+ overlay.overlayWindow("chrome://browser/content/sanitize.xul",
+ function (win) prefOverlay(branch, false, {
+ append: {
+ itemList: [
+ ["listitem", { xmlns: "xul", label: /*L*/"See :help privacy for the following:",
+ disabled: "true", style: "font-style: italic; font-weight: bold;" }],
+ template.map(ourItems(), ([item, desc]) =>
+ ["listitem", { xmlns: "xul", preference: branch + item,
+ type: "checkbox", label: config.appName + ", " + desc,
+ onsyncfrompreference: "return gSanitizePromptDialog.onReadGeneric();" }])
+ ]
+ },
+ ready: function ready(win) {
+ let elem = win.document.getElementById("itemList");
+ elem.setAttribute("rows", elem.itemCount);
+ win.Sanitizer = Class("Sanitizer", win.Sanitizer, {
+ sanitize: function sanitize() {
+ self.withSavedValues(["sanitizing"], function () {
+ self.sanitizing = true;
+ sanitize.superapply(this, arguments);
+ sanitizer.sanitizeItems([item.name for (item in values(self.itemMap))
+ if (item.shouldSanitize(false))],
+ Range.fromArray(this.range || []));
+ }, this);
+ }
+ });
+ }
+ }));
+ }
+ });
},
firstRun: 0,
if (!("value" in prop) || !callable(prop.value) && !(k in item))
Object.defineProperty(item, k, prop);
- let names = Set([name].concat(params.contains || []).map(function (e) "clear-" + e));
+ function getWindow(obj) {
+ obj = Class.objectGlobal(obj);
+ return obj.window || obj;
+ }
+
+ let names = RealSet([name].concat(params.contains || []).map(e => "clear-" + e));
if (params.action)
storage.addObserver("sanitizer",
function (key, event, arg) {
- if (event in names)
+ if (names.has(event))
params.action.apply(params, arg);
},
- Class.objectGlobal(params.action));
+ getWindow(params.action));
if (params.privateEnter || params.privateLeave)
storage.addObserver("private-mode",
if (meth)
meth.call(params);
},
- Class.objectGlobal(params.action));
+ getWindow(params.privateEnter || params.privateLeave));
},
observers: {
}
},
+ /**
+ * Returns a load context for the given thing, to be used with
+ * interfaces needing one for per-window private browsing support.
+ *
+ * @param {Window|Document|Node} thing The thing for which to return
+ * a load context.
+ */
+ getContext: function getContext(thing) {
+ if (!Ci.nsILoadContext)
+ return null;
+
+ if (thing instanceof Ci.nsIDOMNode && thing.ownerDocument)
+ thing = thing.ownerDocument;
+ if (thing instanceof Ci.nsIDOMDocument)
+ thing = thing.defaultView;
+ if (thing instanceof Ci.nsIInterfaceRequestor)
+ thing = thing.getInterface(Ci.nsIWebNavigation);
+ return thing.QueryInterface(Ci.nsILoadContext);
+ },
+
get ranAtShutdown() config.prefs.get("didSanitizeOnShutdown"),
set ranAtShutdown(val) config.prefs.set("didSanitizeOnShutdown", Boolean(val)),
get runAtShutdown() prefs.get("privacy.sanitize.sanitizeOnShutdown"),
set runAtShutdown(val) prefs.set("privacy.sanitize.sanitizeOnShutdown", Boolean(val)),
- sanitize: function (items, range)
+ sanitize: function sanitize(items, range)
this.withSavedValues(["sanitizing"], function () {
this.sanitizing = true;
let errors = this.sanitizeItems(items, range, null);
return errors;
}),
- sanitizeItems: function (items, range, host, key)
+ sanitizeItems: function sanitizeItems(items, range, host, key)
this.withSavedValues(["sanitizing"], function () {
this.sanitizing = true;
if (items == null)
UNPERMS: Class.Memoize(function () iter(this.PERMS).map(Array.reverse).toObject()),
COMMANDS: {
- unset: /*L*/"Unset",
- allow: /*L*/"Allowed",
- deny: /*L*/"Denied",
- session: /*L*/"Allowed for the current session",
- list: /*L*/"List all cookies for domain",
- clear: /*L*/"Clear all cookies for domain",
+ "unset": /*L*/"Unset",
+ "allow": /*L*/"Allowed",
+ "deny": /*L*/"Denied",
+ "session": /*L*/"Allowed for the current session",
+ "list": /*L*/"List all cookies for domain",
+ "clear": /*L*/"Clear all cookies for domain",
"clear-persistent": /*L*/"Clear all persistent cookies for domain",
"clear-session": /*L*/"Clear all session cookies for domain"
},
for (let c in iter(services.cookies, Ci.nsICookie2))
if (!host || util.isSubdomain(c.rawHost, host) ||
c.host[0] == "." && c.host.length < host.length
- && host.indexOf(c.host) == host.length - c.host.length)
+ && host.endsWith(c.host))
yield c;
},
yield p;
}
}, {
- load: function (dactyl, modules, window) {
+ load: function initLoad(dactyl, modules, window) {
if (!sanitizer.firstRun++ && sanitizer.runAtShutdown && !sanitizer.ranAtShutdown)
sanitizer.sanitizeItems(null, Range(), null, "shutdown");
sanitizer.ranAtShutdown = false;
},
- autocommands: function (dactyl, modules, window) {
+ autocommands: function initAutocommands(dactyl, modules, window) {
const { autocommands } = modules;
storage.addObserver("private-mode",
autocommands.trigger("Sanitize", { name: event.substr("clear-".length), domain: value[1] });
}, window);
},
- commands: function (dactyl, modules, window) {
+ commands: function initCommands(dactyl, modules, window) {
const { commands } = modules;
commands.add(["sa[nitize]"],
"Clear private data",
if (args.bang)
dactyl.assert(args.length == 0, _("error.trailingCharacters"));
else {
+ dactyl.assert(args.length, _("error.argumentRequired"));
dactyl.assert(opt.validator(args), _("error.invalidArgument"));
opt = { __proto__: opt, value: args.slice() };
}
- let items = Object.keys(sanitizer.itemMap).slice(1).filter(opt.has, opt);
+ let items = Object.keys(sanitizer.itemMap)
+ .slice(1)
+ .filter(opt.has, opt);
function sanitize(items) {
sanitizer.range = range.native;
sanitizer.sanitize(items, range);
}
- if (array.nth(opt.value, function (i) i == "all" || /^!/.test(i), 0) == "all" && !args["-host"])
+ if ("all" == opt.value.find(i => (i == "all" ||
+ /^!/.test(i)))
+ && !args["-host"])
+
modules.commandline.input(_("sanitize.prompt.deleteAll") + " ",
function (resp) {
if (resp.match(/^y(es)?$/i)) {
names: ["-host", "-h"],
description: "Only sanitize items referring to listed host or hosts",
completer: function (context, args) {
- context.filters.push(function (item)
- !args["-host"].some(function (host) util.isSubdomain(item.text, host)));
+ context.filters.push(item =>
+ !args["-host"].some(host => util.isSubdomain(item.text, host)));
modules.completion.domain(context);
},
type: modules.CommandOption.LIST
description: "Timespan for which to sanitize items",
completer: function (context) modules.options.get("sanitizetimespan").completer(context),
type: modules.CommandOption.STRING,
- validator: function (arg) modules.options.get("sanitizetimespan").validator(arg),
+ validator: function (arg) modules.options.get("sanitizetimespan").validator(arg)
}
],
privateData: true
}
function setPerms(host, perm) {
let uri = util.createURI(host);
- services.permissions.remove(uri, "cookie");
+ services.permissions.remove(uri.host, "cookie");
services.permissions.add(uri, "cookie", Sanitizer.PERMS[perm]);
}
commands.add(["cookies", "ck"],
["Host", "Expiry (UTC)", "Path", "Name", "Value"],
["padding-right: 1em", "padding-right: 1em", "padding-right: 1em", "max-width: 12em; overflow: hidden;", "padding-left: 1ex;"],
([c.host,
- c.isSession ? <span highlight="Enabled">session</span>
+ c.isSession ? ["span", { highlight: "Enabled" }, "session"]
: (new Date(c.expiry * 1000).toJSON() || "Never").replace(/:\d\d\.000Z/, "").replace("T", " ").replace(/-/g, "/"),
c.path,
c.name,
let count = [0, 0];
for (let c in Sanitizer.iterCookies(host))
count[c.isSession + 0]++;
- return <>{Sanitizer.COMMANDS[getPerms(host)]} (session: {count[1]} persistent: {count[0]})</>;
+ return [Sanitizer.COMMANDS[getPerms(host)], " (session: ", count[1], " persistent: ", count[0], ")"].join("");
};
break;
case 1:
},
});
},
- completion: function (dactyl, modules, window) {
+ completion: function initCompletion(dactyl, modules, window) {
modules.completion.visibleHosts = function completeHosts(context) {
let res = util.visibleHosts(window.content);
- if (context.filter && !res.some(function (host) host.indexOf(context.filter) >= 0))
+ if (context.filter && !res.some(host => host.contains(context.filter)))
res.push(context.filter);
context.title = ["Domain"];
context.completions = res;
};
},
- options: function (dactyl, modules) {
+ options: function initOptions(dactyl, modules) {
const options = modules.options;
- if (services.has("privateBrowsing"))
- options.add(["private", "pornmode"],
- "Set the 'private browsing' option",
- "boolean", false,
- {
- initialValue: true,
- getter: function () services.privateBrowsing.privateBrowsingEnabled,
- setter: function (value) {
- if (services.privateBrowsing.privateBrowsingEnabled != value)
- services.privateBrowsing.privateBrowsingEnabled = value;
- },
- persist: false
- });
options.add(["sanitizeitems", "si"],
"The default list of private items to sanitize",
},
has: function has(val)
- let (res = array.nth(this.value, function (v) v == "all" || v.replace(/^!/, "") == val, 0))
+ let (res = this.value.find(v => (v == "all" || v.replace(/^!/, "") == val)))
res && !/^!/.test(res),
validator: function (values) values.length &&
- values.every(function (val) val === "all" || Set.has(sanitizer.itemMap, val.replace(/^!/, "")))
+ values.every(val => (val === "all" || hasOwnProperty(sanitizer.itemMap, val.replace(/^!/, ""))))
});
options.add(["sanitizeshutdown", "ss"],
sanitizer.runAtShutdown = false;
else {
sanitizer.runAtShutdown = true;
- let have = Set(value);
+ let have = RealSet(value);
for (let item in values(sanitizer.itemMap))
prefs.set(item.shutdownPref,
- Boolean(Set.has(have, item.name) ^ Set.has(have, "all")));
+ Boolean(have.has(item.name) ^ have.has("all")));
}
return value;
}
],
getter: function () (this.values[prefs.get(this.PREF)] || ["all"])[0],
setter: function (val) {
- prefs.set(this.PREF, this.values.map(function (i) i[0]).indexOf(val));
+ prefs.set(this.PREF, this.values.map(i => i[0]).indexOf(val));
return val;
},
initialValue: true,
],
getter: function () (this.values[prefs.get(this.PREF)] || [prefs.get(this.PREF_DAYS)])[0],
setter: function (value) {
- let val = this.values.map(function (i) i[0]).indexOf(value);
+ let val = this.values.map(i => i[0]).indexOf(value);
if (val > -1)
prefs.set(this.PREF, val);
else {
// catch(e){dump(e.fileName+":"+e.lineNumber+": "+e+"\n" + e.stack);}
-// vim: set fdm=marker sw=4 ts=4 et ft=javascript:
+// vim: set fdm=marker sw=4 sts=4 ts=8 et ft=javascript: