Files
labiblioteca/public/index.html
2025-11-18 21:45:12 +01:00

248 líneas
8.6 KiB
HTML

<!DOCTYPE html>
<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="#667eea" />
<meta
name="description"
content="LaBiblioteca - Visor de libros EPUB desde IPFS. Lee documentos de forma accesible con múltiples gateways, búsqueda avanzada y diseño moderno."
/>
<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" />
<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
// 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>
<div id="root"></div>
<!--
This HTML file is a template.
If you open it directly in the browser, you will see an empty page.
You can add webfonts, meta tags, or analytics to this file.
The build step will place the bundled scripts into the <body> tag.
To begin the development, run `npm start` or `yarn start`.
To create a production bundle, use `npm run build` or `yarn build`.
-->
</body>
</html>