1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
6 chrome
.cookies
= chrome
.experimental
.cookies
;
9 // A simple Timer class.
11 this.start_
= new Date();
13 this.elapsed = function() {
14 return (new Date()) - this.start_
;
17 this.reset = function() {
18 this.start_
= new Date();
22 // Compares cookies for "key" (name, domain, etc.) equality, but not "value"
24 function cookieMatch(c1
, c2
) {
25 return (c1
.name
== c2
.name
) && (c1
.domain
== c2
.domain
) &&
26 (c1
.hostOnly
== c2
.hostOnly
) && (c1
.path
== c2
.path
) &&
27 (c1
.secure
== c2
.secure
) && (c1
.httpOnly
== c2
.httpOnly
) &&
28 (c1
.session
== c2
.session
) && (c1
.storeId
== c2
.storeId
);
31 // Returns an array of sorted keys from an associative array.
32 function sortedKeys(array
) {
34 for (var i
in array
) {
41 // Shorthand for document.querySelector.
42 function select(selector
) {
43 return document
.querySelector(selector
);
46 // An object used for caching data about the browser's cookies, which we update
47 // as notifications come in.
48 function CookieCache() {
51 this.reset = function() {
55 this.add = function(cookie
) {
56 var domain
= cookie
.domain
;
57 if (!this.cookies_
[domain
]) {
58 this.cookies_
[domain
] = [];
60 this.cookies_
[domain
].push(cookie
);
63 this.remove = function(cookie
) {
64 var domain
= cookie
.domain
;
65 if (this.cookies_
[domain
]) {
67 while (i
< this.cookies_
[domain
].length
) {
68 if (cookieMatch(this.cookies_
[domain
][i
], cookie
)) {
69 this.cookies_
[domain
].splice(i
, 1);
74 if (this.cookies_
[domain
].length
== 0) {
75 delete this.cookies_
[domain
];
80 // Returns a sorted list of cookie domains that match |filter|. If |filter| is
81 // null, returns all domains.
82 this.getDomains = function(filter
) {
84 sortedKeys(this.cookies_
).forEach(function(domain
) {
85 if (!filter
|| domain
.indexOf(filter
) != -1) {
92 this.getCookies = function(domain
) {
93 return this.cookies_
[domain
];
98 var cache
= new CookieCache();
101 function removeAllForFilter() {
102 var filter
= select("#filter").value
;
103 var timer
= new Timer();
104 cache
.getDomains(filter
).forEach(function(domain
) {
105 removeCookiesForDomain(domain
);
109 function removeAll() {
110 var all_cookies
= [];
111 cache
.getDomains().forEach(function(domain
) {
112 cache
.getCookies(domain
).forEach(function(cookie
) {
113 all_cookies
.push(cookie
);
117 var count
= all_cookies
.length
;
118 var timer
= new Timer();
119 for (var i
= 0; i
< count
; i
++) {
120 removeCookie(all_cookies
[i
]);
123 chrome
.cookies
.getAll({}, function(cookies
) {
124 for (var i
in cookies
) {
125 cache
.add(cookies
[i
]);
126 removeCookie(cookies
[i
]);
131 function removeCookie(cookie
) {
132 var url
= "http" + (cookie
.secure
? "s" : "") + "://" + cookie
.domain
+
134 chrome
.cookies
.remove({"url": url
, "name": cookie
.name
});
137 function removeCookiesForDomain(domain
) {
138 var timer
= new Timer();
139 cache
.getCookies(domain
).forEach(function(cookie
) {
140 removeCookie(cookie
);
144 function resetTable() {
145 var table
= select("#cookies");
146 while (table
.rows
.length
> 1) {
147 table
.deleteRow(table
.rows
.length
- 1);
151 var reload_scheduled
= false;
153 function scheduleReloadCookieTable() {
154 if (!reload_scheduled
) {
155 reload_scheduled
= true;
156 setTimeout(reloadCookieTable
, 250);
160 function reloadCookieTable() {
161 reload_scheduled
= false;
163 var filter
= select("#filter").value
;
165 var domains
= cache
.getDomains(filter
);
167 select("#filter_count").innerText
= domains
.length
;
168 select("#total_count").innerText
= cache
.getDomains().length
;
170 select("#delete_all_button").innerHTML
= "";
171 if (domains
.length
) {
172 var button
= document
.createElement("button");
173 button
.onclick
= removeAllForFilter
;
174 button
.innerText
= "delete all " + domains
.length
;
175 select("#delete_all_button").appendChild(button
);
179 var table
= select("#cookies");
181 domains
.forEach(function(domain
) {
182 var cookies
= cache
.getCookies(domain
);
183 var row
= table
.insertRow(-1);
184 row
.insertCell(-1).innerText
= domain
;
185 var cell
= row
.insertCell(-1);
186 cell
.innerText
= cookies
.length
;
187 cell
.setAttribute("class", "cookie_count");
189 var button
= document
.createElement("button");
190 button
.innerText
= "delete";
191 button
.onclick
= (function(dom
){
193 removeCookiesForDomain(dom
);
196 var cell
= row
.insertCell(-1);
197 cell
.appendChild(button
);
198 cell
.setAttribute("class", "button");
202 function focusFilter() {
203 select("#filter").focus();
206 function resetFilter() {
207 var filter
= select("#filter");
209 if (filter
.value
.length
> 0) {
216 window
.onkeydown = function(event
) {
217 if (event
.keyCode
== ESCAPE_KEY
) {
222 function listener(info
) {
223 cache
.remove(info
.cookie
);
225 cache
.add(info
.cookie
);
227 scheduleReloadCookieTable();
230 function startListening() {
231 chrome
.cookies
.onChanged
.addListener(listener
);
234 function stopListening() {
235 chrome
.cookies
.onChanged
.removeListener(listener
);
240 var timer
= new Timer();
241 chrome
.cookies
.getAll({}, function(cookies
) {
244 for (var i
in cookies
) {
245 cache
.add(cookies
[i
]);
252 document
.addEventListener('DOMContentLoaded', function() {
254 document
.body
.addEventListener('click', focusFilter
);
255 document
.querySelector('#remove_button').addEventListener('click', removeAll
);
256 document
.querySelector('#filter_div input').addEventListener(
257 'input', reloadCookieTable
);
258 document
.querySelector('#filter_div button').addEventListener(
259 'click', resetFilter
);