Skip to content

Commit adefe0f

Browse files
committed
Merge branch 'release-2.19.0' into release
2 parents c458c49 + 8b4885a commit adefe0f

File tree

110 files changed

+10739
-5305
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

110 files changed

+10739
-5305
lines changed

.eslintrc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -135,7 +135,7 @@
135135
"import/no-extraneous-dependencies": "off",
136136
"no-unused-vars": "off",
137137
"import/no-default-export": "warn",
138-
"no-underscore-dangle": "warn",
138+
"no-underscore-dangle": "off",
139139
"react/require-default-props": "off",
140140
"no-shadow": "off",
141141
"@typescript-eslint/no-shadow": "error"

.github/workflows/test.yml

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,12 @@ jobs:
77
name: Test and lint code base
88
runs-on: ubuntu-latest
99
steps:
10-
- uses: actions/checkout@v2
11-
- name: Use Node.js
12-
uses: actions/setup-node@v1
13-
with:
14-
node-version: '18.20.x'
15-
- run: npm install
16-
- run: npm run test
17-
- run: npm run lint
18-
19-
10+
- uses: actions/checkout@v2
11+
- name: Use Node.js
12+
uses: actions/setup-node@v1
13+
with:
14+
node-version: '18.20.x'
15+
- run: npm install
16+
- run: npm run test
17+
- run: npm run typecheck
18+
- run: npm run lint

.storybook/preview.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,14 +2,14 @@ import React from 'react';
22
import { Provider } from 'react-redux';
33
import { MemoryRouter } from 'react-router';
44

5-
import configureStore from '../client/store';
5+
import { setupStore } from '../client/store';
66
import '../client/i18n-test';
7-
import '../client/styles/storybook.css'
7+
import '../client/styles/storybook.css';
88
import { withThemeProvider, themeToolbarItem } from './decorator-theme';
99

1010
const initialState = window.__INITIAL_STATE__;
1111

12-
const store = configureStore(initialState);
12+
const store = setupStore(initialState);
1313

