Merge branch 'assignment-manage' into shield-study

This commit is contained in:
Jonathan Kingston 2017-06-13 14:07:21 +01:00
commit d63e887ef7
4 changed files with 147 additions and 41 deletions

View file

@ -56,19 +56,25 @@ const assignManager = {
return this.area.remove([siteStoreKey]); return this.area.remove([siteStoreKey]);
}, },
deleteContainer(userContextId) { async deleteContainer(userContextId) {
const removeKeys = []; const sitesByContainer = await this.getByContainer(userContextId);
this.area.get().then((siteConfigs) => { this.area.remove(Object.keys(sitesByContainer));
},
async getByContainer(userContextId) {
const sites = {};
const siteConfigs = await this.area.get();
Object.keys(siteConfigs).forEach((key) => { Object.keys(siteConfigs).forEach((key) => {
// For some reason this is stored as string... lets check them both as that // For some reason this is stored as string... lets check them both as that
if (String(siteConfigs[key].userContextId) === String(userContextId)) { if (String(siteConfigs[key].userContextId) === String(userContextId)) {
removeKeys.push(key); const site = siteConfigs[key];
// In hindsight we should have stored this
// TODO file a follow up to clean the storage onLoad
site.hostname = key.replace(/^siteContainerMap@@_/, "");
sites[key] = site;
} }
}); });
this.area.remove(removeKeys); return sites;
}).catch((e) => {
throw e;
});
} }
}, },
@ -152,12 +158,8 @@ const assignManager = {
// let actionName; // let actionName;
let remove; let remove;
if (info.menuItemId === this.MENU_ASSIGN_ID) { if (info.menuItemId === this.MENU_ASSIGN_ID) {
//actionName = "added";
// storageAction = this._setAssignment(info.pageUrl, userContextId, setOrRemove);
remove = false; remove = false;
} else { } else {
// actionName = "removed";
//storageAction = this.storageArea.remove(info.pageUrl);
remove = true; remove = true;
} }
await this._setOrRemoveAssignment(info.pageUrl, userContextId, remove); await this._setOrRemoveAssignment(info.pageUrl, userContextId, remove);
@ -228,6 +230,10 @@ const assignManager = {
return false; return false;
}, },
_getByContainer(userContextId) {
return this.storageArea.getByContainer(userContextId);
},
removeContextMenu() { removeContextMenu() {
// There is a focus issue in this menu where if you change window with a context menu click // There is a focus issue in this menu where if you change window with a context menu click
// you get the wrong menu display because of async // you get the wrong menu display because of async
@ -434,11 +440,11 @@ const messageHandler = {
return assignManager._getAssignment(tab); return assignManager._getAssignment(tab);
}); });
break; break;
case "getAssignmentObjectByContainer":
response = assignManager._getByContainer(m.message.userContextId);
break;
case "setOrRemoveAssignment": case "setOrRemoveAssignment":
response = browser.tabs.get(m.tabId).then((tab) => { response = assignManager._setOrRemoveAssignment(m.url, m.userContextId, m.value);
const userContextId = assignManager.getUserContextIdFromCookieStore(tab);
return assignManager._setOrRemoveAssignment(tab.url, userContextId, m.value);
});
break; break;
case "exemptContainerAssignment": case "exemptContainerAssignment":
response = assignManager._exemptTab(m); response = assignManager._exemptTab(m);

View file

