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 |