diff --git a/.changeset/busy-hounds-take.md b/.changeset/busy-hounds-take.md new file mode 100644 index 0000000000..de47cd29fd --- /dev/null +++ b/.changeset/busy-hounds-take.md @@ -0,0 +1,13 @@ +--- +"@lynx-js/web-mainthread-apis": patch +"@lynx-js/web-worker-runtime": patch +"@lynx-js/web-core": patch +--- + +feat: allow lynx code to get JS engine provided properties on globalThis + +``` +globalThis.Reflect; // this will be the Reflect Object +``` + +Note that `assigning to the globalThis` is still not allowed. diff --git a/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts b/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts index 936637ffba..421abe2856 100644 --- a/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts +++ b/packages/web-platform/web-mainthread-apis/src/MainThreadRuntime.ts @@ -205,9 +205,20 @@ export class MainThreadRuntime { */ __lynxGlobalBindingValues: Record = {}; - get globalThis() { - return this; - } + globalThis = new Proxy(this, { + get: (target, prop) => { + // @ts-expect-error + return target[prop] ?? globalThis[prop]; + }, + set: (target, prop, value) => { + // @ts-expect-error + target[prop] = value; + return true; + }, + ownKeys(target) { + return Reflect.ownKeys(target).filter((key) => key !== 'globalThis'); + }, + }); SystemInfo: typeof systemInfo; diff --git a/packages/web-platform/web-mainthread-apis/src/loadMainThread.ts b/packages/web-platform/web-mainthread-apis/src/loadMainThread.ts index a1062e2ce6..421ab2567f 100644 --- a/packages/web-platform/web-mainthread-apis/src/loadMainThread.ts +++ b/packages/web-platform/web-mainthread-apis/src/loadMainThread.ts @@ -169,7 +169,7 @@ export function loadMainThread( publicComponentEvent, postExposure, }, - }).globalThis; + }); markTimingInternal('decode_end'); entry!(runtime); jsContext.__start(); // start the jsContext after the runtime is created diff --git a/packages/web-platform/web-tests/shell-project/mainthread-test.ts b/packages/web-platform/web-tests/shell-project/mainthread-test.ts index f77e864eff..31360ed03e 100644 --- a/packages/web-platform/web-tests/shell-project/mainthread-test.ts +++ b/packages/web-platform/web-tests/shell-project/mainthread-test.ts @@ -135,7 +135,7 @@ function initializeMainThreadTest() { }, postExposure: () => {}, }, - }); + }).globalThis; Object.assign(globalThis, runtime); Object.assign(globalThis, { genFiberElementTree, diff --git a/packages/web-platform/web-tests/tests/react.spec.ts b/packages/web-platform/web-tests/tests/react.spec.ts index d8a0c072b4..364498c59f 100644 --- a/packages/web-platform/web-tests/tests/react.spec.ts +++ b/packages/web-platform/web-tests/tests/react.spec.ts @@ -387,6 +387,16 @@ test.describe('reactlynx3 tests', () => { await wait(100); await expect(page.locator('#target')).toHaveCSS('color', 'rgb(0, 0, 0)'); }); + test('basic-globalThis-property-bts', async ({ page }, { title }) => { + await goto(page, title); + await wait(100); + await expect(page.locator('#target')).toHaveCSS('color', 'rgb(0, 0, 0)'); + }); + test('basic-globalThis-property-mts', async ({ page }, { title }) => { + await goto(page, title); + await wait(100); + await expect(page.locator('#target')).toHaveCSS('color', 'rgb(0, 0, 0)'); + }); }); test.describe('apis', () => { test('api-custom-template-loader', async ({ page }, { title }) => { diff --git a/packages/web-platform/web-tests/tests/react/basic-globalThis-property-bts/index.jsx b/packages/web-platform/web-tests/tests/react/basic-globalThis-property-bts/index.jsx new file mode 100644 index 0000000000..c1211e3bb7 --- /dev/null +++ b/packages/web-platform/web-tests/tests/react/basic-globalThis-property-bts/index.jsx @@ -0,0 +1,19 @@ +// Copyright 2023 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { root } from '@lynx-js/react'; + +function App() { + return ( + + ); +} + +root.render(); diff --git a/packages/web-platform/web-tests/tests/react/basic-globalThis-property-mts/index.jsx b/packages/web-platform/web-tests/tests/react/basic-globalThis-property-mts/index.jsx new file mode 100644 index 0000000000..85f1af63d4 --- /dev/null +++ b/packages/web-platform/web-tests/tests/react/basic-globalThis-property-mts/index.jsx @@ -0,0 +1,23 @@ +// Copyright 2023 The Lynx Authors. All rights reserved. +// Licensed under the Apache License Version 2.0 that can be found in the +// LICENSE file in the root directory of this source tree. +import { useState, root, useEffect } from '@lynx-js/react'; +function App() { + const [color, setColor] = useState('pink'); + useEffect(() => { + if (globalThis.Object) { + setColor('green'); + } + }, []); + return ( + + ); +} +root.render(); diff --git a/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts b/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts index 3b55553d60..a8acf1db79 100644 --- a/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts +++ b/packages/web-platform/web-worker-runtime/src/backgroundThread/background-apis/createNativeApp.ts @@ -66,7 +66,22 @@ export async function createNativeApp(config: { return { init: (lynxCoreInject) => { lynxCoreInject.tt.lynxCoreInject = lynxCoreInject; - lynxCoreInject.tt.globalThis ??= lynxCoreInject; + lynxCoreInject.tt.globalThis ??= new Proxy(lynxCoreInject, { + get(target, prop) { + // @ts-expect-error + return target[prop] ?? globalThis[prop]; + }, + set(target, prop, value) { + // @ts-expect-error + target[prop] = value; + return true; + }, + ownKeys(target) { + return Reflect.ownKeys(target).filter((key) => + key !== 'globalThis' + ); + }, + }); Object.assign(lynxCoreInject.tt, { SystemInfo: { ...systemInfo, ...browserConfig }, });