From 4ee74f7e6c8b918bec5414aa6289c3009864c136 Mon Sep 17 00:00:00 2001 From: Jessica Date: Tue, 19 Feb 2019 15:52:03 +0900 Subject: [PATCH 1/2] Fix encoding of Unicode keys greater than U+00FF (greater than U+FFFF handled by surrogate pairs) --- src/backend/renderer.js | 2 ++ src/utils.js | 6 +++--- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/backend/renderer.js b/src/backend/renderer.js index f856431317..8bf1865af6 100644 --- a/src/backend/renderer.js +++ b/src/backend/renderer.js @@ -566,6 +566,8 @@ export function attach( if (key !== null) { if (typeof key === 'number') { + // unreachable code? + // https://github.com/facebook/react/blob/master/packages/react/src/ReactElement.js#L187 encodedKey = new Uint8Array(1); encodedKey[0] = key; } else { diff --git a/src/utils.js b/src/utils.js index 0f87d8a837..1dcd00e807 100644 --- a/src/utils.js +++ b/src/utils.js @@ -51,7 +51,7 @@ export function getUID(): number { return ++uidCounter; } -export function utfDecodeString(array: Uint8Array): string { +export function utfDecodeString(array: Uint16Array): string { let string = ''; const { length } = array; for (let i = 0; i < length; i++) { @@ -60,8 +60,8 @@ export function utfDecodeString(array: Uint8Array): string { return string; } -export function utfEncodeString(string: string): Uint8Array { - const array = new Uint8Array(string.length); +export function utfEncodeString(string: string): Uint16Array { + const array = new Uint16Array(string.length); const { length } = string; for (let i = 0; i < length; i++) { array[i] = string.charCodeAt(i); From 65d493cae9b3697c96650ae0c973afb71c873f68 Mon Sep 17 00:00:00 2001 From: Jessica Date: Tue, 19 Feb 2019 16:03:53 +0900 Subject: [PATCH 2/2] Just use codepoints as it'll be copied into an Uint32Array anyway --- src/utils.js | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/utils.js b/src/utils.js index 1dcd00e807..9c2c9189b9 100644 --- a/src/utils.js +++ b/src/utils.js @@ -51,20 +51,15 @@ export function getUID(): number { return ++uidCounter; } -export function utfDecodeString(array: Uint16Array): string { - let string = ''; - const { length } = array; - for (let i = 0; i < length; i++) { - string += String.fromCharCode(array[i]); - } - return string; +export function utfDecodeString(array: Uint32Array): string { + return String.fromCodePoint(...array); } -export function utfEncodeString(string: string): Uint16Array { - const array = new Uint16Array(string.length); - const { length } = string; - for (let i = 0; i < length; i++) { - array[i] = string.charCodeAt(i); - } - return array; +export function utfEncodeString(string: string): Uint32Array { + // $FlowFixMe Flow's Uint32Array.from's type definition is wrong; first argument of mapFn will be string + return Uint32Array.from(string, toCodePoint); +} + +function toCodePoint(string: string) { + return string.codePointAt(0); }