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.
7 * @implements {WebInspector.TargetManager.Observer}
8 * @param {!WebInspector.TargetManager} targetManager
9 * @param {!WebInspector.Context} context
11 WebInspector
.ExecutionContextSelector = function(targetManager
, context
)
13 targetManager
.observeTargets(this);
14 context
.addFlavorChangeListener(WebInspector
.ExecutionContext
, this._executionContextChanged
, this);
15 context
.addFlavorChangeListener(WebInspector
.Target
, this._targetChanged
, this);
17 targetManager
.addModelListener(WebInspector
.RuntimeModel
, WebInspector
.RuntimeModel
.Events
.ExecutionContextCreated
, this._onExecutionContextCreated
, this);
18 targetManager
.addModelListener(WebInspector
.RuntimeModel
, WebInspector
.RuntimeModel
.Events
.ExecutionContextDestroyed
, this._onExecutionContextDestroyed
, this);
19 this._targetManager
= targetManager
;
20 this._context
= context
;
23 WebInspector
.ExecutionContextSelector
.prototype = {
27 * @param {!WebInspector.Target} target
29 targetAdded: function(target
)
31 if (!target
.hasJSContext())
33 // Defer selecting default target since we need all clients to get their
34 // targetAdded notifications first.
35 setImmediate(deferred
.bind(this));
38 * @this {WebInspector.ExecutionContextSelector}
42 // We always want the second context for the service worker targets.
43 if (!this._context
.flavor(WebInspector
.Target
))
44 this._context
.setFlavor(WebInspector
.Target
, target
);
50 * @param {!WebInspector.Target} target
52 targetRemoved: function(target
)
54 if (!target
.hasJSContext())
56 var currentExecutionContext
= this._context
.flavor(WebInspector
.ExecutionContext
);
57 if (currentExecutionContext
&& currentExecutionContext
.target() === target
)
58 this._currentExecutionContextGone();
60 var targets
= this._targetManager
.targetsWithJSContext();
61 if (this._context
.flavor(WebInspector
.Target
) === target
&& targets
.length
)
62 this._context
.setFlavor(WebInspector
.Target
, targets
[0]);
66 * @param {!WebInspector.Event} event
68 _executionContextChanged: function(event
)
70 var newContext
= /** @type {?WebInspector.ExecutionContext} */ (event
.data
);
72 this._context
.setFlavor(WebInspector
.Target
, newContext
.target());
73 if (!this._contextIsGoingAway
)
74 this._lastSelectedContextId
= this._contextPersistentId(newContext
);
79 * @param {!WebInspector.ExecutionContext} executionContext
82 _contextPersistentId: function(executionContext
)
84 return executionContext
.isMainWorldContext
? executionContext
.target().name() + ":" + executionContext
.frameId
: "";
88 * @param {!WebInspector.Event} event
90 _targetChanged: function(event
)
92 var newTarget
= /** @type {?WebInspector.Target} */(event
.data
);
93 var currentContext
= this._context
.flavor(WebInspector
.ExecutionContext
);
95 if (!newTarget
|| (currentContext
&& currentContext
.target() === newTarget
))
98 var executionContexts
= newTarget
.runtimeModel
.executionContexts();
99 if (!executionContexts
.length
)
102 var newContext
= executionContexts
[0];
103 for (var i
= 1; i
< executionContexts
.length
; ++i
) {
104 if (executionContexts
[i
].isMainWorldContext
)
105 newContext
= executionContexts
[i
];
107 this._context
.setFlavor(WebInspector
.ExecutionContext
, newContext
);
111 * @param {!WebInspector.Event} event
113 _onExecutionContextCreated: function(event
)
115 var executionContext
= /** @type {!WebInspector.ExecutionContext} */ (event
.data
);
116 if (!this._context
.flavor(WebInspector
.ExecutionContext
) || (this._lastSelectedContextId
&& this._lastSelectedContextId
=== this._contextPersistentId(executionContext
)))
117 this._context
.setFlavor(WebInspector
.ExecutionContext
, executionContext
);
121 * @param {!WebInspector.Event} event
123 _onExecutionContextDestroyed: function(event
)
125 var executionContext
= /** @type {!WebInspector.ExecutionContext}*/ (event
.data
);
126 if (this._context
.flavor(WebInspector
.ExecutionContext
) === executionContext
)
127 this._currentExecutionContextGone();
130 _currentExecutionContextGone: function()
132 var targets
= this._targetManager
.targetsWithJSContext();
133 var newContext
= null;
134 for (var i
= 0; i
< targets
.length
; ++i
) {
135 if (targets
[i
].isServiceWorker())
137 var executionContexts
= targets
[i
].runtimeModel
.executionContexts();
138 if (executionContexts
.length
) {
139 newContext
= executionContexts
[0];
143 this._contextIsGoingAway
= true;
144 this._context
.setFlavor(WebInspector
.ExecutionContext
, newContext
);
145 this._contextIsGoingAway
= false;
150 * @param {!Element} proxyElement
151 * @param {!Range} wordRange
152 * @param {boolean} force
153 * @param {function(!Array.<string>, number=)} completionsReadyCallback
155 WebInspector
.ExecutionContextSelector
.completionsForTextPromptInCurrentContext = function(proxyElement
, wordRange
, force
, completionsReadyCallback
)
157 var executionContext
= WebInspector
.context
.flavor(WebInspector
.ExecutionContext
);
158 if (!executionContext
) {
159 completionsReadyCallback([]);
163 // Pass less stop characters to rangeOfWord so the range will be a more complete expression.
164 var expressionRange
= wordRange
.startContainer
.rangeOfWord(wordRange
.startOffset
, " =:({;,!+-*/&|^<>", proxyElement
, "backward");
165 var expressionString
= expressionRange
.toString();
167 // The "[" is also a stop character, except when it's the last character of the expression.
168 var pos
= expressionString
.lastIndexOf("[", expressionString
.length
- 2);
170 expressionString
= expressionString
.substr(pos
+ 1);
172 var prefix
= wordRange
.toString();
173 executionContext
.completionsForExpression(expressionString
, prefix
, force
, completionsReadyCallback
);