| // 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); |
| }); |