fix(mobile): use split/join for import() patch, gate behind Chrome<63 check
The regex /\bimport\(/g inside a template literal corrupts \b into a backspace and \( into (, producing an unterminated-group SyntaxError in the WebView. Use split().join() instead — no escape sequences, no corruption. Modern WebViews (Chrome 63+) keep the original clean <script>-tag path. Old WebViews (Karoo Chrome 61) take the fetch+patch+Blob path.
This commit is contained in:
@@ -77,14 +77,17 @@ var initError = null;
|
|||||||
try {
|
try {
|
||||||
_post({ type: 'progress', msg: 'Loading Python runtime…' });
|
_post({ type: 'progress', msg: 'Loading Python runtime…' });
|
||||||
|
|
||||||
// Chrome <63 (e.g. Karoo WebView 61) cannot parse the dynamic import()
|
// Chrome <63 cannot parse dynamic import() — a parse-time SyntaxError
|
||||||
// syntax that Pyodide uses to load pyodide.asm.js. The parser rejects
|
// prevents loadPyodide from ever being defined. Detect this once and
|
||||||
// the whole file before it runs, so loadPyodide is never defined.
|
// use a patched loader only for those old WebViews.
|
||||||
//
|
var chromeVer = (navigator.userAgent.match(/Chrome\\/([0-9]+)/) || [])[1];
|
||||||
// Fix: fetch pyodide.js as text, replace every "import(" with a
|
var needsPatch = chromeVer && parseInt(chromeVer) < 63;
|
||||||
// script-tag–based loader that Chrome 61 can execute, then inject the
|
|
||||||
// patched code via a Blob URL. The Blob script is never parsed by the
|
if (needsPatch) {
|
||||||
// module-aware pre-scanner, so the import keyword is invisible to it.
|
// Fetch pyodide.js as text and replace every "import(" with a
|
||||||
|
// script-tag shim before injecting via Blob URL. Using split/join
|
||||||
|
// avoids regex escape sequences, which template literals corrupt.
|
||||||
|
// Node.js import("path") calls are guarded by IN_NODE and never run.
|
||||||
window.__loadScript = function(url) {
|
window.__loadScript = function(url) {
|
||||||
return new Promise(function(res, rej) {
|
return new Promise(function(res, rej) {
|
||||||
var s = document.createElement('script');
|
var s = document.createElement('script');
|
||||||
@@ -94,14 +97,10 @@ var initError = null;
|
|||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
var pyResp = await fetch(_CDN + 'pyodide.js');
|
var pyResp = await fetch(_CDN + 'pyodide.js');
|
||||||
if (!pyResp.ok) throw new Error('Could not fetch pyodide.js (' + pyResp.status + ')');
|
if (!pyResp.ok) throw new Error('Could not fetch pyodide.js (' + pyResp.status + ')');
|
||||||
var pyCode = await pyResp.text();
|
var pyCode = await pyResp.text();
|
||||||
// Replace all dynamic import() calls. Node.js-only paths (importing
|
pyCode = pyCode.split('import(').join('__loadScript(');
|
||||||
// "path", "fs", etc.) are guarded by IN_NODE and never run in WebView.
|
|
||||||
pyCode = pyCode.replace(/\bimport\(/g, '__loadScript(');
|
|
||||||
|
|
||||||
await new Promise(function(res, rej) {
|
await new Promise(function(res, rej) {
|
||||||
var blob = new Blob([pyCode], { type: 'application/javascript' });
|
var blob = new Blob([pyCode], { type: 'application/javascript' });
|
||||||
var blobUrl = URL.createObjectURL(blob);
|
var blobUrl = URL.createObjectURL(blob);
|
||||||
@@ -111,6 +110,14 @@ var initError = null;
|
|||||||
s.onerror = function() { URL.revokeObjectURL(blobUrl); rej(new Error('Failed to execute patched pyodide.js')); };
|
s.onerror = function() { URL.revokeObjectURL(blobUrl); rej(new Error('Failed to execute patched pyodide.js')); };
|
||||||
document.head.appendChild(s);
|
document.head.appendChild(s);
|
||||||
});
|
});
|
||||||
|
} else {
|
||||||
|
await new Promise(function(res, rej) {
|
||||||
|
var s = document.createElement('script');
|
||||||
|
s.src = _CDN + 'pyodide.js';
|
||||||
|
s.onload = res; s.onerror = rej;
|
||||||
|
document.head.appendChild(s);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
pyodide = await loadPyodide({ indexURL: _CDN });
|
pyodide = await loadPyodide({ indexURL: _CDN });
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user