- add 'replayNotFoundError' field to 'urlchange' (propagating 'archive-not-found' postMessage message from wabac.js) to embed frame, with url/ts, for 404 pages - propagate 'page-loading' with loading true/false, to indicate when a page started/finished loading. (URL not available here) - Only send one urlchange event per URL change (keep track of change). - Also ensure multi timestamp change uses replaceHistory to avoid an extra navigation. - replay-web-page embed: send rwp-url-change and rwp-page-loading custom events from webcomponent Fixes #333
This commit is contained in:
committed by
Ilya Kreymer
parent
f3506a1575
commit
105562abf9
+16
-4
@@ -11,15 +11,14 @@ import { wrapCss, updateFaviconLinks } from "./misc";
|
||||
import { SWManager } from "./swmanager";
|
||||
import { property } from "lit/decorators.js";
|
||||
import type { FavIconEventDetail } from "./types";
|
||||
import type { EmbedReplayData } from "./item";
|
||||
import type { EmbedReplayData, EmbedReplayEvent } from "./item";
|
||||
|
||||
type IframeMessage = MessageEvent<
|
||||
| ({
|
||||
type: "urlchange";
|
||||
} & EmbedReplayData)
|
||||
| EmbedReplayEvent
|
||||
| ({
|
||||
type: "favicons";
|
||||
} & FavIconEventDetail)
|
||||
| { loading: boolean; type: "page-loading" }
|
||||
>;
|
||||
|
||||
const scriptSrc =
|
||||
@@ -136,6 +135,19 @@ class Embed extends LitElement {
|
||||
if (this.deepLink) {
|
||||
this.handleUrlChangeMessage(event.data);
|
||||
}
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<EmbedReplayEvent>("rwp-url-change", {
|
||||
detail: event.data,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
|
||||
case "page-loading":
|
||||
this.dispatchEvent(
|
||||
new CustomEvent<{ loading: boolean }>("rwp-page-loading", {
|
||||
detail: event.data,
|
||||
}),
|
||||
);
|
||||
break;
|
||||
|
||||
case "favicons":
|
||||
|
||||
+70
-35
@@ -93,6 +93,11 @@ export type EmbedReplayData = {
|
||||
query?: string;
|
||||
};
|
||||
|
||||
export type EmbedReplayEvent = EmbedReplayData & {
|
||||
type: "urlchange";
|
||||
replayNotFoundError: boolean;
|
||||
};
|
||||
|
||||
export type TabData = EmbedReplayData & {
|
||||
multiTs?: string[];
|
||||
currList?: number;
|
||||
@@ -100,6 +105,13 @@ export type TabData = EmbedReplayData & {
|
||||
currMime?: string;
|
||||
};
|
||||
|
||||
export type TabDataUpdate = {
|
||||
reload: boolean;
|
||||
data: TabData;
|
||||
replaceLoc: boolean;
|
||||
replayNotFoundError: boolean;
|
||||
};
|
||||
|
||||
// ===========================================================================
|
||||
class Item extends LitElement {
|
||||
@property({ type: Boolean })
|
||||
@@ -174,6 +186,9 @@ class Item extends LitElement {
|
||||
@property({ type: String })
|
||||
swName: string | null = null;
|
||||
|
||||
@property({ type: Boolean })
|
||||
replayNotFoundError = false;
|
||||
|
||||
private splitter: Split.Instance | null = null;
|
||||
|
||||
private _replaceLoc = false;
|
||||
@@ -194,6 +209,8 @@ class Item extends LitElement {
|
||||
resources: "URLs",
|
||||
};
|
||||
|
||||
private _lastUrlUpdate: EmbedReplayData | null = null;
|
||||
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
@@ -248,19 +265,16 @@ class Item extends LitElement {
|
||||
return;
|
||||
}
|
||||
const json = await resp.json();
|
||||
this.updateTabData({ multiTs: json.timestamps });
|
||||
this.updateTabData({ multiTs: json.timestamps }, true);
|
||||
}
|
||||
|
||||
willUpdate(changedProperties: Map<string, Record<string, unknown>>) {
|
||||
// TODO: Fix this the next time the file is edited.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unnecessary-condition
|
||||
if (changedProperties.has("tabData") && this.tabData) {
|
||||
if (changedProperties.has("tabData")) {
|
||||
// Format tab data from URL query params
|
||||
const tabData = {};
|
||||
const tabData: TabData = {};
|
||||
Object.entries(this.tabData).forEach(([key, value]) => {
|
||||
if (!value) return;
|
||||
if (key === "multiTs" && typeof value === "string") {
|
||||
// @ts-expect-error [// TODO: Fix this the next time the file is edited.] - TS7053 - Element implicitly has an 'any' type because expression of type '"multiTs"' can't be used to index type '{}'.
|
||||
tabData[key] = value.split(",");
|
||||
} else {
|
||||
// @ts-expect-error [// TODO: Fix this the next time the file is edited.] - TS7053 - Element implicitly has an 'any' type because expression of type 'string' can't be used to index type '{}'.
|
||||
@@ -271,9 +285,7 @@ class Item extends LitElement {
|
||||
|
||||
const prevTabData = changedProperties.get("tabData");
|
||||
if (this.tabData.url && this.tabData.url !== prevTabData?.url) {
|
||||
// TODO: Fix this the next time the file is edited.
|
||||
// eslint-disable-next-line @typescript-eslint/no-floating-promises
|
||||
this.getMultiTimestamps();
|
||||
void this.getMultiTimestamps();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,10 +344,28 @@ class Item extends LitElement {
|
||||
}
|
||||
if (this.embed && window.parent !== window) {
|
||||
const { url, ts, view, query, title }: EmbedReplayData = this.tabData;
|
||||
window.parent.postMessage(
|
||||
{ type: "urlchange", url, ts, view, query, title },
|
||||
"*",
|
||||
);
|
||||
const lastUpdate = this._lastUrlUpdate;
|
||||
const replayNotFoundError = this.replayNotFoundError;
|
||||
if (
|
||||
!lastUpdate ||
|
||||
lastUpdate.url !== url ||
|
||||
lastUpdate.ts !== ts ||
|
||||
lastUpdate.view !== view ||
|
||||
lastUpdate.query !== query ||
|
||||
lastUpdate.title !== title
|
||||
) {
|
||||
const newUpdate: EmbedReplayEvent = {
|
||||
type: "urlchange",
|
||||
url,
|
||||
ts,
|
||||
view,
|
||||
query,
|
||||
title,
|
||||
replayNotFoundError,
|
||||
};
|
||||
window.parent.postMessage(newUpdate, "*");
|
||||
this._lastUrlUpdate = newUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
this._locUpdateNeeded = false;
|
||||
@@ -542,35 +572,28 @@ class Item extends LitElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
// @ts-expect-error [// TODO: Fix this the next time the file is edited.] - TS7006 - Parameter 'event' implicitly has an 'any' type.
|
||||
onItemTabNav(event) {
|
||||
onItemTabNav(event: CustomEvent<TabDataUpdate>) {
|
||||
if (event.detail.reload) {
|
||||
this.onRefresh(null, true);
|
||||
return;
|
||||
}
|
||||
|
||||
const targetId = (event.target as HTMLElement).id;
|
||||
|
||||
const { data, replaceLoc, replayNotFoundError } = event.detail;
|
||||
|
||||
this.replayNotFoundError = replayNotFoundError;
|
||||
|
||||
if (
|
||||
event.target.id === this.tabData.view ||
|
||||
(event.target.id === "replay" && this.tabData.url)
|
||||
targetId === this.tabData.view ||
|
||||
(targetId === "replay" && this.tabData.url) ||
|
||||
(this.showSidebar && this.tabData.url)
|
||||
) {
|
||||
this.updateTabData(
|
||||
event.detail.data,
|
||||
// TODO: Fix this the next time the file is edited.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
event.detail.replaceLoc /*, false */,
|
||||
);
|
||||
} else if (this.showSidebar && this.tabData.url) {
|
||||
this.updateTabData(
|
||||
event.detail.data,
|
||||
// TODO: Fix this the next time the file is edited.
|
||||
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
||||
event.detail.replaceLoc /*, true */,
|
||||
);
|
||||
this.updateTabData(data, replaceLoc);
|
||||
}
|
||||
}
|
||||
|
||||
// @ts-expect-error [// TODO: Fix this the next time the file is edited.] - TS7006 - Parameter 'data' implicitly has an 'any' type.
|
||||
updateTabData(data, replaceLoc = false /*, merge = false*/) {
|
||||
updateTabData(data: TabData, replaceLoc = false) {
|
||||
this.tabData = { ...this.tabData, ...data };
|
||||
if (this.tabData.url) {
|
||||
this.url = this.tabData.url || "";
|
||||
@@ -961,8 +984,7 @@ class Item extends LitElement {
|
||||
ts="${this.tabData.ts || ""}"
|
||||
@coll-tab-nav="${this.onItemTabNav}"
|
||||
id="replay"
|
||||
@replay-loading="${(e: CustomEvent<{ loading: boolean }>) =>
|
||||
(this.isLoading = e.detail.loading)}"
|
||||
@replay-loading="${this.onReplayLoading}"
|
||||
@replay-favicons="${this.onFavIcons}"
|
||||
>
|
||||
</wr-coll-replay>
|
||||
@@ -1653,6 +1675,19 @@ class Item extends LitElement {
|
||||
this.showSidebar = false;
|
||||
}
|
||||
|
||||
async onReplayLoading(
|
||||
event: CustomEvent<{ loading: boolean; url: string; ts: string }>,
|
||||
) {
|
||||
if (
|
||||
this.embed &&
|
||||
window.parent !== window &&
|
||||
this.isLoading !== event.detail.loading
|
||||
) {
|
||||
window.parent.postMessage({ type: "page-loading", ...event.detail }, "*");
|
||||
}
|
||||
this.isLoading = event.detail.loading;
|
||||
}
|
||||
|
||||
async onFavIcons(event: CustomEvent<FavIconEventDetail>) {
|
||||
if (this.embed && window.parent !== window) {
|
||||
window.parent.postMessage({ type: "favicons", ...event.detail }, "*");
|
||||
@@ -1749,7 +1784,7 @@ class Item extends LitElement {
|
||||
|
||||
// @ts-expect-error [// TODO: Fix this the next time the file is edited.] - TS7006 - Parameter 'value' implicitly has an 'any' type.
|
||||
navigateTo(value) {
|
||||
let data;
|
||||
let data: TabData;
|
||||
|
||||
if (value.startsWith("http://") || value.startsWith("https://")) {
|
||||
data = { url: value };
|
||||
|
||||
+13
-2
@@ -39,6 +39,9 @@ class Replay extends LitElement {
|
||||
@property({ type: Boolean })
|
||||
showAuth = false;
|
||||
|
||||
@property({ type: Boolean })
|
||||
replayNotFoundError = false;
|
||||
|
||||
@property({ type: Object })
|
||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any -- requestPermission() type mismatch
|
||||
authFileHandle: any = null;
|
||||
@@ -140,7 +143,13 @@ class Replay extends LitElement {
|
||||
};
|
||||
|
||||
this.dispatchEvent(
|
||||
new CustomEvent("coll-tab-nav", { detail: { replaceLoc: true, data } }),
|
||||
new CustomEvent("coll-tab-nav", {
|
||||
detail: {
|
||||
replaceLoc: true,
|
||||
data,
|
||||
replayNotFoundError: this.replayNotFoundError,
|
||||
},
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -180,12 +189,14 @@ class Replay extends LitElement {
|
||||
if (iframe && event.source === iframe.contentWindow) {
|
||||
if (
|
||||
event.data.wb_type === "load" ||
|
||||
event.data.wb_type === "replace-url"
|
||||
event.data.wb_type === "replace-url" ||
|
||||
event.data.wb_type === "archive-not-found"
|
||||
) {
|
||||
this.replayTS = event.data.is_live ? "" : event.data.ts;
|
||||
this.actualTS = event.data.ts;
|
||||
this.replayUrl = event.data.url;
|
||||
this.title = event.data.title || this.title;
|
||||
this.replayNotFoundError = event.data.wb_type === "archive-not-found";
|
||||
this.clearLoading(iframe.contentWindow);
|
||||
|
||||
if (event.data.icons) {
|
||||
|
||||
Reference in New Issue
Block a user