Skip to content

Commit

Permalink
fix: review
Browse files Browse the repository at this point in the history
Signed-off-by: nullptropy <nullptropy@tutanota.com>
  • Loading branch information
nullptropy committed Sep 23, 2024
1 parent 516c5a1 commit 5c335de
Show file tree
Hide file tree
Showing 2 changed files with 68 additions and 37 deletions.
30 changes: 19 additions & 11 deletions packages/adblocker-electron-preload/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,26 @@
import { ipcRenderer } from 'electron';
import { DOMMonitor, IBackgroundCallback } from '@cliqz/adblocker-content';

interface CosmeticFiltersResponse {
type CosmeticFiltersResponse = {
active: boolean;
error?: string;
}
};

function injectCosmeticFilters(data?: Omit<IBackgroundCallback, 'lifecycle'>): Promise<CosmeticFiltersResponse> {
return ipcRenderer.invoke('inject-cosmetic-filters', window.location.href, data);
function injectCosmeticFilters(
data?: Omit<IBackgroundCallback, 'lifecycle'>,
): Promise<CosmeticFiltersResponse> {
return ipcRenderer.invoke(
'@ghostery/adblocker/inject-cosmetic-filters',
window.location.href,
data,
);
}

if (window === window.top && !window.location.href.startsWith('devtools://')) {
if (window === window.top && window.location.href.startsWith('devtools://') === false) {
(async () => {
const enableMutationObserver = await ipcRenderer.invoke('is-mutation-observer-enabled');
const enableMutationObserver = await ipcRenderer.invoke(
'@ghostery/adblocker/is-mutation-observer-enabled',
);

let ACTIVE: boolean = true;
let DOM_MONITOR: DOMMonitor | null = null;
Expand All @@ -33,7 +41,8 @@ if (window === window.top && !window.location.href.startsWith('devtools://')) {
};

const response = await injectCosmeticFilters();
if (response.error) throw new Error(`error injecting initial cosmetic filters: ${response.error}`)
if (response.error)
throw new Error(`error injecting initial cosmetic filters: ${response.error}`);
if (!(ACTIVE = response.active)) return;

// On DOMContentLoaded, start monitoring the DOM. This means that we will
Expand All @@ -47,8 +56,8 @@ if (window === window.top && !window.location.href.startsWith('devtools://')) {
DOM_MONITOR = new DOMMonitor(async (update) => {
if (update.type === 'features') {
const response = await injectCosmeticFilters();
if (response.error) throw new Error(`error injecting updated cosmetic filters: ${response.error}`)
if (!(ACTIVE = response.active)) unload();
if (response.error)
throw new Error(`error injecting updated cosmetic filters: ${response.error}`);
}
});

Expand All @@ -67,5 +76,4 @@ if (window === window.top && !window.location.href.startsWith('devtools://')) {
})();
}

// Re-export symbols for convenience
export type { IBackgroundCallback } from '@cliqz/adblocker-content';
export type { CosmeticFiltersResponse, IBackgroundCallback };
75 changes: 49 additions & 26 deletions packages/adblocker-electron/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ import * as electron from 'electron';
import { parse } from 'tldts-experimental';

import { ElectronRequestType, FiltersEngine, Request } from '@cliqz/adblocker';
import type { IBackgroundCallback } from '@cliqz/adblocker-electron-preload';
import type {
CosmeticFiltersResponse,
IBackgroundCallback,
} from '@cliqz/adblocker-electron-preload';

import { PRELOAD_PATH } from './preload_path.js';

Expand Down Expand Up @@ -59,14 +62,16 @@ export class BlockingContext {
event: Electron.IpcMainInvokeEvent,
url: string,
msg?: IBackgroundCallback,
) => Promise<{ active: boolean; error?: string }>;
) => Promise<CosmeticFiltersResponse>;

private readonly onHeadersReceived: (
details: Electron.OnHeadersReceivedListenerDetails,
callback: (a: Electron.HeadersReceivedResponse) => void,
) => void;

private readonly onIsMutationObserverEnabled: (event: Electron.IpcMainInvokeEvent) => Promise<boolean>;
private readonly onIsMutationObserverEnabled: (
event: Electron.IpcMainInvokeEvent,
) => Promise<boolean>;

constructor(
private readonly session: Electron.Session,
Expand All @@ -83,8 +88,11 @@ export class BlockingContext {
public enable(): void {
if (this.blocker.config.loadCosmeticFilters === true) {
this.session.setPreloads(this.session.getPreloads().concat([PRELOAD_PATH]));
ipcMain.handle('inject-cosmetic-filters', this.onInjectCosmeticFilters);
ipcMain.handle('is-mutation-observer-enabled', this.onIsMutationObserverEnabled);
ipcMain.handle('@ghostery/adblocker/inject-cosmetic-filters', this.onInjectCosmeticFilters);
ipcMain.handle(
'@ghostery/adblocker/is-mutation-observer-enabled',
this.onIsMutationObserverEnabled,
);
}

if (this.blocker.config.loadNetworkFilters === true) {
Expand All @@ -109,8 +117,8 @@ export class BlockingContext {

if (this.blocker.config.loadCosmeticFilters === true) {
this.session.setPreloads(this.session.getPreloads().filter((p) => p !== PRELOAD_PATH));
ipcMain.removeHandler('inject-cosmetic-filters');
ipcMain.removeHandler('is-mutation-observer-enabled');
ipcMain.removeHandler('@ghostery/adblocker/inject-cosmetic-filters');
ipcMain.removeHandler('@ghostery/adblocker/is-mutation-observer-enabled');
}
}
}
Expand Down Expand Up @@ -158,21 +166,25 @@ export class ElectronBlocker extends FiltersEngine {
// ElectronBlocker-specific additions to FiltersEngine
// ----------------------------------------------------------------------- //

public onIsMutationObserverEnabled = async (_: Electron.IpcMainInvokeEvent): Promise<boolean> => {
public onIsMutationObserverEnabled = async (
_: Electron.IpcMainInvokeEvent,
): Promise<boolean> => {
return this.config.enableMutationObserver;
};

public onInjectCosmeticFilters = async (
event: Electron.IpcMainInvokeEvent,
url: string,
msg?: IBackgroundCallback,
): Promise<{ active: boolean; error?: string }> => {
): Promise<CosmeticFiltersResponse> => {
const parsed = parse(url);
const hostname = parsed.hostname || '';
const domain = parsed.domain || '';

// `msg` is undefined for the initial call and present for subsequent updates
const { active, styles, scripts, extended } = this.getCosmeticsFilters({
const isFirstRun = msg === undefined;

const { active, styles, scripts } = this.getCosmeticsFilters({
domain,
hostname,
url,
Expand All @@ -183,13 +195,13 @@ export class ElectronBlocker extends FiltersEngine {
ids: msg?.ids,

// Rules to fetch: true for initial call, false for updates
getBaseRules: !msg,
getInjectionRules: !msg,
getExtendedRules: !msg,
getRulesFromHostname: !msg,
getBaseRules: isFirstRun,
getInjectionRules: isFirstRun,
getExtendedRules: isFirstRun,
getRulesFromHostname: isFirstRun,

// Only true for update calls when we have DOM information
getRulesFromDOM: !!msg,
getRulesFromDOM: !isFirstRun,

callerContext: {
frameId: event.frameId,
Expand All @@ -202,21 +214,32 @@ export class ElectronBlocker extends FiltersEngine {
return { active: false };
}

try {
if (styles.length > 0) {
if (styles.length > 0) {
try {
await event.sender.insertCSS(styles, { cssOrigin: 'user' });
} catch (error) {
return {
active: false,
error: `CSS insertion failed: ${error instanceof Error ? error.message : String(error)}`,
};
}
}

for (const script of scripts) {
await event.sender.executeJavaScript(script, true);
}

if (extended.length > 0) { }

return { active: true };
} catch (error) {
return { active: true, error: String(error) };
const scriptResults = await Promise.allSettled(
scripts.map((script) => event.sender.executeJavaScript(script, true)),
);
const scriptErrors = scriptResults
.filter((result) => result.status === 'rejected')
.map((result) => result.reason);

if (scriptErrors.length > 0) {
return {
active: false,
error: `Some scripts failed to execute: ${scriptErrors.join(', ')}`,
};
}

return { active: true };
};

public onHeadersReceived = (
Expand Down

0 comments on commit 5c335de

Please sign in to comment.