Refactor paste processing, UI and configuration

pull/20/head
Joe Biellik 5 years ago
parent 52adc1dd4a
commit f492b312db

@ -7,245 +7,235 @@
"random key here" "random key here"
], ],
"prettyHtml": true, "prettyHtml": true,
"cacheAge": 86400, "cacheAge": 2592000,
"sizeLimit": "2mb", "sizeLimit": "2mb",
"expiresDefault": 604800,
"expires": { "expires": {
"600": "10 minutes", "default": {
"3600": "1 hour", "value": 2,
"86400": "1 day", "multiplier": 604800
"604800": "1 week", },
"2592000": "1 month", "multipliers": {
"31536000 ": "1 year" "1": "second",
"60": "minute",
"3600": "hour",
"86400": "day",
"604800": "week",
"2592000": "month"
}
}, },
"highlights": { "highlights": {
"abap": "ABAP", "": {"name": "Plain text"},
"abnf": "Augmented BackusNaur form", "abap": {"name": "ABAP"},
"actionscript": "ActionScript", "abnf": {"name": "Augmented BackusNaur form"},
"ada": "Ada", "actionscript": {"name": "ActionScript"},
"al": "AL", "ada": {"name": "Ada"},
"antlr4": "ANTLR4", "antlr4": {"name": "ANTLR4", "alias": ["g4"]},
"apacheconf": "Apache Configuration", "apacheconf": {"name": "Apache Configuration"},
"apl": "APL", "apl": {"name": "APL"},
"applescript": "AppleScript", "applescript": {"name": "AppleScript"},
"aql": "AQL", "aql": {"name": "AQL"},
"arduino": "Arduino", "arduino": {"name": "Arduino"},
"arff": "ARFF", "arff": {"name": "ARFF"},
"asciidoc": "AsciiDoc", "asciidoc": {"name": "AsciiDoc", "alias": ["adoc"]},
"asm6502": "6502 Assembly", "asm6502": {"name": "6502 Assembly", "alias": ["asm"]},
"aspnet": "ASP.NET (C#)", "aspnet": {"name": "ASP.NET (C#)", "alias": ["dotnet"]},
"atom": "Atom", "autohotkey": {"name": "AutoHotkey"},
"autohotkey": "AutoHotkey", "autoit": {"name": "AutoIt"},
"autoit": "AutoIt", "bash": {"name": "Bash", "alias": ["shell"]},
"bash": "Bash", "basic": {"name": "BASIC"},
"basic": "BASIC", "batch": {"name": "Batch"},
"batch": "Batch", "bbcode": {"name": "BBcode", "alias": ["shortcode"]},
"bbcode": "BBcode", "bison": {"name": "Bison"},
"bison": "Bison", "bnf": {"name": "BackusNaur form", "alias": ["rbnf"]},
"bnf": "BackusNaur form", "brainfuck": {"name": "Brainfuck"},
"brainfuck": "Brainfuck", "brightscript": {"name": "BrightScript"},
"brightscript": "BrightScript", "bro": {"name": "Bro"},
"bro": "Bro", "c": {"name": "C"},
"c": "C", "cil": {"name": "CIL"},
"cil": "CIL", "clike": {"name": "C-like"},
"clike": "C-like", "clojure": {"name": "Clojure"},
"clojure": "Clojure", "cmake": {"name": "CMake"},
"cmake": "CMake", "coffeescript": {"name": "CoffeeScript", "alias": ["coffee"]},
"coffeescript": "CoffeeScript", "concurnas": {"name": "Concurnas", "alias": ["conc"]},
"concurnas": "Concurnas", "cpp": {"name": "C++", "alias": ["cpp"]},
"cpp": "C++", "crystal": {"name": "Crystal"},
"crystal": "Crystal", "csharp": {"name": "C#", "alias": ["cs", "dotnet", "csharp", ".net"]},
"csharp": "C#", "csp": {"name": "Content-Security-Policy", "alias": ["csp"]},
"csp": "Content-Security-Policy", "css": {"name": "CSS"},
"css-extras": "CSS Extras", "css-extras": {"name": "CSS Extras"},
"css": "CSS", "d": {"name": "D"},
"d": "D", "dart": {"name": "Dart"},
"dart": "Dart", "dax": {"name": "DAX"},
"dax": "DAX", "diff": {"name": "Diff"},
"diff": "Diff", "django": {"name": "Django/Jinja2", "alias": ["jinja2"]},
"django": "Django", "dns-zone-file": {"name": "DNS zone file", "alias": ["dns-zone", "bind", "named"]},
"dns-zone-file": "DNS zone file", "docker": {"name": "Docker", "alias": ["dockerfile"]},
"docker": "Docker", "ebnf": {"name": "Extended BackusNaur form"},
"ebnf": "Extended BackusNaur form", "eiffel": {"name": "Eiffel"},
"eiffel": "Eiffel", "ejs": {"name": "EJS"},
"ejs": "EJS", "elixir": {"name": "Elixir"},
"elixir": "Elixir", "elm": {"name": "Elm"},
"elm": "Elm", "erb": {"name": "ERB"},
"erb": "ERB", "erlang": {"name": "Erlang"},
"erlang": "Erlang", "etlua": {"name": "Embedded Lua templating"},
"etlua": "Embedded Lua templating", "excel-formula": {"name": "Excel Formula", "alias": ["xlsx", "xls"]},
"excel-formula": "Excel Formula", "factor": {"name": "Factor"},
"factor": "Factor", "firestore-security-rules": {"name": "Firestore security rules"},
"firestore-security-rules": "Firestore security rules", "flow": {"name": "Flow"},
"flow": "Flow", "fortran": {"name": "Fortran"},
"fortran": "Fortran", "fsharp": {"name": "F#"},
"fsharp": "F#", "ftl": {"name": "FreeMarker Template Language"},
"ftl": "FreeMarker Template Language", "gcode": {"name": "G-code"},
"gcode": "G-code", "gdscript": {"name": "GDScript"},
"gdscript": "GDScript", "gedcom": {"name": "GEDCOM"},
"gedcom": "GEDCOM", "gherkin": {"name": "Gherkin"},
"gherkin": "Gherkin", "git": {"name": "Git"},
"git": "Git", "glsl": {"name": "GLSL"},
"glsl": "GLSL", "gml": {"name": "GameMaker Language", "alias": ["gamemakerlanguage"]},
"gml": "GameMaker Language", "go": {"name": "Go"},
"go": "Go", "graphql": {"name": "GraphQL"},
"graphql": "GraphQL", "groovy": {"name": "Groovy"},
"groovy": "Groovy", "haml": {"name": "Haml"},
"haml": "Haml", "handlebars": {"name": "Handlebars"},
"handlebars": "Handlebars", "haskell": {"name": "Haskell", "alias": ["hs"]},
"haskell": "Haskell", "haxe": {"name": "Haxe"},
"haxe": "Haxe", "hcl": {"name": "HCL"},
"hcl": "HCL", "hpkp": {"name": "HTTP Public-Key-Pins", "alias": ["hpkp"]},
"hlsl": "HLSL", "hsts": {"name": "HTTP Strict-Transport-Security"},
"hpkp": "HTTP Public-Key-Pins", "html": {"name": "HTML"},
"hsts": "HTTP Strict-Transport-Security", "http": {"name": "HTTP"},
"html": "HTML", "ichigojam": {"name": "IchigoJam"},
"http": "HTTP", "icon": {"name": "Icon"},
"ichigojam": "IchigoJam", "inform7": {"name": "Inform 7"},
"icon": "Icon", "ini": {"name": "Ini"},
"iecst": "Structured Text (IEC 61131-3)", "io": {"name": "Io"},
"inform7": "Inform 7", "j": {"name": "J"},
"ini": "Ini", "java": {"name": "Java"},
"io": "Io", "javadoc": {"name": "JavaDoc"},
"j": "J", "javadoclike": {"name": "JavaDoc-like"},
"java": "Java", "javascript": {"name": "JavaScript", "alias": ["js"]},
"javadoc": "JavaDoc", "javastacktrace": {"name": "Java stack trace"},
"javadoclike": "JavaDoc-like", "jolie": {"name": "Jolie"},
"javascript": "JavaScript", "jq": {"name": "JQ"},
"javastacktrace": "Java stack trace", "js-extras": {"name": "JavaScript Extras"},
"jinja2": "Jinja2", "js-templates": {"name": "JavaScript Templates"},
"jolie": "Jolie", "jsdoc": {"name": "JSDoc"},
"jq": "JQ", "json": {"name": "JSON", "alias": ["javascript object notation"]},
"js-extras": "JS Extras", "json5": {"name": "JSON5", "alias": ["javascript object notation"]},
"js-templates": "JS Templates", "jsonp": {"name": "JSONP", "alias": ["javascript object notation"]},
"jsdoc": "JSDoc", "jsx": {"name": "React JSX"},
"json": "JSON", "julia": {"name": "Julia"},
"json5": "JSON5", "keyman": {"name": "Keyman"},
"jsonp": "JSONP", "kotlin": {"name": "Kotlin"},
"jsstacktrace": "JS stack trace", "latex": {"name": "LaTeX", "alias": ["tex", "context"]},
"jsx": "React JSX", "latte": {"name": "Latte"},
"julia": "Julia", "less": {"name": "Less"},
"keyman": "Keyman", "lilypond": {"name": "LilyPond", "alias": ["ly"]},
"kotlin": "Kotlin", "liquid": {"name": "Liquid"},
"latex": "LaTeX", "lisp": {"name": "Lisp", "alias": ["emacs", "elisp", "emacs-lisp"]},
"latte": "Latte", "livescript": {"name": "LiveScript"},
"less": "Less", "llvm": {"name": "LLVM IR"},
"lilypond": "LilyPond", "lolcode": {"name": "LOLCODE"},
"liquid": "Liquid", "lua": {"name": "Lua"},
"lisp": "Lisp", "makefile": {"name": "Makefile"},
"livescript": "LiveScript", "markdown": {"name": "Markdown", "alias": ["md"]},
"llvm": "LLVM IR", "markup-templating": {"name": "Markup templating"},
"lolcode": "LOLCODE", "mathml": {"name": "MathML"},
"lua": "Lua", "matlab": {"name": "MATLAB"},
"makefile": "Makefile", "mel": {"name": "MEL"},
"markdown": "Markdown", "mizar": {"name": "Mizar"},
"markup-templating": "Markup templating", "monkey": {"name": "Monkey"},
"mathml": "MathML", "moonscript": {"name": "MoonScript", "alias": ["moon"]},
"matlab": "MATLAB", "n1ql": {"name": "N1QL"},
"mel": "MEL", "n4js": {"name": "N4JS", "alias": ["n4jsd"]},
"mizar": "Mizar", "nand2tetris-hdl": {"name": "Nand To Tetris HDL"},
"monkey": "Monkey", "nasm": {"name": "NASM", "alias": ["assembly"]},
"moonscript": "MoonScript", "neon": {"name": "NEON"},
"n1ql": "N1QL", "nginx": {"name": "nginx"},
"n4js": "N4JS", "nim": {"name": "Nim"},
"nand2tetris-hdl": "Nand To Tetris HDL", "nix": {"name": "Nix"},
"nasm": "NASM", "nsis": {"name": "NSIS"},
"neon": "NEON", "objectivec": {"name": "Objective-C"},
"nginx": "nginx", "ocaml": {"name": "OCaml"},
"nim": "Nim", "opencl": {"name": "OpenCL"},
"nix": "Nix", "oz": {"name": "Oz"},
"nsis": "NSIS", "parigp": {"name": "PARI/GP"},
"objectivec": "Objective-C", "parser": {"name": "Parser"},
"ocaml": "OCaml", "pascal": {"name": "Pascal", "alias": ["objectpascal"]},
"opencl": "OpenCL", "pascaligo": {"name": "Pascaligo"},
"oz": "Oz", "pcaxis": {"name": "PC-Axis", "alias": ["px"]},
"parigp": "PARI/GP", "perl": {"name": "Perl"},
"parser": "Parser", "php": {"name": "PHP"},
"pascal": "Pascal", "php-extras": {"name": "PHP Extras"},
"pascaligo": "Pascaligo", "phpdoc": {"name": "PHPDoc"},
"pcaxis": "PC-Axis", "plsql": {"name": "PL/SQL"},
"peoplecode": "PeopleCode", "powerquery": {"name": "PowerQuery", "alias": ["pq", "mscript"]},
"perl": "Perl", "powershell": {"name": "PowerShell"},
"php-extras": "PHP Extras", "processing": {"name": "Processing"},
"php": "PHP", "prolog": {"name": "Prolog"},
"phpdoc": "PHPDoc", "properties": {"name": ".properties"},
"plain": "Plain text", "protobuf": {"name": "Protocol Buffers", "alias": ["protobuf"]},
"plsql": "PL/SQL", "pug": {"name": "Pug", "alias": ["jade"]},
"powerquery": "PowerQuery", "puppet": {"name": "Puppet"},
"powershell": "PowerShell", "pure": {"name": "Pure"},
"processing": "Processing", "python": {"name": "Python", "alias": ["py"]},
"prolog": "Prolog", "q": {"name": "Q (kdb+ database)"},
"properties": ".properties", "qml": {"name": "QML"},
"protobuf": "Protocol Buffers", "qore": {"name": "Qore"},
"pug": "Pug", "r": {"name": "R"},
"puppet": "Puppet", "reason": {"name": "Reason"},
"pure": "Pure", "regex": {"name": "Regex", "alias": ["regular expression"]},
"purebasic": "PureBasic", "renpy": {"name": "Ren'py"},
"python": "Python", "rest": {"name": "reST (reStructuredText)"},
"q": "Q (kdb+ database)", "rip": {"name": "Rip"},
"qml": "QML", "roboconf": {"name": "Roboconf"},
"qore": "Qore", "robotframework": {"name": "Robot Framework", "alias": ["robot"]},
"r": "R", "ruby": {"name": "Ruby", "alias": ["rb"]},
"racket": "Racket", "rust": {"name": "Rust"},
"reason": "Reason", "sas": {"name": "SAS"},
"regex": "Regex", "sass": {"name": "Sass (Sass)"},
"renpy": "Ren'py", "scala": {"name": "Scala"},
"rest": "reST (reStructuredText)", "scheme": {"name": "Scheme"},
"rip": "Rip", "scss": {"name": "Sass (Scss)"},
"roboconf": "Roboconf", "shell-session": {"name": "Shell session", "alias": ["terminal", "console"]},
"robotframework": "Robot Framework", "smalltalk": {"name": "Smalltalk"},
"rss": "RSS", "smarty": {"name": "Smarty"},
"ruby": "Ruby", "solidity": {"name": "Solidity (Ethereum)"},
"rust": "Rust", "solution-file": {"name": "Visual Studio Solution", "alias": ["sln", ".net", "dotnet"]},
"sas": "SAS", "soy": {"name": "Soy (Closure Template)"},
"sass": "Sass (Sass)", "sparql": {"name": "SPARQL", "alias": ["rq"]},
"scala": "Scala", "splunk-spl": {"name": "Splunk SPL"},
"scheme": "Scheme", "sqf": {"name": "SQF"},
"scss": "Sass (Scss)", "sql": {"name": "SQL"},
"shell-session": "Shell session", "stylus": {"name": "Stylus"},
"shell": "Shell", "svg": {"name": "SVG"},
"smalltalk": "Smalltalk", "swift": {"name": "Swift"},
"smarty": "Smarty", "t4-cs": {"name": "T4 Text Templates (C#)", "alias": ["t4"]},
"solidity": "Solidity (Ethereum)", "t4-templating": {"name": "T4 templating"},
"solution-file": "Solution file", "t4-vb": {"name": "T4 Text Templates (VB)"},
"soy": "Soy (Closure Template)", "tap": {"name": "TAP"},
"sparql": "SPARQL", "tcl": {"name": "Tcl"},
"splunk-spl": "Splunk SPL", "textile": {"name": "Textile"},
"sqf": "SQF", "toml": {"name": "TOML"},
"sql": "SQL", "tsx": {"name": "React TSX"},
"ssml": "SSML", "tt2": {"name": "Template Toolkit 2"},
"stylus": "Stylus", "turtle": {"name": "Turtle", "alias": ["trig"]},
"svg": "SVG", "twig": {"name": "Twig"},
"swift": "Swift", "typescript": {"name": "TypeScript", "alias": ["ts"]},
"t4-cs": "T4 Text Templates (C#)", "vala": {"name": "Vala"},
"t4-templating": "T4 templating", "vbnet": {"name": "Visual Basic .NET", "alias": ["vb", "dotnet"]},
"t4-vb": "T4 Text Templates (VB)", "velocity": {"name": "Velocity"},
"tap": "TAP", "verilog": {"name": "Verilog"},
"tcl": "Tcl", "vhdl": {"name": "VHDL"},
"textile": "Textile", "vim": {"name": "vim"},
"toml": "TOML", "visual-basic": {"name": "Visual Basic", "alias": ["vb"]},
"tsx": "React TSX", "wasm": {"name": "WebAssembly", "alias": ["wasm", "asm"]},
"tt2": "Template Toolkit 2", "wiki": {"name": "Wiki markup"},
"turtle": "Turtle", "xeora": {"name": "Xeora", "alias": ["xeoracube"]},
"twig": "Twig", "xml": {"name": "XML"},
"typescript": "TypeScript", "xojo": {"name": "Xojo (REALbasic)"},
"unrealscript": "UnrealScript", "xquery": {"name": "XQuery"},
"vala": "Vala", "yaml": {"name": "YAML", "alias": ["yml"]},
"vbnet": "VB.Net", "zig": {"name": "Zig"}
"velocity": "Velocity",
"verilog": "Verilog",
"vhdl": "VHDL",
"vim": "vim",
"visual-basic": "Visual Basic",
"warpscript": "WarpScript",
"wasm": "WebAssembly",
"wiki": "Wiki markup",
"xeora": "Xeora",
"xml-doc": "XML doc (.net)",
"xml": "XML",
"xojo": "Xojo (REALbasic)",
"xquery": "XQuery",
"yaml": "YAML",
"zig": "Zig"
} }
} }

