| Index: devtools-panel.js |
| =================================================================== |
| --- a/devtools-panel.js |
| +++ b/devtools-panel.js |
| @@ -23,17 +23,12 @@ |
| (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) |
| @@ -190,10 +185,79 @@ |
| row.classList.remove("filtered-by-search"); |
| } |
| +/** |
| + * Return a generic <tr> placeholder |
| + * double linked with the <tr> itself to simplify |
| + * tbody swaps / filtering of undesired rows. |
| + * @param {HTMLTableRowElement} tr |
| + * @returns {Comment} |
| + */ |
| +function getPlaceholder(tr) |
| +{ |
| + let placeholder = tr.placeholder; |
| + if (!placeholder) |
| + { |
| + placeholder = document.createComment("placeholder"); |
| + tr.placeholder = placeholder; |
| + placeholder.placeholder = tr; |
| + } |
| + return placeholder; |
| +} |
| + |
| +/** |
| + * Put back all hidden table rows and eventually |
| + * filters those that do not match the state or type. |
| + * @param {HTMLTableSectionElement} tbody |
| + * @param {DOMStringMap} dataset |
| + */ |
| +function updateRows(tbody, dataset) |
| +{ |
| + const {filterState, filterType} = dataset; |
| + |
| + // create a list of possible CSS filter |
| + // excluding #background-items from the list of rows to consider |
| + const query = []; |
| + if (filterState) |
| + { |
| + query.push(`tr:not(#background-items):not([data-state="${filterState}"])`); |
| + } |
| + if (filterType) |
| + { |
| + query.push(`tr:not(#background-items):not([data-type="${filterType}"])`); |
| + } |
| + |
| + // use filters to match nodes or retrieve them later on |
| + const selector = query.join(","); |
| + for (const node of tbody.childNodes) |
| + { |
| + // comments linked to table rows |
| + // that won't match selector will be used |
| + // to place their linked row back in the tbody |
| + if ( |
| + node.nodeType === Node.COMMENT_NODE && |
| + (!selector || !node.placeholder.matches(selector)) |
| + ) |
| + { |
| + tbody.replaceChild(node.placeholder, node); |
| + } |
| + } |
| + |
| + // if there is a list of nodes to filter |
| + if (selector) |
| + { |
| + // per each of them put a placeholder inside the tbody |
| + for (const tr of tbody.querySelectorAll(selector)) |
| + { |
| + tbody.replaceChild(getPlaceholder(tr), tr); |
| + } |
| + } |
| +} |
| + |
| document.addEventListener("DOMContentLoaded", () => |
| { |
| let container = document.getElementById("items"); |
| let table = container.querySelector("tbody"); |
| + let bgItems = container.querySelector("#background-items"); |
| let template = document.querySelector("template").content.firstElementChild; |
| document.getElementById("reload").addEventListener("click", () => |
| @@ -204,11 +268,13 @@ |
| document.getElementById("filter-state").addEventListener("change", (event) => |
| { |
| container.dataset.filterState = event.target.value; |
| + updateRows(table, container.dataset); |
| }, false); |
| document.getElementById("filter-type").addEventListener("change", (event) => |
| { |
| container.dataset.filterType = event.target.value; |
| + updateRows(table, container.dataset); |
| }, false); |
| ext.onMessage.addListener((message) => |
| @@ -216,8 +282,16 @@ |
| switch (message.type) |
| { |
| case "add-record": |
| - table.appendChild(createRecord(message.request, message.filter, |
| - template)); |
| + let record = createRecord(message.request, message.filter, template); |
| + // what is the official way to know if a request is from background tab? |
| + if (/^SCRIPT|BACKGROUND$/.test(message.request.type)) |
| + { |
| + table.appendChild(record.cloneNode(true)); |
| + } |
| + else |
| + { |
| + table.insertBefore(record, bgItems); |
| + } |
| break; |
| case "update-record": |