Skip to content
GitLab
Menu
Projects
Groups
Snippets
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Menu
Open sidebar
chenpangpang
ComfyUI
Commits
34ddbfdc
Commit
34ddbfdc
authored
Jun 15, 2023
by
reaper47
Browse files
Beautify settings dialog
parent
bb1f45d6
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
362 additions
and
196 deletions
+362
-196
web/extensions/core/colorPalette.js
web/extensions/core/colorPalette.js
+129
-112
web/extensions/core/slotDefaults.js
web/extensions/core/slotDefaults.js
+1
-1
web/scripts/ui.js
web/scripts/ui.js
+157
-79
web/style.css
web/style.css
+75
-4
No files found.
web/extensions/core/colorPalette.js
View file @
34ddbfdc
...
@@ -56,7 +56,9 @@ const colorPalettes = {
...
@@ -56,7 +56,9 @@ const colorPalettes = {
"
descrip-text
"
:
"
#999
"
,
"
descrip-text
"
:
"
#999
"
,
"
drag-text
"
:
"
#ccc
"
,
"
drag-text
"
:
"
#ccc
"
,
"
error-text
"
:
"
#ff4444
"
,
"
error-text
"
:
"
#ff4444
"
,
"
border-color
"
:
"
#4e4e4e
"
"
border-color
"
:
"
#4e4e4e
"
,
"
tr-even-bg-color
"
:
"
#222
"
,
"
tr-odd-bg-color
"
:
"
#353535
"
,
}
}
},
},
},
},
...
@@ -111,7 +113,9 @@ const colorPalettes = {
...
@@ -111,7 +113,9 @@ const colorPalettes = {
"
descrip-text
"
:
"
#444
"
,
"
descrip-text
"
:
"
#444
"
,
"
drag-text
"
:
"
#555
"
,
"
drag-text
"
:
"
#555
"
,
"
error-text
"
:
"
#F44336
"
,
"
error-text
"
:
"
#F44336
"
,
"
border-color
"
:
"
#888
"
"
border-color
"
:
"
#888
"
,
"
tr-even-bg-color
"
:
"
#f9f9f9
"
,
"
tr-odd-bg-color
"
:
"
#fff
"
,
}
}
},
},
},
},
...
@@ -165,7 +169,9 @@ const colorPalettes = {
...
@@ -165,7 +169,9 @@ const colorPalettes = {
"
descrip-text
"
:
"
#586e75
"
,
// Base01
"
descrip-text
"
:
"
#586e75
"
,
// Base01
"
drag-text
"
:
"
#839496
"
,
// Base0
"
drag-text
"
:
"
#839496
"
,
// Base0
"
error-text
"
:
"
#dc322f
"
,
// Solarized Red
"
error-text
"
:
"
#dc322f
"
,
// Solarized Red
"
border-color
"
:
"
#657b83
"
// Base00
"
border-color
"
:
"
#657b83
"
,
// Base00
"
tr-even-bg-color
"
:
"
#002b36
"
,
"
tr-odd-bg-color
"
:
"
#073642
"
,
}
}
},
},
}
}
...
@@ -194,7 +200,7 @@ app.registerExtension({
...
@@ -194,7 +200,7 @@ app.registerExtension({
const
nodeData
=
defs
[
nodeId
];
const
nodeData
=
defs
[
nodeId
];
var
inputs
=
nodeData
[
"
input
"
][
"
required
"
];
var
inputs
=
nodeData
[
"
input
"
][
"
required
"
];
if
(
nodeData
[
"
input
"
][
"
optional
"
]
!=
undefined
)
{
if
(
nodeData
[
"
input
"
][
"
optional
"
]
!=
=
undefined
)
{
inputs
=
Object
.
assign
({},
nodeData
[
"
input
"
][
"
required
"
],
nodeData
[
"
input
"
][
"
optional
"
])
inputs
=
Object
.
assign
({},
nodeData
[
"
input
"
][
"
required
"
],
nodeData
[
"
input
"
][
"
optional
"
])
}
}
...
@@ -214,7 +220,7 @@ app.registerExtension({
...
@@ -214,7 +220,7 @@ app.registerExtension({
}
}
return
types
;
return
types
;
}
;
}
function
completeColorPalette
(
colorPalette
)
{
function
completeColorPalette
(
colorPalette
)
{
var
types
=
getSlotTypes
();
var
types
=
getSlotTypes
();
...
@@ -228,7 +234,7 @@ app.registerExtension({
...
@@ -228,7 +234,7 @@ app.registerExtension({
colorPalette
.
colors
.
node_slot
=
sortObjectKeys
(
colorPalette
.
colors
.
node_slot
);
colorPalette
.
colors
.
node_slot
=
sortObjectKeys
(
colorPalette
.
colors
.
node_slot
);
return
colorPalette
;
return
colorPalette
;
}
;
}
const
getColorPaletteTemplate
=
async
()
=>
{
const
getColorPaletteTemplate
=
async
()
=>
{
let
colorPalette
=
{
let
colorPalette
=
{
...
@@ -267,31 +273,31 @@ app.registerExtension({
...
@@ -267,31 +273,31 @@ app.registerExtension({
const
addCustomColorPalette
=
async
(
colorPalette
)
=>
{
const
addCustomColorPalette
=
async
(
colorPalette
)
=>
{
if
(
typeof
(
colorPalette
)
!==
"
object
"
)
{
if
(
typeof
(
colorPalette
)
!==
"
object
"
)
{
a
pp
.
ui
.
dialog
.
show
(
"
Invalid color palette
"
);
a
lert
(
"
Invalid color palette
.
"
);
return
;
return
;
}
}
if
(
!
colorPalette
.
id
)
{
if
(
!
colorPalette
.
id
)
{
a
pp
.
ui
.
dialog
.
show
(
"
Color palette missing id
"
);
a
lert
(
"
Color palette missing id
.
"
);
return
;
return
;
}
}
if
(
!
colorPalette
.
name
)
{
if
(
!
colorPalette
.
name
)
{
a
pp
.
ui
.
dialog
.
show
(
"
Color palette missing name
"
);
a
lert
(
"
Color palette missing name
.
"
);
return
;
return
;
}
}
if
(
!
colorPalette
.
colors
)
{
if
(
!
colorPalette
.
colors
)
{
a
pp
.
ui
.
dialog
.
show
(
"
Color palette missing colors
"
);
a
lert
(
"
Color palette missing colors
.
"
);
return
;
return
;
}
}
if
(
colorPalette
.
colors
.
node_slot
&&
typeof
(
colorPalette
.
colors
.
node_slot
)
!==
"
object
"
)
{
if
(
colorPalette
.
colors
.
node_slot
&&
typeof
(
colorPalette
.
colors
.
node_slot
)
!==
"
object
"
)
{
a
pp
.
ui
.
dialog
.
show
(
"
Invalid color palette colors.node_slot
"
);
a
lert
(
"
Invalid color palette colors.node_slot
.
"
);
return
;
return
;
}
}
le
t
customColorPalettes
=
getCustomColorPalettes
();
cons
t
customColorPalettes
=
getCustomColorPalettes
();
customColorPalettes
[
colorPalette
.
id
]
=
colorPalette
;
customColorPalettes
[
colorPalette
.
id
]
=
colorPalette
;
setCustomColorPalettes
(
customColorPalettes
);
setCustomColorPalettes
(
customColorPalettes
);
...
@@ -312,7 +318,7 @@ app.registerExtension({
...
@@ -312,7 +318,7 @@ app.registerExtension({
};
};
const
deleteCustomColorPalette
=
async
(
colorPaletteId
)
=>
{
const
deleteCustomColorPalette
=
async
(
colorPaletteId
)
=>
{
le
t
customColorPalettes
=
getCustomColorPalettes
();
cons
t
customColorPalettes
=
getCustomColorPalettes
();
delete
customColorPalettes
[
colorPaletteId
];
delete
customColorPalettes
[
colorPaletteId
];
setCustomColorPalettes
(
customColorPalettes
);
setCustomColorPalettes
(
customColorPalettes
);
...
@@ -387,8 +393,7 @@ app.registerExtension({
...
@@ -387,8 +393,7 @@ app.registerExtension({
style
:
{
display
:
"
none
"
},
style
:
{
display
:
"
none
"
},
parent
:
document
.
body
,
parent
:
document
.
body
,
onchange
:
()
=>
{
onchange
:
()
=>
{
let
file
=
fileInput
.
files
[
0
];
const
file
=
fileInput
.
files
[
0
];
if
(
file
.
type
===
"
application/json
"
||
file
.
name
.
endsWith
(
"
.json
"
))
{
if
(
file
.
type
===
"
application/json
"
||
file
.
name
.
endsWith
(
"
.json
"
))
{
const
reader
=
new
FileReader
();
const
reader
=
new
FileReader
();
reader
.
onload
=
async
()
=>
{
reader
.
onload
=
async
()
=>
{
...
@@ -403,104 +408,116 @@ app.registerExtension({
...
@@ -403,104 +408,116 @@ app.registerExtension({
id
,
id
,
name
:
"
Color Palette
"
,
name
:
"
Color Palette
"
,
type
:
(
name
,
setter
,
value
)
=>
{
type
:
(
name
,
setter
,
value
)
=>
{
let
options
=
[];
const
options
=
[
...
Object
.
values
(
colorPalettes
).
map
(
c
=>
$el
(
"
option
"
,
{
for
(
const
c
in
colorPalettes
)
{
textContent
:
c
.
name
,
const
colorPalette
=
colorPalettes
[
c
];
value
:
c
.
id
,
options
.
push
(
$el
(
"
option
"
,
{
selected
:
c
.
id
===
value
textContent
:
colorPalette
.
name
,
})),
value
:
colorPalette
.
id
,
...
Object
.
values
(
getCustomColorPalettes
()).
map
(
c
=>
$el
(
"
option
"
,
{
selected
:
colorPalette
.
id
===
value
textContent
:
`
${
c
.
name
}
(custom)`
,
}));
value
:
`custom_
${
c
.
id
}
`
,
}
selected
:
`custom_
${
c
.
id
}
`
===
value
}))
,
let
customColorPalettes
=
getCustomColorPalettes
();
];
for
(
const
c
in
customColorPalettes
)
{
const
colorPalette
=
customColorPalettes
[
c
];
els
.
select
=
$el
(
"
select
"
,
{
options
.
push
(
$el
(
"
option
"
,
{
style
:
{
textContent
:
colorPalette
.
name
+
"
(custom)
"
,
marginBottom
:
"
0.15rem
"
,
value
:
"
custom_
"
+
colorPalette
.
id
,
width
:
"
100%
"
,
selected
:
"
custom_
"
+
colorPalette
.
id
===
value
},
}));
onchange
:
(
e
)
=>
{
}
setter
(
e
.
target
.
value
);
}
return
$el
(
"
div
"
,
[
},
options
)
$el
(
"
label
"
,
{
textContent
:
name
||
id
},
[
els
.
select
=
$el
(
"
select
"
,
{
return
$el
(
"
tr
"
,
[
onchange
:
(
e
)
=>
{
$el
(
"
td
"
,
[
setter
(
e
.
target
.
value
);
$el
(
"
label
"
,
{
}
for
:
id
.
replaceAll
(
"
.
"
,
"
-
"
),
},
options
)
textContent
:
"
Color palette:
"
,
}),
]),
]),
$el
(
"
input
"
,
{
$el
(
"
td
"
,
[
type
:
"
button
"
,
els
.
select
,
value
:
"
Export
"
,
$el
(
"
div
"
,
{
onclick
:
async
()
=>
{
style
:
{
const
colorPaletteId
=
app
.
ui
.
settings
.
getSettingValue
(
id
,
defaultColorPaletteId
);
display
:
"
grid
"
,
const
colorPalette
=
await
completeColorPalette
(
getColorPalette
(
colorPaletteId
));
gap
:
"
4px
"
,
const
json
=
JSON
.
stringify
(
colorPalette
,
null
,
2
);
// convert the data to a JSON string
gridAutoFlow
:
"
column
"
,
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
},
const
url
=
URL
.
createObjectURL
(
blob
);
},
[
const
a
=
$el
(
"
a
"
,
{
$el
(
"
input
"
,
{
href
:
url
,
type
:
"
button
"
,
download
:
colorPaletteId
+
"
.json
"
,
value
:
"
Export
"
,
style
:
{
display
:
"
none
"
},
onclick
:
async
()
=>
{
parent
:
document
.
body
,
const
colorPaletteId
=
app
.
ui
.
settings
.
getSettingValue
(
id
,
defaultColorPaletteId
);
});
const
colorPalette
=
await
completeColorPalette
(
getColorPalette
(
colorPaletteId
));
a
.
click
();
const
json
=
JSON
.
stringify
(
colorPalette
,
null
,
2
);
// convert the data to a JSON string
setTimeout
(
function
()
{
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
a
.
remove
();
const
url
=
URL
.
createObjectURL
(
blob
);
window
.
URL
.
revokeObjectURL
(
url
);
const
a
=
$el
(
"
a
"
,
{
},
0
);
href
:
url
,
},
download
:
colorPaletteId
+
"
.json
"
,
}),
style
:
{
display
:
"
none
"
},
$el
(
"
input
"
,
{
parent
:
document
.
body
,
type
:
"
button
"
,
});
value
:
"
Import
"
,
a
.
click
();
onclick
:
()
=>
{
setTimeout
(
function
()
{
fileInput
.
click
();
a
.
remove
();
}
window
.
URL
.
revokeObjectURL
(
url
);
}),
},
0
);
$el
(
"
input
"
,
{
},
type
:
"
button
"
,
}),
value
:
"
Template
"
,
$el
(
"
input
"
,
{
onclick
:
async
()
=>
{
type
:
"
button
"
,
const
colorPalette
=
await
getColorPaletteTemplate
();
value
:
"
Import
"
,
const
json
=
JSON
.
stringify
(
colorPalette
,
null
,
2
);
// convert the data to a JSON string
onclick
:
()
=>
{
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
fileInput
.
click
();
const
url
=
URL
.
createObjectURL
(
blob
);
}
const
a
=
$el
(
"
a
"
,
{
}),
href
:
url
,
$el
(
"
input
"
,
{
download
:
"
color_palette.json
"
,
type
:
"
button
"
,
style
:
{
display
:
"
none
"
},
value
:
"
Template
"
,
parent
:
document
.
body
,
onclick
:
async
()
=>
{
});
const
colorPalette
=
await
getColorPaletteTemplate
();
a
.
click
();
const
json
=
JSON
.
stringify
(
colorPalette
,
null
,
2
);
// convert the data to a JSON string
setTimeout
(
function
()
{
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
a
.
remove
();
const
url
=
URL
.
createObjectURL
(
blob
);
window
.
URL
.
revokeObjectURL
(
url
);
const
a
=
$el
(
"
a
"
,
{
},
0
);
href
:
url
,
}
download
:
"
color_palette.json
"
,
}),
style
:
{
display
:
"
none
"
},
$el
(
"
input
"
,
{
parent
:
document
.
body
,
type
:
"
button
"
,
});
value
:
"
Delete
"
,
a
.
click
();
onclick
:
async
()
=>
{
setTimeout
(
function
()
{
let
colorPaletteId
=
app
.
ui
.
settings
.
getSettingValue
(
id
,
defaultColorPaletteId
);
a
.
remove
();
window
.
URL
.
revokeObjectURL
(
url
);
if
(
colorPalettes
[
colorPaletteId
])
{
},
0
);
app
.
ui
.
dialog
.
show
(
"
You cannot delete built-in color palette
"
);
}
return
;
}),
}
$el
(
"
input
"
,
{
type
:
"
button
"
,
if
(
colorPaletteId
.
startsWith
(
"
custom_
"
))
{
value
:
"
Delete
"
,
colorPaletteId
=
colorPaletteId
.
substr
(
7
);
onclick
:
async
()
=>
{
}
let
colorPaletteId
=
app
.
ui
.
settings
.
getSettingValue
(
id
,
defaultColorPaletteId
);
await
deleteCustomColorPalette
(
colorPaletteId
);
if
(
colorPalettes
[
colorPaletteId
])
{
}
alert
(
"
You cannot delete a built-in color palette.
"
);
}),
return
;
]);
}
if
(
colorPaletteId
.
startsWith
(
"
custom_
"
))
{
colorPaletteId
=
colorPaletteId
.
substr
(
7
);
}
await
deleteCustomColorPalette
(
colorPaletteId
);
}
}),
]),
]),
])
},
},
defaultValue
:
defaultColorPaletteId
,
defaultValue
:
defaultColorPaletteId
,
async
onChange
(
value
)
{
async
onChange
(
value
)
{
...
...
web/extensions/core/slotDefaults.js
View file @
34ddbfdc
...
@@ -10,7 +10,7 @@ app.registerExtension({
...
@@ -10,7 +10,7 @@ app.registerExtension({
LiteGraph
.
middle_click_slot_add_default_node
=
true
;
LiteGraph
.
middle_click_slot_add_default_node
=
true
;
this
.
suggestionsNumber
=
app
.
ui
.
settings
.
addSetting
({
this
.
suggestionsNumber
=
app
.
ui
.
settings
.
addSetting
({
id
:
"
Comfy.NodeSuggestions.number
"
,
id
:
"
Comfy.NodeSuggestions.number
"
,
name
:
"
n
umber of nodes suggestions
"
,
name
:
"
N
umber of nodes suggestions
"
,
type
:
"
slider
"
,
type
:
"
slider
"
,
attrs
:
{
attrs
:
{
min
:
1
,
min
:
1
,
...
...
web/scripts/ui.js
View file @
34ddbfdc
import
{
api
}
from
"
./api.js
"
;
import
{
api
}
from
"
./api.js
"
;
export
function
$el
(
tag
,
propsOrChildren
,
children
)
{
export
function
$el
(
tag
,
propsOrChildren
,
children
)
{
const
split
=
tag
.
split
(
"
.
"
);
const
split
=
tag
.
split
(
"
.
"
);
const
element
=
document
.
createElement
(
split
.
shift
());
const
element
=
document
.
createElement
(
split
.
shift
());
element
.
classList
.
add
(...
split
);
if
(
split
.
length
>
0
)
{
element
.
classList
.
add
(...
split
);
}
if
(
propsOrChildren
)
{
if
(
propsOrChildren
)
{
if
(
Array
.
isArray
(
propsOrChildren
))
{
if
(
Array
.
isArray
(
propsOrChildren
))
{
element
.
append
(...
propsOrChildren
);
element
.
append
(...
propsOrChildren
);
}
else
{
}
else
{
const
{
parent
,
$
:
cb
,
dataset
,
style
}
=
propsOrChildren
;
const
{
parent
,
$
:
cb
,
dataset
,
style
}
=
propsOrChildren
;
delete
propsOrChildren
.
parent
;
delete
propsOrChildren
.
parent
;
delete
propsOrChildren
.
$
;
delete
propsOrChildren
.
$
;
delete
propsOrChildren
.
dataset
;
delete
propsOrChildren
.
dataset
;
delete
propsOrChildren
.
style
;
delete
propsOrChildren
.
style
;
if
(
Object
.
hasOwn
(
propsOrChildren
,
"
for
"
))
{
element
.
setAttribute
(
"
for
"
,
propsOrChildren
.
for
)
}
if
(
style
)
{
if
(
style
)
{
Object
.
assign
(
element
.
style
,
style
);
Object
.
assign
(
element
.
style
,
style
);
}
}
...
@@ -119,6 +126,7 @@ function dragElement(dragEl, settings) {
...
@@ -119,6 +126,7 @@ function dragElement(dragEl, settings) {
savePos
=
value
;
savePos
=
value
;
},
},
});
});
function
dragMouseDown
(
e
)
{
function
dragMouseDown
(
e
)
{
e
=
e
||
window
.
event
;
e
=
e
||
window
.
event
;
e
.
preventDefault
();
e
.
preventDefault
();
...
@@ -161,8 +169,8 @@ function dragElement(dragEl, settings) {
...
@@ -161,8 +169,8 @@ function dragElement(dragEl, settings) {
export
class
ComfyDialog
{
export
class
ComfyDialog
{
constructor
()
{
constructor
()
{
this
.
element
=
$el
(
"
div.comfy-modal
"
,
{
parent
:
document
.
body
},
[
this
.
element
=
$el
(
"
div.comfy-modal
"
,
{
parent
:
document
.
body
},
[
$el
(
"
div.comfy-modal-content
"
,
[
$el
(
"
p
"
,
{
$
:
(
p
)
=>
(
this
.
textElement
=
p
)
}),
...
this
.
createButtons
()]),
$el
(
"
div.comfy-modal-content
"
,
[
$el
(
"
p
"
,
{
$
:
(
p
)
=>
(
this
.
textElement
=
p
)}),
...
this
.
createButtons
()]),
]);
]);
}
}
...
@@ -193,7 +201,22 @@ export class ComfyDialog {
...
@@ -193,7 +201,22 @@ export class ComfyDialog {
class
ComfySettingsDialog
extends
ComfyDialog
{
class
ComfySettingsDialog
extends
ComfyDialog
{
constructor
()
{
constructor
()
{
super
();
super
();
this
.
element
.
classList
.
add
(
"
comfy-settings
"
);
this
.
element
=
$el
(
"
dialog
"
,
{
id
:
"
comfy-settings-dialog
"
,
parent
:
document
.
body
,
},
[
$el
(
"
table.comfy-modal-content.comfy-table
"
,
[
$el
(
"
caption
"
,
{
textContent
:
"
Settings
"
}),
$el
(
"
tbody
"
,
{
$
:
(
tbody
)
=>
(
this
.
textElement
=
tbody
)}),
$el
(
"
button
"
,
{
type
:
"
button
"
,
textContent
:
"
Close
"
,
onclick
:
()
=>
{
this
.
element
.
close
();
},
}),
]),
]);
this
.
settings
=
[];
this
.
settings
=
[];
}
}
...
@@ -208,15 +231,16 @@ class ComfySettingsDialog extends ComfyDialog {
...
@@ -208,15 +231,16 @@ class ComfySettingsDialog extends ComfyDialog {
localStorage
[
settingId
]
=
JSON
.
stringify
(
value
);
localStorage
[
settingId
]
=
JSON
.
stringify
(
value
);
}
}
addSetting
({
id
,
name
,
type
,
defaultValue
,
onChange
,
attrs
=
{},
tooltip
=
""
,
})
{
addSetting
({
id
,
name
,
type
,
defaultValue
,
onChange
,
attrs
=
{},
tooltip
=
""
,})
{
if
(
!
id
)
{
if
(
!
id
)
{
throw
new
Error
(
"
Settings must have an ID
"
);
throw
new
Error
(
"
Settings must have an ID
"
);
}
}
if
(
this
.
settings
.
find
((
s
)
=>
s
.
id
===
id
))
{
if
(
this
.
settings
.
find
((
s
)
=>
s
.
id
===
id
))
{
throw
new
Error
(
"
Setting
IDs must be
unique
"
);
throw
new
Error
(
`
Setting
${
id
}
of type
${
type
}
must have a
unique
ID.`
);
}
}
const
settingId
=
"
Comfy.Settings.
"
+
id
;
const
settingId
=
`
Comfy.Settings.
${
id
}
`
;
const
v
=
localStorage
[
settingId
];
const
v
=
localStorage
[
settingId
];
let
value
=
v
==
null
?
defaultValue
:
JSON
.
parse
(
v
);
let
value
=
v
==
null
?
defaultValue
:
JSON
.
parse
(
v
);
...
@@ -234,34 +258,50 @@ class ComfySettingsDialog extends ComfyDialog {
...
@@ -234,34 +258,50 @@ class ComfySettingsDialog extends ComfyDialog {
localStorage
[
settingId
]
=
JSON
.
stringify
(
v
);
localStorage
[
settingId
]
=
JSON
.
stringify
(
v
);
value
=
v
;
value
=
v
;
};
};
value
=
this
.
getSettingValue
(
id
,
defaultValue
);
let
element
;
let
element
;
value
=
this
.
getSettingValue
(
id
,
defaultValue
);
const
htmlID
=
id
.
replaceAll
(
"
.
"
,
"
-
"
);
const
labelCell
=
$el
(
"
td
"
,
[
$el
(
"
label
"
,
{
for
:
htmlID
,
classList
:
[
tooltip
!==
""
?
"
comfy-tooltip-indicator
"
:
""
],
textContent
:
name
.
endsWith
(
"
:
"
)
?
name
:
`
${
name
}
:`
,
})
]);
if
(
typeof
type
===
"
function
"
)
{
if
(
typeof
type
===
"
function
"
)
{
element
=
type
(
name
,
setter
,
value
,
attrs
);
element
=
type
(
name
,
setter
,
value
,
attrs
);
}
else
{
}
else
{
switch
(
type
)
{
switch
(
type
)
{
case
"
boolean
"
:
case
"
boolean
"
:
element
=
$el
(
"
div
"
,
[
element
=
$el
(
"
tr
"
,
[
$el
(
"
label
"
,
{
textContent
:
name
||
id
},
[
labelCell
,
$el
(
"
td
"
,
[
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
id
:
htmlID
,
type
:
"
checkbox
"
,
type
:
"
checkbox
"
,
checked
:
!!
value
,
checked
:
value
,
oninput
:
(
e
)
=>
{
onchange
:
(
event
)
=>
{
setter
(
e
.
target
.
checked
);
const
isChecked
=
event
.
target
.
checked
;
if
(
onChange
!==
undefined
)
{
onChange
(
isChecked
)
}
this
.
setSettingValue
(
id
,
isChecked
);
},
},
...
attrs
}),
}),
]),
]),
])
;
])
break
;
break
;
case
"
number
"
:
case
"
number
"
:
element
=
$el
(
"
div
"
,
[
element
=
$el
(
"
tr
"
,
[
$el
(
"
label
"
,
{
textContent
:
name
||
id
},
[
labelCell
,
$el
(
"
td
"
,
[
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
type
,
type
,
value
,
value
,
id
:
htmlID
,
oninput
:
(
e
)
=>
{
oninput
:
(
e
)
=>
{
setter
(
e
.
target
.
value
);
setter
(
e
.
target
.
value
);
},
},
...
@@ -271,46 +311,62 @@ class ComfySettingsDialog extends ComfyDialog {
...
@@ -271,46 +311,62 @@ class ComfySettingsDialog extends ComfyDialog {
]);
]);
break
;
break
;
case
"
slider
"
:
case
"
slider
"
:
element
=
$el
(
"
div
"
,
[
element
=
$el
(
"
tr
"
,
[
$el
(
"
label
"
,
{
textContent
:
name
},
[
labelCell
,
$el
(
"
input
"
,
{
$el
(
"
td
"
,
[
type
:
"
range
"
,
$el
(
"
div
"
,
{
value
,
style
:
{
oninput
:
(
e
)
=>
{
display
:
"
grid
"
,
setter
(
e
.
target
.
value
);
gridAutoFlow
:
"
column
"
,
e
.
target
.
nextElementSibling
.
value
=
e
.
target
.
value
;
},
},
...
attrs
},
[
}),
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
...
attrs
,
type
:
"
number
"
,
value
,
value
,
type
:
"
range
"
,
oninput
:
(
e
)
=>
{
oninput
:
(
e
)
=>
{
setter
(
e
.
target
.
value
);
setter
(
e
.
target
.
value
);
e
.
target
.
previousElementSibling
.
value
=
e
.
target
.
value
;
e
.
target
.
nextElementSibling
.
value
=
e
.
target
.
value
;
},
},
...
attrs
}),
}),
$el
(
"
input
"
,
{
...
attrs
,
value
,
id
:
htmlID
,
type
:
"
number
"
,
style
:
{
maxWidth
:
"
4rem
"
},
oninput
:
(
e
)
=>
{
setter
(
e
.
target
.
value
);
e
.
target
.
previousElementSibling
.
value
=
e
.
target
.
value
;
},
}),
]),
]),
]),
]);
]);
break
;
break
;
case
"
text
"
:
default
:
default
:
console
.
warn
(
"
Unsupported setting type, defaulting to text
"
);
if
(
type
!==
"
text
"
)
{
element
=
$el
(
"
div
"
,
[
console
.
warn
(
`Unsupported setting type '
${
type
}
, defaulting to text`
);
$el
(
"
label
"
,
{
textContent
:
name
||
id
},
[
}
element
=
$el
(
"
tr
"
,
[
labelCell
,
$el
(
"
td
"
,
[
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
value
,
value
,
id
:
htmlID
,
oninput
:
(
e
)
=>
{
oninput
:
(
e
)
=>
{
setter
(
e
.
target
.
value
);
setter
(
e
.
target
.
value
);
},
},
...
attrs
...
attrs
,
}),
}),
]),
]),
]);
]);
break
;
break
;
}
}
}
}
if
(
tooltip
)
{
if
(
tooltip
)
{
element
.
title
=
tooltip
;
element
.
title
=
tooltip
;
}
}
...
@@ -330,13 +386,16 @@ class ComfySettingsDialog extends ComfyDialog {
...
@@ -330,13 +386,16 @@ class ComfySettingsDialog extends ComfyDialog {
}
}
show
()
{
show
()
{
super
.
show
();
this
.
textElement
.
replaceChildren
(
Object
.
assign
(
this
.
textElement
.
style
,
{
$el
(
"
tr
"
,
{
display
:
"
flex
"
,
style
:
{
display
:
"
none
"
},
flexDirection
:
"
column
"
,
},
[
gap
:
"
10px
"
$el
(
"
th
"
),
});
$el
(
"
th
"
,
{
style
:
{
width
:
"
33%
"
}})
this
.
textElement
.
replaceChildren
(...
this
.
settings
.
map
((
s
)
=>
s
.
render
()));
]),
...
this
.
settings
.
map
((
s
)
=>
s
.
render
()),
)
this
.
element
.
showModal
();
}
}
}
}
...
@@ -369,7 +428,7 @@ class ComfyList {
...
@@ -369,7 +428,7 @@ class ComfyList {
name
:
"
Delete
"
,
name
:
"
Delete
"
,
cb
:
()
=>
api
.
deleteItem
(
this
.
#
type
,
item
.
prompt
[
1
]),
cb
:
()
=>
api
.
deleteItem
(
this
.
#
type
,
item
.
prompt
[
1
]),
};
};
return
$el
(
"
div
"
,
{
textContent
:
item
.
prompt
[
0
]
+
"
:
"
},
[
return
$el
(
"
div
"
,
{
textContent
:
item
.
prompt
[
0
]
+
"
:
"
},
[
$el
(
"
button
"
,
{
$el
(
"
button
"
,
{
textContent
:
"
Load
"
,
textContent
:
"
Load
"
,
onclick
:
()
=>
{
onclick
:
()
=>
{
...
@@ -398,7 +457,7 @@ class ComfyList {
...
@@ -398,7 +457,7 @@ class ComfyList {
await
this
.
load
();
await
this
.
load
();
},
},
}),
}),
$el
(
"
button
"
,
{
textContent
:
"
Refresh
"
,
onclick
:
()
=>
this
.
load
()
}),
$el
(
"
button
"
,
{
textContent
:
"
Refresh
"
,
onclick
:
()
=>
this
.
load
()}),
])
])
);
);
}
}
...
@@ -475,8 +534,8 @@ export class ComfyUI {
...
@@ -475,8 +534,8 @@ export class ComfyUI {
*/
*/
const
previewImage
=
this
.
settings
.
addSetting
({
const
previewImage
=
this
.
settings
.
addSetting
({
id
:
"
Comfy.PreviewFormat
"
,
id
:
"
Comfy.PreviewFormat
"
,
name
:
"
When displaying a preview in the image widget, convert it to a lightweight image.
(
webp, jpeg, webp;50,
...)
"
,
name
:
"
When displaying a preview in the image widget, convert it to a lightweight image
, e.g
. webp, jpeg, webp;50,
etc.
"
,
type
:
"
string
"
,
type
:
"
text
"
,
defaultValue
:
""
,
defaultValue
:
""
,
});
});
...
@@ -484,18 +543,25 @@ export class ComfyUI {
...
@@ -484,18 +543,25 @@ export class ComfyUI {
id
:
"
comfy-file-input
"
,
id
:
"
comfy-file-input
"
,
type
:
"
file
"
,
type
:
"
file
"
,
accept
:
"
.json,image/png,.latent
"
,
accept
:
"
.json,image/png,.latent
"
,
style
:
{
display
:
"
none
"
},
style
:
{
display
:
"
none
"
},
parent
:
document
.
body
,
parent
:
document
.
body
,
onchange
:
()
=>
{
onchange
:
()
=>
{
app
.
handleFile
(
fileInput
.
files
[
0
]);
app
.
handleFile
(
fileInput
.
files
[
0
]);
},
},
});
});
this
.
menuContainer
=
$el
(
"
div.comfy-menu
"
,
{
parent
:
document
.
body
},
[
this
.
menuContainer
=
$el
(
"
div.comfy-menu
"
,
{
parent
:
document
.
body
},
[
$el
(
"
div.drag-handle
"
,
{
style
:
{
overflow
:
"
hidden
"
,
position
:
"
relative
"
,
width
:
"
100%
"
,
cursor
:
"
default
"
}
},
[
$el
(
"
div.drag-handle
"
,
{
style
:
{
overflow
:
"
hidden
"
,
position
:
"
relative
"
,
width
:
"
100%
"
,
cursor
:
"
default
"
}
},
[
$el
(
"
span.drag-handle
"
),
$el
(
"
span.drag-handle
"
),
$el
(
"
span
"
,
{
$
:
(
q
)
=>
(
this
.
queueSize
=
q
)
}),
$el
(
"
span
"
,
{
$
:
(
q
)
=>
(
this
.
queueSize
=
q
)}),
$el
(
"
button.comfy-settings-btn
"
,
{
textContent
:
"
⚙️
"
,
onclick
:
()
=>
this
.
settings
.
show
()
}),
$el
(
"
button.comfy-settings-btn
"
,
{
textContent
:
"
⚙️
"
,
onclick
:
()
=>
this
.
settings
.
show
()}),
]),
]),
$el
(
"
button.comfy-queue-btn
"
,
{
$el
(
"
button.comfy-queue-btn
"
,
{
id
:
"
queue-button
"
,
id
:
"
queue-button
"
,
...
@@ -503,7 +569,7 @@ export class ComfyUI {
...
@@ -503,7 +569,7 @@ export class ComfyUI {
onclick
:
()
=>
app
.
queuePrompt
(
0
,
this
.
batchCount
),
onclick
:
()
=>
app
.
queuePrompt
(
0
,
this
.
batchCount
),
}),
}),
$el
(
"
div
"
,
{},
[
$el
(
"
div
"
,
{},
[
$el
(
"
label
"
,
{
innerHTML
:
"
Extra options
"
},
[
$el
(
"
label
"
,
{
innerHTML
:
"
Extra options
"
},
[
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
type
:
"
checkbox
"
,
type
:
"
checkbox
"
,
onchange
:
(
i
)
=>
{
onchange
:
(
i
)
=>
{
...
@@ -514,14 +580,14 @@ export class ComfyUI {
...
@@ -514,14 +580,14 @@ export class ComfyUI {
}),
}),
]),
]),
]),
]),
$el
(
"
div
"
,
{
id
:
"
extraOptions
"
,
style
:
{
width
:
"
100%
"
,
display
:
"
none
"
}
},
[
$el
(
"
div
"
,
{
id
:
"
extraOptions
"
,
style
:
{
width
:
"
100%
"
,
display
:
"
none
"
}
},
[
$el
(
"
label
"
,
{
innerHTML
:
"
Batch count
"
},
[
$el
(
"
label
"
,
{
innerHTML
:
"
Batch count
"
},
[
$el
(
"
input
"
,
{
$el
(
"
input
"
,
{
id
:
"
batchCountInputNumber
"
,
id
:
"
batchCountInputNumber
"
,
type
:
"
number
"
,
type
:
"
number
"
,
value
:
this
.
batchCount
,
value
:
this
.
batchCount
,
min
:
"
1
"
,
min
:
"
1
"
,
style
:
{
width
:
"
35%
"
,
"
margin-left
"
:
"
0.4em
"
},
style
:
{
width
:
"
35%
"
,
"
margin-left
"
:
"
0.4em
"
},
oninput
:
(
i
)
=>
{
oninput
:
(
i
)
=>
{
this
.
batchCount
=
i
.
target
.
value
;
this
.
batchCount
=
i
.
target
.
value
;
document
.
getElementById
(
"
batchCountInputRange
"
).
value
=
this
.
batchCount
;
document
.
getElementById
(
"
batchCountInputRange
"
).
value
=
this
.
batchCount
;
...
@@ -547,7 +613,11 @@ export class ComfyUI {
...
@@ -547,7 +613,11 @@ export class ComfyUI {
]),
]),
]),
]),
$el
(
"
div.comfy-menu-btns
"
,
[
$el
(
"
div.comfy-menu-btns
"
,
[
$el
(
"
button
"
,
{
id
:
"
queue-front-button
"
,
textContent
:
"
Queue Front
"
,
onclick
:
()
=>
app
.
queuePrompt
(
-
1
,
this
.
batchCount
)
}),
$el
(
"
button
"
,
{
id
:
"
queue-front-button
"
,
textContent
:
"
Queue Front
"
,
onclick
:
()
=>
app
.
queuePrompt
(
-
1
,
this
.
batchCount
)
}),
$el
(
"
button
"
,
{
$el
(
"
button
"
,
{
$
:
(
b
)
=>
(
this
.
queue
.
button
=
b
),
$
:
(
b
)
=>
(
this
.
queue
.
button
=
b
),
id
:
"
comfy-view-queue-button
"
,
id
:
"
comfy-view-queue-button
"
,
...
@@ -582,12 +652,12 @@ export class ComfyUI {
...
@@ -582,12 +652,12 @@ export class ComfyUI {
}
}
}
}
const
json
=
JSON
.
stringify
(
app
.
graph
.
serialize
(),
null
,
2
);
// convert the data to a JSON string
const
json
=
JSON
.
stringify
(
app
.
graph
.
serialize
(),
null
,
2
);
// convert the data to a JSON string
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
const
blob
=
new
Blob
([
json
],
{
type
:
"
application/json
"
});
const
url
=
URL
.
createObjectURL
(
blob
);
const
url
=
URL
.
createObjectURL
(
blob
);
const
a
=
$el
(
"
a
"
,
{
const
a
=
$el
(
"
a
"
,
{
href
:
url
,
href
:
url
,
download
:
filename
,
download
:
filename
,
style
:
{
display
:
"
none
"
},
style
:
{
display
:
"
none
"
},
parent
:
document
.
body
,
parent
:
document
.
body
,
});
});
a
.
click
();
a
.
click
();
...
@@ -597,25 +667,33 @@ export class ComfyUI {
...
@@ -597,25 +667,33 @@ export class ComfyUI {
},
0
);
},
0
);
},
},
}),
}),
$el
(
"
button
"
,
{
id
:
"
comfy-load-button
"
,
textContent
:
"
Load
"
,
onclick
:
()
=>
fileInput
.
click
()
}),
$el
(
"
button
"
,
{
id
:
"
comfy-load-button
"
,
textContent
:
"
Load
"
,
onclick
:
()
=>
fileInput
.
click
()}),
$el
(
"
button
"
,
{
id
:
"
comfy-refresh-button
"
,
textContent
:
"
Refresh
"
,
onclick
:
()
=>
app
.
refreshComboInNodes
()
}),
$el
(
"
button
"
,
{
$el
(
"
button
"
,
{
id
:
"
comfy-clipspace-button
"
,
textContent
:
"
Clipspace
"
,
onclick
:
()
=>
app
.
openClipspace
()
}),
id
:
"
comfy-refresh-button
"
,
$el
(
"
button
"
,
{
id
:
"
comfy-clear-button
"
,
textContent
:
"
Clear
"
,
onclick
:
()
=>
{
textContent
:
"
Refresh
"
,
if
(
!
confirmClear
.
value
||
confirm
(
"
Clear workflow?
"
))
{
onclick
:
()
=>
app
.
refreshComboInNodes
()
app
.
clean
();
}),
app
.
graph
.
clear
();
$el
(
"
button
"
,
{
id
:
"
comfy-clipspace-button
"
,
textContent
:
"
Clipspace
"
,
onclick
:
()
=>
app
.
openClipspace
()}),
$el
(
"
button
"
,
{
id
:
"
comfy-clear-button
"
,
textContent
:
"
Clear
"
,
onclick
:
()
=>
{
if
(
!
confirmClear
.
value
||
confirm
(
"
Clear workflow?
"
))
{
app
.
clean
();
app
.
graph
.
clear
();
}
}
}
}}),
}),
$el
(
"
button
"
,
{
id
:
"
comfy-load-default-button
"
,
textContent
:
"
Load Default
"
,
onclick
:
()
=>
{
$el
(
"
button
"
,
{
if
(
!
confirmClear
.
value
||
confirm
(
"
Load default workflow?
"
))
{
id
:
"
comfy-load-default-button
"
,
textContent
:
"
Load Default
"
,
onclick
:
()
=>
{
app
.
loadGraphData
()
if
(
!
confirmClear
.
value
||
confirm
(
"
Load default workflow?
"
))
{
app
.
loadGraphData
()
}
}
}
}
}),
}),
]);
]);
dragElement
(
this
.
menuContainer
,
this
.
settings
);
dragElement
(
this
.
menuContainer
,
this
.
settings
);
this
.
setStatus
({
exec_info
:
{
queue_remaining
:
"
X
"
}
});
this
.
setStatus
({
exec_info
:
{
queue_remaining
:
"
X
"
}
});
}
}
setStatus
(
status
)
{
setStatus
(
status
)
{
...
...
web/style.css
View file @
34ddbfdc
...
@@ -8,6 +8,8 @@
...
@@ -8,6 +8,8 @@
--drag-text
:
#ccc
;
--drag-text
:
#ccc
;
--error-text
:
#ff4444
;
--error-text
:
#ff4444
;
--border-color
:
#4e4e4e
;
--border-color
:
#4e4e4e
;
--tr-even-bg-color
:
#222
;
--tr-odd-bg-color
:
#353535
;
}
}
@media
(
prefers-color-scheme
:
dark
)
{
@media
(
prefers-color-scheme
:
dark
)
{
...
@@ -220,7 +222,7 @@ button.comfy-queue-btn {
...
@@ -220,7 +222,7 @@ button.comfy-queue-btn {
margin
:
6px
0
!important
;
margin
:
6px
0
!important
;
}
}
.comfy-modal.comfy-settings
,
.comfy-modal.comfy-settings
,
.comfy-modal.comfy-manage-templates
{
.comfy-modal.comfy-manage-templates
{
text-align
:
center
;
text-align
:
center
;
font-family
:
sans-serif
;
font-family
:
sans-serif
;
...
@@ -246,6 +248,11 @@ button.comfy-queue-btn {
...
@@ -246,6 +248,11 @@ button.comfy-queue-btn {
font-size
:
inherit
;
font-size
:
inherit
;
}
}
.comfy-tooltip-indicator
{
text-decoration
:
underline
;
text-decoration-style
:
dashed
;
}
@media
only
screen
and
(
max-height
:
850px
)
{
@media
only
screen
and
(
max-height
:
850px
)
{
.comfy-menu
{
.comfy-menu
{
top
:
0
!important
;
top
:
0
!important
;
...
@@ -254,8 +261,9 @@ button.comfy-queue-btn {
...
@@ -254,8 +261,9 @@ button.comfy-queue-btn {
right
:
0
!important
;
right
:
0
!important
;
border-radius
:
0
;
border-radius
:
0
;
}
}
.comfy-menu
span
.drag-handle
{
.comfy-menu
span
.drag-handle
{
visibility
:
hidden
visibility
:
hidden
}
}
}
}
...
@@ -287,11 +295,74 @@ button.comfy-queue-btn {
...
@@ -287,11 +295,74 @@ button.comfy-queue-btn {
border-radius
:
12px
0
0
12px
;
border-radius
:
12px
0
0
12px
;
}
}
/* Dialogs */
dialog
{
box-shadow
:
0
0
20px
#888888
;
}
dialog
::backdrop
{
background
:
rgba
(
0
,
0
,
0
,
0.5
);
}
#comfy-settings-dialog
{
padding
:
0
;
width
:
41rem
;
}
#comfy-settings-dialog
tr
>
td
:first-child
{
text-align
:
right
;
}
#comfy-settings-dialog
button
{
background-color
:
var
(
--bg-color
);
border
:
1px
var
(
--border-color
)
solid
;
border-radius
:
0
;
color
:
var
(
--input-text
);
font-size
:
1rem
;
padding
:
0.5rem
;
}
#comfy-settings-dialog
button
:hover
{
background-color
:
var
(
--tr-odd-bg-color
);
}
/* General CSS for tables */
.comfy-table
{
border-collapse
:
collapse
;
color
:
var
(
--input-text
);
font-family
:
Arial
,
sans-serif
;
width
:
100%
;
}
.comfy-table
caption
{
background-color
:
var
(
--bg-color
);
color
:
var
(
--input-text
);
font-size
:
1rem
;
font-weight
:
bold
;
padding
:
8px
;
text-align
:
center
;
}
.comfy-table
tr
:nth-child
(
even
)
{
background-color
:
var
(
--tr-even-bg-color
);
}
.comfy-table
tr
:nth-child
(
odd
)
{
background-color
:
var
(
--tr-odd-bg-color
);
}
td
,
th
{
border
:
1px
solid
var
(
--border-color
);
padding
:
8px
;
}
/* Context menu */
/* Context menu */
.litegraph
.dialog
{
.litegraph
.dialog
{
z-index
:
1
;
z-index
:
1
;
font-family
:
Arial
,
sans-serif
;
font-family
:
Arial
,
sans-serif
;
}
}
.litegraph
.litemenu-entry.has_submenu
{
.litegraph
.litemenu-entry.has_submenu
{
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
.
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment