diff --git a/HISTORY.md b/HISTORY.md
index 89a47ae0..353104fa 100755
--- a/HISTORY.md
+++ b/HISTORY.md
@@ -7,6 +7,7 @@
* single blocks palette option, thanks, Michael!
* web-serial support, thanks, Dariusz Dorożalski!
* hide any block, including variables and custom helper blocks in palette, also use "hide/show var" primitive on custom blocks (same as on primitives)
+ * generate Parsons Problems from projects: Hide all unused blocks from the scripting area in the palette
* user defined custom block palettes
* PWA, thanks, Joan and John, for pioneering this at Robolot and in Mircoblocks!
* new "blocksZoom=n" url parameter, thanks, Bernat!
@@ -43,6 +44,7 @@
* scenes, store: store single palette setting per project (for making extensions)
* gui, scenes, objects: added scene-setting to hide/show category names in the unified palette
* store: made "hide/show categories in unified palette" setting persistent
+* byob: hide unused blocks in palette
### 2021-10-11
* objects: sort order of blocks in custom categories alphabetically in the unified palette
diff --git a/snap.html b/snap.html
index 86a36373..94e96ed1 100755
--- a/snap.html
+++ b/snap.html
@@ -23,7 +23,7 @@
-
+
diff --git a/src/byob.js b/src/byob.js
index 6ae137a5..6809bdca 100644
--- a/src/byob.js
+++ b/src/byob.js
@@ -108,7 +108,7 @@ WatcherMorph, XML_Serializer, SnapTranslator, SnapExtensions*/
// Global stuff ////////////////////////////////////////////////////////
-modules.byob = '2021-October-07';
+modules.byob = '2021-October-12';
// Declarations
@@ -4561,8 +4561,15 @@ BlockVisibilityDialogMorph.prototype.popUp
// BlockVisibilityDialogMorph menu
-BlockVisibilityDialogMorph.prototype.userMenu
- = BlockExportDialogMorph.prototype.userMenu;
+BlockVisibilityDialogMorph.prototype.userMenu = function () {
+ var menu = new MenuMorph(this, 'select');
+ menu.addItem('all', 'selectAll');
+ menu.addItem('none', 'selectNone');
+ menu.addLine();
+ menu.addItem('unused', 'selectUnused');
+ return menu;
+};
+
BlockVisibilityDialogMorph.prototype.selectAll = function () {
this.selection = this.blocks.slice(0);
@@ -4578,6 +4585,43 @@ BlockVisibilityDialogMorph.prototype.selectNone = function () {
});
};
+BlockVisibilityDialogMorph.prototype.selectUnused = function () {
+ var used = this.target.scripts.allChildren().filter(
+ m => m instanceof BlockMorph),
+ uPrim = [],
+ uCust = [],
+ uVars = [];
+
+ used.forEach(b => {
+ if (b.isCustomBlock) {
+ uCust.push(b.isGlobal ? b.definition
+ : this.target.getMethod(b.semanticSpec));
+ } else if (b.selector === 'reportGetVar') {
+ uVars.push(b.blockSpec);
+ } else {
+ uPrim.push(b.selector);
+ }
+ });
+
+ this.selection = this.blocks.filter(b => {
+ if (b.isCustomBlock) {
+ return !contains(
+ uCust,
+ b.isGlobal ? b.definition
+ : this.target.getMethod(b.semanticSpec)
+ );
+ } else if (b.selector === 'reportGetVar') {
+ return !contains(uVars, b.blockSpec);
+ } else {
+ return !contains(uPrim, b.selector);
+ }
+ });
+
+ this.body.contents.children.forEach(checkBox => {
+ checkBox.refresh();
+ });
+};
+
// BlockVisibilityDialogMorph ops
BlockVisibilityDialogMorph.prototype.hideBlocks = function () {