<!DOCTYPE html>
<html>
<head>
<script>
function assertEq(left, right)
{
    if (left === right)
        log('PASS: ' + left + " === " + right);
    else
        log('FAIL: ' + left + "(of type " + (typeof left) + ") !== " + right + "(of type " + (typeof right) + ")");
}
function log(str)
{
    var result = document.getElementById('result');
    result.appendChild(document.createTextNode(str));
    result.appendChild(document.createElement('br'));
}

function legacyCopyStart(dataTransfer)
{
    dataTransfer.setData('text', 'sample');
    dataTransfer.setData('url', 'http://www.google.com/');
    dataTransfer.setData('text/html', '<em>Markup</em>');
    dataTransfer.setData('custom-data', 'hello world');
}

function itemListCopyStart(dataTransfer)
{
    dataTransfer.items.add('sample', 'text/plain');
    dataTransfer.items.add('http://www.google.com/', 'text/uri-list');
    dataTransfer.items.add('<em>Markup</em>', 'text/html');
    dataTransfer.items.add('hello world', 'custom-data');
}

function copy(event)
{
    event.preventDefault();
    var copyMethod = document.getElementById('copyMethod');
    if (copyMethod.selectedIndex == 0)
        legacyCopyStart(event.clipboardData);
    else if (copyMethod.selectedIndex == 1)
        itemListCopyStart(event.clipboardData);
}

function legacyPaste(dataTransfer)
{
    assertEq(4, dataTransfer.types.length);
     if (dataTransfer.types.indexOf('text/plain') < 0)
        log('FAIL: types array did not contain "text"');
    if (dataTransfer.types.indexOf('text/uri-list') < 0)
        log('FAIL: types array did not contain "text/uri-list"');
    if (dataTransfer.types.indexOf('text/html') < 0)
        log('FAIL: types array did not contain "text/html"');
     if (dataTransfer.types.indexOf('custom-data') < 0)
        log('FAIL: types array did not contain "custom-data"');
    assertEq('sample', dataTransfer.getData('text'));
    assertEq('http://www.google.com/', dataTransfer.getData('url'));
    assertEq('<em>Markup</em>', dataTransfer.getData('text/html'));
    assertEq('hello world', dataTransfer.getData('custom-data'));
    runNext();
}

var outstandingRequests;
function itemListPaste(dataTransfer)
{
    outstandingRequests = 0;
    assertEq(4, dataTransfer.items.length);
    var types = [];
    for (var i = 0; i < dataTransfer.items.length; ++i) {
        types.push({kind: dataTransfer.items[i].kind, type: dataTransfer.items[i].type});
    }
    types.sort(function (a, b) { return a.type.localeCompare(b.type); });
    var expectedTypes = [
        { kind: 'string', type: 'custom-data'},
        { kind: 'string', type: 'text/html'},
        { kind: 'string', type: 'text/plain'},
        { kind: 'string', type: 'text/uri-list'},
    ];
    assertEq(JSON.stringify(expectedTypes), JSON.stringify(types));
    var expectedResults = {
        'custom-data': 'hello world',
        'text/html': '<em>Markup</em>',
        'text/plain': 'sample',
        'text/uri-list': 'http://www.google.com/',
    }
    function makeClosure(expectedData)
    {
        ++outstandingRequests;
        return function (data) {
            assertEq(expectedData, data);
            if (--outstandingRequests == 0)
                window.setTimeout(runNext, 0);
        }
    }
    // We use this funky loop to make sure we always print out results in the same order.
    for (var i = 0; i < types.length; ++i) {
        for (var j = 0; j < dataTransfer.items.length; ++j) {
            if (types[i].type == dataTransfer.items[j].type) {
                dataTransfer.items[j].getAsString(makeClosure(expectedResults[types[i].type]));
                break;
            }
        }
    }
}

function paste(event)
{
    var pasteMethod= document.getElementById('pasteMethod');
    if (pasteMethod.selectedIndex == 0)
        legacyPaste(event.clipboardData);
    else if (pasteMethod.selectedIndex == 1)
        itemListPaste(event.clipboardData);
}

function runTest(copyMethodIndex, pasteMethodIndex)
{
    var copyMethod = document.getElementById('copyMethod');
    var pasteMethod = document.getElementById('pasteMethod');
    copyMethod.selectedIndex = copyMethodIndex;
    pasteMethod.selectedIndex = pasteMethodIndex;
    log('Running test with ' + copyMethod.value + ' copy handler and ' + pasteMethod.value + ' paste handler');

    document.execCommand('copy');
    document.execCommand('paste');
}

var testCases = [
    [0, 0],
    [0, 1],
    [1, 0],
    [1, 1],
];
function runNext()
{
    if (!window.testRunner)
        return;
    var testCase = testCases.shift();
    if (testCase)
        runTest.apply(null, testCase);
    else
        testRunner.notifyDone();
}

window.onload = function()
{
    if (!window.testRunner)
        return;
    testRunner.dumpAsText();
    testRunner.waitUntilDone();

    runNext();
}
</script>
</head>
<body oncopy="copy(event)" onpaste="paste(event)">
<p>To manually test, press your browser shortcut for copy and then for paste.  Several lines that say 'PASS' should appear below.
<div>Copy handler: <select id="copyMethod"><option>Legacy</option><option>DataTransferItemList</option></select></div>
<div>Paste handler: <select id="pasteMethod"><option>Legacy</option><option>DataTransferItemList</option></select></div>
<div id="result"></div>
</body>
</html>
