Anonymous avatar Anonymous committed 2f7ae24

add lock and delete features to paste

Comments (0)

Files changed (12)

:w

-html, body {
-    height: 100%;
-    width: 99.99%;
-
-}
-
-body {
-    margin: 0;
-    padding: 0;
-    background: url(../../images/bg.png) repeat-x;
-    color: #000;
-    height: 100%;
-    min-width: 750px;
-}
-
-
-* html {
-    height: 100%;
-}
-
-
-section {
-    display: block;
-}
-
-h1 {margin-bottom:0.5em;}
-h2 {margin-bottom:0.75em;}
-h3 {margin-bottom:1em;}
-h4 {height:1.25em;}
-h5 {margin-bottom:1.5em;}
-h1 img, h2 img, h3 img, h4 img, h5 img, h6 img {margin:0;}
-
-ul, ol, li, h1, h2, h3, h4, h5, p {
-    margin: 0 0 0.3em 0;
-    padding: 0;
-}
-
-ol, ul {
-    list-style-image: none;
-    list-style-position: outside;
-    list-style-type: none;
-}
-
-
-
-/* header */
-#site_header {
-    display: block;
-    width: 100%;
-    height: 100px;
-
-
-    z-index: 0
-}
-#site_header h1 {
-    background: transparent url(../../images/logo.gif) no-repeat;
-    width: 306px;
-    height: 80px;
-    z-index: 10;
-    padding: 0;
-    margin: 0 30px 0;
-    position: relative;
-    float: left;
-    top: 10px;
-}
-#site_header h1 a {
-    display: block;
-    font-size: 0px;
-    width: 306px;
-    height: 80px;
-    text-indent: -700em;
-}
-
-#site_header #main_nav {
-    display: block;
-    width: auto;
-    height: 40px;
-    float: left;
-    margin-left: 80px;
-    z-index: 30;
-    position: relative;
-    top: 35px;
-}
-#main_nav li {
-    display: block;
-    float: left;
-    margin-left: 15px;
-}
-#main_nav li a {
-    display: block;
-    padding: 0.5em 1em 0.5em 1em;
-}
-#main_nav li {
-    float: left
-}
-
-/* content */
-.content-wrapper {
-    background: transparent url(../../images/home-back.png) no-repeat 100px 0pt;
-    width: 100%;
-    margin: 0;
-    padding: 0;
-    height: 100%;
-}
-
-#claim {
-    padding-left: 20px; 
-}
-
-/* paste form */
-#snippet_edit,
-#snippet_view,
-#revisions,
-#new_snippet,
-#claim_snippet {
-    padding: 40px 0 25px 0;
-}
-
-section.hidden,
-.hidden {
-    display: none;
-}
-form, #snippet {
-    width: 90%;
-    margin: 0pt auto;
-}
-
-#snippet {
-    display: block;
-    padding-left: 40px;
-    
-}
-
-form li {
-    padding: 5px 0;
-    /*clear: both;*/
-    margin: 0;
-}
-form li * {
-    vertical-align: middle
-}
-form label {
-    display: block;
-    width: 14em;
-    height: 12px;
-    float: left;
-    padding: 0 1em 3px 0;
-}
-input[type='text'], select {
-    width: 174px;
-    border: 1px solid;
-    margin: 0;
-}
-
-textarea {
-    width: 99%;
-    border: 1px solid;
-    height: 300px;
-    z-index: 0;
-}
-
-.wed {
-    width: 99%;
-    height: 450px;
-    
-}
-.wed iframe {
-    width: 100%;
-}
-
-input[type='submit'], input[type='reset'], input[type='button'], button {
-    border-width: 0 1px 1px 0;
-    padding: 0.3em 0.5em 0.3em 0.5em;
-}
-
-
-/* paste detail */
-#snippet r h2 {
-    padding-bottom: 15px;
-}
-#snippet .lsnippet {
-    font-size: 1.3em;
-}
-#actions {
-    padding: 15px 0;
-    vertical-align: middle;
-}
-#actions form {
-    margin: 0;
-    width: auto;
-    height: 2em;
-    float: right;
-    position: relative;
-}
-#actions ul {
-    position: relative;
-}
-#actions li {
-    display: inline;
-    margin-left: 10px;
-    border-left: 1px solid;
-    overflow: hidden;
-    clear: none;
-    padding-left: 10px;
-}
-#actions li.first {
-    border: 0;
-}
-#actions form li label {
-    display: inline;
-    width: auto;
-    float: none;
-}
-
-#info {
-    border: 1px solid;
-    padding: 0.5em 0.3em 0.5em 0.3em;
-}
-#info table {
-    width: auto;
-    padding: 0;
-    margin: 10px 0;
-}
-#info th {
-    padding: 0;
-}
-#dl {
-    clear:both;
-    width: 100%;
-    margin-top: 10px;
-    font-size: 0.9em;
-}
-
-
-
-.highlight {
-    border: 1px solid;
-    background-repeat: repeat;
-
-   
-}
-
-
-#paste_wrapper,
-#diff {
-    clear: both;
-    width: 100%;
-    margin-top: 10px;
-
-}
-
-#diff {
-    position: relative;
-}
-
-#paste_comments {
-    display: block;
-    position: relative;
-    float: left;
- 
-}
-
-#paste_comments h2 {
-    font-size: 12px;
-    margin: 0;
-    padding: 0.3em;
-}
-
-#paste_comments.hidden {
-    display: none;
-}
-
-
-table {
-    border-spacing: 0;
-    /*counter-reset: lines;*/
-    margin: 0;
-    white-space: pre-wrap; 
-    white-space: -moz-pre-wrap !important;
-    white-space: -pre-wrap; 
-    white-space: -o-pre-wrap;
-    word-break: break-word;
-    font-family: monospace;
-    z-index: 5;
-    
-}
-
-
-code {
-    white-space: pre-wrap; 
-    white-space: -moz-pre-wrap !important;
-    white-space: -pre-wrap; 
-    white-space: -o-pre-wrap;
-    word-break: break-word;
-}
-
-code.highlight {
-    margin:0;
-    padding:0;
-}
-
-td {
-    padding: 0 !important;
-    vertical-align: baseline;
-    line-height: 16px;
-}
-
-.line-number {
-    padding: 0 2px !important;
-    min-width: 21px;
-    background-color: rgb(240, 240, 240);
-    border-right: 1px solid rgb(128, 128, 128) !important;
-    -webkit-user-select: none; /* safari */
-    -moz-user-select: none; /* mozilla */
-    user-select: none; /* css3 */
-    -khtml-user-select: none;
-}
-
-.line-gutter-backdrop {
-    /* Keep this in sync with view-source.css (.webkit-line-gutter-backdrop) */
-    position: relative;
-    z-index: 1;
-    left: 0;
-    top: 0;
-    height: 100%;
-}
-
-
-.line-number {
-    text-align: right;
-    color: rgb(128, 128, 128);
-    word-break: normal;
-    white-space: nowrap;
-     
-    font-family: Helvetica;
-    width: 40px;
-}
-
-.line-number::before {
-    /*content: counter(lines);
-    counter-increment: lines;*/
-    -webkit-user-select: none;
-    vertical-align: top;
-}
-
-.line-content {
-    padding: 0 5px !important;
-    word-break: break-word;
-}
-
-
-.comment-icon {
-    background-image: url(../../images/comment-icon.gif);
-    background-position: 20px 0;
-}
-
-#paste.hidenos .line-number,
-#paste.hidenos .linenos {
-    display: none;
-}
-
-.highlighted-line {
-    background-color: rgb(255, 255, 120);
-}
-
-
-.addComment {
-    display: block;
-    position: absolute;
-    z-index: 9999;
-    width: 150px;
-    background: #303030;
-    color: #fff;
-    height: 20px;
-}
-
-td.linenos { 
-    padding: 0 5px; 
-}
- 
-.linenos .special { 
-    font-weight: bold; color: #000;
-    }
- 
-td.code {
-    padding: 0 8px;
-}
-
-
-
-table.difftabular th {
-    width: 2em;
-}
-
-table.difftabular th.linenos {
-    border: 0;
-}
-
-tr.tabularh th.linenos {
-    padding-bottom: 5px;
-}
-
-tbody.hidenos td.linenos,
-tbody.hidenos th.linenos {
-    display: none;
-}
-
-tr.base td.c,
-th.diffm {
-    border-right: 1px solid;
-}
-
-th.diffp,
-tr.changed td.c {
-    border-right: 1px solid;
-}
-
-tr.changed td.first {
-    border-top: 1px solid;
-}
-tr.changed .last {
-    border-bottom: 1px solid;
-}
-
-tr.base td.first {
-    border-top: 1px solid;
-}
-tr.base .last {
-    border-bottom: 1px solid;
-}
-
-
-
-.btop {
-    border-top: 1px solid;
-}
-
-
-#bottoma {
-    position: relative;
-    width: 100%;
-    clear: both;
-    
-    padding: 15pt 0;
-}
-#bottom form {
-    width: auto;
-    margin: 0pt;
-}
-#bottoma ul {
-    list-style: none;
-}
-#bottoma li {
-    display: block;
-    float: left;
-    width: 100px;
-    margin-right: 10px;
-    padding: 0;
-}
-
-
-#revisions,
-#claim_snippet{
-    position: relative;
-    width: 90%;
-    margin: 0pt auto;
-}
-table.revisionstable {
-    position: relative;
-    width: 600px;
-    margin: 0pt 0pt 45px 0pt;
-    padding: 0;
-    border: 1px solid;
-}
-table.revisionstable td {
-    margin-left: 20px;
-}
-#revisions form {
-    margin: 0pt;
-    padding: 0pt;
-}
-td.since {
-    font-style: italic;
-}
-#revisions h2 {
-    margin-bottom: 15px;
-}
-#revisions h3, div.txt h2 {
-    margin: 15px 0 15px 0;
-    padding: 0.1em;
-}
-
-
-h2 span.snippet_actions {
-    float: right; 
-    top: 0;
-    z-index: 100;
-    width: 200px;
-}
-
-span.snippet_actions li {
-    display: inline;
-    padding-left: 10px; 
-}
-table.claimTable {
-    margin-top: 10px;
-    margin-bottom: 10px; 
-}
-div.txt {
-    width: 90%;
-    padding: 15px 0;
-    margin: 0pt auto;
-}
-div.txt h3 {
-    margin: 15px 0 10px 0;
-    padding: 0.1em;
-}
-div.txt pre {
-    border: 1px solid;
-    padding: 0.3em;
-}
-div.txt pre.wrap {
-    width: 99%;
-}
-
-
-li.errors {
-    padding: 0.3em;
-    border: 1px solid;
-}
-
-p.errors,
-ul.errors {
-    padding: 0.3em;
-    border: 1px solid;
-    margin-bottom: 15px;
-}
-
-#switch span {
-    display: block;
-    cursor: pointer;
-    padding: 0 0.5em 0 0.5em;
-    float: left;
-}
-#switch {
-    clear: both;
-    margin-bottom: 5px;
-    margin-top: 10px;
-    width: auto;
-    float: right;
-}
-
-#switch span {
-    cursor: pointer;
-}
-
-div.textmate {
-    background: url(../../images/bundle.png) no-repeat;
-    min-height: 64px;
-    padding-left: 70px;
-}
-
-
-/* bottom */
-
-
-#bottom {
-    display: block;
-    clear: both;
-    width: 100%;
-    margin-top: 15px;
-    background: repeat-y;
-    padding: 0.5em 0 1em 0;
-    height: 40px;
-}
-p.copyright {
-    display: block;
-    margin: 0pt auto 0pt auto;
-    width: 855px;
-}
-
-p.copyright span.brand {
-    float: left;
-    width: 400px;
-}
-p.copyright span.powered {
-    float: right;
-    width: auto;
-    position: relative;
-}
-
-/* resizer */
-div.grippie {
-    background:#E9E9E9 url(../../images/resize2.gif) no-repeat scroll 50% 50%;
-min-height:3px;
-    height: 3px;
-    cursor: row-resize;
-    width: 99%;
-}
-
-    /* embed */
-
-form.embed {
-    margin: 0;
-}
-form.embed table th {
-    font-weight: bold; 
-}
-
-form.embed table td {
-    padding-left: 0.3em;
-}
-
-form.embed label {
-    margin: 0;
-    padding: 0;
-}
-
-form.embed label {
-    width: auto;
-}
-
-form.embed input {
-    font-size: 80%;
-    width: 320px;
-}

friendpaste/models.py

     forked = BooleanField(default=False)
     fork_parent = TextField(default='')
     forked_atrevision = TextField(default='')
-    claimed = TextField(default='')
+    edit_code = TextField(default='')
+    locked = BooleanField(default=False)
     created = DateTimeField()
     updated = DateTimeField()
     
             
                 # save changes
                 db[self.id] = self._data
-            elif old_data['claimed'] != self.claimed:
+            elif old_data['edit_code'] != self.edit_code or \
+                    old_data['locked'] != self.locked:
                 db[self.id] = self._data
         return self
        

friendpaste/urls.py

         'paste/original': views.view_original,
         'paste/edit': views.edit_snippet,
         'paste/fork': views.fork_snippet,
-        'claim': views.claim_snippet,
+        'paste/delete': views.delete_snippet,
+        'paste/lock': views.lock_snippet,
+        'paste/unlock': views.lock_snippet,
         'paste/changeset': views.view_changeset,
         'paste/revisions': views.view_revisions,
         'paste/rss': views.view_rss,
     Rule('/<id>/rss', endpoint='paste/rss'),
     Rule('/<id>/edit', endpoint='paste/edit'),
     Rule('/<id>/fork', endpoint='paste/fork'),
-    Rule('/<id>/claim', endpoint='claim'),
+    Rule('/<id>/delete', endpoint='paste/delete'),
+    Rule('/<id>/lock', endpoint='paste/lock'),
+    Rule('/<id>/unlock', endpoint='paste/unlock'),
     Rule('/<id>/changeset', endpoint='paste/changeset'),
     Rule('/<id>/revisions', endpoint='paste/revisions'),
     Rule('/<id>.js', endpoint='paste/embed'),

