Version in base suite: 4.3-1
Base version: tbsync_4.3-1
Target version: tbsync_4.7-1~deb12u1
Base file: /srv/ftp-master.debian.org/ftp/pool/main/t/tbsync/tbsync_4.3-1.dsc
Target file: /srv/ftp-master.debian.org/policy/pool/main/t/tbsync/tbsync_4.7-1~deb12u1.dsc
_locales/bg/messages.json | 8
_locales/cs/messages.json | 8
_locales/de/messages.json | 92 +--
_locales/en-US/messages.json | 8
_locales/es/messages.json | 8
_locales/et/messages.json | 8
_locales/fr/messages.json | 8
_locales/gl/messages.json | 10
_locales/hu/messages.json | 8
_locales/it/messages.json | 8
_locales/ja/messages.json | 8
_locales/ko/messages.json | 8
_locales/pl/messages.json | 8
_locales/pt_BR/messages.json | 8
_locales/ro/messages.json | 8
_locales/ru/messages.json | 8
_locales/sv/messages.json | 8
content/api/BootstrapLoader/CHANGELOG.md | 15
content/api/BootstrapLoader/implementation.js | 676 ++++++++++++++++++++------
content/api/BootstrapLoader/schema.json | 4
content/manager/accounts.js | 12
content/manager/accounts.xhtml | 4
content/manager/editAccount.js | 3
content/manager/editAccount.xhtml | 7
content/manager/eventlog/eventlog.js | 9
content/manager/eventlog/eventlog.xhtml | 14
content/modules/db.js | 13
content/modules/io.js | 4
content/modules/lightning.js | 2
content/modules/manager.js | 11
content/passwordPrompt/passwordPrompt.css | 13
content/passwordPrompt/passwordPrompt.js | 8
content/passwordPrompt/passwordPrompt.xhtml | 44 -
content/tbsync.jsm | 3
debian/changelog | 26 +
debian/control | 6
debian/gbp.conf | 2
manifest.json | 4
38 files changed, 817 insertions(+), 285 deletions(-)
diff -Nru tbsync-4.3/_locales/bg/messages.json tbsync-4.7/_locales/bg/messages.json
--- tbsync-4.3/_locales/bg/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/bg/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Синхронизирай информацията от всички TbSync регистрации със сървърите"
+ },
+ "password.ok": {
+ "message": "ОК"
+ },
+ "password.cancel": {
+ "message": "Отказ"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/cs/messages.json tbsync-4.7/_locales/cs/messages.json
--- tbsync-4.3/_locales/cs/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/cs/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronizovat poslední změny"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Zrušit"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/de/messages.json tbsync-4.7/_locales/de/messages.json
--- tbsync-4.3/_locales/de/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/de/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -3,28 +3,28 @@
"message": "Um diesen Fehler zu beheben, können Sie einen Fehlerbericht an den Entwickler von TbSync schicken. Soll der Fehlerbericht jetzt angefertigt werden?"
},
"NoDebugLog": {
- "message": "Es liegen keine aussagekräftigen Debug-Meldungen vor. Bitte aktivieren Sie den Debug-Modus, starten Thunderbird neu und wiederholen dann alle Schritte um das fehlerhafte Verhalten zu reproduzieren."
+ "message": "Es liegen keine aussagekräftigen Debug-Meldungen vor. Bitte aktivieren Sie den Debug-Modus, starten Thunderbird neu und wiederholen dann alle Schritte, um das fehlerhafte Verhalten zu reproduzieren."
},
"OopsMessage": {
- "message": "Oops! TbSync konnte nicht starten!"
+ "message": "Hoppla! TbSync konnte nicht starten!"
},
"RestartThunderbirdAndTryAgain": {
- "message": "Der TbSync Debug-Modus wurde aktiviert, bitte starten Sie Thunderbird neu und versuchen Sie dann noch einmal TbSync zu öffnen."
+ "message": "Das TbSync-Debug-Protokoll wurde eingeschaltet. Bitte starten Sie Thunderbird neu, und versuchen Sie dann noch einmal, TbSync zu öffnen!"
},
"UnableToTraceError": {
- "message": "Es ist im Augenblick nicht möglich, diesen Fehler zu untersuchen, da der TbSync Debug-Modus nicht aktiviert ist. Soll der Debug-Modus aktiviert werden, damit dieser Fehler untersucht und behoben werden kann?"
+ "message": "Dieser Fehler kann nicht untersucht werden, solange das Debug-Protokoll deaktiviert ist. Soll das Protokoll jetzt aktiviert werden, damit dieser Fehler untersucht und behoben werden kann?"
},
"accountacctions.delete": {
- "message": "Konto '##accountname##' löschen"
+ "message": "Konto „##accountname##” löschen"
},
"accountacctions.disable": {
"message": "Konto '##accountname##' deaktivieren"
},
"accountacctions.enable": {
- "message": "Konto '##accountname##' aktivieren & Server kontaktieren"
+ "message": "Konto „##accountname##” aktivieren und Server kontaktieren"
},
"accountacctions.sync": {
- "message": "Konto '##accountname##' synchronisieren"
+ "message": "Konto „##accountname##” synchronisieren"
},
"addressbook.searchall": {
"message": "Alle Adressbücher durchsuchen"
@@ -60,25 +60,25 @@
"message": "Leerlauf"
},
"installProvider.header": {
- "message": "Provider '##replace.1##' für TbSync ist noch nicht installiert."
+ "message": "Provider „##replace.1##” für TbSync ist noch nicht installiert."
},
"manager.AccountActions": {
- "message": "Konto Aktionen"
+ "message": "Konto-Aktionen"
},
"manager.AddAccount": {
- "message": "Neues Konto hinzufügen"
+ "message": "Konto hinzufügen"
},
"manager.DeleteAccount": {
- "message": "Konto löschen"
+ "message": "Konto entfernen"
},
"manager.DisableAccount": {
"message": "Konto deaktivieren"
},
"manager.EnableAccount": {
- "message": "Konto aktivieren & mit dem Server verbinden"
+ "message": "Konto aktivieren und mit dem Server verbinden"
},
"manager.RetryConnectAccount": {
- "message": "Erneut versuchen mit dem Server zu verbinden"
+ "message": "Erneut versuchen, mit dem Server zu verbinden"
},
"manager.ShowEventLog": {
"message": "Ereignisprotokoll anzeigen"
@@ -96,10 +96,10 @@
"message": "Kontoeinstellungen"
},
"manager.catman.text": {
- "message": "TbSync synchronisiert auch Kontaktkategorien, die einen effizienten Ersatz für die nicht synchronisierbaren Kontaktlisten darstellen. Um diese im Thunderbird Adressbuch zu nutzen, können Sie das Add-On 'Category Manager' installieren. Dieses Add-On ermöglicht die Verwaltung überlappender kategoriebasierter Kontaktgruppen und stellt eine Reihe anderer kategoriespezifischer Funktionen bereit. Es kann aus dem offiziellen Mozilla Add-On Repository heruntergeladen werden:"
+ "message": "TbSync synchronisiert auch Kontaktkategorien, die einen effizienten Ersatz für die nicht synchronisierbaren Kontaktlisten darstellen. Um diese im Thunderbird-Adressbuch zu nutzen, können Sie das Add-On „Category Manager” installieren. Dieses Add-On ermöglicht die Verwaltung überlappender kategoriebasierter Kontaktgruppen und stellt eine Reihe anderer kategoriespezifischer Funktionen bereit. Es kann aus dem offiziellen Mozilla Add-On Repository heruntergeladen werden:"
},
"manager.community": {
- "message": "Community"
+ "message": "Nutzergemeinschaft"
},
"manager.connecting": {
"message": "Verbindung wird hergestellt"
@@ -120,7 +120,7 @@
"message": "Aktiviert: Protokolliert alle Fehler"
},
"manager.help.debuglevel.2": {
- "message": "Aktiviert: Protokolliert alle gesendeten & empfangenen Daten"
+ "message": "Aktiviert: Protokolliert alle gesendeten und empfangenen Daten"
},
"manager.help.debuglevel.3": {
"message": "Aktiviert: Protokolliert alle Daten und einige interne Debug-Werte"
@@ -138,25 +138,25 @@
"message": "Benötigen Sie Hilfe?"
},
"manager.help.viewdebuglog": {
- "message": "Debug-Log anzeigen"
+ "message": "Debug-Protokoll anzeigen"
},
"manager.help.wiki": {
- "message": "Besuchen Sie die Wikiseiten des TbSync Projektes, diese beinhalten zusätzliche Informationen, Benutzeranleitungen und detaillierte Konfigurationsbeschreibungen."
+ "message": "Besuchen Sie die Wikiseiten des TbSync-Projekts, diese enthalten zusätzliche Informationen, Benutzeranleitungen und detaillierte Konfigurationsbeschreibungen."
},
"manager.installprovider.link": {
- "message": "Klicken Sie auf den folgenden Link, um die Informationsseite des fehlenden Provider aufzurufen. Auf dieser Seite finden Sie weitere Informationen zu dem Provider und haben die Möglichkeit, diesen zu installieren:"
+ "message": "Klicken Sie auf den folgenden Link, um die Informationsseite des fehlenden Synchronisations-Providers aufzurufen. Dort finden Sie weitere Informationen dazu und haben die Möglichkeit, diesen zu installieren:"
},
"manager.installprovider.warning": {
- "message": "Dieser Provider stammt nicht aus dem offiziellen Thunderbird Add-On Verzeichnis und wurde demnach nicht von Thunderbird-Mitarbeitern überprüft. Dieser Provider könnte schlimme Dinge mit Ihrem System anstellen. Benutzung auf eigene Gefahr."
+ "message": "Dieser Provider stammt nicht aus der offiziellen Thunderbird-Add-On-Sammlung und wurde demnach nicht von Thunderbird-Mitarbeitern überprüft. Es könnte sich um Schad-Software handeln, deshalb verwenden Sie es auf eigene Gefahr."
},
"manager.lockedsettings.description": {
"message": "Um Synchronisierungsfehler zu vermeiden, können einige Einstellungen nicht bearbeitet werden, während das Konto aktiviert ist."
},
"manager.missingprovider": {
- "message": "Dieses Konto benötigt den ##provider## Synchronisationsprovider, der zur Zeit aber nicht installiert ist."
+ "message": "Dieses Konto benötigt den ##provider##-Synchronisations-Provider, noch nicht installiert ist."
},
"manager.noaccounts": {
- "message": "Es sind aktuell noch keine Konten konfiguriert."
+ "message": "Es sind noch keine Konten definiert."
},
"manager.provider": {
"message": "Provider installieren"
@@ -174,13 +174,13 @@
"message": "Status"
},
"manager.supporter.contributors": {
- "message": "Mitwirkende & Übersetzer"
+ "message": "Mitwirkende und Übersetzer"
},
"manager.supporter.details": {
"message": "Details"
},
"manager.supporter.sponsors": {
- "message": "Sponsoren von Test-Accounts"
+ "message": "Sponsoren von Testkonten"
},
"manager.tabs.status": {
"message": "Synchronisationsstatus"
@@ -195,7 +195,7 @@
"message": "Allgemein"
},
"manager.tabs.status.never": {
- "message": "Eine Einstellung von 0 deaktiviert periodische Synchronisation. Push Synchronisation wird noch nicht unterstützt."
+ "message": "Eine Einstellung von 0 deaktiviert periodische Synchronisation. Push-Synchronisation wird noch nicht unterstützt."
},
"manager.tabs.status.resources": {
"message": "Verfügbare Ressourcen"
@@ -207,13 +207,13 @@
"message": "Jetzt synchronisieren"
},
"manager.tabs.status.tryagain": {
- "message": "Erneut versuchen mit dem Server zu verbinden"
+ "message": "Erneut versuchen, mit dem Server zu verbinden"
},
"manager.title": {
"message": "TbSync Kontoverwaltung"
},
"manager.tryagain": {
- "message": "Erneut versuchen mit dem Server zu verbinden"
+ "message": "Erneut versuchen, mit dem Server zu verbinden"
},
"menu.settingslabel": {
"message": "Synchronisationseinstellungen (TbSync)"
@@ -228,13 +228,13 @@
"message": "Passwort:"
},
"password.title": {
- "message": "TbSync Anmeldeinformationen"
+ "message": "TbSync-Anmeldeinformationen"
},
"password.user": {
- "message": "Benutzer:"
+ "message": "Nutzer:"
},
"popup.opensettings": {
- "message": "TbSync Kontoverwaltung öffnen"
+ "message": "TbSync-Kontoverwaltung öffnen"
},
"prompt.DeleteAccount": {
"message": "Sind Sie sicher, dass Sie das Konto ##accountName## löschen möchten?"
@@ -243,37 +243,37 @@
"message": "Sind Sie sicher, dass Sie dieses Konto deaktivieren möchten? Alle lokalen Veränderungen, die noch nicht synchronisiert wurden, gehen dabei verloren!"
},
"prompt.Erase": {
- "message": "Sind Sie sicher, dass Sie dieses Konto eines unbekannten Providers aus der Kontoliste entfernen möchten?"
+ "message": "Sind Sie sicher, dass Sie dieses Konto eines unbekannten Anbieters aus der Kontoliste entfernen möchten?"
},
"prompt.Unsubscribe": {
"message": "Sind Sie sicher, dass Sie dieses Element nicht länger abonnieren möchten? Alle lokalen Veränderungen, die noch nicht synchronisiert wurden, gehen dabei verloren!"
},
"status.JavaScriptError": {
- "message": "Javascript Fehler! Bitte prüfen Sie das Ereignisprotokoll für weitere Details."
+ "message": "Javascript-Fehler! Bitte prüfen Sie das Ereignisprotokoll für weitere Details!"
},
"status.OAuthAbortError": {
- "message": "OAuth 2.0 Authentifizierungsprozess vom Benutzer abgebrochen."
+ "message": "OAuth 2.0-Authentifizierungsprozess vom Nutzer abgebrochen."
},
"status.OAuthHttpError": {
- "message": "OAuth 2.0 Authentifizierungsprozess fehlgeschlagen (HTTP Error ##replace.1##)."
+ "message": "OAuth-2.0-Authentifizierungsprozess fehlgeschlagen (HTTP Error ##replace.1##)."
},
"status.OAuthNetworkError": {
- "message": "Verbindung zum OAuth 2.0 Authentifizierungsserver nicht möglich."
+ "message": "Verbindung zum OAuth-2.0-Authentifizierungsserver nicht möglich."
},
"status.OAuthServerError": {
- "message": " OAuth 2.0 Authentifizierungsserver meldet: ##replace.1##"
+ "message": " OAuth-2.0-Authentifizierungsserver meldet: ##replace.1##"
},
"status.aborted": {
"message": "Nicht synchronisiert"
},
"status.apiError": {
- "message": "API Implementierungsfehler"
+ "message": "API-Implementierungsfehler"
},
"status.disabled": {
"message": "Konto ist deaktiviert, Synchronisation ist ausgeschaltet."
},
"status.foldererror": {
- "message": "Bei mindestens einer Resource trat ein Synchronisationsfehler auf. Bitte prüfen sie das Ereignisprotokoll für weitere Details."
+ "message": "Bei mindestens einer Ressource trat ein Synchronisationsfehler auf. Bitte prüfen Sie das Ereignisprotokoll für weitere Details!"
},
"status.modified": {
"message": "Lokale Änderungen"
@@ -282,10 +282,10 @@
"message": "Verbindung zum Server fehlgeschlagen (##replace.1##)."
},
"status.no-folders-found-on-server": {
- "message": "Auf dem Server wurden keine Resourcen gefunden."
+ "message": "Auf dem Server wurden keine Ressourcen gefunden."
},
"status.notargets": {
- "message": "Synchronisation abgebrochen da die Elemente zum Synchronisieren nicht erstellt werden konnten."
+ "message": "Synchronisation abgebrochen, da die Elemente zum Synchronisieren nicht erstellt werden konnten."
},
"status.notsyncronized": {
"message": "Konto muss synchronisiert werden."
@@ -294,7 +294,7 @@
"message": "Warten auf Synchronisation"
},
"status.security": {
- "message": "Fehler beim Aufbau einer sicherern Verbindung. Benutzen Sie eventuell ein selbst signiertes Zertifikat oder ein andersartiges nicht vertrauenswürdiges Zertifikat welches nicht in Thunderbird importiert ist? (##replace.1##)"
+ "message": "Fehler beim Aufbau einer sicheren Verbindung. Benutzen Sie eventuell ein selbst signiertes oder anderweitig nicht vertrauenswürdiges Zertifikat, das nicht in Thunderbird importiert ist? (##replace.1##)"
},
"status.skipped": {
"message": "Nicht unterstützt"
@@ -354,6 +354,12 @@
"message": "Synchronisiere alle TbSync Konten"
},
"toolbar.tooltiptext": {
- "message": "Gleiche alle TbSync Konten mit den Servern ab"
+ "message": "Gleiche alle TbSync-Konten mit den Servern ab"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Abbrechen"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/en-US/messages.json tbsync-4.7/_locales/en-US/messages.json
--- tbsync-4.3/_locales/en-US/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/en-US/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronize latest changes"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Cancel"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/es/messages.json tbsync-4.7/_locales/es/messages.json
--- tbsync-4.3/_locales/es/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/es/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Sincronizar los últimos cambios"
+ },
+ "password.ok": {
+ "message": "Aceptar"
+ },
+ "password.cancel": {
+ "message": "Cancelar"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/et/messages.json tbsync-4.7/_locales/et/messages.json
--- tbsync-4.3/_locales/et/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/et/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronize latest changes"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Tühista"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/fr/messages.json tbsync-4.7/_locales/fr/messages.json
--- tbsync-4.3/_locales/fr/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/fr/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchroniser les dernières modifications"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Annuler"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/gl/messages.json tbsync-4.7/_locales/gl/messages.json
--- tbsync-4.3/_locales/gl/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/gl/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -141,7 +141,7 @@
"message": "Ver rexistro de depuración"
},
"manager.help.wiki": {
- "message": "Abrir as páxinas wiki do proxecto TbSync nas que facilitan información adicional, guías e descricións detalladas da configuración."
+ "message": "Abre o wiki do proxecto TbSync no que se facilita información adicional, guías e descricións detalladas da configuración."
},
"manager.installprovider.link": {
"message": "Preme no seguinte enlace para abrir a páxina de información do provedor de sincronización que falta. Aí atoparás máis información sobre o provedor e terás a opción de instalalo:"
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Sincronizar os últimos cambios"
+ },
+ "password.ok": {
+ "message": "Aceptar"
+ },
+ "password.cancel": {
+ "message": "Cancelar"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/hu/messages.json tbsync-4.7/_locales/hu/messages.json
--- tbsync-4.3/_locales/hu/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/hu/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "A legújabb változtatások szinkronizálása"
+ },
+ "password.ok": {
+ "message": "Rendben"
+ },
+ "password.cancel": {
+ "message": "Mégse"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/it/messages.json tbsync-4.7/_locales/it/messages.json
--- tbsync-4.3/_locales/it/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/it/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Sincronizza le ultime modifiche"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Annulla"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/ja/messages.json tbsync-4.7/_locales/ja/messages.json
--- tbsync-4.3/_locales/ja/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/ja/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "最新の変更を同期"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "キャンセル"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/ko/messages.json tbsync-4.7/_locales/ko/messages.json
--- tbsync-4.3/_locales/ko/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/ko/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronize latest changes"
+ },
+ "password.ok": {
+ "message": "확인"
+ },
+ "password.cancel": {
+ "message": "취소"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/pl/messages.json tbsync-4.7/_locales/pl/messages.json
--- tbsync-4.3/_locales/pl/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/pl/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronizuj najnowsze zmiany"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Anuluj"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/pt_BR/messages.json tbsync-4.7/_locales/pt_BR/messages.json
--- tbsync-4.3/_locales/pt_BR/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/pt_BR/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Sincronizar as alterações mais recentes"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Cancelar"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/ro/messages.json tbsync-4.7/_locales/ro/messages.json
--- tbsync-4.3/_locales/ro/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/ro/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronize latest changes"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Anulare"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/ru/messages.json tbsync-4.7/_locales/ru/messages.json
--- tbsync-4.3/_locales/ru/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/ru/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Синхронизировать последние изменения"
+ },
+ "password.ok": {
+ "message": "ОК"
+ },
+ "password.cancel": {
+ "message": "Отмена"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/_locales/sv/messages.json tbsync-4.7/_locales/sv/messages.json
--- tbsync-4.3/_locales/sv/messages.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/_locales/sv/messages.json 2023-08-29 20:22:49.000000000 +0000
@@ -355,5 +355,11 @@
},
"toolbar.tooltiptext": {
"message": "Synchronize latest changes"
+ },
+ "password.ok": {
+ "message": "OK"
+ },
+ "password.cancel": {
+ "message": "Avbryt"
}
-}
\ No newline at end of file
+}
diff -Nru tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md
--- tbsync-4.3/content/api/BootstrapLoader/CHANGELOG.md 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md 2023-08-29 20:22:49.000000000 +0000
@@ -1,3 +1,18 @@
+Version: 1.21
+-------------
+- Explicitly set hasAddonManagerEventListeners flag to false on uninstall
+
+Version: 1.20
+-------------
+- hard fork BootstrapLoader v1.19 implementation and continue to serve it for
+ Thunderbird 111 and older
+- BootstrapLoader v1.20 has removed a lot of unnecessary code used for backward
+ compatibility
+
+Version: 1.19
+-------------
+- fix race condition which could prevent the AOM tab to be monkey patched correctly
+
Version: 1.18
-------------
- be precise on which revision the wrench symbol should be displayed, instead of
diff -Nru tbsync-4.3/content/api/BootstrapLoader/implementation.js tbsync-4.7/content/api/BootstrapLoader/implementation.js
--- tbsync-4.3/content/api/BootstrapLoader/implementation.js 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/api/BootstrapLoader/implementation.js 2023-08-29 20:22:49.000000000 +0000
@@ -2,7 +2,7 @@
* This file is provided by the addon-developer-support repository at
* https://github.com/thundernest/addon-developer-support
*
- * Version: 1.18
+ * Version: 1.21
*
* Author: John Bieling (john@thunderbird.net)
*
@@ -17,70 +17,65 @@
var { AddonManager } = ChromeUtils.import("resource://gre/modules/AddonManager.jsm");
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var BootstrapLoader = class extends ExtensionCommon.ExtensionAPI {
- getMessenger(context) {
- let apis = [
- "storage",
- "runtime",
- "extension",
- "i18n",
- ];
-
- function getStorage() {
- let localstorage = null;
- try {
- localstorage = context.apiCan.findAPIPath("storage");
- localstorage.local.get = (...args) =>
- localstorage.local.callMethodInParentProcess("get", args);
- localstorage.local.set = (...args) =>
- localstorage.local.callMethodInParentProcess("set", args);
- localstorage.local.remove = (...args) =>
- localstorage.local.callMethodInParentProcess("remove", args);
- localstorage.local.clear = (...args) =>
- localstorage.local.callMethodInParentProcess("clear", args);
- } catch (e) {
- console.info("Storage permission is missing");
- }
- return localstorage;
- }
-
- let messenger = {};
- for (let api of apis) {
- switch (api) {
- case "storage":
- XPCOMUtils.defineLazyGetter(messenger, "storage", () =>
- getStorage()
- );
- break;
+function getThunderbirdVersion() {
+ let parts = Services.appinfo.version.split(".");
+ return {
+ major: parseInt(parts[0]),
+ minor: parseInt(parts[1]),
+ revision: parts.length > 2 ? parseInt(parts[2]) : 0,
+ }
+}
- default:
- XPCOMUtils.defineLazyGetter(messenger, api, () =>
- context.apiCan.findAPIPath(api)
- );
- }
+function getMessenger(context) {
+ let apis = ["storage", "runtime", "extension", "i18n"];
+
+ function getStorage() {
+ let localstorage = null;
+ try {
+ localstorage = context.apiCan.findAPIPath("storage");
+ localstorage.local.get = (...args) =>
+ localstorage.local.callMethodInParentProcess("get", args);
+ localstorage.local.set = (...args) =>
+ localstorage.local.callMethodInParentProcess("set", args);
+ localstorage.local.remove = (...args) =>
+ localstorage.local.callMethodInParentProcess("remove", args);
+ localstorage.local.clear = (...args) =>
+ localstorage.local.callMethodInParentProcess("clear", args);
+ } catch (e) {
+ console.info("Storage permission is missing");
}
- return messenger;
+ return localstorage;
}
- getThunderbirdVersion() {
- let parts = Services.appinfo.version.split(".");
- return {
- major: parseInt(parts[0]),
- minor: parseInt(parts[1]),
- revision: parts.length > 2 ? parseInt(parts[2]) : 0,
+ let messenger = {};
+ for (let api of apis) {
+ switch (api) {
+ case "storage":
+ XPCOMUtils.defineLazyGetter(messenger, "storage", () =>
+ getStorage()
+ );
+ break;
+
+ default:
+ XPCOMUtils.defineLazyGetter(messenger, api, () =>
+ context.apiCan.findAPIPath(api)
+ );
}
}
-
+ return messenger;
+}
+
+var BootstrapLoader_102 = class extends ExtensionCommon.ExtensionAPI {
getCards(e) {
// This gets triggered by real events but also manually by providing the outer window.
// The event is attached to the outer browser, get the inner one.
let doc;
-
+
// 78,86, and 87+ need special handholding. *Yeah*.
- if (this.getThunderbirdVersion().major < 86) {
+ if (getThunderbirdVersion().major < 86) {
let ownerDoc = e.document || e.target.ownerDocument;
doc = ownerDoc.getElementById("html-view-browser").contentDocument;
- } else if (this.getThunderbirdVersion().major < 87) {
+ } else if (getThunderbirdVersion().major < 87) {
let ownerDoc = e.document || e.target;
doc = ownerDoc.getElementById("html-view-browser").contentDocument;
} else {
@@ -88,42 +83,42 @@
}
return doc.querySelectorAll("addon-card");
}
-
+
// Add pref entry to 68
add68PrefsEntry(event) {
let id = this.menu_addonPrefs_id + "_" + this.uniqueRandomID;
// Get the best size of the icon (16px or bigger)
- let iconSizes = this.extension.manifest.icons
+ let iconSizes = this.extension.manifest.icons
? Object.keys(this.extension.manifest.icons)
: [];
- iconSizes.sort((a,b)=>a-b);
+ iconSizes.sort((a, b) => a - b);
let bestSize = iconSizes.filter(e => parseInt(e) >= 16).shift();
let icon = bestSize ? this.extension.manifest.icons[bestSize] : "";
let name = this.extension.manifest.name;
let entry = icon
? event.target.ownerGlobal.MozXULElement.parseXULToFragment(
- ``)
- : event.target.ownerGlobal.MozXULElement.parseXULToFragment(
- ``);
-
+ ``)
+ : event.target.ownerGlobal.MozXULElement.parseXULToFragment(
+ ``);
+
event.target.appendChild(entry);
let noPrefsElem = event.target.querySelector('[disabled="true"]');
// using collapse could be undone by core, so we use display none
// noPrefsElem.setAttribute("collapsed", "true");
noPrefsElem.style.display = "none";
event.target.ownerGlobal.document.getElementById(id).addEventListener("command", this);
- }
+ }
// Event handler for the addon manager, to update the state of the options button.
- handleEvent(e) {
+ handleEvent(e) {
switch (e.type) {
// 68 add-on options menu showing
case "popupshowing": {
this.add68PrefsEntry(e);
}
- break;
+ break;
// 78/88 add-on options menu/button click
case "click": {
@@ -131,31 +126,31 @@
e.stopPropagation();
let BL = {}
BL.extension = this.extension;
- BL.messenger = this.getMessenger(this.context);
+ BL.messenger = getMessenger(this.context);
let w = Services.wm.getMostRecentWindow("mail:3pane");
- w.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
+ w.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
}
- break;
-
+ break;
+
// 68 add-on options menu command
case "command": {
let BL = {}
BL.extension = this.extension;
- BL.messenger = this.getMessenger(this.context);
+ BL.messenger = getMessenger(this.context);
e.target.ownerGlobal.openDialog(this.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
}
- break;
-
+ break;
+
// update, ViewChanged and manual call for add-on manager options overlay
default: {
let cards = this.getCards(e);
for (let card of cards) {
// Setup either the options entry in the menu or the button
if (card.addon.id == this.extension.id) {
- let optionsMenu =
- (this.getThunderbirdVersion().major > 78 && this.getThunderbirdVersion().major < 88) ||
- (this.getThunderbirdVersion().major == 78 && this.getThunderbirdVersion().minor < 10) ||
- (this.getThunderbirdVersion().major == 78 && this.getThunderbirdVersion().minor == 10 && this.getThunderbirdVersion().revision < 2);
+ let optionsMenu =
+ (getThunderbirdVersion().major > 78 && getThunderbirdVersion().major < 88) ||
+ (getThunderbirdVersion().major == 78 && getThunderbirdVersion().minor < 10) ||
+ (getThunderbirdVersion().major == 78 && getThunderbirdVersion().minor == 10 && getThunderbirdVersion().revision < 2);
if (optionsMenu) {
// Options menu in 78.0-78.10 and 79-87
let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
@@ -204,10 +199,10 @@
}
}
}
- }
- }
-
-// Some tab/add-on-manager related functions
+ }
+ }
+
+ // Some tab/add-on-manager related functions
getTabMail(window) {
return window.document.getElementById("tabmail");
}
@@ -215,7 +210,7 @@
// returns the outer browser, not the nested browser of the add-on manager
// events must be attached to the outer browser
getAddonManagerFromTab(tab) {
- if (tab.browser) {
+ if (tab.browser && tab.mode.name == "contentTab") {
let win = tab.browser.contentWindow;
if (win && win.location.href == "about:addons") {
return win;
@@ -226,9 +221,28 @@
getAddonManagerFromWindow(window) {
let tabMail = this.getTabMail(window);
for (let tab of tabMail.tabInfo) {
- let win = this.getAddonManagerFromTab(tab)
- if (win) {
- return win;
+ let managerWindow = this.getAddonManagerFromTab(tab);
+ if (managerWindow) {
+ return managerWindow;
+ }
+ }
+ }
+
+ async getAddonManagerFromWindowWaitForLoad(window) {
+ let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+
+ let tabMail = this.getTabMail(window);
+ for (let tab of tabMail.tabInfo) {
+ if (tab.browser && tab.mode.name == "contentTab") {
+ // Instead of registering a load observer, wait until its loaded. Not nice,
+ // but gets aroud a lot of edge cases.
+ while (!tab.pageLoaded) {
+ await new Promise(r => setTimeout(r, 150));
+ }
+ let managerWindow = this.getAddonManagerFromTab(tab);
+ if (managerWindow) {
+ return managerWindow;
+ }
}
}
}
@@ -237,15 +251,16 @@
if (!managerWindow) {
return;
}
- if (managerWindow
- && managerWindow[this.uniqueRandomID]
- && managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+ if (
+ managerWindow &&
+ managerWindow[this.uniqueRandomID] &&
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
) {
return;
}
managerWindow.document.addEventListener("ViewChanged", this);
managerWindow.document.addEventListener("update", this);
- managerWindow.document.addEventListener("view-loaded", this);
+ managerWindow.document.addEventListener("view-loaded", this);
managerWindow[this.uniqueRandomID] = {};
managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = true;
if (forceLoad) {
@@ -262,13 +277,13 @@
this.pathToOptionsPage = null;
this.chromeHandle = null;
this.chromeData = null;
- this.resourceData = null;
+ this.resourceData = null;
this.bootstrappedObj = {};
// make the extension object and the messenger object available inside
// the bootstrapped scope
this.bootstrappedObj.extension = context.extension;
- this.bootstrappedObj.messenger = this.getMessenger(this.context);
+ this.bootstrappedObj.messenger = getMessenger(this.context);
this.BOOTSTRAP_REASONS = {
APP_STARTUP: 1,
@@ -283,49 +298,413 @@
const aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
-
+
let self = this;
// TabMonitor to detect opening of tabs, to setup the options button in the add-on manager.
this.tabMonitor = {
- onTabTitleChanged(aTab) {},
- onTabClosing(aTab) {},
- onTabPersist(aTab) {},
- onTabRestored(aTab) {},
- onTabSwitched(aNewTab, aOldTab) {
- //self.setupAddonManager(self.getAddonManagerFromTab(aNewTab));
+ onTabTitleChanged(tab) { },
+ onTabClosing(tab) { },
+ onTabPersist(tab) { },
+ onTabRestored(tab) { },
+ onTabSwitched(aNewTab, aOldTab) { },
+ async onTabOpened(tab) {
+ if (tab.browser && tab.mode.name == "contentTab") {
+ let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+ // Instead of registering a load observer, wait until its loaded. Not nice,
+ // but gets aroud a lot of edge cases.
+ while (!tab.pageLoaded) {
+ await new Promise(r => setTimeout(r, 150));
+ }
+ self.setupAddonManager(self.getAddonManagerFromTab(tab));
+ }
},
- async onTabOpened(aTab) {
- if (aTab.browser) {
- if (!aTab.pageLoaded) {
- // await a location change if browser is not loaded yet
- await new Promise(resolve => {
- let reporterListener = {
- QueryInterface: ChromeUtils.generateQI([
- "nsIWebProgressListener",
- "nsISupportsWeakReference",
- ]),
- onStateChange() {},
- onProgressChange() {},
- onLocationChange(
- /* in nsIWebProgress*/ aWebProgress,
- /* in nsIRequest*/ aRequest,
- /* in nsIURI*/ aLocation
- ) {
- aTab.browser.removeProgressListener(reporterListener);
- resolve();
- },
- onStatusChange() {},
- onSecurityChange() {},
- onContentBlockingEvent() {}
- }
- aTab.browser.addProgressListener(reporterListener);
+ };
+
+ return {
+ BootstrapLoader: {
+
+ registerOptionsPage(optionsUrl) {
+ self.pathToOptionsPage = optionsUrl.startsWith("chrome://")
+ ? optionsUrl
+ : context.extension.rootURI.resolve(optionsUrl);
+ },
+
+ openOptionsDialog(windowId) {
+ let window = context.extension.windowManager.get(windowId, context).window
+ let BL = {}
+ BL.extension = self.extension;
+ BL.messenger = getMessenger(self.context);
+ window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
+ },
+
+ registerChromeUrl(data) {
+ let chromeData = [];
+ let resourceData = [];
+ for (let entry of data) {
+ if (entry[0] == "resource") resourceData.push(entry);
+ else chromeData.push(entry)
+ }
+
+ if (chromeData.length > 0) {
+ const manifestURI = Services.io.newURI(
+ "manifest.json",
+ null,
+ context.extension.rootURI
+ );
+ self.chromeHandle = aomStartup.registerChrome(manifestURI, chromeData);
+ }
+
+ for (let res of resourceData) {
+ // [ "resource", "shortname" , "path" ]
+ let uri = Services.io.newURI(
+ res[2],
+ null,
+ context.extension.rootURI
+ );
+ resProto.setSubstitutionWithFlags(
+ res[1],
+ uri,
+ resProto.ALLOW_CONTENT_ACCESS
+ );
+ }
+
+ self.chromeData = chromeData;
+ self.resourceData = resourceData;
+ },
+
+ registerBootstrapScript: async function (aPath) {
+ self.pathToBootstrapScript = aPath.startsWith("chrome://")
+ ? aPath
+ : context.extension.rootURI.resolve(aPath);
+
+ // Get the addon object belonging to this extension.
+ let addon = await AddonManager.getAddonByID(context.extension.id);
+ //make the addon globally available in the bootstrapped scope
+ self.bootstrappedObj.addon = addon;
+
+ // add BOOTSTRAP_REASONS to scope
+ for (let reason of Object.keys(self.BOOTSTRAP_REASONS)) {
+ self.bootstrappedObj[reason] = self.BOOTSTRAP_REASONS[reason];
+ }
+
+ // Load registered bootstrap scripts and execute its startup() function.
+ try {
+ if (self.pathToBootstrapScript) Services.scriptloader.loadSubScript(self.pathToBootstrapScript, self.bootstrappedObj, "UTF-8");
+ if (self.bootstrappedObj.startup) self.bootstrappedObj.startup.call(self.bootstrappedObj, self.extension.addonData, self.BOOTSTRAP_REASONS[self.extension.startupReason]);
+ } catch (e) {
+ Components.utils.reportError(e)
+ }
+
+ // Register window listener for main TB window
+ if (self.pathToOptionsPage) {
+ ExtensionSupport.registerWindowListener("injectListener_" + self.uniqueRandomID, {
+ chromeURLs: [
+ "chrome://messenger/content/messenger.xul",
+ "chrome://messenger/content/messenger.xhtml",
+ ],
+ async onLoadWindow(window) {
+ if (getThunderbirdVersion().major < 78) {
+ let element_addonPrefs = window.document.getElementById(self.menu_addonPrefs_id);
+ element_addonPrefs.addEventListener("popupshowing", self);
+ } else {
+ // Add a tabmonitor, to be able to setup the options button/menu in the add-on manager.
+ self.getTabMail(window).registerTabMonitor(self.tabMonitor);
+ window[self.uniqueRandomID] = {};
+ window[self.uniqueRandomID].hasTabMonitor = true;
+ // Setup the options button/menu in the add-on manager, if it is already open.
+ let managerWindow = await self.getAddonManagerFromWindowWaitForLoad(window);
+ self.setupAddonManager(managerWindow, true);
+ }
+ },
+
+ onUnloadWindow(window) {
+ }
});
}
- // Setup the ViewChange event listener in the outer browser of the add-on,
- // but do not actually add the button/menu, as the inner browser is not yet ready,
- // let the ViewChange event do it
- self.setupAddonManager(self.getAddonManagerFromTab(aTab));
+ }
+ }
+ };
+ }
+
+ onShutdown(isAppShutdown) {
+ if (isAppShutdown) {
+ return; // the application gets unloaded anyway
+ }
+
+ //remove our entry in the add-on options menu
+ if (this.pathToOptionsPage) {
+ for (let window of Services.wm.getEnumerator("mail:3pane")) {
+ if (getThunderbirdVersion().major < 78) {
+ let element_addonPrefs = window.document.getElementById(this.menu_addonPrefs_id);
+ element_addonPrefs.removeEventListener("popupshowing", this);
+ // Remove our entry.
+ let entry = window.document.getElementById(this.menu_addonPrefs_id + "_" + this.uniqueRandomID);
+ if (entry) entry.remove();
+ // Do we have to unhide the noPrefsElement?
+ if (element_addonPrefs.children.length == 1) {
+ let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
+ noPrefsElem.style.display = "inline";
+ }
+ } else {
+ // Remove event listener for addon manager view changes
+ let managerWindow = this.getAddonManagerFromWindow(window);
+ if (
+ managerWindow &&
+ managerWindow[this.uniqueRandomID] &&
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+ ) {
+ managerWindow.document.removeEventListener("ViewChanged", this);
+ managerWindow.document.removeEventListener("update", this);
+ managerWindow.document.removeEventListener("view-loaded", this);
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = false;
+
+ let cards = this.getCards(managerWindow);
+ if (getThunderbirdVersion().major < 88) {
+ // Remove options menu in 78-87
+ for (let card of cards) {
+ let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
+ if (addonOptionsLegacyEntry) addonOptionsLegacyEntry.remove();
+ }
+ } else {
+ // Remove options button in 88
+ for (let card of cards) {
+ if (card.addon.id == this.extension.id) {
+ let addonOptionsButton = card.querySelector(".extension-options-button2");
+ if (addonOptionsButton) addonOptionsButton.remove();
+ break;
+ }
+ }
+ }
+ }
+
+ // Remove tabmonitor
+ if (window[this.uniqueRandomID].hasTabMonitor) {
+ this.getTabMail(window).unregisterTabMonitor(this.tabMonitor);
+ window[this.uniqueRandomID].hasTabMonitor = false;
+ }
+
+ }
+ }
+ // Stop listening for new windows.
+ ExtensionSupport.unregisterWindowListener("injectListener_" + this.uniqueRandomID);
+ }
+
+ // Execute registered shutdown()
+ try {
+ if (this.bootstrappedObj.shutdown) {
+ this.bootstrappedObj.shutdown(
+ this.extension.addonData,
+ isAppShutdown
+ ? this.BOOTSTRAP_REASONS.APP_SHUTDOWN
+ : this.BOOTSTRAP_REASONS.ADDON_DISABLE);
+ }
+ } catch (e) {
+ Components.utils.reportError(e)
+ }
+
+ if (this.resourceData) {
+ const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
+ for (let res of this.resourceData) {
+ // [ "resource", "shortname" , "path" ]
+ resProto.setSubstitution(
+ res[1],
+ null,
+ );
+ }
+ }
+
+ if (this.chromeHandle) {
+ this.chromeHandle.destruct();
+ this.chromeHandle = null;
+ }
+ // Flush all caches
+ Services.obs.notifyObservers(null, "startupcache-invalidate");
+ console.log("BootstrapLoader for " + this.extension.id + " unloaded!");
+ }
+};
+
+// Removed all extra code for backward compatibility for better maintainability.
+var BootstrapLoader_115 = class extends ExtensionCommon.ExtensionAPI {
+ getCards(e) {
+ // This gets triggered by real events but also manually by providing the outer window.
+ // The event is attached to the outer browser, get the inner one.
+ let doc = e.document || e.target;
+ return doc.querySelectorAll("addon-card");
+ }
+
+ // Event handler for the addon manager, to update the state of the options button.
+ handleEvent(e) {
+ switch (e.type) {
+ case "click": {
+ e.preventDefault();
+ e.stopPropagation();
+ let BL = {}
+ BL.extension = this.extension;
+ BL.messenger = getMessenger(this.context);
+ let w = Services.wm.getMostRecentWindow("mail:3pane");
+ w.openDialog(
+ this.pathToOptionsPage,
+ "AddonOptions",
+ "chrome,resizable,centerscreen",
+ BL
+ );
+ }
+ break;
+
+
+ // update, ViewChanged and manual call for add-on manager options overlay
+ default: {
+ let cards = this.getCards(e);
+ for (let card of cards) {
+ // Setup either the options entry in the menu or the button
+ if (card.addon.id == this.extension.id) {
+ // Add-on button
+ let addonOptionsButton = card.querySelector(
+ ".windowlistener-options-button"
+ );
+ if (card.addon.isActive && !addonOptionsButton) {
+ let origAddonOptionsButton = card.querySelector(".extension-options-button")
+ origAddonOptionsButton.setAttribute("hidden", "true");
+
+ addonOptionsButton = card.ownerDocument.createElement("button");
+ addonOptionsButton.classList.add("windowlistener-options-button");
+ addonOptionsButton.classList.add("extension-options-button");
+ card.optionsButton.parentNode.insertBefore(
+ addonOptionsButton,
+ card.optionsButton
+ );
+ card
+ .querySelector(".windowlistener-options-button")
+ .addEventListener("click", this);
+ } else if (!card.addon.isActive && addonOptionsButton) {
+ addonOptionsButton.remove();
+ }
+ }
+ }
+ }
+ }
+ }
+
+ // Some tab/add-on-manager related functions
+ getTabMail(window) {
+ return window.document.getElementById("tabmail");
+ }
+
+ // returns the outer browser, not the nested browser of the add-on manager
+ // events must be attached to the outer browser
+ getAddonManagerFromTab(tab) {
+ if (tab.browser && tab.mode.name == "contentTab") {
+ let win = tab.browser.contentWindow;
+ if (win && win.location.href == "about:addons") {
+ return win;
+ }
+ }
+ }
+
+ getAddonManagerFromWindow(window) {
+ let tabMail = this.getTabMail(window);
+ for (let tab of tabMail.tabInfo) {
+ let managerWindow = this.getAddonManagerFromTab(tab);
+ if (managerWindow) {
+ return managerWindow;
+ }
+ }
+ }
+
+ async getAddonManagerFromWindowWaitForLoad(window) {
+ let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+
+ let tabMail = this.getTabMail(window);
+ for (let tab of tabMail.tabInfo) {
+ if (tab.browser && tab.mode.name == "contentTab") {
+ // Instead of registering a load observer, wait until its loaded. Not nice,
+ // but gets aroud a lot of edge cases.
+ while (!tab.pageLoaded) {
+ await new Promise(r => setTimeout(r, 150));
+ }
+ let managerWindow = this.getAddonManagerFromTab(tab);
+ if (managerWindow) {
+ return managerWindow;
+ }
+ }
+ }
+ }
+
+ setupAddonManager(managerWindow, forceLoad = false) {
+ if (!managerWindow) {
+ return;
+ }
+ if (!this.pathToOptionsPage) {
+ return;
+ }
+ if (
+ managerWindow &&
+ managerWindow[this.uniqueRandomID] &&
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+ ) {
+ return;
+ }
+
+ managerWindow.document.addEventListener("ViewChanged", this);
+ managerWindow.document.addEventListener("update", this);
+ managerWindow.document.addEventListener("view-loaded", this);
+ managerWindow[this.uniqueRandomID] = {};
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = true;
+ if (forceLoad) {
+ this.handleEvent(managerWindow);
+ }
+ }
+
+ getAPI(context) {
+ this.uniqueRandomID = "AddOnNS" + context.extension.instanceId;
+ this.menu_addonPrefs_id = "addonPrefs";
+
+
+ this.pathToBootstrapScript = null;
+ this.pathToOptionsPage = null;
+ this.chromeHandle = null;
+ this.chromeData = null;
+ this.resourceData = null;
+ this.bootstrappedObj = {};
+
+ // make the extension object and the messenger object available inside
+ // the bootstrapped scope
+ this.bootstrappedObj.extension = context.extension;
+ this.bootstrappedObj.messenger = getMessenger(this.context);
+
+ this.BOOTSTRAP_REASONS = {
+ APP_STARTUP: 1,
+ APP_SHUTDOWN: 2,
+ ADDON_ENABLE: 3,
+ ADDON_DISABLE: 4,
+ ADDON_INSTALL: 5,
+ ADDON_UNINSTALL: 6, // not supported
+ ADDON_UPGRADE: 7,
+ ADDON_DOWNGRADE: 8,
+ };
+
+ const aomStartup = Cc["@mozilla.org/addons/addon-manager-startup;1"].getService(Ci.amIAddonManagerStartup);
+ const resProto = Cc["@mozilla.org/network/protocol;1?name=resource"].getService(Ci.nsISubstitutingProtocolHandler);
+
+ let self = this;
+
+ // TabMonitor to detect opening of tabs, to setup the options button in the add-on manager.
+ this.tabMonitor = {
+ onTabTitleChanged(tab) { },
+ onTabClosing(tab) { },
+ onTabPersist(tab) { },
+ onTabRestored(tab) { },
+ onTabSwitched(aNewTab, aOldTab) { },
+ async onTabOpened(tab) {
+ if (tab.browser && tab.mode.name == "contentTab") {
+ let { setTimeout } = Services.wm.getMostRecentWindow("mail:3pane");
+ // Instead of registering a load observer, wait until its loaded. Not nice,
+ // but gets aroud a lot of edge cases.
+ while (!tab.pageLoaded) {
+ await new Promise(r => setTimeout(r, 150));
+ }
+ self.setupAddonManager(self.getAddonManagerFromTab(tab));
}
},
};
@@ -343,8 +722,8 @@
let window = context.extension.windowManager.get(windowId, context).window
let BL = {}
BL.extension = self.extension;
- BL.messenger = self.getMessenger(self.context);
- window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
+ BL.messenger = getMessenger(self.context);
+ window.openDialog(self.pathToOptionsPage, "AddonOptions", "chrome,resizable,centerscreen", BL);
},
registerChromeUrl(data) {
@@ -382,7 +761,7 @@
self.resourceData = resourceData;
},
- registerBootstrapScript: async function(aPath) {
+ registerBootstrapScript: async function (aPath) {
self.pathToBootstrapScript = aPath.startsWith("chrome://")
? aPath
: context.extension.rootURI.resolve(aPath);
@@ -404,32 +783,30 @@
} catch (e) {
Components.utils.reportError(e)
}
-
+
// Register window listener for main TB window
if (self.pathToOptionsPage) {
ExtensionSupport.registerWindowListener("injectListener_" + self.uniqueRandomID, {
chromeURLs: [
"chrome://messenger/content/messenger.xul",
- "chrome://messenger/content/messenger.xhtml",
+ "chrome://messenger/content/messenger.xhtml",
],
async onLoadWindow(window) {
- if (self.getThunderbirdVersion().major < 78) {
+ if (getThunderbirdVersion().major < 78) {
let element_addonPrefs = window.document.getElementById(self.menu_addonPrefs_id);
element_addonPrefs.addEventListener("popupshowing", self);
} else {
- // Setup the options button/menu in the add-on manager, if it is already open.
- self.setupAddonManager(
- self.getAddonManagerFromWindow(window),
- true
- );
// Add a tabmonitor, to be able to setup the options button/menu in the add-on manager.
self.getTabMail(window).registerTabMonitor(self.tabMonitor);
window[self.uniqueRandomID] = {};
window[self.uniqueRandomID].hasTabMonitor = true;
+ // Setup the options button/menu in the add-on manager, if it is already open.
+ let managerWindow = await self.getAddonManagerFromWindowWaitForLoad(window);
+ self.setupAddonManager(managerWindow, true);
}
},
- onUnloadWindow(window) {
+ onUnloadWindow(window) {
}
});
}
@@ -442,11 +819,11 @@
if (isAppShutdown) {
return; // the application gets unloaded anyway
}
-
+
//remove our entry in the add-on options menu
if (this.pathToOptionsPage) {
for (let window of Services.wm.getEnumerator("mail:3pane")) {
- if (this.getThunderbirdVersion().major < 78) {
+ if (getThunderbirdVersion().major < 78) {
let element_addonPrefs = window.document.getElementById(this.menu_addonPrefs_id);
element_addonPrefs.removeEventListener("popupshowing", this);
// Remove our entry.
@@ -454,19 +831,24 @@
if (entry) entry.remove();
// Do we have to unhide the noPrefsElement?
if (element_addonPrefs.children.length == 1) {
- let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
- noPrefsElem.style.display = "inline";
- }
+ let noPrefsElem = element_addonPrefs.querySelector('[disabled="true"]');
+ noPrefsElem.style.display = "inline";
+ }
} else {
// Remove event listener for addon manager view changes
let managerWindow = this.getAddonManagerFromWindow(window);
- if (managerWindow && managerWindow[this.uniqueRandomID] && managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners) {
+ if (
+ managerWindow &&
+ managerWindow[this.uniqueRandomID] &&
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners
+ ) {
managerWindow.document.removeEventListener("ViewChanged", this);
managerWindow.document.removeEventListener("update", this);
managerWindow.document.removeEventListener("view-loaded", this);
-
+ managerWindow[this.uniqueRandomID].hasAddonManagerEventListeners = false;
+
let cards = this.getCards(managerWindow);
- if (this.getThunderbirdVersion().major < 88) {
+ if (getThunderbirdVersion().major < 88) {
// Remove options menu in 78-87
for (let card of cards) {
let addonOptionsLegacyEntry = card.querySelector(".extension-options-legacy");
@@ -483,13 +865,13 @@
}
}
}
-
+
// Remove tabmonitor
if (window[this.uniqueRandomID].hasTabMonitor) {
this.getTabMail(window).unregisterTabMonitor(this.tabMonitor);
window[this.uniqueRandomID].hasTabMonitor = false;
}
-
+
}
}
// Stop listening for new windows.
@@ -529,3 +911,7 @@
console.log("BootstrapLoader for " + this.extension.id + " unloaded!");
}
};
+
+var BootstrapLoader = getThunderbirdVersion().major < 111
+ ? BootstrapLoader_102
+ : BootstrapLoader_115;
diff -Nru tbsync-4.3/content/api/BootstrapLoader/schema.json tbsync-4.7/content/api/BootstrapLoader/schema.json
--- tbsync-4.3/content/api/BootstrapLoader/schema.json 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/api/BootstrapLoader/schema.json 2023-08-29 20:22:49.000000000 +0000
@@ -35,7 +35,7 @@
"type": "array",
"items": {
"type": "array",
- "items" : {
+ "items": {
"type": "string"
}
},
@@ -58,4 +58,4 @@
}
]
}
-]
+]
\ No newline at end of file
diff -Nru tbsync-4.3/content/manager/accounts.js tbsync-4.7/content/manager/accounts.js
--- tbsync-4.3/content/manager/accounts.js 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/manager/accounts.js 2023-08-29 20:22:49.000000000 +0000
@@ -370,9 +370,9 @@
//add icon (use "install provider" icon, if provider not installed)
let itemType = document.createXULElement("image");
- itemType.setAttribute("width", "16");
- itemType.setAttribute("height", "16");
- itemType.setAttribute("style", "margin: 0px 0px 0px 5px;");
+ //itemType.setAttribute("width", "16");
+ //itemType.setAttribute("height", "16");
+ itemType.setAttribute("style", "margin: 0px 0px 0px 5px; width:16px; height:16px");
newListItem.appendChild(itemType);
//add account name
@@ -382,9 +382,9 @@
//add account status
let itemStatus = document.createXULElement("image");
- itemStatus.setAttribute("width", "16");
- itemStatus.setAttribute("height", "16");
- itemStatus.setAttribute("style", "margin: 0px 5px;");
+ //itemStatus.setAttribute("width", "16");
+ //itemStatus.setAttribute("height", "16");
+ itemStatus.setAttribute("style", "margin: 0px 5px; width:16px; height:16px");
newListItem.appendChild(itemStatus);
accountsList.appendChild(newListItem);
diff -Nru tbsync-4.3/content/manager/accounts.xhtml tbsync-4.7/content/manager/accounts.xhtml
--- tbsync-4.3/content/manager/accounts.xhtml 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/manager/accounts.xhtml 2023-08-29 20:22:49.000000000 +0000
@@ -45,9 +45,9 @@
diff -Nru tbsync-4.3/content/manager/editAccount.js tbsync-4.7/content/manager/editAccount.js
--- tbsync-4.3/content/manager/editAccount.js 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/manager/editAccount.js 2023-08-29 20:22:49.000000000 +0000
@@ -9,7 +9,6 @@
"use strict";
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
-var { OS } =ChromeUtils.import("resource://gre/modules/osfile.jsm");
var { TbSync } = ChromeUtils.import("chrome://tbsync/content/tbsync.jsm");
var tbSyncAccountSettings = {
@@ -104,7 +103,7 @@
document.getElementById('tbsync.accountsettings.frame').hidden = false;
tbSyncAccountSettings.updateFolderList();
- if (OS.Constants.Sys.Name == "Darwin") { //we might need to find a way to detect MacOS like styling, other themes move the header bar into the tabpanel as well
+ if (Services.appinfo.OS == "Darwin") { //we might need to find a way to detect MacOS like styling, other themes move the header bar into the tabpanel as well
document.getElementById('manager.tabpanels').style["padding-top"] = "3ex";
}
},
diff -Nru tbsync-4.3/content/manager/editAccount.xhtml tbsync-4.7/content/manager/editAccount.xhtml
--- tbsync-4.3/content/manager/editAccount.xhtml 2022-10-12 19:40:25.000000000 +0000
+++ tbsync-4.7/content/manager/editAccount.xhtml 2023-08-29 20:22:49.000000000 +0000
@@ -39,11 +39,11 @@
-
+
-
+
@@ -58,8 +58,7 @@
__TBSYNCMSG_manager.tabs.status.resources.intro__