initial commit

Signed-off-by: ale <ale@manalejandro.com>
Este commit está contenido en:
ale
2025-11-18 21:45:12 +01:00
padre 585716d86c
commit b2bd63a47e
Se han modificado 21 ficheros con 2633 adiciones y 17660 borrados

Archivo binario no mostrado.

Antes

Anchura:  |  Altura:  |  Tamaño: 3.8 KiB

Después

Anchura:  |  Altura:  |  Tamaño: 15 KiB

Ver fichero

@@ -1,30 +1,234 @@
<!DOCTYPE html>
<html lang="en">
<html lang="es">
<head>
<meta charset="utf-8" />
<link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
<meta name="theme-color" content="#000000" />
<meta name="theme-color" content="#667eea" />
<meta
name="description"
content="Web site created using create-react-app"
content="LaBiblioteca - Visor de libros EPUB desde IPFS. Lee documentos de forma accesible con múltiples gateways, búsqueda avanzada y diseño moderno."
/>
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
<!--
manifest.json provides metadata used when your web app is installed on a
user's mobile device or desktop. See https://developers.google.com/web/fundamentals/web-app-manifest/
-->
<meta name="keywords" content="EPUB, IPFS, libros, lector, biblioteca, descentralizado, accesible" />
<meta name="author" content="LaBiblioteca" />
<link rel="apple-touch-icon" href="%PUBLIC_URL%/logo.png" />
<link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Only files inside the `public` folder can be referenced from the HTML.
<title>LaBiblioteca - Visor EPUB desde IPFS</title>
<script>
// Parche para prevenir errores de epub.js cuando los iframes son destruidos
// Este script corre ANTES de que se cargue cualquier otra cosa
Unlike "/favicon.ico" or "favicon.ico", "%PUBLIC_URL%/favicon.ico" will
work correctly both with client-side routing and a non-root public URL.
Learn how to configure a non-root public URL by running `npm run build`.
-->
<title>React App</title>
// Monkey-patch ResizeObserver para prevenir loops infinitos
const originalResizeObserver = window.ResizeObserver;
if (originalResizeObserver) {
window.ResizeObserver = class PatchedResizeObserver {
constructor(callback) {
const safeCallback = (entries, observer) => {
try {
callback(entries, observer);
} catch (e) {
// Silenciar ResizeObserver errors silently
if (e.message && !e.message.includes('ResizeObserver')) {
throw e;
}
}
};
this._observer = new originalResizeObserver(safeCallback);
}
observe(target) {
try {
this._observer.observe(target);
} catch (e) {}
}
unobserve(target) {
try {
this._observer.unobserve(target);
} catch (e) {}
}
disconnect() {
try {
this._observer.disconnect();
} catch (e) {}
}
};
}
// Crear objeto CSSStyleDeclaration seguro
const safeCSSStyleDeclaration = {
width: '0px',
height: '0px',
display: 'none',
position: 'static',
margin: '0px',
padding: '0px',
border: 'none',
boxSizing: 'content-box',
fontSize: '16px',
lineHeight: 'normal',
color: '#000000',
backgroundColor: 'transparent',
getPropertyValue: function(prop) {
return this[prop] || '0px';
},
setProperty: function() {},
removeProperty: function() {}
};
// Parchear getComputedStyle globalmente
const originalGetComputedStyle = window.getComputedStyle;
window.getComputedStyle = function(element, pseudo) {
try {
if (!element || !element.ownerDocument) {
return safeCSSStyleDeclaration;
}
const result = originalGetComputedStyle.call(window, element, pseudo);
return result || safeCSSStyleDeclaration;
} catch (e) {
return safeCSSStyleDeclaration;
}
};
// Parchear el prototype de HTMLIFrameElement para que tenga window.getComputedStyle seguro
const originalIFrameContentWindow = Object.getOwnPropertyDescriptor(HTMLIFrameElement.prototype, 'contentWindow');
Object.defineProperty(HTMLIFrameElement.prototype, 'contentWindow', {
get: function() {
try {
const realWindow = originalIFrameContentWindow.get.call(this);
if (!realWindow) {
// Retornar un objeto window falso con getComputedStyle seguro
return {
getComputedStyle: function() {
return safeCSSStyleDeclaration;
},
document: {
defaultView: {
getComputedStyle: function() {
return safeCSSStyleDeclaration;
}
}
}
};
}
// Parchear getComputedStyle en el window real del iframe
if (realWindow && !realWindow._patched) {
realWindow._patched = true;
const originalIframeGetComputedStyle = realWindow.getComputedStyle;
realWindow.getComputedStyle = function(element, pseudo) {
try {
if (!element) {
return safeCSSStyleDeclaration;
}
const result = originalIframeGetComputedStyle.call(realWindow, element, pseudo);
return result || safeCSSStyleDeclaration;
} catch (e) {
return safeCSSStyleDeclaration;
}
};
}
return realWindow;
} catch (e) {
return {
getComputedStyle: function() {
return safeCSSStyleDeclaration;
}
};
}
}
});
// Interceptar errores antes de que lleguen a React
// Suprimir todos los errores de ResizeObserver
let errorCount = 0;
const originalError = window.onerror;
window.onerror = function(message, source, lineno, colno, error) {
const msg = (message || '').toString();
// Suprimir completamente cualquier error de ResizeObserver
if (msg.includes('ResizeObserver')) {
return true; // Retornar true previene que el error se propague
}
if (msg.includes('getComputedStyle') ||
msg.includes('width') ||
msg.includes('resizeCheck') ||
msg.includes('_locations') ||
msg.includes('dequeue')) {
return true;
}
if (originalError) {
return originalError(message, source, lineno, colno, error);
}
return false;
};
// Capturar promesas rechazadas
window.addEventListener('unhandledrejection', function(event) {
const msg = (event.reason?.message || event.reason?.toString() || '').toLowerCase();
// Suprimir cualquier error relacionado con ResizeObserver
if (msg.includes('resizeobserver') || msg.includes('undelivered notifications')) {
event.preventDefault();
return;
}
if (msg.includes('getcomputedstyle') ||
msg.includes('width') ||
msg.includes('resizecheck') ||
msg.includes('_locations') ||
msg.includes('dequeue')) {
event.preventDefault();
}
});
// Parchar console.error
const originalConsoleError = console.error;
console.error = function(...args) {
const msg = (args[0] || '').toString();
// Suprimir ResizeObserver loop errors completamente
if (msg.includes('ResizeObserver') ||
msg.includes('undelivered notifications') ||
msg.includes('getComputedStyle') ||
msg.includes('width') ||
msg.includes('resizeCheck')) {
return;
}
originalConsoleError.apply(console, args);
};
// Parchar console.warn también para ResizeObserver
const originalConsoleWarn = console.warn;
console.warn = function(...args) {
const msg = (args[0] || '').toString();
if (msg.includes('ResizeObserver') || msg.includes('undelivered notifications')) {
return;
}
originalConsoleWarn.apply(console, args);
};
</script>
<script>
// Inyectar un hook adicional para capturar errores en tiempo de ejecución
if (window.__REACT_DEVTOOLS_GLOBAL_HOOK__) {
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
const originalOnCommitFiberRoot = hook.onCommitFiberRoot;
if (originalOnCommitFiberRoot) {
hook.onCommitFiberRoot = function(...args) {
try {
return originalOnCommitFiberRoot.apply(hook, args);
} catch (e) {
if (!(e.message && e.message.includes('ResizeObserver'))) {
throw e;
}
}
};
}
}
</script>
</head>
<body>
<noscript>You need to enable JavaScript to run this app.</noscript>

BIN
public/logo.png Archivo normal

Archivo binario no mostrado.

Después

Anchura:  |  Altura:  |  Tamaño: 1.2 KiB

Archivo binario no mostrado.

Antes

Anchura:  |  Altura:  |  Tamaño: 5.2 KiB

Archivo binario no mostrado.

Antes

Anchura:  |  Altura:  |  Tamaño: 9.4 KiB

Ver fichero

@@ -1,6 +1,7 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "LaBiblioteca",
"name": "LaBiblioteca - Visor de EPUB desde IPFS",
"description": "Aplicación web para leer libros EPUB alojados en la red IPFS con búsqueda, múltiples gateways y diseño accesible",
"icons": [
{
"src": "favicon.ico",
@@ -8,18 +9,20 @@
"type": "image/x-icon"
},
{
"src": "logo192.png",
"src": "logo.png",
"type": "image/png",
"sizes": "192x192"
},
{
"src": "logo512.png",
"src": "logo.png",
"type": "image/png",
"sizes": "512x512"
}
],
"start_url": ".",
"display": "standalone",
"theme_color": "#000000",
"background_color": "#ffffff"
"theme_color": "#667eea",
"background_color": "#ffffff",
"orientation": "any",
"categories": ["books", "education", "productivity"]
}