infobar.js 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146
  1. /*
  2. * Copyright 2018 Gildas Lormeau
  3. * contact : gildas.lormeau <at> gmail.com
  4. *
  5. * This file is part of SingleFile.
  6. *
  7. * SingleFile is free software: you can redistribute it and/or modify
  8. * it under the terms of the GNU Lesser General Public License as published by
  9. * the Free Software Foundation, either version 3 of the License, or
  10. * (at your option) any later version.
  11. *
  12. * SingleFile 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
  15. * GNU Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public License
  18. * along with SingleFile. If not, see <http://www.gnu.org/licenses/>.
  19. */
  20. /* global browser, document, Node, window, top, getComputedStyle */
  21. this.singlefile.infobar = this.singlefile.infobar || (() => {
  22. const INFOBAR_TAGNAME = "singlefile-infobar";
  23. const LINK_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAABmJLR0QABQDuAACS38mlAAAACXBIWXMAACfuAAAn7gExzuVDAAAAB3RJTUUH4ggCDDcMnYqGGAAAATtJREFUOMvNk19LwlAYxp+zhOoqpxJ1la3patFVINk/oRDBLuyreiPFMmcj/QQRSOOwpEINDCpwRr7d1HBMc4sufO7Oe877e5/zcA4wbWLDi8urGr2+vXsOFfJZdnPboDtuueoRcQEH6RQDgNBP8bxcpfvmA0QxPHF6u/MMInLVHFDP7kMUwyjks2xU8+ZGkgGAbtSp1e5gRhBc+0KQHHSjTg2TY0tVEItF/wYqV6+pYXKoiox0atvjOuQXYnILqiJj/ztceXUlGEirGGRyC0pCciDDmfm6mlYxiFtNKAkJmb0dV2OxpFGxpNFE0NmFTtxqQpbiHsgojQX1bBuyFMfR4S7zk+PYjE5PcizI0xD+6685jubnZvH41MJwgL+p233B8tKiF7SeXMPnYIB+/8OXg2hERO44wzC1+gJYGGpVbtoqiAAAAABJRU5ErkJggg==";
  24. const SINGLEFILE_COMMENT = "Archive processed by SingleFile";
  25. if (window == top) {
  26. document.addEventListener("DOMContentLoaded", async () => {
  27. const singleFileComment = document.documentElement.childNodes[0];
  28. if (singleFileComment.nodeType == Node.COMMENT_NODE && singleFileComment.textContent.includes(SINGLEFILE_COMMENT)) {
  29. const info = singleFileComment.textContent.split("\n");
  30. const [, , url, saveDate] = info;
  31. const config = await browser.runtime.sendMessage({ getConfig: true });
  32. if (config.displayInfobar) {
  33. initInfobar(url, saveDate);
  34. }
  35. }
  36. });
  37. }
  38. return true;
  39. function initInfobar(url, saveDate) {
  40. let infobarElement = document.querySelector(INFOBAR_TAGNAME);
  41. if (!infobarElement) {
  42. infobarElement = createElement(INFOBAR_TAGNAME, document.body);
  43. infobarElement.style.setProperty("background-color", "#f9f9f9", "important");
  44. infobarElement.style.setProperty("color", "#9aa0a6", "important");
  45. infobarElement.style.setProperty("display", "block", "important");
  46. infobarElement.style.setProperty("position", "fixed", "important");
  47. infobarElement.style.setProperty("top", "16px", "important");
  48. infobarElement.style.setProperty("right", "16px", "important");
  49. infobarElement.style.setProperty("height", "auto", "important");
  50. infobarElement.style.setProperty("line-height", "28px", "important");
  51. infobarElement.style.setProperty("border-radius", "16px", "important");
  52. infobarElement.style.setProperty("border", "2px solid #737373", "important");
  53. infobarElement.style.setProperty("-webkit-border-start", "2px solid #737373", "important");
  54. infobarElement.style.setProperty("-webkit-border-before", "2px solid #737373", "important");
  55. infobarElement.style.setProperty("-webkit-border-end", "2px solid #737373", "important");
  56. infobarElement.style.setProperty("-webkit-border-after", "2px solid #737373", "important");
  57. infobarElement.style.setProperty("z-index", 2147483647, "important");
  58. infobarElement.style.setProperty("text-align", "center", "important");
  59. infobarElement.style.setProperty("transition-property", "opacity, padding-left, padding-right, width, background-color, color", "important");
  60. infobarElement.style.setProperty("transition-duration", "250ms", "important");
  61. infobarElement.style.setProperty("font-family", "Arial", "important");
  62. infobarElement.style.setProperty("will-change", "opacity, padding-left, padding-right, width, background-color, color", "important");
  63. const linkElement = createElement("a", infobarElement);
  64. linkElement.style.setProperty("display", "inline-block", "important");
  65. linkElement.style.setProperty("padding-left", "8px", "important");
  66. linkElement.style.setProperty("line-height", "28px", "important");
  67. linkElement.style.setProperty("cursor", "pointer", "important");
  68. linkElement.target = "_blank";
  69. linkElement.rel = "noopener noreferrer";
  70. linkElement.title = "Open original page";
  71. linkElement.href = url.split("url: ")[1];
  72. const imgElement = createElement("img", linkElement);
  73. imgElement.style.setProperty("vertical-align", "middle", "important");
  74. imgElement.style.setProperty("padding-bottom", "2px", "important");
  75. imgElement.style.setProperty("-webkit-padding-after", "2px", "important");
  76. imgElement.style.setProperty("padding-left", "2px", "important");
  77. imgElement.style.setProperty("-webkit-padding-start", "2px", "important");
  78. imgElement.style.setProperty("cursor", "pointer", "important");
  79. imgElement.src = LINK_ICON;
  80. hideInfobar(infobarElement, linkElement, saveDate);
  81. infobarElement.onmouseover = () => infobarElement.style.setProperty("opacity", 1, "important");
  82. document.addEventListener("click", event => {
  83. if (event.button === 0) {
  84. let element = event.target;
  85. while (element && element != infobarElement) {
  86. element = element.parentElement;
  87. }
  88. if (element != infobarElement) {
  89. hideInfobar(infobarElement, linkElement, saveDate);
  90. }
  91. }
  92. });
  93. }
  94. }
  95. function displayInfobar(infobarElement, linkElement, saveDate) {
  96. infobarElement.style.setProperty("font-size", "15px", "important");
  97. infobarElement.style.setProperty("opacity", 1, "important");
  98. infobarElement.style.setProperty("width", "auto", "important");
  99. infobarElement.style.setProperty("background-color", "#f9f9f9", "important");
  100. infobarElement.style.setProperty("cursor", "auto", "important");
  101. infobarElement.style.setProperty("color", "#9aa0a6", "important");
  102. infobarElement.style.setProperty("padding-left", "16px", "important");
  103. infobarElement.style.setProperty("padding-right", "16px", "important");
  104. infobarElement.style.setProperty("-webkit-padding-start", "16px", "important");
  105. infobarElement.style.setProperty("-webkit-padding-end", "16px", "important");
  106. infobarElement.textContent = saveDate.split("saved date: ")[1];
  107. infobarElement.appendChild(linkElement);
  108. infobarElement.onclick = null;
  109. infobarElement.onmouseout = null;
  110. }
  111. function hideInfobar(infobarElement, linkElement, saveDate) {
  112. infobarElement.style.opacity = .7;
  113. infobarElement.onmouseout = () => infobarElement.style.opacity = .7;
  114. infobarElement.style.setProperty("font-size", "24px", "important");
  115. infobarElement.style.setProperty("width", "28px", "important");
  116. infobarElement.style.setProperty("background-color", "#737373", "important");
  117. infobarElement.style.setProperty("cursor", "pointer", "important");
  118. infobarElement.style.setProperty("color", "white", "important");
  119. infobarElement.style.setProperty("padding-left", 0, "important");
  120. infobarElement.style.setProperty("padding-right", 0, "important");
  121. infobarElement.style.setProperty("-webkit-padding-start", 0, "important");
  122. infobarElement.style.setProperty("-webkit-padding-end", 0, "important");
  123. infobarElement.textContent = "ℹ";
  124. infobarElement.onclick = event => {
  125. if (event.button === 0) {
  126. displayInfobar(infobarElement, linkElement, saveDate);
  127. return false;
  128. }
  129. };
  130. }
  131. function createElement(tagName, parentElement) {
  132. const element = document.createElement(tagName);
  133. parentElement.appendChild(element);
  134. Array.from(getComputedStyle(element)).forEach(property => element.style.setProperty(property, "initial", "important"));
  135. return element;
  136. }
  137. })();