Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Enables URL parsing of p5.js version and add-on libraries #3715

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
Hugo-RM wants to merge 5 commits into processing:develop
base: develop
Choose a base branch
Loading
from Enochteo:feat/url-parsing-p5.js-version
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion client/modules/IDE/reducers/files.js
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,14 @@ import {
defaultCSS,
defaultHTML
} from '../../../../server/domain-objects/createDefaultFiles';
import { parseUrlParams } from '../../../utils/parseURLParams';

export const initialState = () => {
const a = objectID().toHexString();
const b = objectID().toHexString();
const c = objectID().toHexString();
const r = objectID().toHexString();
const params = parseUrlParams(window.location.href);
return [
{
name: 'root',
Expand All @@ -32,7 +34,7 @@ export const initialState = () => {
},
{
name: 'index.html',
content: defaultHTML,
content: defaultHTML(params),
id: b,
_id: b,
fileType: 'file',
Expand Down
87 changes: 87 additions & 0 deletions client/utils/parseURLParams.js
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
import { p5Versions, currentP5Version } from '../../common/p5Versions';

const DEFAULTS = {
sound: true,
preload: false,
shapes: false,
data: false
};

/**
* Sorts version strings in descending order and returns the highest version
* @param {string[]} versions - Array of version strings (e.g., ['1.11.2', '1.11.1'])
* @returns {string} The highest version from the array
*/
function getNewestVersion(versions) {
return versions.sort((a, b) => {
const pa = a.split('.').map((n) => parseInt(n, 10));
const pb = b.split('.').map((n) => parseInt(n, 10));
for (let i = 0; i < 3; i++) {
const na = pa[i] || 0;
const nb = pb[i] || 0;
if (na !== nb) return nb - na;
}
return 0;
})[0];
}

function validateVersion(version) {
if (!version) return currentP5Version;

const ver = String(version).trim();

if (p5Versions.includes(ver)) return ver;

// if only major.minor provided like "1.11"
const majorMinorMatch = /^(\d+)\.(\d+)$/.exec(ver);
if (majorMinorMatch) {
const [, major, minor] = majorMinorMatch;
const matches = p5Versions.filter((v) => {
const parts = v.split('.');
return parts[0] === major && parts[1] === minor;
});
if (matches.length) {
return getNewestVersion(matches);
}
}

// if only major provided like "1"
const majorOnlyMatch = /^(\d+)$/.exec(ver);
if (majorOnlyMatch) {
const [, major] = majorOnlyMatch;
const matches = p5Versions.filter((v) => v.split('.')[0] === major);
if (matches.length) {
return getNewestVersion(matches);
}
}

return currentP5Version;
}

function validateBool(value, defaultValue) {
if (!value) return defaultValue;

const v = String(value).trim().toLowerCase();

const TRUTHY = new Set(['on', 'true', '1']);
const FALSY = new Set(['off', 'false', '0']);

if (TRUTHY.has(v)) return true;
if (FALSY.has(v)) return false;

return defaultValue;
}

export function parseUrlParams(url) {
const params = new URLSearchParams(
new URL(url, 'https://dummy.origin').search
);

return {
version: validateVersion(params.get('version')),
sound: validateBool(params.get('sound'), DEFAULTS.sound),
preload: validateBool(params.get('preload'), DEFAULTS.preload),
shapes: validateBool(params.get('shapes'), DEFAULTS.shapes),
data: validateBool(params.get('data'), DEFAULTS.data)
};
}
51 changes: 51 additions & 0 deletions client/utils/parseURLParams.test.js
View file Open in desktop
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { parseUrlParams } from './parseURLParams';
import { currentP5Version } from '../../common/p5Versions';

describe('parseUrlParams', () => {
test('returns defaults when no params are provided', () => {
const url = 'https://example.com';
const result = parseUrlParams(url);

expect(result).toEqual({
version: currentP5Version,
sound: true,
preload: false,
shapes: false,
data: false
});
});

test('parses a valid p5 version and falls back for invalid versions', () => {
const good = parseUrlParams('https://example.com?version=1.4.0');
expect(good.version).toBe('1.4.0');

const bad = parseUrlParams('https://example.com?version=9.9.9');
expect(bad.version).toBe(currentP5Version);
});

test('parses boolean-like params for sound/preload/shapes/data (true variants)', () => {
const trueVariants = ['on', 'true', '1', 'ON', 'True'];

trueVariants.forEach((v) => {
const url = `https://example.com?sound=${v}&preload=${v}&shapes=${v}&data=${v}`;
const result = parseUrlParams(url);
expect(result.sound).toBe(true);
expect(result.preload).toBe(true);
expect(result.shapes).toBe(true);
expect(result.data).toBe(true);
});
});

test('parses boolean-like params for sound/preload/shapes/data (false variants)', () => {
const falseVariants = ['off', 'false', '0', 'OFF', 'False'];

falseVariants.forEach((v) => {
const url = `https://example.com?sound=${v}&preload=${v}&shapes=${v}&data=${v}`;
const result = parseUrlParams(url);
expect(result.sound).toBe(false);
expect(result.preload).toBe(false);
expect(result.shapes).toBe(false);
expect(result.data).toBe(false);
});
});
});
33 changes: 29 additions & 4 deletions server/domain-objects/createDefaultFiles.js
View file Open in desktop
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,35 @@ function draw() {
background(220);
}`;

export const defaultHTML = `<!DOCTYPE html>
export function defaultHTML({
version = currentP5Version,
sound = true,
preload = false,
shapes = false,
data = false
} = {}) {
const soundURL = version.startsWith('2.')
? `https://cdn.jsdelivr.net/npm/p5.sound@0.2.0/dist/p5.sound.min.js`
: `https://cdnjs.cloudflare.com/ajax/libs/p5.js/${version}/addons/p5.sound.min.js`;

const libraries = [
`<script src="https://cdn.jsdelivr.net/npm/p5@${version}/lib/p5.js"></script>`,
sound ? `<script src="${soundURL}"></script>` : '',
preload
? `<script src="https://cdn.jsdelivr.net/npm/p5.js-compatibility@0.1.2/src/preload.js"></script>`
: '',
shapes
? `<script src="https://cdn.jsdelivr.net/npm/p5.js-compatibility@0.1.2/src/shapes.js"></script>`
: '',
data
? `<script src="https://cdn.jsdelivr.net/npm/p5.js-compatibility@0.1.2/src/data.js"></script>`
: ''
].join('\n ');

return `<!DOCTYPE html>
<html lang="en">
<head>
<script src="https://cdn.jsdelivr.net/npm/p5@${currentP5Version}/lib/p5.js"></script>
<script src="https://cdn.jsdelivr.net/npm/p5@${currentP5Version}/lib/addons/p5.sound.min.js"></script>
${libraries}
<link rel="stylesheet" type="text/css" href="style.css">
<meta charset="utf-8" />

Expand All @@ -24,6 +48,7 @@ export const defaultHTML = `<!DOCTYPE html>
</body>
</html>
`;
}

export const defaultCSS = `html, body {
margin: 0;
Expand All @@ -37,7 +62,7 @@ canvas {
export default function createDefaultFiles() {
return {
'index.html': {
content: defaultHTML
content: defaultHTML()
},
'style.css': {
content: defaultCSS
Expand Down

AltStyle によって変換されたページ (->オリジナル) /