Skip to content

Commit

Permalink
feat: cache document.visibilityState
Browse files Browse the repository at this point in the history
  • Loading branch information
adamdbradley committed Mar 7, 2022
1 parent 29faada commit 026661c
Show file tree
Hide file tree
Showing 10 changed files with 46 additions and 8 deletions.
1 change: 1 addition & 0 deletions scripts/minify.ts
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,7 @@ function managlePropsPlugin(): Plugin {
$tasks$: '',
$thisArg$: '',
$url$: '',
$visibilityState$: '',
$window$: '',
$winId$: '',
};
Expand Down
4 changes: 4 additions & 0 deletions src/lib/sandbox/main-register-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ export const registerWindow = (
$winId$,
$parentWinId$,
$url$: doc.baseURI,
$visibilityState$: doc.visibilityState,
},
]);

Expand All @@ -48,6 +49,9 @@ export const registerWindow = (

$window$.addEventListener('popstate', onLocationChange);
$window$.addEventListener('hashchange', onLocationChange);
doc.addEventListener('visibilitychange', () =>
worker.postMessage([WorkerMessageType.DocumentVisibilityState, $winId$, doc.visibilityState])
);

winCtxs[$winId$] = {
$winId$,
Expand Down
6 changes: 5 additions & 1 deletion src/lib/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export type MessageFromSandboxToWorker =
| [type: WorkerMessageType.InitializedScripts, winId: WinId]
| [type: WorkerMessageType.RefHandlerCallback, callbackData: RefHandlerCallbackData]
| [type: WorkerMessageType.ForwardMainTrigger, triggerData: ForwardMainTriggerData]
| [type: WorkerMessageType.LocationUpdate, winId: WinId, documentBaseURI: string];
| [type: WorkerMessageType.LocationUpdate, winId: WinId, documentBaseURI: string]
| [type: WorkerMessageType.DocumentVisibilityState, winId: WinId, visibilityState: string];

export const enum WorkerMessageType {
MainDataRequestFromWorker,
Expand All @@ -57,6 +58,7 @@ export const enum WorkerMessageType {
ForwardWorkerAccessRequest,
AsyncAccessRequest,
LocationUpdate,
DocumentVisibilityState,
}

export interface ForwardMainTriggerData {
Expand Down Expand Up @@ -138,6 +140,7 @@ export interface InitializeEnvironmentData {
$winId$: WinId;
$parentWinId$: WinId;
$url$: string;
$visibilityState$?: string;
}

export interface WebWorkerEnvironment {
Expand All @@ -149,6 +152,7 @@ export interface WebWorkerEnvironment {
$head$: HTMLElement;
$body$: HTMLElement;
$location$: Location;
$visibilityState$?: string;
$createNode$: (nodeName: string, instanceId: InstanceId, namespace?: string) => WorkerNode;
$currentScriptId$?: InstanceId;
$isInitialized$?: number;
Expand Down
6 changes: 4 additions & 2 deletions src/lib/web-worker/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -36,13 +36,15 @@ const receiveMessageFromSandboxToWorker = (ev: MessageEvent<MessageFromSandboxTo

environments[msgValue].$isInitialized$ = 1;
environments[msgValue].$isLoading$ = 0;
} else if (msgType === WorkerMessageType.DocumentVisibilityState) {
environments[msgValue].$visibilityState$ = msg[2];
} else if (msgType === WorkerMessageType.LocationUpdate) {
environments[msg[1]].$location$.href = msg[2];
environments[msgValue].$location$.href = msg[2];
}
} else if (msgType === WorkerMessageType.MainDataResponseToWorker) {
// received initial main data
// initialize the web worker with the received the main data
initWebWorker(msg[1]);
initWebWorker(msgValue);

// send to the main thread that the web worker has been initialized
webWorkerCtx.$postMessage$([WorkerMessageType.InitializedWebWorker]);
Expand Down
6 changes: 5 additions & 1 deletion src/lib/web-worker/worker-document.ts
Original file line number Diff line number Diff line change
Expand Up @@ -185,7 +185,7 @@ export const patchDocument = (
CallType.Blocking,
docId
);
const docEnv = createWindow(winId, winId, env.$location$ + '', true, true);
const docEnv = createWindow(winId, winId, env.$location$ + '', 'hidden', true, true);
return docEnv.$document$;
},
};
Expand Down Expand Up @@ -216,6 +216,10 @@ export const patchDocument = (
readyState: {
value: 'complete',
},

visibilityState: {
get: () => env.$visibilityState$ || 'visible',
},
};

definePrototypePropertyDescriptor(WorkerDocument, DocumentDescriptorMap);
Expand Down
10 changes: 8 additions & 2 deletions src/lib/web-worker/worker-environment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,19 @@ import { InitializeEnvironmentData, WorkerMessageType } from '../types';
import { logWorker, normalizedWinId } from '../log';

export const createEnvironment = (
{ $winId$, $parentWinId$, $url$ }: InitializeEnvironmentData,
{ $winId$, $parentWinId$, $url$, $visibilityState$ }: InitializeEnvironmentData,
isIframeWindow?: boolean
) => {
if (!environments[$winId$]) {
// create a simulated global environment for this window
// if it hasn't already been created (like an iframe)
environments[$winId$] = createWindow($winId$, $parentWinId$, $url$, isIframeWindow);
environments[$winId$] = createWindow(
$winId$,
$parentWinId$,
$url$,
$visibilityState$,
isIframeWindow
);

if (debug) {
const winType = $winId$ === $parentWinId$ ? 'top' : 'iframe';
Expand Down
2 changes: 2 additions & 0 deletions src/lib/web-worker/worker-window.ts
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ export const createWindow = (
$winId$: WinId,
$parentWinId$: WinId,
url: string,
$visibilityState$?: string,
isIframeWindow?: boolean,
isDocumentImplementation?: boolean
) => {
Expand Down Expand Up @@ -344,6 +345,7 @@ export const createWindow = (
$head$: $createNode$(NodeName.Head, $winId$ + WinDocId.head) as any,
$body$: $createNode$(NodeName.Body, $winId$ + WinDocId.body) as any,
$location$,
$visibilityState$,
$createNode$,
});

Expand Down
5 changes: 4 additions & 1 deletion tests/platform/document/document.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,5 +89,8 @@ test('document', async ({ page }) => {
await expect(testCreateElementError).toHaveText('errored');

const testCreateHTMLDocument = page.locator('#testCreateHTMLDocument');
await expect(testCreateHTMLDocument).toHaveText('88mph');
await expect(testCreateHTMLDocument).toHaveText('88mph hidden');

const testVisibilityState = page.locator('#testVisibilityState');
await expect(testVisibilityState).toHaveText('visible');
});
13 changes: 12 additions & 1 deletion tests/platform/document/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -416,14 +416,25 @@ <h1 class="title">Document</h1>
<script type="text/partytown">
(function () {
const doc = document.implementation.createHTMLDocument();
doc.body.textContent = '88mph';
doc.body.textContent = '88mph ' + doc.visibilityState;

const elm = document.getElementById('testCreateHTMLDocument');
elm.textContent = doc.body.textContent;
})();
</script>
</li>

<li>
<strong>visibilityState</strong>
<code id="testVisibilityState"></code>
<script type="text/partytown">
(function () {
const elm = document.getElementById('testVisibilityState');
elm.textContent = document.visibilityState;
})();
</script>
</li>

<script type="text/partytown">
(function () {
document.body.classList.add('completed');
Expand Down
1 change: 1 addition & 0 deletions tests/unit/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ function createWorkerWindownEnvironment(winId: WinId) {
$head$: {} as any,
$body$: {} as any,
$location$: {} as any,
$visibilityState$: 'visible',
$createNode$: () => null as any,
};

Expand Down

1 comment on commit 026661c

@vercel
Copy link

@vercel vercel bot commented on 026661c Mar 7, 2022

Choose a reason for hiding this comment

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

Please sign in to comment.