Repository navigation
feat(visor): nunca una pantalla en blanco, y el log dice quién se queda fuera - #112
Merged
Merged
Conversation
- assets/compat.js, ES5 y script clásico, va antes que hls.js y que el módulo en las tres páginas del visor. Pone replaceChildren si falta y, si al cargar la página el visor no dejó window.__visorArrancado, explica qué hacer, ofrece la copia sellada de los PDF y lo cuenta a POST /telemetry/compat. Un <noscript> cubre el caso sin JavaScript. - player.js, pdf.js y collection.js ponen la marca al terminar su arranque síncrono, y pdf.js y collection.js dejan el await de nivel superior (Safari 14, Chrome < 89 no lo entienden). El marcador y la telemetría del vídeo van en try/catch: perderlos no puede tumbar el visor. - Suelo del visor (ES2021, sin asignación lógica ni lookbehind) vigilado por test/ui-compat.test.js recorriendo los import, y repetido en eslint.config.js. La guardia se prueba ejecutándola en un DOM mínimo. - app.css: estilo del aviso con CSS antiguo y la capa del <dialog> sin soporte nativo. Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
…isor POST /telemetry/compat exige sesión, deja una línea warn «Visor sin arrancar en este navegador» con el user-agent, la página y el motivo (enumerado y recortado) y responde 204 siempre. No guarda nada propio ni el sub del alumno. Lo usan la guardia, el visor de PDF cuando PDF.js no carga y el vídeo cuando el navegador no puede reproducirlo; esos dos mensajes dicen además qué hacer (otro navegador, actualizar iOS). Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
En Safari < 15.4 y Firefox < 98 no hay showModal y el form method="dialog" se enviaba como un GET a /lti/launch. dialog.js lo abre como capa, cierra con el botón pulsado o con Escape y emite close, sólo en esos navegadores. Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
… respaldo lleva el foco - compat.js: tras un fallo de descarga el botón enseña el error, y el reintento que salía bien volvía a poner ese error en vez del rótulo. Se guarda el rótulo la primera vez y se repone en cualquier descarga buena (también en el camino de msSaveOrOpenBlob, que no lo hacía). - dialog.js: sin showModal (Safari < 15.4, Firefox < 98), el foco entra en el diálogo y vuelve adonde estaba al cerrarlo, como en el nativo. Con teclado o lector de pantalla no se notaba que se había abierto. Las dos pruebas nuevas fallan con el código anterior. Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
…erdad
La prueba del suelo dejaba pasar lo que no entienden Firefox 74–79 (grupos
con nombre, \p{…}, flag s, `export * as`) ni Safari 13 (BigInt). Hoy ningún
módulo del visor lo usa, pero la documentación decía que se vigilaba.
- SUELO_DEL_VISOR añade esos cinco casos.
- Una prueba comprueba que el suelo caza cada caso, y que no marca lo que
esos navegadores sí entienden.
- El grafo del visor se lee del árbol sintáctico: sigue también los
`export … from` y los `import()` con literal.
Refs #110
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
… por el navegador POST /telemetry/compat escribía la misma línea cuando el visor no arrancaba y cuando, ya arrancado, fallaba PDF.js o el vídeo. Eso último también pasa en un navegador al día (un corte de red al cargar PDF.js, un vídeo que no se puede descodificar) y habría inflado la cuenta de quién sigue fuera. Ahora va como «Visor sin poder con el PDF o el vídeo en este navegador». Refs #110 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
jamataran
added a commit
that referenced
this pull request
Oct 8, 2026
539 unitarias (527 pasan, 12 se saltan sin las herramientas del worker) y 187 de integración, medidas sobre la suma de las cuatro ramas. Refs #108 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Segundo paso de #110: si un navegador no puede con el visor, el alumno ve qué hacer en vez de una pantalla en blanco, y el servidor lo deja escrito en el log. Apilado sobre #111: se mergea después de que #111 esté en
test(al borrar su rama, GitHub cambia la base de éste atest; si no, cámbiala a mano).Qué cambia
pdf.jsycollection.jsdejan elawaitde nivel superior (Safari 14 y Chrome < 89 no lo entienden y no ejecutaban ni una línea).test/ui-compat.test.jsrecorre losimportdesde cada entrada y comprueba con elLinterde ESLint que nada pase de ES2021, ni use asignación lógica (Safari 14) ni lookbehind (Safari 16.4).eslint.config.jsrepite el suelo para que lo marque el editor.assets/compat.js, ES5 y script clásico, antes quehls.min.jsy que el módulo:replaceChildrensi falta (el visor lo usa al arrancar);load, si el visor no dejówindow.__visorArrancado, pinta en#contentqué hacer (volver a abrir, otro navegador, Windows 7, iOS, la app de Moodle), ofrece la copia sellada de cada PDF por XHR y lo cuenta al servidor.<noscript>cubre el caso sin JavaScript.POST /telemetry/compat: exige sesión y deja una líneawarn«Visor sin arrancar en este navegador» con user-agent, página y motivo (sin-modulos,sintaxis,carga,ejecucion,sin-arranque,pdfjs,sin-hlsomedio; enumerado y recortado). Responde 204 siempre y no guarda nada propio ni elsub. Lo usan la guardia, el visor de PDF cuando PDF.js no carga y el vídeo cuando el navegador no puede reproducirlo; esos mensajes dicen ahora qué hacer.<dialog>sin soporte nativo (Safari < 15.4, Firefox < 98): el aviso legal se abre como capa y suform method="dialog"se intercepta. Antes, pulsar «Entendido» mandaba un GET a/lti/launch.docs/arquitectura.md, fila «Navegadores» en las limitaciones dedocs/README.mdy trampas enCLAUDE.mdydocs/desarrollo.md.Regla 0-bis
Nada de lo desplegado se rehace. En un navegador que arranca el visor no cambia nada visible: la guardia sólo lee una marca.
Evidencia
Pruebas:
npm run lintlimpio ·npm test515 pruebas, 0 fallos (10 saltadas: las de la imagen del worker).test/ui-compat.test.js(9): suelo de sintaxis por el grafo real; la misma lista en eslint; la guardia en ES5 y en su sitio de cada HTML; la marca de cada entrada; y la guardia ejecutada en un DOM mínimo. Con el visor sano no toca nada; con unSyntaxErrorexplica, ofrece la copia y lo cuenta; reconoce un navegador sin módulos; no confunde el error de un<video>con el de un script.test/telemetry-compat.test.js(3) ytest/dialogo-sin-soporte.test.js(3).Motores reales (Chromium 109, Firefox 115 ESR, Chrome 154), con la CSP de producción y en un iframe de otro origen:
collection.js)coleccion/sintaxispdf-component.js)pdf/sintaxisvideo/medio (bufferAddCodecError)** El Chromium de los snapshots no trae H.264: es justo el caso que el informe tiene que registrar.
Por análisis, no probado aquí: Safari 13.4–16.3 y los Chromium < 109 de los televisores. Para eso está la línea del log.
Tras la revisión (8 oct)
Ningún falso positivo ni regresión para quien ya entraba. Se arreglan cinco cabos menores, cada uno con una prueba que falla con el código anterior. Incluye #111 actualizado (merge).
\p{…}, flags, BigInt yexport * as.export … from.Para cerrar #110
En test, con Moodle y los aparatos de #110; y en prod, una semana de
docker logs <app> 2>&1 | grep -E 'Visor sin (arrancar|poder)'.Refs #110
🤖 Generated with Claude Code
https://claude.ai/code/session_01WqzjFTX6sP8s6J24cx7aYv