friendpaste/views.py

 import time
 
 from jinja2.filters import do_truncate, do_striptags, escape
-from wtforms import Form, TextField, TextAreaField, SelectField, ValidationError, \
-        validators
+from wtforms import Form, TextField, TextAreaField, SelectField, PasswordField, \
+ValidationError, validators
 from pygments.lexers import get_all_lexers, get_lexer_for_filename
 from pygments.styles import get_all_styles
 from pygments.formatters import HtmlFormatter
     title=TextField('Title')
     snippet=TextAreaField('Paste', [validators.length(min=3, max=500000)])
     language = SelectField(u'Programming Language', choices=LEXERS_CHOICE)
+    code = PasswordField('Removal/Lock code', default='')
 
 def create_snippet(request):
     mimetypes = request.accept_mimetypes
             except:
                 language = 'text'
         try:
+            code = d.get('edit_code', '')
+            if code:
+                code = make_hash(code)
             s = Paste(
                     title=d.get('title', ""),
                     content=d.get('snippet'),
-                    language=language
+                    language=language,
+                    edit_code=code
             )
             s.store(local.db)
         except:
 
     form = PasteForm(request.form, prefix='paste')
     if request.method=='POST' and form.validate():
-        s = Paste(title=form.data['title'], content=form.data['snippet'], language=form.data['language'])
+        code = form.data['code']
+        if code:
+            code = make_hash(code)
+
+        s = Paste(
+                title=form.data['title'],
+                content=form.data['snippet'],
+                language=form.data['language'],
+                edit_code= code        
+        )
         s.store(local.db)
         print "id created : %s" % s.pasteid
         return redirect ('/%s' % s.pasteid)
     if not s:
         raise NotFound
 
