Skip to content

XWIKI-22154: "aria-labelledby" for navigation panel entries and corresponding ids contain illegal whitespaces - #6205

Open
Sereza5 wants to merge 2 commits into
xwiki:masterfrom
Sereza5:XWIKI-22154
Open

XWIKI-22154: "aria-labelledby" for navigation panel entries and corresponding ids contain illegal whitespaces#6205
Sereza5 wants to merge 2 commits into
xwiki:masterfrom
Sereza5:XWIKI-22154

Conversation

@Sereza5

@Sereza5 Sereza5 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Jira URL

https://jira.xwiki.org/browse/XWIKI-22154

Changes

Description

  • Escape jsTree node ids (percent-encode spaces/%) before handing them to jsTree, and unescape them back before sending them to the server, so that the rendered id/anchor id/aria-activedescendant attributes never contain literal whitespace.
  • Expose $.fn.xtree.unescapeNodeId() and $.fn.xtree.escapeNodeId() so other scripts can convert between the tree's escaped node id and the raw entity reference.
  • Update every other script that reads a raw node id off the tree's public API (get_selected(), data.node.id) and resolves it into an entity reference, to unescape it first: the location picker (page rename/move), the attachment move dialog, the WYSIWYG entity resource picker, and the extension/class "breaking pages" delete-confirmation dialogs.

Clarifications

  • This is XWIKI-18356 reopened: that original fix (XWIKI-18356: "aria-labelledby" for navigation panel entries and corresponding ids contain illegal whitespaces #3015) only escaped/unescaped the id in getChildren, which missed the "move to a new parent" case and broke XWIKI-22151 (moving a page into a space with a space in its name created a literal A%20B space). It was reverted.
  • This time the escape/unescape is centralized in tree.js for every id the tree itself sends to or receives from the server (children, path, the acted-on node and the move/copy destination parent), and every other consumer that independently parses a tree node id back into an entity reference has been updated to unescape it first, so the same class of regression shouldn't resurface.
  • I found the other consumers by searching for scripts calling get_selected()/reading data.node.id and checking whether they parse the id into an entity reference (risky) or just use it as an opaque token / literal comparison (safe, left untouched — e.g. exporter.js and the data.id field already carry the bare, unprefixed, unescaped reference and are unaffected).

Compatibility note: the jsTree node id (type:reference) is not a documented/@Unstable-tagged API and isn't covered by Revapi (it's JS-only), but it is de facto relied on: this PR itself had to update 6 in-repo scripts that parse it as an entity reference. Any xwiki-contrib extension or wiki-page script doing the same thing (reading get_selected()/data.node.id and parsing it) would need the same one-line fix, now available as $.fn.xtree.unescapeNodeId(). I couldn't find a way to avoid this: jsTree hard-codes the rendered id attribute to the node's model id and resolves clicks back to a model node by reading that same DOM attribute, so a valid (whitespace-free) HTML id and a raw, unescaped model id are mutually exclusive with jsTree's current internals — I verified this by prototyping the DOM-only alternative and it broke click-to-select. The original XWIKI-18356 PR (#3015) took the same position on this id not being a sanctioned front-end API; happy to raise it on the dev list instead if reviewers disagree.

Screenshots & Video

No visible UI change; the fix only affects the id/aria-activedescendant attribute values (now percent-escaped instead of containing raw whitespace) and internal id plumbing.

Executed Tests

  • mvn clean install -B -ntp -Plegacy -pl xwiki-platform-core/xwiki-platform-tree/xwiki-platform-tree-webjar,xwiki-platform-core/xwiki-platform-attachment/xwiki-platform-attachment-api,xwiki-platform-core/xwiki-platform-wysiwyg/xwiki-platform-wysiwyg-webjar — builds clean, jshint/Checkstyle/Revapi pass.
  • mvn clean install -B -ntp -Plegacy -pl xwiki-platform-core/xwiki-platform-web/xwiki-platform-web-war — builds clean, jshint/Checkstyle/Revapi pass.
  • Manually verified on a local 18.7.0-SNAPSHOT instance (hot-swapped jars/resources):
    • The navigation tree's rendered id, anchor id and aria-activedescendant for a page/space with a space in the name are all percent-escaped, no literal whitespace.
    • Moved a page into a space literally named A B via the rename/move tree picker: the destination breadcrumb correctly shows "A B" and the page actually lands in the A B space (verified via REST), not in a corrupted A%20B space — i.e. the XWIKI-22151 regression does not reproduce.

Expected merging strategy

  • Prefers squash: Yes
  • Backport on branches:
    • No backport. This changes how jsTree node ids are represented across several UI flows (navigation tree, rename/move, attachment move, WYSIWYG link/image picker, extension/class delete confirmation), so it should soak on master first.

@Sereza5

Sereza5 commented Aug 20, 2026

Copy link
Copy Markdown
Contributor Author

Will keep this PR as a draft until the discussion at https://forum.xwiki.org/t/escaping-jstree-node-ids/18767 is solved :)

@vmassol

vmassol commented Aug 23, 2026

Copy link
Copy Markdown
Member

@Sereza5 FYI, I have posted a comment (CC did most of the work) at https://forum.xwiki.org/t/escaping-jstree-node-ids/18767/3 Please check if it makes sense.Thx.

@Sereza5
Sereza5 force-pushed the XWIKI-22154 branch 2 times, most recently from 9329ff5 to 3cb9f56 Compare August 26, 2026 15:19
@Sereza5

Sereza5 commented Aug 26, 2026

Copy link
Copy Markdown
Contributor Author

Reworked in 3cb9f56 following the forum analysis: node ids are now escaped on the way in (server responses, data-json, openTo()) and unescaped only on the way out (ids sent to the server, tree field value). This fixes the open_node/select_node/get_node/hide_node/set_text calls that build a raw id, the data-json case, and getPath()/openTo() wrongly unescaping caller-supplied ids. Existing raw-id inputs keep working, so the break is limited to reading an id out of jsTree and parsing it as a reference. Rebased on master, so @since is now 18.8.0RC1.

Two functional tests added: one asserting the tree renders no whitespace in id/aria-activedescendant/aria-labelledby for a page under a space named A B, and one moving a page into a space named Rename Space through the tree picker (the XWIKI-22151 regression).

I ran a xwiki-review on this PR and fixed the medium priority items that were reported.

@Sereza5
Sereza5 marked this pull request as ready for review August 26, 2026 15:37
…sponding ids contain illegal whitespaces

* Escaped jsTree node ids when received from the server and unescaped them when sent back
* Added $.fn.xtree.unescapeNodeId() and $.fn.xtree.escapeNodeId() helpers
* Unescaped the selected node id in the location picker
* Unescaped the selected node id when moving an attachment
* Unescaped and escaped node ids in the WYSIWYG entity resource picker
* Unescaped node ids collected in the extension and class breaking question dialogs
…sponding ids contain illegal whitespaces

* Escaped the node ids on the way into the tree and unescaped them only on the way out
* Percent-encoded the node ids, keeping the colon and the at sign as is
* Escaped the node ids passed to openTo() and the ones specified inline through data-json
* Unescaped the selected node ids written into the tree field value
* Escaped the node ids built by the export tree, the navigation panel configuration, the in-place editor and the annotation configuration
* Unescaped the selected node ids in the template provider picker and the WYSIWYG image selector
* Escaped and unescaped the node ids in the tree page objects
* Added a functional test for the escaping of the node ids
* Added a functional test for moving a page to a parent whose name contains white space
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.

2 participants