Commit 464ade1d authored by Toby Allen's avatar Toby Allen Committed by GitHub

Add new browse sort - namedirfirst (#1551)

* Revert "browse: sort listing by dir first (#1527)"

 commit 4e1229e7.

* Add new browse sort order  namedirfirst. Make namedirfirst default sort
parent ce47cf51
......@@ -16,6 +16,4 @@ Caddyfile
og_static/
.vscode/
caddyhttp/browse/temp*
\ No newline at end of file
.vscode/
\ No newline at end of file
......@@ -21,9 +21,10 @@ import (
)
const (
sortByName = "name"
sortBySize = "size"
sortByTime = "time"
sortByName = "name"
sortByNameDirFirst = "namedirfirst"
sortBySize = "size"
sortByTime = "time"
)
// Browse is an http.Handler that can show a file listing when
......@@ -128,6 +129,7 @@ func (fi FileInfo) HumanModTime(format string) string {
// Implement sorting for Listing
type byName Listing
type byNameDirFirst Listing
type bySize Listing
type byTime Listing
......@@ -137,6 +139,15 @@ func (l byName) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i]
// Treat upper and lower case equally
func (l byName) Less(i, j int) bool {
return strings.ToLower(l.Items[i].Name) < strings.ToLower(l.Items[j].Name)
}
// By Name Dir First
func (l byNameDirFirst) Len() int { return len(l.Items) }
func (l byNameDirFirst) Swap(i, j int) { l.Items[i], l.Items[j] = l.Items[j], l.Items[i] }
// Treat upper and lower case equally
func (l byNameDirFirst) Less(i, j int) bool {
// if both are dir or file sort normally
if l.Items[i].IsDir == l.Items[j].IsDir {
......@@ -176,6 +187,8 @@ func (l Listing) applySort() {
switch l.Sort {
case sortByName:
sort.Sort(sort.Reverse(byName(l)))
case sortByNameDirFirst:
sort.Sort(sort.Reverse(byNameDirFirst(l)))
case sortBySize:
sort.Sort(sort.Reverse(bySize(l)))
case sortByTime:
......@@ -188,6 +201,8 @@ func (l Listing) applySort() {
switch l.Sort {
case sortByName:
sort.Sort(byName(l))
case sortByNameDirFirst:
sort.Sort(byNameDirFirst(l))
case sortBySize:
sort.Sort(bySize(l))
case sortByTime:
......@@ -345,11 +360,11 @@ func (b Browse) handleSortOrder(w http.ResponseWriter, r *http.Request, scope st
// If the query 'sort' or 'order' is empty, use defaults or any values previously saved in Cookies
switch sort {
case "":
sort = sortByName
sort = sortByNameDirFirst
if sortCookie, sortErr := r.Cookie("sort"); sortErr == nil {
sort = sortCookie.Value
}
case sortByName, sortBySize, sortByTime:
case sortByName, sortByNameDirFirst, sortBySize, sortByTime:
http.SetCookie(w, &http.Cookie{Name: "sort", Value: sort, Path: scope, Secure: r.TLS != nil})
}
......
......@@ -70,6 +70,13 @@ func TestSort(t *testing.T) {
t.Errorf("The listing isn't time sorted: %v", listing.Items)
}
// sort by name dir first
listing.Sort = "namedirfirst"
listing.applySort()
if !sort.IsSorted(byNameDirFirst(listing)) {
t.Errorf("The listing isn't namedirfirst sorted: %v", listing.Items)
}
// reverse by name
listing.Sort = "name"
listing.Order = "desc"
......@@ -93,6 +100,14 @@ func TestSort(t *testing.T) {
if !isReversed(byTime(listing)) {
t.Errorf("The listing isn't reversed by time: %v", listing.Items)
}
// reverse by name dir first
listing.Sort = "namedirfirst"
listing.Order = "desc"
listing.applySort()
if !isReversed(byNameDirFirst(listing)) {
t.Errorf("The listing isn't reversed by namedirfirst: %v", listing.Items)
}
}
func TestBrowseHTTPMethods(t *testing.T) {
......@@ -257,6 +272,9 @@ func TestBrowseJson(t *testing.T) {
Mode: f.Mode(),
})
}
// Test that sort=name returns correct listing.
listing := Listing{Items: fileinfos} // this listing will be used for validation inside the tests
tests := []struct {
......@@ -269,33 +287,33 @@ func TestBrowseJson(t *testing.T) {
}{
//test case 1: testing for default sort and order and without the limit parameter, default sort is by name and the default order is ascending
//without the limit query entire listing will be produced
{"/", "", "", -1, false, listing.Items},
{"/?sort=name", "", "", -1, false, listing.Items},
//test case 2: limit is set to 1, orderBy and sortBy is default
{"/?limit=1", "", "", 1, false, listing.Items[:1]},
{"/?limit=1&sort=name", "", "", 1, false, listing.Items[:1]},
//test case 3 : if the listing request is bigger than total size of listing then it should return everything
{"/?limit=100000000", "", "", 100000000, false, listing.Items},
{"/?limit=100000000&sort=name", "", "", 100000000, false, listing.Items},
//test case 4 : testing for negative limit
{"/?limit=-1", "", "", -1, false, listing.Items},
{"/?limit=-1&sort=name", "", "", -1, false, listing.Items},
//test case 5 : testing with limit set to -1 and order set to descending
{"/?limit=-1&order=desc", "", "desc", -1, false, listing.Items},
{"/?limit=-1&order=desc&sort=name", "", "desc", -1, false, listing.Items},
//test case 6 : testing with limit set to 2 and order set to descending
{"/?limit=2&order=desc", "", "desc", 2, false, listing.Items},
{"/?limit=2&order=desc&sort=name", "", "desc", 2, false, listing.Items},
//test case 7 : testing with limit set to 3 and order set to descending
{"/?limit=3&order=desc", "", "desc", 3, false, listing.Items},
{"/?limit=3&order=desc&sort=name", "", "desc", 3, false, listing.Items},
//test case 8 : testing with limit set to 3 and order set to ascending
{"/?limit=3&order=asc", "", "asc", 3, false, listing.Items},
{"/?limit=3&order=asc&sort=name", "", "asc", 3, false, listing.Items},
//test case 9 : testing with limit set to 1111111 and order set to ascending
{"/?limit=1111111&order=asc", "", "asc", 1111111, false, listing.Items},
{"/?limit=1111111&order=asc&sort=name", "", "asc", 1111111, false, listing.Items},
//test case 10 : testing with limit set to default and order set to ascending and sorting by size
{"/?order=asc&sort=size", "size", "asc", -1, false, listing.Items},
{"/?order=asc&sort=size&sort=name", "size", "asc", -1, false, listing.Items},
//test case 11 : testing with limit set to default and order set to ascending and sorting by last modified
{"/?order=asc&sort=time", "time", "asc", -1, false, listing.Items},
{"/?order=asc&sort=time&sort=name", "time", "asc", -1, false, listing.Items},
//test case 12 : testing with limit set to 1 and order set to ascending and sorting by last modified
{"/?order=asc&sort=time&limit=1", "time", "asc", 1, false, listing.Items},
{"/?order=asc&sort=time&limit=1&sort=name", "time", "asc", 1, false, listing.Items},
//test case 13 : testing with limit set to -100 and order set to ascending and sorting by last modified
{"/?order=asc&sort=time&limit=-100", "time", "asc", -100, false, listing.Items},
{"/?order=asc&sort=time&limit=-100&sort=name", "time", "asc", -100, false, listing.Items},
//test case 14 : testing with limit set to -100 and order set to ascending and sorting by size
{"/?order=asc&sort=size&limit=-100", "size", "asc", -100, false, listing.Items},
{"/?order=asc&sort=size&limit=-100&sort=name", "size", "asc", -100, false, listing.Items},
}
for i, test := range tests {
......
......@@ -342,12 +342,20 @@ footer {
<thead>
<tr>
<th>
{{- if and (eq .Sort "namedirfirst") (ne .Order "desc")}}
<a href="?sort=namedirfirst&order=desc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#up-arrow"></use></svg></a>
{{- else if and (eq .Sort "namedirfirst") (ne .Order "asc")}}
<a href="?sort=namedirfirst&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#down-arrow"></use></svg></a>
{{- else}}
<a href="?sort=namedirfirst&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name</a>
{{- end}}
|
{{- if and (eq .Sort "name") (ne .Order "desc")}}
<a href="?sort=name&order=desc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#up-arrow"></use></svg></a>
<a href="?sort=name&order=desc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">(a-z) <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#up-arrow"></use></svg></a>
{{- else if and (eq .Sort "name") (ne .Order "asc")}}
<a href="?sort=name&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#down-arrow"></use></svg></a>
<a href="?sort=name&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">(a-z) <svg width="1em" height=".4em" version="1.1" viewBox="0 0 12.922194 6.0358899"><use xlink:href="#down-arrow"></use></svg></a>
{{- else}}
<a href="?sort=name&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">Name</a>
<a href="?sort=name&order=asc{{if ne 0 .ItemsLimitedTo}}&limit={{.ItemsLimitedTo}}{{end}}">(a-z)</a>
{{- end}}
</th>
<th>
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment