Commit 447eb323 authored by Xueyuan(Sherry) Wang's avatar Xueyuan(Sherry) Wang Committed by Evan W. Patton

Update Sort By Category Function


Change-Id: If1fe3358fb87be47a90dd90a79c794a751ab7288
parent 0e2a9adf
......@@ -132,7 +132,7 @@ Blockly.Blocks['lexical_variable_get'] = {
Blockly.LexicalVariable.eventParamDomToMutation(this, xmlElement);
},
getVars: function() {
return this.getFieldValue('VAR');
return [this.getFieldValue('VAR')];
},
renameLexicalVar: function(oldName, newName) {
// console.log("Renaming lexical variable from " + oldName + " to " + newName);
......@@ -194,7 +194,7 @@ Blockly.Blocks['lexical_variable_set'] = {
Blockly.LexicalVariable.eventParamDomToMutation(this, xmlElement);
},
getVars: function() {
return this.getFieldValue('VAR');
return [this.getFieldValue('VAR')];
},
renameLexicalVar: Blockly.Blocks.lexical_variable_get.renameLexicalVar,
renameFree: function (freeSubstitution) {
......
......@@ -669,19 +669,69 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
/**
* Function that returns a name to be used to sort blocks.
* The general comparator is the block.category attribute.
* In the case of 'Components' the comparator is the instanceName of the component if it exists
* (it does not exist for generic components).
* In the case of Procedures the comparator is the NAME(for definitions) or PROCNAME (for calls)
* In the case of 'Components' the comparator is the type name, instance name, then event name
* @param {!Blockly.Block} block the block that will be compared in the sortByCategory function
* @returns {string} text to be used in the comparison
*/
function comparisonName(block){
if (block.category === 'Component' && block.instanceName)
return block.instanceName;
if (block.category === 'Procedures')
return (block.getFieldValue('NAME') || block.getFieldValue('PROCNAME'));
return block.category;
function comparisonName(block) {
// Add trailing numbers to represent their sequence
if (block.category == 'Variables') {
return ('a,' + block.type + ',' + block.getVars().join(','));
}
if (block.category === 'Procedures') {
// sort procedure definitions before calls
if (block.type.indexOf('procedures_def') == 0) {
return ('b,a:' + (block.getFieldValue('NAME') || block.getFieldValue('PROCNAME')));
} else {
return ('b,b:'+ (block.getFieldValue('NAME') || block.getFieldValue('PROCNAME')));
}
}
if (block.category == 'Component') {
var component = block.type + ',' + block.typeName + ','
+ (block.isGeneric ? '!GENERIC!' : block.instanceName) + ',';
// sort Component blocks first, then events, methods, getters, or setters
if (block.type == 'component_event') {
component += block.eventName;
} else if (block.type == 'component_method') {
component += block.methodName;
} else if (block.type == 'component_set_get') {
component += block.setOrGet + block.propertyName;
} else {
// component blocks
component += '.Component';
}
return ('c,' + component);
}
// Floating blocks that are not Component
return ('d,' + block.type);
}
/**
* Function used to compare two strings with text and numbers
* @param {string} a first string to be compared
* @param {string} b second string to be compared
* @returns {number} returns 0 if the strings are equal, and -1 or 1 if they are not
*/
function compareStrTextNum(strA,strB) {
// Use Regular Expression to match text and numbers
var regexStrA = strA.match(/^(.*?)([0-9]+)/i);
var regexStrB = strB.match(/^(.*?)([0-9]+)/i);
// There are numbers in the strings, compare numbers
if (regexStrA != null && regexStrB != null) {
if (regexStrA[1] < regexStrB[1]) {
return -1;
} else if (regexStrA[1] > regexStrB[1]) {
return 1;
} else {
return parseInt(regexStrA[2]) - parseInt(regexStrB[2]);
}
} else {
return strA.localeCompare(strB, undefined, {numeric:true});
}
}
/**
* Function used to sort blocks by Category.
......@@ -693,9 +743,93 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
var comparatorA = comparisonName(a).toLowerCase();
var comparatorB = comparisonName(b).toLowerCase();
if (comparatorA < comparatorB) return -1;
else if (comparatorA > comparatorB) return +1;
else return 0;
if (a.category != b.category) {
return comparatorA.localeCompare(comparatorB, undefined, {numeric:true});
}
// Sort by Category First, also handles other floating blocks
if (a.category == b.category && a.category != "Component") {
// Remove '1,'
comparatorA = comparatorA.substr(2);
comparatorB = comparatorB.substr(2);
var res = compareStrTextNum(comparatorA, comparatorB);
if (a.category == "Variables" && a.type == b.type) {
// Sort Variables
if (a.type == "global_declaration") {
// initialize variables, extract just global variable names
var nameA = a.svgGroup_.textContent;
// remove substring "initialize global<varname>to" and only keep <varname>
nameA = nameA.substring(17, nameA.length - 2);
var nameB = b.svgGroup_.textContent;
nameB = nameB.substring(17, nameB.length - 2);
res = compareStrTextNum(nameA, nameB);
} else {
var nameA = a.fieldVar_.text_;
var nameB = b.fieldVar_.text_;
if (nameA.includes("global") && nameB.includes("global")) {
// Global Variables and get variable names, remove "global"
res = compareStrTextNum(nameA.substring(6), nameB.substring(6));
}else {
// Other floating variables
res = compareStrTextNum(nameA, nameB);
}
}
}
return res;
}
// 3.Component event handlers, lexicographically sorted by
// type name, instance name, then event name
if (a.category == "Component" && b.category == "Component" && a.eventName && b.eventName) {
if (a.typeName == b.typeName) {
if (a.instanceName == b.instanceName) {
return 0;
} else if (!a.instanceName) {
return -1;
} else if (!b.instanceName) {
return 1;
}
return compareStrTextNum(a.instanceName, b.instanceName);
}
return comparatorA.localeCompare(comparatorB, undefined, {numeric:true});
}
// 4. For Component blocks, sorted internally first by type,
// whether they are generic (generics precede specifics),
// then by instance name (for specific blocks),
// then by method/property name.
if (a.category == "Component" && b.category == "Component") {
var geneA = ',2';
if (a.isGeneric) {
geneA = ',1';
}
var geneB = ',2';
if (b.isGeneric) {
geneB = ',1';
}
var componentA = a.type + geneA;
var componentB = b.type + geneB;
var res = componentA.localeCompare(componentB, undefined, {numeric:true});
if (res == 0) {
// compare type names
res = compareStrTextNum(a.typeName, b.typeName);
}
//the comparator is the type name, instance name, then event name
if (res == 0) {
if (a.instanceName && b.instanceName) {
res = compareStrTextNum(a.instanceName, b.instanceName);
}
// Compare property names
var prop_method_A = a.propertyName || a.methodName;
var prop_method_B = b.propertyName || b.methodName;
res = prop_method_A.toLowerCase().localeCompare(prop_method_B.toLowerCase(), undefined, {numeric:true});
}
return res;
}
}
// Arranges block in layout (Horizontal or Vertical).
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment