Skip to content

Move GeoJson page data from an inline script to a data attribute - #932

Merged
JeroenDeDauw merged 3 commits into
masterfrom
fix/geojson-page-inline-script-escaping
Jul 31, 2026
Merged

Move GeoJson page data from an inline script to a data attribute#932
JeroenDeDauw merged 3 commits into
masterfrom
fix/geojson-page-inline-script-escaping

Conversation

@JeroenDeDauw

@JeroenDeDauw JeroenDeDauw commented Jul 31, 2026

Copy link
Copy Markdown
Member

Not a bug fix. The inline script does not corrupt values: GeoJsonContent::formatJson() goes through FormatJson::encode() without XMLMETA_OK, so <, > and & are already hex-escaped before Html::element() sees them. What this buys is one less inline script, one less global, and the same data-mw-maps-* attribute the other maps use.

The window.GeoJson fallback is only for pages still served from the parser cache with the old markup, and can go once those turn over.

AI-authored — Claude Code, Opus (max); follow-up ask from @JeroenDeDauw, whose premise (that the inline script corrupted values) the investigation disproved, so this was rescoped from bug fix to cleanup; diff not yet human-reviewed; PHPUnit, phpcs, PHPStan and QUnit run locally, the fallback mutation-checked, and all three render paths loaded in a browser on a real GeoJson page.

Production notes

Spec and review by Fable 5 (max), implementation by an Opus (max) subagent. It stopped short of opening this PR because the reported bug did not exist; the branch is offered as optional cleanup rather than as the fix that was asked for. The one real instance of the escaping mechanism is U+0338 COMBINING LONG SOLIDUS OVERLAY, which Sanitizer::escapeCombiningChar() rewrites to &#x338; and a raw-text <script> then passes through verbatim.

The page JSON now travels in data-mw-maps-geojson on the map element, matching
data-mw-maps-mapdata used by every other Maps map, instead of a var GeoJson
inline script. Html::element applies Sanitizer::escapeCombiningChar to the
script body, and a <script> is a raw-text element, so a U+0338 in a value
reached the map as the literal text &#x338;. Attribute values are decoded by
the HTML parser, so nothing is lost.

Pages already in the parser cache carry the inline script and no attribute, so
the reader falls back to window.GeoJson.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JeroenDeDauw
JeroenDeDauw marked this pull request as ready for review July 31, 2026 12:50
JeroenDeDauw and others added 2 commits July 31, 2026 15:19
The wikipage.content handler body moves into maps.geoJsonPage.initializePage,
leaving the hook wiring as one line. The early return for content without a
GeoJson map had no coverage that counts toward a failed run: CI's karma QUnit
environment never fires wikipage.content, and in the browser runner an uncaught
async rethrow from the handler is reported but not counted. Calling
initializePage directly makes guard removal a synchronous, attributed test
failure.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The data attribute must win over window.GeoJson when both are present; with
the sources swapped, every existing test stayed green. The ampersand test set
the attribute via .attr(), which exercises no entity decoding and could not
fail independently of the plain read test. Its replacement parses the markup
shape GeoJsonMapPageUi emits (quotes and newlines entity-encoded, U+0338 as
a character reference), which also pins the attribute name across the PHP/JS
boundary: a consistent rename in reader and test helper previously passed the
suite.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@JeroenDeDauw
JeroenDeDauw merged commit d4eed85 into master Jul 31, 2026
8 checks passed
@JeroenDeDauw
JeroenDeDauw deleted the fix/geojson-page-inline-script-escaping branch July 31, 2026 13:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant