<!DOCTYPE html>
<html>
<body>
<div id="container">
<div id="destination">3. Drop here</div>
</div>
<div id="description"></div>
<div id="console"></div>
<script src="../../resources/js-test-pre.js"></script>
<script>

description('This tests calling setData to set a html in a null origin document. The URL should be sanitized when reading in another document.<br>'
    + 'To manually test, drag and drop the "1. Drag this" above to "2. Drop here" and "3. Drop here".');
jsTestIsAsync = true;

if (window.internals)
    internals.settings.setCustomPasteboardDataEnabled(true);

const iframe = document.createElement('iframe');
const destination = document.getElementById('destination');
document.getElementById('container').prepend(iframe);

iframe.src = `data:text/html;charset=utf-8,<!DOCTYPE html>
<div id="source" draggable="true">1. Drag this</div>
<div id="destination" onpaste="paste(event)">2. Drop here</div>
<script>

const source = document.getElementById('source');
const destination = document.getElementById('destination');
const originalHTML = '<meta content="secret"><b onmouseover="dangerousCode()">hello</b><!-- secret-->, world<script>dangerousCode()</scr' + 'ipt>';
parent.postMessage({kind: 'originalHTML', originalHTML}, '*');

function postContent(kind, dataTransfer) {
    parent.postMessage({
        kind,
        documentLabel: 'the null origin document',
        html: dataTransfer.getData('text/html'),
        types: dataTransfer.types,
        items: Array.from(dataTransfer.items).map((item) => ({kind: item.kind, type: item.type})),
    }, '*');
}

let postDragOver;
source.addEventListener("dragstart", (event) => {
    postDragOver = false;
    event.dataTransfer.setData('text/html', originalHTML);
    postContent('dragstart', event.dataTransfer);
});
destination.addEventListener("dragover", (event) => {
    event.preventDefault();
    if (postDragOver)
        return;
    postDragOver = true;
    postContent('dragover', event.dataTransfer);
});
destination.addEventListener("drop", (event) => {
    postContent('drop', event.dataTransfer);
    destination.remove();
    top.postMessage({kind: 'secondDrop'}, '*');
});

if (window.eventSender) {
    const iframeOffset = {x: 10, y: 10};
    eventSender.mouseMoveTo(iframeOffset.x + source.offsetLeft + 5, iframeOffset.y + source.offsetTop + 5);
    eventSender.mouseDown();
    eventSender.leapForward(500);
    eventSender.mouseMoveTo(iframeOffset.x + destination.offsetLeft + 5, iframeOffset.y + destination.offsetTop + 5);
    eventSender.mouseUp();
}

</scri` + 'pt>';

onmessage = (event) => {
    const kind = event.data.kind;
    if (kind == 'originalHTML') {
        originalHTML = event.data.originalHTML;
        return;
    }
    if (kind == 'secondDrop')
        return doSecondDrop(event.data.postContent);
    debug(`${kind} in ${event.data.documentLabel}:`);
    switch (kind) {
    case 'dragstart':
        html = event.data.html;
        shouldBeEqualToString('html', originalHTML);
        types = event.data.types;
        shouldBeTrue('types.includes("text/html")');
        items = event.data.items;
        shouldBeTrue('items.some((item) => item.kind == "string" && item.type == "text/html")');
        break;
    case 'dragover':
        html = event.data.html;
        shouldBeEqualToString('html', '');
        types = event.data.types;
        shouldBeTrue('types.includes("text/html")');
        items = event.data.items;
        shouldBeTrue('items.some((item) => item.kind == "string" && item.type == "text/html")');
        break;
    case 'drop':
        html = event.data.html;
        if (event.data.documentLabel.includes('null'))
            shouldBeEqualToString('html', originalHTML);
        else {
            shouldBeTrue('html.includes("hello")');
            shouldBeTrue('html.includes(", world")');
            shouldBeFalse('html.includes("secret")');
            shouldBeFalse('html.includes("dangerousCode")');
        }
        types = event.data.types;
        shouldBeTrue('types.includes("text/html")');
        items = event.data.items;
        shouldBeTrue('items.some((item) => item.kind == "string" && item.type == "text/html")');
        if (!event.data.documentLabel.includes('null')) {
            document.getElementById('container').remove();
            finishJSTest();
        }
        break;
    }
    debug('');
}

function postContent(kind, dataTransfer) {
    window.postMessage({
        kind,
        documentLabel: 'the file URL document',
        html: dataTransfer.getData('text/html'),
        types: dataTransfer.types,
        items: Array.from(dataTransfer.items).map((item) => ({kind: item.kind, type: item.type})),
    }, '*');
}

let postDragOver = false;
destination.addEventListener("dragover", (event) => {
    event.preventDefault();
    if (postDragOver)
        return;
    postDragOver = true;
    postContent('dragover', event.dataTransfer);
});
destination.addEventListener("drop", (event) => {
    postContent('drop', event.dataTransfer);
});

function doSecondDrop(postContent) {
    postDragOver = false;
    if (!window.eventSender)
        return;

    eventSender.leapForward(500);
    eventSender.mouseMoveTo(iframe.offsetLeft + 10, iframe.offsetTop + 10);
    eventSender.mouseDown();
    eventSender.leapForward(500);

    const destinationRect = destination.getBoundingClientRect();
    eventSender.mouseMoveTo(destination.offsetLeft + 5, destination.offsetTop + 5);
    eventSender.mouseUp();
}

</script>
<script src="../../resources/js-test-post.js"></script>
</body>
</html>
