Runs in the page before any app script, on every top-level document.
()
| 16 | |
| 17 | /** Runs in the page before any app script, on every top-level document. */ |
| 18 | function injectUrlBar(): void { |
| 19 | // Top frame only (iframes should not each grow their own bar). |
| 20 | if (window.top !== window.self) return; |
| 21 | const flagged = window as Window & { __e2eUrlBar?: boolean }; |
| 22 | if (flagged.__e2eUrlBar) return; |
| 23 | flagged.__e2eUrlBar = true; |
| 24 | |
| 25 | const BAR_H = 32; |
| 26 | |
| 27 | const install = (): void => { |
| 28 | const root = document.documentElement; |
| 29 | if (!root) return; |
| 30 | |
| 31 | const host = document.createElement("div"); |
| 32 | host.style.cssText = `position:fixed;top:0;left:0;width:100%;height:${BAR_H}px;z-index:2147483647;pointer-events:none`; |
| 33 | const shadow = host.attachShadow({ mode: "closed" }); |
| 34 | |
| 35 | const bar = document.createElement("div"); |
| 36 | bar.style.cssText = [ |
| 37 | "display:flex", |
| 38 | "align-items:center", |
| 39 | "gap:8px", |
| 40 | `height:${BAR_H}px`, |
| 41 | "box-sizing:border-box", |
| 42 | "padding:0 12px", |
| 43 | "background:#161b22", |
| 44 | "border-bottom:1px solid #21262d", |
| 45 | "font:13px/1 ui-monospace,SFMono-Regular,Menlo,monospace", |
| 46 | "color:#c9d1d9", |
| 47 | "white-space:nowrap", |
| 48 | "overflow:hidden", |
| 49 | ].join(";"); |
| 50 | |
| 51 | const dot = (color: string): HTMLElement => { |
| 52 | const d = document.createElement("span"); |
| 53 | d.style.cssText = `width:11px;height:11px;border-radius:50%;flex:none;background:${color}`; |
| 54 | return d; |
| 55 | }; |
| 56 | const lights = document.createElement("span"); |
| 57 | lights.style.cssText = "display:inline-flex;gap:6px;margin-right:4px"; |
| 58 | lights.append(dot("#ff5f57"), dot("#febc2e"), dot("#28c840")); |
| 59 | |
| 60 | const lock = document.createElement("span"); |
| 61 | lock.textContent = "⌁"; // the viewer's URL-bar glyph |
| 62 | lock.style.cssText = "color:#8b949e;flex:none"; |
| 63 | |
| 64 | const url = document.createElement("span"); |
| 65 | url.style.cssText = "overflow:hidden;text-overflow:ellipsis"; |
| 66 | |
| 67 | bar.append(lights, lock, url); |
| 68 | shadow.append(bar); |
| 69 | root.appendChild(host); |
| 70 | |
| 71 | const render = (): void => { |
| 72 | const next = location.href.replace(/^https?:\/\//, "") || "about:blank"; |
| 73 | if (url.textContent !== next) url.textContent = next; |
| 74 | }; |
| 75 | render(); |