diff --git a/demos/blocklyfactory/app_controller.js b/demos/blocklyfactory/app_controller.js index 58477cb41..c698ad785 100644 --- a/demos/blocklyfactory/app_controller.js +++ b/demos/blocklyfactory/app_controller.js @@ -294,6 +294,14 @@ AppController.prototype.onTab = function() { // Update toolbox to reflect current block library. this.exporter.updateToolbox(); + // Need accurate state in order to know which blocks are used in workspace + // factory. + this.workspaceFactoryController.saveStateFromWorkspace(); + + // Update exporter's list of the types of blocks used in workspace factory. + var usedBlockTypes = this.workspaceFactoryController.getAllUsedBlockTypes(); + this.exporter.setUsedBlockTypes(usedBlockTypes); + // Show container of exporter. FactoryUtils.show('blockLibraryExporter'); FactoryUtils.hide('workspaceFactoryContent'); @@ -336,7 +344,7 @@ AppController.prototype.styleTabs_ = function() { */ AppController.prototype.assignExporterClickHandlers = function() { var self = this; - // Export blocks when the user submits the export settings. + document.getElementById('button_setBlocks').addEventListener('click', function() { document.getElementById('dropdownDiv_setBlocks').classList.toggle("show"); @@ -344,7 +352,7 @@ AppController.prototype.assignExporterClickHandlers = function() { document.getElementById('dropdown_addAllUsed').addEventListener('click', function() { - self.exporter.export(); + self.exporter.addUsedBlocksToWorkspace(); document.getElementById('dropdownDiv_setBlocks').classList.remove("show"); }); @@ -359,6 +367,12 @@ AppController.prototype.assignExporterClickHandlers = function() { self.exporter.addAllBlocksToWorkspace(); document.getElementById('dropdownDiv_setBlocks').classList.remove("show"); }); + + // Export blocks when the user submits the export settings. + document.getElementById('exporterSubmitButton').addEventListener('click', + function() { + self.exporter.export(); + }); }; /** diff --git a/demos/blocklyfactory/block_exporter_controller.js b/demos/blocklyfactory/block_exporter_controller.js index d6c6fd649..ec1d82449 100644 --- a/demos/blocklyfactory/block_exporter_controller.js +++ b/demos/blocklyfactory/block_exporter_controller.js @@ -51,6 +51,8 @@ BlockExporterController = function(blockLibStorage) { this.view = new BlockExporterView( //Xml representation of the toolbox this.tools.generateToolboxFromLibrary(this.blockLibStorage)); + // Array to hold the block types used in workspace factory. + this.usedBlockTypes = []; }; /** @@ -283,7 +285,7 @@ BlockExporterController.prototype.onDeselectBlockForExport_ = function(event) { var deletedBlockXml = event.oldXml; var blockType = deletedBlockXml.getAttribute('type'); // Do not try to enable any blocks deleted from the block library. - if (this.blockLibStorage[blockType]) { + if (this.blockLibStorage.has(blockType)) { // Enable the deselected block. this.setBlockEnabled(blockType, true); } @@ -332,3 +334,60 @@ BlockExporterController.prototype.addAllBlocksToWorkspace = function() { BlockExporterController.prototype.getBlockLibCategory = function() { return this.tools.generateCategoryFromBlockLib(this.blockLibStorage); }; + +/** + * Tied to the 'Add All Stored Blocks' button in the Block Exporter. + * Adds all blocks stored in block library to the selector workspace. + */ +BlockExporterController.prototype.addUsedBlocksToWorkspace = function() { + // Clear selector workspace. + this.view.clearSelectorWorkspace(); + + // Get list of block types that are in block library and used in workspace + // factory. + var storedBlockTypes = this.blockLibStorage.getBlockTypes(); + var sharedBlockTypes = []; + // Keep list of custom block types used but not in library. + var unstoredCustomBlockTypes = []; + + for (var i = 0, blockType; blockType = this.usedBlockTypes[i]; i++) { + if (storedBlockTypes.indexOf(blockType) != -1) { + sharedBlockTypes.push(blockType); + } else if (BlockFactory.standardBlockTypes.indexOf(blockType) == -1) { + unstoredCustomBlockTypes.push(blockType); + } + } + + // Add and evaluate the shared blocks' definitions. + var blockXmlMap = this.blockLibStorage.getBlockXmlMap(sharedBlockTypes); + this.tools.addBlockDefinitions(blockXmlMap); + + // For every block, render in selector workspace. + for (var i = 0, blockType; blockType = sharedBlockTypes[i]; i++) { + this.view.addBlock(blockType); + } + + // Clean up workspace. + this.view.cleanUpSelectorWorkspace(); + + if (unstoredCustomBlockTypes.length > 0){ + // Warn user to import block definitions and generator code for blocks + // not in their Block Library nor Blockly's standard library. + var blockTypesText = unstoredCustomBlockTypes.join(', '); + var customWarning = 'Custom blocks used in workspace factory but not ' + + 'stored in block library:\n ' + blockTypesText + + '\n\nDon\'t forget to include block definitions and generator code ' + + 'for these blocks.'; + alert(customWarning); + } +}; + +/** + * Set the array that holds the block types used in workspace factory. + * + * @param {!Array.} usedBlockTypes - Block types used in + */ +BlockExporterController.prototype.setUsedBlockTypes = + function(usedBlockTypes) { + this.usedBlockTypes = usedBlockTypes; +}; diff --git a/demos/blocklyfactory/block_library_controller.js b/demos/blocklyfactory/block_library_controller.js index 514eeaaeb..62a3a747a 100644 --- a/demos/blocklyfactory/block_library_controller.js +++ b/demos/blocklyfactory/block_library_controller.js @@ -208,8 +208,7 @@ BlockLibraryController.prototype.setBlockLibStorage * @return {!BlockLibraryStorage} blockLibStorage - Block Library Storage object * that stores the blocks. */ -BlockLibraryController.prototype.getBlockLibStorage = - function(blockLibStorage) { +BlockLibraryController.prototype.getBlockLibStorage = function() { return this.blockLibStorage; }; diff --git a/demos/blocklyfactory/block_library_storage.js b/demos/blocklyfactory/block_library_storage.js index 4bca70242..c4361959e 100644 --- a/demos/blocklyfactory/block_library_storage.js +++ b/demos/blocklyfactory/block_library_storage.js @@ -165,3 +165,14 @@ BlockLibraryStorage.prototype.isEmpty = function() { BlockLibraryStorage.prototype.getBlockXmlTextMap = function() { return this.blocks; }; + +/** + * Returns boolean of whether or not a given blockType is stored in block + * library. + * + * @param {string} blockType - Type of block. + * @return {boolean} Whether or not blockType is stored in block library. + */ +BlockLibraryStorage.prototype.has = function(blockType) { + return this.blocks[blockType] ? true : false; +}; diff --git a/demos/blocklyfactory/factory_utils.js b/demos/blocklyfactory/factory_utils.js index 35a677d68..c167f7136 100644 --- a/demos/blocklyfactory/factory_utils.js +++ b/demos/blocklyfactory/factory_utils.js @@ -872,3 +872,4 @@ FactoryUtils.defineAndGetBlockTypes = function(blockDefsString, format) { return blockTypes; }; + diff --git a/demos/blocklyfactory/workspacefactory/wfactory_controller.js b/demos/blocklyfactory/workspacefactory/wfactory_controller.js index 2c42b865f..da5749921 100644 --- a/demos/blocklyfactory/workspacefactory/wfactory_controller.js +++ b/demos/blocklyfactory/workspacefactory/wfactory_controller.js @@ -1192,3 +1192,12 @@ WorkspaceFactoryController.prototype.setBlockLibCategory = this.toolboxWorkspace.updateToolbox(this.toolbox); }; +/** + * Return the block types used in the custom toolbox and pre-loaded workspace. + * + * @return {!Array.} Block types used in the custom toolbox and + * pre-loaded workspace. + */ +WorkspaceFactoryController.prototype.getAllUsedBlockTypes = function() { + return this.model.getAllUsedBlockTypes(); +}; diff --git a/demos/blocklyfactory/workspacefactory/wfactory_model.js b/demos/blocklyfactory/workspacefactory/wfactory_model.js index 13154c11d..bcb622a11 100644 --- a/demos/blocklyfactory/workspacefactory/wfactory_model.js +++ b/demos/blocklyfactory/workspacefactory/wfactory_model.js @@ -436,7 +436,7 @@ WorkspaceFactoryModel.prototype.getAllUsedBlockTypes = function() { // Given XML for the workspace, adds all block types included in the XML // to the list, not including duplicates. - var pushBlockTypesToList = function (xml, list) { + var pushBlockTypesToList = function(xml, list) { // Get all block XML nodes. var blocks = xml.getElementsByTagName('block'); @@ -451,22 +451,22 @@ WorkspaceFactoryModel.prototype.getAllUsedBlockTypes = function() { if (this.flyout) { // If has a single flyout, add block types for the single flyout. - this.pushBlockTypesToList(this.getSelectedXml(), blockTypeList); + pushBlockTypesToList(this.getSelectedXml(), blockTypeList); } else { // If has categories, add block types for each category. for (var i = 0, category; category = this.toolboxList[i]; i++) { if (category.type == ListElement.TYPE_CATEGORY) { - this.pushBlockTypesToList(category.xml, blockTypeList); + pushBlockTypesToList(category.xml, blockTypeList); } } } // Add the block types from any pre-loaded blocks. - this.pushBlockTypesToList(this.getPreloadXml(), blockTypeList); + pushBlockTypesToList(this.getPreloadXml(), blockTypeList); return blockTypeList; -} +}; /** * Class for a ListElement.