| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright (C) 2009 Google Inc. All rights reserved. | 2 * Copyright (C) 2009 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 | 30 /** |
| 31 /** | |
| 32 * @typedef {{object: ?WebInspector.RemoteObject, wasThrown: (boolean|undefined)
}} | 31 * @typedef {{object: ?WebInspector.RemoteObject, wasThrown: (boolean|undefined)
}} |
| 33 */ | 32 */ |
| 34 WebInspector.CallFunctionResult; | 33 WebInspector.CallFunctionResult; |
| 35 | 34 |
| 36 /** | 35 /** |
| 37 * This may not be an interface due to "instanceof WebInspector.RemoteObject" ch
ecks in the code. | 36 * @unrestricted |
| 38 * | |
| 39 * @constructor | |
| 40 */ | 37 */ |
| 41 WebInspector.RemoteObject = function() { }; | 38 WebInspector.RemoteObject = class { |
| 42 | 39 /** |
| 43 WebInspector.RemoteObject.prototype = { | 40 * This may not be an interface due to "instanceof WebInspector.RemoteObject"
checks in the code. |
| 44 | 41 */ |
| 45 /** | 42 |
| 46 * @return {?RuntimeAgent.CustomPreview} | 43 /** |
| 47 */ | 44 * @param {*} value |
| 48 customPreview: function() | 45 * @return {!WebInspector.RemoteObject} |
| 49 { | 46 */ |
| 50 return null; | 47 static fromLocalObject(value) { |
| 51 }, | |
| 52 | |
| 53 /** @return {string} */ | |
| 54 get type() | |
| 55 { | |
| 56 throw "Not implemented"; | |
| 57 }, | |
| 58 | |
| 59 /** @return {string|undefined} */ | |
| 60 get subtype() | |
| 61 { | |
| 62 throw "Not implemented"; | |
| 63 }, | |
| 64 | |
| 65 /** @return {string|undefined} */ | |
| 66 get description() | |
| 67 { | |
| 68 throw "Not implemented"; | |
| 69 }, | |
| 70 | |
| 71 /** @return {boolean} */ | |
| 72 get hasChildren() | |
| 73 { | |
| 74 throw "Not implemented"; | |
| 75 }, | |
| 76 | |
| 77 /** | |
| 78 * @return {number} | |
| 79 */ | |
| 80 arrayLength: function() | |
| 81 { | |
| 82 throw "Not implemented"; | |
| 83 }, | |
| 84 | |
| 85 /** | |
| 86 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 87 */ | |
| 88 getOwnProperties: function(callback) | |
| 89 { | |
| 90 throw "Not implemented"; | |
| 91 }, | |
| 92 | |
| 93 /** | |
| 94 * @return {!Promise<!{properties: ?Array.<!WebInspector.RemoteObjectPropert
y>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}>} | |
| 95 */ | |
| 96 getOwnPropertiesPromise: function() | |
| 97 { | |
| 98 return new Promise(promiseConstructor.bind(this)); | |
| 99 | |
| 100 /** | |
| 101 * @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProp
erty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} succes
s | |
| 102 * @this {WebInspector.RemoteObject} | |
| 103 */ | |
| 104 function promiseConstructor(success) | |
| 105 { | |
| 106 this.getOwnProperties(getOwnPropertiesCallback.bind(null, success)); | |
| 107 } | |
| 108 | |
| 109 /** | |
| 110 * @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProp
erty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} callba
ck | |
| 111 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | |
| 112 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti
es | |
| 113 */ | |
| 114 function getOwnPropertiesCallback(callback, properties, internalProperti
es) | |
| 115 { | |
| 116 callback({ | |
| 117 properties: properties, | |
| 118 internalProperties: internalProperties | |
| 119 }); | |
| 120 } | |
| 121 }, | |
| 122 | |
| 123 /** | |
| 124 * @param {boolean} accessorPropertiesOnly | |
| 125 * @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebI
nspector.RemoteObjectProperty>)} callback | |
| 126 */ | |
| 127 getAllProperties: function(accessorPropertiesOnly, callback) | |
| 128 { | |
| 129 throw "Not implemented"; | |
| 130 }, | |
| 131 | |
| 132 /** | |
| 133 * @param {boolean} accessorPropertiesOnly | |
| 134 * @return {!Promise<!{properties: ?Array<!WebInspector.RemoteObjectProperty
>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}>} | |
| 135 */ | |
| 136 getAllPropertiesPromise: function(accessorPropertiesOnly) | |
| 137 { | |
| 138 return new Promise(promiseConstructor.bind(this)); | |
| 139 | |
| 140 /** | |
| 141 * @param {function(!{properties: ?Array<!WebInspector.RemoteObjectPrope
rty>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} success | |
| 142 * @this {WebInspector.RemoteObject} | |
| 143 */ | |
| 144 function promiseConstructor(success) | |
| 145 { | |
| 146 this.getAllProperties(accessorPropertiesOnly, getAllPropertiesCallba
ck.bind(null, success)); | |
| 147 } | |
| 148 | |
| 149 /** | |
| 150 * @param {function(!{properties: ?Array<!WebInspector.RemoteObjectPrope
rty>, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>})} callback | |
| 151 * @param {?Array<!WebInspector.RemoteObjectProperty>} properties | |
| 152 * @param {?Array<!WebInspector.RemoteObjectProperty>} internalPropertie
s | |
| 153 */ | |
| 154 function getAllPropertiesCallback(callback, properties, internalProperti
es) | |
| 155 { | |
| 156 callback({ | |
| 157 properties: properties, | |
| 158 internalProperties: internalProperties | |
| 159 }); | |
| 160 } | |
| 161 }, | |
| 162 | |
| 163 /** | |
| 164 * @return {!Promise<?Array<!WebInspector.EventListener>>} | |
| 165 */ | |
| 166 eventListeners: function() | |
| 167 { | |
| 168 throw "Not implemented"; | |
| 169 }, | |
| 170 | |
| 171 /** | |
| 172 * @param {!RuntimeAgent.CallArgument} name | |
| 173 * @param {function(string=)} callback | |
| 174 */ | |
| 175 deleteProperty: function(name, callback) | |
| 176 { | |
| 177 throw "Not implemented"; | |
| 178 }, | |
| 179 | |
| 180 /** | |
| 181 * @param {string|!RuntimeAgent.CallArgument} name | |
| 182 * @param {string} value | |
| 183 * @param {function(string=)} callback | |
| 184 */ | |
| 185 setPropertyValue: function(name, value, callback) | |
| 186 { | |
| 187 throw "Not implemented"; | |
| 188 }, | |
| 189 | |
| 190 /** | |
| 191 * @param {function(this:Object, ...)} functionDeclaration | |
| 192 * @param {!Array<!RuntimeAgent.CallArgument>=} args | |
| 193 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback | |
| 194 */ | |
| 195 callFunction: function(functionDeclaration, args, callback) | |
| 196 { | |
| 197 throw "Not implemented"; | |
| 198 }, | |
| 199 | |
| 200 /** | |
| 201 * @param {function(this:Object, ...)} functionDeclaration | |
| 202 * @param {!Array<!RuntimeAgent.CallArgument>=} args | |
| 203 * @return {!Promise<!WebInspector.CallFunctionResult>} | |
| 204 */ | |
| 205 callFunctionPromise: function(functionDeclaration, args) | |
| 206 { | |
| 207 return new Promise(promiseConstructor.bind(this)); | |
| 208 | |
| 209 /** | |
| 210 * @param {function(!WebInspector.CallFunctionResult)} success | |
| 211 * @this {WebInspector.RemoteObject} | |
| 212 */ | |
| 213 function promiseConstructor(success) | |
| 214 { | |
| 215 this.callFunction(functionDeclaration, args, callFunctionCallback.bi
nd(null, success)); | |
| 216 } | |
| 217 | |
| 218 /** | |
| 219 * @param {function(!WebInspector.CallFunctionResult)} callback | |
| 220 * @param {?WebInspector.RemoteObject} object | |
| 221 * @param {boolean=} wasThrown | |
| 222 */ | |
| 223 function callFunctionCallback(callback, object, wasThrown) | |
| 224 { | |
| 225 callback({ | |
| 226 object: object, | |
| 227 wasThrown: wasThrown | |
| 228 }); | |
| 229 } | |
| 230 }, | |
| 231 | |
| 232 /** | |
| 233 * @template T | |
| 234 * @param {function(this:Object, ...):T} functionDeclaration | |
| 235 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args | |
| 236 * @param {function(T)} callback | |
| 237 */ | |
| 238 callFunctionJSON: function(functionDeclaration, args, callback) | |
| 239 { | |
| 240 throw "Not implemented"; | |
| 241 }, | |
| 242 | |
| 243 /** | |
| 244 * @param {function(this:Object, ...):T} functionDeclaration | |
| 245 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args | |
| 246 * @return {!Promise<T>} | |
| 247 * @template T | |
| 248 */ | |
| 249 callFunctionJSONPromise: function(functionDeclaration, args) | |
| 250 { | |
| 251 return new Promise(promiseConstructor.bind(this)); | |
| 252 | |
| 253 /** | |
| 254 * @this {WebInspector.RemoteObject} | |
| 255 */ | |
| 256 function promiseConstructor(success) | |
| 257 { | |
| 258 this.callFunctionJSON(functionDeclaration, args, success); | |
| 259 } | |
| 260 }, | |
| 261 | |
| 262 /** | |
| 263 * @return {!WebInspector.Target} | |
| 264 */ | |
| 265 target: function() | |
| 266 { | |
| 267 throw new Error("Target-less object"); | |
| 268 }, | |
| 269 | |
| 270 /** | |
| 271 * @return {?WebInspector.DebuggerModel} | |
| 272 */ | |
| 273 debuggerModel: function() | |
| 274 { | |
| 275 throw new Error("DebuggerModel-less object"); | |
| 276 }, | |
| 277 | |
| 278 /** | |
| 279 * @return {boolean} | |
| 280 */ | |
| 281 isNode: function() | |
| 282 { | |
| 283 return false; | |
| 284 } | |
| 285 }; | |
| 286 | |
| 287 /** | |
| 288 * @param {*} value | |
| 289 * @return {!WebInspector.RemoteObject} | |
| 290 */ | |
| 291 WebInspector.RemoteObject.fromLocalObject = function(value) | |
| 292 { | |
| 293 return new WebInspector.LocalJSONObject(value); | 48 return new WebInspector.LocalJSONObject(value); |
| 294 }; | 49 } |
| 295 | 50 |
| 296 /** | 51 /** |
| 297 * @param {!WebInspector.RemoteObject} remoteObject | 52 * @param {!WebInspector.RemoteObject} remoteObject |
| 298 * @return {string} | 53 * @return {string} |
| 299 */ | 54 */ |
| 300 WebInspector.RemoteObject.type = function(remoteObject) | 55 static type(remoteObject) { |
| 301 { | |
| 302 if (remoteObject === null) | 56 if (remoteObject === null) |
| 303 return "null"; | 57 return 'null'; |
| 304 | 58 |
| 305 var type = typeof remoteObject; | 59 var type = typeof remoteObject; |
| 306 if (type !== "object" && type !== "function") | 60 if (type !== 'object' && type !== 'function') |
| 307 return type; | 61 return type; |
| 308 | 62 |
| 309 return remoteObject.type; | 63 return remoteObject.type; |
| 310 }; | 64 } |
| 311 | 65 |
| 312 /** | 66 /** |
| 313 * @param {!WebInspector.RemoteObject|!RuntimeAgent.RemoteObject|!RuntimeAgent.O
bjectPreview} object | 67 * @param {!WebInspector.RemoteObject|!RuntimeAgent.RemoteObject|!RuntimeAgent
.ObjectPreview} object |
| 314 * @return {number} | 68 * @return {number} |
| 315 */ | 69 */ |
| 316 WebInspector.RemoteObject.arrayLength = function(object) | 70 static arrayLength(object) { |
| 317 { | 71 if (object.subtype !== 'array' && object.subtype !== 'typedarray') |
| 318 if (object.subtype !== "array" && object.subtype !== "typedarray") | 72 return 0; |
| 319 return 0; | |
| 320 var matches = object.description.match(/\[([0-9]+)\]/); | 73 var matches = object.description.match(/\[([0-9]+)\]/); |
| 321 if (!matches) | 74 if (!matches) |
| 322 return 0; | 75 return 0; |
| 323 return parseInt(matches[1], 10); | 76 return parseInt(matches[1], 10); |
| 77 } |
| 78 |
| 79 /** |
| 80 * @param {!RuntimeAgent.RemoteObject|!WebInspector.RemoteObject|number|string
|boolean|undefined|null} object |
| 81 * @return {!RuntimeAgent.CallArgument} |
| 82 */ |
| 83 static toCallArgument(object) { |
| 84 var type = typeof object; |
| 85 if (type === 'undefined') |
| 86 return {}; |
| 87 if (type === 'number') { |
| 88 var description = String(object); |
| 89 if (object === 0 && 1 / object < 0) |
| 90 return {unserializableValue: RuntimeAgent.UnserializableValue.Negative0}
; |
| 91 if (description === 'NaN') |
| 92 return {unserializableValue: RuntimeAgent.UnserializableValue.NaN}; |
| 93 if (description === 'Infinity') |
| 94 return {unserializableValue: RuntimeAgent.UnserializableValue.Infinity}; |
| 95 if (description === '-Infinity') |
| 96 return {unserializableValue: RuntimeAgent.UnserializableValue.NegativeIn
finity}; |
| 97 return {value: object}; |
| 98 } |
| 99 if (type === 'string' || type === 'boolean') |
| 100 return {value: object}; |
| 101 |
| 102 if (!object) |
| 103 return {value: null}; |
| 104 |
| 105 if (typeof object.unserializableValue !== 'undefined') |
| 106 return {unserializableValue: object.unserializableValue}; |
| 107 if (typeof object._unserializableValue !== 'undefined') |
| 108 return {unserializableValue: object._unserializableValue}; |
| 109 |
| 110 if (typeof object.objectId !== 'undefined') |
| 111 return {objectId: object.objectId}; |
| 112 if (typeof object._objectId !== 'undefined') |
| 113 return {objectId: object._objectId}; |
| 114 |
| 115 return {value: object.value}; |
| 116 } |
| 117 |
| 118 /** |
| 119 * @param {!WebInspector.RemoteObject} object |
| 120 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 121 */ |
| 122 static loadFromObjectPerProto(object, callback) { |
| 123 // Combines 2 asynch calls. Doesn't rely on call-back orders (some calls may
be loop-back). |
| 124 var savedOwnProperties; |
| 125 var savedAccessorProperties; |
| 126 var savedInternalProperties; |
| 127 var resultCounter = 2; |
| 128 |
| 129 function processCallback() { |
| 130 if (--resultCounter) |
| 131 return; |
| 132 if (savedOwnProperties && savedAccessorProperties) { |
| 133 var propertiesMap = new Map(); |
| 134 var propertySymbols = []; |
| 135 for (var i = 0; i < savedAccessorProperties.length; i++) { |
| 136 var property = savedAccessorProperties[i]; |
| 137 if (property.symbol) |
| 138 propertySymbols.push(property); |
| 139 else |
| 140 propertiesMap.set(property.name, property); |
| 141 } |
| 142 for (var i = 0; i < savedOwnProperties.length; i++) { |
| 143 var property = savedOwnProperties[i]; |
| 144 if (property.isAccessorProperty()) |
| 145 continue; |
| 146 if (property.symbol) |
| 147 propertySymbols.push(property); |
| 148 else |
| 149 propertiesMap.set(property.name, property); |
| 150 } |
| 151 return callback( |
| 152 propertiesMap.valuesArray().concat(propertySymbols), |
| 153 savedInternalProperties ? savedInternalProperties : null); |
| 154 } else { |
| 155 callback(null, null); |
| 156 } |
| 157 } |
| 158 |
| 159 /** |
| 160 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 161 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 162 */ |
| 163 function allAccessorPropertiesCallback(properties, internalProperties) { |
| 164 savedAccessorProperties = properties; |
| 165 processCallback(); |
| 166 } |
| 167 |
| 168 /** |
| 169 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 170 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 171 */ |
| 172 function ownPropertiesCallback(properties, internalProperties) { |
| 173 savedOwnProperties = properties; |
| 174 savedInternalProperties = internalProperties; |
| 175 processCallback(); |
| 176 } |
| 177 |
| 178 object.getAllProperties(true, allAccessorPropertiesCallback); |
| 179 object.getOwnProperties(ownPropertiesCallback); |
| 180 } |
| 181 |
| 182 /** |
| 183 * @return {?RuntimeAgent.CustomPreview} |
| 184 */ |
| 185 customPreview() { |
| 186 return null; |
| 187 } |
| 188 |
| 189 /** @return {string} */ |
| 190 get type() { |
| 191 throw 'Not implemented'; |
| 192 } |
| 193 |
| 194 /** @return {string|undefined} */ |
| 195 get subtype() { |
| 196 throw 'Not implemented'; |
| 197 } |
| 198 |
| 199 /** @return {string|undefined} */ |
| 200 get description() { |
| 201 throw 'Not implemented'; |
| 202 } |
| 203 |
| 204 /** @return {boolean} */ |
| 205 get hasChildren() { |
| 206 throw 'Not implemented'; |
| 207 } |
| 208 |
| 209 /** |
| 210 * @return {number} |
| 211 */ |
| 212 arrayLength() { |
| 213 throw 'Not implemented'; |
| 214 } |
| 215 |
| 216 /** |
| 217 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 218 */ |
| 219 getOwnProperties(callback) { |
| 220 throw 'Not implemented'; |
| 221 } |
| 222 |
| 223 /** |
| 224 * @return {!Promise<!{properties: ?Array.<!WebInspector.RemoteObjectProperty>
, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>}>} |
| 225 */ |
| 226 getOwnPropertiesPromise() { |
| 227 return new Promise(promiseConstructor.bind(this)); |
| 228 |
| 229 /** |
| 230 * @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProperty
>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} success |
| 231 * @this {WebInspector.RemoteObject} |
| 232 */ |
| 233 function promiseConstructor(success) { |
| 234 this.getOwnProperties(getOwnPropertiesCallback.bind(null, success)); |
| 235 } |
| 236 |
| 237 /** |
| 238 * @param {function(!{properties: ?Array.<!WebInspector.RemoteObjectProperty
>, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} callback |
| 239 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 240 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 241 */ |
| 242 function getOwnPropertiesCallback(callback, properties, internalProperties)
{ |
| 243 callback({properties: properties, internalProperties: internalProperties})
; |
| 244 } |
| 245 } |
| 246 |
| 247 /** |
| 248 * @param {boolean} accessorPropertiesOnly |
| 249 * @param {function(?Array<!WebInspector.RemoteObjectProperty>, ?Array<!WebIns
pector.RemoteObjectProperty>)} callback |
| 250 */ |
| 251 getAllProperties(accessorPropertiesOnly, callback) { |
| 252 throw 'Not implemented'; |
| 253 } |
| 254 |
| 255 /** |
| 256 * @param {boolean} accessorPropertiesOnly |
| 257 * @return {!Promise<!{properties: ?Array<!WebInspector.RemoteObjectProperty>,
internalProperties: ?Array<!WebInspector.RemoteObjectProperty>}>} |
| 258 */ |
| 259 getAllPropertiesPromise(accessorPropertiesOnly) { |
| 260 return new Promise(promiseConstructor.bind(this)); |
| 261 |
| 262 /** |
| 263 * @param {function(!{properties: ?Array<!WebInspector.RemoteObjectProperty>
, internalProperties: ?Array.<!WebInspector.RemoteObjectProperty>})} success |
| 264 * @this {WebInspector.RemoteObject} |
| 265 */ |
| 266 function promiseConstructor(success) { |
| 267 this.getAllProperties(accessorPropertiesOnly, getAllPropertiesCallback.bin
d(null, success)); |
| 268 } |
| 269 |
| 270 /** |
| 271 * @param {function(!{properties: ?Array<!WebInspector.RemoteObjectProperty>
, internalProperties: ?Array<!WebInspector.RemoteObjectProperty>})} callback |
| 272 * @param {?Array<!WebInspector.RemoteObjectProperty>} properties |
| 273 * @param {?Array<!WebInspector.RemoteObjectProperty>} internalProperties |
| 274 */ |
| 275 function getAllPropertiesCallback(callback, properties, internalProperties)
{ |
| 276 callback({properties: properties, internalProperties: internalProperties})
; |
| 277 } |
| 278 } |
| 279 |
| 280 /** |
| 281 * @return {!Promise<?Array<!WebInspector.EventListener>>} |
| 282 */ |
| 283 eventListeners() { |
| 284 throw 'Not implemented'; |
| 285 } |
| 286 |
| 287 /** |
| 288 * @param {!RuntimeAgent.CallArgument} name |
| 289 * @param {function(string=)} callback |
| 290 */ |
| 291 deleteProperty(name, callback) { |
| 292 throw 'Not implemented'; |
| 293 } |
| 294 |
| 295 /** |
| 296 * @param {string|!RuntimeAgent.CallArgument} name |
| 297 * @param {string} value |
| 298 * @param {function(string=)} callback |
| 299 */ |
| 300 setPropertyValue(name, value, callback) { |
| 301 throw 'Not implemented'; |
| 302 } |
| 303 |
| 304 /** |
| 305 * @param {function(this:Object, ...)} functionDeclaration |
| 306 * @param {!Array<!RuntimeAgent.CallArgument>=} args |
| 307 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback |
| 308 */ |
| 309 callFunction(functionDeclaration, args, callback) { |
| 310 throw 'Not implemented'; |
| 311 } |
| 312 |
| 313 /** |
| 314 * @param {function(this:Object, ...)} functionDeclaration |
| 315 * @param {!Array<!RuntimeAgent.CallArgument>=} args |
| 316 * @return {!Promise<!WebInspector.CallFunctionResult>} |
| 317 */ |
| 318 callFunctionPromise(functionDeclaration, args) { |
| 319 return new Promise(promiseConstructor.bind(this)); |
| 320 |
| 321 /** |
| 322 * @param {function(!WebInspector.CallFunctionResult)} success |
| 323 * @this {WebInspector.RemoteObject} |
| 324 */ |
| 325 function promiseConstructor(success) { |
| 326 this.callFunction(functionDeclaration, args, callFunctionCallback.bind(nul
l, success)); |
| 327 } |
| 328 |
| 329 /** |
| 330 * @param {function(!WebInspector.CallFunctionResult)} callback |
| 331 * @param {?WebInspector.RemoteObject} object |
| 332 * @param {boolean=} wasThrown |
| 333 */ |
| 334 function callFunctionCallback(callback, object, wasThrown) { |
| 335 callback({object: object, wasThrown: wasThrown}); |
| 336 } |
| 337 } |
| 338 |
| 339 /** |
| 340 * @template T |
| 341 * @param {function(this:Object, ...):T} functionDeclaration |
| 342 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args |
| 343 * @param {function(T)} callback |
| 344 */ |
| 345 callFunctionJSON(functionDeclaration, args, callback) { |
| 346 throw 'Not implemented'; |
| 347 } |
| 348 |
| 349 /** |
| 350 * @param {function(this:Object, ...):T} functionDeclaration |
| 351 * @param {!Array<!RuntimeAgent.CallArgument>|undefined} args |
| 352 * @return {!Promise<T>} |
| 353 * @template T |
| 354 */ |
| 355 callFunctionJSONPromise(functionDeclaration, args) { |
| 356 return new Promise(promiseConstructor.bind(this)); |
| 357 |
| 358 /** |
| 359 * @this {WebInspector.RemoteObject} |
| 360 */ |
| 361 function promiseConstructor(success) { |
| 362 this.callFunctionJSON(functionDeclaration, args, success); |
| 363 } |
| 364 } |
| 365 |
| 366 /** |
| 367 * @return {!WebInspector.Target} |
| 368 */ |
| 369 target() { |
| 370 throw new Error('Target-less object'); |
| 371 } |
| 372 |
| 373 /** |
| 374 * @return {?WebInspector.DebuggerModel} |
| 375 */ |
| 376 debuggerModel() { |
| 377 throw new Error('DebuggerModel-less object'); |
| 378 } |
| 379 |
| 380 /** |
| 381 * @return {boolean} |
| 382 */ |
| 383 isNode() { |
| 384 return false; |
| 385 } |
| 324 }; | 386 }; |
| 325 | 387 |
| 388 |
| 326 /** | 389 /** |
| 327 * @param {!RuntimeAgent.RemoteObject|!WebInspector.RemoteObject|number|string|b
oolean|undefined|null} object | 390 * @unrestricted |
| 328 * @return {!RuntimeAgent.CallArgument} | |
| 329 */ | 391 */ |
| 330 WebInspector.RemoteObject.toCallArgument = function(object) | 392 WebInspector.RemoteObjectImpl = class extends WebInspector.RemoteObject { |
| 331 { | 393 /** |
| 332 var type = typeof object; | 394 * @param {!WebInspector.Target} target |
| 333 if (type === "undefined") | 395 * @param {string|undefined} objectId |
| 334 return {}; | 396 * @param {string} type |
| 335 if (type === "number") { | 397 * @param {string|undefined} subtype |
| 336 var description = String(object); | 398 * @param {*} value |
| 337 if (object === 0 && 1 / object < 0) | 399 * @param {!RuntimeAgent.UnserializableValue=} unserializableValue |
| 338 return { unserializableValue: RuntimeAgent.UnserializableValue.Negat
ive0 }; | 400 * @param {string=} description |
| 339 if (description === "NaN") | 401 * @param {!RuntimeAgent.ObjectPreview=} preview |
| 340 return { unserializableValue: RuntimeAgent.UnserializableValue.NaN }
; | 402 * @param {!RuntimeAgent.CustomPreview=} customPreview |
| 341 if (description === "Infinity") | 403 */ |
| 342 return { unserializableValue: RuntimeAgent.UnserializableValue.Infin
ity }; | 404 constructor(target, objectId, type, subtype, value, unserializableValue, descr
iption, preview, customPreview) { |
| 343 if (description === "-Infinity") | 405 super(); |
| 344 return { unserializableValue: RuntimeAgent.UnserializableValue.Negat
iveInfinity }; | |
| 345 return { value: object }; | |
| 346 } | |
| 347 if (type === "string" || type === "boolean") | |
| 348 return { value: object }; | |
| 349 | |
| 350 if (!object) | |
| 351 return { value: null }; | |
| 352 | |
| 353 if (typeof object.unserializableValue !== "undefined") | |
| 354 return { unserializableValue: object.unserializableValue }; | |
| 355 if (typeof object._unserializableValue !== "undefined") | |
| 356 return { unserializableValue: object._unserializableValue }; | |
| 357 | |
| 358 if (typeof object.objectId !== "undefined") | |
| 359 return { objectId: object.objectId }; | |
| 360 if (typeof object._objectId !== "undefined") | |
| 361 return { objectId: object._objectId }; | |
| 362 | |
| 363 return { value: object.value }; | |
| 364 }; | |
| 365 | |
| 366 /** | |
| 367 * @constructor | |
| 368 * @extends {WebInspector.RemoteObject} | |
| 369 * @param {!WebInspector.Target} target | |
| 370 * @param {string|undefined} objectId | |
| 371 * @param {string} type | |
| 372 * @param {string|undefined} subtype | |
| 373 * @param {*} value | |
| 374 * @param {!RuntimeAgent.UnserializableValue=} unserializableValue | |
| 375 * @param {string=} description | |
| 376 * @param {!RuntimeAgent.ObjectPreview=} preview | |
| 377 * @param {!RuntimeAgent.CustomPreview=} customPreview | |
| 378 */ | |
| 379 WebInspector.RemoteObjectImpl = function(target, objectId, type, subtype, value,
unserializableValue, description, preview, customPreview) | |
| 380 { | |
| 381 WebInspector.RemoteObject.call(this); | |
| 382 | 406 |
| 383 this._target = target; | 407 this._target = target; |
| 384 this._runtimeAgent = target.runtimeAgent(); | 408 this._runtimeAgent = target.runtimeAgent(); |
| 385 this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target); | 409 this._debuggerModel = WebInspector.DebuggerModel.fromTarget(target); |
| 386 | 410 |
| 387 this._type = type; | 411 this._type = type; |
| 388 this._subtype = subtype; | 412 this._subtype = subtype; |
| 389 if (objectId) { | 413 if (objectId) { |
| 390 // handle | 414 // handle |
| 391 this._objectId = objectId; | 415 this._objectId = objectId; |
| 392 this._description = description; | 416 this._description = description; |
| 393 this._hasChildren = (type !== "symbol"); | 417 this._hasChildren = (type !== 'symbol'); |
| 394 this._preview = preview; | 418 this._preview = preview; |
| 395 } else { | 419 } else { |
| 396 this._description = description; | 420 this._description = description; |
| 397 if (!this._description && (typeof value !== "object" || value === null)) | 421 if (!this._description && (typeof value !== 'object' || value === null)) |
| 398 this._description = value + ""; | 422 this._description = value + ''; |
| 399 this._hasChildren = false; | 423 this._hasChildren = false; |
| 400 if (typeof unserializableValue !== "undefined") { | 424 if (typeof unserializableValue !== 'undefined') { |
| 401 this._unserializableValue = unserializableValue; | 425 this._unserializableValue = unserializableValue; |
| 402 if (unserializableValue === RuntimeAgent.UnserializableValue.Infinit
y || | 426 if (unserializableValue === RuntimeAgent.UnserializableValue.Infinity || |
| 403 unserializableValue === RuntimeAgent.UnserializableValue.Negativ
eInfinity || | 427 unserializableValue === RuntimeAgent.UnserializableValue.NegativeInf
inity || |
| 404 unserializableValue === RuntimeAgent.UnserializableValue.Negativ
e0 || | 428 unserializableValue === RuntimeAgent.UnserializableValue.Negative0 |
| |
| 405 unserializableValue === RuntimeAgent.UnserializableValue.NaN) { | 429 unserializableValue === RuntimeAgent.UnserializableValue.NaN) { |
| 406 this.value = Number(unserializableValue); | 430 this.value = Number(unserializableValue); |
| 407 } else { | |
| 408 this.value = unserializableValue; | |
| 409 } | |
| 410 } else { | 431 } else { |
| 411 this.value = value; | 432 this.value = unserializableValue; |
| 412 } | 433 } |
| 434 } else { |
| 435 this.value = value; |
| 436 } |
| 413 } | 437 } |
| 414 this._customPreview = customPreview || null; | 438 this._customPreview = customPreview || null; |
| 439 } |
| 440 |
| 441 /** |
| 442 * @override |
| 443 * @return {?RuntimeAgent.CustomPreview} |
| 444 */ |
| 445 customPreview() { |
| 446 return this._customPreview; |
| 447 } |
| 448 |
| 449 /** @return {!RuntimeAgent.RemoteObjectId} */ |
| 450 get objectId() { |
| 451 return this._objectId; |
| 452 } |
| 453 |
| 454 /** |
| 455 * @override |
| 456 * @return {string} |
| 457 */ |
| 458 get type() { |
| 459 return this._type; |
| 460 } |
| 461 |
| 462 /** |
| 463 * @override |
| 464 * @return {string|undefined} |
| 465 */ |
| 466 get subtype() { |
| 467 return this._subtype; |
| 468 } |
| 469 |
| 470 /** |
| 471 * @override |
| 472 * @return {string|undefined} |
| 473 */ |
| 474 get description() { |
| 475 return this._description; |
| 476 } |
| 477 |
| 478 /** |
| 479 * @override |
| 480 * @return {boolean} |
| 481 */ |
| 482 get hasChildren() { |
| 483 return this._hasChildren; |
| 484 } |
| 485 |
| 486 /** |
| 487 * @return {!RuntimeAgent.ObjectPreview|undefined} |
| 488 */ |
| 489 get preview() { |
| 490 return this._preview; |
| 491 } |
| 492 |
| 493 /** |
| 494 * @override |
| 495 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 496 */ |
| 497 getOwnProperties(callback) { |
| 498 this.doGetProperties(true, false, false, callback); |
| 499 } |
| 500 |
| 501 /** |
| 502 * @override |
| 503 * @param {boolean} accessorPropertiesOnly |
| 504 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 505 */ |
| 506 getAllProperties(accessorPropertiesOnly, callback) { |
| 507 this.doGetProperties(false, accessorPropertiesOnly, false, callback); |
| 508 } |
| 509 |
| 510 /** |
| 511 * @override |
| 512 * @return {!Promise<?Array<!WebInspector.EventListener>>} |
| 513 */ |
| 514 eventListeners() { |
| 515 return new Promise(eventListeners.bind(this)); |
| 516 /** |
| 517 * @param {function(?)} fulfill |
| 518 * @param {function(*)} reject |
| 519 * @this {WebInspector.RemoteObjectImpl} |
| 520 */ |
| 521 function eventListeners(fulfill, reject) { |
| 522 if (!this.target().hasDOMCapability()) { |
| 523 // TODO(kozyatinskiy): figure out how this should work for |window| when
there is no DOMDebugger. |
| 524 fulfill([]); |
| 525 return; |
| 526 } |
| 527 |
| 528 if (!this._objectId) { |
| 529 reject(new Error('No object id specified')); |
| 530 return; |
| 531 } |
| 532 |
| 533 this.target().domdebuggerAgent().getEventListeners(this._objectId, mycallb
ack.bind(this)); |
| 534 |
| 535 /** |
| 536 * @this {WebInspector.RemoteObjectImpl} |
| 537 * @param {?Protocol.Error} error |
| 538 * @param {!Array<!DOMDebuggerAgent.EventListener>} payloads |
| 539 */ |
| 540 function mycallback(error, payloads) { |
| 541 if (error) { |
| 542 reject(new Error(error)); |
| 543 return; |
| 544 } |
| 545 fulfill(payloads.map(createEventListener.bind(this))); |
| 546 } |
| 547 |
| 548 /** |
| 549 * @this {WebInspector.RemoteObjectImpl} |
| 550 * @param {!DOMDebuggerAgent.EventListener} payload |
| 551 */ |
| 552 function createEventListener(payload) { |
| 553 return new WebInspector.EventListener( |
| 554 this._target, this, payload.type, payload.useCapture, payload.passiv
e, |
| 555 payload.handler ? this.target().runtimeModel.createRemoteObject(payl
oad.handler) : null, |
| 556 payload.originalHandler ? this.target().runtimeModel.createRemoteObj
ect(payload.originalHandler) : null, |
| 557 /** @type {!WebInspector.DebuggerModel.Location} */ (this._debuggerM
odel.createRawLocationByScriptId( |
| 558 payload.scriptId, payload.lineNumber, payload.columnNumber)), |
| 559 payload.removeFunction ? this.target().runtimeModel.createRemoteObje
ct(payload.removeFunction) : null); |
| 560 } |
| 561 } |
| 562 } |
| 563 |
| 564 /** |
| 565 * @param {!Array.<string>} propertyPath |
| 566 * @param {function(?WebInspector.RemoteObject, boolean=)} callback |
| 567 */ |
| 568 getProperty(propertyPath, callback) { |
| 569 /** |
| 570 * @param {string} arrayStr |
| 571 * @suppressReceiverCheck |
| 572 * @this {Object} |
| 573 */ |
| 574 function remoteFunction(arrayStr) { |
| 575 var result = this; |
| 576 var properties = JSON.parse(arrayStr); |
| 577 for (var i = 0, n = properties.length; i < n; ++i) |
| 578 result = result[properties[i]]; |
| 579 return result; |
| 580 } |
| 581 |
| 582 var args = [{value: JSON.stringify(propertyPath)}]; |
| 583 this.callFunction(remoteFunction, args, callback); |
| 584 } |
| 585 |
| 586 /** |
| 587 * @param {boolean} ownProperties |
| 588 * @param {boolean} accessorPropertiesOnly |
| 589 * @param {boolean} generatePreview |
| 590 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 591 */ |
| 592 doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview, callba
ck) { |
| 593 if (!this._objectId) { |
| 594 callback(null, null); |
| 595 return; |
| 596 } |
| 597 |
| 598 /** |
| 599 * @param {?Protocol.Error} error |
| 600 * @param {!Array.<!RuntimeAgent.PropertyDescriptor>} properties |
| 601 * @param {!Array.<!RuntimeAgent.InternalPropertyDescriptor>=} internalPrope
rties |
| 602 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 603 * @this {WebInspector.RemoteObjectImpl} |
| 604 */ |
| 605 function remoteObjectBinder(error, properties, internalProperties, exception
Details) { |
| 606 if (error) { |
| 607 callback(null, null); |
| 608 return; |
| 609 } |
| 610 if (exceptionDetails) { |
| 611 this._target.consoleModel.addMessage( |
| 612 WebInspector.ConsoleMessage.fromException(this._target, exceptionDet
ails, undefined, undefined, undefined)); |
| 613 callback(null, null); |
| 614 return; |
| 615 } |
| 616 var result = []; |
| 617 for (var i = 0; properties && i < properties.length; ++i) { |
| 618 var property = properties[i]; |
| 619 var propertyValue = property.value ? this._target.runtimeModel.createRem
oteObject(property.value) : null; |
| 620 var propertySymbol = property.symbol ? this._target.runtimeModel.createR
emoteObject(property.symbol) : null; |
| 621 var remoteProperty = new WebInspector.RemoteObjectProperty( |
| 622 property.name, propertyValue, !!property.enumerable, !!property.writ
able, !!property.isOwn, |
| 623 !!property.wasThrown, propertySymbol); |
| 624 |
| 625 if (typeof property.value === 'undefined') { |
| 626 if (property.get && property.get.type !== 'undefined') |
| 627 remoteProperty.getter = this._target.runtimeModel.createRemoteObject
(property.get); |
| 628 if (property.set && property.set.type !== 'undefined') |
| 629 remoteProperty.setter = this._target.runtimeModel.createRemoteObject
(property.set); |
| 630 } |
| 631 |
| 632 result.push(remoteProperty); |
| 633 } |
| 634 var internalPropertiesResult = null; |
| 635 if (internalProperties) { |
| 636 internalPropertiesResult = []; |
| 637 for (var i = 0; i < internalProperties.length; i++) { |
| 638 var property = internalProperties[i]; |
| 639 if (!property.value) |
| 640 continue; |
| 641 var propertyValue = this._target.runtimeModel.createRemoteObject(prope
rty.value); |
| 642 internalPropertiesResult.push( |
| 643 new WebInspector.RemoteObjectProperty(property.name, propertyValue
, true, false)); |
| 644 } |
| 645 } |
| 646 callback(result, internalPropertiesResult); |
| 647 } |
| 648 this._runtimeAgent.getProperties( |
| 649 this._objectId, ownProperties, accessorPropertiesOnly, generatePreview,
remoteObjectBinder.bind(this)); |
| 650 } |
| 651 |
| 652 /** |
| 653 * @override |
| 654 * @param {string|!RuntimeAgent.CallArgument} name |
| 655 * @param {string} value |
| 656 * @param {function(string=)} callback |
| 657 */ |
| 658 setPropertyValue(name, value, callback) { |
| 659 if (!this._objectId) { |
| 660 callback('Can\'t set a property of non-object.'); |
| 661 return; |
| 662 } |
| 663 |
| 664 this._runtimeAgent.invoke_evaluate({expression: value, silent: true}, evalua
tedCallback.bind(this)); |
| 665 |
| 666 /** |
| 667 * @param {?Protocol.Error} error |
| 668 * @param {!RuntimeAgent.RemoteObject} result |
| 669 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 670 * @this {WebInspector.RemoteObject} |
| 671 */ |
| 672 function evaluatedCallback(error, result, exceptionDetails) { |
| 673 if (error || !!exceptionDetails) { |
| 674 callback(error || (result.type !== 'string' ? result.description : /** @
type {string} */ (result.value))); |
| 675 return; |
| 676 } |
| 677 |
| 678 if (typeof name === 'string') |
| 679 name = WebInspector.RemoteObject.toCallArgument(name); |
| 680 |
| 681 this.doSetObjectPropertyValue(result, name, callback); |
| 682 |
| 683 if (result.objectId) |
| 684 this._runtimeAgent.releaseObject(result.objectId); |
| 685 } |
| 686 } |
| 687 |
| 688 /** |
| 689 * @param {!RuntimeAgent.RemoteObject} result |
| 690 * @param {!RuntimeAgent.CallArgument} name |
| 691 * @param {function(string=)} callback |
| 692 */ |
| 693 doSetObjectPropertyValue(result, name, callback) { |
| 694 // This assignment may be for a regular (data) property, and for an accessor
property (with getter/setter). |
| 695 // Note the sensitive matter about accessor property: the property may be ph
ysically defined in some proto object, |
| 696 // but logically it is bound to the object in question. JavaScript passes th
is object to getters/setters, not the object |
| 697 // where property was defined; so do we. |
| 698 var setPropertyValueFunction = 'function(a, b) { this[a] = b; }'; |
| 699 |
| 700 var argv = [name, WebInspector.RemoteObject.toCallArgument(result)]; |
| 701 this._runtimeAgent.callFunctionOn( |
| 702 this._objectId, setPropertyValueFunction, argv, true, undefined, undefin
ed, undefined, undefined, |
| 703 propertySetCallback); |
| 704 |
| 705 /** |
| 706 * @param {?Protocol.Error} error |
| 707 * @param {!RuntimeAgent.RemoteObject} result |
| 708 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 709 */ |
| 710 function propertySetCallback(error, result, exceptionDetails) { |
| 711 if (error || !!exceptionDetails) { |
| 712 callback(error || result.description); |
| 713 return; |
| 714 } |
| 715 callback(); |
| 716 } |
| 717 } |
| 718 |
| 719 /** |
| 720 * @override |
| 721 * @param {!RuntimeAgent.CallArgument} name |
| 722 * @param {function(string=)} callback |
| 723 */ |
| 724 deleteProperty(name, callback) { |
| 725 if (!this._objectId) { |
| 726 callback('Can\'t delete a property of non-object.'); |
| 727 return; |
| 728 } |
| 729 |
| 730 var deletePropertyFunction = 'function(a) { delete this[a]; return !(a in th
is); }'; |
| 731 this._runtimeAgent.callFunctionOn( |
| 732 this._objectId, deletePropertyFunction, [name], true, undefined, undefin
ed, undefined, undefined, |
| 733 deletePropertyCallback); |
| 734 |
| 735 /** |
| 736 * @param {?Protocol.Error} error |
| 737 * @param {!RuntimeAgent.RemoteObject} result |
| 738 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 739 */ |
| 740 function deletePropertyCallback(error, result, exceptionDetails) { |
| 741 if (error || !!exceptionDetails) { |
| 742 callback(error || result.description); |
| 743 return; |
| 744 } |
| 745 if (!result.value) |
| 746 callback('Failed to delete property.'); |
| 747 else |
| 748 callback(); |
| 749 } |
| 750 } |
| 751 |
| 752 /** |
| 753 * @override |
| 754 * @param {function(this:Object, ...)} functionDeclaration |
| 755 * @param {!Array.<!RuntimeAgent.CallArgument>=} args |
| 756 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback |
| 757 */ |
| 758 callFunction(functionDeclaration, args, callback) { |
| 759 /** |
| 760 * @param {?Protocol.Error} error |
| 761 * @param {!RuntimeAgent.RemoteObject} result |
| 762 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 763 * @this {WebInspector.RemoteObjectImpl} |
| 764 */ |
| 765 function mycallback(error, result, exceptionDetails) { |
| 766 if (!callback) |
| 767 return; |
| 768 if (error) |
| 769 callback(null, false); |
| 770 else |
| 771 callback(this.target().runtimeModel.createRemoteObject(result), !!except
ionDetails); |
| 772 } |
| 773 |
| 774 this._runtimeAgent.callFunctionOn( |
| 775 this._objectId, functionDeclaration.toString(), args, true, undefined, u
ndefined, undefined, undefined, |
| 776 mycallback.bind(this)); |
| 777 } |
| 778 |
| 779 /** |
| 780 * @override |
| 781 * @param {function(this:Object)} functionDeclaration |
| 782 * @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args |
| 783 * @param {function(*)} callback |
| 784 */ |
| 785 callFunctionJSON(functionDeclaration, args, callback) { |
| 786 /** |
| 787 * @param {?Protocol.Error} error |
| 788 * @param {!RuntimeAgent.RemoteObject} result |
| 789 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails |
| 790 */ |
| 791 function mycallback(error, result, exceptionDetails) { |
| 792 callback((error || !!exceptionDetails) ? null : result.value); |
| 793 } |
| 794 |
| 795 this._runtimeAgent.callFunctionOn( |
| 796 this._objectId, functionDeclaration.toString(), args, true, true, false,
undefined, undefined, mycallback); |
| 797 } |
| 798 |
| 799 release() { |
| 800 if (!this._objectId) |
| 801 return; |
| 802 this._runtimeAgent.releaseObject(this._objectId); |
| 803 } |
| 804 |
| 805 /** |
| 806 * @override |
| 807 * @return {number} |
| 808 */ |
| 809 arrayLength() { |
| 810 return WebInspector.RemoteObject.arrayLength(this); |
| 811 } |
| 812 |
| 813 /** |
| 814 * @override |
| 815 * @return {!WebInspector.Target} |
| 816 */ |
| 817 target() { |
| 818 return this._target; |
| 819 } |
| 820 |
| 821 /** |
| 822 * @override |
| 823 * @return {?WebInspector.DebuggerModel} |
| 824 */ |
| 825 debuggerModel() { |
| 826 return this._debuggerModel; |
| 827 } |
| 828 |
| 829 /** |
| 830 * @override |
| 831 * @return {boolean} |
| 832 */ |
| 833 isNode() { |
| 834 return !!this._objectId && this.type === 'object' && this.subtype === 'node'
; |
| 835 } |
| 415 }; | 836 }; |
| 416 | 837 |
| 417 WebInspector.RemoteObjectImpl.prototype = { | |
| 418 | |
| 419 /** | |
| 420 * @override | |
| 421 * @return {?RuntimeAgent.CustomPreview} | |
| 422 */ | |
| 423 customPreview: function() | |
| 424 { | |
| 425 return this._customPreview; | |
| 426 }, | |
| 427 | |
| 428 /** @return {!RuntimeAgent.RemoteObjectId} */ | |
| 429 get objectId() | |
| 430 { | |
| 431 return this._objectId; | |
| 432 }, | |
| 433 | |
| 434 /** | |
| 435 * @override | |
| 436 * @return {string} | |
| 437 */ | |
| 438 get type() | |
| 439 { | |
| 440 return this._type; | |
| 441 }, | |
| 442 | |
| 443 /** | |
| 444 * @override | |
| 445 * @return {string|undefined} | |
| 446 */ | |
| 447 get subtype() | |
| 448 { | |
| 449 return this._subtype; | |
| 450 }, | |
| 451 | |
| 452 /** | |
| 453 * @override | |
| 454 * @return {string|undefined} | |
| 455 */ | |
| 456 get description() | |
| 457 { | |
| 458 return this._description; | |
| 459 }, | |
| 460 | |
| 461 /** | |
| 462 * @override | |
| 463 * @return {boolean} | |
| 464 */ | |
| 465 get hasChildren() | |
| 466 { | |
| 467 return this._hasChildren; | |
| 468 }, | |
| 469 | |
| 470 /** | |
| 471 * @return {!RuntimeAgent.ObjectPreview|undefined} | |
| 472 */ | |
| 473 get preview() | |
| 474 { | |
| 475 return this._preview; | |
| 476 }, | |
| 477 | |
| 478 /** | |
| 479 * @override | |
| 480 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 481 */ | |
| 482 getOwnProperties: function(callback) | |
| 483 { | |
| 484 this.doGetProperties(true, false, false, callback); | |
| 485 }, | |
| 486 | |
| 487 /** | |
| 488 * @override | |
| 489 * @param {boolean} accessorPropertiesOnly | |
| 490 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 491 */ | |
| 492 getAllProperties: function(accessorPropertiesOnly, callback) | |
| 493 { | |
| 494 this.doGetProperties(false, accessorPropertiesOnly, false, callback); | |
| 495 }, | |
| 496 | |
| 497 /** | |
| 498 * @override | |
| 499 * @return {!Promise<?Array<!WebInspector.EventListener>>} | |
| 500 */ | |
| 501 eventListeners: function() | |
| 502 { | |
| 503 return new Promise(eventListeners.bind(this)); | |
| 504 /** | |
| 505 * @param {function(?)} fulfill | |
| 506 * @param {function(*)} reject | |
| 507 * @this {WebInspector.RemoteObjectImpl} | |
| 508 */ | |
| 509 function eventListeners(fulfill, reject) | |
| 510 { | |
| 511 if (!this.target().hasDOMCapability()) { | |
| 512 // TODO(kozyatinskiy): figure out how this should work for |wind
ow| when there is no DOMDebugger. | |
| 513 fulfill([]); | |
| 514 return; | |
| 515 } | |
| 516 | |
| 517 if (!this._objectId) { | |
| 518 reject(new Error("No object id specified")); | |
| 519 return; | |
| 520 } | |
| 521 | |
| 522 this.target().domdebuggerAgent().getEventListeners(this._objectId, m
ycallback.bind(this)); | |
| 523 | |
| 524 /** | |
| 525 * @this {WebInspector.RemoteObjectImpl} | |
| 526 * @param {?Protocol.Error} error | |
| 527 * @param {!Array<!DOMDebuggerAgent.EventListener>} payloads | |
| 528 */ | |
| 529 function mycallback(error, payloads) | |
| 530 { | |
| 531 if (error) { | |
| 532 reject(new Error(error)); | |
| 533 return; | |
| 534 } | |
| 535 fulfill(payloads.map(createEventListener.bind(this))); | |
| 536 } | |
| 537 | |
| 538 /** | |
| 539 * @this {WebInspector.RemoteObjectImpl} | |
| 540 * @param {!DOMDebuggerAgent.EventListener} payload | |
| 541 */ | |
| 542 function createEventListener(payload) | |
| 543 { | |
| 544 return new WebInspector.EventListener(this._target, | |
| 545 this, | |
| 546 payload.type, | |
| 547 payload.useCapture, | |
| 548 payload.passive, | |
| 549 payload.handler ? this.tar
get().runtimeModel.createRemoteObject(payload.handler) : null, | |
| 550 payload.originalHandler ?
this.target().runtimeModel.createRemoteObject(payload.originalHandler) : null, | |
| 551 /** @type {!WebInspector.D
ebuggerModel.Location} */ (this._debuggerModel.createRawLocationByScriptId(paylo
ad.scriptId, payload.lineNumber, payload.columnNumber)), | |
| 552 payload.removeFunction ? t
his.target().runtimeModel.createRemoteObject(payload.removeFunction) : null); | |
| 553 } | |
| 554 } | |
| 555 }, | |
| 556 | |
| 557 /** | |
| 558 * @param {!Array.<string>} propertyPath | |
| 559 * @param {function(?WebInspector.RemoteObject, boolean=)} callback | |
| 560 */ | |
| 561 getProperty: function(propertyPath, callback) | |
| 562 { | |
| 563 /** | |
| 564 * @param {string} arrayStr | |
| 565 * @suppressReceiverCheck | |
| 566 * @this {Object} | |
| 567 */ | |
| 568 function remoteFunction(arrayStr) | |
| 569 { | |
| 570 var result = this; | |
| 571 var properties = JSON.parse(arrayStr); | |
| 572 for (var i = 0, n = properties.length; i < n; ++i) | |
| 573 result = result[properties[i]]; | |
| 574 return result; | |
| 575 } | |
| 576 | |
| 577 var args = [{ value: JSON.stringify(propertyPath) }]; | |
| 578 this.callFunction(remoteFunction, args, callback); | |
| 579 }, | |
| 580 | |
| 581 /** | |
| 582 * @param {boolean} ownProperties | |
| 583 * @param {boolean} accessorPropertiesOnly | |
| 584 * @param {boolean} generatePreview | |
| 585 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 586 */ | |
| 587 doGetProperties: function(ownProperties, accessorPropertiesOnly, generatePre
view, callback) | |
| 588 { | |
| 589 if (!this._objectId) { | |
| 590 callback(null, null); | |
| 591 return; | |
| 592 } | |
| 593 | |
| 594 /** | |
| 595 * @param {?Protocol.Error} error | |
| 596 * @param {!Array.<!RuntimeAgent.PropertyDescriptor>} properties | |
| 597 * @param {!Array.<!RuntimeAgent.InternalPropertyDescriptor>=} internalP
roperties | |
| 598 * @param {?RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 599 * @this {WebInspector.RemoteObjectImpl} | |
| 600 */ | |
| 601 function remoteObjectBinder(error, properties, internalProperties, excep
tionDetails) | |
| 602 { | |
| 603 if (error) { | |
| 604 callback(null, null); | |
| 605 return; | |
| 606 } | |
| 607 if (exceptionDetails) { | |
| 608 this._target.consoleModel.addMessage(WebInspector.ConsoleMessage
.fromException(this._target, exceptionDetails, undefined, undefined, undefined))
; | |
| 609 callback(null, null); | |
| 610 return; | |
| 611 } | |
| 612 var result = []; | |
| 613 for (var i = 0; properties && i < properties.length; ++i) { | |
| 614 var property = properties[i]; | |
| 615 var propertyValue = property.value ? this._target.runtimeModel.c
reateRemoteObject(property.value) : null; | |
| 616 var propertySymbol = property.symbol ? this._target.runtimeModel
.createRemoteObject(property.symbol) : null; | |
| 617 var remoteProperty = new WebInspector.RemoteObjectProperty(prope
rty.name, propertyValue, | |
| 618 !!property.enumerable, !!property.writable, !!property.i
sOwn, !!property.wasThrown, propertySymbol); | |
| 619 | |
| 620 if (typeof property.value === "undefined") { | |
| 621 if (property.get && property.get.type !== "undefined") | |
| 622 remoteProperty.getter = this._target.runtimeModel.create
RemoteObject(property.get); | |
| 623 if (property.set && property.set.type !== "undefined") | |
| 624 remoteProperty.setter = this._target.runtimeModel.create
RemoteObject(property.set); | |
| 625 } | |
| 626 | |
| 627 result.push(remoteProperty); | |
| 628 } | |
| 629 var internalPropertiesResult = null; | |
| 630 if (internalProperties) { | |
| 631 internalPropertiesResult = []; | |
| 632 for (var i = 0; i < internalProperties.length; i++) { | |
| 633 var property = internalProperties[i]; | |
| 634 if (!property.value) | |
| 635 continue; | |
| 636 var propertyValue = this._target.runtimeModel.createRemoteOb
ject(property.value); | |
| 637 internalPropertiesResult.push(new WebInspector.RemoteObjectP
roperty(property.name, propertyValue, true, false)); | |
| 638 } | |
| 639 } | |
| 640 callback(result, internalPropertiesResult); | |
| 641 } | |
| 642 this._runtimeAgent.getProperties(this._objectId, ownProperties, accessor
PropertiesOnly, generatePreview, remoteObjectBinder.bind(this)); | |
| 643 }, | |
| 644 | |
| 645 /** | |
| 646 * @override | |
| 647 * @param {string|!RuntimeAgent.CallArgument} name | |
| 648 * @param {string} value | |
| 649 * @param {function(string=)} callback | |
| 650 */ | |
| 651 setPropertyValue: function(name, value, callback) | |
| 652 { | |
| 653 if (!this._objectId) { | |
| 654 callback("Can't set a property of non-object."); | |
| 655 return; | |
| 656 } | |
| 657 | |
| 658 this._runtimeAgent.invoke_evaluate({expression:value, silent:true}, eval
uatedCallback.bind(this)); | |
| 659 | |
| 660 /** | |
| 661 * @param {?Protocol.Error} error | |
| 662 * @param {!RuntimeAgent.RemoteObject} result | |
| 663 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 664 * @this {WebInspector.RemoteObject} | |
| 665 */ | |
| 666 function evaluatedCallback(error, result, exceptionDetails) | |
| 667 { | |
| 668 if (error || !!exceptionDetails) { | |
| 669 callback(error || (result.type !== "string" ? result.description
: /** @type {string} */(result.value))); | |
| 670 return; | |
| 671 } | |
| 672 | |
| 673 if (typeof name === "string") | |
| 674 name = WebInspector.RemoteObject.toCallArgument(name); | |
| 675 | |
| 676 this.doSetObjectPropertyValue(result, name, callback); | |
| 677 | |
| 678 if (result.objectId) | |
| 679 this._runtimeAgent.releaseObject(result.objectId); | |
| 680 } | |
| 681 }, | |
| 682 | |
| 683 /** | |
| 684 * @param {!RuntimeAgent.RemoteObject} result | |
| 685 * @param {!RuntimeAgent.CallArgument} name | |
| 686 * @param {function(string=)} callback | |
| 687 */ | |
| 688 doSetObjectPropertyValue: function(result, name, callback) | |
| 689 { | |
| 690 // This assignment may be for a regular (data) property, and for an acce
ssor property (with getter/setter). | |
| 691 // Note the sensitive matter about accessor property: the property may b
e physically defined in some proto object, | |
| 692 // but logically it is bound to the object in question. JavaScript passe
s this object to getters/setters, not the object | |
| 693 // where property was defined; so do we. | |
| 694 var setPropertyValueFunction = "function(a, b) { this[a] = b; }"; | |
| 695 | |
| 696 var argv = [name, WebInspector.RemoteObject.toCallArgument(result)]; | |
| 697 this._runtimeAgent.callFunctionOn(this._objectId, setPropertyValueFuncti
on, argv, true, undefined, undefined, undefined, undefined, propertySetCallback)
; | |
| 698 | |
| 699 /** | |
| 700 * @param {?Protocol.Error} error | |
| 701 * @param {!RuntimeAgent.RemoteObject} result | |
| 702 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 703 */ | |
| 704 function propertySetCallback(error, result, exceptionDetails) | |
| 705 { | |
| 706 if (error || !!exceptionDetails) { | |
| 707 callback(error || result.description); | |
| 708 return; | |
| 709 } | |
| 710 callback(); | |
| 711 } | |
| 712 }, | |
| 713 | |
| 714 /** | |
| 715 * @override | |
| 716 * @param {!RuntimeAgent.CallArgument} name | |
| 717 * @param {function(string=)} callback | |
| 718 */ | |
| 719 deleteProperty: function(name, callback) | |
| 720 { | |
| 721 if (!this._objectId) { | |
| 722 callback("Can't delete a property of non-object."); | |
| 723 return; | |
| 724 } | |
| 725 | |
| 726 var deletePropertyFunction = "function(a) { delete this[a]; return !(a i
n this); }"; | |
| 727 this._runtimeAgent.callFunctionOn(this._objectId, deletePropertyFunction
, [name], true, undefined, undefined, undefined, undefined, deletePropertyCallba
ck); | |
| 728 | |
| 729 /** | |
| 730 * @param {?Protocol.Error} error | |
| 731 * @param {!RuntimeAgent.RemoteObject} result | |
| 732 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 733 */ | |
| 734 function deletePropertyCallback(error, result, exceptionDetails) | |
| 735 { | |
| 736 if (error || !!exceptionDetails) { | |
| 737 callback(error || result.description); | |
| 738 return; | |
| 739 } | |
| 740 if (!result.value) | |
| 741 callback("Failed to delete property."); | |
| 742 else | |
| 743 callback(); | |
| 744 } | |
| 745 }, | |
| 746 | |
| 747 /** | |
| 748 * @override | |
| 749 * @param {function(this:Object, ...)} functionDeclaration | |
| 750 * @param {!Array.<!RuntimeAgent.CallArgument>=} args | |
| 751 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback | |
| 752 */ | |
| 753 callFunction: function(functionDeclaration, args, callback) | |
| 754 { | |
| 755 /** | |
| 756 * @param {?Protocol.Error} error | |
| 757 * @param {!RuntimeAgent.RemoteObject} result | |
| 758 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 759 * @this {WebInspector.RemoteObjectImpl} | |
| 760 */ | |
| 761 function mycallback(error, result, exceptionDetails) | |
| 762 { | |
| 763 if (!callback) | |
| 764 return; | |
| 765 if (error) | |
| 766 callback(null, false); | |
| 767 else | |
| 768 callback(this.target().runtimeModel.createRemoteObject(result),
!!exceptionDetails); | |
| 769 } | |
| 770 | |
| 771 this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.to
String(), args, true, undefined, undefined, undefined, undefined, mycallback.bin
d(this)); | |
| 772 }, | |
| 773 | |
| 774 /** | |
| 775 * @override | |
| 776 * @param {function(this:Object)} functionDeclaration | |
| 777 * @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args | |
| 778 * @param {function(*)} callback | |
| 779 */ | |
| 780 callFunctionJSON: function(functionDeclaration, args, callback) | |
| 781 { | |
| 782 /** | |
| 783 * @param {?Protocol.Error} error | |
| 784 * @param {!RuntimeAgent.RemoteObject} result | |
| 785 * @param {!RuntimeAgent.ExceptionDetails=} exceptionDetails | |
| 786 */ | |
| 787 function mycallback(error, result, exceptionDetails) | |
| 788 { | |
| 789 callback((error || !!exceptionDetails) ? null : result.value); | |
| 790 } | |
| 791 | |
| 792 this._runtimeAgent.callFunctionOn(this._objectId, functionDeclaration.to
String(), args, true, true, false, undefined, undefined, mycallback); | |
| 793 }, | |
| 794 | |
| 795 release: function() | |
| 796 { | |
| 797 if (!this._objectId) | |
| 798 return; | |
| 799 this._runtimeAgent.releaseObject(this._objectId); | |
| 800 }, | |
| 801 | |
| 802 /** | |
| 803 * @override | |
| 804 * @return {number} | |
| 805 */ | |
| 806 arrayLength: function() | |
| 807 { | |
| 808 return WebInspector.RemoteObject.arrayLength(this); | |
| 809 }, | |
| 810 | |
| 811 /** | |
| 812 * @override | |
| 813 * @return {!WebInspector.Target} | |
| 814 */ | |
| 815 target: function() | |
| 816 { | |
| 817 return this._target; | |
| 818 }, | |
| 819 | |
| 820 /** | |
| 821 * @override | |
| 822 * @return {?WebInspector.DebuggerModel} | |
| 823 */ | |
| 824 debuggerModel: function() | |
| 825 { | |
| 826 return this._debuggerModel; | |
| 827 }, | |
| 828 | |
| 829 /** | |
| 830 * @override | |
| 831 * @return {boolean} | |
| 832 */ | |
| 833 isNode: function() | |
| 834 { | |
| 835 return !!this._objectId && this.type === "object" && this.subtype === "n
ode"; | |
| 836 }, | |
| 837 | |
| 838 __proto__: WebInspector.RemoteObject.prototype | |
| 839 }; | |
| 840 | |
| 841 | 838 |
| 842 /** | 839 /** |
| 843 * @param {!WebInspector.RemoteObject} object | 840 * @unrestricted |
| 844 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebIns
pector.RemoteObjectProperty>)} callback | |
| 845 */ | 841 */ |
| 846 WebInspector.RemoteObject.loadFromObjectPerProto = function(object, callback) | 842 WebInspector.ScopeRemoteObject = class extends WebInspector.RemoteObjectImpl { |
| 847 { | 843 /** |
| 848 // Combines 2 asynch calls. Doesn't rely on call-back orders (some calls may
be loop-back). | 844 * @param {!WebInspector.Target} target |
| 849 var savedOwnProperties; | 845 * @param {string|undefined} objectId |
| 850 var savedAccessorProperties; | 846 * @param {!WebInspector.ScopeRef} scopeRef |
| 851 var savedInternalProperties; | 847 * @param {string} type |
| 852 var resultCounter = 2; | 848 * @param {string|undefined} subtype |
| 853 | 849 * @param {*} value |
| 854 function processCallback() | 850 * @param {!RuntimeAgent.UnserializableValue=} unserializableValue |
| 855 { | 851 * @param {string=} description |
| 856 if (--resultCounter) | 852 * @param {!RuntimeAgent.ObjectPreview=} preview |
| 857 return; | 853 */ |
| 858 if (savedOwnProperties && savedAccessorProperties) { | 854 constructor(target, objectId, scopeRef, type, subtype, value, unserializableVa
lue, description, preview) { |
| 859 var propertiesMap = new Map(); | 855 super(target, objectId, type, subtype, value, unserializableValue, descripti
on, preview); |
| 860 var propertySymbols = []; | 856 this._scopeRef = scopeRef; |
| 861 for (var i = 0; i < savedAccessorProperties.length; i++) { | 857 this._savedScopeProperties = undefined; |
| 862 var property = savedAccessorProperties[i]; | 858 } |
| 863 if (property.symbol) | 859 |
| 864 propertySymbols.push(property); | 860 /** |
| 865 else | 861 * @override |
| 866 propertiesMap.set(property.name, property); | 862 * @param {boolean} ownProperties |
| 867 } | 863 * @param {boolean} accessorPropertiesOnly |
| 868 for (var i = 0; i < savedOwnProperties.length; i++) { | 864 * @param {boolean} generatePreview |
| 869 var property = savedOwnProperties[i]; | 865 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 870 if (property.isAccessorProperty()) | 866 */ |
| 871 continue; | 867 doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview, callba
ck) { |
| 872 if (property.symbol) | 868 if (accessorPropertiesOnly) { |
| 873 propertySymbols.push(property); | 869 callback([], []); |
| 874 else | 870 return; |
| 875 propertiesMap.set(property.name, property); | 871 } |
| 876 } | 872 |
| 877 return callback(propertiesMap.valuesArray().concat(propertySymbols),
savedInternalProperties ? savedInternalProperties : null); | 873 if (this._savedScopeProperties) { |
| 878 } else { | 874 // No need to reload scope variables, as the remote object never |
| 879 callback(null, null); | 875 // changes its properties. If variable is updated, the properties |
| 880 } | 876 // array is patched locally. |
| 877 callback(this._savedScopeProperties.slice(), []); |
| 878 return; |
| 881 } | 879 } |
| 882 | 880 |
| 883 /** | 881 /** |
| 884 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | 882 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties |
| 885 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties | 883 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties |
| 886 */ | 884 * @this {WebInspector.ScopeRemoteObject} |
| 887 function allAccessorPropertiesCallback(properties, internalProperties) | 885 */ |
| 888 { | 886 function wrappedCallback(properties, internalProperties) { |
| 889 savedAccessorProperties = properties; | 887 if (this._scopeRef && Array.isArray(properties)) { |
| 890 processCallback(); | 888 this._savedScopeProperties = properties.slice(); |
| 891 } | 889 if (!this._scopeRef.callFrameId) { |
| 892 | 890 for (var property of this._savedScopeProperties) |
| 893 /** | 891 property.writable = false; |
| 894 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | 892 } |
| 895 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperties | 893 } |
| 896 */ | 894 callback(properties, internalProperties); |
| 897 function ownPropertiesCallback(properties, internalProperties) | 895 } |
| 898 { | 896 |
| 899 savedOwnProperties = properties; | 897 // Scope objects always fetch preview. |
| 900 savedInternalProperties = internalProperties; | 898 generatePreview = true; |
| 901 processCallback(); | 899 |
| 902 } | 900 super.doGetProperties(ownProperties, accessorPropertiesOnly, generatePreview
, wrappedCallback.bind(this)); |
| 903 | 901 } |
| 904 object.getAllProperties(true, allAccessorPropertiesCallback); | 902 |
| 905 object.getOwnProperties(ownPropertiesCallback); | 903 /** |
| 904 * @override |
| 905 * @param {!RuntimeAgent.RemoteObject} result |
| 906 * @param {!RuntimeAgent.CallArgument} argumentName |
| 907 * @param {function(string=)} callback |
| 908 */ |
| 909 doSetObjectPropertyValue(result, argumentName, callback) { |
| 910 var name = /** @type {string} */ (argumentName.value); |
| 911 this._debuggerModel.setVariableValue( |
| 912 this._scopeRef.number, name, WebInspector.RemoteObject.toCallArgument(re
sult), this._scopeRef.callFrameId, |
| 913 setVariableValueCallback.bind(this)); |
| 914 |
| 915 /** |
| 916 * @param {string=} error |
| 917 * @this {WebInspector.ScopeRemoteObject} |
| 918 */ |
| 919 function setVariableValueCallback(error) { |
| 920 if (error) { |
| 921 callback(error); |
| 922 return; |
| 923 } |
| 924 if (this._savedScopeProperties) { |
| 925 for (var i = 0; i < this._savedScopeProperties.length; i++) { |
| 926 if (this._savedScopeProperties[i].name === name) |
| 927 this._savedScopeProperties[i].value = this._target.runtimeModel.crea
teRemoteObject(result); |
| 928 } |
| 929 } |
| 930 callback(); |
| 931 } |
| 932 } |
| 906 }; | 933 }; |
| 907 | 934 |
| 908 | |
| 909 /** | 935 /** |
| 910 * @constructor | 936 * @unrestricted |
| 911 * @extends {WebInspector.RemoteObjectImpl} | |
| 912 * @param {!WebInspector.Target} target | |
| 913 * @param {string|undefined} objectId | |
| 914 * @param {!WebInspector.ScopeRef} scopeRef | |
| 915 * @param {string} type | |
| 916 * @param {string|undefined} subtype | |
| 917 * @param {*} value | |
| 918 * @param {!RuntimeAgent.UnserializableValue=} unserializableValue | |
| 919 * @param {string=} description | |
| 920 * @param {!RuntimeAgent.ObjectPreview=} preview | |
| 921 */ | 937 */ |
| 922 WebInspector.ScopeRemoteObject = function(target, objectId, scopeRef, type, subt
ype, value, unserializableValue, description, preview) | 938 WebInspector.ScopeRef = class { |
| 923 { | 939 /** |
| 924 WebInspector.RemoteObjectImpl.call(this, target, objectId, type, subtype, va
lue, unserializableValue, description, preview); | 940 * @param {number} number |
| 925 this._scopeRef = scopeRef; | 941 * @param {string=} callFrameId |
| 926 this._savedScopeProperties = undefined; | 942 */ |
| 927 }; | 943 constructor(number, callFrameId) { |
| 928 | |
| 929 WebInspector.ScopeRemoteObject.prototype = { | |
| 930 /** | |
| 931 * @override | |
| 932 * @param {boolean} ownProperties | |
| 933 * @param {boolean} accessorPropertiesOnly | |
| 934 * @param {boolean} generatePreview | |
| 935 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 936 */ | |
| 937 doGetProperties: function(ownProperties, accessorPropertiesOnly, generatePre
view, callback) | |
| 938 { | |
| 939 if (accessorPropertiesOnly) { | |
| 940 callback([], []); | |
| 941 return; | |
| 942 } | |
| 943 | |
| 944 if (this._savedScopeProperties) { | |
| 945 // No need to reload scope variables, as the remote object never | |
| 946 // changes its properties. If variable is updated, the properties | |
| 947 // array is patched locally. | |
| 948 callback(this._savedScopeProperties.slice(), []); | |
| 949 return; | |
| 950 } | |
| 951 | |
| 952 /** | |
| 953 * @param {?Array.<!WebInspector.RemoteObjectProperty>} properties | |
| 954 * @param {?Array.<!WebInspector.RemoteObjectProperty>} internalProperti
es | |
| 955 * @this {WebInspector.ScopeRemoteObject} | |
| 956 */ | |
| 957 function wrappedCallback(properties, internalProperties) | |
| 958 { | |
| 959 if (this._scopeRef && Array.isArray(properties)) { | |
| 960 this._savedScopeProperties = properties.slice(); | |
| 961 if (!this._scopeRef.callFrameId) { | |
| 962 for (var property of this._savedScopeProperties) | |
| 963 property.writable = false; | |
| 964 } | |
| 965 } | |
| 966 callback(properties, internalProperties); | |
| 967 } | |
| 968 | |
| 969 // Scope objects always fetch preview. | |
| 970 generatePreview = true; | |
| 971 | |
| 972 WebInspector.RemoteObjectImpl.prototype.doGetProperties.call(this, ownPr
operties, accessorPropertiesOnly, generatePreview, wrappedCallback.bind(this)); | |
| 973 }, | |
| 974 | |
| 975 /** | |
| 976 * @override | |
| 977 * @param {!RuntimeAgent.RemoteObject} result | |
| 978 * @param {!RuntimeAgent.CallArgument} argumentName | |
| 979 * @param {function(string=)} callback | |
| 980 */ | |
| 981 doSetObjectPropertyValue: function(result, argumentName, callback) | |
| 982 { | |
| 983 var name = /** @type {string} */ (argumentName.value); | |
| 984 this._debuggerModel.setVariableValue(this._scopeRef.number, name, WebIns
pector.RemoteObject.toCallArgument(result), this._scopeRef.callFrameId, setVaria
bleValueCallback.bind(this)); | |
| 985 | |
| 986 /** | |
| 987 * @param {string=} error | |
| 988 * @this {WebInspector.ScopeRemoteObject} | |
| 989 */ | |
| 990 function setVariableValueCallback(error) | |
| 991 { | |
| 992 if (error) { | |
| 993 callback(error); | |
| 994 return; | |
| 995 } | |
| 996 if (this._savedScopeProperties) { | |
| 997 for (var i = 0; i < this._savedScopeProperties.length; i++) { | |
| 998 if (this._savedScopeProperties[i].name === name) | |
| 999 this._savedScopeProperties[i].value = this._target.runti
meModel.createRemoteObject(result); | |
| 1000 } | |
| 1001 } | |
| 1002 callback(); | |
| 1003 } | |
| 1004 }, | |
| 1005 | |
| 1006 __proto__: WebInspector.RemoteObjectImpl.prototype | |
| 1007 }; | |
| 1008 | |
| 1009 /** | |
| 1010 * @constructor | |
| 1011 * @param {number} number | |
| 1012 * @param {string=} callFrameId | |
| 1013 */ | |
| 1014 WebInspector.ScopeRef = function(number, callFrameId) | |
| 1015 { | |
| 1016 this.number = number; | 944 this.number = number; |
| 1017 this.callFrameId = callFrameId; | 945 this.callFrameId = callFrameId; |
| 946 } |
| 1018 }; | 947 }; |
| 1019 | 948 |
| 1020 /** | 949 /** |
| 1021 * @constructor | 950 * @unrestricted |
| 1022 * @param {string} name | |
| 1023 * @param {?WebInspector.RemoteObject} value | |
| 1024 * @param {boolean=} enumerable | |
| 1025 * @param {boolean=} writable | |
| 1026 * @param {boolean=} isOwn | |
| 1027 * @param {boolean=} wasThrown | |
| 1028 * @param {boolean=} synthetic | |
| 1029 * @param {?WebInspector.RemoteObject=} symbol | |
| 1030 */ | 951 */ |
| 1031 WebInspector.RemoteObjectProperty = function(name, value, enumerable, writable,
isOwn, wasThrown, symbol, synthetic) | 952 WebInspector.RemoteObjectProperty = class { |
| 1032 { | 953 /** |
| 954 * @param {string} name |
| 955 * @param {?WebInspector.RemoteObject} value |
| 956 * @param {boolean=} enumerable |
| 957 * @param {boolean=} writable |
| 958 * @param {boolean=} isOwn |
| 959 * @param {boolean=} wasThrown |
| 960 * @param {boolean=} synthetic |
| 961 * @param {?WebInspector.RemoteObject=} symbol |
| 962 */ |
| 963 constructor(name, value, enumerable, writable, isOwn, wasThrown, symbol, synth
etic) { |
| 1033 this.name = name; | 964 this.name = name; |
| 1034 if (value !== null) | 965 if (value !== null) |
| 1035 this.value = value; | 966 this.value = value; |
| 1036 this.enumerable = typeof enumerable !== "undefined" ? enumerable : true; | 967 this.enumerable = typeof enumerable !== 'undefined' ? enumerable : true; |
| 1037 this.writable = typeof writable !== "undefined" ? writable : true; | 968 this.writable = typeof writable !== 'undefined' ? writable : true; |
| 1038 this.isOwn = !!isOwn; | 969 this.isOwn = !!isOwn; |
| 1039 this.wasThrown = !!wasThrown; | 970 this.wasThrown = !!wasThrown; |
| 1040 if (symbol) | 971 if (symbol) |
| 1041 this.symbol = symbol; | 972 this.symbol = symbol; |
| 1042 this.synthetic = !!synthetic; | 973 this.synthetic = !!synthetic; |
| 974 } |
| 975 |
| 976 /** |
| 977 * @return {boolean} |
| 978 */ |
| 979 isAccessorProperty() { |
| 980 return !!(this.getter || this.setter); |
| 981 } |
| 1043 }; | 982 }; |
| 1044 | 983 |
| 1045 WebInspector.RemoteObjectProperty.prototype = { | |
| 1046 /** | |
| 1047 * @return {boolean} | |
| 1048 */ | |
| 1049 isAccessorProperty: function() | |
| 1050 { | |
| 1051 return !!(this.getter || this.setter); | |
| 1052 } | |
| 1053 }; | |
| 1054 | |
| 1055 // Below is a wrapper around a local object that implements the RemoteObject int
erface, | 984 // Below is a wrapper around a local object that implements the RemoteObject int
erface, |
| 1056 // which can be used by the UI code (primarily ObjectPropertiesSection). | 985 // which can be used by the UI code (primarily ObjectPropertiesSection). |
| 1057 // Note that only JSON-compliant objects are currently supported, as there's no
provision | 986 // Note that only JSON-compliant objects are currently supported, as there's no
provision |
| 1058 // for traversing prototypes, extracting class names via constructor, handling p
roperties | 987 // for traversing prototypes, extracting class names via constructor, handling p
roperties |
| 1059 // or functions. | 988 // or functions. |
| 1060 | 989 |
| 1061 /** | 990 /** |
| 1062 * @constructor | 991 * @unrestricted |
| 1063 * @extends {WebInspector.RemoteObject} | |
| 1064 * @param {*} value | |
| 1065 */ | 992 */ |
| 1066 WebInspector.LocalJSONObject = function(value) | 993 WebInspector.LocalJSONObject = class extends WebInspector.RemoteObject { |
| 1067 { | 994 /** |
| 1068 WebInspector.RemoteObject.call(this); | 995 * @param {*} value |
| 996 */ |
| 997 constructor(value) { |
| 998 super(); |
| 1069 this._value = value; | 999 this._value = value; |
| 1000 } |
| 1001 |
| 1002 /** |
| 1003 * @override |
| 1004 * @return {string} |
| 1005 */ |
| 1006 get description() { |
| 1007 if (this._cachedDescription) |
| 1008 return this._cachedDescription; |
| 1009 |
| 1010 /** |
| 1011 * @param {!WebInspector.RemoteObjectProperty} property |
| 1012 * @return {string} |
| 1013 * @this {WebInspector.LocalJSONObject} |
| 1014 */ |
| 1015 function formatArrayItem(property) { |
| 1016 return this._formatValue(property.value); |
| 1017 } |
| 1018 |
| 1019 /** |
| 1020 * @param {!WebInspector.RemoteObjectProperty} property |
| 1021 * @return {string} |
| 1022 * @this {WebInspector.LocalJSONObject} |
| 1023 */ |
| 1024 function formatObjectItem(property) { |
| 1025 var name = property.name; |
| 1026 if (/^\s|\s$|^$|\n/.test(name)) |
| 1027 name = '"' + name.replace(/\n/g, '\u21B5') + '"'; |
| 1028 return name + ': ' + this._formatValue(property.value); |
| 1029 } |
| 1030 |
| 1031 if (this.type === 'object') { |
| 1032 switch (this.subtype) { |
| 1033 case 'array': |
| 1034 this._cachedDescription = this._concatenate('[', ']', formatArrayItem.
bind(this)); |
| 1035 break; |
| 1036 case 'date': |
| 1037 this._cachedDescription = '' + this._value; |
| 1038 break; |
| 1039 case 'null': |
| 1040 this._cachedDescription = 'null'; |
| 1041 break; |
| 1042 default: |
| 1043 this._cachedDescription = this._concatenate('{', '}', formatObjectItem
.bind(this)); |
| 1044 } |
| 1045 } else { |
| 1046 this._cachedDescription = String(this._value); |
| 1047 } |
| 1048 |
| 1049 return this._cachedDescription; |
| 1050 } |
| 1051 |
| 1052 /** |
| 1053 * @param {?WebInspector.RemoteObject} value |
| 1054 * @return {string} |
| 1055 */ |
| 1056 _formatValue(value) { |
| 1057 if (!value) |
| 1058 return 'undefined'; |
| 1059 var description = value.description || ''; |
| 1060 if (value.type === 'string') |
| 1061 return '"' + description.replace(/\n/g, '\u21B5') + '"'; |
| 1062 return description; |
| 1063 } |
| 1064 |
| 1065 /** |
| 1066 * @param {string} prefix |
| 1067 * @param {string} suffix |
| 1068 * @param {function(!WebInspector.RemoteObjectProperty)} formatProperty |
| 1069 * @return {string} |
| 1070 */ |
| 1071 _concatenate(prefix, suffix, formatProperty) { |
| 1072 var previewChars = 100; |
| 1073 |
| 1074 var buffer = prefix; |
| 1075 var children = this._children(); |
| 1076 for (var i = 0; i < children.length; ++i) { |
| 1077 var itemDescription = formatProperty(children[i]); |
| 1078 if (buffer.length + itemDescription.length > previewChars) { |
| 1079 buffer += ',\u2026'; |
| 1080 break; |
| 1081 } |
| 1082 if (i) |
| 1083 buffer += ', '; |
| 1084 buffer += itemDescription; |
| 1085 } |
| 1086 buffer += suffix; |
| 1087 return buffer; |
| 1088 } |
| 1089 |
| 1090 /** |
| 1091 * @override |
| 1092 * @return {string} |
| 1093 */ |
| 1094 get type() { |
| 1095 return typeof this._value; |
| 1096 } |
| 1097 |
| 1098 /** |
| 1099 * @override |
| 1100 * @return {string|undefined} |
| 1101 */ |
| 1102 get subtype() { |
| 1103 if (this._value === null) |
| 1104 return 'null'; |
| 1105 |
| 1106 if (Array.isArray(this._value)) |
| 1107 return 'array'; |
| 1108 |
| 1109 if (this._value instanceof Date) |
| 1110 return 'date'; |
| 1111 |
| 1112 return undefined; |
| 1113 } |
| 1114 |
| 1115 /** |
| 1116 * @override |
| 1117 * @return {boolean} |
| 1118 */ |
| 1119 get hasChildren() { |
| 1120 if ((typeof this._value !== 'object') || (this._value === null)) |
| 1121 return false; |
| 1122 return !!Object.keys(/** @type {!Object} */ (this._value)).length; |
| 1123 } |
| 1124 |
| 1125 /** |
| 1126 * @override |
| 1127 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 1128 */ |
| 1129 getOwnProperties(callback) { |
| 1130 callback(this._children(), null); |
| 1131 } |
| 1132 |
| 1133 /** |
| 1134 * @override |
| 1135 * @param {boolean} accessorPropertiesOnly |
| 1136 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!WebI
nspector.RemoteObjectProperty>)} callback |
| 1137 */ |
| 1138 getAllProperties(accessorPropertiesOnly, callback) { |
| 1139 if (accessorPropertiesOnly) |
| 1140 callback([], null); |
| 1141 else |
| 1142 callback(this._children(), null); |
| 1143 } |
| 1144 |
| 1145 /** |
| 1146 * @return {!Array.<!WebInspector.RemoteObjectProperty>} |
| 1147 */ |
| 1148 _children() { |
| 1149 if (!this.hasChildren) |
| 1150 return []; |
| 1151 var value = /** @type {!Object} */ (this._value); |
| 1152 |
| 1153 /** |
| 1154 * @param {string} propName |
| 1155 * @return {!WebInspector.RemoteObjectProperty} |
| 1156 */ |
| 1157 function buildProperty(propName) { |
| 1158 var propValue = value[propName]; |
| 1159 if (!(propValue instanceof WebInspector.RemoteObject)) |
| 1160 propValue = WebInspector.RemoteObject.fromLocalObject(propValue); |
| 1161 return new WebInspector.RemoteObjectProperty(propName, propValue); |
| 1162 } |
| 1163 if (!this._cachedChildren) |
| 1164 this._cachedChildren = Object.keys(value).map(buildProperty); |
| 1165 return this._cachedChildren; |
| 1166 } |
| 1167 |
| 1168 /** |
| 1169 * @return {boolean} |
| 1170 */ |
| 1171 isError() { |
| 1172 return false; |
| 1173 } |
| 1174 |
| 1175 /** |
| 1176 * @override |
| 1177 * @return {number} |
| 1178 */ |
| 1179 arrayLength() { |
| 1180 return Array.isArray(this._value) ? this._value.length : 0; |
| 1181 } |
| 1182 |
| 1183 /** |
| 1184 * @override |
| 1185 * @param {function(this:Object, ...)} functionDeclaration |
| 1186 * @param {!Array.<!RuntimeAgent.CallArgument>=} args |
| 1187 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback |
| 1188 */ |
| 1189 callFunction(functionDeclaration, args, callback) { |
| 1190 var target = /** @type {?Object} */ (this._value); |
| 1191 var rawArgs = args ? args.map(function(arg) { |
| 1192 return arg.value; |
| 1193 }) : |
| 1194 []; |
| 1195 |
| 1196 var result; |
| 1197 var wasThrown = false; |
| 1198 try { |
| 1199 result = functionDeclaration.apply(target, rawArgs); |
| 1200 } catch (e) { |
| 1201 wasThrown = true; |
| 1202 } |
| 1203 |
| 1204 if (!callback) |
| 1205 return; |
| 1206 callback(WebInspector.RemoteObject.fromLocalObject(result), wasThrown); |
| 1207 } |
| 1208 |
| 1209 /** |
| 1210 * @override |
| 1211 * @param {function(this:Object)} functionDeclaration |
| 1212 * @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args |
| 1213 * @param {function(*)} callback |
| 1214 */ |
| 1215 callFunctionJSON(functionDeclaration, args, callback) { |
| 1216 var target = /** @type {?Object} */ (this._value); |
| 1217 var rawArgs = args ? args.map(function(arg) { |
| 1218 return arg.value; |
| 1219 }) : |
| 1220 []; |
| 1221 |
| 1222 var result; |
| 1223 try { |
| 1224 result = functionDeclaration.apply(target, rawArgs); |
| 1225 } catch (e) { |
| 1226 result = null; |
| 1227 } |
| 1228 |
| 1229 callback(result); |
| 1230 } |
| 1070 }; | 1231 }; |
| 1071 | 1232 |
| 1072 WebInspector.LocalJSONObject.prototype = { | |
| 1073 /** | |
| 1074 * @override | |
| 1075 * @return {string} | |
| 1076 */ | |
| 1077 get description() | |
| 1078 { | |
| 1079 if (this._cachedDescription) | |
| 1080 return this._cachedDescription; | |
| 1081 | |
| 1082 /** | |
| 1083 * @param {!WebInspector.RemoteObjectProperty} property | |
| 1084 * @return {string} | |
| 1085 * @this {WebInspector.LocalJSONObject} | |
| 1086 */ | |
| 1087 function formatArrayItem(property) | |
| 1088 { | |
| 1089 return this._formatValue(property.value); | |
| 1090 } | |
| 1091 | |
| 1092 /** | |
| 1093 * @param {!WebInspector.RemoteObjectProperty} property | |
| 1094 * @return {string} | |
| 1095 * @this {WebInspector.LocalJSONObject} | |
| 1096 */ | |
| 1097 function formatObjectItem(property) | |
| 1098 { | |
| 1099 var name = property.name; | |
| 1100 if (/^\s|\s$|^$|\n/.test(name)) | |
| 1101 name = "\"" + name.replace(/\n/g, "\u21B5") + "\""; | |
| 1102 return name + ": " + this._formatValue(property.value); | |
| 1103 } | |
| 1104 | |
| 1105 if (this.type === "object") { | |
| 1106 switch (this.subtype) { | |
| 1107 case "array": | |
| 1108 this._cachedDescription = this._concatenate("[", "]", formatArra
yItem.bind(this)); | |
| 1109 break; | |
| 1110 case "date": | |
| 1111 this._cachedDescription = "" + this._value; | |
| 1112 break; | |
| 1113 case "null": | |
| 1114 this._cachedDescription = "null"; | |
| 1115 break; | |
| 1116 default: | |
| 1117 this._cachedDescription = this._concatenate("{", "}", formatObje
ctItem.bind(this)); | |
| 1118 } | |
| 1119 } else { | |
| 1120 this._cachedDescription = String(this._value); | |
| 1121 } | |
| 1122 | |
| 1123 return this._cachedDescription; | |
| 1124 }, | |
| 1125 | |
| 1126 /** | |
| 1127 * @param {?WebInspector.RemoteObject} value | |
| 1128 * @return {string} | |
| 1129 */ | |
| 1130 _formatValue: function(value) | |
| 1131 { | |
| 1132 if (!value) | |
| 1133 return "undefined"; | |
| 1134 var description = value.description || ""; | |
| 1135 if (value.type === "string") | |
| 1136 return "\"" + description.replace(/\n/g, "\u21B5") + "\""; | |
| 1137 return description; | |
| 1138 }, | |
| 1139 | |
| 1140 /** | |
| 1141 * @param {string} prefix | |
| 1142 * @param {string} suffix | |
| 1143 * @param {function(!WebInspector.RemoteObjectProperty)} formatProperty | |
| 1144 * @return {string} | |
| 1145 */ | |
| 1146 _concatenate: function(prefix, suffix, formatProperty) | |
| 1147 { | |
| 1148 var previewChars = 100; | |
| 1149 | |
| 1150 var buffer = prefix; | |
| 1151 var children = this._children(); | |
| 1152 for (var i = 0; i < children.length; ++i) { | |
| 1153 var itemDescription = formatProperty(children[i]); | |
| 1154 if (buffer.length + itemDescription.length > previewChars) { | |
| 1155 buffer += ",\u2026"; | |
| 1156 break; | |
| 1157 } | |
| 1158 if (i) | |
| 1159 buffer += ", "; | |
| 1160 buffer += itemDescription; | |
| 1161 } | |
| 1162 buffer += suffix; | |
| 1163 return buffer; | |
| 1164 }, | |
| 1165 | |
| 1166 /** | |
| 1167 * @override | |
| 1168 * @return {string} | |
| 1169 */ | |
| 1170 get type() | |
| 1171 { | |
| 1172 return typeof this._value; | |
| 1173 }, | |
| 1174 | |
| 1175 /** | |
| 1176 * @override | |
| 1177 * @return {string|undefined} | |
| 1178 */ | |
| 1179 get subtype() | |
| 1180 { | |
| 1181 if (this._value === null) | |
| 1182 return "null"; | |
| 1183 | |
| 1184 if (Array.isArray(this._value)) | |
| 1185 return "array"; | |
| 1186 | |
| 1187 if (this._value instanceof Date) | |
| 1188 return "date"; | |
| 1189 | |
| 1190 return undefined; | |
| 1191 }, | |
| 1192 | |
| 1193 /** | |
| 1194 * @override | |
| 1195 * @return {boolean} | |
| 1196 */ | |
| 1197 get hasChildren() | |
| 1198 { | |
| 1199 if ((typeof this._value !== "object") || (this._value === null)) | |
| 1200 return false; | |
| 1201 return !!Object.keys(/** @type {!Object} */ (this._value)).length; | |
| 1202 }, | |
| 1203 | |
| 1204 /** | |
| 1205 * @override | |
| 1206 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 1207 */ | |
| 1208 getOwnProperties: function(callback) | |
| 1209 { | |
| 1210 callback(this._children(), null); | |
| 1211 }, | |
| 1212 | |
| 1213 /** | |
| 1214 * @override | |
| 1215 * @param {boolean} accessorPropertiesOnly | |
| 1216 * @param {function(?Array.<!WebInspector.RemoteObjectProperty>, ?Array.<!We
bInspector.RemoteObjectProperty>)} callback | |
| 1217 */ | |
| 1218 getAllProperties: function(accessorPropertiesOnly, callback) | |
| 1219 { | |
| 1220 if (accessorPropertiesOnly) | |
| 1221 callback([], null); | |
| 1222 else | |
| 1223 callback(this._children(), null); | |
| 1224 }, | |
| 1225 | |
| 1226 /** | |
| 1227 * @return {!Array.<!WebInspector.RemoteObjectProperty>} | |
| 1228 */ | |
| 1229 _children: function() | |
| 1230 { | |
| 1231 if (!this.hasChildren) | |
| 1232 return []; | |
| 1233 var value = /** @type {!Object} */ (this._value); | |
| 1234 | |
| 1235 /** | |
| 1236 * @param {string} propName | |
| 1237 * @return {!WebInspector.RemoteObjectProperty} | |
| 1238 */ | |
| 1239 function buildProperty(propName) | |
| 1240 { | |
| 1241 var propValue = value[propName]; | |
| 1242 if (!(propValue instanceof WebInspector.RemoteObject)) | |
| 1243 propValue = WebInspector.RemoteObject.fromLocalObject(propValue)
; | |
| 1244 return new WebInspector.RemoteObjectProperty(propName, propValue); | |
| 1245 } | |
| 1246 if (!this._cachedChildren) | |
| 1247 this._cachedChildren = Object.keys(value).map(buildProperty); | |
| 1248 return this._cachedChildren; | |
| 1249 }, | |
| 1250 | |
| 1251 /** | |
| 1252 * @return {boolean} | |
| 1253 */ | |
| 1254 isError: function() | |
| 1255 { | |
| 1256 return false; | |
| 1257 }, | |
| 1258 | |
| 1259 /** | |
| 1260 * @override | |
| 1261 * @return {number} | |
| 1262 */ | |
| 1263 arrayLength: function() | |
| 1264 { | |
| 1265 return Array.isArray(this._value) ? this._value.length : 0; | |
| 1266 }, | |
| 1267 | |
| 1268 /** | |
| 1269 * @override | |
| 1270 * @param {function(this:Object, ...)} functionDeclaration | |
| 1271 * @param {!Array.<!RuntimeAgent.CallArgument>=} args | |
| 1272 * @param {function(?WebInspector.RemoteObject, boolean=)=} callback | |
| 1273 */ | |
| 1274 callFunction: function(functionDeclaration, args, callback) | |
| 1275 { | |
| 1276 var target = /** @type {?Object} */ (this._value); | |
| 1277 var rawArgs = args ? args.map(function(arg) { return arg.value; }) : []; | |
| 1278 | |
| 1279 var result; | |
| 1280 var wasThrown = false; | |
| 1281 try { | |
| 1282 result = functionDeclaration.apply(target, rawArgs); | |
| 1283 } catch (e) { | |
| 1284 wasThrown = true; | |
| 1285 } | |
| 1286 | |
| 1287 if (!callback) | |
| 1288 return; | |
| 1289 callback(WebInspector.RemoteObject.fromLocalObject(result), wasThrown); | |
| 1290 }, | |
| 1291 | |
| 1292 /** | |
| 1293 * @override | |
| 1294 * @param {function(this:Object)} functionDeclaration | |
| 1295 * @param {!Array.<!RuntimeAgent.CallArgument>|undefined} args | |
| 1296 * @param {function(*)} callback | |
| 1297 */ | |
| 1298 callFunctionJSON: function(functionDeclaration, args, callback) | |
| 1299 { | |
| 1300 var target = /** @type {?Object} */ (this._value); | |
| 1301 var rawArgs = args ? args.map(function(arg) { return arg.value; }) : []; | |
| 1302 | |
| 1303 var result; | |
| 1304 try { | |
| 1305 result = functionDeclaration.apply(target, rawArgs); | |
| 1306 } catch (e) { | |
| 1307 result = null; | |
| 1308 } | |
| 1309 | |
| 1310 callback(result); | |
| 1311 }, | |
| 1312 | |
| 1313 __proto__: WebInspector.RemoteObject.prototype | |
| 1314 }; | |
| 1315 | |
| 1316 /** | 1233 /** |
| 1317 * @constructor | 1234 * @unrestricted |
| 1318 * @param {!WebInspector.RemoteObject} object | |
| 1319 */ | 1235 */ |
| 1320 WebInspector.RemoteArray = function(object) | 1236 WebInspector.RemoteArray = class { |
| 1321 { | 1237 /** |
| 1238 * @param {!WebInspector.RemoteObject} object |
| 1239 */ |
| 1240 constructor(object) { |
| 1322 this._object = object; | 1241 this._object = object; |
| 1323 }; | 1242 } |
| 1324 | 1243 |
| 1325 /** | 1244 /** |
| 1326 * @param {?WebInspector.RemoteObject} object | 1245 * @param {?WebInspector.RemoteObject} object |
| 1327 * @return {!WebInspector.RemoteArray} | 1246 * @return {!WebInspector.RemoteArray} |
| 1328 */ | 1247 */ |
| 1329 WebInspector.RemoteArray.objectAsArray = function(object) | 1248 static objectAsArray(object) { |
| 1330 { | 1249 if (!object || object.type !== 'object' || (object.subtype !== 'array' && ob
ject.subtype !== 'typedarray')) |
| 1331 if (!object || object.type !== "object" || (object.subtype !== "array" && ob
ject.subtype !== "typedarray")) | 1250 throw new Error('Object is empty or not an array'); |
| 1332 throw new Error("Object is empty or not an array"); | |
| 1333 return new WebInspector.RemoteArray(object); | 1251 return new WebInspector.RemoteArray(object); |
| 1334 }; | 1252 } |
| 1335 | 1253 |
| 1336 /** | 1254 /** |
| 1337 * @param {!Array<!WebInspector.RemoteObject>} objects | 1255 * @param {!Array<!WebInspector.RemoteObject>} objects |
| 1338 * @return {!Promise<!WebInspector.RemoteArray>} | 1256 * @return {!Promise<!WebInspector.RemoteArray>} |
| 1339 */ | 1257 */ |
| 1340 WebInspector.RemoteArray.createFromRemoteObjects = function(objects) | 1258 static createFromRemoteObjects(objects) { |
| 1341 { | |
| 1342 if (!objects.length) | 1259 if (!objects.length) |
| 1343 throw new Error("Input array is empty"); | 1260 throw new Error('Input array is empty'); |
| 1344 var objectArguments = []; | 1261 var objectArguments = []; |
| 1345 for (var i = 0; i < objects.length; ++i) | 1262 for (var i = 0; i < objects.length; ++i) |
| 1346 objectArguments.push(WebInspector.RemoteObject.toCallArgument(objects[i]
)); | 1263 objectArguments.push(WebInspector.RemoteObject.toCallArgument(objects[i]))
; |
| 1347 return objects[0].callFunctionPromise(createArray, objectArguments).then(ret
urnRemoteArray); | 1264 return objects[0].callFunctionPromise(createArray, objectArguments).then(ret
urnRemoteArray); |
| 1348 | 1265 |
| 1349 /** | 1266 /** |
| 1350 * @return {!Array<*>} | 1267 * @return {!Array<*>} |
| 1351 */ | 1268 */ |
| 1352 function createArray() | 1269 function createArray() { |
| 1353 { | 1270 if (arguments.length > 1) |
| 1354 if (arguments.length > 1) | 1271 return new Array(arguments); |
| 1355 return new Array(arguments); | 1272 return [arguments[0]]; |
| 1356 return [arguments[0]]; | |
| 1357 } | 1273 } |
| 1358 | 1274 |
| 1359 /** | 1275 /** |
| 1360 * @param {!WebInspector.CallFunctionResult} result | 1276 * @param {!WebInspector.CallFunctionResult} result |
| 1361 * @return {!WebInspector.RemoteArray} | 1277 * @return {!WebInspector.RemoteArray} |
| 1362 */ | 1278 */ |
| 1363 function returnRemoteArray(result) | 1279 function returnRemoteArray(result) { |
| 1364 { | 1280 if (result.wasThrown || !result.object) |
| 1365 if (result.wasThrown || !result.object) | 1281 throw new Error('Call function throws exceptions or returns empty value'
); |
| 1366 throw new Error("Call function throws exceptions or returns empty va
lue"); | 1282 return WebInspector.RemoteArray.objectAsArray(result.object); |
| 1367 return WebInspector.RemoteArray.objectAsArray(result.object); | 1283 } |
| 1368 } | 1284 } |
| 1285 |
| 1286 /** |
| 1287 * @param {number} index |
| 1288 * @return {!Promise<!WebInspector.RemoteObject>} |
| 1289 */ |
| 1290 at(index) { |
| 1291 if (index < 0 || index > this._object.arrayLength()) |
| 1292 throw new Error('Out of range'); |
| 1293 return this._object.callFunctionPromise(at, [WebInspector.RemoteObject.toCal
lArgument(index)]) |
| 1294 .then(assertCallFunctionResult); |
| 1295 |
| 1296 /** |
| 1297 * @suppressReceiverCheck |
| 1298 * @param {number} index |
| 1299 * @return {*} |
| 1300 * @this {!Object} |
| 1301 */ |
| 1302 function at(index) { |
| 1303 return this[index]; |
| 1304 } |
| 1305 |
| 1306 /** |
| 1307 * @param {!WebInspector.CallFunctionResult} result |
| 1308 * @return {!WebInspector.RemoteObject} |
| 1309 */ |
| 1310 function assertCallFunctionResult(result) { |
| 1311 if (result.wasThrown || !result.object) |
| 1312 throw new Error('Exception in callFunction or result value is empty'); |
| 1313 return result.object; |
| 1314 } |
| 1315 } |
| 1316 |
| 1317 /** |
| 1318 * @return {number} |
| 1319 */ |
| 1320 length() { |
| 1321 return this._object.arrayLength(); |
| 1322 } |
| 1323 |
| 1324 /** |
| 1325 * @param {function(!WebInspector.RemoteObject):!Promise<T>} func |
| 1326 * @return {!Promise<!Array<T>>} |
| 1327 * @template T |
| 1328 */ |
| 1329 map(func) { |
| 1330 var promises = []; |
| 1331 for (var i = 0; i < this.length(); ++i) |
| 1332 promises.push(this.at(i).then(func)); |
| 1333 return Promise.all(promises); |
| 1334 } |
| 1335 |
| 1336 /** |
| 1337 * @return {!WebInspector.RemoteObject} |
| 1338 */ |
| 1339 object() { |
| 1340 return this._object; |
| 1341 } |
| 1369 }; | 1342 }; |
| 1370 | 1343 |
| 1371 WebInspector.RemoteArray.prototype = { | 1344 |
| 1372 /** | 1345 /** |
| 1373 * @param {number} index | 1346 * @unrestricted |
| 1374 * @return {!Promise<!WebInspector.RemoteObject>} | 1347 */ |
| 1375 */ | 1348 WebInspector.RemoteFunction = class { |
| 1376 at: function(index) | 1349 /** |
| 1377 { | 1350 * @param {!WebInspector.RemoteObject} object |
| 1378 if (index < 0 || index > this._object.arrayLength()) | 1351 */ |
| 1379 throw new Error("Out of range"); | 1352 constructor(object) { |
| 1380 return this._object.callFunctionPromise(at, [WebInspector.RemoteObject.t
oCallArgument(index)]).then(assertCallFunctionResult); | 1353 this._object = object; |
| 1381 | 1354 } |
| 1382 /** | 1355 |
| 1383 * @suppressReceiverCheck | 1356 /** |
| 1384 * @param {number} index | 1357 * @param {?WebInspector.RemoteObject} object |
| 1385 * @return {*} | 1358 * @return {!WebInspector.RemoteFunction} |
| 1386 * @this {!Object} | 1359 */ |
| 1387 */ | 1360 static objectAsFunction(object) { |
| 1388 function at(index) | 1361 if (!object || object.type !== 'function') |
| 1389 { | 1362 throw new Error('Object is empty or not a function'); |
| 1390 return this[index]; | 1363 return new WebInspector.RemoteFunction(object); |
| 1391 } | 1364 } |
| 1392 | 1365 |
| 1393 /** | 1366 /** |
| 1394 * @param {!WebInspector.CallFunctionResult} result | 1367 * @return {!Promise<!WebInspector.RemoteObject>} |
| 1395 * @return {!WebInspector.RemoteObject} | 1368 */ |
| 1396 */ | 1369 targetFunction() { |
| 1397 function assertCallFunctionResult(result) | 1370 return this._object.getOwnPropertiesPromise().then(targetFunction.bind(this)
); |
| 1398 { | 1371 |
| 1399 if (result.wasThrown || !result.object) | 1372 /** |
| 1400 throw new Error("Exception in callFunction or result value is em
pty"); | 1373 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, interna
lProperties: ?Array<!WebInspector.RemoteObjectProperty>}} ownProperties |
| 1401 return result.object; | |
| 1402 } | |
| 1403 }, | |
| 1404 | |
| 1405 /** | |
| 1406 * @return {number} | |
| 1407 */ | |
| 1408 length: function() | |
| 1409 { | |
| 1410 return this._object.arrayLength(); | |
| 1411 }, | |
| 1412 | |
| 1413 /** | |
| 1414 * @param {function(!WebInspector.RemoteObject):!Promise<T>} func | |
| 1415 * @return {!Promise<!Array<T>>} | |
| 1416 * @template T | |
| 1417 */ | |
| 1418 map: function(func) | |
| 1419 { | |
| 1420 var promises = []; | |
| 1421 for (var i = 0; i < this.length(); ++i) | |
| 1422 promises.push(this.at(i).then(func)); | |
| 1423 return Promise.all(promises); | |
| 1424 }, | |
| 1425 | |
| 1426 /** | |
| 1427 * @return {!WebInspector.RemoteObject} | 1374 * @return {!WebInspector.RemoteObject} |
| 1428 */ | 1375 * @this {WebInspector.RemoteFunction} |
| 1429 object: function() | 1376 */ |
| 1430 { | 1377 function targetFunction(ownProperties) { |
| 1378 if (!ownProperties.internalProperties) |
| 1431 return this._object; | 1379 return this._object; |
| 1432 } | 1380 var internalProperties = ownProperties.internalProperties; |
| 1381 for (var property of internalProperties) { |
| 1382 if (property.name === '[[TargetFunction]]') |
| 1383 return property.value; |
| 1384 } |
| 1385 return this._object; |
| 1386 } |
| 1387 } |
| 1388 |
| 1389 /** |
| 1390 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>} |
| 1391 */ |
| 1392 targetFunctionDetails() { |
| 1393 return this.targetFunction().then(functionDetails.bind(this)); |
| 1394 |
| 1395 /** |
| 1396 * @param {!WebInspector.RemoteObject} targetFunction |
| 1397 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>} |
| 1398 * @this {WebInspector.RemoteFunction} |
| 1399 */ |
| 1400 function functionDetails(targetFunction) { |
| 1401 var boundReleaseFunctionDetails = |
| 1402 releaseTargetFunction.bind(null, this._object !== targetFunction ? tar
getFunction : null); |
| 1403 return targetFunction.debuggerModel().functionDetailsPromise(targetFunctio
n).then(boundReleaseFunctionDetails); |
| 1404 } |
| 1405 |
| 1406 /** |
| 1407 * @param {?WebInspector.RemoteObject} targetFunction |
| 1408 * @param {?WebInspector.DebuggerModel.FunctionDetails} functionDetails |
| 1409 * @return {?WebInspector.DebuggerModel.FunctionDetails} |
| 1410 */ |
| 1411 function releaseTargetFunction(targetFunction, functionDetails) { |
| 1412 if (targetFunction) |
| 1413 targetFunction.release(); |
| 1414 return functionDetails; |
| 1415 } |
| 1416 } |
| 1417 |
| 1418 /** |
| 1419 * @return {!WebInspector.RemoteObject} |
| 1420 */ |
| 1421 object() { |
| 1422 return this._object; |
| 1423 } |
| 1433 }; | 1424 }; |
| 1434 | 1425 |
| 1435 /** | 1426 |
| 1436 * @constructor | |
| 1437 * @param {!WebInspector.RemoteObject} object | |
| 1438 */ | |
| 1439 WebInspector.RemoteFunction = function(object) | |
| 1440 { | |
| 1441 this._object = object; | |
| 1442 }; | |
| 1443 | |
| 1444 /** | |
| 1445 * @param {?WebInspector.RemoteObject} object | |
| 1446 * @return {!WebInspector.RemoteFunction} | |
| 1447 */ | |
| 1448 WebInspector.RemoteFunction.objectAsFunction = function(object) | |
| 1449 { | |
| 1450 if (!object || object.type !== "function") | |
| 1451 throw new Error("Object is empty or not a function"); | |
| 1452 return new WebInspector.RemoteFunction(object); | |
| 1453 }; | |
| 1454 | |
| 1455 WebInspector.RemoteFunction.prototype = { | |
| 1456 /** | |
| 1457 * @return {!Promise<!WebInspector.RemoteObject>} | |
| 1458 */ | |
| 1459 targetFunction: function() | |
| 1460 { | |
| 1461 return this._object.getOwnPropertiesPromise().then(targetFunction.bind(t
his)); | |
| 1462 | |
| 1463 /** | |
| 1464 * @param {!{properties: ?Array<!WebInspector.RemoteObjectProperty>, int
ernalProperties: ?Array<!WebInspector.RemoteObjectProperty>}} ownProperties | |
| 1465 * @return {!WebInspector.RemoteObject} | |
| 1466 * @this {WebInspector.RemoteFunction} | |
| 1467 */ | |
| 1468 function targetFunction(ownProperties) | |
| 1469 { | |
| 1470 if (!ownProperties.internalProperties) | |
| 1471 return this._object; | |
| 1472 var internalProperties = ownProperties.internalProperties; | |
| 1473 for (var property of internalProperties) { | |
| 1474 if (property.name === "[[TargetFunction]]") | |
| 1475 return property.value; | |
| 1476 } | |
| 1477 return this._object; | |
| 1478 } | |
| 1479 }, | |
| 1480 | |
| 1481 /** | |
| 1482 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>} | |
| 1483 */ | |
| 1484 targetFunctionDetails: function() | |
| 1485 { | |
| 1486 return this.targetFunction().then(functionDetails.bind(this)); | |
| 1487 | |
| 1488 /** | |
| 1489 * @param {!WebInspector.RemoteObject} targetFunction | |
| 1490 * @return {!Promise<?WebInspector.DebuggerModel.FunctionDetails>} | |
| 1491 * @this {WebInspector.RemoteFunction} | |
| 1492 */ | |
| 1493 function functionDetails(targetFunction) | |
| 1494 { | |
| 1495 var boundReleaseFunctionDetails = releaseTargetFunction.bind(null, t
his._object !== targetFunction ? targetFunction : null); | |
| 1496 return targetFunction.debuggerModel().functionDetailsPromise(targetF
unction).then(boundReleaseFunctionDetails); | |
| 1497 } | |
| 1498 | |
| 1499 /** | |
| 1500 * @param {?WebInspector.RemoteObject} targetFunction | |
| 1501 * @param {?WebInspector.DebuggerModel.FunctionDetails} functionDetails | |
| 1502 * @return {?WebInspector.DebuggerModel.FunctionDetails} | |
| 1503 */ | |
| 1504 function releaseTargetFunction(targetFunction, functionDetails) | |
| 1505 { | |
| 1506 if (targetFunction) | |
| 1507 targetFunction.release(); | |
| 1508 return functionDetails; | |
| 1509 } | |
| 1510 }, | |
| 1511 | |
| 1512 /** | |
| 1513 * @return {!WebInspector.RemoteObject} | |
| 1514 */ | |
| 1515 object: function() | |
| 1516 { | |
| 1517 return this._object; | |
| 1518 } | |
| 1519 }; | |
| OLD | NEW |