| 1 | export const ES_APPLE = /.*(iPad|iPhone|iPod|Mac).*/.test(navigator.userAgent) |
| 1 | /** |
| 2 | * @param {HTMLElement} elementoHtml |
| 3 | * @param {string} nombre |
| 4 | * @returns {string} |
| 5 | */ |
| 6 | export function getAttribute(elementoHtml, nombre) { |
| 7 | const valor = elementoHtml.getAttribute(nombre) |
| 8 | return valor === null ? "" : valor |
| 9 | } |
| 1 | import { muestraError } from "./muestraError.js" |
| 2 | |
| 3 | /** |
| 4 | * Intercepta Response.prototype.json para capturar errores de parseo |
| 5 | * y asegurar que se reporten correctamente en navegadores Chromium. |
| 6 | */ |
| 7 | { |
| 8 | const originalJson = Response.prototype.json |
| 9 | |
| 10 | Response.prototype.json = function () { |
| 11 | // Llamamos al método original usando el contexto (this) de la respuesta |
| 12 | return originalJson.call(this) |
| 13 | .catch((/** @type {any} */ error) => { |
| 14 | // Corrige un error de Chrome que evita el manejo correcto de errores. |
| 15 | throw new Error(error) |
| 16 | }) |
| 17 | } |
| 18 | } |
| 19 | |
| 20 | window.onerror = function ( |
| 21 | /** @type {Event | string} */ _event, |
| 22 | /** @type {string | undefined} */ _fuente, |
| 23 | /** @type {number | undefined} */ _numeroDeLinea, |
| 24 | /** @type {number | undefined} */ _numeroDeColumna, |
| 25 | /** @type {Error | undefined} */ error |
| 26 | ) { |
| 27 | muestraError(error) |
| 28 | return true |
| 29 | } |
| 30 | |
| 31 | window.addEventListener('unhandledrejection', event => { |
| 32 | muestraError(event.reason) |
| 33 | event.preventDefault() |
| 34 | }) |
| 1 | import { ProblemDetailsError } from "./ProblemDetailsError.js" |
| 2 | |
| 3 | /** |
| 4 | * Muestra los datos de una Error en la consola y en un cuadro de alerta. |
| 5 | * @param { unknown } error descripción del error. |
| 6 | */ |
| 7 | export function muestraError(error) { |
| 8 | |
| 9 | if (error instanceof ProblemDetailsError) { |
| 10 | |
| 11 | const problemDetails = error.problemDetails |
| 12 | |
| 13 | let mensaje = |
| 14 | typeof problemDetails["title"] === "string" ? problemDetails["title"] : "" |
| 15 | if (typeof problemDetails["detail"] === "string") { |
| 16 | if (mensaje !== "") { |
| 17 | mensaje += "\n" |
| 18 | } |
| 19 | mensaje += problemDetails["detail"] |
| 20 | } |
| 21 | if (mensaje === "") { |
| 22 | mensaje = "Error" |
| 23 | } |
| 24 | console.error(error, problemDetails) |
| 25 | alert(mensaje) |
| 26 | |
| 27 | } else if ( |
| 28 | typeof error === "object" && error !== null && "message" in error |
| 29 | ) { |
| 30 | |
| 31 | console.error(error) |
| 32 | alert(error.message) |
| 33 | |
| 34 | } else { |
| 35 | |
| 36 | console.error("Error", error) |
| 37 | alert("Error") |
| 38 | |
| 39 | } |
| 40 | |
| 41 | } |
| 1 | export class ProblemDetailsError extends Error { |
| 2 | |
| 3 | /** |
| 4 | * Detalle de los errores devueltos por un servicio. |
| 5 | * Crea una instancia de ProblemDetailsError. |
| 6 | * @param {any} problemDetails Objeto con la descripcipon del error. |
| 7 | */ |
| 8 | constructor(problemDetails) { |
| 9 | |
| 10 | super( |
| 11 | typeof problemDetails["detail"] === "string" |
| 12 | ? problemDetails["detail"] |
| 13 | : ( |
| 14 | typeof problemDetails["title"] === "string" |
| 15 | ? problemDetails["title"] |
| 16 | : "Error" |
| 17 | ) |
| 18 | ) |
| 19 | |
| 20 | this.problemDetails = problemDetails |
| 21 | |
| 22 | } |
| 23 | |
| 24 | } |
| 1 | /** |
| 2 | * @template { HTMLElement } T |
| 3 | * @param { Document | Element | ShadowRoot } raiz |
| 4 | * @param { string } query |
| 5 | * @returns { T } |
| 6 | */ |
| 7 | export function querySelector(raiz, query) { |
| 8 | /** @type { T | null } */ |
| 9 | const resutado = raiz.querySelector(query) |
| 10 | if (resutado === null) |
| 11 | throw new Error(`No se encuentra ${query}.`) |
| 12 | return resutado |
| 13 | } |
| 1 | /** |
| 2 | * @param {string[]} paginas |
| 3 | */ |
| 4 | export function resaltaSiEstasEn(paginas) { |
| 5 | |
| 6 | const pathname = location.pathname |
| 7 | |
| 8 | for (const pagina of paginas) { |
| 9 | |
| 10 | if (pathname === pagina) { |
| 11 | queueMicrotask(() => { |
| 12 | const tab = document.querySelector(".active") |
| 13 | if (tab !== null && tab.closest(".scrollable") !== null) { |
| 14 | tab.scrollIntoView({ inline: "center", block: "end" }) |
| 15 | } |
| 16 | }) |
| 17 | return `class="active"` |
| 18 | } |
| 19 | |
| 20 | } |
| 21 | |
| 22 | return "" |
| 23 | |
| 24 | } |