<!DOCTYPE html>

<style>
body {
    margin: 0;
    font-family: Helvetica, sans-serif;
    font-size: 11pt;
}

body > * {
    margin-left: 4px;
    margin-top: 4px;
}

h1 {
    font-size: 14pt;
    margin-top: 1.5em;
}

p {
    margin-bottom: 0.3em;
}

a.clickable {
    color: blue;
    cursor: pointer;
    margin-left: 0.2em;
}

tr:not(.results-row) td {
    white-space: nowrap;
}

tr:not(.results-row) td:first-of-type {
    white-space: normal;
}

td:not(:first-of-type) {
    text-transform: lowercase;
}

th, td {
    padding: 1px 4px;
    vertical-align: top;
}

td:nth-child(1) {  
    min-width: 35em;
}

th:empty, td:empty {
    padding: 0;
}

th {
    -webkit-user-select: none;
    -moz-user-select: none;
}

dt > sup {
    vertical-align:text-top;
    font-size:75%;
}

sup > a {
    text-decoration: none;
}

.content-container {
    min-height: 0;
}

.note {
    color: gray;
    font-size: smaller;
}

.results-row {
    background-color: white;
}

.results-row iframe, .results-row img {
    width: 800px;
    height: 600px;
}

.results-row[data-expanded="false"] {
    display: none;
}

#toolbar {
    position: fixed;
    top: 2px;
    right: 2px;
    text-align: right;
}

.floating-panel {
    padding: 6px;
    background-color: rgba(255, 255, 255, 0.9);
    border: 1px solid silver;
    border-radius: 4px;
}

.expand-button {
    background-color: white;
    width: 11px;
    height: 12px;
    border: 1px solid gray;
    display: inline-block;
    margin: 0 3px 0 0;
    position: relative;
    cursor: default;
}

.current {
    color: red;
}

.current .expand-button {
    border-color: red;
}

.expand-button-text {
    position: absolute;
    top: -0.3em;
    left: 1px;
}

tbody .flag {
    display: none;
}

tbody.flagged .flag {
    display: inline;
}

.stopped-running-early-message {
    border: 3px solid #d00;
    font-weight: bold;
    display: inline-block;
    padding: 3px;
}

.result-container {
    display: inline-block;
    border: 1px solid gray;
    margin: 4px;
}

.result-container iframe, .result-container img {
    border: 0;
    vertical-align: top;
}

.leaks > table {
    margin: 4px;
}
.leaks > td {
    padding-left: 20px;
}

#options {
    background-color: white;
}

#options-menu {
    border: 1px solid gray;
    border-radius: 4px;
    margin-top: 1px;
    padding: 2px 4px;
    box-shadow: 2px 2px 4px rgba(0, 0, 0, 0.6);
    transition: opacity .2s;
    text-align: left;
    position: absolute;
    right: 4px;
    background-color: white;
}

#options-menu label {
    display: block;
}

.hidden-menu {
    pointer-events: none;
    opacity: 0;
}

.label {
    padding-left: 3px;
    font-weight: bold;
    font-size: small;
    background-color: silver;
}

.pixel-zoom-container {
    position: fixed;
    top: 0;
    left: 0;
    width: 96%;
    margin: 10px;
    padding: 10px;
    display: -webkit-box;
    display: -moz-box;
    pointer-events: none;
    background-color: silver;
    border-radius: 20px;
    border: 1px solid gray;
    box-shadow: 0 0 5px rgba(0, 0, 0, 0.75);
}

.pixel-zoom-container > * {
    -webkit-box-flex: 1;
    -moz-box-flex: 1;
    border: 1px solid black;
    margin: 4px;
    overflow: hidden;
    background-color: white;
}

.pixel-zoom-container .scaled-image-container {
    position: relative;
    overflow: hidden;
    width: 100%;
    height: 400px;
}

.scaled-image-container > img {
    position: absolute;
    top: 0;
    left: 0;
    image-rendering: -webkit-optimize-contrast;
}

#flagged-test-container {
    position: fixed;
    bottom: 4px;
    right: 4px;
    width: 50%;
    min-width: 400px;
    background-color: rgba(255, 255, 255, 0.75);
}

#flagged-test-container > h2 {
    margin: 0 0 4px 0;
}

#flagged-tests {
    padding: 0 5px;
    margin: 0;
    height: 7em;
    overflow-y: scroll;
}
</style>
<style id="unexpected-style"></style>

<script>

class Utils
{
    static matchesSelector(node, selector)
    {
        if (node.matches)
            return node.matches(selector);

        if (node.webkitMatchesSelector)
            return node.webkitMatchesSelector(selector);

        if (node.mozMatchesSelector)
            return node.mozMatchesSelector(selector);
    }

    static parentOfType(node, selector)
    {
        while (node = node.parentNode) {
            if (Utils.matchesSelector(node, selector))
                return node;
        }
        return null;
    }

    static stripExtension(testName)
    {
        // Temporary fix, also in Tools/Scripts/webkitpy/layout_tests/constrollers/test_result_writer.py, line 95.
        // FIXME: Refactor to avoid confusing reference to both test and process names.
        if (Utils.splitExtension(testName)[1].length > 5)
            return testName;
        return Utils.splitExtension(testName)[0];
    }

    static splitExtension(testName)
    {
        let index = testName.lastIndexOf('.');
        if (index == -1) {
            return [testName, ''];
        }
        return [testName.substring(0, index), testName.substring(index + 1)];
    }

    static forEach(nodeList, handler)
    {
        Array.prototype.forEach.call(nodeList, handler);
    }

    static toArray(nodeList)
    {
        return Array.prototype.slice.call(nodeList);
    }

    static trim(string)
    {
        return string.replace(/^[\s\xa0]+|[\s\xa0]+$/g, '');
    }

    static async(func, args)
    {
        setTimeout(() => { func.apply(null, args); }, 50);
    }

    static appendHTML(node, html)
    {
        if (node.insertAdjacentHTML)
            node.insertAdjacentHTML('beforeEnd', html);
        else
            node.innerHTML += html;
    }};

class TestResult
{
    constructor(info, name)
    {
        this.name = name;
        this.info = info; // FIXME: make this private.
    }

    isFailureExpected()
    {
        let actual = this.info.actual;    
        let expected = this.info.expected || 'PASS';

        if (actual != 'SKIP') {
            let expectedArray = expected.split(' ');
            let actualArray = actual.split(' ');
            for (let actualValue of actualArray) {
                if (expectedArray.indexOf(actualValue) == -1 && (expectedArray.indexOf('FAIL') == -1 || (actualValue != 'TEXT' && actualValue != 'IMAGE+TEXT' && actualValue != 'AUDIO')))
                    return false;
            }
        }
        return true;
    }
    
    isMissingAllResults()
    {
        return this.info.actual == 'MISSING';
    }
    
    hasMissingResult()
    {
        return this.info.actual.indexOf('MISSING') != -1;
    }
    
