UNPKG

@quick-game/cli

Version:

Command line interface for rapid qg development

248 lines 10.4 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 * as Common from '../common/common.js'; import * as Platform from '../platform/platform.js'; import * as ProtocolClient from '../protocol_client/protocol_client.js'; import { SDKModel } from './SDKModel.js'; export class Target extends ProtocolClient.InspectorBackend.TargetBase { #targetManagerInternal; #nameInternal; #inspectedURLInternal; #inspectedURLName; #capabilitiesMask; #typeInternal; #parentTargetInternal; #idInternal; #modelByConstructor; #isSuspended; #targetInfoInternal; #creatingModels; constructor(targetManager, id, name, type, parentTarget, sessionId, suspended, connection, targetInfo) { const needsNodeJSPatching = type === Type.Node; super(needsNodeJSPatching, parentTarget, sessionId, connection); this.#targetManagerInternal = targetManager; this.#nameInternal = name; this.#inspectedURLInternal = Platform.DevToolsPath.EmptyUrlString; this.#inspectedURLName = ''; this.#capabilitiesMask = 0; switch (type) { case Type.Frame: this.#capabilitiesMask = Capability.Browser | Capability.Storage | Capability.DOM | Capability.JS | Capability.Log | Capability.Network | Capability.Target | Capability.Tracing | Capability.Emulation | Capability.Input | Capability.Inspector | Capability.Audits | Capability.WebAuthn | Capability.IO | Capability.Media; if (parentTarget?.type() !== Type.Frame) { // This matches backend exposing certain capabilities only for the main frame. this.#capabilitiesMask |= Capability.DeviceEmulation | Capability.ScreenCapture | Capability.Security | Capability.ServiceWorker; if (targetInfo?.url.startsWith('chrome-extension://')) { this.#capabilitiesMask &= ~Capability.Security; } // TODO(dgozman): we report service workers for the whole frame tree on the main frame, // while we should be able to only cover the subtree corresponding to the target. } break; case Type.ServiceWorker: this.#capabilitiesMask = Capability.JS | Capability.Log | Capability.Network | Capability.Target | Capability.Inspector | Capability.IO; if (parentTarget?.type() !== Type.Frame) { this.#capabilitiesMask |= Capability.Browser; } break; case Type.SharedWorker: this.#capabilitiesMask = Capability.JS | Capability.Log | Capability.Network | Capability.Target | Capability.IO | Capability.Media | Capability.Inspector; break; case Type.Worker: this.#capabilitiesMask = Capability.JS | Capability.Log | Capability.Network | Capability.Target | Capability.IO | Capability.Media | Capability.Emulation; break; case Type.Node: this.#capabilitiesMask = Capability.JS; break; case Type.AuctionWorklet: this.#capabilitiesMask = Capability.JS | Capability.EventBreakpoints; break; case Type.Browser: this.#capabilitiesMask = Capability.Target | Capability.IO; break; case Type.Tab: this.#capabilitiesMask = Capability.Target | Capability.Tracing; break; } this.#typeInternal = type; this.#parentTargetInternal = parentTarget; this.#idInternal = id; /* } */ this.#modelByConstructor = new Map(); this.#isSuspended = suspended; this.#targetInfoInternal = targetInfo; } createModels(required) { this.#creatingModels = true; const registeredModels = Array.from(SDKModel.registeredModels.entries()); // Create early models. for (const [modelClass, info] of registeredModels) { if (info.early) { this.model(modelClass); } } // Create autostart and required models. for (const [modelClass, info] of registeredModels) { if (info.autostart || required.has(modelClass)) { this.model(modelClass); } } this.#creatingModels = false; } id() { return this.#idInternal; } name() { return this.#nameInternal || this.#inspectedURLName; } setName(name) { if (this.#nameInternal === name) { return; } this.#nameInternal = name; this.#targetManagerInternal.onNameChange(this); } type() { return this.#typeInternal; } markAsNodeJSForTest() { super.markAsNodeJSForTest(); this.#typeInternal = Type.Node; } targetManager() { return this.#targetManagerInternal; } hasAllCapabilities(capabilitiesMask) { // TODO(dgozman): get rid of this method, once we never observe targets with // capability mask. return (this.#capabilitiesMask & capabilitiesMask) === capabilitiesMask; } decorateLabel(label) { return (this.#typeInternal === Type.Worker || this.#typeInternal === Type.ServiceWorker) ? '\u2699 ' + label : label; } parentTarget() { return this.#parentTargetInternal; } outermostTarget() { let lastTarget = null; let currentTarget = this; do { if (currentTarget.type() !== Type.Tab && currentTarget.type() !== Type.Browser) { lastTarget = currentTarget; } currentTarget = currentTarget.parentTarget(); } while (currentTarget); return lastTarget; } dispose(reason) { super.dispose(reason); this.#targetManagerInternal.removeTarget(this); for (const model of this.#modelByConstructor.values()) { model.dispose(); } } model(modelClass) { if (!this.#modelByConstructor.get(modelClass)) { const info = SDKModel.registeredModels.get(modelClass); if (info === undefined) { throw 'Model class is not registered @' + new Error().stack; } if ((this.#capabilitiesMask & info.capabilities) === info.capabilities) { const model = new modelClass(this); this.#modelByConstructor.set(modelClass, model); if (!this.#creatingModels) { this.#targetManagerInternal.modelAdded(this, modelClass, model, this.#targetManagerInternal.isInScope(this)); } } } return this.#modelByConstructor.get(modelClass) || null; } models() { return this.#modelByConstructor; } inspectedURL() { return this.#inspectedURLInternal; } setInspectedURL(inspectedURL) { this.#inspectedURLInternal = inspectedURL; const parsedURL = Common.ParsedURL.ParsedURL.fromString(inspectedURL); this.#inspectedURLName = parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + this.#idInternal; this.#targetManagerInternal.onInspectedURLChange(this); if (!this.#nameInternal) { this.#targetManagerInternal.onNameChange(this); } } async suspend(reason) { if (this.#isSuspended) { return; } this.#isSuspended = true; await Promise.all(Array.from(this.models().values(), m => m.preSuspendModel(reason))); await Promise.all(Array.from(this.models().values(), m => m.suspendModel(reason))); } async resume() { if (!this.#isSuspended) { return; } this.#isSuspended = false; await Promise.all(Array.from(this.models().values(), m => m.resumeModel())); await Promise.all(Array.from(this.models().values(), m => m.postResumeModel())); } suspended() { return this.#isSuspended; } updateTargetInfo(targetInfo) { this.#targetInfoInternal = targetInfo; } targetInfo() { return this.#targetInfoInternal; } } // TODO(crbug.com/1167717): Make this a const enum again // eslint-disable-next-line rulesdir/const_enum export var Type; (function (Type) { Type["Frame"] = "frame"; Type["ServiceWorker"] = "service-worker"; Type["Worker"] = "worker"; Type["SharedWorker"] = "shared-worker"; Type["Node"] = "node"; Type["Browser"] = "browser"; Type["AuctionWorklet"] = "auction-worklet"; Type["Tab"] = "tab"; })(Type || (Type = {})); // TODO(crbug.com/1167717): Make this a const enum again // eslint-disable-next-line rulesdir/const_enum export var Capability; (function (Capability) { Capability[Capability["Browser"] = 1] = "Browser"; Capability[Capability["DOM"] = 2] = "DOM"; Capability[Capability["JS"] = 4] = "JS"; Capability[Capability["Log"] = 8] = "Log"; Capability[Capability["Network"] = 16] = "Network"; Capability[Capability["Target"] = 32] = "Target"; Capability[Capability["ScreenCapture"] = 64] = "ScreenCapture"; Capability[Capability["Tracing"] = 128] = "Tracing"; Capability[Capability["Emulation"] = 256] = "Emulation"; Capability[Capability["Security"] = 512] = "Security"; Capability[Capability["Input"] = 1024] = "Input"; Capability[Capability["Inspector"] = 2048] = "Inspector"; Capability[Capability["DeviceEmulation"] = 4096] = "DeviceEmulation"; Capability[Capability["Storage"] = 8192] = "Storage"; Capability[Capability["ServiceWorker"] = 16384] = "ServiceWorker"; Capability[Capability["Audits"] = 32768] = "Audits"; Capability[Capability["WebAuthn"] = 65536] = "WebAuthn"; Capability[Capability["IO"] = 131072] = "IO"; Capability[Capability["Media"] = 262144] = "Media"; Capability[Capability["EventBreakpoints"] = 524288] = "EventBreakpoints"; Capability[Capability["None"] = 0] = "None"; })(Capability || (Capability = {})); //# sourceMappingURL=Target.js.map