Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code

Unified Diff: lib/devtools.js

Issue 29705719: Issue 6402 - Split filter hit / request logging out into own API (Closed)
Patch Set: Ensure devtools module is included in the bundle Created Feb. 22, 2018, 4:30 p.m.
Use n/p to move between diff chunks; N/P to move between comments.
Jump to:
View side-by-side diff with in-line comments
Download patch
« lib/devLogger.js ('K') | « lib/devLogger.js ('k') | lib/popupBlocker.js » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: lib/devtools.js
diff --git a/lib/devtools.js b/lib/devtools.js
index 167a7650e990cb3819b50d719a3e25501caf9e5f..04e2d58346d889c70e2d2baf45010190a44dbb71 100644
--- a/lib/devtools.js
+++ b/lib/devtools.js
@@ -17,322 +17,8 @@
"use strict";
-const {RegExpFilter,
- WhitelistFilter,
- ElemHideFilter} = require("filterClasses");
-const {SpecialSubscription} = require("subscriptionClasses");
-const {FilterStorage} = require("filterStorage");
-const {defaultMatcher} = require("matcher");
-const {FilterNotifier} = require("filterNotifier");
-const {extractHostFromFrame} = require("url");
const {port} = require("messaging");
-
-const nonRequestTypes = ["DOCUMENT", "ELEMHIDE", "GENERICBLOCK", "GENERICHIDE"];
-
-// Mapping of inspected tabs to their devpanel page
-// and recorded items. We can't use a PageMap here,
-// because data must persist after navigation/reload.
-let panels = new Map();
-
-function isActivePanel(panel)
-{
- return panel && !panel.reload && !panel.reloading;
-}
-
-function getActivePanel(page)
-{
- let panel = panels.get(page.id);
- if (isActivePanel(panel))
- return panel;
- return null;
-}
-
-function getFilterInfo(filter)
-{
- if (!filter)
- return null;
-
- let userDefined = false;
- let subscriptionTitle = null;
-
- for (let subscription of filter.subscriptions)
- {
- if (!subscription.disabled)
- {
- if (subscription instanceof SpecialSubscription)
- userDefined = true;
- else
- subscriptionTitle = subscription.title;
- }
- }
-
- return {
- text: filter.text,
- whitelisted: filter instanceof WhitelistFilter,
- userDefined,
- subscription: subscriptionTitle
- };
-}
-
-function hasRecord(panel, request, filter)
-{
- return panel.records.some(record =>
- record.request.url == request.url &&
- record.request.docDomain == request.docDomain &&
-
- // Ignore partial (e.g. ELEMHIDE) whitelisting if there is already
- // a DOCUMENT exception which disables all means of blocking.
- (record.request.type == "DOCUMENT" ?
- nonRequestTypes.includes(request.type) :
- record.request.type == request.type) &&
-
- // Matched element hiding filters don't relate to a particular request,
- // so we have to compare the selector in order to avoid duplicates.
- (record.filter && record.filter.selector) == (filter && filter.selector)
- );
-}
-
-function addRecord(panel, request, filter)
-{
- if (!hasRecord(panel, request, filter))
- {
- panel.port.postMessage({
- type: "add-record",
- request,
- filter: getFilterInfo(filter)
- });
-
- panel.records.push({request, filter});
- }
-}
-
-function matchRequest(request)
-{
- return defaultMatcher.matchesAny(
- request.url,
- RegExpFilter.typeMap[request.type],
- request.docDomain,
- request.thirdParty,
- request.sitekey,
- request.specificOnly
- );
-}
-
-/**
- * Logs a request to the devtools panel.
- *
- * @param {?Page} page The page the request occured on or null if
- * the request isn't associated with a page
- * @param {string} url The URL of the request
- * @param {string} type The request type
- * @param {string} docDomain The IDN-decoded hostname of the document
- * @param {boolean} thirdParty Whether the origin of the request and
- * document differs
- * @param {?string} sitekey The active sitekey if there is any
- * @param {?boolean} specificOnly Whether generic filters should be ignored
- * @param {?BlockingFilter} filter The matched filter or null if there is no
- * match
- */
-exports.logRequest = function(page, url, type, docDomain,
- thirdParty, sitekey,
- specificOnly, filter)
-{
- if (panels.size == 0)
- return;
-
- let request = {url, type, docDomain, thirdParty, sitekey, specificOnly};
- for (let [tabId, panel] of panels)
- if ((!page || page.id == tabId) && isActivePanel(panel))
- addRecord(panel, request, filter);
-};
-
-/**
- * Logs active element hiding filters to the devtools panel.
- *
- * @param {Page} page The page the elements were hidden on
- * @param {string[]} selectors The selectors of applied ElemHideFilters
- * @param {string[]} filters The text of applied ElemHideEmulationFilters
- * @param {string} docDomain The IDN-decoded hostname of the document
- */
-function logHiddenElements(page, selectors, filters, docDomain)
-{
- let panel = getActivePanel(page);
- if (panel)
- {
- for (let subscription of FilterStorage.subscriptions)
- {
- if (subscription.disabled)
- continue;
-
- for (let filter of subscription.filters)
- {
- // We only know the exact filter in case of element hiding emulation.
- // For regular element hiding filters, the content script only knows
- // the selector, so we have to find a filter that has an identical
- // selector and is active on the domain the match was reported from.
- let isActiveElemHideFilter = filter instanceof ElemHideFilter &&
- selectors.includes(filter.selector) &&
- filter.isActiveOnDomain(docDomain);
-
- if (isActiveElemHideFilter || filters.includes(filter.text))
- addRecord(panel, {type: "ELEMHIDE", docDomain}, filter);
- }
- }
- }
-}
-
-/**
- * Logs a whitelisting filter, that disables (some kind of)
- * blocking for a particular document, to the devtools panel.
- *
- * @param {Page} page The page the whitelisting is active on
- * @param {string} url The url of the whitelisted document
- * @param {number} typeMask The bit mask of whitelisting types checked
- * for
- * @param {string} docDomain The IDN-decoded hostname of the parent
- * document
- * @param {WhitelistFilter} filter The matched whitelisting filter
- */
-exports.logWhitelistedDocument = function(page, url, typeMask, docDomain,
- filter)
-{
- let panel = getActivePanel(page);
- if (panel)
- {
- for (let type of nonRequestTypes)
- {
- if (typeMask & filter.contentType & RegExpFilter.typeMap[type])
- addRecord(panel, {url, type, docDomain}, filter);
- }
- }
-};
-
-/**
- * Checks whether a page is inspected by the devtools panel.
- *
- * @param {Page} page
- * @return {boolean}
- */
-exports.hasPanel = function(page)
-{
- return panels.has(page.id);
-};
-
-function onBeforeRequest(details)
-{
- let panel = panels.get(details.tabId);
-
- // Clear the devtools panel and reload the inspected tab without caching
- // when a new request is issued. However, make sure that we don't end up
- // in an infinite recursion if we already triggered a reload.
- if (panel.reloading)
- {
- panel.reloading = false;
- }
- else
- {
- panel.records = [];
- panel.port.postMessage({type: "reset"});
-
- // We can't repeat the request if it isn't a GET request. Chrome would
- // prompt the user to confirm reloading the page, and POST requests are
- // known to cause issues on many websites if repeated.
- if (details.method == "GET")
- panel.reload = true;
- }
-}
-
-function onLoading(page)
-{
- let tabId = page.id;
- let panel = panels.get(tabId);
-
- // Reloading the tab is the only way that allows bypassing all caches, in
- // order to see all requests in the devtools panel. Reloading must not be
- // performed before the tab changes to "loading", otherwise it will load the
- // previous URL.
- if (panel && panel.reload)
- {
- browser.tabs.reload(tabId, {bypassCache: true});
-
- panel.reload = false;
- panel.reloading = true;
- }
-}
-
-function updateFilters(filters, added)
-{
- for (let panel of panels.values())
- {
- for (let i = 0; i < panel.records.length; i++)
- {
- let record = panel.records[i];
-
- // If an added filter matches a request shown in the devtools panel,
- // update that record to show the new filter. Ignore filters that aren't
- // associated with any sub-resource request. There is no record for these
- // if they don't already match. In particular, in case of element hiding
- // filters, we also wouldn't know if any new element matches.
- if (added)
- {
- if (nonRequestTypes.includes(record.request.type))
- continue;
-
- let filter = matchRequest(record.request);
- if (!filters.includes(filter))
- continue;
-
- record.filter = filter;
- }
-
- // If a filter shown in the devtools panel got removed, update that
- // record to show the filter that matches now, or none, instead.
- // For filters that aren't associated with any sub-resource request,
- // just remove the record. We wouldn't know whether another filter
- // matches instead until the page is reloaded.
- else
- {
- if (!filters.includes(record.filter))
- continue;
-
- if (nonRequestTypes.includes(record.request.type))
- {
- panel.port.postMessage({
- type: "remove-record",
- index: i
- });
- panel.records.splice(i--, 1);
- continue;
- }
-
- record.filter = matchRequest(record.request);
- }
-
- panel.port.postMessage({
- type: "update-record",
- index: i,
- request: record.request,
- filter: getFilterInfo(record.filter)
- });
- }
- }
-}
-
-function onFilterAdded(filter)
-{
- updateFilters([filter], true);
-}
-
-function onFilterRemoved(filter)
-{
- updateFilters([filter], false);
-}
-
-function onSubscriptionAdded(subscription)
-{
- if (subscription instanceof SpecialSubscription)
- updateFilters(subscription.filters, true);
-}
+const {DevLogger} = require("devLogger");
browser.runtime.onConnect.addListener(newPort =>
{
@@ -341,46 +27,11 @@ browser.runtime.onConnect.addListener(newPort =>
return;
let inspectedTabId = parseInt(match[1], 10);
- let localOnBeforeRequest = onBeforeRequest.bind();
-
- browser.webRequest.onBeforeRequest.addListener(
- localOnBeforeRequest,
- {
- urls: ["http://*/*", "https://*/*"],
- types: ["main_frame"],
- tabId: inspectedTabId
- }
- );
-
- if (panels.size == 0)
- {
- ext.pages.onLoading.addListener(onLoading);
- FilterNotifier.on("filter.added", onFilterAdded);
- FilterNotifier.on("filter.removed", onFilterRemoved);
- FilterNotifier.on("subscription.added", onSubscriptionAdded);
- }
+ let onDevLogger = newPort.postMessage.bind(newPort);
+ DevLogger.on(inspectedTabId, onDevLogger);
newPort.onDisconnect.addListener(() =>
{
- panels.delete(inspectedTabId);
- browser.webRequest.onBeforeRequest.removeListener(localOnBeforeRequest);
-
- if (panels.size == 0)
- {
- ext.pages.onLoading.removeListener(onLoading);
- FilterNotifier.off("filter.added", onFilterAdded);
- FilterNotifier.off("filter.removed", onFilterRemoved);
- FilterNotifier.off("subscription.added", onSubscriptionAdded);
- }
+ DevLogger.off(inspectedTabId, onDevLogger);
});
-
- panels.set(inspectedTabId, {port: newPort, records: []});
-});
-
-port.on("devtools.traceElemHide", (message, sender) =>
-{
- logHiddenElements(
- sender.page, message.selectors, message.filters,
- extractHostFromFrame(sender.frame)
- );
});
« lib/devLogger.js ('K') | « lib/devLogger.js ('k') | lib/popupBlocker.js » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld