mirror of
https://github.com/Tygs/0bin.git
synced 2023-08-10 21:13:00 +03:00
merge
This commit is contained in:
commit
5f9427be43
1
.gitignore
vendored
1
.gitignore
vendored
@ -28,3 +28,4 @@ dist
|
|||||||
content
|
content
|
||||||
*.sublime-project
|
*.sublime-project
|
||||||
*.sublime-workspace
|
*.sublime-workspace
|
||||||
|
settings_local.py
|
||||||
|
@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: ai ts=4 sts=4 et sw=4
|
||||||
|
|
||||||
|
VERSION = __version__ = "0.1"
|
32
settings.py
32
settings.py
@ -1,17 +1,14 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
import os
|
# import default settings value from src/default_settings.py
|
||||||
import math
|
# you can refer to this file if you forgot what
|
||||||
ROOT_DIR = os.path.dirname(os.path.abspath(__file__))
|
# settings is for and what it is set to by default
|
||||||
STATIC_FILES_ROOT = os.path.join(ROOT_DIR, 'static')
|
# DO NOT ALTER THIS LINE
|
||||||
|
from src.default_settings import *
|
||||||
#####################################################
|
|
||||||
# You can start editing settings after this comment #
|
|
||||||
#####################################################
|
|
||||||
|
|
||||||
# debug will get you error message and auto reload
|
# debug will get you error message and auto reload
|
||||||
# don't set this to True in production
|
# don't set this to True in production
|
||||||
DEBUG = True
|
DEBUG = False
|
||||||
|
|
||||||
# absolute path where the paste files should be store
|
# absolute path where the paste files should be store
|
||||||
# default in projectdirectory/static/content/
|
# default in projectdirectory/static/content/
|
||||||
@ -19,19 +16,28 @@ DEBUG = True
|
|||||||
PASTE_FILES_ROOT = os.path.join(STATIC_FILES_ROOT, 'content')
|
PASTE_FILES_ROOT = os.path.join(STATIC_FILES_ROOT, 'content')
|
||||||
|
|
||||||
# Port and host the embeded python server should be using
|
# Port and host the embeded python server should be using
|
||||||
|
# You can also specify them using the --host and --port script options
|
||||||
|
# which have priority on these settings
|
||||||
HOST = "127.0.0.1"
|
HOST = "127.0.0.1"
|
||||||
PORT= "8000"
|
PORT= "8000"
|
||||||
|
|
||||||
# User and group the server should run as. Set to None if it should be the
|
# User and group the server should run as. Set to None if it should be the
|
||||||
# current user
|
# current user. Some OS don't support it and if so, it will be ignored.
|
||||||
USER = None
|
USER = None
|
||||||
GROUP = None
|
GROUP = None
|
||||||
|
|
||||||
# limit size of pasted text in bytes. Be carefull allowing too much size can slow down user's
|
# limit size of pasted text in bytes. Be carefull allowing too much
|
||||||
# browser
|
# size can slow down user's browser
|
||||||
MAX_SIZE = 1024 * 500
|
MAX_SIZE = 1024 * 500
|
||||||
MAX_SIZE_KB = int(math.ceil(MAX_SIZE / 1024.0))
|
MAX_SIZE_KB = int(math.ceil(MAX_SIZE / 1024.0))
|
||||||
|
|
||||||
|
|
||||||
# Email for contact
|
# Email for contact
|
||||||
EMAIL = "your@email.com"
|
EMAIL = "your@email.com"
|
||||||
|
|
||||||
|
# this import a file named settings_local.py if it exists
|
||||||
|
# you may want to create such a file to have different settings
|
||||||
|
# on each machine
|
||||||
|
try:
|
||||||
|
from settings_local import *
|
||||||
|
except ImportError:
|
||||||
|
pass
|
||||||
|
@ -1,13 +1,3 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
"""
|
|
||||||
General configuration and imports gathering.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import os
|
|
||||||
import sys
|
|
||||||
|
|
||||||
import settings
|
|
||||||
from paste import Paste
|
|
||||||
from utils import drop_privileges, dmerge
|
|
||||||
|
|
||||||
|
35
src/default_settings.py
Normal file
35
src/default_settings.py
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: ai ts=4 sts=4 et sw=4
|
||||||
|
|
||||||
|
import os
|
||||||
|
import math
|
||||||
|
|
||||||
|
ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||||||
|
STATIC_FILES_ROOT = os.path.join(ROOT_DIR, 'static')
|
||||||
|
|
||||||
|
# debug will get you error message and auto reload
|
||||||
|
# don't set this to True in production
|
||||||
|
DEBUG = False
|
||||||
|
|
||||||
|
# absolute path where the paste files should be store
|
||||||
|
# default in projectdirectory/static/content/
|
||||||
|
# use "/" even under Windows
|
||||||
|
PASTE_FILES_ROOT = os.path.join(STATIC_FILES_ROOT, 'content')
|
||||||
|
|
||||||
|
# Port and host the embeded python server should be using
|
||||||
|
# You can also specify them using the --host and --port script options
|
||||||
|
# which have priority on these settings
|
||||||
|
HOST = "127.0.0.1"
|
||||||
|
PORT= "8000"
|
||||||
|
|
||||||
|
# User and group the server should run as. Set to None if it should be the
|
||||||
|
# current user. Some OS don't support it and if so, it will be ignored.
|
||||||
|
USER = None
|
||||||
|
GROUP = None
|
||||||
|
|
||||||
|
# limit size of pasted text in bytes. Be carefull allowing too much size can slow down user's
|
||||||
|
# browser
|
||||||
|
MAX_SIZE = 1024 * 500
|
||||||
|
MAX_SIZE_KB = int(math.ceil(MAX_SIZE / 1024.0))
|
||||||
|
|
12
start.py
12
start.py
@ -1,4 +1,6 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
# vim: ai ts=4 sts=4 et sw=4
|
||||||
|
|
||||||
"""
|
"""
|
||||||
Main script including controller, rooting, dependancy management, and
|
Main script including controller, rooting, dependancy management, and
|
||||||
@ -13,6 +15,8 @@ import math
|
|||||||
|
|
||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
|
|
||||||
|
# add project dir and libs dir to the PYTHON PATH to ensure they are
|
||||||
|
# importable
|
||||||
import settings
|
import settings
|
||||||
sys.path.insert(0, os.path.dirname(settings.ROOT_DIR))
|
sys.path.insert(0, os.path.dirname(settings.ROOT_DIR))
|
||||||
sys.path.append(os.path.join(settings.ROOT_DIR, 'libs'))
|
sys.path.append(os.path.join(settings.ROOT_DIR, 'libs'))
|
||||||
@ -23,7 +27,10 @@ from bottle import (Bottle, route, run, abort, error,
|
|||||||
|
|
||||||
import clize
|
import clize
|
||||||
|
|
||||||
from src import settings, Paste, drop_privileges, dmerge
|
|
||||||
|
from src.paste import Paste
|
||||||
|
from src.utils import drop_privileges, dmerge
|
||||||
|
|
||||||
|
|
||||||
app = Bottle()
|
app = Bottle()
|
||||||
|
|
||||||
@ -31,7 +38,6 @@ global_vars = {
|
|||||||
'settings' : settings
|
'settings' : settings
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@app.route('/')
|
@app.route('/')
|
||||||
@view('home')
|
@view('home')
|
||||||
def index():
|
def index():
|
||||||
@ -98,10 +104,8 @@ def display_paste(paste_id):
|
|||||||
return error404(ValueError)
|
return error404(ValueError)
|
||||||
|
|
||||||
context = {'paste': paste, 'keep_alive': keep_alive}
|
context = {'paste': paste, 'keep_alive': keep_alive}
|
||||||
|
|
||||||
return dmerge(context, global_vars)
|
return dmerge(context, global_vars)
|
||||||
|
|
||||||
|
|
||||||
@app.error(404)
|
@app.error(404)
|
||||||
@view('404')
|
@view('404')
|
||||||
def error404(code):
|
def error404(code):
|
||||||
|
@ -119,12 +119,21 @@ h4#pixels-total {
|
|||||||
float:left;
|
float:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
.file-upload {
|
html.file-upload p.file-upload {
|
||||||
float: left;
|
float: left;
|
||||||
margin: 22px 0px 0px 21px;
|
margin: 22px 0px 0px 21px;
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
html.file-upload p.file-upload {
|
||||||
|
display:inherit;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.no-file-upload p.file-upload {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
input.btn-upload {
|
input.btn-upload {
|
||||||
position: relative;
|
position: relative;
|
||||||
left: -6px;
|
left: -6px;
|
||||||
@ -147,14 +156,19 @@ input.hide-upload {
|
|||||||
height: 49px;
|
height: 49px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Paste Page */
|
|
||||||
|
|
||||||
.items {
|
/* Paste Page */
|
||||||
text-align: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
#paste-content {
|
#paste-content {
|
||||||
background-color: white;
|
background-color: white;
|
||||||
|
padding:1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#paste-content.done {
|
||||||
|
background-color: white;
|
||||||
|
padding-top:1em;
|
||||||
|
padding-left:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.submit-form {
|
.submit-form {
|
||||||
@ -177,7 +191,7 @@ li.L5, li.L6, li.L7, li.L8, li.L9
|
|||||||
background: inherit;
|
background: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.margin-color {
|
.prettyprint.linenums {
|
||||||
-webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
-webkit-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||||
-moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
-moz-box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||||
box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
box-shadow: inset 40px 0 0 #fbfbfc, inset 41px 0 0 #ececf0;
|
||||||
@ -254,7 +268,7 @@ button.btn, input[type="submit"].btn {
|
|||||||
margin-left: 5px;
|
margin-left: 5px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.btn-primary {
|
.btn-primary, .btn-danger {
|
||||||
position:relative;
|
position:relative;
|
||||||
top:-4px;
|
top:-4px;
|
||||||
}
|
}
|
||||||
@ -275,3 +289,36 @@ button.btn, input[type="submit"].btn {
|
|||||||
text-align:left;
|
text-align:left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.lnk-option canvas {
|
||||||
|
vertical-align:middle;
|
||||||
|
margin-right:10px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Previous paste list */
|
||||||
|
|
||||||
|
.previous-pastes .item {
|
||||||
|
margin-top:5px;
|
||||||
|
vertical-align:middle;
|
||||||
|
line-height:24px;
|
||||||
|
padding-left:1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.previous-pastes canvas {
|
||||||
|
display:block;
|
||||||
|
float:left;
|
||||||
|
margin-right:5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.local-storage .no-local-storage {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
html.no-local-storage .local-storage {
|
||||||
|
display:none;
|
||||||
|
}
|
||||||
|
|
||||||
|
canvas {
|
||||||
|
border: 1px solid white;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -5,11 +5,35 @@ sjcl.random.startCollectors();
|
|||||||
/* Ensure jquery use cache for ajax requests */
|
/* Ensure jquery use cache for ajax requests */
|
||||||
$.ajaxSetup({ cache: true });
|
$.ajaxSetup({ cache: true });
|
||||||
|
|
||||||
|
/** Create a function that create inline callbacks.
|
||||||
|
We use it to create callbacks for onliners with static arguments
|
||||||
|
E.G:
|
||||||
|
$('stuff').hide(function()(console.log(1, 2, 3)))
|
||||||
|
|
||||||
|
Becomes:
|
||||||
|
|
||||||
|
$('stuff').hide(mkcb(console.log, 1, 2, 3))
|
||||||
|
*/
|
||||||
|
function mkcb(func){
|
||||||
|
var args = arguments;
|
||||||
|
return function(){
|
||||||
|
return func.apply(func, Array.prototype.slice.call(args, 1))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
**** 0bin utilities ***
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
|
||||||
zerobin = {
|
zerobin = {
|
||||||
/** Base64 + compress + encrypt, with callbacks before each operation,
|
/** Base64 + compress + encrypt, with callbacks before each operation,
|
||||||
and all of them are executed in a timed continuation to give
|
and all of them are executed in a timed continuation to give
|
||||||
a change to the UI to respond.
|
a change to the UI to respond.
|
||||||
*/
|
*/
|
||||||
|
version: '0.1',
|
||||||
encrypt: function(key, content, toBase64Callback,
|
encrypt: function(key, content, toBase64Callback,
|
||||||
compressCallback, encryptCallback, doneCallback) {
|
compressCallback, encryptCallback, doneCallback) {
|
||||||
|
|
||||||
@ -112,20 +136,21 @@ zerobin = {
|
|||||||
return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
|
return sjcl.codec.base64.fromBits(sjcl.random.randomWords(8, 0), 0);
|
||||||
},
|
},
|
||||||
|
|
||||||
getDate: function(){
|
getFormatedDate: function(date){
|
||||||
var date = new Date();
|
var date = date || new Date();
|
||||||
return date.getDate()+"-"+(date.getMonth()+1)+"-"+date.getFullYear();
|
return ((date.getMonth() +1 ) + '-' +
|
||||||
|
date.getDate() + '-' + date.getFullYear());
|
||||||
},
|
},
|
||||||
|
|
||||||
getTime: function(){
|
getFormatedTime: function(date){
|
||||||
var date = new Date();
|
var date = date || new Date();
|
||||||
var h=date.getHours();
|
var h = date.getHours();
|
||||||
var m=date.getMinutes();
|
var m = date.getMinutes();
|
||||||
var s=date.getSeconds();
|
var s = date.getSeconds();
|
||||||
if (h<10) {h = "0" + h}
|
if (h < 10) {h = "0" + h}
|
||||||
if (m<10) {m = "0" + m}
|
if (m < 10) {m = "0" + m}
|
||||||
if (s<10) {s = "0" + s}
|
if (s < 10) {s = "0" + s}
|
||||||
return h+":"+m+":"+s;
|
return h + ":" + m + ":" + s;
|
||||||
},
|
},
|
||||||
|
|
||||||
numOrdA: function(a, b){
|
numOrdA: function(a, b){
|
||||||
@ -133,8 +158,8 @@ zerobin = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
getKeys: function(){
|
getKeys: function(){
|
||||||
var keys = new Array();
|
var keys = [];
|
||||||
for(i=0; i<=localStorage.length; i++){
|
for(i=0; i <= localStorage.length; i++){
|
||||||
if(localStorage.key(i) != null)
|
if(localStorage.key(i) != null)
|
||||||
keys[i] = parseInt(localStorage.key(i),10);
|
keys[i] = parseInt(localStorage.key(i),10);
|
||||||
}
|
}
|
||||||
@ -148,64 +173,89 @@ zerobin = {
|
|||||||
});
|
});
|
||||||
},
|
},
|
||||||
|
|
||||||
|
/** Check for browser support of the named featured. Store the result
|
||||||
|
and add a class to the html tag with the result */
|
||||||
support: {
|
support: {
|
||||||
localstorage: function(){
|
localStorage: (function(){
|
||||||
return !!(localStorage);
|
var val = !!(localStorage);
|
||||||
},
|
$('html').addClass((val ? '' : 'no-') + 'local-storage');
|
||||||
history: function(){
|
return val;
|
||||||
return !!(window.history && history.pushState);
|
})(),
|
||||||
}
|
|
||||||
|
history: (function(){
|
||||||
|
var val = !!(window.history && history.pushState);
|
||||||
|
$('html').addClass((val ? '' : 'no-') + 'history');
|
||||||
|
return val;
|
||||||
|
})(),
|
||||||
|
|
||||||
|
fileUpload: (function(){
|
||||||
|
var w = window;
|
||||||
|
var val = !!(w.File && w.FileReader && w.FileList && w.Blob);
|
||||||
|
$('html').addClass((val ? '' : 'no-') + 'file-upload');
|
||||||
|
return val;
|
||||||
|
})(),
|
||||||
},
|
},
|
||||||
|
|
||||||
storatePaste: function(url){
|
storatePaste: function(url){
|
||||||
if (zerobin.support.localstorage){
|
if (zerobin.support.localStorage){
|
||||||
var date = new Date();
|
var paste = (zerobin.getFormatedDate() + " " +
|
||||||
var paste = zerobin.getDate()+" "+zerobin.getTime()+";"+url;
|
zerobin.getFormatedTime() + ";" + url);
|
||||||
var keys = zerobin.getKeys();
|
var keys = zerobin.getKeys();
|
||||||
|
|
||||||
if(keys.length < 1)
|
if(keys.length < 1){keys[0] = 0}
|
||||||
keys[0] = 0;
|
|
||||||
|
|
||||||
if (localStorage.length > 19)
|
if (localStorage.length > 19) {
|
||||||
void localStorage.removeItem(keys[0]);
|
void localStorage.removeItem(keys[0]);
|
||||||
|
}
|
||||||
|
|
||||||
localStorage.setItem(keys.reverse()[0]+1, paste);
|
localStorage.setItem(keys.reverse()[0]+1, paste);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
getPastes: function(){
|
/** Return a list of the previous paste url with creation date */
|
||||||
if (zerobin.support.localstorage){
|
getPreviousPastes: function(){
|
||||||
var pastes = '';
|
var pastes = [],
|
||||||
var keys = zerobin.getKeys();
|
keys = zerobin.getKeys(),
|
||||||
|
date = zerobin.getFormatedDate();
|
||||||
keys.reverse();
|
keys.reverse();
|
||||||
|
|
||||||
for (i=0; i<=keys.length-1; i++)
|
for (i=0; i <= keys.length-1; i++) {
|
||||||
{
|
var paste = localStorage.getItem(keys[i]).split(';');
|
||||||
var paste = localStorage.getItem(keys[i]);
|
var displayDate = paste[0].split(' ')[0];
|
||||||
if (paste.split(';')[0].split(' ')[0] == zerobin.getDate()){
|
var prefix = 'the ';
|
||||||
var display_date = paste.split(';')[0].split(' ')[1];
|
if (displayDate == date){
|
||||||
var on_at = 'at ';
|
displayDate = paste[0].split(' ')[1];
|
||||||
}else{
|
prefix = 'at ';
|
||||||
var display_date = zerobin.getDate();
|
|
||||||
var on_at = 'on ';
|
|
||||||
}
|
}
|
||||||
pastes = pastes + '<li><a class="items" href="' + paste.split(';')[1] + '">' + on_at + display_date + '</a></li>';
|
pastes.push({displayDate: displayDate, prefix: prefix, link: paste[1]});
|
||||||
}
|
|
||||||
if (!pastes){
|
|
||||||
return '<i class="grey">Your previous pastes will be saved in your browser using <a href="http://www.w3.org/TR/webstorage/">localStorage</a>.</i>';
|
|
||||||
}
|
|
||||||
return pastes;
|
|
||||||
}else{
|
|
||||||
return 'Sorry your browser does not support LocalStorage, We cannot display your previous pastes.';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return pastes
|
||||||
},
|
},
|
||||||
|
|
||||||
getPasteContent: function(){
|
/** Return an link object with the URL as href so you can extract host,
|
||||||
var content_clone = '' ;
|
protocol, hash, etc*/
|
||||||
$("#paste-content li").each(function(index) {
|
parseUrl: function(url){
|
||||||
content_clone = content_clone + $(this).text() + '\n';
|
var a = document.createElement('a');
|
||||||
});
|
a.href = url
|
||||||
return content_clone;
|
return a
|
||||||
},
|
},
|
||||||
|
|
||||||
|
getPasteId: function(url){
|
||||||
|
loc = url ? zerobin.parseUrl(url) : window.location
|
||||||
|
return loc.pathname.replace(/[/]|paste/g, '');
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Return the paste content stripted from any code coloration */
|
||||||
|
getPasteContent: function(){
|
||||||
|
var copy = '' ;
|
||||||
|
$("#paste-content li").each(function(index) {
|
||||||
|
copy = copy + $(this).text() + '\n';
|
||||||
|
});
|
||||||
|
return copy;
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Return an approximate estimate the number of bytes in a text */
|
||||||
count: function(text, options) {
|
count: function(text, options) {
|
||||||
// Set option defaults
|
// Set option defaults
|
||||||
var crlf = /(\r?\n|\r)/g;
|
var crlf = /(\r?\n|\r)/g;
|
||||||
@ -219,6 +269,7 @@ zerobin = {
|
|||||||
|
|
||||||
return length + nonAscii + Math.max(0, options.lineBreaks * (lineBreaks - 1));
|
return length + nonAscii + Math.max(0, options.lineBreaks * (lineBreaks - 1));
|
||||||
},
|
},
|
||||||
|
/** Create a message, style it and insert it in the alert box */
|
||||||
message: function(type, message, title, flush, callback) {
|
message: function(type, message, title, flush, callback) {
|
||||||
|
|
||||||
$(window).scrollTop(0);
|
$(window).scrollTop(0);
|
||||||
@ -233,10 +284,23 @@ zerobin = {
|
|||||||
else {$('.title', $message).remove()}
|
else {$('.title', $message).remove()}
|
||||||
|
|
||||||
$message.prependTo($('#main')).show('fadeUp', callback);
|
$message.prependTo($('#main')).show('fadeUp', callback);
|
||||||
|
},
|
||||||
|
|
||||||
|
/** Return a progress bar object */
|
||||||
|
progressBar: function(selector){
|
||||||
|
var $container = $(selector);
|
||||||
|
var bar = {container: $container, elem: $container.find('.bar')};
|
||||||
|
bar.set = function(text, rate){bar.elem.text(text).css('width', rate)};
|
||||||
|
return bar;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/***************************
|
||||||
|
**** On document ready ***
|
||||||
|
****************************/
|
||||||
|
|
||||||
|
|
||||||
$(function(){
|
$(function(){
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -245,31 +309,32 @@ $(function(){
|
|||||||
posting it using ajax. Then redirect to the address of the
|
posting it using ajax. Then redirect to the address of the
|
||||||
newly created paste, adding the key in the hash.
|
newly created paste, adding the key in the hash.
|
||||||
*/
|
*/
|
||||||
$('button[type=submit]').live("click", function(e){
|
$('.btn-primary').on("click", function(e){
|
||||||
|
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var paste = $('textarea').val();
|
var paste = $('textarea').val();
|
||||||
|
|
||||||
var sizebytes = zerobin.count($('#content').val(), { });
|
var sizebytes = zerobin.count($('#content').val());
|
||||||
var oversized = sizebytes > zerobin.max_size;
|
var oversized = sizebytes > zerobin.max_size;
|
||||||
var readable_fsize = Math.round(sizebytes/1024);
|
var readableFsize = Math.round(sizebytes / 1024);
|
||||||
var readable_maxsize = Math.round(zerobin.max_size/1024)
|
var readableMaxsize = Math.round(zerobin.max_size / 1024);
|
||||||
|
|
||||||
if (oversized){
|
if (oversized){
|
||||||
zerobin.message('error',
|
zerobin.message('error',
|
||||||
('Your file is <strong class="file-size">' + readable_fsize +
|
('Your file is <strong class="file-size">' + readablFfsize +
|
||||||
'</strong>KB. You have reached the maximum size limit of ' +
|
'</strong>KB. You have reached the maximum size limit of ' +
|
||||||
readable_maxsize + 'KB.'),
|
readableMaxsize + 'KB.'),
|
||||||
'Warning!', true)
|
'Warning!', true)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!oversized && paste.trim()) {
|
if (!oversized && paste.trim()) {
|
||||||
|
|
||||||
$form = $('input, textarea, select, button').prop('disabled', true);
|
$form = $('input, textarea, select, button').prop('disabled', true);
|
||||||
$form.prop('disabled', true);
|
|
||||||
$bar = $('form.well .progress').show();
|
// set up progress bar
|
||||||
var $loading = $('form.well .progress .bar')
|
var bar = zerobin.progressBar('form.well .progress');
|
||||||
.css('width', '25%')
|
bar.container.show();
|
||||||
.text('Converting paste to bits...');
|
bar.set('Converting paste to bits...', '25%');
|
||||||
|
|
||||||
/* Encode, compress, encrypt and send the paste then redirect the user
|
/* Encode, compress, encrypt and send the paste then redirect the user
|
||||||
to the new paste. We ensure a loading animation is updated
|
to the new paste. We ensure a loading animation is updated
|
||||||
@ -282,20 +347,20 @@ $('button[type=submit]').live("click", function(e){
|
|||||||
|
|
||||||
zerobin.encrypt(key, paste,
|
zerobin.encrypt(key, paste,
|
||||||
|
|
||||||
function(){$loading.text('Encoding to base64...').css('width', '45%')},
|
mkcb(bar.set, 'Encoding to base64...', '45%'),
|
||||||
function(){$loading.text('Compressing...').css('width', '65%')},
|
mkcb(bar.set, 'Compressing...', '65%'),
|
||||||
function(){$loading.text('Encrypting...').css('width', '85%')},
|
mkcb(bar.set, 'Encrypting...', '85%'),
|
||||||
|
|
||||||
/* This block deal with sending the data, redirection or error handling */
|
/* This block deal with sending the data, redirection or error handling */
|
||||||
function(content){
|
function(content){
|
||||||
|
|
||||||
$loading.text('Sending...').css('width', '95%');
|
bar.set('Sending...', '95%');
|
||||||
var data = {content: content, expiration: expiration};
|
var data = {content: content, expiration: expiration};
|
||||||
|
|
||||||
$.post('/paste/create', data)
|
$.post('/paste/create', data)
|
||||||
.error(function(error) {
|
.error(function(error) {
|
||||||
$form.prop('disabled', false);
|
$form.prop('disabled', false);
|
||||||
$loading.hide();
|
bar.container.hide();
|
||||||
zerobin.message(
|
zerobin.message(
|
||||||
'error',
|
'error',
|
||||||
'Paste could not be saved. Please try again later.',
|
'Paste could not be saved. Please try again later.',
|
||||||
@ -304,12 +369,12 @@ $('button[type=submit]').live("click", function(e){
|
|||||||
|
|
||||||
})
|
})
|
||||||
.success(function(data) {
|
.success(function(data) {
|
||||||
$loading.text('Redirecting to new paste...').css('width', '100%');
|
bar.set('Redirecting to new paste...', '100%');
|
||||||
|
|
||||||
if (data['status'] == 'error') {
|
if (data['status'] == 'error') {
|
||||||
zerobin.message('error', data['message'], 'Error');
|
zerobin.message('error', data['message'], 'Error');
|
||||||
$form.prop('disabled', false);
|
$form.prop('disabled', false);
|
||||||
$bar.hide();
|
bar.container.hide();
|
||||||
} else {
|
} else {
|
||||||
var paste_url = '/paste/' + data['paste'] + '#' + key;
|
var paste_url = '/paste/' + data['paste'] + '#' + key;
|
||||||
zerobin.storatePaste(paste_url);
|
zerobin.storatePaste(paste_url);
|
||||||
@ -320,7 +385,7 @@ $('button[type=submit]').live("click", function(e){
|
|||||||
);
|
);
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
$form.prop('disabled', false);
|
$form.prop('disabled', false);
|
||||||
$bar.hide();
|
bar.container.hide();
|
||||||
zerobin.message('error', 'Paste could not be encrypted. Aborting.',
|
zerobin.message('error', 'Paste could not be encrypted. Aborting.',
|
||||||
'Error');
|
'Error');
|
||||||
}
|
}
|
||||||
@ -332,29 +397,46 @@ $('button[type=submit]').live("click", function(e){
|
|||||||
DECRYPTION:
|
DECRYPTION:
|
||||||
On the display paste page, decrypt and decompress the paste content,
|
On the display paste page, decrypt and decompress the paste content,
|
||||||
add syntax coloration then setup the copy to clipboard button.
|
add syntax coloration then setup the copy to clipboard button.
|
||||||
|
Also calculate and set the paste visual hash.
|
||||||
*/
|
*/
|
||||||
var content = $('#paste-content').text().trim();
|
var content = $('#paste-content').text().trim();
|
||||||
var key = window.location.hash.substring(1);
|
var key = window.location.hash.substring(1);
|
||||||
var error = false;
|
var error = false;
|
||||||
if (content && key) {
|
if (content && key) {
|
||||||
|
|
||||||
var $bar = $('.well form .progress').show();
|
/* Load the lib for visual canvas, create one from the paste id and
|
||||||
var $loading = $('.well form .progress .bar').css('width', '25%')
|
insert it */
|
||||||
.text('Decrypting paste...');
|
$.getScript("/static/js/vizhash.min.js").done(function(script, textStatus) {
|
||||||
|
if (vizhash.supportCanvas) {
|
||||||
|
var vhash = vizhash.canvasHash(zerobin.getPasteId(), 24, 24);
|
||||||
|
$('<a class="vhash" href="#"></a>').click(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
if(confirm("This picture is unique to your paste so you can identify" +
|
||||||
|
" it quickly. \n\n Do you want to know more about this?")){
|
||||||
|
window.open("http://is.gd/IJaMRG", "_blank");
|
||||||
|
}
|
||||||
|
}).prependTo('.lnk-option').append(vhash.canvas);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$form = $('input, textarea, select, button').prop('disabled', true);
|
||||||
|
|
||||||
|
var bar = zerobin.progressBar('.well form .progress');
|
||||||
|
bar.container.show();
|
||||||
|
bar.set('Decrypting paste...', '25%');
|
||||||
|
|
||||||
zerobin.decrypt(key, content,
|
zerobin.decrypt(key, content,
|
||||||
|
|
||||||
/* On error*/
|
/* On error*/
|
||||||
function(){
|
function(){
|
||||||
$bar.hide();
|
bar.container.hide();
|
||||||
zerobin.message('error', 'Could not decrypt data (Wrong key ?)',
|
zerobin.message('error', 'Could not decrypt data (Wrong key ?)', 'Error');
|
||||||
'Error');
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/* Update progress bar */
|
/* Update progress bar */
|
||||||
function(){$loading.text('Decompressing...').css('width', '45%')},
|
mkcb(bar.set, 'Decompressing...', '45%'),
|
||||||
function(){$loading.text('Base64 decoding...').css('width', '65%')},
|
mkcb(bar.set, 'Base64 decoding...', '65%'),
|
||||||
function(){$loading.text('From bits to string...').css('width', '85%')},
|
mkcb(bar.set, 'From bits to string...', '85%'),
|
||||||
|
|
||||||
/* When done */
|
/* When done */
|
||||||
function(content){
|
function(content){
|
||||||
@ -363,7 +445,7 @@ if (content && key) {
|
|||||||
$('#paste-content').text(content);
|
$('#paste-content').text(content);
|
||||||
content = '';
|
content = '';
|
||||||
|
|
||||||
$loading.text('Code coloration...').css('width', '95%');
|
bar.set('Code coloration...', '95%');
|
||||||
|
|
||||||
/* Add a continuation to let the UI redraw */
|
/* Add a continuation to let the UI redraw */
|
||||||
setTimeout(function(){
|
setTimeout(function(){
|
||||||
@ -372,16 +454,21 @@ if (content && key) {
|
|||||||
ZeroClipboard.setMoviePath('/static/js/ZeroClipboard.swf');
|
ZeroClipboard.setMoviePath('/static/js/ZeroClipboard.swf');
|
||||||
|
|
||||||
var clip = new ZeroClipboard.Client();
|
var clip = new ZeroClipboard.Client();
|
||||||
|
|
||||||
|
// Callback to reposition the clibpboad flash animation overlay
|
||||||
|
var reposition = function(){clip.reposition()};
|
||||||
|
|
||||||
clip.addEventListener('mouseup', function(){
|
clip.addEventListener('mouseup', function(){
|
||||||
clip.setText(zerobin.getPasteContent());
|
clip.setText(zerobin.getPasteContent());
|
||||||
});
|
});
|
||||||
clip.addEventListener('complete', function(){
|
clip.addEventListener('complete',
|
||||||
zerobin.message('info', 'The paste is now in your clipboard',
|
mkcb(zerobin.message, 'info',
|
||||||
'', false, function(){clip.reposition()});
|
'The paste is now in your clipboard',
|
||||||
});
|
'', true, reposition)
|
||||||
|
);
|
||||||
clip.glue('clip-button');
|
clip.glue('clip-button');
|
||||||
|
|
||||||
window.onresize = clip.reposition;
|
window.onresize = reposition;
|
||||||
|
|
||||||
|
|
||||||
/* Setup link to get the paste short url*/
|
/* Setup link to get the paste short url*/
|
||||||
@ -393,7 +480,7 @@ if (content && key) {
|
|||||||
$('#copy-success').hide();
|
$('#copy-success').hide();
|
||||||
zerobin.message('success',
|
zerobin.message('success',
|
||||||
'<a href="' + tinyurl + '">' + tinyurl + '</a>',
|
'<a href="' + tinyurl + '">' + tinyurl + '</a>',
|
||||||
'Short url', true, function(){clip.reposition()}
|
'Short url', true, reposition
|
||||||
)
|
)
|
||||||
$('#short-url').text('Get short url');
|
$('#short-url').text('Get short url');
|
||||||
});
|
});
|
||||||
@ -401,20 +488,23 @@ if (content && key) {
|
|||||||
|
|
||||||
/* Remap the message close handler to include the clipboard
|
/* Remap the message close handler to include the clipboard
|
||||||
flash reposition */
|
flash reposition */
|
||||||
$(".close").die().live('click', function(e){
|
$(".close").off().on('click', function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).parent().fadeOut(function(){clip.reposition()});
|
$(this).parent().fadeOut(reposition);
|
||||||
});
|
});
|
||||||
|
|
||||||
/** Syntaxic coloration */
|
/** Syntaxic coloration */
|
||||||
prettyPrint();
|
prettyPrint();
|
||||||
|
|
||||||
/** Add margin color */
|
/* Class to switch to paste content style with coloration done */
|
||||||
$("#paste-content").addClass("margin-color");
|
$('#paste-content').addClass('done');
|
||||||
|
|
||||||
/* Display result */
|
/* Display result */
|
||||||
$loading.text('Done').css('width', '100%');
|
bar.set('Done', '100%');
|
||||||
$bar.hide();
|
bar.container.hide();
|
||||||
|
|
||||||
|
$form.prop('disabled', false);
|
||||||
|
|
||||||
}, 250);
|
}, 250);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -423,9 +513,9 @@ if (content && key) {
|
|||||||
} /* End of "DECRYPTION" */
|
} /* End of "DECRYPTION" */
|
||||||
|
|
||||||
/* Synchronize expiration select boxes value */
|
/* Synchronize expiration select boxes value */
|
||||||
$('.paste-option select').live('change', function(){
|
$('.paste-option select').on('change', function(){
|
||||||
var value = $(this).val();
|
var $this = $(this);
|
||||||
$('.paste-option select').val(value);
|
$this.val($this.val());
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
@ -434,11 +524,12 @@ $('#content').elastic();
|
|||||||
|
|
||||||
|
|
||||||
/* Display bottom paste option buttons when needed */
|
/* Display bottom paste option buttons when needed */
|
||||||
$('#content').live('keyup change', function(){
|
$('#content').on('keyup change', function(){
|
||||||
if($('#content').height() < 400 ){
|
if($('#content').height() < 400 ){
|
||||||
$('.paste-option.down').remove();
|
$('.paste-option.down').remove();
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
|
||||||
if ($('.paste-option').length == 1) {
|
if ($('.paste-option').length == 1) {
|
||||||
$('.paste-option').clone().addClass('down').appendTo('form.well');
|
$('.paste-option').clone().addClass('down').appendTo('form.well');
|
||||||
}
|
}
|
||||||
@ -446,60 +537,99 @@ $('#content').live('keyup change', function(){
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
/* Display previous pastes */
|
|
||||||
$('.previous-pastes .items').html(zerobin.getPastes());
|
|
||||||
|
|
||||||
/* clone a paste */
|
/* Display previous pastes */
|
||||||
|
if (zerobin.support.localStorage){
|
||||||
|
|
||||||
|
var $container = $('.previous-pastes'),
|
||||||
|
pastes = zerobin.getPreviousPastes();
|
||||||
|
|
||||||
|
if (pastes.length){
|
||||||
|
|
||||||
|
$.getScript("/static/js/vizhash.min.js").done(function(script, textStatus) {
|
||||||
|
|
||||||
|
$container.find('.item').remove();
|
||||||
|
$.each(zerobin.getPreviousPastes(), function(i, paste){
|
||||||
|
|
||||||
|
var $li = $('<li class="item"></li>').appendTo($container);
|
||||||
|
var $link = $('<a></a>').attr('href', paste.link)
|
||||||
|
.text(paste.prefix + paste.displayDate)
|
||||||
|
.appendTo($li);
|
||||||
|
|
||||||
|
if (vizhash.supportCanvas) {
|
||||||
|
var pasteId = zerobin.getPasteId(paste.link);
|
||||||
|
var vhash = vizhash.canvasHash(pasteId, 24, 24).canvas;
|
||||||
|
$link.prepend($(vhash).addClass('vhash'));
|
||||||
|
}
|
||||||
|
|
||||||
|
// hightlite the current link and make sure clicking the link
|
||||||
|
// does redirect to the page
|
||||||
|
if (paste.link.replace(/#[^#]+/, '') == window.location.pathname){
|
||||||
|
$li.addClass('active');
|
||||||
|
$link.click(function(){window.location.reload()});
|
||||||
|
}
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Event handler for "clone paste" button */
|
||||||
$('.btn-clone').click(function(e){
|
$('.btn-clone').click(function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
var content_clone = zerobin.getPasteContent();
|
|
||||||
$('.submit-form').show();
|
$('.submit-form').show();
|
||||||
$('.paste-form').remove();
|
$('.paste-form').hide();
|
||||||
$('#content').val(content_clone);
|
$('#content').val(zerobin.getPasteContent()).trigger('change');
|
||||||
$('#content').trigger('change');
|
});
|
||||||
|
|
||||||
|
$('.clone .btn-danger').click(function(e){
|
||||||
|
e.preventDefault();
|
||||||
|
$('.submit-form').hide();
|
||||||
|
$('.paste-form').show();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
/* Upload file using HTML5 File API */
|
/* Upload file using HTML5 File API */
|
||||||
|
if (zerobin.support.fileUpload) {
|
||||||
|
|
||||||
if (window.File && window.FileReader && window.FileList && window.Blob) {
|
var upload = function(files) {
|
||||||
$('.file-upload').show();
|
|
||||||
}
|
|
||||||
|
|
||||||
var file_upload = function(file) {
|
|
||||||
var reader = new FileReader();
|
var reader = new FileReader();
|
||||||
reader.onload = function(event) {
|
reader.onload = function(event) {
|
||||||
var content = event.target.result;
|
$('#content').val(event.target.result).trigger('change');
|
||||||
$('#content').val(content);
|
|
||||||
$('#content').trigger('change');
|
|
||||||
};
|
};
|
||||||
|
reader.readAsText(files[0]);
|
||||||
|
}
|
||||||
|
|
||||||
reader.readAsText(file[0]);
|
var $buttonOverlay = $('#file-upload');
|
||||||
}
|
var $button = $('.btn-upload');
|
||||||
|
|
||||||
try {
|
try {
|
||||||
$('#file-upload').change(function() {
|
$button.val('Uploading...');
|
||||||
file_upload(this.files);
|
$button.prop('disabled', true);
|
||||||
});
|
$buttonOverlay.change(function(){upload(this.files)});
|
||||||
}
|
}
|
||||||
catch (e) {
|
catch (e) {
|
||||||
zerobin.message('error', 'Could no upload the file', 'Error');
|
zerobin.message('error', 'Could no upload the file', 'Error');
|
||||||
|
$button.val('Upload File');
|
||||||
|
$button.prop('disabled', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
$button.prop('disabled', false);
|
||||||
|
$button.val('Upload File');
|
||||||
|
$buttonOverlay.mouseover(mkcb($(this).css, 'cursor', 'pointer'));
|
||||||
}
|
}
|
||||||
|
|
||||||
$('#file-upload').mouseover(function(){
|
|
||||||
$(this).css( 'cursor', 'pointer' );
|
|
||||||
});
|
|
||||||
|
|
||||||
|
|
||||||
/* Alerts */
|
/* Alerts */
|
||||||
|
|
||||||
$(".close").live('click', function(e){
|
$(".close").on('click', function(e){
|
||||||
e.preventDefault();
|
e.preventDefault();
|
||||||
$(this).parent().fadeOut();
|
$(this).parent().fadeOut();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
||||||
}); /* End of "document ready" jquery callback */
|
}); /* End of "document ready" jquery callback */
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
2
static/js/vizhash.min.js
vendored
Normal file
2
static/js/vizhash.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
@ -1,8 +1,8 @@
|
|||||||
<p class="alert alert-error">
|
<p class="alert alert-error">
|
||||||
<a class="close" data-dismiss="alert" href="#">×</a>
|
<a class="close" data-dismiss="alert" href="#">×</a>
|
||||||
<strong class="title">Error!</strong>
|
<strong class="title">404 Error!</strong>
|
||||||
<span class="message">
|
<span class="message">
|
||||||
This paste has expired or wrong url, please check again.
|
Either this paste has expired or this page never existed.
|
||||||
</span>
|
</span>
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
|
@ -19,9 +19,10 @@
|
|||||||
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
<script src="http://html5shim.googlecode.com/svn/trunk/html5.js"></script>
|
||||||
<![endif]-->
|
<![endif]-->
|
||||||
|
|
||||||
<script src="/static/js/sjcl.js"></script>
|
|
||||||
<script src="/static/js/jquery-1.7.2.min.js"></script>
|
<script src="/static/js/jquery-1.7.2.min.js"></script>
|
||||||
|
<script src="/static/js/sjcl.js"></script>
|
||||||
<script src="/static/js/behavior.js"></script>
|
<script src="/static/js/behavior.js"></script>
|
||||||
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
zerobin.max_size = {{ settings.MAX_SIZE }};
|
zerobin.max_size = {{ settings.MAX_SIZE }};
|
||||||
</script>
|
</script>
|
||||||
@ -59,7 +60,19 @@
|
|||||||
<div class="well sidebar-nav">
|
<div class="well sidebar-nav">
|
||||||
<ul class="nav nav-list previous-pastes">
|
<ul class="nav nav-list previous-pastes">
|
||||||
<li class="nav-header">Previous pastes</li>
|
<li class="nav-header">Previous pastes</li>
|
||||||
<li class="items"></li>
|
<li class="item local-storage">
|
||||||
|
<em class="grey">
|
||||||
|
Your previous pastes will be saved in your browser using
|
||||||
|
<a href="http://www.w3.org/TR/webstorage/">localStorage</a>.
|
||||||
|
</em>
|
||||||
|
</li>
|
||||||
|
<li class="item no-local-storage">
|
||||||
|
<em class="grey">
|
||||||
|
Sorry your browser does not support
|
||||||
|
<a href="http://www.w3.org/TR/webstorage/">LocalStorage</a>,
|
||||||
|
We cannot display your previous pastes.
|
||||||
|
</em>
|
||||||
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div><!--/.well -->
|
</div><!--/.well -->
|
||||||
</div><!--/span-->
|
</div><!--/span-->
|
||||||
@ -95,27 +108,10 @@
|
|||||||
</p>
|
</p>
|
||||||
</footer>
|
</footer>
|
||||||
|
|
||||||
|
|
||||||
<script src="/static/js/jquery.elastic.source.js"></script>
|
<script src="/static/js/jquery.elastic.source.js"></script>
|
||||||
<script src="/static/js/lzw.js"></script>
|
<script src="/static/js/lzw.js"></script>
|
||||||
<script src="/static/js/prettify.min.js"></script>
|
<script src="/static/js/prettify.min.js"></script>
|
||||||
<script src="/static/js/ZeroClipboard.js"></script>
|
<script src="/static/js/ZeroClipboard.js"></script>
|
||||||
<!--
|
|
||||||
<script src="/static/js/jquery.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-transition.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-alert.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-modal.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-dropdown.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-scrollspy.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-tab.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-tooltip.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-popover.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-button.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-collapse.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-carousel.js"></script>
|
|
||||||
<script src="/static/js/bootstrap-typeahead.js"></script>
|
|
||||||
|
|
||||||
-->
|
|
||||||
|
|
||||||
<p id="alert-template">
|
<p id="alert-template">
|
||||||
<a class="close" data-dismiss="alert" href="#">×</a>
|
<a class="close" data-dismiss="alert" href="#">×</a>
|
||||||
|
@ -4,24 +4,24 @@
|
|||||||
</p>
|
</p>
|
||||||
|
|
||||||
<form class="well" method="post" action="/paste/create">
|
<form class="well" method="post" action="/paste/create">
|
||||||
<p class="paste-option">
|
<p class="paste-option">
|
||||||
<label for="expiration" >Expiration:</label>
|
<label for="expiration" >Expiration:</label>
|
||||||
<select id="expiration" name="expiration">
|
<select id="expiration" name="expiration">
|
||||||
<option value="burn_after_reading">Burn after reading</option>
|
<option value="burn_after_reading">Burn after reading</option>
|
||||||
<option selected value="1_day">1 day</option>
|
<option selected value="1_day">1 day</option>
|
||||||
<option value="1_month">1 month</option>
|
<option value="1_month">1 month</option>
|
||||||
<option value="never">Never</option>
|
<option value="never">Never</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<div class="progress progress-striped active">
|
<div class="progress progress-striped active">
|
||||||
<div class="bar"></div>
|
<div class="bar"></div>
|
||||||
</div>
|
</div>
|
||||||
<textarea rows="10" style="width:100%;"
|
<textarea rows="10" style="width:100%;"
|
||||||
class="input-xlarge"
|
class="input-xlarge"
|
||||||
id="content" name="content"></textarea>
|
id="content" name="content"></textarea>
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
|
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- For cloning -->
|
<!-- For cloning -->
|
||||||
<span class="submit-form">
|
<div class="submit-form clone">
|
||||||
<form class="well" method="post" action="/paste/create">
|
<form class="well" method="post" action="/paste/create">
|
||||||
<p class="paste-option">
|
<p class="paste-option">
|
||||||
<label for="expiration" >Expiration:</label>
|
<label for="expiration" >Expiration:</label>
|
||||||
@ -64,14 +64,17 @@
|
|||||||
<option value="never">Never</option>
|
<option value="never">Never</option>
|
||||||
</select>
|
</select>
|
||||||
<button type="submit" class="btn btn-primary">Submit</button>
|
<button type="submit" class="btn btn-primary">Submit</button>
|
||||||
|
</p>
|
||||||
<p>
|
<p>
|
||||||
<p>
|
<div class="progress progress-striped active">
|
||||||
|
<div class="bar"></div>
|
||||||
|
</div>
|
||||||
<textarea rows="10" style="width:100%;"
|
<textarea rows="10" style="width:100%;"
|
||||||
class="input-xlarge"
|
class="input-xlarge"
|
||||||
id="content" name="content"></textarea>
|
id="content" name="content"></textarea>
|
||||||
</p>
|
</p>
|
||||||
</form>
|
</form>
|
||||||
</span>
|
</div>
|
||||||
|
|
||||||
|
|
||||||
%rebase base settings=settings
|
%rebase base settings=settings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user