chrome-devtools-frontend 1.0.1701636 → 1.0.1703574
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/eslint.config.mjs +3 -1
- package/front_end/core/common/ParsedURL.ts +5 -1
- package/front_end/core/host/UserMetricsEnums.ts +2 -1
- package/front_end/core/root/ExperimentNames.ts +1 -0
- package/front_end/core/sdk/CSSPropertyParserMatchers.ts +2 -7
- package/front_end/core/text_utils/Markdown.ts +73 -0
- package/front_end/core/text_utils/text_utils.ts +2 -0
- package/front_end/devtools_compatibility.js +2 -1
- package/front_end/entrypoints/main/MainImpl.ts +8 -0
- package/front_end/generated/InspectorBackendCommands.ts +6 -4
- package/front_end/generated/protocol-mapping.d.ts +8 -0
- package/front_end/generated/protocol-proxy-api.d.ts +6 -0
- package/front_end/generated/protocol.ts +22 -3
- package/front_end/models/ai_assistance/AiAgent2.ts +13 -1
- package/front_end/models/ai_assistance/AiConversation.ts +1 -1
- package/front_end/models/ai_assistance/agents/ContextSelectionAgent.ts +13 -19
- package/front_end/models/change_tracker/ChangeTracker.ts +5 -64
- package/front_end/models/comment_manager/CD4ABridge.ts +5 -0
- package/front_end/models/comment_manager/CommentManager.ts +3 -5
- package/front_end/models/comment_manager/CommentThread.ts +30 -13
- package/front_end/models/issues_manager/CookieDeprecationMetadataIssue.ts +6 -7
- package/front_end/models/issues_manager/DeprecationIssue.ts +1 -1
- package/front_end/models/issues_manager/MarkdownIssueDescription.ts +18 -52
- package/front_end/models/issues_manager/SRIMessageSignatureIssue.ts +2 -4
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantRead.md +0 -1
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantReadOptOut.md +5 -0
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantSet.md +0 -1
- package/front_end/models/issues_manager/descriptions/cookieWarnMetadataGrantSetOptOut.md +5 -0
- package/front_end/models/issues_manager/descriptions/deprecation.md +1 -1
- package/front_end/models/issues_manager/descriptions/sriValidationFailedIntegrityMismatch.md +2 -0
- package/front_end/models/persistence/AutomaticFileSystemWorkspaceBinding.ts +1 -1
- package/front_end/models/persistence/NetworkPersistenceManager.ts +14 -2
- package/front_end/panels/common/CommentThreadWidget.ts +29 -10
- package/front_end/panels/common/CommentsOverlayWidget.ts +50 -14
- package/front_end/panels/common/CommentsStatusBarPill.ts +40 -7
- package/front_end/panels/common/commentThreadWidget.css +11 -0
- package/front_end/panels/common/commentsStatusBarPill.css +13 -0
- package/front_end/panels/elements/StylePropertiesSection.ts +10 -0
- package/front_end/panels/elements/StylePropertyTreeElement.ts +1 -1
- package/front_end/panels/elements/StylesSidebarPane.ts +101 -49
- package/front_end/panels/elements/components/CSSQuery.ts +1 -1
- package/front_end/panels/elements/components/cssQuery.css +4 -0
- package/front_end/panels/elements/elements.ts +0 -1
- package/front_end/panels/elements/stylesSidebarPane.css +6 -0
- package/front_end/panels/issues/IssueView.ts +5 -1
- package/front_end/panels/sources/ResourceOriginPlugin.ts +8 -3
- package/front_end/panels/sources/ScopeChainSidebarPane.ts +3 -4
- package/front_end/panels/sources/SourcesView.ts +127 -147
- package/front_end/panels/sources/TabbedEditorContainer.ts +518 -246
- package/front_end/panels/sources/UISourceCodeFrame.ts +9 -0
- package/front_end/third_party/chromium/README.chromium +1 -1
- package/front_end/third_party/chromium/client-variations/ClientVariations.js +25 -96
- package/front_end/third_party/codemirror.next/chunk/angular.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/codemirror.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/cpp.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/java.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/legacy.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/less.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/markdown.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/php.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/python.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/sass.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/svelte.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/vue.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/wast.js.map +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js +1 -1
- package/front_end/third_party/codemirror.next/chunk/xml.js.map +1 -1
- package/front_end/third_party/codemirror.next/codemirror.next.js +1 -1
- package/front_end/third_party/codemirror.next/package.json +4 -1
- package/front_end/third_party/codemirror.next/rebuild.sh +1 -1
- package/front_end/ui/comments/CommentOverlayManager.ts +11 -10
- package/front_end/ui/components/markdown_view/MarkdownPlaceholderLitRenderer.ts +59 -0
- package/front_end/ui/components/markdown_view/markdown_view.ts +2 -0
- package/front_end/ui/legacy/TabbedPane.ts +51 -40
- package/front_end/ui/legacy/Treeoutline.ts +28 -19
- package/front_end/ui/legacy/UIUtils.ts +1 -1
- package/front_end/ui/legacy/components/object_ui/ObjectPropertiesSection.ts +424 -570
- package/front_end/ui/legacy/components/object_ui/objectPropertiesSection.css +2 -27
- package/front_end/ui/visual_logging/KnownContextValues.ts +1 -0
- package/mcp/mcp.ts +1 -0
- package/package.json +2 -1
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// Copyright 2020 The Chromium Authors
|
|
2
2
|
// Use of this source code is governed by a BSD-style license that can be
|
|
3
3
|
// found in the LICENSE file.
|
|
4
|
-
/* eslint-disable @devtools/no-imperative-dom-api */
|
|
5
4
|
|
|
6
5
|
/*
|
|
7
6
|
* Copyright (C) 2008 Apple Inc. All Rights Reserved.
|
|
@@ -66,6 +65,7 @@ export interface ObjectPropertySearchResult extends UI.TreeOutline.TreeSearchRes
|
|
|
66
65
|
range: TextUtils.TextRange.SourceRange;
|
|
67
66
|
}
|
|
68
67
|
const {widget, widgetRef} = UI.Widget;
|
|
68
|
+
const {ifExpanded} = UI.TreeOutline;
|
|
69
69
|
const {ref, repeat, ifDefined, classMap} = Directives;
|
|
70
70
|
const UIStrings = {
|
|
71
71
|
/**
|
|
@@ -147,21 +147,12 @@ const UIStrings = {
|
|
|
147
147
|
/**
|
|
148
148
|
* @description Tooltip text for the button to open a memory buffer object in the Memory inspector panel.
|
|
149
149
|
*/
|
|
150
|
-
|
|
150
|
+
openInMemoryInspector: 'Open in Memory inspector panel',
|
|
151
151
|
} as const;
|
|
152
152
|
const str_ = i18n.i18n.registerUIStrings('ui/legacy/components/object_ui/ObjectPropertiesSection.ts', UIStrings);
|
|
153
153
|
const i18nString = i18n.i18n.getLocalizedString.bind(undefined, str_);
|
|
154
154
|
export const EXPANDABLE_MAX_DEPTH = 100;
|
|
155
155
|
|
|
156
|
-
// TODO(crbug.com/457388389): This cache is a temporary workaround for the <devtools-tree> migration.
|
|
157
|
-
// It can be removed once the entire ObjectPropertiesSection is fully migrated to Lit and
|
|
158
|
-
// the legacy TreeOutline/TreeElement dependencies are removed.
|
|
159
|
-
const topLevelNodesCache = new WeakMap<ObjectTreeNodeBase, {
|
|
160
|
-
nodes: UI.TreeOutline.TreeElement[],
|
|
161
|
-
listener: () => void,
|
|
162
|
-
linkifier?: Components.Linkifier.Linkifier,
|
|
163
|
-
}>();
|
|
164
|
-
|
|
165
156
|
interface NodeChildren {
|
|
166
157
|
properties?: ObjectTreeNode[];
|
|
167
158
|
internalProperties?: ObjectTreeNode[];
|
|
@@ -392,6 +383,139 @@ const ARRAY_LOAD_THRESHOLD = 100;
|
|
|
392
383
|
const ARRAY_BUCKET_THRESHOLD = 100;
|
|
393
384
|
const ARRAY_SPARSE_ITERATION_THRESHOLD = 250000;
|
|
394
385
|
|
|
386
|
+
async function arrayRangeGroups(object: SDK.RemoteObject.RemoteObject, fromIndex: number,
|
|
387
|
+
toIndex: number): Promise<{ranges: number[][]}|null|undefined> {
|
|
388
|
+
return await object.callFunctionJSON(packArrayRanges, [
|
|
389
|
+
{value: fromIndex},
|
|
390
|
+
{value: toIndex},
|
|
391
|
+
{value: ARRAY_BUCKET_THRESHOLD},
|
|
392
|
+
{value: ARRAY_SPARSE_ITERATION_THRESHOLD},
|
|
393
|
+
]);
|
|
394
|
+
|
|
395
|
+
/**
|
|
396
|
+
* This function is called on the RemoteObject.
|
|
397
|
+
* Note: must declare params as optional.
|
|
398
|
+
*/
|
|
399
|
+
function packArrayRanges(this: Object, fromIndex?: number, toIndex?: number, bucketThreshold?: number,
|
|
400
|
+
sparseIterationThreshold?: number): {
|
|
401
|
+
ranges: number[][],
|
|
402
|
+
}|undefined {
|
|
403
|
+
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined ||
|
|
404
|
+
bucketThreshold === undefined) {
|
|
405
|
+
return;
|
|
406
|
+
}
|
|
407
|
+
let ownPropertyNames: string[]|null = null;
|
|
408
|
+
const consecutiveRange = (toIndex - fromIndex >= sparseIterationThreshold) && ArrayBuffer.isView(this);
|
|
409
|
+
|
|
410
|
+
function* arrayIndexes(object: Object): Generator<number, void, unknown> {
|
|
411
|
+
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined) {
|
|
412
|
+
return;
|
|
413
|
+
}
|
|
414
|
+
|
|
415
|
+
if (toIndex - fromIndex < sparseIterationThreshold) {
|
|
416
|
+
for (let i = fromIndex; i <= toIndex; ++i) {
|
|
417
|
+
if (i in object) {
|
|
418
|
+
yield i;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
} else {
|
|
422
|
+
ownPropertyNames = ownPropertyNames || Object.getOwnPropertyNames(object);
|
|
423
|
+
for (let i = 0; i < ownPropertyNames.length; ++i) {
|
|
424
|
+
const name = ownPropertyNames[i];
|
|
425
|
+
|
|
426
|
+
const index = Number(name) >>> 0;
|
|
427
|
+
if ((String(index)) === name && fromIndex <= index && index <= toIndex) {
|
|
428
|
+
yield index;
|
|
429
|
+
}
|
|
430
|
+
}
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
let count = 0;
|
|
435
|
+
if (consecutiveRange) {
|
|
436
|
+
count = toIndex - fromIndex + 1;
|
|
437
|
+
} else {
|
|
438
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
439
|
+
for (const ignored of arrayIndexes(this)) {
|
|
440
|
+
++count;
|
|
441
|
+
}
|
|
442
|
+
}
|
|
443
|
+
|
|
444
|
+
let bucketSize: number = count;
|
|
445
|
+
if (count <= bucketThreshold) {
|
|
446
|
+
bucketSize = count;
|
|
447
|
+
} else {
|
|
448
|
+
bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
const ranges = [];
|
|
452
|
+
if (consecutiveRange) {
|
|
453
|
+
for (let i = fromIndex; i <= toIndex; i += bucketSize) {
|
|
454
|
+
const groupStart = i;
|
|
455
|
+
let groupEnd: number = groupStart + bucketSize - 1;
|
|
456
|
+
if (groupEnd > toIndex) {
|
|
457
|
+
groupEnd = toIndex;
|
|
458
|
+
}
|
|
459
|
+
ranges.push([groupStart, groupEnd, groupEnd - groupStart + 1]);
|
|
460
|
+
}
|
|
461
|
+
} else {
|
|
462
|
+
count = 0;
|
|
463
|
+
let groupStart = -1;
|
|
464
|
+
let groupEnd = 0;
|
|
465
|
+
for (const i of arrayIndexes(this)) {
|
|
466
|
+
if (groupStart === -1) {
|
|
467
|
+
groupStart = i;
|
|
468
|
+
}
|
|
469
|
+
groupEnd = i;
|
|
470
|
+
if (++count === bucketSize) {
|
|
471
|
+
ranges.push([groupStart, groupEnd, count]);
|
|
472
|
+
count = 0;
|
|
473
|
+
groupStart = -1;
|
|
474
|
+
}
|
|
475
|
+
}
|
|
476
|
+
if (count > 0) {
|
|
477
|
+
ranges.push([groupStart, groupEnd, count]);
|
|
478
|
+
}
|
|
479
|
+
}
|
|
480
|
+
|
|
481
|
+
return {ranges};
|
|
482
|
+
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
/**
|
|
486
|
+
* This function is called on the RemoteObject.
|
|
487
|
+
*/
|
|
488
|
+
function buildArrayFragment(
|
|
489
|
+
this: Record<number, Object>,
|
|
490
|
+
fromIndex?: number,
|
|
491
|
+
toIndex?: number,
|
|
492
|
+
sparseIterationThreshold?: number,
|
|
493
|
+
): unknown {
|
|
494
|
+
const result = Object.create(null);
|
|
495
|
+
|
|
496
|
+
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined) {
|
|
497
|
+
return;
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
if (toIndex - fromIndex < sparseIterationThreshold) {
|
|
501
|
+
for (let i = fromIndex; i <= toIndex; ++i) {
|
|
502
|
+
if (i in this) {
|
|
503
|
+
result[i] = this[i];
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
} else {
|
|
507
|
+
const ownPropertyNames = Object.getOwnPropertyNames(this);
|
|
508
|
+
for (let i = 0; i < ownPropertyNames.length; ++i) {
|
|
509
|
+
const name = ownPropertyNames[i];
|
|
510
|
+
const index = Number(name) >>> 0;
|
|
511
|
+
if (String(index) === name && fromIndex <= index && index <= toIndex) {
|
|
512
|
+
result[index] = this[index];
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
}
|
|
516
|
+
return result;
|
|
517
|
+
}
|
|
518
|
+
|
|
395
519
|
export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrapper<ObjectTreeNodeBase.EventTypes> {
|
|
396
520
|
#children?: NodeChildren;
|
|
397
521
|
protected readonly options: ObjectTreeOptions;
|
|
@@ -502,8 +626,6 @@ export abstract class ObjectTreeNodeBase extends Common.ObjectWrapper.ObjectWrap
|
|
|
502
626
|
}
|
|
503
627
|
|
|
504
628
|
setFilter(filter: {includeNullOrUndefinedValues: boolean, regex: RegExp|null}|null): void {
|
|
505
|
-
this.filter = filter;
|
|
506
|
-
this.dispatchEventToListeners(ObjectTreeNodeBase.Events.FILTER_CHANGED);
|
|
507
629
|
this.#walk().forEach(c => {
|
|
508
630
|
c.filter = filter;
|
|
509
631
|
c.dispatchEventToListeners(ObjectTreeNodeBase.Events.FILTER_CHANGED);
|
|
@@ -766,11 +888,11 @@ class ArrayGroupTreeNode extends ObjectTreeNodeBase {
|
|
|
766
888
|
|
|
767
889
|
export class ObjectTreeNode extends ObjectTreeNodeBase {
|
|
768
890
|
#path?: string;
|
|
891
|
+
showAllChildren: boolean = false;
|
|
769
892
|
constructor(
|
|
770
893
|
readonly property: SDK.RemoteObject.RemoteObjectProperty,
|
|
771
894
|
parent: ObjectTreeNodeBase|undefined,
|
|
772
895
|
options: ObjectTreeOptions,
|
|
773
|
-
readonly nonSyntheticParent?: SDK.RemoteObject.RemoteObject|undefined,
|
|
774
896
|
) {
|
|
775
897
|
super(parent, options);
|
|
776
898
|
}
|
|
@@ -1084,8 +1206,8 @@ export function getMemoryIcon(object: SDK.RemoteObject.RemoteObject, expression?
|
|
|
1084
1206
|
void Common.Revealer.reveal(new SDK.RemoteObject.LinearMemoryInspectable(object, expression));
|
|
1085
1207
|
}}
|
|
1086
1208
|
jslog=${VisualLogging.action('open-memory-inspector').track({click: true})}
|
|
1087
|
-
title=${i18nString(UIStrings.
|
|
1088
|
-
aria-label=${i18nString(UIStrings.
|
|
1209
|
+
title=${i18nString(UIStrings.openInMemoryInspector)}
|
|
1210
|
+
aria-label=${i18nString(UIStrings.openInMemoryInspector)}></devtools-icon>`;
|
|
1089
1211
|
// clang-format on
|
|
1090
1212
|
}
|
|
1091
1213
|
|
|
@@ -1253,13 +1375,16 @@ export const enum ObjectPropertiesMode {
|
|
|
1253
1375
|
OWN_AND_INTERNAL_AND_INHERITED = 1, // Own, internal, and inherited properties
|
|
1254
1376
|
}
|
|
1255
1377
|
|
|
1378
|
+
export interface ContextMenuHandlers {
|
|
1379
|
+
expandRecursively: (node: ObjectTreeNodeBase) => void;
|
|
1380
|
+
collapseChildren: (node: ObjectTreeNodeBase) => void;
|
|
1381
|
+
sortPropertiesAlphabetically: (node: ObjectTreeNodeBase) => void;
|
|
1382
|
+
onShowAllToggled: (node: ObjectTreeNodeBase) => void;
|
|
1383
|
+
}
|
|
1384
|
+
|
|
1256
1385
|
export function populateObjectTreeContextMenu(contextMenu: UI.ContextMenu.ContextMenu,
|
|
1257
|
-
objectOrProperty: ObjectTree|ObjectTreeNode,
|
|
1258
|
-
|
|
1259
|
-
collapseChildren: (node: ObjectTreeNodeBase) => void,
|
|
1260
|
-
sortPropertiesAlphabetically: (node: ObjectTreeNodeBase) => void,
|
|
1261
|
-
onShowAllToggled: (node: ObjectTreeNodeBase) => void,
|
|
1262
|
-
}): void {
|
|
1386
|
+
objectOrProperty: ObjectTree|ObjectTreeNode,
|
|
1387
|
+
handlers: ContextMenuHandlers): void {
|
|
1263
1388
|
contextMenu.appendApplicableItems(objectOrProperty);
|
|
1264
1389
|
if (objectOrProperty instanceof ObjectTreeNode && objectOrProperty.property.symbol) {
|
|
1265
1390
|
contextMenu.appendApplicableItems(objectOrProperty.property.symbol);
|
|
@@ -1314,14 +1439,15 @@ export function populateObjectTreeContextMenu(contextMenu: UI.ContextMenu.Contex
|
|
|
1314
1439
|
{checked: objectOrProperty.includeNullOrUndefinedValues, jslogContext: 'show-all'});
|
|
1315
1440
|
}
|
|
1316
1441
|
|
|
1317
|
-
interface ObjectTreeViewInput {
|
|
1442
|
+
interface ObjectTreeViewInput extends ContextMenuHandlers {
|
|
1443
|
+
onShowAllProperties: (node: ObjectTreeNode) => void;
|
|
1444
|
+
onExpand: (node: ObjectTreeNodeBase, expanded: boolean) => void;
|
|
1318
1445
|
renderAsSubtree: boolean;
|
|
1319
1446
|
objectTree?: ObjectTree;
|
|
1320
1447
|
linkifier?: Components.Linkifier.Linkifier;
|
|
1321
|
-
emptyPlaceholder?:
|
|
1448
|
+
emptyPlaceholder?: LitTemplate;
|
|
1322
1449
|
skipProto: boolean;
|
|
1323
1450
|
skipGettersAndSetters: boolean;
|
|
1324
|
-
onExpand: (expanded: boolean) => void;
|
|
1325
1451
|
}
|
|
1326
1452
|
type ObjectTreeView = (input: ObjectTreeViewInput, output: object, target: HTMLElement) => void;
|
|
1327
1453
|
const OBJECT_TREE_DEFAULT_VIEW: ObjectTreeView = (input, output, target) => {
|
|
@@ -1330,50 +1456,178 @@ const OBJECT_TREE_DEFAULT_VIEW: ObjectTreeView = (input, output, target) => {
|
|
|
1330
1456
|
render(nothing, target);
|
|
1331
1457
|
return;
|
|
1332
1458
|
}
|
|
1333
|
-
|
|
1334
|
-
|
|
1335
|
-
|
|
1336
|
-
|
|
1337
|
-
|
|
1338
|
-
|
|
1339
|
-
const nodes = Array.from(ObjectPropertyTreeElement.createNodes(
|
|
1340
|
-
objectTree, input.skipProto, input.skipGettersAndSetters, input.linkifier, input.emptyPlaceholder));
|
|
1341
|
-
const listener = (): void => {
|
|
1342
|
-
topLevelNodesCache.delete(objectTree);
|
|
1343
|
-
objectTree.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, listener);
|
|
1459
|
+
|
|
1460
|
+
function renderProperty(property: ObjectTreeNode): LitTemplate {
|
|
1461
|
+
const onContextMenu = (e: Event): void => {
|
|
1462
|
+
const contextMenu = new UI.ContextMenu.ContextMenu(e);
|
|
1463
|
+
populateObjectTreeContextMenu(contextMenu, property, input);
|
|
1464
|
+
void contextMenu.show();
|
|
1344
1465
|
};
|
|
1345
|
-
entry = {linkifier: input.linkifier, nodes, listener};
|
|
1346
|
-
topLevelNodesCache.set(objectTree, entry);
|
|
1347
|
-
objectTree.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, listener);
|
|
1348
|
-
}
|
|
1349
1466
|
|
|
1350
|
-
|
|
1351
|
-
|
|
1352
|
-
|
|
1353
|
-
|
|
1354
|
-
|
|
1355
|
-
|
|
1356
|
-
|
|
1357
|
-
|
|
1358
|
-
|
|
1467
|
+
const onExpand = (e: UI.TreeOutline.TreeViewElement.ExpandEvent): void => {
|
|
1468
|
+
input.onExpand(property, e.detail.expanded);
|
|
1469
|
+
e.consume(true);
|
|
1470
|
+
};
|
|
1471
|
+
const childCount = (property.children?.properties?.length ?? 0) +
|
|
1472
|
+
(property.children?.internalProperties?.length ?? 0) + (property.children?.accessors?.length ?? 0) +
|
|
1473
|
+
(property.children?.arrayRanges?.length ?? 0);
|
|
1474
|
+
|
|
1475
|
+
const showAllChildren = childCount <= InitialVisibleChildrenLimit || property.showAllChildren;
|
|
1476
|
+
const children = (): Iterable<LitTemplate> => {
|
|
1477
|
+
const nodes = createNodes(property, false, false, undefined, p => !isDisplayableProperty(p, property.property));
|
|
1478
|
+
return showAllChildren ? nodes : nodes.take(InitialVisibleChildrenLimit);
|
|
1479
|
+
};
|
|
1359
1480
|
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1481
|
+
const expandable = property.object && !property.object.customPreview() && property.object.hasChildren &&
|
|
1482
|
+
!property.property.wasThrown;
|
|
1483
|
+
|
|
1484
|
+
// clang-format off
|
|
1485
|
+
return html`<li
|
|
1486
|
+
?hidden=${property.isFiltered}
|
|
1487
|
+
?open=${property.expanded}
|
|
1488
|
+
@contextmenu=${onContextMenu}
|
|
1489
|
+
@expand=${onExpand}
|
|
1490
|
+
data-object-property-name-for-test=${property.name}
|
|
1491
|
+
toggle-on-click
|
|
1492
|
+
role=treeitem>
|
|
1493
|
+
${widget(ObjectPropertyWidget, {property, linkifier: input.linkifier, editable: !property.readOnly, expanded: property.expanded})}
|
|
1494
|
+
${expandable ? html`
|
|
1495
|
+
<ul role=group>
|
|
1496
|
+
${children()}
|
|
1497
|
+
${showAllChildren ? nothing : html`
|
|
1498
|
+
<li role=treeitem @select=${() => input.onShowAllProperties(property)}>
|
|
1499
|
+
<div
|
|
1500
|
+
class=object-value-calculate-value-button
|
|
1501
|
+
title=${i18nString(UIStrings.showAllD, {PH1: childCount})}>
|
|
1502
|
+
${i18nString(UIStrings.dots)}
|
|
1503
|
+
</div>
|
|
1504
|
+
</li>`}
|
|
1505
|
+
</ul>` : nothing}
|
|
1506
|
+
</li>`;
|
|
1507
|
+
// clang-format on
|
|
1508
|
+
}
|
|
1509
|
+
|
|
1510
|
+
function renderArrayGroup(child: ArrayGroupTreeNode): LitTemplate {
|
|
1511
|
+
const onExpand = (e: UI.TreeOutline.TreeViewElement.ExpandEvent): void => {
|
|
1512
|
+
input.onExpand(child, e.detail.expanded);
|
|
1513
|
+
e.consume(true);
|
|
1514
|
+
};
|
|
1515
|
+
|
|
1516
|
+
// clang-format off
|
|
1517
|
+
return html`<li
|
|
1518
|
+
class=object-properties-section-name
|
|
1519
|
+
role=treeitem
|
|
1520
|
+
toggle-on-click
|
|
1521
|
+
?open=${child.expanded}
|
|
1522
|
+
@expand=${onExpand}>
|
|
1523
|
+
${Platform.StringUtilities.sprintf('[%d … %d]', child.range.fromIndex, child.range.toIndex)}
|
|
1524
|
+
<ul role=group>
|
|
1525
|
+
${ifExpanded(() => createNodes(child, false, false))}
|
|
1526
|
+
</ul>
|
|
1527
|
+
</li>`;
|
|
1528
|
+
// clang-format on
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
function*
|
|
1532
|
+
createNodes(
|
|
1533
|
+
value: ObjectTreeNodeBase,
|
|
1534
|
+
skipProto: boolean,
|
|
1535
|
+
skipGettersAndSetters: boolean,
|
|
1536
|
+
emptyPlaceholder?: LitTemplate,
|
|
1537
|
+
isNotDisplayablePropertyCallback?: (property: SDK.RemoteObject.RemoteObjectProperty) => boolean,
|
|
1538
|
+
): Generator<LitTemplate> {
|
|
1539
|
+
const properties = value.children;
|
|
1540
|
+
if (!properties) {
|
|
1541
|
+
return;
|
|
1542
|
+
}
|
|
1543
|
+
if (properties.arrayRanges) {
|
|
1544
|
+
if (properties.arrayRanges.length === 1) {
|
|
1545
|
+
yield* createNodes(properties.arrayRanges[0], false, false, undefined, isNotDisplayablePropertyCallback);
|
|
1546
|
+
} else {
|
|
1547
|
+
for (const child of properties.arrayRanges) {
|
|
1548
|
+
if (child.singular) {
|
|
1549
|
+
yield* createNodes(child, false, false, undefined, isNotDisplayablePropertyCallback);
|
|
1550
|
+
} else {
|
|
1551
|
+
yield renderArrayGroup(child);
|
|
1552
|
+
}
|
|
1553
|
+
}
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
yield* createPropertyNodes(properties, false, false, undefined, isNotDisplayablePropertyCallback);
|
|
1557
|
+
} else {
|
|
1558
|
+
yield*
|
|
1559
|
+
createPropertyNodes(properties, skipProto, skipGettersAndSetters, emptyPlaceholder,
|
|
1560
|
+
isNotDisplayablePropertyCallback);
|
|
1561
|
+
}
|
|
1364
1562
|
}
|
|
1365
|
-
|
|
1366
|
-
|
|
1367
|
-
|
|
1368
|
-
|
|
1369
|
-
|
|
1563
|
+
|
|
1564
|
+
function*
|
|
1565
|
+
createPropertyNodes({properties, internalProperties, accessors, arrayRanges}: NodeChildren, skipProto: boolean,
|
|
1566
|
+
skipGettersAndSetters: boolean, emptyPlaceholder?: LitTemplate,
|
|
1567
|
+
isNotDisplayablePropertyCallback?: (property: SDK.RemoteObject.RemoteObjectProperty) =>
|
|
1568
|
+
boolean): Generator<LitTemplate> {
|
|
1569
|
+
let empty = true;
|
|
1570
|
+
// Arrays with large numbers of elements are paginated into arrayRanges.
|
|
1571
|
+
// If we have array ranges, the object is not empty.
|
|
1572
|
+
if (arrayRanges && arrayRanges.length > 0) {
|
|
1573
|
+
empty = false;
|
|
1574
|
+
}
|
|
1575
|
+
|
|
1576
|
+
const entriesProperty = internalProperties?.find(({property}) => property.name === '[[Entries]]');
|
|
1577
|
+
if (entriesProperty) {
|
|
1578
|
+
yield renderProperty(entriesProperty);
|
|
1579
|
+
empty = false;
|
|
1580
|
+
}
|
|
1581
|
+
|
|
1582
|
+
for (const property of properties ?? []) {
|
|
1583
|
+
if (isNotDisplayablePropertyCallback?.(property.property)) {
|
|
1584
|
+
continue;
|
|
1585
|
+
}
|
|
1586
|
+
|
|
1587
|
+
const canShowProperty = property.property.getter || !property.property.isAccessorProperty();
|
|
1588
|
+
if (canShowProperty) {
|
|
1589
|
+
yield renderProperty(property);
|
|
1590
|
+
empty = false;
|
|
1591
|
+
}
|
|
1592
|
+
}
|
|
1593
|
+
|
|
1594
|
+
if (!skipGettersAndSetters) {
|
|
1595
|
+
for (const accessor of accessors ?? []) {
|
|
1596
|
+
yield renderProperty(accessor);
|
|
1597
|
+
}
|
|
1598
|
+
}
|
|
1599
|
+
|
|
1600
|
+
for (const property of internalProperties ?? []) {
|
|
1601
|
+
if (property.property.name === '[[Entries]]') {
|
|
1602
|
+
continue;
|
|
1603
|
+
}
|
|
1604
|
+
if (property.property.name === '[[Prototype]]' && skipProto) {
|
|
1605
|
+
continue;
|
|
1606
|
+
}
|
|
1607
|
+
yield renderProperty(property);
|
|
1608
|
+
empty = false;
|
|
1609
|
+
}
|
|
1610
|
+
|
|
1611
|
+
if (empty) {
|
|
1612
|
+
yield html`<li role=treeitem>
|
|
1613
|
+
<div class=gray-info-message>${emptyPlaceholder || i18nString(UIStrings.noProperties)}</div>
|
|
1614
|
+
</li>`;
|
|
1615
|
+
}
|
|
1370
1616
|
}
|
|
1371
|
-
|
|
1617
|
+
|
|
1618
|
+
const nodes =
|
|
1619
|
+
Array.from(createNodes(objectTree, input.skipProto, input.skipGettersAndSetters, input.emptyPlaceholder));
|
|
1620
|
+
nodes.forEach(UI.UIUtils.HTMLElementWithLightDOMTemplate.patchLitTemplate);
|
|
1621
|
+
|
|
1622
|
+
render(nodes, target, {
|
|
1623
|
+
container: {classes: input.renderAsSubtree ? ['source-code', 'object-properties-section'] : []},
|
|
1624
|
+
});
|
|
1625
|
+
};
|
|
1372
1626
|
|
|
1373
1627
|
export class ObjectTreeWidget extends UI.Widget.Widget {
|
|
1374
1628
|
#objectTree: ObjectTree|undefined = undefined;
|
|
1375
1629
|
#linkifier: Components.Linkifier.Linkifier|undefined = undefined;
|
|
1376
|
-
#emptyPlaceholder?:
|
|
1630
|
+
#emptyPlaceholder?: LitTemplate;
|
|
1377
1631
|
#renderAsSubtree = false;
|
|
1378
1632
|
#skipProto = false;
|
|
1379
1633
|
#skipGettersAndSetters = false;
|
|
@@ -1384,9 +1638,77 @@ export class ObjectTreeWidget extends UI.Widget.Widget {
|
|
|
1384
1638
|
this.#view = view;
|
|
1385
1639
|
}
|
|
1386
1640
|
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1641
|
+
async #populateChildrenIfNeeded(node: ObjectTreeNodeBase): Promise<void> {
|
|
1642
|
+
const isFirstPopulation = !node.children;
|
|
1643
|
+
const children = await node.populateChildrenIfNeeded();
|
|
1644
|
+
|
|
1645
|
+
if (isFirstPopulation) {
|
|
1646
|
+
const entriesProperty = children.internalProperties?.find(({property}) => property.name === '[[Entries]]');
|
|
1647
|
+
if (entriesProperty) {
|
|
1648
|
+
entriesProperty.expanded = true;
|
|
1649
|
+
}
|
|
1650
|
+
|
|
1651
|
+
for (const property of children.properties ?? []) {
|
|
1652
|
+
const canShowProperty = property.property.getter || !property.property.isAccessorProperty();
|
|
1653
|
+
if (canShowProperty) {
|
|
1654
|
+
if (property.property.name === 'memories' && property.object?.className === 'Memories') {
|
|
1655
|
+
property.expanded = true;
|
|
1656
|
+
}
|
|
1657
|
+
}
|
|
1658
|
+
}
|
|
1659
|
+
}
|
|
1660
|
+
|
|
1661
|
+
for (const child of node.treeNodeChildren()) {
|
|
1662
|
+
child.removeEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
1663
|
+
child.removeEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
|
|
1664
|
+
child.removeEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.requestUpdate, this);
|
|
1665
|
+
child.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
1666
|
+
child.addEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
1667
|
+
child.addEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.requestUpdate, this);
|
|
1668
|
+
child.addEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.requestUpdate, this);
|
|
1669
|
+
child.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
1670
|
+
if (child.expanded) {
|
|
1671
|
+
await this.#populateChildrenIfNeeded(child);
|
|
1672
|
+
}
|
|
1673
|
+
}
|
|
1674
|
+
|
|
1675
|
+
if (!children.arrayRanges) {
|
|
1676
|
+
return;
|
|
1677
|
+
}
|
|
1678
|
+
if (children.arrayRanges.length === 1) {
|
|
1679
|
+
await this.#populateChildrenIfNeeded(children.arrayRanges[0]);
|
|
1680
|
+
} else {
|
|
1681
|
+
await Promise.all(
|
|
1682
|
+
children.arrayRanges.filter(child => child.singular).map(child => this.#populateChildrenIfNeeded(child)));
|
|
1683
|
+
}
|
|
1684
|
+
}
|
|
1685
|
+
|
|
1686
|
+
onExpand = (node: ObjectTreeNodeBase, expanded: boolean): void => {
|
|
1687
|
+
if (node.expanded !== expanded) {
|
|
1688
|
+
node.expanded = expanded;
|
|
1689
|
+
this.requestUpdate();
|
|
1690
|
+
}
|
|
1691
|
+
};
|
|
1692
|
+
expandRecursively = (node: ObjectTreeNodeBase): void => {
|
|
1693
|
+
void node.expandRecursively(EXPANDABLE_MAX_DEPTH);
|
|
1694
|
+
this.requestUpdate();
|
|
1695
|
+
};
|
|
1696
|
+
collapseChildren = (node: ObjectTreeNodeBase): void => {
|
|
1697
|
+
node.collapseRecursively();
|
|
1698
|
+
this.requestUpdate();
|
|
1699
|
+
};
|
|
1700
|
+
sortPropertiesAlphabetically = (node: ObjectTreeNodeBase): void => {
|
|
1701
|
+
node.sortPropertiesAlphabetically = !node.sortPropertiesAlphabetically;
|
|
1702
|
+
this.requestUpdate();
|
|
1703
|
+
};
|
|
1704
|
+
onShowAllToggled = (node: ObjectTreeNodeBase): void => {
|
|
1705
|
+
node.includeNullOrUndefinedValues = !node.includeNullOrUndefinedValues;
|
|
1706
|
+
this.requestUpdate();
|
|
1707
|
+
};
|
|
1708
|
+
onShowAllProperties = (node: ObjectTreeNode): void => {
|
|
1709
|
+
if (!node.showAllChildren) {
|
|
1710
|
+
node.showAllChildren = true;
|
|
1711
|
+
this.requestUpdate();
|
|
1390
1712
|
}
|
|
1391
1713
|
};
|
|
1392
1714
|
|
|
@@ -1436,11 +1758,11 @@ export class ObjectTreeWidget extends UI.Widget.Widget {
|
|
|
1436
1758
|
this.requestUpdate();
|
|
1437
1759
|
}
|
|
1438
1760
|
|
|
1439
|
-
get emptyPlaceholder():
|
|
1761
|
+
get emptyPlaceholder(): LitTemplate|undefined {
|
|
1440
1762
|
return this.#emptyPlaceholder;
|
|
1441
1763
|
}
|
|
1442
1764
|
|
|
1443
|
-
set emptyPlaceholder(val:
|
|
1765
|
+
set emptyPlaceholder(val: LitTemplate) {
|
|
1444
1766
|
if (val === this.#emptyPlaceholder) {
|
|
1445
1767
|
return;
|
|
1446
1768
|
}
|
|
@@ -1462,7 +1784,7 @@ export class ObjectTreeWidget extends UI.Widget.Widget {
|
|
|
1462
1784
|
|
|
1463
1785
|
override async performUpdate(): Promise<void> {
|
|
1464
1786
|
if (this.#objectTree?.expanded) {
|
|
1465
|
-
await populateChildrenIfNeeded(this.#objectTree);
|
|
1787
|
+
await this.#populateChildrenIfNeeded(this.#objectTree);
|
|
1466
1788
|
}
|
|
1467
1789
|
this.#view(this, {}, this.contentElement);
|
|
1468
1790
|
}
|
|
@@ -1484,7 +1806,7 @@ export class ObjectTreeWidget extends UI.Widget.Widget {
|
|
|
1484
1806
|
export function renderObjectTree(
|
|
1485
1807
|
objectTree: ObjectTree,
|
|
1486
1808
|
linkifier?: Components.Linkifier.Linkifier,
|
|
1487
|
-
emptyPlaceholder?:
|
|
1809
|
+
emptyPlaceholder?: LitTemplate,
|
|
1488
1810
|
): LitTemplate|DirectiveResult {
|
|
1489
1811
|
return html`<ul role="group" ${
|
|
1490
1812
|
widget(ObjectTreeWidget, {objectTree, linkifier, emptyPlaceholder, renderAsSubtree: true})} ${
|
|
@@ -1840,32 +2162,51 @@ export class ObjectPropertyWidget extends UI.Widget.Widget {
|
|
|
1840
2162
|
}
|
|
1841
2163
|
|
|
1842
2164
|
set property(property: ObjectTreeNode) {
|
|
1843
|
-
if (this.#property) {
|
|
1844
|
-
|
|
1845
|
-
this.#property.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
1846
|
-
this.#property.removeEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
2165
|
+
if (property === this.#property) {
|
|
2166
|
+
return;
|
|
1847
2167
|
}
|
|
1848
|
-
this.#
|
|
2168
|
+
this.#removePropertyListeners();
|
|
1849
2169
|
this.#property = property;
|
|
1850
|
-
this.#property.addEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.requestUpdate, this);
|
|
1851
|
-
this.#property.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
1852
|
-
this.#property.addEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
1853
2170
|
this.#search = property.search;
|
|
1854
|
-
this.#
|
|
2171
|
+
this.#addPropertyListeners();
|
|
1855
2172
|
this.requestUpdate();
|
|
1856
2173
|
}
|
|
1857
2174
|
|
|
1858
|
-
|
|
1859
|
-
|
|
2175
|
+
#addPropertyListeners(): void {
|
|
2176
|
+
this.#property?.addEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.requestUpdate, this);
|
|
2177
|
+
this.#property?.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
2178
|
+
this.#property?.addEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
2179
|
+
this.#search?.addEventListener(UI.TreeOutline.TreeSearch.Events.SEARCH_CHANGED, this.requestUpdate, this);
|
|
1860
2180
|
}
|
|
1861
2181
|
|
|
1862
|
-
|
|
1863
|
-
this.#
|
|
1864
|
-
this.requestUpdate
|
|
2182
|
+
#removePropertyListeners(): void {
|
|
2183
|
+
this.#property?.removeEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.requestUpdate, this);
|
|
2184
|
+
this.#property?.removeEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.requestUpdate, this);
|
|
2185
|
+
this.#property?.removeEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.requestUpdate, this);
|
|
2186
|
+
this.#search?.removeEventListener(UI.TreeOutline.TreeSearch.Events.SEARCH_CHANGED, this.requestUpdate, this);
|
|
1865
2187
|
}
|
|
1866
2188
|
|
|
1867
|
-
|
|
1868
|
-
|
|
2189
|
+
override onDetach(): void {
|
|
2190
|
+
this.#removePropertyListeners();
|
|
2191
|
+
}
|
|
2192
|
+
|
|
2193
|
+
override wasShown(): void {
|
|
2194
|
+
super.wasShown();
|
|
2195
|
+
this.#removePropertyListeners();
|
|
2196
|
+
this.#addPropertyListeners();
|
|
2197
|
+
}
|
|
2198
|
+
|
|
2199
|
+
get expanded(): boolean {
|
|
2200
|
+
return this.#expanded;
|
|
2201
|
+
}
|
|
2202
|
+
|
|
2203
|
+
set expanded(expanded: boolean) {
|
|
2204
|
+
this.#expanded = expanded;
|
|
2205
|
+
this.requestUpdate();
|
|
2206
|
+
}
|
|
2207
|
+
|
|
2208
|
+
get linkifier(): Components.Linkifier.Linkifier|undefined {
|
|
2209
|
+
return this.#linkifier;
|
|
1869
2210
|
}
|
|
1870
2211
|
|
|
1871
2212
|
set linkifier(linkifier: Components.Linkifier.Linkifier|undefined) {
|
|
@@ -1934,493 +2275,6 @@ export class ObjectPropertyWidget extends UI.Widget.Widget {
|
|
|
1934
2275
|
}
|
|
1935
2276
|
}
|
|
1936
2277
|
|
|
1937
|
-
class ObjectPropertyTreeElement extends UI.TreeOutline.TreeElement {
|
|
1938
|
-
property: ObjectTreeNode;
|
|
1939
|
-
override toggleOnClick: boolean;
|
|
1940
|
-
private linkifier: Components.Linkifier.Linkifier|undefined;
|
|
1941
|
-
private readonly maxNumPropertiesToShow: number;
|
|
1942
|
-
readonly #widget: ObjectPropertyWidget;
|
|
1943
|
-
constructor(property: ObjectTreeNode, linkifier?: Components.Linkifier.Linkifier) {
|
|
1944
|
-
// Pass an empty title, the title gets made later in onattach.
|
|
1945
|
-
super();
|
|
1946
|
-
|
|
1947
|
-
this.#widget = new ObjectPropertyWidget();
|
|
1948
|
-
this.#widget.markAsRoot();
|
|
1949
|
-
this.property = property;
|
|
1950
|
-
this.hidden = property.isFiltered;
|
|
1951
|
-
this.property.addEventListener(ObjectTreeNodeBase.Events.VALUE_CHANGED, this.#updateValue, this);
|
|
1952
|
-
this.property.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.#updateChildren, this);
|
|
1953
|
-
this.property.addEventListener(ObjectTreeNodeBase.Events.FILTER_CHANGED, this.#updateFilter, this);
|
|
1954
|
-
this.property.addEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.#onExpandedChanged, this);
|
|
1955
|
-
this.toggleOnClick = true;
|
|
1956
|
-
this.linkifier = linkifier;
|
|
1957
|
-
this.maxNumPropertiesToShow = InitialVisibleChildrenLimit;
|
|
1958
|
-
this.listItemElement.addEventListener('contextmenu', this.contextMenuFired.bind(this), false);
|
|
1959
|
-
this.listItemElement.dataset.objectPropertyNameForTest = property.name;
|
|
1960
|
-
this.updateExpandable();
|
|
1961
|
-
this.setExpandRecursively(property.name !== '[[Prototype]]');
|
|
1962
|
-
if (property.expanded) {
|
|
1963
|
-
this.expand();
|
|
1964
|
-
}
|
|
1965
|
-
}
|
|
1966
|
-
|
|
1967
|
-
static async populate(
|
|
1968
|
-
treeElement: UI.TreeOutline.TreeElement,
|
|
1969
|
-
value: ObjectTreeNodeBase,
|
|
1970
|
-
skipProto: boolean,
|
|
1971
|
-
skipGettersAndSetters: boolean,
|
|
1972
|
-
linkifier?: Components.Linkifier.Linkifier,
|
|
1973
|
-
emptyPlaceholder?: string|null,
|
|
1974
|
-
): Promise<void> {
|
|
1975
|
-
await populateChildrenIfNeeded(value);
|
|
1976
|
-
ObjectPropertyTreeElement.populateImpl(treeElement, value, skipProto, skipGettersAndSetters, linkifier,
|
|
1977
|
-
emptyPlaceholder);
|
|
1978
|
-
}
|
|
1979
|
-
|
|
1980
|
-
static populateImpl(
|
|
1981
|
-
treeElement: UI.TreeOutline.TreeElement,
|
|
1982
|
-
value: ObjectTreeNodeBase,
|
|
1983
|
-
skipProto: boolean,
|
|
1984
|
-
skipGettersAndSetters: boolean,
|
|
1985
|
-
linkifier?: Components.Linkifier.Linkifier,
|
|
1986
|
-
emptyPlaceholder?: string|null,
|
|
1987
|
-
): void {
|
|
1988
|
-
for (const childNode of ObjectPropertyTreeElement.createNodes(
|
|
1989
|
-
value, skipProto, skipGettersAndSetters, linkifier, emptyPlaceholder,
|
|
1990
|
-
property => treeElement instanceof ObjectPropertyTreeElement &&
|
|
1991
|
-
!isDisplayableProperty(property, treeElement.property?.property))) {
|
|
1992
|
-
treeElement.appendChild(childNode);
|
|
1993
|
-
}
|
|
1994
|
-
}
|
|
1995
|
-
|
|
1996
|
-
static *
|
|
1997
|
-
createNodes(
|
|
1998
|
-
value: ObjectTreeNodeBase,
|
|
1999
|
-
skipProto: boolean,
|
|
2000
|
-
skipGettersAndSetters: boolean,
|
|
2001
|
-
linkifier?: Components.Linkifier.Linkifier,
|
|
2002
|
-
emptyPlaceholder?: string|null,
|
|
2003
|
-
isNotDisplayablePropertyCallback?: (property: SDK.RemoteObject.RemoteObjectProperty) => boolean,
|
|
2004
|
-
): Generator<UI.TreeOutline.TreeElement> {
|
|
2005
|
-
const properties = value.children;
|
|
2006
|
-
if (!properties) {
|
|
2007
|
-
return;
|
|
2008
|
-
}
|
|
2009
|
-
if (properties.arrayRanges) {
|
|
2010
|
-
yield* ArrayGroupingTreeElement.createNodes(properties, linkifier, isNotDisplayablePropertyCallback);
|
|
2011
|
-
} else {
|
|
2012
|
-
yield*
|
|
2013
|
-
ObjectPropertyTreeElement.createPropertyNodes(properties, skipProto, skipGettersAndSetters, linkifier,
|
|
2014
|
-
emptyPlaceholder, isNotDisplayablePropertyCallback);
|
|
2015
|
-
}
|
|
2016
|
-
}
|
|
2017
|
-
|
|
2018
|
-
static *
|
|
2019
|
-
createPropertyNodes({properties, internalProperties, accessors, arrayRanges}: NodeChildren, skipProto: boolean,
|
|
2020
|
-
skipGettersAndSetters: boolean, linkifier?: Components.Linkifier.Linkifier,
|
|
2021
|
-
emptyPlaceholder?: string|null,
|
|
2022
|
-
isNotDisplayablePropertyCallback?:
|
|
2023
|
-
(property: SDK.RemoteObject.RemoteObjectProperty) => boolean):
|
|
2024
|
-
Generator<UI.TreeOutline.TreeElement> {
|
|
2025
|
-
let empty = true;
|
|
2026
|
-
// Arrays with large numbers of elements are paginated into arrayRanges.
|
|
2027
|
-
// If we have array ranges, the object is not empty.
|
|
2028
|
-
if (arrayRanges && arrayRanges.length > 0) {
|
|
2029
|
-
empty = false;
|
|
2030
|
-
}
|
|
2031
|
-
const sortPropertiesAlphabetically = properties?.[0]?.sortPropertiesAlphabetically ?? true;
|
|
2032
|
-
properties?.sort((a, b) => compareProperties(a, b, sortPropertiesAlphabetically));
|
|
2033
|
-
|
|
2034
|
-
const entriesProperty = internalProperties?.find(({property}) => property.name === '[[Entries]]');
|
|
2035
|
-
if (entriesProperty) {
|
|
2036
|
-
const treeElement = new ObjectPropertyTreeElement(entriesProperty, linkifier);
|
|
2037
|
-
treeElement.setExpandable(true);
|
|
2038
|
-
treeElement.expand();
|
|
2039
|
-
empty = false;
|
|
2040
|
-
yield treeElement;
|
|
2041
|
-
}
|
|
2042
|
-
|
|
2043
|
-
for (const property of properties ?? []) {
|
|
2044
|
-
if (isNotDisplayablePropertyCallback?.(property.property)) {
|
|
2045
|
-
continue;
|
|
2046
|
-
}
|
|
2047
|
-
|
|
2048
|
-
const canShowProperty = property.property.getter || !property.property.isAccessorProperty();
|
|
2049
|
-
if (canShowProperty) {
|
|
2050
|
-
const element = new ObjectPropertyTreeElement(property, linkifier);
|
|
2051
|
-
if (property.property.name === 'memories' && property.object?.className === 'Memories') {
|
|
2052
|
-
element.updateExpandable();
|
|
2053
|
-
if (element.isExpandable()) {
|
|
2054
|
-
element.expand();
|
|
2055
|
-
}
|
|
2056
|
-
}
|
|
2057
|
-
empty = false;
|
|
2058
|
-
yield element;
|
|
2059
|
-
}
|
|
2060
|
-
}
|
|
2061
|
-
|
|
2062
|
-
for (const accessor of accessors ?? []) {
|
|
2063
|
-
yield new ObjectPropertyTreeElement(accessor, linkifier);
|
|
2064
|
-
}
|
|
2065
|
-
|
|
2066
|
-
for (const property of internalProperties ?? []) {
|
|
2067
|
-
const treeElement = new ObjectPropertyTreeElement(property, linkifier);
|
|
2068
|
-
if (property.property.name === '[[Entries]]') {
|
|
2069
|
-
continue;
|
|
2070
|
-
}
|
|
2071
|
-
if (property.property.name === '[[Prototype]]' && skipProto) {
|
|
2072
|
-
continue;
|
|
2073
|
-
}
|
|
2074
|
-
empty = false;
|
|
2075
|
-
yield treeElement;
|
|
2076
|
-
}
|
|
2077
|
-
|
|
2078
|
-
if (empty) {
|
|
2079
|
-
const title = document.createElement('div');
|
|
2080
|
-
title.classList.add('gray-info-message');
|
|
2081
|
-
title.textContent = emptyPlaceholder || i18nString(UIStrings.noProperties);
|
|
2082
|
-
const infoElement = new UI.TreeOutline.TreeElement(title);
|
|
2083
|
-
yield infoElement;
|
|
2084
|
-
}
|
|
2085
|
-
}
|
|
2086
|
-
|
|
2087
|
-
static populateWithProperties(treeNode: UI.TreeOutline.TreeElement, children: NodeChildren, skipProto: boolean,
|
|
2088
|
-
skipGettersAndSetters: boolean, linkifier?: Components.Linkifier.Linkifier,
|
|
2089
|
-
emptyPlaceholder?: string|null): void {
|
|
2090
|
-
for (const childNode of this.createPropertyNodes(
|
|
2091
|
-
children, skipProto, skipGettersAndSetters, linkifier, emptyPlaceholder,
|
|
2092
|
-
property => treeNode instanceof ObjectPropertyTreeElement &&
|
|
2093
|
-
!isDisplayableProperty(property, treeNode.property?.property))) {
|
|
2094
|
-
treeNode.appendChild(childNode);
|
|
2095
|
-
}
|
|
2096
|
-
}
|
|
2097
|
-
|
|
2098
|
-
// This is called by layout tests
|
|
2099
|
-
startEditing(): void {
|
|
2100
|
-
this.#widget.startEditing();
|
|
2101
|
-
}
|
|
2102
|
-
|
|
2103
|
-
// This is called by layout tests
|
|
2104
|
-
get editing(): boolean {
|
|
2105
|
-
return this.#widget.editing;
|
|
2106
|
-
}
|
|
2107
|
-
|
|
2108
|
-
get editable(): boolean {
|
|
2109
|
-
return this.#widget.editable;
|
|
2110
|
-
}
|
|
2111
|
-
|
|
2112
|
-
set editable(val: boolean) {
|
|
2113
|
-
this.#widget.editable = val;
|
|
2114
|
-
}
|
|
2115
|
-
|
|
2116
|
-
// This is called by layout tests
|
|
2117
|
-
async applyExpression(expression: string): Promise<void> {
|
|
2118
|
-
await this.property.setValue(expression);
|
|
2119
|
-
}
|
|
2120
|
-
|
|
2121
|
-
private showAllPropertiesElementSelected(element: UI.TreeOutline.TreeElement): boolean {
|
|
2122
|
-
this.removeChild(element);
|
|
2123
|
-
this.children().forEach(x => {
|
|
2124
|
-
x.hidden = false;
|
|
2125
|
-
});
|
|
2126
|
-
return false;
|
|
2127
|
-
}
|
|
2128
|
-
|
|
2129
|
-
private createShowAllPropertiesButton(): void {
|
|
2130
|
-
const element = document.createElement('div');
|
|
2131
|
-
element.classList.add('object-value-calculate-value-button');
|
|
2132
|
-
element.textContent = i18nString(UIStrings.dots);
|
|
2133
|
-
UI.Tooltip.Tooltip.install(element, i18nString(UIStrings.showAllD, {PH1: this.childCount()}));
|
|
2134
|
-
const children = this.children();
|
|
2135
|
-
for (let i = this.maxNumPropertiesToShow; i < this.childCount(); ++i) {
|
|
2136
|
-
children[i].hidden = true;
|
|
2137
|
-
}
|
|
2138
|
-
const showAllPropertiesButton = new UI.TreeOutline.TreeElement(element);
|
|
2139
|
-
showAllPropertiesButton.onselect = this.showAllPropertiesElementSelected.bind(this, showAllPropertiesButton);
|
|
2140
|
-
this.appendChild(showAllPropertiesButton);
|
|
2141
|
-
}
|
|
2142
|
-
|
|
2143
|
-
override async onpopulate(): Promise<void> {
|
|
2144
|
-
this.removeChildren();
|
|
2145
|
-
|
|
2146
|
-
if (this.property.object) {
|
|
2147
|
-
await ObjectPropertyTreeElement.populate(this, this.property, false, false, this.linkifier);
|
|
2148
|
-
if (this.childCount() > this.maxNumPropertiesToShow) {
|
|
2149
|
-
this.createShowAllPropertiesButton();
|
|
2150
|
-
}
|
|
2151
|
-
}
|
|
2152
|
-
}
|
|
2153
|
-
|
|
2154
|
-
override onattach(): void {
|
|
2155
|
-
this.updateExpandable();
|
|
2156
|
-
this.#widget.show(this.listItemElement);
|
|
2157
|
-
this.#widget.property = this.property;
|
|
2158
|
-
this.#widget.linkifier = this.linkifier;
|
|
2159
|
-
this.#widget.editable = !this.property.readOnly;
|
|
2160
|
-
}
|
|
2161
|
-
|
|
2162
|
-
override onexpand(): void {
|
|
2163
|
-
this.property.expanded = true;
|
|
2164
|
-
this.#widget.expanded = true;
|
|
2165
|
-
}
|
|
2166
|
-
|
|
2167
|
-
override oncollapse(): void {
|
|
2168
|
-
this.property.expanded = false;
|
|
2169
|
-
this.#widget.expanded = false;
|
|
2170
|
-
}
|
|
2171
|
-
|
|
2172
|
-
#updateValue(): void {
|
|
2173
|
-
this.updateExpandable();
|
|
2174
|
-
}
|
|
2175
|
-
|
|
2176
|
-
#updateChildren(): void {
|
|
2177
|
-
this.removeChildren();
|
|
2178
|
-
void this.onpopulate();
|
|
2179
|
-
}
|
|
2180
|
-
|
|
2181
|
-
#updateFilter(): void {
|
|
2182
|
-
this.hidden = this.property.isFiltered;
|
|
2183
|
-
}
|
|
2184
|
-
|
|
2185
|
-
#onExpandedChanged(event: Common.EventTarget.EventTargetEvent<boolean>): void {
|
|
2186
|
-
const expanded = event.data;
|
|
2187
|
-
if (expanded) {
|
|
2188
|
-
this.expand();
|
|
2189
|
-
} else {
|
|
2190
|
-
this.collapse();
|
|
2191
|
-
}
|
|
2192
|
-
}
|
|
2193
|
-
|
|
2194
|
-
private contextMenuFired(event: Event): void {
|
|
2195
|
-
const contextMenu = new UI.ContextMenu.ContextMenu(event);
|
|
2196
|
-
populateObjectTreeContextMenu(contextMenu, this.property, {
|
|
2197
|
-
expandRecursively: () => this.expandRecursively(EXPANDABLE_MAX_DEPTH),
|
|
2198
|
-
collapseChildren: () => this.collapseChildren(),
|
|
2199
|
-
sortPropertiesAlphabetically: node => {
|
|
2200
|
-
node.sortPropertiesAlphabetically = !node.sortPropertiesAlphabetically;
|
|
2201
|
-
},
|
|
2202
|
-
onShowAllToggled: node => {
|
|
2203
|
-
node.includeNullOrUndefinedValues = !node.includeNullOrUndefinedValues;
|
|
2204
|
-
},
|
|
2205
|
-
});
|
|
2206
|
-
|
|
2207
|
-
void contextMenu.show();
|
|
2208
|
-
}
|
|
2209
|
-
|
|
2210
|
-
private updateExpandable(): void {
|
|
2211
|
-
if (this.property.object) {
|
|
2212
|
-
this.setExpandable(!this.property.object.customPreview() && this.property.object.hasChildren &&
|
|
2213
|
-
!this.property.property.wasThrown);
|
|
2214
|
-
} else {
|
|
2215
|
-
this.setExpandable(false);
|
|
2216
|
-
}
|
|
2217
|
-
}
|
|
2218
|
-
}
|
|
2219
|
-
|
|
2220
|
-
async function arrayRangeGroups(object: SDK.RemoteObject.RemoteObject, fromIndex: number,
|
|
2221
|
-
toIndex: number): Promise<{ranges: number[][]}|null|undefined> {
|
|
2222
|
-
return await object.callFunctionJSON(packArrayRanges, [
|
|
2223
|
-
{value: fromIndex},
|
|
2224
|
-
{value: toIndex},
|
|
2225
|
-
{value: ARRAY_BUCKET_THRESHOLD},
|
|
2226
|
-
{value: ARRAY_SPARSE_ITERATION_THRESHOLD},
|
|
2227
|
-
]);
|
|
2228
|
-
|
|
2229
|
-
/**
|
|
2230
|
-
* This function is called on the RemoteObject.
|
|
2231
|
-
* Note: must declare params as optional.
|
|
2232
|
-
*/
|
|
2233
|
-
function packArrayRanges(this: Object, fromIndex?: number, toIndex?: number, bucketThreshold?: number,
|
|
2234
|
-
sparseIterationThreshold?: number): {
|
|
2235
|
-
ranges: number[][],
|
|
2236
|
-
}|undefined {
|
|
2237
|
-
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined ||
|
|
2238
|
-
bucketThreshold === undefined) {
|
|
2239
|
-
return;
|
|
2240
|
-
}
|
|
2241
|
-
let ownPropertyNames: string[]|null = null;
|
|
2242
|
-
const consecutiveRange = (toIndex - fromIndex >= sparseIterationThreshold) && ArrayBuffer.isView(this);
|
|
2243
|
-
|
|
2244
|
-
function* arrayIndexes(object: Object): Generator<number, void, unknown> {
|
|
2245
|
-
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined) {
|
|
2246
|
-
return;
|
|
2247
|
-
}
|
|
2248
|
-
|
|
2249
|
-
if (toIndex - fromIndex < sparseIterationThreshold) {
|
|
2250
|
-
for (let i = fromIndex; i <= toIndex; ++i) {
|
|
2251
|
-
if (i in object) {
|
|
2252
|
-
yield i;
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
} else {
|
|
2256
|
-
ownPropertyNames = ownPropertyNames || Object.getOwnPropertyNames(object);
|
|
2257
|
-
for (let i = 0; i < ownPropertyNames.length; ++i) {
|
|
2258
|
-
const name = ownPropertyNames[i];
|
|
2259
|
-
|
|
2260
|
-
const index = Number(name) >>> 0;
|
|
2261
|
-
if ((String(index)) === name && fromIndex <= index && index <= toIndex) {
|
|
2262
|
-
yield index;
|
|
2263
|
-
}
|
|
2264
|
-
}
|
|
2265
|
-
}
|
|
2266
|
-
}
|
|
2267
|
-
|
|
2268
|
-
let count = 0;
|
|
2269
|
-
if (consecutiveRange) {
|
|
2270
|
-
count = toIndex - fromIndex + 1;
|
|
2271
|
-
} else {
|
|
2272
|
-
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
2273
|
-
for (const ignored of arrayIndexes(this)) {
|
|
2274
|
-
++count;
|
|
2275
|
-
}
|
|
2276
|
-
}
|
|
2277
|
-
|
|
2278
|
-
let bucketSize: number = count;
|
|
2279
|
-
if (count <= bucketThreshold) {
|
|
2280
|
-
bucketSize = count;
|
|
2281
|
-
} else {
|
|
2282
|
-
bucketSize = Math.pow(bucketThreshold, Math.ceil(Math.log(count) / Math.log(bucketThreshold)) - 1);
|
|
2283
|
-
}
|
|
2284
|
-
|
|
2285
|
-
const ranges = [];
|
|
2286
|
-
if (consecutiveRange) {
|
|
2287
|
-
for (let i = fromIndex; i <= toIndex; i += bucketSize) {
|
|
2288
|
-
const groupStart = i;
|
|
2289
|
-
let groupEnd: number = groupStart + bucketSize - 1;
|
|
2290
|
-
if (groupEnd > toIndex) {
|
|
2291
|
-
groupEnd = toIndex;
|
|
2292
|
-
}
|
|
2293
|
-
ranges.push([groupStart, groupEnd, groupEnd - groupStart + 1]);
|
|
2294
|
-
}
|
|
2295
|
-
} else {
|
|
2296
|
-
count = 0;
|
|
2297
|
-
let groupStart = -1;
|
|
2298
|
-
let groupEnd = 0;
|
|
2299
|
-
for (const i of arrayIndexes(this)) {
|
|
2300
|
-
if (groupStart === -1) {
|
|
2301
|
-
groupStart = i;
|
|
2302
|
-
}
|
|
2303
|
-
groupEnd = i;
|
|
2304
|
-
if (++count === bucketSize) {
|
|
2305
|
-
ranges.push([groupStart, groupEnd, count]);
|
|
2306
|
-
count = 0;
|
|
2307
|
-
groupStart = -1;
|
|
2308
|
-
}
|
|
2309
|
-
}
|
|
2310
|
-
if (count > 0) {
|
|
2311
|
-
ranges.push([groupStart, groupEnd, count]);
|
|
2312
|
-
}
|
|
2313
|
-
}
|
|
2314
|
-
|
|
2315
|
-
return {ranges};
|
|
2316
|
-
}
|
|
2317
|
-
}
|
|
2318
|
-
|
|
2319
|
-
/**
|
|
2320
|
-
* This function is called on the RemoteObject.
|
|
2321
|
-
*/
|
|
2322
|
-
function buildArrayFragment(
|
|
2323
|
-
this: Record<number, Object>,
|
|
2324
|
-
fromIndex?: number,
|
|
2325
|
-
toIndex?: number,
|
|
2326
|
-
sparseIterationThreshold?: number,
|
|
2327
|
-
): unknown {
|
|
2328
|
-
const result = Object.create(null);
|
|
2329
|
-
|
|
2330
|
-
if (fromIndex === undefined || toIndex === undefined || sparseIterationThreshold === undefined) {
|
|
2331
|
-
return;
|
|
2332
|
-
}
|
|
2333
|
-
|
|
2334
|
-
if (toIndex - fromIndex < sparseIterationThreshold) {
|
|
2335
|
-
for (let i = fromIndex; i <= toIndex; ++i) {
|
|
2336
|
-
if (i in this) {
|
|
2337
|
-
result[i] = this[i];
|
|
2338
|
-
}
|
|
2339
|
-
}
|
|
2340
|
-
} else {
|
|
2341
|
-
const ownPropertyNames = Object.getOwnPropertyNames(this);
|
|
2342
|
-
for (let i = 0; i < ownPropertyNames.length; ++i) {
|
|
2343
|
-
const name = ownPropertyNames[i];
|
|
2344
|
-
const index = Number(name) >>> 0;
|
|
2345
|
-
if (String(index) === name && fromIndex <= index && index <= toIndex) {
|
|
2346
|
-
result[index] = this[index];
|
|
2347
|
-
}
|
|
2348
|
-
}
|
|
2349
|
-
}
|
|
2350
|
-
return result;
|
|
2351
|
-
}
|
|
2352
|
-
|
|
2353
|
-
class ArrayGroupingTreeElement extends UI.TreeOutline.TreeElement {
|
|
2354
|
-
override toggleOnClick: boolean;
|
|
2355
|
-
private readonly linkifier: Components.Linkifier.Linkifier|undefined;
|
|
2356
|
-
readonly #child: ArrayGroupTreeNode;
|
|
2357
|
-
constructor(child: ArrayGroupTreeNode, linkifier?: Components.Linkifier.Linkifier) {
|
|
2358
|
-
super(Platform.StringUtilities.sprintf('[%d … %d]', child.range.fromIndex, child.range.toIndex), true);
|
|
2359
|
-
this.#child = child;
|
|
2360
|
-
this.#child.addEventListener(ObjectTreeNodeBase.Events.CHILDREN_CHANGED, this.onpopulate, this);
|
|
2361
|
-
this.#child.addEventListener(ObjectTreeNodeBase.Events.EXPANDED_CHANGED, this.#onExpandedChanged, this);
|
|
2362
|
-
this.toggleOnClick = true;
|
|
2363
|
-
this.linkifier = linkifier;
|
|
2364
|
-
if (child.expanded) {
|
|
2365
|
-
this.expand();
|
|
2366
|
-
}
|
|
2367
|
-
}
|
|
2368
|
-
|
|
2369
|
-
#onExpandedChanged(event: Common.EventTarget.EventTargetEvent<boolean>): void {
|
|
2370
|
-
const expanded = event.data;
|
|
2371
|
-
if (expanded) {
|
|
2372
|
-
this.expand();
|
|
2373
|
-
} else {
|
|
2374
|
-
this.collapse();
|
|
2375
|
-
}
|
|
2376
|
-
}
|
|
2377
|
-
|
|
2378
|
-
static *
|
|
2379
|
-
createNodes(children: NodeChildren, linkifier?: Components.Linkifier.Linkifier,
|
|
2380
|
-
isNotDisplayablePropertyCallback?: (property: SDK.RemoteObject.RemoteObjectProperty) => boolean):
|
|
2381
|
-
Generator<UI.TreeOutline.TreeElement> {
|
|
2382
|
-
if (!children.arrayRanges) {
|
|
2383
|
-
return;
|
|
2384
|
-
}
|
|
2385
|
-
if (children.arrayRanges.length === 1) {
|
|
2386
|
-
yield*
|
|
2387
|
-
ObjectPropertyTreeElement.createNodes(children.arrayRanges[0], false, false, linkifier, null,
|
|
2388
|
-
isNotDisplayablePropertyCallback);
|
|
2389
|
-
} else {
|
|
2390
|
-
for (const child of children.arrayRanges) {
|
|
2391
|
-
if (child.singular) {
|
|
2392
|
-
yield*
|
|
2393
|
-
ObjectPropertyTreeElement.createNodes(child, false, false, linkifier, null,
|
|
2394
|
-
isNotDisplayablePropertyCallback);
|
|
2395
|
-
} else {
|
|
2396
|
-
yield new ArrayGroupingTreeElement(child, linkifier);
|
|
2397
|
-
}
|
|
2398
|
-
}
|
|
2399
|
-
}
|
|
2400
|
-
|
|
2401
|
-
yield*
|
|
2402
|
-
ObjectPropertyTreeElement.createPropertyNodes(children, false, false, linkifier, null,
|
|
2403
|
-
isNotDisplayablePropertyCallback);
|
|
2404
|
-
}
|
|
2405
|
-
|
|
2406
|
-
override onexpand(): void {
|
|
2407
|
-
this.#child.expanded = true;
|
|
2408
|
-
}
|
|
2409
|
-
|
|
2410
|
-
override oncollapse(): void {
|
|
2411
|
-
this.#child.expanded = false;
|
|
2412
|
-
}
|
|
2413
|
-
|
|
2414
|
-
override async onpopulate(): Promise<void> {
|
|
2415
|
-
this.removeChildren();
|
|
2416
|
-
await ObjectPropertyTreeElement.populate(this, this.#child, false, false, this.linkifier);
|
|
2417
|
-
}
|
|
2418
|
-
|
|
2419
|
-
override onattach(): void {
|
|
2420
|
-
this.listItemElement.classList.add('object-properties-section-name');
|
|
2421
|
-
}
|
|
2422
|
-
}
|
|
2423
|
-
|
|
2424
2278
|
interface ExpandableTextViewInput {
|
|
2425
2279
|
copyText: () => void;
|
|
2426
2280
|
expandText: () => void;
|