Skip to content

Commit

Permalink
add window message notifications for embeds: (fixes #333) (#335)
Browse files Browse the repository at this point in the history
- 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
  • Loading branch information
ikreymer committed Jun 21, 2024
1 parent f3506a1 commit 105562a
Show file tree
Hide file tree
Showing 3 changed files with 99 additions and 41 deletions.
20 changes: 16 additions & 4 deletions src/embed.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 =
Expand Down Expand Up @@ -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":
Expand Down
105 changes: 70 additions & 35 deletions src/item.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,25 @@ export type EmbedReplayData = {
query?: string;
};

export type EmbedReplayEvent = EmbedReplayData & {
type: "urlchange";
replayNotFoundError: boolean;
};

export type TabData = EmbedReplayData & {
multiTs?: string[];
currList?: number;
urlSearchType?: string;
currMime?: string;
};

export type TabDataUpdate = {
reload: boolean;
data: TabData;
replaceLoc: boolean;
replayNotFoundError: boolean;
};

// ===========================================================================
class Item extends LitElement {
@property({ type: Boolean })
Expand Down Expand Up @@ -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;
Expand All @@ -194,6 +209,8 @@ class Item extends LitElement {
resources: "URLs",
};

private _lastUrlUpdate: EmbedReplayData | null = null;

constructor() {
super();

Expand Down Expand Up @@ -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 '{}'.
Expand All @@ -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();
}
}
}
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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 || "";
Expand Down Expand Up @@ -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>
Expand Down Expand Up @@ -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 }, "*");
Expand Down Expand Up @@ -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 };
Expand Down
15 changes: 13 additions & 2 deletions src/replay.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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,
},
}),
);
}

Expand Down Expand Up @@ -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) {
Expand Down

0 comments on commit 105562a

Please sign in to comment.