diff --git a/change/office-ui-fabric-react-2019-08-19-17-03-13-sohuts-use-getdocument-in-focuszone.json b/change/office-ui-fabric-react-2019-08-19-17-03-13-sohuts-use-getdocument-in-focuszone.json new file mode 100644 index 0000000000000..12692faf88042 --- /dev/null +++ b/change/office-ui-fabric-react-2019-08-19-17-03-13-sohuts-use-getdocument-in-focuszone.json @@ -0,0 +1,8 @@ +{ + "type": "patch", + "comment": "Use getDocument instead document in FocusZone and FocusTrapZone", + "packageName": "office-ui-fabric-react", + "email": "sohuts@microsoft.com", + "commit": "c4766bf28c3c6fe6021e2a0f277524bcc64064b4", + "date": "2019-08-19T15:03:13.879Z" +} diff --git a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx index 4c553eba905f3..455eb07f64e36 100644 --- a/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusTrapZone/FocusTrapZone.tsx @@ -6,6 +6,7 @@ import { getFirstTabbable, getLastTabbable, getNextElement, + getDocument, focusAsync, initializeComponentRef, on @@ -67,7 +68,7 @@ export class FocusTrapZone extends React.Component impl if ( !this.props.disabled || this.props.forceFocusInsideTrap || - !elementContains(this._root.current, document.activeElement as HTMLElement) + !elementContains(this._root.current, this._getDocument().activeElement as HTMLElement) ) { this._returnFocusToInitiator(); } @@ -162,7 +163,7 @@ export class FocusTrapZone extends React.Component impl // even when it's not. Using document.activeElement is another way // for us to be able to get what the relatedTarget without relying // on the event - relatedTarget = document.activeElement as Element; + relatedTarget = this._getDocument().activeElement as Element; } if (!elementContains(this._root.current, relatedTarget as HTMLElement)) { @@ -213,7 +214,7 @@ export class FocusTrapZone extends React.Component impl this._previouslyFocusedElementOutsideTrapZone = elementToFocusOnDismiss ? elementToFocusOnDismiss - : (document.activeElement as HTMLElement); + : (this._getDocument().activeElement as HTMLElement); if (!disableFirstFocus && !elementContains(this._root.current, this._previouslyFocusedElementOutsideTrapZone)) { this.focus(); } @@ -226,12 +227,13 @@ export class FocusTrapZone extends React.Component impl return this !== value; }); - const activeElement = document.activeElement as HTMLElement; + const doc = this._getDocument(); + const activeElement = doc.activeElement as HTMLElement; if ( !ignoreExternalFocusing && this._previouslyFocusedElementOutsideTrapZone && typeof this._previouslyFocusedElementOutsideTrapZone.focus === 'function' && - (elementContains(this._root.current, activeElement) || activeElement === document.body) + (elementContains(this._root.current, activeElement) || activeElement === doc.body) ) { this._focusAsync(this._previouslyFocusedElementOutsideTrapZone); } @@ -277,7 +279,7 @@ export class FocusTrapZone extends React.Component impl } if (FocusTrapZone._focusStack.length && this === FocusTrapZone._focusStack[FocusTrapZone._focusStack.length - 1]) { - const focusedElement = document.activeElement as HTMLElement; + const focusedElement = this._getDocument().activeElement as HTMLElement; if (!elementContains(this._root.current, focusedElement)) { this.focus(); @@ -304,4 +306,8 @@ export class FocusTrapZone extends React.Component impl } } }; + + private _getDocument(): Document { + return getDocument(this._root.current)!; + } } diff --git a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx index c2099689c9e4a..c507303b816b7 100644 --- a/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx +++ b/packages/office-ui-fabric-react/src/components/FocusZone/FocusZone.tsx @@ -139,7 +139,7 @@ export class FocusZone extends React.Component implements IFocu let parentElement = getParent(root, ALLOW_VIRTUAL_ELEMENTS); - while (parentElement && parentElement !== document.body && parentElement.nodeType === 1) { + while (parentElement && parentElement !== this._getDocument().body && parentElement.nodeType === 1) { if (isElementFocusZone(parentElement)) { this._isInnerZone = true; break; @@ -160,7 +160,7 @@ export class FocusZone extends React.Component implements IFocu this._updateTabIndexes(); if (this.props.defaultActiveElement) { - this._activeElement = getDocument()!.querySelector(this.props.defaultActiveElement) as HTMLElement; + this._activeElement = this._getDocument().querySelector(this.props.defaultActiveElement) as HTMLElement; this.focus(); } } @@ -168,7 +168,7 @@ export class FocusZone extends React.Component implements IFocu public componentDidUpdate(): void { const { current: root } = this._root; - const doc = getDocument(root); + const doc = this._getDocument(); if (doc && this._lastIndexPath && (doc.activeElement === doc.body || doc.activeElement === root)) { // The element has been removed after the render, attempt to restore focus. @@ -309,16 +309,15 @@ export class FocusZone extends React.Component implements IFocu private _evaluateFocusBeforeRender(): void { const { current: root } = this._root; - const doc = getDocument(root); + const doc = this._getDocument(); if (doc) { const focusedElement = doc.activeElement as HTMLElement; // Only update the index path if we are not parked on the root. if (focusedElement !== root) { const shouldRestoreFocus = elementContains(root, focusedElement, false); - - this._lastIndexPath = shouldRestoreFocus ? getElementIndexPath(root as HTMLElement, doc.activeElement as HTMLElement) : undefined; + this._lastIndexPath = shouldRestoreFocus ? getElementIndexPath(root as HTMLElement, focusedElement) : undefined; } } } @@ -500,7 +499,7 @@ export class FocusZone extends React.Component implements IFocu return; } - if (document.activeElement === this._root.current && this._isInnerZone) { + if (this._getDocument().activeElement === this._root.current && this._isInnerZone) { // If this element has focus, it is being controlled by a parent. // Ignore the keystroke. return; @@ -948,7 +947,7 @@ export class FocusZone extends React.Component implements IFocu private _getOwnerZone(element?: HTMLElement): HTMLElement | null { let parentElement = getParent(element as HTMLElement, ALLOW_VIRTUAL_ELEMENTS); - while (parentElement && parentElement !== this._root.current && parentElement !== document.body) { + while (parentElement && parentElement !== this._root.current && parentElement !== this._getDocument().body) { if (isElementFocusZone(parentElement)) { return parentElement; } @@ -1060,4 +1059,8 @@ export class FocusZone extends React.Component implements IFocu private _portalContainsElement(element: HTMLElement): boolean { return element && !!this._root.current && portalContainsElement(element, this._root.current); } + + private _getDocument(): Document { + return getDocument(this._root.current)!; + } }