fix(rome_playground): Unicode Support
They playground crashed because `btoa` only supports ASCII.
This PR ensures that non ASCII characters are propertly encoded before running the code throuh `btoa`.
MODIFY
.github/workflows/deploy_playground.yml
.github/workflows/deploy_playground.yml
@@ -22,7 +22,7 @@ jobs:
node-version: '14'
- run: npm install --prefix crates/rome_playground
- uses: jetli/wasm-pack-action@v0.3.0
- - run: wasm-pack build crates/rome_playground --target web
+ - run: wasm-pack build crates/rome_playground --target web --release
- run: npm run build --prefix crates/rome_playground
- name: Publish
uses: cloudflare/wrangler-action@1.3.0

MODIFY
crates/rome_playground/src/App.tsx
crates/rome_playground/src/App.tsx
@@ -62,9 +62,7 @@ function App() {
const searchParams = new URLSearchParams(window.location.search);
const [loadingState, setLoadingState] = useState(LoadingState.Loading);
- const [code, setCode] = useState(
- window.location.hash !== "#" ? atob(window.location.hash.substring(1)) : "",
- );
+ const [code, setCode] = useState(() => window.location.hash !== "#" ? decodeCode(window.location.hash.substring(1)) : "");
const [lineWidth, setLineWidth] = useState(
parseInt(searchParams.get("lineWidth") ?? "80"),
);
@@ -79,18 +77,11 @@ function App() {
);
const [isJsx, setIsJsx] = useState(searchParams.get("jsx") === "true");
- const language = useMemo(
- () => {
- return getLanguage(isJsx, isTypeScript);
- },
- [isJsx, isTypeScript],
- );
+ const language = getLanguage(isJsx, isTypeScript);
useEffect(
() => {
- const url = `${window.location.protocol}//${window.location.host}${window.location.pathname}?lineWidth=${lineWidth}&indentStyle=${indentStyle}&indentWidth=${indentWidth}&typescript=${isTypeScript}&jsx=${isJsx}#${btoa(
- code,
- )}`;
+ const url = `${window.location.protocol}//${window.location.host}${window.location.pathname}?lineWidth=${lineWidth}&indentStyle=${indentStyle}&indentWidth=${indentWidth}&typescript=${isTypeScript}&jsx=${isJsx}#${encodeCode(code)}`;
window.history.pushState({ path: url }, "", url);
},
[lineWidth, indentStyle, indentWidth, code, isTypeScript, isJsx],
@@ -219,4 +210,42 @@ function App() {
}
}
+// See https://developer.mozilla.org/en-US/docs/Web/API/btoa#unicode_strings
+function encodeCode(code: string): string {
+ return btoa(toBinary(code));
+}
+
+function decodeCode(encoded: string): string {
+ return fromBinary(atob(encoded))
+}
+
+// convert a Unicode string to a string in which
+// each 16-bit unit occupies only one byte
+function toBinary(input: string) {
+ const codeUnits = new Uint16Array(input.length);
+ for (let i = 0; i < codeUnits.length; i++) {
+ codeUnits[i] = input.charCodeAt(i);
+ }
+
+ const charCodes = new Uint8Array(codeUnits.buffer);
+ let result = '';
+ for (let i = 0; i < charCodes.byteLength; i++) {
+ result += String.fromCharCode(charCodes[i]);
+ }
+ return result;
+}
+
+function fromBinary(binary: string) {
+ const bytes = new Uint8Array(binary.length);
+ for (let i = 0; i < bytes.length; i++) {
+ bytes[i] = binary.charCodeAt(i);
+ }
+ const charCodes = new Uint16Array(bytes.buffer);
+ let result = '';
+ for (let i = 0; i < charCodes.length; i++) {
+ result += String.fromCharCode(charCodes[i]);
+ }
+ return result;
+}
+
export default App;

fix(rome_playground): Unicode Support (#2332)

They playground crashed because `btoa` only supports ASCII.
This PR ensures that non ASCII characters are propertly encoded before running the code throuh `btoa`.