Index: devtools-panel.js |
=================================================================== |
--- a/devtools-panel.js |
+++ b/devtools-panel.js |
@@ -18,27 +18,22 @@ |
"use strict"; |
let lastFilterQuery = null; |
browser.runtime.sendMessage({type: "types.get"}, |
(filterTypes) => |
{ |
let filterTypesElem = document.getElementById("filter-type"); |
- let filterStyleElem = document.createElement("style"); |
for (let type of filterTypes) |
{ |
- filterStyleElem.innerHTML += |
- `#items[data-filter-type=${type}] tr:not([data-type=${type}])` + |
- "{display: none;}"; |
let optionNode = document.createElement("option"); |
optionNode.appendChild(document.createTextNode(type)); |
filterTypesElem.appendChild(optionNode); |
} |
- document.body.appendChild(filterStyleElem); |
}); |
function generateFilter(request, domainSpecific) |
{ |
let filter = request.url.replace(/^[\w-]+:\/+(?:www\.)?/, "||"); |
let options = []; |
if (request.type == "POPUP") |
@@ -168,94 +163,131 @@ |
{ |
if (element.innerText.search(query) != -1) |
return false; |
} |
} |
return true; |
} |
-function performSearch(table, query) |
+function performSearch(rows, query) |
{ |
- for (let row of table.rows) |
+ for (let row of rows) |
{ |
if (shouldFilterRow(row, query)) |
row.classList.add("filtered-by-search"); |
else |
row.classList.remove("filtered-by-search"); |
} |
} |
function cancelSearch(table) |
{ |
for (let row of table.rows) |
row.classList.remove("filtered-by-search"); |
} |
+function createZebra(rows, state, type) |
+{ |
+ let i = 0; |
+ for (const tr of rows) |
+ { |
+ tr.hidden = (state ? tr.dataset.state !== state : false) || |
+ (type ? tr.dataset.type !== type : false); |
+ |
+ if (!tr.hidden) |
+ tr.classList.toggle("odd", !!(i++ % 2)); |
+ } |
+} |
+ |
document.addEventListener("DOMContentLoaded", () => |
{ |
- let container = document.getElementById("items"); |
- let table = container.querySelector("tbody"); |
- let template = document.querySelector("template").content.firstElementChild; |
+ const container = document.getElementById("items"); |
+ const foregroundTable = container.querySelector("table.foreground tbody"); |
+ const backgroundTable = container.querySelector("table.background tbody"); |
+ const template = document.querySelector("template") |
+ .content.firstElementChild; |
+ |
+ // We update rows by message index. |
+ // Since we don't have a linear collection of rows anymore, |
+ // all records, as row, will be indexed in here. |
+ // Memory wise, this is just a collection that points |
+ // at live DOM nodes (rows), so this does not imply |
+ // higher memory consumption, leaks, or any other concern. |
+ const records = []; |
+ |
+ const filterState = document.getElementById("filter-state"); |
+ const filterType = document.getElementById("filter-type"); |
+ |
+ const updateRowsState = () => |
+ { |
+ const state = filterState.value; |
+ const type = filterType.value; |
+ createZebra(foregroundTable.querySelectorAll("tr"), state, type); |
+ const notFirstTR = "tr:not(:first-child)"; |
+ createZebra(backgroundTable.querySelectorAll(notFirstTR), state, type); |
+ }; |
document.getElementById("reload").addEventListener("click", () => |
{ |
ext.devtools.inspectedWindow.reload(); |
}, false); |
- document.getElementById("filter-state").addEventListener("change", (event) => |
- { |
- container.dataset.filterState = event.target.value; |
- }, false); |
- |
- document.getElementById("filter-type").addEventListener("change", (event) => |
- { |
- container.dataset.filterType = event.target.value; |
- }, false); |
+ // update rows visibility state per each change |
+ filterState.addEventListener("change", updateRowsState, false); |
+ filterType.addEventListener("change", updateRowsState, false); |
ext.onMessage.addListener((message) => |
{ |
switch (message.type) |
{ |
case "add-record": |
- table.appendChild(createRecord(message.request, message.filter, |
- template)); |
+ const record = createRecord(message.request, message.filter, template); |
+ records.push(record); |
+ // waiting for 6402 to ship |
+ if (message.request.docDomain == null) |
+ backgroundTable.appendChild(record); |
+ else |
+ foregroundTable.appendChild(record); |
break; |
case "update-record": |
- let oldRow = table.getElementsByTagName("tr")[message.index]; |
+ let oldRow = records[message.index]; |
let newRow = createRecord(message.request, message.filter, template); |
+ records[message.index] = newRow; |
oldRow.parentNode.replaceChild(newRow, oldRow); |
newRow.classList.add("changed"); |
container.classList.add("has-changes"); |
break; |
case "remove-record": |
- let row = table.getElementsByTagName("tr")[message.index]; |
+ let row = records.splice(message.index, 1)[0]; |
row.parentNode.removeChild(row); |
container.classList.add("has-changes"); |
break; |
case "reset": |
- table.innerHTML = ""; |
+ records.splice(0); |
+ foregroundTable.innerHTML = ""; |
container.classList.remove("has-changes"); |
break; |
} |
+ updateRowsState(); |
}); |
window.addEventListener("message", (event) => |
{ |
switch (event.data.type) |
{ |
case "performSearch": |
- performSearch(table, event.data.queryString); |
+ performSearch(records, event.data.queryString); |
lastFilterQuery = event.data.queryString; |
break; |
case "cancelSearch": |
- cancelSearch(table); |
+ cancelSearch(records); |
lastFilterQuery = null; |
break; |
} |
}); |
// Since Chrome 54 the themeName is accessible, for earlier versions we must |
// assume the default theme is being used. |
// https://bugs.chromium.org/p/chromium/issues/detail?id=608869 |