Merge pull request #255442 from mjbvz/sudden-octopus

Move `multibyteAwareBtoa` out of dom
This commit is contained in:
Matt Bierner
2025-07-11 13:09:05 -07:00
committed by GitHub
7 changed files with 39 additions and 36 deletions
-26
View File
@@ -1869,32 +1869,6 @@ export function safeInnerHtml(node: HTMLElement, value: string, extraDomPurifyCo
}
}
/**
* Convert a Unicode string to a string in which each 16-bit unit occupies only one byte
*
* From https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa
*/
function toBinary(str: string): string {
const codeUnits = new Uint16Array(str.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = str.charCodeAt(i);
}
let binary = '';
const uint8array = new Uint8Array(codeUnits.buffer);
for (let i = 0; i < uint8array.length; i++) {
binary += String.fromCharCode(uint8array[i]);
}
return binary;
}
/**
* Version of the global `btoa` function that handles multi-byte characters instead
* of throwing an exception.
*/
export function multibyteAwareBtoa(str: string): string {
return btoa(toBinary(str));
}
type ModifierKey = 'alt' | 'ctrl' | 'shift' | 'meta';
export interface IModifierKeyStatus {
+27
View File
@@ -1361,3 +1361,30 @@ export class InvisibleCharacters {
}
export const Ellipsis = '\u2026';
/**
* Convert a Unicode string to a string in which each 16-bit unit occupies only one byte
*
* From https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/btoa
*/
function toBinary(str: string): string {
const codeUnits = new Uint16Array(str.length);
for (let i = 0; i < codeUnits.length; i++) {
codeUnits[i] = str.charCodeAt(i);
}
let binary = '';
const uint8array = new Uint8Array(codeUnits.buffer);
for (let i = 0; i < uint8array.length; i++) {
binary += String.fromCharCode(uint8array[i]);
}
return binary;
}
/**
* Version of the global `btoa` function that handles multi-byte characters instead
* of throwing an exception.
*/
export function multibyteAwareBtoa(str: string): string {
return btoa(toBinary(str));
}
+1 -7
View File
@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import assert from 'assert';
import { $, h, multibyteAwareBtoa, trackAttributes, copyAttributes, disposableWindowInterval, getWindows, getWindowsCount, getWindowId, getWindowById, hasWindow, getWindow, getDocument, isHTMLElement, SafeTriangle } from '../../browser/dom.js';
import { $, h, trackAttributes, copyAttributes, disposableWindowInterval, getWindows, getWindowsCount, getWindowId, getWindowById, hasWindow, getWindow, getDocument, isHTMLElement, SafeTriangle } from '../../browser/dom.js';
import { asCssValueWithDefault } from '../../../base/browser/cssValue.js';
import { ensureCodeWindow, isAuxiliaryWindow, mainWindow } from '../../browser/window.js';
import { DeferredPromise, timeout } from '../../common/async.js';
@@ -76,12 +76,6 @@ suite('dom', () => {
assert(!element.classList.contains('bar'));
});
test('multibyteAwareBtoa', () => {
assert.ok(multibyteAwareBtoa('hello world').length > 0);
assert.ok(multibyteAwareBtoa('平仮名').length > 0);
assert.ok(multibyteAwareBtoa(new Array(100000).fill('vs').join('')).length > 0); // https://github.com/microsoft/vscode/issues/112013
});
suite('$', () => {
test('should build simple nodes', () => {
const div = $('div');
+6
View File
@@ -662,6 +662,12 @@ suite('Strings', () => {
assert.strictEqual(strings.InvisibleCharacters.containsInvisibleCharacter('a\u{e015a}\u000bb'), true);
});
test('multibyteAwareBtoa', () => {
assert.ok(strings.multibyteAwareBtoa('hello world').length > 0);
assert.ok(strings.multibyteAwareBtoa('平仮名').length > 0);
assert.ok(strings.multibyteAwareBtoa(new Array(100000).fill('vs').join('')).length > 0); // https://github.com/microsoft/vscode/issues/112013
});
ensureNoDisposablesAreLeakedInTestSuite();
});
@@ -3,7 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { multibyteAwareBtoa } from '../../../base/browser/dom.js';
import { multibyteAwareBtoa } from '../../../base/common/strings.js';
import { CancelablePromise, createCancelablePromise } from '../../../base/common/async.js';
import { VSBuffer } from '../../../base/common/buffer.js';
import { CancellationToken } from '../../../base/common/cancellation.js';
@@ -5,7 +5,8 @@
import './media/sidebysideeditor.css';
import { localize } from '../../../../nls.js';
import { Dimension, $, clearNode, multibyteAwareBtoa } from '../../../../base/browser/dom.js';
import { Dimension, $, clearNode } from '../../../../base/browser/dom.js';
import { multibyteAwareBtoa } from '../../../../base/common/strings.js';
import { Registry } from '../../../../platform/registry/common/platform.js';
import { IEditorControl, IEditorPane, IEditorOpenContext, EditorExtensions, SIDE_BY_SIDE_EDITOR_ID, SideBySideEditor as Side, IEditorPaneSelection, IEditorPaneWithSelection, IEditorPaneSelectionChangeEvent, isEditorPaneWithSelection, EditorPaneSelectionCompareResult } from '../../../common/editor.js';
import { SideBySideEditorInput } from '../../../common/editor/sideBySideEditorInput.js';
@@ -29,7 +29,8 @@ import { CancellationToken } from '../../../../base/common/cancellation.js';
import { EditorActivation, ITextEditorOptions } from '../../../../platform/editor/common/editor.js';
import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js';
import { isEqual } from '../../../../base/common/resources.js';
import { Dimension, multibyteAwareBtoa } from '../../../../base/browser/dom.js';
import { Dimension } from '../../../../base/browser/dom.js';
import { multibyteAwareBtoa } from '../../../../base/common/strings.js';
import { ByteSize, FileOperationError, FileOperationResult, IFileService, TooLargeFileOperationError } from '../../../../platform/files/common/files.js';
import { IBoundarySashes } from '../../../../base/browser/ui/sash/sash.js';
import { IPreferencesService } from '../../../services/preferences/common/preferences.js';