OLD | NEW |
---|---|
1 /* | 1 /* |
2 * Copyright (C) 2007 Apple Inc. All rights reserved. | 2 * Copyright (C) 2007 Apple Inc. All rights reserved. |
3 * Copyright (C) 2013 Google Inc. All rights reserved. | 3 * Copyright (C) 2013 Google Inc. All rights reserved. |
4 * | 4 * |
5 * Redistribution and use in source and binary forms, with or without | 5 * Redistribution and use in source and binary forms, with or without |
6 * modification, are permitted provided that the following conditions | 6 * modification, are permitted provided that the following conditions |
7 * are met: | 7 * are met: |
8 * | 8 * |
9 * 1. Redistributions of source code must retain the above copyright | 9 * 1. Redistributions of source code must retain the above copyright |
10 * notice, this list of conditions and the following disclaimer. | 10 * notice, this list of conditions and the following disclaimer. |
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
328 getProperties: function(object, objectGroupName, ownProperties, accessorProp ertiesOnly, generatePreview) | 328 getProperties: function(object, objectGroupName, ownProperties, accessorProp ertiesOnly, generatePreview) |
329 { | 329 { |
330 var subtype = this._subtype(object); | 330 var subtype = this._subtype(object); |
331 if (subtype === "internal#scope") { | 331 if (subtype === "internal#scope") { |
332 // Internally, scope contains object with scope variables and additi onal information like type, | 332 // Internally, scope contains object with scope variables and additi onal information like type, |
333 // we use additional information for preview and would like to repor t variables as scope | 333 // we use additional information for preview and would like to repor t variables as scope |
334 // properties. | 334 // properties. |
335 object = object.object; | 335 object = object.object; |
336 } | 336 } |
337 | 337 |
338 var descriptors = []; | |
339 var iter = this._propertyDescriptors(object, ownProperties, accessorProp ertiesOnly, undefined); | |
340 // Go over properties, wrap object values. | 338 // Go over properties, wrap object values. |
341 for (var descriptor of iter) { | 339 var descriptors = this._propertyDescriptors(object, ownProperties, acces sorPropertiesOnly, undefined, false); |
342 if (subtype === "internal#scopeList" && descriptor.name === "length" ) | 340 for (var i = 0; i < descriptors.length; ++i) { |
343 continue; | 341 var descriptor = descriptors[i]; |
344 if ("get" in descriptor) | 342 if ("get" in descriptor) |
345 descriptor.get = this._wrapObject(descriptor.get, objectGroupNam e); | 343 descriptor.get = this._wrapObject(descriptor.get, objectGroupNam e); |
346 if ("set" in descriptor) | 344 if ("set" in descriptor) |
347 descriptor.set = this._wrapObject(descriptor.set, objectGroupNam e); | 345 descriptor.set = this._wrapObject(descriptor.set, objectGroupNam e); |
348 if ("value" in descriptor) | 346 if ("value" in descriptor) |
349 descriptor.value = this._wrapObject(descriptor.value, objectGrou pName, false, generatePreview); | 347 descriptor.value = this._wrapObject(descriptor.value, objectGrou pName, false, generatePreview); |
350 if (!("configurable" in descriptor)) | 348 if (!("configurable" in descriptor)) |
351 descriptor.configurable = false; | 349 descriptor.configurable = false; |
352 if (!("enumerable" in descriptor)) | 350 if (!("enumerable" in descriptor)) |
353 descriptor.enumerable = false; | 351 descriptor.enumerable = false; |
354 if ("symbol" in descriptor) | 352 if ("symbol" in descriptor) |
355 descriptor.symbol = this._wrapObject(descriptor.symbol, objectGr oupName); | 353 descriptor.symbol = this._wrapObject(descriptor.symbol, objectGr oupName); |
356 push(descriptors, descriptor); | |
357 } | 354 } |
358 return descriptors; | 355 return descriptors; |
359 }, | 356 }, |
360 | 357 |
361 /** | 358 /** |
362 * @param {!Object} object | 359 * @param {!Object} object |
363 * @return {?Object} | 360 * @return {?Object} |
364 */ | 361 */ |
365 _objectPrototype: function(object) | 362 _objectPrototype: function(object) |
366 { | 363 { |
367 if (InjectedScriptHost.subtype(object) === "proxy") | 364 if (InjectedScriptHost.subtype(object) === "proxy") |
368 return null; | 365 return null; |
369 try { | 366 try { |
370 return Object.getPrototypeOf(object); | 367 return Object.getPrototypeOf(object); |
371 } catch (e) { | 368 } catch (e) { |
372 return null; | 369 return null; |
373 } | 370 } |
374 }, | 371 }, |
375 | 372 |
376 /** | 373 /** |
377 * @param {!Object} object | 374 * @param {!Object} object |
378 * @param {boolean=} ownProperties | 375 * @param {boolean=} ownProperties |
379 * @param {boolean=} accessorPropertiesOnly | 376 * @param {boolean=} accessorPropertiesOnly |
380 * @param {?Array.<string>=} propertyNamesOnly | 377 * @param {?Array<string>=} propertyNamesOnly |
378 * @param {boolean=} forPreview | |
379 * @param {!function(!Array<!Object>, !Object)=} addPropertyIfNeeded | |
380 * @return {!Array<!Object>} | |
381 */ | 381 */ |
382 _propertyDescriptors: function*(object, ownProperties, accessorPropertiesOnl y, propertyNamesOnly) | 382 _propertyDescriptors: function(object, ownProperties, accessorPropertiesOnly , propertyNamesOnly, forPreview, addPropertyIfNeeded) |
383 { | 383 { |
384 var descriptors = []; | |
385 descriptors.__proto__ = null; | |
386 addPropertyIfNeeded = addPropertyIfNeeded || function(descriptors, descr iptor) { push(descriptors, descriptor); return true; }; | |
384 var propertyProcessed = { __proto__: null }; | 387 var propertyProcessed = { __proto__: null }; |
388 var subtype = InjectedScriptHost.subtype(object); | |
385 | 389 |
386 /** | 390 /** |
387 * @param {?Object} o | 391 * @param {!Object} o |
388 * @param {!Iterable<string|symbol|number>|!Array<string|number|symbol>} properties | 392 * @param {!Array<string|number|symbol>=} properties |
393 * @param {number=} objectLength | |
394 * @return {boolean} | |
389 */ | 395 */ |
390 function* process(o, properties) | 396 function process(o, properties, objectLength) |
391 { | 397 { |
392 for (var property of properties) { | 398 // When properties is not provided, iterate over the object's indice s. |
399 var length = properties ? properties.length : objectLength; | |
400 for (var i = 0; i < length; ++i) { | |
401 var property = properties ? properties[i] : ("" + i); | |
402 if (propertyProcessed[property]) | |
403 continue; | |
404 propertyProcessed[property] = true; | |
393 var name; | 405 var name; |
394 if (isSymbol(property)) | 406 if (isSymbol(property)) |
395 name = /** @type {string} */ (injectedScript._describe(prope rty)); | 407 name = /** @type {string} */ (injectedScript._describe(prope rty)); |
396 else | 408 else |
397 name = typeof property === "number" ? ("" + property) : /** @type {string} */(property); | 409 name = typeof property === "number" ? ("" + property) : /** @type {string} */(property); |
398 | 410 |
399 if (propertyProcessed[property]) | 411 if (subtype === "internal#scopeList" && name === "length") |
400 continue; | 412 continue; |
401 | 413 |
414 var descriptor; | |
402 try { | 415 try { |
403 propertyProcessed[property] = true; | 416 descriptor = Object.getOwnPropertyDescriptor(o, property); |
404 var descriptor = nullifyObjectProto(Object.getOwnPropertyDes criptor(o, property)); | 417 var isAccessorProperty = descriptor && ("get" in descriptor || "set" in descriptor); |
405 if (descriptor) { | 418 if (accessorPropertiesOnly && !isAccessorProperty) |
406 if (accessorPropertiesOnly && !("get" in descriptor || " set" in descriptor)) | 419 continue; |
407 continue; | 420 if (descriptor && "get" in descriptor && "set" in descriptor && name !== "__proto__" && |
408 if ("get" in descriptor && "set" in descriptor && name ! = "__proto__" && InjectedScriptHost.formatAccessorsAsProperties(object, descript or.get) && !doesAttributeHaveObservableSideEffectOnGet(object, name)) { | 421 InjectedScriptHost.formatAccessorsAsProperties(objec t, descriptor.get) && |
409 descriptor.value = object[property]; | 422 !doesAttributeHaveObservableSideEffectOnGet(object, name)) { |
410 descriptor.isOwn = true; | 423 descriptor.value = object[property]; |
411 delete descriptor.get; | 424 descriptor.isOwn = true; |
412 delete descriptor.set; | 425 delete descriptor.get; |
413 } | 426 delete descriptor.set; |
414 } else { | 427 } |
415 // Not all bindings provide proper descriptors. Fall bac k to the writable, configurable property. | 428 } catch (e) { |
416 if (accessorPropertiesOnly) | 429 if (accessorPropertiesOnly || forPreview) |
kozy
2017/02/28 17:14:43
Can we filter it inside of addPropertyIfNeeded by
luoe
2017/02/28 21:46:39
Done.
| |
417 continue; | 430 continue; |
418 try { | 431 descriptor = { value: e, wasThrown: true }; |
419 descriptor = { name: name, value: o[property], writa ble: false, configurable: false, enumerable: false, __proto__: null }; | 432 } |
420 if (o === object) | 433 |
421 descriptor.isOwn = true; | 434 // Not all bindings provide proper descriptors. Fall back to the non-configurable, non-enumerable, |
422 yield descriptor; | 435 // non-writable property. |
423 } catch (e) { | 436 if (!descriptor) { |
424 // Silent catch. | 437 try { |
425 } | 438 descriptor = { value: o[property], writable: false }; |
439 } catch (e) { | |
440 // Silent catch. | |
426 continue; | 441 continue; |
427 } | 442 } |
428 } catch (e) { | |
429 if (accessorPropertiesOnly) | |
430 continue; | |
431 var descriptor = { __proto__: null }; | |
432 descriptor.value = e; | |
433 descriptor.wasThrown = true; | |
434 } | 443 } |
435 | 444 |
436 descriptor.name = name; | 445 descriptor.name = name; |
437 if (o === object) | 446 if (o === object) |
438 descriptor.isOwn = true; | 447 descriptor.isOwn = true; |
439 if (isSymbol(property)) | 448 if (isSymbol(property)) |
440 descriptor.symbol = property; | 449 descriptor.symbol = property; |
441 yield descriptor; | 450 if (forPreview) { |
451 // Ignore __proto__ property. | |
kozy
2017/02/28 17:14:43
Can we move this into addPropertyIfNeeded for prev
luoe
2017/02/28 21:46:38
Done.
| |
452 if (name === "__proto__") | |
453 continue; | |
454 | |
455 // Ignore length property of array. | |
456 if ((subtype === "array" || subtype === "typedarray") && nam e === "length") | |
457 continue; | |
458 | |
459 // Ignore size property of map, set. | |
460 if ((subtype === "map" || subtype === "set") && name === "si ze") | |
461 continue; | |
462 | |
463 // Never preview prototype properties. | |
464 if (!descriptor.isOwn) | |
465 continue; | |
466 | |
467 // Ignore computed properties unless they have getters. | |
468 if (!("value" in descriptor) && !descriptor.get) | |
469 continue; | |
470 } | |
471 descriptor = nullifyObjectProto(descriptor); | |
472 if (!addPropertyIfNeeded(descriptors, descriptor)) | |
473 return false; | |
442 } | 474 } |
475 return true; | |
443 } | 476 } |
444 | 477 |
445 if (propertyNamesOnly) { | 478 if (propertyNamesOnly) { |
446 for (var i = 0; i < propertyNamesOnly.length; ++i) { | 479 for (var i = 0; i < propertyNamesOnly.length; ++i) { |
447 var name = propertyNamesOnly[i]; | 480 var name = propertyNamesOnly[i]; |
448 for (var o = object; this._isDefined(o); o = this._objectPrototy pe(o)) { | 481 for (var o = object; this._isDefined(o); o = this._objectPrototy pe(/** @type {!Object} */ (o))) { |
482 o = /** @type {!Object} */ (o); | |
449 if (InjectedScriptHost.objectHasOwnProperty(o, name)) { | 483 if (InjectedScriptHost.objectHasOwnProperty(o, name)) { |
450 for (var descriptor of process(o, [name])) | 484 if (!process(o, [name])) |
451 yield descriptor; | 485 return descriptors; |
452 break; | 486 break; |
453 } | 487 } |
454 if (ownProperties) | 488 if (ownProperties || forPreview) |
kozy
2017/02/28 17:14:43
can we pass ownProperties = true for preview and w
luoe
2017/02/28 21:46:38
Done.
| |
455 break; | 489 break; |
456 } | 490 } |
457 } | 491 } |
458 return; | 492 return descriptors; |
459 } | 493 } |
460 | 494 |
461 /** | 495 for (var o = object; this._isDefined(o); o = this._objectPrototype(/** @ type {!Object} */ (o))) { |
462 * @param {number} length | 496 o = /** @type {!Object} */ (o); |
463 */ | |
464 function* arrayIndexNames(length) | |
465 { | |
466 for (var i = 0; i < length; ++i) | |
467 yield "" + i; | |
468 } | |
469 | |
470 var skipGetOwnPropertyNames; | |
471 try { | |
472 skipGetOwnPropertyNames = InjectedScriptHost.subtype(object) === "ty pedarray" && object.length > 500000; | |
473 } catch (e) { | |
474 } | |
475 | |
476 for (var o = object; this._isDefined(o); o = this._objectPrototype(o)) { | |
477 if (InjectedScriptHost.subtype(o) === "proxy") | 497 if (InjectedScriptHost.subtype(o) === "proxy") |
478 continue; | 498 continue; |
479 if (skipGetOwnPropertyNames && o === object) { | 499 |
480 // Avoid OOM crashes from getting all own property names of a la rge TypedArray. | 500 try { |
481 for (var descriptor of process(o, arrayIndexNames(o.length))) | 501 var objectLength = o.length; |
482 yield descriptor; | 502 var skipGetOwnPropertyNames = subtype === "typedarray" && object Length > 500000; |
483 } else { | 503 if (skipGetOwnPropertyNames && o === object) { |
484 // First call Object.keys() to enforce ordering of the property descriptors. | 504 if (!process(o, undefined, objectLength)) |
485 for (var descriptor of process(o, Object.keys(/** @type {!Object } */ (o)))) | 505 return descriptors; |
486 yield descriptor; | 506 } else { |
487 for (var descriptor of process(o, Object.getOwnPropertyNames(/** @type {!Object} */ (o)))) | 507 // First call Object.keys() to enforce ordering of the prope rty descriptors. |
488 yield descriptor; | 508 if (!process(o, Object.keys(o))) |
509 return descriptors; | |
510 if (!process(o, Object.getOwnPropertyNames(o))) | |
511 return descriptors; | |
512 } | |
513 if (Object.getOwnPropertySymbols) { | |
514 if (!process(o, Object.getOwnPropertySymbols(o))) | |
515 return descriptors; | |
516 } | |
517 if (ownProperties) { | |
518 var proto = this._objectPrototype(o); | |
519 if (proto && !accessorPropertiesOnly) { | |
520 var descriptor = { name: "__proto__", value: proto, writ able: true, configurable: true, enumerable: false, isOwn: true, __proto__: null }; | |
521 if (!addPropertyIfNeeded(descriptors, descriptor)) | |
522 return descriptors; | |
523 } | |
524 } | |
525 } catch (e) { | |
489 } | 526 } |
490 if (Object.getOwnPropertySymbols) { | 527 |
491 for (var descriptor of process(o, Object.getOwnPropertySymbols(/ ** @type {!Object} */ (o)))) | 528 if (ownProperties || forPreview) |
492 yield descriptor; | |
493 } | |
494 if (ownProperties) { | |
495 var proto = this._objectPrototype(o); | |
496 if (proto && !accessorPropertiesOnly) | |
497 yield { name: "__proto__", value: proto, writable: true, con figurable: true, enumerable: false, isOwn: true, __proto__: null }; | |
498 break; | 529 break; |
499 } | |
500 } | 530 } |
531 return descriptors; | |
501 }, | 532 }, |
502 | 533 |
503 /** | 534 /** |
504 * @param {string|undefined} objectGroupName | 535 * @param {string|undefined} objectGroupName |
505 * @param {*} jsonMLObject | 536 * @param {*} jsonMLObject |
506 * @throws {string} error message | 537 * @throws {string} error message |
507 */ | 538 */ |
508 _substituteObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject ) | 539 _substituteObjectTagsInCustomPreview: function(objectGroupName, jsonMLObject ) |
509 { | 540 { |
510 var maxCustomPreviewRecursionDepth = 20; | 541 var maxCustomPreviewRecursionDepth = 20; |
(...skipping 345 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
856 * @param {?Array.<string>=} firstLevelKeys | 887 * @param {?Array.<string>=} firstLevelKeys |
857 * @param {?Array.<string>=} secondLevelKeys | 888 * @param {?Array.<string>=} secondLevelKeys |
858 * @param {boolean=} isTable | 889 * @param {boolean=} isTable |
859 * @param {boolean=} skipEntriesPreview | 890 * @param {boolean=} skipEntriesPreview |
860 * @return {!RuntimeAgent.ObjectPreview} preview | 891 * @return {!RuntimeAgent.ObjectPreview} preview |
861 */ | 892 */ |
862 _generatePreview: function(object, firstLevelKeys, secondLevelKeys, isTable, skipEntriesPreview) | 893 _generatePreview: function(object, firstLevelKeys, secondLevelKeys, isTable, skipEntriesPreview) |
863 { | 894 { |
864 var preview = this._createEmptyPreview(); | 895 var preview = this._createEmptyPreview(); |
865 var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0; | 896 var firstLevelKeysCount = firstLevelKeys ? firstLevelKeys.length : 0; |
866 | 897 var overflow = false; |
867 var propertiesThreshold = { | 898 var propertiesThreshold = { |
868 properties: isTable ? 1000 : max(5, firstLevelKeysCount), | 899 properties: isTable ? 1000 : max(5, firstLevelKeysCount), |
869 indexes: isTable ? 1000 : max(100, firstLevelKeysCount), | 900 indexes: isTable ? 1000 : max(100, firstLevelKeysCount), |
870 __proto__: null | 901 __proto__: null |
871 }; | 902 }; |
872 | 903 |
873 try { | 904 try { |
874 var descriptors = injectedScript._propertyDescriptors(object, undefi ned, undefined, firstLevelKeys); | 905 var descriptors = injectedScript._propertyDescriptors(object, undefi ned, undefined, firstLevelKeys, true, addPropertyIfNeeded); |
kozy
2017/02/28 17:14:43
please add /* propertyNamesOnly */ comment for und
luoe
2017/02/28 21:46:39
added comment for accessorPropertiesOnly here
and
| |
875 | |
876 this._appendPropertyDescriptors(preview, descriptors, propertiesThre shold, secondLevelKeys, isTable); | |
877 if (propertiesThreshold.indexes < 0 || propertiesThreshold.propertie s < 0) | |
878 return preview; | |
879 | 906 |
880 // Add internal properties to preview. | 907 // Add internal properties to preview. |
881 var rawInternalProperties = InjectedScriptHost.getInternalProperties (object) || []; | 908 var rawInternalProperties = InjectedScriptHost.getInternalProperties (object) || []; |
882 var internalProperties = []; | 909 var internalProperties = []; |
883 var entries = null; | 910 var entries = null; |
884 for (var i = 0; i < rawInternalProperties.length; i += 2) { | 911 for (var i = 0; i < rawInternalProperties.length; i += 2) { |
885 if (rawInternalProperties[i] === "[[Entries]]") { | 912 if (rawInternalProperties[i] === "[[Entries]]") { |
886 entries = /** @type {!Array<*>} */(rawInternalProperties[i + 1]); | 913 entries = /** @type {!Array<*>} */(rawInternalProperties[i + 1]); |
887 continue; | 914 continue; |
888 } | 915 } |
889 push(internalProperties, { | 916 var internalPropertyDescriptor = { |
890 name: rawInternalProperties[i], | 917 name: rawInternalProperties[i], |
891 value: rawInternalProperties[i + 1], | 918 value: rawInternalProperties[i + 1], |
892 isOwn: true, | 919 isOwn: true, |
893 enumerable: true, | 920 enumerable: true, |
894 __proto__: null | 921 __proto__: null |
895 }); | 922 }; |
923 if (!addPropertyIfNeeded(descriptors, internalPropertyDescriptor )) | |
924 break; | |
896 } | 925 } |
897 this._appendPropertyDescriptors(preview, internalProperties, propert iesThreshold, secondLevelKeys, isTable); | 926 this._appendPropertyPreviewDescriptors(preview, descriptors, secondL evelKeys, isTable); |
898 | 927 |
899 if (this.subtype === "map" || this.subtype === "set" || this.subtype === "iterator") | 928 if (this.subtype === "map" || this.subtype === "set" || this.subtype === "iterator") |
900 this._appendEntriesPreview(entries, preview, skipEntriesPreview) ; | 929 this._appendEntriesPreview(entries, preview, skipEntriesPreview) ; |
901 | 930 |
902 } catch (e) {} | 931 } catch (e) {} |
932 preview.overflow = preview.overflow || overflow; | |
903 | 933 |
904 return preview; | 934 return preview; |
935 | |
936 /** | |
937 * @param {!Array<!Object>} descriptors | |
938 * @param {!Object} descriptor | |
939 * @return {boolean} | |
940 */ | |
941 function addPropertyIfNeeded(descriptors, descriptor) { | |
942 if (toString(descriptor.name >>> 0) === descriptor.name) | |
943 propertiesThreshold.indexes--; | |
944 else | |
945 propertiesThreshold.properties--; | |
946 | |
947 var canContinue = propertiesThreshold.indexes >= 0 && propertiesThre shold.properties >= 0; | |
948 if (!canContinue) { | |
949 overflow = true; | |
kozy
2017/02/28 17:14:43
preview.overflow = true
luoe
2017/02/28 21:46:39
Done.
| |
950 return false; | |
951 } | |
952 push(descriptors, descriptor); | |
953 return true; | |
954 } | |
905 }, | 955 }, |
906 | 956 |
907 /** | 957 /** |
908 * @param {!RuntimeAgent.ObjectPreview} preview | 958 * @param {!RuntimeAgent.ObjectPreview} preview |
909 * @param {!Array.<*>|!Iterable.<*>} descriptors | 959 * @param {!Array.<*>|!Iterable.<*>} descriptors |
910 * @param {!Object} propertiesThreshold | |
911 * @param {?Array.<string>=} secondLevelKeys | 960 * @param {?Array.<string>=} secondLevelKeys |
912 * @param {boolean=} isTable | 961 * @param {boolean=} isTable |
913 */ | 962 */ |
914 _appendPropertyDescriptors: function(preview, descriptors, propertiesThresho ld, secondLevelKeys, isTable) | 963 _appendPropertyPreviewDescriptors: function(preview, descriptors, secondLeve lKeys, isTable) |
915 { | 964 { |
916 for (var descriptor of descriptors) { | 965 for (var i = 0; i < descriptors.length; ++i) { |
917 if (propertiesThreshold.indexes < 0 || propertiesThreshold.propertie s < 0) | 966 var descriptor = descriptors[i]; |
918 break; | |
919 if (!descriptor || descriptor.wasThrown) | |
920 continue; | |
921 | |
922 var name = descriptor.name; | 967 var name = descriptor.name; |
923 | |
924 // Ignore __proto__ property. | |
925 if (name === "__proto__") | |
926 continue; | |
927 | |
928 // Ignore length property of array. | |
929 if ((this.subtype === "array" || this.subtype === "typedarray") && n ame === "length") | |
930 continue; | |
931 | |
932 // Ignore size property of map, set. | |
933 if ((this.subtype === "map" || this.subtype === "set") && name === " size") | |
934 continue; | |
935 | |
936 // Never preview prototype properties. | |
937 if (!descriptor.isOwn) | |
938 continue; | |
939 | |
940 // Ignore computed properties unless they have getters. | |
941 if (!("value" in descriptor)) { | |
942 if (descriptor.get) | |
943 this._appendPropertyPreview(preview, { name: name, type: "ac cessor", __proto__: null }, propertiesThreshold); | |
944 continue; | |
945 } | |
946 | |
947 var value = descriptor.value; | 968 var value = descriptor.value; |
948 var type = typeof value; | 969 var type = typeof value; |
949 | 970 |
950 // Special-case HTMLAll. | 971 // Special-case HTMLAll. |
951 if (type === "undefined" && injectedScript._isHTMLAllCollection(valu e)) | 972 if (type === "undefined" && injectedScript._isHTMLAllCollection(valu e)) |
952 type = "object"; | 973 type = "object"; |
953 | 974 |
954 // Render own properties. | 975 // Ignore computed properties unless they have getters. |
955 if (value === null) { | 976 if (descriptor.get && !("value" in descriptor)) { |
956 this._appendPropertyPreview(preview, { name: name, type: "object ", subtype: "null", value: "null", __proto__: null }, propertiesThreshold); | 977 push(preview.properties, { name: name, type: "accessor", __proto __: null }); |
957 continue; | 978 continue; |
958 } | 979 } |
959 | 980 |
981 // Render own properties. | |
982 if (value === null) { | |
983 push(preview.properties, { name: name, type: "object", subtype: "null", value: "null", __proto__: null }); | |
984 continue; | |
985 } | |
986 | |
960 var maxLength = 100; | 987 var maxLength = 100; |
961 if (InjectedScript.primitiveTypes[type]) { | 988 if (InjectedScript.primitiveTypes[type]) { |
962 if (type === "string" && value.length > maxLength) | 989 if (type === "string" && value.length > maxLength) |
963 value = this._abbreviateString(value, maxLength, true); | 990 value = this._abbreviateString(value, maxLength, true); |
964 this._appendPropertyPreview(preview, { name: name, type: type, v alue: toStringDescription(value), __proto__: null }, propertiesThreshold); | 991 push(preview.properties, { name: name, type: type, value: toStri ngDescription(value), __proto__: null }); |
965 continue; | 992 continue; |
966 } | 993 } |
967 | 994 |
968 var property = { name: name, type: type, __proto__: null }; | 995 var property = { name: name, type: type, __proto__: null }; |
969 var subtype = injectedScript._subtype(value); | 996 var subtype = injectedScript._subtype(value); |
970 if (subtype) | 997 if (subtype) |
971 property.subtype = subtype; | 998 property.subtype = subtype; |
972 | 999 |
973 if (secondLevelKeys === null || secondLevelKeys) { | 1000 if (secondLevelKeys === null || secondLevelKeys) { |
974 var subPreview = this._generatePreview(value, secondLevelKeys || undefined, undefined, isTable); | 1001 var subPreview = this._generatePreview(value, secondLevelKeys || undefined, undefined, isTable); |
975 property.valuePreview = subPreview; | 1002 property.valuePreview = subPreview; |
976 if (subPreview.overflow) | 1003 if (subPreview.overflow) |
977 preview.overflow = true; | 1004 preview.overflow = true; |
978 } else { | 1005 } else { |
979 var description = ""; | 1006 var description = ""; |
980 if (type !== "function") | 1007 if (type !== "function") |
981 description = this._abbreviateString(/** @type {string} */ ( injectedScript._describe(value)), maxLength, subtype === "regexp"); | 1008 description = this._abbreviateString(/** @type {string} */ ( injectedScript._describe(value)), maxLength, subtype === "regexp"); |
982 property.value = description; | 1009 property.value = description; |
983 } | 1010 } |
984 this._appendPropertyPreview(preview, property, propertiesThreshold); | |
985 } | |
986 }, | |
987 | |
988 /** | |
989 * @param {!RuntimeAgent.ObjectPreview} preview | |
990 * @param {!Object} property | |
991 * @param {!Object} propertiesThreshold | |
992 */ | |
993 _appendPropertyPreview: function(preview, property, propertiesThreshold) | |
994 { | |
995 if (toString(property.name >>> 0) === property.name) | |
996 propertiesThreshold.indexes--; | |
997 else | |
998 propertiesThreshold.properties--; | |
999 if (propertiesThreshold.indexes < 0 || propertiesThreshold.properties < 0) { | |
1000 preview.overflow = true; | |
1001 } else { | |
1002 push(preview.properties, property); | 1011 push(preview.properties, property); |
1003 } | 1012 } |
1004 }, | 1013 }, |
1005 | 1014 |
1006 /** | 1015 /** |
1007 * @param {?Array<*>} entries | 1016 * @param {?Array<*>} entries |
1008 * @param {!RuntimeAgent.ObjectPreview} preview | 1017 * @param {!RuntimeAgent.ObjectPreview} preview |
1009 * @param {boolean=} skipEntriesPreview | 1018 * @param {boolean=} skipEntriesPreview |
1010 */ | 1019 */ |
1011 _appendEntriesPreview: function(entries, preview, skipEntriesPreview) | 1020 _appendEntriesPreview: function(entries, preview, skipEntriesPreview) |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1062 return string.substr(0, leftHalf) + "\u2026" + string.substr(string. length - rightHalf, rightHalf); | 1071 return string.substr(0, leftHalf) + "\u2026" + string.substr(string. length - rightHalf, rightHalf); |
1063 } | 1072 } |
1064 return string.substr(0, maxLength) + "\u2026"; | 1073 return string.substr(0, maxLength) + "\u2026"; |
1065 }, | 1074 }, |
1066 | 1075 |
1067 __proto__: null | 1076 __proto__: null |
1068 } | 1077 } |
1069 | 1078 |
1070 return injectedScript; | 1079 return injectedScript; |
1071 }) | 1080 }) |
OLD | NEW |