|
1 |
| -import { app } from "../../scripts/app.js"; |
2 | 1 | import { api } from "../../scripts/api.js";
|
| 2 | +import { app } from "../../scripts/app.js"; |
3 | 3 | import { $el } from "../../scripts/ui.js";
|
4 | 4 |
|
5 |
| -app.registerExtension({ |
| 5 | +const extension = { |
6 | 6 | name: "Comfy.SaveAsScript",
|
| 7 | +commands: [ |
| 8 | +{ |
| 9 | +id: "triggerSaveAsScript", |
| 10 | +label: "Save As Script", |
| 11 | +function: () => { extension.savePythonScript(); } |
| 12 | +} |
| 13 | +], |
| 14 | +menuCommands: [ |
| 15 | +{ |
| 16 | +path: ["File"], |
| 17 | +commands: ["triggerSaveAsScript"] |
| 18 | +} |
| 19 | +], |
7 | 20 | init() {
|
8 | 21 | $el("style", {
|
9 | 22 | parent: document.head,
|
10 | 23 | });
|
11 | 24 | },
|
12 |
| -async setup() { |
13 |
| -function savePythonScript() { |
14 |
| -var filename = prompt("Save script as:"); |
15 |
| -if(filename === undefined || filename === null || filename === "") { |
16 |
| -return |
17 |
| -} |
18 |
| - |
19 |
| -app.graphToPrompt().then(async (p) => { |
20 |
| -const json = JSON.stringify({name: filename + ".json", workflow: JSON.stringify(p.output, null, 2)}, null, 2); // convert the data to a JSON string |
21 |
| -var response = await api.fetchApi(`/saveasscript`, { method: "POST", body: json }); |
22 |
| -if(response.status == 200) { |
23 |
| -const blob = new Blob([await response.text()], {type: "text/python;charset=utf-8"}); |
24 |
| -const url = URL.createObjectURL(blob); |
25 |
| -if(!filename.endsWith(".py")) { |
26 |
| -filename += ".py"; |
27 |
| -} |
28 |
| - |
29 |
| -const a = $el("a", { |
30 |
| -href: url, |
31 |
| -download: filename, |
32 |
| -style: {display: "none"}, |
33 |
| -parent: document.body, |
34 |
| -}); |
35 |
| -a.click(); |
36 |
| -setTimeout(function () { |
37 |
| -a.remove(); |
38 |
| -window.URL.revokeObjectURL(url); |
39 |
| -}, 0); |
40 |
| -} |
41 |
| -}); |
| 25 | +savePythonScript() { |
| 26 | +var filename = prompt("Save script as:"); |
| 27 | +if(filename === undefined || filename === null || filename === "") { |
| 28 | +return |
42 | 29 | }
|
| 30 | + |
| 31 | +app.graphToPrompt().then(async (p) => { |
| 32 | +const json = JSON.stringify({name: filename + ".json", workflow: JSON.stringify(p.output, null, 2)}, null, 2); // convert the data to a JSON string |
| 33 | +var response = await api.fetchApi(`/saveasscript`, { method: "POST", body: json }); |
| 34 | +if(response.status == 200) { |
| 35 | +const blob = new Blob([await response.text()], {type: "text/python;charset=utf-8"}); |
| 36 | +const url = URL.createObjectURL(blob); |
| 37 | +if(!filename.endsWith(".py")) { |
| 38 | +filename += ".py"; |
| 39 | +} |
43 | 40 |
|
44 |
| -const menu = document.querySelector(".comfy-menu"); |
45 |
| -const separator = document.createElement("hr"); |
46 |
| - |
47 |
| -separator.style.margin = "20px 0"; |
48 |
| -separator.style.width = "100%"; |
49 |
| -menu.append(separator); |
50 |
| - |
51 |
| -const saveButton = document.createElement("button"); |
52 |
| -saveButton.textContent = "Save as Script"; |
53 |
| -saveButton.onclick = () => savePythonScript(); |
54 |
| -menu.append(saveButton); |
55 |
| - |
56 |
| - |
57 |
| -// Also load to new style menu |
58 |
| -const dropdownMenu = document.querySelectorAll(".p-menubar-submenu ")[0]; |
59 |
| -// Get submenu items |
60 |
| -const listItems = dropdownMenu.querySelectorAll("li"); |
61 |
| -let newSetsize = listItems.length; |
62 |
| - |
63 |
| -const separatorMenu = document.createElement("li"); |
64 |
| -separatorMenu.setAttribute("id", "pv_id_8_0_" + (newSetsize - 1).toString()); |
65 |
| -separatorMenu.setAttribute("class", "p-menubar-separator"); |
66 |
| -separatorMenu.setAttribute("role", "separator"); |
67 |
| -separatorMenu.setAttribute("data-pc-section", "separator"); |
68 |
| - |
69 |
| -dropdownMenu.append(separatorMenu); |
70 |
| - |
71 |
| -// Adjust list items within to increase setsize |
72 |
| -listItems.forEach((item) => { |
73 |
| -// First check if it's a separator |
74 |
| -if(item.getAttribute("data-pc-section") !== "separator") { |
75 |
| -item.setAttribute("aria-setsize", newSetsize); |
| 41 | +const a = $el("a", { |
| 42 | +href: url, |
| 43 | +download: filename, |
| 44 | +style: {display: "none"}, |
| 45 | +parent: document.body, |
| 46 | +}); |
| 47 | +a.click(); |
| 48 | +setTimeout(function () { |
| 49 | +a.remove(); |
| 50 | +window.URL.revokeObjectURL(url); |
| 51 | +}, 0); |
76 | 52 | }
|
77 | 53 | });
|
78 |
| - |
79 |
| -console.log(newSetsize); |
80 |
| - |
81 |
| -// Here's the format of list items |
82 |
| -const saveButtonText = document.createElement("li"); |
83 |
| -saveButtonText.setAttribute("id", "pv_id_8_0_" + newSetsize.toString()); |
84 |
| -saveButtonText.setAttribute("class", "p-menubar-item relative"); |
85 |
| -saveButtonText.setAttribute("role", "menuitem"); |
86 |
| -saveButtonText.setAttribute("aria-label", "Save as Script"); |
87 |
| -saveButtonText.setAttribute("aria-level", "2"); |
88 |
| -saveButtonText.setAttribute("aria-setsize", newSetsize.toString()); |
89 |
| -saveButtonText.setAttribute("aria-posinset", newSetsize.toString()); |
90 |
| -saveButtonText.setAttribute("data-pc-section", "item"); |
91 |
| -saveButtonText.setAttribute("data-p-active", "false"); |
92 |
| -saveButtonText.setAttribute("data-p-focused", "false"); |
93 |
| - |
94 |
| -saveButtonText.innerHTML = ` |
95 |
| -<div class="p-menubar-item-content" data-pc-section="itemcontent"> |
96 |
| -<a class="p-menubar-item-link" tabindex="-1" aria-hidden="true" data-pc-section="itemlink" target="_blank"> |
97 |
| -<span class="p-menubar-item-icon pi pi-book"></span> |
98 |
| -<span class="p-menubar-item-label">Save as Script</span> |
99 |
| -</a> |
100 |
| -</div> |
101 |
| -` |
102 |
| - |
103 |
| -saveButtonText.onclick = () => savePythonScript(); |
104 |
| - |
105 |
| -dropdownMenu.append(saveButtonText); |
106 |
| - |
107 |
| - |
108 |
| - |
| 54 | +}, |
| 55 | +async setup() { |
109 | 56 | console.log("SaveAsScript loaded");
|
110 | 57 | }
|
111 |
| -}); |
| 58 | +}; |
| 59 | + |
| 60 | +app.registerExtension(extension); |
0 commit comments