Source code
Revision control
Copy as Markdown
Other Tools
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
import { GeckoViewModule } from "resource://gre/modules/GeckoViewModule.sys.mjs";
export class GeckoViewContentBlocking extends GeckoViewModule {
onEnable() {
const flags = Ci.nsIWebProgress.NOTIFY_CONTENT_BLOCKING;
this.progressFilter = Cc[
"@mozilla.org/appshell/component/browser-status-filter;1"
].createInstance(Ci.nsIWebProgress);
this.progressFilter.addProgressListener(this, flags);
this.browser.addProgressListener(this.progressFilter, flags);
this.registerListener(["ContentBlocking:RequestLog"]);
}
onDisable() {
if (this.progressFilter) {
this.progressFilter.removeProgressListener(this);
this.browser.removeProgressListener(this.progressFilter);
delete this.progressFilter;
}
this.unregisterListener(["ContentBlocking:RequestLog"]);
}
// Bundle event handler.
onEvent(aEvent, aData, aCallback) {
debug`onEvent: event=${aEvent}, data=${aData}`;
switch (aEvent) {
case "ContentBlocking:RequestLog": {
let bc = this.browser.browsingContext;
if (!bc) {
warn`Failed to export content blocking log.`;
break;
}
// Get the top-level browsingContext. The ContentBlockingLog is located
// in its current window global.
bc = bc.top;
const topWindowGlobal = bc.currentWindowGlobal;
if (!topWindowGlobal) {
warn`Failed to export content blocking log.`;
break;
}
const log = JSON.parse(topWindowGlobal.contentBlockingLog);
const res = Object.keys(log).map(key => {
const blockData = log[key].map(data => {
return {
category: data[0],
blocked: data[1],
count: data[2],
};
});
return {
origin: key,
blockData,
};
});
aCallback.onSuccess({ log: res });
break;
}
}
}
onContentBlockingEvent(aWebProgress, aRequest, aEvent) {
debug`onContentBlockingEvent ${aEvent.toString(16)}`;
if (!(aRequest instanceof Ci.nsIClassifiedChannel)) {
return;
}
const channel = aRequest.QueryInterface(Ci.nsIChannel);
const uri = channel.URI && channel.URI.spec;
if (!uri) {
return;
}
const classChannel = aRequest.QueryInterface(Ci.nsIClassifiedChannel);
const blockedList = classChannel.matchedList || null;
let loadedLists = [];
if (aRequest instanceof Ci.nsIHttpChannel) {
loadedLists = classChannel.matchedTrackingLists || [];
}
debug`onContentBlockingEvent matchedList: ${blockedList}`;
debug`onContentBlockingEvent matchedTrackingLists: ${loadedLists}`;
const message = {
type: "GeckoView:ContentBlockingEvent",
uri,
category: aEvent,
blockedList,
loadedLists,
};
this.eventDispatcher.sendRequest(message);
}
}
const { debug, warn } = GeckoViewContentBlocking.initLogging(
"GeckoViewContentBlocking"
);