diff --git a/package-lock.json b/package-lock.json index c9da2dc..0ce68d9 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "testpilot-containers", - "version": "8.1.3", + "version": "8.2.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "testpilot-containers", - "version": "8.1.1", + "version": "8.2.0", "license": "MPL-2.0", "devDependencies": { "addons-linter": "^5.28.0", @@ -15032,8 +15032,7 @@ "version": "5.3.2", "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.3.2.tgz", "integrity": "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ==", - "dev": true, - "requires": {} + "dev": true }, "acorn-walk": { "version": "7.2.0", @@ -17246,15 +17245,13 @@ "version": "4.0.2", "resolved": "https://registry.npmjs.org/eslint-plugin-no-unsanitized/-/eslint-plugin-no-unsanitized-4.0.2.tgz", "integrity": "sha512-Pry0S9YmHoz8NCEMRQh7N0Yexh2MYCNPIlrV52hTmS7qXnTghWsjXouF08bgsrrZqaW9tt1ZiK3j5NEmPE+EjQ==", - "dev": true, - "requires": {} + "dev": true }, "eslint-plugin-promise": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/eslint-plugin-promise/-/eslint-plugin-promise-5.2.0.tgz", "integrity": "sha512-SftLb1pUG01QYq2A/hGAWfDRXqYD82zE7j7TopDOyNdU+7SvvoXREls/+PRTY17vUXzXnZA/zfnyKgRH6x4JJw==", - "dev": true, - "requires": {} + "dev": true }, "eslint-scope": { "version": "5.1.1", @@ -19763,8 +19760,7 @@ "version": "7.5.9", "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.9.tgz", "integrity": "sha512-F+P9Jil7UiSKSkppIiD94dN07AwvFixvLIj1Og1Rl9GGMuNipJnV9JzjD6XuqmAeiswGvUmNLjr5cFuXwNS77Q==", - "dev": true, - "requires": {} + "dev": true } } }, @@ -21971,8 +21967,7 @@ "version": "0.36.2", "resolved": "https://registry.npmjs.org/postcss-syntax/-/postcss-syntax-0.36.2.tgz", "integrity": "sha512-nBRg/i7E3SOHWxF3PpF5WnJM/jQ1YpY9000OaVXlAQj6Zp/kIqJxEDWIZ67tAd7NLuk7zqN4yqe9nc0oNAOs1w==", - "dev": true, - "requires": {} + "dev": true }, "postcss-value-parser": { "version": "4.2.0", @@ -22826,8 +22821,7 @@ "version": "3.7.0", "resolved": "https://registry.npmjs.org/sinon-chai/-/sinon-chai-3.7.0.tgz", "integrity": "sha512-mf5NURdUaSdnatJx3uhoBOrY9dtL19fiOtAdT1Azxg3+lNJFiuN0uzaU3xX1LeAfL17kHQhTAJgpsfhbMJMY2g==", - "dev": true, - "requires": {} + "dev": true }, "slash": { "version": "3.0.0", @@ -23571,8 +23565,7 @@ "version": "3.0.0", "resolved": "https://registry.npmjs.org/stylelint-config-recommended/-/stylelint-config-recommended-3.0.0.tgz", "integrity": "sha512-F6yTRuc06xr1h5Qw/ykb2LuFynJ2IxkKfCMf+1xqPffkxh0S09Zc902XCffcsw/XMFq/OzQ1w54fLIDtmRNHnQ==", - "dev": true, - "requires": {} + "dev": true }, "stylelint-config-standard": { "version": "20.0.0", @@ -24946,8 +24939,7 @@ "version": "8.12.0", "resolved": "https://registry.npmjs.org/ws/-/ws-8.12.0.tgz", "integrity": "sha512-kU62emKIdKVeEIOIKVegvqpXMSTAMLJozpHZaJNDYqBjzlSYXQGviYwN1osDLJ9av68qHd4a2oSjd7yD4pacig==", - "dev": true, - "requires": {} + "dev": true }, "xdg-basedir": { "version": "5.1.0", diff --git a/src/js/popup.js b/src/js/popup.js index 61a3fda..a467eb9 100644 --- a/src/js/popup.js +++ b/src/js/popup.js @@ -10,7 +10,6 @@ const DEFAULT_ICON = "circle"; const NEW_CONTAINER_ID = "new"; const ONBOARDING_STORAGE_KEY = "onboarding-stage"; -const CONTAINER_DRAG_DATA_TYPE = "firefox-container"; // List of panels const P_ONBOARDING_1 = "onboarding1"; @@ -129,7 +128,7 @@ const Logic = { notificationCards.forEach(notificationCard => { notificationCard.textContent = text; notificationCard.classList.add("is-shown"); - + setTimeout(() => { notificationCard.classList.remove("is-shown"); }, 2000); @@ -1198,6 +1197,8 @@ Logic.registerPanel(MANAGE_CONTAINERS_PICKER, { const identities = Logic.identities(); + let dataBeingDragged = null; + for (const identity of identities) { const tr = document.createElement("tr"); tr.classList.add("menu-item", "hover-highlight", "keyboard-nav"); @@ -1226,42 +1227,49 @@ Logic.registerPanel(MANAGE_CONTAINERS_PICKER, { tr.appendChild(td); - tr.draggable = true; tr.dataset.containerId = identity.cookieStoreId; - tr.addEventListener("dragstart", (e) => { - e.dataTransfer.setData(CONTAINER_DRAG_DATA_TYPE, identity.cookieStoreId); - }); - tr.addEventListener("dragover", (e) => { - if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) { - tr.classList.add("drag-over"); - e.preventDefault(); + // Note: The draggable API does not appear to work with this extension on KDE. + // Thus we use mouse events instead of drag events. + tr.addEventListener("mousedown", (e) => { + if (e.target.closest(".move-button")) { + dataBeingDragged = identity.cookieStoreId; } }); - tr.addEventListener("dragenter", (e) => { - if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) { - e.preventDefault(); - tr.classList.add("drag-over"); - } + tr.addEventListener("mouseover", () => { + if (dataBeingDragged !== null) tr.classList.add("drag-over"); }); - tr.addEventListener("dragleave", (e) => { - if (e.dataTransfer.types.includes(CONTAINER_DRAG_DATA_TYPE)) { - e.preventDefault(); - tr.classList.remove("drag-over"); - } + tr.addEventListener("mouseleave", () => { + if (dataBeingDragged !== null) tr.classList.remove("drag-over"); }); - tr.addEventListener("drop", async (e) => { - e.preventDefault(); + tr.addEventListener("mouseup", async () => { + if (dataBeingDragged === null) return; const parent = tr.parentNode; - const containerId = e.dataTransfer.getData(CONTAINER_DRAG_DATA_TYPE); + const containerId = dataBeingDragged; + dataBeingDragged = null; let droppedElement; + let dropAfter = false; parent.childNodes.forEach((node) => { + if (node === tr && droppedElement !== undefined) { + // If the element being dropped was before this tr, drop after this tr. + dropAfter = true; + } if (node.dataset.containerId === containerId) { droppedElement = node; } }); if (droppedElement && droppedElement !== tr) { tr.classList.remove("drag-over"); - parent.insertBefore(droppedElement, tr); + if (dropAfter) { + // Drop it after this tr. + const nextSibling = tr.nextSibling; + if (nextSibling) { + parent.insertBefore(droppedElement, nextSibling); + } else { + parent.appendChild(droppedElement); + } + } else { + parent.insertBefore(droppedElement, tr); + } await Logic.saveContainerOrder(parent.childNodes); await Logic.refreshIdentities(); } @@ -2319,7 +2327,7 @@ Logic.registerPanel(P_CLEAR_CONTAINER_STORAGE, { // This method is called when the panel is shown. prepare() { const identity = Logic.currentIdentity(); - + // Populating the panel: name, icon, and warning message document.getElementById("container-clear-storage-title").textContent = identity.name; return Promise.resolve(null);