Merge branch 'history'
This commit is contained in:
@@ -1,3 +1,6 @@
|
|||||||
|
# stdlib
|
||||||
|
require 'digest/md5'
|
||||||
|
|
||||||
# external
|
# external
|
||||||
require 'grit'
|
require 'grit'
|
||||||
require 'github/markup'
|
require 'github/markup'
|
||||||
|
|||||||
@@ -78,6 +78,23 @@ module Precious
|
|||||||
wiki.preview_page("Preview", data, format).formatted_data
|
wiki.preview_page("Preview", data, format).formatted_data
|
||||||
end
|
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
|
get %r{/(.+?)/([0-9a-f]{40})} do
|
||||||
name = params[:captures][0]
|
name = params[:captures][0]
|
||||||
wiki = Gollum::Wiki.new($path)
|
wiki = Gollum::Wiki.new($path)
|
||||||
|
|||||||
@@ -487,4 +487,236 @@ label.wiki-label {
|
|||||||
|
|
||||||
.comment-form .comment{
|
.comment-form .comment{
|
||||||
margin:5px 0 0 0;
|
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 .gh { color: #999999 } /* Generic.Heading */
|
||||||
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */
|
||||||
.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */
|
.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 .go { color: #888888 } /* Generic.Output */
|
||||||
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
.highlight .gp { color: #555555 } /* Generic.Prompt */
|
||||||
.highlight .gs { font-weight: bold } /* Generic.Strong */
|
.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>
|
</div>
|
||||||
<div style="float: right;">
|
<div style="float: right;">
|
||||||
<small>Versions:</small>
|
<a href="/history/{{name}}">View Revision History</a>
|
||||||
<select id="versions_select" name="versions_select">
|
|
||||||
{{#versions}}
|
|
||||||
<option {{#selected}}selected="true" {{/selected}}value="/{{name}}/{{id}}">Version {{num}} ({{id7}}) by {{author}}</option>
|
|
||||||
{{/versions}}
|
|
||||||
</select>
|
|
||||||
</div>
|
</div>
|
||||||
</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 ||= @page.footer
|
||||||
@footer.format.to_s
|
@footer.format.to_s
|
||||||
end
|
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
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user