Merge branch 'history'
This commit is contained in:
@@ -1,3 +1,6 @@
|
||||
# stdlib
|
||||
require 'digest/md5'
|
||||
|
||||
# external
|
||||
require 'grit'
|
||||
require 'github/markup'
|
||||
|
||||
@@ -78,6 +78,23 @@ module Precious
|
||||
wiki.preview_page("Preview", data, format).formatted_data
|
||||
end
|
||||
|
||||
get '/history/:name' do
|
||||
@name = params[:name]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
@page = wiki.page(@name)
|
||||
mustache :history
|
||||
end
|
||||
|
||||
post '/compare/:name' do
|
||||
@name = params[:name]
|
||||
@versions = params[:versions]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
@page = wiki.page(@name)
|
||||
diffs = wiki.repo.diff(@versions[1], @versions[0], @page.path)
|
||||
@diff = diffs.first
|
||||
mustache :compare
|
||||
end
|
||||
|
||||
get %r{/(.+?)/([0-9a-f]{40})} do
|
||||
name = params[:captures][0]
|
||||
wiki = Gollum::Wiki.new($path)
|
||||
|
||||
@@ -487,4 +487,236 @@ label.wiki-label {
|
||||
|
||||
.comment-form .comment{
|
||||
margin:5px 0 0 0;
|
||||
}
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* History
|
||||
/****************************************************************************/
|
||||
|
||||
table.commits {
|
||||
width: 100%;
|
||||
border-left: 1px solid #ccc;
|
||||
border-right: 1px solid #ccc;
|
||||
border-top: 1px solid #ccc;
|
||||
margin-bottom: 2em;
|
||||
}
|
||||
|
||||
table.commits tr td {
|
||||
background-color: #eaf2f5;
|
||||
}
|
||||
|
||||
table.commits th {
|
||||
font-weight: normal;
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: .3em .6em;
|
||||
background-color: #eee;
|
||||
font-size: 95%;
|
||||
text-align:left;
|
||||
}
|
||||
|
||||
table.commits td {
|
||||
border-bottom: 1px solid #ccc;
|
||||
padding: .3em .6em;
|
||||
}
|
||||
|
||||
table.commits td.sha,
|
||||
table.commits td.message {
|
||||
font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
|
||||
font-size: 80%;
|
||||
}
|
||||
|
||||
table.commits td.checkbox {
|
||||
width: 3%;
|
||||
}
|
||||
|
||||
table.commits td.sha {
|
||||
width: 6%;
|
||||
}
|
||||
|
||||
table.commits td.human {
|
||||
font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
|
||||
font-size: 80%;
|
||||
width: 4%;
|
||||
color: #888;
|
||||
}
|
||||
|
||||
table.commits td.author {
|
||||
width: 15%;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
table.commits td.author img {
|
||||
vertical-align: middle;
|
||||
border: 1px solid #ccc;
|
||||
padding: 1px;
|
||||
background-color: white;
|
||||
}
|
||||
|
||||
table.commits td.message a {
|
||||
color: black;
|
||||
}
|
||||
|
||||
table.commits td.message a:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
|
||||
table.commits td.date {
|
||||
width: 12%;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
/* Files
|
||||
/****************************************************************************/
|
||||
|
||||
#files {
|
||||
|
||||
}
|
||||
|
||||
#files .file {
|
||||
border: 1px solid #ccc;
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
#files .file .syntax{
|
||||
border:none;
|
||||
padding:0;
|
||||
}
|
||||
|
||||
#files .file .meta {
|
||||
padding:0 5px;
|
||||
height:33px;
|
||||
line-height:33px;
|
||||
font-size:12px;
|
||||
color:#333;
|
||||
background:url(/images/modules/commit/file_head.gif) 0 0 repeat-x #eee;
|
||||
text-shadow:1px 1px 0 rgba(255, 255, 255, 0.5);
|
||||
border-bottom: 1px solid #ccc;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
#files .file .meta .info {
|
||||
float: left;
|
||||
height:33px;
|
||||
line-height:33px;
|
||||
font-family: Monaco, "Courier New", "DejaVu Sans Mono", "Bitstream Vera Sans Mono", monospace;
|
||||
}
|
||||
|
||||
#files .file .meta .info span{
|
||||
padding-left:9px;
|
||||
margin-left:5px;
|
||||
background:url(/images/modules/commit/action_separator.png) 0 50% no-repeat;
|
||||
}
|
||||
|
||||
#files .file .meta .info span:first-child, #files .file .meta .info .icon + span{
|
||||
background:transparent;
|
||||
margin-left:0;
|
||||
padding-left:0;
|
||||
}
|
||||
|
||||
#files .file .meta .info span.icon{
|
||||
float:left;
|
||||
margin:5px 5px 0 0;
|
||||
padding:3px;
|
||||
background:#f7f7f7;
|
||||
border:1px solid #ccc;
|
||||
border-right-color:#e5e5e5;
|
||||
border-bottom-color:#e5e5e5;
|
||||
-webkit-border-radius:3px;
|
||||
-moz-border-radius:3px;
|
||||
border-radius:3px;
|
||||
line-height: 1em;
|
||||
}
|
||||
|
||||
#files .file .meta .actions {
|
||||
float: right;
|
||||
height:33px;
|
||||
line-height:33px;
|
||||
}
|
||||
|
||||
#files .file .meta .actions li{
|
||||
list-style-type:none;
|
||||
float:left;
|
||||
margin:0 0 0 7px;
|
||||
height:33px;
|
||||
line-height:33px;
|
||||
padding-left:9px;
|
||||
font-size:11px;
|
||||
background:url(/images/modules/commit/action_separator.png) 0 50% no-repeat;
|
||||
}
|
||||
|
||||
#files .file .meta .actions li:first-child{
|
||||
background:transparent;
|
||||
margin-left:0;
|
||||
padding-left:0;
|
||||
}
|
||||
|
||||
#files .file .meta .actions li a{
|
||||
font-weight:bold;
|
||||
}
|
||||
|
||||
#files .file .meta .actions li code{
|
||||
font-size:11px;
|
||||
}
|
||||
|
||||
#files .file .meta .actions li label input{
|
||||
position:relative;
|
||||
top:1px;
|
||||
}
|
||||
|
||||
#files .file .data {
|
||||
font-size: 80%;
|
||||
overflow: auto;
|
||||
background-color: #f8f8ff;
|
||||
}
|
||||
|
||||
#files .file .data.empty {
|
||||
font-size: 90%;
|
||||
padding:5px 10px;
|
||||
color:#777;
|
||||
}
|
||||
|
||||
#files .image {
|
||||
padding: 1.2em;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
#files .image img {
|
||||
max-width: 60em;
|
||||
}
|
||||
|
||||
#files .file .data pre, #files .file .line-data, #files .file .line-number {
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
font-size: 115%;
|
||||
}
|
||||
|
||||
#files .file .data .highlight {
|
||||
padding: 1em 0;
|
||||
}
|
||||
|
||||
#files .file .data .highlight div {
|
||||
padding-left: 1em;
|
||||
}
|
||||
|
||||
#files .file .data .line_numbers {
|
||||
background-color: #ececec;
|
||||
color: #aaa;
|
||||
padding: 1em .5em;
|
||||
border-right: 1px solid #ddd;
|
||||
text-align: right;
|
||||
}
|
||||
|
||||
#files .file .data td.line_numbers{
|
||||
padding:0 0.5em;
|
||||
font-family: 'Bitstream Vera Sans Mono', 'Courier', monospace;
|
||||
font-size: 115%;
|
||||
-moz-user-select:none;
|
||||
-khtml-user-select:none;
|
||||
user-select:none;
|
||||
}
|
||||
|
||||
#files .file .data .line_numbers span,
|
||||
#files .file .data .line_numbers a {
|
||||
color: #aaa;
|
||||
cursor: pointer;
|
||||
}
|
||||
@@ -14,6 +14,7 @@
|
||||
.highlight .gh { color: #999999 } /* Generic.Heading */
|
||||
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
||||
.highlight .gc { color: #999; background-color: #EAF2F5 }
|
||||
.highlight .go { color: #888888 } /* Generic.Output */
|
||||
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 290 B |
@@ -0,0 +1,33 @@
|
||||
<div class="guide">
|
||||
<div class="main">
|
||||
<div class="actions">
|
||||
<a href="/{{name}}">« Back</a>
|
||||
</div>
|
||||
<h1>Comparison of {{human_name}}: {{before}} → {{after}}</h1>
|
||||
<div id="files">
|
||||
<div class="file">
|
||||
<div class="meta">
|
||||
<div class="info">
|
||||
<span class="icon">
|
||||
<img alt="Txt" height="16" src="/images/txt.png" width="16">
|
||||
</span>
|
||||
{{path}}
|
||||
</div>
|
||||
</div>
|
||||
<div class="data highlight">
|
||||
<table cellpadding="0" cellspacing="0" width="100%">
|
||||
{{#lines}}
|
||||
<tr>
|
||||
<td class="line_numbers">{{ldln}}</td>
|
||||
<td class="line_numbers">{{rdln}}</td>
|
||||
<td width="100%">
|
||||
<pre><div class="{{class}}">{{line}}</div></pre>
|
||||
</td>
|
||||
</tr>
|
||||
{{/lines}}
|
||||
</table>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -0,0 +1,32 @@
|
||||
<div class="guide">
|
||||
<div class="main">
|
||||
<div class="actions">
|
||||
<a href="/{{name}}">« Back</a>
|
||||
</div>
|
||||
<h1>History of {{human_name}}</h1>
|
||||
<form method="post" action="/compare/{{name}}">
|
||||
<table class="commits" cellpadding="0" cellspacing="0">
|
||||
<tr>
|
||||
<th colspan="5">
|
||||
Select any two versions to <input type="submit" value="Compare" />
|
||||
</th>
|
||||
{{#versions}}
|
||||
<tr>
|
||||
<td class="checkbox">
|
||||
<input name="versions[]" type="checkbox" value="{{id}}" />
|
||||
</td>
|
||||
<td class="sha">
|
||||
<a href="/{{name}}/{{id}}">{{id7}}</a>
|
||||
</td>
|
||||
<td nowrap class="author">
|
||||
<img src="http://www.gravatar.com/avatar/{{gravatar}}?s=16" alt="Gravatar" />
|
||||
{{author}}
|
||||
</td>
|
||||
<td class="message">{{message}}</td>
|
||||
<td class="date">{{date}}</td>
|
||||
</tr>
|
||||
{{/versions}}
|
||||
</table>
|
||||
</form>
|
||||
</div>
|
||||
</div>
|
||||
@@ -22,11 +22,6 @@
|
||||
</div>
|
||||
</div>
|
||||
<div style="float: right;">
|
||||
<small>Versions:</small>
|
||||
<select id="versions_select" name="versions_select">
|
||||
{{#versions}}
|
||||
<option {{#selected}}selected="true" {{/selected}}value="/{{name}}/{{id}}">Version {{num}} ({{id7}}) by {{author}}</option>
|
||||
{{/versions}}
|
||||
</select>
|
||||
<a href="/history/{{name}}">View Revision History</a>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
module Precious
|
||||
module Views
|
||||
class Compare < Layout
|
||||
attr_reader :page, :diff, :versions
|
||||
|
||||
def human_name
|
||||
@page.title
|
||||
end
|
||||
|
||||
def title
|
||||
"A Page"
|
||||
end
|
||||
|
||||
def path
|
||||
@page.path
|
||||
end
|
||||
|
||||
def before
|
||||
@versions[1][0..6]
|
||||
end
|
||||
|
||||
def after
|
||||
@versions[0][0..6]
|
||||
end
|
||||
|
||||
def lines
|
||||
lines = []
|
||||
@diff.diff.split("\n")[2..-1].each_with_index do |line, line_index|
|
||||
lines << { :line => line,
|
||||
:class => line_class(line),
|
||||
:ldln => left_diff_line_number(0, line),
|
||||
:rdln => right_diff_line_number(0, line) }
|
||||
end
|
||||
lines
|
||||
end
|
||||
|
||||
# private
|
||||
|
||||
def line_class(line)
|
||||
if line =~ /^@@/
|
||||
'gc'
|
||||
elsif line =~ /^\+/
|
||||
'gi'
|
||||
elsif line =~ /^\-/
|
||||
'gd'
|
||||
else
|
||||
''
|
||||
end
|
||||
end
|
||||
|
||||
@left_diff_line_number = nil
|
||||
def left_diff_line_number(id, line)
|
||||
if line =~ /^@@/
|
||||
m, li = *line.match(/\-(\d+)/)
|
||||
@left_diff_line_number = li.to_i
|
||||
@current_line_number = @left_diff_line_number
|
||||
ret = '...'
|
||||
elsif line[0] == ?-
|
||||
ret = @left_diff_line_number.to_s
|
||||
@left_diff_line_number += 1
|
||||
@current_line_number = @left_diff_line_number - 1
|
||||
elsif line[0] == ?+
|
||||
ret = ' '
|
||||
else
|
||||
ret = @left_diff_line_number.to_s
|
||||
@left_diff_line_number += 1
|
||||
@current_line_number = @left_diff_line_number - 1
|
||||
end
|
||||
ret
|
||||
end
|
||||
|
||||
@right_diff_line_number = nil
|
||||
def right_diff_line_number(id, line)
|
||||
if line =~ /^@@/
|
||||
m, ri = *line.match(/\+(\d+)/)
|
||||
@right_diff_line_number = ri.to_i
|
||||
@current_line_number = @right_diff_line_number
|
||||
ret = '...'
|
||||
elsif line[0] == ?-
|
||||
ret = ' '
|
||||
elsif line[0] == ?+
|
||||
ret = @right_diff_line_number.to_s
|
||||
@right_diff_line_number += 1
|
||||
@current_line_number = @right_diff_line_number - 1
|
||||
else
|
||||
ret = @right_diff_line_number.to_s
|
||||
@right_diff_line_number += 1
|
||||
@current_line_number = @right_diff_line_number - 1
|
||||
end
|
||||
ret
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -0,0 +1,30 @@
|
||||
module Precious
|
||||
module Views
|
||||
class History < Layout
|
||||
attr_reader :page
|
||||
|
||||
def human_name
|
||||
@page.title
|
||||
end
|
||||
|
||||
def title
|
||||
"A Page"
|
||||
end
|
||||
|
||||
def versions
|
||||
i = @page.versions.size + 1
|
||||
@page.versions.map do |v|
|
||||
i -= 1
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:num => i,
|
||||
:selected => @page.version.id == v.id,
|
||||
:author => v.author.name,
|
||||
:message => v.message,
|
||||
:date => v.committed_date.strftime("%B %d, %Y"),
|
||||
:gravatar => Digest::MD5.hexdigest(v.author.email) }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -37,18 +37,6 @@ module Precious
|
||||
@footer ||= @page.footer
|
||||
@footer.format.to_s
|
||||
end
|
||||
|
||||
def versions
|
||||
i = @page.versions.size + 1
|
||||
@page.versions.map do |v|
|
||||
i -= 1
|
||||
{ :id => v.id,
|
||||
:id7 => v.id[0..6],
|
||||
:num => i,
|
||||
:selected => @page.version.id == v.id,
|
||||
:author => v.author.name }
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user