fix(overlays): role preservation + guarded attr storage
This commit is contained in:
parent
5b9f039457
commit
c3f7aa8ea2
2 changed files with 38 additions and 9 deletions
|
|
@ -67,8 +67,7 @@ const supportsCSSTypedObject = window.CSS && CSS.number;
|
|||
* Note that a contentWrapperNode should be provided for [l2], [l3] and [l4]
|
||||
* In case of a global overlay ([g1]), it's enough to provide just the contentNode.
|
||||
* In case of a local overlay or a responsive overlay switching from placementMode, one should
|
||||
* always configure as if it was a local overlay.
|
||||
*
|
||||
* always configure as if it were a local overlay.
|
||||
*/
|
||||
|
||||
export class OverlayController {
|
||||
|
|
@ -358,11 +357,14 @@ export class OverlayController {
|
|||
__setupTeardownAccessibility({ phase }) {
|
||||
if (phase === 'init') {
|
||||
this.__storeOriginalAttrs(this.contentNode, ['role', 'id']);
|
||||
this.__storeOriginalAttrs(this.invokerNode, [
|
||||
'aria-expanded',
|
||||
'aria-labelledby',
|
||||
'aria-describedby',
|
||||
]);
|
||||
|
||||
if (this.invokerNode) {
|
||||
this.__storeOriginalAttrs(this.invokerNode, [
|
||||
'aria-expanded',
|
||||
'aria-labelledby',
|
||||
'aria-describedby',
|
||||
]);
|
||||
}
|
||||
|
||||
if (!this.contentNode.id) {
|
||||
this.contentNode.setAttribute('id', this._contentId);
|
||||
|
|
@ -379,7 +381,7 @@ export class OverlayController {
|
|||
if (this.invokerNode) {
|
||||
this.invokerNode.setAttribute('aria-expanded', this.isShown);
|
||||
}
|
||||
if (!this.contentNode.role) {
|
||||
if (!this.contentNode.getAttribute('role')) {
|
||||
this.contentNode.setAttribute('role', 'dialog');
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ describe('OverlayController', () => {
|
|||
}
|
||||
if (mode === 'inline') {
|
||||
contentNode = await fixture(html`
|
||||
<div style="z-index: ${zIndexVal} ;">
|
||||
<div style="z-index: xxxxxxxxxxxx ;">
|
||||
I should be on top
|
||||
</div>
|
||||
`);
|
||||
|
|
@ -1113,6 +1113,33 @@ describe('OverlayController', () => {
|
|||
expect(ctrl.contentNode.getAttribute('role')).to.equal('dialog');
|
||||
});
|
||||
|
||||
it('preserves [role] on content when present', async () => {
|
||||
const invokerNode = await fixture('<div role="button">invoker</div>');
|
||||
const contentNode = await fixture('<div role="menu">invoker</div>');
|
||||
const ctrl = new OverlayController({
|
||||
...withLocalTestConfig(),
|
||||
handlesAccessibility: true,
|
||||
invokerNode,
|
||||
contentNode,
|
||||
});
|
||||
expect(ctrl.contentNode.getAttribute('role')).to.equal('menu');
|
||||
});
|
||||
|
||||
it('allows to not provide an invokerNode', async () => {
|
||||
let properlyInstantiated = false;
|
||||
try {
|
||||
new OverlayController({
|
||||
...withLocalTestConfig(),
|
||||
handlesAccessibility: true,
|
||||
invokerNode: null,
|
||||
});
|
||||
properlyInstantiated = true;
|
||||
} catch (e) {
|
||||
throw new Error(e);
|
||||
}
|
||||
expect(properlyInstantiated).to.be.true;
|
||||
});
|
||||
|
||||
it('adds attributes inert and aria-hidden="true" on all siblings of rootNode if an overlay is shown', async () => {
|
||||
const ctrl = new OverlayController({
|
||||
...withGlobalTestConfig(),
|
||||
|
|
|
|||
Loading…
Reference in a new issue