From 07afbf17dec8e403248711421f2dc5bc82d71719 Mon Sep 17 00:00:00 2001 From: Hatem Hosny Date: Sun, 11 Oct 2026 07:35:23 +0300 Subject: [PATCH 1/2] fix flutter page encoding --- .../languages/flutter/lang-flutter-script.ts | 28 +++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/livecodes/languages/flutter/lang-flutter-script.ts b/src/livecodes/languages/flutter/lang-flutter-script.ts index edc52057d..11e42fe3d 100644 --- a/src/livecodes/languages/flutter/lang-flutter-script.ts +++ b/src/livecodes/languages/flutter/lang-flutter-script.ts @@ -1,4 +1,32 @@ import { setupDartRuntime } from '../dart/lang-dart-runtime'; +// The result page is served without a UTF-8 charset, so the browser falls back to its default +// (windows-1252). The Dart/Flutter SDK loads its large, non-ASCII runtime scripts as +// `text/javascript` blobs, and a blob script with no charset inherits the document's encoding, +// which corrupts the SDK's data tables — an `Uri.parse` then throws +// `RangeError (index): Index out of range`. Tagging those JS blobs with UTF-8 keeps the SDK +// decoding correctly however the page is served. +const forceUtf8ScriptBlobs = () => { + const scope = globalThis as any; + const OriginalBlob = scope.Blob; + if (typeof OriginalBlob !== 'function' || OriginalBlob.livecodesUtf8) return; + + const Utf8Blob = function (parts: any, options: any) { + if ( + options && + typeof options.type === 'string' && + /^(text|application)\/(java|ecma)script$/.test(options.type) + ) { + options = { ...options, type: `${options.type};charset=utf-8` }; + } + return new OriginalBlob(parts, options); + }; + Utf8Blob.prototype = OriginalBlob.prototype; + Utf8Blob.livecodesUtf8 = true; + scope.Blob = Utf8Blob; +}; + +forceUtf8ScriptBlobs(); + // Flutter renders into the result page, which is also where the compiled Dart runs. setupDartRuntime('flutter'); From 1022bf2bd2893b2626f347dde8b0a64078fb3b5e Mon Sep 17 00:00:00 2001 From: "pullfrog[bot]" <226033991+pullfrog[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2026 05:04:26 +0000 Subject: [PATCH 2/2] fix: apply utf-8 script blob patch to dart engine too --- .../languages/dart/lang-dart-runtime.ts | 27 ++++++++++++++++++ .../languages/flutter/lang-flutter-script.ts | 28 ------------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/livecodes/languages/dart/lang-dart-runtime.ts b/src/livecodes/languages/dart/lang-dart-runtime.ts index 234599e4b..4c2f0b2bd 100644 --- a/src/livecodes/languages/dart/lang-dart-runtime.ts +++ b/src/livecodes/languages/dart/lang-dart-runtime.ts @@ -3,7 +3,34 @@ import { dartWasmBaseUrl } from '../../vendors'; declare const window: any; declare const parent: any; +// The result page is served without a UTF-8 charset, so the browser falls back to its default +// (windows-1252). The Dart/Flutter SDK loads its large, non-ASCII runtime scripts as +// `text/javascript` blobs, and a blob script with no charset inherits the document's encoding, +// which corrupts the SDK's data tables — an `Uri.parse` then throws +// `RangeError (index): Index out of range`. Tagging those JS blobs with UTF-8 keeps the SDK +// decoding correctly however the page is served. Both engines load through the same blob path. +const forceUtf8ScriptBlobs = () => { + const scope = globalThis as any; + const OriginalBlob = scope.Blob; + if (typeof OriginalBlob !== 'function' || OriginalBlob.livecodesUtf8) return; + + const Utf8Blob = function (parts: any, options: any) { + if ( + options && + typeof options.type === 'string' && + /^(text|application)\/(java|ecma)script$/.test(options.type) + ) { + options = { ...options, type: `${options.type};charset=utf-8` }; + } + return new OriginalBlob(parts, options); + }; + Utf8Blob.prototype = OriginalBlob.prototype; + Utf8Blob.livecodesUtf8 = true; + scope.Blob = Utf8Blob; +}; + export const setupDartRuntime = (engine: 'dart' | 'flutter') => { + forceUtf8ScriptBlobs(); window.livecodes = window.livecodes || {}; const ns = (window.livecodes[engine] = window.livecodes[engine] || {}); diff --git a/src/livecodes/languages/flutter/lang-flutter-script.ts b/src/livecodes/languages/flutter/lang-flutter-script.ts index 11e42fe3d..edc52057d 100644 --- a/src/livecodes/languages/flutter/lang-flutter-script.ts +++ b/src/livecodes/languages/flutter/lang-flutter-script.ts @@ -1,32 +1,4 @@ import { setupDartRuntime } from '../dart/lang-dart-runtime'; -// The result page is served without a UTF-8 charset, so the browser falls back to its default -// (windows-1252). The Dart/Flutter SDK loads its large, non-ASCII runtime scripts as -// `text/javascript` blobs, and a blob script with no charset inherits the document's encoding, -// which corrupts the SDK's data tables — an `Uri.parse` then throws -// `RangeError (index): Index out of range`. Tagging those JS blobs with UTF-8 keeps the SDK -// decoding correctly however the page is served. -const forceUtf8ScriptBlobs = () => { - const scope = globalThis as any; - const OriginalBlob = scope.Blob; - if (typeof OriginalBlob !== 'function' || OriginalBlob.livecodesUtf8) return; - - const Utf8Blob = function (parts: any, options: any) { - if ( - options && - typeof options.type === 'string' && - /^(text|application)\/(java|ecma)script$/.test(options.type) - ) { - options = { ...options, type: `${options.type};charset=utf-8` }; - } - return new OriginalBlob(parts, options); - }; - Utf8Blob.prototype = OriginalBlob.prototype; - Utf8Blob.livecodesUtf8 = true; - scope.Blob = Utf8Blob; -}; - -forceUtf8ScriptBlobs(); - // Flutter renders into the result page, which is also where the compiled Dart runs. setupDartRuntime('flutter');