Cleanup Electron App + Dependency Update (#139)

* electron: clean-up / remove unused code in main process, including:
- remove native plugin init (no longer supported)
- remove auto-js-ipfs (used in render process)
- remove ipfs handling logic (handled in render process)
- use custom file2:// scheme for loading files, instead of custom prefix
- proxyLive supports POST requests, using original UA (if set, for archiveweb.page)
- webpack: remove unused __IPFS_CORE_URL__
- ci: add lint check

* dependency update:
- update to wabac.js 2.13.15 for latest auto-js-ipfs (2.1.0) and wombat (3.3.13)
- update to electron 22.0
- update webpack + electron updater to latest

* bump to 1.7.8
This commit is contained in:
Ilya Kreymer
2022-12-07 13:33:36 -08:00
committed by GitHub
parent 591753d6d8
commit e6f837df13
11 changed files with 931 additions and 887 deletions
+26
View File
@@ -0,0 +1,26 @@
name: Build + Lint
on: push
jobs:
lint:
runs-on: ubuntu-latest
steps:
- name: Check out Git repository
uses: actions/checkout@v2
- name: Install Node.js, NPM and Yarn
uses: actions/setup-node@v3
with:
node-version: 18
cache: 'yarn'
- name: Yarn Install
run: yarn install --frozen-lockfile
- name: Yarn Lint
run: yarn run lint
- name: Yarn Build
run: yarn run build
+9 -8
View File
@@ -1,7 +1,7 @@
{ {
"name": "replaywebpage", "name": "replaywebpage",
"productName": "ReplayWeb.page", "productName": "ReplayWeb.page",
"version": "1.7.7", "version": "1.7.8",
"description": "Serverless Web Archive Replay", "description": "Serverless Web Archive Replay",
"repository": "https://github.com/webrecorder/replayweb.page", "repository": "https://github.com/webrecorder/replayweb.page",
"homepage": "https://replayweb.page/", "homepage": "https://replayweb.page/",
@@ -9,11 +9,10 @@
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@webrecorder/wabac": "^2.13.14", "@webrecorder/wabac": "^2.13.15",
"auto-js-ipfs": "^1.5.1",
"bulma": "^0.9.3", "bulma": "^0.9.3",
"electron-log": "^4.4.1", "electron-log": "^4.4.1",
"electron-updater": "^4.3.9", "electron-updater": "^5.3.0",
"fetch-ndjson": "^1.1.6", "fetch-ndjson": "^1.1.6",
"flexsearch": "^0.7.21", "flexsearch": "^0.7.21",
"keyword-mark-element": "^0.2.0", "keyword-mark-element": "^0.2.0",
@@ -21,6 +20,7 @@
"marked": "^4.0.10", "marked": "^4.0.10",
"mime-types": "^2.1.32", "mime-types": "^2.1.32",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"node-fetch": "^3.3.0",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"process": "^0.11.10", "process": "^0.11.10",
"querystring-es3": "^0.2.1", "querystring-es3": "^0.2.1",
@@ -31,7 +31,7 @@
"devDependencies": { "devDependencies": {
"copy-webpack-plugin": "^9.0.1", "copy-webpack-plugin": "^9.0.1",
"css-loader": "^6.2.0", "css-loader": "^6.2.0",
"electron": "^21.3.1", "electron": "^22.0.0",
"electron-builder": "^23.0.3", "electron-builder": "^23.0.3",
"electron-notarize": "^1.1.1", "electron-notarize": "^1.1.1",
"eslint": "^8.23.1", "eslint": "^8.23.1",
@@ -42,9 +42,10 @@
"sass-loader": "^12.1.0", "sass-loader": "^12.1.0",
"style-loader": "^3.2.1", "style-loader": "^3.2.1",
"svg-inline-loader": "^0.8.2", "svg-inline-loader": "^0.8.2",
"webpack": "^5.74.0", "url": "^0.11.0",
"webpack-cli": "^4.8.0", "webpack": "^5.75.0",
"webpack-dev-server": "^4.2.1" "webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}, },
"files": [ "files": [
"/assets", "/assets",
+9 -8
View File
@@ -1,7 +1,7 @@
{ {
"name": "replaywebpage", "name": "replaywebpage",
"productName": "ReplayWeb.page", "productName": "ReplayWeb.page",
"version": "1.7.7", "version": "1.7.8",
"description": "Serverless Web Archive Replay", "description": "Serverless Web Archive Replay",
"repository": "https://github.com/webrecorder/replayweb.page", "repository": "https://github.com/webrecorder/replayweb.page",
"homepage": "https://replayweb.page/", "homepage": "https://replayweb.page/",
@@ -9,11 +9,10 @@
"license": "AGPL-3.0-or-later", "license": "AGPL-3.0-or-later",
"dependencies": { "dependencies": {
"@fortawesome/fontawesome-free": "^5.15.4", "@fortawesome/fontawesome-free": "^5.15.4",
"@webrecorder/wabac": "^2.13.14", "@webrecorder/wabac": "^2.13.15",
"auto-js-ipfs": "^1.5.1",
"bulma": "^0.9.3", "bulma": "^0.9.3",
"electron-log": "^4.4.1", "electron-log": "^4.4.1",
"electron-updater": "^4.3.9", "electron-updater": "^5.3.0",
"fetch-ndjson": "^1.1.6", "fetch-ndjson": "^1.1.6",
"flexsearch": "^0.7.21", "flexsearch": "^0.7.21",
"keyword-mark-element": "^0.2.0", "keyword-mark-element": "^0.2.0",
@@ -21,6 +20,7 @@
"marked": "^4.0.10", "marked": "^4.0.10",
"mime-types": "^2.1.32", "mime-types": "^2.1.32",
"minimist": "^1.2.5", "minimist": "^1.2.5",
"node-fetch": "^3.3.0",
"pretty-bytes": "^5.6.0", "pretty-bytes": "^5.6.0",
"process": "^0.11.10", "process": "^0.11.10",
"querystring-es3": "^0.2.1", "querystring-es3": "^0.2.1",
@@ -31,7 +31,7 @@
"devDependencies": { "devDependencies": {
"copy-webpack-plugin": "^9.0.1", "copy-webpack-plugin": "^9.0.1",
"css-loader": "^6.2.0", "css-loader": "^6.2.0",
"electron": "^21.3.1", "electron": "^22.0.0",
"electron-builder": "^23.0.3", "electron-builder": "^23.0.3",
"electron-notarize": "^1.1.1", "electron-notarize": "^1.1.1",
"eslint": "^8.23.1", "eslint": "^8.23.1",
@@ -42,9 +42,10 @@
"sass-loader": "^12.1.0", "sass-loader": "^12.1.0",
"style-loader": "^3.2.1", "style-loader": "^3.2.1",
"svg-inline-loader": "^0.8.2", "svg-inline-loader": "^0.8.2",
"webpack": "^5.74.0", "url": "^0.11.0",
"webpack-cli": "^4.8.0", "webpack": "^5.75.0",
"webpack-dev-server": "^4.2.1" "webpack-cli": "^5.0.1",
"webpack-dev-server": "^4.11.1"
}, },
"files": [ "files": [
"/assets", "/assets",
+1 -4
View File
@@ -401,12 +401,9 @@ class ReplayWebApp extends LitElement
} }
if (IS_APP && this.sourceUrl.startsWith("file://")) { if (IS_APP && this.sourceUrl.startsWith("file://")) {
// eslint-disable-next-line no-undef
const url = new URL(__APP_FILE_SERVE_PREFIX__);
url.searchParams.set("filename", this.sourceUrl.slice("file://".length));
this.loadInfo = { this.loadInfo = {
sourceUrl: this.sourceUrl, sourceUrl: this.sourceUrl,
loadUrl: url.href, loadUrl: this.sourceUrl.replace("file://", "file2://")
}; };
} }
} }
+1 -3
View File
@@ -79,9 +79,7 @@ class Chooser extends LitElement
// file.path only available in electron app // file.path only available in electron app
if (this.file.path) { if (this.file.path) {
// eslint-disable-next-line no-undef // eslint-disable-next-line no-undef
const url = new URL(__APP_FILE_SERVE_PREFIX__); loadInfo.loadUrl = "file2://" + this.file.path;
url.searchParams.set("filename", this.file.path);
loadInfo.loadUrl = url.href;
loadInfo.noCache = true; loadInfo.noCache = true;
} else if (this.fileHandle) { } else if (this.fileHandle) {
loadInfo.loadUrl = this.fileDisplayName; loadInfo.loadUrl = this.fileDisplayName;
-44
View File
@@ -1,44 +0,0 @@
import { protocol, session } from "electron";
import fetchToHandler from "fetch-to-electron-protocol-handler";
import makeIPFSFetch from "js-ipfs-fetch";
import * as IPFS from "ipfs-core";
export const PROTOCOL_PERMISSIONS = {
standard: true,
secure: true,
allowServiceWorkers: true,
supportFetchAPI: true,
bypassCSP: false,
corsEnabled: true,
stream: true
};
export function registerPrivileges(privileges = PROTOCOL_PERMISSIONS) {
protocol.registerSchemesAsPrivileged([
{scheme: "ipfs", privileges},
{scheme: "ipns", privileges},
{scheme: "ipld", privileges}
]);
}
export function registerHandler(ipfsRepoPath) {
const handler = createHandler(ipfsRepoPath);
protocol.registerStreamProtocol("ipfs", handler);
protocol.registerStreamProtocol("ipns", handler);
protocol.registerStreamProtocol("ipld", handler);
}
export function createHandler (ipfsRepoPath) {
const {handler} = fetchToHandler(async () => {
const ipfs = await IPFS.create({
repo: ipfsRepoPath
});
const fetch = await makeIPFSFetch({ ipfs });
return fetch;
}, session.defaultSession);
return handler;
}
+85 -102
View File
@@ -3,13 +3,12 @@
import fetch from "node-fetch"; import fetch from "node-fetch";
import { Headers } from "node-fetch"; import { Headers } from "node-fetch";
import {app, session, BrowserWindow, ipcMain, screen, shell } from "electron"; import {app, session, BrowserWindow, ipcMain, protocol, screen, shell } from "electron";
import path from "path"; import path from "path";
import fs from "fs"; import fs from "fs";
import { ArchiveResponse, Rewriter } from "@webrecorder/wabac/src/rewrite"; import { ArchiveResponse, Rewriter } from "@webrecorder/wabac/src/rewrite";
import {create as createIPFS} from "auto-js-ipfs";
import { PassThrough, Readable } from "stream"; import { PassThrough, Readable } from "stream";
@@ -17,6 +16,7 @@ import { autoUpdater } from "electron-updater";
import log from "electron-log"; import log from "electron-log";
import mime from "mime-types"; import mime from "mime-types";
import url from "url";
global.Headers = Headers; global.Headers = Headers;
global.fetch = fetch; global.fetch = fetch;
@@ -25,6 +25,8 @@ const STATIC_PREFIX = "http://localhost:5471/";
const REPLAY_PREFIX = STATIC_PREFIX + "w/"; const REPLAY_PREFIX = STATIC_PREFIX + "w/";
const FILE_PROTO = "file2";
const URL_RX = /([^/]+)\/([\d]+)(?:\w\w_)?\/(.*)$/; const URL_RX = /([^/]+)\/([\d]+)(?:\w\w_)?\/(.*)$/;
// ============================================================================ // ============================================================================
@@ -50,7 +52,7 @@ class ElectronReplayApp
this.screenSize = {width: 1024, height: 768}; this.screenSize = {width: 1024, height: 768};
this.ipfsClient = null; this.origUA = null;
} }
get mainWindowWebPreferences() { get mainWindowWebPreferences() {
@@ -69,7 +71,7 @@ class ElectronReplayApp
return "index.html"; return "index.html";
} }
init(includePlugins = false) { init() {
// Single instance check // Single instance check
const gotTheLock = app.requestSingleInstanceLock(); const gotTheLock = app.requestSingleInstanceLock();
@@ -83,36 +85,10 @@ class ElectronReplayApp
}); });
} }
if (includePlugins) {
switch (process.platform) {
case "win32":
this.pluginPath = path.join(this.projPath, "plugins-win", `pepflashplayer-x86${process.arch === "x64" ? "_64" : ""}.dll`);
break;
case "darwin":
this.pluginPath = path.join(this.projPath, "plugins-mac", "PepperFlashPlayer.plugin");
break;
case "linux":
this.pluginPath = path.join(this.projPath, "plugins-mac", "libpepflashplayer.so");
break;
default:
console.log("platform unsupported: " + process.platform);
break;
}
app.commandLine.appendSwitch("ppapi-flash-path", this.pluginPath);
}
console.log("app path", this.appPath); console.log("app path", this.appPath);
console.log("dir name", __dirname); console.log("dir name", __dirname);
console.log("proj path", this.projPath); console.log("proj path", this.projPath);
if (includePlugins) {
console.log("plugin path", this.pluginPath);
}
console.log("app data", app.getPath("appData")); console.log("app data", app.getPath("appData"));
console.log("user data", app.getPath("userData")); console.log("user data", app.getPath("userData"));
@@ -120,6 +96,19 @@ class ElectronReplayApp
app.setPath("userData", path.join(app.getPath("appData"), this.profileName)); app.setPath("userData", path.join(app.getPath("appData"), this.profileName));
} }
protocol.registerSchemesAsPrivileged([{
scheme: FILE_PROTO,
privileges: {
standard: false,
secure: true,
bypassCSP: true,
allowServiceWorkers: true,
supportFetchAPI: true,
corsEnabled: true,
stream: true
}
}]);
app.on("will-finish-launching", () => { app.on("will-finish-launching", () => {
app.on("open-file", (event, filePath) => { app.on("open-file", (event, filePath) => {
this.openNextFile = filePath; this.openNextFile = filePath;
@@ -155,9 +144,6 @@ class ElectronReplayApp
} }
onAppReady() { onAppReady() {
const ipfsRepoPath = path.join(app.getPath("userData"), "js-ipfs");
console.log("ipfs path", ipfsRepoPath);
this.checkUpdates(); this.checkUpdates();
this.screenSize = screen.getPrimaryDisplay().workAreaSize; this.screenSize = screen.getPrimaryDisplay().workAreaSize;
@@ -184,9 +170,48 @@ class ElectronReplayApp
sesh.protocol.interceptStreamProtocol("http", (request, callback) => this.doIntercept(request, callback)); sesh.protocol.interceptStreamProtocol("http", (request, callback) => this.doIntercept(request, callback));
protocol.registerStreamProtocol(FILE_PROTO, (request, callback) => this.doHandleFile(request, callback));
this.origUA = sesh.getUserAgent();
this.mainWindow = this.createMainWindow(process.argv); this.mainWindow = this.createMainWindow(process.argv);
} }
async doHandleFile(request, callback) {
//const parsedUrl = new URL(request.url);
//const filename = parsedUrl.searchParams.get("filename");
if (request.url === FILE_PROTO + "://localhost") {
callback({statusCode: 200, data: null});
return;
}
const filename = url.fileURLToPath(request.url.replace(FILE_PROTO, "file"));
const headers = {"Content-Type": "application/octet-stream"};
const reqHeaders = new Headers(request.headers);
if (filename) {
const stat = await fs.promises.lstat(filename);
if (!stat.isFile()) {
return this.notFound(filename, callback);
}
const size = stat.size;
const {statusCode, start, end} = this.parseRange(reqHeaders, headers, size);
const data = request.method === "HEAD" ? null : fs.createReadStream(filename, {start, end});
callback({statusCode, headers, data});
return;
} else {
return this.notFound("No Resource Specified", callback);
}
}
_bufferToStream(data) { _bufferToStream(data) {
const rv = new PassThrough(); const rv = new PassThrough();
rv.push(data); rv.push(data);
@@ -243,73 +268,6 @@ class ElectronReplayApp
return this.notFound(request.url, callback); return this.notFound(request.url, callback);
} }
// eslint-disable-next-line no-undef
if (request.url.startsWith(__APP_FILE_SERVE_PREFIX__)) {
const parsedUrl = new URL(request.url);
const filename = parsedUrl.searchParams.get("filename");
const ipfsCID = parsedUrl.searchParams.get("ipfs");
const headers = {"Content-Type": "application/octet-stream"};
const reqHeaders = new Headers(request.headers);
if (filename) {
console.log("file serve:", filename);
const stat = await fs.promises.lstat(filename);
if (!stat.isFile()) {
return this.notFound(filename, callback);
}
const size = stat.size;
const {statusCode, start, end} = this.parseRange(reqHeaders, headers, size);
const data = request.method === "HEAD" ? null : fs.createReadStream(filename, {start, end});
callback({statusCode, headers, data});
return;
} else if (ipfsCID) {
const ipfsURL = `ipfs://${ipfsCID}}`;
console.log("ipfs serve:", ipfsCID);
// TODO: Pass in config?
this.ipfsClient = await createIPFS();
console.log("inited");
let size = await this.ipfsClient.getSize(ipfsURL);
console.log("got size", size);
if (size === null) {
return this.notFound(ipfsCID, callback);
}
const {statusCode, start, end} = this.parseRange(reqHeaders, headers, size);
let data = null;
if (request.method === "GET") {
const offset = start || 0;
const length = end ? end - start + 1 : size;
data = Readable.from(await this.ipfsClient.get(ipfsURL, {
start: offset,
end: offset +length
}));
}
callback({statusCode, headers, data});
return;
} else {
return this.notFound("No Resource Specified", callback);
}
}
// possible 'live leak' attempt, return archived version, if any // possible 'live leak' attempt, return archived version, if any
if (request.referrer && request.referrer.startsWith(REPLAY_PREFIX)) { if (request.referrer && request.referrer.startsWith(REPLAY_PREFIX)) {
return await this.resolveArchiveResponse(request, callback); return await this.resolveArchiveResponse(request, callback);
@@ -320,9 +278,24 @@ class ElectronReplayApp
async proxyLive(request, callback) { async proxyLive(request, callback) {
let headers = request.headers; let headers = request.headers;
const {method, url, uploadData} = request;
const method = request.method; const body = uploadData ? Readable.from(readBody(uploadData, session.defaultSession)) : null;
const response = await fetch(request.url, {method, headers});
if (this.origUA) {
// pass UA if origUA is set
headers["User-Agent"] = this.origUA;
}
let response;
try {
response = await fetch(url, {method, headers, body});
} catch (e) {
console.warn("fetch failed for: " + url);
callback({statusCode: 502, headers: {}, data: null});
return;
}
const data = method === "HEAD" ? null : response.body; const data = method === "HEAD" ? null : response.body;
const statusCode = response.status; const statusCode = response.status;
@@ -478,4 +451,14 @@ class ElectronReplayApp
} }
} }
async function * readBody (body, session) {
for (const chunk of body) {
if (chunk.bytes) {
yield await Promise.resolve(chunk.bytes);
} else if (chunk.blobUUID) {
yield await session.getBlobData(chunk.blobUUID);
}
}
}
export { ElectronReplayApp, STATIC_PREFIX }; export { ElectronReplayApp, STATIC_PREFIX };
+11 -11
View File
File diff suppressed because one or more lines are too long
+3 -3
View File
@@ -48,7 +48,7 @@ class oe extends re{constructor(e){if(super(e),this.it=R,e.type!==ie)throw Error
* Copyright 2017 Google LLC * Copyright 2017 Google LLC
* SPDX-License-Identifier: BSD-3-Clause * SPDX-License-Identifier: BSD-3-Clause
*/ */
class se extends oe{}se.directiveName="unsafeSVG",se.resultType=2;const le=ae(se),ce=ae(class extends re{constructor(e){var t;if(super(e),e.type!==te||"style"!==e.name||(null===(t=e.strings)||void 0===t?void 0:t.length)>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(e){return Object.keys(e).reduce(((t,i)=>{const a=e[i];return null==a?t:t+`${i=i.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${a};`}),"")}update(e,[t]){const{style:i}=e.element;if(void 0===this.ct){this.ct=new Set;for(const e in t)this.ct.add(e);return this.render(t)}this.ct.forEach((e=>{null==t[e]&&(this.ct.delete(e),e.includes("-")?i.removeProperty(e):i[e]="")}));for(const e in t){const a=t[e];null!=a&&(this.ct.add(e),e.includes("-")?i.setProperty(e,a):i[e]=a)}return U}});var de=__webpack_require__(6274),he=__webpack_require__(3029),fe=__webpack_require__.n(he);const be=r(de.Z);function ue(e){return[be,e]}const pe=window.IS_APP||window.electron&&window.electron.IS_APP||window.matchMedia("(display-mode: standalone)").matches,me="1.7.7";function ge(e){" "==e.key&&(e.preventDefault(),e.target.click())}class ve extends X{constructor(){super(),this.size="1.1em",this.width=null,this.height=null}static get properties(){return{svg:{type:String},size:{type:String},width:{type:String},height:{type:String}}}static get styles(){return o` class se extends oe{}se.directiveName="unsafeSVG",se.resultType=2;const le=ae(se),ce=ae(class extends re{constructor(e){var t;if(super(e),e.type!==te||"style"!==e.name||(null===(t=e.strings)||void 0===t?void 0:t.length)>2)throw Error("The `styleMap` directive must be used in the `style` attribute and must be the only part in the attribute.")}render(e){return Object.keys(e).reduce(((t,i)=>{const a=e[i];return null==a?t:t+`${i=i.replace(/(?:^(webkit|moz|ms|o)|)(?=[A-Z])/g,"-$&").toLowerCase()}:${a};`}),"")}update(e,[t]){const{style:i}=e.element;if(void 0===this.ct){this.ct=new Set;for(const e in t)this.ct.add(e);return this.render(t)}this.ct.forEach((e=>{null==t[e]&&(this.ct.delete(e),e.includes("-")?i.removeProperty(e):i[e]="")}));for(const e in t){const a=t[e];null!=a&&(this.ct.add(e),e.includes("-")?i.setProperty(e,a):i[e]=a)}return U}});var de=__webpack_require__(6274),he=__webpack_require__(3029),fe=__webpack_require__.n(he);const be=r(de.Z);function ue(e){return[be,e]}const pe=window.IS_APP||window.electron&&window.electron.IS_APP||window.matchMedia("(display-mode: standalone)").matches,me="1.7.8";function ge(e){" "==e.key&&(e.preventDefault(),e.target.click())}class ve extends X{constructor(){super(),this.size="1.1em",this.width=null,this.height=null}static get properties(){return{svg:{type:String},size:{type:String},width:{type:String},height:{type:String}}}static get styles(){return o`
:host { :host {
display: inline-block; display: inline-block;
padding: 0; padding: 0;
@@ -273,7 +273,7 @@ class se extends oe{}se.directiveName="unsafeSVG",se.resultType=2;const le=ae(se
${this.sourceUrl?this.renderColl():this.renderHomeIndex()} ${this.sourceUrl?this.renderColl():this.renderHomeIndex()}
${this.showAbout?this.renderAbout():""} ${this.showAbout?this.renderAbout():""}
`:P``}firstUpdated(){this.initRoute(),window.addEventListener("popstate",(()=>{this.initRoute()}))}updated(e){e.has("sourceUrl")&&(this.collTitle=null)}onFavIcons(e){const t=document.querySelector("head"),i=document.querySelectorAll("link[rel*='icon']");for(const e of i)t.removeChild(e);for(const i of e.detail.icons){const e=document.createElement("link");e.rel=i.rel,e.href=i.href,t.appendChild(e)}}skipMenu(e){e.preventDefault(),this.renderRoot.querySelector("#skip-main-target").focus()}onNavMenu(e){e.preventDefault(),e.stopPropagation(),this.navMenuShown=!this.navMenuShown,this.navMenuShown&&(document.addEventListener("click",(e=>{e.preventDefault(),this.navMenuShown=!1,this.renderRoot.querySelector("#menu-button").focus()}),{once:!0}),document.addEventListener("keypress",(e=>{"Escape"==e.key&&(e.preventDefault(),this.navMenuShown=!1,this.renderRoot.querySelector("#menu-button").focus())}),{once:!0}))}initRoute(){this.inited=!0,this.pageParams=new URLSearchParams(window.location.search);let e=this.pageParams.get("state");if(e)try{if(e=JSON.parse(e),e.ids instanceof Array&&e.userId&&"open"===e.action)return this.pageParams.set("source","googledrive://"+e.ids[0]),this.pageParams.delete("state"),void(window.location.search=this.pageParams.toString())}catch(e){console.log(e)}if(this.source){this.pageParams.set("source",this.source);const e=new URL(window.location.href);e.search=this.pageParams.toString(),window.history.replaceState({},document.title,e.href)}if(this.sourceUrl=this.pageParams.get("source")||"",this.embed=this.pageParams.get("embed")||"",this.pageParams.has("terms")&&(this.showAbout=!0),this.pageParams.has("embed")&&(this.loadInfo||(this.loadInfo={})),this.pageParams.get("config"))try{this.loadInfo.extraConfig=JSON.parse(this.pageParams.get("config"))}catch(e){console.log("invalid config: "+e)}if(this.pageParams.get("baseUrlSourcePrefix")&&(this.loadInfo.extraConfig=this.loadInfo.extraConfig||{},this.loadInfo.extraConfig.baseUrlSourcePrefix=this.pageParams.get("baseUrlSourcePrefix")),this.pageParams.get("basePageUrl")&&(this.loadInfo.extraConfig=this.loadInfo.extraConfig||{},this.loadInfo.extraConfig.baseUrl=this.pageParams.get("basePageUrl")),this.pageParams.get("customColl")&&(this.loadInfo.customColl=this.pageParams.get("customColl")),"1"===this.pageParams.get("noWebWorker")&&(this.loadInfo.noWebWorker=!0),"1"===this.pageParams.get("noCache")&&(this.loadInfo.noCache=!0),"1"===this.pageParams.get("hideOffscreen")&&(this.loadInfo.hideOffscreen=!0),"eager"===this.pageParams.get("loading")&&(this.loadInfo.loadEager=!0),pe&&this.sourceUrl.startsWith("file://")){const e=new URL("http://files.replayweb.page/");e.searchParams.set("filename",this.sourceUrl.slice("file://".length)),this.loadInfo={sourceUrl:this.sourceUrl,loadUrl:e.href}}}onStartLoad(e){this.pageParams.set("source",e.detail.sourceUrl);const t=new URL(window.location.href);t.search=this.pageParams.toString(),this.collPageUrl=t.toString(),e.detail.isFile?(window.history.pushState({},"",this.collPageUrl),this.sourceUrl=e.detail.sourceUrl,this.loadInfo=e.detail):window.location.search=this.pageParams.toString()}onCollLoaded(e){this.loadInfo=null,e.detail.collInfo&&(this.collTitle=e.detail.collInfo.title),e.detail.alreadyLoaded||e.detail.sourceUrl!==this.sourceUrl&&(this.pageParams.set("source",e.detail.sourceUrl),window.location.search=this.pageParams.toString())}onTitle(e){e.detail.title&&(this.pageTitle=e.detail.title,this.pageReplay=e.detail.replayTitle,document.title=(e.detail.replayTitle?"Archive of ":"")+this.pageTitle+" | "+this.appName)}safariKeyframes(){const e=document.createElement("style");document.head.appendChild(e),e.appendChild(document.createTextNode("\n @keyframes spinAround {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(359deg);\n }\n }\n "))}renderAbout(){return P` `:P``}firstUpdated(){this.initRoute(),window.addEventListener("popstate",(()=>{this.initRoute()}))}updated(e){e.has("sourceUrl")&&(this.collTitle=null)}onFavIcons(e){const t=document.querySelector("head"),i=document.querySelectorAll("link[rel*='icon']");for(const e of i)t.removeChild(e);for(const i of e.detail.icons){const e=document.createElement("link");e.rel=i.rel,e.href=i.href,t.appendChild(e)}}skipMenu(e){e.preventDefault(),this.renderRoot.querySelector("#skip-main-target").focus()}onNavMenu(e){e.preventDefault(),e.stopPropagation(),this.navMenuShown=!this.navMenuShown,this.navMenuShown&&(document.addEventListener("click",(e=>{e.preventDefault(),this.navMenuShown=!1,this.renderRoot.querySelector("#menu-button").focus()}),{once:!0}),document.addEventListener("keypress",(e=>{"Escape"==e.key&&(e.preventDefault(),this.navMenuShown=!1,this.renderRoot.querySelector("#menu-button").focus())}),{once:!0}))}initRoute(){this.inited=!0,this.pageParams=new URLSearchParams(window.location.search);let e=this.pageParams.get("state");if(e)try{if(e=JSON.parse(e),e.ids instanceof Array&&e.userId&&"open"===e.action)return this.pageParams.set("source","googledrive://"+e.ids[0]),this.pageParams.delete("state"),void(window.location.search=this.pageParams.toString())}catch(e){console.log(e)}if(this.source){this.pageParams.set("source",this.source);const e=new URL(window.location.href);e.search=this.pageParams.toString(),window.history.replaceState({},document.title,e.href)}if(this.sourceUrl=this.pageParams.get("source")||"",this.embed=this.pageParams.get("embed")||"",this.pageParams.has("terms")&&(this.showAbout=!0),this.pageParams.has("embed")&&(this.loadInfo||(this.loadInfo={})),this.pageParams.get("config"))try{this.loadInfo.extraConfig=JSON.parse(this.pageParams.get("config"))}catch(e){console.log("invalid config: "+e)}this.pageParams.get("baseUrlSourcePrefix")&&(this.loadInfo.extraConfig=this.loadInfo.extraConfig||{},this.loadInfo.extraConfig.baseUrlSourcePrefix=this.pageParams.get("baseUrlSourcePrefix")),this.pageParams.get("basePageUrl")&&(this.loadInfo.extraConfig=this.loadInfo.extraConfig||{},this.loadInfo.extraConfig.baseUrl=this.pageParams.get("basePageUrl")),this.pageParams.get("customColl")&&(this.loadInfo.customColl=this.pageParams.get("customColl")),"1"===this.pageParams.get("noWebWorker")&&(this.loadInfo.noWebWorker=!0),"1"===this.pageParams.get("noCache")&&(this.loadInfo.noCache=!0),"1"===this.pageParams.get("hideOffscreen")&&(this.loadInfo.hideOffscreen=!0),"eager"===this.pageParams.get("loading")&&(this.loadInfo.loadEager=!0),pe&&this.sourceUrl.startsWith("file://")&&(this.loadInfo={sourceUrl:this.sourceUrl,loadUrl:this.sourceUrl.replace("file://","file2://")})}onStartLoad(e){this.pageParams.set("source",e.detail.sourceUrl);const t=new URL(window.location.href);t.search=this.pageParams.toString(),this.collPageUrl=t.toString(),e.detail.isFile?(window.history.pushState({},"",this.collPageUrl),this.sourceUrl=e.detail.sourceUrl,this.loadInfo=e.detail):window.location.search=this.pageParams.toString()}onCollLoaded(e){this.loadInfo=null,e.detail.collInfo&&(this.collTitle=e.detail.collInfo.title),e.detail.alreadyLoaded||e.detail.sourceUrl!==this.sourceUrl&&(this.pageParams.set("source",e.detail.sourceUrl),window.location.search=this.pageParams.toString())}onTitle(e){e.detail.title&&(this.pageTitle=e.detail.title,this.pageReplay=e.detail.replayTitle,document.title=(e.detail.replayTitle?"Archive of ":"")+this.pageTitle+" | "+this.appName)}safariKeyframes(){const e=document.createElement("style");document.head.appendChild(e),e.appendChild(document.createTextNode("\n @keyframes spinAround {\n from {\n transform: rotate(0deg);\n }\n to {\n transform: rotate(359deg);\n }\n }\n "))}renderAbout(){return P`
<div class="modal is-active"> <div class="modal is-active">
<div class="modal-background" @click="${this.onAboutClose}"></div> <div class="modal-background" @click="${this.onAboutClose}"></div>
<div class="modal-card"> <div class="modal-card">
@@ -328,7 +328,7 @@ class se extends oe{}se.directiveName="unsafeSVG",se.resultType=2;const le=ae(se
</section> </section>
</div> </div>
</div> </div>
</div>`}onAboutClose(){this.showAbout=!1}}customElements.define("replay-app-main",Ie);var Le=__webpack_require__(8135),Te=__webpack_require__.n(Le);class Pe extends X{constructor(){super(),this.fileDisplayName="",this.file=null,this.hasNativeFS=!!window.showOpenFilePicker&&!pe,this.newFullImport=!1,this.noHead=!1}static get properties(){return{fileDisplayName:{type:String},newFullImport:{type:Boolean},noHead:{type:Boolean}}}onChooseFile(e){0!==e.currentTarget.files.length&&(this.file=e.currentTarget.files[0],this.fileDisplayName="file://"+(this.file.path||this.file.name))}async onChooseNativeFile(){if(!this.hasNativeFS)return;const[e]=await window.showOpenFilePicker({types:[{description:"WARC, WACZ, HAR and WBN Files",accept:{"application/warc":[".warc",".gz"],"application/har":[".har"],"application/wacz":[".wacz"],"application/wbn":[".wbn"],"application/json":[".json"]}}]});this.fileHandle=e,this.file=await e.getFile(),this.fileDisplayName="file://"+e.name}randomId(){return Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15)}onStartLoad(e){e.preventDefault();const t={sourceUrl:this.fileDisplayName};if(this.file){if(t.isFile=!0,this.file.path){const e=new URL("http://files.replayweb.page/");e.searchParams.set("filename",this.file.path),t.loadUrl=e.href,t.noCache=!0}else this.fileHandle?(t.loadUrl=this.fileDisplayName,t.extra={fileHandle:this.fileHandle},t.noCache=!1):(t.loadUrl=URL.createObjectURL(this.file),t.blob=this.file,t.noCache=!1);t.size=this.file.size,t.name=this.fileDisplayName}return t.newFullImport=this.newFullImport,this.dispatchEvent(new CustomEvent("load-start",{bubbles:!0,composed:!0,detail:t})),!1}onInput(e){this.fileDisplayName=e.currentTarget.value,this.file&&this.fileDisplayName&&this.fileDisplayName.startsWith("file://")&&(this.file=null,this.fileDisplayName="")}static get styles(){return ue(o` </div>`}onAboutClose(){this.showAbout=!1}}customElements.define("replay-app-main",Ie);var Le=__webpack_require__(8135),Te=__webpack_require__.n(Le);class Pe extends X{constructor(){super(),this.fileDisplayName="",this.file=null,this.hasNativeFS=!!window.showOpenFilePicker&&!pe,this.newFullImport=!1,this.noHead=!1}static get properties(){return{fileDisplayName:{type:String},newFullImport:{type:Boolean},noHead:{type:Boolean}}}onChooseFile(e){0!==e.currentTarget.files.length&&(this.file=e.currentTarget.files[0],this.fileDisplayName="file://"+(this.file.path||this.file.name))}async onChooseNativeFile(){if(!this.hasNativeFS)return;const[e]=await window.showOpenFilePicker({types:[{description:"WARC, WACZ, HAR and WBN Files",accept:{"application/warc":[".warc",".gz"],"application/har":[".har"],"application/wacz":[".wacz"],"application/wbn":[".wbn"],"application/json":[".json"]}}]});this.fileHandle=e,this.file=await e.getFile(),this.fileDisplayName="file://"+e.name}randomId(){return Math.random().toString(36).substring(2,15)+Math.random().toString(36).substring(2,15)}onStartLoad(e){e.preventDefault();const t={sourceUrl:this.fileDisplayName};return this.file&&(t.isFile=!0,this.file.path?(t.loadUrl="file2://"+this.file.path,t.noCache=!0):this.fileHandle?(t.loadUrl=this.fileDisplayName,t.extra={fileHandle:this.fileHandle},t.noCache=!1):(t.loadUrl=URL.createObjectURL(this.file),t.blob=this.file,t.noCache=!1),t.size=this.file.size,t.name=this.fileDisplayName),t.newFullImport=this.newFullImport,this.dispatchEvent(new CustomEvent("load-start",{bubbles:!0,composed:!0,detail:t})),!1}onInput(e){this.fileDisplayName=e.currentTarget.value,this.file&&this.fileDisplayName&&this.fileDisplayName.startsWith("file://")&&(this.file=null,this.fileDisplayName="")}static get styles(){return ue(o`
:host { :host {
min-width: 0; min-width: 0;
} }
-14
View File
@@ -7,11 +7,6 @@ const CopyPlugin = require("copy-webpack-plugin");
const TerserPlugin = require("terser-webpack-plugin"); const TerserPlugin = require("terser-webpack-plugin");
const package_json = require("./package.json"); const package_json = require("./package.json");
// fake url used in app to serve files
// can not use custom scheme due to service worker issues
const APP_FILE_SERVE_PREFIX = "http://files.replayweb.page/";
//const APP_FILE_SERVE_PREFIX = "file://files.replayweb.page";
// helper proxy URL, run locally for app // helper proxy URL, run locally for app
const HELPER_PROXY = "https://helper-proxy.webrecorder.workers.dev"; const HELPER_PROXY = "https://helper-proxy.webrecorder.workers.dev";
@@ -66,9 +61,7 @@ const electronMainConfig = (/*env, argv*/) => {
}, },
plugins: [ plugins: [
new webpack.DefinePlugin({ new webpack.DefinePlugin({
__APP_FILE_SERVE_PREFIX__ : JSON.stringify(APP_FILE_SERVE_PREFIX),
__HELPER_PROXY__ : JSON.stringify(HELPER_PROXY), __HELPER_PROXY__ : JSON.stringify(HELPER_PROXY),
__IPFS_CORE_URL__: JSON.stringify("")
}), }),
new webpack.BannerPlugin(BANNER_TEXT), new webpack.BannerPlugin(BANNER_TEXT),
new CopyPlugin({ new CopyPlugin({
@@ -98,12 +91,6 @@ const electronPreloadConfig = (/*env, argv*/) => {
optimization, optimization,
plugins: [ plugins: [
new webpack.BannerPlugin(BANNER_TEXT), new webpack.BannerPlugin(BANNER_TEXT),
// this needs to be defined, but not actually used, as electron app uses
// ipfs-core from node
new webpack.DefinePlugin({
__IPFS_CORE_URL__: JSON.stringify("")
}),
] ]
}; };
}; };
@@ -152,7 +139,6 @@ const browserConfig = (/*env, argv*/) => {
new MiniCssExtractPlugin(), new MiniCssExtractPlugin(),
new webpack.DefinePlugin({ new webpack.DefinePlugin({
__SW_NAME__: JSON.stringify("sw.js"), __SW_NAME__: JSON.stringify("sw.js"),
__APP_FILE_SERVE_PREFIX__ : JSON.stringify(APP_FILE_SERVE_PREFIX),
__HELPER_PROXY__ : JSON.stringify(HELPER_PROXY), __HELPER_PROXY__ : JSON.stringify(HELPER_PROXY),
__GDRIVE_CLIENT_ID__ : JSON.stringify(GDRIVE_CLIENT_ID), __GDRIVE_CLIENT_ID__ : JSON.stringify(GDRIVE_CLIENT_ID),
__VERSION__: JSON.stringify(package_json.version), __VERSION__: JSON.stringify(package_json.version),
+786 -690
View File
File diff suppressed because it is too large Load Diff