|
7 | 7 | * @flow
|
8 | 8 | */
|
9 | 9 |
|
10 |
| -import LRU from 'lru-cache'; |
11 | 10 | import {
|
12 | 11 | isElement,
|
13 | 12 | typeOf,
|
@@ -50,19 +49,9 @@ import {localStorageGetItem, localStorageSetItem} from './storage';
|
50 | 49 | import {meta} from './hydration';
|
51 | 50 |
|
52 | 51 | import type {ComponentFilter, ElementType} from './types';
|
53 |
| -import type {LRUCache} from 'react-devtools-shared/src/types'; |
54 | 52 |
|
55 | 53 | const cachedDisplayNames: WeakMap<Function, string> = new WeakMap();
|
56 | 54 |
|
57 |
| -// On large trees, encoding takes significant time. |
58 |
| -// Try to reuse the already encoded strings. |
59 |
| -const encodedStringCache: LRUCache< |
60 |
| - string, |
61 |
| - Array<number> | Uint8Array, |
62 |
| -> = new LRU({ |
63 |
| - max: 1000, |
64 |
| -}); |
65 |
| - |
66 | 55 | export function alphaSortKeys(
|
67 | 56 | a: string | number | Symbol,
|
68 | 57 | b: string | number | Symbol,
|
@@ -128,47 +117,44 @@ export function getUID(): number {
|
128 | 117 | return ++uidCounter;
|
129 | 118 | }
|
130 | 119 |
|
131 |
| -const isTextEncoderSupported = |
132 |
| - typeof TextDecoder === 'function' && typeof TextEncoder === 'function'; |
133 |
| - |
134 | 120 | export function utfDecodeString(array: Array<number>): string {
|
135 |
| - if (isTextEncoderSupported) { |
136 |
| - // Handles multi-byte characters; use if available. |
137 |
| - return new TextDecoder().decode(new Uint8Array(array)); |
138 |
| - } else { |
139 |
| - // Avoid spreading the array (e.g. String.fromCodePoint(...array)) |
140 |
| - // Functions arguments are first placed on the stack before the function is called |
141 |
| - // which throws a RangeError for large arrays. |
142 |
| - // See github.com/facebook/react/issues/22293 |
143 |
| - let string = ''; |
144 |
| - for (let i = 0; i < array.length; i++) { |
145 |
| - const char = array[i]; |
146 |
| - string += String.fromCodePoint(char); |
147 |
| - } |
148 |
| - return string; |
| 121 | + // Avoid spreading the array (e.g. String.fromCodePoint(...array)) |
| 122 | + // Functions arguments are first placed on the stack before the function is called |
| 123 | + // which throws a RangeError for large arrays. |
| 124 | + // See github.com/facebook/react/issues/22293 |
| 125 | + let string = ''; |
| 126 | + for (let i = 0; i < array.length; i++) { |
| 127 | + const char = array[i]; |
| 128 | + string += String.fromCodePoint(char); |
149 | 129 | }
|
| 130 | + return string; |
150 | 131 | }
|
151 | 132 |
|
152 |
| -export function utfEncodeString(string: string): Array<number> | Uint8Array { |
153 |
| - const cached = encodedStringCache.get(string); |
154 |
| - if (cached !== undefined) { |
155 |
| - return cached; |
156 |
| - } |
| 133 | +function surrogatePairToCodePoint( |
| 134 | + charCode1: number, |
| 135 | + charCode2: number, |
| 136 | +): number { |
| 137 | + return ((charCode1 & 0x3ff) << 10) + (charCode2 & 0x3ff) + 0x10000; |
| 138 | +} |
157 | 139 |
|
158 |
| - let encoded; |
159 |
| - if (isTextEncoderSupported) { |
160 |
| - // Handles multi-byte characters; use if available. |
161 |
| - encoded = new TextEncoder().encode(string); |
162 |
| - } else { |
163 |
| - encoded = new Array(string.length); |
164 |
| - for (let i = 0; i < string.length; i++) { |
165 |
| - encoded[i] = string.codePointAt(i); |
| 140 | +// Credit for this encoding approach goes to Tim Down: |
| 141 | +// https://stackoverflow.com/questions/4877326/how-can-i-tell-if-a-string-contains-multibyte-characters-in-javascript |
| 142 | +export function utfEncodeString(string: string): Array<number> { |
| 143 | + const codePoints = []; |
| 144 | + let i = 0; |
| 145 | + let charCode; |
| 146 | + while (i < string.length) { |
| 147 | + charCode = string.charCodeAt(i); |
| 148 | + if ((charCode & 0xf800) === 0xd800) { |
| 149 | + codePoints.push( |
| 150 | + surrogatePairToCodePoint(charCode, string.charCodeAt(++i)), |
| 151 | + ); |
| 152 | + } else { |
| 153 | + codePoints.push(charCode); |
166 | 154 | }
|
| 155 | + ++i; |
167 | 156 | }
|
168 |
| - |
169 |
| - encodedStringCache.set(string, encoded); |
170 |
| - |
171 |
| - return encoded; |
| 157 | + return codePoints; |
172 | 158 | }
|
173 | 159 |
|
174 | 160 | export function printOperationsArray(operations: Array<number>) {
|
|
0 commit comments