-    print s.fork
     return redirect ('/%s' % s.pasteid)
 
 
         'snippet': s.content,
         'language': str(s.language)
     })
+    print s.locked
+    setattr(s, "lines", s.content.split('\n'))
+    return render_response('paste/view.html', snippet=s, form=form, rev=revid)
+ 
+def delete_snippet(request, id):
+    s = Paste.get_paste(local.db, id)
+    if s is None or not s.edit_code:
+        raise NotFound
 
-    setattr(s, "lines", s.content.split('\n'))
-    print s.claimed
-    return render_response('paste/view.html', snippet=s, form=form, rev=revid)
-    
+    error = False
+    if request.method == "POST" or request.method == "DELETE":
+        edit_code = request.form.get('edit_code', '')
+        if edit_code and make_hash(edit_code) == s.edit_code:
+            del local.db[s.id]
+            if request.is_xhr:
+                return send_json({ "ok": True })
+            return redirect('/')
+        if request.is_xhr:
+            return send_json({ "ok": False })
+        error = True
+
+    return render_response('paste/delete.html', snippet=s, error=error)
+
+
+def lock_snippet(request, id):
+    s = Paste.get_paste(local.db, id)
+    if s is None or not s.edit_code:
+        raise NotFound
+
+    error = False
+    if request.method == "POST":
+        edit_code = request.form.get('edit_code', '')
+        if edit_code and make_hash(edit_code) == s.edit_code:
+            s.locked = not s.locked
+            s.store(local.db)
+
+            if request.is_xhr:
+                return send_json({ "ok": True })
+            return redirect("/%s" % s.pasteid)
+        if request.is_xhr:
+            return send_jsoin({ "ok": False })
+        error = True
+    return render_response('paste/lock.html', snippet=s, error=error)
+
     
 def view_source(request, id):
     s = Paste.get_paste(local.db, id)

static/css/src/colors.css

 form label {
     color: #333;
 }
-input[type='text'], select {
+input[type='text'], 
+input[type='password'],
+select {
     border-color: #949494;
 }
 
     color: #666;
 }
 
+#snippet_actions li {
+    border-color: #899834;
+}
+
+#snippet_actions label {
+    color: #fff;
+}
+
+#snippet_actions h4 {
+    color: #899834;
+    border-bottom-color: #899834;
+}
+
 #lines {
     background: #f8f8f8;
 }

static/css/src/layout.css

 #snippet_view,
 #revisions,
 #new_snippet,
-#claim_snippet {
+#s_snippet_actions {
     padding: 40px 0 25px 0;
 }
 
     float: left;
     padding: 0 1em 3px 0;
 }
-input[type='text'], select {
+input[type='text'], 
+input[type='password'],
+select {
     width: 174px;
     border: 1px solid;
     margin: 0;
     font-size: 0.9em;
 }
 
-    /* embed */
+.tip {
+    margin-top: 20px;
+}
+
+
+/* embed */
 
 form.embed {
     margin: 0;
 #bottom form {
     width: auto;
     margin: 0;
-    padding: ;
+    padding: 0;
 }
 #bottoma ul {
     list-style: none;
 }
 
 #snippet_title h2 {
-    width: 500px;
+    width: 300px;
     float: left;
 }
 
 #snippet_title #snippet_actions {
     float: right;
-    width: 400px;
+    display: block;
+    width: 420px;
     height: 2em;
     line-height: 2em;
     vertical-align: middle;
     background: #303030;
     padding: 0.2em;
     line-height: 1.2em;
