tarantula 0.0.5 → 0.0.8.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (66) hide show
  1. data/CHANGELOG +11 -0
  2. data/MIT-LICENSE +1 -1
  3. data/README.rdoc +48 -38
  4. data/Rakefile +3 -19
  5. data/laf/javascripts/niftyLayout.js +11 -0
  6. data/laf/javascripts/niftycube-details.js +298 -0
  7. data/laf/javascripts/niftycube.js +298 -0
  8. data/laf/stylesheets/NiftyLayout.css +47 -0
  9. data/laf/stylesheets/niftyCorners.css +35 -0
  10. data/{tmp/test_output/stylesheets/tarantula.css → laf/stylesheets/old.css} +1 -1
  11. data/laf/stylesheets/tarantula.css +83 -546
  12. data/laf/stylesheets/tarantula.v2.css +48 -0
  13. data/laf/stylesheets/ui.tabs.css +2 -2
  14. data/laf/v2/detail.html +41 -0
  15. data/laf/v2/images/button_active.png +0 -0
  16. data/laf/v2/images/button_hover.png +0 -0
  17. data/laf/v2/images/button_inactive.png +0 -0
  18. data/laf/v2/images/header_bg.jpg +0 -0
  19. data/laf/v2/images/logo.png +0 -0
  20. data/laf/v2/images/tagline.png +0 -0
  21. data/laf/v2/index.html +77 -0
  22. data/laf/v2/stylesheets/tarantula.v2.css +252 -0
  23. data/lib/relevance/tarantula.rb +4 -5
  24. data/lib/relevance/tarantula/detail.html.erb +55 -41
  25. data/lib/relevance/tarantula/html_report_helper.rb +3 -13
  26. data/lib/relevance/tarantula/html_reporter.rb +2 -2
  27. data/lib/relevance/tarantula/index.html.erb +25 -20
  28. data/lib/relevance/tarantula/test_report.html.erb +9 -9
  29. data/manifest.txt +17 -32
  30. data/rails/init.rb +4 -1
  31. data/tarantula.gemspec +16 -8
  32. data/tasks/tarantula_tasks.rake +8 -6
  33. data/test/relevance/tarantula/html_report_helper_test.rb +2 -3
  34. data/test/relevance/tarantula/rails_init_test.rb +14 -0
  35. metadata +43 -37
  36. data/tmp/test_output/images/background.jpg +0 -0
  37. data/tmp/test_output/images/relevance-os-logo.gif +0 -0
  38. data/tmp/test_output/images/tab.png +0 -0
  39. data/tmp/test_output/images/table-sort.gif +0 -0
  40. data/tmp/test_output/images/tarantula-sprites.png +0 -0
  41. data/tmp/test_output/index.html +0 -255
  42. data/tmp/test_output/javascripts/jquery-1.2.3.js +0 -3408
  43. data/tmp/test_output/javascripts/jquery-ui-tabs.js +0 -890
  44. data/tmp/test_output/javascripts/jquery.tablesorter.js +0 -861
  45. data/tmp/test_output/javascripts/tarantula.js +0 -10
  46. data/tmp/test_output/stylesheets/ui.tabs.css +0 -113
  47. data/tmp/test_output/test_user_pages/1.html +0 -71
  48. data/tmp/test_output/test_user_pages/10.html +0 -71
  49. data/tmp/test_output/test_user_pages/11.html +0 -71
  50. data/tmp/test_output/test_user_pages/12.html +0 -71
  51. data/tmp/test_output/test_user_pages/13.html +0 -71
  52. data/tmp/test_output/test_user_pages/14.html +0 -71
  53. data/tmp/test_output/test_user_pages/15.html +0 -71
  54. data/tmp/test_output/test_user_pages/16.html +0 -71
  55. data/tmp/test_output/test_user_pages/17.html +0 -71
  56. data/tmp/test_output/test_user_pages/18.html +0 -71
  57. data/tmp/test_output/test_user_pages/19.html +0 -71
  58. data/tmp/test_output/test_user_pages/2.html +0 -71
  59. data/tmp/test_output/test_user_pages/20.html +0 -71
  60. data/tmp/test_output/test_user_pages/3.html +0 -71
  61. data/tmp/test_output/test_user_pages/4.html +0 -71
  62. data/tmp/test_output/test_user_pages/5.html +0 -71
  63. data/tmp/test_output/test_user_pages/6.html +0 -71
  64. data/tmp/test_output/test_user_pages/7.html +0 -71
  65. data/tmp/test_output/test_user_pages/8.html +0 -71
  66. data/tmp/test_output/test_user_pages/9.html +0 -71
