# all files / lib/utilities/ focus.js

87.04% Statements 47/54
85.25% Branches 52/61
71.43% Functions 5/7
87.04% Lines 47/54

    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
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99

    1×
    1×
    1×
    1×

    1×
    1×

    1×

    1×
    51×

    20×

    31×

    31×
    14×
    14×

    31×
    14×

    17×
    17×
    14×

    3×
    3×

    1×

    1×
    46×

    19×

    27×

    27×
    12×

    15×
    13×
    13×

    15×

    15×
    15×
    12×

    3×
    3×

    1×
    1×
    58×

    1×
    1×
    26×

    1×
    1×
    37×

    1×

     /* tslint:disable:no-string-literal */
    "use strict";
    var IS_FOCUSABLE_ATTRIBUTE = 'data-is-focusable';
    var IS_VISIBLE_ATTRIBUTE = 'data-is-visible';
    var FOCUSZONE_ID_ATTRIBUTE = 'data-focuszone-id';
    function getFirstFocusable(rootElement, currentElement, includeElementsInFocusZones) {
        return getNextElement(rootElement, currentElement, true, false, false, includeElementsInFocusZones);
    }
    exports.getFirstFocusable = getFirstFocusable;
    function getLastFocusable(rootElement, currentElement, includeElementsInFocusZones) {
        return getPreviousElement(rootElement, currentElement, true, false, true, includeElementsInFocusZones);
    }
    exports.getLastFocusable = getLastFocusable;
    /** Traverse to find the previous element. */
    function getPreviousElement(rootElement, currentElement, checkNode, suppressParentTraversal, traverseChildren, includeElementsInFocusZones) {
        if (!currentElement ||
            currentElement === rootElement) {
            return null;
        }
        var isCurrentElementVisible = isElementVisible(currentElement);
        // Check its children.
        if (traverseChildren && (includeElementsInFocusZones || !isElementFocusZone(currentElement)) && isCurrentElementVisible) {
            var childMatch = getPreviousElement(rootElement, currentElement.lastElementChild, true, true, true, includeElementsInFocusZones);
            Iif (childMatch) {
                return childMatch;
            }
        }
        // Check the current node, if it's not the first traversal.
        if (checkNode && isCurrentElementVisible && isElementTabbable(currentElement)) {
            return currentElement;
        }
        // Check its previous sibling.
        var siblingMatch = getPreviousElement(rootElement, currentElement.previousElementSibling, true, true, true, includeElementsInFocusZones);
        if (siblingMatch) {
            return siblingMatch;
        }
        // Check its parent.
        Eif (!suppressParentTraversal) {
            return getPreviousElement(rootElement, currentElement.parentElement, true, false, false, includeElementsInFocusZones);
        }
        return null;
    }
    exports.getPreviousElement = getPreviousElement;
    /** Traverse to find the next focusable element. */
    function getNextElement(rootElement, currentElement, checkNode, suppressParentTraversal, suppressChildTraversal, includeElementsInFocusZones) {
        if (!currentElement ||
            (currentElement === rootElement && suppressChildTraversal)) {
            return null;
        }
        var isCurrentElementVisible = isElementVisible(currentElement);
        // Check the current node, if it's not the first traversal.
        if (checkNode && isCurrentElementVisible && isElementTabbable(currentElement)) {
            return currentElement;
        }
        // Check its children.
        if (!suppressChildTraversal && isCurrentElementVisible && (includeElementsInFocusZones || !isElementFocusZone(currentElement))) {
            var childMatch = getNextElement(rootElement, currentElement.firstElementChild, true, true, false, includeElementsInFocusZones);
            Iif (childMatch) {
                return childMatch;
            }
        }
        Iif (currentElement === rootElement) {
            return null;
        }
        // Check its sibling.
        var siblingMatch = getNextElement(rootElement, currentElement.nextElementSibling, true, true, false, includeElementsInFocusZones);
        if (siblingMatch) {
            return siblingMatch;
        }
        Eif (!suppressParentTraversal) {
            return getNextElement(rootElement, currentElement.parentElement, false, false, true, includeElementsInFocusZones);
        }
        return null;
    }
    exports.getNextElement = getNextElement;
    function isElementVisible(element) {
        return (!!element &&
            (element.offsetHeight !== 0 ||
                element.offsetParent !== null ||
                element.isVisible === true ||
                (element.getAttribute && element.getAttribute(IS_VISIBLE_ATTRIBUTE) === 'true')));
    }
    exports.isElementVisible = isElementVisible;
    function isElementTabbable(element) {
        return (!!element &&
            (element.tagName === 'A' ||
                (element.tagName === 'BUTTON' && !element.disabled) ||
                (element.tagName === 'INPUT' && !element.disabled) ||
                (element.getAttribute && element.getAttribute(IS_FOCUSABLE_ATTRIBUTE) === 'true')));
    }
    exports.isElementTabbable = isElementTabbable;
    function isElementFocusZone(element) {
        return element && !!element.getAttribute(FOCUSZONE_ID_ATTRIBUTE);
    }
    exports.isElementFocusZone = isElementFocusZone;

    //# sourceMappingURL=focus.js.map