From a5409a6b2a66bfd85a902c468b726e1e60855c71 Mon Sep 17 00:00:00 2001 From: Mike Frysinger Date: Tue, 29 Jan 2013 15:55:33 -0500 Subject: [PATCH] clearhistory-1.5 --- _locales/en/messages.json | 39 +++++++++ _locales/es_419/messages.json | 1 + _locales/pt_BR/messages.json | 1 + css/options.css | 145 ++++++++++++++++++++++++++++++++++ images/check.png | Bin 0 -> 328 bytes images/icon128.png | Bin 0 -> 16022 bytes images/icon16.png | Bin 0 -> 1578 bytes images/icon32.png | Bin 0 -> 2817 bytes images/icon48.png | Bin 0 -> 4403 bytes javascript/background.js | 42 ++++++++++ javascript/clearhistory.js | 121 ++++++++++++++++++++++++++++ javascript/options.js | 86 ++++++++++++++++++++ javascript/util.js | 51 ++++++++++++ manifest.json | 37 +++++++++ views/options.html | 77 ++++++++++++++++++ 15 files changed, 600 insertions(+) create mode 100644 _locales/en/messages.json create mode 100644 _locales/es_419/messages.json create mode 100644 _locales/pt_BR/messages.json create mode 100644 css/options.css create mode 100644 images/check.png create mode 100644 images/icon128.png create mode 100644 images/icon16.png create mode 100644 images/icon32.png create mode 100644 images/icon48.png create mode 100644 javascript/background.js create mode 100644 javascript/clearhistory.js create mode 100644 javascript/options.js create mode 100644 javascript/util.js create mode 100644 manifest.json create mode 100644 views/options.html diff --git a/_locales/en/messages.json b/_locales/en/messages.json new file mode 100644 index 0000000..ce29f1d --- /dev/null +++ b/_locales/en/messages.json @@ -0,0 +1,39 @@ +{ + "name": {"message": "Clear History"}, + "description": {"message": "Quickly clears the browser history."}, + "title": {"message": "Click to clear history"}, + "direction": {"message": "ltr"}, + "optionsTitle": {"message": "Options for Clear History"}, + "optionsHeader": {"message": "Clear History"}, + "optionsTimeFor": {"message": "Delete history for:"}, + "optionsTime": { + "message": "Last $num$ $units$", + "placeholders": { + "num": {"content": "$1"}, + "units": {"content": "$2"} + } + }, + "optionsTimeAll": {"message": "Everything"}, + "optionsPrompt": {"message": "Prompt before deleting"}, + "optionsSaved": {"message": "Preferences saved!"}, + "confirmPrompt": {"message": "Are you sure you want to delete the history?"}, + "notificationTitle": {"message": "History deleted successfully!"}, + "notificationTime": { + "message": "for the last $num$ $units$", + "placeholders": { + "num": {"content": "$1"}, + "units": {"content": "$2"} + } + }, + "notificationTimeAll": {"message": "from the beginning of time"}, + "notificationBody": { + "message": "History deleted $when$.", + "placeholders": { + "when": {"content": "$1"} + } + }, + "hourString": {"message": "hour"}, + "hoursString": {"message": "hours"}, + "dayString": {"message": "day"}, + "daysString": {"message": "days"} +} diff --git a/_locales/es_419/messages.json b/_locales/es_419/messages.json new file mode 100644 index 0000000..3129d39 --- /dev/null +++ b/_locales/es_419/messages.json @@ -0,0 +1 @@ +{"direction":{"message":"ltr"},"name":{"message":"Borrar historial"},"description":{"message":"Borra r\u00e1pidamente el historial del navegador."},"title":{"message":"Haz clic para borrar el historial."},"optionstitle":{"message":"Opciones para Borrar historial"},"optionsheader":{"message":"Borrar historial"},"optionstimefor":{"message":"Eliminar el historial de:"},"optionstime":{"message":"\u00daltimas $1 $2","placeholders":{"1":{"content":"$1"},"2":{"content":"$2"}}},"optionstimeall":{"message":"Todo"},"optionsprompt":{"message":"Preguntar antes de eliminar"},"optionssaved":{"message":"Preferencias guardadas"},"confirmprompt":{"message":"\u00bfEst\u00e1s seguro de que deseas eliminar el historial?"},"notificationtitle":{"message":"El historial se elimin\u00f3 correctamente."},"notificationtime":{"message":"para las \u00faltimas $1 $2","placeholders":{"1":{"content":"$1"},"2":{"content":"$2"}}},"notificationtimeall":{"message":"desde el principio"},"notificationbody":{"message":"Historial eliminado el $1","placeholders":{"1":{"content":"$1"}}},"hourstring":{"message":"hora"},"hoursstring":{"message":"horas"},"daystring":{"message":"d\u00eda"},"daysstring":{"message":"d\u00edas"}} diff --git a/_locales/pt_BR/messages.json b/_locales/pt_BR/messages.json new file mode 100644 index 0000000..6ab5ef3 --- /dev/null +++ b/_locales/pt_BR/messages.json @@ -0,0 +1 @@ +{"direction":{"message":"ltr"},"name":{"message":"Limpar hist\u00f3rico"},"description":{"message":"Limpa rapidamente o hist\u00f3rico do navegador."},"title":{"message":"Clique para limpar o hist\u00f3rico"},"optionstitle":{"message":"Op\u00e7\u00f5es para Limpar hist\u00f3rico"},"optionsheader":{"message":"Limpar hist\u00f3rico"},"optionstimefor":{"message":"Excluir hist\u00f3rico para:"},"optionstime":{"message":"\u00daltimos $1 $2","placeholders":{"1":{"content":"$1"},"2":{"content":"$2"}}},"optionstimeall":{"message":"Tudo"},"optionsprompt":{"message":"Perguntar antes de excluir"},"optionssaved":{"message":"Prefer\u00eancias salvas"},"confirmprompt":{"message":"Deseja excluir o hist\u00f3rico?"},"notificationtitle":{"message":"Hist\u00f3rico exclu\u00eddo."},"notificationtime":{"message":"at\u00e9 os \u00faltimos $1 $2","placeholders":{"1":{"content":"$1"},"2":{"content":"$2"}}},"notificationtimeall":{"message":"desde o come\u00e7o"},"notificationbody":{"message":"Hist\u00f3rico exclu\u00eddo $1","placeholders":{"1":{"content":"$1"}}},"hourstring":{"message":"hora"},"hoursstring":{"message":"horas"},"daystring":{"message":"dia"},"daysstring":{"message":"dias"}} diff --git a/css/options.css b/css/options.css new file mode 100644 index 0000000..9b8ed34 --- /dev/null +++ b/css/options.css @@ -0,0 +1,145 @@ +/* Copyright 2011 Google Inc. All Rights Reserved. */ + +/** + * @fileoverview The styles for elements of the options page + * @author arunjit@google.com (Arunjit Singh) + */ + +@CHARSET "UTF-8"; +body { + background-color: #eef; + color: #222; + direction: __MSG_@@bidi_dir__; /* Predefined message from Chrome Extension */ + font: 13px/18px "Arial"; +} +header { + color: #333; + margin: 0 auto; + text-align: left; + width: 400px; +} +h1 { + color: #dd4b39; + font: 20px/24px "Arial" normal; + margin: 5px 0 0; + padding: 0 5px 3px; +} +h1 > img, +h1 > span { + vertical-align: middle; +} +hr { + background-color: #ebebeb; + border: none; + clear: both; + height: 1px; + margin: 5px auto; + width: 400px; +} +#content { + background-color: #fff; + border: 4px solid rgba(0, 0, 0, 0.2); + border-radius: 12px; + margin: 40px auto 0; + padding: 10px 10px 0; + width: 500px; +} +#opt-form { + margin: 10px auto; + overflow: hidden; + width: 400px; +} +#opt-time, +#opt-prompt { + background-color: white; + clear: left; + margin: 5px auto; + overflow: hidden; + padding: 5px 5px; +} +.opt-name { + float: left; + width: 175px; +} +.opt-value { + float: left; + width: 215px; +} +.opt-value .opt-option { + clear: left; + margin-bottom: 5px; + overflow: hidden; +} +.opt-value .opt-option .opt-chk { + float: left; +} +.opt-value .opt-option .opt-label { + float: left; + margin-top: -3px; + padding-left: 6px; +} +#optionsSaved { + clear: left; + margin: 10px auto 5px; + padding: 5px; + text-align: center; +} +#optionsSaved b { + background-color: #f9edbe; + border: 1px solid #f0c36d; + border-radius: 2px; + color: #333; + font-weight: normal; + opacity: 0; + padding: 6px 16px; + -webkit-transition: opacity 130ms ease-in-out; +} +#optionsSaved.show b { + opacity: 1; + -webkit-transition: opacity 50ms ease-in-out; +} +input[type="checkbox"], +input[type="radio"] { + -webkit-appearance: none; + background-color: white; + border: 1px solid #dcdcdc; + height: 13px; + margin: 0; + width: 13px; +} +input[type="radio"] { + border-radius: 50%; + height: 15px; + width: 15px; +} +input[type="checkbox"]:hover, +input[type="radio"]:hover { + border-color: #c6c6c6; + -webkit-box-shadow: inset 0px 1px 1px rgba(0,0,0,0.1) +} +input[type="checkbox"]:active, +input[type="radio"]:active { + background-color: #ebebeb; + border-color: #c6c6c6; +} +input[type="radio"]:checked::after { + background: #666; + border-radius: 50%; + content: ''; + display: block; + height: 7px; + margin: 3px auto; + width: 7px; +} +input[type="checkbox"]:checked::after { + content: url('../images/check.png'); + display: block; + left: -5px; + position: relative; + top: -6px; +} +input[type="checkbox"]:focus, +input[type="radio"]:focus { + outline: none; + border-color: #4d90fe; +} diff --git a/images/check.png b/images/check.png new file mode 100644 index 0000000000000000000000000000000000000000..d049b55ac84628f9b0fdaf59eb29b25737fd4b0f GIT binary patch literal 328 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 literal 0 HcmV?d00001 diff --git a/images/icon16.png b/images/icon16.png new file mode 100644 index 0000000000000000000000000000000000000000..547908b21251d9b6dab808c7edc36cad1b158e33 GIT binary patch literal 1578 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`k|nMYCBgY=CFO}lsSJ)O`AMk? zp1FzXsX?iUDV2pMQ*9U+nA0*tB1$5BeXNr6bM+EIYV;~{3xK*A7;Nk-3KEmEQ%e+* zQqwc@Y?a>c-mj#PnPRIHZt82`Ti~3Uk?B!Ylp0*+7m{3+ootz+WN)WnQ(*-(AUCxn zQK2F?C$HG5!d3}vt`(3C64qBz04piUwpD^SD#ABF!8yMuRl!uxKsVXI%s|1+P|wiV z#N6CmN5ROz&_Lh7NZ-&%*U;R`*vQJjKmiJrfVLH-q*(>IxIyg#@@$ndN=gc>^!3Zj z%k|2Q_413-^$jg8EkR}&8R-I5=oVMzl_XZ^<`pZ$OmImpPA){ffi_eM3D1{oGuTzrd=COM+4n&cLd=IHa;5RX-@T zIKQ+g85kdF$}r8qu)}W=NFmTQR{lkqz(`5Vami0E%}vcK@pQ3O0?O#6WTsddIXf8} zIa-()8W_@L;4_|_%0D6=dz#jPkmR{oF^Zu{erIt$E=j?#j7{TQtV?rIW@~r%Pg&C3-qD?IzDWb7uB)UX_K6zQqp? z)b9Cx&er&Q#|GYo(^nQdGkaZmJn37M+4-xb#@h^JE4XYOZXI3OIyHHp;Q8f$cekr* zSv3?lI7L4G>GbwX_l0>!{;bEx{RT-0(1E&Bcklp<5eGgla7}?ARKiu`)1iQ?_1f zU&gG+pi<*L;YYQ9kC>@F+uyE|=O5|vXIhs`9jo<%#}5vCHcg!#yhmQ9wEfN`h3mX& z72@XS|6S}^{gPYwsVu92IbY?|)4}@`4RZO`#2xguT=ROta*O$gf8Y0zeCd8|;_H?P zS?&j1D=nh+9gX4-&vMEum0V{(qxEr?ZqT06;;XY`&)-;o-%fGzI7E4K(Mzf}CU(e&fFyEm^1-&0K}3Xpg<{U*y{=L3qn6%uAX2+m$$ zc3iZ(L22=~OP4rp_{@CEIb}j#953pXn!4)9wpBtQUSe}*)^q$j!zOZP-P7~T=hjyl zS)O=zHuhi{^RELXS02}VcU&fI%w%clcl2|<#@{5q>c?|F*Ls|{Z{EV|9u-!+c5Cm} lUzdN}$g4A5ck!3@0S0Yd_HD(U6XQUox2LP0%Q~loCIFZOL&^XE literal 0 HcmV?d00001 diff --git a/images/icon32.png b/images/icon32.png new file mode 100644 index 0000000000000000000000000000000000000000..f6c0b67f0fec6488e71c080d05105187108ab5d2 GIT binary patch literal 2817 zcmbVOc{r478z1|=mdcjb#7POWFw8I*Ge*=%jK;BLj2BaQ$IQf7k3BkyBcdWp7fD5R zl%zP6GaSpYMI~uDmWV7xvVEg+zVDB7oj<rHcVw3CxolZL@y za`yX4&Vm)#cqPRJUruD?N5P`XwRPjVK>pltIva!${2*Ttun(pOfX*P@FCw%Rw1B}x z{FziYt{debjsXQ5(l=}jdBH3J8V0kl;<4zA;~*FC1p}BNc=(691~|a z`}yOXN#yUo1QH$|$mOzdMn>V`;fCR8Lx>$gE#W}YR%y~ zgZ~ZVAFVmm2o`AM4050oY=)p8{<}88g4+GNqYXnrG`K@-rl2YGAQHql5e$ZK?MZmJ z;Kb06>4!rRZO|x!nK2T9LSW30NHa19g(VQoh$hCiXd7eWO^$!Ul8{&umWaU;O;M&u zq%8t#YivRwkOgW}lweQZ#M*~&xbzSPxapTE@cSKW_ODnRkqy$h5St1?L7Nlc6bNx4 zP9Verh%P1oh0b7xY{(n!`IapSWHZA+KQbE%2ENu8$NUHXXsj)ngtkQ?2;cH15D8=~ z+Q!6&gd!1$STy`Q*6;tRnUNqEqmAMCpJCZl2_|r3`}gPzgugEj7$UeaY{AtqIB@+X z3?_lJClRQ;=hd_r7L}%AwfJ)J7Gzr2HhMOzQ}lv$d5<{mDk&7#+^5PHHpsc^d-aKY ze+k;LV3x6>z+WqVa;qQ#=fb>_?qqo^G|zd0x{q3&Wqnicy|H$&eRA}BTGmjx0YF4z|6q*Y!V6msjq+;6P9mzVv6~Ctl5~wX=2o`z*Lb*o(T!7hb0- zKb)tP4pT3t6O2n>wqtRl5*lUuw*TJd_>42eKk8mHUWyg#T6)oX4F8K+LTB!g>5&pOd zp`53Zsx~3qI6mO797#{TT43$nu}Z0q zTL`cK9!A~?<)u>~A$=Lx^+-{&Omf$wF4J6Ve5Xj1qcej0nbtJ6Qn)QeOC)ZsS!HeZ z{8mZFrl>Otd3Q6E-iVAHjncLX(0Fxbc`kd(F=B^*{8BEsUDSfB*Q+erJGrxxvh@bQ z8lruPt?_DCjhlw5EZ*LmcG;2@mj|iFXQp~4?JgX(gVly^`GFEpgZ>3?Hn`Vk;5g}y z=JC2{6SdHo2F>|Sy@Gc_Hb<;sOC@r;gM$>$d2@dKr*}Pa%;q`w*^g<aq&rDczd7Njohtz|Zn4?V1dTrRb`aJJ;lNb+%=fi-*Jw;L? zgD8xqj^#n$wE7H<&$MoQYvQZ4ddko1m@6>%*!e}BYYrOj?u_dbfd`X2cIOF#q^BpX zz}9!@+br&nh!bDC@baWb)Yx^|9Je>>>2t1fNEPF2sYO+qj+{5ziecM*q zNulHFS|=ORW@oDRUUDy$J)HoZpLscB%c{%x?d5LM#zh5ad1Z;Sx_GVPc~4)TjtOB{ zjebD+#?RinCi^vZ|77uia5%f4XHoAnKiUy#YvAmOqLQVx- zq6>>DZcnznS373F8-Id#GS3q7Ek9+SP<7TP#_?fH^V9fJO5}mzuBw>2zT$K+zJWc1 zJT~YWG$m4}L=qo*Iv{49dQXI-aX1imAz^obXi%T3K4K(X8!QenG;pPy%M}oqe&MS1*XLVUM{;YMZzks1B-e9qS-W2> zv@uN2D|<&3wcZn4q+`v$edw)f3wXBk%BSDUp}59FG2;6u5?{tljmJHgw zh{WCB%&(X$k>=N_DZwU6W(7t>k^Tn5f~TBUApKg(=f z1G++mK9pi;xel2VA94@o@AiJNB>5~5y^wb3LaQI@rxU8NfUvsyJC3;aNP26LkACJI zYKxCnO9^<8iA(ove>BvvBBj$^tD#qdvg_7kIiS2k8T{7NOXi7_&!TsdAfr^yJG0@X zK|YW_Ds^K={3opj=K8PvsE%IS+sLtQvSvc6z64RbVkSfRHpfEi0BxX8jq!*qJ>Lg# zRMPIr=4%D%{WxZM(IKzE#v=W)R|P&dQD;HQ*=1e)40qSl3saL)J?o4q-W*>mO&zLF z*F8(`3k|9Jbn@w>u8Las^oP{(!9wvJ5fYrSCuL#J>@x0VJCwTjNl#5Y%>J=r9Js3) zJe)mcP*rG$PFdKAkBqL9{0S4^9{MF|Y9{i*QSuWNOzH6a^XFyK3`XbL>hfxBYMiLI zKGvMEC*t;{OFK`b(B^18Hq~ID%wOhnQB<4ADev`dKCqo(;XROL!Tyb(QhQrRQl*Vg G!hZn1pu7SA literal 0 HcmV?d00001 diff --git a/images/icon48.png b/images/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..d768e45beb1fa8cfff483c729a704320923cda89 GIT binary patch literal 4403 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 eternity. + * @type {Array.} + * @const + */ + TIMES: [-1, 1, 2, 24, 168], + /** + * The default time (in hours) + * @type {number} + * @const + */ + DEFAULT_TIME: 1, + /** + * String for 'yes'. @see {@code CONSTANTS.NO} + * @type {string} + * @const + */ + YES: 'yes', + /** + * String for 'no' that doesn't evaluate to a falsy value. + * @type {string} + * @const + */ + NO: 'no' +}; + +/** + * Go to the options page on first run + */ +if (!localStorage['options-set']) { + var optionsPageURL = chrome.extension.getURL('/views/options.html'); + chrome.tabs.create({url: optionsPageURL}); + localStorage['options-set'] = 1; +} diff --git a/javascript/clearhistory.js b/javascript/clearhistory.js new file mode 100644 index 0000000..af8fdce --- /dev/null +++ b/javascript/clearhistory.js @@ -0,0 +1,121 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +/** + * @fileoverview The main script for the Clear History extension for Chrome. + * @author arunjit@google.com (Arunjit Singh) + */ + +/** + * Removes a single cookie + * @param {Object.} cookie The cookie to delete. + * @param {Function} callback The function to invoke when the cookie is deleted. + */ +function removeCookie(cookie, callback) { + var url = 'http' + (cookie.secure ? 's' : '') + '://' + cookie.domain + + cookie.path; + chrome.cookies.remove({url: url, name: cookie.name}, callback); +} + +/** + * Removes all cookies + * @param {Function=} callback The function to invoke when all cookies are + * deleted (optional). + */ +function clearCookies(callback) { + callback = callback || function() {}; + chrome.cookies.getAll({}, function(cookies) { + var len = cookies.length; + // Synchronize the cookie deletion and execute the callback only when all + // cookie deletion functions have called back (finished). + (function doCookieCleanup(i) { + if (i === len) { + callback(); + } else { + removeCookie(cookies[i], function() { + doCookieCleanup(i + 1); + }); + } + })(0); + }); +} + +/** + * Callback for when history deletion is successful + */ +function didClearHistory() { + var time = ~~(localStorage['time']) || CONSTANTS.DEFAULT_TIME; + time = getUnitsForTime(time); + var timeString = (time.time === -1) ? + chrome.i18n.getMessage('notificationTimeAll') : + chrome.i18n.getMessage('notificationTime', + [time.time, time.units]); + var message = chrome.i18n.getMessage('notificationBody', timeString); + var notification = webkitNotifications.createNotification( + chrome.extension.getURL('/images/icon48.png'), + chrome.i18n.getMessage('notificationTitle'), + message); + notification.show(); + setTimeout(function() { + notification.cancel(); + }, 5000); +} + +/** + * Clears the history for the amount of time stored in {@code localStorage} + */ +function clearHistory() { + //Get the values from localStorage + // time is in hours + var time = ~~(localStorage['time']) || CONSTANTS.DEFAULT_TIME; + if (time === -1) { + // Delete everything + chrome.history.deleteAll(didClearHistory); + } else { + // Create the range + var now = (new Date).getTime(); + var range = { + startTime: (now - time * 60 * 60 * 1000), // time from hrs to ms + endTime: now + }; + // Delete history in the range + chrome.history.deleteRange(range, didClearHistory); + } +} + +/** + * Executes when the user clicks the browser action. Uses stored values from + * {@code localStorage} + */ +chrome.browserAction.onClicked.addListener(function(tab) { + //calls the method to provide the Google Analytics Data + getAnalyticsData(); + // Get the value from localStorage + var showPrompt = localStorage['prompt'] || CONSTANTS.YES; + + // The confirmation message to ask + var message = chrome.i18n.getMessage('confirmPrompt'); + + // Clear cookies, and then clear the history + if (showPrompt === CONSTANTS.YES) { + confirm(message) && clearCookies(clearHistory); + } else { + clearCookies(clearHistory); + } +}); + + var _gaq = _gaq || []; +/** + * provides the Google analytics data + */ +function getAnalyticsData() { + _gaq.push(['_setAccount', 'UA-28968723-1']); + _gaq.push(['_trackPageview']); + + (function() { + var ga = document.createElement('script'); ga.type = 'text/javascript'; + ga.async = true; + ga.src = 'https://ssl.google-analytics.com/ga.js'; + var s = document.getElementsByTagName('script')[0]; + s.parentNode.insertBefore(ga, s); + })(); +} diff --git a/javascript/options.js b/javascript/options.js new file mode 100644 index 0000000..a3f3b01 --- /dev/null +++ b/javascript/options.js @@ -0,0 +1,86 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +/** + * @fileoverview Script for the options page. + * @author arunjit@google.com (Arunjit Singh) + */ + +window.addEventListener('load', init, false); + +//Get the constants from the background page +var CONSTANTS = chrome.extension.getBackgroundPage().CONSTANTS; + +/** + * Initializes the i18n strings. + * Loads values from localStorage and applies them to the elements + */ +function init() { + // Localize strings: + CONSTANTS.TIMES.forEach(function(time) { + var selector = 'input[name=time][value="{t}"], .opt-label#opt-{t}' + .supplant({t: time}); + var elements = $(selector); + time = getUnitsForTime(time); + var message = (time.time === -1) ? + chrome.i18n.getMessage('optionsTimeAll') : + chrome.i18n.getMessage('optionsTime', + [time.time, time.units]); + elements[0].title = message; + elements[1].innerText = message; + }); + + $('#optionsTitle')[0].innerText = chrome.i18n.getMessage('optionsTitle'); + $('#optionsHeader')[0].innerText = chrome.i18n.getMessage('optionsHeader'); + $('#optionsPrompt')[0].innerText = chrome.i18n.getMessage('optionsPrompt'); + $('#optionsTimeFor')[0].innerText = chrome.i18n.getMessage('optionsTimeFor'); + $('#optionsSaved > b')[0].innerText = chrome.i18n.getMessage('optionsSaved'); + + // Bind all the callbacks + $('#opt-time input.opt-chk[type=radio]').forEach(function(e) { + e.onclick = toggle; + }); + $('#opt-prompt input.opt-chk[type=checkbox]').forEach(function(e) { + e.onclick = setPrompt; + }); + + // Load or set localStorage data + var time = ~~(localStorage['time']) || + (localStorage['time'] = CONSTANTS.DEFAULT_TIME); + var showPrompt = localStorage['prompt'] || + (localStorage['prompt'] = CONSTANTS.YES); + + $('input[name=time][value="' + time + '"]')[0].checked = true; + $('input[name=prompt]')[0].checked = (showPrompt === CONSTANTS.YES); +} + +/** + * Toggles the value in localStorage for the element selected + * @this {HTMLInputElement} The element (radio button) that was clicked. + */ +function toggle() { + localStorage['time'] = this.value; + optionSaved(); +} + +/** + * Sets the {@code localStorage.prompt} property when selected + * @this {HTMLInputElement} The element (checkbox) that was clicked. + */ +function setPrompt() { + localStorage['prompt'] = this.checked ? CONSTANTS.YES : CONSTANTS.NO; + optionSaved(); +} + +// For rapid changes/saves +var isSaving = null; +/** + * Updates the UI to indicate save completed + */ +function optionSaved() { + var element = $('#optionsSaved')[0]; + element.classList.add('show'); + clearTimeout(isSaving); + isSaving = setTimeout(function() { + element.classList.remove('show'); + }, 1000); +} diff --git a/javascript/util.js b/javascript/util.js new file mode 100644 index 0000000..a428b3b --- /dev/null +++ b/javascript/util.js @@ -0,0 +1,51 @@ +// Copyright 2011 Google Inc. All Rights Reserved. + +/** + * @fileoverview Some basic, useful utility functions. + */ + +/** + * Pours the data in template string. + * @param {Object} datObject The data object to be filled in template string. + * @return {string} The new string created from template string and filled + * with the given data. + */ +String.prototype.supplant = function(datObject) { + return this.replace(/{([^{}]*)}/g, + function(match, firstSubMatch) { + var replace = datObject[firstSubMatch]; + return (typeof replace === 'string' || typeof replace === 'number') ? + replace : match; + }); +}; + +/** + * Queries the DOM. + * @param {string} selector Selector to execute. + * @param {HTMLElement=} context HTMLElement to query (optional). + * @return {Array.} Array of matched elements (non-live). + */ +function $(selector, context) { + if (!(context && context instanceof HTMLElement)) { + context = document; + } + return Array.prototype.slice.call(context.querySelectorAll(selector)); +} + +/** + * Provides units for time, given in hours, as hours or days. + * @param {number} time The time, in hours. + * @return {Object} The time and units of time (pluralized and localized). + */ +function getUnitsForTime(time) { + var units = 'hour'; + if (time >= 24) { + units = 'day'; + time = time / 24; + } + units = chrome.i18n.getMessage(units + (time === 1 ? '' : 's') + 'String'); + return { + time: time, + units: units + }; +} diff --git a/manifest.json b/manifest.json new file mode 100644 index 0000000..e50a4a7 --- /dev/null +++ b/manifest.json @@ -0,0 +1,37 @@ +{ + "name": "__MSG_name__", + "default_locale": "en", + "manifest_version": 2, + "version": "1.5", + "description": "__MSG_description__", + "permissions": [ + "tabs", + "history", + "cookies", + "notifications", + "http://*/*", + "https://*/*" + ], + "background": { + "scripts": [ + "javascript/background.js", + "javascript/util.js", + "javascript/clearhistory.js" + ] + }, + "options_page": "views/options.html", + "browser_action": { + "default_icon": "images/icon32.png", + "default_title": "__MSG_title__" + }, + "icons": { + "16": "images/icon16.png", + "32": "images/icon32.png", + "48": "images/icon48.png", + "128": "images/icon128.png" + }, + "web_accessible_resources": [ + "images/icon48.png" + ], + "content_security_policy": "script-src 'self' https://ssl.google-analytics.com; object-src 'self'" +} diff --git a/views/options.html b/views/options.html new file mode 100644 index 0000000..ad899fa --- /dev/null +++ b/views/options.html @@ -0,0 +1,77 @@ + + + + + + + + + + +
+
+

+ Clear History logo + +

+
+
+
+
+
+ +
+
+
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+ +
+ +
+
+
+
+
+
+
+   +
+
+
+ +
+
+
+
+
+
+ +
+
+
+ + + + -- 2.39.2