+    border: 1px solid;
 }
 
 #snippet_actions li a {
     color: #fff;
-    font-size: 0.8em;
     text-decoration: none;
+    margin:0;
+   padding:0; 
 }
 
+#snippet_actions li.disabled {
+    display: none;
+}
+
+#snippet_actions form {
+    display: block;
+    width: 350px;
+    float: left; 
+}
+#snippet_actions label {
+    margin: 0;
+    padding: 0.3em;
+    width: auto;
+}
+
+#snippet_actions h4 {
+    border-bottom: 1px solid;
+    margin-bottom: 0.3em;
+    margin-left: 0.3em;
+}
+
+#snippet_actions p {
+    color: #fff;
+    padding: 0.3em;
+} 
+
 table.claimTable {
     margin-top: 10px;
     margin-bottom: 10px; 

static/css/src/typography.css

     font-weight: bold;
 }
 
+#snippet_actions input {
+    font-size: 0.9em;
+    line-height: 1em;
+}
+
+#snippet_actions h4 {
+    font-size: 1.1em;
+    font-weight: bold;
+}
+
+
+#snippet_actions li a,
+#snippet_actions p,
+#snippet_actions form {
+    font-size: 0.9em;
+}
+
 
 #dl {
     text-align: center;
     font-size: 0.9em;
 }
 
+label#paste_code {
+    font-weight: bold;
+}
+
 .highlight {
     font-family: sans-serif;
 }
 
+.tip {
+    font-size: 0.8em;
+}
 
 h2 a.root {
     text-decoration: none;

static/js/src/friendpaste.js

         this.snippet = document.querySelector('#snippet_view');
         this.snippet_edit = document.querySelector('#snippet_edit');
         this.revisions = document.querySelector('#revisions');
+        this.bdelete = document.querySelector("#snippet_actions li.delete");
+
+        if (this.bdelete != null) {
+
+            this.block = document.querySelector("#snippet_actions li.lock"); 
+            this.adelete = document.querySelector("#snippet_actions li.delete a");
+            this.alock = document.querySelector("#snippet_actions li.lock a");
+
         
-        this.adelete = document.querySelector("#snippet_actions li.delete")
-        this.adelete.addEventListener("click", this.deletePaste.bindAsEventListener(this), false);
+            this._deleteListener = function(e) {
+                e.preventDefault()
+                this.removeEventListener('click', arguments.callee, false);
+                self.alock.removeEventListener('click', self._lockListener, false);
+                self.block.classList.add('disabled');
+                self.deletePaste();
+            }
+
+            this._lockListener = function(e) {
+                e.preventDefault();
+                this.removeEventListener('click', arguments.callee, false);
+                self.adelete.removeEventListener('click', self._deleteListener, false);
+                self.bdelete.classList.add('disabled');
+                self.lockPaste();
+            }
+
+            this.listenPasteActions();
+        }
 
         this.editing = false;
         this.show_history = false;
         document.querySelector("#show-linenos").addEventListener("click", 
                     this.toggleLineNumber.bindAsEventListener(this), false);
     },
