// ==UserScript==
// @name WME Road Name Helper NP
// @description Check suffix and common word abbreviations without leaving WME
// @version 2025.06.15.02
// @author Kid4rm90s
// @license MIT
// @match *://*.waze.com/*editor*
// @exclude *://*.waze.com/user/editor*
// @connect greasyfork.org
// @grant GM_xmlhttpRequest
// @namespace https://greasyfork.org/users/1087400
// @require https://greasyfork.org/scripts/24851-wazewrap/code/WazeWrap.js
// @downloadURL none
// ==/UserScript==
(function () {
'use strict';
const updateMessage = `
- Added: Typing "AH2" now suggests "AH02"
- Added: Typing "NH01 - रा१" or using suffix "रा१" now suggests "NH01 - रारा०१"
- Improved: Custom suffix and highway code mapping logic for Nepali and highway abbreviations
- Fixed: Suffix suggestion logic for Nepali abbreviations
`;
const SCRIPT_VERSION = GM_info.script.version.toString();
const SCRIPT_NAME = GM_info.script.name;
const DOWNLOAD_URL = GM_info.script.downloadURL;
const GreasyFork_URL = 'https://greasyfork.org/en/scripts/538171-wme-road-name-helper-np';
const forumURL = 'https://greasyfork.org/en/scripts/538171-wme-road-name-helper-np/feedback';
let sdk;
// Suffix Abbreviation Data (Abbreviation: FullWord)
// This is for suffixes that have standard abbreviations
const wmessa_approvedAbbr = {
Ally: 'Alley',
App: 'Approach',
Arc: 'Arcade',
Av: 'Avenue',
Bwlk: 'Boardwalk',
Bvd: 'Boulevard',
Brk: 'Break',
Bypa: 'Bypass',
Ch: 'Chase',
Cct: 'Circuit',
Cl: 'Close',
Con: 'Concourse',
Ct: 'Court',
Cr: 'Crescent',
Crst: 'Crest',
Dr: 'Drive',
Ent: 'Entrance',
Esp: 'Esplanade',
Exp: 'Expressway',
Ftrl: 'Firetrail',
Fwy: 'Freeway',
Glde: 'Glade',
Gra: 'Grange',
Gr: 'Grove',
Hwy: 'Highway',
Mwy: 'Motorway',
Pde: 'Parade',
Pwy: 'Parkway',
Psge: 'Passage',
Pl: 'Place',
Plza: 'Plaza',
Prom: 'Promenade',
Qys: 'Quays',
Rtt: 'Retreat',
Rdge: 'Ridge',
Rd: 'Road',
Sq: 'Square',
Stps: 'Steps',
St: 'Street',
Sbwy: 'Subway',
Tce: 'Terrace',
Trk: 'Track',
Trl: 'Trail',
Vsta: 'Vista',
};
// Suffix Suggestion Data (UserTyped/FullWord: CorrectAbbreviation)
// This is for suffixes that have specific suggestions
const wmessa_suggestedAbbr = {
Alley: 'Ally',
Approach: 'App',
Arcade: 'Arc',
Avenue: 'Av',
Boardwalk: 'Bwlk',
Boulevard: 'Bvd',
Blvd: 'Bvd',
Break: 'Brk',
Bypass: 'Bypa',
Chase: 'Ch',
Circuit: 'Cct',
Close: 'Cl',
Concourse: 'Con',
Court: 'Ct',
Crescent: 'Cr',
Crest: 'Crst',
Drive: 'Dr',
Entrance: 'Ent',
Esplanade: 'Esp',
Expressway: 'Exp',
Firetrail: 'Ftrl',
Freeway: 'Fwy',
Glade: 'Glde',
Grange: 'Gra',
Grove: 'Gr',
Highway: 'Hwy',
Ln: 'Lane',
Marg: 'Marga',
Motorway: 'Mwy',
Parade: 'Pde',
Parkway: 'Pwy',
Passage: 'Psge',
Place: 'Pl',
Plaza: 'Plza',
Promenade: 'Prom',
Quays: 'Qys',
Retreat: 'Rtt',
Ridge: 'Rdge',
Road: 'Rd',
Square: 'Sq',
Steps: 'Stps',
Street: 'St',
Subway: 'Sbwy',
Terrace: 'Tce',
Track: 'Trk',
Trail: 'Trl',
Vista: 'Vsta',
रा१: 'रारा०१',
रा२: 'रारा०२',
रा३: 'रारा०३',
रा४: 'रारा०४',
रा५: 'रारा०५',
रा६: 'रारा०६',
रा७: 'रारा०७',
रा८: 'रारा०८',
रा९: 'रारा०९',
};
// Suffixes that should be preserved in title case (case-insensitive)
// These words will not be converted to lowercase in title case
// This is useful for words that are proper nouns or have specific casing requirements.
const wmessa_preserveCaseWords = [
'NH01',
'NH02',
'NH03',
'NH04',
'NH05',
'NH06',
'NH07',
'NH08',
'NH09',
'NH10',
'NH11',
'NH12',
'NH13',
'NH14',
'NH15',
'NH16',
'NH17',
'NH18',
'NH19',
'NH20',
'NH21',
'NH22',
'NH23',
'NH24',
'NH25',
'NH26',
'NH27',
'NH28',
'NH29',
'NH30',
'NH31',
'NH32',
'NH33',
'NH34',
'NH35',
'NH36',
'NH37',
'NH38',
'NH39',
'NH40',
'NH41',
'NH42',
'NH43',
'NH44',
'NH45',
'NH46',
'NH47',
'NH48',
'NH49',
'NH50',
'NH51',
'NH52',
'NH53',
'NH54',
'NH55',
'NH56',
'NH57',
'NH58',
'NH59',
'NH60',
'NH61',
'NH62',
'NH63',
'NH64',
'NH65',
'NH66',
'NH67',
'NH68',
'NH69',
'NH70',
'NH71',
'NH72',
'NH73',
'NH74',
'NH75',
'NH76',
'NH77',
'NH78',
'NH79',
'NH80',
'AH01',
'AH02',
'AH03',
'AH04',
'AH05',
'AH06',
'AH07',
'AH08',
'AH09',
'AH10',
];
// Highway Suffix Suggestion Data (EXACT match only)
// This is for highway abbreviations that have specific suggestions
const wmessa_suggestedHwyAbbr = {
'NH01-': 'NH01 - रारा०१',
'NH02-': 'NH02 - रारा०२',
'NH03-': 'NH03 - रारा०३',
'NH04-': 'NH04 - रारा०४',
'NH05-': 'NH05 - रारा०५',
'NH06-': 'NH06 - रारा०६',
'NH07-': 'NH07 - रारा०७',
'NH08-': 'NH08 - रारा०८',
'NH09-': 'NH09 - रारा०९',
'NH10-': 'NH10 - रारा१०',
'NH11-': 'NH11 - रारा११',
'NH12-': 'NH12 - रारा१२',
'NH13-': 'NH13 - रारा१३',
'NH14-': 'NH14 - रारा१४',
'NH15-': 'NH15 - रारा१५',
'NH16-': 'NH16 - रारा१६',
'NH17-': 'NH17 - रारा१७',
'NH18-': 'NH18 - रारा१८',
'NH19-': 'NH19 - रारा१९',
'NH20-': 'NH20 - रारा२०',
'NH21-': 'NH21 - रारा२१',
'NH22-': 'NH22 - रारा२२',
'NH23-': 'NH23 - रारा२३',
'NH24-': 'NH24 - रारा२४',
'NH25-': 'NH25 - रारा२५',
'NH26-': 'NH26 - रारा२६',
'NH27-': 'NH27 - रारा२७',
'NH28-': 'NH28 - रारा२८',
'NH29-': 'NH29 - रारा२९',
'NH30-': 'NH30 - रारा३०',
'NH31-': 'NH31 - रारा३१',
'NH32-': 'NH32 - रारा३२',
'NH33-': 'NH33 - रारा३३',
'NH34-': 'NH34 - रारा३४',
'NH35-': 'NH35 - रारा३५',
'NH36-': 'NH36 - रारा३६',
'NH37-': 'NH37 - रारा३७',
'NH38-': 'NH38 - रारा३८',
'NH39-': 'NH39 - रारा३९',
'NH40-': 'NH40 - रारा४०',
'NH41-': 'NH41 - रारा४१',
'NH42-': 'NH42 - रारा४२',
'NH43-': 'NH43 - रारा४३',
'NH44-': 'NH44 - रारा४४',
'NH45-': 'NH45 - रारा४५',
'NH46-': 'NH46 - रारा४६',
'NH47-': 'NH47 - रारा४७',
'NH48-': 'NH48 - रारा४८',
'NH49-': 'NH49 - रारा४९',
'NH50-': 'NH50 - रारा५०',
'NH51-': 'NH51 - रारा५१',
'NH52-': 'NH52 - रारा५२',
'NH53-': 'NH53 - रारा५३',
'NH54-': 'NH54 - रारा५४',
'NH55-': 'NH55 - रारा५५',
'NH56-': 'NH56 - रारा५६',
'NH57-': 'NH57 - रारा५७',
'NH58-': 'NH58 - रारा५८',
'NH59-': 'NH59 - रारा५९',
'NH60-': 'NH60 - रारा६०',
'NH61-': 'NH61 - रारा६१',
'NH62-': 'NH62 - रारा६२',
'NH63-': 'NH63 - रारा६३',
'NH64-': 'NH64 - रारा६४',
'NH65-': 'NH65 - रारा६५',
'NH66-': 'NH66 - रारा६६',
'NH67-': 'NH67 - रारा६७',
'NH68-': 'NH68 - रारा६८',
'NH69-': 'NH69 - रारा६९',
'NH70-': 'NH70 - रारा७०',
'NH71-': 'NH71 - रारा७१',
'NH72-': 'NH72 - रारा७२',
'NH73-': 'NH73 - रारा७३',
'NH74-': 'NH74 - रारा७४',
'NH75-': 'NH75 - रारा७५',
'NH76-': 'NH76 - रारा७६',
'NH77-': 'NH77 - रारा७७',
'NH78-': 'NH78 - रारा७८',
'NH79-': 'NH79 - रारा७९',
'NH80-': 'NH80 - रारा८०',
AH1: 'AH01',
AH2: 'AH02',
AH3: 'AH03',
AH4: 'AH04',
AH5: 'AH05',
};
// Suffixes with No Standard Abbreviation
const wmessa_knownNoAbbr = ['Lane', 'Loop', 'Mall', 'Mews', 'Path', 'Ramp', 'Rise', 'View', 'Walk', 'Way'];
// --- NEW DATA FOR GENERAL WORDS (PRE-SUFFIX) ---
// General Word Suggestion Data (WordToAbbreviate: Abbreviation)
const wmessa_generalWordSuggestions = {
Mount: 'Mt',
Saint: 'St', // Note: "St" for Saint. Suffix logic handles "St" for Street.
Fort: 'Ft',
Marg: 'Marga', // Example: "Marg Bryant Drive" -> "Marga Bryant Dr"
// Add other common words like "North": "N", "South": "S", etc., if standard for pre-suffix words.
};
// General Word Approved Abbreviation Data (Abbreviation: FullWord) - for validation
const wmessa_generalWordApprovedAbbr = {
Mt: 'Mount',
St: 'Saint',
Ft: 'Fort',
Marga: 'Marg', // Example
// e.g. "N": "North", "S": "South"
};
function wmessa_titleCase(str) {
return str
.split(/\s+/)
.map(function (txt) {
// If word matches a preserve-case word (case-insensitive), use the preserved version
const preserve = wmessa_preserveCaseWords.find((w) => w.toLowerCase() === txt.toLowerCase());
if (preserve) return preserve;
return txt.charAt(0).toUpperCase() + txt.substr(1).toLowerCase();
})
.join(' ');
}
let wmessa_valueObserver;
function wmessa_init() {
const observer = new MutationObserver((mutationsList) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.removedNodes.forEach((node) => {
if (node.classList && node.classList.contains('address-edit-card')) {
if (wmessa_valueObserver) {
wmessa_valueObserver.disconnect();
}
}
});
mutation.addedNodes.forEach((node) => {
if (node.classList && node.classList.contains('address-edit-card')) {
setTimeout(() => {
// Main street name
const streetNameInput = node.querySelector('wz-autocomplete.street-name');
if (streetNameInput && streetNameInput.shadowRoot) {
const wzTextInput = streetNameInput.shadowRoot.querySelector('wz-text-input');
if (wzTextInput) {
wmessa_monitor(wzTextInput);
} else {
console.warn('WMESSA: wz-text-input not found in street-name shadowRoot.');
}
} else {
console.warn('WMESSA: street-name input or its shadowRoot not found.');
}
// Alt street name(s)
const altStreetInputs = node.querySelectorAll('wz-autocomplete.alt-street-name');
altStreetInputs.forEach((altInput) => {
if (altInput && altInput.shadowRoot) {
const altWzTextInput = altInput.shadowRoot.querySelector('wz-text-input');
if (altWzTextInput) {
wmessa_monitor(altWzTextInput);
} else {
console.warn('WMESSA: wz-text-input not found in alt-street-name shadowRoot.');
}
} else {
console.warn('WMESSA: alt-street-name input or its shadowRoot not found.');
}
});
}, 250);
}
});
}
});
});
const editPanel = document.getElementById('edit-panel');
if (editPanel) {
observer.observe(editPanel, { childList: true, subtree: true });
} else {
console.warn('WMESSA: Edit panel not found for observer.');
}
WazeWrap.Interface.ShowScriptUpdate('WME Road Name Helper NP', GM_info.script.version, updateMessage, GreasyFork_URL, forumURL);
}
// Also observe for alt street card (for alt names)
const altStreetPanelObserver = new MutationObserver((mutationsList) => {
mutationsList.forEach((mutation) => {
if (mutation.type === 'childList') {
mutation.addedNodes.forEach((node) => {
if (node.classList && node.classList.contains('edit-alt-street-card')) {
setTimeout(() => {
const altStreetInput = node.querySelector('wz-autocomplete.alt-street-name');
if (altStreetInput && altStreetInput.shadowRoot) {
const altWzTextInput = altStreetInput.shadowRoot.querySelector('wz-text-input');
if (altWzTextInput) {
wmessa_monitor(altWzTextInput);
} else {
console.warn('WMESSA: wz-text-input not found in alt-street-name shadowRoot (alt card).');
}
} else {
console.warn('WMESSA: alt-street-name input or its shadowRoot not found (alt card).');
}
}, 250);
}
});
}
});
});
// Observe the whole document for alt street cards
altStreetPanelObserver.observe(document.body, { childList: true, subtree: true });
function wmessa_monitor(element) {
let abbrContainer = document.createElement('div');
abbrContainer.id = 'WMESSA_container';
abbrContainer.innerHTML =
'