mirror of
https://github.com/angular/angular.git
synced 2026-09-14 13:54:52 +08:00
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
This commit is contained in:
committed by
Jeremy Elbourn
parent
2c192d0a57
commit
6f7332b748
@@ -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);
|
||||
|
||||
|
||||
@@ -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) {
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user