<!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>
if (window.testRunner)
    testRunner.dumpAsText();

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 'http://webkit-test-results.webkit.org/dashboards/flakiness_dashboard.html#showAllRuns=true&tests=' + 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();
}

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>
