27
setSavedComponentFilters,
28
separateDisplayNameAndHOCs,
29
shallowDiffers,
30
- utfDecodeString,
30
+ utfDecodeStringWithRanges,
31
} from '../utils';
32
import {localStorageGetItem, localStorageSetItem} from '../storage';
33
import {__DEBUG__} from '../constants';
450
}
451
452
// This build of DevTools supports the legacy profiler.
453
- // This is a static flag, controled by the Store config.
453
+ // This is a static flag, controlled by the Store config.
454
get supportsProfiling(): boolean {
455
return this._supportsProfiling;
456
}
467
}
468
469
// This build of DevTools supports the Timeline profiler.
470
- // This is a static flag, controled by the Store config.
470
+ // This is a static flag, controlled by the Store config.
471
get supportsTimeline(): boolean {
472
return this._supportsTimeline;
473
}
502
}
503
504
// Find which root this element is in...
505
- let rootID;
505
let root;
506
let rootWeight = 0;
507
for (let i = 0; i < this._roots.length; i++) {
509
- rootID = this._roots[i];
510
- root = ((this._idToElement.get(rootID): any): Element);
508
+ const rootID = this._roots[i];
509
+ root = this._idToElement.get(rootID);
510
+
511
+ if (root === undefined) {
512
+ this._throwAndEmitError(
513
+ Error(
514
+ `Couldn't find root with id "${rootID}": no matching node was found in the Store.`,
515
+ ),
516
+ );
517
+
518
+ return null;
519
+ }
520
+
521
if (root.children.length === 0) {
522
continue;
513
- } else if (rootWeight + root.weight > index) {
523
+ }
524
+
525
+ if (rootWeight + root.weight > index) {
526
break;
527
} else {
528
rootWeight += root.weight;
529
}
530
}
531
532
+ if (root === undefined) {
533
+ return null;
534
+ }
535
+
536
// Find the element in the tree using the weight of each node...
537
// Skip over the root itself, because roots aren't visible in the Elements tree.
522
- let currentElement = ((root: any): Element);
538
+ let currentElement: Element = root;
539
let currentWeight = rootWeight - 1;
540
+
541
while (index !== currentWeight) {
542
const numChildren = currentElement.children.length;
543
for (let i = 0; i < numChildren; i++) {
544
const childID = currentElement.children[i];
528
- const child = ((this._idToElement.get(childID): any): Element);
545
+ const child = this._idToElement.get(childID);
546
+
547
+ if (child === undefined) {
548
+ this._throwAndEmitError(
549
+ Error(
550
+ `Couldn't child element with id "${childID}": no matching node was found in the Store.`,
551
+ ),
552
+ );
553
+
554
+ return null;
555
+ }
556
+
557
const childWeight = child.isCollapsed ? 1 : child.weight;
558
559
if (index <= currentWeight + childWeight) {
566
}
567
}
568
541
- return ((currentElement: any): Element) || null;
569
+ return currentElement || null;
570
}
571
572
getElementIDAtIndex(index: number): number | null {
588
getElementsWithErrorsAndWarnings(): Array<{id: number, index: number}> {
589
if (this._cachedErrorAndWarningTuples !== null) {
590
return this._cachedErrorAndWarningTuples;
563
- } else {
564
- const errorAndWarningTuples: ErrorAndWarningTuples = [];
565
-
566
- this._errorsAndWarnings.forEach((_, id) => {
567
- const index = this.getIndexOfElementID(id);
568
- if (index !== null) {
569
- let low = 0;
570
- let high = errorAndWarningTuples.length;
571
- while (low < high) {
572
- const mid = (low + high) >> 1;
573
- if (errorAndWarningTuples[mid].index > index) {
574
- high = mid;
575
- } else {
576
- low = mid + 1;
577
- }
578
- }
591
+ }
592
580
- errorAndWarningTuples.splice(low, 0, {id, index});
593
+ const errorAndWarningTuples: ErrorAndWarningTuples = [];
594
+
595
+ this._errorsAndWarnings.forEach((_, id) => {
596
+ const index = this.getIndexOfElementID(id);
597
+ if (index !== null) {
598
+ let low = 0;
599
+ let high = errorAndWarningTuples.length;
600
+ while (low < high) {
601
+ const mid = (low + high) >> 1;
602
+ if (errorAndWarningTuples[mid].index > index) {
603
+ high = mid;
604
+ } else {
605
+ low = mid + 1;
606
+ }
607
}
582
- });
608
584
- // Cache for later (at least until the tree changes again).
585
- this._cachedErrorAndWarningTuples = errorAndWarningTuples;
609
+ errorAndWarningTuples.splice(low, 0, {id, index});
610
+ }
611
+ });
612
587
- return errorAndWarningTuples;
588
- }
613
+ // Cache for later (at least until the tree changes again).
614
+ this._cachedErrorAndWarningTuples = errorAndWarningTuples;
615
+ return errorAndWarningTuples;
616
}
617
618
getErrorAndWarningCountForElementID(id: number): {
950
const nextLength = operations[i];
951
i++;
952
926
- const nextString = utfDecodeString(operations.slice(i, i + nextLength));
953
+ const nextString = utfDecodeStringWithRanges(
954
+ operations,
955
+ i,
956
+ i + nextLength - 1,
957
+ );
958
stringTable.push(nextString);
959
i += nextLength;
960
}
1066
),
1067
);
1068
1038
- continue;
1069
+ break;
1070
}
1071
1072
parentElement.children.push(id);
1119
),
1120
);
1121
1091
- continue;
1122
+ break;
1123
}
1124
1125
i += 1;
1157
),
1158
);
1159
1129
- continue;
1160
+ break;
1161
}
1162
1163
const index = parentElement.children.indexOf(id);
1203
}
1204
};
1205
1175
- const root = ((this._idToElement.get(id): any): Element);
1206
+ const root = this._idToElement.get(id);
1207
+ if (root === undefined) {
1208
+ this._throwAndEmitError(
1209
+ Error(
1210
+ `Cannot remove root "${id}": no matching node was found in the Store.`,
1211
+ ),
1212
+ );
1213
+
1214
+ break;
1215
+ }
1216
+
1217
recursivelyDeleteElements(id);
1218
1219
this._rootIDToCapabilities.delete(id);
1235
),
1236
);
1237
1197
- continue;
1238
+ break;
1239
}
1240
1241
const children = element.children;
1320
1321
this._revision++;
1322
1282
- // Any time the tree changes (e.g. elements added, removed, or reordered) cached inidices may be invalid.
1323
+ // Any time the tree changes (e.g. elements added, removed, or reordered) cached indices may be invalid.
1324
this._cachedErrorAndWarningTuples = null;
1325
1326
if (haveErrorsOrWarningsChanged) {