Skip to content

Instantly share code, notes, and snippets.

@musa11971
Created November 4, 2021 12:40
Show Gist options
  • Save musa11971/4e10d987eb7559083c82bd55d1b6ca89 to your computer and use it in GitHub Desktop.
Save musa11971/4e10d987eb7559083c82bd55d1b6ca89 to your computer and use it in GitHub Desktop.
// ==UserScript==
// @name (BETA) WME Advanced Categories
// @namespace https://github.com/musa11971
// @version 1.0
// @description Introducing (country specific) advanced categories to Waze Map Editor.
// @author musa11971 (Waze: mewsa) - https://github.com/musa11971
// @include /^https:\/\/(www|beta)\.waze\.com\/(?!user\/)(.{2,6}\/)?editor.*$/
// @run-at document-end
// @exclude https://www.waze.com/*user/*editor/*
// @grant none
// ==/UserScript==
let WME_Advanced_Categories = {
categories: {
'NL': {
'Musa Test': ['MUSA_TEST'],
'Abortuskliniek': ['DOCTOR_CLINIC'],
'Administratiebureau': ['OFFICES'],
'Advocatenkantoor/Juristenbureau': ['OFFICES'],
'Afvalverwerkingsbedrijf': ['TRASH_AND_RECYCLING_FACILITIES'],
'Auto schadeherstel/Autoplaatwerk': ['GARAGE_AUTOMOTIVE_SHOP'],
'Automaterialen winkel': ['GARAGE_AUTOMOTIVE_SHOP'],
'Basisschool': ['SCHOOL'],
'Beddenwinkel': ['FURNITURE_HOME_STORE'],
'Beek': ['RIVER_STREAM'],
'Begeleid wonen locatie': ['PROFESSIONAL_AND_PUBLIC'],
'Begraafplaats/Kerkhof': ['CEMETERY'],
'Beschermde woonvorm/Woongroep': ['PROFESSIONAL_AND_PUBLIC'],
'Bloedbank': ['DOCTOR_CLINIC'],
'Bowlingbaan': ['CULTURE_AND_ENTERTAINEMENT'],
'Broodjeszaak': ['RESTAURANT'],
'Bruidswinkel': ['SHOPPING_AND_SERVICES'],
'Buurthuis': ['CULTURE_AND_ENTERTAINEMENT'],
'CBR-locatie/CBR-examencentrum': ['PROFESSIONAL_AND_PUBLIC'],
'Crematorium': ['PROFESSIONAL_AND_PUBLIC'],
'Computerwinkel': ['ELECTRONICS'],
'Cosmeticawinkel': ['SHOPPING_AND_SERVICES'],
'COVID-19 testsite/Vaccinatie site': ['OTHER'],
'Dierenasiel': ['PROFESSIONAL_AND_PUBLIC'],
'Drogist': ['PERSONAL_CARE'],
'Edelsmid': ['JEWELRY'],
'Fietsenwinkel/Fietsenmaker': ['SHOPPING_AND_SERVICES'],
'Fysiotherapeut': ['DOCTOR_CLINIC'],
'Galerie': ['ART_GALLERY'],
'Gamewinkel/Spellenwinkel': ['TOY_STORE'],
'Gedenkplaats/Gedenkteken': ['OTHER'],
'Gemeentehuis': ['GOVERNMENT'],
'Gevangenis/Huis van bewaring': ['PRISON_CORRECTIONAL_FACILITY'],
'Gezondheidscentrum': ['DOCTOR_CLINIC'],
'GGZ-locatie/GGZ-kliniek': ['DOCTOR_CLINIC'],
'Hogeschool (HBO)': ['COLLEGE_UNIVERSITY'],
'Horlogewinkel': ['JEWELRY'],
'Huisarts': ['DOCTOR_CLINIC'],
'ICT-bedrijf': ['OFFICES'],
'Kaaswinkel': ['SHOPPING_AND_SERVICES'],
'Kapper/Kapsalon': ['PERSONAL_CARE'],
'Kerk': ['RELIGIOUS_CENTER'],
'Keukenwinkel': ['FURNITURE_HOME_STORE'],
'Kinderboerderij': ['ZOO_AQUARIUM'],
'Kinderopvang': ['PROFESSIONAL_AND_PUBLIC'],
'Kringloopwinkel': ['SHOPPING_AND_SERVICES'],
'Lingeriewinkel': ['FASHION_AND_CLOTHING'],
'Makelaar': ['OFFICES'],
'Massagesalon': ['PERSONAL_CARE'],
'Middelbare school': ['SCHOOL'],
'Milieustraat': ['TRASH_AND_RECYCLING_FACILITIES'],
'Mode zaak': ['FASHION_AND_CLOTHING'],
'Monument': ['OTHER'],
'Moskee': ['RELIGIOUS_CENTER'],
'Motorvoertuigen tuningservice/Tuning garage': ['GARAGE_AUTOMOTIVE_SHOP'],
'Multifunctioneel centrum (MFC)': ['PROFESSIONAL_AND_PUBLIC'],
'Nagelsalon': ['PERSONAL_CARE'],
'Oogarts': ['DOCTOR_CLINIC'],
'Oplaadpaal': ['CHARGING_STATION'],
'Opticien': ['DOCTOR_CLINIC'],
'Orthodontist': ['DOCTOR_CLINIC'],
'Parfumerie': ['SHOPPING_AND_SERVICES'],
'Pedicuresalon': ['PERSONAL_CARE'],
'Peuterspeelzaal': ['SCHOOL'],
'Recycle bedrijf': ['TRASH_AND_RECYCLING_FACILITIES'],
'Rijschool/Rijcursus/Theoriecursus locatie': ['PROFESSIONAL_AND_PUBLIC'],
'Sanitairwinkel': ['FURNITURE_HOME_STORE'],
'Schildersbedrijf': ['SHOPPING_AND_SERVICES'],
'Schoenenwinkel': ['SHOPPING_AND_SERVICES'],
'Slijterij': ['SHOPPING_AND_SERVICES'],
'Snackbar': ['FAST_FOOD'],
'Spoedeisendehulp': ['HOSPITAL_URGENT_CARE'],
'Sportschool': ['GYM_FITNESS'],
'Synagoge': ['RELIGIOUS_CENTER'],
'Tabakswinkel/Sigarenzaak': ['SHOPPING_AND_SERVICES'],
'Tandarts': ['DOCTOR_CLINIC'],
'Tassenwinkel': ['SHOPPING_AND_SERVICES'],
'Tattoo/Piercing/Bodymod winkel': ['SHOPPING_AND_SERVICES'],
'Telefoonwinkel': ['TELECOM'],
'Thuiszorgwinkel/Medische benodigdheden winkel': ['SHOPPING_AND_SERVICES'],
'Toko': ['SUPERMARKET_GROCERY'],
'Tolkenbureau/Vertaalbureau': ['OFFICES'],
'Transportbedrijf': ['PROFESSIONAL_AND_PUBLIC'],
'Tuincentrum': ['SHOPPING_AND_SERVICES'],
'Uitvaartcentrum': ['PROFESSIONAL_AND_PUBLIC'],
'Uitzendbureau': ['OFFICES'],
'Universiteit': ['COLLEGE_UNIVERSITY'],
'Verloskundigenpraktijk': ['SHOPPING_AND_SERVICES'],
'Verzekeringsbedrijf': ['OFFICES'],
'Verzorgingstehuis': ['PROFESSIONAL_AND_PUBLIC'],
'Viswinkel': ['FOOD_AND_DRINK'],
'Voedselbank': ['FOOD_AND_DRINK'],
'Wasstraat/Carwash/Wasbox': ['CAR_WASH'],
'Waterval': ['RIVER_STREAM']
}
},
// Maximum amount of search results in categories
MAX_SEARCH_RESULTS: 10,
// UpdateObject Waze Action
UpdateObject: null,
// Check if everything is ready before initializing
tryInit(attempt = 1) {
let retry = function() {
setTimeout(this.tryInit.bind(this), 500, attempt + 1);
return;
}.bind(this);
this.logString('Trying init. Attempt: ' + attempt);
if( typeof $ === 'undefined' ||
typeof W === 'undefined' ||
typeof W.selectionManager === 'undefined'
) {
retry();
return;
}
this.init();
},
// Initialize the script
init() {
// Add event listeners
W.selectionManager.events.register('selectionchanged', null, (e) => {
this.onSelectionChange(e.selected);
});
// Get UpdateObject Waze action
if(typeof (require) !== 'undefined') {
this.UpdateObject = require('Waze/Action/UpdateObject');
}
else {
this.UpdateObject = W.Action.UpdateObject;
}
this.logString('Initialized.');
},
// Called when WME selection changes
onSelectionChange(selection) {
// Only when there is 1 venue selected, we want to start
// .. listening for category input
if(selection.length !== 1) return;
if(selection[0].model.type !== 'venue') return;
this.startListenForCategoryInput();
},
// Start listening for category input
startListenForCategoryInput() {
this.logString('Start listening for category input.');
$('.select2-input').on('input', () => {
let input = $('.select2-input').val();
this.searchForCategory(input);
});
},
// Search for category
searchForCategory(text) {
// Search for matches
let matches = [];
for(const advancedCategory in this.categories.NL) {
if(text.length < 1) break;
if(advancedCategory.toLowerCase().includes(text.toLowerCase()))
matches.push(advancedCategory);
if(matches.length >= this.MAX_SEARCH_RESULTS) break;
}
// Remove old results
$('.wme-advanced-categories-result').remove();
// Create search result options
let resultsList = $('.select2-results');
for(const i in matches) {
let match = matches[i];
let li = $('<li></li>');
li.attr('class', 'wme-advanced-categories-result select2-results-dept-0 select2-result select2-result-selectable');
li.attr('role', 'presentation');
let div = $('<div>⭐ ' + match + '</div>');
div.attr('class', 'select2-result-label');
div.attr('role', 'option');
li.append(div);
li.on('click', () => {
this.applyAdvancedCategory(match);
});
resultsList.prepend(li);
}
// Remove 'no results' option, if there are results
if(matches.length > 0)
$('.select2-no-results').remove();
},
// Applies the advanced category to the venue
applyAdvancedCategory(categoryName) {
let feature = W.selectionManager.getSelectedFeatures()[0];
let newCategories = this.categories.NL[categoryName];
W.model.actionManager.add(new this.UpdateObject(feature.model, {
'categories': newCategories,
'categoryAttributes': {
'DOCTOR_CLINIC': {
realCategory: 'Abortuskliniek'
}
}
}));
// Drop mask on the options list
$('#select2-drop-mask').click();
// Add the success message
let success = $('<span style="font-weight: bold; color: #01701f ;">✅ ' + categoryName + '</span>');
$('.select2-choices').parent().parent().append(success);
setTimeout(() => {
success.remove();
}, 500);
},
// Logs a message to the console
logString(message) {
console.log('[WME-Advanced-Categories] ' + message);
}
};
WME_Advanced_Categories.tryInit();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment