@pie-players/pie-tool-answer-eliminator 0.3.42 → 0.3.44
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/adapters/adapter-registry.d.ts +0 -1
- package/dist/adapters/choice-adapter.d.ts +0 -1
- package/dist/adapters/ebsr-adapter.d.ts +0 -1
- package/dist/adapters/inline-dropdown-adapter.d.ts +0 -1
- package/dist/adapters/multiple-choice-adapter.d.ts +0 -1
- package/dist/answer-eliminator-core.d.ts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/strategies/elimination-strategy.d.ts +0 -1
- package/dist/strategies/mask-strategy.d.ts +0 -1
- package/dist/strategies/strikethrough-strategy.d.ts +0 -1
- package/dist/vite.config.d.ts +0 -1
- package/package.json +6 -12
- package/adapters/adapter-registry.ts +0 -64
- package/adapters/choice-adapter.ts +0 -50
- package/adapters/ebsr-adapter.ts +0 -61
- package/adapters/inline-dropdown-adapter.ts +0 -46
- package/adapters/multiple-choice-adapter.ts +0 -144
- package/answer-eliminator-core.ts +0 -391
- package/dist/adapters/adapter-registry.d.ts.map +0 -1
- package/dist/adapters/choice-adapter.d.ts.map +0 -1
- package/dist/adapters/ebsr-adapter.d.ts.map +0 -1
- package/dist/adapters/inline-dropdown-adapter.d.ts.map +0 -1
- package/dist/adapters/multiple-choice-adapter.d.ts.map +0 -1
- package/dist/answer-eliminator-core.d.ts.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/strategies/elimination-strategy.d.ts.map +0 -1
- package/dist/strategies/mask-strategy.d.ts.map +0 -1
- package/dist/strategies/strikethrough-strategy.d.ts.map +0 -1
- package/dist/vite.config.d.ts.map +0 -1
- package/strategies/elimination-strategy.ts +0 -47
- package/strategies/mask-strategy.ts +0 -171
- package/strategies/strikethrough-strategy.ts +0 -223
- package/tool-answer-eliminator.svelte +0 -223
|
@@ -1,391 +0,0 @@
|
|
|
1
|
-
import { AdapterRegistry } from "./adapters/adapter-registry.js";
|
|
2
|
-
import type { ChoiceAdapter } from "./adapters/choice-adapter.js";
|
|
3
|
-
import type { EliminationStrategy } from "./strategies/elimination-strategy.js";
|
|
4
|
-
import { MaskStrategy } from "./strategies/mask-strategy.js";
|
|
5
|
-
import { StrikethroughStrategy } from "./strategies/strikethrough-strategy.js";
|
|
6
|
-
|
|
7
|
-
/**
|
|
8
|
-
* Core engine for answer eliminator tool
|
|
9
|
-
* Coordinates adapters, strategies, and state management
|
|
10
|
-
*/
|
|
11
|
-
export class AnswerEliminatorCore {
|
|
12
|
-
private static readonly TOGGLE_CLASS = "pie-answer-eliminator-toggle";
|
|
13
|
-
private static readonly TOGGLE_ACTIVE_CLASS =
|
|
14
|
-
"pie-answer-eliminator-toggle--active";
|
|
15
|
-
private registry: AdapterRegistry;
|
|
16
|
-
private strategy: EliminationStrategy;
|
|
17
|
-
private eliminatedChoices = new Set<string>(); // Set<choiceId> for current element
|
|
18
|
-
private choiceElements = new Map<string, HTMLElement>(); // choiceId -> element
|
|
19
|
-
private choiceButtons = new Map<string, HTMLButtonElement>(); // choiceId -> button
|
|
20
|
-
private choiceAdapters = new Map<string, ChoiceAdapter>(); // choiceId -> adapter
|
|
21
|
-
private buttonAlignment: "left" | "right" | "inline" = "right";
|
|
22
|
-
private shouldRestoreState: boolean = true; // Whether to restore eliminations from state storage
|
|
23
|
-
|
|
24
|
-
// Store integration (replaces session/localStorage)
|
|
25
|
-
private storeIntegration: {
|
|
26
|
-
store: any; // ElementToolStateStore
|
|
27
|
-
globalElementId: string; // Composite key: "assessmentId:sectionId:itemId:elementId"
|
|
28
|
-
} | null = null;
|
|
29
|
-
|
|
30
|
-
constructor(
|
|
31
|
-
strategyType: "strikethrough" | "mask" | "gray" = "strikethrough",
|
|
32
|
-
buttonAlignment: "left" | "right" | "inline" = "right",
|
|
33
|
-
) {
|
|
34
|
-
this.registry = new AdapterRegistry();
|
|
35
|
-
this.strategy = this.createStrategy(strategyType);
|
|
36
|
-
this.strategy.initialize();
|
|
37
|
-
this.buttonAlignment = buttonAlignment;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
private createStrategy(type: string): EliminationStrategy {
|
|
41
|
-
switch (type) {
|
|
42
|
-
case "mask":
|
|
43
|
-
return new MaskStrategy();
|
|
44
|
-
case "strikethrough":
|
|
45
|
-
default:
|
|
46
|
-
return new StrikethroughStrategy();
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Initialize eliminator for a question
|
|
52
|
-
*/
|
|
53
|
-
initializeForQuestion(questionRoot: HTMLElement): void {
|
|
54
|
-
// Clean up previous question
|
|
55
|
-
this.cleanupButtons();
|
|
56
|
-
|
|
57
|
-
// Find all choices with their adapters
|
|
58
|
-
const choicesWithAdapters =
|
|
59
|
-
this.registry.findAllChoicesWithAdapters(questionRoot);
|
|
60
|
-
|
|
61
|
-
// Attach elimination functionality to each choice
|
|
62
|
-
for (const { choice, adapter } of choicesWithAdapters) {
|
|
63
|
-
this.initializeChoice(choice, adapter);
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// Restore eliminated state from store (only if enabled)
|
|
67
|
-
if (this.shouldRestoreState) {
|
|
68
|
-
this.restoreState();
|
|
69
|
-
}
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
/**
|
|
73
|
-
* Initialize a single choice
|
|
74
|
-
*/
|
|
75
|
-
private initializeChoice(choice: HTMLElement, adapter: ChoiceAdapter): void {
|
|
76
|
-
const choiceId = adapter.getChoiceId(choice);
|
|
77
|
-
|
|
78
|
-
// Track element
|
|
79
|
-
this.choiceElements.set(choiceId, choice);
|
|
80
|
-
this.choiceAdapters.set(choiceId, adapter);
|
|
81
|
-
|
|
82
|
-
// Create elimination toggle button
|
|
83
|
-
const button = this.createToggleButton(choice, adapter);
|
|
84
|
-
if (!button) return;
|
|
85
|
-
|
|
86
|
-
this.choiceButtons.set(choiceId, button);
|
|
87
|
-
|
|
88
|
-
// Attach button to choice
|
|
89
|
-
const container = adapter.getButtonContainer(choice);
|
|
90
|
-
if (container) {
|
|
91
|
-
// Position button within container
|
|
92
|
-
container.style.position = "relative";
|
|
93
|
-
container.appendChild(button);
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
|
|
97
|
-
/**
|
|
98
|
-
* Create elimination toggle button
|
|
99
|
-
*/
|
|
100
|
-
private createToggleButton(
|
|
101
|
-
choice: HTMLElement,
|
|
102
|
-
adapter: ChoiceAdapter,
|
|
103
|
-
): HTMLButtonElement | null {
|
|
104
|
-
const choiceId = adapter.getChoiceId(choice);
|
|
105
|
-
const choiceLabel = adapter.getChoiceLabel(choice);
|
|
106
|
-
|
|
107
|
-
const button = document.createElement("button");
|
|
108
|
-
button.type = "button";
|
|
109
|
-
button.className = AnswerEliminatorCore.TOGGLE_CLASS;
|
|
110
|
-
button.setAttribute("aria-label", `Toggle elimination for ${choiceLabel}`);
|
|
111
|
-
button.setAttribute("data-choice-id", choiceId);
|
|
112
|
-
button.textContent = "⊗"; // Cross mark (use textContent instead of innerHTML for better security)
|
|
113
|
-
|
|
114
|
-
// Apply positioning based on alignment configuration
|
|
115
|
-
this.applyButtonAlignment(button);
|
|
116
|
-
|
|
117
|
-
button.addEventListener("click", (e) => {
|
|
118
|
-
e.preventDefault();
|
|
119
|
-
e.stopPropagation();
|
|
120
|
-
this.toggleElimination(choice, adapter);
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
return button;
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
/**
|
|
127
|
-
* Toggle elimination for a choice
|
|
128
|
-
*/
|
|
129
|
-
toggleElimination(choice: HTMLElement, adapter: ChoiceAdapter): void {
|
|
130
|
-
const choiceId = adapter.getChoiceId(choice);
|
|
131
|
-
|
|
132
|
-
// Check if already eliminated
|
|
133
|
-
const isEliminated = this.strategy.isEliminated(choiceId);
|
|
134
|
-
|
|
135
|
-
if (isEliminated) {
|
|
136
|
-
// Restore
|
|
137
|
-
this.restoreChoice(choiceId);
|
|
138
|
-
} else {
|
|
139
|
-
// Eliminate
|
|
140
|
-
if (!adapter.canEliminate(choice)) {
|
|
141
|
-
console.warn(
|
|
142
|
-
"Cannot eliminate this choice (already selected or in evaluate mode)",
|
|
143
|
-
);
|
|
144
|
-
return;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
this.eliminateChoice(choice, adapter);
|
|
148
|
-
}
|
|
149
|
-
|
|
150
|
-
// Save state
|
|
151
|
-
this.saveState();
|
|
152
|
-
}
|
|
153
|
-
|
|
154
|
-
/**
|
|
155
|
-
* Eliminate a choice
|
|
156
|
-
*/
|
|
157
|
-
private eliminateChoice(choice: HTMLElement, adapter: ChoiceAdapter): void {
|
|
158
|
-
const choiceId = adapter.getChoiceId(choice);
|
|
159
|
-
|
|
160
|
-
// Create range for CSS Highlight API
|
|
161
|
-
const range = adapter.createChoiceRange(choice);
|
|
162
|
-
if (!range) {
|
|
163
|
-
console.error("Failed to create range for choice");
|
|
164
|
-
return;
|
|
165
|
-
}
|
|
166
|
-
|
|
167
|
-
// Apply strategy
|
|
168
|
-
this.strategy.apply(choiceId, range);
|
|
169
|
-
|
|
170
|
-
// Track in state
|
|
171
|
-
this.eliminatedChoices.add(choiceId);
|
|
172
|
-
|
|
173
|
-
// Update button appearance to show eliminated state
|
|
174
|
-
const button = this.choiceButtons.get(choiceId);
|
|
175
|
-
if (button) {
|
|
176
|
-
button.classList.add(AnswerEliminatorCore.TOGGLE_ACTIVE_CLASS);
|
|
177
|
-
button.setAttribute("aria-pressed", "true");
|
|
178
|
-
}
|
|
179
|
-
|
|
180
|
-
// Save to store
|
|
181
|
-
this.saveState();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
/**
|
|
185
|
-
* Restore a choice
|
|
186
|
-
*/
|
|
187
|
-
private restoreChoice(choiceId: string): void {
|
|
188
|
-
// Remove from strategy
|
|
189
|
-
this.strategy.remove(choiceId);
|
|
190
|
-
|
|
191
|
-
// Remove from state
|
|
192
|
-
this.eliminatedChoices.delete(choiceId);
|
|
193
|
-
|
|
194
|
-
// Reset button appearance to default state
|
|
195
|
-
const button = this.choiceButtons.get(choiceId);
|
|
196
|
-
if (button) {
|
|
197
|
-
button.classList.remove(AnswerEliminatorCore.TOGGLE_ACTIVE_CLASS);
|
|
198
|
-
button.setAttribute("aria-pressed", "false");
|
|
199
|
-
}
|
|
200
|
-
|
|
201
|
-
// Save to store
|
|
202
|
-
this.saveState();
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
/**
|
|
206
|
-
* Reset all eliminations for current element
|
|
207
|
-
*/
|
|
208
|
-
resetAll(): void {
|
|
209
|
-
if (this.eliminatedChoices.size === 0) return;
|
|
210
|
-
|
|
211
|
-
// Restore all choices
|
|
212
|
-
for (const choiceId of Array.from(this.eliminatedChoices)) {
|
|
213
|
-
this.restoreChoice(choiceId);
|
|
214
|
-
}
|
|
215
|
-
|
|
216
|
-
// Clear state
|
|
217
|
-
this.eliminatedChoices.clear();
|
|
218
|
-
this.saveState();
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
/**
|
|
222
|
-
* Get count of eliminated choices for current element
|
|
223
|
-
*/
|
|
224
|
-
getEliminatedCount(): number {
|
|
225
|
-
return this.eliminatedChoices.size;
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
/**
|
|
229
|
-
* Set store integration for element-level state
|
|
230
|
-
* @param store ElementToolStateStore instance
|
|
231
|
-
* @param globalElementId Composite key: "assessmentId:sectionId:itemId:elementId"
|
|
232
|
-
*/
|
|
233
|
-
setStoreIntegration(store: any, globalElementId: string): void {
|
|
234
|
-
this.storeIntegration = { store, globalElementId };
|
|
235
|
-
}
|
|
236
|
-
|
|
237
|
-
/**
|
|
238
|
-
* Save state to ElementToolStateStore
|
|
239
|
-
*/
|
|
240
|
-
private saveState(): void {
|
|
241
|
-
if (!this.storeIntegration) return;
|
|
242
|
-
|
|
243
|
-
const state = {
|
|
244
|
-
eliminatedChoices: Array.from(this.eliminatedChoices),
|
|
245
|
-
};
|
|
246
|
-
|
|
247
|
-
this.storeIntegration.store.setState(
|
|
248
|
-
this.storeIntegration.globalElementId,
|
|
249
|
-
"answerEliminator",
|
|
250
|
-
state,
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Restore state from ElementToolStateStore
|
|
256
|
-
*/
|
|
257
|
-
private restoreState(): void {
|
|
258
|
-
if (!this.storeIntegration) return;
|
|
259
|
-
|
|
260
|
-
const state = this.storeIntegration.store.getState(
|
|
261
|
-
this.storeIntegration.globalElementId,
|
|
262
|
-
"answerEliminator",
|
|
263
|
-
);
|
|
264
|
-
|
|
265
|
-
if (!state || !state.eliminatedChoices) return;
|
|
266
|
-
|
|
267
|
-
try {
|
|
268
|
-
const eliminated = state.eliminatedChoices;
|
|
269
|
-
|
|
270
|
-
if (!eliminated || eliminated.length === 0) return;
|
|
271
|
-
|
|
272
|
-
// Restore eliminated choices for current element
|
|
273
|
-
for (const choiceId of eliminated) {
|
|
274
|
-
const choice = this.choiceElements.get(choiceId);
|
|
275
|
-
if (!choice) continue;
|
|
276
|
-
|
|
277
|
-
// Use the adapter captured during initialization
|
|
278
|
-
const adapter = this.choiceAdapters.get(choiceId);
|
|
279
|
-
if (!adapter) continue;
|
|
280
|
-
|
|
281
|
-
// Re-eliminate without saving (already in state)
|
|
282
|
-
const range = adapter.createChoiceRange(choice);
|
|
283
|
-
if (range) {
|
|
284
|
-
this.strategy.apply(choiceId, range);
|
|
285
|
-
|
|
286
|
-
// Track in memory
|
|
287
|
-
this.eliminatedChoices.add(choiceId);
|
|
288
|
-
|
|
289
|
-
// Update button appearance to show eliminated state
|
|
290
|
-
const button = this.choiceButtons.get(choiceId);
|
|
291
|
-
if (button) {
|
|
292
|
-
button.classList.add(AnswerEliminatorCore.TOGGLE_ACTIVE_CLASS);
|
|
293
|
-
button.setAttribute("aria-pressed", "true");
|
|
294
|
-
}
|
|
295
|
-
}
|
|
296
|
-
}
|
|
297
|
-
} catch (error) {
|
|
298
|
-
console.error("Failed to restore eliminator state:", error);
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
|
|
302
|
-
/**
|
|
303
|
-
* Cleanup buttons from previous element
|
|
304
|
-
*/
|
|
305
|
-
private cleanupButtons(): void {
|
|
306
|
-
for (const button of this.choiceButtons.values()) {
|
|
307
|
-
button.remove();
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
this.choiceButtons.clear();
|
|
311
|
-
this.choiceElements.clear();
|
|
312
|
-
this.choiceAdapters.clear();
|
|
313
|
-
}
|
|
314
|
-
|
|
315
|
-
/**
|
|
316
|
-
* Apply button positioning based on alignment configuration
|
|
317
|
-
*/
|
|
318
|
-
private applyButtonAlignment(button: HTMLButtonElement): void {
|
|
319
|
-
switch (this.buttonAlignment) {
|
|
320
|
-
case "right":
|
|
321
|
-
// Right-aligned (industry standard) - after choice text
|
|
322
|
-
Object.assign(button.style, {
|
|
323
|
-
position: "absolute",
|
|
324
|
-
right: "8px",
|
|
325
|
-
top: "50%",
|
|
326
|
-
transform: "translateY(-50%)",
|
|
327
|
-
});
|
|
328
|
-
break;
|
|
329
|
-
|
|
330
|
-
case "left":
|
|
331
|
-
// Left-aligned - before choice text
|
|
332
|
-
Object.assign(button.style, {
|
|
333
|
-
position: "absolute",
|
|
334
|
-
left: "8px",
|
|
335
|
-
top: "50%",
|
|
336
|
-
transform: "translateY(-50%)",
|
|
337
|
-
});
|
|
338
|
-
break;
|
|
339
|
-
|
|
340
|
-
case "inline":
|
|
341
|
-
// Inline with checkbox - no absolute positioning
|
|
342
|
-
Object.assign(button.style, {
|
|
343
|
-
position: "relative",
|
|
344
|
-
marginLeft: "8px",
|
|
345
|
-
marginRight: "8px",
|
|
346
|
-
display: "inline-flex",
|
|
347
|
-
verticalAlign: "middle",
|
|
348
|
-
});
|
|
349
|
-
break;
|
|
350
|
-
}
|
|
351
|
-
}
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Enable state restoration from localStorage
|
|
355
|
-
*/
|
|
356
|
-
enableStateRestoration(): void {
|
|
357
|
-
this.shouldRestoreState = true;
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Disable state restoration from localStorage
|
|
362
|
-
*/
|
|
363
|
-
disableStateRestoration(): void {
|
|
364
|
-
this.shouldRestoreState = false;
|
|
365
|
-
}
|
|
366
|
-
|
|
367
|
-
/**
|
|
368
|
-
* Cleanup when tool is turned off (but don't destroy strategy)
|
|
369
|
-
* Hides elimination buttons AND clears all visual eliminations
|
|
370
|
-
* Note: State is preserved in localStorage for when tool is turned back on
|
|
371
|
-
*/
|
|
372
|
-
cleanup(): void {
|
|
373
|
-
// Disable state restoration to prevent restoreState() from re-applying eliminations
|
|
374
|
-
this.disableStateRestoration();
|
|
375
|
-
|
|
376
|
-
// Remove all buttons
|
|
377
|
-
this.cleanupButtons();
|
|
378
|
-
|
|
379
|
-
// Clear all visual eliminations (strikethroughs)
|
|
380
|
-
// This removes the CSS highlights but keeps localStorage state
|
|
381
|
-
this.strategy.clearAll();
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
/**
|
|
385
|
-
* Destroy and cleanup
|
|
386
|
-
*/
|
|
387
|
-
destroy(): void {
|
|
388
|
-
this.cleanupButtons();
|
|
389
|
-
this.strategy.destroy();
|
|
390
|
-
}
|
|
391
|
-
}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"adapter-registry.d.ts","sourceRoot":"","sources":["../../adapters/adapter-registry.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAKzD,MAAM,WAAW,iBAAiB;IACjC,MAAM,EAAE,WAAW,CAAC;IACpB,OAAO,EAAE,aAAa,CAAC;CACvB;AAED;;;GAGG;AACH,qBAAa,eAAe;IAC3B,OAAO,CAAC,QAAQ,CAAkB;;IAWlC;;OAEG;IACH,WAAW,CAAC,OAAO,EAAE,WAAW,GAAG,aAAa,GAAG,IAAI;IAIvD;;OAEG;IACH,0BAA0B,CAAC,IAAI,EAAE,WAAW,GAAG,iBAAiB,EAAE;IAoBlE;;OAEG;IACH,eAAe,CAAC,OAAO,EAAE,aAAa,GAAG,IAAI;CAI7C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"choice-adapter.d.ts","sourceRoot":"","sources":["../../adapters/choice-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC7B,wCAAwC;IACxC,QAAQ,CAAC,WAAW,EAAE,MAAM,CAAC;IAE7B,wCAAwC;IACxC,QAAQ,CAAC,QAAQ,EAAE,MAAM,CAAC;IAE1B;;OAEG;IACH,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC;IAEzC;;OAEG;IACH,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE,CAAC;IAE9C;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI,CAAC;IAErD;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC;IAEzC;;OAEG;IACH,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM,CAAC;IAE5C;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC;IAE3C;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI,CAAC;CAC5D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"ebsr-adapter.d.ts","sourceRoot":"","sources":["../../adapters/ebsr-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD;;;;;GAKG;AACH,qBAAa,WAAY,YAAW,aAAa;IAChD,QAAQ,CAAC,WAAW,UAAU;IAC9B,QAAQ,CAAC,QAAQ,MAAM;IAEvB,OAAO,CAAC,SAAS,CAA+B;IAEhD,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO;IAOxC,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE;IAgB7C,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI;IAIpD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAOxC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAI3C,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAI1C,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI;CAG3D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"inline-dropdown-adapter.d.ts","sourceRoot":"","sources":["../../adapters/inline-dropdown-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;GAIG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IAC1D,QAAQ,CAAC,WAAW,qBAAqB;IACzC,QAAQ,CAAC,QAAQ,MAAM;IAEvB,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO;IAOxC,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE;IAK7C,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI;IAMpD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAIxC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAI3C,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IAK1C,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI;CAG3D"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"multiple-choice-adapter.d.ts","sourceRoot":"","sources":["../../adapters/multiple-choice-adapter.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEzD;;;;;GAKG;AACH,qBAAa,qBAAsB,YAAW,aAAa;IAC1D,QAAQ,CAAC,WAAW,qBAAqB;IACzC,QAAQ,CAAC,QAAQ,OAAO;IACxB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CACH;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAsC;IAC7E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAqC;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CACE;IAC5C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAC+D;IAEtG,SAAS,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO;IAOxC,WAAW,CAAC,IAAI,EAAE,WAAW,GAAG,WAAW,EAAE;IAY7C,iBAAiB,CAAC,MAAM,EAAE,WAAW,GAAG,KAAK,GAAG,IAAI;IAcpD,WAAW,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAYxC,cAAc,CAAC,MAAM,EAAE,WAAW,GAAG,MAAM;IAK3C,YAAY,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO;IA2B1C,kBAAkB,CAAC,MAAM,EAAE,WAAW,GAAG,WAAW,GAAG,IAAI;IAK3D,OAAO,CAAC,kBAAkB;IAa1B,OAAO,CAAC,cAAc;IAQtB,OAAO,CAAC,mBAAmB;IAU3B,OAAO,CAAC,qBAAqB;CAU7B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"answer-eliminator-core.d.ts","sourceRoot":"","sources":["../answer-eliminator-core.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8BAA8B,CAAC;AAKlE;;;GAGG;AACH,qBAAa,oBAAoB;IAChC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,YAAY,CAAkC;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,mBAAmB,CACH;IACxC,OAAO,CAAC,QAAQ,CAAkB;IAClC,OAAO,CAAC,QAAQ,CAAsB;IACtC,OAAO,CAAC,iBAAiB,CAAqB;IAC9C,OAAO,CAAC,cAAc,CAAkC;IACxD,OAAO,CAAC,aAAa,CAAwC;IAC7D,OAAO,CAAC,cAAc,CAAoC;IAC1D,OAAO,CAAC,eAAe,CAAwC;IAC/D,OAAO,CAAC,kBAAkB,CAAiB;IAG3C,OAAO,CAAC,gBAAgB,CAGR;gBAGf,YAAY,GAAE,eAAe,GAAG,MAAM,GAAG,MAAwB,EACjE,eAAe,GAAE,MAAM,GAAG,OAAO,GAAG,QAAkB;IAQvD,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,qBAAqB,CAAC,YAAY,EAAE,WAAW,GAAG,IAAI;IAmBtD;;OAEG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;OAEG;IACH,OAAO,CAAC,kBAAkB;IA0B1B;;OAEG;IACH,iBAAiB,CAAC,MAAM,EAAE,WAAW,EAAE,OAAO,EAAE,aAAa,GAAG,IAAI;IAyBpE;;OAEG;IACH,OAAO,CAAC,eAAe;IA2BvB;;OAEG;IACH,OAAO,CAAC,aAAa;IAkBrB;;OAEG;IACH,QAAQ,IAAI,IAAI;IAahB;;OAEG;IACH,kBAAkB,IAAI,MAAM;IAI5B;;;;OAIG;IACH,mBAAmB,CAAC,KAAK,EAAE,GAAG,EAAE,eAAe,EAAE,MAAM,GAAG,IAAI;IAI9D;;OAEG;IACH,OAAO,CAAC,SAAS;IAcjB;;OAEG;IACH,OAAO,CAAC,YAAY;IA6CpB;;OAEG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,OAAO,CAAC,oBAAoB;IAmC5B;;OAEG;IACH,sBAAsB,IAAI,IAAI;IAI9B;;OAEG;IACH,uBAAuB,IAAI,IAAI;IAI/B;;;;OAIG;IACH,OAAO,IAAI,IAAI;IAYf;;OAEG;IACH,OAAO,IAAI,IAAI;CAIf"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,EAAE,eAAe,EAAE,MAAM,gCAAgC,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"elimination-strategy.d.ts","sourceRoot":"","sources":["../../strategies/elimination-strategy.ts"],"names":[],"mappings":"AAAA;;;GAGG;AACH,MAAM,WAAW,mBAAmB;IACnC,oBAAoB;IACpB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;;;OAIG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI,CAAC;IAE5C;;;OAGG;IACH,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IAE/B;;;OAGG;IACH,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC;IAExC;;OAEG;IACH,QAAQ,IAAI,IAAI,CAAC;IAEjB;;OAEG;IACH,gBAAgB,IAAI,MAAM,EAAE,CAAC;IAE7B;;OAEG;IACH,UAAU,IAAI,IAAI,CAAC;IAEnB;;OAEG;IACH,OAAO,IAAI,IAAI,CAAC;CAChB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"mask-strategy.d.ts","sourceRoot":"","sources":["../../strategies/mask-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE;;;GAGG;AACH,qBAAa,YAAa,YAAW,mBAAmB;IACvD,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CACL;IACzC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAAwB;IACrE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CAAgC;IACtE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CACH;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAgC;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAmC;IAE7E,QAAQ,CAAC,IAAI,UAAU;IAEvB,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,UAAU,IAAI,IAAI;IAIlB,OAAO,IAAI,IAAI;IAIf,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAqB3C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAqB9B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIvC,QAAQ,IAAI,IAAI;IAOhB,gBAAgB,IAAI,MAAM,EAAE;IAI5B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAe1B,OAAO,CAAC,kBAAkB;IAM1B,OAAO,CAAC,iBAAiB;IAQzB,OAAO,CAAC,oBAAoB;IAQ5B,OAAO,CAAC,mBAAmB;IAkB3B,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,cAAc;CAatB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"strikethrough-strategy.d.ts","sourceRoot":"","sources":["../../strategies/strikethrough-strategy.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,2BAA2B,CAAC;AAErE;;;;;;GAMG;AACH,qBAAa,qBAAsB,YAAW,mBAAmB;IAChE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,sBAAsB,CACV;IACpC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,qBAAqB,CAA4B;IACzE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,cAAc,CACO;IAC7C,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,QAAQ,CAA2C;IAC3E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,gBAAgB,CACH;IACrC,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAsC;IAC7E,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,eAAe,CAAgC;IACvE,OAAO,CAAC,MAAM,CAAC,QAAQ,CAAC,kBAAkB,CAAmC;IAE7E,QAAQ,CAAC,IAAI,mBAAmB;IAEhC,OAAO,CAAC,UAAU,CAAgC;IAClD,OAAO,CAAC,MAAM,CAA4B;IAC1C,OAAO,CAAC,kBAAkB,CAAkC;IAE5D,UAAU,IAAI,IAAI;IAOlB,OAAO,IAAI,IAAI;IAIf,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IA0B3C,MAAM,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAyB9B,YAAY,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAIvC,QAAQ,IAAI,IAAI;IAQhB,gBAAgB,IAAI,MAAM,EAAE;IAI5B,OAAO,CAAC,WAAW;IAInB,OAAO,CAAC,kBAAkB;IAiB1B,OAAO,CAAC,kBAAkB;IAQ1B,OAAO,CAAC,iBAAiB;IAkBzB,OAAO,CAAC,oBAAoB;IAc5B,OAAO,CAAC,mBAAmB;IAsB3B,OAAO,CAAC,aAAa;IAWrB,OAAO,CAAC,cAAc;IAetB,OAAO,CAAC,mBAAmB;CAO3B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"vite.config.d.ts","sourceRoot":"","sources":["../vite.config.ts"],"names":[],"mappings":";AAKA,wBAkCG"}
|
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Strategy interface for visual elimination styles
|
|
3
|
-
* Uses CSS Custom Highlight API for zero DOM mutation
|
|
4
|
-
*/
|
|
5
|
-
export interface EliminationStrategy {
|
|
6
|
-
/** Strategy name */
|
|
7
|
-
readonly name: string;
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Apply elimination visual to a choice
|
|
11
|
-
* @param choiceId - Unique identifier for this choice
|
|
12
|
-
* @param range - DOM Range covering the choice content
|
|
13
|
-
*/
|
|
14
|
-
apply(choiceId: string, range: Range): void;
|
|
15
|
-
|
|
16
|
-
/**
|
|
17
|
-
* Remove elimination visual from a choice
|
|
18
|
-
* @param choiceId - Unique identifier for this choice
|
|
19
|
-
*/
|
|
20
|
-
remove(choiceId: string): void;
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Check if a choice is currently eliminated
|
|
24
|
-
* @param choiceId - Unique identifier for this choice
|
|
25
|
-
*/
|
|
26
|
-
isEliminated(choiceId: string): boolean;
|
|
27
|
-
|
|
28
|
-
/**
|
|
29
|
-
* Clear all eliminations
|
|
30
|
-
*/
|
|
31
|
-
clearAll(): void;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* Get all eliminated choice IDs
|
|
35
|
-
*/
|
|
36
|
-
getEliminatedIds(): string[];
|
|
37
|
-
|
|
38
|
-
/**
|
|
39
|
-
* Initialize strategy (inject CSS, etc.)
|
|
40
|
-
*/
|
|
41
|
-
initialize(): void;
|
|
42
|
-
|
|
43
|
-
/**
|
|
44
|
-
* Cleanup strategy (remove CSS, etc.)
|
|
45
|
-
*/
|
|
46
|
-
destroy(): void;
|
|
47
|
-
}
|
|
@@ -1,171 +0,0 @@
|
|
|
1
|
-
import type { EliminationStrategy } from "./elimination-strategy.js";
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Mask strategy using CSS Custom Highlight API
|
|
5
|
-
* Partially hides/grays eliminated choices
|
|
6
|
-
*/
|
|
7
|
-
export class MaskStrategy implements EliminationStrategy {
|
|
8
|
-
private static readonly HIGHLIGHT_STYLE_PREFIX =
|
|
9
|
-
"pie-answer-eliminator-mask-highlight-";
|
|
10
|
-
private static readonly HIGHLIGHT_NAME_PREFIX = "pie-answer-masked-";
|
|
11
|
-
private static readonly FALLBACK_CLASS = "pie-answer-masked-fallback";
|
|
12
|
-
private static readonly CHOICE_HOOK_ATTR =
|
|
13
|
-
"data-pie-answer-eliminator-choice";
|
|
14
|
-
private static readonly ELIMINATED_ATTR = "data-pie-answer-eliminated";
|
|
15
|
-
private static readonly ELIMINATED_ID_ATTR = "data-pie-answer-eliminated-id";
|
|
16
|
-
|
|
17
|
-
readonly name = "mask";
|
|
18
|
-
|
|
19
|
-
private highlights = new Map<string, Highlight>();
|
|
20
|
-
private ranges = new Map<string, Range>();
|
|
21
|
-
private fallbackContainers = new Map<string, HTMLElement>();
|
|
22
|
-
|
|
23
|
-
initialize(): void {
|
|
24
|
-
// No-op: shared fallback styles are owned by @pie-players/pie-theme/components.css.
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
destroy(): void {
|
|
28
|
-
this.clearAll();
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
apply(choiceId: string, range: Range): void {
|
|
32
|
-
if (!this.isSupported()) {
|
|
33
|
-
this.applyFallback(choiceId, range);
|
|
34
|
-
return;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Inject CSS for this specific highlight
|
|
38
|
-
this.injectHighlightCSS(choiceId);
|
|
39
|
-
|
|
40
|
-
const highlight = new Highlight(range);
|
|
41
|
-
CSS.highlights.set(
|
|
42
|
-
`${MaskStrategy.HIGHLIGHT_NAME_PREFIX}${choiceId}`,
|
|
43
|
-
highlight,
|
|
44
|
-
);
|
|
45
|
-
|
|
46
|
-
this.highlights.set(choiceId, highlight);
|
|
47
|
-
this.ranges.set(choiceId, range);
|
|
48
|
-
|
|
49
|
-
this.addAriaAttributes(range);
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
remove(choiceId: string): void {
|
|
53
|
-
if (!this.isSupported()) {
|
|
54
|
-
this.removeFallback(choiceId);
|
|
55
|
-
return;
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
CSS.highlights.delete(`${MaskStrategy.HIGHLIGHT_NAME_PREFIX}${choiceId}`);
|
|
59
|
-
|
|
60
|
-
// Remove CSS for this specific highlight
|
|
61
|
-
this.removeHighlightCSS(choiceId);
|
|
62
|
-
|
|
63
|
-
const range = this.ranges.get(choiceId);
|
|
64
|
-
if (range) {
|
|
65
|
-
this.removeAriaAttributes(range);
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
this.highlights.delete(choiceId);
|
|
69
|
-
this.ranges.delete(choiceId);
|
|
70
|
-
this.fallbackContainers.delete(choiceId);
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
isEliminated(choiceId: string): boolean {
|
|
74
|
-
return this.highlights.has(choiceId);
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
clearAll(): void {
|
|
78
|
-
for (const choiceId of this.highlights.keys()) {
|
|
79
|
-
this.remove(choiceId);
|
|
80
|
-
}
|
|
81
|
-
this.fallbackContainers.clear();
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
getEliminatedIds(): string[] {
|
|
85
|
-
return Array.from(this.highlights.keys());
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
private isSupported(): boolean {
|
|
89
|
-
return typeof CSS !== "undefined" && "highlights" in CSS;
|
|
90
|
-
}
|
|
91
|
-
|
|
92
|
-
private injectHighlightCSS(choiceId: string): void {
|
|
93
|
-
const styleId = `${MaskStrategy.HIGHLIGHT_STYLE_PREFIX}${choiceId}`;
|
|
94
|
-
if (document.getElementById(styleId)) return;
|
|
95
|
-
|
|
96
|
-
const style = document.createElement("style");
|
|
97
|
-
style.id = styleId;
|
|
98
|
-
style.textContent = `
|
|
99
|
-
::highlight(pie-answer-masked-${choiceId}) {
|
|
100
|
-
opacity: 0.2;
|
|
101
|
-
filter: blur(2px);
|
|
102
|
-
}
|
|
103
|
-
`;
|
|
104
|
-
document.head.appendChild(style);
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
private removeHighlightCSS(choiceId: string): void {
|
|
108
|
-
document
|
|
109
|
-
.getElementById(`${MaskStrategy.HIGHLIGHT_STYLE_PREFIX}${choiceId}`)
|
|
110
|
-
?.remove();
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private addAriaAttributes(range: Range): void {
|
|
114
|
-
const container = this.findChoiceContainer(range);
|
|
115
|
-
if (!container) return;
|
|
116
|
-
|
|
117
|
-
container.setAttribute(MaskStrategy.ELIMINATED_ATTR, "true");
|
|
118
|
-
container.setAttribute("aria-hidden", "true");
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
private removeAriaAttributes(range: Range): void {
|
|
122
|
-
const container = this.findChoiceContainer(range);
|
|
123
|
-
if (!container) return;
|
|
124
|
-
|
|
125
|
-
container.removeAttribute(MaskStrategy.ELIMINATED_ATTR);
|
|
126
|
-
container.removeAttribute("aria-hidden");
|
|
127
|
-
}
|
|
128
|
-
|
|
129
|
-
private findChoiceContainer(range: Range): HTMLElement | null {
|
|
130
|
-
let element: HTMLElement | null = range.startContainer as HTMLElement;
|
|
131
|
-
|
|
132
|
-
// If startContainer is a text node, get its parent
|
|
133
|
-
if (element.nodeType === Node.TEXT_NODE) {
|
|
134
|
-
element = element.parentElement;
|
|
135
|
-
}
|
|
136
|
-
|
|
137
|
-
while (element && element !== document.body) {
|
|
138
|
-
if (element.getAttribute(MaskStrategy.CHOICE_HOOK_ATTR) === "true") {
|
|
139
|
-
return element;
|
|
140
|
-
}
|
|
141
|
-
element = element.parentElement;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
return null;
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
private applyFallback(choiceId: string, range: Range): void {
|
|
148
|
-
const container = this.findChoiceContainer(range);
|
|
149
|
-
if (!container) return;
|
|
150
|
-
|
|
151
|
-
container.classList.add(MaskStrategy.FALLBACK_CLASS);
|
|
152
|
-
container.setAttribute(MaskStrategy.ELIMINATED_ATTR, "true");
|
|
153
|
-
container.setAttribute(MaskStrategy.ELIMINATED_ID_ATTR, choiceId);
|
|
154
|
-
this.fallbackContainers.set(choiceId, container);
|
|
155
|
-
this.addAriaAttributes(range);
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
private removeFallback(choiceId: string): void {
|
|
159
|
-
const container = this.fallbackContainers.get(choiceId);
|
|
160
|
-
if (!container) return;
|
|
161
|
-
|
|
162
|
-
container.classList.remove(MaskStrategy.FALLBACK_CLASS);
|
|
163
|
-
container.removeAttribute(MaskStrategy.ELIMINATED_ATTR);
|
|
164
|
-
container.removeAttribute(MaskStrategy.ELIMINATED_ID_ATTR);
|
|
165
|
-
|
|
166
|
-
const range = document.createRange();
|
|
167
|
-
range.selectNodeContents(container);
|
|
168
|
-
this.removeAriaAttributes(range);
|
|
169
|
-
this.fallbackContainers.delete(choiceId);
|
|
170
|
-
}
|
|
171
|
-
}
|