Massive graphical overhaul

This commit is contained in:
2018-01-07 21:42:19 +01:00
parent 9a4eddcbd1
commit 636643c9e0
44 changed files with 600 additions and 548 deletions

View File

@@ -24,6 +24,7 @@ func Init(r *httprouter.Router, prefix string) {
r.GET(prefix+"/", webcontroller.ServeHome)
r.GET(prefix+"/favicon.ico", webcontroller.ServeFavicon)
r.GET(prefix+"/global.css", webcontroller.GlobalCSSHandler)
r.GET(prefix+"/api", webcontroller.ServeAPIDoc)
r.GET(prefix+"/history", webcontroller.ServeHistory)
r.GET(prefix+"/u/:id", webcontroller.ServeFileViewer)

View File

@@ -2,11 +2,18 @@ package pixelapi
import (
"encoding/json"
"io"
"fornaxian.com/pixeldrain-web/conf"
"fornaxian.com/pixeldrain-web/log"
)
// GetFile makes a file download request and returns a readcloser. Don't forget
// to close it!
func GetFile(id string) (io.ReadCloser, error) {
return getRaw(conf.ApiUrlInternal() + "/file/" + id)
}
// FileInfo File information object from the pixeldrain API
type FileInfo struct {
ID string `json:"id"`
@@ -24,7 +31,7 @@ type FileInfo struct {
// GetFileInfo gets the FileInfo from the pixeldrain API
func GetFileInfo(id string) *FileInfo {
body, err := get(conf.ApiUrlInternal() + "/file/" + id + "/info")
body, err := getString(conf.ApiUrlInternal() + "/file/" + id + "/info")
if err != nil {
log.Error("req failed: %v", err)

View File

@@ -28,7 +28,7 @@ type ListFile struct {
// GetList get a List from the pixeldrain API
func GetList(id string) *List {
body, err := get(conf.ApiUrlInternal() + "/list/" + id)
body, err := getString(conf.ApiUrlInternal() + "/list/" + id)
if err != nil {
log.Error("req failed: %v", err)

View File

@@ -2,8 +2,9 @@ package pixelapi
import "net/http"
import "io/ioutil"
import "io"
func get(url string) (string, error) {
func getString(url string) (string, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return "", err
@@ -22,3 +23,19 @@ func get(url string) (string, error) {
return string(bodyBytes), err
}
func getRaw(url string) (io.ReadCloser, error) {
req, err := http.NewRequest("GET", url, nil)
if err != nil {
return nil, err
}
client := &http.Client{}
resp, err := client.Do(req)
if err != nil {
return nil, err
}
return resp.Body, err
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 732 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 700 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 241 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 240 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 251 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 85 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 313 B

View File

@@ -0,0 +1,116 @@
<!DOCTYPE html>
<html>
<head>
<title>PixelDrain ~ Free file sharing service</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/home.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/history.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
<link rel="shortcut icon" href="/res/img/tray32.png"/>
<meta name="theme-color" content="#9FCF6C"/>
<link rel="icon" sizes="180x180" href="/res/img/pixeldrain.png"/>
<link rel="icon" sizes="256x256" href="/res/img/pixeldrain_big.png"/>
<style>
body, .checkers{
background-image: url("/res/img/checker9.png");
background-attachment: fixed;
}
</style>
<script src="/res/script/jquery-2.1.4.min.js"></script>
<meta name="description" content="PixelDrain is a free file sharing service, you
can upload any file and you will be given a shareable link right away.
PixelDrain also supports previews for images, videos, audio, PDFs and much more.
Uncensored, unmonitored and unmoderated."/>
<meta property="og:type" content="website" />
<meta property="og:title" content="Home ~ PixelDrain" />
<meta property="og:site_name" content="PixelDrain" />
<meta property="og:description" content="Instant file and screenshot sharing." />
<meta property="og:url" content="http://pixeldra.in/" />
<meta property="og:image" content="/res/img/pixeldrain_big.png" />
<meta property="og:image:type" content="image/png" />
</head>
<body>
<img id="header-image" src="/res/img/header_blackchancery.png" alt="Header image"/>
<div id="body" class="body">
<div class="highlight_light border-top border-bottom menu">
<a href="/">Home</a> ~
<a href="/history">My&nbsp;Files</a> ~
<a href="/api">API&nbsp;Documentation</a>
</div>
<div class="highlight_middle border-bottom">
<input id="fileInputField" type="file" name="file" multiple='multiple'/>
<button id="selectFileButton" class="big_button button_highlight">Upload Files</button>
<button id="textButton" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<div id="progress-bar" class="progress-bar">
<span class="progress-text"></span>
<div id="upload-progress" class="progressbar-inner">
<span class="progress-text"></span>
</div>
</div>
<div id="uploads-completed"></div>
</div>
<div class="highlight_dark border-bottom">
<button id="btnCreateList">Create list with uploaded files</button>
</div>
<h1>Widgets testing page</h1>
Buttons <button>Regular ol' button!</button>
Width indicator
<button class="button_highlight">Important button!</button>
Width indicator
<button class="button_red">Dangerous button!</button>
<hr/>
Textarea <textarea>Hello!</textarea>
<hr/>
Checkbox <input type="checkbox"/>
<hr/>
Radio
<input name="radioform" type="radio"/>
<input name="radioform" type="radio"/>
<hr/>
Text field <input type="text"/>
<hr/>
Password <input type="password"/>
<hr/>
Number <input type="number"/>
<hr/>
Select
<select name="select">
<option>cherry</option>
<option>orange</option>
<option>apple</option>
</select>
<hr/>
Select2 <select name="select2" size="3">
<option>cherry</option>
<option>orange</option>
<option>apple</option>
</select>
<hr/>
File <input type="file" name="file">
<hr/>
Color <input type="color" name="favcolor" value="#ff0000">
<br/>
<div class="highlight_dark border-top border-bottom">
Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>.
</div>
</div>
</body>
</html>

View File

@@ -3,9 +3,11 @@ var DetailsWindow = {
toggle: function () {
if (this.visible) {
$("#info-popup").fadeOut(500);
$("#btnDetails").removeClass("button_highlight");
this.visible = false;
} else {
$("#info-popup").fadeIn(500);
$("#btnDetails").addClass("button_highlight");
this.visible = true;
}
},
@@ -13,7 +15,7 @@ var DetailsWindow = {
var fileInfo = "<table>"
+ "<tr><td>Name<td><td>" + escapeHTML(file.file_name) + "</td></tr>"
+ "<tr><td>Url<td><td><a href=\"/u/" + file.id + "\">Open</a></td></tr>"
+ "<tr><td>Mime Type<td><td>" + escapeHTML(file.mime) + "</td></tr>"
+ "<tr><td>Mime Type<td><td>" + escapeHTML(file.mime_type) + "</td></tr>"
+ "<tr><td>Id<td><td>" + file.id + "</td></tr>"
+ "<tr><td>Size<td><td class=\"bytecounter\">" + file.file_size + "</td></tr>"
+ "<tr><td>Upload Date<td><td>" + file.date_upload + "</td></tr>"

View File

@@ -102,8 +102,10 @@ var ListNavigator = {
if(this.shuffle){
$("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2611;"); // Check icon
$("#btnShuffle").addClass("button_highlight");
}else{
$("#btnShuffle > span").html("&nbsp;Shuffle&nbsp;&#x2610;"); // Empty checkbox
$("#btnShuffle").removeClass("button_highlight");
}
},
@@ -187,7 +189,7 @@ var ListNavigator = {
// Add the shuffle button to the toolbar
var btnShuffle = document.createElement("button");
btnShuffle.setAttribute("id", "btnShuffle");
btnShuffle.setAttribute("class", "toolbar-button");
btnShuffle.setAttribute("class", "toolbar_button button_full_width");
btnShuffle.setAttribute("onClick", "ListNavigator.toggleShuffle();");
var btnShuffleImg = document.createElement("img");
@@ -205,22 +207,11 @@ var ListNavigator = {
// We need to adjust the height of some elements to make the navigation bar fit
var navHeight = $("#listNavigator").height() + 2;
window.setTimeout(function(){
$("#listNavigator").animate(
{"top": "0"},
{"duration": 800, "queue": false}
);
$("#filepreview").animate(
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#toolbar").animate(
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#sharebar").animate(
{top: navHeight},
{"duration": 1200, "queue": false}
);
$("#listNavigator").animate( {top: 0}, {"duration": 1500, "queue": false});
$("#filepreview").animate( {top: navHeight},{"duration": 1500, "queue": false});
$("#toolbar").animate( {top: navHeight},{"duration": 1500, "queue": false});
$("#button-expand-toolbar").animate({top: navHeight},{"duration": 1500, "queue": false});
$("#sharebar").animate( {top: navHeight},{"duration": 1500, "queue": false});
$("#info-popup").css("top", "120px");
}, 100);
}

View File

@@ -1,12 +1,3 @@
/*
* Time for a more Java-like approach.
* - Fornax
*
* Feel free to use this of course
*/
/* global Toolbar */
var Sharebar = {
visible: false,
@@ -16,11 +7,13 @@ var Sharebar = {
}
if(this.visible){
$("#sharebar").animate({left: "-102"}, 600);
$("#sharebar").animate({left: "-112"}, 600);
$("#btnShare").removeClass("button_highlight");
this.visible = false;
}else{
$("#sharebar").animate({left: "120"}, 400);
$("#btnShare").addClass("button_highlight");
this.visible = true;
}

View File

@@ -16,7 +16,7 @@ var Toolbar = {
Sharebar.toggle();
}
$("#toolbar").animate({left: "-122"}, 400);
$("#toolbar").animate({left: "-132"}, 400);
$("#filepreview").animate({left: "0"}, 400);
$("#button-expand-toolbar").css("visibility", "visible");
@@ -26,7 +26,11 @@ var Toolbar = {
$("#toolbar").animate({left: "0"}, 400);
$("#filepreview").animate({left: "122"}, 400);
setTimeout(function(){
if(this.visible){
$("#button-expand-toolbar").css("visibility", "hidden");
}
}, 1000)
this.visible = true;
}
@@ -49,6 +53,7 @@ var Toolbar = {
var success = document.execCommand('copy');
console.log('Text copied');
$("#btnCopy>span").text("Copied!");
$("#btnCopy").addClass("button_highlight");
} catch (err) {
console.log('Copying not supported');
$("#btnCopy>span").text("Error!");
@@ -56,7 +61,10 @@ var Toolbar = {
}
// Return to normal
setTimeout(function(){$("#btnCopy>span").text("Copy")}, 5000);
setTimeout(function(){
$("#btnCopy>span").text("Copy");
$("#btnCopy").removeClass("button_highlight");
}, 10000);
},
setViews: function(amount){
$("#views").html(amount);

File diff suppressed because one or more lines are too long

1
res/static/res/script/jquery.js vendored Symbolic link
View File

@@ -0,0 +1 @@
jquery-3.2.1.min.js

View File

@@ -1,242 +0,0 @@
/*
* Lazy Load - jQuery plugin for lazy loading images
*
* Copyright (c) 2007-2013 Mika Tuupola
*
* Licensed under the MIT license:
* http://www.opensource.org/licenses/mit-license.php
*
* Project home:
* http://www.appelsiini.net/projects/lazyload
*
* Version: 1.9.3
*
*/
(function($, window, document, undefined) {
var $window = $(window);
$.fn.lazyload = function(options) {
var elements = this;
var $container;
var settings = {
threshold : 0,
failure_limit : 0,
event : "scroll",
effect : "show",
container : window,
data_attribute : "original",
skip_invisible : true,
appear : null,
load : null,
placeholder : "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsQAAA7EAZUrDhsAAAANSURBVBhXYzh8+PB/AAffA0nNPuCLAAAAAElFTkSuQmCC"
};
function update() {
var counter = 0;
elements.each(function() {
var $this = $(this);
if (settings.skip_invisible && !$this.is(":visible")) {
return;
}
if ($.abovethetop(this, settings) ||
$.leftofbegin(this, settings)) {
/* Nothing. */
} else if (!$.belowthefold(this, settings) &&
!$.rightoffold(this, settings)) {
$this.trigger("appear");
/* if we found an image we'll load, reset the counter */
counter = 0;
} else {
if (++counter > settings.failure_limit) {
return false;
}
}
});
}
if(options) {
/* Maintain BC for a couple of versions. */
if (undefined !== options.failurelimit) {
options.failure_limit = options.failurelimit;
delete options.failurelimit;
}
if (undefined !== options.effectspeed) {
options.effect_speed = options.effectspeed;
delete options.effectspeed;
}
$.extend(settings, options);
}
/* Cache container as jQuery as object. */
$container = (settings.container === undefined ||
settings.container === window) ? $window : $(settings.container);
/* Fire one scroll event per scroll. Not one scroll event per image. */
if (0 === settings.event.indexOf("scroll")) {
$container.bind(settings.event, function() {
return update();
});
}
this.each(function() {
var self = this;
var $self = $(self);
self.loaded = false;
/* If no src attribute given use data:uri. */
if ($self.attr("src") === undefined || $self.attr("src") === false) {
if ($self.is("img")) {
$self.attr("src", settings.placeholder);
}
}
/* When appear is triggered load original image. */
$self.one("appear", function() {
if (!this.loaded) {
if (settings.appear) {
var elements_left = elements.length;
settings.appear.call(self, elements_left, settings);
}
$("<img />")
.bind("load", function() {
var original = $self.attr("data-" + settings.data_attribute);
$self.hide();
if ($self.is("img")) {
$self.attr("src", original);
} else {
$self.css("background-image", "url('" + original + "')");
}
$self[settings.effect](settings.effect_speed);
self.loaded = true;
/* Remove image from array so it is not looped next time. */
var temp = $.grep(elements, function(element) {
return !element.loaded;
});
elements = $(temp);
if (settings.load) {
var elements_left = elements.length;
settings.load.call(self, elements_left, settings);
}
})
.attr("src", $self.attr("data-" + settings.data_attribute));
}
});
/* When wanted event is triggered load original image */
/* by triggering appear. */
if (0 !== settings.event.indexOf("scroll")) {
$self.bind(settings.event, function() {
if (!self.loaded) {
$self.trigger("appear");
}
});
}
});
/* Check if something appears when window is resized. */
$window.bind("resize", function() {
update();
});
/* With IOS5 force loading images when navigating with back button. */
/* Non optimal workaround. */
if ((/(?:iphone|ipod|ipad).*os 5/gi).test(navigator.appVersion)) {
$window.bind("pageshow", function(event) {
if (event.originalEvent && event.originalEvent.persisted) {
elements.each(function() {
$(this).trigger("appear");
});
}
});
}
/* Force initial check if images should appear. */
$(document).ready(function() {
update();
});
return this;
};
/* Convenience methods in jQuery namespace. */
/* Use as $.belowthefold(element, {threshold : 100, container : window}) */
$.belowthefold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = (window.innerHeight ? window.innerHeight : $window.height()) + $window.scrollTop();
} else {
fold = $(settings.container).offset().top + $(settings.container).height();
}
return fold <= $(element).offset().top - settings.threshold;
};
$.rightoffold = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.width() + $window.scrollLeft();
} else {
fold = $(settings.container).offset().left + $(settings.container).width();
}
return fold <= $(element).offset().left - settings.threshold;
};
$.abovethetop = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollTop();
} else {
fold = $(settings.container).offset().top;
}
return fold >= $(element).offset().top + settings.threshold + $(element).height();
};
$.leftofbegin = function(element, settings) {
var fold;
if (settings.container === undefined || settings.container === window) {
fold = $window.scrollLeft();
} else {
fold = $(settings.container).offset().left;
}
return fold >= $(element).offset().left + settings.threshold + $(element).width();
};
$.inviewport = function(element, settings) {
return !$.rightoffold(element, settings) && !$.leftofbegin(element, settings) &&
!$.belowthefold(element, settings) && !$.abovethetop(element, settings);
};
/* Custom selectors for your convenience. */
/* Use as $("img:below-the-fold").something() or */
/* $("img").filter(":below-the-fold").something() which is faster */
$.extend($.expr[":"], {
"below-the-fold" : function(a) { return $.belowthefold(a, {threshold : 0}); },
"above-the-top" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-screen": function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-screen" : function(a) { return !$.rightoffold(a, {threshold : 0}); },
"in-viewport" : function(a) { return $.inviewport(a, {threshold : 0}); },
/* Maintain BC for couple of versions. */
"above-the-fold" : function(a) { return !$.belowthefold(a, {threshold : 0}); },
"right-of-fold" : function(a) { return $.rightoffold(a, {threshold : 0}); },
"left-of-fold" : function(a) { return !$.rightoffold(a, {threshold : 0}); }
});
})(jQuery, window, document);

File diff suppressed because one or more lines are too long

View File

@@ -1,11 +0,0 @@
/*!
* jQuery UI Touch Punch 0.2.3
*
* Copyright 20112014, Dave Furfero
* Dual licensed under the MIT or GPL Version 2 licenses.
*
* Depends:
* jquery.ui.widget.js
* jquery.ui.mouse.js
*/
!function(a){function f(a,b){if(!(a.originalEvent.touches.length>1)){a.preventDefault();var c=a.originalEvent.changedTouches[0],d=document.createEvent("MouseEvents");d.initMouseEvent(b,!0,!0,window,1,c.screenX,c.screenY,c.clientX,c.clientY,!1,!1,!1,!1,0,null),a.target.dispatchEvent(d)}}if(a.support.touch="ontouchend"in document,a.support.touch){var e,b=a.ui.mouse.prototype,c=b._mouseInit,d=b._mouseDestroy;b._touchStart=function(a){var b=this;!e&&b._mouseCapture(a.originalEvent.changedTouches[0])&&(e=!0,b._touchMoved=!1,f(a,"mouseover"),f(a,"mousemove"),f(a,"mousedown"))},b._touchMove=function(a){e&&(this._touchMoved=!0,f(a,"mousemove"))},b._touchEnd=function(a){e&&(f(a,"mouseup"),f(a,"mouseout"),this._touchMoved||f(a,"click"),e=!1)},b._mouseInit=function(){var b=this;b.element.bind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),c.call(b)},b._mouseDestroy=function(){var b=this;b.element.unbind({touchstart:a.proxy(b,"_touchStart"),touchmove:a.proxy(b,"_touchMove"),touchend:a.proxy(b,"_touchEnd")}),d.call(b)}}}(jQuery);

View File

@@ -0,0 +1,64 @@
!function(){/*
Copyright (C) 2013 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Copyright (C) 2006 Google Inc.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
(function(){function aa(g){function r(){try{L.doScroll("left")}catch(ba){k.setTimeout(r,50);return}x("poll")}function x(r){if("readystatechange"!=r.type||"complete"==z.readyState)("load"==r.type?k:z)[B](n+r.type,x,!1),!l&&(l=!0)&&g.call(k,r.type||r)}var X=z.addEventListener,l=!1,E=!0,v=X?"addEventListener":"attachEvent",B=X?"removeEventListener":"detachEvent",n=X?"":"on";if("complete"==z.readyState)g.call(k,"lazy");else{if(z.createEventObject&&L.doScroll){try{E=!k.frameElement}catch(ba){}E&&r()}z[v](n+
"DOMContentLoaded",x,!1);z[v](n+"readystatechange",x,!1);k[v](n+"load",x,!1)}}function T(){U&&aa(function(){var g=M.length;ca(g?function(){for(var r=0;r<g;++r)(function(g){k.setTimeout(function(){k.exports[M[g]].apply(k,arguments)},0)})(r)}:void 0)})}for(var k=window,z=document,L=z.documentElement,N=z.head||z.getElementsByTagName("head")[0]||L,B="",F=z.getElementsByTagName("script"),l=F.length;0<=--l;){var O=F[l],Y=O.src.match(/^[^?#]*\/run_prettify\.js(\?[^#]*)?(?:#.*)?$/);if(Y){B=Y[1]||"";O.parentNode.removeChild(O);
break}}var U=!0,H=[],P=[],M=[];B.replace(/[?&]([^&=]+)=([^&]+)/g,function(g,r,x){x=decodeURIComponent(x);r=decodeURIComponent(r);"autorun"==r?U=!/^[0fn]/i.test(x):"lang"==r?H.push(x):"skin"==r?P.push(x):"callback"==r&&M.push(x)});l=0;for(B=H.length;l<B;++l)(function(){var g=z.createElement("script");g.onload=g.onerror=g.onreadystatechange=function(){!g||g.readyState&&!/loaded|complete/.test(g.readyState)||(g.onerror=g.onload=g.onreadystatechange=null,--S,S||k.setTimeout(T,0),g.parentNode&&g.parentNode.removeChild(g),
g=null)};g.type="text/javascript";g.src="https://cdn.rawgit.com/google/code-prettify/master/loader/lang-"+encodeURIComponent(H[l])+".js";N.insertBefore(g,N.firstChild)})(H[l]);for(var S=H.length,F=[],l=0,B=P.length;l<B;++l)F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/skins/"+encodeURIComponent(P[l])+".css");F.push("https://cdn.rawgit.com/google/code-prettify/master/loader/prettify.css");(function(g){function r(l){if(l!==x){var k=z.createElement("link");k.rel="stylesheet";k.type=
"text/css";l+1<x&&(k.error=k.onerror=function(){r(l+1)});k.href=g[l];N.appendChild(k)}}var x=g.length;r(0)})(F);var ca=function(){"undefined"!==typeof window&&(window.PR_SHOULD_USE_CONTINUATION=!0);var g;(function(){function r(a){function d(e){var a=e.charCodeAt(0);if(92!==a)return a;var c=e.charAt(1);return(a=k[c])?a:"0"<=c&&"7">=c?parseInt(e.substring(1),8):"u"===c||"x"===c?parseInt(e.substring(2),16):e.charCodeAt(1)}function f(e){if(32>e)return(16>e?"\\x0":"\\x")+e.toString(16);e=String.fromCharCode(e);
return"\\"===e||"-"===e||"]"===e||"^"===e?"\\"+e:e}function c(e){var c=e.substring(1,e.length-1).match(RegExp("\\\\u[0-9A-Fa-f]{4}|\\\\x[0-9A-Fa-f]{2}|\\\\[0-3][0-7]{0,2}|\\\\[0-7]{1,2}|\\\\[\\s\\S]|-|[^-\\\\]","g"));e=[];var a="^"===c[0],b=["["];a&&b.push("^");for(var a=a?1:0,h=c.length;a<h;++a){var m=c[a];if(/\\[bdsw]/i.test(m))b.push(m);else{var m=d(m),p;a+2<h&&"-"===c[a+1]?(p=d(c[a+2]),a+=2):p=m;e.push([m,p]);65>p||122<m||(65>p||90<m||e.push([Math.max(65,m)|32,Math.min(p,90)|32]),97>p||122<m||
e.push([Math.max(97,m)&-33,Math.min(p,122)&-33]))}}e.sort(function(e,a){return e[0]-a[0]||a[1]-e[1]});c=[];h=[];for(a=0;a<e.length;++a)m=e[a],m[0]<=h[1]+1?h[1]=Math.max(h[1],m[1]):c.push(h=m);for(a=0;a<c.length;++a)m=c[a],b.push(f(m[0])),m[1]>m[0]&&(m[1]+1>m[0]&&b.push("-"),b.push(f(m[1])));b.push("]");return b.join("")}function g(e){for(var a=e.source.match(RegExp("(?:\\[(?:[^\\x5C\\x5D]|\\\\[\\s\\S])*\\]|\\\\u[A-Fa-f0-9]{4}|\\\\x[A-Fa-f0-9]{2}|\\\\[0-9]+|\\\\[^ux0-9]|\\(\\?[:!=]|[\\(\\)\\^]|[^\\x5B\\x5C\\(\\)\\^]+)",
"g")),b=a.length,d=[],h=0,m=0;h<b;++h){var p=a[h];"("===p?++m:"\\"===p.charAt(0)&&(p=+p.substring(1))&&(p<=m?d[p]=-1:a[h]=f(p))}for(h=1;h<d.length;++h)-1===d[h]&&(d[h]=++r);for(m=h=0;h<b;++h)p=a[h],"("===p?(++m,d[m]||(a[h]="(?:")):"\\"===p.charAt(0)&&(p=+p.substring(1))&&p<=m&&(a[h]="\\"+d[p]);for(h=0;h<b;++h)"^"===a[h]&&"^"!==a[h+1]&&(a[h]="");if(e.ignoreCase&&A)for(h=0;h<b;++h)p=a[h],e=p.charAt(0),2<=p.length&&"["===e?a[h]=c(p):"\\"!==e&&(a[h]=p.replace(/[a-zA-Z]/g,function(a){a=a.charCodeAt(0);
return"["+String.fromCharCode(a&-33,a|32)+"]"}));return a.join("")}for(var r=0,A=!1,q=!1,I=0,b=a.length;I<b;++I){var t=a[I];if(t.ignoreCase)q=!0;else if(/[a-z]/i.test(t.source.replace(/\\u[0-9a-f]{4}|\\x[0-9a-f]{2}|\\[^ux]/gi,""))){A=!0;q=!1;break}}for(var k={b:8,t:9,n:10,v:11,f:12,r:13},u=[],I=0,b=a.length;I<b;++I){t=a[I];if(t.global||t.multiline)throw Error(""+t);u.push("(?:"+g(t)+")")}return new RegExp(u.join("|"),q?"gi":"g")}function l(a,d){function f(a){var b=a.nodeType;if(1==b){if(!c.test(a.className)){for(b=
a.firstChild;b;b=b.nextSibling)f(b);b=a.nodeName.toLowerCase();if("br"===b||"li"===b)g[q]="\n",A[q<<1]=r++,A[q++<<1|1]=a}}else if(3==b||4==b)b=a.nodeValue,b.length&&(b=d?b.replace(/\r\n?/g,"\n"):b.replace(/[ \t\r\n]+/g," "),g[q]=b,A[q<<1]=r,r+=b.length,A[q++<<1|1]=a)}var c=/(?:^|\s)nocode(?:\s|$)/,g=[],r=0,A=[],q=0;f(a);return{a:g.join("").replace(/\n$/,""),c:A}}function k(a,d,f,c,g){f&&(a={h:a,l:1,j:null,m:null,a:f,c:null,i:d,g:null},c(a),g.push.apply(g,a.g))}function z(a){for(var d=void 0,f=a.firstChild;f;f=
f.nextSibling)var c=f.nodeType,d=1===c?d?a:f:3===c?S.test(f.nodeValue)?a:d:d;return d===a?void 0:d}function E(a,d){function f(a){for(var q=a.i,r=a.h,b=[q,"pln"],t=0,A=a.a.match(g)||[],u={},e=0,l=A.length;e<l;++e){var D=A[e],w=u[D],h=void 0,m;if("string"===typeof w)m=!1;else{var p=c[D.charAt(0)];if(p)h=D.match(p[1]),w=p[0];else{for(m=0;m<n;++m)if(p=d[m],h=D.match(p[1])){w=p[0];break}h||(w="pln")}!(m=5<=w.length&&"lang-"===w.substring(0,5))||h&&"string"===typeof h[1]||(m=!1,w="src");m||(u[D]=w)}p=t;
t+=D.length;if(m){m=h[1];var C=D.indexOf(m),G=C+m.length;h[2]&&(G=D.length-h[2].length,C=G-m.length);w=w.substring(5);k(r,q+p,D.substring(0,C),f,b);k(r,q+p+C,m,F(w,m),b);k(r,q+p+G,D.substring(G),f,b)}else b.push(q+p,w)}a.g=b}var c={},g;(function(){for(var f=a.concat(d),q=[],k={},b=0,t=f.length;b<t;++b){var n=f[b],u=n[3];if(u)for(var e=u.length;0<=--e;)c[u.charAt(e)]=n;n=n[1];u=""+n;k.hasOwnProperty(u)||(q.push(n),k[u]=null)}q.push(/[\0-\uffff]/);g=r(q)})();var n=d.length;return f}function v(a){var d=
[],f=[];a.tripleQuotedStrings?d.push(["str",/^(?:\'\'\'(?:[^\'\\]|\\[\s\S]|\'{1,2}(?=[^\']))*(?:\'\'\'|$)|\"\"\"(?:[^\"\\]|\\[\s\S]|\"{1,2}(?=[^\"]))*(?:\"\"\"|$)|\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$))/,null,"'\""]):a.multiLineStrings?d.push(["str",/^(?:\'(?:[^\\\']|\\[\s\S])*(?:\'|$)|\"(?:[^\\\"]|\\[\s\S])*(?:\"|$)|\`(?:[^\\\`]|\\[\s\S])*(?:\`|$))/,null,"'\"`"]):d.push(["str",/^(?:\'(?:[^\\\'\r\n]|\\.)*(?:\'|$)|\"(?:[^\\\"\r\n]|\\.)*(?:\"|$))/,null,"\"'"]);a.verbatimStrings&&
f.push(["str",/^@\"(?:[^\"]|\"\")*(?:\"|$)/,null]);var c=a.hashComments;c&&(a.cStyleComments?(1<c?d.push(["com",/^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)/,null,"#"]):d.push(["com",/^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\b|[^\r\n]*)/,null,"#"]),f.push(["str",/^<(?:(?:(?:\.\.\/)*|\/?)(?:[\w-]+(?:\/[\w-]+)+)?[\w-]+\.h(?:h|pp|\+\+)?|[a-z]\w*)>/,null])):d.push(["com",/^#[^\r\n]*/,null,"#"]));a.cStyleComments&&(f.push(["com",/^\/\/[^\r\n]*/,null]),f.push(["com",/^\/\*[\s\S]*?(?:\*\/|$)/,
null]));if(c=a.regexLiterals){var g=(c=1<c?"":"\n\r")?".":"[\\S\\s]";f.push(["lang-regex",RegExp("^(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*("+("/(?=[^/*"+c+"])(?:[^/\\x5B\\x5C"+c+"]|\\x5C"+g+"|\\x5B(?:[^\\x5C\\x5D"+c+"]|\\x5C"+g+")*(?:\\x5D|$))+/")+")")])}(c=a.types)&&f.push(["typ",c]);c=(""+a.keywords).replace(/^ | $/g,"");c.length&&f.push(["kwd",
new RegExp("^(?:"+c.replace(/[\s,]+/g,"|")+")\\b"),null]);d.push(["pln",/^\s+/,null," \r\n\t\u00a0"]);c="^.[^\\s\\w.$@'\"`/\\\\]*";a.regexLiterals&&(c+="(?!s*/)");f.push(["lit",/^@[a-z_$][a-z_$@0-9]*/i,null],["typ",/^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\w+_t\b)/,null],["pln",/^[a-z_$][a-z_$@0-9]*/i,null],["lit",/^(?:0x[a-f0-9]+|(?:\d(?:_\d+)*\d*(?:\.\d*)?|\.\d\+)(?:e[+\-]?\d+)?)[a-z]*/i,null,"0123456789"],["pln",/^\\[\s\S]?/,null],["pun",new RegExp(c),null]);return E(d,f)}function B(a,d,f){function c(a){var b=
a.nodeType;if(1==b&&!r.test(a.className))if("br"===a.nodeName.toLowerCase())g(a),a.parentNode&&a.parentNode.removeChild(a);else for(a=a.firstChild;a;a=a.nextSibling)c(a);else if((3==b||4==b)&&f){var e=a.nodeValue,d=e.match(n);d&&(b=e.substring(0,d.index),a.nodeValue=b,(e=e.substring(d.index+d[0].length))&&a.parentNode.insertBefore(q.createTextNode(e),a.nextSibling),g(a),b||a.parentNode.removeChild(a))}}function g(a){function c(a,b){var e=b?a.cloneNode(!1):a,p=a.parentNode;if(p){var p=c(p,1),d=a.nextSibling;
p.appendChild(e);for(var f=d;f;f=d)d=f.nextSibling,p.appendChild(f)}return e}for(;!a.nextSibling;)if(a=a.parentNode,!a)return;a=c(a.nextSibling,0);for(var e;(e=a.parentNode)&&1===e.nodeType;)a=e;b.push(a)}for(var r=/(?:^|\s)nocode(?:\s|$)/,n=/\r\n?|\n/,q=a.ownerDocument,k=q.createElement("li");a.firstChild;)k.appendChild(a.firstChild);for(var b=[k],t=0;t<b.length;++t)c(b[t]);d===(d|0)&&b[0].setAttribute("value",d);var l=q.createElement("ol");l.className="linenums";d=Math.max(0,d-1|0)||0;for(var t=
0,u=b.length;t<u;++t)k=b[t],k.className="L"+(t+d)%10,k.firstChild||k.appendChild(q.createTextNode("\u00a0")),l.appendChild(k);a.appendChild(l)}function n(a,d){for(var f=d.length;0<=--f;){var c=d[f];V.hasOwnProperty(c)?Q.console&&console.warn("cannot override language handler %s",c):V[c]=a}}function F(a,d){a&&V.hasOwnProperty(a)||(a=/^\s*</.test(d)?"default-markup":"default-code");return V[a]}function H(a){var d=a.j;try{var f=l(a.h,a.l),c=f.a;a.a=c;a.c=f.c;a.i=0;F(d,c)(a);var g=/\bMSIE\s(\d+)/.exec(navigator.userAgent),
g=g&&8>=+g[1],d=/\n/g,r=a.a,k=r.length,f=0,q=a.c,n=q.length,c=0,b=a.g,t=b.length,v=0;b[t]=k;var u,e;for(e=u=0;e<t;)b[e]!==b[e+2]?(b[u++]=b[e++],b[u++]=b[e++]):e+=2;t=u;for(e=u=0;e<t;){for(var x=b[e],z=b[e+1],w=e+2;w+2<=t&&b[w+1]===z;)w+=2;b[u++]=x;b[u++]=z;e=w}b.length=u;var h=a.h;a="";h&&(a=h.style.display,h.style.display="none");try{for(;c<n;){var m=q[c+2]||k,p=b[v+2]||k,w=Math.min(m,p),C=q[c+1],G;if(1!==C.nodeType&&(G=r.substring(f,w))){g&&(G=G.replace(d,"\r"));C.nodeValue=G;var Z=C.ownerDocument,
W=Z.createElement("span");W.className=b[v+1];var B=C.parentNode;B.replaceChild(W,C);W.appendChild(C);f<m&&(q[c+1]=C=Z.createTextNode(r.substring(w,m)),B.insertBefore(C,W.nextSibling))}f=w;f>=m&&(c+=2);f>=p&&(v+=2)}}finally{h&&(h.style.display=a)}}catch(y){Q.console&&console.log(y&&y.stack||y)}}var Q="undefined"!==typeof window?window:{},J=["break,continue,do,else,for,if,return,while"],K=[[J,"auto,case,char,const,default,double,enum,extern,float,goto,inline,int,long,register,restrict,short,signed,sizeof,static,struct,switch,typedef,union,unsigned,void,volatile"],
"catch,class,delete,false,import,new,operator,private,protected,public,this,throw,true,try,typeof"],R=[K,"alignas,alignof,align_union,asm,axiom,bool,concept,concept_map,const_cast,constexpr,decltype,delegate,dynamic_cast,explicit,export,friend,generic,late_check,mutable,namespace,noexcept,noreturn,nullptr,property,reinterpret_cast,static_assert,static_cast,template,typeid,typename,using,virtual,where"],L=[K,"abstract,assert,boolean,byte,extends,finally,final,implements,import,instanceof,interface,null,native,package,strictfp,super,synchronized,throws,transient"],
M=[K,"abstract,add,alias,as,ascending,async,await,base,bool,by,byte,checked,decimal,delegate,descending,dynamic,event,finally,fixed,foreach,from,get,global,group,implicit,in,interface,internal,into,is,join,let,lock,null,object,out,override,orderby,params,partial,readonly,ref,remove,sbyte,sealed,select,set,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,value,var,virtual,where,yield"],K=[K,"abstract,async,await,constructor,debugger,enum,eval,export,function,get,implements,instanceof,interface,let,null,set,undefined,var,with,yield,Infinity,NaN"],
N=[J,"and,as,assert,class,def,del,elif,except,exec,finally,from,global,import,in,is,lambda,nonlocal,not,or,pass,print,raise,try,with,yield,False,True,None"],O=[J,"alias,and,begin,case,class,def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,rescue,retry,self,super,then,true,undef,unless,until,when,yield,BEGIN,END"],J=[J,"case,done,elif,esac,eval,fi,function,in,local,set,then,until"],P=/^(DIR|FILE|array|vector|(de|priority_)?queue|(forward_)?list|stack|(const_)?(reverse_)?iterator|(unordered_)?(multi)?(set|map)|bitset|u?(int|float)\d*)\b/,
S=/\S/,T=v({keywords:[R,M,L,K,"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",N,O,J],hashComments:!0,cStyleComments:!0,multiLineStrings:!0,regexLiterals:!0}),V={};n(T,["default-code"]);n(E([],[["pln",/^[^<?]+/],["dec",/^<!\w[^>]*(?:>|$)/],["com",/^<\!--[\s\S]*?(?:-\->|$)/],["lang-",/^<\?([\s\S]+?)(?:\?>|$)/],["lang-",/^<%([\s\S]+?)(?:%>|$)/],["pun",/^(?:<[%?]|[%?]>)/],["lang-",
/^<xmp\b[^>]*>([\s\S]+?)<\/xmp\b[^>]*>/i],["lang-js",/^<script\b[^>]*>([\s\S]*?)(<\/script\b[^>]*>)/i],["lang-css",/^<style\b[^>]*>([\s\S]*?)(<\/style\b[^>]*>)/i],["lang-in.tag",/^(<\/?[a-z][^<>]*>)/i]]),"default-markup htm html mxml xhtml xml xsl".split(" "));n(E([["pln",/^[\s]+/,null," \t\r\n"],["atv",/^(?:\"[^\"]*\"?|\'[^\']*\'?)/,null,"\"'"]],[["tag",/^^<\/?[a-z](?:[\w.:-]*\w)?|\/?>$/i],["atn",/^(?!style[\s=]|on)[a-z](?:[\w:-]*\w)?/i],["lang-uq.val",/^=\s*([^>\'\"\s]*(?:[^>\'\"\s\/]|\/(?=\s)))/],
["pun",/^[=<>\/]+/],["lang-js",/^on\w+\s*=\s*\"([^\"]+)\"/i],["lang-js",/^on\w+\s*=\s*\'([^\']+)\'/i],["lang-js",/^on\w+\s*=\s*([^\"\'>\s]+)/i],["lang-css",/^style\s*=\s*\"([^\"]+)\"/i],["lang-css",/^style\s*=\s*\'([^\']+)\'/i],["lang-css",/^style\s*=\s*([^\"\'>\s]+)/i]]),["in.tag"]);n(E([],[["atv",/^[\s\S]+/]]),["uq.val"]);n(v({keywords:R,hashComments:!0,cStyleComments:!0,types:P}),"c cc cpp cxx cyc m".split(" "));n(v({keywords:"null,true,false"}),["json"]);n(v({keywords:M,hashComments:!0,cStyleComments:!0,
verbatimStrings:!0,types:P}),["cs"]);n(v({keywords:L,cStyleComments:!0}),["java"]);n(v({keywords:J,hashComments:!0,multiLineStrings:!0}),["bash","bsh","csh","sh"]);n(v({keywords:N,hashComments:!0,multiLineStrings:!0,tripleQuotedStrings:!0}),["cv","py","python"]);n(v({keywords:"caller,delete,die,do,dump,elsif,eval,exit,foreach,for,goto,if,import,last,local,my,next,no,our,print,package,redo,require,sub,undef,unless,until,use,wantarray,while,BEGIN,END",hashComments:!0,multiLineStrings:!0,regexLiterals:2}),
["perl","pl","pm"]);n(v({keywords:O,hashComments:!0,multiLineStrings:!0,regexLiterals:!0}),["rb","ruby"]);n(v({keywords:K,cStyleComments:!0,regexLiterals:!0}),["javascript","js","ts","typescript"]);n(v({keywords:"all,and,by,catch,class,else,extends,false,finally,for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,throw,true,try,unless,until,when,while,yes",hashComments:3,cStyleComments:!0,multilineStrings:!0,tripleQuotedStrings:!0,regexLiterals:!0}),["coffee"]);n(E([],[["str",/^[\s\S]+/]]),
["regex"]);var U=Q.PR={createSimpleLexer:E,registerLangHandler:n,sourceDecorator:v,PR_ATTRIB_NAME:"atn",PR_ATTRIB_VALUE:"atv",PR_COMMENT:"com",PR_DECLARATION:"dec",PR_KEYWORD:"kwd",PR_LITERAL:"lit",PR_NOCODE:"nocode",PR_PLAIN:"pln",PR_PUNCTUATION:"pun",PR_SOURCE:"src",PR_STRING:"str",PR_TAG:"tag",PR_TYPE:"typ",prettyPrintOne:function(a,d,f){f=f||!1;d=d||null;var c=document.createElement("div");c.innerHTML="<pre>"+a+"</pre>";c=c.firstChild;f&&B(c,f,!0);H({j:d,m:f,h:c,l:1,a:null,i:null,c:null,g:null});
return c.innerHTML},prettyPrint:g=function(a,d){function f(){for(var c=Q.PR_SHOULD_USE_CONTINUATION?b.now()+250:Infinity;t<r.length&&b.now()<c;t++){for(var d=r[t],k=h,n=d;n=n.previousSibling;){var q=n.nodeType,l=(7===q||8===q)&&n.nodeValue;if(l?!/^\??prettify\b/.test(l):3!==q||/\S/.test(n.nodeValue))break;if(l){k={};l.replace(/\b(\w+)=([\w:.%+-]+)/g,function(a,b,c){k[b]=c});break}}n=d.className;if((k!==h||u.test(n))&&!e.test(n)){q=!1;for(l=d.parentNode;l;l=l.parentNode)if(w.test(l.tagName)&&l.className&&
u.test(l.className)){q=!0;break}if(!q){d.className+=" prettyprinted";q=k.lang;if(!q){var q=n.match(v),A;!q&&(A=z(d))&&D.test(A.tagName)&&(q=A.className.match(v));q&&(q=q[1])}if(x.test(d.tagName))l=1;else var l=d.currentStyle,y=g.defaultView,l=(l=l?l.whiteSpace:y&&y.getComputedStyle?y.getComputedStyle(d,null).getPropertyValue("white-space"):0)&&"pre"===l.substring(0,3);y=k.linenums;(y="true"===y||+y)||(y=(y=n.match(/\blinenums\b(?::(\d+))?/))?y[1]&&y[1].length?+y[1]:!0:!1);y&&B(d,y,l);H({j:q,h:d,m:y,
l:l,a:null,i:null,c:null,g:null})}}}t<r.length?Q.setTimeout(f,250):"function"===typeof a&&a()}for(var c=d||document.body,g=c.ownerDocument||document,c=[c.getElementsByTagName("pre"),c.getElementsByTagName("code"),c.getElementsByTagName("xmp")],r=[],k=0;k<c.length;++k)for(var n=0,l=c[k].length;n<l;++n)r.push(c[k][n]);var c=null,b=Date;b.now||(b={now:function(){return+new Date}});var t=0,v=/\blang(?:uage)?-([\w.]+)(?!\S)/,u=/\bprettyprint\b/,e=/\bprettyprinted\b/,x=/pre|xmp/i,D=/^code$/i,w=/^(?:pre|code|xmp)$/i,
h={};f()}},R=Q.define;"function"===typeof R&&R.amd&&R("google-code-prettify",[],function(){return U})})();return g}();S||k.setTimeout(T,0)})();}()

View File

@@ -20,7 +20,7 @@
width: 0%;
left: 0;
height: 100%;
background-color: #9FCF6C;
background-color: var(--highlight_color);;
overflow: hidden;
color: #000;
white-space: nowrap;

View File

@@ -6,14 +6,14 @@
body{
background-color: #111;
background-repeat: repeat;
color: #c0c0c0;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
margin: 0;
text-align: center;
text-align: center; /* Center the header and body */
line-height: 140%;
height: 100%;
overflow-x: hidden;
color: var(--text_color);
}
html{
@@ -50,7 +50,7 @@ html{
}
/* Body elements */
/* Layout elements */
.body{
position: relative;
@@ -61,16 +61,21 @@ html{
height: auto;
padding: 0px 8px 0px 8px;
box-sizing: border-box;
background-color: #1A1A1A;
background-color: #242424;
margin-top: 30px;
margin-bottom: 30px;
text-align: left;
box-shadow: #000 0px 0px 40px;
box-shadow: #000 8px 8px 50px;
z-index: 1;
word-break: break-word;
}
.highlight{
.highlight_dark,
.highlight_middle,
.highlight_light,
.highlight_green,
.highlight_blue,
.highlight_red {
position: relative;
width: auto;
height: auto;
@@ -81,27 +86,28 @@ html{
padding: 4px 0px 4px 0px;
z-index: 101;
}
.bg-light {
background-color: #404040;
}
.bg-middle {
background-color: #303030;
}
.bg-dark {
background-color: #222222;
}
.border-top {
border-top: #686868 1px solid;
}
.border-bottom {
border-bottom: #686868 1px solid;
}
.highlight_light {background-color: #484848;}
.highlight_middle {background-color: #3a3a3a;}
.highlight_dark {background-color: #303030;}
.border-top {border-top: #686868 1px solid;}
.border-bottom {border-bottom: #686868 1px solid;}
.menu{
font-family: "Lato", sans-serif;
font-weight: bold;
font-size: 26px;
}
/* Common elements */
hr{
height: 8px;
border: none;
background: linear-gradient(#101010, #303030);
margin: 16px -8px 16px -8px;
}
::-webkit-scrollbar{
width: 12px; /* for vertical scrollbars */
height: 12px; /* for horizontal scrollbars */
@@ -117,59 +123,141 @@ html{
background: transparent;
}
/* Common elements */
a{
color: #9FCF6C;
color: var(--highlight_color);
text-decoration: none;
}
a:hover{
text-decoration: underline;
color: #9FCF6C;
color: var(--highlight_color);
}
.big-button{
position: relative;
.big_button{
height: 40px;
width: 40%;
min-width: 200px;
max-width: 400px;
background-color: #9FCF6C;
margin: 10px !important;
border-radius: 10px;
border: none;
color: #333;
font-size: 30px;
margin: 6px;
cursor: pointer;
box-shadow: #000 3px 3px 1px;
font-weight: normal;
line-height: 8px;
}
.progress-bar{
position: relative;
width: 100%;
height: 0;
background-color: #555;
overflow: hidden;
color: #eeeeee;
text-align: left;
white-space: nowrap;
}
.progressbar-inner{
position: absolute;
top: 0;
width: 0%;
left: 0;
height: 100%;
background-color: var(--highlight_color);;
overflow: hidden;
color: #000;
white-space: nowrap;
}
.progress-text{
overflow: hidden;
width: 100%;
white-space: nowrap;
}
/* Form fields */
input[type="text"], input[type="password"], input[type="email"]{
border: #9FCF6C ridge 2px;
background: #626262;
color: #eeeeee;
height: 20px;
/* BUTTONS */
button,
input[type="submit"],
input[type="button"],
input[type="color"],
select{
border-radius: 4px;
border: 1px hidden transparent;
background: linear-gradient(#606060, #404040);
padding: 6px 10px 6px 10px;
margin: 2px;
box-shadow: 2px 2px 8px #000000;
font-weight: bold;
color: #FFFFFF;
outline: 0;
vertical-align: middle;
cursor: pointer;
}
button:hover,
input[type="submit"]:hover,
input[type="button"]:hover,
input[type="color"]:hover,
select:hover,
button:focus,
input[type="submit"]:focus,
input[type="button"]:focus,
input[type="color"]:focus,
select:focus{
border: 1px solid var(--highlight_color);
margin: 1px;
}
button:active,
input[type="submit"]:active,
input[type="button"]:active,
input[type="color"]:active,
select:active{
border: 1px solid var(--highlight_color);
margin: 1px;
background: linear-gradient(#404040, #606060);
box-shadow: inset 3px 3px 6px #000000;
padding: 8px 8px 4px 12px;
}
.button_full_width {width: calc(100% - 4px);}
.button_highlight {background: linear-gradient(var(--highlight_color), var(--highlight_color_dark));}
.button_highlight:active{background: linear-gradient(var(--highlight_color_dark), var(--highlight_color));}
.button_red {background: linear-gradient(#821C40, #61152F);}
.button_red:active {background: linear-gradient(#61152F, #821C40);}
/* Dropdown list of the select tag */
option{
background-color: #404040;
color: #FFFFFF;
}
/* TEXT FIELDS */
textarea,
input[type="text"],
input[type="password"],
input[type="email"],
input[type="number"]{
border: none;
box-sizing: border-box;
border-radius: 4px;
background: linear-gradient(#404040, #606060);
box-shadow: inset 3px 3px 6px #000000;
padding: 3px 5px;
color: var(--text_color);
height: 26px;
font-size: 18px;
font-family: 'Ubuntu', sans-serif;
vertical-align: bottom;
outline: 0;
}
input[type="submit"], input[type="button"]{
background-color: #222;
border: #9FCF6C solid 1px;
color: #eeeeee;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
cursor: pointer;
vertical-align: bottom;
margin: 0;
}
input[type="submit"]:hover, input[type="button"]:hover{
background-color: #444;
textarea:active,
input[type="text"]:active,
input[type="password"]:active,
input[type="email"]:active,
input[type="number"]:active,
textarea:focus,
input[type="text"]:focus,
input[type="password"]:focus,
input[type="email"]:focus,
input[type="number"]:focus{
border: 1px solid var(--highlight_color);
padding: 3px 4px;
}
input[type=file]{

View File

@@ -28,11 +28,12 @@
top: -100px;
height: 98px;
background-color: #000;
border-bottom: 2px ridge #9FCF6C;
box-shadow: 2px 2px 8px #000000;
border-bottom: 2px ridge var(--highlight_color);
text-align: center;
overflow-x: hidden;
overflow-y: hidden;
z-index: 1000;
z-index: 50;
}
#listNavigatorItems{
@@ -46,8 +47,6 @@
overflow-y: hidden;
border: none;
padding: 0 40px;
z-index: 1001;
}
.listItem{
@@ -70,18 +69,22 @@
margin: 0;
}
#arrow-left{
position: fixed;
height: 92px;
width: 35px;
left: 0;
z-index: 1002;
}
#arrow-left,
#arrow-right{
position: fixed;
height: 92px;
width: 35px;
right: 0;
z-index: 1002;
position: absolute;
display: block;
border-top: 30px solid transparent;
border-bottom: 30px solid transparent;
height: 0;
width: 0;
top: 20px;
cursor: pointer;
}
#arrow-left{
border-right: 40px solid var(--highlight_color);
left: 10px;
}
#arrow-right{
border-left: 40px solid var(--highlight_color);
right: 10px;
}

View File

@@ -7,13 +7,8 @@
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
border: none;
box-sizing: border-box;
padding: 10px;
background-color: #222;
color: #eee;
font-family: 'Ubuntu Mono' , sans-serif;
font-size: 18px;
width: 100%;
border: none !important;
background: #202020;
}

View File

@@ -4,60 +4,9 @@
*/
body{
background-color: #111;
/*background-image: url("img/checker3.png"); Defined in viewer.html*/
background-repeat: repeat;
color: #eeeeee;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
margin: 0;
overflow: hidden;
}
a{
color: #9FCF6C;
text-decoration: none;
}
a:hover{
text-decoration: underline;
color: #9FCF6C;
}
::-webkit-scrollbar{
width: 10px; /* for vertical scrollbars */
height: 10px; /* for horizontal scrollbars */
}
::-webkit-scrollbar-track{
background: #000;
}
::-webkit-scrollbar-thumb{
background-color: #444;
}
::-webkit-scrollbar-corner{
background: transparent;
}
button{
background-color: #333;
border: #777 outset 2px;
color: #eeeeee;
font-size: 16px;
font-family: 'Ubuntu', sans-serif;
cursor: pointer;
padding: 2px;
}
button:active{
background-color: #111;
}
button:hover{
background-color: #444;
}
button:focus{
background-color: #444;
outline: none;
}
#filepreview{
position: absolute;
display: inline-block;
@@ -147,7 +96,7 @@ button:focus{
#toolbar {
position: absolute;
width: 120px;
z-index: 12;
z-index: 52;
overflow: hidden;
float: left;
background-color: #000;
@@ -155,8 +104,9 @@ button:focus{
bottom: 0;
top: 0;
padding: 0;
text-align: center;
border-right: 2px ridge #9FCF6C;
text-align: left;
border-right: 2px ridge var(--highlight_color);
box-shadow: 2px 2px 8px #000000;
}
/* Workaround to hide the scrollbar in non webkit browsers, it's really ugly' */
@@ -177,19 +127,24 @@ button:focus{
height: auto;
}
.toolbar-button {
text-align: left;
width: 100%;
margin-bottom: 3px;
#button-expand-toolbar{
position: absolute;
visibility: hidden;
left: 0;
top: 0;
cursor: pointer;
z-index: 51;
}
.toolbar-button > img {
.toolbar_button{
text-align: left;
}
.toolbar_button > img {
width: 24px;
height: 24px;
}
.toolbar-button > span {
vertical-align: 5px;
.toolbar_button > span {
vertical-align: 6px;
}
#sponsors{
@@ -215,17 +170,13 @@ button:focus{
overflow-x: hidden;
float: left;
background-color: #000;
box-shadow: 2px 2px 8px #000000;
text-align: center;
border-right: 2px ridge #9FCF6C;
z-index: 11;
border-right: 2px ridge var(--highlight_color);
z-index: 50;
overflow: hidden;
}
.sharebar-button {
text-align: center;
width: 100%;
margin-bottom: 3px;
}
.sharebar-button {text-align: center;}
/* =====================
|| MISC COMPONENTS ||
@@ -242,7 +193,7 @@ button:focus{
overflow-y: scroll;
padding: 10px;
box-sizing: border-box;
text-align: left;
box-shadow: #eee 0px 0px 50px;
z-index: 100;
}
@@ -275,15 +226,6 @@ button:focus{
position: fixed;
}
.button-collapse{
width: 100px;
left: 0;
height: 12px;
position: relative;
display: block;
cursor: pointer;
}
.bytecounter{
color: #eeeeee;
font-size: 16px;

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ API Documentation</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/apidoc.css"/>
<link href='http://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ Error</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>

View File

@@ -5,8 +5,9 @@
<title>{{.Title}}</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/viewer.css"/>
<link rel="stylesheet" href="/res/style/season.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/listview.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link rel="shortcut icon" href="/res/img/tray32.png"/>
@@ -35,45 +36,42 @@
<body>
<div id="listNavigator">
<img src="/res/img/arrow-left.png" id="arrow-left" alt="Previous Item" onClick="ListNavigator.previousItem();" />
<img src="/res/img/arrow-right.png" id="arrow-right" alt="Next Item" onClick="ListNavigator.nextItem();" />
<div id="listNavigatorItems"></div>
<div id="arrow-left" alt="Previous Item" onClick="ListNavigator.previousItem();"></div>
<div id="arrow-right" alt="Next Item" onClick="ListNavigator.nextItem();"></div>
</div>
<button id="button-expand-toolbar" onClick="Toolbar.toggle();">Show Toolbar</button>
<div id="toolbar">
<!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers -->
<div>
<div>
<img id="button-expand-toolbar" src="/res/img/toolbar_show.png" alt="Expand Menu"
onClick="Toolbar.toggle();"
style="position: fixed; visibility:hidden; left: 0px; cursor: pointer" />
<button class="toolbar-button" onClick="Toolbar.toggle();">Hide Toolbar</button>
<button class="toolbar_button button_full_width" onClick="Toolbar.toggle();">Hide Toolbar</button>
<!--Views: <span id="views" th:text="${data.views}">0</span>--><br/>
<button id="btnDownload" class="toolbar-button" onClick="Toolbar.download();">
<img src="/res/img/floppy_small.png" alt="Download this file"/>
<span>Download</span>
</button>
<button id="btnCopy" class="toolbar-button" onClick="Toolbar.copyUrl();">
<img src="/res/img/clipboard_small.png" alt="Copy file URL to clipboard"/>
<span>Copy</span>
</button>
<button id="btnShare" onClick="Sharebar.toggle();" class="toolbar-button">
<img src="/res/img/share_small.png" alt="Share this file on social media"/>
<span>Share</span>
</button>
<form action="/" target="_blank">
<button id="btnHome" class="toolbar-button">
<form action="/" target="_self">
<button id="btnHome" class="toolbar_button button_full_width">
<img src="/res/img/pixeldrain_small.png" alt="Back to the Home page"/>
<span>Home</span>
</button>
</form>
<button id="btnDetails" class="toolbar-button" onClick="DetailsWindow.toggle();">
<button id="btnDownload" class="toolbar_button button_full_width" onClick="Toolbar.download();">
<img src="/res/img/floppy_small.png" alt="Download this file"/>
<span>Download</span>
</button>
<button id="btnCopy" class="toolbar_button button_full_width" onClick="Toolbar.copyUrl();">
<img src="/res/img/clipboard_small.png" alt="Copy file URL to clipboard"/>
<span>Copy</span>
</button>
<button id="btnShare" class="toolbar_button button_full_width" onClick="Sharebar.toggle();">
<img src="/res/img/share_small.png" alt="Share this file on social media"/>
<span>Share</span>
</button>
<button id="btnDetails" class="toolbar_button button_full_width" onClick="DetailsWindow.toggle();">
<img src="/res/img/info_small.png" alt="Help"/>
<span>Details</span>
</button>
@@ -91,39 +89,36 @@
</div>
<div id="sharebar" class="sidebar">
<img src="/res/img/arrows-collapse.png" alt="Slide Menu"
onClick="Sharebar.toggle();" class="button-collapse"/>
Share on:<br/>
<button class="sharebar-button" onclick="window.open('https://www.reddit.com/submit?url=' + window.location.href);">
<button class="sharebar-button button_full_width" onclick="window.open('https://www.reddit.com/submit?url=' + window.location.href);">
<img src="/res/img/social_reddit.png" alt="Share on Reddit" style="width:40px; height: 40px;"/>
<br/>Reddit
</button>
<button class="sharebar-button" onClick="window.open('https://voat.co/submit?linkpost=true&url=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('https://voat.co/submit?linkpost=true&url=' + window.location.href);">
<img src="/res/img/social_voat.png" alt="Share on Voat" style="width:40px; height: 40px;"/>
<br/>Voat
</button>
<button class="sharebar-button" onClick="window.open('http://www.facebook.com/sharer.php?u=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('http://www.facebook.com/sharer.php?u=' + window.location.href);">
<img src="/res/img/social_facebook.png" alt="Share on Facebook" style="width:40px; height: 40px;"/>
<br/>Facebook
</button>
<button class="sharebar-button" onClick="window.open('https://twitter.com/share?text=Check%20out%20this%20file%20on%20%23Pixeldrain&url=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('https://twitter.com/share?text=Check%20out%20this%20file%20on%20%23Pixeldrain&url=' + window.location.href);">
<img src="/res/img/social_twitter.png" alt="Share on Twitter" style="width:40px; height: 40px;"/>
<br/>Twitter
</button>
<button class="sharebar-button" onClick="window.open('https://plus.google.com/share?url=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('https://plus.google.com/share?url=' + window.location.href);">
<img src="/res/img/social_googleplus.png" alt="Share on Google Plus" style="width:40px; height: 40px;"/>
<br/>Google+
</button>
<button class="sharebar-button" onClick="window.open('http://www.tumblr.com/share/link?url=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('http://www.tumblr.com/share/link?url=' + window.location.href);">
<img src="/res/img/social_tumblr.png" alt="Share on Tumblr" style="width:40px; height: 40px;"/>
<br/>Tumblr
</button>
<button class="sharebar-button" onClick="window.open('http://www.stumbleupon.com/submit?url=' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('http://www.stumbleupon.com/submit?url=' + window.location.href);">
<img src="/res/img/social_stumbleupon.png" alt="Share on StumbleUpon" style="width:40px; height: 40px;"/>
<br/>StumbleUpon
</button>
<button class="sharebar-button" onClick="window.open('mailto:please@set.address?subject=File%20on%20PixelDrain&body=You%20can%20view%20it%20here%20' + window.location.href);">
<button class="sharebar-button button_full_width" onClick="window.open('mailto:please@set.address?subject=File%20on%20PixelDrain&body=You%20can%20view%20it%20here%20' + window.location.href);">
<img src="/res/img/social_email.png" alt="Share on E-Mail" style="width:40px; height: 40px;"/>
<br/>E-Mail
</button>
@@ -144,7 +139,7 @@
Loading...
</div>
<script src="/res/script/jquery-2.1.4.min.js"></script>
<script src="/res/script/jquery.js"></script>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>
<script src="/res/script/Keyboard.js"></script>
<script src="/res/script/Toolbar.js"></script>

View File

@@ -32,7 +32,6 @@
"file_name": "screenshot.png",
"date_upload": 1485894987, // Timestamp
"date_last_view": 1485894987, // Timestamp
"days_valid": 60, // Days of inactivity until it gets deleted
"file_size": 5694837, // Bytes
"views" 1234, // Amount of unique file views
"mime_type" "image/png",

View File

@@ -31,7 +31,6 @@
the end.
</p>
<pre>HTTP 200: OK
{
{
"success": true,
"id": "L8bhwx",
@@ -67,7 +66,6 @@
}
]
}
}
</pre>
<pre>HTTP 404: Not Found
{

View File

@@ -1,6 +1,6 @@
{{define "footer"}}
<br/>
<div class="highlight bg-dark border-top border-bottom">
<div class="highlight_dark border-top border-bottom">
Pixeldrain is a product by <a href="//fornaxian.com" target="_blank">Fornaxian Technologies</a>.
</div>
{{end}}

View File

@@ -1,5 +1,5 @@
{{define "menu"}}
<div class="highlight bg-light border-top border-bottom menu">
<div class="highlight_light border-top border-bottom menu">
<a href="/">Home</a> ~
<a href="/history">My&nbsp;Files</a> ~
<a href="/api">API&nbsp;Documentation</a>

View File

@@ -5,8 +5,8 @@
<title>Upload History ~ PixelDrain</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/season.css"/>
<link rel="stylesheet" href="/res/style/history.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
<link href="https://fonts.googleapis.com/css?family=Lato:100" rel="stylesheet" type="text/css"/>
@@ -17,7 +17,7 @@
{{template "bgpattern"}}
<script src="res/script/jquery-2.1.4.min.js"></script>
<script src="res/script/jquery.js"></script>
<script src="res/script/jquery-cookie.js"></script>
<link rel="stylesheet" href="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/themes/smoothness/jquery-ui.css"/>
<script src="https://ajax.googleapis.com/ajax/libs/jqueryui/1.11.4/jquery-ui.min.js"></script>

View File

@@ -5,6 +5,7 @@
<title>PixelDrain ~ Free file sharing service</title>
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/global.css"/>
<link rel="stylesheet" href="/res/style/home.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/history.css"/>
@@ -36,10 +37,10 @@
<img id="header-image" src="/res/img/header_blackchancery.png" alt="Header image"/>
<div id="body" class="body">
{{template "menu"}}
<div class="highlight bg-middle border-bottom">
<div class="highlight_middle border-bottom">
<input id="fileInputField" type="file" name="file" multiple='multiple'/>
<button id="selectFileButton" class="big-button">Upload Files</button>
<button id="textButton" class="big-button" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<button id="selectFileButton" class="big_button button_highlight">Upload Files</button>
<button id="textButton" class="big_button button_highlight" onClick="window.location.href = '/t/'">Upload Text</button><br/>
<div id="progress-bar" class="progress-bar">
<span class="progress-text"></span>
@@ -50,8 +51,8 @@
<div id="uploads-completed"></div>
</div>
<div class="highlight bg-dark border-bottom">
<a id="btnCreateList" href="#">Create list with uploaded files</a>
<div class="highlight_dark border-bottom">
<button id="btnCreateList">Create list with uploaded files</button>
</div>
<h1>Pixeldrain Public Beta<img src="/res/img/sia.png" style="height: 40px;"/></h1>
@@ -75,8 +76,8 @@
The upload restrictions that the main site has haven't been
implemented in this version yet, so you can upload as much as
you want. The server only has 256 GiB of space available, if it
runs out before the Sia integration is stable I won't hesitate
to wipe the database and start over.
starts running out os space files will be purged from the local
filesystem and served from Sia on the next request.
</p>
<h2>Legality</h2>
<p>
@@ -130,7 +131,6 @@
These will be added soon enough.
</p>
<ul>
<li>File lists</li>
<li>Zip explorer</li>
<li>Text file viewer (yes, you can upload text but not view it yet)</li>
<li>Some video formats (mime type detection is not complete)</li>

View File

@@ -6,6 +6,7 @@
<meta charset="UTF-8"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<link rel="stylesheet" href="/res/style/viewer.css"/>
<link rel="stylesheet" href="/res/style/layout.css"/>
<link rel="stylesheet" href="/res/style/season.css"/>
<link rel="stylesheet" href="/res/style/paste.css"/>
<link href='https://fonts.googleapis.com/css?family=Ubuntu' rel='stylesheet' type='text/css'/>
@@ -29,21 +30,18 @@
<body>
<div id="filepreview">
<textarea id="textarea"
class="textarea"
placeholder="Your text here..."
autofocus="autofocus"></textarea>
<textarea id="textarea" class="textarea" placeholder="Your text here..." autofocus="autofocus"></textarea>
</div>
<div id="toolbar">
<!-- Ugly workaround to get rid of the scrollbar in non-webkit browsers -->
<div>
<div>
<button class="toolbar-button" onClick="uploadText();">
<button class="toolbar_button button_full_width" onClick="uploadText();">
<img src="/res/img/upload_small.png" alt="Start Upload"/>
<span>Upload</span>
</button>
<form action="/">
<button class="toolbar-button">
<button class="toolbar_button button_full_width">
<img src="/res/img/pixeldrain_small.png" alt="Visit the home page" style="width:22px; height: 22px;"/>
<span>Home</span>
</button>

View File

@@ -2,16 +2,20 @@ package webcontroller
import (
"fmt"
"html"
"io"
"io/ioutil"
"net/http"
"net/url"
"path/filepath"
"strings"
"fornaxian.com/pixeldrain-api/log"
"fornaxian.com/pixeldrain-web/conf"
"fornaxian.com/pixeldrain-web/pixelapi"
"github.com/julienschmidt/httprouter"
"github.com/timakin/gonvert"
)
// ServeFilePreview controller for GET /u/:id/preview
@@ -51,6 +55,9 @@ func (f FilePreview) Run(inf *pixelapi.FileInfo) string {
if strings.HasPrefix(f.FileInfo.MimeType, "audio") {
return f.audio()
}
if strings.HasPrefix(f.FileInfo.MimeType, "text") {
return f.text()
}
switch f.FileInfo.MimeType {
case
@@ -121,6 +128,53 @@ func (f FilePreview) pdf() string {
return f.frame("/res/misc/pdf-viewer/web/viewer.html?file=" + u.String())
}
func (f FilePreview) text() string {
htmlOut := `<div class="text-container">
<pre class="pre-container %s" style="width: 100%%;">%s</pre>
</div>`
if f.FileInfo.FileSize > 1e6 { // Prevent out of memory errors
return fmt.Sprintf(htmlOut, "",
"File is too large to view online.\nPlease download and view it locally.",
)
}
body, err := pixelapi.GetFile(f.FileInfo.ID)
if err != nil {
log.Error("Can't download text file for preview: %s", err)
return fmt.Sprintf(htmlOut, "",
"An error occurred while downloading this file.",
)
}
defer body.Close()
bodyBytes, err := ioutil.ReadAll(body)
if err != nil {
log.Error("Can't read text file for preview: %s", err)
return fmt.Sprintf(htmlOut, "",
"An error occurred while reading this file.",
)
}
converter := gonvert.New(string(bodyBytes), gonvert.UTF8)
result, err := converter.Convert()
if err != nil {
log.Debug("Unable to decode text file: %s", err)
return fmt.Sprintf(htmlOut, "",
"This file is using an unknown character encoding.\nPlease download it and view it locally.",
)
}
result = html.EscapeString(result)
var prettyPrint string
if f.FileInfo.MimeType != "text/plain" {
prettyPrint = "prettyprint linenums"
htmlOut += `<script src="https://cdn.rawgit.com/google/code-prettify/master/loader/run_prettify.js?skin=desert"></script>`
}
return fmt.Sprintf(htmlOut, prettyPrint, result)
}
func (f FilePreview) frame(url string) string {
return fmt.Sprintf(`<iframe src="%s" class="image-container"
seamless="seamless" frameborder="0" allowtransparency="true"

37
webcontroller/style.go Normal file
View File

@@ -0,0 +1,37 @@
package webcontroller
import (
"fmt"
"net/http"
"strings"
"github.com/julienschmidt/httprouter"
)
func GlobalCSSHandler(w http.ResponseWriter, r *http.Request, _ httprouter.Params) {
w.Header().Add("COntent-Type", "text/css; charset=utf-8")
var textColor = "c0c0c0"
// Originals
var highlightColor = "9FCF6C"
var highlightColorDark = "5F7747"
// Purple scheme
// var highlightColor = "843384"
// var highlightColorDark = "672867"
var response = fmt.Sprintf(
`:root {
--text_color: #%s;
--highlight_color: #%s;
--highlight_color_dark: #%s;
}
`,
textColor,
highlightColor,
highlightColorDark,
)
strings.NewReader(response).WriteTo(w)
}