blob: bcf35009a06eacae92be0e0393283d62d2d2789d [file] [log] [blame]
// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
if (!chrome.cookies) {
chrome.cookies = chrome.experimental.cookies;
}
// A simple Timer class.
function Timer() {
this.start_ = new Date();
this.elapsed = function() {
return (new Date()) - this.start_;
}
this.reset = function() {
this.start_ = new Date();
}
}
// Compares cookies for "key" (name, domain, etc.) equality, but not "value"
// equality.
function cookieMatch(c1, c2) {
return (c1.name == c2.name) && (c1.domain == c2.domain) &&
(c1.hostOnly == c2.hostOnly) && (c1.path == c2.path) &&
(c1.secure == c2.secure) && (c1.httpOnly == c2.httpOnly) &&
(c1.session == c2.session) && (c1.storeId == c2.storeId);
}
// Returns an array of sorted keys from an associative array.
function sortedKeys(array) {
var keys = [];
for (var i in array) {
keys.push(i);
}
keys.sort();
return keys;
}
// Shorthand for document.querySelector.
function select(selector) {
return document.querySelector(selector);
}
// An object used for caching data about the browser's cookies, which we update
// as notifications come in.
function CookieCache() {
this.cookies_ = {};
this.reset = function() {
this.cookies_ = {};
}
this.add = function(cookie) {
var domain = cookie.domain;
if (!this.cookies_[domain]) {
this.cookies_[domain] = [];
}
this.cookies_[domain].push(cookie);
};
this.remove = function(cookie) {
var domain = cookie.domain;
if (this.cookies_[domain]) {
var i = 0;
while (i < this.cookies_[domain].length) {
if (cookieMatch(this.cookies_[domain][i], cookie)) {
this.cookies_[domain].splice(i, 1);
} else {
i++;
}
}
if (this.cookies_[domain].length == 0) {
delete this.cookies_[domain];
}
}
};
// Returns a sorted list of cookie domains that match |filter|. If |filter| is
// null, returns all domains.
this.getDomains = function(filter) {
var result = [];
sortedKeys(this.cookies_).forEach(function(domain) {
if (!filter || domain.indexOf(filter) != -1) {
result.push(domain);
}
});
return result;
}
this.getCookies = function(domain) {
return this.cookies_[domain];
};
}
var cache = new CookieCache();
function removeAllForFilter() {
var filter = select("#filter").value;
var timer = new Timer();
cache.getDomains(filter).forEach(function(domain) {
removeCookiesForDomain(domain);
});
}
function removeAll() {
var all_cookies = [];
cache.getDomains().forEach(function(domain) {
cache.getCookies(domain).forEach(function(cookie) {
all_cookies.push(cookie);
});
});
cache.reset();
var count = all_cookies.length;
var timer = new Timer();
for (var i = 0; i < count; i++) {
removeCookie(all_cookies[i]);
}
timer.reset();
chrome.cookies.getAll({}, function(cookies) {
for (var i in cookies) {
cache.add(cookies[i]);
removeCookie(cookies[i]);
}
});
}
function removeCookie(cookie) {
var url = "http" + (cookie.secure ? "s" : "") + "://" + cookie.domain +
cookie.path;
chrome.cookies.remove({"url": url, "name": cookie.name});
}
function removeCookiesForDomain(domain) {
var timer = new Timer();
cache.getCookies(domain).forEach(function(cookie) {
removeCookie(cookie);
});
}
function resetTable() {
var table = select("#cookies");
while (table.rows.length > 1) {
table.deleteRow(table.rows.length - 1);
}
}
var reload_scheduled = false;
function scheduleReloadCookieTable() {
if (!reload_scheduled) {
reload_scheduled = true;
setTimeout(reloadCookieTable, 250);
}
}
function reloadCookieTable() {
reload_scheduled = false;
var filter = select("#filter").value;
var domains = cache.getDomains(filter);
select("#filter_count").innerText = domains.length;
select("#total_count").innerText = cache.getDomains().length;
select("#delete_all_button").innerHTML = "";
if (domains.length) {
var button = document.createElement("button");
button.onclick = removeAllForFilter;
button.innerText = "delete all " + domains.length;
select("#delete_all_button").appendChild(button);
}
resetTable();
var table = select("#cookies");
domains.forEach(function(domain) {
var cookies = cache.getCookies(domain);
var row = table.insertRow(-1);
row.insertCell(-1).innerText = domain;
var cell = row.insertCell(-1);
cell.innerText = cookies.length;
cell.setAttribute("class", "cookie_count");
var button = document.createElement("button");
button.innerText = "delete";
button.onclick = (function(dom){
return function() {
removeCookiesForDomain(dom);
};
}(domain));
var cell = row.insertCell(-1);
cell.appendChild(button);
cell.setAttribute("class", "button");
});
}
function focusFilter() {
select("#filter").focus();
}
function resetFilter() {
var filter = select("#filter");
filter.focus();
if (filter.value.length > 0) {
filter.value = "";
reloadCookieTable();
}
}
var ESCAPE_KEY = 27;
window.onkeydown = function(event) {
if (event.keyCode == ESCAPE_KEY) {
resetFilter();
}
}
function listener(info) {
cache.remove(info.cookie);
if (!info.removed) {
cache.add(info.cookie);
}
scheduleReloadCookieTable();
}
function startListening() {
chrome.cookies.onChanged.addListener(listener);
}
function stopListening() {
chrome.cookies.onChanged.removeListener(listener);
}
function onload() {
focusFilter();
var timer = new Timer();
chrome.cookies.getAll({}, function(cookies) {
startListening();
start = new Date();
for (var i in cookies) {
cache.add(cookies[i]);
}
timer.reset();
reloadCookieTable();
});
}
document.addEventListener('DOMContentLoaded', function() {
onload();
document.body.addEventListener('click', focusFilter);
document.querySelector('#remove_button').addEventListener('click', removeAll);
document.querySelector('#filter_div input').addEventListener(
'input', reloadCookieTable);
document.querySelector('#filter_div button').addEventListener(
'click', resetFilter);
});