Export Web/SCORM : inline les icônes en data: URI (CORS Firefox/file://)
Le chemin relatif ("icons/x.svg") était enfin correct, mais Firefox
bloque encore par CORS TOUT chemin de fichier pour mask-image sous
file:// — chaque ressource file:// y est une origine opaque distincte,
indépendamment du chemin (troisième rapport du même utilisateur). Seule
une data: URI (aucune requête réseau séparée) contourne le problème.
_build_icon_data_uris (build_scorm_package.py) encode chaque icône
RÉELLEMENT posée dans le jeu (élément direct ou niché dans un élément de
jeu réutilisable) en base64, ajouté au payload sous
gameData.icon_data_uris ; forgeRenderIcone (JS) le consulte pour toute
régénération après une action, avec repli sur l'ancien chemin relatif
si jamais une icône n'a pas été pré-encodée.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
b60fe63a54
commit
82d00b3800
@@ -58,6 +58,21 @@ test('icône — repli sur "star" si _icon_slug absent', () => {
|
||||
assert.ok(html.includes("--icon-url:url('icons/star.svg')"));
|
||||
});
|
||||
|
||||
// Régression signalée par un utilisateur (deux fois) : un chemin de
|
||||
// fichier pour --icon-url, même corrigé pour être relatif à
|
||||
// static/style.css (là où mask-image:var(--icon-url) le consomme), reste
|
||||
// bloqué par CORS sous Firefox+file:// (chaque ressource file:// y est une
|
||||
// origine opaque distincte). gameData.icon_data_uris (pré-encodé à
|
||||
// l'export, voir build_scorm_package.py::_build_icon_data_uris) contourne
|
||||
// entièrement le problème : aucune requête réseau séparée pour une data: URI.
|
||||
test('icône — utilise gameData.icon_data_uris quand pré-encodée (contourne le blocage CORS de Firefox sous file://)', () => {
|
||||
const el = { id: 6, widget: 'icone', attributes: { _icon_slug: 'envelope' }, style: {} };
|
||||
const gd = baseGameData();
|
||||
gd.icon_data_uris = { envelope: 'data:image/svg+xml;base64,QUJD' };
|
||||
const html = forgeRenderElementHtml(el, gd, {}, {});
|
||||
assert.ok(html.includes("--icon-url:url('data:image/svg+xml;base64,QUJD')"));
|
||||
});
|
||||
|
||||
test('onglets — un panneau actif, les autres masqués', () => {
|
||||
const parent = { id: 7, widget: 'onglets', attributes: {}, style: {} };
|
||||
const tab1 = { id: 8, name: 'Infos', widget: 'conteneur', content: '', attributes: {}, style: {}, parent_id: 7 };
|
||||
|
||||
@@ -73,17 +73,18 @@ function forgeRenderIcone(el, meta, gameData, childrenMap, ctx, parentFlexDirect
|
||||
var existingClass = attrs.class || "";
|
||||
delete attrs.class;
|
||||
attrs.class = (existingClass + " icon-svg").trim();
|
||||
// Chemin RELATIF, et surtout PAS préfixé "static/" : cette URL est
|
||||
// posée dans --icon-url (style inline) mais CONSOMMÉE par `mask-image:
|
||||
// var(--icon-url)` dans static/style.css (voir .icon-svg) — une URL
|
||||
// relative dans une propriété personnalisée CSS se résout par rapport à
|
||||
// LA FEUILLE DE STYLE où le var() est utilisé (static/style.css), pas
|
||||
// où elle est définie (piège CSS connu) : "static/icons/x.svg" y
|
||||
// redeviendrait "static/static/icons/x.svg" (404/CORS bloqué — bug
|
||||
// signalé). "icons/x.svg" est correct une fois résolu depuis
|
||||
// static/style.css (voir aussi _relativize_absolute_urls dans
|
||||
// publish/build_scorm_package.py, même correctif côté rendu initial).
|
||||
var iconUrl = "icons/" + iconSlug + ".svg";
|
||||
// data: URI pré-calculée à l'export (voir gameData.icon_data_uris,
|
||||
// publish/build_scorm_package.py::_build_icon_data_uris) — jamais un
|
||||
// chemin de fichier, même relatif : Firefox traite chaque ressource
|
||||
// file:// comme une origine opaque distincte, et mask-image y déclenche
|
||||
// un fetch en mode CORS quel que soit le chemin ("Blocage d'une requête
|
||||
// multiorigine... la requête CORS n'utilise pas HTTP", signalé par un
|
||||
// utilisateur MALGRÉ un chemin relatif par ailleurs correct). Repli sur
|
||||
// un chemin relatif si jamais l'icône n'a pas été pré-encodée (ne
|
||||
// devrait pas arriver : _collect_icon_slugs scanne tous les widgets
|
||||
// "icone", posés directement ou nichés dans un élément de jeu
|
||||
// réutilisable) — au moins un lien exploitable plutôt qu'un vide.
|
||||
var iconUrl = (gameData.icon_data_uris && gameData.icon_data_uris[iconSlug]) || ("icons/" + iconSlug + ".svg");
|
||||
var style = forgeStyleString(el, parentFlexDirection, el.widget) + " --icon-url:url('" + iconUrl + "');";
|
||||
return "<i " + forgeAttrString(attrs, style) + "></i>";
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user