mirror of
https://github.com/filebrowser/filebrowser.git
synced 2024-06-07 23:00:43 +00:00
updates
This commit is contained in:
parent
0a3ca3a149
commit
758fe34287
@ -35,6 +35,24 @@ pre {
|
|||||||
word-wrap: break-word;
|
word-wrap: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
button {
|
||||||
|
border: 0;
|
||||||
|
padding: .5em 1em;
|
||||||
|
margin-left: .5em;
|
||||||
|
border-radius: .1em;
|
||||||
|
background-color;
|
||||||
|
cursor: pointer;
|
||||||
|
background: #2196f3;
|
||||||
|
color: #fff;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.05);
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.05);
|
||||||
|
transition: .1s ease all;
|
||||||
|
}
|
||||||
|
|
||||||
|
button:hover {
|
||||||
|
background-color: #1E88E5;
|
||||||
|
}
|
||||||
|
|
||||||
.container {
|
.container {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
max-width: 960px;
|
max-width: 960px;
|
||||||
@ -541,7 +559,7 @@ header .actions {
|
|||||||
vertical-align: middle;
|
vertical-align: middle;
|
||||||
}
|
}
|
||||||
|
|
||||||
#bottom-bar div:first-child>i {
|
#bottom-bar>div:first-child>i {
|
||||||
margin-right: .3em;
|
margin-right: .3em;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -836,6 +854,81 @@ header .actions {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* * * * * * * * * * * * * * * *
|
||||||
|
* PROMPT *
|
||||||
|
* * * * * * * * * * * * * * * */
|
||||||
|
|
||||||
|
.overlay, .prompt {
|
||||||
|
opacity: 0;
|
||||||
|
z-index: -1;
|
||||||
|
transition: .1s ease opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay.active, .prompt.active {
|
||||||
|
z-index: 9999999;
|
||||||
|
opacity: 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
.overlay {
|
||||||
|
background-color: rgba(0, 0, 0, 0.5);
|
||||||
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
height: 100%;
|
||||||
|
z-index: -1;
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt {
|
||||||
|
position: fixed;
|
||||||
|
top: 50%;
|
||||||
|
left: 50%;
|
||||||
|
transform: translate(-50%, -50%);
|
||||||
|
z-index: 99999999;
|
||||||
|
background: #fff;
|
||||||
|
border: 1px solid rgba(0, 0, 0, 0.075);
|
||||||
|
box-shadow: 0 0 5px rgba(0, 0, 0, 0.1);
|
||||||
|
padding: 2em;
|
||||||
|
max-width: 25em;
|
||||||
|
width: 95%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt h3 {
|
||||||
|
margin: 0;
|
||||||
|
font-weight: 500;
|
||||||
|
font-size: 1.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt p {
|
||||||
|
font-size: .9em;
|
||||||
|
color: rgba(0, 0, 0, 0.8);
|
||||||
|
margin: .5em 0 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt input {
|
||||||
|
width: 100%;
|
||||||
|
border: 1px solid #dadada;
|
||||||
|
line-height: 1;
|
||||||
|
padding: .3em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt div {
|
||||||
|
margin-top: 1em;
|
||||||
|
display: flex;
|
||||||
|
justify-content: flex-start;
|
||||||
|
flex-direction: row-reverse;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt .cancel {
|
||||||
|
background-color: #ECEFF1;
|
||||||
|
color: #37474F;
|
||||||
|
}
|
||||||
|
|
||||||
|
.prompt .cancel:hover {
|
||||||
|
background-color: #e9eaeb;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* * * * * * * * * * * * * * * *
|
/* * * * * * * * * * * * * * * *
|
||||||
* FOOTER *
|
* FOOTER *
|
||||||
* * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * */
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
var tempID = "_fm_internal_temporary_id",
|
var tempID = "_fm_internal_temporary_id",
|
||||||
buttons = {},
|
buttons = {},
|
||||||
|
templates = {},
|
||||||
selectedItems = [];
|
selectedItems = [];
|
||||||
|
|
||||||
// Removes an element, if exists, from an array
|
// Removes an element, if exists, from an array
|
||||||
@ -95,7 +96,9 @@ function toWebDavURL(url) {
|
|||||||
// Remove the last directory of an url
|
// Remove the last directory of an url
|
||||||
var removeLastDirectoryPartOf = function(url) {
|
var removeLastDirectoryPartOf = function(url) {
|
||||||
var arr = url.split('/');
|
var arr = url.split('/');
|
||||||
arr.pop();
|
if (arr.pop() === "") {
|
||||||
|
arr.pop();
|
||||||
|
}
|
||||||
return (arr.join('/'));
|
return (arr.join('/'));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,6 +107,29 @@ var removeLastDirectoryPartOf = function(url) {
|
|||||||
* EVENTS *
|
* EVENTS *
|
||||||
* *
|
* *
|
||||||
* * * * * * * * * * * * * * * */
|
* * * * * * * * * * * * * * * */
|
||||||
|
function closePrompt(event) {
|
||||||
|
let prompt = document.querySelector('.prompt');
|
||||||
|
|
||||||
|
event.preventDefault();
|
||||||
|
document.querySelector('.overlay').classList.remove('active');
|
||||||
|
prompt.classList.remove('active');
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
prompt.remove();
|
||||||
|
}, 100);
|
||||||
|
}
|
||||||
|
|
||||||
|
function notImplemented(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
let clone = document.importNode(templates.info.content, true);
|
||||||
|
clone.querySelector('h3').innerHTML = 'Not implemented';
|
||||||
|
clone.querySelector('p').innerHTML = "Sorry, but this feature wasn't implemented yet.";
|
||||||
|
|
||||||
|
document.querySelector('body').appendChild(clone)
|
||||||
|
document.querySelector('.overlay').classList.add('active');
|
||||||
|
document.querySelector('.prompt').classList.add('active');
|
||||||
|
}
|
||||||
|
|
||||||
// Prevent Default event
|
// Prevent Default event
|
||||||
var preventDefault = function(event) {
|
var preventDefault = function(event) {
|
||||||
@ -138,6 +164,45 @@ function openEvent(event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function deleteSelected(single) {
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
Array.from(selectedItems).forEach(id => {
|
||||||
|
let request = new XMLHttpRequest(),
|
||||||
|
html = buttons.delete.changeToLoading(),
|
||||||
|
el, url;
|
||||||
|
|
||||||
|
if (single) {
|
||||||
|
url = window.location.pathname;
|
||||||
|
} else {
|
||||||
|
el = document.getElementById(id);
|
||||||
|
url = el.dataset.url;
|
||||||
|
}
|
||||||
|
|
||||||
|
request.open('DELETE', toWebDavURL(url));
|
||||||
|
request.onreadystatechange = function() {
|
||||||
|
if (request.readyState == 4) {
|
||||||
|
if (request.status == 204) {
|
||||||
|
if (single) {
|
||||||
|
window.location.pathname = removeLastDirectoryPartOf(window.location.pathname);
|
||||||
|
} else {
|
||||||
|
el.remove();
|
||||||
|
selectedItems.removeElement(id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
buttons.delete.changeToDone(request.status != 204, html);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
request.send();
|
||||||
|
});
|
||||||
|
|
||||||
|
closePrompt(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Handles the delete button event
|
// Handles the delete button event
|
||||||
function deleteEvent(event) {
|
function deleteEvent(event) {
|
||||||
let single = false;
|
let single = false;
|
||||||
@ -147,36 +212,16 @@ function deleteEvent(event) {
|
|||||||
single = true;
|
single = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
Array.from(selectedItems).forEach(id => {
|
let clone = document.importNode(templates.question.content, true);
|
||||||
let request = new XMLHttpRequest(),
|
clone.querySelector('h3').innerHTML = 'Delete files';
|
||||||
html = buttons.delete.changeToLoading(),
|
clone.querySelector('p').innerHTML = `Are you sure you want to delete ${selectedItems.length} file(s)?`;
|
||||||
el, url;
|
clone.querySelector('input').remove();
|
||||||
|
clone.querySelector('.ok').innerHTML = 'Delete';
|
||||||
|
clone.querySelector('form').addEventListener('submit', deleteSelected(single));
|
||||||
|
|
||||||
if (single) {
|
document.querySelector('body').appendChild(clone)
|
||||||
url = window.location.pathname;
|
document.querySelector('.overlay').classList.add('active');
|
||||||
} else {
|
document.querySelector('.prompt').classList.add('active');
|
||||||
el = document.getElementById(id);
|
|
||||||
url = el.dataset.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
request.open('DELETE', toWebDavURL(url));
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if (request.readyState == 4) {
|
|
||||||
if (request.status == 204) {
|
|
||||||
if (single) {
|
|
||||||
window.location.pathname = removeLastDirectoryPartOf(window.location.pathname);
|
|
||||||
} else {
|
|
||||||
el.remove();
|
|
||||||
selectedItems.removeElement(id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
buttons.delete.changeToDone(request.status != 204, html);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
request.send();
|
|
||||||
});
|
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -320,6 +365,9 @@ document.addEventListener("DOMContentLoaded", function(event) {
|
|||||||
buttons.logout.addEventListener("click", logoutEvent);
|
buttons.logout.addEventListener("click", logoutEvent);
|
||||||
buttons.open.addEventListener("click", openEvent);
|
buttons.open.addEventListener("click", openEvent);
|
||||||
|
|
||||||
|
templates.question = document.querySelector('#question-template');
|
||||||
|
templates.info = document.querySelector('#info-template');
|
||||||
|
|
||||||
if (user.AllowEdit) {
|
if (user.AllowEdit) {
|
||||||
buttons.delete.addEventListener("click", deleteEvent);
|
buttons.delete.addEventListener("click", deleteEvent);
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,5 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var templates = [];
|
|
||||||
|
|
||||||
function textareaAutoGrow() {
|
function textareaAutoGrow() {
|
||||||
let autogrow = function() {
|
let autogrow = function() {
|
||||||
this.style.height = '5px';
|
this.style.height = '5px';
|
||||||
@ -26,140 +24,133 @@ function deleteFrontMatterItem(event) {
|
|||||||
document.getElementById(this.dataset.delete).remove();
|
document.getElementById(this.dataset.delete).remove();
|
||||||
}
|
}
|
||||||
|
|
||||||
function addFrontMatterItem(event) {
|
function makeFromBaseTemplate(id, type, name, parent) {
|
||||||
event.preventDefault();
|
let clone = document.importNode(templates.base.content, true);
|
||||||
let clone;
|
clone.querySelector('fieldset').id = id;
|
||||||
let temp = document.getElementById(tempID)
|
clone.querySelector('fieldset').dataset.type = type;
|
||||||
if (temp) {
|
clone.querySelector('h3').innerHTML = name;
|
||||||
temp.remove();
|
clone.querySelector('.delete').dataset.delete = id;
|
||||||
|
clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem);
|
||||||
|
clone.querySelector('.add').addEventListener('click', addFrontMatterItem);
|
||||||
|
|
||||||
|
if (parent.classList.contains("frontmatter")) {
|
||||||
|
parent.insertBefore(clone, document.querySelector('div.button.add'));
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
let block = this.parentNode,
|
parent.appendChild(clone);
|
||||||
type = block.dataset.type,
|
}
|
||||||
id = block.id;
|
|
||||||
|
function makeFromArrayItemTemplate(id, number, parent) {
|
||||||
|
let clone = document.importNode(templates.arrayItem.content, true);
|
||||||
|
clone.querySelector('[data-type="array-item"]').id = `${id}-${number}`;
|
||||||
|
clone.querySelector('input').name = id;
|
||||||
|
clone.querySelector('input').id = id;
|
||||||
|
clone.querySelector('div.action').dataset.delete = `${id}-${number}`;
|
||||||
|
clone.querySelector('div.action').addEventListener('click', deleteFrontMatterItem);
|
||||||
|
parent.querySelector('.group').appendChild(clone)
|
||||||
|
document.getElementById(`${id}-${number}`).querySelector('input').focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function makeFromObjectItemTemplate(id, name, parent) {
|
||||||
|
let clone = document.importNode(templates.objectItem.content, true);
|
||||||
|
clone.querySelector('.block').id = `block-${id}`;
|
||||||
|
clone.querySelector('.block').dataset.content = id;
|
||||||
|
clone.querySelector('label').for = id;
|
||||||
|
clone.querySelector('label').innerHTML = name;
|
||||||
|
clone.querySelector('input').name = id;
|
||||||
|
clone.querySelector('input').id = id;
|
||||||
|
clone.querySelector('.action').dataset.delete = `block-${id}`;
|
||||||
|
clone.querySelector('.action').addEventListener('click', deleteFrontMatterItem);
|
||||||
|
|
||||||
|
parent.appendChild(clone)
|
||||||
|
document.getElementById(id).focus();
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFrontMatterItemPrompt(parent) {
|
||||||
|
return function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
let value = event.currentTarget.querySelector('input').value;
|
||||||
|
if (value === '') {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
closePrompt(event);
|
||||||
|
|
||||||
|
let name = value.substring(0, value.lastIndexOf(':')),
|
||||||
|
type = value.substring(value.lastIndexOf(':') + 1, value.length);
|
||||||
|
|
||||||
|
if (type !== "" && type !== "array" && type !== "object") {
|
||||||
|
name = value;
|
||||||
|
}
|
||||||
|
|
||||||
|
name = name.replace(' ', '_');
|
||||||
|
|
||||||
|
let id = name;
|
||||||
|
|
||||||
|
if (parent.id != '') {
|
||||||
|
id = parent.id + "." + id;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (type == "array" || type == "object") {
|
||||||
|
if (parent.dataset.type == "parent") {
|
||||||
|
makeFromBaseTemplate(bid, newtype, name, document.querySelector('.frontmatter'));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
makeFromBaseTemplate(bid, newtype, name, block);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
let group = parent.querySelector('.group');
|
||||||
|
|
||||||
|
if (group == null) {
|
||||||
|
parent.insertAdjacentHTML('afterbegin', '<div class="group"></div>');
|
||||||
|
group = parent.querySelector('.group');
|
||||||
|
}
|
||||||
|
|
||||||
|
makeFromObjectItemTemplate(id, name, group);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function addFrontMatterItem(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
let parent = event.currentTarget.parentNode,
|
||||||
|
type = parent.dataset.type;
|
||||||
|
|
||||||
// If the block is an array
|
// If the block is an array
|
||||||
if (type === "array") {
|
if (type === "array") {
|
||||||
let fieldID = id + "[]",
|
let id = parent.id + "[]",
|
||||||
input = fieldID,
|
count = parent.querySelectorAll('.group > div').length,
|
||||||
count = block.querySelectorAll('.group > div').length;
|
fieldsets = parent.getElementsByTagName("fieldset");
|
||||||
|
|
||||||
input = input.replace(/\[/, '\\[');
|
|
||||||
input = input.replace(/\]/, '\\]');
|
|
||||||
|
|
||||||
let fieldsets = block.getElementsByTagName("fieldset");
|
|
||||||
|
|
||||||
if (fieldsets.length > 0) {
|
if (fieldsets.length > 0) {
|
||||||
let newtype = fieldsets[0].dataset.type,
|
let itemType = fieldsets[0].dataset.type,
|
||||||
bid = id + "[" + fieldsets.length + "]",
|
itemID = parent.id + "[" + fieldsets.length + "]",
|
||||||
name = fieldsets.length;
|
itemName = fieldsets.length;
|
||||||
|
|
||||||
clone = document.importNode(templates.base.content, true);
|
makeFromBaseTemplate(itemID, itemType, itemName, parent);
|
||||||
clone.querySelector('fieldset').id = bid;
|
|
||||||
clone.querySelector('fieldset').dataset.type = newtype;
|
|
||||||
clone.querySelector('h3').innerHTML = name;
|
|
||||||
clone.querySelector('.delete').dataset.delete = bid;
|
|
||||||
clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem);
|
|
||||||
clone.querySelector('.add').addEventListener('click', addFrontMatterItem);
|
|
||||||
block.appendChild(clone);
|
|
||||||
} else {
|
} else {
|
||||||
clone = document.importNode(templates.arrayItem.content, true);
|
makeFromArrayItemTemplate(id, count, parent);
|
||||||
clone.querySelector('[data-type="array-item"]').id = `${fieldID}-${count}`;
|
|
||||||
clone.querySelector('input').name = fieldID;
|
|
||||||
clone.querySelector('input').id = fieldID;
|
|
||||||
clone.querySelector('div.action').dataset.delete = `${fieldID}-${count}`;
|
|
||||||
clone.querySelector('div.action').addEventListener('click', deleteFrontMatterItem);
|
|
||||||
block.querySelector('.group').appendChild(clone)
|
|
||||||
document.getElementById(`${fieldID}-${count}`).querySelector('input').focus();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == "object" || type == "parent") {
|
if (type == "object" || type == "parent") {
|
||||||
clone = document.importNode(templates.temporary.content, true);
|
let clone = document.importNode(templates.question.content, true);
|
||||||
clone.querySelector('.group').id = tempID;
|
clone.querySelector('form').id = tempID;
|
||||||
clone.querySelector('.block').id = tempID;
|
clone.querySelector('h3').innerHTML = 'New field';
|
||||||
clone.querySelector('input').name = tempID;
|
clone.querySelector('p').innerHTML = 'Write the field name and then press enter. If you want to create an array or an object, end the name with <code>:array</code> or <code>:object.</code>';
|
||||||
|
clone.querySelector('.ok').innerHTML = 'Create';
|
||||||
|
clone.querySelector('form').addEventListener('submit', addFrontMatterItemPrompt(parent));
|
||||||
|
clone.querySelector('form').classList.add('active')
|
||||||
|
document.querySelector('body').appendChild(clone);
|
||||||
|
|
||||||
if (type == "parent") {
|
document.querySelector('.overlay').classList.add('active');
|
||||||
document.querySelector('.frontmatter').insertBefore(clone, document.querySelector('div.button.add'));
|
document.getElementById(tempID).classList.add('active');
|
||||||
} else {
|
|
||||||
block.insertBefore(clone, block.querySelector('.group'));
|
|
||||||
}
|
|
||||||
|
|
||||||
let temp = document.getElementById(tempID),
|
|
||||||
input = temp.querySelector('input');
|
|
||||||
input.focus();
|
|
||||||
input.addEventListener('keydown', (event) => {
|
|
||||||
if (event.keyCode == 27) {
|
|
||||||
event.preventDefault();
|
|
||||||
temp.remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.keyCode == 13) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
let value = input.value;
|
|
||||||
if (value === '') {
|
|
||||||
temp.remove();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
let name = value.substring(0, value.lastIndexOf(':')),
|
|
||||||
newtype = value.substring(value.lastIndexOf(':') + 1, value.length);
|
|
||||||
if (newtype !== "" && newtype !== "array" && newtype !== "object") {
|
|
||||||
name = value;
|
|
||||||
}
|
|
||||||
|
|
||||||
name = name.replace(' ', '_');
|
|
||||||
|
|
||||||
let bid = name;
|
|
||||||
if (id != '') {
|
|
||||||
bid = id + "." + bid;
|
|
||||||
}
|
|
||||||
|
|
||||||
temp.remove();
|
|
||||||
|
|
||||||
switch (newtype) {
|
|
||||||
case "array":
|
|
||||||
case "object":
|
|
||||||
clone = document.importNode(templates.base.content, true);
|
|
||||||
clone.querySelector('fieldset').id = bid;
|
|
||||||
clone.querySelector('fieldset').dataset.type = newtype;
|
|
||||||
clone.querySelector('h3').innerHTML = name;
|
|
||||||
clone.querySelector('.delete').dataset.delete = bid;
|
|
||||||
clone.querySelector('.delete').addEventListener('click', deleteFrontMatterItem);
|
|
||||||
clone.querySelector('.add').addEventListener('click', addFrontMatterItem);
|
|
||||||
|
|
||||||
if (type == "parent") {
|
|
||||||
document.querySelector('.frontmatter').insertBefore(clone, document.querySelector('div.button.add'));
|
|
||||||
} else {
|
|
||||||
block.appendChild(clone);
|
|
||||||
}
|
|
||||||
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
let group = block.querySelector('.group');
|
|
||||||
|
|
||||||
if (group == null) {
|
|
||||||
block.insertAdjacentHTML('afterbegin', '<div class="group"></div>');
|
|
||||||
group = block.querySelector('.group');
|
|
||||||
}
|
|
||||||
|
|
||||||
clone = document.importNode(templates.objectItem.content, true);
|
|
||||||
clone.querySelector('.block').id = `block-${bid}`;
|
|
||||||
clone.querySelector('.block').dataset.content = bid;
|
|
||||||
clone.querySelector('label').for = bid;
|
|
||||||
clone.querySelector('label').innerHTML = name;
|
|
||||||
clone.querySelector('input').name = bid;
|
|
||||||
clone.querySelector('input').id = bid;
|
|
||||||
clone.querySelector('.action').dataset.delete = `block-${bid}`;
|
|
||||||
clone.querySelector('.action').addEventListener('click', deleteFrontMatterItem);
|
|
||||||
|
|
||||||
group.appendChild(clone)
|
|
||||||
document.getElementById(bid).focus();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -168,14 +159,13 @@ function addFrontMatterItem(event) {
|
|||||||
document.addEventListener("DOMContentLoaded", (event) => {
|
document.addEventListener("DOMContentLoaded", (event) => {
|
||||||
textareaAutoGrow();
|
textareaAutoGrow();
|
||||||
|
|
||||||
templates.array = document.getElementById("array-template");
|
|
||||||
templates.arrayItem = document.getElementById("array-item-template");
|
templates.arrayItem = document.getElementById("array-item-template");
|
||||||
templates.base = document.getElementById('base-template');
|
templates.base = document.getElementById('base-template');
|
||||||
templates.objectItem = document.getElementById("object-item-template");
|
templates.objectItem = document.getElementById("object-item-template");
|
||||||
templates.temporary = document.getElementById('temporary-template');
|
templates.temporary = document.getElementById('temporary-template');
|
||||||
|
|
||||||
let container = document.getElementById('editor'),
|
let container = document.getElementById('editor'),
|
||||||
button = document.querySelector('#submit span:first-child'),
|
button = document.querySelector('#save'),
|
||||||
kind = container.dataset.kind;
|
kind = container.dataset.kind;
|
||||||
|
|
||||||
if (kind != 'frontmatter-only') {
|
if (kind != 'frontmatter-only') {
|
||||||
@ -232,6 +222,11 @@ document.addEventListener("DOMContentLoaded", (event) => {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
document.querySelector('#save').addEventListener('click', event => {
|
||||||
|
event.preventDefault();
|
||||||
|
saveContent();
|
||||||
|
});
|
||||||
|
|
||||||
document.querySelector('form').addEventListener('submit', (event) => {
|
document.querySelector('form').addEventListener('submit', (event) => {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
saveContent();
|
saveContent();
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
'use strict';
|
'use strict';
|
||||||
|
|
||||||
var reloadListing = function(callback) {
|
var listing = {};
|
||||||
|
|
||||||
|
listing.reload = function(callback) {
|
||||||
let request = new XMLHttpRequest();
|
let request = new XMLHttpRequest();
|
||||||
request.open('GET', window.location);
|
request.open('GET', window.location);
|
||||||
request.setRequestHeader('Minimal', 'true');
|
request.setRequestHeader('Minimal', 'true');
|
||||||
@ -18,9 +20,94 @@ var reloadListing = function(callback) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Rename file event
|
listing.itemDragStart = function(event) {
|
||||||
var renameEvent = function(event) {
|
let el = event.target;
|
||||||
if (this.classList.contains('disabled') || !selectedItems.length) {
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.itemDragOver = function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
let el = event.target;
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
if (!el.classList.contains('item')) {
|
||||||
|
el = el.parentElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
el.style.opacity = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.itemDrop = function(e) {
|
||||||
|
e.preventDefault();
|
||||||
|
|
||||||
|
let el = e.target,
|
||||||
|
id = e.dataTransfer.getData("id"),
|
||||||
|
name = e.dataTransfer.getData("name");
|
||||||
|
|
||||||
|
if (id == "" || name == "") return;
|
||||||
|
|
||||||
|
for (let i = 0; i < 5; i++) {
|
||||||
|
if (!el.classList.contains('item')) {
|
||||||
|
el = el.parentElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (el.id === id) return;
|
||||||
|
|
||||||
|
let oldLink = toWebDavURL(document.getElementById(id).dataset.url),
|
||||||
|
newLink = toWebDavURL(el.dataset.url + name),
|
||||||
|
request = new XMLHttpRequest();
|
||||||
|
|
||||||
|
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();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.documentDrop = function(event) {
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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.rename = function(event) {
|
||||||
|
if (event.currentTarget.classList.contains('disabled') || !selectedItems.length) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,23 +136,20 @@ var renameEvent = function(event) {
|
|||||||
request.setRequestHeader('Destination', newLink);
|
request.setRequestHeader('Destination', newLink);
|
||||||
request.send();
|
request.send();
|
||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
// TODO: redirect if it's moved to another folder
|
|
||||||
|
|
||||||
if (request.readyState == 4) {
|
if (request.readyState == 4) {
|
||||||
if (request.status != 201 && request.status != 204) {
|
if (request.status != 201 && request.status != 204) {
|
||||||
span.innerHTML = name;
|
span.innerHTML = name;
|
||||||
} else {
|
} else {
|
||||||
let newLink = encodeURI(link.replace(name, newName));
|
let newLink = encodeURI(link.replace(name, newName));
|
||||||
console.log(request.body)
|
listing.reload(() => {
|
||||||
reloadListing(() => {
|
|
||||||
newName = btoa(newName);
|
newName = btoa(newName);
|
||||||
selectedItems = [newName];
|
selectedItems = [newName];
|
||||||
document.getElementById(newName).setAttribute("aria-selected", true);
|
document.getElementById(newName).setAttribute("aria-selected", true);
|
||||||
document.sendCostumEvent('changed-selected');
|
listing.handleSelectionChange();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
document.getElementById('rename').changeToDone((request.status != 201 && request.status != 204), html);
|
buttons.rename.changeToDone((request.status != 201 && request.status != 204), html);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -94,8 +178,7 @@ var renameEvent = function(event) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Upload files
|
listing.handleFiles = function(files, base) {
|
||||||
var handleFiles = function(files, base) {
|
|
||||||
let button = document.getElementById("upload"),
|
let button = document.getElementById("upload"),
|
||||||
html = button.changeToLoading();
|
html = button.changeToLoading();
|
||||||
|
|
||||||
@ -107,7 +190,7 @@ var handleFiles = function(files, base) {
|
|||||||
request.onreadystatechange = function() {
|
request.onreadystatechange = function() {
|
||||||
if (request.readyState == 4) {
|
if (request.readyState == 4) {
|
||||||
if (request.status == 201) {
|
if (request.status == 201) {
|
||||||
reloadListing();
|
listing.reload();
|
||||||
}
|
}
|
||||||
|
|
||||||
button.changeToDone((request.status != 201), html);
|
button.changeToDone((request.status != 201), html);
|
||||||
@ -118,53 +201,20 @@ var handleFiles = function(files, base) {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
function unselectAll() {
|
listing.unselectAll = function() {
|
||||||
var items = document.getElementsByClassName('item');
|
let items = document.getElementsByClassName('item');
|
||||||
Array.from(items).forEach(link => {
|
Array.from(items).forEach(link => {
|
||||||
link.setAttribute("aria-selected", false);
|
link.setAttribute("aria-selected", false);
|
||||||
});
|
});
|
||||||
|
|
||||||
selectedItems = [];
|
selectedItems = [];
|
||||||
|
|
||||||
document.sendCostumEvent('changed-selected');
|
listing.handleSelectionChange();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Handles the new directory event
|
listing.handleSelectionChange = function(event) {
|
||||||
var newDirEvent = function(event) {
|
listing.redefineDownloadURLs();
|
||||||
// TODO: create new dir button and new file button
|
|
||||||
if (event.keyCode == 27) {
|
|
||||||
document.getElementById('newdir').classList.toggle('enabled');
|
|
||||||
setTimeout(() => {
|
|
||||||
document.getElementById('newdir').value = '';
|
|
||||||
}, 200);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (event.keyCode == 13) {
|
|
||||||
event.preventDefault();
|
|
||||||
|
|
||||||
let button = document.getElementById('new'),
|
|
||||||
html = button.changeToLoading(),
|
|
||||||
request = new XMLHttpRequest(),
|
|
||||||
name = document.getElementById('newdir').value;
|
|
||||||
|
|
||||||
request.open((name.endsWith("/") ? "MKCOL" : "PUT"), toWebDavURL(window.location.pathname + name));
|
|
||||||
|
|
||||||
request.send();
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if (request.readyState == 4) {
|
|
||||||
button.changeToDone((request.status != 201), html);
|
|
||||||
reloadListing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Handles the event when there is change on selected elements
|
|
||||||
document.addEventListener("changed-selected", function(event) {
|
|
||||||
redefineDownloadURLs();
|
|
||||||
|
|
||||||
let selectedNumber = selectedItems.length,
|
let selectedNumber = selectedItems.length,
|
||||||
fileAction = document.getElementById("file-only");
|
fileAction = document.getElementById("file-only");
|
||||||
@ -173,13 +223,13 @@ document.addEventListener("changed-selected", function(event) {
|
|||||||
fileAction.classList.remove("disabled");
|
fileAction.classList.remove("disabled");
|
||||||
|
|
||||||
if (selectedNumber > 1) {
|
if (selectedNumber > 1) {
|
||||||
document.getElementById("open").classList.add("disabled");
|
buttons.open.classList.add("disabled");
|
||||||
document.getElementById("rename").classList.add("disabled");
|
buttons.rename.classList.add("disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (selectedNumber == 1) {
|
if (selectedNumber == 1) {
|
||||||
document.getElementById("open").classList.remove("disabled");
|
buttons.open.classList.remove("disabled");
|
||||||
document.getElementById("rename").classList.remove("disabled");
|
buttons.rename.classList.remove("disabled");
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
@ -187,9 +237,9 @@ document.addEventListener("changed-selected", function(event) {
|
|||||||
|
|
||||||
fileAction.classList.add("disabled");
|
fileAction.classList.add("disabled");
|
||||||
return false;
|
return false;
|
||||||
});
|
}
|
||||||
|
|
||||||
var redefineDownloadURLs = function() {
|
listing.redefineDownloadURLs = function() {
|
||||||
let files = "";
|
let files = "";
|
||||||
|
|
||||||
for (let i = 0; i < selectedItems.length; i++) {
|
for (let i = 0; i < selectedItems.length; i++) {
|
||||||
@ -206,49 +256,98 @@ var redefineDownloadURLs = function() {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
listing.openItem = function(event) {
|
||||||
|
window.location = event.currentTarget.dataset.url;
|
||||||
|
}
|
||||||
|
|
||||||
document.addEventListener('DOMContentLoaded', event => {
|
listing.selectItem = function(event) {
|
||||||
let updateColumns = () => {
|
let el = event.currentTarget;
|
||||||
let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
|
|
||||||
itens = getCSSRule('#listing.mosaic .item');
|
|
||||||
|
|
||||||
itens.style.width = `calc(${100/columns}% - 1em)`;
|
if (selectedItems.length != 0) event.preventDefault();
|
||||||
|
if (selectedItems.indexOf(el.id) == -1) {
|
||||||
|
if (!event.ctrlKey) listing.unselectAll();
|
||||||
|
|
||||||
|
el.setAttribute("aria-selected", true);
|
||||||
|
selectedItems.push(el.id);
|
||||||
|
} else {
|
||||||
|
el.setAttribute("aria-selected", false);
|
||||||
|
selectedItems.removeElement(el.id);
|
||||||
}
|
}
|
||||||
|
|
||||||
updateColumns();
|
listing.handleSelectionChange();
|
||||||
window.addEventListener("resize", () => {
|
return false;
|
||||||
updateColumns();
|
}
|
||||||
});
|
|
||||||
|
|
||||||
// Add event to back button and executes back event on ESC
|
listing.newFileButton = function(event) {
|
||||||
document.addEventListener('keydown', (event) => {
|
event.preventDefault();
|
||||||
if (event.keyCode == 27) {
|
|
||||||
unselectAll();
|
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');
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.newFilePrompt = function(event) {
|
||||||
|
event.preventDefault();
|
||||||
|
|
||||||
|
let button = document.getElementById('new'),
|
||||||
|
html = button.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.changeToDone((request.status != 201), html);
|
||||||
|
listing.reload();
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
|
|
||||||
|
closePrompt(event);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
listing.updateColumns = function(event) {
|
||||||
|
let columns = Math.floor(document.getElementById('listing').offsetWidth / 300),
|
||||||
|
items = getCSSRule('#listing.mosaic .item');
|
||||||
|
|
||||||
|
items.style.width = `calc(${100/columns}% - 1em)`;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Keydown events
|
||||||
|
document.addEventListener('keydown', (event) => {
|
||||||
|
if (event.keyCode == 27) {
|
||||||
|
listing.unselectAll();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
window.addEventListener("resize", () => {
|
||||||
|
listing.updateColumns();
|
||||||
|
});
|
||||||
|
|
||||||
|
document.addEventListener('DOMContentLoaded', event => {
|
||||||
|
listing.updateColumns();
|
||||||
|
|
||||||
|
buttons.rename = document.getElementById("rename");
|
||||||
|
buttons.upload = document.getElementById("upload");
|
||||||
|
buttons.new = document.getElementById('new');
|
||||||
|
|
||||||
if (user.AllowEdit) {
|
if (user.AllowEdit) {
|
||||||
// Enables rename button
|
buttons.rename.addEventListener("click", listing.rename);
|
||||||
document.getElementById("rename").addEventListener("click", renameEvent);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user.AllowNew) {
|
if (user.AllowNew) {
|
||||||
// Enables upload button
|
buttons.upload.addEventListener("click", (event) => {
|
||||||
document.getElementById("upload").addEventListener("click", (event) => {
|
|
||||||
document.getElementById("upload-input").click();
|
document.getElementById("upload-input").click();
|
||||||
});
|
});
|
||||||
|
|
||||||
document.getElementById('new').addEventListener('click', event => {
|
buttons.new.addEventListener('click', listing.newFileButton);
|
||||||
let newdir = document.getElementById('newdir');
|
|
||||||
newdir.classList.add('enabled');
|
|
||||||
newdir.focus();
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('newdir').addEventListener('blur', event => {
|
|
||||||
document.getElementById('newdir').classList.remove('enabled');
|
|
||||||
});
|
|
||||||
|
|
||||||
document.getElementById('newdir').addEventListener('keydown', newDirEvent);
|
|
||||||
|
|
||||||
// Drag and Drop
|
// Drag and Drop
|
||||||
let items = document.getElementsByClassName('item');
|
let items = document.getElementsByClassName('item');
|
||||||
@ -268,113 +367,6 @@ document.addEventListener('DOMContentLoaded', event => {
|
|||||||
});
|
});
|
||||||
}, false);
|
}, false);
|
||||||
|
|
||||||
document.addEventListener("drop", function(event) {
|
document.addEventListener("drop", listing.documentDrop, false);
|
||||||
event.preventDefault();
|
|
||||||
var dt = event.dataTransfer;
|
|
||||||
var files = dt.files;
|
|
||||||
|
|
||||||
let el = event.target;
|
|
||||||
|
|
||||||
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") {
|
|
||||||
handleFiles(files, el.querySelector('.name').innerHTML + "/");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
handleFiles(files, "");
|
|
||||||
} else {
|
|
||||||
Array.from(items).forEach(file => {
|
|
||||||
file.style.opacity = 1;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}, false);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
function itemDragStart(event) {
|
|
||||||
let el = event.target;
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
function itemDragOver(event) {
|
|
||||||
event.preventDefault();
|
|
||||||
let el = event.target;
|
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
if (!el.classList.contains('item')) {
|
|
||||||
el = el.parentElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
el.style.opacity = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
function itemDrop(e) {
|
|
||||||
e.preventDefault();
|
|
||||||
|
|
||||||
let el = e.target,
|
|
||||||
id = e.dataTransfer.getData("id"),
|
|
||||||
name = e.dataTransfer.getData("name");
|
|
||||||
|
|
||||||
if (id == "" || name == "") return;
|
|
||||||
|
|
||||||
for (let i = 0; i < 5; i++) {
|
|
||||||
if (!el.classList.contains('item')) {
|
|
||||||
el = el.parentElement;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (el.id === id) return;
|
|
||||||
|
|
||||||
let oldLink = toWebDavURL(document.getElementById(id).dataset.url),
|
|
||||||
newLink = toWebDavURL(el.dataset.url + name),
|
|
||||||
request = new XMLHttpRequest();
|
|
||||||
|
|
||||||
request.open('MOVE', oldLink);
|
|
||||||
request.setRequestHeader('Destination', newLink);
|
|
||||||
request.send();
|
|
||||||
request.onreadystatechange = function() {
|
|
||||||
if (request.readyState == 4) {
|
|
||||||
if (request.status == 201 || request.status == 204) {
|
|
||||||
reloadListing();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function openItemEvent(event) {
|
|
||||||
window.location = event.currentTarget.dataset.url;
|
|
||||||
}
|
|
||||||
|
|
||||||
function selectItemEvent(event) {
|
|
||||||
let el = event.currentTarget;
|
|
||||||
|
|
||||||
if (selectedItems.length != 0) event.preventDefault();
|
|
||||||
if (selectedItems.indexOf(el.id) == -1) {
|
|
||||||
if (!event.ctrlKey) unselectAll();
|
|
||||||
|
|
||||||
el.setAttribute("aria-selected", true);
|
|
||||||
selectedItems.push(el.id);
|
|
||||||
} else {
|
|
||||||
el.setAttribute("aria-selected", false);
|
|
||||||
selectedItems.removeElement(el.id);
|
|
||||||
}
|
|
||||||
|
|
||||||
document.sendCostumEvent("changed-selected");
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
<header>
|
<header>
|
||||||
<!-- TOP BAR -->
|
|
||||||
<div id="top-bar">
|
<div id="top-bar">
|
||||||
<div><p>File Manager</p></div>
|
<div><p>File Manager</p></div>
|
||||||
<div id="search">
|
<div id="search">
|
||||||
@ -48,86 +47,124 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- BOTTOM BAR -->
|
|
||||||
<div id="bottom-bar">
|
<div id="bottom-bar">
|
||||||
<div>
|
<div>
|
||||||
{{ if ne .Name "/"}}
|
{{- if ne .Name "/"}}
|
||||||
<p id="breadcrumbs-button">Previous</p>
|
<p id="breadcrumbs-button">Previous</p>
|
||||||
<ul id="breadcrumbs">
|
<ul id="breadcrumbs">
|
||||||
{{ range $item := .BreadcrumbMap }}
|
{{- range $item := .BreadcrumbMap }}
|
||||||
<a href="{{ $absURL }}{{ $item.URL }}"><li>{{ $item.Name }}</li></a>
|
<a href="{{ $absURL }}{{ $item.URL }}"><li>{{ $item.Name }}</li></a>
|
||||||
{{ end }}
|
{{- end }}
|
||||||
</ul><i class="material-icons">keyboard_arrow_right</i>
|
</ul><i class="material-icons">keyboard_arrow_right</i>
|
||||||
|
{{- end }}
|
||||||
{{ end }}
|
|
||||||
|
|
||||||
<p id="current-file">{{ if ne .Name "/"}}{{ .Name }}{{ else }}Root{{ end }}</p>
|
<p id="current-file">{{ if ne .Name "/"}}{{ .Name }}{{ else }}Root{{ end }}</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- ACTIONS -->
|
|
||||||
<div class="actions">
|
<div class="actions">
|
||||||
<div id="file-only" {{ if .IsDir }}class="disabled"{{ end }}>
|
<div id="file-only" {{ if .IsDir }}class="disabled"{{ end }}>
|
||||||
|
{{- if and (not .IsDir) (.User.AllowEdit) }}
|
||||||
|
{{- if .Editor}}
|
||||||
|
{{- if eq .Data.Mode "markdown" }}
|
||||||
|
<div class="action" id="preview" onclick="notImplemented(event);">
|
||||||
|
<i class="material-icons">remove_red_eye</i>
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
<div class="action" id="save">
|
||||||
|
<i class="material-icons" title="Save">save</i>
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
<div class="action" id="open">
|
<div class="action" id="open">
|
||||||
<i class="material-icons" title="See raw">open_in_new</i>
|
<i class="material-icons" title="See raw">open_in_new</i>
|
||||||
</div>
|
</div>
|
||||||
{{ if and .IsDir .User.AllowEdit }}
|
|
||||||
|
{{- if and .IsDir .User.AllowEdit }}
|
||||||
<div class="action" id="rename">
|
<div class="action" id="rename">
|
||||||
<i class="material-icons" title="Edit">mode_edit</i>
|
<i class="material-icons" title="Edit">mode_edit</i>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{- end }}
|
||||||
|
|
||||||
{{ if .User.AllowEdit }}
|
{{- if .User.AllowEdit }}
|
||||||
<div class="action" id="delete">
|
<div class="action" id="delete">
|
||||||
<i class="material-icons" title="Delete">delete</i> <span>Delete</span>
|
<i class="material-icons" title="Delete">delete</i> <span>Delete</span>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{- end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ if and (.User.AllowNew) (.IsDir) }}
|
{{- if .IsDir }}
|
||||||
|
<div class="action" id="view">
|
||||||
|
{{- if eq .Display "mosaic" }}
|
||||||
|
<a href="?display=list"><i class="material-icons" title="Switch View">view_list</i></a>
|
||||||
|
{{- else }}
|
||||||
|
<a href="?display=mosaic"><i class="material-icons" title="Switch View">view_module</i></a>
|
||||||
|
{{- end }}
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if and (.User.AllowNew) (.IsDir) }}
|
||||||
<div class="action" id="upload">
|
<div class="action" id="upload">
|
||||||
<i class="material-icons" title="Upload">file_upload</i> <span>Upload</span>
|
<i class="material-icons" title="Upload">file_upload</i> <span>Upload</span>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{- end }}
|
||||||
|
|
||||||
<div class="action" id="download">
|
<div class="action" id="download">
|
||||||
<a href="?download=true">
|
<a href="?download=true">
|
||||||
<i class="material-icons" title="Download">file_download</i> <span>Download</span>
|
<i class="material-icons" title="Download">file_download</i> <span>Download</span>
|
||||||
</a>
|
</a>
|
||||||
{{ if .IsDir }}
|
{{- if .IsDir }}
|
||||||
<ul class="prev-links">
|
<ul class="prev-links">
|
||||||
<a data-format="tarbz2" href="?download=tarbz2"><li>tar.bz2</li></a>
|
<a data-format="tarbz2" href="?download=tarbz2"><li>tar.bz2</li></a>
|
||||||
<a data-format="targz" href="?download=targz"><li>tar.gz</li></a>
|
<a data-format="targz" href="?download=targz"><li>tar.gz</li></a>
|
||||||
<a data-format="tar" href="?download=tar"><li>tar</li></a>
|
<a data-format="tar" href="?download=tar"><li>tar</li></a>
|
||||||
<a data-format="zip" href="?download=zip"><li>zip</li></a>
|
<a data-format="zip" href="?download=zip"><li>zip</li></a>
|
||||||
</ul>
|
</ul>
|
||||||
{{ end }}
|
{{- end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{{ if .IsDir }}
|
<div class="action" id="info" onclick="notImplemented(event);">
|
||||||
<div class="action" id="view">
|
<i class="material-icons" title="Info">info</i>
|
||||||
{{ if eq .Display "mosaic" }}
|
|
||||||
<a href="?display=list"><i class="material-icons" title="Switch View">view_list</i></a>
|
|
||||||
{{ else }}
|
|
||||||
<a href="?display=mosaic"><i class="material-icons" title="Switch View">view_module</i></a>
|
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</header>
|
</header>
|
||||||
|
|
||||||
<main>
|
<main>
|
||||||
{{ template "content" . }}
|
{{- template "content" . }}
|
||||||
|
</main>
|
||||||
|
|
||||||
{{ if and (.User.AllowNew) (.IsDir) }}
|
<div class="overlay"></div>
|
||||||
<input id="newdir" type="text" placeholder="Name. End with a trailing slash to create a dir.">
|
|
||||||
<div class="floating">
|
{{- if and (.User.AllowNew) (.IsDir) }}
|
||||||
<div class="action" id="new">
|
<div class="floating">
|
||||||
<i class="material-icons" title="New file or directory. End name with a trailing slash to create a directory.">add</i>
|
<div class="action" id="new">
|
||||||
|
<i class="material-icons" title="New file or directory">add</i>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
<template id="question-template">
|
||||||
|
<form class="prompt">
|
||||||
|
<h3></h3>
|
||||||
|
<p></p>
|
||||||
|
<input autofocus type="text">
|
||||||
|
<div>
|
||||||
|
<button type="submit" default class="ok">OK</button>
|
||||||
|
<button class="cancel" onclick="closePrompt(event);">Cancel</button>
|
||||||
|
</div>
|
||||||
|
</form>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template id="info-template">
|
||||||
|
<div class="prompt">
|
||||||
|
<h3></h3>
|
||||||
|
<p></p>
|
||||||
|
<div>
|
||||||
|
<button type="submit" onclick="closePrompt(event);" class="ok">OK</button>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
</template>
|
||||||
</main>
|
|
||||||
|
|
||||||
<footer>Served with <a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a> and <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer>
|
<footer>Served with <a rel="noopener noreferrer" href="https://caddyserver.com">Caddy</a> and <a rel="noopener noreferrer" href="https://github.com/hacdias/caddy-filemanager">File Manager</a>.</footer>
|
||||||
</body>
|
</body>
|
||||||
|
@ -18,27 +18,10 @@
|
|||||||
<textarea name="content">{{ .Content }}</textarea>
|
<textarea name="content">{{ .Content }}</textarea>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<div>
|
|
||||||
<button id="submit" type="submit" data-type="{{ .Class }}">
|
|
||||||
<span>
|
|
||||||
<i class="material-icons" title="Save">save</i>
|
|
||||||
</span>
|
|
||||||
<span>save</span>
|
|
||||||
</button>
|
|
||||||
</div>
|
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
|
|
||||||
<template id="temporary-template">
|
|
||||||
<div class="group temp" id="">
|
|
||||||
<div class="block" id="">
|
|
||||||
<label>Write the field name and then press enter. If you want to create an array or an object, end the name with ":array" or ":object".</label>
|
|
||||||
<input name="" type="text" placeholder="Write the field name and press enter.."></input>
|
|
||||||
</div></div>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="base-template">
|
<template id="base-template">
|
||||||
<fieldset id="" data-type="">
|
<fieldset id="" data-type="">
|
||||||
<h3></h3>
|
<h3></h3>
|
||||||
@ -62,19 +45,6 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<template id="array-template">
|
|
||||||
<fieldset id="" data-type="">
|
|
||||||
<h3></h3>
|
|
||||||
<div class="action add">
|
|
||||||
<i class="material-icons">add</i>
|
|
||||||
</div>
|
|
||||||
<div class="action delete" data-delete="">
|
|
||||||
<i class="material-icons">close</i>
|
|
||||||
</div>
|
|
||||||
<div class="group"></div>
|
|
||||||
</fieldset>
|
|
||||||
</template>
|
|
||||||
|
|
||||||
<template id="array-item-template">
|
<template id="array-item-template">
|
||||||
<div id="" data-type="array-item">
|
<div id="" data-type="array-item">
|
||||||
<input name="" id="" type="text" data-parent-type="array"></input>
|
<input name="" id="" type="text" data-parent-type="array"></input>
|
||||||
|
@ -32,6 +32,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{{- if not (eq .NumDirs 0)}}
|
||||||
<h2>Folders</h2>
|
<h2>Folders</h2>
|
||||||
<div>
|
<div>
|
||||||
{{- range .Items }}
|
{{- range .Items }}
|
||||||
@ -40,7 +41,9 @@
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
</div>
|
</div>
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
{{- if not (eq .NumFiles 0)}}
|
||||||
<h2>Files</h2>
|
<h2>Files</h2>
|
||||||
<div>
|
<div>
|
||||||
{{- range .Items }}
|
{{- range .Items }}
|
||||||
@ -49,6 +52,7 @@
|
|||||||
{{- end }}
|
{{- end }}
|
||||||
{{- end }}
|
{{- end }}
|
||||||
</div>
|
</div>
|
||||||
|
{{- end }}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<input style="display:none" type="file" id="upload-input" onchange="handleFiles(this.files, '')" value="Upload" multiple>
|
<input style="display:none" type="file" id="upload-input" onchange="handleFiles(this.files, '')" value="Upload" multiple>
|
||||||
@ -56,12 +60,12 @@
|
|||||||
{{- end -}}
|
{{- end -}}
|
||||||
|
|
||||||
{{ define "item" }}
|
{{ define "item" }}
|
||||||
<div ondragstart="itemDragStart(event)"
|
<div ondragstart="listing.itemDragStart(event)"
|
||||||
{{ if .IsDir}}ondragover="itemDragOver(event)" ondrop="itemDrop(event)"{{ end }}
|
{{ if .IsDir}}ondragover="listing.itemDragOver(event)" ondrop="listing.itemDrop(event)"{{ end }}
|
||||||
draggable="true"
|
draggable="true"
|
||||||
class="item"
|
class="item"
|
||||||
onclick="selectItemEvent(event)"
|
onclick="listing.selectItem(event)"
|
||||||
ondblclick="openItemEvent(event)"
|
ondblclick="listing.openItem(event)"
|
||||||
data-dir="{{ .IsDir }}"
|
data-dir="{{ .IsDir }}"
|
||||||
data-url="{{ .URL }}"
|
data-url="{{ .URL }}"
|
||||||
id="{{ EncodeBase64 .Name }}">
|
id="{{ EncodeBase64 .Name }}">
|
||||||
|
@ -37,6 +37,7 @@ func ServeSingle(w http.ResponseWriter, r *http.Request, c *config.Config, u *co
|
|||||||
|
|
||||||
if i.CanBeEdited() && u.AllowEdit {
|
if i.CanBeEdited() && u.AllowEdit {
|
||||||
p.Data, err = GetEditor(i)
|
p.Data, err = GetEditor(i)
|
||||||
|
p.Editor = true
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return http.StatusInternalServerError, err
|
return http.StatusInternalServerError, err
|
||||||
}
|
}
|
||||||
|
@ -29,6 +29,7 @@ type Info struct {
|
|||||||
User *config.User
|
User *config.User
|
||||||
Config *config.Config
|
Config *config.Config
|
||||||
Data interface{}
|
Data interface{}
|
||||||
|
Editor bool
|
||||||
Display string
|
Display string
|
||||||
Token string
|
Token string
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user