From 0a76f1c7f5e459b84fa799c585661905744ac5c5 Mon Sep 17 00:00:00 2001
From: DD <liudi08@gmail.com>
Date: Thu, 16 Nov 2017 11:27:49 -0500
Subject: [PATCH] remake toolbox xml when target changes

---
 src/containers/blocks.jsx   | 19 ++++++++++++-------
 src/lib/make-toolbox-xml.js | 17 ++++++++++-------
 src/reducers/toolbox.js     |  4 +---
 3 files changed, 23 insertions(+), 17 deletions(-)

diff --git a/src/containers/blocks.jsx b/src/containers/blocks.jsx
index 471dc6cd0..6f8ce8177 100644
--- a/src/containers/blocks.jsx
+++ b/src/containers/blocks.jsx
@@ -172,6 +172,11 @@ class Blocks extends React.Component {
         this.workspace.reportValue(data.id, data.value);
     }
     onWorkspaceUpdate (data) {
+        // When we change sprites, update the toolbox to have the new sprite's blocks
+        if (this.props.vm.editingTarget) {
+            this.props.updateToolboxState(makeToolboxXML(this.props.vm.editingTarget.id));
+        }
+
         if (this.props.vm.editingTarget && !this.state.workspaceMetrics[this.props.vm.editingTarget.id]) {
             this.onWorkspaceMetricsChange();
         }
@@ -193,8 +198,8 @@ class Blocks extends React.Component {
     handleExtensionAdded (blocksInfo) {
         this.ScratchBlocks.defineBlocksWithJsonArray(blocksInfo.map(blockInfo => blockInfo.json));
         const dynamicBlocksXML = this.props.vm.runtime.getBlocksXML();
-        const toolboxXML = makeToolboxXML(dynamicBlocksXML);
-        this.props.onExtensionAdded(toolboxXML);
+        const toolboxXML = makeToolboxXML(this.props.vm.editingTarget.id, dynamicBlocksXML);
+        this.props.updateToolboxState(toolboxXML);
     }
     handleCategorySelected (categoryName) {
         this.workspace.toolbox_.setSelectedCategoryByName(categoryName);
@@ -220,7 +225,7 @@ class Blocks extends React.Component {
             vm,
             isVisible,
             onActivateColorPicker,
-            onExtensionAdded,
+            updateToolboxState,
             onRequestCloseExtensionLibrary,
             toolboxXML,
             ...props
@@ -257,7 +262,6 @@ Blocks.propTypes = {
     extensionLibraryVisible: PropTypes.bool,
     isVisible: PropTypes.bool,
     onActivateColorPicker: PropTypes.func,
-    onExtensionAdded: PropTypes.func,
     onRequestCloseExtensionLibrary: PropTypes.func,
     options: PropTypes.shape({
         media: PropTypes.string,
@@ -281,6 +285,7 @@ Blocks.propTypes = {
         comments: PropTypes.bool
     }),
     toolboxXML: PropTypes.string,
+    updateToolboxState: PropTypes.func,
     vm: PropTypes.instanceOf(VM).isRequired
 };
 
@@ -322,11 +327,11 @@ const mapStateToProps = state => ({
 
 const mapDispatchToProps = dispatch => ({
     onActivateColorPicker: callback => dispatch(activateColorPicker(callback)),
-    onExtensionAdded: toolboxXML => {
-        dispatch(updateToolbox(toolboxXML));
-    },
     onRequestCloseExtensionLibrary: () => {
         dispatch(closeExtensionLibrary());
+    },
+    updateToolboxState: toolboxXML => {
+        dispatch(updateToolbox(toolboxXML));
     }
 });
 
diff --git a/src/lib/make-toolbox-xml.js b/src/lib/make-toolbox-xml.js
index 315e1388c..94ffc44ab 100644
--- a/src/lib/make-toolbox-xml.js
+++ b/src/lib/make-toolbox-xml.js
@@ -120,9 +120,9 @@ const motion = `
         ${blockSeparator}
         <block type="motion_setrotationstyle"/>
         ${blockSeparator}
-        <block id="xposition" type="motion_xposition"/>
-        <block id="yposition" type="motion_yposition"/>
-        <block id="direction" type="motion_direction"/>
+        <block id="<TARGET_ID>_xposition" type="motion_xposition"/>
+        <block id="<TARGET_ID>_yposition" type="motion_yposition"/>
+        <block id="<TARGET_ID>_direction" type="motion_direction"/>
         ${categorySeparator}
     </category>
 `;
@@ -229,10 +229,10 @@ const looks = `
             </value>
         </block>
         ${blockSeparator}
-        <block id="costumeorder" type="looks_costumeorder"/>
+        <block id="<TARGET_ID>_costumeorder" type="looks_costumeorder"/>
         <block id="backdroporder" type="looks_backdroporder"/>
         <block id="backdropname" type="looks_backdropname"/>
-        <block id="size" type="looks_size"/>
+        <block id="<TARGET_ID>_size" type="looks_size"/>
         ${categorySeparator}
     </category>
 `;
@@ -613,10 +613,11 @@ const xmlOpen = '<xml style="display: none">';
 const xmlClose = '</xml>';
 
 /**
+ * @param {!string} targetId - The current editing target
  * @param {string?} categoriesXML - null for default toolbox, or an XML string with <category> elements.
  * @returns {string} - a ScratchBlocks-style XML document for the contents of the toolbox.
  */
-const makeToolboxXML = function (categoriesXML) {
+const makeToolboxXML = function (targetId, categoriesXML) {
     const gap = [categorySeparator];
 
     const everything = [
@@ -636,7 +637,9 @@ const makeToolboxXML = function (categoriesXML) {
     }
 
     everything.push(xmlClose);
-    return everything.join('\n');
+    return everything.join('\n').split('<TARGET_ID>')
+        .join(targetId); // targetIds are designed to not break XML.
+    // @todo consider something less hacky?
 };
 
 export default makeToolboxXML;
diff --git a/src/reducers/toolbox.js b/src/reducers/toolbox.js
index 4b06a807c..0d3257df1 100644
--- a/src/reducers/toolbox.js
+++ b/src/reducers/toolbox.js
@@ -1,9 +1,7 @@
 const UPDATE_TOOLBOX = 'scratch-gui/toolbox/UPDATE_TOOLBOX';
 
-import makeToolboxXML from '../lib/make-toolbox-xml';
-
 const initialState = {
-    toolboxXML: makeToolboxXML()
+    toolboxXML: ''
 };
 
 const reducer = function (state, action) {
-- 
GitLab