    isFlakey(pixelTestsEnabled)
    {
        let actualTokens = this.info.actual.split(' ');
        let passedWithImageOnlyFailureInRetry = actualTokens[0] == 'TEXT' && actualTokens[1] == 'IMAGE';
        if (actualTokens[1] && this.info.actual.indexOf('PASS') != -1 || (!pixelTestsEnabled && passedWithImageOnlyFailureInRetry))
            return true;
        
        return false;
    }
    
    isPass()
    {
        return this.info.actual == 'PASS';
    }

    isTextFailure()
    {
        return this.info.actual.indexOf('TEXT') != -1;
    }

    isImageFailure()
    {
        return this.info.actual.indexOf('IMAGE') != -1;
    }

    isAudioFailure()
    {
        return this.info.actual.indexOf('AUDIO') != -1;
    }

    hasLeak()
    {
        return this.info.actual.indexOf('LEAK') != -1;
    }

    isCrash()
    {
        return this.info.actual == 'CRASH';
    }
    
    isTimeout()
    {
        return this.info.actual == 'TIMEOUT';
    }
    
    isUnexpectedPass(pixelTestsEnabled)
    {
        if (this.info.actual == 'PASS' && this.info.expected != 'PASS') {
            if (this.info.expected != 'IMAGE' || (pixelTestsEnabled || this.isRefTest()))
                return true;
        }
        
        return false;
    }
    
    isRefTest()
    {
        return !!this.info.reftest_type;
    }

    isMismatchRefTest()
    {
        return this.isRefTest() && this.info.reftest_type.indexOf('!=') != -1;
    }

    isMatchRefTest()
    {
        return this.isRefTest() && this.info.reftest_type.indexOf('==') != -1;
    }
    
    isMissingText()
    {
        return this.info.is_missing_text;
    }

    isMissingImage()
    {
        return this.info.is_missing_image;
    }

    isMissingAudio()
    {
        return this.info.is_missing_audio;
    }
    
    hasStdErr()
    {
        return this.info.has_stderr;
    }
};

class TestResults
{
    constructor(results)
    {
        this._results = results;

        this.crashTests = [];
        this.crashOther = [];
        this.missingResults = [];
        this.failingTests = [];
        this.testsWithStderr = [];
        this.timeoutTests = [];
        this.unexpectedPassTests = [];
        this.flakyPassTests = [];

        this.hasHttpTests = false;
        this.hasImageFailures = false;
        this.hasTextFailures = false;

        this._testsByName = new Map;

        this._forEachTest(this._results.tests, '');
        this._forOtherCrashes(this._results.other_crashes);
    }
    
    date()
    {
        return this._results.date;
    }

    layoutTestsDir()
    {
        return this._results.layout_tests_dir;
    }
    
    usesExpectationsFile()
    {
        return this._results.uses_expectations_file;
    }
    
    resultForTest(testName)
    {
        return this._resultsByTest[testName];
    }
    
    wasInterrupted()
    {
        return this._results.interrupted;
    }

    hasPrettyPatch()
    {
        return this._results.has_pretty_patch;
    }
    
    hasWDiff()
    {
        return this._results.has_wdiff;
    }
    
    testWithName(testName)
    {
        return this._testsByName.get(testName);
    }

    _processResultForTest(testResult)
    {
        this._testsByName.set(testResult.name, testResult);

        let test = testResult.name;
        if (testResult.hasStdErr())
            this.testsWithStderr.push(testResult);

        this.hasHttpTests |= test.indexOf('http/') == 0;

        if (this.usesExpectationsFile())
            testResult.isExpected = testResult.isFailureExpected();
        
        if (testResult.isTextFailure())
            this.hasTextFailures = true;

        if (testResult.isImageFailure())
            this.hasImageFailures = true;

        if (testResult.isMissingAllResults()) {
            // FIXME: make sure that new-run-webkit-tests spits out an -actual.txt file for tests with MISSING results.
            this.missingResults.push(testResult);
            return;
        }

        if (testResult.isFlakey(this._results.pixel_tests_enabled)) {
            this.flakyPassTests.push(testResult);
            return;
        }

        if (testResult.isPass()) {
            if (testResult.isUnexpectedPass(this._results.pixel_tests_enabled))
                this.unexpectedPassTests.push(testResult);
            return;
        }

        if (testResult.isCrash()) {
            this.crashTests.push(testResult);
            return;
        }

        if (testResult.isTimeout()) {
            this.timeoutTests.push(testResult);
            return;
        }
    
        this.failingTests.push(testResult);
    }
    
    _forEachTest(tree, prefix)
    {
        for (let key in tree) {
            let newPrefix = prefix ? (prefix + '/' + key) : key;
            if ('actual' in tree[key]) {
                let testObject = new TestResult(tree[key], newPrefix);
                this._processResultForTest(testObject);
            } else
                this._forEachTest(tree[key], newPrefix);
        }
    }

    _forOtherCrashes(tree)
    {
        for (let key in tree) {
            let testObject = new TestResult(tree[key], key);
            this.crashOther.push(testObject);
        }
    }
    
    static sortByName(tests)
    {
        tests.sort(function (a, b) { return a.name.localeCompare(b.name) });
    }

    static hasUnexpectedResult(tests)
    {
        return tests.some(function (test) { return !test.isExpected; });
    }
};

class TestResultsController
{        
    constructor(containerElement, testResults)
    {
        this.containerElement = containerElement;
        this.testResults = testResults;

        this.shouldToggleImages = true;
        this._togglingImageInterval = null;
        
        this._updatePageTitle();

        this.buildResultsTables();
        this.hideNonApplicableUI();
        this.setupSorting();
        this.setupOptions();
    }
    
    buildResultsTables()
    {
        if (this.testResults.wasInterrupted()) {
            let interruptionMessage = document.createElement('p');
            interruptionMessage.textContent = 'Testing exited early';
            interruptionMessage.classList.add('stopped-running-early-message');
            this.containerElement.appendChild(interruptionMessage);
        }

        if (this.testResults.crashTests.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.crashTests, 'crash-tests-table'));

