Archivo binario no mostrado.
|
Antes Anchura: | Altura: | Tamaño: 3.8 KiB Después Anchura: | Altura: | Tamaño: 15 KiB |
@@ -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
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 |
@@ -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"]
|
||||
}
|
||||
|
||||
Referencia en una nueva incidencia
Block a user