@@ -27,7 +27,7 @@ import {
2727 setSavedComponentFilters ,
2828 separateDisplayNameAndHOCs ,
2929 shallowDiffers ,
30- utfDecodeString ,
30+ utfDecodeStringWithRanges ,
3131} from '../utils' ;
3232import { localStorageGetItem , localStorageSetItem } from '../storage' ;
3333import { __DEBUG__ } from '../constants' ;
@@ -450,7 +450,7 @@ export default class Store extends EventEmitter<{
450450 }
451451
452452 // 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.
454454 get supportsProfiling ( ) : boolean {
455455 return this . _supportsProfiling ;
456456 }
@@ -467,7 +467,7 @@ export default class Store extends EventEmitter<{
467467 }
468468
469469 // 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.
471471 get supportsTimeline ( ) : boolean {
472472 return this . _supportsTimeline ;
473473 }
@@ -502,30 +502,58 @@ export default class Store extends EventEmitter<{
502502 }
503503
504504 // Find which root this element is in...
505- let rootID ;
506505 let root ;
507506 let rootWeight = 0 ;
508507 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+
511521 if ( root . children . length === 0 ) {
512522 continue ;
513- } else if ( rootWeight + root . weight > index ) {
523+ }
524+
525+ if ( rootWeight + root . weight > index ) {
514526 break ;
515527 } else {
516528 rootWeight += root . weight ;
517529 }
518530 }
519531
532+ if ( root === undefined ) {
533+ return null ;
534+ }
535+
520536 // Find the element in the tree using the weight of each node...
521537 // 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 ;
523539 let currentWeight = rootWeight - 1 ;
540+
524541 while ( index !== currentWeight ) {
525542 const numChildren = currentElement . children . length ;
526543 for ( let i = 0 ; i < numChildren ; i ++ ) {
527544 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+
529557 const childWeight = child . isCollapsed ? 1 : child . weight ;
530558
531559 if ( index <= currentWeight + childWeight ) {
@@ -538,7 +566,7 @@ export default class Store extends EventEmitter<{
538566 }
539567 }
540568
541- return ( ( currentElement : any ) : Element ) || null ;
569+ return currentElement || null ;
542570 }
543571
544572 getElementIDAtIndex ( index : number ) : number | null {
@@ -560,32 +588,31 @@ export default class Store extends EventEmitter<{
560588 getElementsWithErrorsAndWarnings ( ) : Array < { id : number , index : number } > {
561589 if ( this . _cachedErrorAndWarningTuples !== null ) {
562590 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+ }
579592
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+ }
581607 }
582- } ) ;
583608
584- // Cache for later (at least until the tree changes again).
585- this . _cachedErrorAndWarningTuples = errorAndWarningTuples ;
609+ errorAndWarningTuples . splice ( low , 0 , { id, index} ) ;
610+ }
611+ } ) ;
586612
587- return errorAndWarningTuples ;
588- }
613+ // Cache for later (at least until the tree changes again).
614+ this . _cachedErrorAndWarningTuples = errorAndWarningTuples ;
615+ return errorAndWarningTuples ;
589616 }
590617
591618 getErrorAndWarningCountForElementID ( id : number ) : {
@@ -923,7 +950,11 @@ export default class Store extends EventEmitter<{
923950 const nextLength = operations [ i ] ;
924951 i ++ ;
925952
926- const nextString = utfDecodeString ( operations . slice ( i , i + nextLength ) ) ;
953+ const nextString = utfDecodeStringWithRanges (
954+ operations ,
955+ i ,
956+ i + nextLength - 1 ,
957+ ) ;
927958 stringTable . push ( nextString ) ;
928959 i += nextLength ;
929960 }
@@ -1035,7 +1066,7 @@ export default class Store extends EventEmitter<{
10351066 ) ,
10361067 ) ;
10371068
1038- continue ;
1069+ break ;
10391070 }
10401071
10411072 parentElement . children . push ( id ) ;
@@ -1088,7 +1119,7 @@ export default class Store extends EventEmitter<{
10881119 ) ,
10891120 ) ;
10901121
1091- continue ;
1122+ break ;
10921123 }
10931124
10941125 i += 1 ;
@@ -1126,7 +1157,7 @@ export default class Store extends EventEmitter<{
11261157 ) ,
11271158 ) ;
11281159
1129- continue ;
1160+ break ;
11301161 }
11311162
11321163 const index = parentElement . children . indexOf ( id ) ;
@@ -1172,7 +1203,17 @@ export default class Store extends EventEmitter<{
11721203 }
11731204 } ;
11741205
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+
11761217 recursivelyDeleteElements ( id ) ;
11771218
11781219 this . _rootIDToCapabilities . delete ( id ) ;
@@ -1194,7 +1235,7 @@ export default class Store extends EventEmitter<{
11941235 ) ,
11951236 ) ;
11961237
1197- continue ;
1238+ break ;
11981239 }
11991240
12001241 const children = element . children ;
@@ -1279,7 +1320,7 @@ export default class Store extends EventEmitter<{
12791320
12801321 this . _revision ++ ;
12811322
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.
12831324 this . _cachedErrorAndWarningTuples = null ;
12841325
12851326 if ( haveErrorsOrWarningsChanged ) {
0 commit comments