Index: main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js
===================================================================
--- main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js	(revision 33101)
+++ main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js	(revision 33102)
@@ -1,2 +1,4 @@
+// Global autocomplete labels list: one list for all the map editors' shape labels in a page
+// We use the global labels hashmap to more efficiently ensure uniqueness of labels in our autocomplete list
 var global_autocompleteLabelsList = [];
 var global_labels_hashmap = {};
@@ -183,8 +185,13 @@
 // Ensure only unique labels are added to our autocomplete list
 MapEditor.prototype.addToAutocompleteLabelsList = function (newLabel) {
-    if (newLabel !== "" && !global_autocompleteLabelsList.includes(newLabel)) {
+
+    // We use a hashmap to more efficiently ensure uniqueness of labels in our array
+    // https://stackoverflow.com/questions/11040472/how-to-check-if-object-property-exists-with-a-variable-holding-the-property-name
+    if (newLabel !== "" && !global_labels_hashmap.hasOwnProperty(newLabel)) { // label is not empty and unique, so
+        // add to hashmap now
+        global_labels_hashmap[newLabel] = 1;
         // add to autocomplete list and sort alphabetically
         global_autocompleteLabelsList.push(newLabel);
-        global_autocompleteLabelsList.sort();        
+        global_autocompleteLabelsList.sort();
     }
 }
@@ -500,5 +507,5 @@
 			}
 		}
-	); // TODO: responseFunction in setMeta call
+	); // responseFunctions are now in the setMeta calls
 }
 
@@ -801,15 +808,10 @@
 	map_editor.overlays = new_overlays;
 
-	var local_labels_hashmap = {};
 	for (var i=0; i<map_editor.overlays.length; i++) {
 	    var shape = map_editor.overlays[i];
 
 	    // set up the autocomplete list using saved labels/descriptions
-	    //map_editor.addToAutocompleteLabelsList(shape.description); // inefficient in ensuring uniqueness of values, use (hash)map
-	    if (shape.description !== "") {
-	        local_labels_hashmap[shape.description] = 1;  // we just want the shape.description added to the map as key, don't care about value
-	                                                // so that we can maintain a list of unique descriptions
-	    }
-
+	    map_editor.addToAutocompleteLabelsList(shape.description); // now efficiently ensures uniqueness of values using (hash)map
+        
 		// make the shapes selectable on load:
 		if (ShapesUtil.overlayItemIsShape(shape)) {
@@ -822,27 +824,4 @@
 
 	this.mapEditorHistory.presentOverlayPush();
-	
-    // DO NOT assign "this.autocompleteLabelsList = keys(local_labels_hashmap);"
-    // Because Javascript is like Java and (in this) like C, not like C++. JavaScript uses Call-By-Sharing for objects:
-    // when reference addresses that are overwritten inside functions,
-	// the new address local to the function is not remembered/visible back outside the function
-    // https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language
-    // Instead, push.apply=addAll elements of keys to our autocomplete list, see 
-    // https://stackoverflow.com/questions/35658464/what-is-the-equivalent-of-java-collection-addall-for-javascript-arrays/35658514
-
-    // Combining contents of one JavaScript Object/hashmap (or associative 'array') into another is also described as merging our JavaScript Objects, so see
-    // https://stackoverflow.com/questions/929776/merging-objects-associative-arrays
-    // We've decided to use the jQuery based suggested solution for merging hashmaps:
-    // $.extend(obj1, obj2); means obj1 = obj1 + obj2. Note: it additionally overwrites any existing properties in obj1 with new values in obj2.
-	$.extend(global_labels_hashmap, local_labels_hashmap);
-
-    // important to empty our global autocomplete labels list array
-    // See https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript
-    // and https://www.jstips.co/en/javascript/two-ways-to-empty-an-array/
-	global_autocompleteLabelsList.length = 0;
-    
-	var keys = Object.keys(global_labels_hashmap);
-	global_autocompleteLabelsList.push.apply(global_autocompleteLabelsList, keys); // addAll keys to our global_autocompleteLabelsList (turns map's keys into array)
-	global_autocompleteLabelsList.sort();	
 }
 
@@ -888,5 +867,5 @@
 }
 
-// Having got our unique (set) of descriptions/labels, we're ready to set it up as the source for our autocomplete list
+// Global function that uses jquery to set the autocomplete list's data source to whatever's in our global autocomplete labels array
 $(function setupAutocompleteLabelsList() {
     // Overrides the default autocomplete filter function to