        if (this.testResults.crashOther.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.crashOther, 'other-crash-tests-table'));

        if (this.testResults.failingTests.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.failingTests, 'results-table'));

        if (this.testResults.missingResults.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.missingResults, 'missing-table'));

        if (this.testResults.timeoutTests.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.timeoutTests, 'timeout-tests-table'));

        if (this.testResults.testsWithStderr.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.testsWithStderr, 'stderr-table'));

        if (this.testResults.flakyPassTests.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.flakyPassTests, 'flaky-tests-table'));

        if (this.testResults.usesExpectationsFile() && this.testResults.unexpectedPassTests.length)
            this.containerElement.appendChild(this.buildOneSection(this.testResults.unexpectedPassTests, 'passes-table'));

        if (this.testResults.hasHttpTests) {
            let httpdAccessLogLink = document.createElement('p');
            httpdAccessLogLink.innerHTML = 'httpd access log: <a href="access_log.txt">access_log.txt</a>';

            let httpdErrorLogLink = document.createElement('p');
            httpdErrorLogLink.innerHTML = 'httpd error log: <a href="error_log.txt">error_log.txt</a>';
            
            this.containerElement.appendChild(httpdAccessLogLink);
            this.containerElement.appendChild(httpdErrorLogLink);
        }
        
        this.updateTestlistCounts();
    }

    static sectionBuilderClassForTableID(tableID)
    {
        const idToBuilderClassMap = {
            'crash-tests-table' : CrashingTestsSectionBuilder,
            'other-crash-tests-table' : OtherCrashesSectionBuilder,
            'results-table' : FailingTestsSectionBuilder,
            'missing-table' : TestsWithMissingResultsSectionBuilder,
            'timeout-tests-table' : TimedOutTestsSectionBuilder,
            'stderr-table' : TestsWithStdErrSectionBuilder,
            'flaky-tests-table' : FlakyPassTestsSectionBuilder,
            'passes-table' : UnexpectedPassTestsSectionBuilder,
        };
        return idToBuilderClassMap[tableID];
    }
    
    setupSorting()
    {
        let resultsTable = document.getElementById('results-table');
        if (!resultsTable)
            return;
        
        // FIXME: Make all the tables sortable. Maybe SectionBuilder should put a TableSorter on each table.
        resultsTable.addEventListener('click', TableSorter.handleClick, false);
        TableSorter.sortColumn(0);
    }
    
    hideNonApplicableUI()
    {
        // FIXME: do this all through body classnames.
        if (!this.testResults.hasTextFailures) {
            let textResultsHeader = document.getElementById('text-results-header');
            if (textResultsHeader)
                textResultsHeader.textContent = '';
        }

        if (!this.testResults.hasImageFailures) {
            let imageResultsHeader = document.getElementById('image-results-header');
            if (imageResultsHeader)
                imageResultsHeader.textContent = '';

            Utils.parentOfType(document.getElementById('toggle-images'), 'label').style.display = 'none';
        }
    }
    
    setupOptions()
    {
        // FIXME: do this all through body classnames.
        if (!this.testResults.usesExpectationsFile())
            Utils.parentOfType(document.getElementById('unexpected-results'), 'label').style.display = 'none';
    }

    buildOneSection(tests, tableID)
    {
        TestResults.sortByName(tests);
        
        let sectionBuilderClass = TestResultsController.sectionBuilderClassForTableID(tableID);
        let sectionBuilder = new sectionBuilderClass(tests, tableID, this);
        return sectionBuilder.build();
    }

    updateTestlistCounts()
    {
        // FIXME: do this through the data model, not through the DOM.
        let onlyShowUnexpectedFailures = this.onlyShowUnexpectedFailures();
        Utils.forEach(document.querySelectorAll('.test-list-count'), count => {
            let container = Utils.parentOfType(count, 'section');
            let testContainers;
            if (onlyShowUnexpectedFailures)
                testContainers = container.querySelectorAll('tbody:not(.expected)');
            else
                testContainers = container.querySelectorAll('tbody');

            count.textContent = testContainers.length;
        })
    }
    
    flagAll(headerLink)
    {
        let tests = this.visibleTests(Utils.parentOfType(headerLink, 'section'));
        Utils.forEach(tests, tests => {
            let shouldFlag = true;
            testNavigator.flagTest(tests, shouldFlag);
        })
    }

    unflag(flag)
    {
        const shouldFlag = false;
        testNavigator.flagTest(Utils.parentOfType(flag, 'tbody'), shouldFlag);
    }

    visibleTests(opt_container)
    {
        let container = opt_container || document;
        if (this.onlyShowUnexpectedFailures())
            return container.querySelectorAll('tbody:not(.expected)');
        else
            return container.querySelectorAll('tbody');
    }

    // FIXME: this is confusing. Flip the sense around.
    onlyShowUnexpectedFailures()
    {
        return document.getElementById('unexpected-results').checked;
    }

    static _testListHeader(title)
    {
        let header = document.createElement('h1');
        header.innerHTML = title + ' (<span class=test-list-count></span>): <a href="#" class=flag-all onclick="controller.flagAll(this)">flag all</a>';
        return header;
    }

    testToURL(testResult, layoutTestsPath)
    {
        const mappings = {
            "http/tests/ssl/": "https://127.0.0.1:8443/ssl/",
            "http/tests/": "http://127.0.0.1:8000/",
            "http/wpt/": "http://localhost:8800/WebKit/",
            "imported/w3c/web-platform-tests/": "http://localhost:8800/"
        };

        for (let key in mappings) {
            if (testResult.name.startsWith(key))
                return mappings[key] + testResult.name.substring(key.length);

        }
        return "file://" + layoutTestsPath + "/" + testResult.name;
    }

    layoutTestURL(testResult)
    {
        if (this.shouldUseTracLinks())
            return this.layoutTestsBasePath() + testResult.name;

        return this.testToURL(testResult, this.layoutTestsBasePath());
    }

    layoutTestsBasePath()
    {
        let basePath;
        if (this.shouldUseTracLinks()) {
            let revision = this.testResults.revision;
            basePath = 'http://trac.webkit.org';
            basePath += revision ? ('/export/' + revision) : '/browser';
            basePath += '/trunk/LayoutTests/';
        } else
            basePath = this.testResults.layoutTestsDir() + '/';

        return basePath;
    }

    convertToLayoutTestBaseRelativeURL(fullURL)
    {
        if (fullURL.startsWith('file://')) {
            let urlPrefix = 'file://' + this.layoutTestsBasePath();
            if (fullURL.startsWith(urlPrefix))
                return fullURL.substring(urlPrefix.length);
        }
        
        return fullURL;
    }

    shouldUseTracLinks()
    {
        return !this.testResults.layoutTestsDir() || !location.toString().indexOf('file://') == 0;
    }

    checkServerIsRunning(event)
    {
        if (this.shouldUseTracLinks())
            return;

        let url = event.target.href;
        if (url.startsWith("file://"))
            return;

        event.preventDefault();
        fetch(url, { mode: "no-cors" }).then(() => {
            window.location = url;
        }, () => {
            alert("HTTP server does not seem to be running, please use the run-webkit-httpd script");
        });
    }

    testLink(testResult)
    {
        return '<a class=test-link onclick="controller.checkServerIsRunning(event)" href="' + this.layoutTestURL(testResult) + '">' + testResult.name + '</a><span class=flag onclick="controller.unflag(this)"> \u2691</span>';
    }
    
    expandButtonSpan()
    {
        return '<span class=expand-button onclick="controller.toggleExpectations(this)"><span class=expand-button-text>+</span></span>';
    }
    
    static resultLink(testPrefix, suffix, contents)
    {
        return '<a class=result-link href="' + testPrefix + suffix + '" data-prefix="' + testPrefix + '">' + contents + '</a> ';
    }

    textResultLinks(prefix)
    {
        let html = TestResultsController.resultLink(prefix, '-expected.txt', 'expected') +
            TestResultsController.resultLink(prefix, '-actual.txt', 'actual') +
            TestResultsController.resultLink(prefix, '-diff.txt', 'diff');

        if (this.testResults.hasPrettyPatch())
            html += TestResultsController.resultLink(prefix, '-pretty-diff.html', 'pretty diff');

        if (this.testResults.hasWDiff())
            html += TestResultsController.resultLink(prefix, '-wdiff.html', 'wdiff');

        return html;
    }

    flakinessDashboardURLForTests(testObjects)
    {
        // FIXME: just map and join here.
        let testList = '';
        for (let i = 0; i < testObjects.length; ++i) {
            testList += testObjects[i].name;

            if (i != testObjects.length - 1)
                testList += ',';
        }

        return 'https://results.webkit.org/?suite=layout-tests&test=' + encodeURIComponent(testList);
    }

    _updatePageTitle()
    {
        let dateString = this.testResults.date();
        let title = document.createElement('title');
        title.textContent = 'Layout Test Results from ' + dateString;
        document.head.appendChild(title);
    }
    
    // Options handling. FIXME: move to a separate class?
    updateAllOptions()
    {
        Utils.forEach(document.querySelectorAll('#options-menu input'), input => { input.onchange() });
    }

    toggleOptionsMenu()
    {
        let menu = document.getElementById('options-menu');
        menu.className = (menu.className == 'hidden-menu') ? '' : 'hidden-menu';
    }

    handleToggleUseNewlines()
    {
        OptionWriter.save();
        testNavigator.updateFlaggedTests();
    }

    handleUnexpectedResultsChange()
    {
        OptionWriter.save();
        this._updateExpectedFailures();
    }

    expandAllExpectations()
    {
        let expandLinks = this._visibleExpandLinks();
        for (let link of expandLinks)
            Utils.async(link => { controller.expandExpectations(link) }, [ link ]);
    }

    collapseAllExpectations()
    {
        let expandLinks = this._visibleExpandLinks();
        for (let link of expandLinks)
            Utils.async(link => { controller.collapseExpectations(link) }, [ link ]);
    }

    expandExpectations(expandLink)
    {
        let row = Utils.parentOfType(expandLink, 'tr');
        let parentTbody = row.parentNode;
        let existingResultsRow = parentTbody.querySelector('.results-row');
    
        const enDash = '\u2013';
        expandLink.textContent = enDash;
        if (existingResultsRow) {
            this._updateExpandedState(existingResultsRow, true);
            return;
        }

        let testName = row.getAttribute('data-test-name');
        let testResult = this.testResults.testWithName(testName);

        let newRow = TestResultsController._buildExpandedRowForTest(testResult, row);
        parentTbody.appendChild(newRow);

        this._updateExpandedState(newRow, true);

        this._updateImageTogglingTimer();
    }

    collapseExpectations(expandLink)
    {
        expandLink.textContent = '+';
        let existingResultsRow = Utils.parentOfType(expandLink, 'tbody').querySelector('.results-row');
        if (existingResultsRow)
            this._updateExpandedState(existingResultsRow, false);
    }

    toggleExpectations(element)
    {
        let expandLink = element;
        if (expandLink.className != 'expand-button-text')
            expandLink = expandLink.querySelector('.expand-button-text');

        if (expandLink.textContent == '+')
            this.expandExpectations(expandLink);
        else
            this.collapseExpectations(expandLink);
    }

    _updateExpandedState(row, isExpanded)
    {
        row.setAttribute('data-expanded', isExpanded);
        this._updateImageTogglingTimer();
    }

    handleToggleImagesChange()
    {
        OptionWriter.save();
        this._updateTogglingImages();
    }

    _visibleExpandLinks()
    {
        if (this.onlyShowUnexpectedFailures())
            return document.querySelectorAll('tbody:not(.expected) .expand-button-text');
        else
            return document.querySelectorAll('.expand-button-text');
    }

    static _togglingImage(prefix)
    {
        return '<div class=result-container><div class="label imageText"></div><img class=animatedImage data-prefix="' + prefix + '"></img></div>';
    }

    _updateTogglingImages()
    {
        this.shouldToggleImages = document.getElementById('toggle-images').checked;

        // FIXME: this is all pretty confusing. Simplify.
        if (this.shouldToggleImages) {
            Utils.forEach(document.querySelectorAll('table:not(#missing-table) tbody:not([mismatchreftest]) a[href$=".png"]'), TestResultsController._convertToTogglingHandler(function(prefix) {
                return TestResultsController.resultLink(prefix, '-diffs.html', 'images');
            }));
            Utils.forEach(document.querySelectorAll('table:not(#missing-table) tbody:not([mismatchreftest]) img[src$=".png"]'), TestResultsController._convertToTogglingHandler(TestResultsController._togglingImage));
        } else {
            Utils.forEach(document.querySelectorAll('a[href$="-diffs.html"]'), element => {
                TestResultsController._convertToNonTogglingHandler(element);
            });
            Utils.forEach(document.querySelectorAll('.animatedImage'), TestResultsController._convertToNonTogglingHandler(function (absolutePrefix, suffix) {
                return TestResultsController._resultIframe(absolutePrefix + suffix);
            }));
        }

        this._updateImageTogglingTimer();
    }

    _updateExpectedFailures()
    {
        // Gross to do this by setting stylesheet text. Use a body class!
        document.getElementById('unexpected-style').textContent = this.onlyShowUnexpectedFailures() ? '.expected { display: none; }' : '';

        this.updateTestlistCounts();
        testNavigator.onlyShowUnexpectedFailuresChanged();
    }

    static _buildExpandedRowForTest(testResult, row)
    {
        let newRow = document.createElement('tr');
        newRow.className = 'results-row';
        let newCell = document.createElement('td');
        newCell.colSpan = row.querySelectorAll('td').length;

        // FIXME: migrate more of code to using testResult for building the expanded content.
        let resultLinks = row.querySelectorAll('.result-link');
        let hasTogglingImages = false;
        for (let link of resultLinks) {
            let result;
            if (link.textContent == 'images') {
                hasTogglingImages = true;
                result = TestResultsController._togglingImage(link.getAttribute('data-prefix'));
            } else
                result = TestResultsController._resultIframe(link.href);

            Utils.appendHTML(newCell, result);    
        }

        if (testResult.hasLeak())
            newCell.appendChild(TestResultsController._makeLeaksCell(testResult));

        newRow.appendChild(newCell);

        return newRow;
    }
    
    static _makeLeaksCell(testResult)
    {
        let container = document.createElement('div');
        container.className = 'result-container leaks';
        
        let label = document.createElement('div');
        label.className = 'label';
        label.textContent = "Leaks";
        container.appendChild(label);

        let leaksTable = document.createElement('table');
        
        for (let leak of testResult.info.leaks) {
            let leakRow = document.createElement('tr');

            for (let leakedObjectType in leak) {
                let th = document.createElement('th');
                th.textContent = leakedObjectType;
                let td = document.createElement('td');
                
                let url = leak[leakedObjectType]; // FIXME: when we track leaks other than documents, this might not be a URL.
                td.textContent = controller.convertToLayoutTestBaseRelativeURL(url)
                
                leakRow.appendChild(th);
                leakRow.appendChild(td);
            }
            
            leaksTable.appendChild(leakRow);
        }
        
        container.appendChild(leaksTable);
        return container;
    }

    static _resultIframe(src)
    {
        // FIXME: use audio tags for AUDIO tests?
        let layoutTestsIndex = src.indexOf('LayoutTests');
        let name;
        if (layoutTestsIndex != -1) {
            let hasTrac = src.indexOf('trac.webkit.org') != -1;
            let prefix = hasTrac ? 'trac.webkit.org/.../' : '';
            name = prefix + src.substring(layoutTestsIndex + 'LayoutTests/'.length);
        } else {
            let lastDashIndex = src.lastIndexOf('-pretty');
            if (lastDashIndex == -1)
                lastDashIndex = src.lastIndexOf('-');
            name = src.substring(lastDashIndex + 1);
        }

        let tagName = (src.lastIndexOf('.png') == -1) ? 'iframe' : 'img';

        if (tagName != 'img')
            src += '?format=txt';
        return '<div class=result-container><div class=label>' + name + '</div><' + tagName + ' src="' + src + '"></' + tagName + '></div>';
    }


    static _toggleImages()
    {
        let images = document.querySelectorAll('.animatedImage');
        let imageTexts = document.querySelectorAll('.imageText');
        for (let i = 0, len = images.length; i < len; i++) {
            let image = images[i];
            let text = imageTexts[i];
            if (text.textContent == 'Expected Image') {
                text.textContent = 'Actual Image';
                image.src = image.getAttribute('data-prefix') + '-actual.png';
            } else {
                text.textContent = 'Expected Image';
                image.src = image.getAttribute('data-prefix') + '-expected.png';
            }
        }
    }

    _updateImageTogglingTimer()
    {
        let hasVisibleAnimatedImage = document.querySelector('.results-row[data-expanded="true"] .animatedImage');
        if (!hasVisibleAnimatedImage) {
            clearInterval(this._togglingImageInterval);
            this._togglingImageInterval = null;
            return;
        }

        if (!this._togglingImageInterval) {
            TestResultsController._toggleImages();
            this._togglingImageInterval = setInterval(TestResultsController._toggleImages, 2000);
        }
    }
    
    static _getResultContainer(node)
    {
        return (node.tagName == 'IMG') ? Utils.parentOfType(node, '.result-container') : node;
    }

    static _convertToTogglingHandler(togglingImageFunction)
    {
        return function(node) {
            let url = (node.tagName == 'IMG') ? node.src : node.href;
            if (url.match('-expected.png$'))
                TestResultsController._getResultContainer(node).remove();
            else if (url.match('-actual.png$')) {
                let name = Utils.parentOfType(node, 'tbody').querySelector('.test-link').textContent;
                TestResultsController._getResultContainer(node).outerHTML = togglingImageFunction(Utils.stripExtension(name));
            }
        }
    }
    
    static _convertToNonTogglingHandler(resultFunction)
    {
        return function(node) {
            let prefix = node.getAttribute('data-prefix');
            TestResultsController._getResultContainer(node).outerHTML = resultFunction(prefix, '-expected.png', 'expected') + resultFunction(prefix, '-actual.png', 'actual');
        }
    }
};

class SectionBuilder {
    
    constructor(tests, tableID, resultsController)
    {
        this._tests = tests;
        this._table = null;
        this._resultsController = resultsController;
        this._tableID = tableID;
    }

    build()
    {
        TestResults.sortByName(this._tests);
        
        let section = document.createElement('section');
        section.appendChild(TestResultsController._testListHeader(this.sectionTitle()));
        if (this.hideWhenShowingUnexpectedResultsOnly())
            section.classList.add('expected');

        this._table = document.createElement('table');
        this._table.id = this.tableID();
        this.addTableHeader();

        let visibleResultsCount = 0;
        for (let testResult of this._tests) {
            let tbody = this.createTableRow(testResult);
            this._table.appendChild(tbody);
            
            if (!this._resultsController.onlyShowUnexpectedFailures() || testResult.isExpected)
                ++visibleResultsCount;
        }
        
        section.querySelector('.test-list-count').textContent = visibleResultsCount;
        section.appendChild(this._table);
        return section;
    }

    createTableRow(testResult)
    {
        let tbody = document.createElement('tbody');
        if (testResult.isExpected)
            tbody.classList.add('expected');
        
        let row = document.createElement('tr');
        row.setAttribute('data-test-name', testResult.name);
        tbody.appendChild(row);

        let testNameCell = document.createElement('td');
        this.fillTestCell(testResult, testNameCell);
        row.appendChild(testNameCell);

        let resultCell = document.createElement('td');
        this.fillTestResultCell(testResult, resultCell);
        row.appendChild(resultCell);

        let historyCell = this.createHistoryCell(testResult);
        if (historyCell)
            row.appendChild(historyCell);

        return tbody;
    }
    
