Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 1321x 5173x 5173x 1321x 1321x 1x 1x 288x 288x 288x 288x 225x 225x 225x 288x 288x 191x 191x 288x 288x 1x 1x 535x 535x 438x 438x 535x 535x 1x 1x 823x 499x 499x 324x 324x 324x 823x 823x 1x | import {
ContentChildren,
Directive,
EventEmitter,
Output,
QueryList,
forwardRef,
} from '@angular/core';
import { FocusTargetDirective } from './focus-target.directive';
@Directive({
selector: '[data-gc-focus-scope]',
standalone: false,
})
export class FocusScopeDirective {
@Output()
public readonly onFocusLeft: EventEmitter<EventTarget | null> =
new EventEmitter<EventTarget | null>();
@Output()
public readonly onFocusEntered: EventEmitter<void> = new EventEmitter<void>();
// FocusTargetDirective gets the FocusScopeDirective injected in its constructor, hence
// Angular will order the declaration of the FocusTargetDirective after the declaration
// of the current class in the built library output. due to this, the FocusTargetDirective
// is not yet declared at the point when the code/metadata for this decorator is emitted
// and the class is missing => break this interdependency with a forwardRef, so the
// FocusTargetDirective can be used before its declared.
// note that the described error would be only visible at runtime when using the built library
// in another project!
@ContentChildren(forwardRef(() => FocusTargetDirective), {
descendants: true,
})
protected focusTargets!: QueryList<FocusTargetDirective>;
public get focusWithin(): boolean {
return this._focusWithin;
}
private _focusWithin = false;
public onTargetBlur(event: FocusEvent): void {
const newFocusedElement = event.relatedTarget;
if (
event.relatedTarget &&
(event.relatedTarget as HTMLElement).getAttribute(
'data-gc-refuse-focus',
) === 'true'
) {
// Workaround for https://gitlab.bestsolution.at/gefa/gefa-web-controls/-/issues/2670
const el = event.target as HTMLElement;
setTimeout(() => {
el.focus();
});
} else if (!this.isFocusWithin(newFocusedElement)) {
this._focusWithin = false;
this.onFocusLeft.emit(event.relatedTarget);
}
}
public onTargetFocus(event: FocusEvent): void {
const previousFocusedElement = event.relatedTarget;
if (!this.isFocusWithin(previousFocusedElement)) {
this._focusWithin = true;
this.onFocusEntered.emit();
}
}
private isFocusWithin(eventTarget: EventTarget | null): boolean {
if (eventTarget !== null) {
return this.focusTargets.some(target =>
target.isFocusTarget(eventTarget),
);
} else {
return false;
}
}
}
|