diff --git a/blockly_compressed.js b/blockly_compressed.js index 034ee966e..dd378c0a4 100644 --- a/blockly_compressed.js +++ b/blockly_compressed.js @@ -981,8 +981,8 @@ Blockly.ConnectionDB.prototype.searchForClosest=function(a,b,c){if(!this.length) Blockly.ConnectionDB.init=function(a){var b=[];b[Blockly.INPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.OUTPUT_VALUE]=new Blockly.ConnectionDB;b[Blockly.NEXT_STATEMENT]=new Blockly.ConnectionDB;b[Blockly.PREVIOUS_STATEMENT]=new Blockly.ConnectionDB;a.connectionDBList=b};Blockly.constants={};Blockly.DRAG_RADIUS=5;Blockly.SNAP_RADIUS=20;Blockly.BUMP_DELAY=250;Blockly.COLLAPSE_CHARS=30;Blockly.LONGPRESS=750;Blockly.SOUND_LIMIT=100;Blockly.HSV_SATURATION=.45;Blockly.HSV_VALUE=.65;Blockly.SPRITE={width:96,height:124,url:"sprites.png"};Blockly.SVG_NS="http://www.w3.org/2000/svg";Blockly.HTML_NS="http://www.w3.org/1999/xhtml";Blockly.INPUT_VALUE=1;Blockly.OUTPUT_VALUE=2;Blockly.NEXT_STATEMENT=3;Blockly.PREVIOUS_STATEMENT=4;Blockly.DUMMY_INPUT=5;Blockly.ALIGN_LEFT=-1; Blockly.ALIGN_CENTRE=0;Blockly.ALIGN_RIGHT=1;Blockly.DRAG_NONE=0;Blockly.DRAG_STICKY=1;Blockly.DRAG_BEGIN=1;Blockly.DRAG_FREE=2;Blockly.OPPOSITE_TYPE=[];Blockly.OPPOSITE_TYPE[Blockly.INPUT_VALUE]=Blockly.OUTPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.OUTPUT_VALUE]=Blockly.INPUT_VALUE;Blockly.OPPOSITE_TYPE[Blockly.NEXT_STATEMENT]=Blockly.PREVIOUS_STATEMENT;Blockly.OPPOSITE_TYPE[Blockly.PREVIOUS_STATEMENT]=Blockly.NEXT_STATEMENT;Blockly.TOOLBOX_AT_TOP=0;Blockly.TOOLBOX_AT_BOTTOM=1; Blockly.TOOLBOX_AT_LEFT=2;Blockly.TOOLBOX_AT_RIGHT=3;Blockly.Options=function(a){var b=!!a.readOnly;if(b)var c=null,d=!1,e=!1,f=!1,g=!1,h=!1,k=!1;else c=Blockly.Options.parseToolboxTree(a.toolbox),d=!(!c||!c.getElementsByTagName("category").length),e=a.trashcan,void 0===e&&(e=d),f=a.collapse,void 0===f&&(f=d),g=a.comments,void 0===g&&(g=d),h=a.disable,void 0===h&&(h=d),k=a.sounds,void 0===k&&(k=!0);var m=!!a.rtl,p=a.horizontalLayout;void 0===p&&(p=!1);var l=a.toolboxPosition,l="end"===l?!1:!0,l=p?l?Blockly.TOOLBOX_AT_TOP:Blockly.TOOLBOX_AT_BOTTOM:l== -m?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT,n=a.scrollbars;void 0===n&&(n=d);var q=a.css;void 0===q&&(q=!0);var t="https://blockly-demo.appspot.com/static/media/";a.media?t=a.media:a.path&&(t=a.path+"media/");var r=!a.oneBasedIndex;this.RTL=m;this.oneBasedIndex=r;this.collapse=f;this.comments=g;this.disable=h;this.readOnly=b;this.maxBlocks=a.maxBlocks||Infinity;this.pathToMedia=t;this.hasCategories=d;this.hasScrollbars=n;this.hasTrashcan=e;this.hasSounds=k;this.hasCss=q;this.horizontalLayout= -p;this.languageTree=c;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=l};Blockly.Options.prototype.parentWorkspace=null;Blockly.Options.prototype.setMetrics=null;Blockly.Options.prototype.getMetrics=null; +m?Blockly.TOOLBOX_AT_RIGHT:Blockly.TOOLBOX_AT_LEFT,n=a.scrollbars;void 0===n&&(n=d);var q=a.css;void 0===q&&(q=!0);var t="https://blockly-demo.appspot.com/static/media/";a.media?t=a.media:a.path&&(t=a.path+"media/");var r=void 0===a.oneBasedIndex?!0:!!a.oneBasedIndex;this.RTL=m;this.oneBasedIndex=r;this.collapse=f;this.comments=g;this.disable=h;this.readOnly=b;this.maxBlocks=a.maxBlocks||Infinity;this.pathToMedia=t;this.hasCategories=d;this.hasScrollbars=n;this.hasTrashcan=e;this.hasSounds=k;this.hasCss= +q;this.horizontalLayout=p;this.languageTree=c;this.gridOptions=Blockly.Options.parseGridOptions_(a);this.zoomOptions=Blockly.Options.parseZoomOptions_(a);this.toolboxPosition=l};Blockly.Options.prototype.parentWorkspace=null;Blockly.Options.prototype.setMetrics=null;Blockly.Options.prototype.getMetrics=null; Blockly.Options.parseZoomOptions_=function(a){a=a.zoom||{};var b={};b.controls=void 0===a.controls?!1:!!a.controls;b.wheel=void 0===a.wheel?!1:!!a.wheel;b.startScale=void 0===a.startScale?1:parseFloat(a.startScale);b.maxScale=void 0===a.maxScale?3:parseFloat(a.maxScale);b.minScale=void 0===a.minScale?.3:parseFloat(a.minScale);b.scaleSpeed=void 0===a.scaleSpeed?1.2:parseFloat(a.scaleSpeed);return b}; Blockly.Options.parseGridOptions_=function(a){a=a.grid||{};var b={};b.spacing=parseFloat(a.spacing)||0;b.colour=a.colour||"#888";b.length=parseFloat(a.length)||1;b.snap=0} elementArray - Array of elements to show when - * block is checked. + * If given checkbox is checked, enable the given elements. Otherwise, disable. + * @param {boolean} enabled True if enabled, false otherwise. + * @param {!Array.} idArray Array of element IDs to enable when + * checkbox is checked. */ -AppController.prototype.ifCheckedDisplay = function(checkbox, elementArray) { - for (var i = 0, element; element = elementArray[i]; i++) { - element.style.display = checkbox.checked ? 'block' : 'none'; +AppController.prototype.ifCheckedEnable = function(enabled, idArray) { + for (var i = 0, id; id = idArray[i]; i++) { + var element = document.getElementById(id); + if (enabled) { + element.classList.remove('disabled'); + } else { + element.classList.add('disabled'); + } + var fields = element.querySelectorAll('input, textarea, select'); + for (var j = 0, field; field = fields[j]; j++) { + field.disabled = !enabled; + } } }; @@ -485,7 +487,7 @@ AppController.prototype.assignLibraryClickHandlers = function() { // Hide and show the block library dropdown. document.getElementById('button_blockLib').addEventListener('click', function() { - document.getElementById('dropdownDiv_blockLib').classList.toggle("show"); + self.openModal('dropdownDiv_blockLib'); }); }; @@ -534,7 +536,7 @@ AppController.prototype.assignBlockFactoryClickHandlers = function() { self.blockLibraryController.setNoneSelected(); // Close the Block Library Dropdown. - document.getElementById('dropdownDiv_blockLib').classList.remove('show'); + self.closeModal(); }); }; @@ -629,11 +631,42 @@ AppController.prototype.confirmLeavePage = function() { } }; +/** + * Show a modal element, usually a dropdown list. + * @param {string} id ID of element to show. + */ +AppController.prototype.openModal = function(id) { + Blockly.hideChaff(); + this.modalName_ = id; + document.getElementById(id).style.display = 'block'; + document.getElementById('modalShadow').style.display = 'block'; +}; + +/** + * Hide a previously shown modal element. + */ +AppController.prototype.closeModal = function() { + var id = this.modalName_; + if (!id) { + return; + } + document.getElementById(id).style.display = 'none'; + document.getElementById('modalShadow').style.display = 'none'; + this.modalName_ = null; +}; + +/** + * Name of currently open modal. + * @type {string?} + * @private + */ +AppController.prototype.modalName_ = null; + /** * Initialize Blockly and layout. Called on page load. */ AppController.prototype.init = function() { - // Blockly factory has a dependency on bits of Closure that core Blockly + // Block Factory has a dependency on bits of Closure that core Blockly // doesn't have. When you run this from file:// without a copy of Closure, // it breaks it non-obvious ways. Warning about this for now until the // dependency is broken. @@ -641,12 +674,13 @@ AppController.prototype.init = function() { if (!window.goog.dom.xml) { alert('Sorry: Closure dependency not found. We are working on removing ' + 'this dependency. In the meantime, you can use our hosted demo\n ' + - 'https://blockly-demo.appspot.com/static/demos/blocklyfactory/index.html' + + 'https://blockly-demo.appspot.com/static/demos/blockfactory/index.html' + '\nor use these instructions to continue running locally:\n' + - 'https:developers.google.com/blockly/guides/modify/web/closure'); + 'https://developers.google.com/blockly/guides/modify/web/closure'); return; } + var self = this; // Handle Blockly Storage with App Engine. if ('BlocklyStorage' in window) { this.initializeBlocklyStorage(); @@ -656,9 +690,13 @@ AppController.prototype.init = function() { this.assignExporterClickHandlers(); this.assignLibraryClickHandlers(); this.assignBlockFactoryClickHandlers(); + // Hide and show the block library dropdown. + document.getElementById('modalShadow').addEventListener('click', + function() { + self.closeModal(); + }); this.onresize(); - var self = this; window.addEventListener('resize', function() { self.onresize(); }); diff --git a/demos/blockfactory/block_exporter_controller.js b/demos/blockfactory/block_exporter_controller.js index 55da2d4fc..b237f48a7 100644 --- a/demos/blockfactory/block_exporter_controller.js +++ b/demos/blockfactory/block_exporter_controller.js @@ -40,7 +40,7 @@ goog.require('goog.dom.xml'); /** * BlockExporter Controller Class - * @param {!BlockLibrary.Storage} blockLibStorage - Block Library Storage. + * @param {!BlockLibrary.Storage} blockLibStorage Block Library Storage. * @constructor */ BlockExporterController = function(blockLibStorage) { @@ -61,7 +61,7 @@ BlockExporterController = function(blockLibStorage) { /** * Set the block library storage object from which exporter exports. - * @param {!BlockLibraryStorage} blockLibStorage - Block Library Storage object + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object * that stores the blocks. */ BlockExporterController.prototype.setBlockLibraryStorage = @@ -71,7 +71,7 @@ BlockExporterController.prototype.setBlockLibraryStorage = /** * Get the block library storage object from which exporter exports. - * @return {!BlockLibraryStorage} blockLibStorage - Block Library Storage object + * @return {!BlockLibraryStorage} blockLibStorage Block Library Storage object * that stores the blocks. */ BlockExporterController.prototype.getBlockLibraryStorage = @@ -263,7 +263,7 @@ BlockExporterController.prototype.selectUsedBlocks = function() { /** * Set the array that holds the block types used in workspace factory. - * @param {!Array.} usedBlockTypes - Block types used in + * @param {!Array.} usedBlockTypes Block types used in */ BlockExporterController.prototype.setUsedBlockTypes = function(usedBlockTypes) { diff --git a/demos/blockfactory/block_exporter_tools.js b/demos/blockfactory/block_exporter_tools.js index 596ad8764..4d6d9bec6 100644 --- a/demos/blockfactory/block_exporter_tools.js +++ b/demos/blockfactory/block_exporter_tools.js @@ -236,13 +236,13 @@ BlockExporterTools.prototype.generateCategoryFromBlockLib = * Generate selector dom from block library storage. For each block in the * library, it has a block option, which consists of a checkbox, a label, * and a fixed size preview workspace. - * @param {!BlockLibraryStorage} blockLibStorage - Block Library Storage object. - * @param {string} blockSelectorID - ID of the div element that will contain + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object. + * @param {string} blockSelectorId ID of the div element that will contain * the block options. * @return {!Object} Map of block type to Block Option object. */ BlockExporterTools.prototype.createBlockSelectorFromLib = - function(blockLibStorage, blockSelectorID) { + function(blockLibStorage, blockSelectorId) { // Object mapping each stored block type to XML. var allBlockTypes = blockLibStorage.getBlockTypes(); var blockXmlMap = blockLibStorage.getBlockXmlMap(allBlockTypes); @@ -251,7 +251,7 @@ BlockExporterTools.prototype.createBlockSelectorFromLib = // them in the exporter workspace. this.addBlockDefinitions(blockXmlMap); - var blockSelector = document.getElementById(blockSelectorID); + var blockSelector = document.getElementById(blockSelectorId); // Clear the block selector. var child; while ((child = blockSelector.firstChild)) { diff --git a/demos/blockfactory/block_exporter_view.js b/demos/blockfactory/block_exporter_view.js index 011fc2bf5..198598c14 100644 --- a/demos/blockfactory/block_exporter_view.js +++ b/demos/blockfactory/block_exporter_view.js @@ -53,21 +53,6 @@ BlockExporterView.prototype.setBlockOptions = function(blockOptions) { this.blockOptions = blockOptions; }; -/** - * Updates the helper text. - * @param {string} newText New helper text. - * @param {boolean} opt_append True if appending to helper Text, false if - * replacing. - */ -BlockExporterView.prototype.updateHelperText = function(newText, opt_append) { - if (opt_append) { - document.getElementById('helperText').textContent = - document.getElementById('helperText').textContent + newText; - } else { - document.getElementById('helperText').textContent = newText; - } -}; - /** * Updates the helper text to show list of currently selected blocks. */ diff --git a/demos/blockfactory/block_library_controller.js b/demos/blockfactory/block_library_controller.js index 6754e6f41..fc5398c8c 100644 --- a/demos/blockfactory/block_library_controller.js +++ b/demos/blockfactory/block_library_controller.js @@ -203,8 +203,7 @@ BlockLibraryController.prototype.getBlockXml = function(blockType) { /** * Set the block library storage object from which exporter exports. - * @param {!BlockLibraryStorage} blockLibStorage - Block Library Storage - * object. + * @param {!BlockLibraryStorage} blockLibStorage Block Library Storage object. */ BlockLibraryController.prototype.setBlockLibraryStorage = function(blockLibStorage) { @@ -276,7 +275,7 @@ BlockLibraryController.prototype.addOptionSelectHandler = function(blockType) { // Thus, the buttons show up as a disabled update button and an enabled // delete. self.view.updateButtons(blockType, true, true); - self.view.hide(); + blocklyFactory.closeModal(); }; // Returns a block option select handler. diff --git a/demos/blockfactory/block_library_view.js b/demos/blockfactory/block_library_view.js index 6179841cd..16181f290 100644 --- a/demos/blockfactory/block_library_view.js +++ b/demos/blockfactory/block_library_view.js @@ -39,8 +39,6 @@ goog.require('goog.dom.classlist'); */ var BlockLibraryView = function() { // Div element to contain the block types to choose from. - // Id of the div that holds the block library view. - this.blockLibraryViewDivID = 'dropdownDiv_blockLib'; this.dropdown = document.getElementById('dropdownDiv_blockLib'); // Map of block type to corresponding 'a' element that is the option in the // dropdown. Used to quickly and easily get a specific option. @@ -54,23 +52,9 @@ var BlockLibraryView = function() { }; /** - * Open the Block Library dropdown. - */ -BlockLibraryView.prototype.show = function() { - this.dropdown.classList.add("show"); -}; - -/** - * Close the Block Library dropdown. - */ -BlockLibraryView.prototype.hide = function() { - this.dropdown.classList.remove("show"); -}; - -/** - * Creates a node of a given element type and appends to the node with given id. - * @param {string} blockType - Type of block. - * @param {boolean} selected - Whether or not the option should be selected on + * Creates a node of a given element type and appends to the node with given ID. + * @param {string} blockType Type of block. + * @param {boolean} selected Whether or not the option should be selected on * the dropdown. */ BlockLibraryView.prototype.addOption = function(blockType, selected) { @@ -93,7 +77,7 @@ BlockLibraryView.prototype.addOption = function(blockType, selected) { /** * Sets a given block type to selected and all other blocks to deselected. * If null, deselects all blocks. - * @param {string} blockTypeToSelect - Type of block to select or null. + * @param {string} blockTypeToSelect Type of block to select or null. */ BlockLibraryView.prototype.setSelectedBlockType = function(blockTypeToSelect) { // Select given block type and deselect all others. Will deselect all blocks @@ -210,7 +194,8 @@ BlockLibraryView.prototype.getSelectedOption = function() { */ BlockLibraryView.prototype.clearOptions = function() { var blockOpts = this.dropdown.getElementsByClassName('blockLibOpt'); - for (var i = 0, option; option = blockOpts[i]; i++) { + var option; + while ((option = blockOpts[0])) { option.parentNode.removeChild(option); } }; diff --git a/demos/blockfactory/block_option.js b/demos/blockfactory/block_option.js index 9e03b601a..8bc1a2fd4 100644 --- a/demos/blockfactory/block_option.js +++ b/demos/blockfactory/block_option.js @@ -35,10 +35,10 @@ goog.require('goog.dom'); * BlockOption Class * A block option includes checkbox, label, and div element that shows a preview * of the block. - * @param {!Element} blockSelector - Scrollable div that will contain the + * @param {!Element} blockSelector Scrollable div that will contain the * block options for the selector. - * @param {string} blockType - Type of block for which to create an option. - * @param {!Element} previewBlockXml - Xml element containing the preview block. + * @param {string} blockType Type of block for which to create an option. + * @param {!Element} previewBlockXml XML element containing the preview block. * @constructor */ var BlockOption = function(blockSelector, blockType, previewBlockXml) { diff --git a/demos/blockfactory/factory.css b/demos/blockfactory/factory.css index be2ebc40a..fa99314bb 100644 --- a/demos/blockfactory/factory.css +++ b/demos/blockfactory/factory.css @@ -102,6 +102,10 @@ pre, padding: 5px; } +.disabled { + color: #888; +} + button:disabled, .buttonStyle:disabled { opacity: 0.6; } @@ -386,11 +390,6 @@ td.taboff:hover { font-size: large; } -td { - padding: 0; - vertical-align: top; -} - .inputfile { height: 0; opacity: 0; @@ -467,12 +466,13 @@ td { #preload_div { display: table; - height: 70%; - margin-right: 5%; + height: 75%; + margin-left: 2%; + margin-right: 2%; max-height: 500px; overflow: hidden; overflow-y: scroll; - width: 35%; + width: 30%; } #shadowBlockDropdown { @@ -504,6 +504,17 @@ td { padding-left: 15px; } +#modalShadow { + display: none; + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(0, 0, 0, 0.05); + z-index: 100; +} + /* Rules for Closure popup color picker */ .goog-palette { outline: none; @@ -517,19 +528,19 @@ td { border: 0; text-align: center; vertical-align: middle; - border-right: 1px solid #000000; + border-right: 1px solid #000; font-size: 1px; } .goog-palette-colorswatch { - border: 1px solid #000000; + border: 1px solid #000; height: 13px; position: relative; width: 15px; } .goog-palette-cell-hover .goog-palette-colorswatch { - border: 1px solid #FFF; + border: 1px solid #fff; } .goog-palette-cell-selected .goog-palette-colorswatch { @@ -544,6 +555,7 @@ td { .goog-popupcolorpicker { position: absolute; + z-index: 101; /* On top of the modal Shadow. */ } /* The container
- needed to position the dropdown content */ @@ -553,13 +565,13 @@ td { /* Dropdown Content (Hidden by Default) */ .dropdown-content { - background-color: #FFF; + background-color: #fff; box-shadow: 0px 8px 16px 0px rgba(0,0,0,.2); display: none; min-width: 170px; opacity: 1; position: absolute; - z-index: 1; + z-index: 101; /* On top of the modal Shadow. */ } /* Links inside the dropdown */ diff --git a/demos/blockfactory/factory_utils.js b/demos/blockfactory/factory_utils.js index 17c2c4817..c5dc38982 100644 --- a/demos/blockfactory/factory_utils.js +++ b/demos/blockfactory/factory_utils.js @@ -36,11 +36,11 @@ goog.provide('FactoryUtils'); /** * Get block definition code for the current block. - * @param {string} blockType - Type of block. - * @param {!Blockly.Block} rootBlock - RootBlock from main workspace in which + * @param {string} blockType Type of block. + * @param {!Blockly.Block} rootBlock RootBlock from main workspace in which * user uses Block Factory Blocks to create a custom block. - * @param {string} format - 'JSON' or 'JavaScript'. - * @param {!Blockly.Workspace} workspace - Where the root block lives. + * @param {string} format 'JSON' or 'JavaScript'. + * @param {!Blockly.Workspace} workspace Where the root block lives. * @return {string} Block definition. */ FactoryUtils.getBlockDefinition = function(blockType, rootBlock, format, workspace) { @@ -259,7 +259,7 @@ FactoryUtils.formatJson_ = function(blockType, rootBlock) { * Update the language code as JavaScript. * @param {string} blockType Name of block. * @param {!Blockly.Block} rootBlock Factory_base block. - * @param {!Blockly.Workspace} workspace - Where the root block lives. + * @param {!Blockly.Workspace} workspace Where the root block lives. * @return {string} Generated language code. * @private */ @@ -345,7 +345,7 @@ FactoryUtils.formatJavaScript_ = function(blockType, rootBlock, workspace) { * Create JS code required to create a top, bottom, or value connection. * @param {string} functionName JavaScript function name. * @param {string} typeName Name of type input. - * @param {!Blockly.Workspace} workspace - Where the root block lives. + * @param {!Blockly.Workspace} workspace Where the root block lives. * @return {string} Line of JavaScript code to create connection. * @private */ @@ -639,9 +639,9 @@ FactoryUtils.escapeString = function(string) { /** * Return the uneditable container block that everything else attaches to in - * given workspace - * @param {!Blockly.Workspace} workspace - where the root block lives - * @return {Blockly.Block} root block + * given workspace. + * @param {!Blockly.Workspace} workspace Where the root block lives. + * @return {Blockly.Block} Root block. */ FactoryUtils.getRootBlock = function(workspace) { var blocks = workspace.getTopBlocks(false); @@ -884,8 +884,8 @@ FactoryUtils.injectCode = function(code, id) { */ FactoryUtils.sameBlockXml = function(blockXml1, blockXml2) { // Each XML element should contain a single child element with a 'block' tag - if (!blockXml1.tagName.toLowerCase() == 'xml' || - !blockXml2.tagName.toLowerCase() == 'xml') { + if (blockXml1.tagName.toLowerCase() != 'xml' || + blockXml2.tagName.toLowerCase() != 'xml') { throw new Error('Expected two XML elements, recieved elements with tag ' + 'names: ' + blockXml1.tagName + ' and ' + blockXml2.tagName + '.'); } @@ -943,7 +943,7 @@ FactoryUtils.isProcedureBlock = function(block) { * Returns whether or not a modified block's changes has been saved to the * Block Library. * TODO(quachtina96): move into the Block Factory Controller once made. - * @param {!BlockLibraryController} blockLibraryController - Block Library + * @param {!BlockLibraryController} blockLibraryController Block Library * Controller storing custom blocks. * @return {boolean} True if all changes made to the block have been saved to * the given Block Library. diff --git a/demos/blockfactory/index.html b/demos/blockfactory/index.html index 0ac9176da..b76151b74 100644 --- a/demos/blockfactory/index.html +++ b/demos/blockfactory/index.html @@ -5,20 +5,19 @@ - Blockly Demo: Blockly Factory + Blockly Demo: Blockly Developer Tools - + + + + - - - - @@ -29,6 +28,7 @@ + @@ -42,33 +42,34 @@ -

Blockly > - Demos > Blockly Developer Tools - -

-
-
Block Factory
-
Block Exporter
-
Workspace Factory
+

Blockly > + Demos > Blockly Developer Tools + +

+
+
Block Factory
+
Block Exporter
+
Workspace Factory

-

First, select blocks from your block library by clicking on them. Then, use the Export Settings form to download starter code for selected blocks. +

+ First, select blocks from your block library by clicking on them. Then, use the Export Settings form to download starter code for selected blocks.


-

Block Selector

- - Block Definition(s)
+
- Format: +
- File Name: -
- +
-
- Generator Stub(s)
+
+ +
- Language: +
- File Name: -
-
+
-
+
- +

-

Export Preview

-
-

Block Definitions:

-

-        
-
-

Generator Stubs:

-

-        
+

Export Preview

+
+

Block Definitions:

+

+      
+
+

Generator Stubs:

+

+      
@@ -158,15 +158,14 @@ -

@@ -175,27 +174,29 @@

Edit

Drag blocks into the workspace to configure the toolbox in your custom workspace.

- - - +
ToolboxWorkspace
+ + + +
ToolboxWorkspace
- - + + -