| 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 |