OLD | NEW |
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 }; |
OLD | NEW |