Skip to content

Commit 6f7332b

Browse files
devversionjelbourn
authored andcommitted
fix(interactivity-checker): carefully handle frame elements (#9340)
* Browsers like MS Edge throw errors if the frameElement property is being accessed from a different host address. This means that the `frameElement` property should be accessed carefully. Fixes #3372
1 parent 2c192d0 commit 6f7332b

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

src/cdk/a11y/interactivity-checker.spec.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -337,6 +337,22 @@ describe('InteractivityChecker', () => {
337337
expect(checker.isTabbable(button)).toBe(true);
338338
});
339339

340+
it('should carefully try to access the frame element of an elements window', () => {
341+
const iframe = createFromTemplate('<iframe>', true) as HTMLFrameElement;
342+
const button = createFromTemplate('<button tabindex="1">Not Tabbable</button>');
343+
344+
appendElements([iframe]);
345+
346+
iframe.setAttribute('tabindex', '-1');
347+
iframe.contentDocument.body.appendChild(button);
348+
349+
Object.defineProperty(iframe.contentWindow, 'frameElement', {
350+
get: () => { throw 'Access Denied!'; }
351+
});
352+
353+
expect(() => checker.isTabbable(button)).not.toThrow();
354+
});
355+
340356
it('should mark elements which are contentEditable as tabbable', () => {
341357
let editableEl = createFromTemplate('<div contenteditable="true">', true);
342358

src/cdk/a11y/interactivity-checker.ts

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,10 @@ export class InteractivityChecker {
6060
return false;
6161
}
6262

63-
let frameElement = getWindow(element).frameElement as HTMLElement;
63+
const frameElement = getFrameElement(getWindow(element));
6464

6565
if (frameElement) {
66-
67-
let frameType = frameElement && frameElement.nodeName.toLowerCase();
66+
const frameType = frameElement && frameElement.nodeName.toLowerCase();
6867

6968
// Frame elements inherit their tabindex onto all child elements.
7069
if (getTabIndexValue(frameElement) === -1) {
@@ -143,6 +142,19 @@ export class InteractivityChecker {
143142

144143
}
145144

145+
/**
146+
* Returns the frame element from a window object. Since browsers like MS Edge throw errors if
147+
* the frameElement property is being accessed from a different host address, this property
148+
* should be accessed carefully.
149+
*/
150+
function getFrameElement(window: Window) {
151+
try {
152+
return window.frameElement as HTMLElement;
153+
} catch (e) {
154+
return null;
155+
}
156+
}
157+
146158
/** Checks whether the specified element has any geometry / rectangles. */
147159
function hasGeometry(element: HTMLElement): boolean {
148160
// Use logic from jQuery to check for an invisible element.

0 commit comments

Comments
 (0)