diff --git a/.editorconfig b/.editorconfig index c9dfe8a4..63339e38 100644 --- a/.editorconfig +++ b/.editorconfig @@ -5,20 +5,14 @@ root = true # Unix-style newlines with a newline ending every file [*] +charset = utf-8 +indent_style = space +indent_size = 2 end_of_line = lf insert_final_newline = true - -# Matches multiple files with brace expansion notation -# Set default charset -[*.{js,go}] -charset = utf-8 +trim_trailing_whitespace = true # 4 space indentation [*.go] indent_style = tab -indent_size = 2 - -# Indentation override for all JS under lib directory -[*.js] -indent_style = space -indent_size = 2 +indent_size = 4 diff --git a/.travis.yml b/.travis.yml index ddd75393..3744e57a 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,13 +1,18 @@ language: go + go: - tip -sudo: false + install: -- go generate -- go get -u -v $(go list -f '{{join .Imports "\n"}}' ./... | sort | uniq | grep -v caddy-filemanager) -- go get -u -v github.com/mholt/caddy/caddyhttp -- go get -u -v github.com/caddyserver/caddydev -- go install github.com/caddyserver/caddydev + - go generate + - go get -u -v $(go list -f '{{join .Imports "\n"}}' ./... | sort | uniq | grep -v caddy-filemanager) + - go get -u -v github.com/mholt/caddy/caddyhttp + - go get -u -v github.com/caddyserver/caddydev + - go install github.com/caddyserver/caddydev + - go get github.com/gordonklaus/ineffassign + script: -- sed -i 's/\_ \"github.com\/mholt\/caddy\/caddyhttp\"/\_ \"github.com\/mholt\/caddy\/caddyhttp\"\n\_ \"github.com\/hacdias\/caddy-filemanager\"/g' $GOPATH/src/github.com/mholt/caddy/caddy/caddymain/run.go -- go build github.com/mholt/caddy/caddy + - sed -i 's/\_ \"github.com\/mholt\/caddy\/caddyhttp\"/\_ \"github.com\/mholt\/caddy\/caddyhttp\"\n\_ \"github.com\/hacdias\/caddy-filemanager\"/g' $GOPATH/src/github.com/mholt/caddy/caddy/caddymain/run.go + - go build github.com/mholt/caddy/caddy + - diff <(echo -n) <(gofmt -s -d .) + - ineffassign . diff --git a/_embed/public/js/.jsbeautifyrc b/_embed/public/js/.jsbeautifyrc index 3077c481..fe7d3e4c 100644 --- a/_embed/public/js/.jsbeautifyrc +++ b/_embed/public/js/.jsbeautifyrc @@ -15,7 +15,7 @@ "end_with_newline": false, // End output with newline "indent_char": " ", // Indentation character "indent_level": 0, // Initial indentation level - "indent_size": 4, // Indentation size + "indent_size": 2, // Indentation size "indent_with_tabs": false, // Indent with tabs, overrides `indent_size` and `indent_char` "jslint_happy": false, // If true, then jslint-stricter mode is enforced "keep_array_indentation": false, // Preserve array indentation diff --git a/_embed/public/js/common.js b/_embed/public/js/common.js index 65fea17d..ae550b94 100644 --- a/_embed/public/js/common.js +++ b/_embed/public/js/common.js @@ -121,7 +121,6 @@ function getCSSRule(rules) { * * * * * * * * * * * * * * * */ // TODO: here, we should create an abstraction layer from the webdav. // We must create functions that do the requests to the webdav backend. -// this functions will contain a 'callback' to be used withing the other function. webdav.move = function(oldLink, newLink) { return new Promise((resolve, reject) => { @@ -140,6 +139,22 @@ webdav.move = function(oldLink, newLink) { }); } +webdav.put = function(link, body) { + return new Promise((resolve, reject) => { + let request = new XMLHttpRequest(); + request.open('PUT', toWebDavURL(link), true); + request.onload = () => { + if (request.status == 201) { + resolve(request.response); + } else { + reject(request.statusText); + } + } + request.onerror = () => reject(request.statusText); + request.send(body); + }); +} + /* * * * * * * * * * * * * * * * * * @@ -614,4 +629,4 @@ document.addEventListener("DOMContentLoaded", function(event) { setupSearch(); return false; -}); +}); \ No newline at end of file diff --git a/_embed/public/js/listing.js b/_embed/public/js/listing.js index a52acab2..09ba2974 100644 --- a/_embed/public/js/listing.js +++ b/_embed/public/js/listing.js @@ -1,430 +1,420 @@ 'use strict'; var listing = { - selectMultiple: false + selectMultiple: false }; listing.reload = function(callback) { - let request = new XMLHttpRequest(); + let request = new XMLHttpRequest(); - request.open('GET', window.location); - request.setRequestHeader('Minimal', 'true'); - request.send(); - request.onreadystatechange = function() { - if (request.readyState == 4) { - if (request.status == 200) { - document.querySelector('body main').innerHTML = request.responseText; - listing.addDoubleTapEvent(); + request.open('GET', window.location); + request.setRequestHeader('Minimal', 'true'); + request.send(); + request.onreadystatechange = function() { + if (request.readyState == 4) { + if (request.status == 200) { + document.querySelector('body main').innerHTML = request.responseText; + listing.addDoubleTapEvent(); - if (typeof callback == 'function') { - callback(); - } - } + if (typeof callback == 'function') { + callback(); } + } } + } } listing.itemDragStart = function(event) { - let el = event.target; + let el = event.target; - for (let i = 0; i < 5; i++) { - if (!el.classList.contains('item')) { - el = el.parentElement; - } + for (let i = 0; i < 5; i++) { + if (!el.classList.contains('item')) { + el = el.parentElement; } + } - event.dataTransfer.setData("id", el.id); - event.dataTransfer.setData("name", el.querySelector('.name').innerHTML); + event.dataTransfer.setData("id", el.id); + event.dataTransfer.setData("name", el.querySelector('.name').innerHTML); } listing.itemDragOver = function(event) { - event.preventDefault(); - let el = event.target; + event.preventDefault(); + let el = event.target; - for (let i = 0; i < 5; i++) { - if (!el.classList.contains('item')) { - el = el.parentElement; - } + for (let i = 0; i < 5; i++) { + if (!el.classList.contains('item')) { + el = el.parentElement; } + } - el.style.opacity = 1; + el.style.opacity = 1; } listing.itemDrop = function(e) { - e.preventDefault(); + e.preventDefault(); - let el = e.target, - id = e.dataTransfer.getData("id"), - name = e.dataTransfer.getData("name"); + let el = e.target, + id = e.dataTransfer.getData("id"), + name = e.dataTransfer.getData("name"); - if (id == "" || name == "") return; + if (id == "" || name == "") return; - for (let i = 0; i < 5; i++) { - if (!el.classList.contains('item')) { - el = el.parentElement; - } + for (let i = 0; i < 5; i++) { + if (!el.classList.contains('item')) { + el = el.parentElement; } + } - if (el.id === id) return; + if (el.id === id) return; - let oldLink = toWebDavURL(document.getElementById(id).dataset.url), - newLink = toWebDavURL(el.dataset.url + name), - request = new XMLHttpRequest(); + let oldLink = document.getElementById(id).dataset.url, + newLink = el.dataset.url + name; - request.open('MOVE', oldLink); - request.setRequestHeader('Destination', newLink); - request.send(); - request.onreadystatechange = function() { - if (request.readyState == 4) { - if (request.status == 201 || request.status == 204) { - listing.reload(); - } - } - } + webdav.move(oldLink, newLink) + .then(() => listing.reload()) + .catch(e => console.log(e)); } listing.documentDrop = function(event) { - event.preventDefault(); - let dt = event.dataTransfer, - files = dt.files, - el = event.target, - items = document.getElementsByClassName('item'); + event.preventDefault(); + let dt = event.dataTransfer, + files = dt.files, + el = event.target, + items = document.getElementsByClassName('item'); - for (let i = 0; i < 5; i++) { - if (el != null && !el.classList.contains('item')) { - el = el.parentElement; - } + for (let i = 0; i < 5; i++) { + if (el != null && !el.classList.contains('item')) { + el = el.parentElement; + } + } + + if (files.length > 0) { + if (el != null && el.classList.contains('item') && el.dataset.dir == "true") { + listing.handleFiles(files, el.querySelector('.name').innerHTML + "/"); + return; } - if (files.length > 0) { - if (el != null && el.classList.contains('item') && el.dataset.dir == "true") { - listing.handleFiles(files, el.querySelector('.name').innerHTML + "/"); - return; - } - - listing.handleFiles(files, ""); - } else { - Array.from(items).forEach(file => { - file.style.opacity = 1; - }); - } + listing.handleFiles(files, ""); + } else { + Array.from(items).forEach(file => { + file.style.opacity = 1; + }); + } } listing.rename = function(event) { - if (!selectedItems.length || selectedItems.length > 1) { - return false; - } + if (!selectedItems.length || selectedItems.length > 1) { + return false; + } - let item = document.getElementById(selectedItems[0]); + let item = document.getElementById(selectedItems[0]); - if (item.classList.contains('disabled')) { - return false; - } + if (item.classList.contains('disabled')) { + return false; + } - let link = item.dataset.url, - name = item.querySelector('.name').innerHTML; + let link = item.dataset.url, + field = item.querySelector('.name'), + name = field.innerHTML; - let submit = (event) => { - event.preventDefault(); + let submit = (event) => { + event.preventDefault(); - let newName = event.currentTarget.querySelector('input').value, - newLink = removeLastDirectoryPartOf(link) + "/" + newName, - html = buttons.rename.querySelector('i').changeToLoading(); - closePrompt(event); + let newName = event.currentTarget.querySelector('input').value, + newLink = removeLastDirectoryPartOf(link) + "/" + newName, + html = buttons.rename.querySelector('i').changeToLoading(); + closePrompt(event); - webdav.move(link, newLink) - .then(data => { - listing.reload(() => { - newName = btoa(newName); - selectedItems = [newName]; - document.getElementById(newName).setAttribute("aria-selected", true); - listing.handleSelectionChange(); - }); + webdav.move(link, newLink).then(() => { + listing.reload(() => { + newName = btoa(newName); + selectedItems = [newName]; + document.getElementById(newName).setAttribute("aria-selected", true); + listing.handleSelectionChange(); + }); - buttons.rename.querySelector('i').changeToDone(false, html); - }) - .catch(error => { - item.querySelector('.name').innerHTML = name; - buttons.rename.querySelector('i').changeToDone(true, html); - }); - - return false; - } + buttons.rename.querySelector('i').changeToDone(false, html); + }).catch(error => { + field.innerHTML = name; + buttons.rename.querySelector('i').changeToDone(true, html); - let clone = document.importNode(templates.question.content, true); - clone.querySelector('h3').innerHTML = 'Rename'; - clone.querySelector('input').value = name; - clone.querySelector('.ok').innerHTML = 'Rename'; - clone.querySelector('form').addEventListener('submit', submit); - - document.querySelector('body').appendChild(clone) - document.querySelector('.overlay').classList.add('active'); - document.querySelector('.prompt').classList.add('active'); + console.log(error); + }); return false; + } + + let clone = document.importNode(templates.question.content, true); + clone.querySelector('h3').innerHTML = 'Rename'; + clone.querySelector('input').value = name; + clone.querySelector('.ok').innerHTML = 'Rename'; + clone.querySelector('form').addEventListener('submit', submit); + + document.querySelector('body').appendChild(clone) + document.querySelector('.overlay').classList.add('active'); + document.querySelector('.prompt').classList.add('active'); + + return false; } listing.handleFiles = function(files, base) { - let button = document.getElementById("upload"), - html = button.querySelector('i').changeToLoading(); + let html = buttons.upload.querySelector('i').changeToLoading(), + promises = []; - for (let i = 0; i < files.length; i++) { - let request = new XMLHttpRequest(); - request.open('PUT', toWebDavURL(window.location.pathname + base + files[i].name)); + for (let file of files) { + promises.push(webdav.put(window.location.pathname + base + file.name, file)); + } - request.send(files[i]); - request.onreadystatechange = function() { - if (request.readyState == 4) { - if (request.status == 201) { - listing.reload(); - } + Promise.all(promises) + .then(() => { + listing.reload(); + buttons.upload.querySelector('i').changeToDone(false, html); + }) + .catch(e => { + console.log(e); + buttons.upload.querySelector('i').changeToDone(true, html); + }) - button.querySelector('i').changeToDone((request.status != 201), html); - } - } - } - - return false; + return false; } listing.unselectAll = function() { - let items = document.getElementsByClassName('item'); - Array.from(items).forEach(link => { - link.setAttribute("aria-selected", false); - }); + let items = document.getElementsByClassName('item'); + Array.from(items).forEach(link => { + link.setAttribute("aria-selected", false); + }); - selectedItems = []; + selectedItems = []; - listing.handleSelectionChange(); - return false; + listing.handleSelectionChange(); + return false; } listing.handleSelectionChange = function(event) { - listing.redefineDownloadURLs(); + listing.redefineDownloadURLs(); - let selectedNumber = selectedItems.length, - fileAction = document.getElementById("file-only"); + let selectedNumber = selectedItems.length, + fileAction = document.getElementById("file-only"); - if (selectedNumber) { - fileAction.classList.remove("disabled"); + if (selectedNumber) { + fileAction.classList.remove("disabled"); - if (selectedNumber > 1) { - buttons.open.classList.add("disabled"); - buttons.rename.classList.add("disabled"); - } - - if (selectedNumber == 1) { - if (document.getElementById(selectedItems[0]).dataset.dir == "true") { - buttons.open.classList.add("disabled"); - } else { - buttons.open.classList.remove("disabled"); - } - - buttons.rename.classList.remove("disabled"); - } - - return false; + if (selectedNumber > 1) { + buttons.open.classList.add("disabled"); + buttons.rename.classList.add("disabled"); + } + + if (selectedNumber == 1) { + if (document.getElementById(selectedItems[0]).dataset.dir == "true") { + buttons.open.classList.add("disabled"); + } else { + buttons.open.classList.remove("disabled"); + } + + buttons.rename.classList.remove("disabled"); } - fileAction.classList.add("disabled"); return false; + } + + fileAction.classList.add("disabled"); + return false; } listing.redefineDownloadURLs = function() { - let files = ""; + let files = ""; - for (let i = 0; i < selectedItems.length; i++) { - let url = document.getElementById(selectedItems[i]).dataset.url; - files += url.replace(window.location.pathname, "") + ","; - } + for (let i = 0; i < selectedItems.length; i++) { + let url = document.getElementById(selectedItems[i]).dataset.url; + files += url.replace(window.location.pathname, "") + ","; + } - files = files.substring(0, files.length - 1); - files = encodeURIComponent(files); + files = files.substring(0, files.length - 1); + files = encodeURIComponent(files); - let links = document.querySelectorAll("#download ul a"); - Array.from(links).forEach(link => { - link.href = "?download=" + link.dataset.format + "&files=" + files; - }); + let links = document.querySelectorAll("#download ul a"); + Array.from(links).forEach(link => { + link.href = "?download=" + link.dataset.format + "&files=" + files; + }); } listing.openItem = function(event) { - window.location = event.currentTarget.dataset.url; + window.location = event.currentTarget.dataset.url; } listing.selectItem = function(event) { - let el = event.currentTarget; + let el = event.currentTarget; - if (selectedItems.length != 0) event.preventDefault(); - if (selectedItems.indexOf(el.id) == -1) { - if (!event.ctrlKey && !listing.selectMultiple) listing.unselectAll(); + if (selectedItems.length != 0) event.preventDefault(); + if (selectedItems.indexOf(el.id) == -1) { + if (!event.ctrlKey && !listing.selectMultiple) listing.unselectAll(); - el.setAttribute("aria-selected", true); - selectedItems.push(el.id); - } else { - el.setAttribute("aria-selected", false); - selectedItems.removeElement(el.id); - } + el.setAttribute("aria-selected", true); + selectedItems.push(el.id); + } else { + el.setAttribute("aria-selected", false); + selectedItems.removeElement(el.id); + } - listing.handleSelectionChange(); - return false; + listing.handleSelectionChange(); + return false; } listing.newFileButton = function(event) { - event.preventDefault(); + event.preventDefault(); - let clone = document.importNode(templates.question.content, true); - clone.querySelector('h3').innerHTML = 'New file'; - clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.'; - clone.querySelector('.ok').innerHTML = 'Create'; - clone.querySelector('form').addEventListener('submit', listing.newFilePrompt); + let clone = document.importNode(templates.question.content, true); + clone.querySelector('h3').innerHTML = 'New file'; + clone.querySelector('p').innerHTML = 'End with a trailing slash to create a dir.'; + clone.querySelector('.ok').innerHTML = 'Create'; + clone.querySelector('form').addEventListener('submit', listing.newFilePrompt); - document.querySelector('body').appendChild(clone) - document.querySelector('.overlay').classList.add('active'); - document.querySelector('.prompt').classList.add('active'); + document.querySelector('body').appendChild(clone) + document.querySelector('.overlay').classList.add('active'); + document.querySelector('.prompt').classList.add('active'); } listing.newFilePrompt = function(event) { - event.preventDefault(); + event.preventDefault(); - let button = document.getElementById('new'), - html = button.querySelector('i').changeToLoading(), - request = new XMLHttpRequest(), - name = event.currentTarget.querySelector('input').value; + let button = document.getElementById('new'), + html = button.querySelector('i').changeToLoading(), + request = new XMLHttpRequest(), + name = event.currentTarget.querySelector('input').value; - request.open((name.endsWith("/") ? "MKCOL" : "PUT"), toWebDavURL(window.location.pathname + name)); - request.send(); - request.onreadystatechange = function() { - if (request.readyState == 4) { - button.querySelector('i').changeToDone((request.status != 201), html); - listing.reload(); - } + request.open((name.endsWith("/") ? "MKCOL" : "PUT"), toWebDavURL(window.location.pathname + name)); + request.send(); + request.onreadystatechange = function() { + if (request.readyState == 4) { + button.querySelector('i').changeToDone((request.status != 201), html); + listing.reload(); } + } - closePrompt(event); - return false; + closePrompt(event); + return false; } listing.updateColumns = function(event) { - let columns = Math.floor(document.getElementById('listing').offsetWidth / 300), - items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item']); + let columns = Math.floor(document.getElementById('listing').offsetWidth / 300), + items = getCSSRule(['#listing.mosaic .item', '.mosaic#listing .item']); - items.style.width = `calc(${100/columns}% - 1em)`; + items.style.width = `calc(${100/columns}% - 1em)`; } listing.addDoubleTapEvent = function() { - let items = document.getElementsByClassName('item'), - touches = { - id: '', - count: 0 - }; + let items = document.getElementsByClassName('item'), + touches = { + id: '', + count: 0 + }; - Array.from(items).forEach(file => { - file.addEventListener('touchstart', event => { - console.log("hey") - if (touches.id != file.id) { - touches.id = file.id; - touches.count = 1; + Array.from(items).forEach(file => { + file.addEventListener('touchstart', event => { + if (touches.id != file.id) { + touches.id = file.id; + touches.count = 1; - setTimeout(() => { - touches.count = 0; - }, 500) + setTimeout(() => { + touches.count = 0; + }, 500) - return; - } + return; + } - touches.count++; + touches.count++; - if (touches.count > 1) { - window.location = file.dataset.url; - } - }); + if (touches.count > 1) { + window.location = file.dataset.url; + } }); + }); } // Keydown events window.addEventListener('keydown', (event) => { - if (event.keyCode == 27) { - listing.unselectAll(); + if (event.keyCode == 27) { + listing.unselectAll(); - if (document.querySelectorAll('.prompt').length) { - closePrompt(event); - } + if (document.querySelectorAll('.prompt').length) { + closePrompt(event); } + } - if (event.keyCode == 113) { - listing.rename(); - } + if (event.keyCode == 113) { + listing.rename(); + } - if (event.ctrlKey || event.metaKey) { - console.log("hey") - switch (String.fromCharCode(event.which).toLowerCase()) { - case 's': - event.preventDefault(); - window.location = "?download=true" - } + if (event.ctrlKey || event.metaKey) { + console.log("hey") + switch (String.fromCharCode(event.which).toLowerCase()) { + case 's': + event.preventDefault(); + window.location = "?download=true" } + } }); window.addEventListener("resize", () => { - listing.updateColumns(); + listing.updateColumns(); }); document.addEventListener('DOMContentLoaded', event => { - listing.updateColumns(); - listing.addDoubleTapEvent(); + listing.updateColumns(); + listing.addDoubleTapEvent(); - buttons.rename = document.getElementById("rename"); - buttons.upload = document.getElementById("upload"); - buttons.new = document.getElementById('new'); - buttons.download = document.getElementById('download'); + buttons.rename = document.getElementById("rename"); + buttons.upload = document.getElementById("upload"); + buttons.new = document.getElementById('new'); + buttons.download = document.getElementById('download'); - document.getElementById('multiple-selection-activate').addEventListener('click', event => { - listing.selectMultiple = true; - clickOverlay.click(); + document.getElementById('multiple-selection-activate').addEventListener('click', event => { + listing.selectMultiple = true; + clickOverlay.click(); - document.getElementById('multiple-selection').classList.add('active'); - document.querySelector('body').style.paddingBottom = "4em"; - }) + document.getElementById('multiple-selection').classList.add('active'); + document.querySelector('body').style.paddingBottom = "4em"; + }) - document.getElementById('multiple-selection-cancel').addEventListener('click', event => { - listing.selectMultiple = false; + document.getElementById('multiple-selection-cancel').addEventListener('click', event => { + listing.selectMultiple = false; - document.querySelector('body').style.paddingBottom = "0"; - document.getElementById('multiple-selection').classList.remove('active'); - }) + document.querySelector('body').style.paddingBottom = "0"; + document.getElementById('multiple-selection').classList.remove('active'); + }) - if (user.AllowEdit) { - buttons.rename.addEventListener("click", listing.rename); - } + if (user.AllowEdit) { + buttons.rename.addEventListener("click", listing.rename); + } - let items = document.getElementsByClassName('item'); + let items = document.getElementsByClassName('item'); - if (user.AllowNew) { - buttons.upload.addEventListener("click", (event) => { - document.getElementById("upload-input").click(); - }); + if (user.AllowNew) { + buttons.upload.addEventListener("click", (event) => { + document.getElementById("upload-input").click(); + }); - buttons.new.addEventListener('click', listing.newFileButton); + buttons.new.addEventListener('click', listing.newFileButton); - // Drag and Drop - document.addEventListener("dragover", function(event) { - event.preventDefault(); - }, false); + // Drag and Drop + document.addEventListener("dragover", function(event) { + event.preventDefault(); + }, false); - document.addEventListener("dragenter", (event) => { - Array.from(items).forEach(file => { - file.style.opacity = 0.5; - }); - }, false); + document.addEventListener("dragenter", (event) => { + Array.from(items).forEach(file => { + file.style.opacity = 0.5; + }); + }, false); - document.addEventListener("dragend", (event) => { - Array.from(items).forEach(file => { - file.style.opacity = 1; - }); - }, false); + document.addEventListener("dragend", (event) => { + Array.from(items).forEach(file => { + file.style.opacity = 1; + }); + }, false); - document.addEventListener("drop", listing.documentDrop, false); - } + document.addEventListener("drop", listing.documentDrop, false); + } });