Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(925)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/sdk/RuntimeModel.js

Issue 2466123002: DevTools: reformat front-end code to match chromium style. (Closed)
Patch Set: all done Created 4 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 /* 1 /*
2 * Copyright (C) 2012 Google Inc. All rights reserved. 2 * Copyright (C) 2012 Google Inc. All rights reserved.
3 * 3 *
4 * Redistribution and use in source and binary forms, with or without 4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are 5 * modification, are permitted provided that the following conditions are
6 * met: 6 * met:
7 * 7 *
8 * * Redistributions of source code must retain the above copyright 8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer. 9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above 10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer 11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the 12 * in the documentation and/or other materials provided with the
13 * distribution. 13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its 14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from 15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission. 16 * this software without specific prior written permission.
17 * 17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */ 29 */
30
31 /** 30 /**
32 * @constructor 31 * @unrestricted
33 * @extends {WebInspector.SDKModel}
34 * @param {!WebInspector.Target} target
35 */ 32 */
36 WebInspector.RuntimeModel = function(target) 33 WebInspector.RuntimeModel = class extends WebInspector.SDKModel {
37 { 34 /**
38 WebInspector.SDKModel.call(this, WebInspector.RuntimeModel, target); 35 * @param {!WebInspector.Target} target
36 */
37 constructor(target) {
38 super(WebInspector.RuntimeModel, target);
39 39
40 this._agent = target.runtimeAgent(); 40 this._agent = target.runtimeAgent();
41 this.target().registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(t his)); 41 this.target().registerRuntimeDispatcher(new WebInspector.RuntimeDispatcher(t his));
42 if (target.hasJSCapability()) 42 if (target.hasJSCapability())
43 this._agent.enable(); 43 this._agent.enable();
44 /** @type {!Map<number, !WebInspector.ExecutionContext>} */ 44 /** @type {!Map<number, !WebInspector.ExecutionContext>} */
45 this._executionContextById = new Map(); 45 this._executionContextById = new Map();
46 this._executionContextComparator = WebInspector.ExecutionContext.comparator; 46 this._executionContextComparator = WebInspector.ExecutionContext.comparator;
47 47
48 if (WebInspector.moduleSetting("customFormatters").get()) 48 if (WebInspector.moduleSetting('customFormatters').get())
49 this._agent.setCustomObjectFormatterEnabled(true); 49 this._agent.setCustomObjectFormatterEnabled(true);
50 50
51 WebInspector.moduleSetting("customFormatters").addChangeListener(this._custo mFormattersStateChanged.bind(this)); 51 WebInspector.moduleSetting('customFormatters').addChangeListener(this._custo mFormattersStateChanged.bind(this));
52 }
53
54 /**
55 * @return {!Array.<!WebInspector.ExecutionContext>}
56 */
57 executionContexts() {
58 return this._executionContextById.valuesArray().sort(this.executionContextCo mparator());
59 }
60
61 /**
62 * @param {function(!WebInspector.ExecutionContext,!WebInspector.ExecutionCont ext)} comparator
63 */
64 setExecutionContextComparator(comparator) {
65 this._executionContextComparator = comparator;
66 }
67
68 /**
69 * @return {function(!WebInspector.ExecutionContext,!WebInspector.ExecutionCon text)} comparator
70 */
71 executionContextComparator() {
72 return this._executionContextComparator;
73 }
74
75 /**
76 * @return {?WebInspector.ExecutionContext}
77 */
78 defaultExecutionContext() {
79 for (var context of this._executionContextById.values()) {
80 if (context.isDefault)
81 return context;
82 }
83 return null;
84 }
85
86 /**
87 * @param {!RuntimeAgent.ExecutionContextId} id
88 * @return {?WebInspector.ExecutionContext}
89 */
90 executionContext(id) {
91 return this._executionContextById.get(id) || null;
92 }
93
94 /**
95 * @param {!RuntimeAgent.ExecutionContextDescription} context
96 */
97 _executionContextCreated(context) {
98 // The private script context should be hidden behind an experiment.
99 if (context.name === WebInspector.RuntimeModel._privateScript && !context.or igin &&
100 !Runtime.experiments.isEnabled('privateScriptInspection')) {
101 return;
102 }
103 var data = context.auxData || {isDefault: true};
104 var executionContext = new WebInspector.ExecutionContext(
105 this.target(), context.id, context.name, context.origin, data['isDefault '], data['frameId']);
106 this._executionContextById.set(executionContext.id, executionContext);
107 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionCont extCreated, executionContext);
108 }
109
110 /**
111 * @param {number} executionContextId
112 */
113 _executionContextDestroyed(executionContextId) {
114 var executionContext = this._executionContextById.get(executionContextId);
115 if (!executionContext)
116 return;
117 this._executionContextById.delete(executionContextId);
118 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionCont extDestroyed, executionContext);
119 }
120
121 fireExecutionContextOrderChanged() {
122 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionCont extOrderChanged, this);
123 }
124
125 _executionContextsCleared() {
126 var debuggerModel = WebInspector.DebuggerModel.fromTarget(this.target());
127 if (debuggerModel)
128 debuggerModel.globalObjectCleared();
129 var contexts = this.executionContexts();
130 this._executionContextById.clear();
131 for (var i = 0; i < contexts.length; ++i)
132 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.ExecutionCo ntextDestroyed, contexts[i]);
133 }
134
135 /**
136 * @param {!RuntimeAgent.RemoteObject} payload
137 * @return {!WebInspector.RemoteObject}
138 */
139 createRemoteObject(payload) {
140 console.assert(typeof payload === 'object', 'Remote object payload should on ly be an object');
141 return new WebInspector.RemoteObjectImpl(
142 this.target(), payload.objectId, payload.type, payload.subtype, payload. value, payload.unserializableValue,
143 payload.description, payload.preview, payload.customPreview);
144 }
145
146 /**
147 * @param {!RuntimeAgent.RemoteObject} payload
148 * @param {!WebInspector.ScopeRef} scopeRef
149 * @return {!WebInspector.RemoteObject}
150 */
151 createScopeRemoteObject(payload, scopeRef) {
152 return new WebInspector.ScopeRemoteObject(
153 this.target(), payload.objectId, scopeRef, payload.type, payload.subtype , payload.value,
154 payload.unserializableValue, payload.description, payload.preview);
155 }
156
157 /**
158 * @param {number|string|boolean|undefined} value
159 * @return {!WebInspector.RemoteObject}
160 */
161 createRemoteObjectFromPrimitiveValue(value) {
162 var type = typeof value;
163 var unserializableValue = undefined;
164 if (typeof value === 'number') {
165 var description = String(value);
166 if (value === 0 && 1 / value < 0)
167 unserializableValue = RuntimeAgent.UnserializableValue.Negative0;
168 if (description === 'NaN')
169 unserializableValue = RuntimeAgent.UnserializableValue.NaN;
170 if (description === 'Infinity')
171 unserializableValue = RuntimeAgent.UnserializableValue.Infinity;
172 if (description === '-Infinity')
173 unserializableValue = RuntimeAgent.UnserializableValue.NegativeInfinity;
174 if (typeof unserializableValue !== 'undefined')
175 value = undefined;
176 }
177 return new WebInspector.RemoteObjectImpl(this.target(), undefined, type, und efined, value, unserializableValue);
178 }
179
180 /**
181 * @param {string} name
182 * @param {number|string|boolean} value
183 * @return {!WebInspector.RemoteObjectProperty}
184 */
185 createRemotePropertyFromPrimitiveValue(name, value) {
186 return new WebInspector.RemoteObjectProperty(name, this.createRemoteObjectFr omPrimitiveValue(value));
187 }
188
189 discardConsoleEntries() {
190 this._agent.discardConsoleEntries();
191 }
192
193 /**
194 * @param {!WebInspector.Event} event
195 */
196 _customFormattersStateChanged(event) {
197 var enabled = /** @type {boolean} */ (event.data);
198 this._agent.setCustomObjectFormatterEnabled(enabled);
199 }
200
201 /**
202 * @param {string} expression
203 * @param {string} sourceURL
204 * @param {boolean} persistScript
205 * @param {number} executionContextId
206 * @param {function(!RuntimeAgent.ScriptId=, ?RuntimeAgent.ExceptionDetails=)= } callback
207 */
208 compileScript(expression, sourceURL, persistScript, executionContextId, callba ck) {
209 this._agent.compileScript(expression, sourceURL, persistScript, executionCon textId, innerCallback);
210
211 /**
212 * @param {?Protocol.Error} error
213 * @param {!RuntimeAgent.ScriptId=} scriptId
214 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
215 */
216 function innerCallback(error, scriptId, exceptionDetails) {
217 if (error) {
218 console.error(error);
219 return;
220 }
221 if (callback)
222 callback(scriptId, exceptionDetails);
223 }
224 }
225
226 /**
227 * @param {!RuntimeAgent.ScriptId} scriptId
228 * @param {number} executionContextId
229 * @param {string=} objectGroup
230 * @param {boolean=} silent
231 * @param {boolean=} includeCommandLineAPI
232 * @param {boolean=} returnByValue
233 * @param {boolean=} generatePreview
234 * @param {boolean=} awaitPromise
235 * @param {function(?RuntimeAgent.RemoteObject, ?RuntimeAgent.ExceptionDetails =)=} callback
236 */
237 runScript(
238 scriptId,
239 executionContextId,
240 objectGroup,
241 silent,
242 includeCommandLineAPI,
243 returnByValue,
244 generatePreview,
245 awaitPromise,
246 callback) {
247 this._agent.runScript(
248 scriptId, executionContextId, objectGroup, silent, includeCommandLineAPI , returnByValue, generatePreview,
249 awaitPromise, innerCallback);
250
251 /**
252 * @param {?Protocol.Error} error
253 * @param {!RuntimeAgent.RemoteObject} result
254 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
255 */
256 function innerCallback(error, result, exceptionDetails) {
257 if (error) {
258 console.error(error);
259 return;
260 }
261 if (callback)
262 callback(result, exceptionDetails);
263 }
264 }
265
266 /**
267 * @param {!RuntimeAgent.RemoteObject} payload
268 * @param {!Object=} hints
269 */
270 _inspectRequested(payload, hints) {
271 var object = this.createRemoteObject(payload);
272
273 if (hints.copyToClipboard) {
274 this._copyRequested(object);
275 return;
276 }
277
278 if (object.isNode()) {
279 WebInspector.Revealer.revealPromise(object).then(object.release.bind(objec t));
280 return;
281 }
282
283 if (object.type === 'function') {
284 WebInspector.RemoteFunction.objectAsFunction(object).targetFunctionDetails ().then(didGetDetails);
285 return;
286 }
287
288 /**
289 * @param {?WebInspector.DebuggerModel.FunctionDetails} response
290 */
291 function didGetDetails(response) {
292 object.release();
293 if (!response || !response.location)
294 return;
295 WebInspector.Revealer.reveal(response.location);
296 }
297 object.release();
298 }
299
300 /**
301 * @param {!WebInspector.RemoteObject} object
302 */
303 _copyRequested(object) {
304 if (!object.objectId) {
305 InspectorFrontendHost.copyText(object.value);
306 return;
307 }
308 object.callFunctionJSON(
309 toStringForClipboard, [{value: object.subtype}], InspectorFrontendHost.c opyText.bind(InspectorFrontendHost));
310
311 /**
312 * @param {string} subtype
313 * @this {Object}
314 * @suppressReceiverCheck
315 */
316 function toStringForClipboard(subtype) {
317 if (subtype === 'node')
318 return this.outerHTML;
319 if (subtype && typeof this === 'undefined')
320 return subtype + '';
321 try {
322 return JSON.stringify(this, null, ' ');
323 } catch (e) {
324 return '' + this;
325 }
326 }
327 }
52 }; 328 };
53 329
54 /** @enum {symbol} */ 330 /** @enum {symbol} */
55 WebInspector.RuntimeModel.Events = { 331 WebInspector.RuntimeModel.Events = {
56 ExecutionContextCreated: Symbol("ExecutionContextCreated"), 332 ExecutionContextCreated: Symbol('ExecutionContextCreated'),
57 ExecutionContextDestroyed: Symbol("ExecutionContextDestroyed"), 333 ExecutionContextDestroyed: Symbol('ExecutionContextDestroyed'),
58 ExecutionContextChanged: Symbol("ExecutionContextChanged"), 334 ExecutionContextChanged: Symbol('ExecutionContextChanged'),
59 ExecutionContextOrderChanged: Symbol("ExecutionContextOrderChanged") 335 ExecutionContextOrderChanged: Symbol('ExecutionContextOrderChanged')
60 }; 336 };
61 337
62 WebInspector.RuntimeModel._privateScript = "private script"; 338 WebInspector.RuntimeModel._privateScript = 'private script';
63 339
64 WebInspector.RuntimeModel.prototype = { 340 /**
65 341 * @implements {RuntimeAgent.Dispatcher}
66 /** 342 * @unrestricted
67 * @return {!Array.<!WebInspector.ExecutionContext>} 343 */
68 */ 344 WebInspector.RuntimeDispatcher = class {
69 executionContexts: function() 345 /**
70 { 346 * @param {!WebInspector.RuntimeModel} runtimeModel
71 return this._executionContextById.valuesArray().sort(this.executionConte xtComparator()); 347 */
72 }, 348 constructor(runtimeModel) {
73 349 this._runtimeModel = runtimeModel;
74 /** 350 }
75 * @param {function(!WebInspector.ExecutionContext,!WebInspector.ExecutionCo ntext)} comparator 351
76 */ 352 /**
77 setExecutionContextComparator: function(comparator) 353 * @override
78 { 354 * @param {!RuntimeAgent.ExecutionContextDescription} context
79 this._executionContextComparator = comparator; 355 */
80 }, 356 executionContextCreated(context) {
81 357 this._runtimeModel._executionContextCreated(context);
82 /** 358 }
83 * @return {function(!WebInspector.ExecutionContext,!WebInspector.ExecutionC ontext)} comparator 359
84 */ 360 /**
85 executionContextComparator: function() 361 * @override
86 { 362 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
87 return this._executionContextComparator; 363 */
88 }, 364 executionContextDestroyed(executionContextId) {
89 365 this._runtimeModel._executionContextDestroyed(executionContextId);
90 /** 366 }
91 * @return {?WebInspector.ExecutionContext} 367
92 */ 368 /**
93 defaultExecutionContext: function() 369 * @override
94 { 370 */
95 for (var context of this._executionContextById.values()) { 371 executionContextsCleared() {
96 if (context.isDefault) 372 this._runtimeModel._executionContextsCleared();
97 return context; 373 }
98 } 374
99 return null; 375 /**
100 }, 376 * @override
101 377 * @param {number} timestamp
102 /** 378 * @param {!RuntimeAgent.ExceptionDetails} exceptionDetails
103 * @param {!RuntimeAgent.ExecutionContextId} id 379 */
104 * @return {?WebInspector.ExecutionContext} 380 exceptionThrown(timestamp, exceptionDetails) {
105 */ 381 var consoleMessage = WebInspector.ConsoleMessage.fromException(
106 executionContext: function(id) 382 this._runtimeModel.target(), exceptionDetails, undefined, timestamp, und efined);
107 { 383 consoleMessage.setExceptionId(exceptionDetails.exceptionId);
108 return this._executionContextById.get(id) || null; 384 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
109 }, 385 }
110 386
111 /** 387 /**
112 * @param {!RuntimeAgent.ExecutionContextDescription} context 388 * @override
113 */ 389 * @param {string} reason
114 _executionContextCreated: function(context) 390 * @param {number} exceptionId
115 { 391 */
116 // The private script context should be hidden behind an experiment. 392 exceptionRevoked(reason, exceptionId) {
117 if (context.name === WebInspector.RuntimeModel._privateScript && !contex t.origin && !Runtime.experiments.isEnabled("privateScriptInspection")) { 393 var consoleMessage = new WebInspector.ConsoleMessage(
118 return; 394 this._runtimeModel.target(), WebInspector.ConsoleMessage.MessageSource.J S,
119 } 395 WebInspector.ConsoleMessage.MessageLevel.RevokedError, reason, undefined , undefined, undefined, undefined,
120 var data = context.auxData || { isDefault: true }; 396 undefined, undefined, undefined, undefined, undefined, undefined);
121 var executionContext = new WebInspector.ExecutionContext(this.target(), context.id, context.name, context.origin, data["isDefault"], data["frameId"]); 397 consoleMessage.setRevokedExceptionId(exceptionId);
122 this._executionContextById.set(executionContext.id, executionContext); 398 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
123 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.Execution ContextCreated, executionContext); 399 }
124 }, 400
125 401 /**
126 /** 402 * @override
127 * @param {number} executionContextId 403 * @param {string} type
128 */ 404 * @param {!Array.<!RuntimeAgent.RemoteObject>} args
129 _executionContextDestroyed: function(executionContextId) 405 * @param {number} executionContextId
130 { 406 * @param {number} timestamp
131 var executionContext = this._executionContextById.get(executionContextId ); 407 * @param {!RuntimeAgent.StackTrace=} stackTrace
132 if (!executionContext) 408 */
133 return; 409 consoleAPICalled(type, args, executionContextId, timestamp, stackTrace) {
134 this._executionContextById.delete(executionContextId); 410 var level = WebInspector.ConsoleMessage.MessageLevel.Log;
135 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.Execution ContextDestroyed, executionContext); 411 if (type === WebInspector.ConsoleMessage.MessageType.Debug)
136 }, 412 level = WebInspector.ConsoleMessage.MessageLevel.Debug;
137 413 if (type === WebInspector.ConsoleMessage.MessageType.Error ||
138 fireExecutionContextOrderChanged: function() 414 type === WebInspector.ConsoleMessage.MessageType.Assert)
139 { 415 level = WebInspector.ConsoleMessage.MessageLevel.Error;
140 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.Execution ContextOrderChanged, this); 416 if (type === WebInspector.ConsoleMessage.MessageType.Warning)
141 }, 417 level = WebInspector.ConsoleMessage.MessageLevel.Warning;
142 418 if (type === WebInspector.ConsoleMessage.MessageType.Info)
143 _executionContextsCleared: function() 419 level = WebInspector.ConsoleMessage.MessageLevel.Info;
144 { 420 var message = '';
145 var debuggerModel = WebInspector.DebuggerModel.fromTarget(this.target()) ; 421 if (args.length && typeof args[0].value === 'string')
146 if (debuggerModel) 422 message = args[0].value;
147 debuggerModel.globalObjectCleared(); 423 else if (args.length && args[0].description)
148 var contexts = this.executionContexts(); 424 message = args[0].description;
149 this._executionContextById.clear(); 425 var callFrame = stackTrace && stackTrace.callFrames.length ? stackTrace.call Frames[0] : null;
150 for (var i = 0; i < contexts.length; ++i) 426 var consoleMessage = new WebInspector.ConsoleMessage(
151 this.dispatchEventToListeners(WebInspector.RuntimeModel.Events.Execu tionContextDestroyed, contexts[i]); 427 this._runtimeModel.target(), WebInspector.ConsoleMessage.MessageSource.C onsoleAPI, level,
152 }, 428 /** @type {string} */ (message), type, callFrame ? callFrame.url : undef ined,
153 429 callFrame ? callFrame.lineNumber : undefined, callFrame ? callFrame.colu mnNumber : undefined, undefined, args,
154 /** 430 stackTrace, timestamp, executionContextId, undefined);
155 * @param {!RuntimeAgent.RemoteObject} payload 431 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
156 * @return {!WebInspector.RemoteObject} 432 }
157 */ 433
158 createRemoteObject: function(payload) 434 /**
159 { 435 * @override
160 console.assert(typeof payload === "object", "Remote object payload shoul d only be an object"); 436 * @param {!RuntimeAgent.RemoteObject} payload
161 return new WebInspector.RemoteObjectImpl(this.target(), payload.objectId , payload.type, payload.subtype, payload.value, payload.unserializableValue, pay load.description, payload.preview, payload.customPreview); 437 * @param {!Object=} hints
162 }, 438 */
163 439 inspectRequested(payload, hints) {
164 /** 440 this._runtimeModel._inspectRequested(payload, hints);
165 * @param {!RuntimeAgent.RemoteObject} payload 441 }
166 * @param {!WebInspector.ScopeRef} scopeRef
167 * @return {!WebInspector.RemoteObject}
168 */
169 createScopeRemoteObject: function(payload, scopeRef)
170 {
171 return new WebInspector.ScopeRemoteObject(this.target(), payload.objectI d, scopeRef, payload.type, payload.subtype, payload.value, payload.unserializabl eValue, payload.description, payload.preview);
172 },
173
174 /**
175 * @param {number|string|boolean|undefined} value
176 * @return {!WebInspector.RemoteObject}
177 */
178 createRemoteObjectFromPrimitiveValue: function(value)
179 {
180 var type = typeof value;
181 var unserializableValue = undefined;
182 if (typeof value === "number") {
183 var description = String(value);
184 if (value === 0 && 1 / value < 0)
185 unserializableValue = RuntimeAgent.UnserializableValue.Negative0 ;
186 if (description === "NaN")
187 unserializableValue = RuntimeAgent.UnserializableValue.NaN;
188 if (description === "Infinity")
189 unserializableValue = RuntimeAgent.UnserializableValue.Infinity;
190 if (description === "-Infinity")
191 unserializableValue = RuntimeAgent.UnserializableValue.NegativeI nfinity;
192 if (typeof unserializableValue !== "undefined")
193 value = undefined;
194 }
195 return new WebInspector.RemoteObjectImpl(this.target(), undefined, type, undefined, value, unserializableValue);
196 },
197
198 /**
199 * @param {string} name
200 * @param {number|string|boolean} value
201 * @return {!WebInspector.RemoteObjectProperty}
202 */
203 createRemotePropertyFromPrimitiveValue: function(name, value)
204 {
205 return new WebInspector.RemoteObjectProperty(name, this.createRemoteObje ctFromPrimitiveValue(value));
206 },
207
208 discardConsoleEntries: function()
209 {
210 this._agent.discardConsoleEntries();
211 },
212
213 /**
214 * @param {!WebInspector.Event} event
215 */
216 _customFormattersStateChanged: function(event)
217 {
218 var enabled = /** @type {boolean} */ (event.data);
219 this._agent.setCustomObjectFormatterEnabled(enabled);
220 },
221
222 /**
223 * @param {string} expression
224 * @param {string} sourceURL
225 * @param {boolean} persistScript
226 * @param {number} executionContextId
227 * @param {function(!RuntimeAgent.ScriptId=, ?RuntimeAgent.ExceptionDetails= )=} callback
228 */
229 compileScript: function(expression, sourceURL, persistScript, executionConte xtId, callback)
230 {
231 this._agent.compileScript(expression, sourceURL, persistScript, executio nContextId, innerCallback);
232
233 /**
234 * @param {?Protocol.Error} error
235 * @param {!RuntimeAgent.ScriptId=} scriptId
236 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails
237 */
238 function innerCallback(error, scriptId, exceptionDetails)
239 {
240 if (error) {
241 console.error(error);
242 return;
243 }
244 if (callback)
245 callback(scriptId, exceptionDetails);
246 }
247 },
248
249 /**
250 * @param {!RuntimeAgent.ScriptId} scriptId
251 * @param {number} executionContextId
252 * @param {string=} objectGroup
253 * @param {boolean=} silent
254 * @param {boolean=} includeCommandLineAPI
255 * @param {boolean=} returnByValue
256 * @param {boolean=} generatePreview
257 * @param {boolean=} awaitPromise
258 * @param {function(?RuntimeAgent.RemoteObject, ?RuntimeAgent.ExceptionDetai ls=)=} callback
259 */
260 runScript: function(scriptId, executionContextId, objectGroup, silent, inclu deCommandLineAPI, returnByValue, generatePreview, awaitPromise, callback)
261 {
262 this._agent.runScript(scriptId, executionContextId, objectGroup, silent, includeCommandLineAPI, returnByValue, generatePreview, awaitPromise, innerCallb ack);
263
264 /**
265 * @param {?Protocol.Error} error
266 * @param {!RuntimeAgent.RemoteObject} result
267 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
268 */
269 function innerCallback(error, result, exceptionDetails)
270 {
271 if (error) {
272 console.error(error);
273 return;
274 }
275 if (callback)
276 callback(result, exceptionDetails);
277 }
278 },
279
280 /**
281 * @param {!RuntimeAgent.RemoteObject} payload
282 * @param {!Object=} hints
283 */
284 _inspectRequested: function(payload, hints)
285 {
286 var object = this.createRemoteObject(payload);
287
288 if (hints.copyToClipboard) {
289 this._copyRequested(object);
290 return;
291 }
292
293 if (object.isNode()) {
294 WebInspector.Revealer.revealPromise(object).then(object.release.bind (object));
295 return;
296 }
297
298 if (object.type === "function") {
299 WebInspector.RemoteFunction.objectAsFunction(object).targetFunctionD etails().then(didGetDetails);
300 return;
301 }
302
303 /**
304 * @param {?WebInspector.DebuggerModel.FunctionDetails} response
305 */
306 function didGetDetails(response)
307 {
308 object.release();
309 if (!response || !response.location)
310 return;
311 WebInspector.Revealer.reveal(response.location);
312 }
313 object.release();
314 },
315
316 /**
317 * @param {!WebInspector.RemoteObject} object
318 */
319 _copyRequested: function(object)
320 {
321 if (!object.objectId) {
322 InspectorFrontendHost.copyText(object.value);
323 return;
324 }
325 object.callFunctionJSON(toStringForClipboard, [ { value : object.subtype } ], InspectorFrontendHost.copyText.bind(InspectorFrontendHost));
326
327 /**
328 * @param {string} subtype
329 * @this {Object}
330 * @suppressReceiverCheck
331 */
332 function toStringForClipboard(subtype)
333 {
334 if (subtype === "node")
335 return this.outerHTML;
336 if (subtype && typeof this === "undefined")
337 return subtype + "";
338 try {
339 return JSON.stringify(this, null, " ");
340 } catch (e) {
341 return "" + this;
342 }
343 }
344 },
345
346 __proto__: WebInspector.SDKModel.prototype
347 }; 442 };
348 443
349 /** 444 /**
350 * @constructor 445 * @unrestricted
351 * @implements {RuntimeAgent.Dispatcher}
352 * @param {!WebInspector.RuntimeModel} runtimeModel
353 */ 446 */
354 WebInspector.RuntimeDispatcher = function(runtimeModel) 447 WebInspector.ExecutionContext = class extends WebInspector.SDKObject {
355 { 448 /**
356 this._runtimeModel = runtimeModel; 449 * @param {!WebInspector.Target} target
357 }; 450 * @param {number} id
358 451 * @param {string} name
359 WebInspector.RuntimeDispatcher.prototype = { 452 * @param {string} origin
360 /** 453 * @param {boolean} isDefault
361 * @override 454 * @param {string=} frameId
362 * @param {!RuntimeAgent.ExecutionContextDescription} context 455 */
363 */ 456 constructor(target, id, name, origin, isDefault, frameId) {
364 executionContextCreated: function(context) 457 super(target);
365 {
366 this._runtimeModel._executionContextCreated(context);
367 },
368
369 /**
370 * @override
371 * @param {!RuntimeAgent.ExecutionContextId} executionContextId
372 */
373 executionContextDestroyed: function(executionContextId)
374 {
375 this._runtimeModel._executionContextDestroyed(executionContextId);
376 },
377
378 /**
379 * @override
380 */
381 executionContextsCleared: function()
382 {
383 this._runtimeModel._executionContextsCleared();
384 },
385
386 /**
387 * @override
388 * @param {number} timestamp
389 * @param {!RuntimeAgent.ExceptionDetails} exceptionDetails
390 */
391 exceptionThrown: function(timestamp, exceptionDetails)
392 {
393 var consoleMessage = WebInspector.ConsoleMessage.fromException(this._run timeModel.target(), exceptionDetails, undefined, timestamp, undefined);
394 consoleMessage.setExceptionId(exceptionDetails.exceptionId);
395 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
396 },
397
398 /**
399 * @override
400 * @param {string} reason
401 * @param {number} exceptionId
402 */
403 exceptionRevoked: function(reason, exceptionId)
404 {
405 var consoleMessage = new WebInspector.ConsoleMessage(
406 this._runtimeModel.target(),
407 WebInspector.ConsoleMessage.MessageSource.JS,
408 WebInspector.ConsoleMessage.MessageLevel.RevokedError,
409 reason,
410 undefined,
411 undefined,
412 undefined,
413 undefined,
414 undefined,
415 undefined,
416 undefined,
417 undefined,
418 undefined,
419 undefined);
420 consoleMessage.setRevokedExceptionId(exceptionId);
421 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
422 },
423
424 /**
425 * @override
426 * @param {string} type
427 * @param {!Array.<!RuntimeAgent.RemoteObject>} args
428 * @param {number} executionContextId
429 * @param {number} timestamp
430 * @param {!RuntimeAgent.StackTrace=} stackTrace
431 */
432 consoleAPICalled: function(type, args, executionContextId, timestamp, stackT race)
433 {
434 var level = WebInspector.ConsoleMessage.MessageLevel.Log;
435 if (type === WebInspector.ConsoleMessage.MessageType.Debug)
436 level = WebInspector.ConsoleMessage.MessageLevel.Debug;
437 if (type === WebInspector.ConsoleMessage.MessageType.Error || type === W ebInspector.ConsoleMessage.MessageType.Assert)
438 level = WebInspector.ConsoleMessage.MessageLevel.Error;
439 if (type === WebInspector.ConsoleMessage.MessageType.Warning)
440 level = WebInspector.ConsoleMessage.MessageLevel.Warning;
441 if (type === WebInspector.ConsoleMessage.MessageType.Info)
442 level = WebInspector.ConsoleMessage.MessageLevel.Info;
443 var message = "";
444 if (args.length && typeof args[0].value === "string")
445 message = args[0].value;
446 else if (args.length && args[0].description)
447 message = args[0].description;
448 var callFrame = stackTrace && stackTrace.callFrames.length ? stackTrace. callFrames[0] : null;
449 var consoleMessage = new WebInspector.ConsoleMessage(
450 this._runtimeModel.target(),
451 WebInspector.ConsoleMessage.MessageSource.ConsoleAPI,
452 level,
453 /** @type {string} */ (message),
454 type,
455 callFrame ? callFrame.url : undefined,
456 callFrame ? callFrame.lineNumber : undefined,
457 callFrame ? callFrame.columnNumber : undefined,
458 undefined,
459 args,
460 stackTrace,
461 timestamp,
462 executionContextId,
463 undefined);
464 this._runtimeModel.target().consoleModel.addMessage(consoleMessage);
465 },
466
467 /**
468 * @override
469 * @param {!RuntimeAgent.RemoteObject} payload
470 * @param {!Object=} hints
471 */
472 inspectRequested: function(payload, hints)
473 {
474 this._runtimeModel._inspectRequested(payload, hints);
475 }
476 };
477
478 /**
479 * @constructor
480 * @extends {WebInspector.SDKObject}
481 * @param {!WebInspector.Target} target
482 * @param {number} id
483 * @param {string} name
484 * @param {string} origin
485 * @param {boolean} isDefault
486 * @param {string=} frameId
487 */
488 WebInspector.ExecutionContext = function(target, id, name, origin, isDefault, fr ameId)
489 {
490 WebInspector.SDKObject.call(this, target);
491 this.id = id; 458 this.id = id;
492 this.name = name; 459 this.name = name;
493 this.origin = origin; 460 this.origin = origin;
494 this.isDefault = isDefault; 461 this.isDefault = isDefault;
495 this.runtimeModel = target.runtimeModel; 462 this.runtimeModel = target.runtimeModel;
496 this.debuggerModel = WebInspector.DebuggerModel.fromTarget(target); 463 this.debuggerModel = WebInspector.DebuggerModel.fromTarget(target);
497 this.frameId = frameId; 464 this.frameId = frameId;
498 465
499 this._label = name; 466 this._label = name;
500 var parsedUrl = origin.asParsedURL(); 467 var parsedUrl = origin.asParsedURL();
501 if (!this._label && parsedUrl) 468 if (!this._label && parsedUrl)
502 this._label = parsedUrl.lastPathComponentWithFragment(); 469 this._label = parsedUrl.lastPathComponentWithFragment();
503 }; 470 }
504 471
505 /** 472 /**
506 * @param {!WebInspector.ExecutionContext} a 473 * @param {!WebInspector.ExecutionContext} a
507 * @param {!WebInspector.ExecutionContext} b 474 * @param {!WebInspector.ExecutionContext} b
508 * @return {number} 475 * @return {number}
509 */ 476 */
510 WebInspector.ExecutionContext.comparator = function(a, b) 477 static comparator(a, b) {
511 {
512 /** 478 /**
513 * @param {!WebInspector.Target} target 479 * @param {!WebInspector.Target} target
514 * @return {number} 480 * @return {number}
515 */ 481 */
516 function targetWeight(target) 482 function targetWeight(target) {
517 { 483 if (target.hasBrowserCapability())
518 if (target.hasBrowserCapability()) 484 return 3;
519 return 3; 485 if (target.hasJSCapability())
520 if (target.hasJSCapability()) 486 return 2;
521 return 2; 487 return 1;
522 return 1;
523 } 488 }
524 489
525 var weightDiff = targetWeight(a.target()) - targetWeight(b.target()); 490 var weightDiff = targetWeight(a.target()) - targetWeight(b.target());
526 if (weightDiff) 491 if (weightDiff)
527 return -weightDiff; 492 return -weightDiff;
528 493
529 // Main world context should always go first. 494 // Main world context should always go first.
530 if (a.isDefault) 495 if (a.isDefault)
531 return -1; 496 return -1;
532 if (b.isDefault) 497 if (b.isDefault)
533 return +1; 498 return +1;
534 return a.name.localeCompare(b.name); 499 return a.name.localeCompare(b.name);
500 }
501
502 /**
503 * @param {string} expression
504 * @param {string} objectGroup
505 * @param {boolean} includeCommandLineAPI
506 * @param {boolean} silent
507 * @param {boolean} returnByValue
508 * @param {boolean} generatePreview
509 * @param {boolean} userGesture
510 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails =)} callback
511 */
512 evaluate(
513 expression,
514 objectGroup,
515 includeCommandLineAPI,
516 silent,
517 returnByValue,
518 generatePreview,
519 userGesture,
520 callback) {
521 // FIXME: It will be moved to separate ExecutionContext.
522 if (this.debuggerModel.selectedCallFrame()) {
523 this.debuggerModel.evaluateOnSelectedCallFrame(
524 expression, objectGroup, includeCommandLineAPI, silent, returnByValue, generatePreview, callback);
525 return;
526 }
527 this._evaluateGlobal.apply(this, arguments);
528 }
529
530 /**
531 * @param {string} objectGroup
532 * @param {boolean} generatePreview
533 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails =)} callback
534 */
535 globalObject(objectGroup, generatePreview, callback) {
536 this._evaluateGlobal('this', objectGroup, false, true, false, generatePrevie w, false, callback);
537 }
538
539 /**
540 * @param {string} expression
541 * @param {string} objectGroup
542 * @param {boolean} includeCommandLineAPI
543 * @param {boolean} silent
544 * @param {boolean} returnByValue
545 * @param {boolean} generatePreview
546 * @param {boolean} userGesture
547 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetails =)} callback
548 */
549 _evaluateGlobal(
550 expression,
551 objectGroup,
552 includeCommandLineAPI,
553 silent,
554 returnByValue,
555 generatePreview,
556 userGesture,
557 callback) {
558 if (!expression) {
559 // There is no expression, so the completion should happen against global properties.
560 expression = 'this';
561 }
562
563 /**
564 * @this {WebInspector.ExecutionContext}
565 * @param {?Protocol.Error} error
566 * @param {!RuntimeAgent.RemoteObject} result
567 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
568 */
569 function evalCallback(error, result, exceptionDetails) {
570 if (error) {
571 console.error(error);
572 callback(null);
573 return;
574 }
575 callback(this.runtimeModel.createRemoteObject(result), exceptionDetails);
576 }
577 this.target().runtimeAgent().evaluate(
578 expression, objectGroup, includeCommandLineAPI, silent, this.id, returnB yValue, generatePreview, userGesture,
579 false, evalCallback.bind(this));
580 }
581
582 /**
583 * @param {string} expressionString
584 * @param {string} prefix
585 * @param {boolean=} force
586 * @return {!Promise<!Array<string>>}
587 */
588 completionsForExpression(expressionString, prefix, force) {
589 var lastIndex = expressionString.length - 1;
590
591 var dotNotation = (expressionString[lastIndex] === '.');
592 var bracketNotation = (expressionString[lastIndex] === '[');
593
594 if (dotNotation || bracketNotation)
595 expressionString = expressionString.substr(0, lastIndex);
596
597 // User is entering float value, do not suggest anything.
598 if (expressionString && !isNaN(expressionString))
599 return Promise.resolve([]);
600
601 if (!prefix && !expressionString && !force)
602 return Promise.resolve([]);
603
604 var fufill;
605 var promise = new Promise(x => fufill = x);
606 if (!expressionString && this.debuggerModel.selectedCallFrame())
607 this.debuggerModel.selectedCallFrame().variableNames(receivedPropertyNames .bind(this));
608 else
609 this.evaluate(expressionString, 'completion', true, true, false, false, fa lse, evaluated.bind(this));
610
611 return promise;
612 /**
613 * @param {?WebInspector.RemoteObject} result
614 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
615 * @this {WebInspector.ExecutionContext}
616 */
617 function evaluated(result, exceptionDetails) {
618 if (!result || !!exceptionDetails) {
619 fufill([]);
620 return;
621 }
622
623 /**
624 * @param {?WebInspector.RemoteObject} object
625 * @return {!Promise<?WebInspector.RemoteObject>}
626 */
627 function extractTarget(object) {
628 if (!object)
629 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */ (null ));
630 if (object.type !== 'object' || object.subtype !== 'proxy')
631 return Promise.resolve(/** @type {?WebInspector.RemoteObject} */ (obje ct));
632 return object.getOwnPropertiesPromise().then(extractTargetFromProperties ).then(extractTarget);
633 }
634
635 /**
636 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, inter nalProperties: ?Array<!WebInspector.RemoteObjectProperty>}} properties
637 * @return {?WebInspector.RemoteObject}
638 */
639 function extractTargetFromProperties(properties) {
640 var internalProperties = properties.internalProperties || [];
641 var target = internalProperties.find(property => property.name === '[[Ta rget]]');
642 return target ? target.value : null;
643 }
644
645 /**
646 * @param {string=} type
647 * @return {!Object}
648 * @suppressReceiverCheck
649 * @this {Object}
650 */
651 function getCompletions(type) {
652 var object;
653 if (type === 'string')
654 object = new String('');
655 else if (type === 'number')
656 object = new Number(0);
657 else if (type === 'boolean')
658 object = new Boolean(false);
659 else
660 object = this;
661
662 var resultSet = {__proto__: null};
663 try {
664 for (var o = object; o; o = Object.getPrototypeOf(o)) {
665 if ((type === 'array' || type === 'typedarray') && o === object && A rrayBuffer.isView(o) && o.length > 9999)
666 continue;
667 var names = Object.getOwnPropertyNames(o);
668 var isArray = Array.isArray(o);
669 for (var i = 0; i < names.length; ++i) {
670 // Skip array elements indexes.
671 if (isArray && /^[0-9]/.test(names[i]))
672 continue;
673 resultSet[names[i]] = true;
674 }
675 }
676 } catch (e) {
677 }
678 return resultSet;
679 }
680
681 /**
682 * @param {?WebInspector.RemoteObject} object
683 * @this {WebInspector.ExecutionContext}
684 */
685 function completionsForObject(object) {
686 if (!object)
687 receivedPropertyNames.call(this, null);
688 else if (object.type === 'object' || object.type === 'function')
689 object.callFunctionJSON(
690 getCompletions, [WebInspector.RemoteObject.toCallArgument(object.s ubtype)],
691 receivedPropertyNames.bind(this));
692 else if (object.type === 'string' || object.type === 'number' || object. type === 'boolean')
693 this.evaluate(
694 '(' + getCompletions + ')("' + result.type + '")', 'completion', f alse, true, true, false, false,
695 receivedPropertyNamesFromEval.bind(this));
696 }
697
698 extractTarget(result).then(completionsForObject.bind(this));
699 }
700
701 /**
702 * @param {?WebInspector.RemoteObject} result
703 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
704 * @this {WebInspector.ExecutionContext}
705 */
706 function receivedPropertyNamesFromEval(result, exceptionDetails) {
707 this.target().runtimeAgent().releaseObjectGroup('completion');
708 if (result && !exceptionDetails)
709 receivedPropertyNames.call(this, /** @type {!Object} */ (result.value));
710 else
711 fufill([]);
712 }
713
714 /**
715 * @param {?Object} propertyNames
716 * @this {WebInspector.ExecutionContext}
717 */
718 function receivedPropertyNames(propertyNames) {
719 this.target().runtimeAgent().releaseObjectGroup('completion');
720 if (!propertyNames) {
721 fufill([]);
722 return;
723 }
724 var includeCommandLineAPI = (!dotNotation && !bracketNotation);
725 if (includeCommandLineAPI) {
726 const commandLineAPI = [
727 'dir',
728 'dirxml',
729 'keys',
730 'values',
731 'profile',
732 'profileEnd',
733 'monitorEvents',
734 'unmonitorEvents',
735 'inspect',
736 'copy',
737 'clear',
738 'getEventListeners',
739 'debug',
740 'undebug',
741 'monitor',
742 'unmonitor',
743 'table',
744 '$',
745 '$$',
746 '$x'
747 ];
748 for (var i = 0; i < commandLineAPI.length; ++i)
749 propertyNames[commandLineAPI[i]] = true;
750 }
751 fufill(this._completionsForPrefix(
752 dotNotation, bracketNotation, expressionString, prefix, Object.keys(pr opertyNames)));
753 }
754 }
755
756 /**
757 * @param {boolean} dotNotation
758 * @param {boolean} bracketNotation
759 * @param {string} expressionString
760 * @param {string} prefix
761 * @param {!Array.<string>} properties
762 * @return {!Array<string>}
763 */
764 _completionsForPrefix(dotNotation, bracketNotation, expressionString, prefix, properties) {
765 if (bracketNotation) {
766 if (prefix.length && prefix[0] === '\'')
767 var quoteUsed = '\'';
768 else
769 var quoteUsed = '"';
770 }
771
772 var results = [];
773
774 if (!expressionString) {
775 const keywords = [
776 'break', 'case', 'catch', 'continue', 'default', 'delete', 'do', 'else', 'finally',
777 'for', 'function', 'if', 'in', 'instanceof', 'new', 'retu rn', 'switch', 'this',
778 'throw', 'try', 'typeof', 'var', 'void', 'while', 'with '
779 ];
780 properties = properties.concat(keywords);
781 }
782
783 properties.sort();
784
785 for (var i = 0; i < properties.length; ++i) {
786 var property = properties[i];
787
788 // Assume that all non-ASCII characters are letters and thus can be used a s part of identifier.
789 if (dotNotation && !/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFFFF]*$/ .test(property))
790 continue;
791
792 if (bracketNotation) {
793 if (!/^[0-9]+$/.test(property))
794 property = quoteUsed + property.escapeCharacters(quoteUsed + '\\') + q uoteUsed;
795 property += ']';
796 }
797
798 if (property.length < prefix.length)
799 continue;
800 if (prefix.length && !property.startsWith(prefix))
801 continue;
802
803 // Substitute actual newlines with newline characters. @see crbug.com/4984 21
804 results.push(property.split('\n').join('\\n'));
805 }
806 return results;
807 }
808
809 /**
810 * @return {string}
811 */
812 label() {
813 return this._label;
814 }
815
816 /**
817 * @param {string} label
818 */
819 setLabel(label) {
820 this._label = label;
821 this.runtimeModel.dispatchEventToListeners(WebInspector.RuntimeModel.Events. ExecutionContextChanged, this);
822 }
535 }; 823 };
536 824
537 WebInspector.ExecutionContext.prototype = {
538 /**
539 * @param {string} expression
540 * @param {string} objectGroup
541 * @param {boolean} includeCommandLineAPI
542 * @param {boolean} silent
543 * @param {boolean} returnByValue
544 * @param {boolean} generatePreview
545 * @param {boolean} userGesture
546 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetai ls=)} callback
547 */
548 evaluate: function(expression, objectGroup, includeCommandLineAPI, silent, r eturnByValue, generatePreview, userGesture, callback)
549 {
550 // FIXME: It will be moved to separate ExecutionContext.
551 if (this.debuggerModel.selectedCallFrame()) {
552 this.debuggerModel.evaluateOnSelectedCallFrame(expression, objectGro up, includeCommandLineAPI, silent, returnByValue, generatePreview, callback);
553 return;
554 }
555 this._evaluateGlobal.apply(this, arguments);
556 },
557
558 /**
559 * @param {string} objectGroup
560 * @param {boolean} generatePreview
561 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetai ls=)} callback
562 */
563 globalObject: function(objectGroup, generatePreview, callback)
564 {
565 this._evaluateGlobal("this", objectGroup, false, true, false, generatePr eview, false, callback);
566 },
567
568 /**
569 * @param {string} expression
570 * @param {string} objectGroup
571 * @param {boolean} includeCommandLineAPI
572 * @param {boolean} silent
573 * @param {boolean} returnByValue
574 * @param {boolean} generatePreview
575 * @param {boolean} userGesture
576 * @param {function(?WebInspector.RemoteObject, !RuntimeAgent.ExceptionDetai ls=)} callback
577 */
578 _evaluateGlobal: function(expression, objectGroup, includeCommandLineAPI, si lent, returnByValue, generatePreview, userGesture, callback)
579 {
580 if (!expression) {
581 // There is no expression, so the completion should happen against g lobal properties.
582 expression = "this";
583 }
584
585 /**
586 * @this {WebInspector.ExecutionContext}
587 * @param {?Protocol.Error} error
588 * @param {!RuntimeAgent.RemoteObject} result
589 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
590 */
591 function evalCallback(error, result, exceptionDetails)
592 {
593 if (error) {
594 console.error(error);
595 callback(null);
596 return;
597 }
598 callback(this.runtimeModel.createRemoteObject(result), exceptionDeta ils);
599 }
600 this.target().runtimeAgent().evaluate(expression, objectGroup, includeCo mmandLineAPI, silent, this.id, returnByValue, generatePreview, userGesture, fals e, evalCallback.bind(this));
601 },
602
603 /**
604 * @param {string} expressionString
605 * @param {string} prefix
606 * @param {boolean=} force
607 * @return {!Promise<!Array<string>>}
608 */
609 completionsForExpression: function(expressionString, prefix, force)
610 {
611 var lastIndex = expressionString.length - 1;
612
613 var dotNotation = (expressionString[lastIndex] === ".");
614 var bracketNotation = (expressionString[lastIndex] === "[");
615
616 if (dotNotation || bracketNotation)
617 expressionString = expressionString.substr(0, lastIndex);
618
619 // User is entering float value, do not suggest anything.
620 if (expressionString && !isNaN(expressionString))
621 return Promise.resolve([]);
622
623 if (!prefix && !expressionString && !force)
624 return Promise.resolve([]);
625
626 var fufill;
627 var promise = new Promise(x => fufill = x);
628 if (!expressionString && this.debuggerModel.selectedCallFrame())
629 this.debuggerModel.selectedCallFrame().variableNames(receivedPropert yNames.bind(this));
630 else
631 this.evaluate(expressionString, "completion", true, true, false, fal se, false, evaluated.bind(this));
632
633 return promise;
634 /**
635 * @param {?WebInspector.RemoteObject} result
636 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
637 * @this {WebInspector.ExecutionContext}
638 */
639 function evaluated(result, exceptionDetails)
640 {
641 if (!result || !!exceptionDetails) {
642 fufill([]);
643 return;
644 }
645
646 /**
647 * @param {?WebInspector.RemoteObject} object
648 * @return {!Promise<?WebInspector.RemoteObject>}
649 */
650 function extractTarget(object)
651 {
652 if (!object)
653 return Promise.resolve(/** @type {?WebInspector.RemoteObject } */(null));
654 if (object.type !== "object" || object.subtype !== "proxy")
655 return Promise.resolve(/** @type {?WebInspector.RemoteObject } */(object));
656 return object.getOwnPropertiesPromise().then(extractTargetFromPr operties).then(extractTarget);
657 }
658
659 /**
660 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}} properties
661 * @return {?WebInspector.RemoteObject}
662 */
663 function extractTargetFromProperties(properties)
664 {
665 var internalProperties = properties.internalProperties || [];
666 var target = internalProperties.find(property => property.name = == "[[Target]]");
667 return target ? target.value : null;
668 }
669
670 /**
671 * @param {string=} type
672 * @return {!Object}
673 * @suppressReceiverCheck
674 * @this {Object}
675 */
676 function getCompletions(type)
677 {
678 var object;
679 if (type === "string")
680 object = new String("");
681 else if (type === "number")
682 object = new Number(0);
683 else if (type === "boolean")
684 object = new Boolean(false);
685 else
686 object = this;
687
688 var resultSet = { __proto__: null };
689 try {
690 for (var o = object; o; o = Object.getPrototypeOf(o)) {
691 if ((type === "array" || type === "typedarray") && o === object && ArrayBuffer.isView(o) && o.length > 9999)
692 continue;
693 var names = Object.getOwnPropertyNames(o);
694 var isArray = Array.isArray(o);
695 for (var i = 0; i < names.length; ++i) {
696 // Skip array elements indexes.
697 if (isArray && /^[0-9]/.test(names[i]))
698 continue;
699 resultSet[names[i]] = true;
700 }
701 }
702 } catch (e) {
703 }
704 return resultSet;
705 }
706
707 /**
708 * @param {?WebInspector.RemoteObject} object
709 * @this {WebInspector.ExecutionContext}
710 */
711 function completionsForObject(object)
712 {
713 if (!object)
714 receivedPropertyNames.call(this, null);
715 else if (object.type === "object" || object.type === "function")
716 object.callFunctionJSON(getCompletions, [WebInspector.Remote Object.toCallArgument(object.subtype)], receivedPropertyNames.bind(this));
717 else if (object.type === "string" || object.type === "number" || object.type === "boolean")
718 this.evaluate("(" + getCompletions + ")(\"" + result.type + "\")", "completion", false, true, true, false, false, receivedPropertyNamesFromE val.bind(this));
719 }
720
721 extractTarget(result).then(completionsForObject.bind(this));
722 }
723
724 /**
725 * @param {?WebInspector.RemoteObject} result
726 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails
727 * @this {WebInspector.ExecutionContext}
728 */
729 function receivedPropertyNamesFromEval(result, exceptionDetails)
730 {
731 this.target().runtimeAgent().releaseObjectGroup("completion");
732 if (result && !exceptionDetails)
733 receivedPropertyNames.call(this, /** @type {!Object} */(result.v alue));
734 else
735 fufill([]);
736 }
737
738 /**
739 * @param {?Object} propertyNames
740 * @this {WebInspector.ExecutionContext}
741 */
742 function receivedPropertyNames(propertyNames)
743 {
744 this.target().runtimeAgent().releaseObjectGroup("completion");
745 if (!propertyNames) {
746 fufill([]);
747 return;
748 }
749 var includeCommandLineAPI = (!dotNotation && !bracketNotation);
750 if (includeCommandLineAPI) {
751 const commandLineAPI = ["dir", "dirxml", "keys", "values", "prof ile", "profileEnd", "monitorEvents", "unmonitorEvents", "inspect", "copy", "clea r",
752 "getEventListeners", "debug", "undebug", "monitor", "unmonit or", "table", "$", "$$", "$x"];
753 for (var i = 0; i < commandLineAPI.length; ++i)
754 propertyNames[commandLineAPI[i]] = true;
755 }
756 fufill(this._completionsForPrefix(dotNotation, bracketNotation, expr essionString, prefix, Object.keys(propertyNames)));
757 }
758 },
759
760 /**
761 * @param {boolean} dotNotation
762 * @param {boolean} bracketNotation
763 * @param {string} expressionString
764 * @param {string} prefix
765 * @param {!Array.<string>} properties
766 * @return {!Array<string>}
767 */
768 _completionsForPrefix: function(dotNotation, bracketNotation, expressionStri ng, prefix, properties) {
769 if (bracketNotation) {
770 if (prefix.length && prefix[0] === "'")
771 var quoteUsed = "'";
772 else
773 var quoteUsed = "\"";
774 }
775
776 var results = [];
777
778 if (!expressionString) {
779 const keywords = ["break", "case", "catch", "continue", "default", " delete", "do", "else", "finally", "for", "function", "if", "in",
780 "instanceof", "new", "return", "switch", "this", " throw", "try", "typeof", "var", "void", "while", "with"];
781 properties = properties.concat(keywords);
782 }
783
784 properties.sort();
785
786 for (var i = 0; i < properties.length; ++i) {
787 var property = properties[i];
788
789 // Assume that all non-ASCII characters are letters and thus can be used as part of identifier.
790 if (dotNotation && !/^[a-zA-Z_$\u008F-\uFFFF][a-zA-Z0-9_$\u008F-\uFF FF]*$/.test(property))
791 continue;
792
793 if (bracketNotation) {
794 if (!/^[0-9]+$/.test(property))
795 property = quoteUsed + property.escapeCharacters(quoteUsed + "\\") + quoteUsed;
796 property += "]";
797 }
798
799 if (property.length < prefix.length)
800 continue;
801 if (prefix.length && !property.startsWith(prefix))
802 continue;
803
804 // Substitute actual newlines with newline characters. @see crbug.co m/498421
805 results.push(property.split("\n").join("\\n"));
806 }
807 return results;
808 },
809
810 /**
811 * @return {string}
812 */
813 label: function()
814 {
815 return this._label;
816 },
817
818 /**
819 * @param {string} label
820 */
821 setLabel: function(label)
822 {
823 this._label = label;
824 this.runtimeModel.dispatchEventToListeners(WebInspector.RuntimeModel.Eve nts.ExecutionContextChanged, this);
825 },
826
827 __proto__: WebInspector.SDKObject.prototype
828 };
829 825
830 /** 826 /**
831 * @constructor 827 * @unrestricted
832 * @extends {WebInspector.SDKObject}
833 * @param {!WebInspector.Target} target
834 * @param {!WebInspector.RemoteObject} eventTarget
835 * @param {string} type
836 * @param {boolean} useCapture
837 * @param {boolean} passive
838 * @param {?WebInspector.RemoteObject} handler
839 * @param {?WebInspector.RemoteObject} originalHandler
840 * @param {!WebInspector.DebuggerModel.Location} location
841 * @param {?WebInspector.RemoteObject} removeFunction
842 * @param {string=} listenerType
843 */ 828 */
844 WebInspector.EventListener = function(target, eventTarget, type, useCapture, pas sive, handler, originalHandler, location, removeFunction, listenerType) 829 WebInspector.EventListener = class extends WebInspector.SDKObject {
845 { 830 /**
846 WebInspector.SDKObject.call(this, target); 831 * @param {!WebInspector.Target} target
832 * @param {!WebInspector.RemoteObject} eventTarget
833 * @param {string} type
834 * @param {boolean} useCapture
835 * @param {boolean} passive
836 * @param {?WebInspector.RemoteObject} handler
837 * @param {?WebInspector.RemoteObject} originalHandler
838 * @param {!WebInspector.DebuggerModel.Location} location
839 * @param {?WebInspector.RemoteObject} removeFunction
840 * @param {string=} listenerType
841 */
842 constructor(
843 target,
844 eventTarget,
845 type,
846 useCapture,
847 passive,
848 handler,
849 originalHandler,
850 location,
851 removeFunction,
852 listenerType) {
853 super(target);
847 this._eventTarget = eventTarget; 854 this._eventTarget = eventTarget;
848 this._type = type; 855 this._type = type;
849 this._useCapture = useCapture; 856 this._useCapture = useCapture;
850 this._passive = passive; 857 this._passive = passive;
851 this._handler = handler; 858 this._handler = handler;
852 this._originalHandler = originalHandler || handler; 859 this._originalHandler = originalHandler || handler;
853 this._location = location; 860 this._location = location;
854 var script = location.script(); 861 var script = location.script();
855 this._sourceURL = script ? script.contentURL() : ""; 862 this._sourceURL = script ? script.contentURL() : '';
856 this._removeFunction = removeFunction; 863 this._removeFunction = removeFunction;
857 this._listenerType = listenerType || "normal"; 864 this._listenerType = listenerType || 'normal';
858 }; 865 }
859 866
860 WebInspector.EventListener.prototype = { 867 /**
861 /** 868 * @return {string}
862 * @return {string} 869 */
863 */ 870 type() {
864 type: function() 871 return this._type;
865 { 872 }
866 return this._type; 873
867 }, 874 /**
875 * @return {boolean}
876 */
877 useCapture() {
878 return this._useCapture;
879 }
880
881 /**
882 * @return {boolean}
883 */
884 passive() {
885 return this._passive;
886 }
887
888 /**
889 * @return {?WebInspector.RemoteObject}
890 */
891 handler() {
892 return this._handler;
893 }
894
895 /**
896 * @return {!WebInspector.DebuggerModel.Location}
897 */
898 location() {
899 return this._location;
900 }
901
902 /**
903 * @return {string}
904 */
905 sourceURL() {
906 return this._sourceURL;
907 }
908
909 /**
910 * @return {?WebInspector.RemoteObject}
911 */
912 originalHandler() {
913 return this._originalHandler;
914 }
915
916 /**
917 * @return {?WebInspector.RemoteObject}
918 */
919 removeFunction() {
920 return this._removeFunction;
921 }
922
923 /**
924 * @return {!Promise<undefined>}
925 */
926 remove() {
927 if (!this._removeFunction)
928 return Promise.resolve();
929 return this._removeFunction
930 .callFunctionPromise(
931 callCustomRemove,
932 [
933 WebInspector.RemoteObject.toCallArgument(this._type),
934 WebInspector.RemoteObject.toCallArgument(this._originalHandler),
935 WebInspector.RemoteObject.toCallArgument(this._useCapture),
936 WebInspector.RemoteObject.toCallArgument(this._passive),
937 ])
938 .then(() => undefined);
868 939
869 /** 940 /**
870 * @return {boolean} 941 * @param {string} type
942 * @param {function()} listener
943 * @param {boolean} useCapture
944 * @param {boolean} passive
945 * @this {Function}
946 * @suppressReceiverCheck
871 */ 947 */
872 useCapture: function() 948 function callCustomRemove(type, listener, useCapture, passive) {
873 { 949 this.call(null, type, listener, useCapture, passive);
874 return this._useCapture; 950 }
875 }, 951 }
952
953 /**
954 * @return {!Promise<undefined>}
955 */
956 togglePassive() {
957 return new Promise(promiseConstructor.bind(this));
876 958
877 /** 959 /**
878 * @return {boolean} 960 * @param {function()} success
961 * @this {WebInspector.EventListener}
879 */ 962 */
880 passive: function() 963 function promiseConstructor(success) {
881 { 964 this._eventTarget
882 return this._passive; 965 .callFunctionPromise(
883 }, 966 callTogglePassive,
884 967 [
885 /**
886 * @return {?WebInspector.RemoteObject}
887 */
888 handler: function()
889 {
890 return this._handler;
891 },
892
893 /**
894 * @return {!WebInspector.DebuggerModel.Location}
895 */
896 location: function()
897 {
898 return this._location;
899 },
900
901 /**
902 * @return {string}
903 */
904 sourceURL: function()
905 {
906 return this._sourceURL;
907 },
908
909 /**
910 * @return {?WebInspector.RemoteObject}
911 */
912 originalHandler: function()
913 {
914 return this._originalHandler;
915 },
916
917 /**
918 * @return {?WebInspector.RemoteObject}
919 */
920 removeFunction: function()
921 {
922 return this._removeFunction;
923 },
924
925 /**
926 * @return {!Promise<undefined>}
927 */
928 remove: function()
929 {
930 if (!this._removeFunction)
931 return Promise.resolve();
932 return this._removeFunction.callFunctionPromise(callCustomRemove, [
933 WebInspector.RemoteObject.toCallArgument(this._type),
934 WebInspector.RemoteObject.toCallArgument(this._originalHandler),
935 WebInspector.RemoteObject.toCallArgument(this._useCapture),
936 WebInspector.RemoteObject.toCallArgument(this._passive),
937 ]).then(() => undefined);
938
939 /**
940 * @param {string} type
941 * @param {function()} listener
942 * @param {boolean} useCapture
943 * @param {boolean} passive
944 * @this {Function}
945 * @suppressReceiverCheck
946 */
947 function callCustomRemove(type, listener, useCapture, passive)
948 {
949 this.call(null, type, listener, useCapture, passive);
950 }
951 },
952
953 /**
954 * @return {!Promise<undefined>}
955 */
956 togglePassive: function()
957 {
958 return new Promise(promiseConstructor.bind(this));
959
960 /**
961 * @param {function()} success
962 * @this {WebInspector.EventListener}
963 */
964 function promiseConstructor(success)
965 {
966 this._eventTarget.callFunctionPromise(callTogglePassive, [
967 WebInspector.RemoteObject.toCallArgument(this._type), 968 WebInspector.RemoteObject.toCallArgument(this._type),
968 WebInspector.RemoteObject.toCallArgument(this._originalHandler), 969 WebInspector.RemoteObject.toCallArgument(this._originalHandler),
969 WebInspector.RemoteObject.toCallArgument(this._useCapture), 970 WebInspector.RemoteObject.toCallArgument(this._useCapture),
970 WebInspector.RemoteObject.toCallArgument(this._passive), 971 WebInspector.RemoteObject.toCallArgument(this._passive),
971 ]).then(success); 972 ])
973 .then(success);
972 974
973 /** 975 /**
974 * @param {string} type 976 * @param {string} type
975 * @param {function()} listener 977 * @param {function()} listener
976 * @param {boolean} useCapture 978 * @param {boolean} useCapture
977 * @param {boolean} passive 979 * @param {boolean} passive
978 * @this {Object} 980 * @this {Object}
979 * @suppressReceiverCheck 981 * @suppressReceiverCheck
980 */ 982 */
981 function callTogglePassive(type, listener, useCapture, passive) 983 function callTogglePassive(type, listener, useCapture, passive) {
982 { 984 this.removeEventListener(type, listener, {capture: useCapture});
983 this.removeEventListener(type, listener, {capture: useCapture}); 985 this.addEventListener(type, listener, {capture: useCapture, passive: !pa ssive});
984 this.addEventListener(type, listener, {capture: useCapture, pass ive: !passive}); 986 }
985 } 987 }
986 } 988 }
987 },
988 989
989 /** 990 /**
990 * @return {string} 991 * @return {string}
991 */ 992 */
992 listenerType: function() 993 listenerType() {
993 { 994 return this._listenerType;
994 return this._listenerType; 995 }
995 },
996 996
997 /** 997 /**
998 * @param {string} listenerType 998 * @param {string} listenerType
999 */ 999 */
1000 setListenerType: function(listenerType) 1000 setListenerType(listenerType) {
1001 { 1001 this._listenerType = listenerType;
1002 this._listenerType = listenerType; 1002 }
1003 },
1004 1003
1005 /** 1004 /**
1006 * @return {boolean} 1005 * @return {boolean}
1007 */ 1006 */
1008 isScrollBlockingType: function() 1007 isScrollBlockingType() {
1009 { 1008 return this._type === 'touchstart' || this._type === 'touchmove' || this._ty pe === 'mousewheel' ||
1010 return this._type === "touchstart" || this._type === "touchmove" || this ._type === "mousewheel" || this._type === "wheel"; 1009 this._type === 'wheel';
1011 }, 1010 }
1012 1011
1013 /** 1012 /**
1014 * @return {boolean} 1013 * @return {boolean}
1015 */ 1014 */
1016 isNormalListenerType: function() 1015 isNormalListenerType() {
1017 { 1016 return this._listenerType === 'normal';
1018 return this._listenerType === "normal"; 1017 }
1019 },
1020
1021 __proto__: WebInspector.SDKObject.prototype
1022 }; 1018 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698