Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
import type { IframeMessage } from "../types";
import { EVENTS } from "./customWidgetscript";

export class IframeMessenger {
private iframe: HTMLIFrameElement;

constructor(iframe: HTMLIFrameElement) {
this.iframe = iframe;
}

handleMessage = (
event: MessageEvent,
handlers: Record<string, (data: Record<string, unknown>) => void>,
) => {
const iframeWindow =
this.iframe.contentWindow || this.iframe.contentDocument?.defaultView;

// Without this check, malicious scripts from other windows could inject
// unauthorized messages into our application, potentially leading to data
// breaches or unauthorized state modifications
if (event.source !== iframeWindow) return;

// We send an acknowledgement message for every event to ensure reliable communication
// between the parent window and iframe. This helps in maintaining message ordering
// and preventing race conditions.
this.acknowledgeMessage(event.data);

const handler = handlers[event.data.type];

if (handler) {
handler(event.data.data);
}
};

private acknowledgeMessage(message: IframeMessage) {
this.postMessage({
type: EVENTS.CUSTOM_WIDGET_MESSAGE_RECEIVED_ACK,
key: message.key,
success: true,
});
}

postMessage(message: IframeMessage) {
this.iframe.contentWindow?.postMessage(message, "*");
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// @ts-expect-error - Type error due to raw loader
import css from "!!raw-loader!./reset.css";

// @ts-expect-error - Type error due to raw loader
import script from "!!raw-loader!./customWidgetscript.js";

// @ts-expect-error - Type error due to raw loader
import appsmithConsole from "!!raw-loader!./appsmithConsole.js";

interface CreateHtmlTemplateProps {
cssTokens: string;
onConsole: boolean;
srcDoc: { html: string; js: string; css: string };
}

export const createHtmlTemplate = (props: CreateHtmlTemplateProps) => {
const { cssTokens, onConsole, srcDoc } = props;

return `<html>
<head>
<style>${css}</style>
<style data-appsmith-theme>${cssTokens}</style>
</head>
<body>
${onConsole ? `<script type="text/javascript">${appsmithConsole}</script>` : ""}
<script type="module">
${script}
main();
</script>
${srcDoc.html}
<script type="module">${srcDoc.js}</script>
<style>${srcDoc.css}</style>
</body>
</html>`;
};
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ export const EVENTS = {
CUSTOM_WIDGET_UPDATE_MODEL: "CUSTOM_WIDGET_UPDATE_MODEL",
CUSTOM_WIDGET_TRIGGER_EVENT: "CUSTOM_WIDGET_TRIGGER_EVENT",
CUSTOM_WIDGET_MODEL_CHANGE: "CUSTOM_WIDGET_MODEL_CHANGE",
CUSTOM_WIDGET_UI_CHANGE: "CUSTOM_WIDGET_UI_CHANGE",
CUSTOM_WIDGET_MESSAGE_RECEIVED_ACK: "CUSTOM_WIDGET_MESSAGE_RECEIVED_ACK",
CUSTOM_WIDGET_CONSOLE_EVENT: "CUSTOM_WIDGET_CONSOLE_EVENT",
CUSTOM_WIDGET_THEME_UPDATE: "CUSTOM_WIDGET_THEME_UPDATE",
Expand Down Expand Up @@ -119,7 +118,6 @@ export function main() {
* Variables to hold the subscriber functions
*/
const modelSubscribers = [];
const uiSubscribers = [];
const themeSubscribers = [];
/*
* Variables to hold ready function and state
Expand All @@ -139,15 +137,12 @@ export function main() {
// Callback for when the READY_ACK message is received
channel.onMessage(EVENTS.CUSTOM_WIDGET_READY_ACK, (event) => {
window.appsmith.model = event.model;
window.appsmith.ui = event.ui;
window.appsmith.theme = event.theme;
window.appsmith.mode = event.mode;
heightObserver.observe(window.document.body);

// Subscribe to model and UI changes
window.appsmith.onModelChange(generateAppsmithCssVariables("model"));
window.appsmith.onUiChange(generateAppsmithCssVariables("ui"));
window.appsmith.onThemeChange(generateAppsmithCssVariables("theme"));

// Set the widget as ready
isReady = true;
Expand All @@ -170,18 +165,6 @@ export function main() {
});
}
});
// Callback for when UI_CHANGE message is received
channel.onMessage(EVENTS.CUSTOM_WIDGET_UI_CHANGE, (event) => {
if (event.ui) {
const prevUi = window.appsmith.ui;

window.appsmith.ui = event.ui;
// Notify UI subscribers
uiSubscribers.forEach((fn) => {
fn(event.ui, prevUi);
});
}
});

channel.onMessage(EVENTS.CUSTOM_WIDGET_THEME_UPDATE, (event) => {
if (event.theme) {
Expand Down Expand Up @@ -235,23 +218,6 @@ export function main() {
}
};
},
onUiChange: (fn) => {
if (typeof fn !== "function") {
throw new Error("onUiChange expects a function as parameter");
}

uiSubscribers.push(fn);
fn(window.appsmith.ui);

return () => {
// Unsubscribe from UI changes
const index = uiSubscribers.indexOf(fn);

if (index > -1) {
uiSubscribers.splice(index, 1);
}
};
},
onModelChange: (fn) => {
if (typeof fn !== "function") {
throw new Error("onModelChange expects a function as parameter");
Expand Down Expand Up @@ -296,7 +262,6 @@ export function main() {
});
},
model: {},
ui: {},
onReady: (fn) => {
if (typeof fn !== "function") {
throw new Error("onReady expects a function as parameter");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -165,10 +165,6 @@ describe("CustomWidgetScript", () => {
model: {
test: 1,
},
ui: {
width: 1,
height: 2,
},
mode: "test",
theme: {
color: "#fff",
Expand All @@ -182,11 +178,6 @@ describe("CustomWidgetScript", () => {
test: 1,
});

expect(window.appsmith.ui).toEqual({
width: 1,
height: 2,
});

expect(handler).toHaveBeenCalled();
});

Expand Down
Loading