fix: Tokyo UX stripped when mock is active
Two bugs caused the Tokyo UX to be stripped/broken when mock mode was ON:
1. **Double callback firing**: the interceptor's `setTimeout` called both
`onreadystatechange.call(self)` AND `dispatchEvent(new Event('readystatechange'))`.
Since `dispatchEvent` already fires `onXxx` property handlers via the DOM event
model, the page's callback fired twice, causing a second DOM re-render that could
overwrite Tokyo UX modifications. Fixed by relying on `dispatchEvent` only (with
`ProgressEvent` for load events), with a direct-call fallback only for environments
that lack `dispatchEvent`.
2. **No double-injection guard**: if `injectedJavaScriptBeforeContentLoaded` caused
the interceptor to run more than once (e.g., `onPageStarted` fires multiple times
on Android), `_origOpen` would capture the already-patched version, leading to
unexpected behaviour. Fixed by adding `if (window.__jrsMockActive) return;` at the
top of the interceptor IIFE.
3. **Belt-and-suspenders injection**: the interceptor is now also prepended to
`injectedJavaScript` (Tokyo UX script) via the restored `mockApiConfig` parameter
on `injectJavascriptData`. The `__jrsMockActive` guard ensures it's a no-op when
`injectedJavaScriptBeforeContentLoaded` already ran it, but guarantees the
interceptor is active on platforms where IJBCL is unreliable — before
`MoveDisplayStation` triggers the first train-data poll via `onLoadEnd`.
Co-authored-by: Copilot <[email protected]>
This commit is contained in:
co-authored by
Copilot
parent
8ee546277c
commit
c6aecd151c
@@ -27,8 +27,15 @@ export interface InjectJavascriptOptions {
|
||||
* 未指定または null の場合、インターセプターは無効で通常通り公式APIに接続します。
|
||||
*/
|
||||
mockApiConfig?: MockApiConfig | null;
|
||||
/**
|
||||
* バックエンドAPIのベースURL。省略時は本番URL。
|
||||
* experimental 環境では https://jr-shikoku-backend-api-v1-beta.haruk.in を渡す。
|
||||
*/
|
||||
backendApiBaseUrl?: string;
|
||||
}
|
||||
|
||||
const PRODUCTION_BACKEND_BASE = 'https://jr-shikoku-backend-api-v1.haruk.in';
|
||||
|
||||
export const injectJavascriptData = ({
|
||||
mapSwitch,
|
||||
iconSetting,
|
||||
@@ -38,7 +45,9 @@ export const injectJavascriptData = ({
|
||||
useUnyohub,
|
||||
useElesite,
|
||||
isDark,
|
||||
}: Omit<InjectJavascriptOptions, 'mockApiConfig'>): string => {
|
||||
backendApiBaseUrl,
|
||||
mockApiConfig,
|
||||
}: InjectJavascriptOptions): string => {
|
||||
|
||||
// 一番上のメニュー非表示 地図スイッチによって切り替え
|
||||
const topMenu =
|
||||
@@ -1399,7 +1408,7 @@ setStationMenuDialog.observe(document.querySelector('#disp'), {
|
||||
});
|
||||
`
|
||||
: ``;
|
||||
return (
|
||||
let result =
|
||||
bootData +
|
||||
topMenu +
|
||||
trainIcon +
|
||||
@@ -1407,8 +1416,21 @@ setStationMenuDialog.observe(document.querySelector('#disp'), {
|
||||
makeTrainView +
|
||||
makeTrainMenu +
|
||||
textInsert +
|
||||
makeStationMenu
|
||||
);
|
||||
makeStationMenu;
|
||||
|
||||
if (backendApiBaseUrl && backendApiBaseUrl !== PRODUCTION_BACKEND_BASE) {
|
||||
result = result.split(PRODUCTION_BACKEND_BASE).join(backendApiBaseUrl);
|
||||
}
|
||||
|
||||
// Prepend XHR interceptor as a fallback for platforms where
|
||||
// injectedJavaScriptBeforeContentLoaded doesn't run reliably.
|
||||
// The __jrsMockActive guard in the interceptor prevents double-patching
|
||||
// when IJBCL already installed it.
|
||||
if (mockApiConfig) {
|
||||
result = generateXhrInterceptorJs(mockApiConfig) + '\n' + result;
|
||||
}
|
||||
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user