mirror of
https://github.com/lowdefy/lowdefy.git
synced 2025-03-19 15:01:06 +08:00
feat: Move browser globals to lowdefy._internal.globals.
This commit is contained in:
parent
e2c3291992
commit
94c4016608
packages
client/src
engine/src
operators/src
plugins
actions/actions-core/src/actions
operators/operators-js/src/operators/client
@ -3,6 +3,7 @@ import { createLink } from '@lowdefy/engine';
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
const createLinkComponent = (lowdefy, Link) => {
|
||||
const { window } = lowdefy._internal.globals;
|
||||
const backLink = ({ ariaLabel, children, className, id, rel }) => (
|
||||
<a
|
||||
id={id}
|
||||
|
@ -56,8 +56,11 @@ function initLowdefyContext({ auth, Components, config, router, stage, types, wi
|
||||
lowdefy.urlQuery = urlQuery.parse(window.location.search.slice(1));
|
||||
lowdefy.user = auth?.session?.user ?? null;
|
||||
|
||||
lowdefy._internal.window = window;
|
||||
lowdefy._internal.document = window.document;
|
||||
lowdefy._internal.globals = {
|
||||
document: window.document,
|
||||
fetch: window.fetch,
|
||||
window,
|
||||
};
|
||||
lowdefy._internal.router = router;
|
||||
lowdefy._internal.link = setupLink(lowdefy);
|
||||
lowdefy._internal.updateBlock = (blockId) =>
|
||||
|
@ -17,7 +17,8 @@
|
||||
import { createLink } from '@lowdefy/engine';
|
||||
|
||||
function setupLink(lowdefy) {
|
||||
const { router, window } = lowdefy._internal;
|
||||
const { router } = lowdefy._internal;
|
||||
const { window } = lowdefy._internal.globals;
|
||||
const backLink = () => router.back();
|
||||
const disabledLink = () => {};
|
||||
const newOriginLink = ({ url, query, newTab }) => {
|
||||
|
@ -165,6 +165,7 @@ class Actions {
|
||||
});
|
||||
try {
|
||||
response = await this.actions[action.type]({
|
||||
globals: this.context._internal.lowdefy._internal.globals,
|
||||
methods: getActionMethods({
|
||||
actions: responses,
|
||||
arrayIndices,
|
||||
@ -172,9 +173,7 @@ class Actions {
|
||||
context: this.context,
|
||||
event,
|
||||
}),
|
||||
document: this.context._internal.lowdefy._internal.document,
|
||||
params: parsedAction.params,
|
||||
window: this.context._internal.lowdefy._internal.window,
|
||||
});
|
||||
if (progress) {
|
||||
progress();
|
||||
|
@ -130,6 +130,7 @@ test('operator returns value', () => {
|
||||
"payload": Object {
|
||||
"payload": true,
|
||||
},
|
||||
"runtime": "node",
|
||||
"secrets": Object {
|
||||
"secrets": true,
|
||||
},
|
||||
|
@ -56,6 +56,7 @@ class WebParser {
|
||||
basePath,
|
||||
event,
|
||||
eventLog: this.context.eventLog,
|
||||
globals: _internal.globals,
|
||||
home,
|
||||
input: inputs ? inputs[this.context.id] : {},
|
||||
location: applyArrayIndices(arrayIndices, location),
|
||||
@ -72,7 +73,6 @@ class WebParser {
|
||||
state: this.context.state,
|
||||
urlQuery: urlQuery ?? {},
|
||||
user: user ?? {},
|
||||
window: _internal.window,
|
||||
});
|
||||
return res;
|
||||
} catch (e) {
|
||||
|
@ -39,17 +39,19 @@ const context = {
|
||||
configured: false,
|
||||
},
|
||||
_internal: {
|
||||
window: {
|
||||
location: {
|
||||
hash: 'window.location.hash',
|
||||
host: 'window.location.host',
|
||||
hostname: 'window.location.hostname',
|
||||
href: 'window.location.href',
|
||||
origin: 'window.location.origin',
|
||||
pathname: 'window.location.pathname',
|
||||
port: 'window.location.port',
|
||||
protocol: 'window.location.protocol',
|
||||
search: 'window.location.search',
|
||||
globals: {
|
||||
window: {
|
||||
location: {
|
||||
hash: 'window.location.hash',
|
||||
host: 'window.location.host',
|
||||
hostname: 'window.location.hostname',
|
||||
href: 'window.location.href',
|
||||
origin: 'window.location.origin',
|
||||
pathname: 'window.location.pathname',
|
||||
port: 'window.location.port',
|
||||
protocol: 'window.location.protocol',
|
||||
search: 'window.location.search',
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -137,6 +139,21 @@ test('operator returns value', () => {
|
||||
"eventLog": true,
|
||||
},
|
||||
],
|
||||
"globals": Object {
|
||||
"window": Object {
|
||||
"location": Object {
|
||||
"hash": "window.location.hash",
|
||||
"host": "window.location.host",
|
||||
"hostname": "window.location.hostname",
|
||||
"href": "window.location.href",
|
||||
"origin": "window.location.origin",
|
||||
"pathname": "window.location.pathname",
|
||||
"port": "window.location.port",
|
||||
"protocol": "window.location.protocol",
|
||||
"search": "window.location.search",
|
||||
},
|
||||
},
|
||||
},
|
||||
"home": Object {
|
||||
"configured": false,
|
||||
"pageId": "home.pageId",
|
||||
@ -175,17 +192,19 @@ test('operator returns value', () => {
|
||||
"_internal": Object {
|
||||
"lowdefy": Object {
|
||||
"_internal": Object {
|
||||
"window": Object {
|
||||
"location": Object {
|
||||
"hash": "window.location.hash",
|
||||
"host": "window.location.host",
|
||||
"hostname": "window.location.hostname",
|
||||
"href": "window.location.href",
|
||||
"origin": "window.location.origin",
|
||||
"pathname": "window.location.pathname",
|
||||
"port": "window.location.port",
|
||||
"protocol": "window.location.protocol",
|
||||
"search": "window.location.search",
|
||||
"globals": Object {
|
||||
"window": Object {
|
||||
"location": Object {
|
||||
"hash": "window.location.hash",
|
||||
"host": "window.location.host",
|
||||
"hostname": "window.location.hostname",
|
||||
"href": "window.location.href",
|
||||
"origin": "window.location.origin",
|
||||
"pathname": "window.location.pathname",
|
||||
"port": "window.location.port",
|
||||
"protocol": "window.location.protocol",
|
||||
"search": "window.location.search",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
@ -248,6 +267,7 @@ test('operator returns value', () => {
|
||||
"requests": true,
|
||||
},
|
||||
],
|
||||
"runtime": "browser",
|
||||
"state": Object {
|
||||
"state": true,
|
||||
},
|
||||
@ -257,19 +277,6 @@ test('operator returns value', () => {
|
||||
"user": Object {
|
||||
"user": true,
|
||||
},
|
||||
"window": Object {
|
||||
"location": Object {
|
||||
"hash": "window.location.hash",
|
||||
"host": "window.location.host",
|
||||
"hostname": "window.location.hostname",
|
||||
"href": "window.location.href",
|
||||
"origin": "window.location.origin",
|
||||
"pathname": "window.location.pathname",
|
||||
"port": "window.location.port",
|
||||
"protocol": "window.location.protocol",
|
||||
"search": "window.location.search",
|
||||
},
|
||||
},
|
||||
},
|
||||
],
|
||||
]
|
||||
|
@ -16,7 +16,8 @@
|
||||
|
||||
import { type } from '@lowdefy/helpers';
|
||||
|
||||
function ScrollTo({ document, params, window }) {
|
||||
function ScrollTo({ globals, params }) {
|
||||
const { document, window } = globals;
|
||||
if (!type.isObject(params)) {
|
||||
throw new Error(`Invalid ScrollTo, check action params. Received "${JSON.stringify(params)}".`);
|
||||
}
|
||||
|
@ -34,14 +34,16 @@ const window = {
|
||||
scrollTo: mockWindowScrollTo,
|
||||
};
|
||||
|
||||
const globals = { document, window };
|
||||
|
||||
test('ScrollTo with no params', async () => {
|
||||
expect(() => ScrollTo({ document, window })).toThrow(
|
||||
expect(() => ScrollTo({ globals })).toThrow(
|
||||
'Invalid ScrollTo, check action params. Received "undefined".'
|
||||
);
|
||||
});
|
||||
|
||||
test('ScrollTo with no blockId', async () => {
|
||||
ScrollTo({ document, window, params: { behavior: 'smooth', top: 0 } });
|
||||
ScrollTo({ globals, params: { behavior: 'smooth', top: 0 } });
|
||||
expect(mockWindowScrollTo.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
@ -56,7 +58,7 @@ test('ScrollTo with blockId', async () => {
|
||||
mockDocGetElementById.mockImplementation((id) => {
|
||||
if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView };
|
||||
});
|
||||
ScrollTo({ document, window, params: { blockId: 'blockId' } });
|
||||
ScrollTo({ globals, params: { blockId: 'blockId' } });
|
||||
expect(mockDocGetElementById.mock.calls).toEqual([['blockId']]);
|
||||
expect(mockElemScrollIntoView.mock.calls).toEqual([[undefined]]);
|
||||
});
|
||||
@ -65,7 +67,7 @@ test('ScrollTo with blockId and options', async () => {
|
||||
mockDocGetElementById.mockImplementation((id) => {
|
||||
if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView };
|
||||
});
|
||||
ScrollTo({ document, window, params: { blockId: 'blockId', options: { behavior: 'smooth' } } });
|
||||
ScrollTo({ globals, params: { blockId: 'blockId', options: { behavior: 'smooth' } } });
|
||||
expect(mockDocGetElementById.mock.calls).toEqual([['blockId']]);
|
||||
expect(mockElemScrollIntoView.mock.calls).toEqual([[{ behavior: 'smooth' }]]);
|
||||
});
|
||||
@ -74,7 +76,7 @@ test('ScrollTo with blockId, block not found', async () => {
|
||||
mockDocGetElementById.mockImplementation((id) => {
|
||||
if (id === 'blockId') return { id, scrollIntoView: mockElemScrollIntoView };
|
||||
});
|
||||
ScrollTo({ document, window, params: { blockId: 'not_there' } });
|
||||
ScrollTo({ globals, params: { blockId: 'not_there' } });
|
||||
expect(mockDocGetElementById.mock.calls).toEqual([['not_there']]);
|
||||
expect(mockElemScrollIntoView.mock.calls).toEqual([]);
|
||||
expect(mockWindowScrollTo.mock.calls).toEqual([]);
|
||||
|
@ -31,7 +31,8 @@ const validProperties = [
|
||||
'search',
|
||||
];
|
||||
|
||||
function _location({ arrayIndices, basePath, home, location, pageId, params, window }) {
|
||||
function _location({ arrayIndices, basePath, home, location, pageId, params, globals }) {
|
||||
const { window } = globals;
|
||||
if (!window?.location) {
|
||||
throw new Error(
|
||||
`Operator Error: Browser window.location not available for _location. Received: ${JSON.stringify(
|
||||
|
@ -34,6 +34,8 @@ const window = {
|
||||
},
|
||||
};
|
||||
|
||||
const globals = { window };
|
||||
|
||||
const input = {
|
||||
arrayIndices: [0],
|
||||
basePath: 'base',
|
||||
@ -48,7 +50,7 @@ const input = {
|
||||
|
||||
test('location calls getFromObject', async () => {
|
||||
const lowdefyOperators = await import('@lowdefy/operators');
|
||||
location({ ...input, window });
|
||||
location({ ...input, globals });
|
||||
expect(lowdefyOperators.getFromObject.mock.calls).toEqual([
|
||||
[
|
||||
{
|
||||
@ -76,19 +78,19 @@ test('location calls getFromObject', async () => {
|
||||
});
|
||||
|
||||
test('_location throw on no window', () => {
|
||||
expect(() => location(input)).toThrow(
|
||||
expect(() => location({ ...input, globals: {} })).toThrow(
|
||||
'Operator Error: Browser window.location not available for _location. Received: "origin" at location.'
|
||||
);
|
||||
});
|
||||
|
||||
test('_location throw on no location', () => {
|
||||
expect(() => location({ ...input, window: {} })).toThrow(
|
||||
expect(() => location({ ...input, globals: { window: {} } })).toThrow(
|
||||
'Operator Error: Browser window.location not available for _location. Received: "origin" at location.'
|
||||
);
|
||||
});
|
||||
|
||||
test('_location throw invalid param', () => {
|
||||
expect(() => location({ ...input, window, params: 'invalid' })).toThrow(
|
||||
expect(() => location({ ...input, globals, params: 'invalid' })).toThrow(
|
||||
'Operator Error: _location only returns values for basePath, hash, homePageId, host, hostname, href, origin, pageId, pathname, port, protocol, search. Received: "invalid" at location.'
|
||||
);
|
||||
});
|
||||
|
@ -24,7 +24,8 @@ const breakpoints = {
|
||||
xl: 1600,
|
||||
};
|
||||
|
||||
function _media({ arrayIndices, location, params, window }) {
|
||||
function _media({ arrayIndices, location, params, globals }) {
|
||||
const { window } = globals;
|
||||
if (!window?.innerWidth) {
|
||||
throw new Error(
|
||||
`Operator Error: device window width not available for _media. Received: ${JSON.stringify(
|
||||
|
@ -20,9 +20,10 @@ import media from './media.js';
|
||||
console.error = () => {};
|
||||
|
||||
const window = { innerHeight: 300, innerWidth: 500 };
|
||||
const globals = { window };
|
||||
|
||||
test('_media full media object', () => {
|
||||
expect(media({ params: true, location: 'locationId', window })).toEqual({
|
||||
expect(media({ params: true, location: 'locationId', globals })).toEqual({
|
||||
height: 300,
|
||||
size: 'xs',
|
||||
width: 500,
|
||||
@ -31,47 +32,59 @@ test('_media full media object', () => {
|
||||
|
||||
test('_media size', () => {
|
||||
expect(
|
||||
media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 500 } })
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
globals: { window: { innerHeight: 300, innerWidth: 500 } },
|
||||
})
|
||||
).toEqual('xs');
|
||||
expect(
|
||||
media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 700 } })
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
globals: { window: { innerHeight: 300, innerWidth: 700 } },
|
||||
})
|
||||
).toEqual('sm');
|
||||
expect(
|
||||
media({ params: 'size', location: 'locationId', window: { innerHeight: 300, innerWidth: 900 } })
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
globals: { window: { innerHeight: 300, innerWidth: 900 } },
|
||||
})
|
||||
).toEqual('md');
|
||||
expect(
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
window: { innerHeight: 300, innerWidth: 1100 },
|
||||
globals: { window: { innerHeight: 300, innerWidth: 1100 } },
|
||||
})
|
||||
).toEqual('lg');
|
||||
expect(
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
window: { innerHeight: 300, innerWidth: 1400 },
|
||||
globals: { window: { innerHeight: 300, innerWidth: 1400 } },
|
||||
})
|
||||
).toEqual('xl');
|
||||
expect(
|
||||
media({
|
||||
params: 'size',
|
||||
location: 'locationId',
|
||||
window: { innerHeight: 300, innerWidth: 1900 },
|
||||
globals: { window: { innerHeight: 300, innerWidth: 1900 } },
|
||||
})
|
||||
).toEqual('xxl');
|
||||
});
|
||||
|
||||
test('_media width', () => {
|
||||
expect(media({ params: 'width', location: 'locationId', window })).toEqual(500);
|
||||
expect(media({ params: 'width', location: 'locationId', globals })).toEqual(500);
|
||||
});
|
||||
|
||||
test('_media height', () => {
|
||||
expect(media({ params: 'height', location: 'locationId', window })).toEqual(300);
|
||||
expect(media({ params: 'height', location: 'locationId', globals })).toEqual(300);
|
||||
});
|
||||
|
||||
test('_media throw on no innerWidth', () => {
|
||||
expect(() => media({ params: true, location: 'locationId', window: {} })).toThrow(
|
||||
expect(() => media({ params: true, location: 'locationId', globals: { window: {} } })).toThrow(
|
||||
'Operator Error: device window width not available for _media. Received: true at locationId.'
|
||||
);
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user