248 líneas
8.6 KiB
HTML
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>
|