From 8fd8a56893dc5d2723eadf75f275bd4e4eb4e3c2 Mon Sep 17 00:00:00 2001
From: Daniel Kimsey
Date: Fri, 30 Nov 2012 13:18:42 -0500
Subject: [PATCH] New and Rename buttons now support directories
* Also fixes renaming a file from a subdirectory moves it to the root.
* Add context info option to dialog, used in the new dialog
* Added CSS to support new context option for dialogs
* Fix /pages view messing up directory creation in new
* Removed the Edit and Rename buttons from historic view
---
lib/gollum/frontend/app.rb | 43 +++++-
.../frontend/public/gollum/css/dialog.css | 12 +-
.../public/gollum/javascript/gollum.dialog.js | 4 +
.../public/gollum/javascript/gollum.js | 99 ++++++++++---
lib/gollum/frontend/templates/layout.mustache | 7 +-
lib/gollum/frontend/templates/page.mustache | 7 +-
lib/gollum/wiki.rb | 56 ++++++++
test/examples/revert.git/config | 2 +
test/examples/revert.git/logs/HEAD | 1 +
.../revert.git/logs/refs/heads/master | 1 +
.../08/4a558a1fb3cded23129e2dfad3a17d07d73fd3 | 3 +
.../46/3cabd49fa7daa55d786ab504afbb8c019bafb8 | Bin 0 -> 49 bytes
.../ff/3854dfc50af42e85bc4d45584555cdf95be43d | Bin 0 -> 196 bytes
test/examples/revert.git/refs/heads/master | 2 +-
test/test_app.rb | 78 +++++++++-
test/test_wiki.rb | 133 ++++++++++++++++++
16 files changed, 413 insertions(+), 35 deletions(-)
create mode 100644 test/examples/revert.git/objects/08/4a558a1fb3cded23129e2dfad3a17d07d73fd3
create mode 100644 test/examples/revert.git/objects/46/3cabd49fa7daa55d786ab504afbb8c019bafb8
create mode 100644 test/examples/revert.git/objects/ff/3854dfc50af42e85bc4d45584555cdf95be43d
diff --git a/lib/gollum/frontend/app.rb b/lib/gollum/frontend/app.rb
index 357b52d7..d5dc87e0 100644
--- a/lib/gollum/frontend/app.rb
+++ b/lib/gollum/frontend/app.rb
@@ -143,25 +143,57 @@ module Precious
end
end
+ post '/rename/*' do
+ wikip = wiki_page(params[:splat].first)
+ halt 500 if wikip.nil?
+ wiki = wikip.wiki
+ page = wiki.paged(wikip.name, wikip.path, exact = true)
+ rename = params[:rename]
+ halt 500 if page.nil?
+ halt 500 if rename.nil? or rename.empty?
+
+ # Fixup the rename if it is a relative path
+ # In 1.8.7 rename[0] != rename[0..0]
+ if rename[0..0] != '/'
+ source_dir = ::File.dirname(page.path)
+ source_dir = '' if source_dir == '.'
+ (target_dir, target_name) = ::File.split(rename)
+ target_dir = target_dir == '' ? source_dir : "#{source_dir}/#{target_dir}"
+ rename = "#{target_dir}/#{target_name}"
+ end
+
+ committer = Gollum::Committer.new(wiki, commit_message)
+ commit = {:committer => committer}
+
+ success = wiki.rename_page(page, rename, commit)
+ if !success
+ # This occurs on NOOPs, for example renaming A => A
+ redirect to("/#{page.escaped_url_path}")
+ return
+ end
+ committer.commit
+
+ wikip = wiki_page(rename)
+ page = wiki.paged(wikip.name, wikip.path, exact = true)
+ return if page.nil?
+ redirect to("/#{page.escaped_url_path}")
+ end
+
post '/edit/*' do
path = '/' + clean_url(sanitize_empty_params(params[:path])).to_s
page_name = CGI.unescape(params[:page])
wiki = wiki_new
page = wiki.paged(page_name, path, exact = true)
return if page.nil?
- rename = params[:rename].to_url if params[:rename]
- name = rename || page.name
committer = Gollum::Committer.new(wiki, commit_message)
commit = {:committer => committer}
- update_wiki_page(wiki, page, params[:content], commit, name, params[:format])
+ update_wiki_page(wiki, page, params[:content], commit, page.name, params[:format])
update_wiki_page(wiki, page.header, params[:header], commit) if params[:header]
update_wiki_page(wiki, page.footer, params[:footer], commit) if params[:footer]
update_wiki_page(wiki, page.sidebar, params[:sidebar], commit) if params[:sidebar]
committer.commit
- page = wiki.page(rename) if rename
-
redirect to("/#{page.escaped_url_path}") unless page.nil?
end
@@ -298,7 +330,6 @@ module Precious
@page = page
@name = name
@content = page.formatted_data
- @editable = true
mustache :page
else
halt 404
diff --git a/lib/gollum/frontend/public/gollum/css/dialog.css b/lib/gollum/frontend/public/gollum/css/dialog.css
index 8c0135ca..5816c064 100755
--- a/lib/gollum/frontend/public/gollum/css/dialog.css
+++ b/lib/gollum/frontend/public/gollum/css/dialog.css
@@ -87,6 +87,16 @@
font-family: 'Monaco', 'Courier New', Courier, monospace;
}
+ #gollum-dialog-dialog-body fieldset .field span.context {
+ font-size: .9em;
+ color: #666;
+ }
+ #gollum-dialog-dialog-body fieldset .field span.context span.path {
+ font-family: 'Monaco', 'Courier New', Courier, monospace;
+ font-weight: bold;
+ }
+
+
#gollum-dialog-dialog-body fieldset .field:last-child {
margin: 0 0 1em 0;
}
@@ -138,4 +148,4 @@
filter:progid:DXImageTransform.Microsoft.gradient(GradientType=0, startColorstr='#599bdc', endColorstr='#3072b3');
background: -webkit-gradient(linear, left top, left bottom, from(#599bdc), to(#3072b3));
background: -moz-linear-gradient(top, #599bdc, #3072b3);
-}
\ No newline at end of file
+}
diff --git a/lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js b/lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js
index 85daed0e..969842ac 100755
--- a/lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js
+++ b/lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js
@@ -79,6 +79,10 @@
fieldAttributes.id + '">';
}
+ if( fieldAttributes.context ){
+ html += '' + fieldAttributes.context + '';
+ }
+
return html;
},
diff --git a/lib/gollum/frontend/public/gollum/javascript/gollum.js b/lib/gollum/frontend/public/gollum/javascript/gollum.js
index 3153390d..9724f5cc 100755
--- a/lib/gollum/frontend/public/gollum/javascript/gollum.js
+++ b/lib/gollum/frontend/public/gollum/javascript/gollum.js
@@ -1,10 +1,44 @@
+// Helpers
+function pageName(){
+ // "my/dir/file" => "file"
+ return typeof(pageFullPath) == 'undefined' ? undefined : pageFullPath.split('/').pop();
+}
+function pagePath(){
+ // "my/dir/file" => "my/dir"
+ return typeof(pageFullPath) == 'undefined' ? undefined : pageFullPath.split('/').slice(0,-1).join('/');
+}
+
+// Generic HTML escape function
+function htmlEscape( str ) {
+ // The (slower) alternative is: return $('').text(str).html();
+ // http://stackoverflow.com/questions/1219860/javascript-jquery-html-encoding/7124052#7124052
+ return String(str)
+ .replace(/&/g, '&')
+ .replace(/"/g, '"')
+ .replace(/'/g, ''')
+ .replace(//g, '>');
+}
+
+// Given a page name and a current path, returns a fully qualified path.
+function abspath(path, name){
+ // Make sure the given path starts at the root.
+ if(name[0] != '/'){
+ name = '/' + path + '/' + name;
+ }
+ var name_parts = name.split('/');
+ var newPath = name_parts.slice(0, -1).join('/');
+ var newName = name_parts.pop();
+ // return array of [path, name]
+ return [newPath, newName];
+}
+
// ua
$(document).ready(function() {
$('#delete-link').click( function(e) {
var ok = confirm($(this).data('confirm'));
if ( ok ) {
- var loc = window.location;
- loc = baseUrl + '/delete' + loc.pathname.replace(baseUrl,'');
+ var loc = baseUrl + '/delete/' + pageFullPath;
window.location = loc;
}
// Don't navigate on cancel.
@@ -113,11 +147,12 @@ $(document).ready(function() {
$('#minibutton-rename-page').click(function(e) {
e.preventDefault();
- // Path name without the leading slash.
- var pathname = window.location.pathname.substr(1);
- var slashIndex = pathname.lastIndexOf('/');
- var oldName = pathname.substr(slashIndex + 1)
- var path = pathname.substr(0, slashIndex);
+ var path = pagePath();
+ var oldName = pageName();
+ var context_blurb =
+ "Renamed page will be under " +
+ "" + htmlEscape('/' + path) + "" +
+ " unless an absolute path is given."
$.GollumDialog.init({
title: 'Rename Page',
@@ -126,7 +161,8 @@ $(document).ready(function() {
id: 'name',
name: 'Rename to',
type: 'text',
- defaultValue: oldName || ''
+ defaultValue: oldName || '',
+ context: context_blurb
}
],
OK: function( res ) {
@@ -134,16 +170,17 @@ $(document).ready(function() {
if ( res['name'] ) {
newName = res['name'];
}
+ var name_parts = abspath(path, newName);
+ var newPath = name_parts[0];
- var msg = 'Renamed ' + oldName + ' to ' + newName;
- jQuery.ajax( {
- type: 'POST',
- url: baseUrl + '/edit/' + oldName,
- data: { path: path, rename: newName, page: oldName, message: msg },
- success: function() {
- window.location = baseUrl + '/' + encodeURIComponent(newName);
- }
- });
+ var msg = '/' + path == newPath ? 'Renamed ' + oldName + ' to ' + newName
+ : 'Renamed ' + oldName + ' to ' + name_parts.join('/');
+ // Fill in the rename form
+ // This is preferable to AJAX so that we automatically follow the 302 response.
+ var rename_form = $("form[name=rename]");
+ rename_form.children("input[name=rename]").val(name_parts.join('/'));
+ rename_form.children("input[name=message]").val(msg);
+ rename_form.submit();
}
});
});
@@ -154,6 +191,23 @@ $(document).ready(function() {
$('#minibutton-new-page').click(function(e) {
e.preventDefault();
+ var path = pagePath();
+ if( path === undefined && $('#file-browser').length != 0 ){
+ // In the pages view, pageFullPath isn't defined.
+ // The new button will still expect a value however.
+ // So we try to figure one out from window.location
+ path = baseUrl == '' ? window.location.pathname.substr(1)
+ : window.location.pathname.substr(baseUrl.length + 1);
+ // Remove the page viewer part of the url.
+ path = path.replace(/^pages\/?/,'')
+ // For consistency remove the trailing /
+ path = path.replace(/\/$/,'')
+ }
+ var context_blurb =
+ "Page will be created under " +
+ "" + htmlEscape('/' + path) + "" +
+ " unless an absolute path is given."
+
$.GollumDialog.init({
title: 'Create New Page',
fields: [
@@ -161,7 +215,8 @@ $(document).ready(function() {
id: 'name',
name: 'Page Name',
type: 'text',
- defaultValue: ''
+ defaultValue: '',
+ context: context_blurb
}
],
OK: function( res ) {
@@ -169,7 +224,13 @@ $(document).ready(function() {
if ( res['name'] ) {
name = res['name'];
}
- window.location = baseUrl + '/' + encodeURIComponent(name);
+ var name_encoded = [];
+ var name_parts = abspath(path, name).join('/').split('/');
+ // Split and encode each component individually.
+ for( var i=0; i < name_parts.length; i++ ){
+ name_encoded.push(encodeURIComponent(name_parts[i]));
+ }
+ window.location = baseUrl + name_encoded.join('/');
}
});
});
diff --git a/lib/gollum/frontend/templates/layout.mustache b/lib/gollum/frontend/templates/layout.mustache
index 95d97c1d..493ca8d1 100644
--- a/lib/gollum/frontend/templates/layout.mustache
+++ b/lib/gollum/frontend/templates/layout.mustache
@@ -12,7 +12,12 @@
-
+
diff --git a/lib/gollum/frontend/templates/page.mustache b/lib/gollum/frontend/templates/page.mustache
index 083f8a83..709bfce1 100644
--- a/lib/gollum/frontend/templates/page.mustache
+++ b/lib/gollum/frontend/templates/page.mustache
@@ -20,9 +20,9 @@ Mousetrap.bind(['e'], function( e ) {
class="action-all-pages">Files
New
+ {{#editable}}
Rename
- {{#editable}}
Edit
{{/editable}}
@@ -73,3 +73,8 @@ Mousetrap.bind(['e'], function( e ) {
+
+