54
.gitignore
vendido
54
.gitignore
vendido
@@ -1,2 +1,56 @@
|
|||||||
|
# Base de datos SQLite (repositorio)
|
||||||
*.sqlite
|
*.sqlite
|
||||||
skin/icons/
|
skin/icons/
|
||||||
|
|
||||||
|
# Archivos de build
|
||||||
|
dist/
|
||||||
|
*.xpi
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
*.crx
|
||||||
|
|
||||||
|
# Dependencias Node.js
|
||||||
|
node_modules/
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# Archivos del editor
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# Sistema operativo
|
||||||
|
.DS_Store
|
||||||
|
.DS_Store?
|
||||||
|
._*
|
||||||
|
.Spotlight-V100
|
||||||
|
.Trashes
|
||||||
|
Thumbs.db
|
||||||
|
Desktop.ini
|
||||||
|
|
||||||
|
# Archivos temporales
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
*.cache
|
||||||
|
.cache/
|
||||||
|
|
||||||
|
# Logs y artifacts
|
||||||
|
npm-debug.log*
|
||||||
|
yarn-debug.log*
|
||||||
|
yarn-error.log*
|
||||||
|
web-ext-artifacts/
|
||||||
|
|
||||||
|
# Archivos de backup
|
||||||
|
*.bak
|
||||||
|
*.backup
|
||||||
|
|
||||||
|
# Cobertura de tests
|
||||||
|
coverage/
|
||||||
|
.nyc_output/
|
||||||
|
|
||||||
|
# sql.js descargado localmente (opcional)
|
||||||
|
content/sql-wasm.js
|
||||||
|
content/sql-wasm.wasm
|
||||||
|
|
||||||
|
|||||||
39
.webextignore
Archivo normal
39
.webextignore
Archivo normal
@@ -0,0 +1,39 @@
|
|||||||
|
# Archivos legacy de XUL/XPCOM (no necesarios en WebExtensions)
|
||||||
|
install.rdf
|
||||||
|
chrome.manifest
|
||||||
|
bootstrap.js
|
||||||
|
update.xml
|
||||||
|
|
||||||
|
# Documentación (opcional, pero puede incluirse)
|
||||||
|
README.md
|
||||||
|
MIGRATION.md
|
||||||
|
INSTALL.md
|
||||||
|
|
||||||
|
# Control de versiones
|
||||||
|
.git/
|
||||||
|
.gitignore
|
||||||
|
.gitattributes
|
||||||
|
|
||||||
|
# Archivos de desarrollo
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*~
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Archivos de build
|
||||||
|
*.xpi
|
||||||
|
*.zip
|
||||||
|
*.tar.gz
|
||||||
|
|
||||||
|
# Node modules (si se usan herramientas de build)
|
||||||
|
node_modules/
|
||||||
|
package.json
|
||||||
|
package-lock.json
|
||||||
|
yarn.lock
|
||||||
|
|
||||||
|
# Archivos temporales
|
||||||
|
*.tmp
|
||||||
|
*.log
|
||||||
|
.cache/
|
||||||
196
CHANGELOG.md
Archivo normal
196
CHANGELOG.md
Archivo normal
@@ -0,0 +1,196 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
Todos los cambios notables de este proyecto serán documentados en este archivo.
|
||||||
|
|
||||||
|
El formato está basado en [Keep a Changelog](https://keepachangelog.com/es/1.0.0/),
|
||||||
|
y este proyecto adhiere a [Semantic Versioning](https://semver.org/lang/es/).
|
||||||
|
|
||||||
|
## [3.0.0] - 2026-02-08
|
||||||
|
|
||||||
|
### 🎉 Reescritura completa a WebExtensions
|
||||||
|
|
||||||
|
Esta es una actualización mayor que moderniza completamente la extensión desde el sistema legacy XUL/XPCOM a WebExtensions modernas.
|
||||||
|
|
||||||
|
### ✨ Añadido
|
||||||
|
|
||||||
|
- **manifest.json** - Manifiesto WebExtensions Manifest v2
|
||||||
|
- **background.js** - Script de fondo con APIs modernas
|
||||||
|
- **db-webext.js** - Wrapper para base de datos usando sql.js
|
||||||
|
- **Hash routing** - Navegación usando `#` en lugar de protocolo personalizado
|
||||||
|
- **Compatibilidad con Chrome** - Ahora funciona en Chrome, Edge, Brave, Vivaldi
|
||||||
|
- **Documentación moderna**:
|
||||||
|
- `MIGRATION.md` - Guía completa de migración desde v2
|
||||||
|
- `INSTALL.md` - Instrucciones de instalación
|
||||||
|
- `README-v3.md` - Documentación actualizada
|
||||||
|
- `CHANGELOG.md` - Este archivo
|
||||||
|
- **package.json** - Scripts de build y desarrollo
|
||||||
|
- **.webextignore** - Exclusión de archivos legacy del paquete
|
||||||
|
- Permiso `unlimitedStorage` para bases de datos grandes
|
||||||
|
- Carga dinámica de módulos JavaScript
|
||||||
|
- Compatibilidad Chrome/Firefox con detección automática de API
|
||||||
|
|
||||||
|
### 🔄 Cambiado
|
||||||
|
|
||||||
|
- **Protocolo de navegación**: `caa:` → hash routing (`#list`, `#addon/...`)
|
||||||
|
- **URLs de recursos**: `chrome://ca-archive/` → rutas relativas
|
||||||
|
- **Base de datos**: mozIStorageService → sql.js (WebAssembly)
|
||||||
|
- **Storage**: Perfil de Firefox → `browser.storage.local`
|
||||||
|
- **Imports**: `Cu.import()` → Carga dinámica de scripts
|
||||||
|
- **APIs**: Components/XPCOM → WebExtensions APIs estándar
|
||||||
|
- **ca-archive.html** - Actualizado con rutas relativas y hash links
|
||||||
|
- **ca-archive.js** - Refactorizado sin Components, async/await
|
||||||
|
- Versión mínima de Firefox: 45 → 57 (Quantum)
|
||||||
|
|
||||||
|
### ❌ Eliminado (deprecado, aún en carpeta pero no usado)
|
||||||
|
|
||||||
|
- **install.rdf** - Reemplazado por manifest.json
|
||||||
|
- **chrome.manifest** - Ya no necesario en WebExtensions
|
||||||
|
- **bootstrap.js** - Reemplazado por background.js
|
||||||
|
- **update.xml** - Actualizaciones vía stores oficiales
|
||||||
|
- Soporte para Firefox <57 (ESR 45-52)
|
||||||
|
- Soporte para Pale Moon, Basilisk, SeaMonkey, Waterfox Classic
|
||||||
|
- Protocolo personalizado `caa:`
|
||||||
|
- Botón personalizable en barra de herramientas
|
||||||
|
- Menú en Tools
|
||||||
|
- Modificación de páginas de addons.mozilla.org
|
||||||
|
- Compatibilidad con e10s deshabilitado
|
||||||
|
|
||||||
|
### 🐛 Corregido
|
||||||
|
|
||||||
|
- Ya no requiere deshabilitar firma de extensiones en Firefox
|
||||||
|
- Compatible con multi-proceso (e10s) obligatorio
|
||||||
|
- No conflictos con Content Security Policy moderna
|
||||||
|
- Carga correcta en navegadores basados en Chromium
|
||||||
|
|
||||||
|
### 🔒 Seguridad
|
||||||
|
|
||||||
|
- Uso de APIs estándar y seguras de WebExtensions
|
||||||
|
- Eliminación de acceso a componentes internos del navegador
|
||||||
|
- CSP estricto con excepciones mínimas necesarias
|
||||||
|
|
||||||
|
### 📊 Compatibilidad
|
||||||
|
|
||||||
|
#### ✅ Ahora compatible con:
|
||||||
|
- Firefox 57+ (Quantum)
|
||||||
|
- Chrome 80+
|
||||||
|
- Microsoft Edge 80+ (Chromium)
|
||||||
|
- Brave 1.20+
|
||||||
|
- Vivaldi 3.0+
|
||||||
|
- Opera 67+
|
||||||
|
|
||||||
|
#### ❌ Ya no compatible con:
|
||||||
|
- Firefox <57 (ESR 45-56, Firefox 45-56)
|
||||||
|
- Pale Moon
|
||||||
|
- Basilisk
|
||||||
|
- Waterfox Classic (pre-Current)
|
||||||
|
- SeaMonkey
|
||||||
|
- IceCat/IceApe legacy
|
||||||
|
|
||||||
|
**Nota:** Para navegadores legacy, seguir usando la versión 2.x.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## [2.0.3] - 2018 (Legacy)
|
||||||
|
|
||||||
|
Última versión del sistema XUL/XPCOM legacy.
|
||||||
|
|
||||||
|
### Características
|
||||||
|
|
||||||
|
- Protocolo personalizado `caa:`
|
||||||
|
- Base de datos SQLite nativa
|
||||||
|
- Compatible con Firefox 45-56
|
||||||
|
- Compatible con Pale Moon, Basilisk, SeaMonkey
|
||||||
|
- Botón personalizable en toolbar
|
||||||
|
- Menú en Tools
|
||||||
|
- Modificación de páginas AMO (inyección de hints)
|
||||||
|
- 93,598 versiones de 19,450 addons
|
||||||
|
|
||||||
|
### Limitaciones conocidas
|
||||||
|
|
||||||
|
- No funciona con e10s en Firefox (excepto Waterfox)
|
||||||
|
- Requiere deshabilitar firma de extensiones en Firefox 48+
|
||||||
|
- No compatible con Firefox 57+ (Quantum)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Notas de migración
|
||||||
|
|
||||||
|
### De 2.x a 3.0
|
||||||
|
|
||||||
|
**⚠️ ATENCIÓN: Cambios que rompen compatibilidad**
|
||||||
|
|
||||||
|
Esta no es una actualización compatible hacia atrás. La versión 3.0 es una reescritura completa.
|
||||||
|
|
||||||
|
#### Si usas Firefox <57
|
||||||
|
→ **Quedate en v2.0.3**. La v3.0 no funcionará.
|
||||||
|
|
||||||
|
#### Si usas Firefox 57+ o Chrome
|
||||||
|
→ **Actualiza a v3.0**. La v2.0.3 no funcionará.
|
||||||
|
|
||||||
|
#### Migración de datos
|
||||||
|
|
||||||
|
No hay migración automática de datos porque:
|
||||||
|
- Las APIs de storage son incompatibles
|
||||||
|
- La base de datos se descarga nueva
|
||||||
|
- No hay configuraciones persistentes importantes
|
||||||
|
|
||||||
|
#### Enlaces rotos
|
||||||
|
|
||||||
|
Si tienes bookmarks con URLs `caa:*`, necesitarás recrearlos con:
|
||||||
|
```
|
||||||
|
moz-extension://[id]/content/ca-archive.html#[ruta]
|
||||||
|
```
|
||||||
|
|
||||||
|
El ID de la extensión se puede obtener de `about:debugging`.
|
||||||
|
|
||||||
|
### Pasos recomendados
|
||||||
|
|
||||||
|
1. **Backup** (opcional): Exportar favoritos si tienes links `caa:`
|
||||||
|
2. **Desinstalar** v2.x desde `about:addons`
|
||||||
|
3. **Instalar** v3.0 (ver [INSTALL.md](INSTALL.md))
|
||||||
|
4. **Recrear** bookmarks si es necesario
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Formato de versiones
|
||||||
|
|
||||||
|
Este proyecto usa [Semantic Versioning](https://semver.org/):
|
||||||
|
|
||||||
|
- **MAJOR** (3.x.x) - Cambios incompatibles
|
||||||
|
- **MINOR** (x.1.x) - Nuevas características compatibles
|
||||||
|
- **PATCH** (x.x.1) - Correcciones de bugs
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Roadmap futuro
|
||||||
|
|
||||||
|
### [3.1.0] - Planificado
|
||||||
|
|
||||||
|
- [ ] Dark mode / tema oscuro
|
||||||
|
- [ ] Mejora de búsqueda (índices full-text)
|
||||||
|
- [ ] Favoritos sincronizados
|
||||||
|
- [ ] Exportar/importar colecciones
|
||||||
|
- [ ] Optimización de carga de DB (chunks)
|
||||||
|
- [ ] Mejor manejo de errores
|
||||||
|
|
||||||
|
### [4.0.0] - Considerando
|
||||||
|
|
||||||
|
- [ ] Migración a Manifest V3 (cuando Firefox tenga soporte completo)
|
||||||
|
- [ ] Reescritura con framework moderno (React/Vue/Svelte)
|
||||||
|
- [ ] API pública para datos de addons
|
||||||
|
- [ ] Versión web (sin extensión)
|
||||||
|
- [ ] Integración con Archive.org API
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Enlaces
|
||||||
|
|
||||||
|
- [Código fuente](https://github.com/JustOff/ca-archive)
|
||||||
|
- [Releases](https://github.com/JustOff/ca-archive/releases)
|
||||||
|
- [Issues](https://github.com/JustOff/ca-archive/issues)
|
||||||
|
- [Discusiones](https://github.com/JustOff/ca-archive/discussions)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[3.0.0]: https://github.com/JustOff/ca-archive/releases/tag/v3.0.0
|
||||||
|
[2.0.3]: https://github.com/JustOff/ca-archive/releases/tag/2.0.3
|
||||||
171
INSTALL.md
Archivo normal
171
INSTALL.md
Archivo normal
@@ -0,0 +1,171 @@
|
|||||||
|
# Guía de Instalación Rápida - Classic Add-ons Archive v3.0
|
||||||
|
|
||||||
|
## Para Desarrolladores / Testing Local
|
||||||
|
|
||||||
|
### Firefox
|
||||||
|
|
||||||
|
**Opción 1: Carga temporal (recomendado para desarrollo)**
|
||||||
|
|
||||||
|
1. Abre Firefox
|
||||||
|
2. Escribe en la barra de direcciones: `about:debugging#/runtime/this-firefox`
|
||||||
|
3. Click en "Cargar complemento temporal..."
|
||||||
|
4. Navega a la carpeta del proyecto y selecciona el archivo `manifest.json`
|
||||||
|
|
||||||
|
La extensión se instalará hasta que cierres Firefox.
|
||||||
|
|
||||||
|
**Opción 2: Instalación permanente (requiere firmado)**
|
||||||
|
|
||||||
|
1. Empaquetar la extensión:
|
||||||
|
```bash
|
||||||
|
cd /home/ale/projects/firefox/ca-archive
|
||||||
|
zip -r ca-archive-3.0.xpi manifest.json background.js content/ skin/ -x "*.git*" -x "*~"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Firmar en addons.mozilla.org o usar Firefox Developer/Nightly con firma deshabilitada
|
||||||
|
|
||||||
|
### Chrome / Edge / Brave
|
||||||
|
|
||||||
|
**Modo desarrollador (sin empaquetar):**
|
||||||
|
|
||||||
|
1. Abre el navegador
|
||||||
|
2. Ve a: `chrome://extensions/` (o `edge://extensions/`)
|
||||||
|
3. Activa el interruptor "Modo de desarrollador" (esquina superior derecha)
|
||||||
|
4. Click en "Cargar extensión sin empaquetar"
|
||||||
|
5. Selecciona la carpeta: `/home/ale/projects/firefox/ca-archive`
|
||||||
|
|
||||||
|
La extensión quedará instalada permanentemente en modo desarrollo.
|
||||||
|
|
||||||
|
**Empaquetar para distribución:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd /home/ale/projects/firefox/ca-archive
|
||||||
|
zip -r ca-archive-3.0.zip manifest.json background.js content/ skin/ -x "*.git*" -x "*~"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verificación de Instalación
|
||||||
|
|
||||||
|
Después de instalar, deberías ver:
|
||||||
|
|
||||||
|
1. ✅ Icono de la extensión en la barra de herramientas
|
||||||
|
2. ✅ Click en el icono abre la página del catálogo
|
||||||
|
3. ✅ Mensaje de carga de base de datos (primera vez)
|
||||||
|
4. ✅ Navegación funcionando (categorías, búsqueda, etc.)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### La base de datos no carga
|
||||||
|
|
||||||
|
**Error:** "Loading database for the first time. Please wait..."
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
1. Asegúrate de tener la carpeta `content/db/` con el archivo SQLite
|
||||||
|
2. Verifica que el archivo `ca-archive-19030501.sqlite` exista y no esté corrupto
|
||||||
|
3. Revisa la consola del navegador (`F12` > Console) para errores específicos
|
||||||
|
|
||||||
|
### El icono no aparece
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
1. Refresca la página `about:debugging` o `chrome://extensions/`
|
||||||
|
2. Verifica que `manifest.json` tiene el campo `browser_action` correctamente
|
||||||
|
3. Revisa que las imágenes en `skin/button.png` existan
|
||||||
|
|
||||||
|
### Errores de carga de scripts
|
||||||
|
|
||||||
|
**Error:** "Failed to load script: ..."
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
1. Verifica que todos los archivos JS estén en `content/`
|
||||||
|
2. Revisa la política CSP en `manifest.json`
|
||||||
|
3. Asegúrate de que `db-webext.js` se carga antes de `ca-archive.js`
|
||||||
|
|
||||||
|
### sql.js no carga
|
||||||
|
|
||||||
|
**Error:** "Could not load SQL engine"
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
1. Verifica conexión a internet (se descarga desde CDN)
|
||||||
|
2. O descarga sql.js localmente:
|
||||||
|
```bash
|
||||||
|
cd content/
|
||||||
|
wget https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js
|
||||||
|
wget https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.wasm
|
||||||
|
```
|
||||||
|
3. Actualiza las rutas en `content/db-webext.js`
|
||||||
|
|
||||||
|
## Para Usuarios Finales
|
||||||
|
|
||||||
|
### Instalar desde archivo .xpi/.zip
|
||||||
|
|
||||||
|
**Firefox:**
|
||||||
|
1. Descarga el archivo `.xpi`
|
||||||
|
2. Arrastra y suelta en Firefox
|
||||||
|
3. Autoriza la instalación
|
||||||
|
|
||||||
|
**Chrome:**
|
||||||
|
1. Descarga el archivo `.zip`
|
||||||
|
2. Descomprime en una carpeta
|
||||||
|
3. Sigue los pasos de "Modo desarrollador" arriba
|
||||||
|
|
||||||
|
### Instalar desde stores (cuando esté publicado)
|
||||||
|
|
||||||
|
**Firefox Add-ons (AMO):**
|
||||||
|
- Visita: https://addons.mozilla.org/firefox/addon/ca-archive/
|
||||||
|
- Click en "Añadir a Firefox"
|
||||||
|
|
||||||
|
**Chrome Web Store:**
|
||||||
|
- Visita: [URL de Chrome Web Store]
|
||||||
|
- Click en "Añadir a Chrome"
|
||||||
|
|
||||||
|
## Desinstalación
|
||||||
|
|
||||||
|
### Firefox
|
||||||
|
1. `about:addons` > Extensiones
|
||||||
|
2. Busca "Classic Add-ons Archive"
|
||||||
|
3. Click en "..." > Eliminar
|
||||||
|
|
||||||
|
### Chrome
|
||||||
|
1. `chrome://extensions/`
|
||||||
|
2. Busca la extensión
|
||||||
|
3. Click en "Eliminar"
|
||||||
|
|
||||||
|
## Archivos Necesarios
|
||||||
|
|
||||||
|
Archivos mínimos para que funcione la extensión:
|
||||||
|
|
||||||
|
```
|
||||||
|
ca-archive/
|
||||||
|
├── manifest.json ← REQUERIDO
|
||||||
|
├── background.js ← REQUERIDO
|
||||||
|
├── content/
|
||||||
|
│ ├── ca-archive.html ← REQUERIDO
|
||||||
|
│ ├── ca-archive.js ← REQUERIDO
|
||||||
|
│ ├── db-webext.js ← REQUERIDO
|
||||||
|
│ ├── db/
|
||||||
|
│ │ └── ca-archive-19030501.sqlite ← REQUERIDO
|
||||||
|
│ ├── addon.js
|
||||||
|
│ ├── list.js
|
||||||
|
│ ├── versions.js
|
||||||
|
│ ├── tcloud.js
|
||||||
|
│ ├── about.js
|
||||||
|
│ └── epl.js
|
||||||
|
└── skin/
|
||||||
|
├── logo.png ← REQUERIDO
|
||||||
|
├── button.png ← REQUERIDO
|
||||||
|
├── ca-archive.css ← REQUERIDO
|
||||||
|
└── ...
|
||||||
|
```
|
||||||
|
|
||||||
|
## Siguientes Pasos
|
||||||
|
|
||||||
|
Una vez instalada y funcionando:
|
||||||
|
|
||||||
|
1. 📖 Lee [MIGRATION.md](MIGRATION.md) para entender los cambios
|
||||||
|
2. 🔧 Si eres desarrollador, revisa la arquitectura modernizada
|
||||||
|
3. 🐛 Reporta bugs en GitHub Issues
|
||||||
|
4. 🌟 Si te gusta, deja una valoración
|
||||||
|
|
||||||
|
## Soporte
|
||||||
|
|
||||||
|
- 📝 Documentación completa: [MIGRATION.md](MIGRATION.md)
|
||||||
|
- 🐛 Reportar problemas: https://github.com/JustOff/ca-archive/issues
|
||||||
|
- 💬 Discusiones: https://github.com/JustOff/ca-archive/discussions
|
||||||
237
MIGRATION.md
Archivo normal
237
MIGRATION.md
Archivo normal
@@ -0,0 +1,237 @@
|
|||||||
|
# Migración a WebExtensions (Versión 3.0)
|
||||||
|
|
||||||
|
## Resumen de cambios
|
||||||
|
|
||||||
|
La extensión Classic Add-ons Archive ha sido modernizada desde el sistema legacy XUL/XPCOM a WebExtensions para ser compatible con navegadores modernos Firefox (57+) y Chrome.
|
||||||
|
|
||||||
|
## Cambios principales
|
||||||
|
|
||||||
|
### 1. Sistema de manifiesto
|
||||||
|
|
||||||
|
**ANTES (Legacy):**
|
||||||
|
- `install.rdf` - Manifiesto XML
|
||||||
|
- `chrome.manifest` - Registro de recursos chrome://
|
||||||
|
- `bootstrap.js` - Script de arranque con XPCOM
|
||||||
|
|
||||||
|
**AHORA (WebExtensions):**
|
||||||
|
- `manifest.json` - Manifiesto estándar WebExtensions (Manifest V2)
|
||||||
|
- `background.js` - Script de fondo con APIs modernas
|
||||||
|
|
||||||
|
### 2. Protocolo de navegación
|
||||||
|
|
||||||
|
**ANTES:**
|
||||||
|
```
|
||||||
|
caa:list
|
||||||
|
caa:addon/some-addon
|
||||||
|
caa:about
|
||||||
|
```
|
||||||
|
|
||||||
|
**AHORA:**
|
||||||
|
```
|
||||||
|
chrome-extension://.../content/ca-archive.html#list
|
||||||
|
chrome-extension://.../content/ca-archive.html#addon/some-addon
|
||||||
|
chrome-extension://.../content/ca-archive.html#about
|
||||||
|
```
|
||||||
|
|
||||||
|
La navegación ahora usa hash (#) en lugar de un protocolo personalizado.
|
||||||
|
|
||||||
|
### 3. Acceso a recursos
|
||||||
|
|
||||||
|
**ANTES:**
|
||||||
|
```html
|
||||||
|
<link href="chrome://ca-archive/skin/ca-archive.css">
|
||||||
|
<script src="chrome://ca-archive/content/ca-archive.js">
|
||||||
|
```
|
||||||
|
|
||||||
|
**AHORA:**
|
||||||
|
```html
|
||||||
|
<link href="../skin/ca-archive.css">
|
||||||
|
<script src="ca-archive.js">
|
||||||
|
```
|
||||||
|
|
||||||
|
Todos los recursos usan rutas relativas.
|
||||||
|
|
||||||
|
### 4. Base de datos SQLite
|
||||||
|
|
||||||
|
**ANTES:**
|
||||||
|
- Acceso directo a SQLite usando `mozIStorageService`
|
||||||
|
- Almacenamiento en perfil del usuario
|
||||||
|
|
||||||
|
**AHORA:**
|
||||||
|
- Usa `sql.js` (SQLite compilado a JavaScript/WebAssembly)
|
||||||
|
- Base de datos almacenada en `browser.storage.local`
|
||||||
|
- Primera carga descarga y cachea la DB
|
||||||
|
|
||||||
|
### 5. APIs reemplazadas
|
||||||
|
|
||||||
|
| Legacy API | WebExtensions API |
|
||||||
|
|------------|-------------------|
|
||||||
|
| `Components.utils` | Scripts estándar ES6 |
|
||||||
|
| `Services.prefs` | `browser.storage.local` |
|
||||||
|
| `Services.wm` | `browser.tabs` y `browser.windows` |
|
||||||
|
| `mozIStorageService` | `sql.js` |
|
||||||
|
| `XPCOMUtils` | APIs nativas del navegador |
|
||||||
|
| `Cu.import()` | `import` / carga dinámica de scripts |
|
||||||
|
|
||||||
|
### 6. Interfaz de usuario
|
||||||
|
|
||||||
|
**ANTES:**
|
||||||
|
- Botón insertado directamente en la barra de herramientas
|
||||||
|
- Menú en Tools
|
||||||
|
|
||||||
|
**AHORA:**
|
||||||
|
- `browser.browserAction` - Botón estándar en la barra
|
||||||
|
- Sin menú en Tools (no disponible en WebExtensions)
|
||||||
|
|
||||||
|
## Estructura de archivos
|
||||||
|
|
||||||
|
### Archivos nuevos
|
||||||
|
- `manifest.json` - Manifiesto WebExtensions
|
||||||
|
- `background.js` - Script de fondo
|
||||||
|
- `content/db-webext.js` - Wrapper de base de datos moderno
|
||||||
|
|
||||||
|
### Archivos modificados
|
||||||
|
- `content/ca-archive.html` - Rutas relativas, navegación por hash
|
||||||
|
- `content/ca-archive.js` - Sin Components, carga dinámica de módulos
|
||||||
|
|
||||||
|
### Archivos obsoletos (ya no se usan)
|
||||||
|
- `install.rdf` - Reemplazado por manifest.json
|
||||||
|
- `chrome.manifest` - Ya no necesario
|
||||||
|
- `bootstrap.js` - Reemplazado por background.js
|
||||||
|
- `update.xml` - Actualizaciones ahora vía Firefox/Chrome stores
|
||||||
|
|
||||||
|
## Compatibilidad
|
||||||
|
|
||||||
|
### Navegadores soportados
|
||||||
|
|
||||||
|
| Navegador | Versión mínima | Notas |
|
||||||
|
|-----------|----------------|-------|
|
||||||
|
| Firefox | 57+ (Quantum) | Soporte completo |
|
||||||
|
| Chrome | 80+ | Requiere manifest V2 |
|
||||||
|
| Edge (Chromium) | 80+ | Compatible con Chrome |
|
||||||
|
| Brave | 1.20+ | Compatible con Chrome |
|
||||||
|
| Vivaldi | 3.0+ | Compatible con Chrome |
|
||||||
|
|
||||||
|
### Navegadores NO soportados
|
||||||
|
|
||||||
|
Los siguientes navegadores que usaban la versión legacy ya no son compatibles con la versión WebExtensions:
|
||||||
|
|
||||||
|
- Firefox ESR 45-52
|
||||||
|
- Firefox 45-56
|
||||||
|
- Pale Moon
|
||||||
|
- Basilisk
|
||||||
|
- Waterfox Classic (pre-Current)
|
||||||
|
- SeaMonkey
|
||||||
|
|
||||||
|
**Nota:** Para estos navegadores, seguir usando la versión 2.x legacy.
|
||||||
|
|
||||||
|
## Instalación
|
||||||
|
|
||||||
|
### Firefox
|
||||||
|
|
||||||
|
1. **Desde archivo local:**
|
||||||
|
```bash
|
||||||
|
# Empaquetar la extensión
|
||||||
|
cd /home/ale/projects/firefox/ca-archive
|
||||||
|
zip -r ca-archive-3.0.zip * -x ".*" -x "*.md" -x "update.xml" -x "install.rdf" -x "chrome.manifest" -x "bootstrap.js"
|
||||||
|
```
|
||||||
|
|
||||||
|
2. En Firefox, ir a `about:debugging` > Este Firefox > Cargar extensión temporal
|
||||||
|
3. Seleccionar el archivo `manifest.json` o el archivo `.zip`
|
||||||
|
|
||||||
|
### Chrome/Edge/Brave
|
||||||
|
|
||||||
|
1. Ir a `chrome://extensions/`
|
||||||
|
2. Activar "Modo de desarrollador"
|
||||||
|
3. Click en "Cargar extensión sin empaquetar"
|
||||||
|
4. Seleccionar la carpeta del proyecto
|
||||||
|
|
||||||
|
## Desarrollo
|
||||||
|
|
||||||
|
### Dependencias
|
||||||
|
|
||||||
|
La extensión requiere `sql.js` para el acceso a la base de datos SQLite:
|
||||||
|
|
||||||
|
```html
|
||||||
|
<!-- Cargado automáticamente desde CDN en db-webext.js -->
|
||||||
|
<script src="https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
**Para producción:** Descargar sql.js localmente y actualizar las rutas en `db-webext.js`.
|
||||||
|
|
||||||
|
### Debugging
|
||||||
|
|
||||||
|
**Firefox:**
|
||||||
|
- `about:debugging` > Inspeccionar
|
||||||
|
- Console del navegador: `Ctrl+Shift+J`
|
||||||
|
|
||||||
|
**Chrome:**
|
||||||
|
- `chrome://extensions/` > Detalles > Inspeccionar vistas: background page
|
||||||
|
- DevTools: `F12`
|
||||||
|
|
||||||
|
### Testing
|
||||||
|
|
||||||
|
1. Abrir la extensión
|
||||||
|
2. Verificar que la base de datos se carga correctamente
|
||||||
|
3. Probar navegación: listados, búsquedas, detalles de addons
|
||||||
|
4. Verificar que las descargas funcionan
|
||||||
|
|
||||||
|
## Limitaciones conocidas
|
||||||
|
|
||||||
|
### WebExtensions vs Legacy
|
||||||
|
|
||||||
|
1. **Multi-proceso (e10s):** Ahora sólo funciona con e10s activado
|
||||||
|
2. **Protocolo personalizado:** Ya no disponible, usa rutas de extensión
|
||||||
|
3. **Modificación de AMO pages:** No puede inyectar hints en addons.mozilla.org
|
||||||
|
4. **Barra de herramientas:** Botón en ubicación fija, no personalizable
|
||||||
|
5. **Storage:** Base de datos limitada por cuota de storage del navegador
|
||||||
|
|
||||||
|
### Tamaño de base de datos
|
||||||
|
|
||||||
|
Chrome/Firefox tienen límites de storage:
|
||||||
|
- Chrome: ~10MB en `storage.local` (puede ampliarse con `unlimitedStorage`)
|
||||||
|
- Firefox: Sin límite práctico en `storage.local`
|
||||||
|
|
||||||
|
Si la base de datos es muy grande (>10MB), considerar:
|
||||||
|
1. Agregar permiso `unlimitedStorage` en manifest.json
|
||||||
|
2. Usar chunks/compresión
|
||||||
|
3. Almacenar en IndexedDB
|
||||||
|
|
||||||
|
## Migración de datos de usuario
|
||||||
|
|
||||||
|
La nueva versión NO migra automáticamente datos de la versión legacy porque:
|
||||||
|
|
||||||
|
1. Las APIs de storage son completamente diferentes
|
||||||
|
2. La base de datos se descarga nueva en cada instalación
|
||||||
|
3. No hay configuraciones de usuario persistentes
|
||||||
|
|
||||||
|
## Próximos pasos
|
||||||
|
|
||||||
|
### Para publicar en stores
|
||||||
|
|
||||||
|
1. **Firefox Add-ons (AMO):**
|
||||||
|
- Crear cuenta en addons.mozilla.org
|
||||||
|
- Subir archivo .zip
|
||||||
|
- Esperar revisión
|
||||||
|
|
||||||
|
2. **Chrome Web Store:**
|
||||||
|
- Crear cuenta de desarrollador ($5 USD único)
|
||||||
|
- Subir archivo .zip
|
||||||
|
- Completar listing
|
||||||
|
|
||||||
|
### Mejoras futuras
|
||||||
|
|
||||||
|
- [ ] Migrar a Manifest V3 (cuando Firefox tenga mejor soporte)
|
||||||
|
- [ ] Offline-first: cachear más contenido
|
||||||
|
- [ ] Sincronización de favoritos/bookmarks
|
||||||
|
- [ ] Dark mode
|
||||||
|
- [ ] Búsqueda mejorada con índices
|
||||||
|
|
||||||
|
## Soporte
|
||||||
|
|
||||||
|
- GitHub: https://github.com/JustOff/ca-archive/
|
||||||
|
- Issues: https://github.com/JustOff/ca-archive/issues
|
||||||
|
|
||||||
|
## Licencia
|
||||||
|
|
||||||
|
La extensión continúa bajo Mozilla Public License 2.0 (MPL-2.0).
|
||||||
287
README-v3.md
Archivo normal
287
README-v3.md
Archivo normal
@@ -0,0 +1,287 @@
|
|||||||
|
# Classic Add-ons Archive v3.0 - WebExtensions Edition
|
||||||
|
|
||||||
|
[](https://opensource.org/licenses/MPL-2.0)
|
||||||
|
[](https://www.mozilla.org/firefox/)
|
||||||
|
[](https://www.google.com/chrome/)
|
||||||
|
|
||||||
|
## 🎉 Nueva versión modernizada
|
||||||
|
|
||||||
|
Esta es la versión 3.0 de Classic Add-ons Archive, completamente reescrita usando **WebExtensions** para ser compatible con navegadores modernos.
|
||||||
|
|
||||||
|
### ✨ Características principales
|
||||||
|
|
||||||
|
- 📦 **93,598 versiones** de **19,450 extensiones clásicas de Firefox**
|
||||||
|
- 🔍 Búsqueda y navegación por categorías
|
||||||
|
- 📊 Ordenamiento por popularidad, valoración, fecha, etc.
|
||||||
|
- 💾 Base de datos SQLite embebida
|
||||||
|
- 🌐 Compatible con Firefox 57+, Chrome 80+, Edge, Brave, Vivaldi
|
||||||
|
|
||||||
|
### 🆕 Novedades de la versión 3.0
|
||||||
|
|
||||||
|
- ✅ Compatible con Firefox Quantum (57+) y Chrome
|
||||||
|
- ✅ Usa APIs modernas de WebExtensions
|
||||||
|
- ✅ Ya no requiere Firefox legacy
|
||||||
|
- ✅ Navegación mejorada con hash routing
|
||||||
|
- ✅ Base de datos en memoria con sql.js
|
||||||
|
- ✅ Sin dependencias de XPCOM/XUL
|
||||||
|
|
||||||
|
## 🚀 Instalación rápida
|
||||||
|
|
||||||
|
### Para usuarios
|
||||||
|
|
||||||
|
**Firefox:**
|
||||||
|
```bash
|
||||||
|
# Descargar release
|
||||||
|
# Ir a about:debugging
|
||||||
|
# Cargar extensión temporal > seleccionar manifest.json
|
||||||
|
```
|
||||||
|
|
||||||
|
**Chrome/Edge/Brave:**
|
||||||
|
```bash
|
||||||
|
# Ir a chrome://extensions/
|
||||||
|
# Activar "Modo de desarrollador"
|
||||||
|
# "Cargar extensión sin empaquetar" > seleccionar carpeta
|
||||||
|
```
|
||||||
|
|
||||||
|
Documentación completa: [INSTALL.md](INSTALL.md)
|
||||||
|
|
||||||
|
### Para desarrolladores
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Clonar repositorio
|
||||||
|
git clone https://github.com/JustOff/ca-archive.git
|
||||||
|
cd ca-archive
|
||||||
|
|
||||||
|
# (Opcional) Instalar web-ext para testing
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Probar en Firefox
|
||||||
|
npm run start:firefox
|
||||||
|
|
||||||
|
# O probar en Chrome
|
||||||
|
npm run start:chrome
|
||||||
|
|
||||||
|
# Construir paquete
|
||||||
|
npm run build:firefox # Crea .xpi para Firefox
|
||||||
|
npm run build:chrome # Crea .zip para Chrome
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📁 Estructura del proyecto
|
||||||
|
|
||||||
|
```
|
||||||
|
ca-archive/
|
||||||
|
├── manifest.json # Manifiesto WebExtensions v2
|
||||||
|
├── background.js # Script de fondo
|
||||||
|
├── package.json # Scripts de build (opcional)
|
||||||
|
│
|
||||||
|
├── content/ # Scripts y páginas de contenido
|
||||||
|
│ ├── ca-archive.html # Página principal de la extensión
|
||||||
|
│ ├── ca-archive.js # Router y controlador principal
|
||||||
|
│ ├── db-webext.js # Wrapper de base de datos (sql.js)
|
||||||
|
│ ├── db.js # [Legacy] No usado en v3
|
||||||
|
│ ├── addon.js # Vista de detalle de addon
|
||||||
|
│ ├── list.js # Vista de listado
|
||||||
|
│ ├── versions.js # Vista de versiones
|
||||||
|
│ ├── tcloud.js # Nube de tags
|
||||||
|
│ ├── about.js # Página "Acerca de"
|
||||||
|
│ ├── epl.js # EULA/Privacy/License
|
||||||
|
│ └── db/
|
||||||
|
│ └── ca-archive-*.sqlite # Base de datos SQLite
|
||||||
|
│
|
||||||
|
├── skin/ # Assets visuales
|
||||||
|
│ ├── ca-archive.css # Estilos principales
|
||||||
|
│ ├── button.css # [Legacy] No usado en v3
|
||||||
|
│ ├── logo.png # Logo de la extensión
|
||||||
|
│ ├── button.png # Icono del botón
|
||||||
|
│ └── ... # Otros assets
|
||||||
|
│
|
||||||
|
├── MIGRATION.md # Guía de migración desde v2
|
||||||
|
├── INSTALL.md # Guía de instalación
|
||||||
|
├── README-v3.md # Este archivo
|
||||||
|
│
|
||||||
|
└── [Legacy - no usados en v3]
|
||||||
|
├── install.rdf
|
||||||
|
├── chrome.manifest
|
||||||
|
├── bootstrap.js
|
||||||
|
└── update.xml
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 Migración desde v2 (Legacy)
|
||||||
|
|
||||||
|
Si vienes de la versión 2.x (XUL/XPCOM), lee la [Guía de Migración](MIGRATION.md) que explica:
|
||||||
|
|
||||||
|
- ❌ Qué dejó de funcionar
|
||||||
|
- ✅ Cómo se reemplazó cada funcionalidad
|
||||||
|
- 🔧 Cambios en la arquitectura
|
||||||
|
- 📊 Tabla de compatibilidad de navegadores
|
||||||
|
|
||||||
|
### Resumen rápido de cambios
|
||||||
|
|
||||||
|
| Aspecto | v2 (Legacy) | v3 (WebExtensions) |
|
||||||
|
|---------|-------------|-------------------|
|
||||||
|
| **Manifest** | install.rdf | manifest.json |
|
||||||
|
| **Protocolo** | caa: | hash routing (#) |
|
||||||
|
| **APIs** | Components/XPCOM | WebExtensions APIs |
|
||||||
|
| **Base de datos** | mozIStorageService | sql.js |
|
||||||
|
| **Navegadores** | Firefox ≤56 | Firefox 57+, Chrome 80+ |
|
||||||
|
|
||||||
|
## 🛠️ Desarrollo
|
||||||
|
|
||||||
|
### Requisitos
|
||||||
|
|
||||||
|
- Node.js 16+ (opcional, para herramientas de build)
|
||||||
|
- Firefox Developer Edition o Chrome
|
||||||
|
- Editor de código (VS Code recomendado)
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Instalar dependencias de desarrollo
|
||||||
|
npm install
|
||||||
|
|
||||||
|
# Lint
|
||||||
|
npm run lint
|
||||||
|
|
||||||
|
# Testing local
|
||||||
|
npm run start:firefox # Abre Firefox con la extensión
|
||||||
|
# o
|
||||||
|
npm run start:chrome # Abre Chrome con la extensión
|
||||||
|
```
|
||||||
|
|
||||||
|
### Testing manual
|
||||||
|
|
||||||
|
1. Hacer cambios en el código
|
||||||
|
2. En `about:debugging` (Firefox) o `chrome://extensions/` (Chrome), click en "Recargar"
|
||||||
|
3. Abrir la extensión y verificar cambios
|
||||||
|
4. Revisar console (`F12`) para errores
|
||||||
|
|
||||||
|
### Build para distribución
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Firefox (.xpi)
|
||||||
|
npm run build:firefox
|
||||||
|
# Output: dist/ca-archive-3.0.0.zip (renombrar a .xpi)
|
||||||
|
|
||||||
|
# Chrome (.zip)
|
||||||
|
npm run build:chrome
|
||||||
|
# Output: dist/ca-archive-3.0-chrome.zip
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🐛 Debugging
|
||||||
|
|
||||||
|
### Abrir consola de la extensión
|
||||||
|
|
||||||
|
**Firefox:**
|
||||||
|
1. `about:debugging` > Este Firefox
|
||||||
|
2. Click en "Inspeccionar" en la extensión
|
||||||
|
|
||||||
|
**Chrome:**
|
||||||
|
1. `chrome://extensions/`
|
||||||
|
2. Click en "Inspeccionar vistas: background page"
|
||||||
|
|
||||||
|
### Logs útiles
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// En background.js
|
||||||
|
console.log("Background script:", message);
|
||||||
|
|
||||||
|
// En content scripts
|
||||||
|
console.log("Content script:", message);
|
||||||
|
|
||||||
|
// Errores de base de datos
|
||||||
|
// Revisar consola de la página ca-archive.html
|
||||||
|
```
|
||||||
|
|
||||||
|
## 📝 Notas técnicas
|
||||||
|
|
||||||
|
### Base de datos SQLite
|
||||||
|
|
||||||
|
- **Tamaño:** ~50MB (comprimido: ~15MB)
|
||||||
|
- **Engine:** sql.js (SQLite compilado a WebAssembly)
|
||||||
|
- **Storage:** `browser.storage.local` (primera carga)
|
||||||
|
- **Límite:** Chrome 10MB (usa `unlimitedStorage` permission)
|
||||||
|
|
||||||
|
### Permisos requeridos
|
||||||
|
|
||||||
|
- `storage` - Cachear base de datos
|
||||||
|
- `unlimitedStorage` - DB grande (>10MB)
|
||||||
|
- `tabs` - Abrir tabs del catálogo
|
||||||
|
- `webRequest` + `webRequestBlocking` - Modificar headers de descarga
|
||||||
|
- `<all_urls>` - Interceptar requests a web.archive.org
|
||||||
|
|
||||||
|
### Políticas de seguridad
|
||||||
|
|
||||||
|
```json
|
||||||
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
|
||||||
|
```
|
||||||
|
|
||||||
|
- `'unsafe-eval'` - Requerido por sql.js (usa WebAssembly)
|
||||||
|
- Todos los scripts deben estar en el paquete (no CDN inline)
|
||||||
|
|
||||||
|
## 🤝 Contribuir
|
||||||
|
|
||||||
|
¡Las contribuciones son bienvenidas!
|
||||||
|
|
||||||
|
### Áreas de mejora
|
||||||
|
|
||||||
|
- [ ] Migrar a Manifest V3 (cuando Firefox tenga mejor soporte)
|
||||||
|
- [ ] Optimizar carga de base de datos (chunks, compresión)
|
||||||
|
- [ ] Modo oscuro (dark mode)
|
||||||
|
- [ ] Búsqueda con índices full-text
|
||||||
|
- [ ] Favoritos/bookmarks sincronizados
|
||||||
|
- [ ] Mejoras de UI/UX
|
||||||
|
|
||||||
|
### Proceso
|
||||||
|
|
||||||
|
1. Fork del repositorio
|
||||||
|
2. Crear branch: `git checkout -b feature/mi-mejora`
|
||||||
|
3. Commit: `git commit -am 'Añadir nueva característica'`
|
||||||
|
4. Push: `git push origin feature/mi-mejora`
|
||||||
|
5. Crear Pull Request
|
||||||
|
|
||||||
|
## 📄 Licencia
|
||||||
|
|
||||||
|
**Mozilla Public License 2.0 (MPL-2.0)**
|
||||||
|
|
||||||
|
- ✅ Uso comercial
|
||||||
|
- ✅ Modificación
|
||||||
|
- ✅ Distribución
|
||||||
|
- ✅ Uso privado
|
||||||
|
- ⚠️ Divulgar fuente si se modifica
|
||||||
|
|
||||||
|
Ver [LICENSE](LICENSE) para más detalles.
|
||||||
|
|
||||||
|
### Atribuciones
|
||||||
|
|
||||||
|
- Diseño original: Mozilla AMO (CC-BY-SA-3.0)
|
||||||
|
- Datos: Dominio público / respectivos autores
|
||||||
|
- sql.js: MIT License
|
||||||
|
- Logos y marcas: Propiedad de sus respectivos dueños
|
||||||
|
|
||||||
|
## 👥 Autores
|
||||||
|
|
||||||
|
- **Off JustOff** - Autor original - [JustOff](https://github.com/JustOff)
|
||||||
|
- Migración a WebExtensions v3.0 - 2026
|
||||||
|
|
||||||
|
## 🔗 Enlaces
|
||||||
|
|
||||||
|
- 🏠 [Sitio web](https://ca-archive.us.to/)
|
||||||
|
- 📦 [Releases](https://github.com/JustOff/ca-archive/releases)
|
||||||
|
- 🐛 [Issues](https://github.com/JustOff/ca-archive/issues)
|
||||||
|
- 💬 [Discusiones](https://github.com/JustOff/ca-archive/discussions)
|
||||||
|
- 📖 [Documentación](https://github.com/JustOff/ca-archive/wiki)
|
||||||
|
|
||||||
|
## ⭐ Agradecimientos
|
||||||
|
|
||||||
|
- Mozilla y la comunidad AMO
|
||||||
|
- Wayback Machine (Internet Archive)
|
||||||
|
- Zetamex Network (hosting)
|
||||||
|
- Todos los desarrolladores de extensiones clásicas
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**¿Te gusta el proyecto?** Dale una ⭐ en GitHub!
|
||||||
|
|
||||||
|
**¿Encontraste un bug?** [Repórtalo aquí](https://github.com/JustOff/ca-archive/issues)
|
||||||
|
|
||||||
|
**¿Tienes preguntas?** [Pregunta en Discusiones](https://github.com/JustOff/ca-archive/discussions)
|
||||||
544
TROUBLESHOOTING.md
Archivo normal
544
TROUBLESHOOTING.md
Archivo normal
@@ -0,0 +1,544 @@
|
|||||||
|
# Guía de Solución de Problemas (Troubleshooting)
|
||||||
|
|
||||||
|
Esta guía te ayudará a resolver problemas comunes al usar Classic Add-ons Archive v3.0.
|
||||||
|
|
||||||
|
## 📋 Índice
|
||||||
|
|
||||||
|
1. [Problemas de Instalación](#problemas-de-instalación)
|
||||||
|
2. [Problemas con la Base de Datos](#problemas-con-la-base-de-datos)
|
||||||
|
3. [Problemas de Navegación](#problemas-de-navegación)
|
||||||
|
4. [Problemas de Rendimiento](#problemas-de-rendimiento)
|
||||||
|
5. [Errores en la Consola](#errores-en-la-consola)
|
||||||
|
6. [Incompatibilidades](#incompatibilidades)
|
||||||
|
7. [Obtener Ayuda](#obtener-ayuda)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemas de Instalación
|
||||||
|
|
||||||
|
### El icono de la extensión no aparece
|
||||||
|
|
||||||
|
**Síntomas:**
|
||||||
|
- No veo el icono en la barra de herramientas
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Recargar la extensión:**
|
||||||
|
- Firefox: `about:debugging` > Click en "Recargar"
|
||||||
|
- Chrome: `chrome://extensions/` > Click en el icono de recargar ↻
|
||||||
|
|
||||||
|
2. **Verificar que está habilitada:**
|
||||||
|
- Firefox: `about:addons` > Extensiones > Buscar "Classic Add-ons Archive"
|
||||||
|
- Chrome: `chrome://extensions/` > Buscar la extensión y verificar que el toggle está activado
|
||||||
|
|
||||||
|
3. **Verificar manifest.json:**
|
||||||
|
```bash
|
||||||
|
cat manifest.json | grep -A 5 browser_action
|
||||||
|
```
|
||||||
|
Debe existir la sección `browser_action` con iconos válidos.
|
||||||
|
|
||||||
|
### Error al cargar la extensión
|
||||||
|
|
||||||
|
**Error:** "There was an error during installation"
|
||||||
|
|
||||||
|
**Causas comunes:**
|
||||||
|
- `manifest.json` inválido
|
||||||
|
- Archivos requeridos faltantes
|
||||||
|
- Permisos incorrectos
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Validar el manifest:**
|
||||||
|
```bash
|
||||||
|
# Instalar web-ext si no lo tienes
|
||||||
|
npm install -g web-ext
|
||||||
|
|
||||||
|
# Validar
|
||||||
|
web-ext lint
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verificar archivos requeridos:**
|
||||||
|
```bash
|
||||||
|
ls -la manifest.json background.js
|
||||||
|
ls -la content/ca-archive.html content/ca-archive.js content/db-webext.js
|
||||||
|
ls -la skin/logo.png skin/button.png
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verificar sintaxis JSON:**
|
||||||
|
- Usar herramienta online: https://jsonlint.com/
|
||||||
|
- O con python:
|
||||||
|
```bash
|
||||||
|
python3 -m json.tool manifest.json > /dev/null
|
||||||
|
```
|
||||||
|
|
||||||
|
### Firefox: "This add-on could not be installed because it appears to be corrupt"
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
|
||||||
|
1. Reconstruir el paquete:
|
||||||
|
```bash
|
||||||
|
./build.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
2. Verificar integridad:
|
||||||
|
```bash
|
||||||
|
unzip -t dist/ca-archive-3.0.0.xpi
|
||||||
|
```
|
||||||
|
|
||||||
|
3. Si persiste, cargar sin empaquetar:
|
||||||
|
- `about:debugging` > Cargar complemento temporal
|
||||||
|
- Seleccionar `manifest.json` directamente
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemas con la Base de Datos
|
||||||
|
|
||||||
|
### "Loading database for the first time" se queda cargando
|
||||||
|
|
||||||
|
**Síntomas:**
|
||||||
|
- Mensaje de carga de DB sin terminar
|
||||||
|
- Página en blanco
|
||||||
|
|
||||||
|
**Causas:**
|
||||||
|
- Base de datos muy grande
|
||||||
|
- Falta archivo SQLite
|
||||||
|
- Error de red (si carga desde CDN)
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar que existe el archivo DB:**
|
||||||
|
```bash
|
||||||
|
ls -lh content/db/*.sqlite
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verificar tamaño de la DB:**
|
||||||
|
```bash
|
||||||
|
du -h content/db/*.sqlite
|
||||||
|
```
|
||||||
|
Si es >50MB, puede tardar en el primer acceso.
|
||||||
|
|
||||||
|
3. **Revisar la consola del navegador** (`F12` > Console):
|
||||||
|
- Buscar errores relacionados con fetch o sql.js
|
||||||
|
|
||||||
|
4. **Limpiar storage y reintentar:**
|
||||||
|
```javascript
|
||||||
|
// En la consola del navegador
|
||||||
|
browser.storage.local.clear()
|
||||||
|
// o en Chrome:
|
||||||
|
chrome.storage.local.clear()
|
||||||
|
```
|
||||||
|
|
||||||
|
5. **Verificar permisos del archivo:**
|
||||||
|
```bash
|
||||||
|
chmod 644 content/db/*.sqlite
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error: "Could not load SQL engine"
|
||||||
|
|
||||||
|
**Causa:** sql.js no se pudo cargar
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar conexión a internet** (si usa CDN)
|
||||||
|
|
||||||
|
2. **Descargar sql.js localmente:**
|
||||||
|
```bash
|
||||||
|
cd content/
|
||||||
|
wget https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js
|
||||||
|
wget https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.wasm
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Actualizar rutas en `db-webext.js`:**
|
||||||
|
```javascript
|
||||||
|
// Cambiar:
|
||||||
|
locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/${file}`
|
||||||
|
|
||||||
|
// Por:
|
||||||
|
locateFile: file => browser.runtime.getURL(`content/${file}`)
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Agregar archivos a `web_accessible_resources` en manifest.json:**
|
||||||
|
```json
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"content/*.wasm",
|
||||||
|
"content/sql-wasm.js"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### Error: "Database has just been updated, not ready or corrupted!"
|
||||||
|
|
||||||
|
**Causa:** Archivo SQLite corrupto o inaccesible
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar integridad de la DB:**
|
||||||
|
```bash
|
||||||
|
sqlite3 content/db/ca-archive-*.sqlite "PRAGMA integrity_check;"
|
||||||
|
```
|
||||||
|
Debe retornar "ok"
|
||||||
|
|
||||||
|
2. **Re-descargar la base de datos:**
|
||||||
|
- Si tienes repositorio Git: `git checkout content/db/*.sqlite`
|
||||||
|
- O descargar manualmente desde releases
|
||||||
|
|
||||||
|
3. **Permisos de lectura:**
|
||||||
|
```bash
|
||||||
|
chmod 644 content/db/*.sqlite
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemas de Navegación
|
||||||
|
|
||||||
|
### Los enlaces no funcionan
|
||||||
|
|
||||||
|
**Síntomas:**
|
||||||
|
- Click en categoría/addon no hace nada
|
||||||
|
- URL no cambia
|
||||||
|
- Página en blanco
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar hash routing:**
|
||||||
|
- La URL debe ser: `moz-extension://[id]/content/ca-archive.html#list`
|
||||||
|
- No debe ser: `caa:list` (eso es legacy)
|
||||||
|
|
||||||
|
2. **Revisar consola JavaScript** (`F12`):
|
||||||
|
- Buscar errores en `ca-archive.js`
|
||||||
|
|
||||||
|
3. **Verificar que los módulos se cargan:**
|
||||||
|
```javascript
|
||||||
|
// En la consola del navegador
|
||||||
|
console.log(typeof List, typeof Addon, typeof DB);
|
||||||
|
// Debe mostrar los tipos de objeto/function
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Limpiar caché del navegador:**
|
||||||
|
- Firefox: `Ctrl+Shift+Del` > Marcar "Caché"
|
||||||
|
- Chrome: `Ctrl+Shift+Del` > "Cached images and files"
|
||||||
|
|
||||||
|
### Búsqueda no funciona
|
||||||
|
|
||||||
|
**Síntomas:**
|
||||||
|
- Campo de búsqueda no responde
|
||||||
|
- No muestra resultados
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar que la DB está cargada:**
|
||||||
|
- Debe haber completado la carga inicial
|
||||||
|
- Revisar que no hay mensajes de error en consola
|
||||||
|
|
||||||
|
2. **Verificar el formulario:**
|
||||||
|
```html
|
||||||
|
<form id="search" action="#list">
|
||||||
|
```
|
||||||
|
Debe tener `action="#list"` (no `caa:list`)
|
||||||
|
|
||||||
|
3. **Probar búsqueda directa:**
|
||||||
|
- Navegar manualmente a: `#list?q=tu-búsqueda`
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Problemas de Rendimiento
|
||||||
|
|
||||||
|
### La extensión es lenta
|
||||||
|
|
||||||
|
**Síntomas:**
|
||||||
|
- Navegación lenta entre páginas
|
||||||
|
- La UI se congela
|
||||||
|
- Alta uso de CPU/RAM
|
||||||
|
|
||||||
|
**Causas:**
|
||||||
|
- Base de datos muy grande en memoria
|
||||||
|
- Consultas SQL no optimizadas
|
||||||
|
- Demasiados addons en listado
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar uso de memoria:**
|
||||||
|
- Firefox: `about:performance`
|
||||||
|
- Chrome: `chrome://process-internals/`
|
||||||
|
|
||||||
|
2. **Reducir resultados por página:**
|
||||||
|
- Editar módulos que hacen consultas (list.js, addon.js)
|
||||||
|
- Agregar límite LIMIT a queries SQL
|
||||||
|
|
||||||
|
3. **Considerar IndexedDB en lugar de sql.js:**
|
||||||
|
- sql.js carga toda la DB en RAM
|
||||||
|
- IndexedDB maneja datos en disco de forma nativa
|
||||||
|
|
||||||
|
4. **Cerrar otras extensiones:**
|
||||||
|
- Conflictos con otras extensiones pueden causar lentitud
|
||||||
|
|
||||||
|
### Carga inicial muy lenta (>30 segundos)
|
||||||
|
|
||||||
|
**Causa:** Base de datos grande descargándose por primera vez
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Paciencia:** Primera carga es normal que tarde
|
||||||
|
- DB de ~50MB puede tardar 30-60s en redes lentas
|
||||||
|
|
||||||
|
2. **Verificar progreso:**
|
||||||
|
- Abrir Network tab (`F12` > Network)
|
||||||
|
- Buscar descarga del archivo .sqlite
|
||||||
|
|
||||||
|
3. **Pre-cargar la DB:**
|
||||||
|
- Copiar manualmente a storage:
|
||||||
|
```javascript
|
||||||
|
// Demasiado complejo, mejor esperar carga natural
|
||||||
|
```
|
||||||
|
|
||||||
|
4. **Usar conexión más rápida** para primera instalación
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Errores en la Consola
|
||||||
|
|
||||||
|
### "ReferenceError: DB is not defined"
|
||||||
|
|
||||||
|
**Causa:** `db-webext.js` no se cargó antes de `ca-archive.js`
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
|
||||||
|
Verificar orden en `ca-archive.html`:
|
||||||
|
```html
|
||||||
|
<!-- CORRECTO: -->
|
||||||
|
<script src="db-webext.js"></script>
|
||||||
|
<script src="ca-archive.js"></script>
|
||||||
|
|
||||||
|
<!-- INCORRECTO: -->
|
||||||
|
<script src="ca-archive.js"></script>
|
||||||
|
<script src="db-webext.js"></script>
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Failed to load script: versions.js"
|
||||||
|
|
||||||
|
**Causa:** Módulo no existe o ruta incorrecta
|
||||||
|
|
||||||
|
**Soluciones:**
|
||||||
|
|
||||||
|
1. **Verificar que existe:**
|
||||||
|
```bash
|
||||||
|
ls -la content/versions.js
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Verificar permisos:**
|
||||||
|
```bash
|
||||||
|
chmod 644 content/*.js
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Verificar en web_accessible_resources** (manifest.json):
|
||||||
|
```json
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"content/*.js"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
### "Unsafe attempt to load URL"
|
||||||
|
|
||||||
|
**Causa:** Violación de Content Security Policy
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
|
||||||
|
Actualizar CSP en manifest.json:
|
||||||
|
```json
|
||||||
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'"
|
||||||
|
```
|
||||||
|
|
||||||
|
**Nota:** `'unsafe-eval'` es necesario para sql.js (WebAssembly).
|
||||||
|
|
||||||
|
### "TypeError: Cannot read property 'openDB' of undefined"
|
||||||
|
|
||||||
|
**Causa:** Variable `DB` no está definida globalmente
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
|
||||||
|
En `db-webext.js`, verificar al final:
|
||||||
|
```javascript
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
window.DB = DB;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Incompatibilidades
|
||||||
|
|
||||||
|
### No funciona en Firefox 56 o inferior
|
||||||
|
|
||||||
|
**Explicación:**
|
||||||
|
- v3.0 requiere Firefox 57+ (WebExtensions puras)
|
||||||
|
- Firefox 56 y anteriores usan sistema legacy
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
- Usar la versión 2.x para Firefox ≤56
|
||||||
|
- O actualizar Firefox a versión moderna
|
||||||
|
|
||||||
|
### No funciona en Pale Moon / Basilisk
|
||||||
|
|
||||||
|
**Explicación:**
|
||||||
|
- Estos navegadores no soportan WebExtensions completas
|
||||||
|
- Usan sistema legacy de Firefox
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
- Usar la versión 2.x legacy
|
||||||
|
- No hay planes de portar v3 a estos navegadores
|
||||||
|
|
||||||
|
### Problemas en Chrome con storage
|
||||||
|
|
||||||
|
**Error:** "QUOTA_BYTES quota exceeded"
|
||||||
|
|
||||||
|
**Causa:** Base de datos muy grande para storage.local de Chrome (límite 10MB)
|
||||||
|
|
||||||
|
**Solución:**
|
||||||
|
|
||||||
|
1. **Ya incluido:** Permiso `unlimitedStorage` en manifest.json
|
||||||
|
|
||||||
|
2. **Verificar que está presente:**
|
||||||
|
```json
|
||||||
|
"permissions": [
|
||||||
|
"unlimitedStorage"
|
||||||
|
]
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Si sigue fallando:** Considerar:
|
||||||
|
- Comprimir la DB
|
||||||
|
- Usar chunks para storage
|
||||||
|
- Usar IndexedDB nativa
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Obtener Ayuda
|
||||||
|
|
||||||
|
Si ninguna solución funciona:
|
||||||
|
|
||||||
|
### 1. Recopilar información
|
||||||
|
|
||||||
|
**Información del sistema:**
|
||||||
|
- Navegador y versión: `about:support` (Firefox) o `chrome://version/` (Chrome)
|
||||||
|
- Versión de la extensión: Ver manifest.json
|
||||||
|
- Sistema operativo
|
||||||
|
|
||||||
|
**Logs:**
|
||||||
|
```javascript
|
||||||
|
// En consola del navegador (F12)
|
||||||
|
console.log("Extension ID:", browser.runtime.id);
|
||||||
|
console.log("Extension URL:", browser.runtime.getURL(""));
|
||||||
|
|
||||||
|
// En consola de background script
|
||||||
|
// (about:debugging > Inspeccionar)
|
||||||
|
// Copiar todos los console.log relevantes
|
||||||
|
```
|
||||||
|
|
||||||
|
**Errores:**
|
||||||
|
- Captura de pantalla de errores en consola
|
||||||
|
- Texto completo de mensajes de error
|
||||||
|
|
||||||
|
### 2. Verificar problemas conocidos
|
||||||
|
|
||||||
|
- GitHub Issues: https://github.com/JustOff/ca-archive/issues
|
||||||
|
- Buscar error específico
|
||||||
|
|
||||||
|
### 3. Reportar bug
|
||||||
|
|
||||||
|
Si no existe issue similar, crear uno nuevo:
|
||||||
|
|
||||||
|
**Plantilla:**
|
||||||
|
|
||||||
|
```markdown
|
||||||
|
## Descripción del problema
|
||||||
|
[Describe qué está fallando]
|
||||||
|
|
||||||
|
## Pasos para reproducir
|
||||||
|
1. [Primer paso]
|
||||||
|
2. [Segundo paso]
|
||||||
|
3. [...]
|
||||||
|
|
||||||
|
## Comportamiento esperado
|
||||||
|
[Qué debería pasar]
|
||||||
|
|
||||||
|
## Comportamiento actual
|
||||||
|
[Qué está pasando]
|
||||||
|
|
||||||
|
## Entorno
|
||||||
|
- Navegador: [Firefox 100 / Chrome 105]
|
||||||
|
- SO: [Linux / Windows / macOS]
|
||||||
|
- Versión extensión: [3.0.0]
|
||||||
|
|
||||||
|
## Logs
|
||||||
|
```
|
||||||
|
[Pegar logs de consola aquí]
|
||||||
|
```
|
||||||
|
|
||||||
|
## Capturas
|
||||||
|
[Adjuntar screenshots si aplica]
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Contacto
|
||||||
|
|
||||||
|
- GitHub Issues: https://github.com/JustOff/ca-archive/issues
|
||||||
|
- Discusiones: https://github.com/JustOff/ca-archive/discussions
|
||||||
|
- Email: [Especificar si aplica]
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Debugging Avanzado
|
||||||
|
|
||||||
|
### Habilitar logging detallado
|
||||||
|
|
||||||
|
En `background.js`, agregar al inicio:
|
||||||
|
```javascript
|
||||||
|
const DEBUG = true;
|
||||||
|
|
||||||
|
function log(...args) {
|
||||||
|
if (DEBUG) console.log("[CA Archive]", ...args);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Luego usar `log()` en lugar de `console.log()`.
|
||||||
|
|
||||||
|
### Inspeccionar storage
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// Firefox
|
||||||
|
browser.storage.local.get(null).then(console.log);
|
||||||
|
|
||||||
|
// Chrome
|
||||||
|
chrome.storage.local.get(null, console.log);
|
||||||
|
```
|
||||||
|
|
||||||
|
### Ejecutar queries SQL manualmente
|
||||||
|
|
||||||
|
```javascript
|
||||||
|
// En consola de ca-archive.html
|
||||||
|
if (DB.db) {
|
||||||
|
const results = DB.execute("SELECT COUNT(*) FROM addons");
|
||||||
|
console.log(results);
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
### Profiling de rendimiento
|
||||||
|
|
||||||
|
1. Abrir DevTools (`F12`)
|
||||||
|
2. Ir a tab "Performance" / "Rendimiento"
|
||||||
|
3. Click en "Record" / "Grabar"
|
||||||
|
4. Realizar acción lenta
|
||||||
|
5. Stop y analizar flamegraph
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
## Recursos Adicionales
|
||||||
|
|
||||||
|
- [Documentación Mozilla WebExtensions](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions)
|
||||||
|
- [Chrome Extensions API](https://developer.chrome.com/docs/extensions/reference/)
|
||||||
|
- [sql.js Documentation](https://sql.js.org/)
|
||||||
|
- [Debugging WebExtensions (Firefox)](https://extensionworkshop.com/documentation/develop/debugging/)
|
||||||
|
- [Debugging Chrome Extensions](https://developer.chrome.com/docs/extensions/mv2/tut_debugging/)
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
**¿Solucionaste tu problema?** ¡Considera contribuir esta solución a la documentación!
|
||||||
|
|
||||||
|
**¿Problema diferente?** Abre un issue en GitHub: https://github.com/JustOff/ca-archive/issues
|
||||||
149
background.js
Archivo normal
149
background.js
Archivo normal
@@ -0,0 +1,149 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Compatibilidad con Chrome y Firefox
|
||||||
|
const browserAPI = typeof browser !== "undefined" ? browser : chrome;
|
||||||
|
|
||||||
|
// Configuración por defecto
|
||||||
|
const DEFAULT_SETTINGS = {
|
||||||
|
url: "about",
|
||||||
|
firstRun: true
|
||||||
|
};
|
||||||
|
|
||||||
|
// Inicializar storage con valores por defecto
|
||||||
|
browserAPI.runtime.onInstalled.addListener(async (details) => {
|
||||||
|
if (details.reason === "install") {
|
||||||
|
await browserAPI.storage.local.set(DEFAULT_SETTINGS);
|
||||||
|
// Abrir la página "about" en la primera instalación
|
||||||
|
openArchivePage("about");
|
||||||
|
} else if (details.reason === "update") {
|
||||||
|
console.log("Classic Add-ons Archive updated to version", browserAPI.runtime.getManifest().version);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// Manejar clic en el botón de la barra de herramientas
|
||||||
|
browserAPI.browserAction.onClicked.addListener(() => {
|
||||||
|
openArchivePage();
|
||||||
|
});
|
||||||
|
|
||||||
|
// Función para abrir la página del archivo
|
||||||
|
async function openArchivePage(page) {
|
||||||
|
try {
|
||||||
|
// Obtener la URL guardada o usar la página especificada
|
||||||
|
const settings = await browserAPI.storage.local.get("url");
|
||||||
|
const targetPage = page || settings.url || "about";
|
||||||
|
|
||||||
|
// Construir la URL de la extensión
|
||||||
|
const extensionUrl = browserAPI.runtime.getURL("content/ca-archive.html");
|
||||||
|
const fullUrl = `${extensionUrl}#${targetPage}`;
|
||||||
|
|
||||||
|
// Verificar si ya hay una pestaña abierta con el archivo
|
||||||
|
const tabs = await browserAPI.tabs.query({});
|
||||||
|
let foundTab = null;
|
||||||
|
|
||||||
|
for (let tab of tabs) {
|
||||||
|
if (tab.url && tab.url.startsWith(extensionUrl)) {
|
||||||
|
foundTab = tab;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (foundTab) {
|
||||||
|
// Si existe, activar la pestaña
|
||||||
|
await browserAPI.tabs.update(foundTab.id, { active: true });
|
||||||
|
await browserAPI.windows.update(foundTab.windowId, { focused: true });
|
||||||
|
// Actualizar el hash si es necesario
|
||||||
|
if (page) {
|
||||||
|
await browserAPI.tabs.update(foundTab.id, { url: fullUrl });
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// Si no existe, crear nueva pestaña
|
||||||
|
await browserAPI.tabs.create({ url: fullUrl });
|
||||||
|
}
|
||||||
|
|
||||||
|
// Si abrimos "about" en primera ejecución, cambiar a página principal para siguientes veces
|
||||||
|
if (targetPage === "about") {
|
||||||
|
await browserAPI.storage.local.set({ url: "list", firstRun: false });
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error opening archive page:", error);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Interceptar peticiones para modificar headers cuando sea necesario
|
||||||
|
browserAPI.webRequest.onHeadersReceived.addListener(
|
||||||
|
(details) => {
|
||||||
|
// Modificar headers para archivos de addons.mozilla.org archivados
|
||||||
|
const headers = details.responseHeaders || [];
|
||||||
|
|
||||||
|
// Si es una descarga desde nuestro storage, manejar Content-Disposition
|
||||||
|
if (details.url.includes("origin=caa")) {
|
||||||
|
const newHeaders = headers.filter(h => h.name.toLowerCase() !== "content-disposition");
|
||||||
|
|
||||||
|
if (details.url.includes("action=install")) {
|
||||||
|
// No forzar descarga para instalación
|
||||||
|
return { responseHeaders: newHeaders };
|
||||||
|
} else if (details.url.includes("action=download")) {
|
||||||
|
// Forzar descarga
|
||||||
|
newHeaders.push({
|
||||||
|
name: "Content-Disposition",
|
||||||
|
value: "attachment"
|
||||||
|
});
|
||||||
|
return { responseHeaders: newHeaders };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
urls: ["<all_urls>"]
|
||||||
|
},
|
||||||
|
["blocking", "responseHeaders"]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Bloquear ciertas peticiones de web.archive.org
|
||||||
|
browserAPI.webRequest.onBeforeRequest.addListener(
|
||||||
|
(details) => {
|
||||||
|
if (details.url.includes("web.archive.org")) {
|
||||||
|
// Bloquear scripts y recursos específicos de AMO que no queremos cargar
|
||||||
|
if (/\/web\/.+?\/(addons\.mozilla\.org\/.+?\/more|addons\.cdn\.mozilla\.net\/.+?\/loading-more\.gif|addons-amo\.cdn\.mozilla\.net\/amo-.+?\.js)/.test(details.url)) {
|
||||||
|
return { cancel: true };
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return {};
|
||||||
|
},
|
||||||
|
{
|
||||||
|
urls: ["*://web.archive.org/*"]
|
||||||
|
},
|
||||||
|
["blocking"]
|
||||||
|
);
|
||||||
|
|
||||||
|
// Manejar comandos de teclado (si se configuran)
|
||||||
|
if (browserAPI.commands && browserAPI.commands.onCommand) {
|
||||||
|
browserAPI.commands.onCommand.addListener((command) => {
|
||||||
|
if (command === "open-archive") {
|
||||||
|
openArchivePage();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Escuchar mensajes desde content scripts
|
||||||
|
browserAPI.runtime.onMessage.addListener((message, sender, sendResponse) => {
|
||||||
|
if (message.action === "openPage") {
|
||||||
|
openArchivePage(message.page);
|
||||||
|
sendResponse({ success: true });
|
||||||
|
} else if (message.action === "getSettings") {
|
||||||
|
browserAPI.storage.local.get(null).then(settings => {
|
||||||
|
sendResponse({ settings });
|
||||||
|
});
|
||||||
|
return true; // Mantener el canal abierto para respuesta asíncrona
|
||||||
|
} else if (message.action === "saveSettings") {
|
||||||
|
browserAPI.storage.local.set(message.settings).then(() => {
|
||||||
|
sendResponse({ success: true });
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
console.log("Classic Add-ons Archive background script loaded");
|
||||||
192
build.sh
Archivo ejecutable
192
build.sh
Archivo ejecutable
@@ -0,0 +1,192 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Script de construcción para Classic Add-ons Archive v3.0
|
||||||
|
# Genera paquetes .xpi (Firefox) y .zip (Chrome)
|
||||||
|
|
||||||
|
set -e # Salir si hay errores
|
||||||
|
|
||||||
|
echo "=================================================="
|
||||||
|
echo " Classic Add-ons Archive - Build Script v3.0"
|
||||||
|
echo "=================================================="
|
||||||
|
echo ""
|
||||||
|
|
||||||
|
# Colores para output
|
||||||
|
RED='\033[0;31m'
|
||||||
|
GREEN='\033[0;32m'
|
||||||
|
YELLOW='\033[1;33m'
|
||||||
|
NC='\033[0m' # No Color
|
||||||
|
|
||||||
|
# Configuración
|
||||||
|
VERSION="3.0.0"
|
||||||
|
DIST_DIR="dist"
|
||||||
|
FIREFOX_PACKAGE="ca-archive-${VERSION}.xpi"
|
||||||
|
CHROME_PACKAGE="ca-archive-${VERSION}-chrome.zip"
|
||||||
|
|
||||||
|
# Archivos a incluir (relativos al directorio raíz)
|
||||||
|
INCLUDE_FILES=(
|
||||||
|
"manifest.json"
|
||||||
|
"background.js"
|
||||||
|
"content/"
|
||||||
|
"skin/"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Archivos a excluir (patrones de exclusión)
|
||||||
|
EXCLUDE_PATTERNS=(
|
||||||
|
"*.git*"
|
||||||
|
"*~"
|
||||||
|
"*.swp"
|
||||||
|
".DS_Store"
|
||||||
|
"Thumbs.db"
|
||||||
|
"*.tmp"
|
||||||
|
"*.log"
|
||||||
|
"*.md" # Excluir documentación (opcional: comentar para incluir)
|
||||||
|
"install.rdf" # Legacy
|
||||||
|
"chrome.manifest" # Legacy
|
||||||
|
"bootstrap.js" # Legacy
|
||||||
|
"update.xml" # Legacy
|
||||||
|
"content/db.js" # Legacy (usamos db-webext.js)
|
||||||
|
"package.json"
|
||||||
|
"package-lock.json"
|
||||||
|
"node_modules/"
|
||||||
|
"dist/"
|
||||||
|
)
|
||||||
|
|
||||||
|
# Función para imprimir con color
|
||||||
|
print_status() {
|
||||||
|
echo -e "${GREEN}[✓]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_warning() {
|
||||||
|
echo -e "${YELLOW}[!]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
print_error() {
|
||||||
|
echo -e "${RED}[✗]${NC} $1"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Verificar que estamos en el directorio correcto
|
||||||
|
if [ ! -f "manifest.json" ]; then
|
||||||
|
print_error "No se encuentra manifest.json"
|
||||||
|
print_error "Ejecuta este script desde el directorio raíz del proyecto"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
print_status "Directorio de proyecto detectado"
|
||||||
|
|
||||||
|
# Crear directorio de distribución
|
||||||
|
if [ -d "$DIST_DIR" ]; then
|
||||||
|
print_warning "Limpiando directorio de distribución existente..."
|
||||||
|
rm -rf "$DIST_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$DIST_DIR"
|
||||||
|
print_status "Directorio de distribución creado: $DIST_DIR/"
|
||||||
|
|
||||||
|
# Función para construir el comando de exclusión para zip
|
||||||
|
build_exclude_args() {
|
||||||
|
local args=""
|
||||||
|
for pattern in "${EXCLUDE_PATTERNS[@]}"; do
|
||||||
|
args="$args -x '$pattern'"
|
||||||
|
done
|
||||||
|
echo "$args"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Construir paquete para Firefox (.xpi)
|
||||||
|
echo ""
|
||||||
|
echo "Construyendo paquete para Firefox..."
|
||||||
|
print_status "Empaquetando archivos..."
|
||||||
|
|
||||||
|
# Crear archivo zip temporal
|
||||||
|
TMP_ZIP="$DIST_DIR/temp.zip"
|
||||||
|
|
||||||
|
# Comando de zip con exclusiones
|
||||||
|
zip -r "$TMP_ZIP" "${INCLUDE_FILES[@]}" \
|
||||||
|
-x "${EXCLUDE_PATTERNS[@]}" \
|
||||||
|
> /dev/null 2>&1
|
||||||
|
|
||||||
|
# Renombrar a .xpi
|
||||||
|
mv "$TMP_ZIP" "$DIST_DIR/$FIREFOX_PACKAGE"
|
||||||
|
|
||||||
|
if [ -f "$DIST_DIR/$FIREFOX_PACKAGE" ]; then
|
||||||
|
FIREFOX_SIZE=$(du -h "$DIST_DIR/$FIREFOX_PACKAGE" | cut -f1)
|
||||||
|
print_status "Paquete Firefox creado: $FIREFOX_PACKAGE ($FIREFOX_SIZE)"
|
||||||
|
else
|
||||||
|
print_error "Error al crear paquete Firefox"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Construir paquete para Chrome (.zip)
|
||||||
|
echo ""
|
||||||
|
echo "Construyendo paquete para Chrome..."
|
||||||
|
print_status "Empaquetando archivos..."
|
||||||
|
|
||||||
|
zip -r "$DIST_DIR/$CHROME_PACKAGE" "${INCLUDE_FILES[@]}" \
|
||||||
|
-x "${EXCLUDE_PATTERNS[@]}" \
|
||||||
|
> /dev/null 2>&1
|
||||||
|
|
||||||
|
if [ -f "$DIST_DIR/$CHROME_PACKAGE" ]; then
|
||||||
|
CHROME_SIZE=$(du -h "$DIST_DIR/$CHROME_PACKAGE" | cut -f1)
|
||||||
|
print_status "Paquete Chrome creado: $CHROME_PACKAGE ($CHROME_SIZE)"
|
||||||
|
else
|
||||||
|
print_error "Error al crear paquete Chrome"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verificar integridad de los paquetes
|
||||||
|
echo ""
|
||||||
|
echo "Verificando paquetes..."
|
||||||
|
|
||||||
|
# Verificar Firefox
|
||||||
|
if unzip -t "$DIST_DIR/$FIREFOX_PACKAGE" > /dev/null 2>&1; then
|
||||||
|
print_status "Paquete Firefox verificado (integridad OK)"
|
||||||
|
else
|
||||||
|
print_error "Paquete Firefox corrupto"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Verificar Chrome
|
||||||
|
if unzip -t "$DIST_DIR/$CHROME_PACKAGE" > /dev/null 2>&1; then
|
||||||
|
print_status "Paquete Chrome verificado (integridad OK)"
|
||||||
|
else
|
||||||
|
print_error "Paquete Chrome corrupto"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Listar contenido (opcional)
|
||||||
|
if [ "$1" = "--list" ] || [ "$1" = "-l" ]; then
|
||||||
|
echo ""
|
||||||
|
echo "Contenido del paquete Firefox:"
|
||||||
|
unzip -l "$DIST_DIR/$FIREFOX_PACKAGE"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Resumen final
|
||||||
|
echo ""
|
||||||
|
echo "=================================================="
|
||||||
|
echo " ✨ Build completado exitosamente"
|
||||||
|
echo "=================================================="
|
||||||
|
echo ""
|
||||||
|
echo "Paquetes generados en: $DIST_DIR/"
|
||||||
|
echo ""
|
||||||
|
echo " Firefox: $FIREFOX_PACKAGE ($FIREFOX_SIZE)"
|
||||||
|
echo " Chrome: $CHROME_PACKAGE ($CHROME_SIZE)"
|
||||||
|
echo ""
|
||||||
|
echo "Próximos pasos:"
|
||||||
|
echo ""
|
||||||
|
echo " Firefox:"
|
||||||
|
echo " 1. Ir a about:debugging#/runtime/this-firefox"
|
||||||
|
echo " 2. Click en 'Cargar complemento temporal'"
|
||||||
|
echo " 3. Seleccionar: $DIST_DIR/$FIREFOX_PACKAGE"
|
||||||
|
echo ""
|
||||||
|
echo " Chrome:"
|
||||||
|
echo " 1. Ir a chrome://extensions/"
|
||||||
|
echo " 2. Activar 'Modo de desarrollador'"
|
||||||
|
echo " 3. Click en 'Cargar extensión sin empaquetar'"
|
||||||
|
echo " 4. Extraer y seleccionar la carpeta de $CHROME_PACKAGE"
|
||||||
|
echo ""
|
||||||
|
echo " Para publicar:"
|
||||||
|
echo " - Firefox AMO: https://addons.mozilla.org/developers/"
|
||||||
|
echo " - Chrome Web Store: https://chrome.google.com/webstore/devconsole"
|
||||||
|
echo ""
|
||||||
|
echo "=================================================="
|
||||||
|
|
||||||
|
exit 0
|
||||||
@@ -4,8 +4,8 @@
|
|||||||
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
|
||||||
<meta charset="utf-8">
|
<meta charset="utf-8">
|
||||||
|
|
||||||
<link rel="shortcut icon" type="image/x-icon" href="chrome://ca-archive/skin/logo.png">
|
<link rel="shortcut icon" type="image/x-icon" href="../skin/logo.png">
|
||||||
<link rel="stylesheet" href="chrome://ca-archive/skin/ca-archive.css">
|
<link rel="stylesheet" href="../skin/ca-archive.css">
|
||||||
|
|
||||||
<title>Classic Add-ons Archive</title>
|
<title>Classic Add-ons Archive</title>
|
||||||
</head>
|
</head>
|
||||||
@@ -16,58 +16,58 @@
|
|||||||
<div id="page" class="c">
|
<div id="page" class="c">
|
||||||
<div class="amo-header">
|
<div class="amo-header">
|
||||||
<div class="header-search" role="search">
|
<div class="header-search" role="search">
|
||||||
<form id="search" action="caa:list">
|
<form id="search" action="#list">
|
||||||
<input id="search-q" name="q" autocomplete="off" title="" class="text placeholder" placeholder="search for add-ons" type="text">
|
<input id="search-q" name="q" autocomplete="off" title="" class="text placeholder" placeholder="search for add-ons" type="text">
|
||||||
<button class="search-button" type="submit" title="Search" src="chrome://ca-archive/skin/btn-search.png"></button>
|
<button class="search-button" type="submit" title="Search" src="../skin/btn-search.png"></button>
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
<div id="masthead">
|
<div id="masthead">
|
||||||
<h1 class="site-title">
|
<h1 class="site-title">
|
||||||
<a href="caa:">
|
<a href="#">
|
||||||
<img alt="Firefox" src="chrome://ca-archive/skin/logo.png">Classic Add-ons Archive <font size="1">(2004-2018)</font></a>
|
<img alt="Firefox" src="../skin/logo.png">Classic Add-ons Archive <font size="1">(2004-2018)</font></a>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<nav id="site-nav" class="menu-nav c">
|
<nav id="site-nav" class="menu-nav c">
|
||||||
<ul>
|
<ul>
|
||||||
<li id="extensions">
|
<li id="extensions">
|
||||||
<a href="caa:list">Categories</a>
|
<a href="#list">Categories</a>
|
||||||
<ul class="two-col">
|
<ul class="two-col">
|
||||||
<li><a href="caa:list/alerts-updates">Alerts & Updates</a></li>
|
<li><a href="#list/alerts-updates">Alerts & Updates</a></li>
|
||||||
<li><a href="caa:list/appearance">Appearance</a></li>
|
<li><a href="#list/appearance">Appearance</a></li>
|
||||||
<li><a href="caa:list/bookmarks">Bookmarks</a></li>
|
<li><a href="#list/bookmarks">Bookmarks</a></li>
|
||||||
<li><a href="caa:list/download-management">Download Management</a></li>
|
<li><a href="#list/download-management">Download Management</a></li>
|
||||||
<li><a href="caa:list/feeds-news-blogging">Feeds, News & Blogging</a></li>
|
<li><a href="#list/feeds-news-blogging">Feeds, News & Blogging</a></li>
|
||||||
<li><a href="caa:list/games-entertainment">Games & Entertainment</a></li>
|
<li><a href="#list/games-entertainment">Games & Entertainment</a></li>
|
||||||
<li><a href="caa:list/language-support">Language Support</a></li>
|
<li><a href="#list/language-support">Language Support</a></li>
|
||||||
<li><a href="caa:list/photos-music-videos">Photos, Music & Videos</a></li>
|
<li><a href="#list/photos-music-videos">Photos, Music & Videos</a></li>
|
||||||
<li><a href="caa:list/privacy-security">Privacy & Security</a></li>
|
<li><a href="#list/privacy-security">Privacy & Security</a></li>
|
||||||
<li><a href="caa:list/search-tools">Search Tools</a></li>
|
<li><a href="#list/search-tools">Search Tools</a></li>
|
||||||
<li><a href="caa:list/shopping">Shopping</a></li>
|
<li><a href="#list/shopping">Shopping</a></li>
|
||||||
<li><a href="caa:list/social-communication">Social & Communication</a></li>
|
<li><a href="#list/social-communication">Social & Communication</a></li>
|
||||||
<li><a href="caa:list/tabs">Tabs</a></li>
|
<li><a href="#list/tabs">Tabs</a></li>
|
||||||
<li><a href="caa:list/web-development">Web Development</a></li>
|
<li><a href="#list/web-development">Web Development</a></li>
|
||||||
<li><a href="caa:list/other">Other</a></li>
|
<li><a href="#list/other">Other</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li id="listby">
|
<li id="listby">
|
||||||
<a href="caa:list">List by</a>
|
<a href="#list">List by</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a href="caa:list?sort=users">Most Users</a></li>
|
<li><a href="#list?sort=users">Most Users</a></li>
|
||||||
<li><a href="caa:list?sort=rating">Top Rated</a></li>
|
<li><a href="#list?sort=rating">Top Rated</a></li>
|
||||||
<li><a href="caa:list?sort=reviews">Most Reviews</a></li>
|
<li><a href="#list?sort=reviews">Most Reviews</a></li>
|
||||||
<li><a href="caa:list?sort=created">Newest</a></li>
|
<li><a href="#list?sort=created">Newest</a></li>
|
||||||
<li><a href="caa:list?sort=updated">Recently Updated</a></li>
|
<li><a href="#list?sort=updated">Recently Updated</a></li>
|
||||||
<li><a href="caa:list?sort=name">Name </a></li>
|
<li><a href="#list?sort=name">Name </a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
|
|
||||||
<li id="more">
|
<li id="more">
|
||||||
<a href="caa:">More…</a>
|
<a href="#">More…</a>
|
||||||
<ul>
|
<ul>
|
||||||
<li><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/">Live Firefox Add-ons Site</a></li>
|
<li><a target="_blank" href="https://addons.mozilla.org/en-US/firefox/">Live Firefox Add-ons Site</a></li>
|
||||||
<li><a target="_blank" href="http://web.archive.org/web/*/https://addons.mozilla.org/en-US/firefox/">Wayback Machine</a></li>
|
<li><a target="_blank" href="http://web.archive.org/web/*/https://addons.mozilla.org/en-US/firefox/">Wayback Machine</a></li>
|
||||||
<li><a href="caa:about">About</a></li>
|
<li><a href="#about">About</a></li>
|
||||||
</ul>
|
</ul>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -83,7 +83,8 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script src="chrome://ca-archive/content/ca-archive.js"></script>
|
<script src="db-webext.js"></script>
|
||||||
|
<script src="ca-archive.js"></script>
|
||||||
|
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
@@ -1,51 +1,107 @@
|
|||||||
"use strict";
|
"use strict";
|
||||||
(function () {
|
|
||||||
var Cu = Components.utils;
|
|
||||||
|
|
||||||
let dbname = "ca-archive-19030501.sqlite";
|
// Compatibilidad con Chrome y Firefox
|
||||||
|
const browserAPI = typeof browser !== "undefined" ? browser : chrome;
|
||||||
|
|
||||||
Cu.import("chrome://ca-archive/content/db.js");
|
(async function () {
|
||||||
if (!DB.openDB(dbname, document)) {
|
const dbname = "ca-archive-19030501.sqlite";
|
||||||
|
|
||||||
|
// Cargar el módulo de base de datos
|
||||||
|
// NOTA: Los scripts deben cargarse en el HTML antes de este script
|
||||||
|
// o usar import dinámico
|
||||||
|
|
||||||
|
// Inicializar la base de datos (ahora es asíncrono)
|
||||||
|
const dbOpened = await DB.openDB(dbname, document);
|
||||||
|
if (!dbOpened) {
|
||||||
|
console.error("Failed to open database");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
caa:addon/{slug|id}/versions[?page=[#ver]]
|
Rutas soportadas (usando hash):
|
||||||
caa:addon/{slug|id}/{eula|privacy|license/lid}
|
#addon/{slug|id}/versions[?page=[#ver]]
|
||||||
caa:addon/{slug|id}
|
#addon/{slug|id}/{eula|privacy|license/lid}
|
||||||
caa:list[/category][?{tag|q}=][?sort=][?page=]
|
#addon/{slug|id}
|
||||||
caa:[search-query]
|
#list[/category][?{tag|q}=][?sort=][?page=]
|
||||||
*/
|
#about
|
||||||
|
#{search-query}
|
||||||
|
*/
|
||||||
|
|
||||||
try {
|
// Función para manejar la navegación
|
||||||
let params, url = decodeURI(document.location);
|
async function handleNavigation() {
|
||||||
if ((params = /^caa:addon\/(.+?)\/versions\/?(\?page=(\d+)(#.+)?)?$/.exec(url)) !== null) {
|
try {
|
||||||
Cu.import("chrome://ca-archive/content/versions.js");
|
// Obtener la URL del hash
|
||||||
Versions.showPage(document, DB.db, params[1], params[3]);
|
let hash = window.location.hash.substring(1); // Remover el '#'
|
||||||
} else if ((params = /^caa:addon\/(.+?)\/(eula|privacy|license\/(.+))$/.exec(url)) !== null) {
|
if (!hash) {
|
||||||
Cu.import("chrome://ca-archive/content/epl.js");
|
hash = "list"; // Por defecto mostrar listado
|
||||||
EPL.showPage(document, DB.db, params[1], params[2], params[3]);
|
}
|
||||||
} else if ((params = /^caa:addon\/(.+?)\/?$/.exec(url)) !== null) {
|
|
||||||
Cu.import("chrome://ca-archive/content/addon.js");
|
let params;
|
||||||
Addon.showPage(document, DB.db, params[1]);
|
const url = decodeURI(hash);
|
||||||
} else if ((params = /^caa:list(\/([a-z-]+))?(\?tag=(.+?)|\?q=(.+?))?([\?|\&]sort=(\w+))?\&?(page=(\d+))?$/.exec(url)) !== null) {
|
|
||||||
Cu.import("chrome://ca-archive/content/list.js");
|
if ((params = /^addon\/(.+?)\/versions\/?(\?page=(\d+)(#.+)?)?$/.exec(url)) !== null) {
|
||||||
List.showPage(document, DB.db, params[2], params[4], params[5], params[7], params[9]);
|
// Cargar dinámicamente el módulo de versiones si no está cargado
|
||||||
} else if (url == "caa:") {
|
if (typeof Versions === "undefined") {
|
||||||
Cu.import("chrome://ca-archive/content/tcloud.js");
|
await loadScript("versions.js");
|
||||||
TCloud.showPage(document, DB.db);
|
}
|
||||||
} else if (url == "caa:about") {
|
Versions.showPage(document, DB.db, params[1], params[3]);
|
||||||
Cu.import("chrome://ca-archive/content/about.js");
|
} else if ((params = /^addon\/(.+?)\/(eula|privacy|license\/(.+))$/.exec(url)) !== null) {
|
||||||
About.showPage(document, DB.db);
|
if (typeof EPL === "undefined") {
|
||||||
} else if ((params = /^caa:(.+)$/.exec(url)) !== null) {
|
await loadScript("epl.js");
|
||||||
Cu.import("chrome://ca-archive/content/list.js");
|
}
|
||||||
List.showPage(document, DB.db, undefined, undefined, params[1], undefined, undefined);
|
EPL.showPage(document, DB.db, params[1], params[2], params[3]);
|
||||||
} else {
|
} else if ((params = /^addon\/(.+?)\/?$/.exec(url)) !== null) {
|
||||||
document.location = "caa:list";
|
if (typeof Addon === "undefined") {
|
||||||
|
await loadScript("addon.js");
|
||||||
|
}
|
||||||
|
Addon.showPage(document, DB.db, params[1]);
|
||||||
|
} else if ((params = /^list(\/([a-z-]+))?(\?tag=(.+?)|\?q=(.+?))?([\?|\&]sort=(\w+))?\&?(page=(\d+))?$/.exec(url)) !== null) {
|
||||||
|
if (typeof List === "undefined") {
|
||||||
|
await loadScript("list.js");
|
||||||
|
}
|
||||||
|
List.showPage(document, DB.db, params[2], params[4], params[5], params[7], params[9]);
|
||||||
|
} else if (url === "" || url === "list") {
|
||||||
|
if (typeof TCloud === "undefined") {
|
||||||
|
await loadScript("tcloud.js");
|
||||||
|
}
|
||||||
|
TCloud.showPage(document, DB.db);
|
||||||
|
} else if (url === "about") {
|
||||||
|
if (typeof About === "undefined") {
|
||||||
|
await loadScript("about.js");
|
||||||
|
}
|
||||||
|
About.showPage(document, DB.db);
|
||||||
|
} else {
|
||||||
|
// Búsqueda genérica
|
||||||
|
if (typeof List === "undefined") {
|
||||||
|
await loadScript("list.js");
|
||||||
|
}
|
||||||
|
List.showPage(document, DB.db, undefined, undefined, url, undefined, undefined);
|
||||||
|
}
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Navigation error:", e);
|
||||||
}
|
}
|
||||||
} catch (e) {
|
|
||||||
Cu.reportError(e);
|
|
||||||
}
|
}
|
||||||
DB.closeDB();
|
|
||||||
|
// Función auxiliar para cargar scripts dinámicamente
|
||||||
|
function loadScript(filename) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src = filename;
|
||||||
|
script.onload = () => resolve();
|
||||||
|
script.onerror = () => reject(new Error(`Failed to load script: ${filename}`));
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Manejar el cambio de hash
|
||||||
|
window.addEventListener("hashchange", handleNavigation);
|
||||||
|
|
||||||
|
// Inicializar la navegación inicial
|
||||||
|
await handleNavigation();
|
||||||
|
|
||||||
|
// Cerrar la base de datos cuando se cierre la página
|
||||||
|
window.addEventListener("beforeunload", () => {
|
||||||
|
DB.closeDB();
|
||||||
|
});
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
|||||||
245
content/db-webext.js
Archivo normal
245
content/db-webext.js
Archivo normal
@@ -0,0 +1,245 @@
|
|||||||
|
"use strict";
|
||||||
|
|
||||||
|
// Módulo de base de datos para WebExtensions
|
||||||
|
// Usa sql.js (SQLite compilado a JavaScript/WebAssembly)
|
||||||
|
|
||||||
|
const DB = {
|
||||||
|
db: null,
|
||||||
|
SQL: null,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Inicializa sql.js (debe ser llamado primero)
|
||||||
|
*/
|
||||||
|
async initSQL() {
|
||||||
|
if (this.SQL) return this.SQL;
|
||||||
|
|
||||||
|
// Cargar sql.js desde CDN o localmente
|
||||||
|
// Para producción, incluir sql.js localmente
|
||||||
|
try {
|
||||||
|
// Intentar cargar sql.js si no está ya cargado
|
||||||
|
if (typeof window.initSqlJs === "undefined") {
|
||||||
|
await this.loadScript("https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/sql-wasm.js");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.SQL = await initSqlJs({
|
||||||
|
locateFile: file => `https://cdnjs.cloudflare.com/ajax/libs/sql.js/1.8.0/${file}`
|
||||||
|
});
|
||||||
|
|
||||||
|
return this.SQL;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Failed to initialize sql.js:", e);
|
||||||
|
throw new Error("Could not load SQL engine");
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cargar script dinámicamente
|
||||||
|
*/
|
||||||
|
loadScript(src) {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
const script = document.createElement("script");
|
||||||
|
script.src = src;
|
||||||
|
script.onload = resolve;
|
||||||
|
script.onerror = reject;
|
||||||
|
document.head.appendChild(script);
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Abre o crea la base de datos
|
||||||
|
* @param {string} dbname - Nombre del archivo de base de datos
|
||||||
|
* @param {Document} document - Documento HTML
|
||||||
|
* @returns {boolean} - true si se abrió correctamente
|
||||||
|
*/
|
||||||
|
async openDB(dbname, document) {
|
||||||
|
try {
|
||||||
|
await this.initSQL();
|
||||||
|
|
||||||
|
// Intentar cargar la base de datos desde el storage de la extensión
|
||||||
|
const dbData = await this.loadDBFromStorage(dbname);
|
||||||
|
|
||||||
|
if (dbData) {
|
||||||
|
// Cargar base de datos existente
|
||||||
|
this.db = new this.SQL.Database(new Uint8Array(dbData));
|
||||||
|
console.log("Database loaded from storage");
|
||||||
|
} else {
|
||||||
|
// Intentar descargar la base de datos empaquetada
|
||||||
|
await this.downloadAndStoreDB(dbname, document);
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error opening database:", e);
|
||||||
|
this.showMessage(document,
|
||||||
|
"Error loading database. Please check the console for details.",
|
||||||
|
"db-warning"
|
||||||
|
);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Carga la base de datos desde el storage local de la extensión
|
||||||
|
*/
|
||||||
|
async loadDBFromStorage(dbname) {
|
||||||
|
try {
|
||||||
|
const browserAPI = typeof browser !== "undefined" ? browser : chrome;
|
||||||
|
const result = await browserAPI.storage.local.get(dbname);
|
||||||
|
return result[dbname];
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Could not load DB from storage:", e);
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Descarga y almacena la base de datos
|
||||||
|
*/
|
||||||
|
async downloadAndStoreDB(dbname, document) {
|
||||||
|
this.showMessage(document,
|
||||||
|
"Loading database for the first time. Please wait...",
|
||||||
|
"db-warning ok"
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Intentar cargar desde la extensión
|
||||||
|
const browserAPI = typeof browser !== "undefined" ? browser : chrome;
|
||||||
|
const dbUrl = browserAPI.runtime.getURL(`content/db/${dbname}`);
|
||||||
|
|
||||||
|
const response = await fetch(dbUrl);
|
||||||
|
if (!response.ok) {
|
||||||
|
throw new Error(`Failed to fetch database: ${response.status}`);
|
||||||
|
}
|
||||||
|
|
||||||
|
const arrayBuffer = await response.arrayBuffer();
|
||||||
|
this.db = new this.SQL.Database(new Uint8Array(arrayBuffer));
|
||||||
|
|
||||||
|
// Guardar en storage para uso futuro
|
||||||
|
await this.saveDBToStorage(dbname, arrayBuffer);
|
||||||
|
|
||||||
|
this.showMessage(document,
|
||||||
|
"Database loaded successfully!",
|
||||||
|
"db-warning ok"
|
||||||
|
);
|
||||||
|
|
||||||
|
console.log("Database downloaded and stored");
|
||||||
|
} catch (e) {
|
||||||
|
console.error("Error downloading database:", e);
|
||||||
|
this.showMessage(document,
|
||||||
|
"Failed to load database. Please reinstall the extension.",
|
||||||
|
"db-warning bad"
|
||||||
|
);
|
||||||
|
throw e;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Guarda la base de datos en el storage local
|
||||||
|
*/
|
||||||
|
async saveDBToStorage(dbname, arrayBuffer) {
|
||||||
|
try {
|
||||||
|
const browserAPI = typeof browser !== "undefined" ? browser : chrome;
|
||||||
|
|
||||||
|
// Convertir ArrayBuffer a Array para storage
|
||||||
|
const uint8Array = new Uint8Array(arrayBuffer);
|
||||||
|
const array = Array.from(uint8Array);
|
||||||
|
|
||||||
|
// Chrome tiene límite de storage, considerar usar chunks para DBs grandes
|
||||||
|
// Por ahora, intentar guardar directamente
|
||||||
|
await browserAPI.storage.local.set({ [dbname]: array });
|
||||||
|
|
||||||
|
console.log("Database saved to storage");
|
||||||
|
} catch (e) {
|
||||||
|
console.warn("Could not save DB to storage (may be too large):", e);
|
||||||
|
// No es crítico si falla, se recargará la próxima vez
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Muestra un mensaje en la página
|
||||||
|
*/
|
||||||
|
showMessage(document, msg, style) {
|
||||||
|
const div = document.createElement("div");
|
||||||
|
div.className = style;
|
||||||
|
div.appendChild(document.createTextNode(msg));
|
||||||
|
const page = document.getElementById("page");
|
||||||
|
if (page) {
|
||||||
|
page.appendChild(div);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Cierra la base de datos
|
||||||
|
*/
|
||||||
|
closeDB() {
|
||||||
|
if (this.db) {
|
||||||
|
this.db.close();
|
||||||
|
this.db = null;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ejecuta una consulta SQL
|
||||||
|
*/
|
||||||
|
execute(sql, params = []) {
|
||||||
|
if (!this.db) {
|
||||||
|
throw new Error("Database not opened");
|
||||||
|
}
|
||||||
|
return this.db.exec(sql, params);
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ejecuta una consulta y retorna la primera fila
|
||||||
|
*/
|
||||||
|
executeRow(sql, params = []) {
|
||||||
|
const results = this.execute(sql, params);
|
||||||
|
if (results.length > 0 && results[0].values.length > 0) {
|
||||||
|
return results[0].values[0];
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
},
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Prepara una statement (compatible con API antigua)
|
||||||
|
*/
|
||||||
|
createStatement(sql) {
|
||||||
|
if (!this.db) {
|
||||||
|
throw new Error("Database not opened");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Crear un objeto que emule la API de mozIStorageStatement
|
||||||
|
const stmt = this.db.prepare(sql);
|
||||||
|
|
||||||
|
return {
|
||||||
|
params: {},
|
||||||
|
executeStep() {
|
||||||
|
return stmt.step();
|
||||||
|
},
|
||||||
|
reset() {
|
||||||
|
stmt.reset();
|
||||||
|
},
|
||||||
|
finalize() {
|
||||||
|
stmt.free();
|
||||||
|
},
|
||||||
|
row: new Proxy({}, {
|
||||||
|
get(target, prop) {
|
||||||
|
return stmt.get()[stmt.getColumnNames().indexOf(prop)];
|
||||||
|
}
|
||||||
|
}),
|
||||||
|
getString(index) {
|
||||||
|
return stmt.get()[index];
|
||||||
|
},
|
||||||
|
getInt32(index) {
|
||||||
|
return stmt.get()[index];
|
||||||
|
},
|
||||||
|
getDouble(index) {
|
||||||
|
return stmt.get()[index];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Hacer disponible globalmente para compatibilidad
|
||||||
|
if (typeof window !== "undefined") {
|
||||||
|
window.DB = DB;
|
||||||
|
}
|
||||||
52
manifest.json
Archivo normal
52
manifest.json
Archivo normal
@@ -0,0 +1,52 @@
|
|||||||
|
{
|
||||||
|
"manifest_version": 2,
|
||||||
|
"name": "Classic Add-ons Archive",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"description": "Catalog of classic Firefox add-ons created before WebExtensions apocalypse",
|
||||||
|
"author": "Off JustOff",
|
||||||
|
"homepage_url": "https://github.com/JustOff/ca-archive/",
|
||||||
|
|
||||||
|
"icons": {
|
||||||
|
"48": "skin/logo.png",
|
||||||
|
"96": "skin/logo.png"
|
||||||
|
},
|
||||||
|
|
||||||
|
"browser_action": {
|
||||||
|
"default_icon": {
|
||||||
|
"16": "skin/button.png",
|
||||||
|
"32": "skin/button.png"
|
||||||
|
},
|
||||||
|
"default_title": "Classic Add-ons Archive",
|
||||||
|
"default_popup": ""
|
||||||
|
},
|
||||||
|
|
||||||
|
"background": {
|
||||||
|
"scripts": ["background.js"]
|
||||||
|
},
|
||||||
|
|
||||||
|
"permissions": [
|
||||||
|
"storage",
|
||||||
|
"unlimitedStorage",
|
||||||
|
"tabs",
|
||||||
|
"webRequest",
|
||||||
|
"webRequestBlocking",
|
||||||
|
"<all_urls>"
|
||||||
|
],
|
||||||
|
|
||||||
|
"web_accessible_resources": [
|
||||||
|
"content/ca-archive.html",
|
||||||
|
"content/*.js",
|
||||||
|
"skin/*.css",
|
||||||
|
"skin/*.png",
|
||||||
|
"skin/*.gif"
|
||||||
|
],
|
||||||
|
|
||||||
|
"content_security_policy": "script-src 'self' 'unsafe-eval'; object-src 'self'",
|
||||||
|
|
||||||
|
"browser_specific_settings": {
|
||||||
|
"gecko": {
|
||||||
|
"id": "ca-archive@Off.JustOff",
|
||||||
|
"strict_min_version": "57.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
31
package.json
Archivo normal
31
package.json
Archivo normal
@@ -0,0 +1,31 @@
|
|||||||
|
{
|
||||||
|
"name": "ca-archive",
|
||||||
|
"version": "3.0.0",
|
||||||
|
"description": "Classic Add-ons Archive - WebExtensions Edition",
|
||||||
|
"author": "Off JustOff <Off.Just.Off@gmail.com>",
|
||||||
|
"license": "MPL-2.0",
|
||||||
|
"homepage": "https://github.com/JustOff/ca-archive",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://github.com/JustOff/ca-archive.git"
|
||||||
|
},
|
||||||
|
"scripts": {
|
||||||
|
"lint": "web-ext lint --source-dir=.",
|
||||||
|
"build:firefox": "web-ext build --source-dir=. --artifacts-dir=./dist --overwrite-dest",
|
||||||
|
"build:chrome": "npm run zip",
|
||||||
|
"zip": "zip -r dist/ca-archive-3.0-chrome.zip manifest.json background.js content/ skin/ -x '*.git*' -x '*~' -x '*.md' -x 'install.rdf' -x 'chrome.manifest' -x 'bootstrap.js' -x 'update.xml'",
|
||||||
|
"start:firefox": "web-ext run --source-dir=. --firefox-preview",
|
||||||
|
"start:chrome": "web-ext run --source-dir=. --target=chromium"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"web-ext": "^7.9.0"
|
||||||
|
},
|
||||||
|
"keywords": [
|
||||||
|
"firefox",
|
||||||
|
"chrome",
|
||||||
|
"extensions",
|
||||||
|
"addons",
|
||||||
|
"archive",
|
||||||
|
"webextensions"
|
||||||
|
]
|
||||||
|
}
|
||||||
Referencia en una nueva incidencia
Block a user