-    
-    deletePaste: function(e) {
-        e.preventDefault();
-        form = this.formPassword("delete", "Delete paste");
+
+    listenPasteActions: function() {
+        this.adelete.addEventListener("click", this._deleteListener, false);
+        this.alock.addEventListener("click", this._lockListener, false);
+    },
+
+    deletePaste: function() {
+        var self = this;
+        var form = this.formPassword("delete", "Delete paste");
+            
+        var parent_ = base2.DOM.bind(this.adelete.parentNode);
+        this.adelete.style.display = "none";
+        parent_.appendChild(form);
+        parent_.querySelector("input.ano").addEventListener('click', function(e) {
+            e.preventDefault();
+            this.removeEventListener('click', arguments.callee, false);
+            self.adelete.style.display = "inline";
+            self.block.classList.remove('disabled');
+            remove(form);
+
+            self.listenPasteActions();
+        }, false);
+        return false;
+    },
+
+    lockPaste: function() {
+        var self = this;
+        if ( !this.snippet_edit)
+            var form = this.formPassword("unlock", "Unlock paste");
+        else
+            var form = this.formPassword("lock", "Lock paste");
+            
+        var parent_ = base2.DOM.bind(this.alock.parentNode);
+        parent_.appendChild(form);
+        this.alock.style.display = "none";
         
-        this.adelete.querySelector("a").style.display = "none";
-        this.adelete.appendChild(form);
-        
+        parent_.querySelector("input.ano").addEventListener('click', function(e) {
+            e.preventDefault();
+            this.removeEventListener('click', arguments.callee, false);
+            self.alock.style.display = "inline";
+            self.bdelete.classList.remove('disabled');
+
+            remove(form);
+            self.listenPasteActions();
+        }, false);
         return false;
     },
     
-    formPassword: function(action, label) {
+
+
+
+    formPassword: function(action, title) {
         url = "/" + snippet_id + "/" + action;
         form = document.createElement('form');
         form.className = "fsnippet_action";
         form.action = url;
+        form.method = "POST";
+        h4 = document.createElement('h4');
+        h4.appendChild(document.createTextNode(title));
+        form.appendChild(h4);
+        p = document.createElement('p');
+        p.appendChild(document.createTextNode('Enter code entered when '+ 
+                    'you create the paste to confirm:'));
+        form.appendChild(p);
         label = document.createElement('label');
-        label.setAttribute("for", "snippet_passwd");
-        label.value = label;
+        label.setAttribute("for", "edit_code");
+        label.appendChild(document.createTextNode('Code: '));
         form.appendChild(label);
         input = document.createElement('input');
         input.type = "password";
-        input.name = "snippet_passwd";
+        input.name = "edit_code";
         input.className = "password";
         form.appendChild(input);
         
         submit = document.createElement('input');
         submit.name="f" + action;
         submit.type = "submit";
-        submit.value = "Yes";
+        submit.value = action.substring(0,1).toUpperCase() + action.substring(1, action.length);
+        submit.className = "ayes";
         form.appendChild(submit);
         cancel = document.createElement('input');
         cancel.type = "submit";
-        cancel.value = "No";
+        cancel.value = "Cancel";
         cancel.className = "ano";
         form.appendChild(cancel);
+        
         return form;
     },
     
 
     _cancel: function() {
         this.editing = false;
-        if (!this.snippet_edit.classList.has('hidden'))
+        if (this.snippet_edit && !this.snippet_edit.classList.has('hidden'))
             this.snippet_edit.classList.add("hidden");
 
         if (!this.revisions.classList.has('hidden'))

templates/paste/delete.html

+{% extends "base.html" %}
+
+{% block title %}Delete #{{ snippet.pasteid }}{% endblock %}
+
+{% block content %}
+<section id="s_snippet_actions">
+    <form name="factions" id="factions" action="{{ url_for('paste/delete',
+        id=snippet.pasteid) }}" method="post">
+        <h2>Delete paste #<a href="{{ url_for('paste/view',
+                id=snippet.pasteid) }}">{{ snippet.pasteid }}</a></h2>
+        {% if error %}
+        <p class="errors">Paste code is empty or invalid.</p>
+        {% endif %}
+        <p>Enter code entered when you created the paste to confirm
+        deletetion:</p>
+        <table class="claimTable"> 
+            <tr id="row_password">
+                <th>Code:</th>
+                <td><input type="password" name="edit_code"
+                    id="edit_code" value="" autocomplete="off"/></td>
+            </tr>
+        </table>
+        <p><input type="submit" id="sactions" name="sactions"
+            value="Delete paste"> or <a href="{{ url_for('paste/view',
+                id=snippet.pasteid) }}" />Back to paste</a></p>
+</section>
+{% endblock %}