@ -19,6 +19,13 @@ html {
box-sizing: inherit; box-sizing: inherit;
} }
form {
margin-block-end: 0;
margin-block-start: 0;
margin-inline-end: 0;
margin-inline-start: 0;
}
table { table {
border: 0; border: 0;
border-spacing: 0; border-spacing: 0;
@ -581,6 +588,10 @@ span ~ .panel-header-text {
padding-block-start: 4px; padding-block-start: 4px;
} }
.container-info-list tbody {
display: contents;
}
.clickable { .clickable {
cursor: pointer; cursor: pointer;
} }
@ -631,6 +642,32 @@ span ~ .panel-header-text {
padding-inline-start: 16px; padding-inline-start: 16px;
} }
#edit-sites-assigned {
flex: 1;
}
#edit-sites-assigned h3 {
font-size: 14px;
font-weight: normal;
padding-block-end: 5px;
padding-inline-end: 16px;
padding-inline-start: 16px;
}
#edit-sites-assigned table td {
display: flex;
padding-inline-end: 16px;
padding-inline-start: 16px;
}
#edit-sites-assigned .delete-assignment {
display: none;
}
#edit-sites-assigned tr:hover > td > .delete-assignment {
display: block;
}
.column-panel-content form span { .column-panel-content form span {
align-items: center; align-items: center;
block-size: 44px; block-size: 44px;
@ -679,6 +716,10 @@ span ~ .panel-header-text {
padding-inline-start: 0; padding-inline-start: 0;
} }
.edit-container-panel fieldset:last-of-type {
margin-block-end: 0;
}
.edit-container-panel input[type="text"] { .edit-container-panel input[type="text"] {
block-size: 36px; block-size: 36px;
border-radius: 3px; border-radius: 3px;

View file

@ -119,7 +119,9 @@ const Logic = {
}, },
addEnterHandler(element, handler) { addEnterHandler(element, handler) {
element.addEventListener("click", handler); element.addEventListener("click", (e) => {
handler(e);
});
element.addEventListener("keydown", (e) => { element.addEventListener("keydown", (e) => {
if (e.keyCode === 13) { if (e.keyCode === 13) {
handler(e); handler(e);
@ -208,6 +210,11 @@ const Logic = {
return this._currentIdentity; return this._currentIdentity;
}, },
currentUserContextId() {
const identity = Logic.currentIdentity();
return Logic.userContextId(identity.cookieStoreId);
},
sendTelemetryPayload(message = {}) { sendTelemetryPayload(message = {}) {
if (!message.event) { if (!message.event) {
throw new Error("Missing event name for telemetry"); throw new Error("Missing event name for telemetry");
@ -234,10 +241,18 @@ const Logic = {
}); });
}, },
setOrRemoveAssignment(tab, value) { getAssignmentObjectByContainer(userContextId) {
return browser.runtime.sendMessage({
method: "getAssignmentObjectByContainer",
message: {userContextId}
});
},
setOrRemoveAssignment(url, userContextId, value) {
return browser.runtime.sendMessage({ return browser.runtime.sendMessage({
method: "setOrRemoveAssignment", method: "setOrRemoveAssignment",
tabId: tab.id, url,
userContextId,
value value
}); });
}, },
@ -437,7 +452,8 @@ Logic.registerPanel(P_CONTAINERS_LIST, {
const currentTabElement = document.getElementById("current-tab"); const currentTabElement = document.getElementById("current-tab");
const assignmentCheckboxElement = document.getElementById("container-page-assigned"); const assignmentCheckboxElement = document.getElementById("container-page-assigned");
assignmentCheckboxElement.addEventListener("change", () => { assignmentCheckboxElement.addEventListener("change", () => {
Logic.setOrRemoveAssignment(currentTab, !assignmentCheckboxElement.checked); const userContextId = Logic.userContextId(currentTab.cookieStoreId);
Logic.setOrRemoveAssignment(currentTab.url, userContextId, !assignmentCheckboxElement.checked);
}); });
currentTabElement.hidden = !currentTab; currentTabElement.hidden = !currentTab;
this.setupAssignmentCheckbox(false); this.setupAssignmentCheckbox(false);
@ -561,7 +577,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
const identity = Logic.currentIdentity(); const identity = Logic.currentIdentity();
browser.runtime.sendMessage({ browser.runtime.sendMessage({
method: identity.hasHiddenTabs ? "showTabs" : "hideTabs", method: identity.hasHiddenTabs ? "showTabs" : "hideTabs",
userContextId: Logic.userContextId(identity.cookieStoreId) userContextId: Logic.currentUserContextId()
}).then(() => { }).then(() => {
window.close(); window.close();
}).catch(() => { }).catch(() => {
@ -633,7 +649,7 @@ Logic.registerPanel(P_CONTAINER_INFO, {
// Let's retrieve the list of tabs. // Let's retrieve the list of tabs.
return browser.runtime.sendMessage({ return browser.runtime.sendMessage({
method: "getTabs", method: "getTabs",
userContextId: Logic.userContextId(identity.cookieStoreId), userContextId: Logic.currentUserContextId(),
}).then(this.buildInfoTable); }).then(this.buildInfoTable);
}, },
@ -743,27 +759,19 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
this.initializeRadioButtons(); this.initializeRadioButtons();
Logic.addEnterHandler(document.querySelector("#edit-container-panel-back-arrow"), () => { Logic.addEnterHandler(document.querySelector("#edit-container-panel-back-arrow"), () => {
Logic.showPreviousPanel(); this._submitForm();
}); });
Logic.addEnterHandler(document.querySelector("#edit-container-cancel-link"), () => {
Logic.showPreviousPanel();
});
this._editForm = document.getElementById("edit-container-panel-form"); this._editForm = document.getElementById("edit-container-panel-form");
const editLink = document.querySelector("#edit-container-ok-link");
Logic.addEnterHandler(editLink, this._submitForm.bind(this));
editLink.addEventListener("submit", this._submitForm.bind(this));
this._editForm.addEventListener("submit", this._submitForm.bind(this)); this._editForm.addEventListener("submit", this._submitForm.bind(this));
}, },
_submitForm() { _submitForm() {
const identity = Logic.currentIdentity();
const formValues = new FormData(this._editForm); const formValues = new FormData(this._editForm);
return browser.runtime.sendMessage({ return browser.runtime.sendMessage({
method: "createOrUpdateContainer", method: "createOrUpdateContainer",
message: { message: {
userContextId: Logic.userContextId(identity.cookieStoreId) || false, userContextId: Logic.currentUserContextId() || false,
params: { params: {
name: document.getElementById("edit-container-panel-name-input").value || Logic.generateIdentityName(), name: document.getElementById("edit-container-panel-name-input").value || Logic.generateIdentityName(),
icon: formValues.get("container-icon") || DEFAULT_ICON, icon: formValues.get("container-icon") || DEFAULT_ICON,
@ -779,6 +787,44 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
}); });
}, },
showAssignedContainers(assignments) {
const assignmentPanel = document.getElementById("edit-sites-assigned");
const assignmentKeys = Object.keys(assignments);
assignmentPanel.hidden = !(assignmentKeys.length > 0);
if (assignments) {
const tableElement = assignmentPanel.querySelector("table > tbody");
/* Remove previous assignment list,
after removing one we rerender the list */
while (tableElement.firstChild) {
tableElement.firstChild.remove();
}
assignmentKeys.forEach((siteKey) => {
const site = assignments[siteKey];
const trElement = document.createElement("tr");
/* As we don't have the full or correct path the best we can assume is the path is HTTPS and then replace with a broken icon later if it doesn't load.
This is pending a better solution for favicons from web extensions */
const assumedUrl = `https://${site.hostname}`;
trElement.innerHTML = escaped`
<td><img class="icon" src="${assumedUrl}/favicon.ico"></td>
<td title="${site.hostname}" class="truncate-text">${site.hostname}
<img
class="pop-button-image delete-assignment"
src="/img/container-delete.svg"
/>
</td>`;
const deleteButton = trElement.querySelector(".delete-assignment");
Logic.addEnterHandler(deleteButton, () => {
const userContextId = Logic.currentUserContextId();
Logic.setOrRemoveAssignment(assumedUrl, userContextId, true);
delete assignments[siteKey];
this.showAssignedContainers(assignments);
});
trElement.classList.add("container-info-tab-row", "clickable");
tableElement.appendChild(trElement);
});
}
},
initializeRadioButtons() { initializeRadioButtons() {
const colorRadioTemplate = (containerColor) => { const colorRadioTemplate = (containerColor) => {
return escaped`<input type="radio" value="${containerColor}" name="container-color" id="edit-container-panel-choose-color-${containerColor}" /> return escaped`<input type="radio" value="${containerColor}" name="container-color" id="edit-container-panel-choose-color-${containerColor}" />
@ -808,8 +854,13 @@ Logic.registerPanel(P_CONTAINER_EDIT, {
}, },
// This method is called when the panel is shown. // This method is called when the panel is shown.
prepare() { async prepare() {
const identity = Logic.currentIdentity(); const identity = Logic.currentIdentity();
const userContextId = Logic.currentUserContextId();
const assignments = await Logic.getAssignmentObjectByContainer(userContextId);
this.showAssignedContainers(assignments);
document.querySelector("#edit-container-panel-name-input").value = identity.name || ""; document.querySelector("#edit-container-panel-name-input").value = identity.name || "";
[...document.querySelectorAll("[name='container-color']")].forEach(colorInput => { [...document.querySelectorAll("[name='container-color']")].forEach(colorInput => {
colorInput.checked = colorInput.value === identity.color; colorInput.checked = colorInput.value === identity.color;

View file

@ -3,6 +3,7 @@
<meta http-equiv="content-type" content="text/html; charset=utf-8"> <meta http-equiv="content-type" content="text/html; charset=utf-8">
<title>Containers browserAction Popup</title> <title>Containers browserAction Popup</title>
<link rel="stylesheet" href="/css/popup.css"> <link rel="stylesheet" href="/css/popup.css">
</head> </head>
<body> <body>
@ -125,9 +126,16 @@
<legend>Choose an icon</legend> <legend>Choose an icon</legend>
</fieldset> </fieldset>
</form> </form>
<div class="panel-footer"> <div id="edit-sites-assigned" class="scrollable" hidden>
<a href="#" class="button secondary expanded footer-button cancel-button" id="edit-container-cancel-link">Cancel</a> <table id="container-assignement-table" class="container-info-list">
<a class="button primary expanded footer-button" id="edit-container-ok-link">OK</a> <thead>
<th colspan="3">
<h3>Sites assigned to this container</h3>
</th>
</thead>
<tbody>
</tbody>
</table>
</div> </div>
</div> </div>
</div> </div>