fix: cleanup iframe messaging
This commit is contained in:
parent
990d4e98ac
commit
585a7b903e
@ -74,11 +74,3 @@ export enum BusMessageType {
|
||||
CONTENT_THEME = 'content.theme'
|
||||
// Options
|
||||
}
|
||||
|
||||
export enum IFrameMessage {
|
||||
FETCH = 'fetch',
|
||||
PING = 'ping',
|
||||
ALIVE = 'alive',
|
||||
START_LISTENERS = 'start-listeners',
|
||||
STOP_LISTENERS = 'stop-listeners'
|
||||
}
|
||||
|
@ -47,7 +47,7 @@ export interface FetchImageRequest {
|
||||
}
|
||||
|
||||
export interface FetchIframeRequest {
|
||||
id: string;
|
||||
uid: string;
|
||||
depth: number;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@
|
||||
import { CssStyleListDto } from './obj-pin.dto';
|
||||
|
||||
export interface ObjIframeContentDto {
|
||||
id: string;
|
||||
uid: string;
|
||||
ok: boolean;
|
||||
url: string;
|
||||
html: string;
|
||||
|
@ -32,7 +32,7 @@ export class ContentFetchIframeCommand implements ICommand<Promise<void>> {
|
||||
const css = await CssFactory.computeCssContent();
|
||||
const dto: ObjIframeContentDto = {
|
||||
ok: true,
|
||||
id: this.data.id,
|
||||
uid: this.data.uid,
|
||||
url: this.href,
|
||||
html: htmlContent.html,
|
||||
htmlAttr: HtmlFactory.computeHtmlAttr(),
|
||||
|
@ -24,6 +24,7 @@ import '@fontsource/roboto/700.css';
|
||||
import '../css/prosemirror.css';
|
||||
|
||||
import { ContentExtensionData, ExtensionThemeDto } from '../common/model/settings.model';
|
||||
import { IFrameMessageFactory, IFrameMessageType } from './factory/html/iframe-message.model';
|
||||
import { fnConsoleError, fnConsoleLog } from '../common/fn/console.fn';
|
||||
import { BrowserApi } from '../common/service/browser.api.wrapper';
|
||||
import { BrowserStorageWrapper } from '../common/service/browser.storage.wrapper';
|
||||
@ -47,18 +48,16 @@ class PinMeScript {
|
||||
this.href = UrlFactory.normalizeHref(window.location.href);
|
||||
window.addEventListener('message', async (e) => {
|
||||
// TODO RECEIVE
|
||||
try {
|
||||
const msg = JSON.parse(e.data);
|
||||
if (msg.foo === 'bar') {
|
||||
//eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
window.top?.postMessage(`{"bar":"foo", "id":"${msg.id}"}`, '*');
|
||||
await new ContentFetchIframeCommand(msg, this.href).execute();
|
||||
} else if (msg.bar === 'foo') {
|
||||
fnConsoleLog('PinMeScript->constructor->ping->from-iframe', msg);
|
||||
TinyEventDispatcher.dispatch(BusMessageType.CONTENT_FETCH_IFRAME_PING, msg);
|
||||
}
|
||||
} catch (e) {
|
||||
/* IGNORE */
|
||||
const msg = IFrameMessageFactory.parse(e.data);
|
||||
if (!msg) return;
|
||||
if (msg.type === IFrameMessageType.PING) {
|
||||
//eslint-disable-next-line @typescript-eslint/restrict-template-expressions
|
||||
window.top?.postMessage(IFrameMessageFactory.create({ type: IFrameMessageType.PONG, data: msg.data }));
|
||||
} else if (msg.type === IFrameMessageType.PONG) {
|
||||
fnConsoleLog('PinMeScript->constructor->ping->from-iframe', msg);
|
||||
TinyEventDispatcher.dispatch(BusMessageType.CONTENT_FETCH_IFRAME_PING, msg.data);
|
||||
} else if (msg.type === IFrameMessageType.FETCH) {
|
||||
await new ContentFetchIframeCommand(msg.data, this.href).execute();
|
||||
}
|
||||
});
|
||||
ContentMessageHandler.start(this.href);
|
||||
|
@ -196,6 +196,7 @@ export class CssFactory {
|
||||
css = css.replace(urlMatch, newUrl);
|
||||
} else {
|
||||
fnConsoleLog('CssFactory->fetchUrl->ERROR !!!', result, baseurl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
return css;
|
||||
|
@ -78,13 +78,13 @@ export class HtmlAttrFactory {
|
||||
const urlList = attrValue.match(CSS_URL_REG);
|
||||
if (urlList) {
|
||||
const value = await CssFactory.fetchUrls(attrValue);
|
||||
fnConsoleLog(
|
||||
'HtmlFactory->computeHtmlIntermediateData->image-inside-style',
|
||||
/*fnConsoleLog(
|
||||
'HtmlAttrFactory->computeHtmlIntermediateData->image-inside-style',
|
||||
'prev',
|
||||
attrValue,
|
||||
'result',
|
||||
value
|
||||
);
|
||||
);*/
|
||||
html += `${attr.name}="${value}" `;
|
||||
} else {
|
||||
html += `${attr.name}="${attrValue}" `;
|
||||
|
@ -15,7 +15,6 @@
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { fnComputeUrl } from '../../../common/fn/compute-url.fn';
|
||||
import { fnConsoleLog } from '../../../common/fn/console.fn';
|
||||
import { fnFetchImage } from '../../../common/fn/fetch-image.fn';
|
||||
|
||||
export class HtmlImgFactory {
|
||||
@ -67,7 +66,7 @@ export class HtmlImgFactory {
|
||||
const url = fnComputeUrl(value);
|
||||
|
||||
const imageData = await fnFetchImage(url);
|
||||
fnConsoleLog('HtmlImgFactory->computeImgValue', url);
|
||||
// fnConsoleLog('HtmlImgFactory->computeImgValue', url);
|
||||
if (imageData.ok) {
|
||||
return imageData.res;
|
||||
}
|
||||
|
48
src/content-script/factory/html/iframe-message.model.ts
Normal file
48
src/content-script/factory/html/iframe-message.model.ts
Normal file
@ -0,0 +1,48 @@
|
||||
/*
|
||||
* This file is part of the pinmenote-extension distribution (https://github.com/pinmenote/pinmenote-extension).
|
||||
* Copyright (c) 2023 Michal Szczepanski.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful, but
|
||||
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
* General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { fnConsoleLog } from '../../../common/fn/console.fn';
|
||||
|
||||
export enum IFrameMessageType {
|
||||
FETCH = 'fetch',
|
||||
PING = 'ping',
|
||||
PONG = 'png',
|
||||
ALIVE = 'alive',
|
||||
START_LISTENERS = 'start-listeners',
|
||||
STOP_LISTENERS = 'stop-listeners'
|
||||
}
|
||||
|
||||
export interface IFrameMessage {
|
||||
type: IFrameMessageType;
|
||||
data: any;
|
||||
}
|
||||
|
||||
export class IFrameMessageFactory {
|
||||
static create(message: IFrameMessage) {
|
||||
fnConsoleLog('IFrameMessageFactory->create', message);
|
||||
return JSON.stringify(message);
|
||||
}
|
||||
|
||||
static parse(msg: string): IFrameMessage | undefined {
|
||||
try {
|
||||
return JSON.parse(msg);
|
||||
} catch (e) {
|
||||
/* IGNORE */
|
||||
fnConsoleLog('IFrameMessageFactory->parse->error', e, msg);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
}
|
@ -14,6 +14,7 @@
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
import { IFrameMessageFactory, IFrameMessageType } from './iframe-message.model';
|
||||
import { ObjContentTypeDto, ObjIframeContentDto } from '../../../common/model/obj/obj-content.dto';
|
||||
import { BusMessageType } from '../../../common/model/bus.model';
|
||||
import { HtmlAttrFactory } from './html-attr.factory';
|
||||
@ -57,17 +58,24 @@ export class IframeFactory {
|
||||
fnConsoleLog('HtmlFactory->fetchIframe', ref.src);
|
||||
return new Promise<ObjIframeContentDto>((resolve, reject) => {
|
||||
if (!ref.contentWindow) return HtmlAttrFactory.EMPTY_RESULT;
|
||||
TinyEventDispatcher.addListener<{ id: string }>(BusMessageType.CONTENT_FETCH_IFRAME_PING, (event, key, value) => {
|
||||
fnConsoleLog('HtmlFactory->fetchIframe->ping->clear', value.id, uid);
|
||||
if (value.id === uid) {
|
||||
TinyEventDispatcher.removeListener(event, key);
|
||||
clearTimeout(iframeTimeout);
|
||||
TinyEventDispatcher.addListener<{ uid: string; depth: number }>(
|
||||
BusMessageType.CONTENT_FETCH_IFRAME_PING,
|
||||
(event, key, value) => {
|
||||
fnConsoleLog('HtmlFactory->fetchIframe->ping->clear', value.uid, uid);
|
||||
if (value.uid === uid && value.depth === depth) {
|
||||
TinyEventDispatcher.removeListener(event, key);
|
||||
clearTimeout(iframeTimeout);
|
||||
ref.contentWindow?.postMessage(
|
||||
IFrameMessageFactory.create({ type: IFrameMessageType.FETCH, data: { depth, uid } }),
|
||||
'*'
|
||||
);
|
||||
}
|
||||
}
|
||||
});
|
||||
);
|
||||
const eventKey = TinyEventDispatcher.addListener<ObjIframeContentDto>(
|
||||
BusMessageType.CONTENT_FETCH_IFRAME_RESULT,
|
||||
(event, key, value) => {
|
||||
if (value.id === uid) {
|
||||
if (value.uid === uid) {
|
||||
fnConsoleLog('HtmlFactory->fetchIframe->result', uid, value.url, value);
|
||||
clearTimeout(iframeTimeout);
|
||||
clearInterval(iframeFetchTimeout);
|
||||
@ -76,11 +84,15 @@ export class IframeFactory {
|
||||
}
|
||||
}
|
||||
);
|
||||
ref.contentWindow.postMessage(`{"foo":"bar", "depth":${depth}, "id":"${uid}"}`, '*');
|
||||
ref.contentWindow.postMessage(
|
||||
IFrameMessageFactory.create({ type: IFrameMessageType.PING, data: { depth, uid } }),
|
||||
'*'
|
||||
);
|
||||
// ref.contentWindow.postMessage(`{"foo":"bar", "depth":${depth}, "id":"${uid}"}`, '*');
|
||||
const iframeTimeout = setTimeout(() => {
|
||||
TinyEventDispatcher.removeListener(BusMessageType.CONTENT_FETCH_IFRAME_RESULT, eventKey);
|
||||
reject(`Iframe timeout ${uid} ${ref.src}`);
|
||||
}, 500);
|
||||
}, 1000);
|
||||
// TODO handle this more gracefully - like ping iframe for status
|
||||
const iframeFetchTimeout = setTimeout(() => {
|
||||
TinyEventDispatcher.removeListener(BusMessageType.CONTENT_FETCH_IFRAME_RESULT, eventKey);
|
||||
|
Loading…
Reference in New Issue
Block a user