Skip to content

Commit

Permalink
feat: run whitelisted inline scripts on main thread (#235)
Browse files Browse the repository at this point in the history
  • Loading branch information
slawekkolodziej committed Aug 29, 2022
1 parent 8b20c66 commit 5e8955c
Show file tree
Hide file tree
Showing 5 changed files with 49 additions and 9 deletions.
2 changes: 1 addition & 1 deletion docs/configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Partytown does not require a config for it to work, however a config can be set
| `debug` | When `true`, Partytown scripts are not inlined and not minified. See the [Debugging](/debugging) docs on how to enable more logging. |
| `forward` | An array of strings representing function calls on the main thread to forward to the web worker. See [Forwarding Events and Triggers](/forwarding-events) for more info. |
| `lib` | Path where the Partytown library can be found your server. Note that the path must both start and end with a `/` character, and the files must be hosted from the same origin as the webpage. Default is `/~partytown/` |
| `loadScriptsOnMainThread` | An array of strings used to filter out which script are executed via Partytown and the main thread. An example is as follows: `loadScriptsOnMainThread: ["https://test.com/analytics.js"]`.|
| `loadScriptsOnMainThread` | An array of strings used to filter out which script are executed via Partytown and the main thread. An example is as follows: `loadScriptsOnMainThread: ["https://test.com/analytics.js", "inline-script-id"]`.|
| `resolveUrl` | Hook that is called to resolve URLs which can be used to modify URLs. The hook uses the API: `resolveUrl(url: URL, location: URL, method: string)`. See the [Proxying Requests](/proxying-requests) for more information. |

## Vanilla Config
Expand Down
4 changes: 2 additions & 2 deletions src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -429,8 +429,8 @@ export interface PartytownConfig {
* This array can be used to filter which script are executed via
* Partytown and which you would like to execute on the main thread.
*
* @example loadScriptsOnMainThread:['https://test.com/analytics.js']
* // Loads the `https://test.com/analytics.js` script on the main thread
* @example loadScriptsOnMainThread:['https://test.com/analytics.js', 'inline-script-id']
* // Loads the `https://test.com/analytics.js` script on the main thread
*/
loadScriptsOnMainThread?: string[]
get?: GetHook;
Expand Down
20 changes: 15 additions & 5 deletions src/lib/web-worker/worker-node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ export const createNodeCstr = (
env: WebWorkerEnvironment,
WorkerBase: WorkerConstructor
) => {
const config = webWorkerCtx.$config$;

const WorkerNode = defineConstructorName(
class extends WorkerBase {
appendChild(node: WorkerNode) {
Expand Down Expand Up @@ -54,11 +56,19 @@ export const createNodeCstr = (

if (scriptContent) {
if (isScriptJsType(scriptType)) {
const errorMsg = runScriptContent(env, instanceId, scriptContent, winId, '');
const datasetType = errorMsg ? 'pterror' : 'ptid';
const datasetValue = errorMsg || instanceId;
setter(newNode, ['type'], SCRIPT_TYPE + SCRIPT_TYPE_EXEC);
setter(newNode, ['dataset', datasetType], datasetValue);
// @ts-ignore
const scriptId = newNode.id;
const loadOnMainThread = scriptId && config.loadScriptsOnMainThread?.includes?.(scriptId);

if (loadOnMainThread) {
setter(newNode, ['type'], 'text/javascript');
} else {
const errorMsg = runScriptContent(env, instanceId, scriptContent, winId, '');
const datasetType = errorMsg ? 'pterror' : 'ptid';
const datasetValue = errorMsg || instanceId;
setter(newNode, ['type'], SCRIPT_TYPE + SCRIPT_TYPE_EXEC);
setter(newNode, ['dataset', datasetType], datasetValue);
}
}
setter(newNode, ['innerHTML'], scriptContent);
}
Expand Down
28 changes: 27 additions & 1 deletion tests/integrations/load-scripts-on-main-thread/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@
logSetters: true,
logStackTraces: false,
logScriptExecution: true,
loadScriptsOnMainThread: [`http://${location.host}/tests/integrations/load-scripts-on-main-thread/test-script.js`],
loadScriptsOnMainThread: [
`http://${location.host}/tests/integrations/load-scripts-on-main-thread/test-script.js`,
`inline-test-script`
],
};
</script>
<script src='/~partytown/debug/partytown.js'></script>
Expand Down Expand Up @@ -112,6 +115,29 @@ <h1>Load scripts on main thread 馃帀</h1>
})()
</script>
</li>

<li>
<strong>Inline script</strong>
<code id="testInlineScript"></code>
<script type="text/javascript">const globalVariable = 12;</script>
<script type="text/partytown">
(function () {
const script = document.createElement('script');

script.type = "text/javascript";
script.id = "inline-test-script";
script.innerHTML = `
document.getElementById('testInlineScript');
const testEl = document.getElementById('testInlineScript');
testEl.className = 'testInlineScript';
testEl.innerHTML = globalVariable;
`;

document.body.appendChild(script);
})();
</script>
</li>
</ul>

<hr />
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,8 @@ test('integration window accessor', async ({ page }) => {

const scriptElement = page.locator('#testScript');
await expect(scriptElement).toHaveAttribute('type', 'text/javascript')

await page.waitForSelector('.testInlineScript');
const testInlineScript = page.locator('#testInlineScript');
await expect(testInlineScript).toHaveText('12');
});

0 comments on commit 5e8955c

Please sign in to comment.