Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
A
appinventor-sources
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Commits
Open sidebar
xpstem
appinventor-sources
Commits
447eb323
Commit
447eb323
authored
Sep 09, 2019
by
Xueyuan(Sherry) Wang
Committed by
Evan W. Patton
Sep 09, 2019
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Update Sort By Category Function
Change-Id: If1fe3358fb87be47a90dd90a79c794a751ab7288
parent
0e2a9adf
Changes
2
Show whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
147 additions
and
13 deletions
+147
-13
appinventor/blocklyeditor/src/blocks/lexical-variables.js
appinventor/blocklyeditor/src/blocks/lexical-variables.js
+2
-2
appinventor/blocklyeditor/src/workspace_svg.js
appinventor/blocklyeditor/src/workspace_svg.js
+145
-11
No files found.
appinventor/blocklyeditor/src/blocks/lexical-variables.js
View file @
447eb323
...
@@ -132,7 +132,7 @@ Blockly.Blocks['lexical_variable_get'] = {
...
@@ -132,7 +132,7 @@ Blockly.Blocks['lexical_variable_get'] = {
Blockly
.
LexicalVariable
.
eventParamDomToMutation
(
this
,
xmlElement
);
Blockly
.
LexicalVariable
.
eventParamDomToMutation
(
this
,
xmlElement
);
},
},
getVars
:
function
()
{
getVars
:
function
()
{
return
this
.
getFieldValue
(
'
VAR
'
)
;
return
[
this
.
getFieldValue
(
'
VAR
'
)]
;
},
},
renameLexicalVar
:
function
(
oldName
,
newName
)
{
renameLexicalVar
:
function
(
oldName
,
newName
)
{
// console.log("Renaming lexical variable from " + oldName + " to " + newName);
// console.log("Renaming lexical variable from " + oldName + " to " + newName);
...
@@ -194,7 +194,7 @@ Blockly.Blocks['lexical_variable_set'] = {
...
@@ -194,7 +194,7 @@ Blockly.Blocks['lexical_variable_set'] = {
Blockly
.
LexicalVariable
.
eventParamDomToMutation
(
this
,
xmlElement
);
Blockly
.
LexicalVariable
.
eventParamDomToMutation
(
this
,
xmlElement
);
},
},
getVars
:
function
()
{
getVars
:
function
()
{
return
this
.
getFieldValue
(
'
VAR
'
)
;
return
[
this
.
getFieldValue
(
'
VAR
'
)]
;
},
},
renameLexicalVar
:
Blockly
.
Blocks
.
lexical_variable_get
.
renameLexicalVar
,
renameLexicalVar
:
Blockly
.
Blocks
.
lexical_variable_get
.
renameLexicalVar
,
renameFree
:
function
(
freeSubstitution
)
{
renameFree
:
function
(
freeSubstitution
)
{
...
...
appinventor/blocklyeditor/src/workspace_svg.js
View file @
447eb323
...
@@ -669,19 +669,69 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
...
@@ -669,19 +669,69 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
/**
/**
* Function that returns a name to be used to sort blocks.
* Function that returns a name to be used to sort blocks.
* The general comparator is the block.category attribute.
* 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 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
* @param {!Blockly.Block} block the block that will be compared in the sortByCategory function
* @returns {string} text to be used in the comparison
* @returns {string} text to be used in the comparison
*/
*/
function
comparisonName
(
block
){
function
comparisonName
(
block
)
{
if
(
block
.
category
===
'
Component
'
&&
block
.
instanceName
)
// Add trailing numbers to represent their sequence
return
block
.
instanceName
;
if
(
block
.
category
==
'
Variables
'
)
{
if
(
block
.
category
===
'
Procedures
'
)
return
(
'
a,
'
+
block
.
type
+
'
,
'
+
block
.
getVars
().
join
(
'
,
'
));
return
(
block
.
getFieldValue
(
'
NAME
'
)
||
block
.
getFieldValue
(
'
PROCNAME
'
));
}
return
block
.
category
;
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.
* Function used to sort blocks by Category.
...
@@ -693,9 +743,93 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
...
@@ -693,9 +743,93 @@ Blockly.WorkspaceSvg.prototype.customContextMenu = function(menuOptions) {
var
comparatorA
=
comparisonName
(
a
).
toLowerCase
();
var
comparatorA
=
comparisonName
(
a
).
toLowerCase
();
var
comparatorB
=
comparisonName
(
b
).
toLowerCase
();
var
comparatorB
=
comparisonName
(
b
).
toLowerCase
();
if
(
comparatorA
<
comparatorB
)
return
-
1
;
if
(
a
.
category
!=
b
.
category
)
{
else
if
(
comparatorA
>
comparatorB
)
return
+
1
;
return
comparatorA
.
localeCompare
(
comparatorB
,
undefined
,
{
numeric
:
true
});
else
return
0
;
}
// 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).
// Arranges block in layout (Horizontal or Vertical).
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment