install-button.ts 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. import { FlashState } from "./const";
  2. export class InstallButton extends HTMLElement {
  3. public static isSupported = "serial" in navigator;
  4. public static isAllowed = window.isSecureContext;
  5. private static style = `
  6. button {
  7. position: relative;
  8. cursor: pointer;
  9. font-size: 14px;
  10. padding: 8px 28px;
  11. color: var(--esp-tools-button-text-color, #fff);
  12. background-color: var(--esp-tools-button-color, #03a9f4);
  13. border: none;
  14. border-radius: 4px;
  15. box-shadow: 0 2px 2px 0 rgba(0,0,0,.14), 0 3px 1px -2px rgba(0,0,0,.12), 0 1px 5px 0 rgba(0,0,0,.2);
  16. }
  17. button::before {
  18. content: " ";
  19. position: absolute;
  20. top: 0;
  21. bottom: 0;
  22. left: 0;
  23. right: 0;
  24. opacity: 0.2;
  25. border-radius: 4px;
  26. }
  27. button:hover {
  28. box-shadow: 0 4px 8px 0 rgba(0,0,0,.14), 0 1px 7px 0 rgba(0,0,0,.12), 0 3px 1px -1px rgba(0,0,0,.2);
  29. }
  30. button:hover::before {
  31. background-color: rgba(255,255,255,.8);
  32. }
  33. button:focus {
  34. outline: none;
  35. }
  36. button:focus::before {
  37. background-color: white;
  38. }
  39. button:active::before {
  40. background-color: grey;
  41. }
  42. :host([active]) button {
  43. color: rgba(0, 0, 0, 0.38);
  44. background-color: rgba(0, 0, 0, 0.12);
  45. box-shadow: none;
  46. cursor: unset;
  47. pointer-events: none;
  48. }
  49. improv-wifi-launch-button {
  50. display: block;
  51. margin-top: 16px;
  52. }
  53. .hidden {
  54. display: none;
  55. }`;
  56. public manifest?: string;
  57. public eraseFirst?: boolean;
  58. public hideProgress?: boolean;
  59. public showLog?: boolean;
  60. public logConsole?: boolean;
  61. public state?: FlashState;
  62. public renderRoot?: ShadowRoot;
  63. public static preload() {
  64. import("./start-flash");
  65. }
  66. public connectedCallback() {
  67. if (this.renderRoot) {
  68. return;
  69. }
  70. this.renderRoot = this.attachShadow({ mode: "open" });
  71. if (!InstallButton.isSupported || !InstallButton.isAllowed) {
  72. this.toggleAttribute("install-unsupported", true);
  73. this.renderRoot.innerHTML = !InstallButton.isSupported
  74. ? "<slot name='unsupported'>Your browser does not support installing things on ESP devices. Use Google Chrome or Microsoft Edge.</slot>"
  75. : "<slot name='not-allowed'>You can only install ESP devices on HTTPS websites or on the localhost.</slot>";
  76. return;
  77. }
  78. this.toggleAttribute("install-supported", true);
  79. this.addEventListener("mouseover", InstallButton.preload);
  80. const slot = document.createElement("slot");
  81. slot.addEventListener("click", async (ev) => {
  82. ev.preventDefault();
  83. const mod = await import("./start-flash");
  84. mod.startFlash(this);
  85. });
  86. slot.name = "activate";
  87. const button = document.createElement("button");
  88. button.innerText = "INSTALL";
  89. slot.append(button);
  90. if (
  91. "adoptedStyleSheets" in Document.prototype &&
  92. "replaceSync" in CSSStyleSheet.prototype
  93. ) {
  94. const sheet = new CSSStyleSheet();
  95. // @ts-expect-error
  96. sheet.replaceSync(InstallButton.style);
  97. // @ts-expect-error
  98. this.renderRoot.adoptedStyleSheets = [sheet];
  99. } else {
  100. const styleSheet = document.createElement("style");
  101. styleSheet.innerText = InstallButton.style;
  102. this.renderRoot.append(styleSheet);
  103. }
  104. this.renderRoot.append(slot);
  105. }
  106. }
  107. customElements.define("esp-web-install-button", InstallButton);