mirror of
https://github.com/AUTOMATIC1111/stable-diffusion-webui.git
synced 2026-02-01 13:22:04 -08:00
fix bugs with multi-function buttons and recursive filters.
This commit is contained in:
parent
d912e720f7
commit
250e7673e8
5 changed files with 267 additions and 168 deletions
|
|
@ -540,11 +540,12 @@ class ExtraNetworksTab {
|
|||
row.style.gridTemplateColumns = `${max_width}px ${pad}px 1fr`;
|
||||
}
|
||||
|
||||
async setDirectoryButtons({source_elem, source_selector, source_class}={}) {
|
||||
async setDirectoryButtons({source_elem, source_selector, source_class, reset_all}={}) {
|
||||
// At least one argument must be specified.
|
||||
if (isNullOrUndefined(source_elem)
|
||||
&& isNullOrUndefined(source_selector)
|
||||
&& isNullOrUndefined(source_class)) {
|
||||
&& isNullOrUndefined(source_class)
|
||||
&& isNullOrUndefined(reset_all)) {
|
||||
console.error("At least one argument must be specified.")
|
||||
return;
|
||||
}
|
||||
|
|
@ -596,6 +597,13 @@ class ExtraNetworksTab {
|
|||
};
|
||||
_set_recursion_depth.bind(this);
|
||||
|
||||
if (reset_all === true) {
|
||||
_reset_all_buttons();
|
||||
await this.tree_list.onRowSelected(); // no args deselects all.
|
||||
this.applyDirectoryFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!_exists(source_elem) && isString(source_selector)) {
|
||||
source_elem = this.container_elem.querySelector(source_selector);
|
||||
}
|
||||
|
|
@ -604,11 +612,17 @@ class ExtraNetworksTab {
|
|||
source_elem = this.container_elem.querySelector(`${source_class}[data-selected]`);
|
||||
}
|
||||
|
||||
// try to find any selected buttons to use as a source.
|
||||
if (!_exists(source_elem)) {
|
||||
source_elem = this.container_elem.querySelector("[data-selected]");
|
||||
}
|
||||
|
||||
// If we got here with no source elem, then we will take this to mean that
|
||||
// we are deselecting all.
|
||||
if (!_exists(source_elem)) {
|
||||
_reset_all_buttons();
|
||||
await this.tree_list.onRowSelected(); // no args deselects all.
|
||||
this.applyDirectoryFilter();
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -626,6 +640,10 @@ class ExtraNetworksTab {
|
|||
} else {
|
||||
await this.tree_list.onRowSelected();
|
||||
}
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? data_path : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -643,6 +661,10 @@ class ExtraNetworksTab {
|
|||
await this.tree_list.onRowSelected(source_is_tree ? source_elem : other_elem);
|
||||
const div_id = source_is_tree ? source_elem.dataset.divId : other_elem.dataset.divId;
|
||||
_set_recursion_depth(div_id, data_recurse);
|
||||
this.applyDirectoryFilter(
|
||||
"selected" in source_elem.dataset ? data_path : null,
|
||||
"recurse" in source_elem.dataset,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1129,11 +1151,11 @@ async function extraNetworksTreeDirectoryOnDblClick(event) {
|
|||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
if ("expanded" in btn.dataset) {
|
||||
await extraNetworksBtnTreeViewCollapseOnClick(event);
|
||||
} else {
|
||||
await extraNetworksBtnTreeViewExpandOnClick(event);
|
||||
}
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
await tab.tree_list.toggleRowExpanded(div_id);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryOnClick(event) {
|
||||
|
|
@ -1141,48 +1163,36 @@ async function extraNetworksTreeDirectoryOnClick(event) {
|
|||
if (event.target.closest(".tree-list-item-action")) {
|
||||
return;
|
||||
}
|
||||
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
tab.setDirectoryButtons({source_elem: btn});
|
||||
}
|
||||
|
||||
async function extraNetworksTreeDirectoryChevronOnLongPress(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const chevron = event.target.closest(".tree-list-item-action--chevron");
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
if ("expanded" in btn.dataset) {
|
||||
await tab.tree_list.collapseAllRows(div_id);
|
||||
} else {
|
||||
await tab.tree_list.expandAllRows(div_id);
|
||||
}
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
async function extraNetworksBtnTreeViewChevronOnClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item-action-chevron");
|
||||
const row = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = row.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
await tab.tree_list.onRowExpandClick(div_id, btn);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
async function extraNetworksBtnTreeViewExpandOnClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
await tab.tree_list.onExpandAllClick(div_id);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
async function extraNetworksBtnTreeViewCollapseOnClick(event) {
|
||||
// stopPropagation so we don't also trigger event on parent since this btn is nested.
|
||||
event.stopPropagation();
|
||||
const btn = event.target.closest(".tree-list-item");
|
||||
const pane = btn.closest(".extra-network-pane");
|
||||
const div_id = btn.dataset.divId;
|
||||
const tab = extra_networks_tabs[pane.dataset.tabnameFull];
|
||||
|
||||
await tab.tree_list.onCollapseAllClick(div_id);
|
||||
await tab.tree_list.toggleRowExpanded(div_id);
|
||||
tab.setDirectoryButtons({source_class: ".tree-list-item"});
|
||||
}
|
||||
|
||||
|
|
@ -1278,9 +1288,6 @@ function extraNetworksSetupEventDelegators() {
|
|||
".copy-path-button": extraNetworksBtnCopyPathOnClick,
|
||||
".edit-button": extraNetworksBtnEditMetadataOnClick,
|
||||
".metadata-button": extraNetworksBtnShowMetadataOnClick,
|
||||
".tree-list-item-action-chevron": extraNetworksBtnTreeViewChevronOnClick,
|
||||
".tree-list-item-action-expand": extraNetworksBtnTreeViewExpandOnClick,
|
||||
".tree-list-item-action-collapse": extraNetworksBtnTreeViewCollapseOnClick,
|
||||
".extra-network-control--search-clear": extraNetworksControlSearchClearOnClick,
|
||||
".extra-network-control--sort-mode": extraNetworksControlSortModeOnClick,
|
||||
".extra-network-control--sort-dir": extraNetworksControlSortDirOnClick,
|
||||
|
|
@ -1297,40 +1304,56 @@ function extraNetworksSetupEventDelegators() {
|
|||
}
|
||||
});
|
||||
|
||||
// effectively just a click but we need to handle separate from "click" events
|
||||
// since the same elements are also handling long press events.
|
||||
const short_press_event_map = {
|
||||
".tree-list-item--dir": extraNetworksTreeDirectoryOnClick,
|
||||
".extra-network-dirs-view-button": extraNetworksBtnDirsViewItemOnClick,
|
||||
}
|
||||
const short_press_ignore_map = {
|
||||
".tree-list-item--dir": [".tree-list-item-action"],
|
||||
}
|
||||
const long_press_event_map = {
|
||||
".tree-list-item--dir": extraNetworksTreeDirectoryOnLongPress,
|
||||
".extra-network-dirs-view-button": extraNetworksBtnDirsViewItemOnLongPress,
|
||||
};
|
||||
const long_press_ignore_map = {
|
||||
".tree-list-item--dir": [".tree-list-item-action"],
|
||||
}
|
||||
// Order in these maps matters since we may have separate events for both a div
|
||||
// and for a child within that div however if the child is clicked then we wouldn't
|
||||
// want to handle clicks for the parent as well. In this case, order the child's event
|
||||
// before the parent and the parent will be ignored.
|
||||
// Can add entries with handler=null to forcefully ignore specific event types.
|
||||
|
||||
const dbl_press_event_map = {
|
||||
".tree-list-item--dir": extraNetworksTreeDirectoryOnDblClick,
|
||||
}
|
||||
const short_press_event_map = [
|
||||
{
|
||||
"selector": ".tree-list-item-action--chevron",
|
||||
"handler": extraNetworksBtnTreeViewChevronOnClick,
|
||||
},
|
||||
{
|
||||
"selector": ".tree-list-item--dir",
|
||||
"negative": ".tree-list-item-action",
|
||||
"handler": extraNetworksTreeDirectoryOnClick,
|
||||
},
|
||||
{
|
||||
"selector": ".extra-network-dirs-view-button",
|
||||
"handler": extraNetworksBtnDirsViewItemOnClick,
|
||||
},
|
||||
];
|
||||
|
||||
const dbl_press_ignore_map = {
|
||||
".tree-list-item--dir": [".tree-list-item-action"],
|
||||
}
|
||||
|
||||
const on_short_press = (event, elem, selector) => {
|
||||
let ignores = short_press_ignore_map[selector];
|
||||
ignores = ignores || [];
|
||||
for (const ignore of Object.values(ignores)) {
|
||||
if (event.target.closest(ignore)) {
|
||||
return;
|
||||
}
|
||||
const long_press_event_map = [
|
||||
{
|
||||
"selector": ".tree-list-item-action--chevron",
|
||||
"handler": extraNetworksTreeDirectoryChevronOnLongPress,
|
||||
},
|
||||
{
|
||||
"selector": ".tree-list-item--dir",
|
||||
"negative": ".tree-list-item-action",
|
||||
"handler": extraNetworksTreeDirectoryOnLongPress,
|
||||
},
|
||||
{
|
||||
"selector": ".extra-network-dirs-view-button",
|
||||
"handler": extraNetworksBtnDirsViewItemOnLongPress,
|
||||
},
|
||||
];
|
||||
|
||||
const dbl_press_event_map = [
|
||||
{
|
||||
"selector": ".tree-list-item--dir",
|
||||
"negative": ".tree-list-item-action",
|
||||
"handler": extraNetworksTreeDirectoryOnDblClick,
|
||||
},
|
||||
];
|
||||
|
||||
const on_short_press = (event, elem, handler) => {
|
||||
if (!handler) {
|
||||
return;
|
||||
}
|
||||
elem.classList.remove("pressed");
|
||||
// Toggle
|
||||
if (elem.classList.contains("long-pressed")) {
|
||||
elem.classList.remove("long-pressed");
|
||||
|
|
@ -1342,18 +1365,13 @@ function extraNetworksSetupEventDelegators() {
|
|||
}
|
||||
|
||||
elem.dispatchEvent(new Event("shortpress", event));
|
||||
short_press_event_map[selector](event);
|
||||
handler(event);
|
||||
};
|
||||
|
||||
const on_long_press = (event, elem, selector) => {
|
||||
let ignores = long_press_ignore_map[selector];
|
||||
ignores = ignores || [];
|
||||
for (const ignore of Object.values(ignores)) {
|
||||
if (event.target.closest(ignore)) {
|
||||
return;
|
||||
}
|
||||
const on_long_press = (event, elem, handler) => {
|
||||
if (!handler) {
|
||||
return;
|
||||
}
|
||||
elem.classList.remove("pressed");
|
||||
// If long pressed, we deselect.
|
||||
// Else we set as long pressed.
|
||||
if (elem.classList.contains("short-pressed")) {
|
||||
|
|
@ -1368,61 +1386,91 @@ function extraNetworksSetupEventDelegators() {
|
|||
}
|
||||
|
||||
elem.dispatchEvent(new Event("longpress", event));
|
||||
long_press_event_map[selector](event);
|
||||
handler(event);
|
||||
};
|
||||
|
||||
const on_dbl_press = (event, elem, selector) => {
|
||||
let ignores = dbl_press_ignore_map[selector];
|
||||
ignores = ignores || [];
|
||||
for (const ignore of Object.values(ignores)) {
|
||||
if (event.target.closest(ignore)) {
|
||||
return;
|
||||
}
|
||||
const on_dbl_press = (event, elem, handler) => {
|
||||
if (!handler) {
|
||||
return;
|
||||
}
|
||||
elem.classList.remove("pressed");
|
||||
dbl_press_event_map[selector](event);
|
||||
handler(event);
|
||||
}
|
||||
|
||||
let press_timer;
|
||||
let press_time_ms = 800;
|
||||
const event_maps = [
|
||||
short_press_event_map,
|
||||
long_press_event_map,
|
||||
dbl_press_event_map,
|
||||
];
|
||||
const selectors = Object.keys(Object.assign({}, ...event_maps));
|
||||
|
||||
window.addEventListener("mousedown", event => {
|
||||
for (const selector of selectors) {
|
||||
const elem = event.target.closest(selector);
|
||||
if (elem) {
|
||||
for (const obj of short_press_event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
elem.classList.add("pressed");
|
||||
}
|
||||
}
|
||||
|
||||
for (const obj of long_press_event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
elem.classList.add("pressed");
|
||||
press_timer = setTimeout(() => {
|
||||
elem.classList.remove("pressed");
|
||||
on_long_press(event, elem, obj.handler);
|
||||
}, press_time_ms);
|
||||
}
|
||||
}
|
||||
|
||||
for (const obj of dbl_press_event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
elem.classList.add("pressed");
|
||||
press_timer = setTimeout((event) => {
|
||||
on_long_press(event, elem, selector);
|
||||
}, press_time_ms, event);
|
||||
return;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
window.addEventListener("mouseup", event => {
|
||||
for (const selector of selectors) {
|
||||
const elem = event.target.closest(selector);
|
||||
if (elem) {
|
||||
for (const obj of short_press_event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
clearTimeout(press_timer);
|
||||
|
||||
if (elem.classList.contains("pressed")) {
|
||||
if (event.detail === 1) {
|
||||
on_short_press(event, elem, selector);
|
||||
} else if (event.detail === 2) {
|
||||
on_dbl_press(event, elem, selector);
|
||||
if (event.detail === 1
|
||||
|| !dbl_press_event_map.map(x => x.selector).includes(obj.selector)
|
||||
) {
|
||||
elem.classList.remove("pressed");
|
||||
on_short_press(event, elem, obj.handler);
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (event.detail === 2) {
|
||||
for (const obj of dbl_press_event_map) {
|
||||
const elem = event.target.closest(obj.selector);
|
||||
const neg = obj.negative ? event.target.closest(obj.negative) : null;
|
||||
if (elem && !neg) {
|
||||
event.preventDefault();
|
||||
event.stopPropagation();
|
||||
clearTimeout(press_timer);
|
||||
if (elem.classList.contains("pressed")) {
|
||||
elem.classList.remove("pressed");
|
||||
on_dbl_press(event, elem, obj.handler);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// long_press_event_map is handled by the timer setup in "mousedown" handlers.
|
||||
});
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -347,7 +347,8 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
return max_width;
|
||||
}
|
||||
|
||||
async onExpandAllClick(div_id) {
|
||||
async expandAllRows(div_id) {
|
||||
/** Recursively expands all directories below the passed div_id. */
|
||||
if (!keyExistsLogError(this.data_obj, div_id)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -372,7 +373,8 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
await this.sortData();
|
||||
}
|
||||
|
||||
async onCollapseAllClick(div_id) {
|
||||
async collapseAllRows(div_id) {
|
||||
/** Recursively collapses all directories below the passed div_id. */
|
||||
if (!keyExistsLogError(this.data_obj, div_id)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -403,8 +405,8 @@ class ExtraNetworksClusterizeTreeList extends ExtraNetworksClusterize {
|
|||
await this.sortData();
|
||||
}
|
||||
|
||||
async onRowExpandClick(div_id, elem) {
|
||||
/** Expands or collapses a row to show/hide children. */
|
||||
async toggleRowExpanded(div_id) {
|
||||
/** Toggles a row between expanded and collapses states. */
|
||||
if (!keyExistsLogError(this.data_obj, div_id)) {
|
||||
return;
|
||||
}
|
||||
|
|
@ -584,11 +586,11 @@ class ExtraNetworksClusterizeCardsList extends ExtraNetworksClusterize {
|
|||
for (const [div_id, v] of Object.entries(this.data_obj)) {
|
||||
let visible = true;
|
||||
|
||||
if (this.directory_filter_recurse) {
|
||||
if (this.directory_filter_str && this.directory_filter_recurse) {
|
||||
// Filter as directory with recurse shows all nested children.
|
||||
// Case sensitive comparison against the relative directory of each object.
|
||||
if (this.directory_filter_str && !this.directory_filter_str.startsWith(v.rel_parent_dir)) {
|
||||
this.data_obj[div_id].visible = false;
|
||||
this.data_obj[div_id].visible = v.rel_parent_dir.startsWith(this.directory_filter_str);
|
||||
if (!this.data_obj[div_id].visible) {
|
||||
continue;
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue