--- /dev/null
+{
+ "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"}
+}
--- /dev/null
+{"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"}}
--- /dev/null
+{"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"}}
--- /dev/null
+/* 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;
+}
--- /dev/null
+// Copyright 2013 Google Inc. All Rights Reserved.
+
+/**
+ * @fileoverview Background initialization.
+ * @author arunjit@google.com (Arunjit Singh)
+ */
+
+var CONSTANTS = {
+ /**
+ * The available time ranges (in hours). -1 => eternity.
+ * @type {Array.<number>}
+ * @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;
+}
--- /dev/null
+// 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>} 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);
+ })();
+}
--- /dev/null
+// 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);
+}
--- /dev/null
+// 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.<HTMLElement>} 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
+ };
+}
--- /dev/null
+{
+ "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'"
+}
--- /dev/null
+<!DOCTYPE html>
+<!-- Copyright 2011 Google Inc. All Rights Reserved. -->
+
+<!--
+ * @fileoverview The main options page for the extension to customize the time
+ * for cleaning the history and if prompt needs to be displayed
+ * @author arunjit@google.com (Arunjit Singh)
+-->
+<html>
+ <head>
+ <title id="optionsTitle"></title>
+ <link rel="stylesheet" type="text/css" href="../css/options.css">
+ </head>
+ <body>
+ <div id="content">
+ <header>
+ <h1>
+ <img alt="Clear History logo" src="../images/icon32.png">
+ <span id="optionsHeader"></span>
+ </h1>
+ </header>
+ <hr>
+ <div id="opt-form">
+ <div id="opt-time">
+ <div class="opt-name">
+ <b id="optionsTimeFor"></b>
+ </div>
+ <div class="opt-value">
+ <div class="opt-option">
+ <input name="time" class="opt-chk" type="radio" value="1"
+ tabindex="1" checked>
+ <div class="opt-label" id="opt-1"></div>
+ </div>
+ <!-- <br> -->
+ <div class="opt-option">
+ <input name="time" class="opt-chk" type="radio" value="2">
+ <div class="opt-label" id="opt-2"></div>
+ </div>
+ <!-- <br> -->
+ <div class="opt-option">
+ <input name="time" class="opt-chk" type="radio" value="24">
+ <div class="opt-label" id="opt-24"></div>
+ </div>
+ <!-- <br> -->
+ <div class="opt-option">
+ <input name="time" class="opt-chk" type="radio" value="168">
+ <div class="opt-label" id="opt-168"></div>
+ </div>
+ <!-- <br> -->
+ <div class="opt-option">
+ <input name="time" class="opt-chk" type="radio" value="-1">
+ <div class="opt-label" id="opt--1"></div>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <div id="opt-prompt">
+ <div class="opt-name">
+ <b> </b>
+ </div>
+ <div class="opt-value">
+ <div class="opt-option">
+ <input name="prompt" class="opt-chk" type="checkbox" checked>
+ <div class="opt-label" id="optionsPrompt"></div>
+ </div>
+ </div>
+ </div>
+ <hr>
+ <div id="optionsSaved">
+ <b></b>
+ </div>
+ </div>
+ </div>
+ <script src="../javascript/util.js"></script>
+ <script src="../javascript/options.js"></script>
+ </body>
+</html>