File size: 4,525 Bytes
194b4ef
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
function getClassValue(elem, prefix) {
    for (let cls of elem.classList) {
        if (cls.startsWith(prefix)) {
            return cls.slice(prefix.length);
        }
    }

    return null;
}

function initializeReorderableLists() {
    let current = null;

    let observer = new MutationObserver(() => {
        gradioApp().querySelectorAll(".temporal-reorderable-list").forEach((list) => {
            if (list.classList.contains("temporal-initialized")) return;

            let listIndex = getClassValue(list, "temporal-index-");

            listTextbox = gradioApp().querySelector(`.temporal-reorderable-list-textbox.temporal-index-${listIndex}`);

            list.querySelectorAll(".temporal-reorderable-accordion").forEach((accordion) => {
                let accordionIndex = getClassValue(accordion, "temporal-index-");

                let dragger = document.createElement("span");
                dragger.classList.add("temporal-reorderable-accordion-dragger");
                dragger.classList.add(`temporal-index-${accordionIndex}`);
                dragger.innerText = ":::";
                dragger.addEventListener("pointerdown", (event) => {
                    event.stopPropagation();

                    accordion.classList.add("temporal-dragged");

                    current = accordion;
                });

                let checkbox = list.querySelector(`.temporal-reorderable-accordion-checkbox.temporal-index-${accordionIndex}`);
                checkbox.addEventListener("click", (event) => {
                    event.stopPropagation();
                });

                let labelWrap = accordion.querySelector(".label-wrap");
                labelWrap.insertBefore(dragger, labelWrap.lastChild);
                labelWrap.insertBefore(checkbox, labelWrap.lastChild);

                let specialCheckbox = accordion.querySelector(".temporal-reorderable-accordion-special-checkbox");

                if (specialCheckbox != null) {
                    specialCheckbox.addEventListener("click", (event) => {
                        event.stopPropagation();
                    });

                    labelWrap.insertBefore(specialCheckbox, labelWrap.lastChild);
                }

                accordion.checkbox = checkbox;
                accordion.list = list;
                accordion.listTextbox = listTextbox;
            });
            list.classList.add("temporal-initialized");
        });
    });
    observer.observe(gradioApp(), {childList: true, subtree: true});

    window.addEventListener("touchmove", (event) => {
        if (!current) return;

        event.stopPropagation();
        event.preventDefault();
    }, {passive: false});
    window.addEventListener("pointermove", (event) => {
        if (!current) return;

        event.stopPropagation();

        let parent = current.parentElement;

        parent.querySelectorAll(".temporal-reorderable-accordion").forEach((other) => {
            if (current == other) return;

            let selfRect = current.getBoundingClientRect();
            let otherRect = other.getBoundingClientRect();

            if (selfRect.top < otherRect.top && event.clientY > otherRect.top) {
                parent.insertBefore(other, current);
            }

            if (selfRect.top > otherRect.top && event.clientY < otherRect.bottom) {
                parent.insertBefore(current, other);
            }
        })
    });
    window.addEventListener("pointerup", (event) => {
        if (!current) return;

        event.stopPropagation();

        let textArea = current.listTextbox.querySelector("textarea");
        textArea.value =
            [...current.list.querySelectorAll(".temporal-reorderable-accordion")]
            .map((x) => getClassValue(x, "temporal-index-"))
            .join("|");

        let inputEvent = new Event("input", {bubbles: true});
        Object.defineProperty(inputEvent, "target", {value: textArea});
        textArea.dispatchEvent(inputEvent);

        current.classList.remove("temporal-dragged");

        current = null;
    });
}

function updateReorderableListOrder(listIndex, accordionIndexString) {
    let list = gradioApp().querySelector(`.temporal-reorderable-list.temporal-index-${listIndex}`);

    for (let index of accordionIndexString.split("|")) {
        list.appendChild(list.querySelector(`.temporal-reorderable-accordion.temporal-index-${index}`));
    }
}

document.addEventListener("DOMContentLoaded", () => {
    initializeReorderableLists();
});