// Export Web/SCORM (voir le plan "port complet du runtime jouable côté // navigateur") — étape 5 : orchestrateur appelé par refreshRuntimeData() // (static/js/play/bindings.js) en mode FORGE_OFFLINE, à la place du // fetch(runtimePayload) habituel. Rejoue, pour chaque écran "document" // (kind !== 'jeu_2d'), la même boucle que screens/payload/ // full_game_payload.py : régénère le rendered_html de CHAQUE élément // (premier niveau ET imbriqué — voir screens/elements/list_elements.py, // qui donne à chacun son propre rendered_html indépendant, pas seulement // aux éléments de premier niveau) à partir de gameData déjà en mémoire // (variables/score/données déjà mutées par apply-actions.js). // // Un écran "jeu_2d" (scène 2D) n'a JAMAIS besoin d'être régénéré ici : // ses objets se mutent déjà directement dans le DOM, sans aller-retour // serveur ni rendered_html à recalculer (voir applyObjectProperty() dans // static/js/play/actions.js, appelée par l'action "Modifier un objet de // scène" — comportement identique en ligne et hors ligne, rien à porter). function forgeRecomputeElementsForScreenOffline(gameData, screen) { const elements = screen.elements || []; const childrenMap = {}; elements.forEach((el) => { if (el.parent_id) { if (!childrenMap[el.parent_id]) childrenMap[el.parent_id] = []; childrenMap[el.parent_id].push(el); } }); const playCtx = { _forge_play_mode: true }; elements.forEach((el) => { el.rendered_html = forgeRenderElementHtml(el, gameData, childrenMap, playCtx); }); } function forgeRecomputeFullPayloadOffline(gameData) { (gameData.screens || []).forEach((s) => { if (s.kind !== 'jeu_2d') forgeRecomputeElementsForScreenOffline(gameData, s); }); return gameData; } if (typeof module !== 'undefined' && module.exports) { module.exports = { forgeRecomputeElementsForScreenOffline, forgeRecomputeFullPayloadOffline }; global.forgeRenderElementHtml = global.forgeRenderElementHtml || require('./render-element.js').forgeRenderElementHtml; }