Skip to content

Commit

Permalink
Add Delete History feature
Browse files Browse the repository at this point in the history
Part of #17
  • Loading branch information
stoically committed Feb 3, 2018
1 parent 4cfc35f commit 47a7848
Show file tree
Hide file tree
Showing 9 changed files with 136 additions and 19 deletions.
8 changes: 8 additions & 0 deletions manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,12 @@
},
"description": "Open a new Tab in a new Temporary Container"
},
"new_no_history_tab": {
"suggested_key": {
"default": "Alt+P"
},
"description": "Open a new Tab in a new 'Deletes History Temporary Container'"
},
"new_no_container_tab": {
"suggested_key": {
"default": "Alt+N"
Expand All @@ -57,6 +63,8 @@
"contextMenus",
"contextualIdentities",
"cookies",
"history",
"management",
"storage",
"tabs",
"webRequest",
Expand Down
42 changes: 42 additions & 0 deletions options/options.html
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
<a class="item active" data-tab="general">General</a>
<a class="item" data-tab="mouseclicks">Mouse Clicks</a>
<a class="item" data-tab="alwaysopenin">Always per Website</a>
<a class="item" data-tab="advanced">Advanced</a>
</div>
<div class="ui bottom attached active tab segment" data-tab="general">
<form class="ui form">
Expand Down Expand Up @@ -238,6 +239,47 @@ <h3>Website Rules</h3>
</div>
</form>
</div>
<div class="ui bottom attached tab segment" data-tab="advanced">
<form class="ui form">
<div id="advancedPreferences">
<div class="field">
<label>Delete History</label>
<div class="ui negative message">
<strong>
WARNING: EVERY WEBSITE URL that you visit in a
"Deletes History Temporary Container" WILL GET DELETED FROM YOUR HISTORY.
This means if you visited a Website URL in another Container, Temporary Container
or in No Container before or while visiting it in a "Deletes History Temporary Container"
- those visits will get deleted from History too. This is true until Firefox supports a special History for Container Tabs.
<a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1283320">The related Bug can be found here</a>.<br>
<br>
You can open "Deletes History Temporary Containers" with the keyboard shortcut Alt+P instead of configuring it here. The same WARNING applies.<br>
<br>
"Deletes History Temporary Containers" will delete history when the "Deletes History Temporary Container" itself gets deleted.<br>
<br>
Be careful. You have been warned. "Deletes History Temporary Containers" tabs have a "-deletes-history" suffix
in the container name to remind you.
</strong>
</div>
<select id="deletesHistoryContainer" class="ui fluid dropdown">
<option value="never">DO NOT automatically create "Deletes History Temporary Containers"</option>
<option value="automatic">Automatically create "Deletes History Temporary Containers" instead of normal Temporary Containers</option>
</select>
</div>
<div class="field">
<label>Mouse Clicks in "Deletes History Temporary Containers"</label>
<select id="deletesHistoryContainerMouseClicks" class="ui fluid dropdown">
<option value="never">Default</option>
<option value="automatic">Open New "Deletes History Temporary Containers" with Mouse Clicks in "No History Temporary Containers" instead of normal
Temporary Containers. Same behavior regarding Mouse Clicks and the Mouse Clicks configuration still applies.</option>
</select>
</div>
<div class="field">
<button id="saveAdvancedPreferences" class="ui button primary">Save</button>
</div>
</div>
</form>
</div>
<div id="message" class="ui positive message hidden"></div>
</div>

Expand Down
13 changes: 13 additions & 0 deletions options/options.js
Original file line number Diff line number Diff line change
Expand Up @@ -156,6 +156,15 @@ const updateAlwaysOpenInDomainRules = () => {
}
};

const saveAdvancedPreferences = async (event) => {
event.preventDefault();

preferences.deletesHistoryContainer = document.querySelector('#deletesHistoryContainer').value;
preferences.deletesHistoryContainerMouseClicks = document.querySelector('#deletesHistoryContainerMouseClicks').value;

await savePreferences();
};

const initialize = async () => {
$('.menu .item').tab();
$('.ui.dropdown').dropdown();
Expand All @@ -180,6 +189,9 @@ const initialize = async () => {
document.querySelector('#linkClickGlobalLeftOverwritesAutomaticMode').checked =
preferences.linkClickGlobal.left.overwriteAutomaticMode;

$('#deletesHistoryContainer').dropdown('set selected', preferences.deletesHistoryContainer);
$('#deletesHistoryContainerMouseClicks').dropdown('set selected', preferences.deletesHistoryContainerMouseClicks);

updateLinkClickDomainRules();
updateAlwaysOpenInDomainRules();
};
Expand Down Expand Up @@ -245,4 +257,5 @@ const initialize = async () => {

document.addEventListener('DOMContentLoaded', initialize);
$('#saveContainerPreferences').on('click', saveContainerPreferences);
$('#saveAdvancedPreferences').on('click', saveAdvancedPreferences);
$('#saveLinkClickGlobalPreferences').on('click', saveLinkClickGlobalPreferences);
13 changes: 10 additions & 3 deletions src/background.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class TemporaryContainers extends Emittery {


async initialize() {
new MultiAccountContainers(this);
this.mac = new MultiAccountContainers(this);

this.request.initialize(this);
this.container.initialize(this);
Expand All @@ -41,7 +41,7 @@ class TemporaryContainers extends Emittery {
browser.tabs.onCreated.addListener(this.tabsOnCreated.bind(this));
browser.tabs.onUpdated.addListener(this.tabsOnUpdated.bind(this));
browser.tabs.onRemoved.addListener(this.tabsOnRemoved.bind(this));
browser.browserAction.onClicked.addListener(this.container.createTabInTempContainer.bind(this.container));
browser.browserAction.onClicked.addListener(this.browserActionOnClicked.bind(this));
browser.webRequest.onBeforeRequest.addListener(this.request.webRequestOnBeforeRequest.bind(this.request), {
urls: ['<all_urls>'],
types: ['main_frame']
Expand Down Expand Up @@ -88,6 +88,11 @@ class TemporaryContainers extends Emittery {
}


browserActionOnClicked(tab, url) {
this.container.createTabInTempContainer({tab, url});
}


async tabsOnCreated(tab) {
debug('[browser.tabs.onCreated] tab created', tab);
if (tab.incognito) {
Expand Down Expand Up @@ -161,7 +166,7 @@ class TemporaryContainers extends Emittery {
async contextMenusOnClicked(info, tab) {
switch (info.menuItemId) {
case 'open-link-in-new-temporary-container-tab':
this.container.createTabInTempContainer(tab, info.linkUrl, null, false, true);
this.container.createTabInTempContainer({tab, url: info.linkUrl, active: false});
break;
}
}
Expand Down Expand Up @@ -194,6 +199,8 @@ class TemporaryContainers extends Emittery {
}
break;

case 'new_no_history_tab':
this.container.createTabInTempContainer({deletesHistory: true});
}
}

Expand Down
29 changes: 24 additions & 5 deletions src/background/container.js
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class Container {
}


async createTabInTempContainer(tab, url, alwaysOpenIn, active, dontPin) {
async createTabInTempContainer({tab, url, alwaysOpenIn = false, active = false, dontPin = true, deletesHistory = false}) {
let tempContainerNumber;
if (this.storage.local.preferences.containerNumberMode === 'keep') {
this.storage.local.tempContainerCounter++;
Expand All @@ -53,7 +53,10 @@ class Container {
if (this.storage.local.preferences.containerNumberMode === 'reuse') {
tempContainerNumber = this.getReusedContainerNumber();
}
const containerName = `${this.storage.local.preferences.containerNamePrefix}${tempContainerNumber}`;
let containerName = `${this.storage.local.preferences.containerNamePrefix}${tempContainerNumber}`;
if (deletesHistory) {
containerName += '-deletes-history';
}
try {
let containerColor = this.storage.local.preferences.containerColor;
if (this.storage.local.preferences.containerColorRandom) {
Expand All @@ -72,6 +75,7 @@ class Container {
const contextualIdentity = await browser.contextualIdentities.create(containerOptions);
debug('[createTabInTempContainer] contextualIdentity created', contextualIdentity);
containerOptions.number = tempContainerNumber;
containerOptions.deletesHistory = deletesHistory;
this.storage.local.tempContainers[contextualIdentity.cookieStoreId] = containerOptions;
await this.storage.persist();

Expand Down Expand Up @@ -110,8 +114,9 @@ class Container {
}


async reloadTabInTempContainer(tab, url, active) {
const newTab = await this.createTabInTempContainer(tab, url, false, active);
async reloadTabInTempContainer(tab, url, active, deletesHistory) {
console.log('??', deletesHistory)
const newTab = await this.createTabInTempContainer({tab, url, active, deletesHistory});
if (!tab) {
return newTab;
}
Expand Down Expand Up @@ -165,7 +170,11 @@ class Container {
(tab.url === 'about:home' ||
tab.url === 'about:newtab')) {
debug('[maybeReloadTabInTempContainer] about:home/new tab in firefox-default container, reload in temp container', tab);
await this.reloadTabInTempContainer(tab);
let deletesHistoryContainer = false;
if (this.storage.local.preferences.deletesHistoryContainer === 'automatic') {
deletesHistoryContainer = true;
}
await this.reloadTabInTempContainer(tab, null, null, deletesHistoryContainer);
return;
}

Expand Down Expand Up @@ -206,6 +215,16 @@ class Container {
} catch (error) {
debug('[tryToRemoveContainer] error while removing container', cookieStoreId, error);
}
if (this.storage.local.tempContainers[cookieStoreId].deletesHistory &&
this.storage.local.tempContainers[cookieStoreId].history) {
Object.keys(this.storage.local.tempContainers[cookieStoreId].history).map(url => {
if (!url) {
return;
}
debug('[tryToRemoveContainer] removing url from history', url);
browser.history.deleteUrl({url});
});
}
delete this.storage.local.tempContainers[cookieStoreId];
await this.storage.persist();
}
Expand Down
33 changes: 25 additions & 8 deletions src/background/request.js
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,19 @@ class Request {
}
}

if (tab.cookieStoreId !== 'firefox-default' &&
this.storage.local.tempContainers[tab.cookieStoreId] &&
this.storage.local.tempContainers[tab.cookieStoreId].deletesHistory) {
if (!this.storage.local.tempContainers[tab.cookieStoreId].history) {
this.storage.local.tempContainers[tab.cookieStoreId].history = {};
}
this.storage.local.tempContainers[tab.cookieStoreId].history[request.url] = {
tabId: request.tabId,
timeStamp: request.timeStamp
};
await this.storage.persist();
}

if (alwaysOpenIn && !this.mouseclick.linksClicked[request.url] && tab.openerTabId) {
debug('[browser.webRequest.onBeforeRequest] always open in tmpcontainer request, simulating click', request);
this.linkClicked(request.url, {
Expand Down Expand Up @@ -101,8 +114,13 @@ class Request {
return;
}

let newTab;
newTab = await this.container.reloadTabInTempContainer(tab, request.url);
let deletesHistoryContainer = false;
if (this.storage.local.tempContainers[tab.cookieStoreId] &&
this.storage.local.tempContainers[tab.cookieStoreId].deletesHistory &&
this.storage.local.preferences.deletesHistoryContainerMouseClicks === 'automatic') {
deletesHistoryContainer = true;
}
const newTab = await this.container.reloadTabInTempContainer(tab, request.url, null, deletesHistoryContainer);
debug('[handleClickedLink] created new tab', newTab);

await this.background.emit('handleClickedLinkAfterReload', {request, newTab});
Expand All @@ -113,7 +131,6 @@ class Request {


async handleNotClickedLink(request, tab) {

let containerExists = false;
if (tab.cookieStoreId === 'firefox-default') {
containerExists = true;
Expand All @@ -125,8 +142,6 @@ class Request {
}
}



const hook = await this.background.emit('handleNotClickedLink', {request, tab, containerExists});
if (typeof hook[0] !== 'undefined') {
if (!hook[0]) {
Expand All @@ -140,15 +155,17 @@ class Request {
return;
}

let deletesHistoryContainer = false;
if (this.storage.local.preferences.deletesHistoryContainer === 'automatic') {
deletesHistoryContainer = true;
}
debug('[handleNotClickedLink] onBeforeRequest reload in temp tab', tab, request);
await this.container.reloadTabInTempContainer(tab, request.url, true);
await this.container.reloadTabInTempContainer(tab, request.url, true, deletesHistoryContainer);

return { cancel: true };
}




shouldAlwaysOpenInTemporaryContainer(request) {
const parsedRequestURL = new URL(request.url);

Expand Down
4 changes: 3 additions & 1 deletion src/background/storage.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ class Storage {
containerIcon: 'circle',
containerIconRandom: false,
containerNumberMode: 'keep',
iconColor: 'default'
iconColor: 'default',
deletesHistoryContainer: 'never',
deletesHistoryContainerMouseClicks: 'never'
};
}

Expand Down
6 changes: 4 additions & 2 deletions test/background.browseractions.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@ describe('when triggering browseraction', () => {
name: 'tmp1',
color: 'red',
icon: 'circle',
number: 1
number: 1,
deletesHistory: false
});
browser.tabs.create.should.have.been.calledWith({
url: undefined,
Expand Down Expand Up @@ -47,7 +48,8 @@ describe('when triggering browseraction', () => {
name: sinon.match.string,
color: sinon.match.string,
icon: sinon.match.string,
number: 1
number: 1,
deletesHistory: false
});
browser.tabs.create.should.have.been.calledWith({
url: undefined,
Expand Down
7 changes: 7 additions & 0 deletions test/setup.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
if (!process.listenerCount('unhandledRejection')) {
// eslint-disable-next-line no-console
process.on('unhandledRejection', r => console.log(r));
}
const chai = require('chai');
const sinonChai = require('sinon-chai');
global.reload = require('require-reload')(require);
Expand Down Expand Up @@ -75,6 +79,9 @@ global.injectBrowser = () => {
onCommand: {
addListener: sinon.stub()
}
},
history: {
deleteUrl: sinon.stub()
}
};
};
Expand Down

0 comments on commit 47a7848

Please sign in to comment.