blob: 87cc1c6af87007d091ab98d85278fd5fb6685257 [file] [log] [blame]
/*
* Copyright 2014 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.
*/
/**
* @unrestricted
*/
SDK.Target = class extends Protocol.TargetBase {
/**
* @param {!SDK.TargetManager} targetManager
* @param {string} id
* @param {string} name
* @param {number} capabilitiesMask
* @param {!Protocol.InspectorBackend.Connection.Factory} connectionFactory
* @param {?SDK.Target} parentTarget
* @param {boolean} suspended
*/
constructor(targetManager, id, name, capabilitiesMask, connectionFactory, parentTarget, suspended) {
super(connectionFactory);
this._targetManager = targetManager;
this._name = name;
this._inspectedURL = '';
this._capabilitiesMask = capabilitiesMask;
this._parentTarget = parentTarget;
this._id = id;
this._modelByConstructor = new Map();
this._isSuspended = suspended;
}
createModels(required) {
this._creatingModels = true;
// TODO(dgozman): fix this in bindings layer.
this.model(SDK.ResourceTreeModel);
const registered = Array.from(SDK.SDKModel._registeredModels.keys());
for (const modelClass of registered) {
const info = SDK.SDKModel._registeredModels.get(modelClass);
if (info.autostart || required.has(modelClass))
this.model(modelClass);
}
this._creatingModels = false;
}
/**
* @return {boolean}
*/
isNodeJS() {
// TODO(lushnikov): this is an unreliable way to detect Node.js targets.
return this._capabilitiesMask === SDK.Target.Capability.JS || this._isNodeJSForTest;
}
setIsNodeJSForTest() {
this._isNodeJSForTest = true;
}
/**
* @return {string}
*/
id() {
return this._id;
}
/**
* @return {string}
*/
name() {
return this._name || this._inspectedURLName;
}
/**
* @return {!SDK.TargetManager}
*/
targetManager() {
return this._targetManager;
}
/**
* @param {number} capabilitiesMask
* @return {boolean}
*/
hasAllCapabilities(capabilitiesMask) {
return (this._capabilitiesMask & capabilitiesMask) === capabilitiesMask;
}
/**
* @param {string} label
* @return {string}
*/
decorateLabel(label) {
return !this.hasBrowserCapability() ? '\u2699 ' + label : label;
}
/**
* @return {boolean}
*/
hasBrowserCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.Browser);
}
/**
* @return {boolean}
*/
hasJSCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.JS);
}
/**
* @return {boolean}
*/
hasLogCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.Log);
}
/**
* @return {boolean}
*/
hasNetworkCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.Network);
}
/**
* @return {boolean}
*/
hasTargetCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.Target);
}
/**
* @return {boolean}
*/
hasDOMCapability() {
return this.hasAllCapabilities(SDK.Target.Capability.DOM);
}
/**
* @return {?SDK.Target}
*/
parentTarget() {
return this._parentTarget;
}
/**
* @override
*/
dispose() {
this._targetManager.removeTarget(this);
for (const model of this._modelByConstructor.valuesArray())
model.dispose();
}
/**
* @param {function(new:T, !SDK.Target)} modelClass
* @return {?T}
* @template T
*/
model(modelClass) {
if (!this._modelByConstructor.get(modelClass)) {
const info = SDK.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._targetManager.modelAdded(this, modelClass, model);
}
}
return this._modelByConstructor.get(modelClass) || null;
}
/**
* @return {!Map<function(new:SDK.SDKModel, !SDK.Target), !SDK.SDKModel>}
*/
models() {
return this._modelByConstructor;
}
/**
* @return {string}
*/
inspectedURL() {
return this._inspectedURL;
}
/**
* @param {string} inspectedURL
*/
setInspectedURL(inspectedURL) {
this._inspectedURL = inspectedURL;
const parsedURL = inspectedURL.asParsedURL();
this._inspectedURLName = parsedURL ? parsedURL.lastPathComponentWithFragment() : '#' + this._id;
if (!this.parentTarget())
InspectorFrontendHost.inspectedURLChanged(inspectedURL || '');
this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.InspectedURLChanged, this);
if (!this._name)
this._targetManager.dispatchEventToListeners(SDK.TargetManager.Events.NameChanged, this);
}
/**
* @return {!Promise}
*/
suspend() {
if (this._isSuspended)
return Promise.resolve();
this._isSuspended = true;
const promises = [];
for (const model of this.models().values())
promises.push(model.suspendModel());
return Promise.all(promises);
}
/**
* @return {!Promise}
*/
resume() {
if (!this._isSuspended)
return Promise.resolve();
this._isSuspended = false;
const promises = [];
for (const model of this.models().values())
promises.push(model.resumeModel());
return Promise.all(promises);
}
/**
* @return {boolean}
*/
suspended() {
return this._isSuspended;
}
};
/**
* @enum {number}
*/
SDK.Target.Capability = {
Browser: 1 << 0,
DOM: 1 << 1,
JS: 1 << 2,
Log: 1 << 3,
Network: 1 << 4,
Target: 1 << 5,
ScreenCapture: 1 << 6,
Tracing: 1 << 7,
Emulation: 1 << 8,
Security: 1 << 9,
Input: 1 << 10,
Inspector: 1 << 11,
DeviceEmulation: 1 << 12,
None: 0,
AllForTests: (1 << 13) - 1
};
/**
* @unrestricted
*/
SDK.SDKModel = class extends Common.Object {
/**
* @param {!SDK.Target} target
*/
constructor(target) {
super();
this._target = target;
}
/**
* @return {!SDK.Target}
*/
target() {
return this._target;
}
/**
* @return {!Promise}
*/
suspendModel() {
return Promise.resolve();
}
/**
* @return {!Promise}
*/
resumeModel() {
return Promise.resolve();
}
dispose() {
}
};
/**
* @param {function(new:SDK.SDKModel, !SDK.Target)} modelClass
* @param {number} capabilities
* @param {boolean} autostart
*/
SDK.SDKModel.register = function(modelClass, capabilities, autostart) {
if (!SDK.SDKModel._registeredModels)
SDK.SDKModel._registeredModels = new Map();
SDK.SDKModel._registeredModels.set(modelClass, {capabilities: capabilities, autostart: autostart});
};
/** @type {!Map<function(new:SDK.SDKModel, !SDK.Target), !{capabilities: number, autostart: boolean}>} */
SDK.SDKModel._registeredModels;