diff --git a/demos/blocklyfactory/app_controller.js b/demos/blocklyfactory/app_controller.js index c698ad785..0e686631b 100644 --- a/demos/blocklyfactory/app_controller.js +++ b/demos/blocklyfactory/app_controller.js @@ -302,6 +302,9 @@ AppController.prototype.onTab = function() { var usedBlockTypes = this.workspaceFactoryController.getAllUsedBlockTypes(); this.exporter.setUsedBlockTypes(usedBlockTypes); + // Update the preview to reflect any changes made to the blocks. + this.exporter.updatePreview(); + // Show container of exporter. FactoryUtils.show('blockLibraryExporter'); FactoryUtils.hide('workspaceFactoryContent'); @@ -344,7 +347,6 @@ AppController.prototype.styleTabs_ = function() { */ AppController.prototype.assignExporterClickHandlers = function() { var self = this; - document.getElementById('button_setBlocks').addEventListener('click', function() { document.getElementById('dropdownDiv_setBlocks').classList.toggle("show"); @@ -375,6 +377,68 @@ AppController.prototype.assignExporterClickHandlers = function() { }); }; +/** + * Assign change listeners for the exporter. These allow for the dynamic update + * of the exporter preview. + */ +AppController.prototype.assignExporterChangeListeners = function() { + var self = this; + + var blockDefCheck = document.getElementById('blockDefCheck'); + var genStubCheck = document.getElementById('genStubCheck'); + + var blockDefs = document.getElementById('blockDefs'); + var blockDefSettings = document.getElementById('blockDefSettings'); + var blockDefElements = [blockDefs, blockDefSettings]; + + var genStubs = document.getElementById('genStubs'); + var genStubSettings = document.getElementById('genStubSettings'); + var genStubElements = [genStubs, genStubSettings]; + + // Select the block definitions and generator stubs on default. + blockDefCheck.checked = true; + genStubCheck.checked = true; + + // Checking the block definitions checkbox displays preview of code to export. + document.getElementById('blockDefCheck').addEventListener('change', + function(e) { + self.ifCheckedDisplay(blockDefCheck, blockDefElements); + }); + + // Preview updates when user selects different block definition format. + document.getElementById('exportFormat').addEventListener('change', + function(e) { + self.exporter.updatePreview(); + }); + + // Checking the generator stub checkbox displays preview of code to export. + document.getElementById('genStubCheck').addEventListener('change', + function(e) { + self.ifCheckedDisplay(genStubCheck, genStubElements); + }); + + // Preview updates when user selects different generator stub language. + document.getElementById('exportLanguage').addEventListener('change', + function(e) { + self.exporter.updatePreview(); + }); + + self.exporter.addChangeListenersToSelectorWorkspace(); +}; + +/** + * If given checkbox is checked, display given elements. Otherwise, hide. + * + * @param {!Element} checkbox - Input element of type checkbox. + * @param {!Array.} elementArray - Array of elements to show when + * block is checked. + */ +AppController.prototype.ifCheckedDisplay = function(checkbox, elementArray) { + for (var i = 0, element; element = elementArray[i]; i++) { + element.style.display = checkbox.checked ? 'block' : 'none'; + } +}; + /** * Assign button click handlers for the block library. */ @@ -522,7 +586,8 @@ AppController.prototype.init = function() { // Add tab handlers for switching between Block Factory and Block Exporter. this.addTabHandlers(this.tabMap); - this.exporter.addChangeListenersToSelectorWorkspace(); + // Assign exporter change listeners. + this.assignExporterChangeListeners(); // Create the root block on Block Factory main workspace. if ('BlocklyStorage' in window && window.location.hash.length > 1) { diff --git a/demos/blocklyfactory/block_exporter_controller.js b/demos/blocklyfactory/block_exporter_controller.js index ec1d82449..017bef4ca 100644 --- a/demos/blocklyfactory/block_exporter_controller.js +++ b/demos/blocklyfactory/block_exporter_controller.js @@ -103,13 +103,6 @@ BlockExporterController.prototype.export = function() { var blockTypes = this.getSelectedBlockTypes_(); var blockXmlMap = this.blockLibStorage.getBlockXmlMap(blockTypes); - // Pull workspace-related settings from the Export Settings form. - var wantToolbox = document.getElementById('toolboxCheck').checked; - var wantPreloadedWorkspace = - document.getElementById('preloadedWorkspaceCheck').checked; - var wantWorkspaceOptions = - document.getElementById('workspaceOptsCheck').checked; - // Pull block definition(s) settings from the Export Settings form. var wantBlockDef = document.getElementById('blockDefCheck').checked; var definitionFormat = document.getElementById('exportFormat').value; @@ -121,21 +114,6 @@ BlockExporterController.prototype.export = function() { var generatorStub_filename = document.getElementById( 'generatorStub_filename').value; - if (wantToolbox) { - // TODO(quachtina96): create and download file once wfactory has been - // integrated. - } - - if (wantPreloadedWorkspace) { - // TODO(quachtina96): create and download file once wfactory has been - // integrated. - } - - if (wantWorkspaceOptions) { - // TODO(quachtina96): create and download file once wfactory has been - // integrated. - } - if (wantBlockDef) { // User wants to export selected blocks' definitions. if (!blockDef_filename) { @@ -143,7 +121,7 @@ BlockExporterController.prototype.export = function() { alert('Please enter a filename for your block definition(s) download.'); } else { // Get block definition code in the selected format for the blocks. - var blockDefs = this.tools.getBlockDefs(blockXmlMap, + var blockDefs = this.tools.getBlockDefinitions(blockXmlMap, definitionFormat); // Download the file, using .js file ending for JSON or Javascript. FactoryUtils.createAndDownloadFile( @@ -267,6 +245,7 @@ BlockExporterController.prototype.onSelectBlockForExport_ = function(event) { this.setBlockEnabled(blockType, false); // Show currently selected blocks in helper text. this.view.listSelectedBlocks(this.getSelectedBlockTypes_()); + this.updatePreview(); } }; @@ -291,6 +270,7 @@ BlockExporterController.prototype.onDeselectBlockForExport_ = function(event) { } // Show currently selected blocks in helper text. this.view.listSelectedBlocks(this.getSelectedBlockTypes_()); + this.updatePreview(); } }; @@ -391,3 +371,58 @@ BlockExporterController.prototype.setUsedBlockTypes = function(usedBlockTypes) { this.usedBlockTypes = usedBlockTypes; }; + +/** + * Updates preview code (block definitions and generator stubs) in the exporter + * preview to reflect selected blocks. + */ +BlockExporterController.prototype.updatePreview = function() { + // Generate preview code for selected blocks. + var blockDefs = this.getBlockDefinitionsOfSelected(); + var genStubs = this.getGeneratorStubsOfSelected(); + + // Update the text areas containing the code. + FactoryUtils.injectCode(blockDefs, 'blockDefs_textArea'); + FactoryUtils.injectCode(genStubs, 'genStubs_textArea'); +}; + +/** + * Returns a map of each selected block's type to its corresponding xml. + * + * @return {!Object} a map of each selected block's type (a string) to its + * corresponding xml element. + */ +BlockExporterController.prototype.getSelectedBlockXmlMap = function() { + var blockTypes = this.getSelectedBlockTypes_(); + return this.blockLibStorage.getBlockXmlMap(blockTypes); +}; + +/** + * Get block definition code in the selected format for selected blocks. + * + * @return {!string} The concatenation of each selected block's language code + * in the format specified in export settings. + */ +BlockExporterController.prototype.getBlockDefinitionsOfSelected = function() { + // Get selected blocks' information. + var blockXmlMap = this.getSelectedBlockXmlMap(); + + // Get block definition code in the selected format for the blocks. + var definitionFormat = document.getElementById('exportFormat').value; + return this.tools.getBlockDefinitions(blockXmlMap, definitionFormat); +}; + +/** + * Get generator stubs in the selected language for selected blocks. + * + * @return {!string} The concatenation of each selected block's generator stub + * in the language specified in export settings. + */ +BlockExporterController.prototype.getGeneratorStubsOfSelected = function() { + // Get selected blocks' information. + var blockXmlMap = this.getSelectedBlockXmlMap(); + + // Get generator stub code in the selected language for the blocks. + var language = document.getElementById('exportLanguage').value; + return this.tools.getGeneratorCode(blockXmlMap, language); +}; diff --git a/demos/blocklyfactory/block_exporter_tools.js b/demos/blocklyfactory/block_exporter_tools.js index 4c4381715..d41dd10a2 100644 --- a/demos/blocklyfactory/block_exporter_tools.js +++ b/demos/blocklyfactory/block_exporter_tools.js @@ -83,7 +83,7 @@ BlockExporterTools.prototype.getRootBlockFromXml_ = function(xml) { * @return {string} The concatenation of each block's language code in the * desired format. */ -BlockExporterTools.prototype.getBlockDefs = +BlockExporterTools.prototype.getBlockDefinitions = function(blockXmlMap, definitionFormat) { var blockCode = []; for (var blockType in blockXmlMap) { @@ -160,7 +160,7 @@ BlockExporterTools.prototype.getGeneratorCode = * @param {!Object} blockXmlMap - Map of block type to xml. */ BlockExporterTools.prototype.addBlockDefinitions = function(blockXmlMap) { - var blockDefs = this.getBlockDefs(blockXmlMap, 'JavaScript'); + var blockDefs = this.getBlockDefinitions(blockXmlMap, 'JavaScript'); eval(blockDefs); }; diff --git a/demos/blocklyfactory/factory.css b/demos/blocklyfactory/factory.css index 96736febd..4ce84e68c 100644 --- a/demos/blocklyfactory/factory.css +++ b/demos/blocklyfactory/factory.css @@ -20,6 +20,7 @@ html, body { height: 100%; + min-height: 375px; } body { @@ -209,24 +210,49 @@ button, .buttonStyle { } ::-webkit-scrollbar { - -webkit-appearance: none; - width: 7px; + -webkit-appearance: none; + width: 7px; } + ::-webkit-scrollbar-thumb { - border-radius: 4px; - background-color: #ccc; - -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); + border-radius: 4px; + background-color: #ccc; + -webkit-box-shadow: 0 0 1px rgba(255,255,255,.5); +} + +.subsettings { + margin: 0px 25px; } #exporterHiddenWorkspace { display: none; } -#exporterPreview { +#exportPreview { float: right; - padding: 16px; + height: 90%; overflow: hidden; - background-color: blue; + width: 45%; +} + +.exportPreviewTextArea { + display: block; + float: right; + height: 40%; + width: 100%; +} + +#genStubs_textArea, #blockDefs_textArea { + display: block; + height: 80%; + margin-right: 20px; + max-height: 300px; + overflow: scroll; + position: static; +} + +#blockDefs_label, #genStubs_label { + display: block; } /* Tabs */ diff --git a/demos/blocklyfactory/factory.js b/demos/blocklyfactory/factory.js index f881730ed..964b6a85b 100644 --- a/demos/blocklyfactory/factory.js +++ b/demos/blocklyfactory/factory.js @@ -87,7 +87,7 @@ BlockFactory.oldDir = null; * @param {string} code Lines of code. * @param {string} id ID of
 element to inject into.
  */
-BlockFactory.injectCode = function(code, id) {
+FactoryUtils.injectCode = function(code, id) {
   var pre = document.getElementById(id);
   pre.textContent = code;
   code = pre.innerHTML;
@@ -135,7 +135,7 @@ BlockFactory.updateLanguage = function() {
   var format = document.getElementById('format').value;
   var code = FactoryUtils.getBlockDefinition(blockType, rootBlock, format,
       BlockFactory.mainWorkspace);
-  BlockFactory.injectCode(code, 'languagePre');
+  FactoryUtils.injectCode(code, 'languagePre');
   BlockFactory.updatePreview();
 };
 
@@ -146,7 +146,7 @@ BlockFactory.updateLanguage = function() {
 BlockFactory.updateGenerator = function(block) {
   var language = document.getElementById('language').value;
   var generatorStub = FactoryUtils.getGeneratorStub(block, language);
-  BlockFactory.injectCode(generatorStub, 'generatorPre');
+  FactoryUtils.injectCode(generatorStub, 'generatorPre');
 };
 
 /**
diff --git a/demos/blocklyfactory/factory_utils.js b/demos/blocklyfactory/factory_utils.js
index c167f7136..098a0a3de 100644
--- a/demos/blocklyfactory/factory_utils.js
+++ b/demos/blocklyfactory/factory_utils.js
@@ -873,3 +873,16 @@ FactoryUtils.defineAndGetBlockTypes = function(blockDefsString, format) {
   return blockTypes;
 };
 
+/**
+ * Inject code into a pre tag, with syntax highlighting.
+ * Safe from HTML/script injection.
+ * @param {string} code Lines of code.
+ * @param {string} id ID of 
 element to inject into.
+ */
+FactoryUtils.injectCode = function(code, id) {
+  var pre = document.getElementById(id);
+  pre.textContent = code;
+  code = pre.innerHTML;
+  code = prettyPrintOne(code, 'js');
+  pre.innerHTML = code;
+};
diff --git a/demos/blocklyfactory/index.html b/demos/blocklyfactory/index.html
index b9f47a06d..febef6609 100644
--- a/demos/blocklyfactory/index.html
+++ b/demos/blocklyfactory/index.html
@@ -79,43 +79,54 @@
     

Export Settings

-

Currently Selected:

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

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

+


-

Preview Workspace:

-
-
+

Export Preview

+
+

Block Definitions:

+

+        
+
+

Generator Stubs:

+

+