<commit_before>/* global ux, utils */
angular.module('ux').directive('focusGroup', function (focusManager, focusQuery, focusDispatcher) {

    var groupId = 1,
        elementId = 1,
        dispatcher = focusDispatcher(),
        delay = 100;

    function compile(groupName, el) {
        var els, i, len, elementName;

        els = focusQuery.getElementsWithoutParents(el);
        len = els.length;
        i = 0;
        while (i < len) {
            elementName = 'element-' + elementId;
            focusQuery.setParentId(els[i], groupName);
            focusQuery.setElementId(els[i], elementName);
            focusQuery.setTabIndex(els[i], -1); // elements in focus manager should not be tab enabled through browser
            elementId += 1;
            i += 1;
        }

        els = focusQuery.getGroupsWithoutContainers(el);
        len = els.length;

        i = 0;
        while (i < len) {
            focusQuery.setContainerId(els[i], groupName);
            i += 1;
        }

        return groupName;
    }

    function linker(scope, element, attr) {

        var el = element[0];
        var groupName = 'group-' + (groupId++);
        var bound = false;
        var cacheHtml = '';
        var cacheCount = 0;
        var newCacheHtml = '';
        var newCacheCount = 0;

        function init() {
            scope.$on('focus::' + groupName, function(){
                compile(groupName, el);
            });

            if (!focusQuery.getContainerId(el)) { // this is an isolate focus group

                cacheHtml = el.innerHTML;
                cacheCount = cacheHtml.match(/<\w+/g).length;

                scope.$watch(utils.debounce(function () {
                    newCacheHtml = el.innerHTML;
                    if (cacheHtml !== newCacheHtml) {
                        newCacheCount = newCacheHtml.match(/<\w+/g).length;
                        if (cacheCount !== newCacheCount) {
                            var els = el.querySelectorAll('[focus-group]');
                            var i = els.length, groupId;
                            while (i) {
                                i -= 1;
                                groupId = els[i].getAttribute('focus-group-id');
                                scope.$broadcast('focus::' + groupId);
                            }
                        }
                        cacheHtml = newCacheHtml;
                        cacheCount = newCacheCount;
                    }
                }, delay));

                dispatcher.on('focusin', utils.debounce(function (evt) {
                    // if group contains target then bind keys
                    if (focusQuery.contains(el, evt.newTarget)) {
                        if (bound === false) {
                            bound = true;
                            scope.$broadcast('bindKeys', groupName);
                        }
                    } else {
                        if (bound === true) {
                            bound = false;
                            scope.$broadcast('unbindKeys');
                        }
                    }
                }, delay));

                focusManager.callback = function (el) {
                    focusQuery.setTabIndex(el, null);
                };
                focusManager.findPrevChildGroup(groupName);
                focusManager.findNextElement(groupName);

                focusManager.callback = null;
            }
        }

        function onFocus() {
            focusManager.enable();
        }

        el.addEventListener('focus', onFocus, true);<commit_msg>group support for allowing non-FM items to be part of the focus navigation. Better mix between FM and Browser focus management<commit_after>/* global ux, utils */
angular.module('ux').directive('focusGroup', function (focusManager, focusQuery, focusDispatcher) {

    var groupId = 1,
        elementId = 1,
        dispatcher = focusDispatcher(),
        delay = 100;

    function compile(groupName, el) {
        var els, i, len, elementName;

        els = focusQuery.getElementsWithoutParents(el);
        len = els.length;
        i = 0;
        while (i < len) {
            elementName = 'element-' + elementId;
            focusQuery.setParentId(els[i], groupName);
            focusQuery.setElementId(els[i], elementName);

            var tabIndex = focusQuery.getTabIndex(els[i]);
            if (tabIndex === undefined || tabIndex === null) {
                focusQuery.setTabIndex(els[i], -1); // elements in focus manager should not be tab enabled through browser
            }

            elementId += 1;
            i += 1;
        }

        els = focusQuery.getGroupsWithoutContainers(el);
        len = els.length;

        i = 0;
        while (i < len) {
            focusQuery.setContainerId(els[i], groupName);
            i += 1;
        }
    }

    function linker(scope, element, attr) {

        var el = element[0];
        var groupName = 'group-' + (groupId++);
        var bound = false;
        var cacheHtml = '';
        var cacheCount = 0;
        var newCacheHtml = '';
        var newCacheCount = 0;

        function init() {
            scope.$on('focus::' + groupName, function () {
                compile(groupName, el);
                createBrowserEntryPoints();
            });

            if (!focusQuery.getContainerId(el)) { // this is an isolate focus group

                cacheHtml = el.innerHTML;
                cacheCount = cacheHtml.match(/<\w+/g).length;

                scope.$watch(utils.debounce(function () {
                    newCacheHtml = el.innerHTML;
                    if (cacheHtml !== newCacheHtml) {
                        newCacheCount = newCacheHtml.match(/<\w+/g).length;
                        if (cacheCount !== newCacheCount) {
                            var els = el.querySelectorAll('[focus-group]');
                            var i = els.length, groupId;
                            while (i) {
                                i -= 1;
                                groupId = els[i].getAttribute('focus-group-id');
                                scope.$broadcast('focus::' + groupId);
                            }
                        }
                        cacheHtml = newCacheHtml;
                        cacheCount = newCacheCount;
                    }
                    compile(groupName, el);
                    createBrowserEntryPoints();
                }, delay));

                dispatcher.on('focusin', utils.debounce(function (evt) {
                    // if group contains target then bind keys
                    if (focusQuery.contains(el, evt.newTarget)) {
                        if (bound === false) {
                            bound = true;
                            scope.$broadcast('bindKeys', groupName);
                        }
                    } else {
                        if (bound === true) {
                            bound = false;
                            scope.$broadcast('unbindKeys');
                        }
                    }
                }, delay));
            }
        }

        function createBrowserEntryPoints() {
            focusManager.callback = function (el) {
                focusQuery.setTabIndex(el, 0);
            };
            focusManager.findPrevChildGroup(groupName);
            focusManager.findNextElement(groupName);

            focusManager.callback = null;
        }

        function onFocus() {
            focusManager.enable();
        }

        el.addEventListener('focus', onFocus, true);
{'fraction_non_alphanumeric': 0.10612244897959183, 'fraction_numerical': 0.004081632653061225, 'mean_word_length': 1.2453443689033403, 'pattern_counts': {'":': 0, '<': 11, '<?xml version=': 0, '>': 3, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 6, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1744641', 'n_tokens_mistral': 1920, 'n_tokens_neox': 1798, 'n_words': 413}