gitlyx / static / js / gitly.js
227 lines · 202 sloc · 6.13 KB · 3e6e1621f046018306c4254719b20acd01c1a8da
Raw
1function post(url, dataObj, success) {
2 // Create a FormData object
3 const formData = new FormData();
4
5 console.log(dataObj);
6 if (dataObj !== undefined) {
7 // Populate the FormData object with the object entries
8 Object.entries(dataObj).forEach(([key, value]) => {
9 formData.append(key, value);
10 });
11 }
12
13 // Send the POST request with the FormData object
14 fetch(url, {
15 method: "POST",
16 body: formData,
17 })
18 .then((response) => {
19 /*
20 if (!response.ok) {
21 throw new Error("Network response was not ok");
22 }
23 */
24 return response.json(); // or .text() if the response is not in JSON format
25 })
26 .then((data) => {
27 if (success !== undefined) {
28 //const json_data = JSON.parse(data);
29 success(data);
30 //success(json_data);
31 }
32 //console.log("Success:", data);
33 })
34 .catch((error) => {
35 console.error("Error:", error);
36 });
37}
38
39
40function change_lang(x) {
41 var y = document.getElementById("select_lang");
42 post('/change_lang/' + y.value, {}, () => {
43 window.location.reload();
44 } )
45}
46
47function initPrFilesTree() {
48 const input = document.querySelector("[data-pr-files-filter]");
49 const tree = document.querySelector("[data-pr-files-tree]");
50 if (!input || !tree) {
51 return;
52 }
53
54 const clearButton = document.querySelector("[data-pr-files-filter-clear]");
55 const countEl = document.querySelector("[data-pr-files-count]");
56 const emptyEl = document.querySelector("[data-pr-files-filter-empty]");
57 const rows = Array.from(tree.querySelectorAll(".r, [data-pr-tree-row]"));
58 const fileRows = rows.filter((row) => row.hasAttribute("p") || row.hasAttribute("data-file-path"));
59 const diffEls = Array.from(document.querySelectorAll("[data-diff-path]"));
60 const totalFiles = fileRows.length;
61 const collapsedDirs = new Set();
62
63 function pathForRow(row) {
64 return row.getAttribute("p") || row.getAttribute("q") || row.getAttribute("data-file-path") || row.getAttribute("data-dir-path") || "";
65 }
66
67 function addParentDirs(path, visibleDirs) {
68 const parts = path.split("/");
69 let current = "";
70 for (let i = 0; i < parts.length - 1; i++) {
71 current = current === "" ? parts[i] : current + "/" + parts[i];
72 visibleDirs.add(current);
73 }
74 }
75
76 function isUnderCollapsed(path) {
77 for (const dir of collapsedDirs) {
78 if (path !== dir && path.indexOf(dir + "/") === 0) {
79 return true;
80 }
81 }
82 return false;
83 }
84
85 function applyPrFilesFilter() {
86 const query = input.value.trim().toLowerCase();
87 const visibleDirs = new Set();
88 let visibleFileCount = 0;
89
90 for (const row of fileRows) {
91 const path = row.getAttribute("p") || row.getAttribute("data-file-path") || "";
92 if (query === "" || path.toLowerCase().indexOf(query) !== -1) {
93 visibleFileCount++;
94 addParentDirs(path, visibleDirs);
95 }
96 }
97
98 for (const row of rows) {
99 const filePath = row.getAttribute("p") || row.getAttribute("data-file-path");
100 const dirPath = row.getAttribute("q") || row.getAttribute("data-dir-path");
101 let visible = true;
102
103 if (filePath) {
104 visible = query === "" || filePath.toLowerCase().indexOf(query) !== -1;
105 } else if (dirPath) {
106 visible = query === "" || visibleDirs.has(dirPath);
107 }
108
109 if (visible && query === "" && isUnderCollapsed(pathForRow(row))) {
110 visible = false;
111 }
112 row.hidden = !visible;
113 }
114
115 for (const diffEl of diffEls) {
116 const path = diffEl.getAttribute("data-diff-path") || "";
117 diffEl.hidden = query !== "" && path.toLowerCase().indexOf(query) === -1;
118 }
119
120 if (countEl) {
121 countEl.textContent = query === "" ? String(totalFiles) : visibleFileCount + " / " + totalFiles;
122 }
123 if (emptyEl) {
124 emptyEl.hidden = query === "" || visibleFileCount > 0;
125 }
126 if (clearButton) {
127 clearButton.hidden = input.value === "";
128 }
129 }
130
131 for (const row of rows) {
132 if (!row.hasAttribute("q") && !row.hasAttribute("data-dir-path")) {
133 continue;
134 }
135 row.addEventListener("click", () => {
136 const path = row.getAttribute("q") || row.getAttribute("data-dir-path");
137 if (!path) {
138 return;
139 }
140 if (collapsedDirs.has(path)) {
141 collapsedDirs.delete(path);
142 row.setAttribute("aria-expanded", "true");
143 } else {
144 collapsedDirs.add(path);
145 row.setAttribute("aria-expanded", "false");
146 }
147 applyPrFilesFilter();
148 });
149 }
150
151 input.addEventListener("input", applyPrFilesFilter);
152 input.addEventListener("keydown", (event) => {
153 if (event.key === "Enter") {
154 event.preventDefault();
155 }
156 });
157
158 if (clearButton) {
159 clearButton.addEventListener("click", () => {
160 input.value = "";
161 input.focus();
162 applyPrFilesFilter();
163 });
164 }
165
166 applyPrFilesFilter();
167}
168
169function initPrReviewCommentBoxes() {
170 const root = document.querySelector(".pr-files-diffs");
171 if (!root) {
172 return;
173 }
174 const placeholder = root.getAttribute("data-line-comment-placeholder") || "";
175
176 function ensureBox(row) {
177 if (!row || !row.hasAttribute("s") || !row.hasAttribute("l")) {
178 return null;
179 }
180 const next = row.nextElementSibling;
181 if (next && next.classList.contains("m")) {
182 return next;
183 }
184 const diff = row.closest("[data-diff-path]");
185 const path = diff ? diff.getAttribute("data-diff-path") : "";
186 const side = row.getAttribute("s") === "n" ? "new" : "old";
187 const line = row.getAttribute("l") || "";
188 if (!path || !line) {
189 return null;
190 }
191 const wrap = document.createElement("p");
192 wrap.className = "m";
193 const textarea = document.createElement("textarea");
194 textarea.name = "rc::" + path + "::" + side + "::" + line;
195 textarea.rows = 2;
196 if (placeholder) {
197 textarea.placeholder = placeholder;
198 }
199 wrap.appendChild(textarea);
200 row.insertAdjacentElement("afterend", wrap);
201 return wrap;
202 }
203
204 function rowFromEvent(event) {
205 const target = event.target instanceof Element ? event.target : null;
206 return target ? target.closest(".pr-diff__table > p[s][l]") : null;
207 }
208
209 root.addEventListener("mouseover", (event) => {
210 ensureBox(rowFromEvent(event));
211 });
212 root.addEventListener("focusin", (event) => {
213 ensureBox(rowFromEvent(event));
214 });
215 root.addEventListener("click", (event) => {
216 const box = ensureBox(rowFromEvent(event));
217 const textarea = box ? box.querySelector("textarea") : null;
218 if (textarea) {
219 textarea.focus();
220 }
221 });
222}
223
224document.addEventListener("DOMContentLoaded", () => {
225 initPrFilesTree();
226 initPrReviewCommentBoxes();
227});
228