4988 |
kaklik |
1 |
var tableRows = document.getElementsByTagName('tr'); |
|
|
2 |
|
|
|
3 |
function toggleGroup(groupName) |
|
|
4 |
{ |
|
|
5 |
for (var i = 0; i < tableRows.length; i++) |
|
|
6 |
{ |
|
|
7 |
if (tableRows[i].title == groupName) |
|
|
8 |
{ |
|
|
9 |
if (tableRows[i].style.display == 'none') |
|
|
10 |
{ |
|
|
11 |
tableRows[i].style.display = 'table-row'; |
|
|
12 |
} |
|
|
13 |
else |
|
|
14 |
{ |
|
|
15 |
tableRows[i].style.display = 'none'; |
|
|
16 |
} |
|
|
17 |
} |
|
|
18 |
} |
|
|
19 |
} |
|
|
20 |
|
|
|
21 |
function collapseAllGroups() |
|
|
22 |
{ |
|
|
23 |
for (var i = 0; i < tableRows.length; i++) |
|
|
24 |
{ |
|
|
25 |
if (tableRows[i].title != '') |
|
|
26 |
{ |
|
|
27 |
tableRows[i].style.display = 'none'; |
|
|
28 |
} |
|
|
29 |
} |
|
|
30 |
} |
|
|
31 |
|
|
|
32 |
$("table.collapsible thead").find("th").on("click", function() |
|
|
33 |
{ |
|
|
34 |
let oldClass = $(this).get(0).className; |
|
|
35 |
let newClass = (oldClass == 'open') ? 'closed' : 'open'; |
|
|
36 |
|
|
|
37 |
$(this).get(0).className = newClass; |
|
|
38 |
$(this).closest("table").find("tbody").toggle(); |
|
|
39 |
}); |
|
|
40 |
|
|
|
41 |
/** |
|
|
42 |
* Hide all non-root entries currently visible. |
|
|
43 |
* <p> |
|
|
44 |
* Depending on the config, the site is able to load ALL files and directories of the current repo |
|
|
45 |
* recursively to prevent additional requests. The use case is to hide all of the root-dirs and let |
|
|
46 |
* users simply toggle the next level of interest without additional waiting. This is implemented by |
|
|
47 |
* using the {@code title}-attribute and the {@code /}-character to represent some path and ONLY the |
|
|
48 |
* root-dirs themself to show DON'T contain such. All other entries have some, either because they |
|
|
49 |
* belong to a subdir or file within some parent dir. |
|
|
50 |
* </p> |
|
|
51 |
* <p> |
|
|
52 |
* There's currently no additional config necessary to apply this JS or not, because the rows worked |
|
|
53 |
* on are only generated in case recursive loading is enabled already! |
|
|
54 |
* </p> |
|
|
55 |
*/ |
|
|
56 |
$('table#listing > tbody > tr[title*="/"]').each(function() |
|
|
57 |
{ |
|
|
58 |
// "visibility: collapse" leaves some space at the bottom of the whole list, resulting in not |
|
|
59 |
// wanted scrollbars being shown by default. |
|
|
60 |
$(this).hide(); |
|
|
61 |
}); |
|
|
62 |
|
|
|
63 |
/** |
|
|
64 |
* Select all direct children for the given parent. |
|
|
65 |
* <p> |
|
|
66 |
* The markup doesn't model parent-child relationships currently, but instead all directories, |
|
|
67 |
* files etc. are maintained as individual rows one after each other. In theory not even the order |
|
|
68 |
* of those rows needs to be alphabetically or fit the parent-child-order in the repo or else, all |
|
|
69 |
* can be mixed-up. So this function searches all rows of the given {@code body} for DIRECT children |
|
|
70 |
* of the given parent row, which can be identified by their paths maintained in the {@code title}- |
|
|
71 |
* attribute. Such filtering is non-trivial and one can't use CSS-selectors only, because those |
|
|
72 |
* paths need to fulfill certain conditions. |
|
|
73 |
* </p> |
|
|
74 |
* @param[in] body |
|
|
75 |
* @param[in] rowParent |
|
|
76 |
* @return Array with direct children of the given parent. |
|
|
77 |
*/ |
|
|
78 |
function recursiveLoadDirectChildrenSelect(body, rowParent) |
|
|
79 |
{ |
|
|
80 |
// The parent title is used in some reg exp, so properly escape/quote it. Sadly "\Q...\E" does |
|
|
81 |
// not work and JS doesn't seem to provide anythign else on its own as well. |
|
|
82 |
// https://stackoverflow.com/a/3561711/2055163 |
|
|
83 |
let titleParent = rowParent.attr('title') || ''; |
|
|
84 |
titleParent = titleParent.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&'); |
|
|
85 |
let selector = 'tr[title^="' + titleParent + '/"]'; |
|
|
86 |
let directChildren = []; |
|
|
87 |
|
|
|
88 |
// Selectors don't support regular expressions, but direct children not only start with the |
|
|
89 |
// parent, but don't contain additional children in their title as well. One can't select |
|
|
90 |
// that condition easily, so find ALL children and filter later to direct ones only. |
|
|
91 |
body.children(selector).each(function() |
|
|
92 |
{ |
|
|
93 |
let rowChild = $(this); |
|
|
94 |
let titleChild = rowChild.attr('title') || ''; |
|
|
95 |
|
|
|
96 |
let ptChildDirs = titleParent + '/$'; |
|
|
97 |
let ptChildFiles = titleParent + '/[^/]+$'; |
|
|
98 |
let pattern = ptChildDirs + '|' + ptChildFiles; |
|
|
99 |
|
|
|
100 |
if (titleChild.match(pattern)) |
|
|
101 |
{ |
|
|
102 |
directChildren.push(rowChild); |
|
|
103 |
} |
|
|
104 |
}); |
|
|
105 |
|
|
|
106 |
return directChildren; |
|
|
107 |
} |
|
|
108 |
|
|
|
109 |
/** |
|
|
110 |
* Click-handler for some parent directory. |
|
|
111 |
* <p> |
|
|
112 |
* What needs to happen depends on the visibility of the direct children associated with some parent |
|
|
113 |
* and therefore given: If children are NOT visible, simply show them and ONLY those, as showing |
|
|
114 |
* should not be recursive currently. If children are visible OTOH, ALL of those need to be hidden |
|
|
115 |
* or otherwise some lower level children would still be shown. This is because of the currently |
|
|
116 |
* used markup, which doesn't model parent-child-relationships properly, but places everything at |
|
|
117 |
* one level. Someone needs to take care of hiding children of children of children, when hiding |
|
|
118 |
* associated markup itself only hides some of those. To hide recursively, a custom event named |
|
|
119 |
* {@code hide_children} seems the easiest approach currently, which is then simply handled by the |
|
|
120 |
* parent directory again. |
|
|
121 |
* </p> |
|
|
122 |
* @param[in] directChildren |
|
|
123 |
* @return {@code false} to stop propagation of the current event. |
|
|
124 |
*/ |
|
|
125 |
function recursiveLoadRowParentOnClick(directChildren) |
|
|
126 |
{ |
|
|
127 |
$.each(directChildren, function() |
|
|
128 |
{ |
|
|
129 |
let self = $(this); |
|
|
130 |
let isVisible = self.is(':visible'); |
|
|
131 |
|
|
|
132 |
if (!isVisible) |
|
|
133 |
{ |
|
|
134 |
self.show(); |
|
|
135 |
return true; |
|
|
136 |
} |
|
|
137 |
|
|
|
138 |
self.trigger('hide_children'); |
|
|
139 |
self.hide(); |
|
|
140 |
}); |
|
|
141 |
|
|
|
142 |
return false; |
|
|
143 |
} |
|
|
144 |
|
|
|
145 |
/** |
|
|
146 |
* Handler to hide direct children. |
|
|
147 |
* <p> |
|
|
148 |
* While showing only the next level of children is wanted, when hiding ALL levels need to be hidden |
|
|
149 |
* instead. This can not easily be achieved with the current markup placing ALL directories, files |
|
|
150 |
* etc. regardless of their depth on the same level. So a special event is registered on each dir |
|
|
151 |
* to simply hide ALL of it's own children and that event is triggered on ALL children of some dir |
|
|
152 |
* as necessary. |
|
|
153 |
* </p> |
|
|
154 |
* @param[in] directChildren |
|
|
155 |
* @return {@code false} to stop propagation of the current event. |
|
|
156 |
*/ |
|
|
157 |
function recursiveLoadRowParentOnHideChildren(directChildren) |
|
|
158 |
{ |
|
|
159 |
$.each(directChildren, function() |
|
|
160 |
{ |
|
|
161 |
let self = $(this); |
|
|
162 |
|
|
|
163 |
self.trigger('hide_children'); |
|
|
164 |
self.hide(); |
|
|
165 |
}); |
|
|
166 |
|
|
|
167 |
return false; |
|
|
168 |
} |
|
|
169 |
|
|
|
170 |
/** |
|
|
171 |
* Process one row when loading all directories and files of some repo recursively. |
|
|
172 |
* <p> |
|
|
173 |
* Markup currently doesn't proiperly model parent-child-relationships, so the current approach is |
|
|
174 |
* to iterated all rows of some rendered table to find direct children on our own. Those children |
|
|
175 |
* are the once to show or hide in the end any by iterating all rows and search the whole body for |
|
|
176 |
* children, all of those can be found easily to register necessary event handlers. |
|
|
177 |
* </p> |
|
|
178 |
* @param[in] body |
|
|
179 |
* @param[in] rowParent |
|
|
180 |
*/ |
|
|
181 |
function recursiveLoadRowProc(body, rowParent) |
|
|
182 |
{ |
|
|
183 |
let directChildren = recursiveLoadDirectChildrenSelect(body, rowParent); |
|
|
184 |
|
|
|
185 |
rowParent.find('td.path a[href^="listing.php?"]').on('click', function() |
|
|
186 |
{ |
|
|
187 |
return recursiveLoadRowParentOnClick(directChildren); |
|
|
188 |
}); |
|
|
189 |
|
|
|
190 |
rowParent.on('hide_children', function() |
|
|
191 |
{ |
|
|
192 |
return recursiveLoadRowParentOnHideChildren(directChildren); |
|
|
193 |
}); |
|
|
194 |
} |
|
|
195 |
|
|
|
196 |
/** |
|
|
197 |
* Register event handlers to hide and show children of root-directories. |
|
|
198 |
*/ |
|
|
199 |
$('table#listing > tbody').each(function() |
|
|
200 |
{ |
|
|
201 |
let body = $(this); |
|
|
202 |
|
|
|
203 |
// Each row needs to be checked for its direct children, so that only those can be toggled. The |
|
|
204 |
// "tbody" is necessary so that one can find direct children per row as well, because all those |
|
|
205 |
// are maintained on the same level and only distinguished by their textual path. So we either |
|
|
206 |
// need to search the "tbody" per row for all children or implement some other approach mapping |
|
|
207 |
// things by only iterating rows once. The current approach seems easier for now. |
|
|
208 |
body.children('tr').each(function() { recursiveLoadRowProc(body, $(this)); }); |
|
|
209 |
}); |