mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2024-06-07 21:20:49 +00:00
fix bugs. introduce new ones.
This commit is contained in:
parent
019f6e3c5a
commit
d88424ef2a
@ -1,11 +1,22 @@
|
|||||||
<span data-filterable-item-text hidden>{search_terms}</span>
|
<span data-filterable-item-text hidden>{search_terms}</span>
|
||||||
<button class="action-list-content action-list-content-file"
|
<button class="tree-list-content {subclass}"
|
||||||
|
expanded="false"
|
||||||
type="button"
|
type="button"
|
||||||
onclick="extraNetworksTreeOnClick(event, '{tabname}', '{tab_id}');"
|
onclick="extraNetworksTreeOnClick(event, '{tabname}', '{tab_id}');{onclick_extra}"
|
||||||
>
|
>
|
||||||
<span class="action-list-item-visual action-list-item-visual--leading">🗎</span>
|
<span class='tree-list-item-action tree-list-item-action--leading'>
|
||||||
<span class="action-list-item-label action-list-item-label--truncate">{name}</span>
|
{action_list_item_action_leading}
|
||||||
<span class="action-list-item-action action-list-item-action--trailing">
|
</span>
|
||||||
<div class="button-row">{copy_path_button}{metadata_button}{edit_button}</div>
|
<span class="tree-list-item-visual tree-list-item-visual--leading">
|
||||||
|
{action_list_item_visual_leading}
|
||||||
|
</span>
|
||||||
|
<span class="tree-list-item-label tree-list-item-label--truncate">
|
||||||
|
{action_list_item_label}
|
||||||
|
</span>
|
||||||
|
<span class="tree-list-item-visual tree-list-item-visual--trailing">
|
||||||
|
{action_list_item_visual_trailing}
|
||||||
|
</span>
|
||||||
|
<span class="tree-list-item-action tree-list-item-action--trailing">
|
||||||
|
{action_list_item_action_trailing}
|
||||||
</span>
|
</span>
|
||||||
</button>
|
</button>
|
@ -267,7 +267,7 @@ function extraNetworksTreeProcessFileClick(event, btn, tabname, tab_id) {
|
|||||||
* Processes `onclick` events when user clicks on files in tree.
|
* Processes `onclick` events when user clicks on files in tree.
|
||||||
*
|
*
|
||||||
* @param event The generated event.
|
* @param event The generated event.
|
||||||
* @param btn The clicked `action-list-item` button.
|
* @param btn The clicked `tree-list-item` button.
|
||||||
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
|
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
|
||||||
* @param tab_id The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
|
* @param tab_id The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
|
||||||
*/
|
*/
|
||||||
@ -288,7 +288,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
|
|||||||
* chevron is clicked: Directory is expanded or collapsed. Selected state unchanged.
|
* chevron is clicked: Directory is expanded or collapsed. Selected state unchanged.
|
||||||
*
|
*
|
||||||
* @param event The generated event.
|
* @param event The generated event.
|
||||||
* @param btn The clicked `action-list-item` button.
|
* @param btn The clicked `tree-list-item` button.
|
||||||
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
|
* @param tabname The name of the active tab in the sd webui. Ex: txt2img, img2img, etc.
|
||||||
* @param tab_id The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
|
* @param tab_id The id of the active extraNetworks tab. Ex: lora, checkpoints, etc.
|
||||||
*/
|
*/
|
||||||
@ -310,7 +310,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
|
|||||||
|
|
||||||
function _remove_selected_from_all() {
|
function _remove_selected_from_all() {
|
||||||
// Removes the `selected` attribute from all buttons.
|
// Removes the `selected` attribute from all buttons.
|
||||||
var sels = document.querySelectorAll("button.action-list-content");
|
var sels = document.querySelectorAll("button.tree-list-content");
|
||||||
[...sels].forEach(el => {
|
[...sels].forEach(el => {
|
||||||
el.removeAttribute("selected");
|
el.removeAttribute("selected");
|
||||||
});
|
});
|
||||||
@ -331,7 +331,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
|
|||||||
|
|
||||||
|
|
||||||
// If user clicks on the chevron, then we do not select the folder.
|
// If user clicks on the chevron, then we do not select the folder.
|
||||||
if (true_targ.matches(".action-list-item-action--leading, .action-list-item-action-chevron")) {
|
if (true_targ.matches(".tree-list-item-action--leading, .tree-list-item-action-chevron")) {
|
||||||
_expand_or_collapse(ul, btn);
|
_expand_or_collapse(ul, btn);
|
||||||
} else {
|
} else {
|
||||||
// User clicked anywhere else on the button.
|
// User clicked anywhere else on the button.
|
||||||
@ -356,7 +356,7 @@ function extraNetworksTreeProcessDirectoryClick(event, btn, tabname, tab_id) {
|
|||||||
|
|
||||||
function extraNetworksTreeOnClick(event, tabname, tab_id) {
|
function extraNetworksTreeOnClick(event, tabname, tab_id) {
|
||||||
/**
|
/**
|
||||||
* Handles `onclick` events for buttons within an `extra-network-tree .action-list--tree`.
|
* Handles `onclick` events for buttons within an `extra-network-tree .tree-list--tree`.
|
||||||
*
|
*
|
||||||
* Determines whether the clicked button in the tree is for a file entry or a directory
|
* Determines whether the clicked button in the tree is for a file entry or a directory
|
||||||
* then calls the appropriate function.
|
* then calls the appropriate function.
|
||||||
|
@ -20,28 +20,28 @@ allowed_dirs = set()
|
|||||||
default_allowed_preview_extensions = ["png", "jpg", "jpeg", "webp", "gif"]
|
default_allowed_preview_extensions = ["png", "jpg", "jpeg", "webp", "gif"]
|
||||||
|
|
||||||
tree_tpl = (
|
tree_tpl = (
|
||||||
"<div class='action-list-search'>"
|
"<div class='tree-list-search'>"
|
||||||
"<input "
|
"<input "
|
||||||
"id='{tabname}_{tab_id}_extra_search' "
|
"id='{tabname}_{tab_id}_extra_search' "
|
||||||
"class='action-list-search-text' "
|
"class='tree-list-search-text' "
|
||||||
"type='search' "
|
"type='search' "
|
||||||
"placeholder='Filter files'"
|
"placeholder='Filter files'"
|
||||||
">"
|
">"
|
||||||
"</div>"
|
"</div>"
|
||||||
"<ul class='action-list action-list--tree'>"
|
"<ul class='tree-list tree-list--tree'>"
|
||||||
"{content}"
|
"{content}"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
)
|
)
|
||||||
|
|
||||||
tree_ul_tpl = (
|
tree_ul_tpl = (
|
||||||
"<ul class='action-list action-list--subgroup' data-hidden>"
|
"<ul class='tree-list tree-list--subgroup' data-hidden>"
|
||||||
"{content}"
|
"{content}"
|
||||||
"</ul>"
|
"</ul>"
|
||||||
)
|
)
|
||||||
|
|
||||||
tree_li_dir_tpl = (
|
tree_li_dir_tpl = (
|
||||||
"<li "
|
"<li "
|
||||||
"class='action-list-item action-list-item--has-subitem' "
|
"class='tree-list-item tree-list-item--has-subitem' "
|
||||||
"data-path='{path}' "
|
"data-path='{path}' "
|
||||||
"data-tree-entry-type='dir'>"
|
"data-tree-entry-type='dir'>"
|
||||||
"{content}"
|
"{content}"
|
||||||
@ -50,59 +50,19 @@ tree_li_dir_tpl = (
|
|||||||
tree_li_file_tpl = (
|
tree_li_file_tpl = (
|
||||||
"<li "
|
"<li "
|
||||||
"id='file-tree-item-{hash}' "
|
"id='file-tree-item-{hash}' "
|
||||||
"class='action-list-item action-list-item--subitem' "
|
"class='tree-list-item tree-list-item--subitem' "
|
||||||
"data-path='{path}' "
|
"data-path='{path}' "
|
||||||
"data-tree-entry-type='file'>"
|
"data-tree-entry-type='file'>"
|
||||||
"{content}"
|
"{content}"
|
||||||
"</li>"
|
"</li>"
|
||||||
)
|
)
|
||||||
|
|
||||||
tree_btn_dir_tpl = (
|
action_list_item_action_leading = (
|
||||||
"<button "
|
"<span class='tree-list-item-action tree-list-item-action--leading'>"
|
||||||
"class='action-list-content action-list-content-dir' "
|
"<i class='tree-list-item-action-chevron'></i>"
|
||||||
"type='button' "
|
|
||||||
"expanded='false' "
|
|
||||||
"onclick='extraNetworksTreeOnClick(event, \"{tabname}\", \"{tab_id}\")'>"
|
|
||||||
"<span class='action-list-item-action action-list-item-action--leading'>"
|
|
||||||
"<i class='action-list-item-action-chevron'></i>"
|
|
||||||
"</span>"
|
"</span>"
|
||||||
"<span class='action-list-item-visual action-list-item-visual--leading'>🗀</span>"
|
|
||||||
"<span class='action-list-item-label action-list-item-label--truncate'>{label}</span>"
|
|
||||||
"</button>"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
tree_btn_file_action_buttons_tpl = (
|
|
||||||
"<div "
|
|
||||||
"class='copy-path-button card-button' "
|
|
||||||
"title='Copy path to clipboard' "
|
|
||||||
"onclick='extraNetworksCopyCardPath(event, {path})' "
|
|
||||||
"data-clipboard-text={path}>"
|
|
||||||
"</div>"
|
|
||||||
"<div "
|
|
||||||
"class='metadata-button card-button' "
|
|
||||||
"title='Show internal metadata' "
|
|
||||||
"onclick='extraNetworksRequestMetadata(event, {tab_id}, {filename})'>"
|
|
||||||
"</div>"
|
|
||||||
"<div "
|
|
||||||
"class='edit-button card-button' "
|
|
||||||
"title='Edit metadata' "
|
|
||||||
"onclick='extraNetworksEditUserMetadata(event, {tabname}, {tab_id}, {filename})'>"
|
|
||||||
"</div>"
|
|
||||||
)
|
|
||||||
|
|
||||||
tree_btn_file_tpl = (
|
|
||||||
"<span data-filterable-item-text hidden>{filter}</span>"
|
|
||||||
"<button "
|
|
||||||
"class='action-list-content action-list-content-file' "
|
|
||||||
"type='button' "
|
|
||||||
"onclick='extraNetworksTreeOnClick(event, \"{tabname}\", \"{tab_id}\")'>"
|
|
||||||
"<span class='action-list-item-visual action-list-item-visual--leading'>🗎</span>"
|
|
||||||
"<span class='action-list-item-label action-list-item-label--truncate'>{label}</span>"
|
|
||||||
"<span class='action-list-item-action action-list-item-action--trailing'>{buttons}</span>"
|
|
||||||
"</button>"
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|
||||||
@functools.cache
|
@functools.cache
|
||||||
def allowed_preview_extensions_with_extra(extra_extensions=None):
|
def allowed_preview_extensions_with_extra(extra_extensions=None):
|
||||||
return set(default_allowed_preview_extensions) | set(extra_extensions or [])
|
return set(default_allowed_preview_extensions) | set(extra_extensions or [])
|
||||||
@ -243,7 +203,6 @@ class ExtraNetworksPage:
|
|||||||
self.id_page = self.name.replace(" ", "_")
|
self.id_page = self.name.replace(" ", "_")
|
||||||
self.extra_networks_pane_template = shared.html("extra-networks-pane.html")
|
self.extra_networks_pane_template = shared.html("extra-networks-pane.html")
|
||||||
self.card_page_template = shared.html("extra-networks-card.html")
|
self.card_page_template = shared.html("extra-networks-card.html")
|
||||||
self.card_page_minimal_template = shared.html("extra-networks-card-minimal.html")
|
|
||||||
self.tree_button_template = shared.html("extra-networks-tree-button.html")
|
self.tree_button_template = shared.html("extra-networks-tree-button.html")
|
||||||
self.allow_prompt = True
|
self.allow_prompt = True
|
||||||
self.allow_negative_prompt = False
|
self.allow_negative_prompt = False
|
||||||
@ -278,7 +237,12 @@ class ExtraNetworksPage:
|
|||||||
|
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
def create_item_html(self, tabname: str, item: dict, template: Optional[str] = None) -> str:
|
def create_item_html(
|
||||||
|
self,
|
||||||
|
tabname: str,
|
||||||
|
item: dict,
|
||||||
|
template: Optional[str] = None,
|
||||||
|
) -> Union[str, dict]:
|
||||||
"""Generates HTML for a single ExtraNetworks Item
|
"""Generates HTML for a single ExtraNetworks Item
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
@ -301,19 +265,32 @@ class ExtraNetworksPage:
|
|||||||
width = f"width: {shared.opts.extra_networks_card_width}px;" if shared.opts.extra_networks_card_width else ''
|
width = f"width: {shared.opts.extra_networks_card_width}px;" if shared.opts.extra_networks_card_width else ''
|
||||||
background_image = f'<img src="{html.escape(preview)}" class="preview" loading="lazy">' if preview else ''
|
background_image = f'<img src="{html.escape(preview)}" class="preview" loading="lazy">' if preview else ''
|
||||||
|
|
||||||
|
|
||||||
onclick = item.get("onclick", None)
|
onclick = item.get("onclick", None)
|
||||||
if onclick is None:
|
if onclick is None:
|
||||||
if "negative_prompt" in item:
|
print("HERE")
|
||||||
onclick = '"' + html.escape(f"""return cardClicked({quote_js(tabname)}, {item["prompt"]}, {item["negative_prompt"]}, {"true" if self.allow_negative_prompt else "false"})""") + '"'
|
print("TABNAME:", tabname)
|
||||||
else:
|
print("PROMPT:", item["prompt"])
|
||||||
onclick = '"' + html.escape(f"""return cardClicked({quote_js(tabname)}, {item["prompt"]}, {'""'}, {"true" if self.allow_negative_prompt else "false"})""") + '"'
|
print("NEG_PROMPT:", item.get("negative_prompt", ""))
|
||||||
|
print("ALLOW_NEG:", self.allow_negative_prompt)
|
||||||
|
onclick_js_tpl = "cardClicked('{tabname}', '{prompt}', '{neg_prompt}', '{allow_neg}');"
|
||||||
|
onclick = onclick_js_tpl.format(
|
||||||
|
**{
|
||||||
|
"tabname": tabname,
|
||||||
|
"prompt": item["prompt"],
|
||||||
|
"neg_prompt": item.get("negative_prompt", ""),
|
||||||
|
"allow_neg": "true" if self.allow_negative_prompt else "false"
|
||||||
|
}
|
||||||
|
)
|
||||||
|
onclick = html.escape(onclick)
|
||||||
|
|
||||||
|
|
||||||
copy_path_button = f"<div class='copy-path-button card-button' title='Copy path to clipboard' onclick='extraNetworksCopyCardPath(event, {quote_js(item['filename'])})' data-clipboard-text='{quote_js(item['filename'])}'></div>"
|
copy_path_button = f"<div class='copy-path-button card-button' title='Copy path to clipboard' onclick='extraNetworksCopyCardPath(event, {quote_js(item['filename'])})' data-clipboard-text='{quote_js(item['filename'])}'></div>"
|
||||||
|
|
||||||
metadata_button = ""
|
metadata_button = ""
|
||||||
metadata = item.get("metadata")
|
metadata = item.get("metadata")
|
||||||
if metadata:
|
if metadata:
|
||||||
metadata_button = f"<div class='metadata-button card-button' title='Show internal metadata' onclick='extraNetworksRequestMetadata(event, {quote_js(self.name)}, {quote_js(html.escape(item['name']))})'></div>"
|
metadata_button = f"<div class='metadata-button card-button' title='Show internal metadata' onclick='extraNetworksRequestMetadata(event, {quote_js(self.id_page)}, {quote_js(html.escape(item['name']))})'></div>"
|
||||||
|
|
||||||
edit_button = f"<div class='edit-button card-button' title='Edit metadata' onclick='extraNetworksEditUserMetadata(event, {quote_js(tabname)}, {quote_js(self.id_page)}, {quote_js(html.escape(item['name']))})'></div>"
|
edit_button = f"<div class='edit-button card-button' title='Edit metadata' onclick='extraNetworksEditUserMetadata(event, {quote_js(tabname)}, {quote_js(self.id_page)}, {quote_js(html.escape(item['name']))})'></div>"
|
||||||
|
|
||||||
@ -335,7 +312,12 @@ class ExtraNetworksPage:
|
|||||||
if search_only and shared.opts.extra_networks_hidden_models == "Never":
|
if search_only and shared.opts.extra_networks_hidden_models == "Never":
|
||||||
return ""
|
return ""
|
||||||
|
|
||||||
sort_keys = " ".join([f'data-sort-{k}="{html.escape(str(v))}"' for k, v in item.get("sort_keys", {}).items()]).strip()
|
sort_keys = " ".join(
|
||||||
|
[
|
||||||
|
f'data-sort-{k}="{html.escape(str(v))}"'
|
||||||
|
for k, v in item.get("sort_keys", {}).items()
|
||||||
|
]
|
||||||
|
).strip()
|
||||||
|
|
||||||
search_terms_html = ""
|
search_terms_html = ""
|
||||||
search_term_template = "<span style='{style}' class='{class}'>{search_term}</span>"
|
search_term_template = "<span style='{style}' class='{class}'>{search_term}</span>"
|
||||||
@ -366,13 +348,12 @@ class ExtraNetworksPage:
|
|||||||
"style": f"'display: none; {height}{width}; font-size: {shared.opts.extra_networks_card_text_scale*100}%'",
|
"style": f"'display: none; {height}{width}; font-size: {shared.opts.extra_networks_card_text_scale*100}%'",
|
||||||
"tabname": tabname,
|
"tabname": tabname,
|
||||||
"tab_id": self.id_page,
|
"tab_id": self.id_page,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if template:
|
if template:
|
||||||
return template.format(**args)
|
return template.format(**args)
|
||||||
else:
|
else:
|
||||||
return self.card_page.format(**args)
|
return args
|
||||||
|
|
||||||
def create_tree_view_html(self, tabname: str) -> str:
|
def create_tree_view_html(self, tabname: str) -> str:
|
||||||
"""Generates HTML for displaying folders in a tree view.
|
"""Generates HTML for displaying folders in a tree view.
|
||||||
@ -393,73 +374,94 @@ class ExtraNetworksPage:
|
|||||||
if not tree:
|
if not tree:
|
||||||
return res
|
return res
|
||||||
|
|
||||||
def _build_tree(data: Optional[dict[str, ExtraNetworksItem]] = None) -> str:
|
def _build_tree(data: Optional[dict[str, ExtraNetworksItem]] = None) -> Optional[str]:
|
||||||
"""Recursively builds HTML for a tree."""
|
"""Recursively builds HTML for a tree."""
|
||||||
_res = ""
|
|
||||||
if not data:
|
if not data:
|
||||||
return (
|
return None
|
||||||
"<details open disabled class='folder-item-empty'>"
|
|
||||||
"<summary class='folder-item-summary-empty'>Directory is empty</summary>"
|
# Lists for storing <li> items html for directories and files separately.
|
||||||
"</details>"
|
_dir_li = []
|
||||||
)
|
_file_li = []
|
||||||
|
|
||||||
for k, v in sorted(data.items(), key=lambda x: shared.natural_sort_key(x[0])):
|
for k, v in sorted(data.items(), key=lambda x: shared.natural_sort_key(x[0])):
|
||||||
if isinstance(v, (ExtraNetworksItem,)):
|
if isinstance(v, (ExtraNetworksItem,)):
|
||||||
_action_buttons = tree_btn_file_action_buttons_tpl.format(
|
_item_html_args = self.create_item_html(tabname, v.item)
|
||||||
**{
|
_action_buttons = "".join(
|
||||||
"path": quote_js(k),
|
[
|
||||||
"filename": quote_js(v.item["name"]),
|
_item_html_args["copy_path_button"],
|
||||||
"tabname": quote_js(tabname),
|
_item_html_args["metadata_button"],
|
||||||
"tab_id": quote_js(self.id_page),
|
_item_html_args["edit_button"],
|
||||||
}
|
]
|
||||||
)
|
)
|
||||||
_btn = tree_btn_file_tpl.format(
|
_action_buttons = f"<div class=\"button-row\">{_action_buttons}</div>"
|
||||||
|
_btn = self.tree_button_template.format(
|
||||||
**{
|
**{
|
||||||
"label": v.item["name"],
|
"search_terms": "",
|
||||||
"filter": v.item["search_terms"],
|
"subclass": "tree-list-content-file",
|
||||||
"tabname": tabname,
|
"tabname": tabname,
|
||||||
"tab_id": self.id_page,
|
"tab_id": self.id_page,
|
||||||
"buttons": _action_buttons,
|
"onclick_extra": _item_html_args["card_clicked"],
|
||||||
|
"action_list_item_action_leading": action_list_item_action_leading,
|
||||||
|
"action_list_item_visual_leading": "🗎",
|
||||||
|
"action_list_item_label": v.item["name"],
|
||||||
|
"action_list_item_visual_trailing": "",
|
||||||
|
"action_list_item_action_trailing": _action_buttons,
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
_li = tree_li_file_tpl.format(
|
_li = tree_li_file_tpl.format(
|
||||||
**{
|
**{
|
||||||
"hash": v.item["shorthash"],
|
"hash": v.item["shorthash"],
|
||||||
"path": k,
|
"path": k,
|
||||||
"type": "file",
|
"type": "file",
|
||||||
#"content": _btn,
|
"content": _btn,
|
||||||
"content": self.create_item_html(tabname, v.item, self.tree_button_template),
|
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_res += _li
|
_file_li.append(_li)
|
||||||
#item_html = self.create_item_html(tabname, v.item, self.card_page_minimal_template)
|
|
||||||
#_res += file_template.format(**{"card": item_html})
|
|
||||||
else:
|
else:
|
||||||
_btn = tree_btn_dir_tpl.format(
|
_btn = self.tree_button_template.format(
|
||||||
**{
|
**{
|
||||||
"label": os.path.basename(k),
|
"search_terms": "",
|
||||||
|
"subclass": "tree-list-content-dir",
|
||||||
"tabname": tabname,
|
"tabname": tabname,
|
||||||
"tab_id": self.id_page,
|
"tab_id": self.id_page,
|
||||||
|
"onclick_extra": "",
|
||||||
|
"action_list_item_action_leading": action_list_item_action_leading,
|
||||||
|
"action_list_item_visual_leading": "🗀",
|
||||||
|
"action_list_item_label": os.path.basename(k),
|
||||||
|
"action_list_item_visual_trailing": "",
|
||||||
|
"action_list_item_action_trailing": "",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
_ul = tree_ul_tpl.format(**{"content": _build_tree(v)})
|
_ul = tree_ul_tpl.format(**{"content": _build_tree(v)})
|
||||||
_li = tree_li_dir_tpl.format(**{"content": _btn + _ul, "path": k})
|
_li = tree_li_dir_tpl.format(**{"content": _btn + _ul, "path": k})
|
||||||
_res += _li
|
_dir_li.append(_li)
|
||||||
return _res
|
|
||||||
|
# Directories should always be displayed before files.
|
||||||
|
return "".join(_dir_li) + "".join(_file_li)
|
||||||
|
|
||||||
# Add each root directory to the tree.
|
# Add each root directory to the tree.
|
||||||
for k, v in sorted(tree.items(), key=lambda x: shared.natural_sort_key(x[0])):
|
for k, v in sorted(tree.items(), key=lambda x: shared.natural_sort_key(x[0])):
|
||||||
# If root is empty, append the "disabled" attribute to the template details tag.
|
# If root is empty, append the "disabled" attribute to the template details tag.
|
||||||
btn = tree_btn_dir_tpl.format(
|
btn = self.tree_button_template.format(
|
||||||
**{
|
**{
|
||||||
"label": os.path.basename(k),
|
"search_terms": "",
|
||||||
|
"subclass": "tree-list-content-dir",
|
||||||
"tabname": tabname,
|
"tabname": tabname,
|
||||||
"tab_id": self.id_page,
|
"tab_id": self.id_page,
|
||||||
|
"onclick_extra": "",
|
||||||
|
"action_list_item_action_leading": action_list_item_action_leading,
|
||||||
|
"action_list_item_visual_leading": "🗀",
|
||||||
|
"action_list_item_label": os.path.basename(k),
|
||||||
|
"action_list_item_visual_trailing": "",
|
||||||
|
"action_list_item_action_trailing": "",
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
ul = tree_ul_tpl.format(**{"content": _build_tree(v)})
|
subtree = _build_tree(v)
|
||||||
li = tree_li_dir_tpl.format(**{"content": btn + ul, "path": k})
|
if subtree:
|
||||||
res += li
|
ul = tree_ul_tpl.format(**{"content": _build_tree(v)})
|
||||||
|
li = tree_li_dir_tpl.format(**{"content": btn + ul, "path": k})
|
||||||
|
res += li
|
||||||
|
|
||||||
return tree_tpl.format(
|
return tree_tpl.format(
|
||||||
**{
|
**{
|
||||||
@ -473,6 +475,7 @@ class ExtraNetworksPage:
|
|||||||
res = ""
|
res = ""
|
||||||
self.items = {x["name"]: x for x in self.list_items()}
|
self.items = {x["name"]: x for x in self.list_items()}
|
||||||
for item in self.items.values():
|
for item in self.items.values():
|
||||||
|
print("HEEEERRE:", item)
|
||||||
res += self.create_item_html(tabname, item, self.card_page_template)
|
res += self.create_item_html(tabname, item, self.card_page_template)
|
||||||
|
|
||||||
if res == "":
|
if res == "":
|
||||||
|
185
style.css
185
style.css
@ -929,7 +929,7 @@ footer {
|
|||||||
margin-left: 0.5em;
|
margin-left: 0.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-pane :is(.card, .card-minimal) .button-row{
|
.extra-network-pane .card .button-row{
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
color: white;
|
color: white;
|
||||||
@ -941,13 +941,7 @@ footer {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-pane .card-minimal .button-row {
|
.extra-network-pane .card:hover .button-row{
|
||||||
padding-left: 0.5rem;
|
|
||||||
padding-right: 0.5rem;
|
|
||||||
align-items: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
.extra-network-pane :is(.card:hover, .card-minimal:hover) .button-row{
|
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1110,9 +1104,6 @@ div.block.gradio-box.edit-user-metadata {
|
|||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
div.block.gradio-box.popup-dialog, .popup-dialog {
|
div.block.gradio-box.popup-dialog, .popup-dialog {
|
||||||
width: 56em;
|
width: 56em;
|
||||||
background: var(--body-background-fill);
|
background: var(--body-background-fill);
|
||||||
@ -1205,7 +1196,7 @@ body.resizing .resize-handle {
|
|||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list--tree {
|
.extra-network-tree .tree-list--tree {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
-moz-user-select: none;
|
-moz-user-select: none;
|
||||||
@ -1213,43 +1204,42 @@ body.resizing .resize-handle {
|
|||||||
user-select: none;
|
user-select: none;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
|
margin-left: 0.25rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Remove auto indentation from tree. Will be overridden later. */
|
/* Remove auto indentation from tree. Will be overridden later. */
|
||||||
.extra-network-tree .action-list--subgroup {
|
.extra-network-tree .tree-list--subgroup {
|
||||||
margin: 0 !important;
|
margin: 0 !important;
|
||||||
padding: 0 !important;
|
padding: 0 !important;
|
||||||
box-shadow: 0.6rem 0 0 var(--body-background-fill) inset,
|
box-shadow: 0.5rem 0 0 var(--body-background-fill) inset,
|
||||||
0.8rem 0 0 var(--neutral-800) inset;
|
0.7rem 0 0 var(--neutral-800) inset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Set indentation for each depth of tree. */
|
/* Set indentation for each depth of tree. */
|
||||||
.extra-network-tree .action-list--subgroup > .action-list-item {
|
.extra-network-tree .tree-list--subgroup > .tree-list-item {
|
||||||
margin-left: 0.4rem !important;
|
margin-left: 0.4rem !important;
|
||||||
padding-left: 0.4rem !important;
|
padding-left: 0.4rem !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Styles for tree <ul> elements. */
|
/* Styles for tree <ul> elements. */
|
||||||
.extra-network-tree .action-list {
|
.extra-network-tree .tree-list {}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Styles for tree <li> elements. */
|
/* Styles for tree <li> elements. */
|
||||||
.extra-network-tree .action-list-item {
|
.extra-network-tree .tree-list-item {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
position: relative;
|
position: relative;
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Directory <ul> */
|
/* Directory <ul> visibility based on expanded attribute. */
|
||||||
.extra-network-tree .action-list-content[expanded=false]+.action-list--subgroup {
|
.extra-network-tree .tree-list-content[expanded=false]+.tree-list--subgroup {
|
||||||
height: 0;
|
height: 0;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
visibility: hidden;
|
visibility: hidden;
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-content[expanded=true]+.action-list--subgroup {
|
.extra-network-tree .tree-list-content[expanded=true]+.tree-list--subgroup {
|
||||||
height: auto;
|
height: auto;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
@ -1257,20 +1247,25 @@ body.resizing .resize-handle {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* File <li> */
|
/* File <li> */
|
||||||
.extra-network-tree .action-list-item--subitem {
|
.extra-network-tree .tree-list-item--subitem {
|
||||||
|
padding-top: 0 !important;
|
||||||
|
padding-bottom: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* <li> containing <ul> */
|
/* <li> containing <ul> */
|
||||||
.extra-network-tree .action-list-item--has-subitem {
|
.extra-network-tree .tree-list-item--has-subitem {}
|
||||||
}
|
|
||||||
|
|
||||||
/* BUTTON ELEMENTS */
|
/* BUTTON ELEMENTS */
|
||||||
/* <button> */
|
/* <button> */
|
||||||
.extra-network-tree .action-list-content {
|
.extra-network-tree .tree-list-content {
|
||||||
position: relative;
|
position: relative;
|
||||||
display: grid;
|
display: grid;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 6px 8px;
|
padding: 0 !important;
|
||||||
|
margin-top: 0 !important;
|
||||||
|
margin-bottom: 0 !important;
|
||||||
font-size: 1rem;
|
font-size: 1rem;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
user-select: none;
|
user-select: none;
|
||||||
@ -1278,160 +1273,164 @@ body.resizing .resize-handle {
|
|||||||
border: none;
|
border: none;
|
||||||
transition: background 33.333ms linear;
|
transition: background 33.333ms linear;
|
||||||
grid-template-rows: min-content;
|
grid-template-rows: min-content;
|
||||||
grid-template-areas: "leading-action leading-visual label trailing-visual spacer trailing-action";
|
grid-template-areas: "leading-action leading-visual label trailing-visual trailing-action";
|
||||||
grid-template-columns: min-content min-content minmax(0, auto) min-content 1fr min-content;
|
grid-template-columns: min-content min-content minmax(0, auto) min-content min-content;
|
||||||
grid-gap: 0.1em;
|
grid-gap: 0.1rem;
|
||||||
align-items: start;
|
align-items: start;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
flex-basis: 100%;
|
flex-basis: 100%;
|
||||||
}
|
}
|
||||||
|
/* Buttons for directories. */
|
||||||
|
.extra-network-tree .tree-list-content-dir {}
|
||||||
|
|
||||||
.dark .extra-network-tree button.action-list-content:hover {
|
/* Buttons for files. */
|
||||||
|
.extra-network-tree .tree-list-item--has-subitem .tree-list--subgroup > li:first-child {
|
||||||
|
padding-top: 0.5rem !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dark .extra-network-tree button.tree-list-content:hover {
|
||||||
-webkit-transition: all 0.05s ease-in-out;
|
-webkit-transition: all 0.05s ease-in-out;
|
||||||
transition: all 0.05s ease-in-out;
|
transition: all 0.05s ease-in-out;
|
||||||
background-color: var(--neutral-800);
|
background-color: var(--neutral-800);
|
||||||
}
|
}
|
||||||
|
|
||||||
.dark .extra-network-tree button.action-list-content[selected] {
|
.dark .extra-network-tree button.tree-list-content[selected] {
|
||||||
background-color: var(--neutral-700);
|
background-color: var(--neutral-700);
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree button.action-list-content:hover {
|
.extra-network-tree button.tree-list-content:hover {
|
||||||
-webkit-transition: all 0.05s ease-in-out;
|
-webkit-transition: all 0.05s ease-in-out;
|
||||||
transition: all 0.05s ease-in-out;
|
transition: all 0.05s ease-in-out;
|
||||||
background-color: var(--neutral-200);
|
background-color: var(--neutral-200);
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree button.action-list-content[selected] {
|
.extra-network-tree button.tree-list-content[selected] {
|
||||||
background-color: var(--neutral-300);
|
background-color: var(--neutral-300);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Buttons for directories. */
|
|
||||||
.extra-network-tree .action-list-content-dir {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Buttons for files. */
|
|
||||||
.extra-network-tree .action-list-content-file {
|
|
||||||
margin-left: 2em;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Text for button. */
|
/* Text for button. */
|
||||||
.extra-network-tree .action-list-item-label {
|
.extra-network-tree .tree-list-item-label {
|
||||||
position: relative;
|
position: relative;
|
||||||
line-height: 1.25em;
|
line-height: 1.25rem;
|
||||||
color: var(--button-secondary-text-color);
|
color: var(--button-secondary-text-color);
|
||||||
grid-area: label;
|
grid-area: label;
|
||||||
padding-left: 0.5em;
|
padding-left: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Text for button truncated. */
|
/* Text for button truncated. */
|
||||||
.extra-network-tree .action-list-item-label--truncate {
|
.extra-network-tree .tree-list-item-label--truncate {
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icon for button. */
|
/* Icon for button. */
|
||||||
.extra-network-tree .action-list-item-visual {
|
.extra-network-tree .tree-list-item-visual {
|
||||||
min-height: 1em;
|
min-height: 1rem;
|
||||||
color: var(--button-secondary-text-color);
|
color: var(--button-secondary-text-color);
|
||||||
pointer-events: none;
|
pointer-events: none;
|
||||||
align-items: right;
|
align-items: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icon for button when it is before label. */
|
/* Icon for button when it is before label. */
|
||||||
.extra-network-tree .action-list-item-visual--leading {
|
.extra-network-tree .tree-list-item-visual--leading {
|
||||||
grid-area: leading-visual;
|
grid-area: leading-visual;
|
||||||
|
width: 1rem;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Icon for button when it is after label. */
|
/* Icon for button when it is after label. */
|
||||||
.extra-network-tree .action-list-item-visual--trailing {
|
.extra-network-tree .tree-list-item-visual--trailing {
|
||||||
grid-area: trailing-visual;
|
grid-area: trailing-visual;
|
||||||
|
width: 1rem;
|
||||||
|
text-align: right;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dropdown arrow for button. */
|
/* Dropdown arrow for button. */
|
||||||
.extra-network-tree .action-list-item-action--leading {
|
.extra-network-tree .tree-list-item-action--leading {
|
||||||
margin-right: 1em;
|
margin-right: 0.2rem;
|
||||||
|
margin-left: 0.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-network-tree .tree-list-content-file .tree-list-item-action--leading {
|
||||||
|
visibility: hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Define the animation for the arrow when it is clicked. */
|
/* Define the animation for the arrow when it is clicked. */
|
||||||
.extra-network-tree .action-list-content-dir[expanded=false] .action-list-item-action {
|
.extra-network-tree .tree-list-content-dir[expanded=false] .tree-list-item-action-chevron {
|
||||||
-ms-transform: rotate(0deg);
|
-ms-transform: rotate(135deg);
|
||||||
-webkit-transform: rotate(0deg);
|
-webkit-transform: rotate(135deg);
|
||||||
transform: rotate(0deg);
|
transform: rotate(135deg);
|
||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-content-dir[expanded=true] .action-list-item-action {
|
.extra-network-tree .tree-list-content-dir[expanded=true] .tree-list-item-action-chevron {
|
||||||
-ms-transform: rotate(90deg);
|
-ms-transform: rotate(225deg);
|
||||||
-webkit-transform: rotate(90deg);
|
-webkit-transform: rotate(225deg);
|
||||||
transform: rotate(90deg);
|
transform: rotate(225deg);
|
||||||
transition: transform 0.2s;
|
transition: transform 0.2s;
|
||||||
}
|
}
|
||||||
|
|
||||||
.action-list-item-action-chevron {
|
.tree-list-item-action-chevron {
|
||||||
display: inline-block;
|
display: inline-flex;
|
||||||
padding: 0.3em;
|
/* Uses box shadow to generate a pseudo chevron `>` icon. */
|
||||||
box-shadow: 0.1em 0.1em 0 0px var(--neutral-200) inset;
|
padding: 0.3rem;
|
||||||
|
box-shadow: 0.1rem 0.1rem 0 0 var(--neutral-200) inset;
|
||||||
transform: rotate(135deg);
|
transform: rotate(135deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-item-action--leading {
|
|
||||||
|
.extra-network-tree .tree-list-item-action--leading {
|
||||||
grid-area: leading-action;
|
grid-area: leading-action;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Dropdown arrow for button when it is after label. UNUSED? */
|
.extra-network-tree .tree-list-item-action--trailing {
|
||||||
.extra-network-tree .action-list-item-action--trailing {
|
|
||||||
grid-area: trailing-action;
|
grid-area: trailing-action;
|
||||||
}
|
|
||||||
|
|
||||||
.extra-network-tree .action-list-item-action .button-row {
|
|
||||||
display: flex;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
.extra-network-tree .action-list-content .button-row {
|
|
||||||
display: inline-flex;
|
display: inline-flex;
|
||||||
visibility: hidden !important;
|
|
||||||
color: white;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-content:hover .button-row {
|
.extra-network-tree .tree-list-content .button-row {
|
||||||
|
display: inline-flex;
|
||||||
|
visibility: hidden;
|
||||||
|
color: var(--button-secondary-text-color);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-network-tree .tree-list-content:hover .button-row {
|
||||||
visibility: visible;
|
visibility: visible;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Add icon to left side of <input> */
|
/* Add icon to left side of <input> */
|
||||||
.extra-network-tree .action-list-search::before {
|
.extra-network-tree .tree-list-search::before {
|
||||||
content: "🔎︎";
|
content: "🔎︎";
|
||||||
position: absolute;
|
position: absolute;
|
||||||
margin: 0.5em;
|
margin: 0.5rem;
|
||||||
font-size: 1em;
|
font-size: 1rem;
|
||||||
color: var(--input-placeholder-color);
|
color: var(--input-placeholder-color);
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-search {
|
.extra-network-tree .tree-list-search {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 0.5em;
|
margin: 0.5rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.extra-network-tree .action-list-search .action-list-search-text {
|
.extra-network-tree .tree-list-search .tree-list-search-text {
|
||||||
border: 1px solid var(--button-secondary-border-color);
|
border: 1px solid var(--button-secondary-border-color);
|
||||||
border-radius: 0.5em;
|
border-radius: 0.5rem;
|
||||||
color: var(--button-secondary-text-color);
|
color: var(--button-secondary-text-color);
|
||||||
background-color: transparent;
|
background-color: transparent;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding-left: 2em;
|
padding-left: 2rem;
|
||||||
line-height: 1em;
|
line-height: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* <input> clear button (x on right side) styling */
|
/* <input> clear button (x on right side) styling */
|
||||||
.extra-network-tree .action-list-search .action-list-search-text::-webkit-search-cancel-button {
|
.extra-network-tree .tree-list-search .tree-list-search-text::-webkit-search-cancel-button {
|
||||||
-webkit-appearance: none;
|
-webkit-appearance: none;
|
||||||
appearance: none;
|
appearance: none;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
height: 1em;
|
height: 1rem;
|
||||||
width: 1em;
|
width: 1rem;
|
||||||
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>');
|
mask-image: url('data:image/svg+xml,<svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="black" stroke-width="4" stroke-linecap="round" stroke-linejoin="round"><line x1="18" y1="6" x2="6" y2="18"></line><line x1="6" y1="6" x2="18" y2="18"></line></svg>');
|
||||||
mask-repeat: no-repeat;
|
mask-repeat: no-repeat;
|
||||||
mask-position: center center;
|
mask-position: center center;
|
||||||
|
Loading…
Reference in New Issue
Block a user