blob: 7db4a5b178d7cf58cac03273e54e9537eabcb457 [file] [log] [blame]
// Copyright 2018 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 Components from '../components/components.js';
import * as Host from '../host/host.js';
import * as MobileThrottling from '../mobile_throttling/mobile_throttling.js';
import * as Root from '../root/root.js';
import * as SDK from '../sdk/sdk.js';
import * as UI from '../ui/ui.js';
/**
* @implements {Common.Runnable.Runnable}
*/
export class InspectorMainImpl extends Common.ObjectWrapper.ObjectWrapper {
/**
* @override
*/
async run() {
let firstCall = true;
await SDK.Connections.initMainConnection(async () => {
const type = Root.Runtime.Runtime.queryParam('v8only') ? SDK.SDKModel.Type.Node : SDK.SDKModel.Type.Frame;
const waitForDebuggerInPage =
type === SDK.SDKModel.Type.Frame && Root.Runtime.Runtime.queryParam('panel') === 'sources';
const target = SDK.SDKModel.TargetManager.instance().createTarget(
'main', Common.UIString.UIString('Main'), type, null, undefined, waitForDebuggerInPage);
// Only resume target during the first connection,
// subsequent connections are due to connection hand-over,
// there is no need to pause in debugger.
if (!firstCall) {
return;
}
firstCall = false;
if (waitForDebuggerInPage) {
const debuggerModel = target.model(SDK.DebuggerModel.DebuggerModel);
if (debuggerModel) {
if (!debuggerModel.isReadyToPause()) {
await debuggerModel.once(SDK.DebuggerModel.Events.DebuggerIsReadyToPause);
}
debuggerModel.pause();
}
}
await target.runtimeAgent().invoke_runIfWaitingForDebugger();
}, Components.TargetDetachedDialog.TargetDetachedDialog.webSocketConnectionLost);
new SourcesPanelIndicator();
new BackendSettingsSync();
new MobileThrottling.NetworkPanelIndicator.NetworkPanelIndicator();
Host.InspectorFrontendHost.InspectorFrontendHostInstance.events.addEventListener(
Host.InspectorFrontendHostAPI.Events.ReloadInspectedPage, event => {
const hard = /** @type {boolean} */ (event.data);
SDK.ResourceTreeModel.ResourceTreeModel.reloadAllPages(hard);
});
}
}
/**
* @implements {UI.ActionRegistration.ActionDelegate}
* @unrestricted
*/
export class ReloadActionDelegate {
/**
* @override
* @param {!UI.Context.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction(context, actionId) {
switch (actionId) {
case 'inspector_main.reload':
SDK.ResourceTreeModel.ResourceTreeModel.reloadAllPages(false);
return true;
case 'inspector_main.hard-reload':
SDK.ResourceTreeModel.ResourceTreeModel.reloadAllPages(true);
return true;
}
return false;
}
}
/**
* @implements {UI.ActionRegistration.ActionDelegate}
* @unrestricted
*/
export class FocusDebuggeeActionDelegate {
/**
* @override
* @param {!UI.Context.Context} context
* @param {string} actionId
* @return {boolean}
*/
handleAction(context, actionId) {
const mainTarget = SDK.SDKModel.TargetManager.instance().mainTarget();
if (!mainTarget) {
return false;
}
mainTarget.pageAgent().invoke_bringToFront();
return true;
}
}
/**
* @implements {UI.Toolbar.Provider}
*/
export class NodeIndicator {
constructor() {
const element = document.createElement('div');
const shadowRoot = UI.Utils.createShadowRootWithCoreStyles(
element, {cssFile: 'inspector_main/nodeIcon.css', enableLegacyPatching: true, delegatesFocus: undefined});
this._element = shadowRoot.createChild('div', 'node-icon');
element.addEventListener(
'click', () => Host.InspectorFrontendHost.InspectorFrontendHostInstance.openNodeFrontend(), false);
this._button = new UI.Toolbar.ToolbarItem(element);
this._button.setTitle(Common.UIString.UIString('Open dedicated DevTools for Node.js'));
SDK.SDKModel.TargetManager.instance().addEventListener(
SDK.SDKModel.Events.AvailableTargetsChanged,
event => this._update(/** @type {!Array<!Protocol.Target.TargetInfo>} */ (event.data)));
this._button.setVisible(false);
this._update([]);
}
/**
* @param {!Array<!Protocol.Target.TargetInfo>} targetInfos
*/
_update(targetInfos) {
const hasNode = !!targetInfos.find(target => target.type === 'node' && !target.attached);
this._element.classList.toggle('inactive', !hasNode);
if (hasNode) {
this._button.setVisible(true);
}
}
/**
* @override
* @return {?UI.Toolbar.ToolbarItem}
*/
item() {
return this._button;
}
}
/**
* @unrestricted
*/
export class SourcesPanelIndicator {
constructor() {
Common.Settings.Settings.instance()
.moduleSetting('javaScriptDisabled')
.addChangeListener(javaScriptDisabledChanged);
javaScriptDisabledChanged();
function javaScriptDisabledChanged() {
let icon = null;
const javaScriptDisabled = Common.Settings.Settings.instance().moduleSetting('javaScriptDisabled').get();
if (javaScriptDisabled) {
icon = UI.Icon.Icon.create('smallicon-warning');
icon.title = Common.UIString.UIString('JavaScript is disabled');
}
UI.InspectorView.InspectorView.instance().setPanelIcon('sources', icon);
}
}
}
/**
* @implements {SDK.SDKModel.Observer}
* @unrestricted
*/
export class BackendSettingsSync {
constructor() {
this._autoAttachSetting = Common.Settings.Settings.instance().moduleSetting('autoAttachToCreatedPages');
this._autoAttachSetting.addChangeListener(this._updateAutoAttach, this);
this._updateAutoAttach();
this._adBlockEnabledSetting = Common.Settings.Settings.instance().moduleSetting('network.adBlockingEnabled');
this._adBlockEnabledSetting.addChangeListener(this._update, this);
this._emulatePageFocusSetting = Common.Settings.Settings.instance().moduleSetting('emulatePageFocus');
this._emulatePageFocusSetting.addChangeListener(this._update, this);
SDK.SDKModel.TargetManager.instance().observeTargets(this);
}
/**
* @param {!SDK.SDKModel.Target} target
*/
_updateTarget(target) {
if (target.type() !== SDK.SDKModel.Type.Frame || target.parentTarget()) {
return;
}
target.pageAgent().invoke_setAdBlockingEnabled({enabled: this._adBlockEnabledSetting.get()});
target.emulationAgent().invoke_setFocusEmulationEnabled({enabled: this._emulatePageFocusSetting.get()});
}
_updateAutoAttach() {
Host.InspectorFrontendHost.InspectorFrontendHostInstance.setOpenNewWindowForPopups(this._autoAttachSetting.get());
}
_update() {
for (const target of SDK.SDKModel.TargetManager.instance().targets()) {
this._updateTarget(target);
}
}
/**
* @param {!SDK.SDKModel.Target} target
* @override
*/
targetAdded(target) {
this._updateTarget(target);
}
/**
* @param {!SDK.SDKModel.Target} target
* @override
*/
targetRemoved(target) {
}
}
SDK.ChildTargetManager.ChildTargetManager.install();