ginatra 3.0.1 → 4.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.gitignore +18 -15
- data/.travis.yml +7 -6
- data/CONTRIBUTING.md +30 -0
- data/Gemfile +1 -9
- data/LICENSE.txt +30 -0
- data/README.md +63 -114
- data/Rakefile +10 -12
- data/bin/ginatra +79 -63
- data/config.ru +35 -3
- data/ginatra.gemspec +29 -18
- data/lib/ginatra.rb +161 -148
- data/lib/ginatra/config.rb +18 -121
- data/lib/ginatra/errors.rb +10 -0
- data/lib/ginatra/helpers.rb +154 -139
- data/lib/ginatra/repo.rb +67 -82
- data/lib/ginatra/repo_list.rb +25 -18
- data/lib/ginatra/repo_stats.rb +93 -0
- data/lib/ginatra/version.rb +4 -0
- data/lib/git/webby.rb +292 -0
- data/lib/git/webby/extensions.rb +10 -0
- data/lib/git/webby/http_backend.rb +177 -0
- data/lib/sinatra/partials.rb +1 -1
- data/public/css/application.css +6 -0
- data/public/css/custom.css +57 -0
- data/public/css/lib/bootstrap-responsive.min.css +9 -0
- data/public/css/lib/bootstrap.min.css +9 -0
- data/public/css/lib/highlight.css +209 -0
- data/public/img/glyphicons-halflings-white.png +0 -0
- data/public/img/glyphicons-halflings.png +0 -0
- data/public/img/spin.gif +0 -0
- data/public/js/application.js +5 -0
- data/public/js/custom.js +51 -0
- data/public/js/lib/bootstrap.min.js +6 -0
- data/public/js/lib/jquery.lazyload.min.js +2 -0
- data/public/js/lib/jquery.min.js +2 -0
- data/public/js/lib/jquery.pjax.js +739 -0
- data/repos/README.md +21 -8
- data/spec/ginatra/helpers_spec.rb +95 -0
- data/spec/ginatra/repo_list_spec.rb +66 -0
- data/spec/ginatra/repo_spec.rb +78 -0
- data/spec/ginatra/repo_stats_spec.rb +27 -0
- data/spec/ginatra_spec.rb +121 -0
- data/spec/spec_helper.rb +8 -17
- data/views/404.erb +18 -0
- data/views/500.erb +18 -0
- data/views/_footer.erb +7 -0
- data/views/_header.erb +12 -6
- data/views/_tree_nav.erb +53 -0
- data/views/atom.erb +32 -0
- data/views/blob.erb +27 -8
- data/views/commit.erb +95 -17
- data/views/empty_repo.erb +10 -0
- data/views/index.erb +27 -11
- data/views/layout.erb +16 -20
- data/views/log.erb +74 -54
- data/views/stats.erb +89 -0
- data/views/tree.erb +32 -20
- metadata +168 -94
- data/bin/ginatra-daemon +0 -87
- data/bin/ginatra-directory +0 -55
- data/bin/ginatra-server +0 -27
- data/bin/ginatra-setup +0 -28
- data/lib/ginatra/graph_commit.rb +0 -77
- data/public/img/add.png +0 -0
- data/public/img/diff.png +0 -0
- data/public/img/doc.png +0 -0
- data/public/img/rm.png +0 -0
- data/public/img/tree.png +0 -0
- data/public/src/branch-graph.js +0 -170
- data/public/src/colour.css +0 -86
- data/public/src/commit.css +0 -211
- data/public/src/ginatra.js +0 -7
- data/public/src/github.css +0 -129
- data/public/src/graph.css +0 -9
- data/public/src/highlight.pack.js +0 -1
- data/public/src/index.css +0 -92
- data/public/src/lists.css +0 -25
- data/public/src/raphael.js +0 -7
- data/public/src/reset.css +0 -49
- data/public/src/table.css +0 -33
- data/public/src/type.css +0 -30
- data/rackup.ru +0 -5
- data/spec/graph_commit_spec.rb +0 -54
- data/spec/repo_list_spec.rb +0 -84
- data/spec/repo_spec.rb +0 -61
- data/views/_actor_box.erb +0 -13
- data/views/_commit_info_box.erb +0 -27
- data/views/_tree_part.erb +0 -11
- data/views/atom.builder +0 -32
- data/views/graph.erb +0 -15
data/bin/ginatra-daemon
DELETED
@@ -1,87 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "ginatra"
|
4
|
-
|
5
|
-
module Ginatra::Daemon
|
6
|
-
|
7
|
-
SYMLINK_DIR = File.expand_path('~/.ginatra/symlinks')
|
8
|
-
PID_FILE = File.expand_path('~/.ginatra/daemon.pid')
|
9
|
-
HELP = <<HELP
|
10
|
-
Usage: ginatra-daemon [ start | stop | restart | status ]
|
11
|
-
|
12
|
-
Commands:
|
13
|
-
start - Starts the Git Daemon servimg Ginatra's Repositories
|
14
|
-
stop - Stops the Git Daemon
|
15
|
-
restart - Restarts the Git Daemon
|
16
|
-
status - Is the Git Daemon on or off?
|
17
|
-
|
18
|
-
HELP
|
19
|
-
|
20
|
-
def self.start
|
21
|
-
# Create Symlinks
|
22
|
-
FileUtils.mkdir_p(SYMLINK_DIR)
|
23
|
-
logger.info "Creating Symlinks"
|
24
|
-
dirs = Ginatra::Config.git_dirs.map{|path| Dir.glob(path)}.flatten
|
25
|
-
FileUtils.ln_sf(dirs, SYMLINK_DIR)
|
26
|
-
# Start Process
|
27
|
-
if File.exists?(PID_FILE)
|
28
|
-
logger.warn "Ginatra Daemon running at pid:#{File.new(PID_FILE).read}"
|
29
|
-
else
|
30
|
-
logger.info "Starting ginatra-daemon"
|
31
|
-
Kernel.fork do
|
32
|
-
system "git daemon --reuseaddr --base-path=#{SYMLINK_DIR} --pid-file=#{PID_FILE} #{SYMLINK_DIR}/*"
|
33
|
-
end
|
34
|
-
end
|
35
|
-
end
|
36
|
-
|
37
|
-
def self.stop
|
38
|
-
# Stop Process
|
39
|
-
pid = File.new(PID_FILE).read.to_i
|
40
|
-
logger.warn "Sending INT to #{pid}"
|
41
|
-
FileUtils.rm(PID_FILE)
|
42
|
-
Process.kill(:INT, pid)
|
43
|
-
# Remove Symlinks
|
44
|
-
links = Dir.glob("#{SYMLINK_DIR}/*")
|
45
|
-
logger.warn "Removing Symlinks"
|
46
|
-
FileUtils.rm(links)
|
47
|
-
end
|
48
|
-
|
49
|
-
def self.restart
|
50
|
-
self.stop
|
51
|
-
self.start
|
52
|
-
end
|
53
|
-
|
54
|
-
def self.status
|
55
|
-
logger.level = Logger::INFO
|
56
|
-
if File.exists?(PID_FILE)
|
57
|
-
logger.info "Ginatra Daemon running at pid:#{File.new(PID_FILE).read}"
|
58
|
-
else
|
59
|
-
logger.info "Ginatra Daemon not running"
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
def self.logger
|
64
|
-
Ginatra::Config.logger
|
65
|
-
end
|
66
|
-
|
67
|
-
def self.execute(command)
|
68
|
-
case command
|
69
|
-
when "start"
|
70
|
-
start
|
71
|
-
when "stop"
|
72
|
-
stop
|
73
|
-
when "restart"
|
74
|
-
restart
|
75
|
-
when "status"
|
76
|
-
status
|
77
|
-
else
|
78
|
-
puts Ginatra::Daemon::HELP
|
79
|
-
end
|
80
|
-
end
|
81
|
-
|
82
|
-
end
|
83
|
-
|
84
|
-
Ginatra::Daemon.execute ARGV[0]
|
85
|
-
|
86
|
-
|
87
|
-
|
data/bin/ginatra-directory
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "ginatra"
|
4
|
-
|
5
|
-
module Ginatra::Directory
|
6
|
-
|
7
|
-
HELP = <<HELP
|
8
|
-
Usage: ginatra-directory [ list | add <globs> | remove <globs> ]
|
9
|
-
|
10
|
-
Commands:
|
11
|
-
add - Adds the <globs> to the array of dirs that Ginatra
|
12
|
-
looks in for repositories.
|
13
|
-
remove - Removes the <globs> from the aforementioned array.
|
14
|
-
list - Lists the globs Ginatra looks in for repositories
|
15
|
-
|
16
|
-
HELP
|
17
|
-
|
18
|
-
def self.add(globs)
|
19
|
-
Ginatra::Config.load!
|
20
|
-
Ginatra::Config[:git_dirs] += globs
|
21
|
-
Ginatra::Config.logger.info "Added #{globs.join(" ")} to your config"
|
22
|
-
Ginatra::Config.dump!
|
23
|
-
end
|
24
|
-
|
25
|
-
def self.remove(globs)
|
26
|
-
Ginatra::Config.load!
|
27
|
-
globs.each do |glob|
|
28
|
-
Ginatra::Config[:git_dirs].delete(glob)
|
29
|
-
end
|
30
|
-
Ginatra::Config.logger.info "Removed #{globs.join(" ")} from your config"
|
31
|
-
Ginatra::Config.dump!
|
32
|
-
end
|
33
|
-
|
34
|
-
def self.list
|
35
|
-
Ginatra::Config.load!
|
36
|
-
puts "Directories Ginatra will look for repos in:"
|
37
|
-
puts Ginatra::Config[:git_dirs].map{|r| " - #{r}"}.join("\n")
|
38
|
-
puts ""
|
39
|
-
end
|
40
|
-
|
41
|
-
def self.execute(command, args)
|
42
|
-
case command
|
43
|
-
when "add"
|
44
|
-
add(args)
|
45
|
-
when "remove"
|
46
|
-
remove(args)
|
47
|
-
when "list"
|
48
|
-
list
|
49
|
-
else
|
50
|
-
puts Ginatra::Directory::HELP
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
Ginatra::Directory.execute ARGV[0], ARGV[1..-1]
|
data/bin/ginatra-server
DELETED
@@ -1,27 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "ginatra"
|
4
|
-
require "vegas"
|
5
|
-
|
6
|
-
Vegas::Runner.new(Ginatra::App, 'ginatra-server', {:port => Ginatra::Config.port, :host => Ginatra::Config.host}) do |runner, opts, app|
|
7
|
-
|
8
|
-
opts.banner = "Usage: ginatra-server [[options] start | stop | status]"
|
9
|
-
|
10
|
-
opts.separator " start - Start the Ginatra HTTP Server"
|
11
|
-
opts.separator " stop - Stop the Ginatra Server"
|
12
|
-
opts.separator " status - How's your Ginatra Server holding up?"
|
13
|
-
|
14
|
-
if ARGV[-1] == "start"
|
15
|
-
elsif ARGV[-1] == "stop"
|
16
|
-
runner.kill!
|
17
|
-
exit
|
18
|
-
elsif ARGV[-1] == "status"
|
19
|
-
runner.status
|
20
|
-
exit!
|
21
|
-
elsif ARGV.length == 0 || ARGV[-1] !~ /^(start|stop|status)$/
|
22
|
-
runner.options[:start] = false
|
23
|
-
at_exit { puts opts }
|
24
|
-
end
|
25
|
-
|
26
|
-
end
|
27
|
-
|
data/bin/ginatra-setup
DELETED
@@ -1,28 +0,0 @@
|
|
1
|
-
#!/usr/bin/env ruby
|
2
|
-
|
3
|
-
require "ginatra/config"
|
4
|
-
require "rbconfig"
|
5
|
-
|
6
|
-
unless ENV['TRAVIS']
|
7
|
-
if RbConfig::CONFIG["ruby_version"] < "1.9"
|
8
|
-
$stderr.puts "You need Ruby 1.9.2 to run ginatra"
|
9
|
-
exit(1)
|
10
|
-
end
|
11
|
-
|
12
|
-
if `which pygmentize` !~ /pygmentize/
|
13
|
-
$stderr.puts "You need Pygmentize to run ginatra"
|
14
|
-
exit(1)
|
15
|
-
end
|
16
|
-
|
17
|
-
if `git --version` < "git version 1.6.3"
|
18
|
-
$stderr.puts "You need at least git version 1.6.3 to run ginatra"
|
19
|
-
exit(1)
|
20
|
-
end
|
21
|
-
|
22
|
-
puts "checked deps"
|
23
|
-
end
|
24
|
-
|
25
|
-
Ginatra::Config.safe_setup
|
26
|
-
puts "installed config"
|
27
|
-
|
28
|
-
exit(0)
|
data/lib/ginatra/graph_commit.rb
DELETED
@@ -1,77 +0,0 @@
|
|
1
|
-
require "grit"
|
2
|
-
|
3
|
-
module Ginatra
|
4
|
-
|
5
|
-
class GraphCommit
|
6
|
-
attr_accessor :time, :space
|
7
|
-
def initialize(commit)
|
8
|
-
@_commit = commit
|
9
|
-
@time = -1
|
10
|
-
@space = 0
|
11
|
-
end
|
12
|
-
|
13
|
-
def method_missing(m, *args, &block)
|
14
|
-
@_commit.send(m, *args, &block)
|
15
|
-
end
|
16
|
-
|
17
|
-
# Method is adding time and space on the
|
18
|
-
# list of commits. As well as returns date list
|
19
|
-
# corelated with time set on commits.
|
20
|
-
#
|
21
|
-
# @param [Array<GraphCommit>] comits to index
|
22
|
-
#
|
23
|
-
# @return [Array<TimeDate>] list of commit dates corelated with time on commits
|
24
|
-
def self.index_commits(commits)
|
25
|
-
days, heads = [], []
|
26
|
-
map = {}
|
27
|
-
|
28
|
-
commits.reverse.each_with_index do |c,i|
|
29
|
-
c.time = i
|
30
|
-
days[i]=c.committed_date
|
31
|
-
map[c.id] = c
|
32
|
-
heads += c.refs unless c.refs.nil?
|
33
|
-
end
|
34
|
-
|
35
|
-
heads.select!{|h|h.is_a? Grit::Head or h.is_a? Grit::Remote}
|
36
|
-
# sort heads so the master is top and current branches are closer
|
37
|
-
heads.sort! do |a,b|
|
38
|
-
if a.name == "master"
|
39
|
-
-1
|
40
|
-
elsif b.name == "master"
|
41
|
-
1
|
42
|
-
else
|
43
|
-
b.commit.committed_date <=> a.commit.committed_date
|
44
|
-
end
|
45
|
-
end
|
46
|
-
|
47
|
-
j=0
|
48
|
-
heads.each do |h|
|
49
|
-
if map.include? h.commit.id then
|
50
|
-
j = mark_chain(j+=1,map[h.commit.id], map)
|
51
|
-
end
|
52
|
-
end
|
53
|
-
return days
|
54
|
-
end
|
55
|
-
|
56
|
-
# Add space mark on commit and its parents
|
57
|
-
#
|
58
|
-
# @param [Fixnum] space (row on the graph) to be set
|
59
|
-
# @param [GraphCommit] the commit object.
|
60
|
-
# @param [Hash<String,GraphCommit>] map of commits
|
61
|
-
#
|
62
|
-
# @return [Fixnum] max space used.
|
63
|
-
def self.mark_chain(mark, commit, map)
|
64
|
-
commit.space = mark if commit.space == 0
|
65
|
-
m1 = mark-1
|
66
|
-
marks = commit.parents.collect do |p|
|
67
|
-
if map.include? p.id and map[p.id].space == 0 then
|
68
|
-
mark_chain(m1+=1, map[p.id],map)
|
69
|
-
else
|
70
|
-
m1+1
|
71
|
-
end
|
72
|
-
end
|
73
|
-
marks << mark
|
74
|
-
return marks.compact.max
|
75
|
-
end
|
76
|
-
end
|
77
|
-
end
|
data/public/img/add.png
DELETED
Binary file
|
data/public/img/diff.png
DELETED
Binary file
|
data/public/img/doc.png
DELETED
Binary file
|
data/public/img/rm.png
DELETED
Binary file
|
data/public/img/tree.png
DELETED
Binary file
|
data/public/src/branch-graph.js
DELETED
@@ -1,170 +0,0 @@
|
|
1
|
-
var commits = chunk1.commits,
|
2
|
-
comms = {},
|
3
|
-
pixelsX = [],
|
4
|
-
pixelsY = [],
|
5
|
-
mmax = Math.max,
|
6
|
-
mtime = 0,
|
7
|
-
mspace = 0,
|
8
|
-
parents = {};
|
9
|
-
for (var i = 0, ii = commits.length; i < ii; i++) {
|
10
|
-
for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
|
11
|
-
parents[commits[i].parents[j][0]] = true;
|
12
|
-
}
|
13
|
-
mtime = Math.max(mtime, commits[i].time);
|
14
|
-
mspace = Math.max(mspace, commits[i].space);
|
15
|
-
}
|
16
|
-
mtime = mtime + 4;
|
17
|
-
mspace = mspace + 10;
|
18
|
-
for (i = 0; i < ii; i++) {
|
19
|
-
if (commits[i].id in parents) {
|
20
|
-
commits[i].isParent = true;
|
21
|
-
}
|
22
|
-
comms[commits[i].id] = commits[i];
|
23
|
-
}
|
24
|
-
var colors = ["#000"];
|
25
|
-
for (var k = 0; k < mspace; k++) {
|
26
|
-
colors.push(Raphael.getColor());
|
27
|
-
}
|
28
|
-
function branchGraph(holder) {
|
29
|
-
var ch = mspace * 20 + 20, cw = mtime * 20 + 20,
|
30
|
-
r = Raphael("holder", cw, ch),
|
31
|
-
top = r.set();
|
32
|
-
var cuday = 0, cumonth = "";
|
33
|
-
r.rect(0,0,days.length*20+20,40).attr({fill: "#999"});
|
34
|
-
|
35
|
-
for (mm = 0; mm < days.length; mm++) {
|
36
|
-
if(days[mm] != null){
|
37
|
-
if(cuday != days[mm][0]){
|
38
|
-
r.text(10+mm*20,30,days[mm][0]).attr({font: "12px Fontin-Sans, Arial", fill: "#444"});
|
39
|
-
cuday = days[mm][0]
|
40
|
-
}
|
41
|
-
if(cumonth != days[mm][1]){
|
42
|
-
r.text(10+mm*20,10,days[mm][1]).attr({font: "12px Fontin-Sans, Arial", fill: "#444"});
|
43
|
-
cumonth = days[mm][1]
|
44
|
-
}
|
45
|
-
|
46
|
-
}
|
47
|
-
}
|
48
|
-
for (i = 0; i < ii; i++) {
|
49
|
-
var x = 10 + 20 * commits[i].time,
|
50
|
-
y = 70 + 20 * commits[i].space;
|
51
|
-
r.circle(x, y, 3).attr({fill: colors[commits[i].space], stroke: "none"});
|
52
|
-
if (commits[i].refs != null && commits[i].refs != "") {
|
53
|
-
var longrefs = commits[i].refs
|
54
|
-
var shortrefs = commits[i].refs;
|
55
|
-
if (shortrefs.length > 15){
|
56
|
-
shortrefs = shortrefs.substr(0,13) + "...";
|
57
|
-
}
|
58
|
-
var t = r.text(x+5,y+5,shortrefs).attr({font: "12px Fontin-Sans, Arial", fill: "#666",
|
59
|
-
title: longrefs, cursor: "pointer", rotation: "90"});
|
60
|
-
|
61
|
-
var textbox = t.getBBox();
|
62
|
-
t.translate(textbox.height/-4,textbox.width/2);
|
63
|
-
}
|
64
|
-
for (var j = 0, jj = commits[i].parents.length; j < jj; j++) {
|
65
|
-
var c = comms[commits[i].parents[j][0]];
|
66
|
-
if (c) {
|
67
|
-
var cx = 10 + 20 * c.time,
|
68
|
-
cy = 70 + 20 * c.space;
|
69
|
-
if (c.space == commits[i].space) {
|
70
|
-
r.path("M" + (x - 5) + "," + (y + .0001) + "L" + (15 + 20 * c.time) + "," + (y + .0001))
|
71
|
-
.attr({stroke: colors[c.space], "stroke-width": 2});
|
72
|
-
|
73
|
-
} else if (c.space < commits[i].space) {
|
74
|
-
r.path(["M", x - 5, y + .0001, "l-5-2,0,4,5,-2C",x-5,y,x -17, y+2, x -20, y-10,"L", cx,y-10,cx , cy])
|
75
|
-
.attr({stroke: colors[commits[i].space], "stroke-width": 2});
|
76
|
-
} else {
|
77
|
-
r.path(["M", x-5, y, "l-5-2,0,4,5,-2C",x-5,y,x -17, y-2, x -20, y+10,"L", cx,y+10,cx , cy])
|
78
|
-
.attr({stroke: colors[commits[i].space], "stroke-width": 2});
|
79
|
-
}
|
80
|
-
}
|
81
|
-
}
|
82
|
-
(function (c, x, y) {
|
83
|
-
top.push(r.circle(x, y, 10).attr({fill: "#000", opacity: 0, cursor: "pointer"})
|
84
|
-
.hover(function () {
|
85
|
-
var s = r.text(100, 100,c.author + "\n \n" +c.id + "\n \n" + c.message).attr({fill: "#fff"});
|
86
|
-
this.popup = r.popupit(x, y + 5, s, 0);
|
87
|
-
top.push(this.popup.insertBefore(this));
|
88
|
-
}, function () {
|
89
|
-
this.popup && this.popup.remove() && delete this.popup;
|
90
|
-
}));
|
91
|
-
}(commits[i], x, y));
|
92
|
-
}
|
93
|
-
top.toFront();
|
94
|
-
var hw = holder.offsetWidth,
|
95
|
-
hh = holder.offsetHeight,
|
96
|
-
v = r.rect(hw - 8, 0, 4, Math.pow(hh, 2) / ch, 2).attr({fill: "#000", opacity: 0}),
|
97
|
-
h = r.rect(0, hh - 8, Math.pow(hw, 2) / cw, 4, 2).attr({fill: "#000", opacity: 0}),
|
98
|
-
bars = r.set(v, h),
|
99
|
-
drag,
|
100
|
-
dragger = function (e) {
|
101
|
-
if (drag) {
|
102
|
-
e = e || window.event;
|
103
|
-
holder.scrollLeft = drag.sl - (e.clientX - drag.x);
|
104
|
-
holder.scrollTop = drag.st - (e.clientY - drag.y);
|
105
|
-
}
|
106
|
-
};
|
107
|
-
holder.onmousedown = function (e) {
|
108
|
-
e = e || window.event;
|
109
|
-
drag = {x: e.clientX, y: e.clientY, st: holder.scrollTop, sl: holder.scrollLeft};
|
110
|
-
document.onmousemove = dragger;
|
111
|
-
bars.animate({opacity: .5}, 300);
|
112
|
-
};
|
113
|
-
document.onmouseup = function () {
|
114
|
-
drag = false;
|
115
|
-
document.onmousemove = null;
|
116
|
-
bars.animate({opacity: 0}, 300);
|
117
|
-
};
|
118
|
-
holder.scrollLeft = cw;
|
119
|
-
};
|
120
|
-
Raphael.fn.popupit = function (x, y, set, dir, size) {
|
121
|
-
dir = dir == null ? 2 : dir;
|
122
|
-
size = size || 5;
|
123
|
-
x = Math.round(x);
|
124
|
-
y = Math.round(y);
|
125
|
-
var bb = set.getBBox(),
|
126
|
-
w = Math.round(bb.width / 2),
|
127
|
-
h = Math.round(bb.height / 2),
|
128
|
-
dx = [0, w + size * 2, 0, -w - size * 2],
|
129
|
-
dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
|
130
|
-
p = ["M", x - dx[dir], y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
|
131
|
-
"l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
|
132
|
-
"l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
|
133
|
-
"l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
|
134
|
-
"l", -mmax(w - size, 0), 0, "z"].join(","),
|
135
|
-
xy = [{x: x, y: y + size * 2 + h}, {x: x - size * 2 - w, y: y}, {x: x, y: y - size * 2 - h}, {x: x + size * 2 + w, y: y}][dir];
|
136
|
-
set.translate(xy.x - w - bb.x, xy.y - h - bb.y);
|
137
|
-
return this.set(this.path(p).attr({fill: "#234", stroke: "none"}).insertBefore(set.node ? set : set[0]), set);
|
138
|
-
};
|
139
|
-
Raphael.fn.popup = function (x, y, text, dir, size) {
|
140
|
-
dir = dir == null ? 2 : dir > 3 ? 3 : dir;
|
141
|
-
size = size || 5;
|
142
|
-
text = text || "$9.99";
|
143
|
-
var res = this.set(),
|
144
|
-
d = 3;
|
145
|
-
res.push(this.path().attr({fill: "#000", stroke: "#000"}));
|
146
|
-
res.push(this.text(x, y, text).attr(this.g.txtattr).attr({fill: "#fff", "font-family": "Helvetica, Arial"}));
|
147
|
-
res.update = function (X, Y, withAnimation) {
|
148
|
-
X = X || x;
|
149
|
-
Y = Y || y;
|
150
|
-
var bb = this[1].getBBox(),
|
151
|
-
w = bb.width / 2,
|
152
|
-
h = bb.height / 2,
|
153
|
-
dx = [0, w + size * 2, 0, -w - size * 2],
|
154
|
-
dy = [-h * 2 - size * 3, -h - size, 0, -h - size],
|
155
|
-
p = ["M", X - dx[dir], Y - dy[dir], "l", -size, (dir == 2) * -size, -mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, -size, -size,
|
156
|
-
"l", 0, -mmax(h - size, 0), (dir == 3) * -size, -size, (dir == 3) * size, -size, 0, -mmax(h - size, 0), "a", size, size, 0, 0, 1, size, -size,
|
157
|
-
"l", mmax(w - size, 0), 0, size, !dir * -size, size, !dir * size, mmax(w - size, 0), 0, "a", size, size, 0, 0, 1, size, size,
|
158
|
-
"l", 0, mmax(h - size, 0), (dir == 1) * size, size, (dir == 1) * -size, size, 0, mmax(h - size, 0), "a", size, size, 0, 0, 1, -size, size,
|
159
|
-
"l", -mmax(w - size, 0), 0, "z"].join(","),
|
160
|
-
xy = [{x: X, y: Y + size * 2 + h}, {x: X - size * 2 - w, y: Y}, {x: X, y: Y - size * 2 - h}, {x: X + size * 2 + w, y: Y}][dir];
|
161
|
-
xy.path = p;
|
162
|
-
if (withAnimation) {
|
163
|
-
this.animate(xy, 500, ">");
|
164
|
-
} else {
|
165
|
-
this.attr(xy);
|
166
|
-
}
|
167
|
-
return this;
|
168
|
-
};
|
169
|
-
return res.update(x, y);
|
170
|
-
};
|