    hideWhenShowingUnexpectedResultsOnly()
    {
        return !TestResults.hasUnexpectedResult(this._tests);
    }
    
    addTableHeader()
    {
    }
    
    fillTestCell(testResult, cell)
    {
        let testLink = this.linkifyTestName() ? this._resultsController.testLink(testResult) : testResult.name;
        if (this.rowsAreExpandable()) {
            cell.innerHTML = this._resultsController.expandButtonSpan() + testLink;
            return;
        }

        cell.innerHTML = testLink;
    }

    fillTestResultCell(testResult, cell)
    {
    }
    
    createHistoryCell(testResult)
    {
        let historyCell = document.createElement('td');
        historyCell.innerHTML = '<a href="' + this._resultsController.flakinessDashboardURLForTests([testResult]) + '">history</a>'
        return historyCell;
    }
    
    tableID()
    {
        return this._tableID;
    }
    
    rowsAreExpandable()
    {
        return true;
    }
    
    linkifyTestName()
    {
        return true;
    }

    sectionTitle() { return ''; }
};

class FailuresSectionBuilder extends SectionBuilder {
    
    addTableHeader()
    {
        let header = document.createElement('thead');
        let html = '<th>test</th><th id="text-results-header">results</th><th id="image-results-header">image results</th>';

        if (this._resultsController.testResults.usesExpectationsFile())
            html += '<th>actual failure</th><th>expected failure</th>';

        html += '<th><a href="' + this._resultsController.flakinessDashboardURLForTests(this._tests) + '">history</a></th>';

        if (this.tableID() == 'flaky-tests-table') // FIXME: use the classes, Luke!
            html += '<th>failures</th>';

        header.innerHTML = html;
        this._table.appendChild(header);
    }
    
