diff --git a/src/argo-archive-list.ts b/src/argo-archive-list.ts index bc4a602..09737c5 100644 --- a/src/argo-archive-list.ts +++ b/src/argo-archive-list.ts @@ -59,7 +59,6 @@ export class ArgoArchiveList extends LitElement { height: 100%; } - img.favicon { width: 20px !important; height: 20px !important; diff --git a/src/ext/bg.ts b/src/ext/bg.ts index 658f01e..3e2ade9 100644 --- a/src/ext/bg.ts +++ b/src/ext/bg.ts @@ -4,7 +4,11 @@ import { CollectionLoader } from "@webrecorder/wabac/swlib"; import { listAllMsg } from "../utils"; -import { getLocalOption, removeLocalOption, setLocalOption } from "../localstorage"; +import { + getLocalOption, + removeLocalOption, + setLocalOption, +} from "../localstorage"; // =========================================================================== self.recorders = {}; @@ -63,10 +67,12 @@ chrome.runtime.onConnect.addListener((port) => { } }); - // @ts-expect-error - TS7006 - Parameter 'port' implicitly has an 'any' type. function sidepanelHandler(port) { - if (!port.sender || port.sender.url !== chrome.runtime.getURL("sidepanel.html")) { + if ( + !port.sender || + port.sender.url !== chrome.runtime.getURL("sidepanel.html") + ) { return; } @@ -110,22 +116,29 @@ function sidepanelHandler(port) { autorun = message.autorun; // @ts-expect-error - tabs doesn't have type definitions - chrome.tabs.query({ active: true, currentWindow: true }, async (tabs) => { - for (const tab of tabs) { - if (!isValidUrl(tab.url)) continue; - - // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. - await startRecorder(tab.id, { collId: defaultCollId, port: null, autorun }, tab.url); - } - - port.postMessage({ - type: "status", - recording: true, - autorun, - // @ts-expect-error - defaultCollId implicitly has an 'any' type. - collId: defaultCollId, - }); - }); + chrome.tabs.query( + { active: true, currentWindow: true }, + async (tabs) => { + for (const tab of tabs) { + if (!isValidUrl(tab.url)) continue; + + // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. + await startRecorder( + tab.id, + { collId: defaultCollId, port: null, autorun }, + tab.url, + ); + } + + port.postMessage({ + type: "status", + recording: true, + autorun, + // @ts-expect-error - defaultCollId implicitly has an 'any' type. + collId: defaultCollId, + }); + }, + ); break; } @@ -171,8 +184,6 @@ function sidepanelHandler(port) { self.recorders[tabId].port = null; } }); - - } // =========================================================================== chrome.runtime.onMessage.addListener( @@ -208,7 +219,6 @@ chrome.debugger.onDetach.addListener((tab, reason) => { // @ts-expect-error - TS7006 - Parameter 'tab' implicitly has an 'any' type. chrome.tabs.onActivated.addListener(async ({ tabId }) => { - // @ts-expect-error - TS7034 - Variable 'err' implicitly has type 'any' in some locations where its type cannot be determined. if (sidepanelPort) { sidepanelPort.postMessage({ type: "update" }); @@ -216,12 +226,18 @@ chrome.tabs.onActivated.addListener(async ({ tabId }) => { if (!isRecordingEnabled) return; // @ts-expect-error - chrome doesn't have type definitions - const tab = await new Promise((resolve) => chrome.tabs.get(tabId, resolve)); + const tab = await new Promise((resolve) => + chrome.tabs.get(tabId, resolve), + ); if (!isValidUrl(tab.url)) return; if (!self.recorders[tabId]) { // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. - await startRecorder(tabId, { collId: defaultCollId, port: null, autorun }, tab.url); + await startRecorder( + tabId, + { collId: defaultCollId, port: null, autorun }, + tab.url, + ); } }); @@ -301,7 +317,11 @@ chrome.tabs.onUpdated.addListener((tabId, changeInfo) => { } } } else if (changeInfo.url) { - if (isRecordingEnabled && isValidUrl(changeInfo.url) && !self.recorders[tabId]) { + if ( + isRecordingEnabled && + isValidUrl(changeInfo.url) && + !self.recorders[tabId] + ) { // @ts-expect-error - TS2554 - Expected 2 arguments, but got 3. startRecorder(tabId, { collId: defaultCollId, autorun }, changeInfo.url); return; @@ -363,7 +383,6 @@ async function startRecorder(tabId, opts) { } const { waitForTabUpdate } = opts; - // @ts-expect-error - TS2339 - Property 'running' does not exist on type 'BrowserRecorder'. if (!waitForTabUpdate && !self.recorders[tabId].running) { try { @@ -409,11 +428,14 @@ function isRecording(tabId) { // =========================================================================== // @ts-expect-error - TS7006 - Parameter 'url' implicitly has an 'any' type. function isValidUrl(url) { - return url && (url === "about:blank" || url.startsWith("https:") || url.startsWith("http:")); + return ( + url && + (url === "about:blank" || + url.startsWith("https:") || + url.startsWith("http:")) + ); } - - // =========================================================================== // @ts-expect-error - TS7006 - Parameter 'tabId' implicitly has an 'any' type. async function disableCSPForTab(tabId) { diff --git a/src/ext/browser-recorder.ts b/src/ext/browser-recorder.ts index 45cad0a..abaab74 100644 --- a/src/ext/browser-recorder.ts +++ b/src/ext/browser-recorder.ts @@ -125,7 +125,9 @@ class BrowserRecorder extends Recorder { } if (numOtherRecorders > 0) { - console.log(`closing session, not detaching, ${numOtherRecorders} other recording tab(s) left`); + console.log( + `closing session, not detaching, ${numOtherRecorders} other recording tab(s) left`, + ); return this.sessionClose([]); } else { console.log("detaching debugger, already tabs stopped"); @@ -234,7 +236,9 @@ class BrowserRecorder extends Recorder { this.doUpdateStatus(); } catch (msg) { // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'BrowserRecorder'. - this.failureMsg = chrome.runtime.lastError ? chrome.runtime.lastError.message : msg; + this.failureMsg = chrome.runtime.lastError + ? chrome.runtime.lastError.message + : msg; this.doUpdateStatus(); throw msg; } @@ -371,7 +375,9 @@ class BrowserRecorder extends Recorder { prr.resolve(res); } else { // @ts-expect-error - TS7005 - Variable 'prr' implicitly has an 'any' type. - prr.reject(chrome.runtime.lastError ? chrome.runtime.lastError.message : ""); + prr.reject( + chrome.runtime.lastError ? chrome.runtime.lastError.message : "", + ); } }; diff --git a/src/recorder.ts b/src/recorder.ts index d0cfd5b..f6c0fb0 100644 --- a/src/recorder.ts +++ b/src/recorder.ts @@ -160,7 +160,8 @@ class Recorder { this.archiveCookies = (await getLocalOption("archiveCookies")) === "1"; this.archiveStorage = (await getLocalOption("archiveStorage")) === "1"; this.archiveFlash = (await getLocalOption("archiveFlash")) === "1"; - this.archiveScreenshots = (await getLocalOption("archiveScreenshots")) === "1"; + this.archiveScreenshots = + (await getLocalOption("archiveScreenshots")) === "1"; this.archivePDF = (await getLocalOption("archivePDF")) === "1"; } @@ -943,13 +944,13 @@ class Recorder { // eslint-disable-next-line @typescript-eslint/no-explicit-any async savePDF(pageInfo: any) { // @ts-expect-error: ignore param - await this.send("Emulation.setEmulatedMedia", {type: "screen"}); + await this.send("Emulation.setEmulatedMedia", { type: "screen" }); // @ts-expect-error: ignore param - const resp = await this.send("Page.printToPDF", {printBackground: true}); + const resp = await this.send("Page.printToPDF", { printBackground: true }); // @ts-expect-error: ignore param - await this.send("Emulation.setEmulatedMedia", {type: ""}); + await this.send("Emulation.setEmulatedMedia", { type: "" }); const payload = Buffer.from(resp.data, "base64"); const mime = "application/pdf"; @@ -961,10 +962,13 @@ class Recorder { statusText: "OK", pageId: pageInfo.id, mime, - respHeaders: {"Content-Type": mime, "Content-Length": payload.length + ""}, + respHeaders: { + "Content-Type": mime, + "Content-Length": payload.length + "", + }, reqHeaders: {}, payload, - extraOpts: {resource: true}, + extraOpts: { resource: true }, }; console.log("pdf", payload.length); @@ -975,21 +979,25 @@ class Recorder { // eslint-disable-next-line @typescript-eslint/no-explicit-any async saveScreenshot(pageInfo: any) { - // View Screenshot const width = 1920; const height = 1080; // @ts-expect-error: ignore param - await this.send("Emulation.setDeviceMetricsOverride", {width, height, deviceScaleFactor: 0, mobile: false}); + await this.send("Emulation.setDeviceMetricsOverride", { + width, + height, + deviceScaleFactor: 0, + mobile: false, + }); // @ts-expect-error: ignore param - const resp = await this.send("Page.captureScreenshot", {format: "png"}); + const resp = await this.send("Page.captureScreenshot", { format: "png" }); const payload = Buffer.from(resp.data, "base64"); - const blob = new Blob([payload], {type: "image/png"}); + const blob = new Blob([payload], { type: "image/png" }); await this.send("Emulation.clearDeviceMetricsOverride"); - + const mime = "image/png"; const fullData = { @@ -999,35 +1007,44 @@ class Recorder { statusText: "OK", pageId: pageInfo.id, mime, - respHeaders: {"Content-Type": mime, "Content-Length": payload.length + ""}, + respHeaders: { + "Content-Type": mime, + "Content-Length": payload.length + "", + }, reqHeaders: {}, payload, - extraOpts: {resource: true}, + extraOpts: { resource: true }, }; const thumbWidth = 640; const thumbHeight = 360; - const bitmap = await self.createImageBitmap(blob, {resizeWidth: thumbWidth, resizeHeight: thumbHeight}); - + const bitmap = await self.createImageBitmap(blob, { + resizeWidth: thumbWidth, + resizeHeight: thumbHeight, + }); + const canvas = new OffscreenCanvas(thumbWidth, thumbWidth); const context = canvas.getContext("bitmaprenderer")!; context.transferFromImageBitmap(bitmap); - const resizedBlob = await canvas.convertToBlob({type: "image/png"}); + const resizedBlob = await canvas.convertToBlob({ type: "image/png" }); const thumbPayload = new Uint8Array(await resizedBlob.arrayBuffer()); - const thumbData = {...fullData, + const thumbData = { + ...fullData, url: "urn:thumbnail:" + pageInfo.url, - respHeaders: {"Content-Type": mime, "Content-Length": thumbPayload.length + ""}, - payload: thumbPayload + respHeaders: { + "Content-Type": mime, + "Content-Length": thumbPayload.length + "", + }, + payload: thumbPayload, }; - + // @ts-expect-error - TS2339 - Property '_doAddResource' does not exist on type 'Recorder'. await this._doAddResource(fullData); - // @ts-expect-error - TS2339 - Property '_doAddResource' does not exist on type 'Recorder'. await this._doAddResource(thumbData); } diff --git a/src/sidepanel.ts b/src/sidepanel.ts index bd95d44..a0d606d 100644 --- a/src/sidepanel.ts +++ b/src/sidepanel.ts @@ -1,6 +1,6 @@ import "@material/web/all.js"; import { styles as typescaleStyles } from "@material/web/typography/md-typescale-styles.js"; -import { LitElement, html, css, CSSResultGroup } from "lit"; +import { LitElement, html, css, CSSResultGroup } from "lit"; import { unsafeSVG } from "lit/directives/unsafe-svg.js"; import "./argo-archive-list"; import "@material/web/textfield/outlined-text-field.js"; @@ -8,7 +8,6 @@ import "@material/web/icon/icon.js"; import { ArgoArchiveList } from "./argo-archive-list"; import { Downloader } from "./sw/downloader"; - import wrRec from "./assets/icons/recLogo.svg"; import { @@ -35,17 +34,15 @@ document.adoptedStyleSheets.push(typescaleStyles.styleSheet!); const collLoader = new CollectionLoader(); class ArgoViewer extends LitElement { - static styles: CSSResultGroup = [ typescaleStyles as unknown as CSSResultGroup, css` - md-tabs { - background-color: white; + background-color: white; } .search-container { - margin: 16px 12px; + margin: 16px 12px; height: 32px; background: #ece7f8; border-radius: 9999px; @@ -58,10 +55,9 @@ class ArgoViewer extends LitElement { width: 100%; --md-filled-text-field-container-color: transparent; --md-ref-shape-corner-radius: 9999px; - overflow: hidden; + overflow: hidden; } - .search-field::part(container), .search-field::part(hover-overlay), .search-field::part(focus-overlay) { @@ -75,7 +71,7 @@ class ArgoViewer extends LitElement { .search-field md-icon, .search-field input::placeholder { color: #6b6b6b; - }, + } md-elevated-card { display: block; @@ -127,7 +123,7 @@ class ArgoViewer extends LitElement { border-radius: 4px; filter: drop-shadow(0 0 1px rgba(0, 0, 0, 0.6)); } - ` + `, ]; private archiveList!: ArgoArchiveList; @@ -209,8 +205,8 @@ class ArgoViewer extends LitElement { behaviorMsg: { type: String }, autorun: { type: Boolean }, }; - } - + } + // @ts-expect-error - TS7006 - Parameter 'match' implicitly has an 'any' type. findTitleFor(match) { if (!match) { @@ -581,14 +577,11 @@ class ArgoViewer extends LitElement { return html`
-
- ${this.renderStatus()} -
+
${this.renderStatus()}
`; } - renderStatus() { // @ts-expect-error - TS2339 - Property 'behaviorState' does not exist on type 'ArgoViewer'. @@ -610,47 +603,59 @@ class ArgoViewer extends LitElement { // @ts-expect-error - TS2339 - Property 'favIconUrl' does not exist on type 'ArgoViewer'. this.favIconUrl || // @ts-expect-error - TS2339 - Property 'pageUrl' does not exist on type 'ArgoViewer'. - this.pageTitle ? html` -
- Favicon - ${ - //@ts-expect-error - TS2339 - Property 'pageTitle' does not exist on type 'ArgoViewer'. - truncateString(this.pageTitle) - } -
- ` : "" + this.pageTitle + ? html` +
+ Favicon + ${ + //@ts-expect-error - TS2339 - Property 'pageTitle' does not exist on type 'ArgoViewer'. + truncateString(this.pageTitle) + } +
+ ` + : "" } Status ${ // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. - this.status?.numPending ? html` - - ` : "" + value=${mapIntegerToRange( + // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. + this.status?.numPending || 0, + )} + style="--md-sys-color-primary: #7b1fa2; width: 100%; margin-bottom: 0.5rem;" + > + ` + : "" } ${ // @ts-expect-error - TS2339 - Property 'status' does not exist on type 'ArgoViewer'. | TS2339 - Property 'status' does not exist on type 'ArgoViewer'. !this.status?.numPending - ? html`All resources archived` : "" - }`; + ? html`All resources archived` + : "" + } + `; } // @ts-expect-error - TS2339 - Property 'failureMsg' does not exist on type 'ArgoViewer'. @@ -699,24 +704,21 @@ class ArgoViewer extends LitElement { `; } - return html` - Status -
+ return html` Status +

Can't archive this page.

`; } // @ts-expect-error - TS2339 - Property 'waitingForStart' does not exist on type 'ArgoViewer'. if (this.waitingForStart) { - return html` - Status -
+ return html` Status +

Archiving will start after the page reloads...

`; } - return html` - Status -
-

${this.notRecordingMessage}

`; + return html` Status +
+

${this.notRecordingMessage}

`; } renderSearch() { @@ -737,11 +739,18 @@ class ArgoViewer extends LitElement { renderTabs() { return html` - My Archives - My Shared Archives + My Archives + My Shared Archives -
+
@@ -754,39 +763,40 @@ class ArgoViewer extends LitElement { render() { return html` - ${this.renderSearch()} - ${this.renderStatusCard()} - ${this.renderTabs()} + ${this.renderSearch()} ${this.renderStatusCard()} ${this.renderTabs()}
-
+
${ // @ts-expect-error - TS2339 - Property 'recording' does not exist on type 'ArgoViewer'. !this.recording ? html` - - public - Resume Archiving - - - download - - - - share - + !this.canRecord} + @click=${this.onStart} + > + public + Resume Archiving + + + download + + + + share + ` : html` ${ showEmbed ? ` - ` + ` : ` ` } diff --git a/src/sw/recproxy.ts b/src/sw/recproxy.ts index 3e86acb..415fd69 100644 --- a/src/sw/recproxy.ts +++ b/src/sw/recproxy.ts @@ -97,7 +97,11 @@ export class RecProxy extends ArchiveDB { return await (this.db! as any).get("rec", "numPending"); } - override async getResource(request: ArchiveRequest, prefix: string, event: FetchEvent) { + override async getResource( + request: ArchiveRequest, + prefix: string, + event: FetchEvent, + ) { if (!this.isRecording) { return await super.getResource(request, prefix, event); } @@ -224,7 +228,13 @@ export class RecProxy extends ArchiveDB { } } - isPage(url: string, request: Request, status: number, referrer: string, mod: string) { + isPage( + url: string, + request: Request, + status: number, + referrer: string, + mod: string, + ) { if (!this.isNew) { return false; } @@ -259,7 +269,9 @@ export class RecProxy extends ArchiveDB { if (!pageId) { return; } - const page = await this.db!.get("pages", pageId) as ExtPageEntry | undefined; + const page = (await this.db!.get("pages", pageId)) as + | ExtPageEntry + | undefined; if (!page) { return; } @@ -311,7 +323,6 @@ export class RecordingCollections extends SWCollections { } break; - default: return await super._handleMessage(event); } diff --git a/src/utils.ts b/src/utils.ts index 0f6500d..050b80d 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -63,7 +63,6 @@ export async function listAllMsg(collLoader, { defaultCollId = null } = {}) { return msg; } - export function mapIntegerToRange(integer: number) { // Calculate distance from 0 (use absolute value for negative numbers) const distance = Math.abs(integer); @@ -88,4 +87,4 @@ export function truncateString(str: string) { // Otherwise, truncate to maxLength - 3 characters and add "..." // This ensures the total length (including "...") doesn't exceed maxLength return str.substring(0, maxLength - 3) + "..."; -} \ No newline at end of file +}