dmeiz-croc 0.9.1
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.
- 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);
|