diff --git a/00.config.sh b/00.config.sh index 946a559..530ee0f 100644 --- a/00.config.sh +++ b/00.config.sh @@ -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" diff --git a/99.build.sh b/99.build.sh index 7e65c65..dd21d41 100644 --- a/99.build.sh +++ b/99.build.sh @@ -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" \ diff --git a/CLAUDE.md b/CLAUDE.md new file mode 100644 index 0000000..9ed7cce --- /dev/null +++ b/CLAUDE.md @@ -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/.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 diff --git a/doc/ChangeLog.txt b/doc/ChangeLog.txt index ca8f65f..340e21d 100644 --- a/doc/ChangeLog.txt +++ b/doc/ChangeLog.txt @@ -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. @@ -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 \ No newline at end of file +- report of a very long street names has moved to a Polish country pack diff --git a/meta/meta-begin.js b/meta/meta-begin.js index 8451e92..615124b 100644 --- a/meta/meta-begin.js +++ b/meta/meta-begin.js @@ -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* @@ -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 // @copyright 2013-2018 Andriy Berestovskyy // @license GPLv3 @@ -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, @@ -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 () { \ No newline at end of file +(function () { diff --git a/src/login.js b/src/login.js index 5756a87..0ecba44 100644 --- a/src/login.js +++ b/src/login.js @@ -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)) @@ -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)) diff --git a/src/release.js b/src/release.js index 05d4428..8178750 100644 --- a/src/release.js +++ b/src/release.js @@ -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 */ diff --git a/src/report.js b/src/report.js index ba01ca4..6064287 100644 --- a/src/report.js +++ b/src/report.js @@ -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) ; @@ -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) ; diff --git a/src/validate.js b/src/validate.js index cb8718d..d3bcb3f 100644 --- a/src/validate.js +++ b/src/validate.js @@ -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];