From e03b191f7344ed168642d63a0d6e853808a3c7b8 Mon Sep 17 00:00:00 2001 From: Sean Lip Date: Thu, 18 Aug 2016 19:27:25 -0700 Subject: [PATCH 1/5] Add more help labels. --- accessible/field.component.js | 3 ++- accessible/tree.service.js | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/accessible/field.component.js b/accessible/field.component.js index b8e7d79be..e10323db7 100644 --- a/accessible/field.component.js +++ b/accessible/field.component.js @@ -46,7 +46,8 @@ blocklyApp.FieldComponent = ng.core
  • diff --git a/accessible/tree.service.js b/accessible/tree.service.js index 0c463e191..3b41659d9 100644 --- a/accessible/tree.service.js +++ b/accessible/tree.service.js @@ -290,6 +290,8 @@ blocklyApp.TreeService = ng.core break; } else if (currentNode.tagName == 'INPUT') { currentNode.focus(); + this.notificationsService.setStatusMessage( + 'Type a value, then press Escape to exit'); break; } else if (currentNode.tagName == 'LI') { continue; From 88eac2480bc6f8b84f39ea14cac8d010b0541b6a Mon Sep 17 00:00:00 2001 From: Rodrigo Queiro Date: Fri, 19 Aug 2016 12:55:45 +0200 Subject: [PATCH 2/5] Convert string tag name to goog.dom.TagName (#515) in createDom calls only. This improves the type information of the created objects. --- core/field_textinput.js | 4 +++- core/toolbox.js | 4 +++- core/tooltip.js | 4 +++- core/widgetdiv.js | 4 +++- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/core/field_textinput.js b/core/field_textinput.js index 859244bba..5af8bf9a7 100644 --- a/core/field_textinput.js +++ b/core/field_textinput.js @@ -30,6 +30,7 @@ goog.require('Blockly.Field'); goog.require('Blockly.Msg'); goog.require('goog.asserts'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.userAgent'); @@ -124,7 +125,8 @@ Blockly.FieldTextInput.prototype.showEditor_ = function(opt_quietInput) { Blockly.WidgetDiv.show(this, this.sourceBlock_.RTL, this.widgetDispose_()); var div = Blockly.WidgetDiv.DIV; // Create the input. - var htmlInput = goog.dom.createDom('input', 'blocklyHtmlInput'); + var htmlInput = + goog.dom.createDom(goog.dom.TagName.INPUT, 'blocklyHtmlInput'); htmlInput.setAttribute('spellcheck', this.spellcheck_); var fontSize = (Blockly.FieldTextInput.FONTSIZE * this.workspace_.scale) + 'pt'; diff --git a/core/toolbox.js b/core/toolbox.js index eab72b30e..f9bac9e6d 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -28,6 +28,7 @@ goog.provide('Blockly.Toolbox'); goog.require('Blockly.Flyout'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.events'); goog.require('goog.events.BrowserFeature'); goog.require('goog.html.SafeHtml'); @@ -147,7 +148,8 @@ Blockly.Toolbox.prototype.init = function() { var svg = this.workspace_.getParentSvg(); // Create an HTML container for the Toolbox menu. - this.HtmlDiv = goog.dom.createDom('div', 'blocklyToolboxDiv'); + this.HtmlDiv = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyToolboxDiv'); this.HtmlDiv.setAttribute('dir', workspace.RTL ? 'RTL' : 'LTR'); svg.parentNode.insertBefore(this.HtmlDiv, svg); diff --git a/core/tooltip.js b/core/tooltip.js index 3aa828812..2ff612b7b 100644 --- a/core/tooltip.js +++ b/core/tooltip.js @@ -32,6 +32,7 @@ goog.provide('Blockly.Tooltip'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); /** @@ -120,7 +121,8 @@ Blockly.Tooltip.createDom = function() { return; // Already created. } // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.Tooltip.DIV = goog.dom.createDom('div', 'blocklyTooltipDiv'); + Blockly.Tooltip.DIV = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyTooltipDiv'); document.body.appendChild(Blockly.Tooltip.DIV); }; diff --git a/core/widgetdiv.js b/core/widgetdiv.js index 837364d99..a811339b3 100644 --- a/core/widgetdiv.js +++ b/core/widgetdiv.js @@ -30,6 +30,7 @@ goog.provide('Blockly.WidgetDiv'); goog.require('Blockly.Css'); goog.require('goog.dom'); +goog.require('goog.dom.TagName'); goog.require('goog.style'); @@ -61,7 +62,8 @@ Blockly.WidgetDiv.createDom = function() { return; // Already created. } // Create an HTML container for popup overlays (e.g. editor widgets). - Blockly.WidgetDiv.DIV = goog.dom.createDom('div', 'blocklyWidgetDiv'); + Blockly.WidgetDiv.DIV = + goog.dom.createDom(goog.dom.TagName.DIV, 'blocklyWidgetDiv'); document.body.appendChild(Blockly.WidgetDiv.DIV); }; From 61af94314efde493ff627b83789c148d2e42d4a5 Mon Sep 17 00:00:00 2001 From: Emma Dauterman Date: Fri, 19 Aug 2016 09:48:51 -0700 Subject: [PATCH 3/5] Blockly Factory: Generate Block Library Category in Workspace Factory (#568) * Added block library category to toolbox workspace in workspace factory and update it each time user switches to workspace factory * Added whitespace to end of index.html * Bug fixes for convertShadowBlocks and updateState * Last part of bug fix for adding separators --- demos/blocklyfactory/app_controller.js | 3 ++ demos/blocklyfactory/index.html | 3 +- .../workspacefactory/wfactory_controller.js | 49 ++++++++++++------- .../workspacefactory/wfactory_view.js | 3 +- 4 files changed, 39 insertions(+), 19 deletions(-) diff --git a/demos/blocklyfactory/app_controller.js b/demos/blocklyfactory/app_controller.js index d9a092132..58477cb41 100644 --- a/demos/blocklyfactory/app_controller.js +++ b/demos/blocklyfactory/app_controller.js @@ -304,6 +304,9 @@ AppController.prototype.onTab = function() { FactoryUtils.hide('workspaceFactoryContent'); } else if (this.selectedTab == 'WORKSPACE_FACTORY') { + // Update block library category. + var categoryXml = this.exporter.getBlockLibCategory(); + this.workspaceFactoryController.setBlockLibCategory(categoryXml); // Hide container of exporter. FactoryUtils.hide('blockLibraryExporter'); // Show workspace factory container. diff --git a/demos/blocklyfactory/index.html b/demos/blocklyfactory/index.html index c7792cd37..c866d7b35 100644 --- a/demos/blocklyfactory/index.html +++ b/demos/blocklyfactory/index.html @@ -715,7 +715,8 @@ + - \ No newline at end of file + diff --git a/demos/blocklyfactory/workspacefactory/wfactory_controller.js b/demos/blocklyfactory/workspacefactory/wfactory_controller.js index 10fce767b..2a24660bb 100644 --- a/demos/blocklyfactory/workspacefactory/wfactory_controller.js +++ b/demos/blocklyfactory/workspacefactory/wfactory_controller.js @@ -232,7 +232,6 @@ WorkspaceFactoryController.prototype.removeElement = function() { // when there are no categories. this.allowToSetDefaultOptions(); } - // Update preview. this.updatePreview(); }; @@ -288,12 +287,6 @@ WorkspaceFactoryController.prototype.clearAndLoadElement = function(id) { this.view.setCategoryTabSelection(this.model.getSelectedId(), false); } - // If switching from a separator, enable workspace in view. - if (this.model.getSelectedId() != null && this.model.getSelected().type == - ListElement.TYPE_SEPARATOR) { - this.view.disableWorkspace(false); - } - // If switching to another category, set category selection in the model and // view. if (id != null) { @@ -305,16 +298,19 @@ WorkspaceFactoryController.prototype.clearAndLoadElement = function(id) { // Selects the next tab. this.view.setCategoryTabSelection(id, true); + + // Mark all shadow blocks laoded and order blocks as if shown in a flyout. + this.view.markShadowBlocks(this.model.getShadowBlocksInWorkspace + (this.toolboxWorkspace.getAllBlocks())); + this.toolboxWorkspace.cleanUp(); + + // Update category editing buttons. + this.view.updateState(this.model.getIndexByElementId + (this.model.getSelectedId()), this.model.getSelected()); + } else { + // Update category editing buttons for no categories. + this.view.updateState(-1, null); } - - // Mark all shadow blocks laoded and order blocks as if shown in a flyout. - this.view.markShadowBlocks(this.model.getShadowBlocksInWorkspace - (this.toolboxWorkspace.getAllBlocks())); - this.toolboxWorkspace.cleanUp(); - - // Update category editing buttons. - this.view.updateState(this.model.getIndexByElementId - (this.model.getSelectedId()), this.model.getSelected()); }; /** @@ -608,7 +604,7 @@ WorkspaceFactoryController.prototype.loadCategory = function() { // Switch to loaded category. this.switchElement(copy.id); // Convert actual shadow blocks to user-generated shadow blocks. - this.convertShadowBlocks_(); + this.convertShadowBlocks(); // Save state from workspace before updating preview. this.saveStateFromWorkspace(); if (isFirstCategory) { @@ -1177,3 +1173,22 @@ WorkspaceFactoryController.prototype.importBlocks = reader.readAsText(file); }; +/* + * Updates the block library category in the toolbox workspace toolbox. + * + * @param {!Element} categoryXml XML for the block library category. + */ +WorkspaceFactoryController.prototype.setBlockLibCategory = + function(categoryXml) { + var blockLibCategory = document.getElementById('blockLibCategory'); + + // Set category id so that it can be easily replaced, and set a standard, + // arbitrary block library color. + categoryXml.setAttribute('id', 'blockLibCategory'); + categoryXml.setAttribute('colour', 260); + + // Update the toolbox and toolboxWorkspace. + this.toolbox.replaceChild(categoryXml, blockLibCategory); + this.toolboxWorkspace.updateToolbox(this.toolbox); +}; + diff --git a/demos/blocklyfactory/workspacefactory/wfactory_view.js b/demos/blocklyfactory/workspacefactory/wfactory_view.js index d843a9365..ad855709c 100644 --- a/demos/blocklyfactory/workspacefactory/wfactory_view.js +++ b/demos/blocklyfactory/workspacefactory/wfactory_view.js @@ -282,7 +282,8 @@ WorkspaceFactoryView.prototype.disableWorkspace = function(disable) { * @return {boolean} True if the workspace should be disabled, false otherwise. */ WorkspaceFactoryView.prototype.shouldDisableWorkspace = function(category) { - return category != null && (category.type == ListElement.TYPE_SEPARATOR || + return category != null && category.type != ListElement.TYPE_FLYOUT && + (category.type == ListElement.TYPE_SEPARATOR || category.custom == 'VARIABLE' || category.custom == 'PROCEDURE'); }; From 7fc476db36121fdf87071be87ed305150df4c995 Mon Sep 17 00:00:00 2001 From: Emma Dauterman Date: Fri, 19 Aug 2016 14:59:09 -0700 Subject: [PATCH 4/5] Made StandardCategories a namespace for all of BlocklyFactory to use, included coreBlockTypes (#572) --- demos/blocklyfactory/index.html | 9 +- .../standard_categories.js | 97 +++++++++++-------- .../workspacefactory/wfactory_controller.js | 10 +- 3 files changed, 60 insertions(+), 56 deletions(-) rename demos/blocklyfactory/{workspacefactory => }/standard_categories.js (79%) diff --git a/demos/blocklyfactory/index.html b/demos/blocklyfactory/index.html index c866d7b35..9f5841292 100644 --- a/demos/blocklyfactory/index.html +++ b/demos/blocklyfactory/index.html @@ -15,7 +15,7 @@ - + @@ -487,13 +487,6 @@ - - - - 1 - - - diff --git a/demos/blocklyfactory/workspacefactory/standard_categories.js b/demos/blocklyfactory/standard_categories.js similarity index 79% rename from demos/blocklyfactory/workspacefactory/standard_categories.js rename to demos/blocklyfactory/standard_categories.js index 322eab6e4..ef102fc95 100644 --- a/demos/blocklyfactory/workspacefactory/standard_categories.js +++ b/demos/blocklyfactory/standard_categories.js @@ -22,16 +22,25 @@ * @fileoverview Contains a map of standard Blockly categories used to load * standard Blockly categories into the user's toolbox. The map is keyed by * the lower case name of the category, and contains the Category object for - * that particular category. + * that particular category. Also has a list of core block types provided + * by Blockly. * * @author Emma Dauterman (evd2014) */ + 'use strict'; -WorkspaceFactoryController.prototype.standardCategories = Object.create(null); +/** + * Namespace for StandardCategories + */ +goog.provide('StandardCategories'); -WorkspaceFactoryController.prototype.standardCategories['logic'] = +// Map of standard category information necessary to add a standard category +// to the toolbox. +StandardCategories.categoryMap = Object.create(null); + +StandardCategories.categoryMap['logic'] = new ListElement(ListElement.TYPE_CATEGORY, 'Logic'); -WorkspaceFactoryController.prototype.standardCategories['logic'].xml = +StandardCategories.categoryMap['logic'].xml = Blockly.Xml.textToDom( '' + '' + @@ -42,12 +51,11 @@ WorkspaceFactoryController.prototype.standardCategories['logic'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['logic'].color = - '#5C81A6'; +StandardCategories.categoryMap['logic'].color ='#5C81A6'; -WorkspaceFactoryController.prototype.standardCategories['loops'] = +StandardCategories.categoryMap['loops'] = new ListElement(ListElement.TYPE_CATEGORY, 'Loops'); -WorkspaceFactoryController.prototype.standardCategories['loops'].xml = +StandardCategories.categoryMap['loops'].xml = Blockly.Xml.textToDom( '' + '' + @@ -78,12 +86,11 @@ WorkspaceFactoryController.prototype.standardCategories['loops'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['loops'].color = - '#5CA65C'; +StandardCategories.categoryMap['loops'].color = '#5CA65C'; -WorkspaceFactoryController.prototype.standardCategories['math'] = +StandardCategories.categoryMap['math'] = new ListElement(ListElement.TYPE_CATEGORY, 'Math'); -WorkspaceFactoryController.prototype.standardCategories['math'].xml = +StandardCategories.categoryMap['math'].xml = Blockly.Xml.textToDom( '' + '' + @@ -121,13 +128,6 @@ WorkspaceFactoryController.prototype.standardCategories['math'].xml = '' + '' + '' + - '' + - '' + - '' + - '1' + - '' + - '' + - '' + '' + '' + '' + @@ -179,12 +179,11 @@ WorkspaceFactoryController.prototype.standardCategories['math'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['math'].color = - '#5C68A6'; +StandardCategories.categoryMap['math'].color = '#5C68A6'; -WorkspaceFactoryController.prototype.standardCategories['text'] = +StandardCategories.categoryMap['text'] = new ListElement(ListElement.TYPE_CATEGORY, 'Text'); -WorkspaceFactoryController.prototype.standardCategories['text'].xml = +StandardCategories.categoryMap['text'].xml = Blockly.Xml.textToDom( '' + '' + @@ -263,12 +262,11 @@ WorkspaceFactoryController.prototype.standardCategories['text'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['text'].color = - '#5CA68D'; +StandardCategories.categoryMap['text'].color = '#5CA68D'; -WorkspaceFactoryController.prototype.standardCategories['lists'] = +StandardCategories.categoryMap['lists'] = new ListElement(ListElement.TYPE_CATEGORY, 'Lists'); -WorkspaceFactoryController.prototype.standardCategories['lists'].xml = +StandardCategories.categoryMap['lists'].xml = Blockly.Xml.textToDom( '' + '' + @@ -321,12 +319,11 @@ WorkspaceFactoryController.prototype.standardCategories['lists'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['lists'].color = - '#745CA6'; +StandardCategories.categoryMap['lists'].color = '#745CA6'; -WorkspaceFactoryController.prototype.standardCategories['colour'] = +StandardCategories.categoryMap['colour'] = new ListElement(ListElement.TYPE_CATEGORY, 'Colour'); -WorkspaceFactoryController.prototype.standardCategories['colour'].xml = +StandardCategories.categoryMap['colour'].xml = Blockly.Xml.textToDom( '' + '' + @@ -366,19 +363,33 @@ WorkspaceFactoryController.prototype.standardCategories['colour'].xml = '' + '' + ''); -WorkspaceFactoryController.prototype.standardCategories['colour'].color = - '#A6745C'; +StandardCategories.categoryMap['colour'].color = '#A6745C'; -WorkspaceFactoryController.prototype.standardCategories['functions'] = +StandardCategories.categoryMap['functions'] = new ListElement(ListElement.TYPE_CATEGORY, 'Functions'); -WorkspaceFactoryController.prototype.standardCategories['functions'].color = - '#9A5CA6' -WorkspaceFactoryController.prototype.standardCategories['functions'].custom = - 'PROCEDURE'; +StandardCategories.categoryMap['functions'].color = '#9A5CA6' +StandardCategories.categoryMap['functions'].custom = 'PROCEDURE'; -WorkspaceFactoryController.prototype.standardCategories['variables'] = +StandardCategories.categoryMap['variables'] = new ListElement(ListElement.TYPE_CATEGORY, 'Variables'); -WorkspaceFactoryController.prototype.standardCategories['variables'].color = - '#A65C81'; -WorkspaceFactoryController.prototype.standardCategories['variables'].custom = - 'VARIABLE'; +StandardCategories.categoryMap['variables'].color = '#A65C81'; +StandardCategories.categoryMap['variables'].custom = 'VARIABLE'; + +// All standard block types in provided in Blockly core. +StandardCategories.coreBlockTypes = ["controls_if", "logic_compare", + "logic_operation", "logic_negate", "logic_boolean", "logic_null", + "logic_ternary", "controls_repeat_ext", "controls_whileUntil", + "controls_for", "controls_forEach", "controls_flow_statements", + "math_number", "math_arithmetic", "math_single", "math_trig", + "math_constant", "math_number_property", "math_change", "math_round", + "math_on_list", "math_modulo", "math_constrain", "math_random_int", + "math_random_float", "text", "text_join", "text_append", "text_length", + "text_isEmpty", "text_indexOf", "variables_get", "text_charAt", + "text_getSubstring", "text_changeCase", "text_trim", "text_print", + "text_prompt_ext", "colour_picker", "colour_random", "colour_rgb", + "colour_blend", "lists_create_with", "lists_repeat", "lists_length", + "lists_isEmpty", "lists_indexOf", "lists_getIndex", "lists_setIndex", + "lists_getSublist", "lists_split", "lists_sort", "variables_set", + "procedures_defreturn", "procedures_ifreturn", "procedures_defnoreturn", + "procedures_callreturn"]; + diff --git a/demos/blocklyfactory/workspacefactory/wfactory_controller.js b/demos/blocklyfactory/workspacefactory/wfactory_controller.js index 2a24660bb..192b8d21c 100644 --- a/demos/blocklyfactory/workspacefactory/wfactory_controller.js +++ b/demos/blocklyfactory/workspacefactory/wfactory_controller.js @@ -35,6 +35,7 @@ */ goog.require('FactoryUtils'); + goog.require('StandardCategories'); /** * Class for a WorkspaceFactoryController @@ -555,8 +556,7 @@ WorkspaceFactoryController.prototype.changeSelectedCategoryColor = /** * Tied to the "Standard Category" dropdown option, this function prompts * the user for a name of a standard Blockly category (case insensitive) and - * loads it as a new category and switches to it. Leverages standardCategories - * map in standard_categories.js. + * loads it as a new category and switches to it. Leverages StandardCategories. */ WorkspaceFactoryController.prototype.loadCategory = function() { // Prompt user for the name of the standard category to load. @@ -580,7 +580,7 @@ WorkspaceFactoryController.prototype.loadCategory = function() { return; } // Check if the user can create a category with that name. - var standardCategory = this.standardCategories[name.toLowerCase()] + var standardCategory = StandardCategories.categoryMap[name.toLowerCase()] if (this.model.hasCategoryByName(standardCategory.name)) { alert('You already have a category with the name ' + standardCategory.name + '. Rename your category and try again.'); @@ -621,11 +621,11 @@ WorkspaceFactoryController.prototype.loadCategory = function() { * category (case insensitive). * * @param {string} name The name of the category that should be checked if it's - * in standardCategories + * in StandardCategories categoryMap * @return {boolean} True if name is a standard category name, false otherwise. */ WorkspaceFactoryController.prototype.isStandardCategoryName = function(name) { - for (var category in this.standardCategories) { + for (var category in StandardCategories.categoryMap) { if (name.toLowerCase() == category) { return true; } From c41a4fa6e4f77530066fcb49662b187db9edac9a Mon Sep 17 00:00:00 2001 From: Neil Fraser Date: Sun, 21 Aug 2016 14:29:07 -0700 Subject: [PATCH 5/5] Fix ability to expand toolbox categories. --- core/toolbox.js | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/core/toolbox.js b/core/toolbox.js index f9bac9e6d..7de0256b4 100644 --- a/core/toolbox.js +++ b/core/toolbox.js @@ -188,8 +188,11 @@ Blockly.Toolbox.prototype.init = function() { tree.setShowLines(false); tree.setShowExpandIcons(false); tree.setSelectedItem(null); - this.populate_(workspace.options.languageTree); + var openNode = this.populate_(workspace.options.languageTree); tree.render(this.HtmlDiv); + if (openNode) { + tree.setSelectedItem(openNode); + } this.addColour_(); this.position(); }; @@ -257,14 +260,16 @@ Blockly.Toolbox.prototype.position = function() { /** * Fill the toolbox with categories and blocks. - * @param {Node} newTree DOM tree of blocks, or null. + * @param {!Node} newTree DOM tree of blocks. + * @return {Node} Tree node to open at startup (or null). * @private */ Blockly.Toolbox.prototype.populate_ = function(newTree) { this.tree_.removeChildren(); // Delete any existing content. this.tree_.blocks = []; this.hasColours_ = false; - this.syncTrees_(newTree, this.tree_, this.workspace_.options.pathToMedia); + var openNode = + this.syncTrees_(newTree, this.tree_, this.workspace_.options.pathToMedia); if (this.tree_.blocks.length) { throw 'Toolbox cannot have both blocks and categories in the root level.'; @@ -272,16 +277,19 @@ Blockly.Toolbox.prototype.populate_ = function(newTree) { // Fire a resize event since the toolbox may have changed width and height. Blockly.resizeSvgContents(this.workspace_); + return openNode; }; /** * Sync trees of the toolbox. - * @param {Node} treeIn DOM tree of blocks, or null. - * @param {Blockly.Toolbox.TreeControl} treeOut + * @param {!Node} treeIn DOM tree of blocks. + * @param {!Blockly.Toolbox.TreeControl} treeOut * @param {string} pathToMedia + * @return {Node} Tree node to open at startup (or null). * @private */ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) { + var openNode = null; var lastElement = null; for (var i = 0, childIn; childIn = treeIn.childNodes[i]; i++) { if (!childIn.tagName) { @@ -298,7 +306,10 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) { // Variables and procedures are special dynamic categories. childOut.blocks = custom; } else { - this.syncTrees_(childIn, childOut, pathToMedia); + var newOpenNode = this.syncTrees_(childIn, childOut, pathToMedia); + if (newOpenNode) { + openNode = newOpenNode; + } } var colour = childIn.getAttribute('colour'); if (goog.isString(colour)) { @@ -313,7 +324,9 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) { } if (childIn.getAttribute('expanded') == 'true') { if (childOut.blocks.length) { - this.tree_.setSelectedItem(childOut); + // This is a category that directly contians blocks. + // After the tree is rendered, open this category and show flyout. + openNode = childOut; } childOut.setExpanded(true); } else { @@ -348,6 +361,7 @@ Blockly.Toolbox.prototype.syncTrees_ = function(treeIn, treeOut, pathToMedia) { break; } } + return openNode; }; /**