@@ -27,106 +27,6 @@ import { convertRemToPixels } from "../utils/numbers";
27
27
import { findSingleActiveFunboxWithFunction } from "./funbox/list" ;
28
28
import * as TestState from "./test-state" ;
29
29
30
- function createHintsHtml (
31
- incorrectLettersIndices : number [ ] [ ] ,
32
- activeWordLetters : NodeListOf < Element > ,
33
- input : string | string [ ] ,
34
- wrapWithDiv : boolean = true
35
- ) : string {
36
- // if input is an array, it contains only incorrect letters input.
37
- // if input is a string, it contains the whole word input.
38
- const isFullWord = typeof input === "string" ;
39
- const inputChars = isFullWord ? Strings . splitIntoCharacters ( input ) : input ;
40
-
41
- let hintsHtml = "" ;
42
- let currentHint = 0 ;
43
-
44
- for ( const adjacentLetters of incorrectLettersIndices ) {
45
- for ( const letterIndex of adjacentLetters ) {
46
- const letter = activeWordLetters [ letterIndex ] as HTMLElement ;
47
- const blockIndices = `${ letterIndex } ` ;
48
- const blockChars = isFullWord
49
- ? inputChars [ letterIndex ]
50
- : inputChars [ currentHint ++ ] ;
51
-
52
- hintsHtml += `<hint data-chars-index=${ blockIndices } style="left:${
53
- letter . offsetLeft + letter . offsetWidth / 2
54
- } px;">${ blockChars } </hint>`;
55
- }
56
- }
57
- if ( wrapWithDiv ) hintsHtml = `<div class="hints">${ hintsHtml } </div>` ;
58
- return hintsHtml ;
59
- }
60
-
61
- async function joinOverlappingHints (
62
- incorrectLettersIndices : number [ ] [ ] ,
63
- activeWordLetters : NodeListOf < Element > ,
64
- hintElements : HTMLCollection
65
- ) : Promise < void > {
66
- const currentLanguage = await JSONData . getCurrentLanguage ( Config . language ) ;
67
- const isLanguageRTL = currentLanguage . rightToLeft ;
68
-
69
- let firstHintInSeq = 0 ;
70
- for ( const adjacentLettersSequence of incorrectLettersIndices ) {
71
- const lastHintInSeq = firstHintInSeq + adjacentLettersSequence . length - 1 ;
72
- joinHintsOfAdjacentLetters ( firstHintInSeq , lastHintInSeq ) ;
73
- firstHintInSeq += adjacentLettersSequence . length ;
74
- }
75
-
76
- function joinHintsOfAdjacentLetters (
77
- firstHintInSequence : number ,
78
- lastHintInSequence : number
79
- ) : void {
80
- let currentHint = firstHintInSequence ;
81
-
82
- while ( currentHint < lastHintInSequence ) {
83
- const block1El = hintElements [ currentHint ] as HTMLElement ;
84
- const block2El = hintElements [ currentHint + 1 ] as HTMLElement ;
85
-
86
- const leftBlock = isLanguageRTL ? block2El : block1El ;
87
- const rightBlock = isLanguageRTL ? block1El : block2El ;
88
-
89
- // block edge is offset half its width because of transform: translate(-50%)
90
- const leftBlockEnds = leftBlock . offsetLeft + leftBlock . offsetWidth / 2 ;
91
- const rightBlockStarts =
92
- rightBlock . offsetLeft - rightBlock . offsetWidth / 2 ;
93
-
94
- const sameTop = leftBlock . offsetTop === rightBlock . offsetTop ;
95
-
96
- if ( sameTop && leftBlockEnds > rightBlockStarts ) {
97
- joinHintBlocks ( block1El , block2El ) ;
98
-
99
- // after joining blocks, the sequence is shorter
100
- lastHintInSequence -- ;
101
- // check if the newly formed block overlaps with the previous one
102
- currentHint -- ;
103
- if ( currentHint < firstHintInSeq ) currentHint = firstHintInSeq ;
104
- } else {
105
- currentHint ++ ;
106
- }
107
- }
108
- }
109
-
110
- function joinHintBlocks ( block1 : HTMLElement , block2 : HTMLElement ) : void {
111
- const block1Indices = block1 . dataset [ "charsIndex" ] ?. split ( "," ) ?? [ ] ;
112
- const block2Indices = block2 . dataset [ "charsIndex" ] ?. split ( "," ) ?? [ ] ;
113
- block1 . dataset [ "charsIndex" ] = [ ...block1Indices , ...block2Indices ] . join (
114
- ","
115
- ) ;
116
-
117
- const block1Letter1Index = parseInt ( block1Indices [ 0 ] ?? "0" ) ;
118
- const block1Letter1 = activeWordLetters [ block1Letter1Index ] as HTMLElement ;
119
- const block1Letter1Pos =
120
- block1Letter1 . offsetLeft +
121
- ( isLanguageRTL ? block1Letter1 . offsetWidth : 0 ) ;
122
- const bothBlocksLettersWidthHalved = block2 . offsetLeft - block1 . offsetLeft ;
123
- block1 . style . left = block1Letter1Pos + bothBlocksLettersWidthHalved + "px" ;
124
-
125
- block1 . insertAdjacentHTML ( "beforeend" , block2 . innerHTML ) ;
126
- block2 . remove ( ) ;
127
- }
128
- }
129
-
130
30
const debouncedZipfCheck = debounce ( 250 , async ( ) => {
131
31
const supports = await JSONData . checkIfLanguageSupportsZipf ( Config . language ) ;
132
32
if ( supports === "no" ) {
@@ -298,6 +198,106 @@ export function updateActiveElement(
298
198
}
299
199
}
300
200
201
+ function createHintsHtml (
202
+ incorrectLettersIndices : number [ ] [ ] ,
203
+ activeWordLetters : NodeListOf < Element > ,
204
+ input : string | string [ ] ,
205
+ wrapWithDiv : boolean = true
206
+ ) : string {
207
+ // if input is an array, it contains only incorrect letters input.
208
+ // if input is a string, it contains the whole word input.
209
+ const isFullWord = typeof input === "string" ;
210
+ const inputChars = isFullWord ? Strings . splitIntoCharacters ( input ) : input ;
211
+
212
+ let hintsHtml = "" ;
213
+ let currentHint = 0 ;
214
+
215
+ for ( const adjacentLetters of incorrectLettersIndices ) {
216
+ for ( const letterIndex of adjacentLetters ) {
217
+ const letter = activeWordLetters [ letterIndex ] as HTMLElement ;
218
+ const blockIndices = `${ letterIndex } ` ;
219
+ const blockChars = isFullWord
220
+ ? inputChars [ letterIndex ]
221
+ : inputChars [ currentHint ++ ] ;
222
+
223
+ hintsHtml += `<hint data-chars-index=${ blockIndices } style="left:${
224
+ letter . offsetLeft + letter . offsetWidth / 2
225
+ } px;">${ blockChars } </hint>`;
226
+ }
227
+ }
228
+ if ( wrapWithDiv ) hintsHtml = `<div class="hints">${ hintsHtml } </div>` ;
229
+ return hintsHtml ;
230
+ }
231
+
232
+ async function joinOverlappingHints (
233
+ incorrectLettersIndices : number [ ] [ ] ,
234
+ activeWordLetters : NodeListOf < Element > ,
235
+ hintElements : HTMLCollection
236
+ ) : Promise < void > {
237
+ const currentLanguage = await JSONData . getCurrentLanguage ( Config . language ) ;
238
+ const isLanguageRTL = currentLanguage . rightToLeft ;
239
+
240
+ let firstHintInSeq = 0 ;
241
+ for ( const adjacentLettersSequence of incorrectLettersIndices ) {
242
+ const lastHintInSeq = firstHintInSeq + adjacentLettersSequence . length - 1 ;
243
+ joinHintsOfAdjacentLetters ( firstHintInSeq , lastHintInSeq ) ;
244
+ firstHintInSeq += adjacentLettersSequence . length ;
245
+ }
246
+
247
+ function joinHintsOfAdjacentLetters (
248
+ firstHintInSequence : number ,
249
+ lastHintInSequence : number
250
+ ) : void {
251
+ let currentHint = firstHintInSequence ;
252
+
253
+ while ( currentHint < lastHintInSequence ) {
254
+ const block1El = hintElements [ currentHint ] as HTMLElement ;
255
+ const block2El = hintElements [ currentHint + 1 ] as HTMLElement ;
256
+
257
+ const leftBlock = isLanguageRTL ? block2El : block1El ;
258
+ const rightBlock = isLanguageRTL ? block1El : block2El ;
259
+
260
+ // block edge is offset half its width because of transform: translate(-50%)
261
+ const leftBlockEnds = leftBlock . offsetLeft + leftBlock . offsetWidth / 2 ;
262
+ const rightBlockStarts =
263
+ rightBlock . offsetLeft - rightBlock . offsetWidth / 2 ;
264
+
265
+ const sameTop = leftBlock . offsetTop === rightBlock . offsetTop ;
266
+
267
+ if ( sameTop && leftBlockEnds > rightBlockStarts ) {
268
+ joinHintBlocks ( block1El , block2El ) ;
269
+
270
+ // after joining blocks, the sequence is shorter
271
+ lastHintInSequence -- ;
272
+ // check if the newly formed block overlaps with the previous one
273
+ currentHint -- ;
274
+ if ( currentHint < firstHintInSeq ) currentHint = firstHintInSeq ;
275
+ } else {
276
+ currentHint ++ ;
277
+ }
278
+ }
279
+ }
280
+
281
+ function joinHintBlocks ( block1 : HTMLElement , block2 : HTMLElement ) : void {
282
+ const block1Indices = block1 . dataset [ "charsIndex" ] ?. split ( "," ) ?? [ ] ;
283
+ const block2Indices = block2 . dataset [ "charsIndex" ] ?. split ( "," ) ?? [ ] ;
284
+ block1 . dataset [ "charsIndex" ] = [ ...block1Indices , ...block2Indices ] . join (
285
+ ","
286
+ ) ;
287
+
288
+ const block1Letter1Index = parseInt ( block1Indices [ 0 ] ?? "0" ) ;
289
+ const block1Letter1 = activeWordLetters [ block1Letter1Index ] as HTMLElement ;
290
+ const block1Letter1Pos =
291
+ block1Letter1 . offsetLeft +
292
+ ( isLanguageRTL ? block1Letter1 . offsetWidth : 0 ) ;
293
+ const bothBlocksLettersWidthHalved = block2 . offsetLeft - block1 . offsetLeft ;
294
+ block1 . style . left = block1Letter1Pos + bothBlocksLettersWidthHalved + "px" ;
295
+
296
+ block1 . insertAdjacentHTML ( "beforeend" , block2 . innerHTML ) ;
297
+ block2 . remove ( ) ;
298
+ }
299
+ }
300
+
301
301
async function updateHintsPosition ( ) : Promise < void > {
302
302
if (
303
303
ActivePage . get ( ) !== "test" ||
0 commit comments