Skip to content

Commit 4c16357

Browse files
author
HugoFara
committed
chore(frontend): getting rid of LWT_DATA for cleaner patterns
1 parent 068f5de commit 4c16357

16 files changed

+268
-388
lines changed

src/frontend/js/core/language_config.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,6 +172,24 @@ export function getTtsVoiceApi(): string {
172172
*/
173173
export function setTtsVoiceApi(api: string): void {
174174
currentConfig.ttsVoiceApi = api;
175+
isInitialized = true;
176+
}
177+
178+
/**
179+
* Set dictionary links.
180+
* Used when initializing from page-specific configuration.
181+
*/
182+
export function setDictionaryLinks(links: { dict1?: string; dict2?: string; translator?: string }): void {
183+
if (links.dict1 !== undefined) {
184+
currentConfig.dictLink1 = links.dict1;
185+
}
186+
if (links.dict2 !== undefined) {
187+
currentConfig.dictLink2 = links.dict2;
188+
}
189+
if (links.translator !== undefined) {
190+
currentConfig.translatorLink = links.translator;
191+
}
192+
isInitialized = true;
175193
}
176194

177195
/**

src/frontend/js/core/user_interactions.ts

Lines changed: 2 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -9,30 +9,7 @@
99
import { overlib, cClick } from '../ui/word_popup';
1010
import { scrollTo } from '../core/hover_intent';
1111
import { getTTSSettingsWithMigration, type TTSLanguageSettings } from './tts_storage';
12-
13-
// Type for LWT_DATA global
14-
interface LwtLanguage {
15-
id: number;
16-
name: string;
17-
abbreviation: string;
18-
reading_mode?: string;
19-
voiceapi?: string;
20-
}
21-
22-
interface LwtText {
23-
id: number;
24-
reading_position: number;
25-
}
26-
27-
interface LwtDataGlobal {
28-
language: LwtLanguage;
29-
text: LwtText;
30-
settings: {
31-
hts: number;
32-
};
33-
}
34-
35-
declare const LWT_DATA: LwtDataGlobal;
12+
import { getReadingPosition } from './reading_state';
3613

3714
// Type for text dictionary in newExpressionInteractable
3815
interface TextDictionary {
@@ -203,7 +180,7 @@ export function newExpressionInteractable(
203180
*/
204181
export function goToLastPosition(): void {
205182
// Last registered position to go to
206-
const lookPos = LWT_DATA.text.reading_position;
183+
const lookPos = getReadingPosition();
207184
// Element to scroll to
208185
let targetElement: HTMLElement | null = null;
209186
if (lookPos > 0) {

src/frontend/js/reading/text_annotations.ts

Lines changed: 30 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77

88
import { make_tooltip } from '../terms/word_status';
9+
import { getAnnotation } from '../core/text_config';
10+
import { getDelimiter } from '../core/language_config';
911

1012
/**
1113
* Helper to safely get an HTML attribute value as a string.
@@ -30,37 +32,6 @@ export function getAttrElement(el: HTMLElement, attr: string): string {
3032
return el.getAttribute(attr) || '';
3133
}
3234

33-
// Type definitions
34-
interface LwtLanguage {
35-
id: number;
36-
dict_link1: string;
37-
dict_link2: string;
38-
translator_link: string;
39-
delimiter: string;
40-
rtl: boolean;
41-
}
42-
43-
interface LwtText {
44-
id: number;
45-
reading_position: number;
46-
annotations: Record<string, [unknown, string, string]>;
47-
}
48-
49-
interface LwtSettings {
50-
jQuery_tooltip: boolean;
51-
hts: number;
52-
word_status_filter: string;
53-
annotations_mode: number;
54-
}
55-
56-
interface LwtDataGlobal {
57-
language: LwtLanguage;
58-
text: LwtText;
59-
settings: LwtSettings;
60-
}
61-
62-
declare const LWT_DATA: LwtDataGlobal;
63-
6435
/**
6536
* Add annotations to a word.
6637
*/
@@ -70,13 +41,15 @@ export function word_each_do_text_text(
7041
const wid = getAttr(this, 'data_wid');
7142
if (wid !== '') {
7243
const order = getAttr(this, 'data_order');
73-
if (order in LWT_DATA.text.annotations) {
74-
if (wid === LWT_DATA.text.annotations[order][1]) {
75-
const ann = LWT_DATA.text.annotations[order][2];
44+
const annotation = getAnnotation(order);
45+
if (annotation) {
46+
if (wid === annotation[1]) {
47+
const ann = annotation[2];
48+
const delimiter = getDelimiter();
7649
const re = new RegExp(
77-
'([' + LWT_DATA.language.delimiter + '][ ]{0,1}|^)(' +
50+
'([' + delimiter + '][ ]{0,1}|^)(' +
7851
ann.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + ')($|[ ]{0,1}[' +
79-
LWT_DATA.language.delimiter + '])',
52+
delimiter + '])',
8053
''
8154
);
8255
const dataTrans = getAttr(this, 'data_trans');
@@ -88,14 +61,13 @@ export function word_each_do_text_text(
8861
}
8962
}
9063
}
91-
if (!LWT_DATA.settings.jQuery_tooltip) {
92-
this.title = make_tooltip(
93-
this.textContent || '',
94-
getAttr(this, 'data_trans'),
95-
getAttr(this, 'data_rom'),
96-
getAttr(this, 'data_status') || '0'
97-
);
98-
}
64+
// Native tooltips are always used (jQuery tooltips removed)
65+
this.title = make_tooltip(
66+
this.textContent || '',
67+
getAttr(this, 'data_trans'),
68+
getAttr(this, 'data_rom'),
69+
getAttr(this, 'data_status') || '0'
70+
);
9971
}
10072

10173
/**
@@ -111,15 +83,17 @@ export function mword_each_do_text_text(
11183
const wid = getAttr(this, 'data_wid');
11284
if (wid !== '') {
11385
const order = parseInt(getAttr(this, 'data_order') || '0', 10);
86+
const delimiter = getDelimiter();
11487
for (let j = 2; j <= 16; j = j + 2) {
11588
const index = (order + j).toString();
116-
if (index in LWT_DATA.text.annotations) {
117-
if (wid === LWT_DATA.text.annotations[index][1]) {
118-
const ann = LWT_DATA.text.annotations[index][2];
89+
const annotation = getAnnotation(index);
90+
if (annotation) {
91+
if (wid === annotation[1]) {
92+
const ann = annotation[2];
11993
const re = new RegExp(
120-
'([' + LWT_DATA.language.delimiter + '][ ]{0,1}|^)(' +
94+
'([' + delimiter + '][ ]{0,1}|^)(' +
12195
ann.replace(/[-/\\^$*+?.()|[\]{}]/g, '\\$&') + ')($|[ ]{0,1}[' +
122-
LWT_DATA.language.delimiter + '])',
96+
delimiter + '])',
12397
''
12498
);
12599
const dataTrans = getAttr(this, 'data_trans');
@@ -133,14 +107,13 @@ export function mword_each_do_text_text(
133107
}
134108
}
135109
}
136-
if (!LWT_DATA.settings.jQuery_tooltip) {
137-
this.title = make_tooltip(
138-
getAttr(this, 'data_text'),
139-
getAttr(this, 'data_trans'),
140-
getAttr(this, 'data_rom'),
141-
getAttr(this, 'data_status') || '0'
142-
);
143-
}
110+
// Native tooltips are always used (jQuery tooltips removed)
111+
this.title = make_tooltip(
112+
getAttr(this, 'data_text'),
113+
getAttr(this, 'data_trans'),
114+
getAttr(this, 'data_rom'),
115+
getAttr(this, 'data_status') || '0'
116+
);
144117
}
145118
}
146119

src/frontend/js/reading/text_multiword_selection.ts

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@
1111
import Alpine from 'alpinejs';
1212
import { loadModalFrame } from './frame_management';
1313
import type { MultiWordFormStoreState } from './stores/multi_word_form_store';
14+
import { getTextId as getTextIdFromConfig } from '../core/text_config';
1415

1516
/**
16-
* Get text ID from URL (fallback when LWT_DATA is not available).
17+
* Get text ID from URL (fallback when config is not available).
1718
*/
1819
function getTextIdFromUrl(): number {
1920
// Try to get from URL path: /text/read/123
@@ -31,14 +32,12 @@ function getTextIdFromUrl(): number {
3132
}
3233

3334
/**
34-
* Get the text ID from LWT_DATA or URL.
35+
* Get the text ID from config or URL.
3536
*/
3637
function getTextId(): number {
37-
if (typeof window !== 'undefined') {
38-
const win = window as unknown as { LWT_DATA?: { text?: { id?: number } } };
39-
if (win.LWT_DATA?.text?.id) {
40-
return win.LWT_DATA.text.id;
41-
}
38+
const configId = getTextIdFromConfig();
39+
if (configId > 0) {
40+
return configId;
4241
}
4342
return getTextIdFromUrl();
4443
}

src/frontend/js/reading/text_reading_init.ts

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,15 +15,14 @@ import { getLangFromDict } from '../terms/dictionary';
1515
import { prepareTextInteractions } from './text_events';
1616
import { goToLastPosition, saveReadingPosition, saveAudioPosition, readRawTextAloud } from '../core/user_interactions';
1717
import { getAudioPlayer } from '../media/html5_audio_player';
18-
import { LWT_DATA } from '../core/lwt_state';
1918
import { initNativeTooltips } from '../ui/native_tooltip';
2019
import { resetReadingPosition } from '../core/reading_state';
2120
import {
2221
initLanguageConfig,
2322
getDictionaryLinks,
2423
setTtsVoiceApi
2524
} from '../core/language_config';
26-
import { initTextConfig, getTextId, setAnnotations } from '../core/text_config';
25+
import { initTextConfig, getTextId } from '../core/text_config';
2726
import { initSettingsConfig } from '../core/settings_config';
2827
import { resetAnswer } from '../core/test_state';
2928

@@ -124,11 +123,6 @@ export function initTTS(): void {
124123
// Update TTS voice API in language config
125124
setTtsVoiceApi(config.voiceApi || '');
126125

127-
// Also update legacy LWT_DATA for backwards compatibility
128-
if (typeof LWT_DATA !== 'undefined' && LWT_DATA.language) {
129-
LWT_DATA.language.ttsVoiceApi = config.voiceApi || '';
130-
}
131-
132126
// Store textId for later use
133127
window._lwtTextId = config.textId;
134128
}
@@ -330,15 +324,9 @@ export function initTextReading(): void {
330324

331325
// Reset reading position (will be set by goToLastPosition)
332326
resetReadingPosition();
333-
if (LWT_DATA.text) {
334-
LWT_DATA.text.reading_position = -1;
335-
}
336327

337328
// Initialize test answer state
338329
resetAnswer();
339-
if (LWT_DATA.test) {
340-
LWT_DATA.test.answer_opened = false;
341-
}
342330

343331
// Set the language of the current frame
344332
if (window.LANG && window.LANG !== dictLinks.translator) {

src/frontend/js/terms/overlib_interface.ts

Lines changed: 3 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@ import { showRightFramesPanel } from '../reading/frame_management';
2323
import { speechDispatcher } from '../core/user_interactions';
2424
import type { MultiWordFormStoreState } from '../reading/stores/multi_word_form_store';
2525
import { parseInlineMarkdown } from '../core/inline_markdown';
26+
import { getLanguageId } from '../core/language_config';
2627

2728
// Import the popup system
2829
import { overlib } from '../ui/word_popup';
@@ -44,17 +45,6 @@ export { overlib, cClick, nd } from '../ui/word_popup';
4445
// and accessed via window at runtime: showRightFramesPanel, confirmDelete, successSound, failureSound
4546
// They are exported to window in globals.ts
4647

47-
// Type for LWT_DATA global
48-
interface LwtLanguage {
49-
id: number;
50-
}
51-
52-
interface LwtDataGlobal {
53-
language: LwtLanguage;
54-
}
55-
56-
declare const LWT_DATA: LwtDataGlobal;
57-
5848
/**************************************************************
5949
* Modern API-based popup content generators
6050
*
@@ -401,7 +391,7 @@ function createAudioElement(text: string): HTMLElement {
401391
});
402392
icon.style.cursor = 'pointer';
403393
icon.addEventListener('click', () => {
404-
speechDispatcher(text, LWT_DATA.language.id);
394+
speechDispatcher(text, getLanguageId());
405395
});
406396

407397
container.appendChild(icon);
@@ -1281,7 +1271,7 @@ export function make_overlib_audio(txt: string): string {
12811271
icon.style.cursor = 'pointer';
12821272
icon.setAttribute(
12831273
'onclick',
1284-
"speechDispatcher('" + escape_html_chars(txt) + "', '" + LWT_DATA.language.id + "')"
1274+
"speechDispatcher('" + escape_html_chars(txt) + "', '" + getLanguageId() + "')"
12851275
);
12861276
return icon.outerHTML;
12871277
}

src/frontend/js/testing/test_ajax.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
* @since 3.0.0 Extracted from PHP inline scripts
77
*/
88

9-
import { LWT_DATA } from '../core/lwt_state';
109
import { cClick } from '../ui/word_popup';
1110
import { speechDispatcher } from '../core/user_interactions';
1211
import { word_click_event_do_test_test, keydown_event_do_test_test } from './test_mode';
1312
import { startElapsedTimer } from './elapsed_timer';
1413
import { ReviewApi } from '../api/review';
14+
import { setCurrentWordId, setTestSolution, setAnswerOpened } from '../core/test_state';
15+
import { getLanguageId, initLanguageConfig } from '../core/language_config';
1516

1617
// Interface for review data
1718
interface ReviewData {
@@ -71,8 +72,8 @@ export function prepareWordReading(termText: string, langId: number): void {
7172
* @param group HTML content for the term
7273
*/
7374
export function insertNewWord(wordId: number, solution: string, group: string): void {
74-
LWT_DATA.test.solution = solution;
75-
LWT_DATA.word.id = wordId;
75+
setTestSolution(solution);
76+
setCurrentWordId(wordId);
7677

7778
const termTestEl = document.getElementById('term-test');
7879
if (termTestEl) {
@@ -144,7 +145,7 @@ export async function testQueryHandler(
144145
);
145146
const utteranceCheckbox = document.getElementById('utterance-allowed') as HTMLInputElement | null;
146147
if (utteranceCheckbox?.checked) {
147-
prepareWordReading(currentTest.word_text, LWT_DATA.language.id);
148+
prepareWordReading(currentTest.word_text, getLanguageId());
148149
}
149150
}
150151
}
@@ -369,17 +370,21 @@ export function initTestInteractionGlobals(config: {
369370
translateUri: string;
370371
langCode: string;
371372
}): void {
372-
LWT_DATA.language.id = config.langId;
373-
LWT_DATA.language.dict_link1 = config.dict1Uri;
374-
LWT_DATA.language.dict_link2 = config.dict2Uri;
375-
LWT_DATA.language.translator_link = config.translateUri;
373+
initLanguageConfig({
374+
id: config.langId,
375+
dictLink1: config.dict1Uri,
376+
dictLink2: config.dict2Uri,
377+
translatorLink: config.translateUri,
378+
delimiter: '',
379+
rtl: false
380+
});
376381

377382
// Set html lang attribute if we have a valid language code
378383
if (config.langCode && config.langCode !== config.translateUri) {
379384
document.documentElement.setAttribute('lang', config.langCode);
380385
}
381386

382-
LWT_DATA.test.answer_opened = false;
387+
setAnswerOpened(false);
383388
}
384389

385390
/**

0 commit comments

Comments
 (0)