Package: release.debian.org Severity: normal Tags: bookworm User: release.debian....@packages.debian.org Usertags: pu X-Debbugs-Cc: eas4tbs...@packages.debian.org, mechti...@debian.org Control: affects -1 + src:eas4tbsync
[ Reason ]This package is a dependency of the extension tbsync to thunderbird. After thunderbird is updated to version 115.* in bookwork it is necessary to update this extension too.
[ Impact ] Otherwise this extension doesn't work anymore [ Risks ] Only tbsync, dav4tbsync and eas4tbsync are affected and will be updated too [ Checklist ] [X] *all* changes are documented in the d/changelog [X] I reviewed all changes and I approve them [X] attach debdiff against the package in (old)stable [X] the issue is verified as fixed in unstable [ Changes ] There is a new version of dav4tbsync to work with thunderbird 115.x [ Other info ] The output of debdiff (stable vs stable-pu is attached) Tbsync and dav4tbsync are already updated Kind regards to the release team Mechtilde -- Mechtilde Stehmann ## Debian Developer ## PGP encryption welcome ## F0E3 7F3D C87A 4998 2899 39E7 F287 7BBA 141A AD7F
diffstat for eas4tbsync-4.1.5 eas4tbsync-4.7 Makefile | 25 background.js | 2 content/api/BootstrapLoader/CHANGELOG.md | 15 content/api/BootstrapLoader/implementation.js | 676 ++++++++++++++++++++------ content/api/BootstrapLoader/schema.json | 4 content/bootstrap.js | 10 content/includes/calendarsync.js | 13 content/includes/network.js | 25 content/includes/tasksync.js | 32 + content/includes/tools.js | 16 content/manager/createAccount.xhtml | 2 content/provider.js | 21 debian/changelog | 22 debian/control | 4 debian/gbp.conf | 2 manifest.json | 6 16 files changed, 677 insertions(+), 198 deletions(-) diff -Nru eas4tbsync-4.1.5/background.js eas4tbsync-4.7/background.js --- eas4tbsync-4.1.5/background.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/background.js 2023-08-18 16:51:43.000000000 +0200 @@ -16,7 +16,7 @@ let manifest = browser.runtime.getManifest(); browser.notifications.create({ type: "basic", - iconUrl: browser.runtime.getURL("content/skin/sabredav32.png"), + iconUrl: browser.runtime.getURL("content/skin/eas32.png"), title: `${manifest.name}`, message: "Please update Thunderbird to at least 102.3.3 to be able to use this provider.", }); diff -Nru eas4tbsync-4.1.5/content/api/BootstrapLoader/CHANGELOG.md eas4tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md --- eas4tbsync-4.1.5/content/api/BootstrapLoader/CHANGELOG.md 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/api/BootstrapLoader/CHANGELOG.md 2023-08-18 16:51:43.000000000 +0200 @@ -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 eas4tbsync-4.1.5/content/api/BootstrapLoader/implementation.js eas4tbsync-4.7/content/api/BootstrapLoader/implementation.js --- eas4tbsync-4.1.5/content/api/BootstrapLoader/implementation.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/api/BootstrapLoader/implementation.js 2023-08-18 16:51:43.000000000 +0200 @@ -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 (j...@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( - `<menuitem class="menuitem-iconic" id="${id}" image="${icon}" label="${name}" />`) - : event.target.ownerGlobal.MozXULElement.parseXULToFragment( - `<menuitem id="${id}" label="${name}" />`); - + `<menuitem class="menuitem-iconic" id="${id}" image="${icon}" label="${name}" />`) + : event.target.ownerGlobal.MozXULElement.parseXULToFragment( + `<menuitem id="${id}" label="${name}" />`); + 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 eas4tbsync-4.1.5/content/api/BootstrapLoader/schema.json eas4tbsync-4.7/content/api/BootstrapLoader/schema.json --- eas4tbsync-4.1.5/content/api/BootstrapLoader/schema.json 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/api/BootstrapLoader/schema.json 2023-08-18 16:51:43.000000000 +0200 @@ -35,7 +35,7 @@ "type": "array", "items": { "type": "array", - "items" : { + "items": { "type": "string" } }, @@ -58,4 +58,4 @@ } ] } -] +] \ Kein Zeilenumbruch am Dateiende. diff -Nru eas4tbsync-4.1.5/content/bootstrap.js eas4tbsync-4.7/content/bootstrap.js --- eas4tbsync-4.1.5/content/bootstrap.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/bootstrap.js 2023-08-18 16:51:43.000000000 +0200 @@ -32,14 +32,8 @@ Services.obs.addObserver(onInitDoneObserver, "tbsync.observer.initialized", false); - // The startup of TbSync is delayed until all add-ons have called their startup(), - // so all providers have registered the "tbsync.observer.initialized" observer. - // Once TbSync has finished its startup, all providers will be notified (also if - // TbSync itself is restarted) to load themself. - // If this is not startup, we need load manually. - if (reason != APP_STARTUP) { - onInitDoneObserver.observe(); - } + // Did we miss the observer? + onInitDoneObserver.observe(); } function shutdown(data, reason) { diff -Nru eas4tbsync-4.1.5/content/includes/calendarsync.js eas4tbsync-4.7/content/includes/calendarsync.js --- eas4tbsync-4.1.5/content/includes/calendarsync.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/includes/calendarsync.js 2023-08-18 16:51:43.000000000 +0200 @@ -348,11 +348,10 @@ //C can be reconstucted from TB STATUS //O can be reconstructed by looking at the original value, or (if not present) by comparing EAS ownerID with TB ownerID - let countAttendees = {}; - let attendees = item.getAttendees(countAttendees); - //if (!(isException && asversion == "2.5")) { //MeetingStatus is not supported in exceptions in EAS 2.5 + let attendees = item.getAttendees(); + //if (!(isException && asversion == "2.5")) { //MeetingStatus is not supported in exceptions in EAS 2.5 if (!isException) { //Exchange 2010 does not seem to support MeetingStatus at all in exceptions - if (countAttendees == 0) wbxml.atag("MeetingStatus", "0"); + if (attendees.length == 0) wbxml.atag("MeetingStatus", "0"); else { //get owner information let isReceived = false; @@ -369,11 +368,11 @@ } } } - + //Attendees - let TB_responseType = null; + let TB_responseType = null; if (!(isException && asversion == "2.5")) { //attendees are not supported in exceptions in EAS 2.5 - if (countAttendees.value > 0) { + if (attendees.length > 0) { //We should use it instead of countAttendees.value wbxml.otag("Attendees"); for (let attendee of attendees) { wbxml.otag("Attendee"); diff -Nru eas4tbsync-4.1.5/content/includes/network.js eas4tbsync-4.7/content/includes/network.js --- eas4tbsync-4.1.5/content/includes/network.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/includes/network.js 2023-08-18 16:51:43.000000000 +0200 @@ -76,16 +76,15 @@ return null; let config = {}; + let customID = eas.Base.getCustomeOauthClientID(); switch (host) { case "outlook.office365.com": + case "eas.outlook.com": config = { auth_uri : "https://login.microsoftonline.com/common/oauth2/v2.0/authorize", token_uri : "https://login.microsoftonline.com/common/oauth2/v2.0/token", redirect_uri : "https://login.microsoftonline.com/common/oauth2/nativeclient", - // changed in beta 1.14.1, according to - // https://docs.microsoft.com/en-us/azure/active-directory/develop/v2-permissions-and-consent#default-and-consent - scope : "offline_access https://outlook.office.com/.default", //"offline_access https://outlook.office.com/EAS.AccessAsUser.All", - client_id : "2980deeb-7460-4723-864a-f9b0f10cd992", + client_id : customID != "" ? customID : "2980deeb-7460-4723-864a-f9b0f10cd992", } break; @@ -93,7 +92,21 @@ return null; } - let oauth = new OAuth2(config.auth_uri, config.token_uri, config.scope, config.client_id, config.client_secret); + switch (host) { + case "outlook.office365.com": + config.scope = "offline_access https://outlook.office.com/.default"; + break; + case "eas.outlook.com": + config.scope = "offline_access https://outlook.office.com/EAS.AccessAsUser.All"; + break; + } + + let oauth = new OAuth2(config.scope, { + authorizationEndpoint: config.auth_uri, + tokenEndpoint: config.token_uri, + clientId: config.client_id, + clientSecret: config.client_secret + }); oauth.requestWindowFeatures = "chrome,private,centerscreen,width=500,height=750"; // The v2 redirection endpoint differs from the default and needs manual override @@ -691,7 +704,7 @@ wbxml.otag("Set"); wbxml.atag("Model", "Computer"); wbxml.atag("FriendlyName", "TbSync on Device " + syncData.accountData.getAccountProperty("deviceId").substring(4)); - wbxml.atag("OS", OS.Constants.Sys.Name); + wbxml.atag("OS", Services.appinfo.OS); wbxml.atag("UserAgent", syncData.accountData.getAccountProperty("useragent")); wbxml.ctag(); wbxml.ctag(); diff -Nru eas4tbsync-4.1.5/content/includes/tasksync.js eas4tbsync-4.7/content/includes/tasksync.js --- eas4tbsync-4.1.5/content/includes/tasksync.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/includes/tasksync.js 2023-08-18 16:51:43.000000000 +0200 @@ -73,14 +73,38 @@ eas.sync.mapEasPropertyToThunderbird ("Sensitivity", "CLASS", data, item); eas.sync.mapEasPropertyToThunderbird ("Importance", "PRIORITY", data, item); + let msTodoCompat = eas.prefs.getBoolPref("msTodoCompat"); + item.clearAlarms(); - if (data.ReminderSet && data.ReminderTime && data.UtcStartDate) { - let UtcDate = eas.tools.createDateTime(data.UtcStartDate); + if (data.ReminderSet && data.ReminderTime) { let UtcAlarmDate = eas.tools.createDateTime(data.ReminderTime); let alarm = new CalAlarm(); - alarm.related = Components.interfaces.calIAlarm.ALARM_RELATED_START; //TB saves new alarms as offsets, so we add them as such as well - alarm.offset = UtcAlarmDate.subtractDate(UtcDate); alarm.action = "DISPLAY"; + + if (msTodoCompat) + { + // Microsoft To-Do only uses due dates (no start dates) an doesn't have a time part in the due date + // dirty hack: Use the reminder date as due date and set a reminder exactly to the due date + // drawback: only works if due date and reminder is set to the same day - this could maybe checked here but I don't know how + item.entryDate = UtcAlarmDate; + item.dueDate = UtcAlarmDate; + alarm.related = Components.interfaces.calIAlarm.ALARM_RELATED_START; + alarm.offset = TbSync.lightning.cal.createDuration(); + alarm.offset.inSeconds = 0; + } + else if (data.UtcStartDate) + { + let UtcDate = eas.tools.createDateTime(data.UtcStartDate); + alarm.related = Components.interfaces.calIAlarm.ALARM_RELATED_START; + alarm.offset = UtcAlarmDate.subtractDate(UtcDate); + } + else + { + // Alternative solution for Microsoft To-Do: + // alarm correctly set but because time part of due date is always "0:00", all tasks for today are shown as overdue + alarm.related = Components.interfaces.calIAlarm.ALARM_RELATED_ABSOLUTE; + alarm.alarmDate = UtcAlarmDate; + } item.addAlarm(alarm); } diff -Nru eas4tbsync-4.1.5/content/includes/tools.js eas4tbsync-4.7/content/includes/tools.js --- eas4tbsync-4.1.5/content/includes/tools.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/includes/tools.js 2023-08-18 16:51:43.000000000 +0200 @@ -303,10 +303,8 @@ if (test.timezoneOffset/-60 == curOffset) return test.timezone; //third try all others - let enumerator = tzService.timezoneIds; - while (enumerator.hasMore()) { - let id = enumerator.getNext(); - let test = utcDateTime.getInTimezone(tzService.getTimezone(id)); + for (let timezoneId of tzService.timezoneIds) { + let test = utcDateTime.getInTimezone(tzService.getTimezone(timezoneId)); TbSync.dump("Matching TZ via current offset: " + test.timezone.tzid + " @ " + curOffset, test.timezoneOffset/-60); if (test.timezoneOffset/-60 == curOffset) return test.timezone; } @@ -334,17 +332,15 @@ let tzService = TbSync.lightning.cal.timezoneService; //cache timezones data from internal IANA data - let enumerator = tzService.timezoneIds; - while (enumerator.hasMore()) { - let id = enumerator.getNext(); - let timezone = tzService.getTimezone(id); + for (let timezoneId of tzService.timezoneIds) { + let timezone = tzService.getTimezone(timezoneId); let tzInfo = eas.tools.getTimezoneInfo(timezone); eas.cachedTimezoneData.bothOffsets[tzInfo.std.offset+":"+tzInfo.dst.offset] = timezone; eas.cachedTimezoneData.stdOffset[tzInfo.std.offset] = timezone; - eas.cachedTimezoneData.abbreviations[tzInfo.std.abbreviation] = id; - eas.cachedTimezoneData.iana[id] = tzInfo; + eas.cachedTimezoneData.abbreviations[tzInfo.std.abbreviation] = timezoneId; + eas.cachedTimezoneData.iana[timezoneId] = tzInfo; //TbSync.dump("TZ ("+ tzInfo.std.id + " :: " + tzInfo.dst.id + " :: " + tzInfo.std.displayname + " :: " + tzInfo.dst.displayname + " :: " + tzInfo.std.offset + " :: " + tzInfo.dst.offset + ")", tzService.getTimezone(id)); } diff -Nru eas4tbsync-4.1.5/content/manager/createAccount.xhtml eas4tbsync-4.7/content/manager/createAccount.xhtml --- eas4tbsync-4.1.5/content/manager/createAccount.xhtml 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/manager/createAccount.xhtml 2023-08-18 16:51:43.000000000 +0200 @@ -2,8 +2,6 @@ <?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?> <window - width="500" - height="600" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" xmlns:html="http://www.w3.org/1999/xhtml" onload="tbSyncEasNewAccount.onLoad();" diff -Nru eas4tbsync-4.1.5/content/provider.js eas4tbsync-4.7/content/provider.js --- eas4tbsync-4.1.5/content/provider.js 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/content/provider.js 2023-08-18 16:51:43.000000000 +0200 @@ -38,8 +38,10 @@ let branch = Services.prefs.getDefaultBranch("extensions.eas4tbsync."); branch.setIntPref("timeout", 90000); branch.setIntPref("maxitems", 50); + branch.setBoolPref("msTodoCompat", false); branch.setCharPref("clientID.type", "TbSync"); branch.setCharPref("clientID.useragent", "Thunderbird ActiveSync"); + branch.setCharPref("oauth.clientID", ""); eas.defaultTimezone = null; eas.utcTimezone = null; @@ -102,18 +104,15 @@ } let tzService = TbSync.lightning.cal.timezoneService; - let enumerator = tzService.timezoneIds; - while (enumerator.hasMore()) { - let id = enumerator.getNext(); - if (!eas.ianaToWindowsTimezoneMap[id]) { - TbSync.eventlog.add("info", eventLogInfo, "The IANA timezone <"+id+"> cannot be mapped to any Exchange timezone."); + for (let timezoneId of tzService.timezoneIds) { + if (!eas.ianaToWindowsTimezoneMap[timezoneId]) { + TbSync.eventlog.add("info", eventLogInfo, "The IANA timezone <"+timezoneId+"> cannot be mapped to any Exchange timezone."); } } - //If an EAS calendar is currently NOT associated with an email identity, try to associate, //but do not change any explicitly set association - // - A) find email identity and accociate (which sets organizer to that user identity) + // - A) find email identity and associate (which sets organizer to that user identity) // - B) overwrite default organizer with current best guess //TODO: Do this after email accounts changed, not only on restart? let providerData = new TbSync.ProviderData("eas"); @@ -440,6 +439,14 @@ // Fall through, if there was no error. return new TbSync.StatusData(); } + + + /** + * Return the custom OAuth2 ClientID. + */ + static getCustomeOauthClientID() { + return eas.prefs.getCharPref("oauth.clientID"); + } } diff -Nru eas4tbsync-4.1.5/debian/changelog eas4tbsync-4.7/debian/changelog --- eas4tbsync-4.1.5/debian/changelog 2022-10-14 13:46:15.000000000 +0200 +++ eas4tbsync-4.7/debian/changelog 2023-10-22 12:57:50.000000000 +0200 @@ -1,3 +1,25 @@ +eas4tbsync (4.7-1~deb12u1) bookworm; urgency=medium + + * [4af7393] Adjust version of dependencies + * Prepared for release in bookworm (proposed-updates) + + -- Mechtilde Stehmann <mechti...@debian.org> Sun, 22 Oct 2023 12:57:50 +0200 + +eas4tbsync (4.7-1) unstable; urgency=medium + + * [a18dc06] Changed compression for tar.gz + * [4286976] New upstream version 4.7 + * Removed double entries in the version before + + -- Mechtilde Stehmann <mechti...@debian.org> Tue, 12 Sep 2023 20:12:53 +0200 + +eas4tbsync (4.1.5+git20230524+c788967-1) experimental; urgency=medium + + * [976c125] Changed compression for using zip file + * [b9b95cd] New upstream version 4.1.5+git20230524+c788967 + + -- Mechtilde Stehmann <mechti...@debian.org> Sat, 29 Jul 2023 20:48:42 +0200 + eas4tbsync (4.1.5-1) unstable; urgency=medium * [dc50cf2] New upstream version 4.1.5 diff -Nru eas4tbsync-4.1.5/debian/control eas4tbsync-4.7/debian/control --- eas4tbsync-4.1.5/debian/control 2022-09-24 13:33:37.000000000 +0200 +++ eas4tbsync-4.7/debian/control 2023-10-22 12:47:25.000000000 +0200 @@ -15,8 +15,8 @@ Package: webext-eas4tbsync Architecture: all Depends: ${misc:Depends} - , thunderbird (>= 1:102.2) - , webext-tbsync (>= 4.0) + , thunderbird (>= 1:115.3) + , webext-tbsync (>= 4.7) Description: Provide Exchange ActiveSync (EAS v2.5 & v14.0) synchronization capabilities The Exchange ActiveSync provider for TbSync to sync contacts, tasks and calendars to Thunderbird. diff -Nru eas4tbsync-4.1.5/debian/gbp.conf eas4tbsync-4.7/debian/gbp.conf --- eas4tbsync-4.1.5/debian/gbp.conf 2022-09-24 10:34:50.000000000 +0200 +++ eas4tbsync-4.7/debian/gbp.conf 2023-09-12 20:07:05.000000000 +0200 @@ -4,7 +4,7 @@ # use pristine-tar: pristine-tar = True # generate gz compressed orig file -compression = gz +# compression = xz debian-branch = debian/sid upstream-branch = upstream diff -Nru eas4tbsync-4.1.5/Makefile eas4tbsync-4.7/Makefile --- eas4tbsync-4.1.5/Makefile 1970-01-01 01:00:00.000000000 +0100 +++ eas4tbsync-4.7/Makefile 2023-08-18 16:51:43.000000000 +0200 @@ -0,0 +1,25 @@ +# This file is part of EAS-4-TbSync. +# +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. + +PACKAGE_NAME=EAS-4-TbSync + +ARCHIVE_NAME=$(PACKAGE_NAME).xpi + +PACKAGE_FILES= \ + content \ + _locales \ + manifest.json \ + CONTRIBUTORS.md \ + LICENSE README.md \ + background.js + +all: clean $(PACKAGE_FILES) + zip -r $(ARCHIVE_NAME) $(PACKAGE_FILES) + +clean: + rm -f $(ARCHIVE_NAME) + +.PHONY: clean diff -Nru eas4tbsync-4.1.5/manifest.json eas4tbsync-4.7/manifest.json --- eas4tbsync-4.1.5/manifest.json 2022-10-13 11:05:56.000000000 +0200 +++ eas4tbsync-4.7/manifest.json 2023-08-18 16:51:43.000000000 +0200 @@ -2,13 +2,13 @@ "applications": { "gecko": { "id": "eas4tbs...@jobisoft.de", - "strict_min_version": "102.3.0", - "strict_max_version": "102.*" + "strict_min_version": "102.7.0", + "strict_max_version": "115.*" } }, "manifest_version": 2, "name": "__MSG_extensionName__", - "version": "4.1.5", + "version": "4.7", "author": "John Bieling", "homepage_url": "https://github.com/jobisoft/EAS-4-TbSync/", "default_locale": "en-US",
OpenPGP_signature.asc
Description: OpenPGP digital signature