content-error.js 5.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  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 document, globalThis, getComputedStyle */
  24. const singlefile = globalThis.singlefile;
  25. const CLOSE_ICON = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAEAAAABACAYAAACqaXHeAAABhmlDQ1BJQ0MgcHJvZmlsZQAAKJF9kT1Iw0AYht+mSlUqHewg4hChOogFURFHqWIRLJS2QqsOJpf+CE0akhQXR8G14ODPYtXBxVlXB1dBEPwBcXNzUnSREr9LCi1ivOO4h/e+9+XuO0Col5lqdowDqmYZqXhMzOZWxMAruhGiOYohiZl6Ir2Qgef4uoeP73dRnuVd9+foVfImA3wi8SzTDYt4nXh609I57xOHWUlSiM+Jxwy6IPEj12WX3zgXHRZ4ZtjIpOaIw8RisY3lNmYlQyWeIo4oqkb5QtZlhfMWZ7VcZc178hcG89pymuu0BhHHIhJIQoSMKjZQhoUo7RopJlJ0HvPwDzj+JLlkcm2AkWMeFaiQHD/4H/zurVmYnHCTgjGg88W2P4aBwC7QqNn297FtN04A/zNwpbX8lTow80l6raVFjoDQNnBx3dLkPeByB+h/0iVDciQ/LaFQAN7P6JtyQN8t0LPq9q15jtMHIEO9WroBDg6BkSJlr3m8u6u9b//WNPv3A6mTcr3f/E/sAAAABmJLR0QAigCKAIrj2uckAAAACXBIWXMAAC4jAAAuIwF4pT92AAAAB3RJTUUH5QkPDysvCdPVuwAAABl0RVh0Q29tbWVudABDcmVhdGVkIHdpdGggR0lNUFeBDhcAAAELSURBVHja7ZpLFsIwDAPj3v/OsGHDe1BIa8tKO7Mnlkw+dpoxAAAAAGCfx4ur6Yx/B337UUS4mp/VuWUEcjSfOgO+BXCZCWe0hSqQo/npBLglIUNLdAV2MH84Ad1JyIwdLkK6YoabIHWscBWmihHuAqvHtv+XqmdXOK9TxdKy3axUm2vZkXXGgPJksTuz1bVFeeU2Y6ijsLIpXbtKa1kDs2ews69o7+A+ihJ2lvI+/lcS1G21zUVG18XKNm4OS4BNkGOQQohSmGaIdpgLESvzyiRwKepsXjE2H0ZWMF8Zi4+jK5mviM0DiRXNZ2rhkdTK5jO0xermz2o8dCnq+FS2XNNVH0sDAAAA3JYnre9cH8BZmhEAAAAASUVORK5CYII=";
  26. const SINGLE_FILE_UI_ELEMENT_CLASS = singlefile.helper.SINGLE_FILE_UI_ELEMENT_CLASS;
  27. const ERROR_BAR_TAGNAME = "singlefile-error-bar";
  28. const CSS_PROPERTIES = new Set(Array.from(getComputedStyle(document.documentElement)));
  29. let errorBarElement;
  30. export {
  31. onError
  32. };
  33. function onError(message, link) {
  34. try {
  35. console.error("SingleFile", message, link); // eslint-disable-line no-console
  36. errorBarElement = document.querySelector(ERROR_BAR_TAGNAME);
  37. if (!errorBarElement) {
  38. errorBarElement = createElement(ERROR_BAR_TAGNAME);
  39. const shadowRoot = errorBarElement.attachShadow({ mode: "open" });
  40. const styleElement = document.createElement("style");
  41. styleElement.textContent = `
  42. .container {
  43. background-color: #ff6c00;
  44. color: white;
  45. display: flex;
  46. position: fixed;
  47. top: 0px;
  48. left: 0px;
  49. right: 0px;
  50. height: auto;
  51. width: auto;
  52. min-height: 24px;
  53. min-width: 24px;
  54. z-index: 2147483647;
  55. margin: 0;
  56. padding: 2px;
  57. font-family: Arial;
  58. }
  59. .text {
  60. flex: 1;
  61. padding-top: 4px;
  62. padding-bottom: 4px;
  63. padding-left: 8px;
  64. }
  65. .close-button {
  66. opacity: .7;
  67. padding-top: 4px;
  68. padding-left: 8px;
  69. padding-right: 8px;
  70. cursor: pointer;
  71. transition: opacity 250ms;
  72. height: 16px;
  73. }
  74. a {
  75. color: #303036;
  76. }
  77. .close-button:hover {
  78. opacity: 1;
  79. }
  80. `;
  81. shadowRoot.appendChild(styleElement);
  82. const containerElement = document.createElement("div");
  83. containerElement.className = "container";
  84. const errorTextElement = document.createElement("span");
  85. errorTextElement.classList.add("text");
  86. const content = message.split("__DOC_LINK__");
  87. errorTextElement.textContent = "SingleFile error: " + content[0];
  88. if (link && content.length == 2) {
  89. const linkElement = document.createElement("a");
  90. linkElement.textContent = link;
  91. linkElement.href = link;
  92. linkElement.target = "_blank";
  93. errorTextElement.appendChild(linkElement);
  94. errorTextElement.appendChild(document.createTextNode(content[1]));
  95. }
  96. containerElement.appendChild(errorTextElement);
  97. const closeElement = document.createElement("img");
  98. closeElement.classList.add("close-button");
  99. containerElement.appendChild(closeElement);
  100. shadowRoot.appendChild(containerElement);
  101. closeElement.src = CLOSE_ICON;
  102. closeElement.onclick = event => {
  103. if (event.button === 0) {
  104. errorBarElement.remove();
  105. }
  106. };
  107. document.body.appendChild(errorBarElement);
  108. }
  109. } catch (error) {
  110. // iignored
  111. }
  112. }
  113. function createElement(tagName, parentElement) {
  114. const element = document.createElement(tagName);
  115. element.className = SINGLE_FILE_UI_ELEMENT_CLASS;
  116. if (parentElement) {
  117. parentElement.appendChild(element);
  118. }
  119. CSS_PROPERTIES.forEach(property => element.style.setProperty(property, "initial", "important"));
  120. return element;
  121. }