    createTableRow(testResult)
    {
        let tbody = document.createElement('tbody');
        if (testResult.isExpected)
            tbody.classList.add('expected');
        
        if (testResult.isMismatchRefTest())
            tbody.setAttribute('mismatchreftest', 'true');

        let row = document.createElement('tr');
        row.setAttribute('data-test-name', testResult.name);
        tbody.appendChild(row);
        
        let testNameCell = document.createElement('td');
        this.fillTestCell(testResult, testNameCell);
        row.appendChild(testNameCell);

        let resultCell = document.createElement('td');
        this.fillTestResultCell(testResult, resultCell);
        row.appendChild(resultCell);

        if (testResult.isTextFailure())
            this.appendTextFailureLinks(testResult, resultCell);

        if (testResult.isAudioFailure())
            this.appendAudioFailureLinks(testResult, resultCell);
            
        if (testResult.hasMissingResult())
            this.appendActualOnlyLinks(testResult, resultCell);

        let actualTokens = testResult.info.actual.split(/\s+/);

        let testPrefix = Utils.stripExtension(testResult.name);
        let imageResults = this.imageResultLinks(testResult, testPrefix, actualTokens[0]);
        if (!imageResults && actualTokens.length > 1)
            imageResults = this.imageResultLinks(testResult, 'retries/' + testPrefix, actualTokens[1]);

        let imageResultsCell = document.createElement('td');
        imageResultsCell.innerHTML = imageResults;
        row.appendChild(imageResultsCell);

        if (this._resultsController.testResults.usesExpectationsFile() || actualTokens.length) {
            let actualCell = document.createElement('td');
            actualCell.textContent = testResult.info.actual;
            row.appendChild(actualCell);
        }

        if (this._resultsController.testResults.usesExpectationsFile()) {
            let expectedCell = document.createElement('td');
            expectedCell.textContent = testResult.hasMissingResult() ? '' : testResult.info.expected;
            row.appendChild(expectedCell);
        }

        let historyCell = this.createHistoryCell(testResult);
        if (historyCell)
            row.appendChild(historyCell);

        return tbody;
    }

    appendTextFailureLinks(testResult, cell)
    {
        cell.innerHTML += this._resultsController.textResultLinks(Utils.stripExtension(testResult.name));
    }
    
    appendAudioFailureLinks(testResult, cell)
    {
        let prefix = Utils.stripExtension(testResult.name);
        cell.innerHTML += TestResultsController.resultLink(prefix, '-expected.wav', 'expected audio')
            + TestResultsController.resultLink(prefix, '-actual.wav', 'actual audio')
            + TestResultsController.resultLink(prefix, '-diff.txt', 'textual diff');
    }
    
    appendActualOnlyLinks(testResult, cell)
    {
        let prefix = Utils.stripExtension(testResult.name);
        if (testResult.isMissingAudio())
            cell.innerHTML += TestResultsController.resultLink(prefix, '-actual.wav', 'audio result');

        if (testResult.isMissingText())
            cell.innerHTML += TestResultsController.resultLink(prefix, '-actual.txt', 'result');
    }

    imageResultLinks(testResult, testPrefix, resultToken)
    {
        let result = '';
        if (resultToken.indexOf('IMAGE') != -1) {
            let testExtension = Utils.splitExtension(testResult.name)[1];

            if (testResult.isMismatchRefTest()) {
                result += TestResultsController.resultLink(this._resultsController.layoutTestsBasePath() + testPrefix, '-expected-mismatch.' + testExtension, 'ref mismatch');
                result += TestResultsController.resultLink(testPrefix, '-actual.png', 'actual');
            } else {
                if (testResult.isMatchRefTest())
                    result += TestResultsController.resultLink(this._resultsController.layoutTestsBasePath() + testPrefix, '-expected.' + testExtension, 'reference');

                if (this._resultsController.shouldToggleImages)
                    result += TestResultsController.resultLink(testPrefix, '-diffs.html', 'images');
                else {
                    result += TestResultsController.resultLink(testPrefix, '-expected.png', 'expected');
                    result += TestResultsController.resultLink(testPrefix, '-actual.png', 'actual');
                }

                let diff = testResult.info.image_diff_percent;
                result += TestResultsController.resultLink(testPrefix, '-diff.png', 'diff (' + diff + '%)');
            }
        }
        
        if (testResult.hasMissingResult() && testResult.isMissingImage())
            result += TestResultsController.resultLink(testPrefix, '-actual.png', 'png result');
        
        return result;
    }
};

class FailingTestsSectionBuilder extends FailuresSectionBuilder {
    sectionTitle() { return 'Tests that failed text/pixel/audio diff'; }
};

class TestsWithMissingResultsSectionBuilder extends FailuresSectionBuilder {
    sectionTitle() { return 'Tests that had no expected results (probably new)'; }

    rowsAreExpandable()
    {
        return false;
    }
};

class FlakyPassTestsSectionBuilder extends FailuresSectionBuilder {
    sectionTitle() { return 'Flaky tests (failed the first run and passed on retry)'; }
};

class UnexpectedPassTestsSectionBuilder extends SectionBuilder {
    sectionTitle() { return 'Tests expected to fail but passed'; }

    addTableHeader()
    {
        let header = document.createElement('thead');
        header.innerHTML = '<th>test</th><th>expected failure</th><th>history</th>';
        this._table.appendChild(header);
    }
    
    fillTestResultCell(testResult, cell)
    {
        cell.innerHTML = testResult.info.expected;
    }

    rowsAreExpandable()
    {
        return false;
    }
};

class TestsWithStdErrSectionBuilder extends SectionBuilder {
    sectionTitle() { return 'Tests that had stderr output'; }
    hideWhenShowingUnexpectedResultsOnly() { return false; }

    fillTestResultCell(testResult, cell)
    {
        cell.innerHTML = TestResultsController.resultLink(Utils.stripExtension(testResult.name), '-stderr.txt', 'stderr');
    }
};

class TimedOutTestsSectionBuilder extends SectionBuilder {
    sectionTitle() { return 'Tests that timed out'; }

    fillTestResultCell(testResult, cell)
    {
        // FIXME: only include timeout actual/diff results here if we actually spit out results for timeout tests.
        cell.innerHTML = this._resultsController.textResultLinks(Utils.stripExtension(testResult.name));
    }
};

class CrashingTestsSectionBuilder extends SectionBuilder {
    sectionTitle() { return 'Tests that crashed'; }

    fillTestResultCell(testResult, cell)
    {
        cell.innerHTML = TestResultsController.resultLink(Utils.stripExtension(testResult.name), '-crash-log.txt', 'crash log')
                       + TestResultsController.resultLink(Utils.stripExtension(testResult.name), '-sample.txt', 'sample');
    }
};

class OtherCrashesSectionBuilder extends SectionBuilder {
    sectionTitle() { return 'Other crashes'; }
    fillTestResultCell(testResult, cell)
    {
        cell.innerHTML = TestResultsController.resultLink(Utils.stripExtension(testResult.name), '-crash-log.txt', 'crash log');
    }

    createHistoryCell(testResult)
    {
        return null;
    }

    linkifyTestName()
    {
        return false;
    }
};

class PixelZoomer {
    constructor()
    {
        this.showOnDelay = true;
        this._zoomFactor = 6;

        this._resultWidth = 800;
        this._resultHeight = 600;
        
        this._percentX = 0;
        this._percentY = 0;

        document.addEventListener('mousemove', this, false);
        document.addEventListener('mouseout', this, false);
    }

    _zoomedResultWidth()
    {
        return this._resultWidth * this._zoomFactor;
    }
    
    _zoomedResultHeight()
    {
        return this._resultHeight * this._zoomFactor;
    }
    
