Skip to content

Commit 37a5396

Browse files
authored
Merge branch 'main' into 415-attrib
2 parents 9353c52 + da3a49c commit 37a5396

File tree

267 files changed

+6534
-3603
lines changed

Some content is hidden

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

267 files changed

+6534
-3603
lines changed

public/reference/data.json

+1,437-1,646
Large diffs are not rendered by default.

public/search-indices/en.json

+1-1
Large diffs are not rendered by default.

public/search-indices/es.json

+1-1
Large diffs are not rendered by default.

public/search-indices/hi.json

+1-1
Large diffs are not rendered by default.

public/search-indices/ko.json

+1-1
Large diffs are not rendered by default.

public/search-indices/zh-Hans.json

+1-1
Large diffs are not rendered by default.

src/api/OpenProcessing.ts

+35-5
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,9 @@ export type OpenProcessingCurationResponse = Array<{
2323
title: string;
2424
/** Description of sketch */
2525
description: string;
26+
instructions: string;
27+
mode: string;
28+
createdOn: string;
2629
userID: string;
2730
submittedOn: string;
2831
/** Author's name */
@@ -36,16 +39,19 @@ export type OpenProcessingCurationResponse = Array<{
3639
* @param limit max number of sketches to return
3740
* @returns sketches
3841
*/
39-
export const getCurationSketches = async (
42+
export const getCurationSketches = memoize(async (
4043
limit?: number,
4144
): Promise<OpenProcessingCurationResponse> => {
4245
const limitParam = limit ? `limit=${limit}` : "";
4346
const response = await fetch(
4447
`${openProcessingEndpoint}curation/${curationId}/sketches?${limitParam}`,
4548
);
49+
if(!response.ok){ //log error instead of throwing error to not cache result in memoize
50+
console.error('getCurationSketches', response.status, response.statusText)
51+
}
4652
const payload = await response.json();
4753
return payload as OpenProcessingCurationResponse;
48-
};
54+
});
4955

5056
/**
5157
* API Response from a call to the Sketch endpoint
@@ -69,26 +75,50 @@ export type OpenProcessingSketchResponse = {
6975

7076
/**
7177
* Get info about a specific sketch from the OpenProcessing API
78+
* First checks if the sketch is in the memoized curated sketches and returns the data if so,
79+
* Otherwise calls OpenProcessing API for this specific sketch
7280
*
7381
* https://documenter.getpostman.com/view/16936458/2s9YC1Xa6X#7cd344f6-6e87-426a-969b-2b4a79701dd1
7482
* @param id
7583
* @returns
7684
*/
77-
export const getSketch = memoize(async (
78-
id: string,
79-
): Promise<OpenProcessingSketchResponse> => {
85+
export const getSketch = memoize(
86+
async (id: string): Promise<OpenProcessingSketchResponse> => {
87+
// check for memoized sketch in curation sketches
88+
const curationSketches = await getCurationSketches();
89+
const memoizedSketch = curationSketches.find((el) => el.visualID === id);
90+
if (memoizedSketch) {
91+
return {
92+
...memoizedSketch,
93+
license: "",
94+
} as OpenProcessingSketchResponse;
95+
}
96+
97+
// check for sketch data in Open Processing API
8098
const response = await fetch(`${openProcessingEndpoint}sketch/${id}`);
99+
if (!response.ok) {
100+
//log error instead of throwing error to not cache result in memoize
101+
console.error("getSketch", id, response.status, response.statusText);
102+
}
81103
const payload = await response.json();
82104
return payload as OpenProcessingSketchResponse;
83105
});
84106

107+
/**
108+
* Note: this currently calls `/api/sketch/:id/code`
109+
* But only uses the width and height properties from this call
110+
* Width and height should instead be added to properties for `/api/sketch/:id` or `api/curation/:curationId/sketches` instead
111+
*/
85112
export const getSketchSize = memoize(async (id: string) => {
86113
const sketch = await getSketch(id)
87114
if (sketch.mode !== 'p5js') {
88115
return { width: undefined, height: undefined };
89116
}
90117

91118
const response = await fetch(`${openProcessingEndpoint}sketch/${id}/code`);
119+
if(!response.ok){ //log error instead of throwing error to not cache result in memoize
120+
console.error('getSketchSize', id, response.status, response.statusText)
121+
}
92122
const payload = await response.json();
93123

94124
for (const tab of payload) {

src/components/CodeEmbed/frame.tsx

+10-10
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { useRef, useLayoutEffect, useEffect } from "preact/hooks";
1+
import { useRef, useLayoutEffect, useEffect, useState } from "preact/hooks";
22
import { cdnLibraryUrl } from "@/src/globals/globals";
33

44
interface CodeBundle {
@@ -42,7 +42,9 @@ canvas {
4242
}
4343
${code.css || ""}
4444
</style>
45-
${(code.scripts ? [cdnLibraryUrl, ...code.scripts] : []).map((src) => `<script type="text/javascript" src="${src}"></script>`).join('\n')}
45+
<!-- If we need an addon script, load p5 the usual way with no caching to make sure
46+
the import order doesn't get messed up. -->
47+
${((code.scripts?.length ?? 0) > 0 ? [cdnLibraryUrl, ...(code.scripts ?? [])] : []).map((src) => `<script type="text/javascript" src="${src}"></script>`).join('\n')}
4648
<body>${code.htmlBody || ""}</body>
4749
<script id="code" type="text/javascript">${wrapSketch(code.js) || ""}</script>
4850
${(code.scripts?.length ?? 0) > 0 ? '' : `
@@ -84,6 +86,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
8486
const p5ScriptTag = document.getElementById(
8587
"p5ScriptTag",
8688
) as HTMLScriptElement;
89+
const [mounted, setMounted] = useState(false);
8790

8891
// For performance, set the iframe to display:none when
8992
// not visible on the page. This will stop the browser
@@ -99,11 +102,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
99102
(entries) => {
100103
entries.forEach((entry) => {
101104
if (!iframeRef.current) return;
102-
if (entry.isIntersecting) {
103-
iframeRef.current.style.removeProperty("display");
104-
} else {
105-
iframeRef.current.style.display = "none";
106-
}
105+
setMounted(entry.isIntersecting);
107106
});
108107
},
109108
{ rootMargin: "20px" },
@@ -116,6 +115,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
116115
useEffect(() => {
117116
(async () => {
118117
if (!p5ScriptTag || !iframeRef.current) return;
118+
if (!mounted) return;
119119

120120
/*
121121
* Uses postMessage to receive the text content of p5.min.js, to be included
@@ -146,7 +146,7 @@ export const CodeFrame = (props: CodeFrameProps) => {
146146
return;
147147
}
148148
})();
149-
}, [props.jsCode]);
149+
}, [props.jsCode, mounted]);
150150

151151
return (
152152
<div
@@ -155,13 +155,13 @@ export const CodeFrame = (props: CodeFrameProps) => {
155155
>
156156
<iframe
157157
ref={iframeRef}
158-
srcDoc={wrapInMarkup({
158+
srcDoc={mounted ? wrapInMarkup({
159159
js: props.jsCode,
160160
css: props.cssCode,
161161
htmlBody: props.htmlBodyCode,
162162
base: props.base,
163163
scripts: props.scripts,
164-
})}
164+
}) : undefined}
165165
sandbox="allow-scripts allow-popups allow-modals allow-forms allow-same-origin"
166166
aria-label="Code Preview"
167167
title="Code Preview"

src/components/CodeEmbed/index.jsx

+6-4
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,12 @@ export const CodeEmbed = (props) => {
6767
setRendered(true);
6868

6969
// Includes p5.min.js script to be used by `CodeFrame` iframe(s)
70-
const p5ScriptElement = document.createElement("script");
71-
p5ScriptElement.id = "p5ScriptTag";
72-
p5ScriptElement.src = cdnLibraryUrl;
73-
document.head.appendChild(p5ScriptElement);
70+
if (!document.getElementById("p5ScriptTag")) {
71+
const p5ScriptElement = document.createElement("script");
72+
p5ScriptElement.id = "p5ScriptTag";
73+
p5ScriptElement.src = cdnLibraryUrl;
74+
document.head.appendChild(p5ScriptElement);
75+
}
7476
}, []);
7577

7678
if (!rendered) return <div className="code-placeholder" />;

src/components/ReferenceDirectoryWithFilter/index.tsx

+9-2
Original file line numberDiff line numberDiff line change
@@ -72,18 +72,25 @@ export const ReferenceDirectoryWithFilter = ({
7272

7373
return categoryData.reduce((acc: FilteredCategoryData[], category) => {
7474
const filteredSubcats = category.subcats.reduce(
75-
(subAcc, subcat) => {
75+
(subAcc: typeof category.subcats, subcat) => {
7676
const filteredEntries = subcat.entries.filter((entry) =>
7777
entry.data.title
7878
.toLowerCase()
7979
.includes(searchKeyword.toLowerCase()),
8080
);
81+
if (
82+
subcat.entry &&
83+
subcat.entry.data.title.toLowerCase().includes(searchKeyword.toLowerCase())
84+
) {
85+
filteredEntries.push(subcat.entry);
86+
}
87+
8188
if (filteredEntries.length > 0) {
8289
subAcc.push({ ...subcat, entries: filteredEntries });
8390
}
8491
return subAcc;
8592
},
86-
[] as typeof category.subcats,
93+
[],
8794
);
8895

8996
if (filteredSubcats.length > 0) {

src/content/contributor-docs/en/contributing_to_the_p5js_reference.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ If the parameter is optional, add square brackets around the name:
120120

121121
### Additional info: Constants
122122

123-
If the parameter takes one or more values defined in [`constants.js`](https://github.com/processing/p5.js/blob/main/src/core/constants.js) , then the type should be specified as `{Constant}` and the valid values should be enumerated in the comment following the `either` keyword, e.g.:
123+
If the parameter takes one or more values defined in [`constants.js`](https://github.com/processing/p5.js/blob/main/src/core/constants.js), then the type should be specified as `{Constant}` and the valid values should be enumerated in the comment following the `either` keyword, e.g.:
124124

125125
```
126126
@param {Constant} horizAlign horizontal alignment, either LEFT, CENTER, or RIGHT
@@ -225,7 +225,7 @@ The relevant `@example` tag to create the above is as follows:
225225

226226
After the `@example` tag, you should start an HTML `<div>` tag followed by a `<code>` tag. In between the opening and closing `<code>` tag, you will insert the relevant example code. The basic principle of writing good example code for the reference is to keep things simple and minimal. The example should be meaningful and explain how the feature works without being too complicated. The example’s canvas should be 100x100 pixels and if the `setup()` function is not included, such as in the example above, the code will be automatically wrapped in a `setup()` function with a default 100x100 pixels gray background canvas created. We won’t go through the details about best practices and code style for the example code here; please see the reference style guide instead.
227227

228-
You can have multiple examples for one feature.To do so, add an additional `<div>` and `<code>` HTML block right after the first closed, separated by a blank line.
228+
You can have multiple examples for one feature. To do so, add an additional `<div>` and `<code>` HTML block right after the first closed, separated by a blank line.
229229

230230
```
231231
* @example

src/content/contributor-docs/en/contributor_guidelines.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ p5.js' code standard or code style is enforced by [ESLlint](https://eslint.org/)
386386

387387
While working on any features of p5.js, it is important to keep in mind the design principles of p5.js. Our priorities may differ from the priorities of other projects, so if you are coming from a different project, we recommend that you familiarize yourself with p5.js' design principles.
388388

389-
* **Access** We prioritize accessibility first and foremost, and decisions we make must take into account how it increases access to historically marginalized groups. Read more about this in our access statement.
389+
* **Access** We prioritize accessibility first and foremost, and decisions we make must take into account how they increase access to historically marginalized groups. Read more about this in our access statement.
390390
* **Beginner Friendly** The p5.js API aims to be friendly to beginner coders, offering a low barrier to creating interactive and visual web content with cutting-edge HTML5/Canvas/DOM APIs.
391391
* **Educational** p5.js is focused on an API and curriculum that supports educational use, including a complete reference to the API with supporting examples, as well as tutorials and sample class curricula that introduce core creative coding principles in a clear and engaging order.
392392
* **JavaScript and its community** p5.js aims to make web development practices more accessible to beginners by modeling proper JavaScript design patterns and usage while abstracting them where necessary. As an open-source library, p5.js also includes the wider JavaScript community in its creation, documentation, and dissemination.

src/content/contributor-docs/en/creating_libraries.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -278,7 +278,7 @@ Your addon library may not extend p5 or p5 classes at all, but instead just offe
278278

279279
**p5.js has two modes, global mode and instance mode.** In global mode, all p5 properties and methods are bound to the `window` object, allowing users to call methods like `background()` without having to prefix them with anything. However, this means you need to be careful not to overwrite native JavaScript functionality. For example “`Math`” and “`console`” are both native Javascript functionalities so you shouldn’t have methods named “`Math`” or “`console`”.
280280

281-
**Class names should use** `PascalCase`**, while methods and properties should use** `camelCase`**.** Classes in p5 are prefixed with p5. We would like to keep this namespace for p5 core classes only, so when you create your own namespace, **do not include the** `p5.` **prefix for class names**. You are welcomed to create your own prefix, or just give them non-prefixed names.
281+
**Class names should use** `PascalCase`**, while methods and properties should use** `camelCase`**.** Classes in p5 are prefixed with p5. We would like to keep this namespace for p5 core classes only, so when you create your own namespace, **do not include the** `p5.` **prefix for class names**. You are welcome to create your own prefix, or just give them non-prefixed names.
282282

283283
```js
284284
// Do not do this
@@ -306,4 +306,4 @@ p5.prototype.myMethod = function(){
306306

307307
**Examples are great, too!** They show people what your library can do. Because this is all JavaScript, people can see them running online before they download anything.[ ](http://jsfiddle.net/) You can create a collection of examples on the p5.js web editor to showcase how your library works.
308308

309-
**Submit your library!** Once your library is ready for distribution and you’d like it included on the [p5js.org/libraries](https://p5js.org/libraries/) page, please submit a pull request on the p5.js website GitHub repository following [this intruction](https://github.com/processing/p5.js-website/blob/main/docs/contributing_libraries.md)!
309+
**Submit your library!** Once your library is ready for distribution and you’d like it included on the [p5js.org/libraries](https://p5js.org/libraries/) page, please submit a pull request on the p5.js website GitHub repository following [this instruction](https://github.com/processing/p5.js-website/blob/main/docs/contributing_libraries.md)!

src/content/contributor-docs/en/documentation_style_guide.mdx

+3-3
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ Always use `let` to declare variables.
149149

150150
**Accessibility terminology**
151151

152-
The following terminiology is adapted from the WordPress documentation guidelines for [Writing inclusive documentation](https://make.wordpress.org/docs/style-guide/general-guidelines/inclusivity/#accessibility-terminology). For more background on people-first language, see the CDC's guide on [Communicating With and About People with Disabilities](https://www.cdc.gov/ncbddd/disabilityandhealth/materials/factsheets/fs-communicating-with-people.html).
152+
The following terminology is adapted from the WordPress documentation guidelines for [Writing inclusive documentation](https://make.wordpress.org/docs/style-guide/general-guidelines/inclusivity/#accessibility-terminology). For more background on people-first language, see the CDC's guide on [Communicating With and About People with Disabilities](https://www.cdc.gov/ncbddd/disabilityandhealth/materials/factsheets/fs-communicating-with-people.html).
153153

154154
| Recommended | Not Recommended |
155155
| --------------------------------------------------------------- | ------------------------------------------------------------------ |
@@ -722,7 +722,7 @@ if (
722722

723723
## Iteration
724724

725-
* Don’t use a `while` or `do-while` loops unless it's necessary. Use `for` loops to iterate a fixed number of times.
725+
* Don’t use `while` or `do-while` loops unless it's necessary. Use `for` loops to iterate a fixed number of times.
726726

727727
```javascript
728728
let numPetals = 7;
@@ -905,7 +905,7 @@ for (let i = 0; i < numbers.length; i += 1) {
905905
let numbersCopy = numbers.slice();
906906
```
907907

908-
* Write arrays on multiple lines when it improves readibility. Use line breaks after the opening bracket and before the closing bracket. Add a trailing comma.
908+
* Write arrays on multiple lines when it improves readability. Use line breaks after the opening bracket and before the closing bracket. Add a trailing comma.
909909

910910
```javascript
911911
// Bad.

src/content/contributor-docs/en/friendly_error_system.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ The basic format of a translation file's item has a key and a value (message) in
9090
{ "key": "value" }
9191
```
9292

93-
For example, we have a ASCII logo saved in this format:
93+
For example, we have an ASCII logo saved in this format:
9494

9595
```json
9696
"logo": " _ \n /\\| |/\\ \n \\ ` ' / \n / , . \\ \n \\/|_|\\/ \n\n"

src/content/contributor-docs/en/how-to-add-friendly-error-messages.mdx

+1-1
Original file line numberDiff line numberDiff line change
@@ -162,7 +162,7 @@ Next, you will file an issue ticket to discuss creating a new case or confirm yo
162162

163163
Go to the [issue board](https://github.com/processing/p5.js/issues/), press the "New Issue" button, and then choose the "Issue: 💡 Existing Feature Enhancement" option. An empty form should appear.
164164

165-
Add a title along the lines of “Adding a new case to `fileLoadErrrorCases`: \[a high-level description of your file load error case].” For the “Increasing access” section, enter a short paragraph on the typical scenario you prepared at the beginning of this step.
165+
Add a title along the lines of “Adding a new case to `fileLoadErrorCases`: \[a high-level description of your file load error case].” For the “Increasing access” section, enter a short paragraph on the typical scenario you prepared at the beginning of this step.
166166

167167
Then, check the “Friendly Errors” box for the “Most appropriate sub-area of p5.js?” question. Lastly, for the “Feature enhancement details” section, enter your paragraph detailing your error handling and what file types it loads.
168168

src/content/contributor-docs/en/method.example.js

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
* "This is a template for inline documentation of a method. Remove all text
33
* between double quotes for using this template. Some description about the
44
* method goes here. Explain in simple words, what the function does and what
5-
* would be good/bad use cases for it. If there are any corners cases or warnings,
5+
* would be good/bad use cases for it. If there are any corner cases or warnings,
66
* do explain them over here."
77
*
88
* By default, the background is transparent.
@@ -32,8 +32,8 @@
3232
* "A single line precisely describing the second example"
3333
*/
3434

35-
// "If your method has more than one signatures, they can be documentated each
36-
// in their own block with description about their parameters as follows."
35+
// "If your method has more than one signature, they can be documented each
36+
// in their own block with description of their parameters as follows."
3737
/**
3838
* @method "methodName"
3939
* @param {"dataType"} "paramName" "Description of the param"

src/content/contributor-docs/en/release_process.mdx

+2-2
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ CDNs will take a bit more time (a day or two) to update but they will automatica
5353

5454
## What's actually happening
5555

56-
The GitHub Action ["New p5.js release"](../.github/workflows/release-workflow.yml) is triggered on a tag that matches the pattern `v*.*.*` which is created by the `npm version ___` command.
56+
The GitHub Action ["New p5.js release"](../.github/workflows/release.yml) is triggered on a tag that matches the pattern `v*.*.*` which is created by the `npm version ___` command.
5757

5858
Once triggered, it will run the following steps:
5959

@@ -76,7 +76,7 @@ In principle, we try to concentrate as many steps as possible to be run in one p
7676

7777
## Testing
7878

79-
As the release steps are run in CI, testing them can be difficult. Using [act](https://github.com/nektos/act/) to test running of the steps locally is possible (and was how they were tested while being developed) but require some temporary modifications to the workflow definition, we'll roughly document here as the precise steps will likely change over time.
79+
As the release steps are run in CI, testing them can be difficult. Using [act](https://github.com/nektos/act/) to test running of the steps locally is possible (and was how they were tested while being developed) but requires some temporary modifications to the workflow definition, we'll roughly document here as the precise steps will likely change over time.
8080

8181
The test steps will not run because not all system requirements are present to run the mocha Chrome tests. Some system dependencies will likely be needed to be installed with `apt` before setting up the rest of the environment. Keep an eye on the error messages which should give some information on what packages are missing.
8282

0 commit comments

Comments
 (0)