diff --git a/_embed/public/css/styles.css b/_embed/public/css/styles.css
index 6b9b4927..0fa6c0cc 100644
--- a/_embed/public/css/styles.css
+++ b/_embed/public/css/styles.css
@@ -558,7 +558,17 @@ header p i {
top: 100%;
}
-#search div {
+#search ul {
+ padding: 0;
+ margin: 0;
+ list-style: none;
+}
+
+#search li {
+ margin-bottom: .5em;
+}
+
+#search>div {
position: absolute;
top: 0;
width: 100%;
@@ -577,6 +587,9 @@ header p i {
overflow-x: hidden;
overflow-y: auto;
max-height: 50vh;
+}
+
+#search>div div {
white-space: pre-wrap;
white-space: -moz-pre-wrap;
white-space: -pre-wrap;
@@ -584,6 +597,18 @@ header p i {
word-wrap: break-word;
}
+#search>div p {
+ width: 100%;
+ text-align: center;
+ display: none;
+ margin: 0;
+ max-width: none;
+}
+
+#search.ongoing p {
+ display: block;
+}
+
#search.active div i,
#sidebar #search.active div i {
color: #ccc;
diff --git a/_embed/public/js/application.js b/_embed/public/js/application.js
index 4878ae1f..a3583d00 100644
--- a/_embed/public/js/application.js
+++ b/_embed/public/js/application.js
@@ -466,10 +466,12 @@ var redefineDownloadURLs = function() {
var searchEvent = function(event) {
let value = this.value;
- let box = document.querySelector('#search div');
+ let search = document.getElementById('search');
+ let scrollable = document.querySelector('#search > div');
+ let box = document.querySelector('#search > div div');
if (value.length == 0) {
- box.innerHTML = "Write one of your supported commands: " + user.Commands.join(", ") + ".";
+ box.innerHTML = "Search or use one of your supported commands: " + user.Commands.join(", ") + ".";
return;
}
@@ -483,27 +485,47 @@ var searchEvent = function(event) {
});
if (!supported) {
- box.innerHTML = "Command not supported."
- return;
+ box.innerHTML = "Press enter to search."
+ } else {
+ box.innerHTML = "Press enter to execute."
}
- box.innerHTML = "Press enter to continue."
-
if (event.keyCode == 13) {
- box.innerHTML = 'autorenew';
+ box.innerHTML = '';
+ search.classList.add('ongoing');
- var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?command=true');
- conn.onopen = function() {
- conn.send(value);
- };
+ if (supported) {
+ var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?command=true');
+ conn.onopen = function() {
+ conn.send(value);
+ };
- conn.onmessage = function(event) {
- box.innerHTML = event.data
- box.scrollTop = box.scrollHeight;
- }
+ conn.onmessage = function(event) {
+ box.innerHTML = event.data;
+ scrollable.scrollTop = scrollable.scrollHeight;
+ }
- conn.onclose = function(event) {
- reloadListing();
+ conn.onclose = function(event) {
+ search.classList.remove('ongoing');
+ reloadListing();
+ }
+ } else {
+ box.innerHTML = '
';
+ let ul = box.querySelector('ul');
+
+ var conn = new WebSocket('ws://' + window.location.host + window.location.pathname + '?search=true');
+ conn.onopen = function() {
+ conn.send(value);
+ };
+
+ conn.onmessage = function(event) {
+ ul.innerHTML += '' + event.data + '';
+ scrollable.scrollTop = scrollable.scrollHeight;
+ }
+
+ conn.onclose = function(event) {
+ search.classList.remove('ongoing');
+ }
}
}
}
@@ -557,7 +579,7 @@ document.addEventListener('listing', event => {
document.getElementById('search').classList.remove('active');
});
- document.querySelector('#search div').innerHTML = "Write one of yours suported commands: " + user.Commands.join(", ") + ".";
+ document.querySelector('#search > div div').innerHTML = "Search or use one of yours suported commands: " + user.Commands.join(", ") + ".";
document.querySelector('#search input').addEventListener('keyup', searchEvent);
}
@@ -900,4 +922,4 @@ document.addEventListener("DOMContentLoaded", function(event) {
}
return false;
-});
+});
\ No newline at end of file
diff --git a/_embed/templates/base.tmpl b/_embed/templates/base.tmpl
index 88a4568f..78c9aa10 100644
--- a/_embed/templates/base.tmpl
+++ b/_embed/templates/base.tmpl
@@ -52,7 +52,10 @@
storage
-
Write your git, mercurial or svn command and press enter.
+
+
Write your git, mercurial or svn command and press enter.
+
autorenew
+
{{ end }}
diff --git a/filemanager.go b/filemanager.go
index b2da027f..9a64c276 100644
--- a/filemanager.go
+++ b/filemanager.go
@@ -67,10 +67,6 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
user = c.User
}
- if r.URL.Query().Get("command") != "" {
- return handlers.Command(w, r, c, user)
- }
-
// Checks if the request URL is for the WebDav server
if strings.HasPrefix(r.URL.Path, c.WebDavURL) {
// Checks for user permissions relatively to this PATH
@@ -112,6 +108,14 @@ func (f FileManager) ServeHTTP(w http.ResponseWriter, r *http.Request) (int, err
return http.StatusForbidden, nil
}
+ if r.URL.Query().Get("search") != "" {
+ return handlers.Search(w, r, c, user)
+ }
+
+ if r.URL.Query().Get("command") != "" {
+ return handlers.Command(w, r, c, user)
+ }
+
if r.Method == http.MethodGet {
// Gets the information of the directory/file
fi, code, err = file.GetInfo(r.URL, c, user)
diff --git a/handlers/search.go b/handlers/search.go
new file mode 100644
index 00000000..13fde593
--- /dev/null
+++ b/handlers/search.go
@@ -0,0 +1,65 @@
+package handlers
+
+import (
+ "net/http"
+ "os"
+ "path/filepath"
+ "strings"
+
+ "github.com/gorilla/websocket"
+ "github.com/hacdias/caddy-filemanager/config"
+)
+
+func Search(w http.ResponseWriter, r *http.Request, c *config.Config, u *config.User) (int, error) {
+ // Upgrades the connection to a websocket and checks for errors.
+ conn, err := upgrader.Upgrade(w, r, nil)
+ if err != nil {
+ return 0, err
+ }
+ defer conn.Close()
+
+ var search string
+
+ // Starts an infinite loop until a valid command is captured.
+ for {
+ _, message, err := conn.ReadMessage()
+ if err != nil {
+ return http.StatusInternalServerError, err
+ }
+
+ if len(message) != 0 {
+ search = string(message)
+ break
+ }
+ }
+
+ scope := strings.Replace(r.URL.Path, c.BaseURL, "", 1)
+ scope = strings.TrimPrefix(scope, "/")
+ scope = "/" + scope
+ scope = u.Scope + scope
+ scope = strings.Replace(scope, "\\", "/", -1)
+ scope = filepath.Clean(scope)
+
+ err = filepath.Walk(scope, func(path string, f os.FileInfo, err error) error {
+ // TODO: check user permissions?
+
+ if strings.Contains(path, search) {
+ path = strings.TrimPrefix(path, scope)
+ path = strings.Replace(path, "\\", "/", -1)
+ path = strings.TrimPrefix(path, "/")
+
+ err = conn.WriteMessage(websocket.TextMessage, []byte(path))
+ if err != nil {
+ return err
+ }
+ }
+
+ return nil
+ })
+
+ if err != nil {
+ return http.StatusInternalServerError, err
+ }
+
+ return http.StatusOK, nil
+}
diff --git a/page/page.go b/page/page.go
index 9d30d851..3cc08fd5 100644
--- a/page/page.go
+++ b/page/page.go
@@ -139,7 +139,7 @@ func (p Page) PrintAsHTML(w http.ResponseWriter, templates ...string) (int, erro
// PrintAsJSON prints the current Page infromation in JSON
func (p Page) PrintAsJSON(w http.ResponseWriter) (int, error) {
- marsh, err := json.Marshal(p.Info.Data)
+ marsh, err := json.MarshalIndent(p.Info.Data, "", " ")
if err != nil {
return http.StatusInternalServerError, err
}