data/CHANGELOG CHANGED
@@ -1,2 +1,13 @@
1
+ v0.0.8.1
2
+ * Fix numerous installation and initial setup issues
3
+ * Enhance rake tasks to support use of Tarantula in a continuous integration environment
4
+ ** Use "rake tarantula:test" to run headless with build-friendly exit codes
5
+ ** Use "rake tarantula:report" to open the Tarantula report in your browser
6
+ * Update README
7
+ ** Provide better installation and setup documentation
8
+ ** Include example of adding a custom attack handler
9
+ * Simplify design to address concerns about hard-to-read fonts
10
+
1
11
  v0.0.5 Make sure we don't include Relevance::Tarantula into Object - will cause issues Rails dependencies and is a bad idea in general; update Rakefile for dev dependencies; another small clean up tasks
12
+
2
13
  v0.0.1 Tarantula becomes a gem. (Aaron Bedra)
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008 Relevance, Inc.
1
+ Copyright (c) 2008-2009 Relevance, Inc.
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
@@ -4,14 +4,6 @@
4
4
 
5
5
  Tarantula is a big fuzzy spider. It crawls your Rails application, fuzzing data to see what breaks.
6
6
 
7
- == Dependencies
8
-
9
- htmlentities
10
- hpricot
11
- facets >= 2.4.3
12
- actionpack
13
- activesupport
14
-
15
7
  == Usage
16
8
 
17
9
  #!sh
@@ -24,8 +16,6 @@ Creates a Rails integration test that looks like this, filling in your own auth
24
16
  # in your test
25
17
  def test_with_login
26
18
  post '/sessions/create', :password => 'your-pass'
27
- assert_response :redirect
28
- assert_redirected_to '/'
29
19
  follow_redirect!
30
20
  tarantula_crawl(self)
31
21
  end
@@ -44,9 +34,9 @@ If you want to set custom options, you can get access to the crawler and set pro
44
34
 
45
35
  Assuming your project is at /work/project/:
46
36
 
47
- #!sh
48
- cd /work/project
49
- rake tarantula:test
37
+ #!sh
38
+ cd /work/project
39
+ rake tarantula:test
50
40
 
51
41
  == Verbose Mode
52
42
 
@@ -62,45 +52,65 @@ tell Tarantula to allow 404s for URLs matching a regexp:
62
52
  t = tarantula_crawler(self)
63
53
  t.allow_404_for %r{/users/\d+/}
64
54
 
55
+ == Custom Attack Handlers
56
+
57
+ You can specify the attack strings that Tarantula throws at your application.
58
+
59
+ def test_tarantula
60
+ t = tarantula_crawler(self)
61
+
62
+ Relevance::Tarantula::AttackFormSubmission.attacks << {
63
+ :name => :xss,
64
+ :input => "<script>gotcha!</script>",
65
+ :output => "<script>gotcha!</script>",
66
+ }
67
+
68
+ Relevance::Tarantula::AttackFormSubmission.attacks << {
69
+ :name => :sql_injection,
70
+ :input => "a'; DROP TABLE posts;",
71
+ }
72
+
73
+ t.handlers << Relevance::Tarantula::AttackHandler.new
74
+ t.fuzzers << Relevance::Tarantula::AttackFormSubmission
75
+ t.times_to_crawl = 2
76
+ t.crawl "/posts"
77
+ end
78
+
79
+ This example adds custom attacks for both SQL injection and XSS. It also tells tarantula to crawl the app 2 times. This
80
+ is important for XSS attacks because the results won't appear until the second time tarantula performs the crawl.
81
+
65
82
  == Install
66
83
 
84
+ See the rakefile for dependencies, or just let Rubygems handle it.
85
+
67
86
  The latest and greatest gem will always be available from Github:
68
87
 
69
88
  gem install relevance-tarantula --source http://gems.github.com
70
89
 
71
- You can also grab it from Rubyforge, where we will push stable releases but may not be as bleeding edge as the Github gem.
90
+ To setup tarantula in your application add the following line into either config/environment.rb or config/environments/test.rb (preferred).
91
+ This assumes that you have Rails 2.1 or higher installed.
72
92
 
