Merge pull request #574 from dekimsey/local-gravatar-identicons
Extendable user-icons with optional identicon js library.
This commit is contained in:
@@ -73,6 +73,10 @@ opts = OptionParser.new do |opts|
|
|||||||
wiki_options[:mathjax] = true
|
wiki_options[:mathjax] = true
|
||||||
end
|
end
|
||||||
|
|
||||||
|
opts.on("--user-icons [SOURCE]", "Set the history user icons. Valid values: gravatar, identicon, none. Default: none.") do
|
||||||
|
wiki_options[:user_icons] = source
|
||||||
|
end
|
||||||
|
|
||||||
opts.on("--show-all", "Shows all files in file view. By default only valid pages are shown.") do
|
opts.on("--show-all", "Shows all files in file view. By default only valid pages are shown.") do
|
||||||
wiki_options[:show_all] = true
|
wiki_options[:show_all] = true
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ Gem::Specification.new do |s|
|
|||||||
lib/gollum/frontend/public/gollum/css/gollum.css
|
lib/gollum/frontend/public/gollum/css/gollum.css
|
||||||
lib/gollum/frontend/public/gollum/css/ie7.css
|
lib/gollum/frontend/public/gollum/css/ie7.css
|
||||||
lib/gollum/frontend/public/gollum/css/template.css
|
lib/gollum/frontend/public/gollum/css/template.css
|
||||||
|
lib/gollum/frontend/public/gollum/images/man_24.png
|
||||||
lib/gollum/frontend/public/gollum/images/dirty-shade.png
|
lib/gollum/frontend/public/gollum/images/dirty-shade.png
|
||||||
lib/gollum/frontend/public/gollum/images/fileview/document.png
|
lib/gollum/frontend/public/gollum/images/fileview/document.png
|
||||||
lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png
|
lib/gollum/frontend/public/gollum/images/fileview/folder-horizontal.png
|
||||||
@@ -91,6 +92,7 @@ Gem::Specification.new do |s|
|
|||||||
lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js
|
lib/gollum/frontend/public/gollum/javascript/gollum.dialog.js
|
||||||
lib/gollum/frontend/public/gollum/javascript/gollum.js
|
lib/gollum/frontend/public/gollum/javascript/gollum.js
|
||||||
lib/gollum/frontend/public/gollum/javascript/gollum.placeholder.js
|
lib/gollum/frontend/public/gollum/javascript/gollum.placeholder.js
|
||||||
|
lib/gollum/frontend/public/gollum/javascript/identicon_canvas.js
|
||||||
lib/gollum/frontend/public/gollum/javascript/jquery-1.7.2.min.js
|
lib/gollum/frontend/public/gollum/javascript/jquery-1.7.2.min.js
|
||||||
lib/gollum/frontend/public/gollum/javascript/jquery.color.js
|
lib/gollum/frontend/public/gollum/javascript/jquery.color.js
|
||||||
lib/gollum/frontend/public/gollum/javascript/mousetrap.min.js
|
lib/gollum/frontend/public/gollum/javascript/mousetrap.min.js
|
||||||
@@ -443,6 +445,9 @@ Gem::Specification.new do |s|
|
|||||||
lib/gollum/frontend/templates/pages.mustache
|
lib/gollum/frontend/templates/pages.mustache
|
||||||
lib/gollum/frontend/templates/search.mustache
|
lib/gollum/frontend/templates/search.mustache
|
||||||
lib/gollum/frontend/templates/searchbar.mustache
|
lib/gollum/frontend/templates/searchbar.mustache
|
||||||
|
lib/gollum/frontend/templates/history_authors/gravatar.mustache
|
||||||
|
lib/gollum/frontend/templates/history_authors/identicon.mustache
|
||||||
|
lib/gollum/frontend/templates/history_authors/none.mustache
|
||||||
lib/gollum/frontend/uri_encode_component.rb
|
lib/gollum/frontend/uri_encode_component.rb
|
||||||
lib/gollum/frontend/views/compare.rb
|
lib/gollum/frontend/views/compare.rb
|
||||||
lib/gollum/frontend/views/create.rb
|
lib/gollum/frontend/views/create.rb
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
# ~*~ encoding: utf-8 ~*~
|
# ~*~ encoding: utf-8 ~*~
|
||||||
# stdlib
|
# stdlib
|
||||||
require 'digest/md5'
|
require 'digest/md5'
|
||||||
|
require 'digest/sha1'
|
||||||
require 'ostruct'
|
require 'ostruct'
|
||||||
|
|
||||||
# external
|
# external
|
||||||
|
|||||||
Binary file not shown.
|
After Width: | Height: | Size: 376 B |
@@ -228,4 +228,21 @@ $(document).ready(function() {
|
|||||||
});
|
});
|
||||||
$.GollumEditor({ NewFile: true, MarkupType: default_markup });
|
$.GollumEditor({ NewFile: true, MarkupType: default_markup });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if( $('#wiki-history').length ){
|
||||||
|
var lookup = {};
|
||||||
|
$('img.identicon').each(function(index, element){
|
||||||
|
var $item = $(element);
|
||||||
|
var code = parseInt($item.data('identicon'), 10);
|
||||||
|
var img_bin = lookup[code];
|
||||||
|
if( img_bin === undefined ){
|
||||||
|
var size = 16;
|
||||||
|
var canvas = $('<canvas width=16 height=16/>').get(0);
|
||||||
|
render_identicon(canvas, code, 16);
|
||||||
|
img_bin = canvas.toDataURL("image/png");
|
||||||
|
lookup[code] = img_bin;
|
||||||
|
}
|
||||||
|
$item.attr('src', img_bin);
|
||||||
|
});
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -0,0 +1,111 @@
|
|||||||
|
/*
|
||||||
|
Client-side Canvas tag based Identicon rendering code
|
||||||
|
|
||||||
|
@author Don Park
|
||||||
|
@version 0.2
|
||||||
|
@date January 21th, 2007
|
||||||
|
*/
|
||||||
|
|
||||||
|
var patch0 = new Array( 0, 4, 24, 20 );
|
||||||
|
var patch1 = new Array( 0, 4, 20 );
|
||||||
|
var patch2 = new Array( 2, 24, 20 );
|
||||||
|
var patch3 = new Array( 0, 2, 20, 22 );
|
||||||
|
var patch4 = new Array( 2, 14, 22, 10 );
|
||||||
|
var patch5 = new Array( 0, 14, 24, 22 );
|
||||||
|
var patch6 = new Array( 2, 24, 22, 13, 11, 22, 20 );
|
||||||
|
var patch7 = new Array( 0, 14, 22 );
|
||||||
|
var patch8 = new Array( 6, 8, 18, 16 );
|
||||||
|
var patch9 = new Array( 4, 20, 10, 12, 2 );
|
||||||
|
var patch10 = new Array( 0, 2, 12, 10 );
|
||||||
|
var patch11 = new Array( 10, 14, 22 );
|
||||||
|
var patch12 = new Array( 20, 12, 24 );
|
||||||
|
var patch13 = new Array( 10, 2, 12 );
|
||||||
|
var patch14 = new Array( 0, 2, 10 );
|
||||||
|
var patchTypes = new Array( patch0, patch1, patch2, patch3, patch4,
|
||||||
|
patch5, patch6, patch7, patch8, patch9, patch10, patch11,
|
||||||
|
patch12, patch13, patch14, patch0 );
|
||||||
|
var centerPatchTypes = new Array(0, 4, 8, 15);
|
||||||
|
|
||||||
|
function render_identicon_patch(ctx, x, y, size, patch, turn, invert, foreColor, backColor) {
|
||||||
|
patch %= patchTypes.length;
|
||||||
|
turn %= 4;
|
||||||
|
if (patch == 15)
|
||||||
|
invert = !invert;
|
||||||
|
|
||||||
|
var vertices = patchTypes[patch];
|
||||||
|
var offset = size / 2;
|
||||||
|
var scale = size / 4;
|
||||||
|
|
||||||
|
ctx.save();
|
||||||
|
|
||||||
|
// paint background
|
||||||
|
ctx.fillStyle = invert ? foreColor : backColor;
|
||||||
|
ctx.fillRect(x, y, size, size);
|
||||||
|
|
||||||
|
// build patch path
|
||||||
|
ctx.translate(x + offset, y + offset);
|
||||||
|
ctx.rotate(turn * Math.PI / 2);
|
||||||
|
ctx.beginPath();
|
||||||
|
ctx.moveTo((vertices[0] % 5 * scale - offset), (Math.floor(vertices[0] / 5) * scale - offset));
|
||||||
|
for (var i = 1; i < vertices.length; i++)
|
||||||
|
ctx.lineTo((vertices[i] % 5 * scale - offset), (Math.floor(vertices[i] / 5) * scale - offset));
|
||||||
|
ctx.closePath();
|
||||||
|
|
||||||
|
// offset and rotate coordinate space by patch position (x, y) and
|
||||||
|
// 'turn' before rendering patch shape
|
||||||
|
|
||||||
|
// render rotated patch using fore color (back color if inverted)
|
||||||
|
ctx.fillStyle = invert ? backColor : foreColor;
|
||||||
|
ctx.fill();
|
||||||
|
|
||||||
|
// restore rotation
|
||||||
|
ctx.restore();
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_identicon(node, code, size) {
|
||||||
|
if (!node || !code || !size) return;
|
||||||
|
|
||||||
|
var patchSize = size / 3;
|
||||||
|
var middleType = centerPatchTypes[code & 3];
|
||||||
|
var middleInvert = ((code >> 2) & 1) != 0;
|
||||||
|
var cornerType = (code >> 3) & 15;
|
||||||
|
var cornerInvert = ((code >> 7) & 1) != 0;
|
||||||
|
var cornerTurn = (code >> 8) & 3;
|
||||||
|
var sideType = (code >> 10) & 15;
|
||||||
|
var sideInvert = ((code >> 14) & 1) != 0;
|
||||||
|
var sideTurn = (code >> 15) & 3;
|
||||||
|
var blue = (code >> 16) & 31;
|
||||||
|
var green = (code >> 21) & 31;
|
||||||
|
var red = (code >> 27) & 31;
|
||||||
|
var foreColor = "rgb(" + (red << 3) + "," + (green << 3) + "," + (blue << 3) + ")";
|
||||||
|
var backColor = "rgb(255,255,255)";
|
||||||
|
|
||||||
|
var ctx = node.getContext("2d");
|
||||||
|
|
||||||
|
// middle patch
|
||||||
|
render_identicon_patch(ctx, patchSize, patchSize, patchSize, middleType, 0, middleInvert, foreColor, backColor);
|
||||||
|
// side patchs, starting from top and moving clock-wise
|
||||||
|
render_identicon_patch(ctx, patchSize, 0, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, patchSize * 2, patchSize, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, patchSize, patchSize * 2, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, 0, patchSize, patchSize, sideType, sideTurn++, sideInvert, foreColor, backColor);
|
||||||
|
// corner patchs, starting from top left and moving clock-wise
|
||||||
|
render_identicon_patch(ctx, 0, 0, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, patchSize * 2, 0, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, patchSize * 2, patchSize * 2, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
|
||||||
|
render_identicon_patch(ctx, 0, patchSize * 2, patchSize, cornerType, cornerTurn++, cornerInvert, foreColor, backColor);
|
||||||
|
}
|
||||||
|
|
||||||
|
function render_identicon_canvases(prefix) {
|
||||||
|
var canvases = document.getElementsByTagName("canvas");
|
||||||
|
var n = canvases.length;
|
||||||
|
for (var i = 0; i < n; i++) {
|
||||||
|
var node = canvases[i];
|
||||||
|
if (node.title && node.title.indexOf(prefix) == 0) {
|
||||||
|
if (node.style.display == 'none') node.style.display = "inline";
|
||||||
|
var code = node.title.substring(prefix.length) * 1;
|
||||||
|
var size = node.width;
|
||||||
|
render_identicon(node, code, size);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -30,11 +30,7 @@
|
|||||||
<input type="checkbox" name="versions[]" value="{{id}}">
|
<input type="checkbox" name="versions[]" value="{{id}}">
|
||||||
</td>
|
</td>
|
||||||
<td class="author">
|
<td class="author">
|
||||||
<a href="javascript:void(0)">
|
{{>author_template}}
|
||||||
<img src="https://secure.gravatar.com/avatar/{{gravatar}}?s=16"
|
|
||||||
alt="avatar: {{author}}" class="mini-gravatar">
|
|
||||||
<span class="username">{{author}}</span>
|
|
||||||
</a>
|
|
||||||
</td>
|
</td>
|
||||||
<td class="commit-name">
|
<td class="commit-name">
|
||||||
<span class="time-elapsed">{{date}}:</span>
|
<span class="time-elapsed">{{date}}:</span>
|
||||||
|
|||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<a href="javascript:void(0)">
|
||||||
|
<img src="https://secure.gravatar.com/avatar/{{gravatar}}?s=16"
|
||||||
|
alt="avatar: {{author}}" class="mini-gravatar"/>
|
||||||
|
<span class="username">{{author}}</span>
|
||||||
|
</a>
|
||||||
@@ -0,0 +1,5 @@
|
|||||||
|
<a href="javascript:void(0)">
|
||||||
|
<img src="{{base_url}}/images/man_24.png" alt="avatar: {{author}}"
|
||||||
|
class="mini-gravatar identicon" data-identicon="{{identicon}}"/>
|
||||||
|
<span class="username">{{author}}</span>
|
||||||
|
</a>
|
||||||
@@ -0,0 +1,3 @@
|
|||||||
|
<a href="javascript:void(0)">
|
||||||
|
<span class="username">{{author}}</span>
|
||||||
|
</a>
|
||||||
@@ -19,6 +19,9 @@
|
|||||||
<script type="text/javascript" src="{{base_url}}/javascript/gollum.dialog.js"></script>
|
<script type="text/javascript" src="{{base_url}}/javascript/gollum.dialog.js"></script>
|
||||||
<script type="text/javascript" src="{{base_url}}/javascript/gollum.placeholder.js"></script>
|
<script type="text/javascript" src="{{base_url}}/javascript/gollum.placeholder.js"></script>
|
||||||
<script type="text/javascript" src="{{base_url}}/javascript/editor/gollum.editor.js"></script>
|
<script type="text/javascript" src="{{base_url}}/javascript/editor/gollum.editor.js"></script>
|
||||||
|
{{#use_identicon}}
|
||||||
|
<script type="text/javascript" src="{{base_url}}/javascript/identicon_canvas.js"></script>
|
||||||
|
{{/use_identicon}}
|
||||||
{{#mathjax}}
|
{{#mathjax}}
|
||||||
<script type="text/x-mathjax-config">
|
<script type="text/x-mathjax-config">
|
||||||
MathJax.Hub.Config({
|
MathJax.Hub.Config({
|
||||||
|
|||||||
@@ -20,7 +20,30 @@ module Precious
|
|||||||
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
:author => v.author.name.respond_to?(:force_encoding) ? v.author.name.force_encoding('UTF-8') : v.author.name,
|
||||||
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
:message => v.message.respond_to?(:force_encoding) ? v.message.force_encoding('UTF-8') : v.message,
|
||||||
:date => v.authored_date.strftime("%B %d, %Y"),
|
:date => v.authored_date.strftime("%B %d, %Y"),
|
||||||
:gravatar => Digest::MD5.hexdigest(v.author.email) }
|
:gravatar => Digest::MD5.hexdigest(v.author.email),
|
||||||
|
:identicon => self._identicon_code(v.author.email),
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def _identicon_code(blob)
|
||||||
|
sha_bytes = Digest::SHA1.hexdigest(blob + @request.host)[0,20]
|
||||||
|
# Thanks donpark's IdenticonUtil.java for this.
|
||||||
|
return ((sha_bytes[0] & 0xFF) << 24) |
|
||||||
|
((sha_bytes[1] & 0xFF) << 16) |
|
||||||
|
((sha_bytes[2] & 0xFF) << 8) |
|
||||||
|
(sha_bytes[3] & 0xFF)
|
||||||
|
end
|
||||||
|
|
||||||
|
def use_identicon
|
||||||
|
@page.wiki.user_icons == 'identicon'
|
||||||
|
end
|
||||||
|
|
||||||
|
def partial(name)
|
||||||
|
if name == :author_template
|
||||||
|
self.class.partial("history_authors/#{@page.wiki.user_icons}")
|
||||||
|
else
|
||||||
|
super
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -93,6 +93,10 @@ module Precious
|
|||||||
@css
|
@css
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def use_identicon
|
||||||
|
@page.wiki.user_icons == 'identicon'
|
||||||
|
end
|
||||||
|
|
||||||
# Access to embedded metadata.
|
# Access to embedded metadata.
|
||||||
#
|
#
|
||||||
# Examples
|
# Examples
|
||||||
|
|||||||
@@ -163,6 +163,8 @@ module Gollum
|
|||||||
# :ref - String the repository ref to retrieve pages from
|
# :ref - String the repository ref to retrieve pages from
|
||||||
# :ws_subs - Array of chars to sub for ws in filenames.
|
# :ws_subs - Array of chars to sub for ws in filenames.
|
||||||
# :mathjax - Set to false to disable mathjax.
|
# :mathjax - Set to false to disable mathjax.
|
||||||
|
# :user_icons - Enable user icons on the history page. [gravatar, identicon, none].
|
||||||
|
# Default: none
|
||||||
# :show_all - Show all files in file view, not just valid pages.
|
# :show_all - Show all files in file view, not just valid pages.
|
||||||
# Default: false
|
# Default: false
|
||||||
# :collapse_tree - Start with collapsed file view. Default: false
|
# :collapse_tree - Start with collapsed file view. Default: false
|
||||||
@@ -201,6 +203,7 @@ module Gollum
|
|||||||
@collapse_tree = options.fetch :collapse_tree, false
|
@collapse_tree = options.fetch :collapse_tree, false
|
||||||
@css = options.fetch :css, false
|
@css = options.fetch :css, false
|
||||||
@h1_title = options.fetch :h1_title, false
|
@h1_title = options.fetch :h1_title, false
|
||||||
|
@user_icons = options.fetch :user_icons, 'none'
|
||||||
end
|
end
|
||||||
|
|
||||||
# Public: check whether the wiki's git repo exists on the filesystem.
|
# Public: check whether the wiki's git repo exists on the filesystem.
|
||||||
@@ -609,6 +612,9 @@ module Gollum
|
|||||||
# Toggles mathjax.
|
# Toggles mathjax.
|
||||||
attr_reader :mathjax
|
attr_reader :mathjax
|
||||||
|
|
||||||
|
# Toggles user icons. Default: 'gravatar'
|
||||||
|
attr_reader :user_icons
|
||||||
|
|
||||||
# Toggles showing all files in files view. Default is false.
|
# Toggles showing all files in files view. Default is false.
|
||||||
# When false, only valid pages in the git repo are displayed.
|
# When false, only valid pages in the git repo are displayed.
|
||||||
attr_reader :show_all
|
attr_reader :show_all
|
||||||
|
|||||||
@@ -30,3 +30,23 @@ http://www.thecssninja.com/css/css-tree-menu
|
|||||||
http://www.thecssninja.com/demo/license.txt
|
http://www.thecssninja.com/demo/license.txt
|
||||||
|
|
||||||
lib/gollum/frontend/public/css/_styles.css
|
lib/gollum/frontend/public/css/_styles.css
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Default profile image (man_24.png) is used under the CC BY-SA 3.0 Unported license.
|
||||||
|
|
||||||
|
CC BY-SA 3.0 Unported
|
||||||
|
http://blog.twg.ca/2010/11/retina-display-icon-set/
|
||||||
|
http://creativecommons.org/licenses/by-sa/3.0/legalcode.txt
|
||||||
|
|
||||||
|
lib/gollum/frontend/public/images/man_24.png
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
The canvas_identicon code is used under the MIT license.
|
||||||
|
|
||||||
|
https://github.com/donpark/identicon/blob/master/identicon-canvas/identicon_canvas.js
|
||||||
|
https://github.com/donpark/identicon/blob/master/README
|
||||||
|
|
||||||
|
lib/gollum/frontend/public/gollum/javascript/identicon_canvas.js
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user