mirror of
https://github.com/scratchfoundation/scratch-blocks.git
synced 2025-06-30 14:10:25 -04:00
Track cloud variable info and handle naming and renaming cloud variables.
This commit is contained in:
parent
88091d21df
commit
93bbd0b00f
7 changed files with 59 additions and 18 deletions
|
@ -89,6 +89,7 @@ Blockly.Events.VarCreate = function(variable) {
|
||||||
this.varType = variable.type;
|
this.varType = variable.type;
|
||||||
this.varName = variable.name;
|
this.varName = variable.name;
|
||||||
this.isLocal = variable.isLocal;
|
this.isLocal = variable.isLocal;
|
||||||
|
this.isCloud = variable.isCloud;
|
||||||
};
|
};
|
||||||
goog.inherits(Blockly.Events.VarCreate, Blockly.Events.VarBase);
|
goog.inherits(Blockly.Events.VarCreate, Blockly.Events.VarBase);
|
||||||
|
|
||||||
|
@ -107,6 +108,7 @@ Blockly.Events.VarCreate.prototype.toJson = function() {
|
||||||
json['varType'] = this.varType;
|
json['varType'] = this.varType;
|
||||||
json['varName'] = this.varName;
|
json['varName'] = this.varName;
|
||||||
json['isLocal'] = this.isLocal;
|
json['isLocal'] = this.isLocal;
|
||||||
|
json['isCloud'] = this.isCloud;
|
||||||
return json;
|
return json;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -119,6 +121,7 @@ Blockly.Events.VarCreate.prototype.fromJson = function(json) {
|
||||||
this.varType = json['varType'];
|
this.varType = json['varType'];
|
||||||
this.varName = json['varName'];
|
this.varName = json['varName'];
|
||||||
this.isLocal = json['isLocal'];
|
this.isLocal = json['isLocal'];
|
||||||
|
this.isCloud = json['isCloud'];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -128,7 +131,7 @@ Blockly.Events.VarCreate.prototype.fromJson = function(json) {
|
||||||
Blockly.Events.VarCreate.prototype.run = function(forward) {
|
Blockly.Events.VarCreate.prototype.run = function(forward) {
|
||||||
var workspace = this.getEventWorkspace_();
|
var workspace = this.getEventWorkspace_();
|
||||||
if (forward) {
|
if (forward) {
|
||||||
workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal);
|
workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal, this.isCloud);
|
||||||
} else {
|
} else {
|
||||||
workspace.deleteVariableById(this.varId);
|
workspace.deleteVariableById(this.varId);
|
||||||
}
|
}
|
||||||
|
@ -149,6 +152,7 @@ Blockly.Events.VarDelete = function(variable) {
|
||||||
this.varType = variable.type;
|
this.varType = variable.type;
|
||||||
this.varName = variable.name;
|
this.varName = variable.name;
|
||||||
this.isLocal = variable.isLocal;
|
this.isLocal = variable.isLocal;
|
||||||
|
this.isCloud = variable.isCloud;
|
||||||
};
|
};
|
||||||
goog.inherits(Blockly.Events.VarDelete, Blockly.Events.VarBase);
|
goog.inherits(Blockly.Events.VarDelete, Blockly.Events.VarBase);
|
||||||
|
|
||||||
|
@ -167,6 +171,7 @@ Blockly.Events.VarDelete.prototype.toJson = function() {
|
||||||
json['varType'] = this.varType;
|
json['varType'] = this.varType;
|
||||||
json['varName'] = this.varName;
|
json['varName'] = this.varName;
|
||||||
json['isLocal'] = this.isLocal;
|
json['isLocal'] = this.isLocal;
|
||||||
|
json['isCloud'] = this.isCloud;
|
||||||
return json;
|
return json;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -179,6 +184,7 @@ Blockly.Events.VarDelete.prototype.fromJson = function(json) {
|
||||||
this.varType = json['varType'];
|
this.varType = json['varType'];
|
||||||
this.varName = json['varName'];
|
this.varName = json['varName'];
|
||||||
this.isLocal = json['isLocal'];
|
this.isLocal = json['isLocal'];
|
||||||
|
this.isCloud = json['isCloud'];
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -190,7 +196,7 @@ Blockly.Events.VarDelete.prototype.run = function(forward) {
|
||||||
if (forward) {
|
if (forward) {
|
||||||
workspace.deleteVariableById(this.varId);
|
workspace.deleteVariableById(this.varId);
|
||||||
} else {
|
} else {
|
||||||
workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal);
|
workspace.createVariable(this.varName, this.varType, this.varId, this.isLocal, this.isCloud);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -175,10 +175,11 @@ Blockly.VariableMap.prototype.renameVariableWithConflict_ = function(variable,
|
||||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||||
* a UUID.
|
* a UUID.
|
||||||
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
||||||
|
* @param {boolean=} opt_isCloud Whether the variable is a cloud variable.
|
||||||
* @return {?Blockly.VariableModel} The newly created variable.
|
* @return {?Blockly.VariableModel} The newly created variable.
|
||||||
*/
|
*/
|
||||||
Blockly.VariableMap.prototype.createVariable = function(name,
|
Blockly.VariableMap.prototype.createVariable = function(name,
|
||||||
opt_type, opt_id, opt_isLocal) {
|
opt_type, opt_id, opt_isLocal, opt_isCloud) {
|
||||||
var variable = this.getVariable(name, opt_type);
|
var variable = this.getVariable(name, opt_type);
|
||||||
if (variable) {
|
if (variable) {
|
||||||
if (opt_id && variable.getId() != opt_id) {
|
if (opt_id && variable.getId() != opt_id) {
|
||||||
|
@ -203,7 +204,7 @@ Blockly.VariableMap.prototype.createVariable = function(name,
|
||||||
opt_type = opt_type || '';
|
opt_type = opt_type || '';
|
||||||
|
|
||||||
variable = new Blockly.VariableModel(this.workspace, name, opt_type, opt_id,
|
variable = new Blockly.VariableModel(this.workspace, name, opt_type, opt_id,
|
||||||
opt_isLocal);
|
opt_isLocal, opt_isCloud);
|
||||||
// If opt_type is not a key, create a new list.
|
// If opt_type is not a key, create a new list.
|
||||||
if (!this.variableMap_[opt_type]) {
|
if (!this.variableMap_[opt_type]) {
|
||||||
this.variableMap_[opt_type] = [variable];
|
this.variableMap_[opt_type] = [variable];
|
||||||
|
|
|
@ -43,10 +43,12 @@ goog.require('goog.string');
|
||||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||||
* a UUID.
|
* a UUID.
|
||||||
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
||||||
|
* @param {boolean=} opt_isCloud Whether the variable is a cloud variable.
|
||||||
* @see {Blockly.FieldVariable}
|
* @see {Blockly.FieldVariable}
|
||||||
* @constructor
|
* @constructor
|
||||||
*/
|
*/
|
||||||
Blockly.VariableModel = function(workspace, name, opt_type, opt_id, opt_isLocal) {
|
Blockly.VariableModel = function(workspace, name, opt_type, opt_id,
|
||||||
|
opt_isLocal, opt_isCloud) {
|
||||||
/**
|
/**
|
||||||
* The workspace the variable is in.
|
* The workspace the variable is in.
|
||||||
* @type {!Blockly.Workspace}
|
* @type {!Blockly.Workspace}
|
||||||
|
@ -85,6 +87,12 @@ Blockly.VariableModel = function(workspace, name, opt_type, opt_id, opt_isLocal)
|
||||||
*/
|
*/
|
||||||
this.isLocal = opt_isLocal || false;
|
this.isLocal = opt_isLocal || false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Whether the variable is a cloud variable.
|
||||||
|
* @package
|
||||||
|
*/
|
||||||
|
this.isCloud = opt_isCloud || false;
|
||||||
|
|
||||||
Blockly.Events.fire(new Blockly.Events.VarCreate(this));
|
Blockly.Events.fire(new Blockly.Events.VarCreate(this));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,15 @@ goog.require('goog.string');
|
||||||
*/
|
*/
|
||||||
Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME;
|
Blockly.Variables.NAME_TYPE = Blockly.VARIABLE_CATEGORY_NAME;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constant prefix to differentiate cloud variable names from other types
|
||||||
|
* of variables.
|
||||||
|
* This is the \u2601 cloud unicode character followed by a space.
|
||||||
|
* @type {string}
|
||||||
|
* @package
|
||||||
|
*/
|
||||||
|
Blockly.Variables.CLOUD_PREFIX = '☁ ';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find all user-created variables that are in use in the workspace.
|
* Find all user-created variables that are in use in the workspace.
|
||||||
* For use by generators.
|
* For use by generators.
|
||||||
|
@ -289,14 +298,16 @@ Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
|
||||||
|
|
||||||
// Prompt the user to enter a name for the variable
|
// Prompt the user to enter a name for the variable
|
||||||
Blockly.prompt(newMsg, '',
|
Blockly.prompt(newMsg, '',
|
||||||
function(text, additionalVars, scope) {
|
function(text, additionalVars, variableOptions) {
|
||||||
|
var scope = variableOptions.scope;
|
||||||
var isLocal = (scope === 'local') || false;
|
var isLocal = (scope === 'local') || false;
|
||||||
|
var isCloud = variableOptions.isCloud || false;
|
||||||
// Default to [] if additionalVars is not provided
|
// Default to [] if additionalVars is not provided
|
||||||
additionalVars = additionalVars || [];
|
additionalVars = additionalVars || [];
|
||||||
// Only use additionalVars for global variable creation.
|
// Only use additionalVars for global variable creation.
|
||||||
var additionalVarNames = isLocal ? [] : additionalVars;
|
var additionalVarNames = isLocal ? [] : additionalVars;
|
||||||
|
|
||||||
var validatedText = validate(text, workspace, additionalVarNames, opt_callback);
|
var validatedText = validate(text, workspace, additionalVarNames, isCloud, opt_callback);
|
||||||
if (validatedText) {
|
if (validatedText) {
|
||||||
// The name is valid according to the type, create the variable
|
// The name is valid according to the type, create the variable
|
||||||
var potentialVarMap = workspace.getPotentialVariableMap();
|
var potentialVarMap = workspace.getPotentialVariableMap();
|
||||||
|
@ -311,7 +322,7 @@ Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
|
||||||
opt_type, workspace, false);
|
opt_type, workspace, false);
|
||||||
}
|
}
|
||||||
if (!variable) {
|
if (!variable) {
|
||||||
variable = workspace.createVariable(validatedText, opt_type, null, isLocal);
|
variable = workspace.createVariable(validatedText, opt_type, null, isLocal, isCloud);
|
||||||
}
|
}
|
||||||
|
|
||||||
var flyout = workspace.isFlyout ? workspace : workspace.getFlyout();
|
var flyout = workspace.isFlyout ? workspace : workspace.getFlyout();
|
||||||
|
@ -346,6 +357,7 @@ Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
|
||||||
* already exists.
|
* already exists.
|
||||||
* @param {Array<string>} additionalVars A list of additional var names to check
|
* @param {Array<string>} additionalVars A list of additional var names to check
|
||||||
* for conflicts against.
|
* for conflicts against.
|
||||||
|
* @param {boolean} isCloud Whether the variable is a cloud variable.
|
||||||
* @param {function(?string=)=} opt_callback An optional function to be called on
|
* @param {function(?string=)=} opt_callback An optional function to be called on
|
||||||
* a pre-existing variable of the user-provided name. This function is currently
|
* a pre-existing variable of the user-provided name. This function is currently
|
||||||
* only used for broadcast messages.
|
* only used for broadcast messages.
|
||||||
|
@ -355,7 +367,8 @@ Blockly.Variables.createVariable = function(workspace, opt_callback, opt_type) {
|
||||||
* proceed with creating or renaming the variable.
|
* proceed with creating or renaming the variable.
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Blockly.Variables.nameValidator_ = function(type, text, workspace, additionalVars, opt_callback) {
|
Blockly.Variables.nameValidator_ = function(type, text, workspace, additionalVars,
|
||||||
|
isCloud, opt_callback) {
|
||||||
// The validators for the different variable types require slightly different arguments.
|
// The validators for the different variable types require slightly different arguments.
|
||||||
// For broadcast messages, if a broadcast message of the provided name already exists,
|
// For broadcast messages, if a broadcast message of the provided name already exists,
|
||||||
// the validator needs to call a function that updates the selected
|
// the validator needs to call a function that updates the selected
|
||||||
|
@ -367,10 +380,10 @@ Blockly.Variables.nameValidator_ = function(type, text, workspace, additionalVar
|
||||||
if (type == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) {
|
if (type == Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE) {
|
||||||
return Blockly.Variables.validateBroadcastMessageName_(text, workspace, opt_callback);
|
return Blockly.Variables.validateBroadcastMessageName_(text, workspace, opt_callback);
|
||||||
} else if (type == Blockly.LIST_VARIABLE_TYPE) {
|
} else if (type == Blockly.LIST_VARIABLE_TYPE) {
|
||||||
return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, type,
|
return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, false, type,
|
||||||
Blockly.Msg.LIST_ALREADY_EXISTS);
|
Blockly.Msg.LIST_ALREADY_EXISTS);
|
||||||
} else {
|
} else {
|
||||||
return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, type,
|
return Blockly.Variables.validateScalarVarOrListName_(text, workspace, additionalVars, isCloud, type,
|
||||||
Blockly.Msg.VARIABLE_ALREADY_EXISTS);
|
Blockly.Msg.VARIABLE_ALREADY_EXISTS);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -417,6 +430,7 @@ Blockly.Variables.validateBroadcastMessageName_ = function(name, workspace, opt_
|
||||||
* against.
|
* against.
|
||||||
* @param {Array<string>} additionalVars A list of additional variable names to check
|
* @param {Array<string>} additionalVars A list of additional variable names to check
|
||||||
* for conflicts against.
|
* for conflicts against.
|
||||||
|
* @param {boolean} isCloud Whether the variable is a cloud variable.
|
||||||
* @param {string} type The type to validate the variable as. This should be one of
|
* @param {string} type The type to validate the variable as. This should be one of
|
||||||
* Blockly.SCALAR_VARIABLE_TYPE or Blockly.LIST_VARIABLE_TYPE.
|
* Blockly.SCALAR_VARIABLE_TYPE or Blockly.LIST_VARIABLE_TYPE.
|
||||||
* @param {string} errorMsg The type-specific error message the user should see
|
* @param {string} errorMsg The type-specific error message the user should see
|
||||||
|
@ -425,12 +439,15 @@ Blockly.Variables.validateBroadcastMessageName_ = function(name, workspace, opt_
|
||||||
* @private
|
* @private
|
||||||
*/
|
*/
|
||||||
Blockly.Variables.validateScalarVarOrListName_ = function(name, workspace, additionalVars,
|
Blockly.Variables.validateScalarVarOrListName_ = function(name, workspace, additionalVars,
|
||||||
type, errorMsg) {
|
isCloud, type, errorMsg) {
|
||||||
// For scalar variables, we don't want leading or trailing white space
|
// For scalar variables, we don't want leading or trailing white space
|
||||||
name = Blockly.Variables.trimName_(name);
|
name = Blockly.Variables.trimName_(name);
|
||||||
if (!name) {
|
if (!name) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
if (isCloud) {
|
||||||
|
name = Blockly.Variables.CLOUD_PREFIX + name;
|
||||||
|
}
|
||||||
if (workspace.getVariable(name, type) || additionalVars.indexOf(name) >= 0) {
|
if (workspace.getVariable(name, type) || additionalVars.indexOf(name) >= 0) {
|
||||||
// error
|
// error
|
||||||
Blockly.alert(errorMsg.replace('%1', name));
|
Blockly.alert(errorMsg.replace('%1', name));
|
||||||
|
@ -472,9 +489,13 @@ Blockly.Variables.renameVariable = function(workspace, variable,
|
||||||
var promptText = promptMsg.replace('%1', variable.name);
|
var promptText = promptMsg.replace('%1', variable.name);
|
||||||
Blockly.prompt(promptText, '',
|
Blockly.prompt(promptText, '',
|
||||||
function(newName, additionalVars) {
|
function(newName, additionalVars) {
|
||||||
|
if (variable.isCloud &&
|
||||||
|
newName.length > 0 && newName.indexOf(Blockly.Variables.CLOUD_PREFIX) == 0 ) {
|
||||||
|
newName = newName.substring(2); // The name validator will add the prefix back
|
||||||
|
}
|
||||||
additionalVars = additionalVars || [];
|
additionalVars = additionalVars || [];
|
||||||
var additionalVarNames = variable.isLocal ? [] : additionalVars;
|
var additionalVarNames = variable.isLocal ? [] : additionalVars;
|
||||||
var validatedText = validate(newName, workspace, additionalVarNames);
|
var validatedText = validate(newName, workspace, additionalVarNames, variable.isCloud);
|
||||||
if (validatedText) {
|
if (validatedText) {
|
||||||
workspace.renameVariableById(variable.getId(), validatedText);
|
workspace.renameVariableById(variable.getId(), validatedText);
|
||||||
if (opt_callback) {
|
if (opt_callback) {
|
||||||
|
|
|
@ -341,10 +341,12 @@ Blockly.Workspace.prototype.renameVariableById = function(id, newName) {
|
||||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||||
* a UUID.
|
* a UUID.
|
||||||
* @param {boolean=} opt_isLocal Whether the variable to create is locally scoped.
|
* @param {boolean=} opt_isLocal Whether the variable to create is locally scoped.
|
||||||
|
* @param {boolean=} opt_isCloud Whether the variable to create is locally scoped.
|
||||||
* @return {?Blockly.VariableModel} The newly created variable.
|
* @return {?Blockly.VariableModel} The newly created variable.
|
||||||
*/
|
*/
|
||||||
Blockly.Workspace.prototype.createVariable = function(name, opt_type, opt_id, opt_isLocal) {
|
Blockly.Workspace.prototype.createVariable = function(name, opt_type, opt_id,
|
||||||
return this.variableMap_.createVariable(name, opt_type, opt_id, opt_isLocal);
|
opt_isLocal, opt_isCloud) {
|
||||||
|
return this.variableMap_.createVariable(name, opt_type, opt_id, opt_isLocal, opt_isCloud);
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1161,14 +1161,15 @@ Blockly.WorkspaceSvg.prototype.deleteVariableById = function(id) {
|
||||||
* @param {string=} opt_id The unique ID of the variable. This will default to
|
* @param {string=} opt_id The unique ID of the variable. This will default to
|
||||||
* a UUID.
|
* a UUID.
|
||||||
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
* @param {boolean=} opt_isLocal Whether the variable is locally scoped.
|
||||||
|
* @param {boolean=} opt_isCloud Whether the variable is a cloud variable.
|
||||||
* @return {?Blockly.VariableModel} The newly created variable.
|
* @return {?Blockly.VariableModel} The newly created variable.
|
||||||
* @package
|
* @package
|
||||||
*/
|
*/
|
||||||
Blockly.WorkspaceSvg.prototype.createVariable = function(name, opt_type, opt_id,
|
Blockly.WorkspaceSvg.prototype.createVariable = function(name, opt_type, opt_id,
|
||||||
opt_isLocal) {
|
opt_isLocal, opt_isCloud) {
|
||||||
var variableInMap = (this.getVariable(name, opt_type) != null);
|
var variableInMap = (this.getVariable(name, opt_type) != null);
|
||||||
var newVar = Blockly.WorkspaceSvg.superClass_.createVariable.call(
|
var newVar = Blockly.WorkspaceSvg.superClass_.createVariable.call(
|
||||||
this, name, opt_type, opt_id, opt_isLocal);
|
this, name, opt_type, opt_id, opt_isLocal, opt_isCloud);
|
||||||
// For performance reasons, only refresh the the toolbox for new variables.
|
// For performance reasons, only refresh the the toolbox for new variables.
|
||||||
// Variables that already exist should already be there.
|
// Variables that already exist should already be there.
|
||||||
if (!variableInMap && (opt_type != Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE)) {
|
if (!variableInMap && (opt_type != Blockly.BROADCAST_MESSAGE_VARIABLE_TYPE)) {
|
||||||
|
|
|
@ -72,6 +72,7 @@ Blockly.Xml.variablesToDom = function(variableList) {
|
||||||
element.setAttribute('type', variable.type);
|
element.setAttribute('type', variable.type);
|
||||||
element.setAttribute('id', variable.getId());
|
element.setAttribute('id', variable.getId());
|
||||||
element.setAttribute('islocal', variable.isLocal);
|
element.setAttribute('islocal', variable.isLocal);
|
||||||
|
element.setAttribute('isCloud', variable.isCloud);
|
||||||
variables.appendChild(element);
|
variables.appendChild(element);
|
||||||
}
|
}
|
||||||
return variables;
|
return variables;
|
||||||
|
@ -638,12 +639,13 @@ Blockly.Xml.domToVariables = function(xmlVariables, workspace) {
|
||||||
var type = xmlChild.getAttribute('type');
|
var type = xmlChild.getAttribute('type');
|
||||||
var id = xmlChild.getAttribute('id');
|
var id = xmlChild.getAttribute('id');
|
||||||
var isLocal = xmlChild.getAttribute('islocal') == 'true';
|
var isLocal = xmlChild.getAttribute('islocal') == 'true';
|
||||||
|
var isCloud = xmlChild.getAttribute('isCloud') == 'true';
|
||||||
var name = xmlChild.textContent;
|
var name = xmlChild.textContent;
|
||||||
|
|
||||||
if (typeof(type) === undefined || type === null) {
|
if (typeof(type) === undefined || type === null) {
|
||||||
throw Error('Variable with id, ' + id + ' is without a type');
|
throw Error('Variable with id, ' + id + ' is without a type');
|
||||||
}
|
}
|
||||||
workspace.createVariable(name, type, id, isLocal);
|
workspace.createVariable(name, type, id, isLocal, isCloud);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue