Checkpoint current interactive fiction changes

This commit is contained in:
2026-06-03 12:59:43 +02:00
parent 61127c0a92
commit bccefd2a68
11 changed files with 342 additions and 895 deletions
+36 -3
View File
@@ -8,11 +8,13 @@ class ChoiceDisplayModule extends BaseModule {
constructor() {
super('choice-display', 'Choice Display');
this.dependencies = ['socket-client', 'markup-parser'];
this.dependencies = ['socket-client', 'markup-parser', 'layout-renderer'];
this.socketClient = null;
this.markupParser = null;
this.layoutRenderer = null;
this.container = null;
this.choices = [];
this.currentGlossaryEntries = [];
this.inputMode = 'none';
this.processState = document.documentElement.dataset.processState || 'loading';
this.currentTurnId = 0;
@@ -52,13 +54,15 @@ class ChoiceDisplayModule extends BaseModule {
'getTagValue',
'getTag',
'getTemplateCell',
'renderChoiceText'
'renderChoiceText',
'applyChoiceGlossary'
]);
}
async initialize() {
this.socketClient = this.getModule('socket-client');
this.markupParser = this.getModule('markup-parser');
this.layoutRenderer = this.getModule('layout-renderer');
this.setupContainer();
this.addEventListener(document, 'story:choices', (event) => {
@@ -124,7 +128,14 @@ class ChoiceDisplayModule extends BaseModule {
}
handleChoices(choices) {
this.choices = this.normalizeChoices(Array.isArray(choices) ? choices : []);
const detail = Array.isArray(choices)
? { choices, glossaryEntries: [] }
: {
choices: Array.isArray(choices?.choices) ? choices.choices : [],
glossaryEntries: Array.isArray(choices?.glossaryEntries) ? choices.glossaryEntries : []
};
this.currentGlossaryEntries = detail.glossaryEntries;
this.choices = this.normalizeChoices(detail.choices);
this.render();
}
@@ -344,6 +355,7 @@ class ChoiceDisplayModule extends BaseModule {
const renderedText = this.renderChoiceText(choice.text);
const displayKey = this.formatChoiceKey(choice.letter);
button.innerHTML = `<kbd>${this.escapeHtml(displayKey)}</kbd><span>${choice.optional ? `<em>${renderedText}</em>` : renderedText}</span>`;
this.applyChoiceGlossary(button.querySelector('span'), choice);
button.addEventListener('click', () => this.selectChoice(choice.index));
item.appendChild(button);
list.appendChild(item);
@@ -470,6 +482,27 @@ class ChoiceDisplayModule extends BaseModule {
.replace(/_([^_\s][^_]*?)_/g, '<em>$1</em>');
}
applyChoiceGlossary(label, choice = null) {
if (!label) return;
if (!this.layoutRenderer) {
this.layoutRenderer = this.getModule('layout-renderer');
}
if (!this.markupParser) {
this.markupParser = this.getModule('markup-parser');
}
const choiceEntries = this.markupParser && typeof this.markupParser.extractGlossaryTags === 'function'
? this.markupParser.extractGlossaryTags(choice?.tags || [])
: [];
const entries = [
...(Array.isArray(this.currentGlossaryEntries) ? this.currentGlossaryEntries : []),
...choiceEntries
];
if (entries.length === 0) return;
if (this.layoutRenderer && typeof this.layoutRenderer.applyGlossaryEntriesToInline === 'function') {
this.layoutRenderer.applyGlossaryEntriesToInline(label, entries);
}
}
formatChoiceKey(key) {
const value = String(key || '').trim().charAt(0);
return /^[A-Z]$/.test(value) ? value.toLowerCase() : value;