templates/paste/index.html

      class="errors"{% endif %}>{{ form.snippet(cols=70,rows=10,class="resizable") }}</li>
             <li>{{ form.language.label }}{{ form.language }}</li>
             <li>{{ form.title.label }}{{ form.title }}</li>
-            <li><input type="submit" name="psubmit" value="Submit post" /></li>
+            <li>{{ form.code.label }}{{ form.code(autocomplete="off")
+                }}</li>
+            <li class="ccode"><input type="submit" name="psubmit" value="Submit post" /></li>
         </ol>
+        <p class="tip">Removal/Lock code is a password to let you
+        <strong>remove</strong> or 
+        <strong>lock edit</strong> of paste you upload.</p>
     </form>
 
 </section>

templates/paste/lock.html

+{% extends "base.html" %}
+
+{% block title %}Lock edit of #{{ snippet.pasteid }}{% endblock %}
+
+{% block content %}
+<section id="s_snippet_actions">
+    <form name="factions" id="factions" action="{{ url_for('paste/lock',
+        id=snippet.pasteid) }}" method="post">
+        <h2>Lock edit of paste #<a href="{{ url_for('paste/view',
+                id=snippet.pasteid) }}">{{ snippet.pasteid }}</a></h2>
+        {% if error %}
+        <p class="errors">Paste code is empty or invalid.</p>
+        {% endif %}
+        <p>Enter code entered when you created the paste to confirm
+        deletetion:</p>
+        <table class="claimTable"> 
+            <tr id="row_password">
+                <th>Code:</th>
+                <td><input type="password" name="edit_code"
+                    id="edit_code" value="" autocomplete="off"/></td>
+            </tr>
+        </table>
+        <p><input type="submit" id="sactions" name="sactions"
+            value="Lock edit"> or <a href="{{ url_for('paste/view',
+                id=snippet.pasteid) }}" />Back to paste</a></p>
+</section>
+{% endblock %}

templates/paste/view.html

                 <h2><a href="/{{ snippet.pasteid }}" class="root">{{
                     snippet.pasteid }}</a>&nbsp;/&nbsp;{% if
                 snippet.title %}{{ snippet.title }}{% else %}No title{%
-                endif %}<span id="claim">{% if snippet.claimed %}claimed{% else %}<a
-                        href="{{ url_for('claim', id=snippet.pasteid) }}">claim this paste</a>{% endif %}</span></h2>
-                {% if snippet.claimed %}
+                endif %}</h2>
+                {% if snippet.edit_code %}
                 <div id="snippet_actions">
                     <ul>
                         <li class="delete"><a href="#" title="Delete paste">delete</a></li>
+                        {% if snippet.locked %}
+                        <li class="lock" title="Unlock edit"><a
+                            href="#">unlock</a></li>
+                        {% else %}
                         <li class="lock" title="Lock edit"><a href="#">lock</a></li>
+                        {% endif %}
                     </ul>
                 </div>
                 {% endif %}
         <footer>
             <div id="bottoma">
                 <ul>
+                    {% if not snippet.locked %}
                     <li>
+                        
                         <form action="/{{ snippet.pasteid }}/edit" method="get">
                             <input type="submit" class="e" value="Edit paste" />
                         </form>
                     </li>
+                    {% endif %}
                     <li>
                         <form action="/{{ snippet.pasteid }}/fork" method="post">
                             <input type="submit" value="Fork paste" />
     </article>
 </section>
 
+{% if not snippet.locked %}
 <section id="snippet_edit" class="hidden">
     <form id="fedit" name="fedit" method="post" action="/{{
         snippet.pasteid }}/edit" class="aligned">
         </ol>
     </form>
 </section>
+{% endif %}
 
 <section id="revisions" class="hidden">
     <h2><a href="/{{ snippet.pasteid }}" class="root">{{ snippet.pasteid }}</a>&nbsp;/&nbsp;{% if snippet.title %}{{ snippet.title }}{% else %}No title{% endif %}</h2>
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.