    _zoomImageContainer(url)
    {
        let container = document.createElement('div');
        container.className = 'zoom-image-container';

        let title = url.match(/\-([^\-]*)\.png/)[1];
    
        let label = document.createElement('div');
        label.className = 'label';
        label.appendChild(document.createTextNode(title));
        container.appendChild(label);
    
        let imageContainer = document.createElement('div');
        imageContainer.className = 'scaled-image-container';
    
        let image = new Image();
        image.src = url;
        image.style.width = this._zoomedResultWidth() + 'px';
        image.style.height = this._zoomedResultHeight() + 'px';
        image.style.border = '1px solid black';
        imageContainer.appendChild(image);
        container.appendChild(imageContainer);
    
        return container;
    }

    _createContainer(e)
    {
        let tbody = Utils.parentOfType(e.target, 'tbody');
        let row = tbody.querySelector('tr');
        let imageDiffLinks = row.querySelectorAll('a[href$=".png"]');
    
        let container = document.createElement('div');
        container.className = 'pixel-zoom-container';
    
        let html = '';
    
        let togglingImageLink = row.querySelector('a[href$="-diffs.html"]');
        if (togglingImageLink) {
            let prefix = togglingImageLink.getAttribute('data-prefix');
            container.appendChild(this._zoomImageContainer(prefix + '-expected.png'));
            container.appendChild(this._zoomImageContainer(prefix + '-actual.png'));
        }
    
        for (let link of imageDiffLinks)
            container.appendChild(this._zoomImageContainer(link.href));

        document.body.appendChild(container);
        this._drawAll();
    }

    _draw(imageContainer)
    {
        let image = imageContainer.querySelector('img');
        let containerBounds = imageContainer.getBoundingClientRect();
        image.style.left = (containerBounds.width / 2 - this._percentX * this._zoomedResultWidth()) + 'px';
        image.style.top = (containerBounds.height / 2 - this._percentY * this._zoomedResultHeight()) + 'px';
    }

    _drawAll()
    {
        Utils.forEach(document.querySelectorAll('.pixel-zoom-container .scaled-image-container'), element => { this._draw(element) });
    }
    
    handleEvent(event)
    {
        if (event.type == 'mousemove') {
            this._handleMouseMove(event);
            return;
        }

        if (event.type == 'mouseout') {
            this._handleMouseOut(event);
            return;
        }
    }

    _handleMouseOut(event)
    {
        if (event.relatedTarget && event.relatedTarget.tagName != 'IFRAME')
            return;

        // If e.relatedTarget is null, we've moused out of the document.
        let container = document.querySelector('.pixel-zoom-container');
        if (container)
            container.remove();
    }

    _handleMouseMove(event)
    {
        if (this._mouseMoveTimeout) {
            clearTimeout(this._mouseMoveTimeout);
            this._mouseMoveTimeout = 0;
        }

        if (Utils.parentOfType(event.target, '.pixel-zoom-container'))
            return;

        let container = document.querySelector('.pixel-zoom-container');
    
        let resultContainer = (event.target.className == 'result-container') ? event.target : Utils.parentOfType(event.target, '.result-container');
        if (!resultContainer || !resultContainer.querySelector('img')) {
            if (container)
                container.remove();
            return;
        }

        let targetLocation = event.target.getBoundingClientRect();
        this._percentX = (event.clientX - targetLocation.left) / targetLocation.width;
        this._percentY = (event.clientY - targetLocation.top) / targetLocation.height;

        if (!container) {
            if (this.showOnDelay) {
                this._mouseMoveTimeout = setTimeout(() => {
                    this._createContainer(event);
                }, 400);
                return;
            }

            this._createContainer(event);
            return;
        }
    
        this._drawAll();
    }
};

class TableSorter
{
    static _forwardArrow()
    {
        return '<svg style="width:10px;height:10px"><polygon points="0,0 10,0 5,10" style="fill:#ccc"></svg>';
    }

    static _backwardArrow()
    {
        return '<svg style="width:10px;height:10px"><polygon points="0,10 10,10 5,0" style="fill:#ccc"></svg>';
    }

    static _sortedContents(header, arrow)
    {
        return arrow + ' ' + Utils.trim(header.textContent) + ' ' + arrow;
    }

    static _updateHeaderClassNames(newHeader)
    {
        let sortHeader = document.querySelector('.sortHeader');
        if (sortHeader) {
            if (sortHeader == newHeader) {
                let isAlreadyReversed = sortHeader.classList.contains('reversed');
                if (isAlreadyReversed)
                    sortHeader.classList.remove('reversed');
                else
                    sortHeader.classList.add('reversed');
            } else {
                sortHeader.textContent = sortHeader.textContent;
                sortHeader.classList.remove('sortHeader');
                sortHeader.classList.remove('reversed');
            }
        }

        newHeader.classList.add('sortHeader');
    }

    static _textContent(tbodyRow, column)
    {
        return tbodyRow.querySelectorAll('td')[column].textContent;
    }

    static _sortRows(newHeader, reversed)
    {
        let testsTable = document.getElementById('results-table');
        let headers = Utils.toArray(testsTable.querySelectorAll('th'));
        let sortColumn = headers.indexOf(newHeader);

        let rows = Utils.toArray(testsTable.querySelectorAll('tbody'));

        rows.sort(function(a, b) {
            // Only need to support lexicographic sort for now.
            let aText = TableSorter._textContent(a, sortColumn);
            let bText = TableSorter._textContent(b, sortColumn);
        
            // Forward sort equal values by test name.
            if (sortColumn && aText == bText) {
                let aTestName = TableSorter._textContent(a, 0);
                let bTestName = TableSorter._textContent(b, 0);
                if (aTestName == bTestName)
                    return 0;
                return aTestName < bTestName ? -1 : 1;
            }

            if (reversed)
                return aText < bText ? 1 : -1;
            else
                return aText < bText ? -1 : 1;
        });

        for (let row of rows)
            testsTable.appendChild(row);
    }

    static sortColumn(columnNumber)
    {
        let newHeader = document.getElementById('results-table').querySelectorAll('th')[columnNumber];
        TableSorter._sort(newHeader);
    }

    static handleClick(e)
    {
        let newHeader = e.target;
        if (newHeader.localName != 'th')
            return;
        TableSorter._sort(newHeader);
    }

    static _sort(newHeader)
    {
        TableSorter._updateHeaderClassNames(newHeader);
    
        let reversed = newHeader.classList.contains('reversed');
        let sortArrow = reversed ? TableSorter._backwardArrow() : TableSorter._forwardArrow();
        newHeader.innerHTML = TableSorter._sortedContents(newHeader, sortArrow);
    
        TableSorter._sortRows(newHeader, reversed);
    }    
};

class OptionWriter {
    static save()
    {
        let options = document.querySelectorAll('label input');
        let data = {};
        for (let option of options)
            data[option.id] = option.checked;

        try {
            localStorage.setItem(OptionWriter._key, JSON.stringify(data));
        } catch (err) {
            if (err.name != "SecurityError")
                throw err;
        }
    }

    static apply()
    {
        let json;
        try {
            json = localStorage.getItem(OptionWriter._key);
        } catch (err) {
           if (err.name != "SecurityError")
              throw err;
        }

        if (!json) {
            controller.updateAllOptions();
            return;
        }

        let data = JSON.parse(json);
        for (let id in data) {
            let input = document.getElementById(id);
            if (input)
                input.checked = data[id];
        }
        controller.updateAllOptions();
    }

    static get _key()
    {
        return 'run-webkit-tests-options';
    }
};

let testResults;
function ADD_RESULTS(input)
{
    testResults = new TestResults(input);
}
</script>

<script src="full_results.json"></script>

<script>

class TestNavigator
{
    constructor() {
        this.currentTestIndex = -1;
        this.flaggedTests = {};
        document.addEventListener('keypress', this, false);
    }
    
    handleEvent(event)
    {
        if (event.type == 'keypress') {
            this.handleKeyEvent(event);
            return;
        }
    }

    handleKeyEvent(event)
    {
        if (event.metaKey || event.shiftKey || event.ctrlKey)
            return;

        switch (String.fromCharCode(event.charCode)) {
            case 'i':
                this._scrollToFirstTest();
                break;
            case 'j':
                this._scrollToNextTest();
                break;
            case 'k':
                this._scrollToPreviousTest();
                break;
            case 'l':
                this._scrollToLastTest();
                break;
            case 'e':
                this._expandCurrentTest();
                break;
            case 'c':
                this._collapseCurrentTest();
                break;
            case 't':
                this._toggleCurrentTest();
                break;
            case 'f':
                this._toggleCurrentTestFlagged();
                break;
        }
    }

    _scrollToFirstTest()
    {
        if (this._setCurrentTest(0))
            this._scrollToCurrentTest();
    }

    _scrollToLastTest()
    {
        let links = controller.visibleTests();
        if (this._setCurrentTest(links.length - 1))
            this._scrollToCurrentTest();
    }

    _scrollToNextTest()
    {
        if (this.currentTestIndex == -1)
            this._scrollToFirstTest();
        else if (this._setCurrentTest(this.currentTestIndex + 1))
            this._scrollToCurrentTest();
    }

    _scrollToPreviousTest()
    {
        if (this.currentTestIndex == -1)
            this._scrollToLastTest();
        else if (this._setCurrentTest(this.currentTestIndex - 1))
            this._scrollToCurrentTest();
    }

    _currentTestLink()
    {
        let links = controller.visibleTests();
        return links[this.currentTestIndex];
    }

    _currentTestExpandLink()
    {
        return this._currentTestLink().querySelector('.expand-button-text');
    }

    _expandCurrentTest()
    {
        controller.expandExpectations(this._currentTestExpandLink());
    }

    _collapseCurrentTest()
    {
        controller.collapseExpectations(this._currentTestExpandLink());
    }

    _toggleCurrentTest()
    {
        controller.toggleExpectations(this._currentTestExpandLink());
    }

    _toggleCurrentTestFlagged()
    {
        let testLink = this._currentTestLink();
        this.flagTest(testLink, !testLink.classList.contains('flagged'));
    }

    // FIXME: Test navigator shouldn't know anything about flagging. It should probably call out to TestFlagger or something.
    // FIXME: Batch flagging (avoid updateFlaggedTests on each test).
    flagTest(testTbody, shouldFlag)
    {
        let testName = testTbody.querySelector('.test-link').innerText;
    
        if (shouldFlag) {
            testTbody.classList.add('flagged');
            this.flaggedTests[testName] = 1;
        } else {
            testTbody.classList.remove('flagged');
            delete this.flaggedTests[testName];
        }

        this.updateFlaggedTests();
    }

    updateFlaggedTests()
    {
        let flaggedTestTextbox = document.getElementById('flagged-tests');
        if (!flaggedTestTextbox) {
            let flaggedTestContainer = document.createElement('div');
            flaggedTestContainer.id = 'flagged-test-container';
            flaggedTestContainer.className = 'floating-panel';
            flaggedTestContainer.innerHTML = '<h2>Flagged Tests</h2><pre id="flagged-tests" contentEditable></pre>';
            document.body.appendChild(flaggedTestContainer);

            flaggedTestTextbox = document.getElementById('flagged-tests');
        }

        let flaggedTests = Object.keys(this.flaggedTests);
        flaggedTests.sort();
        let separator = document.getElementById('use-newlines').checked ? '\n' : ' ';
        flaggedTestTextbox.innerHTML = flaggedTests.join(separator);
        document.getElementById('flagged-test-container').style.display = flaggedTests.length ? '' : 'none';
    }

    _setCurrentTest(testIndex)
    {
        let links = controller.visibleTests();
        if (testIndex < 0 || testIndex >= links.length)
            return false;

        let currentTest = links[this.currentTestIndex];
        if (currentTest)
            currentTest.classList.remove('current');

        this.currentTestIndex = testIndex;

        currentTest = links[this.currentTestIndex];
        currentTest.classList.add('current');

        return true;
    }

    _scrollToCurrentTest()
    {
        let targetLink = this._currentTestLink();
        if (!targetLink)
            return;

        let rowRect = targetLink.getBoundingClientRect();
        // rowRect is in client coords (i.e. relative to viewport), so we just want to add its top to the current scroll position.
        document.scrollingElement.scrollTop += rowRect.top;
    }

    onlyShowUnexpectedFailuresChanged()
    {
        let currentTest = document.querySelector('.current');
        if (!currentTest)
            return;

        // If our currentTest became hidden, reset the currentTestIndex.
        if (controller.onlyShowUnexpectedFailures() && currentTest.classList.contains('expected'))
            this._scrollToFirstTest();
        else {
            // Recompute this.currentTestIndex
            let links = controller.visibleTests();
            this.currentTestIndex = links.indexOf(currentTest);
        }
    }
};

function handleMouseDown(e)
{
    if (!Utils.parentOfType(e.target, '#options-menu') && e.target.id != 'options-link')
        document.getElementById('options-menu').className = 'hidden-menu';
}

document.addEventListener('mousedown', handleMouseDown, false);

let controller;
let pixelZoomer;
let testNavigator;

function generatePage()
{
    let container = document.getElementById('main-content');

    controller = new TestResultsController(container, testResults);
    pixelZoomer = new PixelZoomer();
    testNavigator = new TestNavigator();

    OptionWriter.apply();

    console.log("rendered test results page!");
}

window.addEventListener('load', generatePage, false);

</script>
<body>
    
    <div class="content-container">
        <div id="toolbar" class="floating-panel">
        <div class="note">Use the i, j, k and l keys to navigate, e, c to expand and collapse, and f to flag</div>
        <a class="clickable" onclick="controller.expandAllExpectations()">expand all</a>
        <a class="clickable" onclick="controller.collapseAllExpectations()">collapse all</a>
        <a class="clickable" id=options-link onclick="controller.toggleOptionsMenu()">options</a>
        <div id="options-menu" class="hidden-menu">
            <label><input id="unexpected-results" type="checkbox" checked onchange="controller.handleUnexpectedResultsChange()">Only unexpected results</label>
            <label><input id="toggle-images" type="checkbox" checked onchange="controller.handleToggleImagesChange()">Toggle images</label>
            <label title="Use newlines instead of spaces to separate flagged tests"><input id="use-newlines" type="checkbox" checked onchange="controller.handleToggleUseNewlines()">Use newlines in flagged list</label>
        </div>
    </div>

<div id="main-content"></div>

</body>
