UNPKG

@dcloudio/uni-debugger

Version:

uni-app debugger

207 lines (188 loc) 6.99 kB
// 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. /** * @implements {SDK.TargetManager.Observer} * @unrestricted */ Main.ExecutionContextSelector = class { /** * @param {!SDK.TargetManager} targetManager * @param {!UI.Context} context */ constructor(targetManager, context) { targetManager.observeTargets(this, SDK.Target.Capability.JS); context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContextChanged, this); context.addFlavorChangeListener(SDK.Target, this._targetChanged, this); targetManager.addModelListener( SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this._onExecutionContextCreated, this); targetManager.addModelListener( SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, this._onExecutionContextDestroyed, this); targetManager.addModelListener( SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextOrderChanged, this._onExecutionContextOrderChanged, this); this._targetManager = targetManager; this._context = context; } /** * @override * @param {!SDK.Target} target */ targetAdded(target) { // Defer selecting default target since we need all clients to get their // targetAdded notifications first. setImmediate(deferred.bind(this)); /** * @this {Main.ExecutionContextSelector} */ function deferred() { // We always want the second context for the service worker targets. if (!this._context.flavor(SDK.Target)) this._context.setFlavor(SDK.Target, target); } } /** * @override * @param {!SDK.Target} target */ targetRemoved(target) { const currentExecutionContext = this._context.flavor(SDK.ExecutionContext); if (currentExecutionContext && currentExecutionContext.target() === target) this._currentExecutionContextGone(); const targets = this._targetManager.targets(SDK.Target.Capability.JS); if (this._context.flavor(SDK.Target) === target && targets.length) this._context.setFlavor(SDK.Target, targets[0]); } /** * @param {!Common.Event} event */ _executionContextChanged(event) { const newContext = /** @type {?SDK.ExecutionContext} */ (event.data); if (newContext) { this._context.setFlavor(SDK.Target, newContext.target()); if (!this._ignoreContextChanged) this._lastSelectedContextId = this._contextPersistentId(newContext); } } /** * @param {!SDK.ExecutionContext} executionContext * @return {string} */ _contextPersistentId(executionContext) { return executionContext.isDefault ? executionContext.target().name() + ':' + executionContext.frameId : ''; } /** * @param {!Common.Event} event */ _targetChanged(event) { const newTarget = /** @type {?SDK.Target} */ (event.data); const currentContext = this._context.flavor(SDK.ExecutionContext); if (!newTarget || (currentContext && currentContext.target() === newTarget)) return; const runtimeModel = newTarget.model(SDK.RuntimeModel); const executionContexts = runtimeModel ? runtimeModel.executionContexts() : []; if (!executionContexts.length) return; let newContext = null; for (let i = 0; i < executionContexts.length && !newContext; ++i) { if (this._shouldSwitchToContext(executionContexts[i])) newContext = executionContexts[i]; } for (let i = 0; i < executionContexts.length && !newContext; ++i) { if (this._isDefaultContext(executionContexts[i])) newContext = executionContexts[i]; } this._ignoreContextChanged = true; this._context.setFlavor(SDK.ExecutionContext, newContext || executionContexts[0]); this._ignoreContextChanged = false; } /** * @param {!SDK.ExecutionContext} executionContext * @return {boolean} */ _shouldSwitchToContext(executionContext) { if (this._lastSelectedContextId && this._lastSelectedContextId === this._contextPersistentId(executionContext)) return true; if (!this._lastSelectedContextId && this._isDefaultContext(executionContext)) return true; return false; } /** * @param {!SDK.ExecutionContext} executionContext * @return {boolean} */ _isDefaultContext(executionContext) { if (!executionContext.isDefault || !executionContext.frameId) return false; if (executionContext.target().parentTarget()) return false; const resourceTreeModel = executionContext.target().model(SDK.ResourceTreeModel); const frame = resourceTreeModel && resourceTreeModel.frameForId(executionContext.frameId); if (frame && frame.isTopFrame()) return true; return false; } /** * @param {!Common.Event} event */ _onExecutionContextCreated(event) { this._switchContextIfNecessary(/** @type {!SDK.ExecutionContext} */ (event.data)); } /** * @param {!Common.Event} event */ _onExecutionContextDestroyed(event) { const executionContext = /** @type {!SDK.ExecutionContext}*/ (event.data); if (this._context.flavor(SDK.ExecutionContext) === executionContext) this._currentExecutionContextGone(); } /** * @param {!Common.Event} event */ _onExecutionContextOrderChanged(event) { const runtimeModel = /** @type {!SDK.RuntimeModel} */ (event.data); const executionContexts = runtimeModel.executionContexts(); for (let i = 0; i < executionContexts.length; i++) { if (this._switchContextIfNecessary(executionContexts[i])) break; } } /** * @param {!SDK.ExecutionContext} executionContext * @return {boolean} */ _switchContextIfNecessary(executionContext) { if (!this._context.flavor(SDK.ExecutionContext) || this._shouldSwitchToContext(executionContext)) { this._ignoreContextChanged = true; this._context.setFlavor(SDK.ExecutionContext, executionContext); this._ignoreContextChanged = false; return true; } return false; } _currentExecutionContextGone() { const runtimeModels = this._targetManager.models(SDK.RuntimeModel); let newContext = null; for (let i = 0; i < runtimeModels.length && !newContext; ++i) { const executionContexts = runtimeModels[i].executionContexts(); for (const executionContext of executionContexts) { if (this._isDefaultContext(executionContext)) { newContext = executionContext; break; } } } if (!newContext) { for (let i = 0; i < runtimeModels.length && !newContext; ++i) { const executionContexts = runtimeModels[i].executionContexts(); if (executionContexts.length) { newContext = executionContexts[0]; break; } } } this._ignoreContextChanged = true; this._context.setFlavor(SDK.ExecutionContext, newContext); this._ignoreContextChanged = false; } };