Skip to content

Commit 71791d7

Browse files
authored
JS editor update: Ability to convert JS code from editor to blocks (simple flow, pitch, tone, and rhythm blocks) (#4591)
* Add functionality to convert JavaScript code to block list format that can be loaded into the MusicBlocks editor. This is the first commit for such functionality, which allows users to write JavaScript code in the JS Editor directly and convert the code back to music blocks. Blocks supported in this commit are: 1. settimbre 2. newnote 3. pitch (only supports solfege) 4. if 5. for 6. All number blocks. Supports arbitrary expressions like 1 / 2, Math.abs(-1) / 2, MathUtility.doRandom(1, 2) / 4, etc. 7. All boolean blocks. Supports arbitrary boolean expressions like MathUtility.doRandom(0, 1) == 1, false | MathUtility.doRandom(0, 1) == 1, etc. 8. Action (supports recursion) 9. Dictionary (setValue, getValue, function overloading) New files in the commit: 1. ast2blocklist.js - main logic to convert an AST generated from JavaScript code to block list format that can be loaded into the block editor 2. ast2blocklist.test.js - unit tests that cover all supported blocks conversion 3. acorn.js - library that converts JavaScript code to AST * Updated UI to include button for converting JS code in the editor to musicblocks. Updated structure of ast2blocklist.js for better readability, and makes adding more block support easier. Minor change: Play pitch now supports notes (A-G) in addition to solfege. * Updated tooltips in jseditor to use _() so that it is available for translation. * 1. Added logic to calculate the vertical spaces used by blocks and arguments, and adds v-spacers based on the information 2. Instead of console.error for errors, it now throws error and shows in console panel of jseditor 3. Uses minified version of acorn library for faster loading 4. Removed driver code from ast2blocklist * Updated ast2blocklist, ast2blocklist.test, jseditor, and activity to fix lint errors.
1 parent a22aefe commit 71791d7

File tree

7 files changed

+1684
-20
lines changed

7 files changed

+1684
-20
lines changed

.eslintrc.json

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
}
1515
},
1616
"extends": ["eslint:recommended", "prettier"],
17+
"ignorePatterns": ["lib/**"],
1718
"rules": {
1819
"no-console": "off",
1920
"no-mixed-spaces-and-tabs": "warn",
@@ -36,4 +37,4 @@
3637
"no-dupe-keys" : "off",
3738
"no-useless-catch" : "off"
3839
}
39-
}
40+
}

index.html

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,11 @@
5454
<script src="lib/codejar/codejar.min.js" defer></script>
5555
<script src="lib/codejar/highlight.pack.js" defer></script>
5656
<script src="lib/astring.min.js" defer></script>
57-
<link rel="prefetch" type="application/l10n" href="./localization.ini">
57+
58+
<script src="lib/acorn.min.js" defer></script>
59+
60+
<link rel="prefetch" type="application/l10n" href="./localization.ini" />
61+
5862
<script data-main="js/loader" src="lib/require.js" defer></script>
5963
<link type="text/css" href="fonts/material-icons.css" rel="stylesheet">
6064
<link rel="preload" href="/fonts/material-icons.woff2" as="font" type="font/woff2" crossorigin="anonymous">

js/activity.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,7 @@ let MYDEFINES = [
105105
"activity/js-export/constraints",
106106
"activity/js-export/ASTutils",
107107
"activity/js-export/generate",
108+
"activity/js-export/ast2blocklist",
108109
"activity/js-export/API/GraphicsBlocksAPI",
109110
"activity/js-export/API/PenBlocksAPI",
110111
"activity/js-export/API/RhythmBlocksAPI",
@@ -2995,7 +2996,7 @@ class Activity {
29952996
// First, check if the pitch slider is open
29962997
if (window.widgetWindows.isOpen("slider") === true) {
29972998
// If the event is an arrow key, let the PitchSlider handle it
2998-
if (event.keyCode === 37 || event.keyCode === 38 ||
2999+
if (event.keyCode === 37 || event.keyCode === 38 ||
29993000
event.keyCode === 39 || event.keyCode === 40) {
30003001
// Simply prevent default behavior here
30013002
// The actual pitch slider handling is done in the PitchSlider class
@@ -4004,8 +4005,9 @@ class Activity {
40044005
* Hide the palettes before update, then deletes everything/sends all to trash.
40054006
* @param {boolean} addStartBlock {if true adds a new start block to new project instance}
40064007
* @param {boolean} doNotSave {if true discards any changes to project}
4008+
* @param {boolean} closeAllWidgets {if true close all open widgets}
40074009
*/
4008-
this.sendAllToTrash = (addStartBlock, doNotSave) => {
4010+
this.sendAllToTrash = (addStartBlock, doNotSave, closeAllWidgets = true) => {
40094011
// Return to home position after loading new blocks.
40104012
this.blocksContainer.x = 0;
40114013
this.blocksContainer.y = 0;
@@ -4065,7 +4067,9 @@ class Activity {
40654067
this.update = true;
40664068

40674069
// Close any open widgets.
4068-
closeWidgets();
4070+
if (closeAllWidgets) {
4071+
closeWidgets();
4072+
}
40694073
};
40704074

40714075
/*

0 commit comments

Comments
 (0)