@ -1,11 +1,12 @@
const config = require('config'); const config = require('config');
const fs = require('fs').promises;
const Paste = require('../models/paste'); const Paste = require('../models/paste');
module.exports = { module.exports = {
async view(ctx) { async view(ctx) {
try { try {
let paste = await Paste.findById(ctx.params.id).exec(); const paste = await Paste.findById(ctx.params.id).exec();
let lang = (Object.keys(ctx.query)[0] || '').toLowerCase(); const lang = (Object.keys(ctx.query)[0] || '').toLowerCase();
ctx.set('Cache-Control', 'public'); ctx.set('Cache-Control', 'public');
ctx.set('Expires', paste.expiresAt.toUTCString()); ctx.set('Expires', paste.expiresAt.toUTCString());
@ -18,7 +19,6 @@ module.exports = {
lang: Object.keys(config.highlights).includes(lang) ? lang : 'unknown' lang: Object.keys(config.highlights).includes(lang) ? lang : 'unknown'
}); });
} else { } else {
ctx.type = 'text/plain';
ctx.body = paste.paste; ctx.body = paste.paste;
} }
} catch (ex) { } catch (ex) {
@ -33,39 +33,106 @@ module.exports = {
async create(ctx) { async create(ctx) {
ctx.set('Cache-Control', 'no-cache'); ctx.set('Cache-Control', 'no-cache');
if (ctx.request.body.fields) { // Request body
if (ctx.request.body.fields.paste) { if (!ctx.request.body.paste && ctx.request.files) {
ctx.request.body.paste = ctx.request.body.fields.paste; try {
} // Request body, xxx
if (ctx.request.body.fields.highlight) { let path = Object.values(ctx.request.files)[0].path;
ctx.request.body.highlight = ctx.request.body.fields.highlight.toLowerCase();
// Request body, paste=xxx
if (ctx.request.files.paste) {
path = ctx.request.files.paste.path;
}
ctx.request.body.paste = await fs.readFile(path);
try {
await fs.unlink(path);
} catch (ex) {
// Ignore
}
} catch (ex) {
ctx.throw(400, 'Error Processing Request Body', {
headers: {
'Cache-Control': 'no-cache'
}
});
} }
if (ctx.request.body.fields.expire) { }
ctx.request.body.expire = ctx.request.body.fields.expire;
// Expiry multiplier
try {
if (ctx.request.body.expire && ctx.request.body.multiplier) {
ctx.request.body.expire = ctx.request.body.expire * ctx.request.body.multiplier;
} }
} catch (ex) {
ctx.throw(400, 'Error Processing Paste Expiry', {
headers: {
'Cache-Control': 'no-cache'
}
});
}
// Raw request body
if (typeof ctx.request.body === 'string') {
ctx.request.body = {
paste: ctx.request.body
};
}
if (!ctx.request.body.paste) {
ctx.throw(400, 'Error No Paste Provided', {
headers: {
'Cache-Control': 'no-cache'
}
});
} }
// /?expire=xxx
if (!ctx.request.body.expire && ctx.query.expire) {
ctx.request.body.expire = ctx.query.expire;
}
// No expire provided
if (!ctx.request.body.expire) { if (!ctx.request.body.expire) {
ctx.request.body.expire = config.expiresDefault; ctx.request.body.expire = config.expires.default.value * config.expires.default.multiplier;
} }
let paste = new Paste({ const paste = new Paste({
paste: ctx.request.body.paste, paste: ctx.request.body.paste,
expiresAt: new Date(Date.now() + ctx.request.body.expire * 1000) expiresAt: new Date(Date.now() + ctx.request.body.expire * 1000)
}); });
await paste.save(); try {
await paste.save();
} catch (ex) {
ctx.throw(500, 'Error Storing Paste', {
headers: {
'Cache-Control': 'no-cache'
}
});
}
// /?highlight=xxx
if (!ctx.request.body.highlight && ctx.query.highlight) {
ctx.request.body.highlight = ctx.query.highlight;
}
// /?xxx
if (!ctx.request.body.highlight && !ctx.query.highlight && ctx.query) {
ctx.request.body.highlight = Object.keys(ctx.query).filter(k => k != 'redirect' && k != 'expire')[0];
}
let link = paste.id; let highlight = '';
if (ctx.request.body.highlight && ctx.request.body.highlight != 'plain' && Object.keys(config.highlights).includes(ctx.request.body.highlight)) { if (ctx.request.body.highlight && Object.keys(config.highlights).includes(ctx.request.body.highlight)) {
link += '?' + ctx.request.body.highlight; highlight = '?' + ctx.request.body.highlight;
} }
if (Object.keys(ctx.query).includes('redirect')) { if (Object.keys(ctx.query).includes('redirect')) {
ctx.redirect(link); ctx.redirect(ctx.request.origin + '/' + paste.id + highlight);
} else { } else {
ctx.body = ctx.request.origin + '/' + link + '\n'; ctx.body = ctx.request.origin + '/' + paste.id + highlight + '\n';
} }
} }
}; };

