User tests: Successful: Unsuccessful:
Pull Request resolves #48152.
This PR was drafted with AI assistance (Claude). I reviewed, tested (see below), and am accountable for the change per the Generative AI policy.
layouts/libraries/html/bootstrap/modal/iframe.php sets both name and title on the rendered iframe markup, but Joomla.initialiseModal re-injects that markup through Joomla.sanitizeHtml on show.bs.modal using an allowlist that only permits src/name/width/height on <iframe>. The title attribute the PHP layout added for accessibility is stripped in transit, so the live iframe has no accessible name (axe-core: frame-title, WCAG 4.1.2, serious). Affects every consumer of bootstrap.renderModal with a URL, including all core modal-select fields.
build/media_source/vendor/bootstrap/js/modal.es6.js is the single source of this allowlist (verified no other copy exists in the tree). This PR adds 'title' to it:
const allowed = {
iframe: ['src', 'name', 'title', 'width', 'height'],
};Only the ES6 source is touched; media/vendor/bootstrap/js/modal.js is build output (gitignored) regenerated by the release build.
The safest, most direct way to verify this is to exercise the exact mechanism the bug and fix are about — Joomla.sanitizeHtml with the old vs. new allowlist — using Joomla's own live sanitizer (loaded from core.js on any Joomla page, admin or site):
const sampleIframe = '<iframe class="iframe" src="about:blank" name="Select an item" title="Select an item" height="400px" width="800px"></iframe>';
Joomla.sanitizeHtml(sampleIframe, { iframe: ['src', 'name', 'width', 'height'] }); // BEFORE allowlist
Joomla.sanitizeHtml(sampleIframe, { iframe: ['src', 'name', 'title', 'width', 'height'] }); // AFTER allowlistRun this in the browser console on any Joomla page (open DevTools, paste, compare the two outputs) — no UI reproduction needed since the allowlist is passed as a plain argument. See screenshot below for the actual output on a live 6.1.3 instance.
You can also exercise it end-to-end: render any Bootstrap modal with a URL (e.g. HTMLHelper::_('bootstrap.renderModal', 'x', ['title' => 'Select an item', 'url' => $url]), as every core modal-select field does), open it, and inspect the injected <iframe> for the title attribute.
Joomla.sanitizeHtml strips the title attribute from the iframe markup because the allowlist (['src', 'name', 'width', 'height']) omits it. The live iframe has name but no title, so axe-core flags frame-title (serious, WCAG 4.1.2) — a frame with no accessible name.
Joomla.sanitizeHtml preserves the title attribute, so the live iframe carries the same title the PHP layout rendered, giving it an accessible name.
Please select:
Documentation link for guide.joomla.org:
No documentation changes for guide.joomla.org needed
Pull Request link for manual.joomla.org:
No documentation changes for manual.joomla.org needed
🤖 Generated with Claude Code
| Status | New | ⇒ | Pending |
| Category | ⇒ | JavaScript Repository NPM Change |