Skip to content
Open
Show file tree
Hide file tree
Changes from 5 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
4 changes: 2 additions & 2 deletions apps/kitchen-sink/src/ensemble/scripts/common.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
const productTitleName = "SgrDvr";

const getDateLabel = (val) => {
return `i am a date label ${val}`
}
return `i am a date label ${val}`;
};
41 changes: 17 additions & 24 deletions packages/framework/src/evaluate/evaluate.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@ export const widgetStatesToInvokables = (widgets: {
});
};

interface InvokableWindow extends Window {
[key: string]: unknown;
}

export const buildEvaluateFn = (
screen: Partial<ScreenContextDefinition>,
js?: string,
Expand All @@ -38,14 +42,21 @@ export const buildEvaluateFn = (
// Need to filter out invalid JS identifiers
].filter(([key, _]) => !key.includes(".")),
);
const globalBlock = screen.model?.global;
const importedScriptBlock = screen.model?.importedScripts;

const args = Object.keys(invokableObj).join(",");

const combinedJs = `
return myScreenScope(() => {
${formatJs(js)};
}, {${args}});
`;

Object.entries(invokableObj).forEach(([key, value]) => {
(window as unknown as InvokableWindow)[key] = value;
});

// eslint-disable-next-line @typescript-eslint/no-implied-eval, no-new-func
const jsFunc = new Function(
...Object.keys(invokableObj),
addScriptBlock(formatJs(js), globalBlock, importedScriptBlock),
);
const jsFunc = new Function(...Object.keys(invokableObj), combinedJs);

// eslint-disable-next-line @typescript-eslint/no-unsafe-return
return () => jsFunc(...Object.values(invokableObj));
Expand Down Expand Up @@ -80,24 +91,6 @@ const formatJs = (js?: string): string => {
return `return ${sanitizedJs}`;
};

const addScriptBlock = (
js: string,
globalBlock?: string,
importedScriptBlock?: string,
): string => {
let jsString = ``;

if (importedScriptBlock) {
jsString += `${importedScriptBlock}\n\n`;
}

if (globalBlock) {
jsString += `${globalBlock}\n\n`;
}

return (jsString += `${js}`);
};

/**
* @deprecated Consider using useEvaluate or createBinding which will
* optimize creating the evaluation context
Expand Down
29 changes: 29 additions & 0 deletions packages/runtime/src/runtime/screen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,35 @@ export const EnsembleScreen: React.FC<EnsembleScreenProps> = ({
};
}, [screen.customWidgets]);

useEffect(() => {
const globalBlock = screen.global;
const importedScripts = screen.importedScripts;

const isScriptExist = document.getElementById("custom-scope-script");
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This needs to be unique per screen.


const jsString = `
${importedScripts || ""}
${globalBlock || ""}

const myScreenScope = function(scriptToExecute, context) {
with (context) {
return eval('(' + scriptToExecute.toString() + ')()');
}
}
`;

if (isScriptExist) {
isScriptExist.textContent = jsString;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not rerun the script, you need to remove the node and reinsert it.

} else {
const script = document.createElement("script");
script.id = "custom-scope-script";
script.type = "text/javascript";
script.textContent = jsString;

document.body.appendChild(script);
}
}, [screen.global, screen.importedScripts]);

if (!isInitialized) {
return null;
}
Expand Down
Loading