@ -2,30 +2,63 @@
/* global $ autosize */ /* global $ autosize */
$(function() { $(function() {
if (localStorage.getItem('expire-value') != null) $('input#expire').val(localStorage.getItem('expire-value'));
if (localStorage.getItem('expire-multiplier') != null) $('#multiplier').val(localStorage.getItem('expire-multiplier'));
$.fn.selectpicker.Constructor.BootstrapVersion = '4'; $.fn.selectpicker.Constructor.BootstrapVersion = '4';
autosize($('textarea')); autosize($('textarea'));
$('select#highlight').removeClass('custom-select');
$('input#expire').removeClass('mr-3');
$('select#highlight').selectpicker(); $('select#highlight').selectpicker();
$('input#expire').TouchSpin({
min: 1,
max: 999,
buttondown_class: 'btn text-dark border-gray',
buttonup_class: 'btn text-dark border-gray'
});
$('textarea').on('keydown', function(e) { $('textarea').on('keydown', function(e) {
if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey && $(this).val()) { if ((e.keyCode == 10 || e.keyCode == 13) && e.ctrlKey && $(this).val()) {
$(this).closest('form').submit(); $(this).closest('form').submit();
} }
}); });
$('pre').on('click', function() { $('input#expire').on('change', function(e) {
var range = document.createRange(); var value = $(e.target).val();
$('#multiplier option').text(function(_, t) {
var plural = t.substring(t.length - 1) == 's';
range.setStart(this.firstChild, 19); if (value > 1) {
range.setEnd(this.firstChild, this.firstChild.textContent.length); if (!plural) {
return t + 's';
}
} else {
if (plural) {
return t.slice(0, -1);
}
}
window.getSelection().removeAllRanges(); return t;
window.getSelection().addRange(range); });
localStorage.setItem('expire-value', value);
});
$('#multiplier').on('change', function(e) {
localStorage.setItem('expire-multiplier', $(e.target).val());
}); });
$('select#highlight').on('change', function() { $('select#highlight').on('change', function() {
location.hash = $(this).val(); if ($(this).val() == '') {
history.pushState({}, '', '/');
} else {
location.hash = $(this).val();
}
}); });
$(window).on('hashchange', function() { $(window).on('hashchange', function() {
@ -39,4 +72,5 @@ $(function() {
}); });
$(window).trigger('hashchange'); $(window).trigger('hashchange');
$('input#expire').trigger('change');
}); });

@ -13,6 +13,7 @@ router
title: config.name, title: config.name,
url: ctx.request.origin, url: ctx.request.origin,
expires: config.expires, expires: config.expires,
expiresDefault: config.expiresDefault,
highlights: config.highlights highlights: config.highlights
}); });
}) })

