Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion 00.config.sh
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
## Path to Closure Compiler
COMPILER="java -jar closure-compiler-v20230103.jar"
COMPILER="java -jar closure-compiler-v20260526.jar"

EXT_NAME=WV
EXT_FILE_NAME="WME_Validator.user.js"
Expand Down
1 change: 1 addition & 0 deletions 99.build.sh
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ cat "${SRC_DIR}/meta/i18n-end.js" >> "${LOC_FILE}"

${COMPILER} \
--language_in ECMASCRIPT_2017 \
--language_out ECMASCRIPT_2017 \
--js "${SRC_DIR}/src/release.js" \
--js "${LOC_FILE}" \
--js "${SRC_DIR}/src/helpers.js" \
Expand Down
112 changes: 112 additions & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

## What This Is

WME Validator is a Tampermonkey/GreasyFork userscript for the [Waze Map Editor](https://waze.com). It validates map data (segments, nodes, venues) against 150+ rules across 26+ countries, highlights issues in the editor, and generates detailed reports with wiki references and solutions.

## Build Commands

The project uses shell scripts wrapping the Google Closure Compiler (Java). No `npm` or `package.json`.

```bash
./10.release.sh # Release build → build/WME_Validator.user.js (ADVANCED_OPTIMIZATIONS)
./20.debug.sh # Debug build → build/WME_Validator.debug.js (BUNDLE, DEF_DEBUG=true)
./30.gf.sh # GreasyFork build → build/WME_Validator.gf.js (WHITESPACE_ONLY)
./98.format.sh # Format the compiled output with clang-format (Google style, tab width 4)
./99.build.sh # Orchestrator — runs all three build variants
```

Configuration (compiler path, output dirs) is in `./00.config.sh`. The closure compiler binary must be installed; the repo was last tested with v20230103.

There are **no automated tests**. Validation is done manually per `doc/RELENG.md`.

## Architecture

### Build Pipeline

Source files are concatenated in a specific order and fed to Closure Compiler:

1. `meta/meta-begin.js` — UserScript `@userscript` header
2. `meta/i18n-begin.js` — opens the translations object
3. `i18n/default.js` + `i18n/<CC>.js` (26 countries) — localization rules, auto-concatenated
4. `meta/i18n-end.js` — closes the translations object
5. `src/*.js` — core application code
6. `meta/meta-end.js` — closing wrapper
7. `meta/wme-externs.js` + `meta/jquery-1.9.js` — Closure Compiler extern definitions (not bundled, only used for type-checking)

The post-build steps prepend the UserScript metadata header and run `clang-format`.

### Global Namespaces

All runtime state lives in four top-level objects defined in `src/data.js`:

| Namespace | Purpose |
|-----------|---------|
| `_WV` | Private validator state and configuration |
| `_UI` | User interface state |
| `_RT` | Runtime data (current scan results, active segment info) |
| `_REP` | Report accumulator |

The `_THUI` namespace (from `src/lib/thui.js`) is a small embedded HTML UI toolkit.

### Core Execution Flow

```
WME login event
└─ F_LOGIN (src/login.js) — access control, UI initialization

User triggers scan
└─ F_VALIDATE (src/validate.js) — runs all rules against segments/nodes/venues

Map change events (segments/nodes/venues)
└─ F_ONSEGMENTSCHANGED / F_ONNODESCHANGED / F_ONVENUESCHANGED (src/other.js)
└─ re-validates affected objects

User requests report
└─ F_SHOWREPORT (src/report.js) — generates HTML/text/CSV output
```

### Source File Roles

- `src/release.js` — version string, release/expiry dates, CDN URLs, global access lists
- `src/data.js` — namespace definitions, constants, `DEF_DEBUG` flag
- `src/helpers.js` — pure utilities: `classOf`, `deepCopy`, `deepCompare`, `getDirection`
- `src/basic.js` — logging, HTML escaping, Trusted Types policy, error handling
- `src/validate.js` — validation engine; each rule is a function called per object
- `src/report.js` — report rendering (HTML table, plain text, CSV)
- `src/login.js` — login handler, access list parsing, country/user/level gates
- `src/other.js` — WME event listeners and layer change handler
- `src/lib/i18n.js` — i18n lookup helpers
- `src/lib/audio.js` — audio notification system
- `src/lib/thui.js` — tiny UI library for building form controls

### Localization and Country Rules

`i18n/` is a **git submodule** (`https://github.com/WMEValidator/i18n.git`). Each country file (`i18n/AR.js`, `i18n/DE.js`, etc.) overrides or extends the default English rules in `i18n/default.js`. When editing country-specific rules, changes go in the submodule, not in the main repo.

### Access Control

Rules can be gated by user level, username, country, or city using constants from `src/release.js`:
- `GA_FORLEVEL` — minimum WME user level
- `GA_FORUSER` / `GA_FORCOUNTRY` / `GA_FORCITY` — allowlists with negation (`"!Dekis,*"`)

These are evaluated in `F_LOGIN` against `WLM.user` attributes.

### Conventions

- Main handler functions are named `F_ACTION()` (e.g., `F_VALIDATE`, `F_LOGIN`, `F_SHOWREPORT`)
- Constants are `ALL_CAPS`
- JSDoc annotations (`@const`, `@type`, `@suppress`, `@struct`, `@define`) are used throughout — they matter for Closure Compiler's type checker and dead code elimination
- Debug-only code is guarded by `DEF_DEBUG` (a `@define` constant, stripped in release builds)
- All HTML written to the DOM must go through the Trusted Types policy defined in `src/basic.js`

## Release Checklist

See `doc/RELENG.md` for the full checklist. Key steps before releasing:
- Ensure all `window.console` calls are commented out
- Resolve all `TEST:`, `TODO:`, `BETA:` markers
- Verify header fields: country locks, user levels, release date, expiration date
- Run release build and test both in Tampermonkey and Firefox
- Check Unicode characters in the output file
10 changes: 9 additions & 1 deletion doc/ChangeLog.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
Current changes:

v2026.06.01:
- adds '--language_out ECMASCRIPT_2017' in 99.build.sh to fix a build issue.
- fixes ES-CL language by falling back to spanish language.
- fixes wazeopedia issue links for waze discuss search links.
- updates script meta headers with WME Validator page in waze discuss forum.
- updates closure-compiler version called from v20230103 to v20260526.
- adds CLAUDE.md basic init.

v2025.02.26:
- DaveAcincy: fix for #107 and #108.

Expand Down Expand Up @@ -866,4 +874,4 @@ Bugs & Issues:
- Run once mode permalinks were fixed

Other changes
- report of a very long street names has moved to a Polish country pack
- report of a very long street names has moved to a Polish country pack
9 changes: 5 additions & 4 deletions meta/meta-begin.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// ==UserScript==
// @name WME Validator
// @version 2025.02.26
// @version 2026.06.01
// @description This script validates a map area in Waze Map Editor, highlights issues and generates a very detailed report with wiki references and solutions
// @match https://beta.waze.com/*editor*
// @match https://www.waze.com/*editor*
Expand All @@ -9,7 +9,7 @@
// @grant none
// @icon https://raw.githubusercontent.com/WMEValidator/release/master/img/WV-icon96.png
// @namespace a
// @homepage https://www.waze.com/forum/viewtopic.php?f=819&t=76488
// @homepage https://www.waze.com/discuss/t/script-wme-validator-v2025-02-26-places-beta/44877
// @author Andriy Berestovskyy <berestovskyy@gmail.com>
// @copyright 2013-2018 Andriy Berestovskyy
// @license GPLv3
Expand All @@ -18,6 +18,7 @@
// @contributor jangliss
// @contributor Glodenox
// @contributor DaveAcincy
// @contributor miguelovergara
// ==/UserScript==
/*
* WME Validator uses Open Source GPLv3 license, i.e. you may copy,
Expand All @@ -30,10 +31,10 @@
* https://github.com/WMEValidator/
*
* For questions please use official forum:
* https://www.waze.com/forum/viewtopic.php?f=819&t=76488
* https://www.waze.com/discuss/t/script-wme-validator-v2025-02-26-places-beta/44877
*
* Report bugs on GitHub Issues Tracker:
* https://github.com/WMEValidator/validator/issues
*/

(function () {
(function () {
8 changes: 4 additions & 4 deletions src/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -558,12 +558,12 @@ async function F_LOGIN() {
if (labelPL in translation) {
var l = translation[labelPL]
.replace('W:', PFX_WIKI)
.replace('P:', PFX_PEDIA)
.replace('P:', PFX_SEARCH)
.replace('F:', PFX_FORUM)
.replace('D:', PFX_DISCUSS)
;
check.PROBLEMLINK[ccode] = encodeURI(l);
if (-1 !== l.indexOf(PFX_WIKI) || -1 !== l.indexOf(PFX_PEDIA))
if (-1 !== l.indexOf(PFX_WIKI) || -1 !== l.indexOf(PFX_SEARCH))
check.PROBLEMLINKTEXT[ccode] = trS('report.link.wiki');
else
if (-1 !== l.indexOf(PFX_FORUM))
Expand All @@ -574,12 +574,12 @@ async function F_LOGIN() {
if (labelSL in translation) {
var l = translation[labelSL]
.replace('W:', PFX_WIKI)
.replace('P:', PFX_PEDIA)
.replace('P:', PFX_SEARCH)
.replace('F:', PFX_FORUM)
.replace('D:', PFX_DISCUSS)
;
check.SOLUTIONLINK[ccode] = encodeURI(l);
if (-1 !== l.indexOf(PFX_WIKI || -1 !== l.indexOf(PFX_PEDIA)))
if (-1 !== l.indexOf(PFX_WIKI || -1 !== l.indexOf(PFX_SEARCH)))
check.SOLUTIONLINKTEXT[ccode] = trS('report.link.wiki');
else
if (-1 !== l.indexOf(PFX_FORUM))
Expand Down
2 changes: 1 addition & 1 deletion src/release.js
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,7 @@ var MAX_CHECKS = 310;
/** @const */
var PFX_WIKI = 'https://www.waze.com/wiki/';
/** @const */
var PFX_PEDIA = 'https://wazeopedia.waze.com/wiki/';
var PFX_SEARCH = 'https://www.waze.com/discuss/search?q=';
/** @const */
var PFX_FORUM = 'https://www.waze.com/forum/viewtopic.php?';
/** @const */
Expand Down
6 changes: 3 additions & 3 deletions src/report.js
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,7 @@ function F_SHOWREPORT(reportFormat) {
function addTextLabels(pack, label, defSet, oldPack) {
var defData = (defSet[label] || '')
.replace(new RegExp('^W:'), PFX_WIKI)
.replace(new RegExp('^P:'), PFX_PEDIA)
.replace(new RegExp('^P:'), PFX_SEARCH)
.replace(new RegExp('^F:'), PFX_FORUM)
.replace(new RegExp('^D:'), PFX_DISCUSS)
;
Expand All @@ -381,14 +381,14 @@ function F_SHOWREPORT(reportFormat) {
var oldData = origData
.replace(new RegExp('^' + GL_TODOMARKER), '')
.replace(new RegExp('^W:'), PFX_WIKI)
.replace(new RegExp('^P:'), PFX_PEDIA)
.replace(new RegExp('^P:'), PFX_SEARCH)
.replace(new RegExp('^F:'), PFX_FORUM)
.replace(new RegExp('^D:'), PFX_DISCUSS)
;
// preserve old data
var oldDataEN = (oldPack[label + '.en'] || '')
.replace(new RegExp('^W:'), PFX_WIKI)
.replace(new RegExp('^P:'), PFX_PEDIA)
.replace(new RegExp('^P:'), PFX_SEARCH)
.replace(new RegExp('^F:'), PFX_FORUM)
.replace(new RegExp('^D:'), PFX_DISCUSS)
;
Expand Down
2 changes: 1 addition & 1 deletion src/validate.js
Original file line number Diff line number Diff line change
Expand Up @@ -2588,7 +2588,7 @@ function F_VALIDATE(disabledHL) {
var foundPublicConnection = checkPublicConnection(segment, null);
if (!foundPublicConnection) {
// We might have a isolated segment. Could be a Restricted Gate
// See https://wazeopedia.waze.com/wiki/USA/Private_Installations#Specialty_Gate:_Restricted_Gate
// See: https://www.waze.com/discuss/t/private-installations/378216#p-2277317-specialty-gate-restricted-gate-30
if (nodeA.$otherSegmentsLen == 1 && nodeB.$otherSegmentsLen == 1) {
// both sides are connected to just one private segment
var nodeASegment = nodeA.$otherSegments[0];
Expand Down