File size: 2,842 Bytes
f555b43
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
// 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('[aria-label="Clear"]')?.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());
  }
}

window.document.addEventListener("dragover", (e) => {
  const target = e.composedPath()[0];
  const imgWrap = target.closest('[data-testid="image"]');
  if (
    !imgWrap &&
    target.placeholder &&
    target.placeholder.indexOf("Prompt") == -1
  ) {
    return;
  }
  e.stopPropagation();
  e.preventDefault();
  e.dataTransfer.dropEffect = "copy";
});

window.document.addEventListener("drop", (e) => {
  const target = e.composedPath()[0];
  if (target.placeholder.indexOf("Prompt") == -1) {
    return;
  }
  const imgWrap = target.closest('[data-testid="image"]');
  if (!imgWrap) {
    return;
  }
  e.stopPropagation();
  e.preventDefault();
  const files = e.dataTransfer.files;
  dropReplaceImage(imgWrap, files);

});

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

  const visibleImageFields = [
    ...gradioApp().querySelectorAll('[data-testid="image"]'),
  ].filter((el) => uiElementIsVisible(el));
  if (!visibleImageFields.length) {
    return;
  }

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

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