dmeiz-croc 0.9.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README +6 -0
- data/bin/croc +120 -0
- data/lib/croc.rb +128 -0
- data/public/about.html +46 -0
- data/public/index.html +189 -0
- data/public/jquery.dimensions.js +119 -0
- data/public/jquery.js +3549 -0
- metadata +59 -0
data/README
ADDED
data/bin/croc
ADDED
@@ -0,0 +1,120 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
require "rubygems"
|
3
|
+
require "croc"
|
4
|
+
|
5
|
+
$gems = []
|
6
|
+
$classes = {}
|
7
|
+
$methods = []
|
8
|
+
|
9
|
+
install_assets
|
10
|
+
|
11
|
+
specs = get_specs
|
12
|
+
|
13
|
+
homes = {}
|
14
|
+
specs.each do |spec|
|
15
|
+
spec.loaded_from =~ /^(.+)\/specifications/
|
16
|
+
homes[$1] = true
|
17
|
+
end
|
18
|
+
|
19
|
+
# find gem home
|
20
|
+
$home = homes.keys.detect { |home| home !~ /^\/System/ }
|
21
|
+
$rdoc_home = File.join($home, "doc")
|
22
|
+
$gem_home = File.join($home, "gems")
|
23
|
+
$croc_home = File.join(user_home_dir, ".croc")
|
24
|
+
|
25
|
+
puts "Indexing gems in #{$gem_home}"
|
26
|
+
|
27
|
+
# install system gems
|
28
|
+
gems_to_install = specs.select { |spec| spec.loaded_from =~ /^\/System/ }
|
29
|
+
|
30
|
+
unless gems_to_install.empty?
|
31
|
+
puts "It looks like you're using a Mac and these gems are installed under /System:"
|
32
|
+
puts
|
33
|
+
puts " #{gems_to_install.collect {|spec| "#{spec.name}-#{spec.version}"}.join(" ")}"
|
34
|
+
puts
|
35
|
+
puts "Croc can't index these, but installing them in your main gems directory"
|
36
|
+
puts "should solve the problem. Install them (may require sudo)? (y/n)"
|
37
|
+
if gets.strip == "y"
|
38
|
+
gems_to_install.each do |spec|
|
39
|
+
puts "Installing #{spec.name}-#{spec.version}"
|
40
|
+
`gem install -v #{spec.version} #{spec.name}`
|
41
|
+
end
|
42
|
+
else
|
43
|
+
specs = specs - gems_to_install
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
# install rdocs
|
48
|
+
rdocs_to_install = specs.select { |spec| !File.exists?(File.join($rdoc_home, "#{spec.name}-#{spec.version}", "rdoc"))}
|
49
|
+
|
50
|
+
unless rdocs_to_install.empty?
|
51
|
+
puts "These gems have rdocs, but they're not installed:"
|
52
|
+
puts
|
53
|
+
puts " #{rdocs_to_install.collect {|spec| "#{spec.name}-#{spec.version}"}.join(" ")}"
|
54
|
+
puts
|
55
|
+
puts "Install them (may require sudo)? (y/n)"
|
56
|
+
if gets.strip == "y"
|
57
|
+
rdocs_to_install.each do |spec|
|
58
|
+
puts "Installing rdocs for #{spec.name}-#{spec.version}"
|
59
|
+
`sudo gem rdoc -v #{spec.version} #{spec.name}`
|
60
|
+
end
|
61
|
+
else
|
62
|
+
specs = specs - rdocs_to_install
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
croc_rdoc_dir = File.join($croc_home, "rdoc")
|
67
|
+
unless File.exist?(File.join(croc_rdoc_dir, "ruby"))
|
68
|
+
puts "Install Ruby and Stdlib rdocs from www.ruby-doc.org? (y/n)"
|
69
|
+
if gets.strip == "y"
|
70
|
+
install_rdocs("http://www.ruby-doc.org/download/ruby-1.8.6-core-rdocs.tgz", "core-1.8.6_HEAD", "ruby")
|
71
|
+
|
72
|
+
Dir.chdir(croc_rdoc_dir)
|
73
|
+
puts "Installing http://www.ruby-doc.org/download/stdlib/ruby-doc-stdlib-0.10.1.tgz"
|
74
|
+
tgz_file = File.join(croc_rdoc_dir, "dest.tgz")
|
75
|
+
download("http://www.ruby-doc.org/download/stdlib/ruby-doc-stdlib-0.10.1.tgz", tgz_file)
|
76
|
+
`tar xzf #{tgz_file}`
|
77
|
+
src_file = File.join(croc_rdoc_dir, "ruby-doc-stdlib-0.10.1")
|
78
|
+
libdoc_dir = File.join(src_file, "stdlib", "libdoc")
|
79
|
+
Dir.chdir(libdoc_dir)
|
80
|
+
Dir.glob("**/index.html").each do |f|
|
81
|
+
f = File.split(f)[0]
|
82
|
+
move_to = File.split(f)[0].split(File::SEPARATOR).join('-')
|
83
|
+
File.move(File.join(libdoc_dir, f), File.join(croc_rdoc_dir, move_to))
|
84
|
+
end
|
85
|
+
File.delete(tgz_file)
|
86
|
+
FileUtils.rm_r(src_file)
|
87
|
+
else
|
88
|
+
specs = specs - rdocs_to_install
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
Dir.chdir(File.join(user_home_dir, ".croc", "rdoc"))
|
93
|
+
Dir.glob("*").each do |name|
|
94
|
+
next if name == "." || name == ".."
|
95
|
+
index_rdoc(name, File.join(Dir.pwd, name))
|
96
|
+
end
|
97
|
+
|
98
|
+
specs.each { |spec| index_rdoc(spec.name, File.join($rdoc_home, "#{spec.name}-#{spec.version}", "rdoc")) }
|
99
|
+
|
100
|
+
idx = -1
|
101
|
+
File.open(File.join(user_home_dir, ".croc", "data.js"), "w") do |f|
|
102
|
+
f.puts "objs = ["
|
103
|
+
$gems.each do |gem|
|
104
|
+
f.puts " {t: 'g', p: null, n: '#{gem[:name]}', l: '#{gem[:name].downcase}', u: '#{gem[:dir]}'},"
|
105
|
+
idx += 1
|
106
|
+
gidx = idx
|
107
|
+
gem[:classes].each_pair do |key, value|
|
108
|
+
f.puts " {t: 'c', p: #{gidx}, n: '#{key}', l: '#{key.downcase}', u: '#{value[:url]}'},"
|
109
|
+
idx += 1
|
110
|
+
cidx = idx
|
111
|
+
value[:methods].each do |method|
|
112
|
+
f.puts " {t: 'm', p: #{cidx}, n: '#{method[:name]}', l: '#{method[:name].downcase}', u: '#{method[:url]}'},"
|
113
|
+
idx += 1
|
114
|
+
end
|
115
|
+
end
|
116
|
+
end
|
117
|
+
f.puts "];"
|
118
|
+
end
|
119
|
+
|
120
|
+
puts "Bookmark file://#{File.join(user_home_dir, ".croc", "index.html")}"
|
data/lib/croc.rb
ADDED
@@ -0,0 +1,128 @@
|
|
1
|
+
require "rubygems"
|
2
|
+
require "hpricot"
|
3
|
+
require "ftools"
|
4
|
+
|
5
|
+
# Figure out where rdocs are installed.
|
6
|
+
def find_gem_home
|
7
|
+
if File.exists?("/Library/Ruby/Gems/1.8/gems")
|
8
|
+
return "/Library/Ruby/Gems/1.8/gems"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the user's home directory as a string.
|
13
|
+
def user_home_dir
|
14
|
+
ENV["HOME"]
|
15
|
+
end
|
16
|
+
|
17
|
+
# Creates ~/.croc and installs assets from public directory.
|
18
|
+
def install_assets
|
19
|
+
croc_dir = File.join(user_home_dir, ".croc")
|
20
|
+
unless File.exists?(croc_dir)
|
21
|
+
Dir.mkdir(croc_dir)
|
22
|
+
Dir.mkdir(File.join(croc_dir, "rdoc"))
|
23
|
+
end
|
24
|
+
|
25
|
+
public_dir = File.join(File.dirname(__FILE__), "..", "public")
|
26
|
+
Dir.new(public_dir).each do |f|
|
27
|
+
next if f == "." || f == ".."
|
28
|
+
File.copy(File.join(public_dir, f), File.join(croc_dir, f))
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
# Print installed gems and whether rdocs are available and indeed installed.
|
33
|
+
def print_gems
|
34
|
+
Gem.source_index.search(nil).each do |spec|
|
35
|
+
puts "#{spec.name} #{spec.version} #{spec.has_rdoc? ? "has rdoc" : ""} #{File.exists?(rdoc_dir) ? "and it exists" : "but it doesn't exist"}"
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# Collect specs for most recent version of all installed gems.
|
40
|
+
def get_specs
|
41
|
+
specs = {}
|
42
|
+
Gem.source_index.search(nil).each do |spec|
|
43
|
+
next unless spec.has_rdoc?
|
44
|
+
if specs[spec.name]
|
45
|
+
specs[spec.name] = spec if (spec.version <=> specs[spec.name].version) > 0
|
46
|
+
else
|
47
|
+
specs[spec.name] = spec
|
48
|
+
end
|
49
|
+
end
|
50
|
+
specs.values
|
51
|
+
end
|
52
|
+
|
53
|
+
def index_rdoc(name, rdoc_dir)
|
54
|
+
unless File.exists?(rdoc_dir)
|
55
|
+
puts "WARN Couldn't find rdoc dir #{rdoc_dir}"
|
56
|
+
return
|
57
|
+
end
|
58
|
+
|
59
|
+
methods_file = File.join(rdoc_dir, "fr_method_index.html")
|
60
|
+
unless File.exists?(methods_file)
|
61
|
+
puts "ERROR Couldn't find #{methods_file}"
|
62
|
+
end
|
63
|
+
|
64
|
+
classes_file = File.join(rdoc_dir, "fr_class_index.html")
|
65
|
+
unless File.exists?(classes_file)
|
66
|
+
puts "ERROR Couldn't find #{classes_file}"
|
67
|
+
end
|
68
|
+
|
69
|
+
# collect gem
|
70
|
+
gem = {:name => name, :dir => rdoc_dir, :classes => {}}
|
71
|
+
$gems << gem
|
72
|
+
|
73
|
+
# collect classes
|
74
|
+
doc = Hpricot(open(classes_file))
|
75
|
+
(doc/"#index-entries a").each do |el|
|
76
|
+
klass = el.inner_html
|
77
|
+
|
78
|
+
if $classes[klass]
|
79
|
+
puts "Already have class #{klass}"
|
80
|
+
else
|
81
|
+
gem[:classes][klass] = {:name => klass, :url => el["href"], :methods => []}
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# collect methods
|
86
|
+
doc = Hpricot(open(methods_file))
|
87
|
+
(doc/"#index-entries a").each do |el|
|
88
|
+
if el.inner_html =~ /(\S+)\s+\((\S+)\)/
|
89
|
+
method = $1
|
90
|
+
if klass = gem[:classes][$2]
|
91
|
+
el["href"] =~ /#(.*)$/
|
92
|
+
url = $1
|
93
|
+
klass[:methods] << {:name => method, :class => klass, :url => url}
|
94
|
+
else
|
95
|
+
# puts %Q(Couldn't find class "#{$2} for method #{method}")
|
96
|
+
end
|
97
|
+
else
|
98
|
+
# puts %Q(Couldn't get method and class from "#{el.inner_html}")
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
puts "Indexed #{name}"
|
103
|
+
end
|
104
|
+
|
105
|
+
def download(url, dest)
|
106
|
+
File.open(dest, "w") do |f|
|
107
|
+
url = URI.parse(url)
|
108
|
+
http = Net::HTTP.new(url.host, url.port)
|
109
|
+
http.request_get(url.path) do |resp|
|
110
|
+
resp.read_body do |s|
|
111
|
+
f.write(s)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
116
|
+
|
117
|
+
def install_rdocs(url, src_dir_name, dest_dir_name)
|
118
|
+
croc_rdoc_dir = File.join($croc_home, "rdoc")
|
119
|
+
Dir.chdir(croc_rdoc_dir)
|
120
|
+
puts "Installing #{url}"
|
121
|
+
tgz_file = File.join(croc_rdoc_dir, "dest.tgz")
|
122
|
+
src_file = File.join(croc_rdoc_dir, src_dir_name)
|
123
|
+
dest_file = File.join(croc_rdoc_dir, dest_dir_name)
|
124
|
+
download(url, tgz_file)
|
125
|
+
`tar xzf #{tgz_file}`
|
126
|
+
File.rename(src_file, dest_file)
|
127
|
+
File.delete(tgz_file)
|
128
|
+
end
|
data/public/about.html
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<style>
|
4
|
+
th {
|
5
|
+
text-align: left;
|
6
|
+
}
|
7
|
+
</style>
|
8
|
+
</head>
|
9
|
+
<body>
|
10
|
+
<h1>croc</h1>
|
11
|
+
<p>
|
12
|
+
Quick access to your locally installed rdocs.
|
13
|
+
</p>
|
14
|
+
|
15
|
+
<h2>Examples with rspec</h2>
|
16
|
+
<table>
|
17
|
+
<tr>
|
18
|
+
<th>test</th>
|
19
|
+
<td>Gems, classes and methods that contain <em>test</em></td>
|
20
|
+
</tr>
|
21
|
+
<tr>
|
22
|
+
<th>test_finished.</th>
|
23
|
+
<td>Classes and methods named exactly <em>test_finished</em></td>
|
24
|
+
</tr>
|
25
|
+
<tr>
|
26
|
+
<th>rsp test</th>
|
27
|
+
<td>Classes and methods that contain <em>test</em> in gems that contain <em>rsp</em></td>
|
28
|
+
</tr>
|
29
|
+
<tr>
|
30
|
+
<th>rsp test_finished.</th>
|
31
|
+
<td>Classes and methods named exactly <em>test_finished</em> in gems that contain <em>rsp</em></td>
|
32
|
+
</tr>
|
33
|
+
</table>
|
34
|
+
|
35
|
+
<h2>Install your own rdocs</h2>
|
36
|
+
<p>
|
37
|
+
Copy your rdocs directory to ~/.croc/rdoc and make sure it's named
|
38
|
+
something sensible. Rerun croc.
|
39
|
+
</p>
|
40
|
+
|
41
|
+
<h2>About</h2>
|
42
|
+
Copyright 2008 <a href="http://blog.methodhead.com">Dan Hensgen</a>.
|
43
|
+
Feeback appreciated at
|
44
|
+
<a href="mailto:dan@methodhead.com">dan@methodhead.com</a>.
|
45
|
+
</body>
|
46
|
+
</html>
|
data/public/index.html
ADDED
@@ -0,0 +1,189 @@
|
|
1
|
+
<html>
|
2
|
+
<head>
|
3
|
+
<script type="text/javascript" src="jquery.js"></script>
|
4
|
+
<script type="text/javascript" src="jquery.dimensions.js"></script>
|
5
|
+
<script type="text/javascript" src="data.js"></script>
|
6
|
+
<script>
|
7
|
+
suggestions = [];
|
8
|
+
|
9
|
+
function find(q) {
|
10
|
+
if (q == null || jQuery.trim(q).length == 0) {
|
11
|
+
return [];
|
12
|
+
}
|
13
|
+
|
14
|
+
gemPart = null;
|
15
|
+
if (q.indexOf(' ') > 0) {
|
16
|
+
a = q.split(/\s+/)
|
17
|
+
gemPart = a[0];
|
18
|
+
q = a[1];
|
19
|
+
}
|
20
|
+
|
21
|
+
var sugs = [];
|
22
|
+
var includedGems = {};
|
23
|
+
var parentGems = {};
|
24
|
+
|
25
|
+
if (gemPart) {
|
26
|
+
for (i in objs) {
|
27
|
+
o = objs[i];
|
28
|
+
if (o.t == "g") {
|
29
|
+
if (o.l.indexOf(gemPart) >= 0) {
|
30
|
+
parentGems[i] = true;
|
31
|
+
}
|
32
|
+
}
|
33
|
+
}
|
34
|
+
}
|
35
|
+
|
36
|
+
for (i in objs) {
|
37
|
+
o = objs[i];
|
38
|
+
if ((q[q.length - 1] == '.' && o.l == q.substr(0, q.length - 1)) || o.l.indexOf(q) >= 0) {
|
39
|
+
if (o.t == "c") {
|
40
|
+
if (!gemPart || parentGems[o.p]) {
|
41
|
+
if (!includedGems[o.p]) {
|
42
|
+
includedGems[o.p] = true;
|
43
|
+
sugs.push(objs[o.p]);
|
44
|
+
}
|
45
|
+
sugs.push(o);
|
46
|
+
}
|
47
|
+
}
|
48
|
+
else if (o.t == "m") {
|
49
|
+
if (!gemPart || parentGems[objs[o.p].p]) {
|
50
|
+
if (!includedGems[objs[o.p].p]) {
|
51
|
+
includedGems[objs[o.p].p] = true;
|
52
|
+
sugs.push(objs[objs[o.p].p])
|
53
|
+
}
|
54
|
+
sugs.push(o);
|
55
|
+
}
|
56
|
+
}
|
57
|
+
else {
|
58
|
+
if (!gemPart || parentGems[i]) {
|
59
|
+
includedGems[i] = true;
|
60
|
+
sugs.push(o);
|
61
|
+
}
|
62
|
+
}
|
63
|
+
|
64
|
+
if (sugs.length > 50) {
|
65
|
+
sugs.push(0)
|
66
|
+
break;
|
67
|
+
}
|
68
|
+
}
|
69
|
+
}
|
70
|
+
|
71
|
+
return sugs;
|
72
|
+
}
|
73
|
+
|
74
|
+
function resultsToHtml(results) {
|
75
|
+
html = '';
|
76
|
+
jQuery.each(results, function(i, o) {
|
77
|
+
if (o == 0) {
|
78
|
+
html += '<div>...</div>';
|
79
|
+
}
|
80
|
+
else {
|
81
|
+
switch (o.t) {
|
82
|
+
case "g":
|
83
|
+
html += '<div class="gem"><a target="iframe" href="file://' + o.u + '/index.html">' + o.n + '</a></div>'; break;
|
84
|
+
case "c":
|
85
|
+
html += '<div class="class-or-method"><a target="iframe" href="file://' + objs[o.p].u + '/' + o.u + '">' + o.n + '</a></div>'; break;
|
86
|
+
case "m":
|
87
|
+
html += '<div class="class-or-method"><a target="iframe" href="file://' + objs[objs[o.p].p].u + '/' + objs[o.p].u + '#' + o.u + '">' + o.n + '</a> (' + objs[o.p].n + ')</div>'; break;
|
88
|
+
}
|
89
|
+
}
|
90
|
+
});
|
91
|
+
|
92
|
+
return html;
|
93
|
+
}
|
94
|
+
|
95
|
+
function sizeElements() {
|
96
|
+
$('#suggestions').css('top', $('input').position()['top'] + $('input').outerHeight() + 'px');
|
97
|
+
$('#iframe').css('height', $(window).height() - $('input').outerHeight() - 5 + 'px' );
|
98
|
+
$('#iframe').css('width', $(window).width() - 5 + 'px' );
|
99
|
+
}
|
100
|
+
|
101
|
+
$(document).ready(function(){
|
102
|
+
sizeElements();
|
103
|
+
|
104
|
+
$(document).keyup(function(e) {
|
105
|
+
if (e.keyCode == 27) {
|
106
|
+
$('#suggestions').hide();
|
107
|
+
}
|
108
|
+
});
|
109
|
+
|
110
|
+
$('iframe').keyup(function(e) {
|
111
|
+
if (e.keyCode == 27) {
|
112
|
+
$('#suggestions').hide();
|
113
|
+
}
|
114
|
+
});
|
115
|
+
|
116
|
+
// search and update results
|
117
|
+
$('input').keyup(function(e) {
|
118
|
+
if (e.keyCode == 27) {
|
119
|
+
return;
|
120
|
+
}
|
121
|
+
|
122
|
+
matches = find(e.target.value.toLowerCase());
|
123
|
+
|
124
|
+
html = resultsToHtml(matches);
|
125
|
+
|
126
|
+
if (matches.length > 0) {
|
127
|
+
$('#suggestions').html(html).show();
|
128
|
+
}
|
129
|
+
else {
|
130
|
+
$('#suggestions').hide();
|
131
|
+
}
|
132
|
+
});
|
133
|
+
|
134
|
+
// hide suggestions if user clicks on a link
|
135
|
+
$('#suggestions').click(function(e) {
|
136
|
+
if (e.target.nodeName == "A") {
|
137
|
+
$('#suggestions').hide();
|
138
|
+
$('#recents').prepend(' <a target="iframe" href="' + e.target.href + '">' + e.target.innerHTML + '</a>');
|
139
|
+
}
|
140
|
+
});
|
141
|
+
|
142
|
+
$('input').focus();
|
143
|
+
|
144
|
+
$('input').focus(function() {
|
145
|
+
if ($('#suggestions').innerHTML != "") {
|
146
|
+
$('#suggestions').show();
|
147
|
+
}
|
148
|
+
});
|
149
|
+
});
|
150
|
+
</script>
|
151
|
+
|
152
|
+
<style>
|
153
|
+
* {
|
154
|
+
margin: 0;
|
155
|
+
font: 9pt sans-serif;
|
156
|
+
}
|
157
|
+
body {
|
158
|
+
margin: 0;
|
159
|
+
padding: 0;
|
160
|
+
}
|
161
|
+
|
162
|
+
#suggestions {
|
163
|
+
border: 1px solid #bbb;
|
164
|
+
position: absolute;
|
165
|
+
background-color: #fff;
|
166
|
+
color: #aaa;
|
167
|
+
padding: 3px;
|
168
|
+
}
|
169
|
+
|
170
|
+
#suggestions div.gem {
|
171
|
+
font-weight: bold;
|
172
|
+
}
|
173
|
+
|
174
|
+
#suggestions div.class-or-method {
|
175
|
+
padding-left: 1em;
|
176
|
+
}
|
177
|
+
</style>
|
178
|
+
</head>
|
179
|
+
<body>
|
180
|
+
<form>
|
181
|
+
<input>
|
182
|
+
<span id="recents"></span>
|
183
|
+
<div id="suggestions" style="display:none">
|
184
|
+
</div>
|
185
|
+
</form>
|
186
|
+
<iframe id="iframe" name="iframe" src="about.html">
|
187
|
+
</iframe>
|
188
|
+
</body>
|
189
|
+
</html>
|
@@ -0,0 +1,119 @@
|
|
1
|
+
/* Copyright (c) 2007 Paul Bakaus (paul.bakaus@googlemail.com) and Brandon Aaron (brandon.aaron@gmail.com || http://brandonaaron.net)
|
2
|
+
* Dual licensed under the MIT (http://www.opensource.org/licenses/mit-license.php)
|
3
|
+
* and GPL (http://www.opensource.org/licenses/gpl-license.php) licenses.
|
4
|
+
*
|
5
|
+
* $LastChangedDate: 2007-12-20 08:46:55 -0600 (Thu, 20 Dec 2007) $
|
6
|
+
* $Rev: 4259 $
|
7
|
+
*
|
8
|
+
* Version: 1.2
|
9
|
+
*
|
10
|
+
* Requires: jQuery 1.2+
|
11
|
+
*/
|
12
|
+
|
13
|
+
(function($){
|
14
|
+
|
15
|
+
$.dimensions = {
|
16
|
+
version: '1.2'
|
17
|
+
};
|
18
|
+
|
19
|
+
// Create innerHeight, innerWidth, outerHeight and outerWidth methods
|
20
|
+
$.each( [ 'Height', 'Width' ], function(i, name){
|
21
|
+
|
22
|
+
// innerHeight and innerWidth
|
23
|
+
$.fn[ 'inner' + name ] = function() {
|
24
|
+
if (!this[0]) return;
|
25
|
+
|
26
|
+
var torl = name == 'Height' ? 'Top' : 'Left', // top or left
|
27
|
+
borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
|
28
|
+
|
29
|
+
return this.is(':visible') ? this[0]['client' + name] : num( this, name.toLowerCase() ) + num(this, 'padding' + torl) + num(this, 'padding' + borr);
|
30
|
+
};
|
31
|
+
|
32
|
+
// outerHeight and outerWidth
|
33
|
+
$.fn[ 'outer' + name ] = function(options) {
|
34
|
+
if (!this[0]) return;
|
35
|
+
|
36
|
+
var torl = name == 'Height' ? 'Top' : 'Left', // top or left
|
37
|
+
borr = name == 'Height' ? 'Bottom' : 'Right'; // bottom or right
|
38
|
+
|
39
|
+
options = $.extend({ margin: false }, options || {});
|
40
|
+
|
41
|
+
var val = this.is(':visible') ?
|
42
|
+
this[0]['offset' + name] :
|
43
|
+
num( this, name.toLowerCase() )
|
44
|
+
+ num(this, 'border' + torl + 'Width') + num(this, 'border' + borr + 'Width')
|
45
|
+
+ num(this, 'padding' + torl) + num(this, 'padding' + borr);
|
46
|
+
|
47
|
+
return val + (options.margin ? (num(this, 'margin' + torl) + num(this, 'margin' + borr)) : 0);
|
48
|
+
};
|
49
|
+
});
|
50
|
+
|
51
|
+
// Create scrollLeft and scrollTop methods
|
52
|
+
$.each( ['Left', 'Top'], function(i, name) {
|
53
|
+
$.fn[ 'scroll' + name ] = function(val) {
|
54
|
+
if (!this[0]) return;
|
55
|
+
|
56
|
+
return val != undefined ?
|
57
|
+
|
58
|
+
// Set the scroll offset
|
59
|
+
this.each(function() {
|
60
|
+
this == window || this == document ?
|
61
|
+
window.scrollTo(
|
62
|
+
name == 'Left' ? val : $(window)[ 'scrollLeft' ](),
|
63
|
+
name == 'Top' ? val : $(window)[ 'scrollTop' ]()
|
64
|
+
) :
|
65
|
+
this[ 'scroll' + name ] = val;
|
66
|
+
}) :
|
67
|
+
|
68
|
+
// Return the scroll offset
|
69
|
+
this[0] == window || this[0] == document ?
|
70
|
+
self[ (name == 'Left' ? 'pageXOffset' : 'pageYOffset') ] ||
|
71
|
+
$.boxModel && document.documentElement[ 'scroll' + name ] ||
|
72
|
+
document.body[ 'scroll' + name ] :
|
73
|
+
this[0][ 'scroll' + name ];
|
74
|
+
};
|
75
|
+
});
|
76
|
+
|
77
|
+
$.fn.extend({
|
78
|
+
position: function() {
|
79
|
+
var left = 0, top = 0, elem = this[0], offset, parentOffset, offsetParent, results;
|
80
|
+
|
81
|
+
if (elem) {
|
82
|
+
// Get *real* offsetParent
|
83
|
+
offsetParent = this.offsetParent();
|
84
|
+
|
85
|
+
// Get correct offsets
|
86
|
+
offset = this.offset();
|
87
|
+
parentOffset = offsetParent.offset();
|
88
|
+
|
89
|
+
// Subtract element margins
|
90
|
+
offset.top -= num(elem, 'marginTop');
|
91
|
+
offset.left -= num(elem, 'marginLeft');
|
92
|
+
|
93
|
+
// Add offsetParent borders
|
94
|
+
parentOffset.top += num(offsetParent, 'borderTopWidth');
|
95
|
+
parentOffset.left += num(offsetParent, 'borderLeftWidth');
|
96
|
+
|
97
|
+
// Subtract the two offsets
|
98
|
+
results = {
|
99
|
+
top: offset.top - parentOffset.top,
|
100
|
+
left: offset.left - parentOffset.left
|
101
|
+
};
|
102
|
+
}
|
103
|
+
|
104
|
+
return results;
|
105
|
+
},
|
106
|
+
|
107
|
+
offsetParent: function() {
|
108
|
+
var offsetParent = this[0].offsetParent;
|
109
|
+
while ( offsetParent && (!/^body|html$/i.test(offsetParent.tagName) && $.css(offsetParent, 'position') == 'static') )
|
110
|
+
offsetParent = offsetParent.offsetParent;
|
111
|
+
return $(offsetParent);
|
112
|
+
}
|
113
|
+
});
|
114
|
+
|
115
|
+
function num(el, prop) {
|
116
|
+
return parseInt($.curCSS(el.jquery?el[0]:el,prop,true))||0;
|
117
|
+
};
|
118
|
+
|
119
|
+
})(jQuery);
|