UNPKG

chrome-devtools-frontend

Version:
179 lines (143 loc) 6.56 kB
// Copyright 2021 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import type * as Common from '../common/common.js'; import * as i18n from '../i18n/i18n.js'; import type * as ProtocolProxyApi from '../../generated/protocol-proxy-api.js'; import {CategorizedBreakpoint} from './CategorizedBreakpoint.js'; import {Capability, type Target} from './Target.js'; import {SDKModel} from './SDKModel.js'; import {TargetManager, type SDKModelObserver} from './TargetManager.js'; const UIStrings = { /** * @description Category of breakpoints */ auctionWorklet: 'Ad Auction Worklet', /** * @description Name of a breakpoint type. * https://github.com/WICG/turtledove/blob/main/FLEDGE.md#32-on-device-bidding */ beforeBidderWorkletBiddingStart: 'Bidder Bidding Phase Start', /** * @description Name of a breakpoint type. * https://github.com/WICG/turtledove/blob/main/FLEDGE.md#52-buyer-reporting-on-render-and-ad-events */ beforeBidderWorkletReportingStart: 'Bidder Reporting Phase Start', /** * @description Name of a breakpoint type. * https://github.com/WICG/turtledove/blob/main/FLEDGE.md#23-scoring-bids */ beforeSellerWorkletScoringStart: 'Seller Scoring Phase Start', /** * @description Name of a breakpoint type. * https://github.com/WICG/turtledove/blob/main/FLEDGE.md#51-seller-reporting-on-render */ beforeSellerWorkletReportingStart: 'Seller Reporting Phase Start', }; const str_ = i18n.i18n.registerUIStrings('core/sdk/EventBreakpointsModel.ts', UIStrings); const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_); const enum InstrumentationNames { BeforeBidderWorkletBiddingStart = 'beforeBidderWorkletBiddingStart', BeforeBidderWorkletReportingStart = 'beforeBidderWorkletReportingStart', BeforeSellerWorkletScoringStart = 'beforeSellerWorkletScoringStart', BeforeSellerWorkletReportingStart = 'beforeSellerWorkletReportingStart', } function getTitleForInstrumentationName(instrumentationName: InstrumentationNames): Common.UIString.LocalizedString { switch (instrumentationName) { case InstrumentationNames.BeforeBidderWorkletBiddingStart: return i18nString(UIStrings.beforeBidderWorkletBiddingStart); case InstrumentationNames.BeforeBidderWorkletReportingStart: return i18nString(UIStrings.beforeBidderWorkletReportingStart); case InstrumentationNames.BeforeSellerWorkletScoringStart: return i18nString(UIStrings.beforeSellerWorkletScoringStart); case InstrumentationNames.BeforeSellerWorkletReportingStart: return i18nString(UIStrings.beforeSellerWorkletReportingStart); } } export class EventBreakpointsModel extends SDKModel<void> { readonly agent: ProtocolProxyApi.EventBreakpointsApi; constructor(target: Target) { super(target); this.agent = target.eventBreakpointsAgent(); } } // This implementation (as opposed to similar class in DOMDebuggerModel) is for // instrumentation breakpoints in targets that run JS but do not have a DOM. class EventListenerBreakpoint extends CategorizedBreakpoint { readonly instrumentationName: string; constructor(instrumentationName: InstrumentationNames, category: string) { super(category, getTitleForInstrumentationName(instrumentationName)); this.instrumentationName = instrumentationName; } override setEnabled(enabled: boolean): void { if (this.enabled() === enabled) { return; } super.setEnabled(enabled); for (const model of TargetManager.instance().models(EventBreakpointsModel)) { this.updateOnModel(model); } } updateOnModel(model: EventBreakpointsModel): void { if (this.enabled()) { void model.agent.invoke_setInstrumentationBreakpoint({eventName: this.instrumentationName}); } else { void model.agent.invoke_removeInstrumentationBreakpoint({eventName: this.instrumentationName}); } } static readonly instrumentationPrefix = 'instrumentation:'; } let eventBreakpointManagerInstance: EventBreakpointsManager; export class EventBreakpointsManager implements SDKModelObserver<EventBreakpointsModel> { readonly #eventListenerBreakpointsInternal: EventListenerBreakpoint[] = []; constructor() { this.createInstrumentationBreakpoints(i18nString(UIStrings.auctionWorklet), [ InstrumentationNames.BeforeBidderWorkletBiddingStart, InstrumentationNames.BeforeBidderWorkletReportingStart, InstrumentationNames.BeforeSellerWorkletScoringStart, InstrumentationNames.BeforeSellerWorkletReportingStart, ]); TargetManager.instance().observeModels(EventBreakpointsModel, this); } static instance(opts: { forceNew: boolean|null, } = {forceNew: null}): EventBreakpointsManager { const {forceNew} = opts; if (!eventBreakpointManagerInstance || forceNew) { eventBreakpointManagerInstance = new EventBreakpointsManager(); } return eventBreakpointManagerInstance; } private createInstrumentationBreakpoints(category: string, instrumentationNames: InstrumentationNames[]): void { for (const instrumentationName of instrumentationNames) { this.#eventListenerBreakpointsInternal.push(new EventListenerBreakpoint(instrumentationName, category)); } } eventListenerBreakpoints(): EventListenerBreakpoint[] { return this.#eventListenerBreakpointsInternal.slice(); } resolveEventListenerBreakpointTitle(auxData: { eventName: string, }): string|null { const breakpoint = this.resolveEventListenerBreakpoint(auxData); return breakpoint ? breakpoint.title() : null; } resolveEventListenerBreakpoint(auxData: {eventName: string}): EventListenerBreakpoint|null { const eventName = auxData.eventName; if (!eventName.startsWith(EventListenerBreakpoint.instrumentationPrefix)) { return null; } const instrumentationName = eventName.substring(EventListenerBreakpoint.instrumentationPrefix.length); return this.#eventListenerBreakpointsInternal.find(b => b.instrumentationName === instrumentationName) || null; } modelAdded(eventBreakpointModel: EventBreakpointsModel): void { for (const breakpoint of this.#eventListenerBreakpointsInternal) { if (breakpoint.enabled()) { breakpoint.updateOnModel(eventBreakpointModel); } } } modelRemoved(_eventBreakpointModel: EventBreakpointsModel): void { } } SDKModel.register(EventBreakpointsModel, {capabilities: Capability.EventBreakpoints, autostart: false});