| OLD | NEW |
| 1 <html> | 1 <html> |
| 2 <head> | 2 <head> |
| 3 <style> | 3 <style> |
| 4 table { | 4 table { |
| 5 border-collapse:collapse; | 5 border-collapse:collapse; |
| 6 } | 6 } |
| 7 | 7 |
| 8 td { | 8 td { |
| 9 border: 1px solid black; | 9 border: 1px solid black; |
| 10 padding-left: 5px; | 10 padding-left: 5px; |
| 11 } | 11 } |
| 12 | 12 |
| 13 td.button { | 13 td.button { |
| 14 border: none; | 14 border: none; |
| 15 } | 15 } |
| 16 | 16 |
| 17 td.cookie_count { | 17 td.cookie_count { |
| 18 text-align: right; | 18 text-align: right; |
| 19 } | 19 } |
| 20 | 20 |
| 21 </style> | 21 </style> |
| 22 | 22 |
| 23 <script> | 23 <script src="manager.js"></script> |
| 24 | 24 |
| 25 if (!chrome.cookies) { | |
| 26 chrome.cookies = chrome.experimental.cookies; | |
| 27 } | |
| 28 | |
| 29 // A simple Timer class. | |
| 30 function Timer() { | |
| 31 this.start_ = new Date(); | |
| 32 | |
| 33 this.elapsed = function() { | |
| 34 return (new Date()) - this.start_; | |
| 35 } | |
| 36 | |
| 37 this.reset = function() { | |
| 38 this.start_ = new Date(); | |
| 39 } | |
| 40 } | |
| 41 | |
| 42 // Compares cookies for "key" (name, domain, etc.) equality, but not "value" | |
| 43 // equality. | |
| 44 function cookieMatch(c1, c2) { | |
| 45 return (c1.name == c2.name) && (c1.domain == c2.domain) && | |
| 46 (c1.hostOnly == c2.hostOnly) && (c1.path == c2.path) && | |
| 47 (c1.secure == c2.secure) && (c1.httpOnly == c2.httpOnly) && | |
| 48 (c1.session == c2.session) && (c1.storeId == c2.storeId); | |
| 49 } | |
| 50 | |
| 51 // Returns an array of sorted keys from an associative array. | |
| 52 function sortedKeys(array) { | |
| 53 var keys = []; | |
| 54 for (var i in array) { | |
| 55 keys.push(i); | |
| 56 } | |
| 57 keys.sort(); | |
| 58 return keys; | |
| 59 } | |
| 60 | |
| 61 // Shorthand for document.querySelector. | |
| 62 function select(selector) { | |
| 63 return document.querySelector(selector); | |
| 64 } | |
| 65 | |
| 66 // An object used for caching data about the browser's cookies, which we update | |
| 67 // as notifications come in. | |
| 68 function CookieCache() { | |
| 69 this.cookies_ = {}; | |
| 70 | |
| 71 this.reset = function() { | |
| 72 this.cookies_ = {}; | |
| 73 } | |
| 74 | |
| 75 this.add = function(cookie) { | |
| 76 var domain = cookie.domain; | |
| 77 if (!this.cookies_[domain]) { | |
| 78 this.cookies_[domain] = []; | |
| 79 } | |
| 80 this.cookies_[domain].push(cookie); | |
| 81 }; | |
| 82 | |
| 83 this.remove = function(cookie) { | |
| 84 var domain = cookie.domain; | |
| 85 if (this.cookies_[domain]) { | |
| 86 var i = 0; | |
| 87 while (i < this.cookies_[domain].length) { | |
| 88 if (cookieMatch(this.cookies_[domain][i], cookie)) { | |
| 89 this.cookies_[domain].splice(i, 1); | |
| 90 } else { | |
| 91 i++; | |
| 92 } | |
| 93 } | |
| 94 if (this.cookies_[domain].length == 0) { | |
| 95 delete this.cookies_[domain]; | |
| 96 } | |
| 97 } | |
| 98 }; | |
| 99 | |
| 100 // Returns a sorted list of cookie domains that match |filter|. If |filter| is | |
| 101 // null, returns all domains. | |
| 102 this.getDomains = function(filter) { | |
| 103 var result = []; | |
| 104 sortedKeys(this.cookies_).forEach(function(domain) { | |
| 105 if (!filter || domain.indexOf(filter) != -1) { | |
| 106 result.push(domain); | |
| 107 } | |
| 108 }); | |
| 109 return result; | |
| 110 } | |
| 111 | |
| 112 this.getCookies = function(domain) { | |
| 113 return this.cookies_[domain]; | |
| 114 }; | |
| 115 } | |
| 116 | |
| 117 | |
| 118 var cache = new CookieCache(); | |
| 119 | |
| 120 | |
| 121 function removeAllForFilter() { | |
| 122 var filter = select("#filter").value; | |
| 123 var timer = new Timer(); | |
| 124 cache.getDomains(filter).forEach(function(domain) { | |
| 125 removeCookiesForDomain(domain); | |
| 126 }); | |
| 127 } | |
| 128 | |
| 129 function removeAll() { | |
| 130 var all_cookies = []; | |
| 131 cache.getDomains().forEach(function(domain) { | |
| 132 cache.getCookies(domain).forEach(function(cookie) { | |
| 133 all_cookies.push(cookie); | |
| 134 }); | |
| 135 }); | |
| 136 cache.reset(); | |
| 137 var count = all_cookies.length; | |
| 138 var timer = new Timer(); | |
| 139 for (var i = 0; i < count; i++) { | |
| 140 removeCookie(all_cookies[i]); | |
| 141 } | |
| 142 timer.reset(); | |
| 143 chrome.cookies.getAll({}, function(cookies) { | |
| 144 for (var i in cookies) { | |
| 145 cache.add(cookies[i]); | |
| 146 removeCookie(cookies[i]); | |
| 147 } | |
| 148 }); | |
| 149 } | |
| 150 | |
| 151 function removeCookie(cookie) { | |
| 152 var url = "http" + (cookie.secure ? "s" : "") + "://" + cookie.domain + | |
| 153 cookie.path; | |
| 154 chrome.cookies.remove({"url": url, "name": cookie.name}); | |
| 155 } | |
| 156 | |
| 157 function removeCookiesForDomain(domain) { | |
| 158 var timer = new Timer(); | |
| 159 cache.getCookies(domain).forEach(function(cookie) { | |
| 160 removeCookie(cookie); | |
| 161 }); | |
| 162 } | |
| 163 | |
| 164 function resetTable() { | |
| 165 var table = select("#cookies"); | |
| 166 while (table.rows.length > 1) { | |
| 167 table.deleteRow(table.rows.length - 1); | |
| 168 } | |
| 169 } | |
| 170 | |
| 171 var reload_scheduled = false; | |
| 172 | |
| 173 function scheduleReloadCookieTable() { | |
| 174 if (!reload_scheduled) { | |
| 175 reload_scheduled = true; | |
| 176 setTimeout(reloadCookieTable, 250); | |
| 177 } | |
| 178 } | |
| 179 | |
| 180 function reloadCookieTable() { | |
| 181 reload_scheduled = false; | |
| 182 | |
| 183 var filter = select("#filter").value; | |
| 184 | |
| 185 var domains = cache.getDomains(filter); | |
| 186 | |
| 187 select("#filter_count").innerText = domains.length; | |
| 188 select("#total_count").innerText = cache.getDomains().length; | |
| 189 | |
| 190 select("#delete_all_button").innerHTML = ""; | |
| 191 if (domains.length) { | |
| 192 var button = document.createElement("button"); | |
| 193 button.onclick = removeAllForFilter; | |
| 194 button.innerText = "delete all " + domains.length; | |
| 195 select("#delete_all_button").appendChild(button); | |
| 196 } | |
| 197 | |
| 198 resetTable(); | |
| 199 var table = select("#cookies"); | |
| 200 | |
| 201 domains.forEach(function(domain) { | |
| 202 var cookies = cache.getCookies(domain); | |
| 203 var row = table.insertRow(-1); | |
| 204 row.insertCell(-1).innerText = domain; | |
| 205 var cell = row.insertCell(-1); | |
| 206 cell.innerText = cookies.length; | |
| 207 cell.setAttribute("class", "cookie_count"); | |
| 208 | |
| 209 var button = document.createElement("button"); | |
| 210 button.innerText = "delete"; | |
| 211 button.onclick = (function(dom){ | |
| 212 return function() { | |
| 213 removeCookiesForDomain(dom); | |
| 214 }; | |
| 215 }(domain)); | |
| 216 var cell = row.insertCell(-1); | |
| 217 cell.appendChild(button); | |
| 218 cell.setAttribute("class", "button"); | |
| 219 }); | |
| 220 } | |
| 221 | |
| 222 function focusFilter() { | |
| 223 select("#filter").focus(); | |
| 224 } | |
| 225 | |
| 226 function resetFilter() { | |
| 227 var filter = select("#filter"); | |
| 228 filter.focus(); | |
| 229 if (filter.value.length > 0) { | |
| 230 filter.value = ""; | |
| 231 reloadCookieTable(); | |
| 232 } | |
| 233 } | |
| 234 | |
| 235 var ESCAPE_KEY = 27; | |
| 236 window.onkeydown = function(event) { | |
| 237 if (event.keyCode == ESCAPE_KEY) { | |
| 238 resetFilter(); | |
| 239 } | |
| 240 } | |
| 241 | |
| 242 function listener(info) { | |
| 243 cache.remove(info.cookie); | |
| 244 if (!info.removed) { | |
| 245 cache.add(info.cookie); | |
| 246 } | |
| 247 scheduleReloadCookieTable(); | |
| 248 } | |
| 249 | |
| 250 function startListening() { | |
| 251 chrome.cookies.onChanged.addListener(listener); | |
| 252 } | |
| 253 | |
| 254 function stopListening() { | |
| 255 chrome.cookies.onChanged.removeListener(listener); | |
| 256 } | |
| 257 | |
| 258 function onload() { | |
| 259 focusFilter(); | |
| 260 var timer = new Timer(); | |
| 261 chrome.cookies.getAll({}, function(cookies) { | |
| 262 startListening(); | |
| 263 start = new Date(); | |
| 264 for (var i in cookies) { | |
| 265 cache.add(cookies[i]); | |
| 266 } | |
| 267 timer.reset(); | |
| 268 reloadCookieTable(); | |
| 269 }); | |
| 270 } | |
| 271 | |
| 272 | |
| 273 </script> | |
| 274 </head> | 25 </head> |
| 275 | 26 |
| 276 <body onload="onload()" onclick="focusFilter()"> | 27 <body> |
| 277 <h2>Cookies! ... Nom Nom Nom...</h2> | 28 <h2>Cookies! ... Nom Nom Nom...</h2> |
| 278 <button onclick="removeAll()">DELETE ALL!</button> | 29 <button id="remove_button">DELETE ALL!</button> |
| 279 <div id="filter_div"> | 30 <div id="filter_div"> |
| 280 Filter: <input id="filter" type="text" oninput="reloadCookieTable()"> | 31 Filter: <input id="filter" type="text"> |
| 281 <button onclick="resetFilter()">x</button> | 32 <button>x</button> |
| 282 </div> | 33 </div> |
| 283 <br> | 34 <br /> |
| 284 <div id="summary_div"> | 35 <div id="summary_div"> |
| 285 Showing <span id="filter_count"></span> of <span id="total_count"></span> cookie
domains. | 36 Showing <span id="filter_count"></span> of <span id="total_count"></span> cook
ie domains. |
| 286 <span id="delete_all_button"></span> | 37 <span id="delete_all_button"></span> |
| 287 </div> | 38 </div> |
| 288 <br> | 39 <br /> |
| 289 <table id="cookies"> | 40 <table id="cookies"> |
| 290 <tr class="header"> | 41 <tr class="header"> |
| 291 <th>Name</th> | 42 <th>Name</th> |
| 292 <th>#Cookies</th> | 43 <th>#Cookies</th> |
| 293 </tr> | 44 </tr> |
| 294 </table> | 45 </table> |
| 295 | 46 |
| 296 </body> | 47 </body> |
| 297 </html> | 48 </html> |
| OLD | NEW |