Skip to content

Commit

Permalink
fix(interactivity-checker): carefully handle frame elements (#9340)
Browse files Browse the repository at this point in the history
* 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
  • Loading branch information
devversion authored and jelbourn committed Jan 23, 2018
1 parent 2c192d0 commit 6f7332b
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 3 deletions.
16 changes: 16 additions & 0 deletions src/cdk/a11y/interactivity-checker.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -337,6 +337,22 @@ describe('InteractivityChecker', () => {
expect(checker.isTabbable(button)).toBe(true);
});

it('should carefully try to access the frame element of an elements window', () => {
const iframe = createFromTemplate('<iframe>', true) as HTMLFrameElement;
const button = createFromTemplate('<button tabindex="1">Not Tabbable</button>');

appendElements([iframe]);

iframe.setAttribute('tabindex', '-1');
iframe.contentDocument.body.appendChild(button);

Object.defineProperty(iframe.contentWindow, 'frameElement', {
get: () => { throw 'Access Denied!'; }
});

expect(() => checker.isTabbable(button)).not.toThrow();
});

it('should mark elements which are contentEditable as tabbable', () => {
let editableEl = createFromTemplate('<div contenteditable="true">', true);

Expand Down
18 changes: 15 additions & 3 deletions src/cdk/a11y/interactivity-checker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,10 @@ export class InteractivityChecker {
return false;
}

let frameElement = getWindow(element).frameElement as HTMLElement;
const frameElement = getFrameElement(getWindow(element));

if (frameElement) {

let frameType = frameElement && frameElement.nodeName.toLowerCase();
const frameType = frameElement && frameElement.nodeName.toLowerCase();

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

}

/**
* Returns the frame element from a window object. Since browsers like MS Edge throw errors if
* the frameElement property is being accessed from a different host address, this property
* should be accessed carefully.
*/
function getFrameElement(window: Window) {
try {
return window.frameElement as HTMLElement;
} catch (e) {
return null;
}
}

/** Checks whether the specified element has any geometry / rectangles. */
function hasGeometry(element: HTMLElement): boolean {
// Use logic from jQuery to check for an invisible element.
Expand Down

0 comments on commit 6f7332b

Please sign in to comment.