1414
export const decorators = [
1515
(Story) => (

README.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -10,45 +10,36 @@ We are a community of, and in solidarity with, people from every gender identity
1010

1111
Learn more about [our community](https://p5js.org/community/) and read our [Community Statement and Code of Conduct](./.github/CODE_OF_CONDUCT.md). You can directly support our work with p5.js by [donating to the Processing Foundation](https://processingfoundation.org/support).
1212

13-
Stay in touch with Processing Foundation across other platforms:
13+
Stay in touch with Processing Foundation across other platforms:
14+
1415
- [Instagram](https://www.instagram.com/p5xjs)
1516
- [Youtube](https://www.youtube.com/@ProcessingFoundation)
1617
- [X](https://x.com/p5xjs)
1718
- [Discord](https://discord.com/invite/esmGA6H6wm)
1819
- [Forum](https://discourse.processing.org)
1920

20-
2121
## Using the p5.js Editor 🤔
2222

23-
Make your first sketch in the [p5.js Editor](https://editor.p5js.org/)! Learn more about sketching with p5.js on the [Get Started](https://p5js.org/tutorials/get-started/) and find everything you can do in the [Reference](https://p5js.org/reference/). You can also look at [examples](https://editor.p5js.org/p5/sketches) and remix them in the p5.js Editor.
23+
Make your first sketch in the [p5.js Editor](https://editor.p5js.org/)! Learn more about sketching with p5.js on the [Get Started](https://p5js.org/tutorials/get-started/) and find everything you can do in the [Reference](https://p5js.org/reference/). You can also look at [examples](https://editor.p5js.org/p5/sketches) and remix them in the p5.js Editor.
2424

25-
For more information on usage guidelines for the p5.js Editor, check out the [p5.js Editor Terms of Use](https://editor.p5js.org/terms-of-use). To gain better insight into how we handle user data and data privacy, refer to the [p5.js Editor Privacy Policy](https://editor.p5js.org/privacy-policy).
25+
For more information on usage guidelines for the p5.js Editor, check out the [p5.js Editor Terms of Use](https://editor.p5js.org/terms-of-use). To gain better insight into how we handle user data and data privacy, refer to the [p5.js Editor Privacy Policy](https://editor.p5js.org/privacy-policy).
2626

2727
## Contributing 📖 🐛 🎨
2828

29-
The p5.js Editor is a collaborative project created by many individuals, mostly volunteers, and you are invited to help. All types of involvement are welcome. To get started with contributing to the p5.js Editor, we recommend exploring the following resources in order:
29+
The p5.js Editor is a collaborative project created by many individuals, mostly volunteers, and you are invited to help. All types of involvement are welcome. To get started with contributing to the p5.js Editor, we recommend exploring the following resources in order:
3030

3131
1. [p5.js Community Statement and Code of Conduct](https://editor.p5js.org/code-of-conduct) - Read our Community Statement and Code of Conduct to understand the values that guide our community and how to participate respectfully and constructively.
3232

3333
2. [Contributor Docs](https://github.com/processing/p5.js-web-editor/blob/develop/contributor_docs/README.md) - For a deeper look at how to get involved with the p5.js Editor, check out our Contributor Docs for more in-depth details about contributing to different areas of the project, including code, bug fixes, documentation, discussion, and more.
3434

3535
3. [All Contributors list on the p5.js repository](https://github.com/processing/p5.js?tab=readme-ov-file#contributors) - Explore the All Contributors list to see the wide range of contributions by our amazing community!
3636

37-
> **TypeScript Migration:**
38-
> As of July 2025, we are working on migrating the repo to TypeScript as part of the **[p5.js Web Editor pr05 Grant](https://github.com/processing/pr05-grant/wiki/2025-pr05-Program-Page)**.
39-
> This migration will occur in two phases:
40-
> 1. **Grant Work (July – October 31, 2025)** – Setting up TypeScript configuration, tooling, and starting partial migration. Contributions will be **closed** during this period.
41-
> 2. **Open Contribution (After October 31, 2025)** – TypeScript migration tasks will **open** to all contributors, with guidelines and tutorials available.
37+
> **TypeScript Migration:** We have initiated migrating the repo to Typescript as part of the **[p5.js Web Editor pr05 Grant](https://github.com/processing/pr05-grant/wiki/2025-pr05-Program-Page)**, and the repo is now open to migration contributions.
4238
>
43-
> For full details, see [TypeScript Migration Plan](./contributor_docs/typescript-migration.md).
39+
> Please see [Typescript Migration](contributor_docs/typescript_migration.md) for migration guidelines. Please see [2025 pr05 Typescript Migration Project](contributor_docs/pr05_2025_typescript_migration/index.md) for details and technical decisions for the migration project.
4440
4541
## Acknowledgements 🙏
4642

47-
Support for this project has come from [Processing Foundation](https://processingfoundation.org/), [NYU ITP](https://tisch.nyu.edu/itp), [CS4All, NYC DOE](http://cs4all.nyc/), [COSA at DU](https://liberalarts.du.edu/emergent-digital-practices/open-source-arts), [STUDIO for Creative Inquiry](https://studioforcreativeinquiry.org/), [Grant for the Web](https://www.grantfortheweb.org/), [New Media Rights](https://www.newmediarights.org/), and many others.
43+
Support for this project has come from [Processing Foundation](https://processingfoundation.org/), [NYU ITP](https://tisch.nyu.edu/itp), [CS4All, NYC DOE](http://cs4all.nyc/), [COSA at DU](https://liberalarts.du.edu/emergent-digital-practices/open-source-arts), [STUDIO for Creative Inquiry](https://studioforcreativeinquiry.org/), [Grant for the Web](https://www.grantfortheweb.org/), [New Media Rights](https://www.newmediarights.org/), and many others.
4844

49-
Hosting and technical support has come from:
50-
<br />
51-
<br />
52-
<a href="https://releasehub.com/" target="_blank"><img width="100" src="https://assets.website-files.com/603dd147c5b0a480611bd348/603dd147c5b0a469bc1bd451_logo--dark.svg" /></a>
53-
<br />
54-
<a href="https://www.browserstack.com/" target="_blank"><img width="100" src="https://user-images.githubusercontent.com/6063380/46976166-ab280a80-d096-11e8-983b-18dd38c8cc9b.png" /></a>
45+
Hosting and technical support has come from: <br /> <br /> <a href="https://releasehub.com/" target="_blank"><img width="100" src="https://assets.website-files.com/603dd147c5b0a480611bd348/603dd147c5b0a469bc1bd451_logo--dark.svg" /></a> <br /> <a href="https://www.browserstack.com/" target="_blank"><img width="100" src="https://user-images.githubusercontent.com/6063380/46976166-ab280a80-d096-11e8-983b-18dd38c8cc9b.png" /></a>

client/custom.d.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,18 @@ declare module '*.svg' {
44
const ReactComponent: React.FunctionComponent<
55
React.SVGProps<SVGSVGElement> & { title?: string }
66
>;
7+
// eslint-disable-next-line import/no-default-export
78
export default ReactComponent;
89
}
10+
11+
// Extend window for Redux DevTools
12+
interface Window {
13+
__REDUX_DEVTOOLS_EXTENSION__?: () => any;
14+
}
15+
16+
// Extend NodeModule for hot reloading
17+
interface NodeModule {
18+
hot?: {
19+
accept(path?: string, callback?: () => void): void;
20+
};
21+
}

client/index.integration.test.jsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,13 @@ import React from 'react';
44
import Routing from './routes';
55

66
import { reduxRender, act, waitFor, screen, within } from './test-utils';
7-
import configureStore from './store';
7+
import { setupStore } from './store';
88
import * as Actions from './modules/User/actions';
99
import { userResponse } from './testData/testServerResponses';
1010

1111
// setup for the app
1212
const initialState = window.__INITIAL_STATE__;
13-
const store = configureStore(initialState);
13+
const store = setupStore(initialState);
1414

1515
// need to mock this file or it'll throw ERRCONNECTED
1616
jest.mock('./i18n');

client/index.jsx

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import { Router } from 'react-router-dom';
55

66
import { useTranslation } from 'react-i18next';
77
import browserHistory from './browserHistory';
8-
import configureStore from './store';
8+
import { setupStore } from './store';
99
import Routing from './routes';
1010
import ThemeProvider from './modules/App/components/ThemeProvider';
1111
import Loader from './modules/App/components/loader';
@@ -19,11 +19,14 @@ require('./images/p5js-square-logo.png');
1919

2020
const initialState = window.__INITIAL_STATE__;
2121

22-
const store = configureStore(initialState);
22+
const store = setupStore(initialState);
2323

2424
const DONATE_LOGO_IMAGE_URL = 'https://donorbox.org/images/white_logo.svg';
2525

26+
const showDonateCampaign = false;
27+
2628
if (
29+
showDonateCampaign &&
2730
window.location.href.indexOf('full') === -1 &&
2831
window.location.href.indexOf('embed') === -1
2932
) {
@@ -93,13 +96,19 @@ const App = () => {
9396
);
9497
};
9598

96-
render(
97-
<Provider store={store}>
98-
<ThemeProvider>
99-
<Suspense fallback={<Loader />}>
100-
<App />
101-
</Suspense>
102-
</ThemeProvider>
103-
</Provider>,
104-
document.getElementById('root')
105-
);
99+
// This prevents crashes in test environments (like Jest) where document.getElementById('root') may return null.
100+
const rootEl = document.getElementById('root');
101+
if (rootEl) {
102+
render(
103+
<Provider store={store}>
104+
<ThemeProvider>
105+
<Suspense fallback={<Loader />}>
106+
<App />
107+
</Suspense>
108+
</ThemeProvider>
109+
</Provider>,
110+
rootEl
111+
);
112+
}
113+
114+
export default store;

client/modules/About/pages/About.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ const About = () => {
9595
))}
9696

9797
<Contact>
98-
<h2>{t('Contact')}</h2>
98+
<h2>{t('About.Contact')}</h2>
9999
<div>
100100
<ContactTitle>{t('About.Email')}</ContactTitle>
101101
<ContactHandles>

client/modules/IDE/actions/preferences.js renamed to client/modules/IDE/actions/preferences.ts

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,30 @@
11
import i18next from 'i18next';
2+
import { UpdatePreferencesRequestBody } from '../../../../common/types';
23
import { apiClient } from '../../../utils/apiClient';
34
import * as ActionTypes from '../../../constants';
5+
import type {
6+
UpdatePreferencesDispatch,
7+
SetPreferencesTabValue,
8+
SetFontSizeValue,
9+
GetRootState,
10+
SetLineNumbersValue,
11+
SetAutocloseBracketsQuotesValue,
12+
SetAutocompleteHinterValue,
13+
SetAutosaveValue,
14+
SetLinewrapValue,
15+
SetLintWarningValue,
16+
SetTextOutputValue,
17+
SetAllAccessibleOutputValue,
18+
SetAutorefreshValue,
19+
SetGridOutputValue,
20+
SetLanguageValue,
21+
SetThemeValue
22+
} from './preferences.types';
423

5-
function updatePreferences(formParams, dispatch) {
24+
function updatePreferences(
25+
formParams: UpdatePreferencesRequestBody,
26+
dispatch: UpdatePreferencesDispatch
27+
) {
628
apiClient
729
.put('/preferences', formParams)
830
.then(() => {})
@@ -14,15 +36,15 @@ function updatePreferences(formParams, dispatch) {
1436
});
1537
}
1638

17-
export function setPreferencesTab(value) {
39+
export function setPreferencesTab(value: SetPreferencesTabValue) {
1840
return {
1941
type: ActionTypes.SET_PREFERENCES_TAB,
2042
value
2143
};
2244
}
2345

24-
export function setFontSize(value) {
25-
return (dispatch, getState) => {
46+
export function setFontSize(value: SetFontSizeValue) {
47+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
2648
// eslint-disable-line
2749
dispatch({
2850
type: ActionTypes.SET_FONT_SIZE,
@@ -40,8 +62,8 @@ export function setFontSize(value) {
4062
};
4163
}
4264

43-
export function setLineNumbers(value) {
44-
return (dispatch, getState) => {
65+
export function setLineNumbers(value: SetLineNumbersValue) {
66+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
4567
dispatch({
4668
type: ActionTypes.SET_LINE_NUMBERS,
4769
value
@@ -58,8 +80,10 @@ export function setLineNumbers(value) {
5880
};
5981
}
6082

61-
export function setAutocloseBracketsQuotes(value) {
62-
return (dispatch, getState) => {
83+
export function setAutocloseBracketsQuotes(
84+
value: SetAutocloseBracketsQuotesValue
85+
) {
86+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
6387
dispatch({
6488
type: ActionTypes.SET_AUTOCLOSE_BRACKETS_QUOTES,
6589
value
@@ -76,8 +100,8 @@ export function setAutocloseBracketsQuotes(value) {
76100
};
77101
}
78102

79-
export function setAutocompleteHinter(value) {
80-
return (dispatch, getState) => {
103+
export function setAutocompleteHinter(value: SetAutocompleteHinterValue) {
104+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
81105
dispatch({
82106
type: ActionTypes.SET_AUTOCOMPLETE_HINTER,
83107
value
@@ -94,8 +118,8 @@ export function setAutocompleteHinter(value) {
94118
};
95119
}
96120

97-
export function setAutosave(value) {
98-
return (dispatch, getState) => {
121+
export function setAutosave(value: SetAutosaveValue) {
122+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
99123
dispatch({
100124
type: ActionTypes.SET_AUTOSAVE,
101125
value
@@ -112,8 +136,8 @@ export function setAutosave(value) {
112136
};
113137
}
114138

115-
export function setLinewrap(value) {
116-
return (dispatch, getState) => {
139+
export function setLinewrap(value: SetLinewrapValue) {
140+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
117141
dispatch({
118142
type: ActionTypes.SET_LINEWRAP,
119143
value
@@ -130,8 +154,8 @@ export function setLinewrap(value) {
130154
};
131155
}
132156

133-
export function setLintWarning(value) {
134-
return (dispatch, getState) => {
157+
export function setLintWarning(value: SetLintWarningValue) {
158+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
135159
dispatch({
136160
type: ActionTypes.SET_LINT_WARNING,
137161
value
@@ -148,8 +172,8 @@ export function setLintWarning(value) {
148172
};
149173
}
150174

151-
export function setTextOutput(value) {
152-
return (dispatch, getState) => {
175+
export function setTextOutput(value: SetTextOutputValue) {
176+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
153177
dispatch({
154178
type: ActionTypes.SET_TEXT_OUTPUT,
155179
value
@@ -166,8 +190,8 @@ export function setTextOutput(value) {
166190
};
167191
}
168192

169-
export function setGridOutput(value) {
170-
return (dispatch, getState) => {
193+
export function setGridOutput(value: SetGridOutputValue) {
194+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
171195
dispatch({
172196
type: ActionTypes.SET_GRID_OUTPUT,
173197
value
@@ -184,12 +208,8 @@ export function setGridOutput(value) {
184208
};
185209
}
186210

187-
export function setTheme(value) {
188-
// return {
189-
// type: ActionTypes.SET_THEME,
190-
// value
191-
// };
192-
return (dispatch, getState) => {
211+
export function setTheme(value: SetThemeValue) {
212+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
193213
dispatch({
194214
type: ActionTypes.SET_THEME,
195215
value
@@ -206,12 +226,8 @@ export function setTheme(value) {
206226
};
207227
}
208228

209-
export function setAutorefresh(value) {
210-
// return {
211-
// type: ActionTypes.SET_AUTOREFRESH,
212-
// value
213-
// };
214-
return (dispatch, getState) => {
229+
export function setAutorefresh(value: SetAutorefreshValue) {
230+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
215231
dispatch({
216232
type: ActionTypes.SET_AUTOREFRESH,
217233
value
@@ -228,15 +244,18 @@ export function setAutorefresh(value) {
228244
};
229245
}
230246

231-
export function setAllAccessibleOutput(value) {
232-
return (dispatch) => {
247+
export function setAllAccessibleOutput(value: SetAllAccessibleOutputValue) {
248+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
233249
dispatch(setTextOutput(value));
234250
dispatch(setGridOutput(value));
235251
};
236252
}
237253

238-
export function setLanguage(value, { persistPreference = true } = {}) {
239-
return (dispatch, getState) => {
254+
export function setLanguage(
255+
value: SetLanguageValue,
256+
{ persistPreference = true } = {}
257+
) {
258+
return (dispatch: UpdatePreferencesDispatch, getState: GetRootState) => {
240259
i18next.changeLanguage(value);
241260
dispatch({
242261
type: ActionTypes.SET_LANGUAGE,

0 commit comments

Comments
 (0)