File size: 4,221 Bytes
2540f3b
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
// allows drag-dropping files into gradio image elements, and also pasting images from clipboard

function isValidImageList(files) {
    return files && files?.length === 1 && ['image/png', 'image/gif', 'image/jpeg'].includes(files[0].type);
}

function dropReplaceImage(imgWrap, files) {
    if (!isValidImageList(files)) {
        return;
    }

    const tmpFile = files[0];

    imgWrap.querySelector('.modify-upload button + button, .touch-none + div button + button')?.click();
    const callback = () => {
        const fileInput = imgWrap.querySelector('input[type="file"]');
        if (fileInput) {
            if (files.length === 0) {
                files = new DataTransfer();
                files.items.add(tmpFile);
                fileInput.files = files.files;
            } else {
                fileInput.files = files;
            }
            fileInput.dispatchEvent(new Event('change'));
        }
    };

    if (imgWrap.closest('#pnginfo_image')) {
        // special treatment for PNG Info tab, wait for fetch request to finish
        const oldFetch = window.fetch;
        window.fetch = async(input, options) => {
            const response = await oldFetch(input, options);
            if ('api/predict/' === input) {
                const content = await response.text();
                window.fetch = oldFetch;
                window.requestAnimationFrame(() => callback());
                return new Response(content, {
                    status: response.status,
                    statusText: response.statusText,
                    headers: response.headers
                });
            }
            return response;
        };
    } else {
        window.requestAnimationFrame(() => callback());
    }
}

function eventHasFiles(e) {
    if (!e.dataTransfer || !e.dataTransfer.files) return false;
    if (e.dataTransfer.files.length > 0) return true;
    if (e.dataTransfer.items.length > 0 && e.dataTransfer.items[0].kind == "file") return true;

    return false;
}

function dragDropTargetIsPrompt(target) {
    if (target?.placeholder && target?.placeholder.indexOf("Prompt") >= 0) return true;
    if (target?.parentNode?.parentNode?.className?.indexOf("prompt") > 0) return true;
    return false;
}

window.document.addEventListener('dragover', e => {
    const target = e.composedPath()[0];
    if (!eventHasFiles(e)) return;

    var targetImage = target.closest('[data-testid="image"]');
    if (!dragDropTargetIsPrompt(target) && !targetImage) return;

    e.stopPropagation();
    e.preventDefault();
    e.dataTransfer.dropEffect = 'copy';
});

window.document.addEventListener('drop', e => {
    const target = e.composedPath()[0];
    if (!eventHasFiles(e)) return;

    if (dragDropTargetIsPrompt(target)) {
        e.stopPropagation();
        e.preventDefault();

        let prompt_target = get_tab_index('tabs') == 1 ? "img2img_prompt_image" : "txt2img_prompt_image";

        const imgParent = gradioApp().getElementById(prompt_target);
        const files = e.dataTransfer.files;
        const fileInput = imgParent.querySelector('input[type="file"]');
        if (fileInput) {
            fileInput.files = files;
            fileInput.dispatchEvent(new Event('change'));
        }
    }

    var targetImage = target.closest('[data-testid="image"]');
    if (targetImage) {
        e.stopPropagation();
        e.preventDefault();
        const files = e.dataTransfer.files;
        dropReplaceImage(targetImage, files);
        return;
    }
});

window.addEventListener('paste', e => {
    const files = e.clipboardData.files;
    if (!isValidImageList(files)) {
        return;
    }

    const visibleImageFields = [...gradioApp().querySelectorAll('[data-testid="image"]')]
        .filter(el => uiElementIsVisible(el))
        .sort((a, b) => uiElementInSight(b) - uiElementInSight(a));


    if (!visibleImageFields.length) {
        return;
    }

    const firstFreeImageField = visibleImageFields
        .filter(el => el.querySelector('input[type=file]'))?.[0];

    dropReplaceImage(
        firstFreeImageField ?
            firstFreeImageField :
            visibleImageFields[visibleImageFields.length - 1]
        , files
    );
});