mirror of
https://seed.radicle.dev/rad:z4D5UCArafTzTQpDZNQRuqswh3ury.git
synced 2026-10-24 05:50:35 +08:00
78 lines
2.5 KiB
TypeScript
78 lines
2.5 KiB
TypeScript
import { beforeAll, describe, expect, test } from "vitest";
|
|
|
|
import { disableDropNavigation } from "@app/lib/disableDropNavigation";
|
|
|
|
// happy-dom's DragEvent ignores `dataTransfer`, so it is attached by hand.
|
|
function drag(type: "dragover" | "drop", target: Element, types: string[]) {
|
|
const dataTransfer = { types, dropEffect: "copy" };
|
|
const event = new DragEvent(type, { bubbles: true, cancelable: true });
|
|
Object.defineProperty(event, "dataTransfer", { value: dataTransfer });
|
|
target.dispatchEvent(event);
|
|
return {
|
|
prevented: event.defaultPrevented,
|
|
dropEffect: dataTransfer.dropEffect,
|
|
};
|
|
}
|
|
|
|
function element(html: string): Element {
|
|
const template = document.createElement("template");
|
|
template.innerHTML = html;
|
|
const node = template.content.firstElementChild as Element;
|
|
document.body.append(node);
|
|
return node;
|
|
}
|
|
|
|
beforeAll(() => {
|
|
disableDropNavigation();
|
|
});
|
|
|
|
describe("disableDropNavigation", () => {
|
|
test.each([
|
|
["a link", ["text/uri-list", "text/plain"]],
|
|
["a file", ["Files"]],
|
|
])("refuses %s dropped on the page", (_, types) => {
|
|
const page = element("<div>page</div>");
|
|
expect(drag("dragover", page, types)).toEqual({
|
|
prevented: true,
|
|
dropEffect: "none",
|
|
});
|
|
expect(drag("drop", page, types).prevented).toBe(true);
|
|
});
|
|
|
|
test.each([
|
|
["a textarea", "<textarea></textarea>"],
|
|
["an input", "<input>"],
|
|
["an editable element", '<div contenteditable="true">x</div>'],
|
|
])("leaves text dropped into %s to the webview", (_, html) => {
|
|
const field = element(html);
|
|
const types = ["text/plain"];
|
|
expect(drag("dragover", field, types)).toEqual({
|
|
prevented: false,
|
|
dropEffect: "copy",
|
|
});
|
|
expect(drag("drop", field, types).prevented).toBe(false);
|
|
});
|
|
|
|
test("refuses text dropped on an element that isn't editable", () => {
|
|
const field = element('<div contenteditable="false">x</div>');
|
|
expect(drag("drop", field, ["text/plain"]).prevented).toBe(true);
|
|
});
|
|
|
|
test("refuses a file over a field that didn't accept it", () => {
|
|
const field = element("<textarea></textarea>");
|
|
expect(drag("dragover", field, ["Files"])).toEqual({
|
|
prevented: true,
|
|
dropEffect: "none",
|
|
});
|
|
});
|
|
|
|
test("keeps the drop effect of a field that accepted the file", () => {
|
|
const field = element("<div></div>");
|
|
field.addEventListener("dragover", event => event.preventDefault());
|
|
expect(drag("dragover", field, ["Files"])).toEqual({
|
|
prevented: true,
|
|
dropEffect: "copy",
|
|
});
|
|
});
|
|
});
|