infobar.js 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129
  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 */
  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);
  43. infobarElement.style.display = "block";
  44. infobarElement.style.fontSize = "15px";
  45. infobarElement.style.color = "#9aa0a6";
  46. infobarElement.style.position = "fixed";
  47. infobarElement.style.top = "16px";
  48. infobarElement.style.right = "16px";
  49. infobarElement.style.height = "auto";
  50. infobarElement.style.width = "36px";
  51. infobarElement.style.lineHeight = "28px";
  52. infobarElement.style.borderRadius = "16px";
  53. infobarElement.style.border = infobarElement.style["-webkit-border-start"] = infobarElement.style["-webkit-border-end"] = infobarElement.style["-webkit-border-before"] = infobarElement.style["-webkit-border-after"] = "2px solid #737373";
  54. infobarElement.style.zIndex = 2147483647;
  55. infobarElement.style.textAlign = "center";
  56. infobarElement.style.transition = "all 250ms";
  57. infobarElement.style.fontFamily = "Arial";
  58. infobarElement.style.willChange = "opacity, padding-left, padding-right, width, background-color";
  59. const linkElement = createElement("a");
  60. linkElement.style.display = "inline-block";
  61. linkElement.style.paddingLeft = "8px";
  62. linkElement.style.lineHeight = "28px";
  63. linkElement.style.cursor = "pointer";
  64. linkElement.target = "_blank";
  65. linkElement.rel = "noopener noreferrer";
  66. linkElement.title = "Open original page";
  67. linkElement.href = url.split("url: ")[1];
  68. const imgElement = createElement("img");
  69. imgElement.style.verticalAlign = "middle";
  70. imgElement.style.paddingBottom = imgElement.style["-webkit-padding-after"] = "2px";
  71. imgElement.style.paddingLeft = imgElement.style["-webkit-padding-start"] = "2px";
  72. imgElement.src = LINK_ICON;
  73. linkElement.appendChild(imgElement);
  74. hideInfobar(infobarElement, linkElement, saveDate);
  75. infobarElement.onmouseover = () => infobarElement.style.opacity = 1;
  76. document.body.appendChild(infobarElement);
  77. document.addEventListener("click", event => {
  78. let element = event.target;
  79. while (element && element != infobarElement) {
  80. element = element.parentElement;
  81. }
  82. if (element != infobarElement) {
  83. hideInfobar(infobarElement, linkElement, saveDate);
  84. }
  85. });
  86. }
  87. }
  88. function displayInfobar(infobarElement, linkElement, saveDate) {
  89. infobarElement.style.opacity = 1;
  90. infobarElement.onmouseout = null;
  91. infobarElement.style.paddingLeft = infobarElement.style.paddingRight = infobarElement.style["-webkit-padding-end"] = infobarElement.style["-webkit-padding-start"] = "16px";
  92. infobarElement.textContent = saveDate.split("saved date: ")[1];
  93. infobarElement.style.width = "auto";
  94. infobarElement.style.backgroundColor = "#f9f9f9";
  95. infobarElement.style.cursor = "auto";
  96. infobarElement.appendChild(linkElement);
  97. infobarElement.onclick = null;
  98. }
  99. function hideInfobar(infobarElement, linkElement, saveDate) {
  100. infobarElement.style.opacity = .7;
  101. infobarElement.onmouseout = () => infobarElement.style.opacity = .7;
  102. infobarElement.style.paddingLeft = infobarElement.style.paddingRight = infobarElement.style["-webkit-padding-end"] = infobarElement.style["-webkit-padding-start"] = "0px";
  103. infobarElement.style.width = "28px";
  104. infobarElement.style.backgroundColor = "#737373";
  105. infobarElement.style.cursor = "pointer";
  106. infobarElement.textContent = "❔";
  107. infobarElement.onclick = event => {
  108. if (event.button === 0) {
  109. displayInfobar(infobarElement, linkElement, saveDate);
  110. return false;
  111. }
  112. };
  113. }
  114. function createElement(tagName) {
  115. const element = document.createElement(tagName);
  116. Object.keys(element.style).forEach(property => element.style[property] = "initial");
  117. // element.style.all == "initial";
  118. return element;
  119. }
  120. })();