ui-pendings.js 6.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /*
  2. * Copyright 2010-2020 Gildas Lormeau
  3. * contact : gildas.lormeau <at> gmail.com
  4. *
  5. * This file is part of SingleFile.
  6. *
  7. * The code in this file is free software: you can redistribute it and/or
  8. * modify it under the terms of the GNU Affero General Public License
  9. * (GNU AGPL) as published by the Free Software Foundation, either version 3
  10. * of the License, or (at your option) any later version.
  11. *
  12. * The code in this file is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero
  15. * General Public License for more details.
  16. *
  17. * As additional permission under GNU AGPL version 3 section 7, you may
  18. * distribute UNMODIFIED VERSIONS OF THIS file without the copy of the GNU
  19. * AGPL normally required by section 4, provided you include this license
  20. * notice and a URL through which recipients can access the Corresponding
  21. * Source.
  22. */
  23. /* global browser, window, document, setInterval, location */
  24. (async () => {
  25. const URLLabel = document.getElementById("URLLabel");
  26. const titleLabel = document.getElementById("titleLabel");
  27. const resultsTable = document.getElementById("resultsTable");
  28. const cancelAllButton = document.getElementById("cancelAllButton");
  29. const addUrlsButton = document.getElementById("addUrlsButton");
  30. const addUrlsInput = document.getElementById("addUrlsInput");
  31. const addUrlsCancelButton = document.getElementById("addUrlsCancelButton");
  32. const addUrlsOKButton = document.getElementById("addUrlsOKButton");
  33. document.title = browser.i18n.getMessage("pendingsTitle");
  34. cancelAllButton.textContent = browser.i18n.getMessage("pendingsCancelAllButton");
  35. addUrlsButton.textContent = browser.i18n.getMessage("pendingsAddUrlsButton");
  36. addUrlsCancelButton.textContent = browser.i18n.getMessage("pendingsAddUrlsCancelButton");
  37. addUrlsOKButton.textContent = browser.i18n.getMessage("pendingsAddUrlsOKButton");
  38. document.getElementById("addUrlsLabel").textContent = browser.i18n.getMessage("pendingsAddUrls");
  39. URLLabel.textContent = browser.i18n.getMessage("pendingsURLTitle");
  40. titleLabel.textContent = browser.i18n.getMessage("pendingsTitleTitle");
  41. document.getElementById("statusLabel").textContent = browser.i18n.getMessage("pendingsStatusTitle");
  42. const statusText = {
  43. pending: browser.i18n.getMessage("pendingsPendingStatus"),
  44. processing: browser.i18n.getMessage("pendingsProcessingStatus"),
  45. cancelling: browser.i18n.getMessage("pendingsCancellingStatus")
  46. };
  47. const noPendingsText = browser.i18n.getMessage("pendingsNoPendings");
  48. cancelAllButton.onclick = async () => {
  49. await browser.runtime.sendMessage({ method: "downloads.cancelAll" });
  50. await refresh();
  51. };
  52. addUrlsButton.onclick = displayAddUrlsPopup;
  53. if (location.href.endsWith("#side-panel")) {
  54. document.documentElement.classList.add("side-panel");
  55. }
  56. let URLDisplayed = true;
  57. document.getElementById("URLTitleLabel").onclick = () => {
  58. URLDisplayed = !URLDisplayed;
  59. refresh(true);
  60. };
  61. let previousState;
  62. setInterval(refresh, 1000);
  63. await refresh();
  64. function resetTable() {
  65. resultsTable.innerHTML = "";
  66. }
  67. function updateTable(results) {
  68. if (results.length) {
  69. results.sort((taskInfo1, taskInfo2) => taskInfo1.index - taskInfo2.index);
  70. results.forEach((taskInfo) => {
  71. const row = document.createElement("div");
  72. const cellURL = document.createElement("span");
  73. const cellStatus = document.createElement("span");
  74. const cellCancel = document.createElement("span");
  75. const buttonCancel = document.createElement("button");
  76. row.className = "result-row";
  77. if (URLDisplayed) {
  78. cellURL.textContent = taskInfo.url;
  79. } else {
  80. cellURL.textContent = taskInfo.title;
  81. }
  82. cellURL.className = "result-url-title";
  83. cellURL.onclick = () => selectTab(taskInfo.tabId);
  84. if (taskInfo.cancelled) {
  85. cellStatus.textContent = statusText.cancelling;
  86. } else {
  87. cellStatus.textContent = statusText[taskInfo.status];
  88. buttonCancel.textContent = "×";
  89. buttonCancel.onclick = () => cancel(taskInfo.id);
  90. cellCancel.appendChild(buttonCancel);
  91. }
  92. cellStatus.className = "result-status";
  93. cellCancel.className = "result-cancel";
  94. row.appendChild(cellURL);
  95. row.appendChild(cellStatus);
  96. row.appendChild(cellCancel);
  97. resultsTable.appendChild(row);
  98. });
  99. }
  100. }
  101. async function cancel(taskId) {
  102. await browser.runtime.sendMessage({ method: "downloads.cancel", taskId });
  103. await refresh();
  104. }
  105. async function selectTab(tabId) {
  106. await browser.runtime.sendMessage({ method: "tabs.activate", tabId });
  107. await refresh();
  108. }
  109. async function displayAddUrlsPopup() {
  110. document.getElementById("formAddUrls").style.setProperty("display", "flex");
  111. document.querySelector("#formAddUrls .popup-content").style.setProperty("align-self", "center");
  112. addUrlsInput.value = "";
  113. addUrlsInput.focus();
  114. document.body.style.setProperty("overflow-y", "hidden");
  115. const urls = await new Promise(resolve => {
  116. addUrlsOKButton.onclick = event => hideAndResolve(event, addUrlsInput.value);
  117. addUrlsCancelButton.onclick = event => hideAndResolve(event);
  118. window.onkeyup = event => {
  119. if (event.key == "Escape") {
  120. hideAndResolve(event);
  121. }
  122. };
  123. function hideAndResolve(event, value = "") {
  124. event.preventDefault();
  125. document.getElementById("formAddUrls").style.setProperty("display", "none");
  126. document.body.style.setProperty("overflow-y", "");
  127. resolve(value.split("\n").map(url => url.trim()).filter(url => url));
  128. }
  129. });
  130. if (urls.length) {
  131. await browser.runtime.sendMessage({ method: "downloads.saveUrls", urls });
  132. }
  133. }
  134. async function refresh(force) {
  135. const results = await browser.runtime.sendMessage({ method: "downloads.getInfo" });
  136. const currentState = JSON.stringify(results);
  137. if (previousState != currentState || force) {
  138. previousState = currentState;
  139. resetTable();
  140. if (URLDisplayed) {
  141. URLLabel.className = "";
  142. titleLabel.className = "unselected";
  143. } else {
  144. URLLabel.className = "unselected";
  145. titleLabel.className = "";
  146. }
  147. updateTable(results);
  148. if (!results.length) {
  149. const row = document.createElement("div");
  150. row.className = "result-row";
  151. const cell = document.createElement("span");
  152. cell.colSpan = 3;
  153. cell.className = "no-result";
  154. cell.textContent = noPendingsText;
  155. row.appendChild(cell);
  156. resultsTable.appendChild(row);
  157. }
  158. }
  159. }
  160. })();