@ -1,10 +1,9 @@
extends layout extends layout
block head block head
link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Open+Sans:400,300') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/themes/prism-coy.min.css' integrity='sha256-VcuSs+n31yebPlEcehu6PvnidJ808ScFBsK8+tJKX+Q=' crossorigin='anonymous')
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/themes/prism-coy.min.css', integrity='sha256-VcuSs+n31yebPlEcehu6PvnidJ808ScFBsK8+tJKX+Q=', crossorigin='anonymous') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/toolbar/prism-toolbar.min.css' integrity='sha256-P45OhhEWm49G8sadt2n5rDaWLa3xZbDOQhJliuaojH0=' crossorigin='anonymous')
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/toolbar/prism-toolbar.min.css', integrity='sha256-P45OhhEWm49G8sadt2n5rDaWLa3xZbDOQhJliuaojH0=', crossorigin='anonymous') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/line-numbers/prism-line-numbers.min.css' integrity='sha256-Afz2ZJtXw+OuaPX10lZHY7fN1+FuTE/KdCs+j7WZTGc=' crossorigin='anonymous')
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/line-numbers/prism-line-numbers.min.css', integrity='sha256-Afz2ZJtXw+OuaPX10lZHY7fN1+FuTE/KdCs+j7WZTGc=', crossorigin='anonymous')
style. style.
html, body, .code-toolbar, pre, code { html, body, .code-toolbar, pre, code {
@ -19,10 +18,6 @@ block head
pre[class*="language-"] > code { pre[class*="language-"] > code {
border-left: none; border-left: none;
} }
.line-numbers-rows {
-webkit-user-select: none;
user-select: none;
}
div.code-toolbar > .toolbar { div.code-toolbar > .toolbar {
top: 1rem; top: 1rem;
right: 2.5rem; right: 2.5rem;
@ -44,7 +39,7 @@ block head
display: inline-block; display: inline-block;
font-weight: 400; font-weight: 400;
transition: color 0.15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out; transition: color 0.15s ease-in-out,background-color .15s ease-in-out,border-color .15s ease-in-out,box-shadow .15s ease-in-out;
font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
border: 1px solid transparent; border: 1px solid transparent;
} }
div.code-toolbar > .toolbar a:focus, div.code-toolbar > .toolbar a:hover, div.code-toolbar > .toolbar button:focus, div.code-toolbar > .toolbar button:hover, div.code-toolbar > .toolbar span:focus, div.code-toolbar > .toolbar span:hover { div.code-toolbar > .toolbar a:focus, div.code-toolbar > .toolbar a:hover, div.code-toolbar > .toolbar button:focus, div.code-toolbar > .toolbar button:hover, div.code-toolbar > .toolbar span:focus, div.code-toolbar > .toolbar span:hover {
@ -58,9 +53,9 @@ block content
code(class='language-' + lang) code(class='language-' + lang)
| #{paste} | #{paste}
script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/prism.min.js', integrity='sha256-3teItwIfMuVB74Alnxw/y5HAZ2irOsCULFff3EgbtEs=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/prism.min.js' integrity='sha256-3teItwIfMuVB74Alnxw/y5HAZ2irOsCULFff3EgbtEs=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/components/prism-' + lang + '.min.js') script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/components/prism-' + lang + '.min.js')
script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/toolbar/prism-toolbar.min.js', integrity='sha256-7I/IdbPM17QdjqRNwpVYj4iDGAQw7ZFHy9RSSU1yvLE=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/toolbar/prism-toolbar.min.js' integrity='sha256-7I/IdbPM17QdjqRNwpVYj4iDGAQw7ZFHy9RSSU1yvLE=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/line-numbers/prism-line-numbers.min.js', integrity='sha256-hep5s8952MqR7Y79JYfCXZD6vQjVHs7sOu/ZGrs1OEQ=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/line-numbers/prism-line-numbers.min.js' integrity='sha256-hep5s8952MqR7Y79JYfCXZD6vQjVHs7sOu/ZGrs1OEQ=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js', integrity='sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/2.0.6/clipboard.min.js' integrity='sha256-inc5kl9MA1hkeYUt+EC3BhlIgyp/2jDIyBLS6k3UxPI=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js', integrity='sha256-5F8rynXScCOEtnwlm5P293TlCvTT1beoEJcmWHCg4BU=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/prism/1.20.0/plugins/copy-to-clipboard/prism-copy-to-clipboard.min.js' integrity='sha256-5F8rynXScCOEtnwlm5P293TlCvTT1beoEJcmWHCg4BU=' crossorigin='anonymous')

@ -1,18 +1,15 @@
extends layout extends layout
block head block head
link(rel='stylesheet', href='https://fonts.googleapis.com/css?family=Open+Sans:400,300') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/css/bootstrap-select.min.css' integrity='sha256-wiMI7buOV5UBzdWN4s4kXqE/LZ794hx5oJOOIQlDBaM=' crossorigin='anonymous')
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.17/css/bootstrap-select.min.css', integrity='sha256-VMPhaMmJn7coDSbzwqB0jflvb+CDnoAlfStC5RogOQo=', crossorigin='anonymous') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-touchspin/4.3.0/jquery.bootstrap-touchspin.min.css' integrity='sha256-lo84g8NnZnmj6M802u7YMGf8mMuoQYV4xKEIb2DrRnk=' crossorigin='anonymous')
style. style.
html { html {
position: relative; position: relative;
min-height: 100%; min-height: 100%;
} }
body { body {
margin-bottom: 4rem; font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, "Noto Sans", sans-serif, "Apple Color Emoji", "Segoe UI Emoji", "Segoe UI Symbol", "Noto Color Emoji";
}
body, button, input, optgroup, select, textarea {
font-family: "Open Sans", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif;
} }
@media (min-width: 1800px) { @media (min-width: 1800px) {
.container { .container {
@ -24,58 +21,104 @@ block head
min-width: 1800px; min-width: 1800px;
} }
} }
@media (min-width: 2800px) {
.container {
min-width: 80%;
}
}
.display-3 { .display-3 {
font-size: 5.5rem; font-size: 5.5rem;
} }
textarea, textarea:required, textarea:invalid { @media (max-width: 575.98px) {
font-family: monospace, serif; .display-3 {
line-height: 1.5em; font-size: 4rem;
}
}
textarea {
font-family: Consolas, Monaco, 'Andale Mono', 'Ubuntu Mono', monospace;
line-height: 1.5rem;
box-shadow: none; box-shadow: none;
} }
label {
width: 7.5rem;
font-size: 1.2rem;
}
.border-gray { .border-gray {
border: 1px solid #ced4da; border: 1px solid #ced4da;
} }
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 18rem;
}
@media (max-width: 318px) {
.bootstrap-select:not([class*="col-"]):not([class*="form-control"]):not(.input-group-btn) {
width: 100%;
}
}
#highlight {
max-width: 18rem;
}
#expire {
max-width: 7.5rem;
}
.bootstrap-touchspin {
max-width: 7.5rem;
float: left;
margin-right: 1rem;
margin-bottom: 1rem;
}
#multiplier {
max-width: 9.5rem;
}
button.btn-lg {
font-size: 1.5rem;
}
@media (min-width: 768px) {
button.btn-lg {
margin-top: -6rem;
}
}
footer { footer {
width: 100%;
height: 2.5rem; height: 2.5rem;
position: absolute;
bottom: 0; bottom: 0;
line-height: 2rem; line-height: 2rem;
} }
block content block content
a(href='https://github.com/JoeBiellik/paste', style='position: absolute; top: 0; right: 0; border: 0;') a.position-absolute.dropdown-menu-right.d-none.d-sm-block(href='https://github.com/JoeBiellik/paste')
img(src='https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png', alt='Fork me on GitHub') img(src='https://s3.amazonaws.com/github/ribbons/forkme_right_gray_6d6d6d.png' alt='Fork me on GitHub')
main.container.pt-5.mx-6 main.container.py-3.pt-sm-5.pb-md-5
h1.display-3.mb-5 #{title} h1.display-3 #{title}
form(action='/?redirect', method='POST', accept-charset='UTF-8') form(action='/?redirect' method='POST' accept-charset='UTF-8')
fieldset.form-group label.sr-only(for="paste") Paste content
textarea.form-control(name='paste', rows='10', required, autofocus) textarea#paste.my-3.my-sm-5.form-control(name='paste' rows='10' required autofocus)
div.row.mt-4 .row
div.col-md-auto.col-sm-12 .col-12.col-md-9.mb-3.mb-sm-4.clearfix
select#highlight.mt-3(name='highlight', data-live-search='true', data-width='auto', data-style='text-dark border-gray', data-styleBase='custom-select') label.d-block.float-sm-left(for="highlight") Highlight
option(value='', selected) Choose syntax highlighting select#highlight.custom-select.float-sm-left(name='highlight' data-live-search='true' data-style='text-dark border-gray' data-styleBase='custom-select')
each val, key in highlights each val, key in highlights
option(value=key) #{val} option(value=key data-tokens=(val.alias || []).join(' ') || false) #{val.name}
div.col-md-auto.col-sm-12 .col-md-9.col-sm-12.mb-3.clearfix
select#expire.custom-select.mt-3(name='expire') label.d-block.float-sm-left(for="expire") Expiry
option(value='', selected) Choose expiry input#expire.mr-3.form-control.text-center.float-sm-left(name='expire' type='text' value=expires.default.value required)
each val, key in expires label.sr-only(for="multiplier") Expiry multiplier
option(value=key) #{val} select#multiplier.custom-select.float-sm-left(name='multiplier' required)
each val, key in expires.multipliers
option(value=key selected=key == expires.default.multiplier) #{val}
div.col.text-md-right .col-12.col-md-3.mb-3.text-md-right
button.btn.btn-primary.btn-lg.mt-3(type='submit') Upload button.btn.btn-primary.btn-lg(type='submit') Upload
footer.hidden-sm-down footer.w-100.position-absolute.d-none.d-md-block
pre.text-center.text-muted.mb-0. pre.text-center.text-muted.mb-0 echo 'Hello World'
echo 'Hello World' | curl -F 'paste=<-' #{url} span.user-select-all | curl -F 'paste=<-' #{url}
script(src='https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js' integrity='sha256-dW8u4dvEKDThJpWRwLgGugbARnA3O2wqBcVerlg9LMc=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/autosize.js/4.0.2/autosize.min.js' integrity='sha256-dW8u4dvEKDThJpWRwLgGugbARnA3O2wqBcVerlg9LMc=' crossorigin='anonymous')
script(src='https://code.jquery.com/jquery-3.5.1.min.js', integrity='sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=', crossorigin='anonymous') script(src='https://code.jquery.com/jquery-3.5.1.min.js' integrity='sha256-9/aliU8dGd2tb6OSsuzixeV4y/faTqgFtohetphbbj0=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.bundle.min.js', integrity='sha256-Xt8pc4G0CdcRvI0nZ2lRpZ4VHng0EoUDMlGcBSQ9HiQ=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/js/bootstrap.bundle.min.js' integrity='sha256-Xt8pc4G0CdcRvI0nZ2lRpZ4VHng0EoUDMlGcBSQ9HiQ=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.17/js/bootstrap-select.min.js', integrity='sha256-QOE02Glo1C1gHzP96JOaxyIMt4XSFv/exZaYLY4dwO0=', crossorigin='anonymous') script(src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-select/1.13.18/js/bootstrap-select.min.js' integrity='sha256-qo0Cam4XJ0QQ06XnCiCFYBh3GDXU45j3lpUp+em2yBU=' crossorigin='anonymous')
script(src='https://cdnjs.cloudflare.com/ajax/libs/bootstrap-touchspin/4.3.0/jquery.bootstrap-touchspin.min.js' integrity='sha256-i215zpldm5iRs4r/PqXbdfyahPFuW/gtPECq5Dn3gSc=' crossorigin='anonymous')
script(src='/main.js') script(src='/main.js')

@ -2,9 +2,10 @@ doctype html
html(lang='en') html(lang='en')
head head
meta(charset='utf-8') meta(charset='utf-8')
meta(name='viewport', content='width=device-width, initial-scale=1, shrink-to-fit=no') meta(name='viewport' content='width=device-width, initial-scale=1, shrink-to-fit=no')
title #{title} title #{title}
link(rel='stylesheet', href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css', integrity='sha256-aAr2Zpq8MZ+YA/D6JtRD3xtrwpEz2IqOS+pWD/7XKIw=', crossorigin='anonymous') link(rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css' integrity='sha256-aAr2Zpq8MZ+YA/D6JtRD3xtrwpEz2IqOS+pWD/7XKIw=' crossorigin='anonymous')
link(rel='stylesheet' href='https://fonts.googleapis.com/css?family=Open+Sans:400,300')
block head block head

Loading…
Cancel
Save