73
- gem install tarantula
93
+ config.gem 'relevance-tarantula', :source => "http://gems.github.com", :lib => 'relevance/tarantula'
74
94
 
75
- == Bugs/Requests
95
+ Since rails doesn't (yet) support loading rake tasks that live inside gems you will need to update your Rakefile. This assumes that you have vendored tarantula. Simply run
96
+
97
+ cd vendor/gems
98
+ gem unpack relevance-tarantula
76
99
 
77
- Please submit your bug reports, patches or feature requests as a ticket under the component "tarantula" on our Trac instance here:
100
+ You can then add the following line into your Rakefile, substituting the proper version of relevance-tarantula in the path.
78
101
 
79
- http://opensource.thinkrelevance.com/
102
+ load File.join(RAILS_ROOT, "vendor/gems/relevance-tarantula-0.0.8.1/tasks/tarantula_tasks.rake")
80
103
 
81
- You'll have to create an account (Sorry! Otherwise we'd get way too much spam).
104
+ You can also grab it from Rubyforge, where we will push stable releases but may not be as bleeding edge as the Github gem.
82
105
 
83
- == License and Copyright
106
+ gem install tarantula
84
107
 
85
- (The MIT License)
108
+ == Bugs/Requests
86
109
 
87
- Copyright (c) 2008 Relevance, Inc. - http://thinkrelevance.com
110
+ Please submit your bug reports, patches or feature requests at Lighthouse:
88
111
 
89
- Permission is hereby granted, free of charge, to any person obtaining
90
- a copy of this software and associated documentation files (the
91
- 'Software'), to deal in the Software without restriction, including
92
- without limitation the rights to use, copy, modify, merge, publish,
93
- distribute, sublicense, and/or sell copies of the Software, and to
94
- permit persons to whom the Software is furnished to do so, subject to
95
- the following conditions:
112
+ http://relevance.lighthouseapp.com/projects/17868-tarantula/overview
96
113
 
97
- The above copyright notice and this permission notice shall be
98
- included in all copies or substantial portions of the Software.
114
+ == License
99
115
 
100
- THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
101
- EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
102
- MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
103
- IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
104
- CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
105
- TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
106
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
116
+ Tarantula is released under the MIT license.
data/Rakefile CHANGED
@@ -3,13 +3,7 @@ require 'rake/testtask'
3
3
  require 'rake/rdoctask'
4
4
  require 'rubygems'
5
5
 
6
- begin
7
- gem 'technicalpickles-echoe'
8
- rescue LoadError => e
9
- puts "Couldn't find the correct version of echoe - please install from forked version on github: http://github.com/technicalpickles/echoe/ ->"
10
- puts "sudo gem install technicalpickles-echoe --source http://gems.github.com"
11
- end
12
-
6
+ gem 'echoe', '~> 3.0.1'
13
7
  require 'echoe'
14
8
  require 'lib/relevance/tarantula.rb'
15
9
 
@@ -20,26 +14,16 @@ echoe = Echoe.new('tarantula') do |p|
20
14
  p.version = Relevance::Tarantula::VERSION
21
15
  p.summary = "A big hairy fuzzy spider that crawls your site, wreaking havoc"
22
16
  p.description = "A big hairy fuzzy spider that crawls your site, wreaking havoc"
23
- p.url = "http://opensource.thinkrelevance.com/wiki/tarantula"
17
+ p.url = "http://github.com/relevance/tarantula"
24
18
  p.rdoc_pattern = /^(lib|bin)|txt|rdoc|CHANGELOG|MIT-LICENSE$/
25
19
  rdoc_template = `allison --path`.strip << ".rb"
26
20
  p.rdoc_template = rdoc_template
27
21
  p.test_pattern = 'test/**/*_test.rb'
28
22
  p.manifest_name = 'manifest.txt'
29
- p.dependencies = ['htmlentities', 'hpricot', 'facets >=2.4.3']
23
+ p.dependencies = ['htmlentities', 'hpricot', 'facets >=2.4.3', 'actionpack', 'activesupport']
30
24
  p.development_dependencies = ['ruby-debug', 'test-spec', 'mocha']
31
25
  end
32
26
 
33
- desc 'Default: run unit tests.'
34
- task :default => :test
35
-
36
- desc 'Test the tarantula plugin.'
37
- Rake::TestTask.new(:test) do |t|
38
- t.libs << 'lib'
39
- t.pattern = 'test/**/*_test.rb'
40
- t.verbose = true
41
- end
42
-
43
27
  desc 'Generate documentation for the tarantula plugin.'
