2
0
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:
Sam 2022-06-24 12:32:44 +02:00
parent e2c3291992
commit 94c4016608
No known key found for this signature in database
GPG Key ID: D004126FCD1A6DF0
13 changed files with 95 additions and 63 deletions

@ -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.'
);
});