diff options
-rw-r--r-- | .gitignore | 9 | ||||
-rw-r--r-- | pages/index.html | 40 | ||||
-rw-r--r-- | static/gomf.css | 159 | ||||
-rw-r--r-- | static/gomf.js | 184 |
4 files changed, 392 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..fbd7d54 --- /dev/null +++ b/.gitignore @@ -0,0 +1,9 @@ +*.swp +/gomf +/*.go +/*.txt +/upload/ +/run-gomf.bash +/gomf-modpanel +/deleted.log.json +/log/ diff --git a/pages/index.html b/pages/index.html new file mode 100644 index 0000000..f27d46d --- /dev/null +++ b/pages/index.html @@ -0,0 +1,40 @@ +<!doctype html> +<html> + <head> + <meta charset="utf-8" /> + <title>{{.SiteName}}</title> + <meta name="viewport" content="width=device-width, initial-scale=1" /> + <link rel="stylesheet" href="/static/gomf.css" /> + <link rel="shortcut icon" href="/favicon.ico" type="image/x-icon" /> + <script type="text/javascript" src="/static/gomf.js" async></script> + </head> + <body> + <h1>{{.SiteName}}</h1> + + <main> + <p>Maximum file size: <b>{{.MaxSize}}</b>.</p> + <form method="post" enctype="multipart/form-data" action="upload.php?output=html"> + <div> + <span>Select file</span> + <input type="file" name="files[]" multiple data-max-size="{{.MaxSizeBytes}}" id="file" /> + </div> + <input id="file-submit" type="submit" value="upload" /> + </form> + {{with .Result}}<ul id="results"> + {{range .Files}}<li><b>{{.Name}}</b>: <a href="{{.Url}}">{{.Url}}</a></li>{{end}} + {{if .Description}}<span style="color: red">{{.Description}}</span>{{end}} + </ul>{{end}} + </main> + + <nav> + <ul> + <li><a href="/">{{.SiteName}}</a></li> + <li><a href="mailto:{{.Contact}}">Contact</a></li> + <li><a href="mailto:{{.Abuse}}">Report abuse</a></li> + {{range $name, $path := .Pages}}{{if ne $path "index.html"}} + <li><a href="{{$path}}">{{$name}}</a></li> + {{end}}{{end}} + </ul> + </nav> + </body> +</html> diff --git a/static/gomf.css b/static/gomf.css new file mode 100644 index 0000000..5b34792 --- /dev/null +++ b/static/gomf.css @@ -0,0 +1,159 @@ +html, body, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, address, cite, +code, b, u, i, form, label, article, aside, footer, header, menu, nav, section { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline; +} + +article, aside, footer, header, menu, nav, section { + display: block; +} + +body { + line-height: 1.25; + padding: 1em; + color: #000; + background-color: #fff; + max-width: 800px; + margin-left: auto; + margin-right: auto; +} + +html { + font-family: "DejaVu Sans", sans-serif; +} + +h1 { + font-size: 200%; + font-weight: bold; + border-bottom: 1px solid black; + margin-bottom: 0.5em; +} + +input, select, textarea, code { + border: 1px solid black; + background: inherit; + font: inherit; + font-family: "DejaVu Sans Mono", monospace; +} + +progress { + appearance: none; + background-color: inherit; + color: inherit; + border: 1px solid black; + font: inherit; +} + +input, select { + font: inherit; + cursor: pointer; +} + +.file span { + padding-left: 0.25em; + padding-right: 0.25em; + padding-top: 2em; + padding-bottom: 2em; + overflow: hidden; + width: 100%; + text-align: center; +} + +.file { + padding-top: 2em; + padding-bottom: 2em; + height: 22px; + min-height: 22px; + position: relative; + border: 1px solid black; + margin-right: 0.2em; + width: 100%; +} + +main form { + margin-top: 1em; + margin-bottom: 1em; + display: flex; +} + +.file input[type=file] { + margin-top: -2em; + padding-top: 2em; + padding-bottom: 2em; + position: relative; + text-align: right; + opacity: 0; + filter: alpha(opacity: 0); + -moz-opacity: 0; + z-index: 2; + width: 100%; +} + +.file span { + position: absolute; + top: 0px; + left: 0px; + z-index: 1; +} + +.file:hover { + background-color: #eee; +} + +input:disabled { + background-color: #ddd; +} + +b { + font-weight: bold; +} + +i { + font-style: italic; +} + +nav { + margin-top: 2em; + list-style-type: none; + font-size: 80%; + text-align: center; + font-weight: bold; +} + +nav a { + display: inline; + cursor: pointer; + font-weight: normal; + border: none; + background: inherit; + color: inherit; + padding: 0; + font: inherit; + font-weight: normal; + text-decoration: none; +} + +nav a:hover { + text-decoration: underline; +} + +nav li { + display: inline-block; +} + +nav li:after { + content: " | "; + white-space: pre; + cursor: default; + text-decoration: none; + display: inline-block; + font-weight: normal; +} + +nav li:last-child:after { + content: ""; +} diff --git a/static/gomf.js b/static/gomf.js new file mode 100644 index 0000000..da14d14 --- /dev/null +++ b/static/gomf.js @@ -0,0 +1,184 @@ +(function() { + var gomfload = function() { + "use strict"; + + var required = ['FormData', 'XMLHttpRequest']; + for (var i=0; i<required.length; ++i) { + if (typeof window[required[i]] === 'undefined') { + console.log('browser does not support window.' + required[i] + ', Gomf JS disabled'); + return; + } + } + + var fileName = document.querySelector('main form span'); + var fileDiv = document.querySelector('main form div'); + var fileSubmit = document.querySelector('#file-submit'); + var fileInput = document.querySelector('#file'); + var resultList = document.querySelector('#results'); + var maxSize = parseInt(fileInput.attributes['data-max-size'].value); + + if (!Element.prototype.remove) { + Element.prototype.remove = function() { + this.parentElement.removeChild(this); + } + } + + var upload = function(files) { + if (files.length ==0) { + alert('No files selected'); + fileInput.value = ''; + updateName(); + return; + } + + for (var i=0; i<files.length; ++i) { + if (files[i].size > maxSize) { + alert('File ' + files[i].name + ' too large, maximum allowed size is ' + humanize(maxSize)); + fileInput.value = ''; + updateName(); + return; + } + } + + for (var i=0; i<files.length; ++i) { + uploadFile(files[i]); + } + + fileInput.value = ''; + updateName(); + }; + + var uploadFile = function(file) { + var xhr = new XMLHttpRequest(); + + var formData = new FormData(); + formData.append('files[]', file); + + var resultItem = document.createElement('li'); + var name = document.createElement('b'); + name.appendChild(document.createTextNode(file.name)); + resultItem.appendChild(name); + resultItem.appendChild(document.createTextNode(': ')); + var progressBar = document.createElement('progress'); + progressBar.min = 0; + progressBar.max = 100; + progressBar.value = 0; + resultItem.appendChild(progressBar); + var progressText = document.createElement('span'); + progressText.textContent = ' 0% - 0/0'; + resultItem.appendChild(progressText); + resultList.appendChild(resultItem); + + xhr.upload.addEventListener('progress', function(e) { + if (e.lengthComputable) { + progressBar.max = e.total; + progressBar.value = e.loaded; + progressText.textContent = ' ' + (Math.round(e.loaded / e.total * 10000) / 100) + '% - ' + humanize(e.loaded) + ' / ' + humanize(e.total); + } else { + progressBar.value = ''; + progressText.textContent = ''; + } + }, false); + + xhr.addEventListener('readystatechange', function() { + if (xhr.readyState == 4) { + fileInput.value = ''; + progressBar.remove(); + progressText.remove(); + var resp = xhr.responseText.replace(/\s$/, '');; + //if (resp.indexOf('http') == 0) { + if (xhr.status == 200) { + var a = document.createElement('a'); + a.href = resp; + a.textContent = resp; + var input = document.createElement('input'); + input.type = 'text'; + input.readOnly = true; + input.value = resp; + console.log(input); + console.log(resp); + console.log(input.value); + console.log(input.value.length); + input.size = input.value.length; + input.addEventListener('click', function() { + this.select(); + }); + resultItem.appendChild(a); + resultItem.appendChild(document.createTextNode(' ')); + resultItem.appendChild(input); + } else { + var span = document.createElement('span'); + span.style.color = 'red'; + span.textContent = resp; + resultItem.appendChild(span); + } + updateName(); + } + }); + + var postPath = 'upload.php?output=text'; + + xhr.open('POST', postPath); + + xhr.send(formData); + }; + + var humanize = function(n) { + var units = ['B', 'KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']; + var i = 0; + while (n >= 1024 && i < units.length-1) { + n /= 1024; + ++i; + } + return (Math.round(n*10)/10) + ' ' + units[i]; + }; + + var submit = function(e) { + upload(fileInput.files); + e.preventDefault(); + }; + + var updateName = function(files) { + files = files || fileInput.files; + if (files.length > 0) { + if (files.length == 1) { + fileName.textContent = files[0].name; + } else { + fileName.textContent = files.length + ' files selected'; + } + } else { + fileName.textContent = fileName.originalText; + } + }; + + var dragenter = function(e) { + e.stopPropagation(); + e.preventDefault(); + }; + + var drop = function(e) { + e.stopPropagation(); + e.preventDefault(); + upload(e.dataTransfer.files); + }; + + fileInput.addEventListener('change', submit); + fileInput.addEventListener('dragenter', dragenter); + fileInput.addEventListener('dragover', dragenter); + fileInput.addEventListener('drop', drop); + + fileName.textContent = 'Select or drop files here'; + fileName.originalText = fileName.textContent; + fileDiv.className = 'file'; + fileInput.multiple = 'multiple'; + fileSubmit.style.display = 'none'; + + updateName(); + }; + + if (document.readyState !== 'loading') { + gomfload(); + } else { + document.addEventListener('DOMContentLoaded', gomfload); + } +})(); |