| OLD | NEW |
| 1 /* | 1 /* |
| 2 * This file is part of Adblock Plus <https://adblockplus.org/>, | 2 * This file is part of Adblock Plus <https://adblockplus.org/>, |
| 3 * Copyright (C) 2006-present eyeo GmbH | 3 * Copyright (C) 2006-present eyeo GmbH |
| 4 * | 4 * |
| 5 * Adblock Plus is free software: you can redistribute it and/or modify | 5 * Adblock Plus is free software: you can redistribute it and/or modify |
| 6 * it under the terms of the GNU General Public License version 3 as | 6 * it under the terms of the GNU General Public License version 3 as |
| 7 * published by the Free Software Foundation. | 7 * published by the Free Software Foundation. |
| 8 * | 8 * |
| 9 * Adblock Plus is distributed in the hope that it will be useful, | 9 * Adblock Plus is distributed in the hope that it will be useful, |
| 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of | 10 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 12 * GNU General Public License for more details. | 12 * GNU General Public License for more details. |
| 13 * | 13 * |
| 14 * You should have received a copy of the GNU General Public License | 14 * You should have received a copy of the GNU General Public License |
| 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. | 15 * along with Adblock Plus. If not, see <http://www.gnu.org/licenses/>. |
| 16 */ | 16 */ |
| 17 | 17 |
| 18 "use strict"; | 18 "use strict"; |
| 19 | 19 |
| 20 let lastFilterQuery = null; | 20 let lastFilterQuery = null; |
| 21 | 21 |
| 22 browser.runtime.sendMessage({type: "types.get"}, | 22 browser.runtime.sendMessage({type: "types.get"}, |
| 23 (filterTypes) => | 23 (filterTypes) => |
| 24 { | 24 { |
| 25 let filterTypesElem = document.getElementById("filter-type"); | 25 let filterTypesElem = document.getElementById("filter-type"); |
| 26 let filterStyleElem = document.createElement("style"); | |
| 27 for (let type of filterTypes) | 26 for (let type of filterTypes) |
| 28 { | 27 { |
| 29 filterStyleElem.innerHTML += | |
| 30 `#items[data-filter-type=${type}] tr:not([data-type=${type}])` + | |
| 31 "{display: none;}"; | |
| 32 let optionNode = document.createElement("option"); | 28 let optionNode = document.createElement("option"); |
| 33 optionNode.appendChild(document.createTextNode(type)); | 29 optionNode.appendChild(document.createTextNode(type)); |
| 34 filterTypesElem.appendChild(optionNode); | 30 filterTypesElem.appendChild(optionNode); |
| 35 } | 31 } |
| 36 document.body.appendChild(filterStyleElem); | |
| 37 }); | 32 }); |
| 38 | 33 |
| 39 function generateFilter(request, domainSpecific) | 34 function generateFilter(request, domainSpecific) |
| 40 { | 35 { |
| 41 let filter = request.url.replace(/^[\w-]+:\/+(?:www\.)?/, "||"); | 36 let filter = request.url.replace(/^[\w-]+:\/+(?:www\.)?/, "||"); |
| 42 let options = []; | 37 let options = []; |
| 43 | 38 |
| 44 if (request.type == "POPUP") | 39 if (request.type == "POPUP") |
| 45 { | 40 { |
| 46 options.push("popup"); | 41 options.push("popup"); |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 166 { | 161 { |
| 167 for (let element of elements) | 162 for (let element of elements) |
| 168 { | 163 { |
| 169 if (element.innerText.search(query) != -1) | 164 if (element.innerText.search(query) != -1) |
| 170 return false; | 165 return false; |
| 171 } | 166 } |
| 172 } | 167 } |
| 173 return true; | 168 return true; |
| 174 } | 169 } |
| 175 | 170 |
| 176 function performSearch(table, query) | 171 function performSearch(rows, query) |
| 177 { | 172 { |
| 178 for (let row of table.rows) | 173 for (let row of rows) |
| 179 { | 174 { |
| 180 if (shouldFilterRow(row, query)) | 175 if (shouldFilterRow(row, query)) |
| 181 row.classList.add("filtered-by-search"); | 176 row.classList.add("filtered-by-search"); |
| 182 else | 177 else |
| 183 row.classList.remove("filtered-by-search"); | 178 row.classList.remove("filtered-by-search"); |
| 184 } | 179 } |
| 185 } | 180 } |
| 186 | 181 |
| 187 function cancelSearch(table) | 182 function cancelSearch(table) |
| 188 { | 183 { |
| 189 for (let row of table.rows) | 184 for (let row of table.rows) |
| 190 row.classList.remove("filtered-by-search"); | 185 row.classList.remove("filtered-by-search"); |
| 191 } | 186 } |
| 192 | 187 |
| 188 function createZebra(rows, state, type) |
| 189 { |
| 190 let i = 0; |
| 191 for (const tr of rows) |
| 192 { |
| 193 tr.hidden = (state ? tr.dataset.state !== state : false) || |
| 194 (type ? tr.dataset.type !== type : false); |
| 195 |
| 196 if (!tr.hidden) |
| 197 tr.classList.toggle("odd", !!(i++ % 2)); |
| 198 } |
| 199 } |
| 200 |
| 193 document.addEventListener("DOMContentLoaded", () => | 201 document.addEventListener("DOMContentLoaded", () => |
| 194 { | 202 { |
| 195 let container = document.getElementById("items"); | 203 const container = document.getElementById("items"); |
| 196 let table = container.querySelector("tbody"); | 204 const foregroundTable = container.querySelector("table.foreground tbody"); |
| 197 let template = document.querySelector("template").content.firstElementChild; | 205 const backgroundTable = container.querySelector("table.background tbody"); |
| 206 const template = document.querySelector("template") |
| 207 .content.firstElementChild; |
| 208 |
| 209 // We update rows by message index. |
| 210 // Since we don't have a linear collection of rows anymore, |
| 211 // all records, as row, will be indexed in here. |
| 212 // Memory wise, this is just a collection that points |
| 213 // at live DOM nodes (rows), so this does not imply |
| 214 // higher memory consumption, leaks, or any other concern. |
| 215 const records = []; |
| 216 |
| 217 const filterState = document.getElementById("filter-state"); |
| 218 const filterType = document.getElementById("filter-type"); |
| 219 |
| 220 const updateRowsState = () => |
| 221 { |
| 222 const state = filterState.value; |
| 223 const type = filterType.value; |
| 224 createZebra(foregroundTable.querySelectorAll("tr"), state, type); |
| 225 const notFirstTR = "tr:not(:first-child)"; |
| 226 createZebra(backgroundTable.querySelectorAll(notFirstTR), state, type); |
| 227 }; |
| 198 | 228 |
| 199 document.getElementById("reload").addEventListener("click", () => | 229 document.getElementById("reload").addEventListener("click", () => |
| 200 { | 230 { |
| 201 ext.devtools.inspectedWindow.reload(); | 231 ext.devtools.inspectedWindow.reload(); |
| 202 }, false); | 232 }, false); |
| 203 | 233 |
| 204 document.getElementById("filter-state").addEventListener("change", (event) => | 234 // update rows visibility state per each change |
| 205 { | 235 filterState.addEventListener("change", updateRowsState, false); |
| 206 container.dataset.filterState = event.target.value; | 236 filterType.addEventListener("change", updateRowsState, false); |
| 207 }, false); | |
| 208 | |
| 209 document.getElementById("filter-type").addEventListener("change", (event) => | |
| 210 { | |
| 211 container.dataset.filterType = event.target.value; | |
| 212 }, false); | |
| 213 | 237 |
| 214 ext.onMessage.addListener((message) => | 238 ext.onMessage.addListener((message) => |
| 215 { | 239 { |
| 216 switch (message.type) | 240 switch (message.type) |
| 217 { | 241 { |
| 218 case "add-record": | 242 case "add-record": |
| 219 table.appendChild(createRecord(message.request, message.filter, | 243 const record = createRecord(message.request, message.filter, template); |
| 220 template)); | 244 records.push(record); |
| 245 // waiting for 6402 to ship |
| 246 if (message.request.docDomain == null) |
| 247 backgroundTable.appendChild(record); |
| 248 else |
| 249 foregroundTable.appendChild(record); |
| 221 break; | 250 break; |
| 222 | 251 |
| 223 case "update-record": | 252 case "update-record": |
| 224 let oldRow = table.getElementsByTagName("tr")[message.index]; | 253 let oldRow = records[message.index]; |
| 225 let newRow = createRecord(message.request, message.filter, template); | 254 let newRow = createRecord(message.request, message.filter, template); |
| 255 records[message.index] = newRow; |
| 226 oldRow.parentNode.replaceChild(newRow, oldRow); | 256 oldRow.parentNode.replaceChild(newRow, oldRow); |
| 227 newRow.classList.add("changed"); | 257 newRow.classList.add("changed"); |
| 228 container.classList.add("has-changes"); | 258 container.classList.add("has-changes"); |
| 229 break; | 259 break; |
| 230 | 260 |
| 231 case "remove-record": | 261 case "remove-record": |
| 232 let row = table.getElementsByTagName("tr")[message.index]; | 262 let row = records.splice(message.index, 1)[0]; |
| 233 row.parentNode.removeChild(row); | 263 row.parentNode.removeChild(row); |
| 234 container.classList.add("has-changes"); | 264 container.classList.add("has-changes"); |
| 235 break; | 265 break; |
| 236 | 266 |
| 237 case "reset": | 267 case "reset": |
| 238 table.innerHTML = ""; | 268 records.splice(0); |
| 269 foregroundTable.innerHTML = ""; |
| 239 container.classList.remove("has-changes"); | 270 container.classList.remove("has-changes"); |
| 240 break; | 271 break; |
| 241 } | 272 } |
| 273 updateRowsState(); |
| 242 }); | 274 }); |
| 243 | 275 |
| 244 window.addEventListener("message", (event) => | 276 window.addEventListener("message", (event) => |
| 245 { | 277 { |
| 246 switch (event.data.type) | 278 switch (event.data.type) |
| 247 { | 279 { |
| 248 case "performSearch": | 280 case "performSearch": |
| 249 performSearch(table, event.data.queryString); | 281 performSearch(records, event.data.queryString); |
| 250 lastFilterQuery = event.data.queryString; | 282 lastFilterQuery = event.data.queryString; |
| 251 break; | 283 break; |
| 252 case "cancelSearch": | 284 case "cancelSearch": |
| 253 cancelSearch(table); | 285 cancelSearch(records); |
| 254 lastFilterQuery = null; | 286 lastFilterQuery = null; |
| 255 break; | 287 break; |
| 256 } | 288 } |
| 257 }); | 289 }); |
| 258 | 290 |
| 259 // Since Chrome 54 the themeName is accessible, for earlier versions we must | 291 // Since Chrome 54 the themeName is accessible, for earlier versions we must |
| 260 // assume the default theme is being used. | 292 // assume the default theme is being used. |
| 261 // https://bugs.chromium.org/p/chromium/issues/detail?id=608869 | 293 // https://bugs.chromium.org/p/chromium/issues/detail?id=608869 |
| 262 let theme = browser.devtools.panels.themeName || "default"; | 294 let theme = browser.devtools.panels.themeName || "default"; |
| 263 document.body.classList.add(theme); | 295 document.body.classList.add(theme); |
| 264 }, false); | 296 }, false); |
| OLD | NEW |