OLD | NEW |
| (Empty) |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | |
2 // Use of this source code is governed by a BSD-style license that can be | |
3 // found in the LICENSE file. | |
4 /** | |
5 * @implements {SDK.TargetManager.Observer} | |
6 * @unrestricted | |
7 */ | |
8 Components.ExecutionContextSelector = class { | |
9 /** | |
10 * @param {!SDK.TargetManager} targetManager | |
11 * @param {!UI.Context} context | |
12 */ | |
13 constructor(targetManager, context) { | |
14 targetManager.observeTargets(this, SDK.Target.Capability.JS); | |
15 context.addFlavorChangeListener(SDK.ExecutionContext, this._executionContext
Changed, this); | |
16 context.addFlavorChangeListener(SDK.Target, this._targetChanged, this); | |
17 | |
18 targetManager.addModelListener( | |
19 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextCreated, this.
_onExecutionContextCreated, this); | |
20 targetManager.addModelListener( | |
21 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextDestroyed, thi
s._onExecutionContextDestroyed, this); | |
22 targetManager.addModelListener( | |
23 SDK.RuntimeModel, SDK.RuntimeModel.Events.ExecutionContextOrderChanged,
this._onExecutionContextOrderChanged, | |
24 this); | |
25 this._targetManager = targetManager; | |
26 this._context = context; | |
27 } | |
28 | |
29 /** | |
30 * @override | |
31 * @param {!SDK.Target} target | |
32 */ | |
33 targetAdded(target) { | |
34 // Defer selecting default target since we need all clients to get their | |
35 // targetAdded notifications first. | |
36 setImmediate(deferred.bind(this)); | |
37 | |
38 /** | |
39 * @this {Components.ExecutionContextSelector} | |
40 */ | |
41 function deferred() { | |
42 // We always want the second context for the service worker targets. | |
43 if (!this._context.flavor(SDK.Target)) | |
44 this._context.setFlavor(SDK.Target, target); | |
45 } | |
46 } | |
47 | |
48 /** | |
49 * @override | |
50 * @param {!SDK.Target} target | |
51 */ | |
52 targetRemoved(target) { | |
53 var currentExecutionContext = this._context.flavor(SDK.ExecutionContext); | |
54 if (currentExecutionContext && currentExecutionContext.target() === target) | |
55 this._currentExecutionContextGone(); | |
56 | |
57 var targets = this._targetManager.targets(SDK.Target.Capability.JS); | |
58 if (this._context.flavor(SDK.Target) === target && targets.length) | |
59 this._context.setFlavor(SDK.Target, targets[0]); | |
60 } | |
61 | |
62 /** | |
63 * @param {!Common.Event} event | |
64 */ | |
65 _executionContextChanged(event) { | |
66 var newContext = /** @type {?SDK.ExecutionContext} */ (event.data); | |
67 if (newContext) { | |
68 this._context.setFlavor(SDK.Target, newContext.target()); | |
69 if (!this._ignoreContextChanged) | |
70 this._lastSelectedContextId = this._contextPersistentId(newContext); | |
71 } | |
72 } | |
73 | |
74 /** | |
75 * @param {!SDK.ExecutionContext} executionContext | |
76 * @return {string} | |
77 */ | |
78 _contextPersistentId(executionContext) { | |
79 return executionContext.isDefault ? executionContext.target().name() + ':' +
executionContext.frameId : ''; | |
80 } | |
81 | |
82 /** | |
83 * @param {!Common.Event} event | |
84 */ | |
85 _targetChanged(event) { | |
86 var newTarget = /** @type {?SDK.Target} */ (event.data); | |
87 var currentContext = this._context.flavor(SDK.ExecutionContext); | |
88 | |
89 if (!newTarget || (currentContext && currentContext.target() === newTarget)) | |
90 return; | |
91 | |
92 var executionContexts = newTarget.runtimeModel.executionContexts(); | |
93 if (!executionContexts.length) | |
94 return; | |
95 | |
96 var newContext = null; | |
97 for (var i = 0; i < executionContexts.length && !newContext; ++i) { | |
98 if (this._shouldSwitchToContext(executionContexts[i])) | |
99 newContext = executionContexts[i]; | |
100 } | |
101 for (var i = 0; i < executionContexts.length && !newContext; ++i) { | |
102 if (this._isDefaultContext(executionContexts[i])) | |
103 newContext = executionContexts[i]; | |
104 } | |
105 this._ignoreContextChanged = true; | |
106 this._context.setFlavor(SDK.ExecutionContext, newContext || executionContext
s[0]); | |
107 this._ignoreContextChanged = false; | |
108 } | |
109 | |
110 /** | |
111 * @param {!SDK.ExecutionContext} executionContext | |
112 * @return {boolean} | |
113 */ | |
114 _shouldSwitchToContext(executionContext) { | |
115 if (this._lastSelectedContextId && this._lastSelectedContextId === this._con
textPersistentId(executionContext)) | |
116 return true; | |
117 if (!this._lastSelectedContextId && this._isDefaultContext(executionContext)
) | |
118 return true; | |
119 return false; | |
120 } | |
121 | |
122 /** | |
123 * @param {!SDK.ExecutionContext} executionContext | |
124 * @return {boolean} | |
125 */ | |
126 _isDefaultContext(executionContext) { | |
127 if (!executionContext.isDefault || !executionContext.frameId) | |
128 return false; | |
129 if (executionContext.target().parentTarget()) | |
130 return false; | |
131 var resourceTreeModel = SDK.ResourceTreeModel.fromTarget(executionContext.ta
rget()); | |
132 var frame = resourceTreeModel && resourceTreeModel.frameForId(executionConte
xt.frameId); | |
133 if (frame && frame.isMainFrame()) | |
134 return true; | |
135 return false; | |
136 } | |
137 | |
138 /** | |
139 * @param {!Common.Event} event | |
140 */ | |
141 _onExecutionContextCreated(event) { | |
142 this._switchContextIfNecessary(/** @type {!SDK.ExecutionContext} */ (event.d
ata)); | |
143 } | |
144 | |
145 /** | |
146 * @param {!Common.Event} event | |
147 */ | |
148 _onExecutionContextDestroyed(event) { | |
149 var executionContext = /** @type {!SDK.ExecutionContext}*/ (event.data); | |
150 if (this._context.flavor(SDK.ExecutionContext) === executionContext) | |
151 this._currentExecutionContextGone(); | |
152 } | |
153 | |
154 /** | |
155 * @param {!Common.Event} event | |
156 */ | |
157 _onExecutionContextOrderChanged(event) { | |
158 var runtimeModel = /** @type {!SDK.RuntimeModel} */ (event.data); | |
159 var executionContexts = runtimeModel.executionContexts(); | |
160 for (var i = 0; i < executionContexts.length; i++) { | |
161 if (this._switchContextIfNecessary(executionContexts[i])) | |
162 break; | |
163 } | |
164 } | |
165 | |
166 /** | |
167 * @param {!SDK.ExecutionContext} executionContext | |
168 * @return {boolean} | |
169 */ | |
170 _switchContextIfNecessary(executionContext) { | |
171 if (!this._context.flavor(SDK.ExecutionContext) || this._shouldSwitchToConte
xt(executionContext)) { | |
172 this._ignoreContextChanged = true; | |
173 this._context.setFlavor(SDK.ExecutionContext, executionContext); | |
174 this._ignoreContextChanged = false; | |
175 return true; | |
176 } | |
177 return false; | |
178 } | |
179 | |
180 _currentExecutionContextGone() { | |
181 var targets = this._targetManager.targets(SDK.Target.Capability.JS); | |
182 var newContext = null; | |
183 for (var i = 0; i < targets.length && !newContext; ++i) { | |
184 var executionContexts = targets[i].runtimeModel.executionContexts(); | |
185 for (var executionContext of executionContexts) { | |
186 if (this._isDefaultContext(executionContext)) { | |
187 newContext = executionContext; | |
188 break; | |
189 } | |
190 } | |
191 } | |
192 if (!newContext) { | |
193 for (var i = 0; i < targets.length && !newContext; ++i) { | |
194 var executionContexts = targets[i].runtimeModel.executionContexts(); | |
195 if (executionContexts.length) { | |
196 newContext = executionContexts[0]; | |
197 break; | |
198 } | |
199 } | |
200 } | |
201 this._ignoreContextChanged = true; | |
202 this._context.setFlavor(SDK.ExecutionContext, newContext); | |
203 this._ignoreContextChanged = false; | |
204 } | |
205 }; | |
OLD | NEW |