parent
							
								
									c4da5d4f67
								
							
						
					
					
						commit
						f07d360f9b
					
				
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							|  | @ -0,0 +1,269 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var tempID = "_fm_internal_temporary_id", | ||||
|     buttons = {}; | ||||
| 
 | ||||
| // Removes an element, if exists, from an array
 | ||||
| Array.prototype.removeElement = function(element) { | ||||
|     var i = this.indexOf(element); | ||||
|     if (i != -1) { | ||||
|         this.splice(i, 1); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Replaces an element inside an array by another
 | ||||
| Array.prototype.replaceElement = function(begin, end) { | ||||
|     var i = this.indexOf(begin); | ||||
|     if (i != -1) { | ||||
|         this[i] = end; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Sends a costum event to itself
 | ||||
| Document.prototype.sendCostumEvent = function(text) { | ||||
|     this.dispatchEvent(new CustomEvent(text)); | ||||
| } | ||||
| 
 | ||||
| // Gets the content of a cookie
 | ||||
| Document.prototype.getCookie = function(name) { | ||||
|     var re = new RegExp("(?:(?:^|.*;\\s*)" + name + "\\s*\\=\\s*([^;]*).*$)|^.*$"); | ||||
|     return document.cookie.replace(re, "$1"); | ||||
| } | ||||
| 
 | ||||
| // Changes a button to the loading animation
 | ||||
| Element.prototype.changeToLoading = function() { | ||||
|     let element = this; | ||||
|     let originalText = element.innerHTML; | ||||
| 
 | ||||
|     element.style.opacity = 0; | ||||
| 
 | ||||
|     setTimeout(function() { | ||||
|         element.innerHTML = '<i class="material-icons spin">autorenew</i>'; | ||||
|         element.style.opacity = 1; | ||||
|     }, 200); | ||||
| 
 | ||||
|     return originalText; | ||||
| } | ||||
| 
 | ||||
| // Changes an element to done animation
 | ||||
| Element.prototype.changeToDone = function(error, html) { | ||||
|     this.style.opacity = 0; | ||||
| 
 | ||||
|     let thirdStep = () => { | ||||
|         this.innerHTML = html; | ||||
|         this.style.opacity = null; | ||||
| 
 | ||||
|         if (selectedItems.length == 0 && document.getElementById('listing')) { | ||||
|             document.sendCostumEvent('changed-selected'); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     let secondStep = () => { | ||||
|         this.style.opacity = 0; | ||||
|         setTimeout(thirdStep, 200); | ||||
|     } | ||||
| 
 | ||||
|     let firstStep = () => { | ||||
|         if (error) { | ||||
|             this.innerHTML = '<i class="material-icons">close</i>'; | ||||
|         } else { | ||||
|             this.innerHTML = '<i class="material-icons">done</i>'; | ||||
|         } | ||||
| 
 | ||||
|         this.style.opacity = 1; | ||||
| 
 | ||||
|         setTimeout(secondStep, 1000); | ||||
|     } | ||||
| 
 | ||||
|     setTimeout(firstStep, 200); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| function getCSSRule(ruleName) { | ||||
|     ruleName = ruleName.toLowerCase(); | ||||
|     var result = null; | ||||
|     var find = Array.prototype.find; | ||||
| 
 | ||||
|     find.call(document.styleSheets, styleSheet => { | ||||
|         result = find.call(styleSheet.cssRules, cssRule => { | ||||
|             return cssRule instanceof CSSStyleRule && | ||||
|                 cssRule.selectorText.toLowerCase() == ruleName; | ||||
|         }); | ||||
|         return result != null; | ||||
|     }); | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| function toWebDavURL(url) { | ||||
|     return window.location.origin + url.replace(baseURL + "/", webdavURL + "/"); | ||||
| } | ||||
| 
 | ||||
| // Remove the last directory of an url
 | ||||
| var removeLastDirectoryPartOf = function(url) { | ||||
|     var arr = url.split('/'); | ||||
|     arr.pop(); | ||||
|     return (arr.join('/')); | ||||
| } | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *                             * | ||||
|  *            EVENTS           * | ||||
|  *                             * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| // Prevent Default event
 | ||||
| var preventDefault = function(event) { | ||||
|     event.preventDefault(); | ||||
| } | ||||
| 
 | ||||
| function logoutEvent(event) { | ||||
|     let request = new XMLHttpRequest(); | ||||
|     request.open('GET', window.location.pathname, true, "username", "password"); | ||||
|     request.send(); | ||||
|     request.onreadystatechange = function() { | ||||
|         if (request.readyState == 4) { | ||||
|             window.location = "/"; | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function openEvent(event) { | ||||
|     if (event.currentTarget.classList.contains('disabled')) { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     let link = '?raw=true'; | ||||
| 
 | ||||
|     if (selectedItems.length) { | ||||
|         link = document.getElementById(selectedItems[0]).dataset.url + link; | ||||
|     } else { | ||||
|         link = window.location + link; | ||||
|     } | ||||
| 
 | ||||
|     window.open(link); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Handles the delete button event
 | ||||
| function deleteEvent(event) { | ||||
|     let single = false; | ||||
| 
 | ||||
|     if (!selectedItems.length) { | ||||
|         selectedItems = [window.location.pathname]; | ||||
|         single = true; | ||||
|     } | ||||
| 
 | ||||
|     Array.from(selectedItems).forEach(id => { | ||||
|         let request = new XMLHttpRequest(), | ||||
|             html = buttons.delete.changeToLoading(), | ||||
|             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); | ||||
|             } | ||||
|         } | ||||
|         r.send(); | ||||
|     }); | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| var searchEvent = function(event) { | ||||
|     let value = this.value, | ||||
|         search = document.getElementById('search'), | ||||
|         scrollable = document.querySelector('#search > div'), | ||||
|         box = document.querySelector('#search > div div'); | ||||
| 
 | ||||
|     if (value.length == 0) { | ||||
|         box.innerHTML = "Search or use one of your supported commands: " + user.Commands.join(", ") + "."; | ||||
|         return; | ||||
|     } | ||||
| 
 | ||||
|     let pieces = value.split(' '); | ||||
|     let supported = false; | ||||
| 
 | ||||
|     user.Commands.forEach(function(cmd) { | ||||
|         if (cmd == pieces[0]) { | ||||
|             supported = true; | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     if (!supported) { | ||||
|         box.innerHTML = "Press enter to search." | ||||
|     } else { | ||||
|         box.innerHTML = "Press enter to execute." | ||||
|     } | ||||
| 
 | ||||
|     if (event.keyCode == 13) { | ||||
|         box.innerHTML = ''; | ||||
|         search.classList.add('ongoing'); | ||||
| 
 | ||||
|         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; | ||||
|                 scrollable.scrollTop = scrollable.scrollHeight; | ||||
|             } | ||||
| 
 | ||||
|             conn.onclose = function(event) { | ||||
|                 search.classList.remove('ongoing'); | ||||
|                 reloadListing(); | ||||
|             } | ||||
|         } else { | ||||
|             box.innerHTML = '<ul></ul>'; | ||||
|             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 += '<li><a href="' + event.data + '">' + event.data + '</a></li>'; | ||||
|                 scrollable.scrollTop = scrollable.scrollHeight; | ||||
|             } | ||||
| 
 | ||||
|             conn.onclose = function(event) { | ||||
|                 search.classList.remove('ongoing'); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| /* * * * * * * * * * * * * * * * | ||||
|  *                             * | ||||
|  *           BOOTSTRAP         * | ||||
|  *                             * | ||||
|  * * * * * * * * * * * * * * * */ | ||||
| 
 | ||||
| document.addEventListener("DOMContentLoaded", function(event) { | ||||
|     buttons.logout = document.getElementById("logout"); | ||||
|     buttons.open = document.getElementById("open"); | ||||
|     buttons.delete = document.getElementById("delete"); | ||||
| 
 | ||||
|     // Attach event listeners
 | ||||
|     buttons.logout.addEventListener("click", logoutEvent); | ||||
|     buttons.open.addEventListener("click", openEvent); | ||||
| 
 | ||||
|     if (user.AllowEdit) { | ||||
|         buttons.delete.addEventListener("click", deleteEvent); | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| }); | ||||
|  | @ -0,0 +1,258 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| function textareaAutoGrow() { | ||||
|     let autogrow = function() { | ||||
|         this.style.height = '5px'; | ||||
|         this.style.height = this.scrollHeight + 'px'; | ||||
|     } | ||||
| 
 | ||||
|     let textareas = document.getElementsByTagName('textarea'); | ||||
| 
 | ||||
|     let addAutoGrow = () => { | ||||
|         Array.from(textareas).forEach(textarea => { | ||||
|             autogrow.bind(textarea)(); | ||||
|             textarea.addEventListener('keyup', autogrow); | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     addAutoGrow(); | ||||
|     window.addEventListener('resize', addAutoGrow) | ||||
| } | ||||
| 
 | ||||
| function deleteFrontMatterItem(event) { | ||||
|     event.preventDefault(); | ||||
|     document.getElementById(this.dataset.delete).remove(); | ||||
| } | ||||
| 
 | ||||
| function addFrontMatterItem(event) { | ||||
|     event.preventDefault(); | ||||
| 
 | ||||
|     let temp = document.getElementById(tempID) | ||||
|     if (temp) { | ||||
|         temp.remove(); | ||||
|     } | ||||
| 
 | ||||
|     let block = this.parentNode, | ||||
|         type = block.dataset.type, | ||||
|         id = block.id; | ||||
| 
 | ||||
|     // If the block is an array
 | ||||
|     if (type === "array") { | ||||
|         let fieldID = id + "[]", | ||||
|             input = fieldID, | ||||
|             count = block.querySelectorAll('.group > div').length; | ||||
|              | ||||
|         input = input.replace(/\[/, '\\['); | ||||
|         input = input.replace(/\]/, '\\]'); | ||||
| 
 | ||||
|         let fieldsets = block.getElementsByTagName("fieldset"); | ||||
| 
 | ||||
|         if (fieldsets.length > 0) { | ||||
|             let newtype = fieldsets[0].dataset.type; | ||||
|             let bid = id + "[" + fieldsets.length + "]"; | ||||
|             let name = fieldsets.length; | ||||
| 
 | ||||
|             let template = `<fieldset id="${bid}" data-type="${newtype}">
 | ||||
|               <h3>${name}</h3> | ||||
|               <div class="action add"> | ||||
|                   <i class="material-icons">add</i> | ||||
|               </div> | ||||
|               <div class="action delete" data-delete="${bid}"> | ||||
|                   <i class="material-icons">close</i> | ||||
|               </div> | ||||
|              <div class="group"> | ||||
|              </div> | ||||
|             </fieldset>`; | ||||
| 
 | ||||
|             block.insertAdjacentHTML('beforeend', template); | ||||
| 
 | ||||
|             document.querySelector(`div[data-delete="${bid}"]`).addEventListener('click', deleteFrontMatterItem); | ||||
|             document.getElementById(bid).querySelector('.action.add').addEventListener('click', addFrontMatterItem); | ||||
|         } else { | ||||
|             block.querySelector('.group').insertAdjacentHTML('beforeend', `<div id="${fieldID}-${count}" data-type="array-item">
 | ||||
|                 <input name="${fieldID}" id="${fieldID}" type="text" data-parent-type="array"></input> | ||||
|                 <div class="action delete"  data-delete="${fieldID}-${count}"> | ||||
|                     <i class="material-icons">close</i> | ||||
|                 </div> | ||||
|             </div>`); | ||||
| 
 | ||||
|             document.getElementById(`${fieldID}-${count}`).querySelector('input').focus(); | ||||
|             document.querySelector(`div[data-delete="${fieldID}-${count}"]`).addEventListener('click', deleteFrontMatterItem); | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     if (type == "object" || type == "parent") { | ||||
|         let template = `<div class="group temp" id="${tempID}">
 | ||||
|         <div class="block" id="${tempID}"> | ||||
|             <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="${tempID}" type="text" placeholder="Write the field name and press enter.."></input> | ||||
|         </div></div>`; | ||||
| 
 | ||||
|         if (type == "parent") { | ||||
|             document.querySelector('div.button.add').insertAdjacentHTML('beforebegin', template); | ||||
|         } else { | ||||
|             block.querySelector('.delete').insertAdjacentHTML('afterend', template); | ||||
|         } | ||||
| 
 | ||||
|         let temp = document.getElementById(tempID); | ||||
|         let 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(':')); | ||||
|                 let 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": | ||||
|                         let template = `<fieldset id="${bid}" data-type="${newtype}">
 | ||||
|                           <h3>${name}</h3> | ||||
|                           <div class="action add"> | ||||
|                               <i class="material-icons">add</i> | ||||
|                           </div> | ||||
|                           <div class="action delete" data-delete="${bid}"> | ||||
|                               <i class="material-icons">close</i> | ||||
|                           </div> | ||||
|                          <div class="group"> | ||||
|                          </div> | ||||
|                         </fieldset>`; | ||||
| 
 | ||||
|                         if (type == "parent") { | ||||
|                             document.querySelector('div.button.add').insertAdjacentHTML('beforebegin', template); | ||||
|                         } else { | ||||
|                             block.insertAdjacentHTML('beforeend', template); | ||||
|                         } | ||||
| 
 | ||||
|                         document.querySelector(`div[data-delete="${bid}"]`).addEventListener('click', deleteFrontMatterItem); | ||||
|                         document.getElementById(bid).querySelector('.action.add').addEventListener('click', addFrontMatterItem); | ||||
|                         break; | ||||
|                     default: | ||||
|                         let group = block.querySelector('.group'); | ||||
| 
 | ||||
|                         if (group == null) { | ||||
|                             block.insertAdjacentHTML('afterbegin', '<div class="group"></div>'); | ||||
|                             group = block.querySelector('.group'); | ||||
|                         } | ||||
| 
 | ||||
|                         group.insertAdjacentHTML('beforeend', `<div class="block" id="block-${bid}" data-content="${bid}">
 | ||||
|                           <label for="${bid}">${name}</label> | ||||
|                           <input name="${bid}" id="${bid}" type="text" data-parent-type="object"></input> | ||||
|                           <div class="action delete" data-delete="block-${bid}"> | ||||
|                               <i class="material-icons">close</i> | ||||
|                           </div> | ||||
|                         </div>`); | ||||
| 
 | ||||
|                         document.getElementById(bid).focus(); | ||||
|                         document.querySelector(`div[data-delete="block-${bid}"]`).addEventListener('click', deleteFrontMatterItem); | ||||
|                 } | ||||
|             } | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| document.addEventListener("DOMContentLoaded", (event) => { | ||||
|     textareaAutoGrow(); | ||||
| 
 | ||||
|     let container = document.getElementById('editor'); | ||||
|     let button = document.querySelector('#submit span:first-child'); | ||||
|     let kind = container.dataset.kind; | ||||
| 
 | ||||
|     if (kind != 'frontmatter-only') { | ||||
|         let editor = document.getElementById('editor-source'); | ||||
|         let mode = editor.dataset.mode; | ||||
|         let textarea = document.querySelector('textarea[name="content"]'); | ||||
|         let aceEditor = ace.edit('editor-source'); | ||||
|         aceEditor.getSession().setMode("ace/mode/" + mode); | ||||
|         aceEditor.getSession().setValue(textarea.value); | ||||
|         aceEditor.getSession().on('change', function() { | ||||
|             textarea.value = aceEditor.getSession().getValue(); | ||||
|         }); | ||||
|         aceEditor.setOptions({ | ||||
|             wrap: true, | ||||
|             maxLines: Infinity, | ||||
|             theme: "ace/theme/github", | ||||
|             showPrintMargin: false, | ||||
|             fontSize: "1em", | ||||
|             minLines: 20 | ||||
|         }); | ||||
|     } | ||||
| 
 | ||||
|     let deleteFrontMatterItemButtons = document.getElementsByClassName('delete'); | ||||
|     Array.from(deleteFrontMatterItemButtons).forEach(button => { | ||||
|         button.addEventListener('click', deleteFrontMatterItem); | ||||
|     }); | ||||
| 
 | ||||
|     let addFrontMatterItemButtons = document.getElementsByClassName('add'); | ||||
|     Array.from(addFrontMatterItemButtons).forEach(button => { | ||||
|         button.addEventListener('click', addFrontMatterItem); | ||||
|     }); | ||||
| 
 | ||||
|     let saveContent = function() { | ||||
|         let data = form2js(document.querySelector('form')); | ||||
| 
 | ||||
|         if (typeof data.content === "undefined" && kind != 'frontmatter-only') { | ||||
|             data.content = ""; | ||||
|         } | ||||
| 
 | ||||
|         if (typeof data.content === "number") { | ||||
|             data.content = data.content.toString(); | ||||
|         } | ||||
| 
 | ||||
|         let html = button.changeToLoading(); | ||||
|         let request = new XMLHttpRequest(); | ||||
|         request.open("PUT", toWebDavURL(window.location.pathname)); | ||||
|         request.setRequestHeader('Kind', kind); | ||||
| 
 | ||||
|         request.send(JSON.stringify(data)); | ||||
|         request.onreadystatechange = function() { | ||||
|             if (request.readyState == 4) { | ||||
|                 button.changeToDone((request.status != 201), html); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     document.querySelector('form').addEventListener('submit', (event) => { | ||||
|         event.preventDefault(); | ||||
|         saveContent(); | ||||
|     }); | ||||
| 
 | ||||
|     window.addEventListener('keydown', (event) => { | ||||
|         if (event.ctrlKey || event.metaKey) { | ||||
|             switch (String.fromCharCode(event.which).toLowerCase()) { | ||||
|                 case 's': | ||||
|                     event.preventDefault(); | ||||
|                     saveContent(); | ||||
|                     break; | ||||
|             } | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     return false; | ||||
| }); | ||||
|  | @ -0,0 +1,465 @@ | |||
| 'use strict'; | ||||
| 
 | ||||
| var selectedItems = []; | ||||
| 
 | ||||
| var reloadListing = function(callback) { | ||||
|     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; | ||||
|                 addNewDirEvents(); | ||||
| 
 | ||||
|                 if (typeof callback == 'function') { | ||||
|                     callback(); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| // Rename file event
 | ||||
| var renameEvent = function(event) { | ||||
|     if (this.classList.contains('disabled') || !selectedItems.length) { | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     // This mustn't happen
 | ||||
|     if (selectedItems.length > 1) { | ||||
|         alert("Something went wrong. Please refresh the page."); | ||||
|         location.refresh(); | ||||
|     } | ||||
| 
 | ||||
|     let item = document.getElementById(selectedItems[0]), | ||||
|         link = item.dataset.url, | ||||
|         span = item.getElementsByTagName('span')[0], | ||||
|         name = span.innerHTML; | ||||
| 
 | ||||
|     span.setAttribute('contenteditable', 'true'); | ||||
|     span.focus(); | ||||
| 
 | ||||
|     let keyDownEvent = (event) => { | ||||
|         if (event.keyCode == 13) { | ||||
|             let newName = span.innerHTML, | ||||
|                 newLink = removeLastDirectoryPartOf(toWebDavURL(link)) + newName, | ||||
|                 html = document.getElementById('rename').changeToLoading(), | ||||
|                 request = new XMLHttpRequest(); | ||||
| 
 | ||||
|             request.open('MOVE', toWebDavURL(link)); | ||||
|             request.setRequestHeader('Destination', newLink); | ||||
|             request.setRequestHeader('Content-type', 'text/plain; charset=utf-8'); | ||||
|             request.send(); | ||||
|             request.onreadystatechange = function() { | ||||
|                 // TODO: redirect if it's moved to another folder
 | ||||
| 
 | ||||
|                 if (request.readyState == 4) { | ||||
|                     if (request.status != 201 && request.status != 204) { | ||||
|                         span.innerHTML = name; | ||||
|                     } else { | ||||
|                         let newLink = encodeURI(link.replace(name, newName)); | ||||
|                         console.log(request.body) | ||||
|                         reloadListing(() => { | ||||
|                             newName = btoa(newName); | ||||
|                             selectedItems = [newName]; | ||||
|                             document.getElementById(newName).setAttribute("aria-selected", true); | ||||
|                             document.sendCostumEvent('changed-selected'); | ||||
|                         }); | ||||
|                     } | ||||
| 
 | ||||
|                     document.getElementById('rename').changeToDone((request.status != 201 && request.status != 204), html); | ||||
|                 } | ||||
|             } | ||||
|         } | ||||
| 
 | ||||
|         if (event.KeyCode == 27) { | ||||
|             span.innerHTML = name; | ||||
|         } | ||||
| 
 | ||||
|         if (event.keyCode == 13 || event.keyCode == 27) { | ||||
|             span.setAttribute('contenteditable', 'false'); | ||||
|             span.removeEventListener('keydown', keyDownEvent); | ||||
|             event.preventDefault(); | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     span.addEventListener('keydown', keyDownEvent); | ||||
|     span.addEventListener('blur', (event) => { | ||||
|         span.innerHTML = name; | ||||
|         span.setAttribute('contenteditable', 'false'); | ||||
|         span.removeEventListener('keydown', keyDownEvent); | ||||
|         item.removeEventListener('click', preventDefault); | ||||
|     }); | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Upload files
 | ||||
| var handleFiles = function(files, base) { | ||||
|     let button = document.getElementById("upload"); | ||||
|     let html = button.changeToLoading(); | ||||
| 
 | ||||
|     for (let i = 0; i < files.length; i++) { | ||||
|         let request = new XMLHttpRequest(); | ||||
|         request.open('PUT', toWebDavURL(window.location.pathname + base + files[i].name)); | ||||
| 
 | ||||
|         request.send(files[i]); | ||||
|         request.onreadystatechange = function() { | ||||
|             if (request.readyState == 4) { | ||||
|                 if (request.status == 201) { | ||||
|                     reloadListing(); | ||||
|                 } | ||||
| 
 | ||||
|                 button.changeToDone((request.status != 201), html); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Handles the back button event
 | ||||
| var backEvent = function(event) { | ||||
|     var items = document.getElementsByClassName('item'); | ||||
|     Array.from(items).forEach(link => { | ||||
|         link.setAttribute("aria-selected", false); | ||||
|     }); | ||||
|     selectedItems = []; | ||||
| 
 | ||||
|     var event = new CustomEvent('changed-selected'); | ||||
|     document.dispatchEvent(event); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Toggles the view mode
 | ||||
| var viewEvent = function(event) { | ||||
|     let cookie = document.getCookie('view-list'); | ||||
|     let listing = document.getElementById('listing'); | ||||
| 
 | ||||
|     if (cookie != 'true') { | ||||
|         document.cookie = 'view-list=true'; | ||||
|     } else { | ||||
|         document.cookie = 'view-list=false'; | ||||
|     } | ||||
| 
 | ||||
|     handleViewType(document.getCookie('view-list')); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Handles the view mode change
 | ||||
| var handleViewType = function(viewList) { | ||||
|     let listing = document.getElementById('listing'); | ||||
|     let button = document.getElementById('view'); | ||||
| 
 | ||||
|     if (viewList == "true") { | ||||
|         listing.classList.add('list'); | ||||
|         button.innerHTML = '<i class="material-icons" title="Switch View">view_module</i> <span>Switch view</span>'; | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     button.innerHTML = '<i class="material-icons" title="Switch View">view_list</i> <span>Switch view</span>'; | ||||
|     listing.classList.remove('list'); | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| var addNewDirEvents = function() { | ||||
|     document.getElementById('new').addEventListener('click', event => { | ||||
|         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); | ||||
| } | ||||
| 
 | ||||
| // Handles the new directory event
 | ||||
| var newDirEvent = function(event) { | ||||
|     // 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'); | ||||
|         let html = button.changeToLoading(); | ||||
|         let request = new XMLHttpRequest(); | ||||
|         let 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(() => { | ||||
|                     addNewDirEvents(); | ||||
|                 }); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
|     return false; | ||||
| } | ||||
| 
 | ||||
| // Handles the event when there is change on selected elements
 | ||||
| document.addEventListener("changed-selected", function(event) { | ||||
|     redefineDownloadURLs(); | ||||
| 
 | ||||
|     let selectedNumber = selectedItems.length, | ||||
|         fileAction = document.getElementById("file-only"); | ||||
| 
 | ||||
|     if (selectedNumber) { | ||||
|         fileAction.classList.remove("disabled"); | ||||
| 
 | ||||
|         if (selectedNumber > 1) { | ||||
|             document.getElementById("open").classList.add("disabled"); | ||||
|             document.getElementById("rename").classList.add("disabled"); | ||||
|         } | ||||
| 
 | ||||
|         if (selectedNumber == 1) { | ||||
|             document.getElementById("open").classList.remove("disabled"); | ||||
|             document.getElementById("rename").classList.remove("disabled"); | ||||
|         } | ||||
| 
 | ||||
|         return false; | ||||
|     } | ||||
| 
 | ||||
|     fileAction.classList.add("disabled"); | ||||
|     return false; | ||||
| }); | ||||
| 
 | ||||
| var redefineDownloadURLs = function() { | ||||
|     let files = ""; | ||||
| 
 | ||||
|     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); | ||||
| 
 | ||||
|     let links = document.querySelectorAll("#download ul a"); | ||||
|     Array.from(links).forEach(link => { | ||||
|         link.href = "?download=" + link.dataset.format + "&files=" + files; | ||||
|     }); | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| document.addEventListener('listing', event => { | ||||
|     // Handles the current view mode and adds the event to the button
 | ||||
|     handleViewType(document.getCookie("view-list")); | ||||
|     document.getElementById("view").addEventListener("click", viewEvent); | ||||
| 
 | ||||
|     let updateColumns = () => { | ||||
|         let columns = Math.floor(document.getElementById('listing').offsetWidth / 300), | ||||
|             itens = getCSSRule('#listing .item'); | ||||
| 
 | ||||
|         itens.style.width = `calc(${100/columns}% - 1em)`; | ||||
|     } | ||||
| 
 | ||||
|     updateColumns(); | ||||
|     window.addEventListener("resize", () => { | ||||
|         updateColumns(); | ||||
|     }); | ||||
| 
 | ||||
|     // Add event to back button and executes back event on ESC
 | ||||
|     document.addEventListener('keydown', (event) => { | ||||
|         if (event.keyCode == 27) { | ||||
|             backEvent(event); | ||||
|         } | ||||
|     }); | ||||
| 
 | ||||
|     if (user.AllowCommands) { | ||||
|         let search = document.getElementById("search"), | ||||
|             searchInput = search.querySelector("input"), | ||||
|             searchDiv = search.querySelector("div"), | ||||
|             hover = false, | ||||
|             focus = false; | ||||
| 
 | ||||
|         searchInput.addEventListener('focus', event => { | ||||
|             focus = true; | ||||
|             search.classList.add('active'); | ||||
|         }); | ||||
| 
 | ||||
|         searchDiv.addEventListener('mouseover', event => { | ||||
|             hover = true; | ||||
|             search.classList.add('active'); | ||||
|         }); | ||||
| 
 | ||||
|         searchInput.addEventListener('blur', event => { | ||||
|             focus = false; | ||||
|             if (hover) return; | ||||
|             search.classList.remove('active'); | ||||
|         }); | ||||
| 
 | ||||
|         search.addEventListener('mouseleave', event => { | ||||
|             hover = false; | ||||
|             if (focus) return; | ||||
|             search.classList.remove('active'); | ||||
|         }); | ||||
| 
 | ||||
|         search.addEventListener("click", event => { | ||||
|             search.classList.add("active"); | ||||
|             search.querySelector("input").focus(); | ||||
|         }); | ||||
| 
 | ||||
|         document.querySelector('#search > div div').innerHTML = "Search or use one of your supported commands: " + user.Commands.join(", ") + "."; | ||||
|         document.querySelector('#search input').addEventListener('keyup', searchEvent); | ||||
|     } | ||||
| 
 | ||||
|     if (user.AllowEdit) { | ||||
|         // Enables rename button
 | ||||
|         document.getElementById("rename").addEventListener("click", renameEvent); | ||||
|     } | ||||
| 
 | ||||
|     if (user.AllowNew) { | ||||
|         // Enables upload button
 | ||||
|         document.getElementById("upload").addEventListener("click", (event) => { | ||||
|             document.getElementById("upload-input").click(); | ||||
|         }); | ||||
| 
 | ||||
|         addNewDirEvents(); | ||||
| 
 | ||||
|         // Drag and Drop
 | ||||
|         let items = document.getElementsByClassName('item'); | ||||
|         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("dragend", (event) => { | ||||
|             Array.from(items).forEach(file => { | ||||
|                 file.style.opacity = 1; | ||||
|             }); | ||||
|         }, false); | ||||
| 
 | ||||
|         document.addEventListener("drop", function(event) { | ||||
|             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 openItem(event) { | ||||
|     window.location = event.currentTarget.dataset.url; | ||||
| } | ||||
| 
 | ||||
| function selectItem(event) { | ||||
|     let el = event.currentTarget; | ||||
| 
 | ||||
|     if (selectedItems.length != 0) event.preventDefault(); | ||||
|     if (selectedItems.indexOf(el.id) == -1) { | ||||
|         if (!event.ctrlKey) backEvent(event); | ||||
| 
 | ||||
|         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; | ||||
| } | ||||
Some files were not shown because too many files have changed in this diff Show More
		Loading…
	
		Reference in New Issue
	
	 Henrique Dias
						Henrique Dias