The 100ms pure-debounce approach caused a visible layout flash on every
render (normal mode too) because Tokyo UX was not applied for 100ms.
Fix: call setStrings() immediately in the MutationObserver callback to
prevent any flash, AND keep a 250ms delayed follow-up call to catch
async train re-renders from mock XHR setTimeout(0) responses.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Root cause: setStrings() was called synchronously in setReload(),
but the mock XHR interceptor responds via setTimeout(0), so the
site re-rendered train elements AFTER setStrings() ran, stripping
Tokyo UX styling.
Two-pronged fix:
1. setReload() now calls setStrings() again after 200ms to
re-apply Tokyo UX once the async re-render completes.
2. textInsert MutationObserver now watches with subtree:true
(childList only, not attributes - no infinite loop risk)
with 100ms debouncing, so ANY train element re-render
(including those triggered by mock XHR data) will trigger
a re-application of Tokyo UX.
- currentLines postMessage now only fires when direct
children of #disp change (line selection changes only)
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
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 <223556219+Copilot@users.noreply.github.com>
- Scrape & analyse all 19 internal APIs of train.jr-shikoku.co.jp/sp.html
using puppeteer + Chromium remote debugging
- Save live-captured sample JSON for every API endpoint under
lib/mockApi/mockData/ (station lists, lang, timetable, train positions, etc.)
- Add lib/mockApi/webviewXhrInterceptor.ts – generates a JS snippet that
overrides XMLHttpRequest inside the WebView before page scripts run;
intercepts /g?arg1=train&arg2=train (and optionally all static APIs)
returning mock data instead of the real server response
- Add lib/mockApi/index.ts – convenience re-exports + MOCK_TRAIN_POSITIONS
constant pre-populated with captured sample data
- Extend InjectJavascriptOptions with optional mockApiConfig field
- injectJavascriptData() prepends the interceptor JS when mockApiConfig is set
- TrainMenuContext gains mockApiEnabled / setMockApiEnabled and
mockTrainPositions / setMockTrainPositions state; consumers can enable
mock mode and inject custom TrainEntry[] without reloading the app
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Introduced useElesite hook for managing elesite data and settings.
- Added elesite logo asset.
- Updated types to include elesite data structures.
- Enhanced TrainMenuProvider to manage elesite usage settings.
- Implemented data fetching and caching for elesite information.
- Added utility functions to retrieve train information from elesite data.
- Introduced `stationData.ts` to store station information including names, numbers, and features.
- Created `trainIconMap.ts` for mapping train numbers to their respective image URLs, including dynamic URLs for special trains.
- Added `trainTypeConfig.ts` to define display settings for various train types, including colors and labels for different categories.