44
28
  Rake::RDocTask.new(:rdoc) do |rdoc|
45
29
  rdoc.rdoc_dir = 'rdoc'
@@ -0,0 +1,11 @@
1
+ /*nifty corners layout*/
2
+
3
+ window.onload=function(){
4
+ Nifty("div#menu a","small transparent top");
5
+ Nifty("ul#intro li","same-height");
6
+ Nifty("div.date");
7
+ Nifty("div#content,div#side","same-height");
8
+ Nifty("div.comments div");
9
+ Nifty("div#footer");
10
+ Nifty("div#container","bottom");
11
+ }
@@ -0,0 +1,298 @@
1
+ /* Nifty Corners Cube - rounded corners with CSS and Javascript
2
+ Copyright 2006 Alessandro Fulciniti (a.fulciniti@html.it)
3
+
4
+ This program is free software; you can redistribute it and/or modify
5
+ it under the terms of the GNU General Public License as published by
6
+ the Free Software Foundation; either version 2 of the License, or
7
+ (at your option) any later version.
8
+
9
+ This program is distributed in the hope that it will be useful,
10
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
11
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12
+ GNU General Public License for more details.
13
+
14
+ You should have received a copy of the GNU General Public License
15
+ along with this program; if not, write to the Free Software
16
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17
+ */
18
+
19
+ var niftyOk=(document.getElementById && document.createElement && Array.prototype.push);
20
+ var niftyCss=false;
21
+
22
+ String.prototype.find=function(what){
23
+ return(this.indexOf(what)>=0 ? true : false);
24
+ }
25
+
26
+ var oldonload=window.onload;
27
+ if(typeof(NiftyLoad)!='function') NiftyLoad=function(){};
28
+ if(typeof(oldonload)=='function')
29
+ window.onload=function(){oldonload();AddCss();NiftyLoad()};
30
+ else window.onload=function(){AddCss();NiftyLoad()};
31
+
32
+ function AddCss(){
33
+ niftyCss=true;
34
+ var l=CreateEl("link");
35
+ l.setAttribute("type","text/css");
36
+ l.setAttribute("rel","stylesheet");
37
+ l.setAttribute("href","../stylesheets/niftyCorners.css");
38
+ l.setAttribute("media","screen");
39
+ document.getElementsByTagName("head")[0].appendChild(l);
40
+ }
41
+
42
+ function Nifty(selector,options){
43
+ if(niftyOk==false) return;
44
+ if(niftyCss==false) AddCss();
45
+ var i,v=selector.split(","),h=0;
46
+ if(options==null) options="";
47
+ if(options.find("fixed-height"))
48
+ h=getElementsBySelector(v[0])[0].offsetHeight;
49
+ for(i=0;i<v.length;i++)
50
+ Rounded(v[i],options);
51
+ if(options.find("height")) SameHeight(selector,h);
52
+ }
53
+
54
+ function Rounded(selector,options){
55
+ var i,top="",bottom="",v=new Array();
56
+ if(options!=""){
57
+ options=options.replace("left","tl bl");
58
+ options=options.replace("right","tr br");
59
+ options=options.replace("top","tr tl");
60
+ options=options.replace("bottom","br bl");
61
+ options=options.replace("transparent","alias");
62
+ if(options.find("tl")){
63
+ top="both";
64
+ if(!options.find("tr")) top="left";
65
+ }
66
+ else if(options.find("tr")) top="right";
67
+ if(options.find("bl")){
68
+ bottom="both";
69
+ if(!options.find("br")) bottom="left";
70
+ }
71
+ else if(options.find("br")) bottom="right";
72
+ }
73
+ if(top=="" && bottom=="" && !options.find("none")){top="both";bottom="both";}
74
+ v=getElementsBySelector(selector);
75
+ for(i=0;i<v.length;i++){
76
+ FixIE(v[i]);
77
+ if(top!="") AddTop(v[i],top,options);
78
+ if(bottom!="") AddBottom(v[i],bottom,options);
79
+ }
80
+ }
81
+
82
+ function AddTop(el,side,options){
83
+ var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
84
+ d.style.marginLeft="-"+getPadding(el,"Left")+"px";
85
+ d.style.marginRight="-"+getPadding(el,"Right")+"px";
86
+ if(options.find("alias") || (color=getBk(el))=="transparent"){
87
+ color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
88
+ }
89
+ else{
90
+ bk=getParentBk(el); border=Mix(color,bk);
91
+ }
92
+ d.style.background=bk;
93
+ d.className="niftycorners";
94
+ p=getPadding(el,"Top");
95
+ if(options.find("small")){
96
+ d.style.marginBottom=(p-2)+"px";
97
+ btype+="s"; lim=2;
98
+ }
99
+ else if(options.find("big")){
100
+ d.style.marginBottom=(p-10)+"px";
101
+ btype+="b"; lim=8;
102
+ }
103
+ else d.style.marginBottom=(p-5)+"px";
104
+ for(i=1;i<=lim;i++)
105
+ d.appendChild(CreateStrip(i,side,color,border,btype));
106
+ el.style.paddingTop="0";
107
+ el.insertBefore(d,el.firstChild);
108
+ }
109
+
110
+ function AddBottom(el,side,options){
111
+ var d=CreateEl("b"),lim=4,border="",p,i,btype="r",bk,color;
112
+ d.style.marginLeft="-"+getPadding(el,"Left")+"px";
113
+ d.style.marginRight="-"+getPadding(el,"Right")+"px";
114
+ if(options.find("alias") || (color=getBk(el))=="transparent"){
115
+ color="transparent";bk="transparent"; border=getParentBk(el);btype="t";
116
+ }
117
+ else{
118
+ bk=getParentBk(el); border=Mix(color,bk);
119
+ }
120
+ d.style.background=bk;
121
+ d.className="niftycorners";
122
+ p=getPadding(el,"Bottom");
123
+ if(options.find("small")){
124
+ d.style.marginTop=(p-2)+"px";
125
+ btype+="s"; lim=2;
126
+ }
127
+ else if(options.find("big")){
128
+ d.style.marginTop=(p-10)+"px";
129
+ btype+="b"; lim=8;
130
+ }
131
+ else d.style.marginTop=(p-5)+"px";
132
+ for(i=lim;i>0;i--)
133
+ d.appendChild(CreateStrip(i,side,color,border,btype));
134
+ el.style.paddingBottom=0;
135
+ el.appendChild(d);
136
+ }
137
+
138
+ function CreateStrip(index,side,color,border,btype){
139
+ var x=CreateEl("b");
140
+ x.className=btype+index;
141
+ x.style.backgroundColor=color;
142
+ x.style.borderColor=border;
143
+ if(side=="left"){
144
+ x.style.borderRightWidth="0";
145
+ x.style.marginRight="0";
146
+ }
147
+ else if(side=="right"){
148
+ x.style.borderLeftWidth="0";
149
+ x.style.marginLeft="0";
150
+ }
151
+ return(x);
152
+ }
153
+
154
+ function CreateEl(x){
155
+ return(document.createElement(x));
156
+ }
157
+
158
+ function FixIE(el){
159
+ if(el.currentStyle!=null && el.currentStyle.hasLayout!=null && el.currentStyle.hasLayout==false)
160
+ el.style.display="inline-block";
161
+ }
162
+
163
+ function SameHeight(selector,maxh){
164
+ var i,v=selector.split(","),t,j,els=[],gap;
165
+ for(i=0;i<v.length;i++){
166
+ t=getElementsBySelector(v[i]);
167
+ els=els.concat(t);
168
+ }
169
+ for(i=0;i<els.length;i++){
170
+ if(els[i].offsetHeight>maxh) maxh=els[i].offsetHeight;
171
+ els[i].style.height="auto";
172
+ }
173
+ for(i=0;i<els.length;i++){
174
+ gap=maxh-els[i].offsetHeight;
175
+ if(gap>0){
176
+ t=CreateEl("b");t.className="niftyfill";t.style.height=gap+"px";
177
+ nc=els[i].lastChild;
178
+ if(nc.className=="niftycorners")
179
+ els[i].insertBefore(t,nc);
180
+ else els[i].appendChild(t);
181
+ }
182
+ }
183
+ }
184
+
185
+ function getElementsBySelector(selector){
186
+ var i,j,selid="",selclass="",tag=selector,tag2="",v2,k,f,a,s=[],objlist=[],c;
187
+ if(selector.find("#")){ //id selector like "tag#id"
188
+ if(selector.find(" ")){ //descendant selector like "tag#id tag"
189
+ s=selector.split(" ");
190
+ var fs=s[0].split("#");
191
+ if(fs.length==1) return(objlist);
192
+ f=document.getElementById(fs[1]);
193
+ if(f){
194
+ v=f.getElementsByTagName(s[1]);
195
+ for(i=0;i<v.length;i++) objlist.push(v[i]);
196
+ }
197
+ return(objlist);
198
+ }
199
+ else{
200
+ s=selector.split("#");
201
+ tag=s[0];
202
+ selid=s[1];
203
+ if(selid!=""){
204
+ f=document.getElementById(selid);
205
+ if(f) objlist.push(f);
206
+ return(objlist);
207
+ }
208
+ }
209
+ }
210
+ if(selector.find(".")){ //class selector like "tag.class"
211
+ s=selector.split(".");
212
+ tag=s[0];
213
+ selclass=s[1];
214
+ if(selclass.find(" ")){ //descendant selector like tag1.classname tag2
215
+ s=selclass.split(" ");
216
+ selclass=s[0];
217
+ tag2=s[1];
218
+ }
219
+ }
220
+ var v=document.getElementsByTagName(tag); // tag selector like "tag"
221
+ if(selclass==""){
222
+ for(i=0;i<v.length;i++) objlist.push(v[i]);
223
+ return(objlist);
224
+ }
225
+ for(i=0;i<v.length;i++){
226
+ c=v[i].className.split(" ");
227
+ for(j=0;j<c.length;j++){
228
+ if(c[j]==selclass){
229
+ if(tag2=="") objlist.push(v[i]);
230
+ else{
231
+ v2=v[i].getElementsByTagName(tag2);
232
+ for(k=0;k<v2.length;k++) objlist.push(v2[k]);
233
+ }
234
+ }
235
+ }
236
+ }
237
+ return(objlist);
238
+ }
239
+
240
+ function getParentBk(x){
241
+ var el=x.parentNode,c;
242
+ while(el.tagName.toUpperCase()!="HTML" && (c=getBk(el))=="transparent")
243
+ el=el.parentNode;
244
+ if(c=="transparent") c="#FFFFFF";
245
+ return(c);
246
+ }
247
+
248
+ function getBk(x){
249
+ var c=getStyleProp(x,"backgroundColor");
250
+ if(c==null || c=="transparent" || c.find("rgba(0, 0, 0, 0)"))
251
+ return("transparent");
252
+ if(c.find("rgb")) c=rgb2hex(c);
253
+ return(c);
254
+ }
255
+
256
+ function getPadding(x,side){
257
+ var p=getStyleProp(x,"padding"+side);
258
+ if(p==null || !p.find("px")) return(0);
259
+ return(parseInt(p));
260
+ }
261
+
262
+ function getStyleProp(x,prop){
263
+ if(x.currentStyle)
264
+ return(x.currentStyle[prop]);
265
+ if(document.defaultView.getComputedStyle)
266
+ return(document.defaultView.getComputedStyle(x,'')[prop]);
267
+ return(null);
268
+ }
269
+
270
+ function rgb2hex(value){
271
+ var hex="",v,h,i;
272
+ var regexp=/([0-9]+)[, ]+([0-9]+)[, ]+([0-9]+)/;
273
+ var h=regexp.exec(value);
274
+ for(i=1;i<4;i++){
275
+ v=parseInt(h[i]).toString(16);
276
+ if(v.length==1) hex+="0"+v;
277
+ else hex+=v;
278
+ }
279
+ return("#"+hex);
280
+ }
281
+
282
+ function Mix(c1,c2){
283
+ var i,step1,step2,x,y,r=new Array(3);
284
+ if(c1.length==4)step1=1;
285
+ else step1=2;
286
+ if(c2.length==4) step2=1;
287
+ else step2=2;
288
+ for(i=0;i<3;i++){
289
+ x=parseInt(c1.substr(1+step1*i,step1),16);
290
+ if(step1==1) x=16*x+x;
291
+ y=parseInt(c2.substr(1+step2*i,step2),16);
292
+ if(step2==1) y=16*y+y;
293
+ r[i]=Math.floor((x*50+y*50)/100);
294
+ r[i]=r[i].toString(16);
295
+ if(r[i].length==1) r[i]="0"+r[i];
296
+ }
297
+ return("#"+r[0]+r[1]+r[2]);
298
+ }