Changeset 33102

Show
Ignore:
Timestamp:
22.05.2019 16:58:53 (4 weeks ago)
Author:
wy59
Message:

In previous commits we weren't using the capabilities of the (hash)map. Now we finally make proper use of it to efficiently ensure the uniqueness of labels we put into the autocomplete list.

Files:
1 modified

Legend:

Unmodified
Added
Removed
  • main/trunk/greenstone3/web/interfaces/default/js/map-scripts-editor.js

    r33100 r33102  
     1// Global autocomplete labels list: one list for all the map editors' shape labels in a page 
     2// We use the global labels hashmap to more efficiently ensure uniqueness of labels in our autocomplete list 
    13var global_autocompleteLabelsList = []; 
    24var global_labels_hashmap = {}; 
     
    183185// Ensure only unique labels are added to our autocomplete list 
    184186MapEditor.prototype.addToAutocompleteLabelsList = function (newLabel) { 
    185     if (newLabel !== "" && !global_autocompleteLabelsList.includes(newLabel)) { 
     187 
     188    // We use a hashmap to more efficiently ensure uniqueness of labels in our array 
     189    // https://stackoverflow.com/questions/11040472/how-to-check-if-object-property-exists-with-a-variable-holding-the-property-name 
     190    if (newLabel !== "" && !global_labels_hashmap.hasOwnProperty(newLabel)) { // label is not empty and unique, so 
     191        // add to hashmap now 
     192        global_labels_hashmap[newLabel] = 1; 
    186193        // add to autocomplete list and sort alphabetically 
    187194        global_autocompleteLabelsList.push(newLabel); 
    188         global_autocompleteLabelsList.sort();         
     195        global_autocompleteLabelsList.sort(); 
    189196    } 
    190197} 
     
    500507            } 
    501508        } 
    502     ); // TODO: responseFunction in setMeta call 
     509    ); // responseFunctions are now in the setMeta calls 
    503510} 
    504511 
     
    801808    map_editor.overlays = new_overlays; 
    802809 
    803     var local_labels_hashmap = {}; 
    804810    for (var i=0; i<map_editor.overlays.length; i++) { 
    805811        var shape = map_editor.overlays[i]; 
    806812 
    807813        // set up the autocomplete list using saved labels/descriptions 
    808         //map_editor.addToAutocompleteLabelsList(shape.description); // inefficient in ensuring uniqueness of values, use (hash)map 
    809         if (shape.description !== "") { 
    810             local_labels_hashmap[shape.description] = 1;  // we just want the shape.description added to the map as key, don't care about value 
    811                                                     // so that we can maintain a list of unique descriptions 
    812         } 
    813  
     814        map_editor.addToAutocompleteLabelsList(shape.description); // now efficiently ensures uniqueness of values using (hash)map 
     815         
    814816        // make the shapes selectable on load: 
    815817        if (ShapesUtil.overlayItemIsShape(shape)) { 
     
    822824 
    823825    this.mapEditorHistory.presentOverlayPush(); 
    824      
    825     // DO NOT assign "this.autocompleteLabelsList = keys(local_labels_hashmap);" 
    826     // Because Javascript is like Java and (in this) like C, not like C++. JavaScript uses Call-By-Sharing for objects: 
    827     // when reference addresses that are overwritten inside functions, 
    828     // the new address local to the function is not remembered/visible back outside the function 
    829     // https://stackoverflow.com/questions/518000/is-javascript-a-pass-by-reference-or-pass-by-value-language 
    830     // Instead, push.apply=addAll elements of keys to our autocomplete list, see  
    831     // https://stackoverflow.com/questions/35658464/what-is-the-equivalent-of-java-collection-addall-for-javascript-arrays/35658514 
    832  
    833     // Combining contents of one JavaScript Object/hashmap (or associative 'array') into another is also described as merging our JavaScript Objects, so see 
    834     // https://stackoverflow.com/questions/929776/merging-objects-associative-arrays 
    835     // We've decided to use the jQuery based suggested solution for merging hashmaps: 
    836     // $.extend(obj1, obj2); means obj1 = obj1 + obj2. Note: it additionally overwrites any existing properties in obj1 with new values in obj2. 
    837     $.extend(global_labels_hashmap, local_labels_hashmap); 
    838  
    839     // important to empty our global autocomplete labels list array 
    840     // See https://stackoverflow.com/questions/1232040/how-do-i-empty-an-array-in-javascript 
    841     // and https://www.jstips.co/en/javascript/two-ways-to-empty-an-array/ 
    842     global_autocompleteLabelsList.length = 0; 
    843      
    844     var keys = Object.keys(global_labels_hashmap); 
    845     global_autocompleteLabelsList.push.apply(global_autocompleteLabelsList, keys); // addAll keys to our global_autocompleteLabelsList (turns map's keys into array) 
    846     global_autocompleteLabelsList.sort();    
    847826} 
    848827 
     
    888867} 
    889868 
    890 // Having got our unique (set) of descriptions/labels, we're ready to set it up as the source for our autocomplete list 
     869// Global function that uses jquery to set the autocomplete list's data source to whatever's in our global autocomplete labels array 
    891870$(function setupAutocompleteLabelsList() { 
    892871    // Overrides the default autocomplete filter function to