<commit_before>﻿document.appLauncher = (function (document, window) {

    console.log("app-launcher loaded.");

    function init(containerElement, apps) {

        var table = document.createElement("table");
        table.className = "app-launcher-apps";
        var tr = document.createElement("tr");
        table.appendChild(tr);

        var columns = 5; // todo option.

        apps.forEach(function(app, index) {

            if (index % columns === 0) {
                tr = document.createElement("tr");
                table.appendChild(tr);
            }

            var td = document.createElement("td");
            tr.appendChild(td);

            var a = document.createElement("a");
            a.href = app.href;
            a.title = app.name; // Added because of the ellipses.

            // todo: support images in the future.
            //var img = document.createElement("img");
            //img.src = "http://placehold.it/100x100";
            //a.appendChild(img);

            var div = document.createElement("div");
            var iconLetter = (app.name) ? app.name.substring(0, 1).toLowerCase() : "z";
            div.className = "app-launcher-icon-" + iconLetter
                + " app-launcher-icon-" + app.name.toLowerCase().replace(" ", "-").replace(/\W/g, "");
            var span = document.createElement("span");
            var iconText = document.createTextNode(iconLetter);
            span.appendChild(iconText);
            div.appendChild(span);
            a.appendChild(div);

            var linkText = document.createTextNode(app.name);
            a.appendChild(linkText);
            td.appendChild(a);

        });

        containerElement.appendChild(table);
    }

    
    /**
     * Use XHR to get the dom of the app list page.
     * @param {} callback 
     * @returns {} 
     */
    function getAppListDom(uri, callback) {
        var xhr = new XMLHttpRequest();
        xhr.onload = function () {
            console.log(this.responseXML.title);
            callback(this.responseXML);
        }
        xhr.open("GET", uri);
        xhr.responseType = "document";
        xhr.send();
    }

    /**
     * Using a dom, find the app list table and convert into an object.
     */
    function tableDomToAppList(dom) {
        console.log(dom.title);

        var rows = dom.querySelector("table").querySelectorAll("tr");
        var apps = [];

        // start at 1 since the first row is a header.
        for (var index = 1; index < rows.length; index++) {
            var name = rows[index].cells[0].innerText.trim();
            var href = rows[index].cells[1].querySelector("a").href;
            apps.push({ "name": name, "href": href });
        }<commit_msg>Fix null on a.href<commit_after>﻿document.appLauncher = (function (document, window) {

    console.log("app-launcher loaded.");

    function init(containerElement, apps) {

        var table = document.createElement("table");
        table.className = "app-launcher-apps";
        var tr = document.createElement("tr");
        table.appendChild(tr);

        var columns = 5; // todo option.

        apps.forEach(function(app, index) {

            if (index % columns === 0) {
                tr = document.createElement("tr");
                table.appendChild(tr);
            }

            var td = document.createElement("td");
            tr.appendChild(td);

            var a = document.createElement("a");
            a.href = app.href;
            a.title = app.name; // Added because of the ellipses.

            // todo: support images in the future.
            //var img = document.createElement("img");
            //img.src = "http://placehold.it/100x100";
            //a.appendChild(img);

            var div = document.createElement("div");
            var iconLetter = (app.name) ? app.name.substring(0, 1).toLowerCase() : "z";
            div.className = "app-launcher-icon-" + iconLetter
                + " app-launcher-icon-" + app.name.toLowerCase().replace(" ", "-").replace(/\W/g, "");
            var span = document.createElement("span");
            var iconText = document.createTextNode(iconLetter);
            span.appendChild(iconText);
            div.appendChild(span);
            a.appendChild(div);

            var linkText = document.createTextNode(app.name);
            a.appendChild(linkText);
            td.appendChild(a);

        });

        containerElement.appendChild(table);
    }

    
    /**
     * Use XHR to get the dom of the app list page.
     * @param {} callback 
     * @returns {} 
     */
    function getAppListDom(uri, callback) {
        var xhr = new XMLHttpRequest();
        xhr.onload = function () {
            console.log(this.responseXML.title);
            callback(this.responseXML);
        }
        xhr.open("GET", uri);
        xhr.responseType = "document";
        xhr.send();
    }

    /**
     * Using a dom, find the app list table and convert into an object.
     */
    function tableDomToAppList(dom) {
        console.log(dom.title);

        var rows = dom.querySelector("table").querySelectorAll("tr");
        var apps = [];

        // start at 1 since the first row is a header.
        for (var index = 1; index < rows.length; index++) {
            var name = rows[index].cells[0].innerText.trim();
            var a = rows[index].cells[1].querySelector("a");
            var href = (a) ? a.href : "";
            apps.push({ "name": name, "href": href });
        }
{'fraction_non_alphanumeric': 0.14140497367943367, 'fraction_numerical': 0.005082592121982211, 'mean_word_length': 1.847545219638243, 'pattern_counts': {'":': 4, '<': 5, '<?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': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '376', 'n_tokens_mistral': 1558, 'n_tokens_neox': 1486, 'n_words': 345}