railties 3.0.0.beta4 → 3.0.0.rc

Sign up to get free protection for your applications and to get access to all the features.
Files changed (113) hide show
  1. data/CHANGELOG +24 -6
  2. data/README.rdoc +25 -0
  3. data/guides/assets/javascripts/code_highlighter.js +0 -0
  4. data/guides/assets/javascripts/guides.js +0 -0
  5. data/guides/assets/stylesheets/print.css +0 -0
  6. data/guides/assets/stylesheets/reset.css +0 -0
  7. data/guides/assets/stylesheets/style.css +0 -0
  8. data/guides/source/3_0_release_notes.textile +5 -3
  9. data/guides/source/action_controller_overview.textile +19 -0
  10. data/guides/source/active_record_basics.textile +27 -21
  11. data/guides/source/active_record_querying.textile +39 -37
  12. data/guides/source/{activerecord_validations_callbacks.textile → active_record_validations_callbacks.textile} +30 -29
  13. data/guides/source/active_support_core_extensions.textile +232 -107
  14. data/guides/source/api_documentation_guidelines.textile +187 -0
  15. data/guides/source/association_basics.textile +45 -1
  16. data/guides/source/configuring.textile +7 -7
  17. data/guides/source/contributing_to_rails.textile +42 -15
  18. data/guides/source/form_helpers.textile +1 -1
  19. data/guides/source/generators.textile +37 -37
  20. data/guides/source/getting_started.textile +11 -11
  21. data/guides/source/i18n.textile +1 -1
  22. data/guides/source/index.html.erb +14 -6
  23. data/guides/source/initialization.textile +130 -124
  24. data/guides/source/layout.html.erb +5 -2
  25. data/guides/source/layouts_and_rendering.textile +2 -2
  26. data/guides/source/migrations.textile +4 -3
  27. data/guides/source/plugins.textile +15 -15
  28. data/guides/source/rails_application_templates.textile +2 -2
  29. data/guides/source/routing.textile +83 -62
  30. data/guides/source/security.textile +2 -2
  31. data/guides/w3c_validator.rb +30 -6
  32. data/lib/rails.rb +3 -3
  33. data/lib/rails/application.rb +43 -19
  34. data/lib/rails/application/bootstrap.rb +2 -0
  35. data/lib/rails/application/configuration.rb +3 -3
  36. data/lib/rails/application/finisher.rb +6 -6
  37. data/lib/rails/cli.rb +1 -19
  38. data/lib/rails/commands.rb +5 -5
  39. data/lib/rails/commands/application.rb +1 -1
  40. data/lib/rails/commands/console.rb +1 -4
  41. data/lib/rails/commands/generate.rb +0 -0
  42. data/lib/rails/commands/plugin.rb +57 -52
  43. data/lib/rails/commands/runner.rb +2 -1
  44. data/lib/rails/commands/server.rb +6 -2
  45. data/lib/rails/configuration.rb +2 -3
  46. data/lib/rails/console/app.rb +0 -2
  47. data/lib/rails/engine.rb +14 -15
  48. data/lib/rails/engine/configuration.rb +5 -5
  49. data/lib/rails/generators.rb +2 -3
  50. data/lib/rails/generators/actions.rb +4 -4
  51. data/lib/rails/generators/base.rb +1 -1
  52. data/lib/rails/generators/erb/scaffold/scaffold_generator.rb +1 -6
  53. data/lib/rails/generators/erb/scaffold/templates/_form.html.erb +4 -4
  54. data/lib/rails/generators/erb/scaffold/templates/edit.html.erb +3 -3
  55. data/lib/rails/generators/erb/scaffold/templates/index.html.erb +7 -7
  56. data/lib/rails/generators/erb/scaffold/templates/new.html.erb +2 -2
  57. data/lib/rails/generators/erb/scaffold/templates/show.html.erb +3 -3
  58. data/lib/rails/generators/generated_attribute.rb +2 -1
  59. data/lib/rails/generators/named_base.rb +24 -0
  60. data/lib/rails/generators/rails/app/app_generator.rb +10 -9
  61. data/lib/rails/generators/rails/app/templates/Gemfile +4 -3
  62. data/lib/rails/generators/rails/app/templates/README +6 -31
  63. data/lib/rails/generators/rails/app/templates/Rakefile +1 -1
  64. data/lib/rails/generators/rails/app/templates/app/controllers/application_controller.rb +0 -1
  65. data/lib/rails/generators/rails/app/templates/app/mailers/.empty_directory +0 -0
  66. data/lib/rails/generators/rails/app/templates/config/application.rb +11 -11
  67. data/lib/rails/generators/rails/app/templates/config/databases/ibm_db.yml +36 -24
  68. data/lib/rails/generators/rails/app/templates/config/databases/mysql.yml +1 -1
  69. data/lib/rails/generators/rails/app/templates/config/databases/oracle.yml +1 -1
  70. data/lib/rails/generators/rails/app/templates/config/environments/development.rb.tt +3 -0
  71. data/lib/rails/generators/rails/app/templates/config/environments/production.rb.tt +3 -0
  72. data/lib/rails/generators/rails/app/templates/config/environments/test.rb.tt +3 -0
  73. data/lib/rails/generators/rails/app/templates/config/initializers/inflections.rb +1 -1
  74. data/lib/rails/generators/rails/app/templates/config/initializers/secret_token.rb.tt +2 -2
  75. data/lib/rails/generators/rails/app/templates/config/initializers/session_store.rb.tt +2 -2
  76. data/lib/rails/generators/rails/app/templates/config/routes.rb +1 -1
  77. data/lib/rails/generators/rails/app/templates/public/index.html +0 -17
  78. data/lib/rails/generators/rails/app/templates/public/javascripts/prototype.js +2027 -900
  79. data/lib/rails/generators/rails/app/templates/public/javascripts/rails.js +114 -57
  80. data/lib/rails/generators/rails/app/templates/test/test_helper.rb.tt +1 -1
  81. data/lib/rails/generators/rails/model/USAGE +1 -1
  82. data/lib/rails/generators/rails/resource/resource_generator.rb +4 -14
  83. data/lib/rails/generators/rails/scaffold_controller/scaffold_controller_generator.rb +0 -2
  84. data/lib/rails/generators/rails/scaffold_controller/templates/controller.rb +28 -30
  85. data/lib/rails/generators/resource_helpers.rb +1 -1
  86. data/lib/rails/generators/test_case.rb +25 -11
  87. data/lib/rails/generators/test_unit/model/model_generator.rb +1 -1
  88. data/lib/rails/generators/test_unit/scaffold/scaffold_generator.rb +0 -1
  89. data/lib/rails/generators/test_unit/scaffold/templates/functional_test.rb +13 -15
  90. data/lib/rails/info.rb +1 -2
  91. data/lib/rails/info_routes.rb +1 -1
  92. data/lib/rails/initializable.rb +3 -16
  93. data/lib/rails/paths.rb +31 -36
  94. data/lib/rails/plugin.rb +10 -6
  95. data/lib/rails/rack/logger.rb +11 -13
  96. data/lib/rails/railtie.rb +14 -42
  97. data/lib/rails/ruby_version_check.rb +19 -5
  98. data/lib/rails/script_rails_loader.rb +29 -0
  99. data/lib/rails/tasks/annotations.rake +2 -2
  100. data/lib/rails/tasks/documentation.rake +47 -16
  101. data/lib/rails/tasks/framework.rake +9 -9
  102. data/lib/rails/tasks/middleware.rake +1 -1
  103. data/lib/rails/tasks/misc.rake +5 -5
  104. data/lib/rails/tasks/routes.rake +1 -1
  105. data/lib/rails/tasks/tmp.rake +5 -5
  106. data/lib/rails/test_unit/testing.rake +38 -14
  107. data/lib/rails/version.rb +1 -1
  108. metadata +29 -17
  109. data/README +0 -281
  110. data/lib/rails/application/routes_reloader.rb +0 -46
  111. data/lib/rails/log_subscriber.rb +0 -115
  112. data/lib/rails/log_subscriber/test_helper.rb +0 -97
  113. data/lib/rails/webrick_server.rb +0 -156
@@ -29,46 +29,21 @@ link:files/vendor/rails/actionpack/README.html.
29
29
  == Getting Started
30
30
 
31
31
  1. At the command prompt, create a new Rails application:
32
- <tt>rails myapp</tt> (where <tt>myapp</tt> is the application name)
32
+ <tt>rails new myapp</tt> (where <tt>myapp</tt> is the application name)
33
33
 
34
34
  2. Change directory to <tt>myapp</tt> and start the web server:
35
35
  <tt>cd myapp; rails server</tt> (run with --help for options)
36
36
 
37
37
  3. Go to http://localhost:3000/ and you'll see:
38
- "Welcome aboard: You're riding the Rails!"
38
+ "Welcome aboard: You're riding Ruby on Rails!"
39
39
 
40
- 4. Follow the guidelines to start developing your application. You can find
40
+ 4. Follow the guidelines to start developing your application. You can find
41
41
  the following resources handy:
42
42
 
43
43
  * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
44
44
  * Ruby on Rails Tutorial Book: http://www.railstutorial.org/
45
45
 
46
46
 
47
- == Web Servers
48
-
49
- By default, Rails will try to use Mongrel if it's installed when started with
50
- <tt>rails server</tt>, otherwise Rails will use WEBrick, the web server that
51
- ships with Ruby.
52
-
53
- Mongrel is a Ruby-based web server with a C component (which requires
54
- compilation) that is suitable for development. If you have Ruby Gems installed,
55
- getting up and running with mongrel is as easy as:
56
- <tt>sudo gem install mongrel</tt>.
57
-
58
- You can find more info at: http://mongrel.rubyforge.org
59
-
60
- You can alternatively run Rails applications with other Ruby web servers, e.g.,
61
- {Thin}[http://code.macournoyer.com/thin/], {Ebb}[http://ebb.rubyforge.org/], and
62
- Apache with {mod_rails}[http://www.modrails.com/]. However, <tt>rails server</tt>
63
- doesn't search for or start them.
64
-
65
- For production use, often a web/proxy server, e.g., {Apache}[http://apache.org],
66
- {Nginx}[http://nginx.net/], {LiteSpeed}[http://litespeedtech.com/],
67
- {Lighttpd}[http://www.lighttpd.net/], or {IIS}[http://www.iis.net/], is deployed
68
- as the front end server with the chosen Ruby web server running in the back end
69
- and receiving the proxied requests via one of several protocols (HTTP, CGI, FCGI).
70
-
71
-
72
47
  == Debugging Rails
73
48
 
74
49
  Sometimes your application goes wrong. Fortunately there are a lot of tools that
@@ -96,13 +71,13 @@ The result will be a message in your log file along the lines of:
96
71
 
97
72
  More information on how to use the logger is at http://www.ruby-doc.org/core/
98
73
 
99
- Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
74
+ Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
100
75
  several books available online as well:
101
76
 
102
77
  * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
103
78
  * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
104
79
 
105
- These two books will bring you up to speed on the Ruby language and also on
80
+ These two books will bring you up to speed on the Ruby language and also on
106
81
  programming in general.
107
82
 
108
83
 
@@ -224,7 +199,7 @@ app/controllers
224
199
  ApplicationController which itself descends from ActionController::Base.
225
200
 
226
201
  app/models
227
- Holds models that should be named like post.rb. Models descend from
202
+ Holds models that should be named like post.rb. Models descend from
228
203
  ActiveRecord::Base by default.
229
204
 
230
205
  app/views
@@ -4,4 +4,4 @@
4
4
  require File.expand_path('../config/application', __FILE__)
5
5
  require 'rake'
6
6
 
7
- Rails::Application.load_tasks
7
+ <%= app_const %>.load_tasks
@@ -1,4 +1,3 @@
1
1
  class ApplicationController < ActionController::Base
2
2
  protect_from_forgery
3
- layout 'application'
4
3
  end
@@ -1,6 +1,6 @@
1
1
  require File.expand_path('../boot', __FILE__)
2
2
 
3
- <% unless options[:skip_activerecord] -%>
3
+ <% unless options[:skip_active_record] -%>
4
4
  require 'rails/all'
5
5
  <% else -%>
6
6
  # Pick the frameworks you want:
@@ -21,14 +21,14 @@ module <%= app_const_base %>
21
21
  # Application configuration should go into files in config/initializers
22
22
  # -- all .rb files in that directory are automatically loaded.
23
23
 
24
- # Add additional load paths for your own custom dirs
25
- # config.load_paths += %W( #{config.root}/extras )
24
+ # Custom directories with classes and modules you want to be autoloadable.
25
+ # config.autoload_paths += %W(#{config.root}/extras)
26
26
 
27
27
  # Only load the plugins named here, in the order given (default is alphabetical).
28
- # :all can be used as a placeholder for all plugins not explicitly named
28
+ # :all can be used as a placeholder for all plugins not explicitly named.
29
29
  # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
30
30
 
31
- # Activate observers that should always be running
31
+ # Activate observers that should always be running.
32
32
  # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
33
33
 
34
34
  # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
@@ -39,12 +39,12 @@ module <%= app_const_base %>
39
39
  # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
40
40
  # config.i18n.default_locale = :de
41
41
 
42
- # Configure generators values. Many other options are available, be sure to check the documentation.
43
- # config.generators do |g|
44
- # g.orm :active_record
45
- # g.template_engine :erb
46
- # g.test_framework :test_unit, :fixture => true
47
- # end
42
+ # JavaScript files you want as :defaults (application.js is always included).
43
+ <% if options[:skip_prototype] -%>
44
+ config.action_view.javascript_expansions[:defaults] = %w()
45
+ <% else -%>
46
+ # config.action_view.javascript_expansions[:defaults] = %w(jquery rails)
47
+ <% end -%>
48
48
 
49
49
  # Configure the default encoding used in templates for Ruby 1.9.
50
50
  config.encoding = "utf-8"
@@ -32,40 +32,52 @@
32
32
  # please refer to the latest documents at http://rubyforge.org/docman/?group_id=2361
33
33
 
34
34
  development:
35
- adapter: ibm_db
36
- username: db2inst1
35
+ adapter: ibm_db
36
+ username: db2inst1
37
37
  password:
38
- database: <%= app_name[0,4] %>_dev
39
- #schema: db2inst1
40
- #host: localhost
41
- #port: 50000
42
- #account: my_account
43
- #app_user: my_app_user
38
+ database: <%= app_name[0,4] %>_dev
39
+ #schema: db2inst1
40
+ #host: localhost
41
+ #port: 50000
42
+ #account: my_account
43
+ #app_user: my_app_user
44
44
  #application: my_application
45
45
  #workstation: my_workstation
46
+ #security: SSL
47
+ #timeout: 10
48
+ #authentication: SERVER
49
+ #parameterized: false
46
50
 
47
51
  test:
48
- adapter: ibm_db
49
- username: db2inst1
52
+ adapter: ibm_db
53
+ username: db2inst1
50
54
  password:
51
- database: <%= app_name[0,4] %>_tst
52
- #schema: db2inst1
53
- #host: localhost
54
- #port: 50000
55
- #account: my_account
56
- #app_user: my_app_user
55
+ database: <%= app_name[0,4] %>_tst
56
+ #schema: db2inst1
57
+ #host: localhost
58
+ #port: 50000
59
+ #account: my_account
60
+ #app_user: my_app_user
57
61
  #application: my_application
58
62
  #workstation: my_workstation
63
+ #security: SSL
64
+ #timeout: 10
65
+ #authentication: SERVER
66
+ #parameterized: false
59
67
 
60
68
  production:
61
- adapter: ibm_db
62
- username: db2inst1
69
+ adapter: ibm_db
70
+ username: db2inst1
63
71
  password:
64
- database: <%= app_name[0,8] %>
65
- #schema: db2inst1
66
- #host: localhost
67
- #port: 50000
68
- #account: my_account
69
- #app_user: my_app_user
72
+ database: <%= app_name[0,8] %>
73
+ #schema: db2inst1
74
+ #host: localhost
75
+ #port: 50000
76
+ #account: my_account
77
+ #app_user: my_app_user
70
78
  #application: my_application
71
79
  #workstation: my_workstation
80
+ #security: SSL
81
+ #timeout: 10
82
+ #authentication: SERVER
83
+ #parameterized: false
@@ -52,7 +52,7 @@ production:
52
52
  database: <%= app_name %>_production
53
53
  pool: 5
54
54
  username: root
55
- password:
55
+ password:
56
56
  <% if mysql_socket -%>
57
57
  socket: <%= mysql_socket %>
58
58
  <% else -%>
@@ -36,4 +36,4 @@ production:
36
36
  adapter: oracle
37
37
  database: <%= app_name %>_production
38
38
  username: <%= app_name %>
39
- password:
39
+ password:
@@ -16,4 +16,7 @@
16
16
 
17
17
  # Don't care if the mailer can't send
18
18
  config.action_mailer.raise_delivery_errors = false
19
+
20
+ # Print deprecation notices to the Rails logger
21
+ config.active_support.deprecation = :log
19
22
  end
@@ -43,4 +43,7 @@
43
43
  # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
44
44
  # the I18n.default_locale when a translation can not be found)
45
45
  config.i18n.fallbacks = true
46
+
47
+ # Send deprecation notices to registered listeners
48
+ config.active_support.deprecation = :notify
46
49
  end
@@ -29,4 +29,7 @@
29
29
  # This is necessary if your schema can't be completely dumped by the schema dumper,
30
30
  # like if you have constraints or database-specific column types
31
31
  # config.active_record.schema_format = :sql
32
+
33
+ # Print deprecation notices to the stderr
34
+ config.active_support.deprecation = :stderr
32
35
  end
@@ -1,6 +1,6 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- # Add new inflection rules using the following format
3
+ # Add new inflection rules using the following format
4
4
  # (all these examples are active by default):
5
5
  # ActiveSupport::Inflector.inflections do |inflect|
6
6
  # inflect.plural /^(ox)$/i, '\1en'
@@ -2,6 +2,6 @@
2
2
 
3
3
  # Your secret key for verifying the integrity of signed cookies.
4
4
  # If you change this key, all old signed cookies will become invalid!
5
- # Make sure the secret is at least 30 characters and all random,
5
+ # Make sure the secret is at least 30 characters and all random,
6
6
  # no regular words or you'll be exposed to dictionary attacks.
7
- Rails.application.config.secret_token = '<%= app_secret %>'
7
+ <%= app_const %>.config.secret_token = '<%= app_secret %>'
@@ -1,8 +1,8 @@
1
1
  # Be sure to restart your server when you modify this file.
2
2
 
3
- Rails.application.config.session_store :cookie_store, :key => '_<%= app_name %>_session'
3
+ <%= app_const %>.config.session_store :cookie_store, :key => '_<%= app_name %>_session'
4
4
 
5
5
  # Use the database for sessions instead of the cookie-based default,
6
6
  # which shouldn't be used to store highly confidential information
7
7
  # (create the session table with "rake db:sessions:create")
8
- # Rails.application.config.session_store :active_record_store
8
+ # <%= app_const %>.config.session_store :active_record_store
@@ -1,4 +1,4 @@
1
- <%= app_const %>.routes.draw do |map|
1
+ <%= app_const %>.routes.draw do
2
2
  # The priority is based upon order of creation:
3
3
  # first created -> highest priority.
4
4
 
@@ -210,23 +210,6 @@
210
210
  <div id="page">
211
211
  <div id="sidebar">
212
212
  <ul id="sidebar-items">
213
- <li>
214
- <form id="search" action="http://www.google.com/search" method="get" onSubmit="prepend();">
215
- <input type="hidden" name="hl" value="en" />
216
- <input type="text" id="search-text" name="q" value="site:rubyonrails.org " />
217
- <input type="submit" value="Search" /> the Rails site
218
- </form>
219
- </li>
220
-
221
- <li>
222
- <h3>Join the community</h3>
223
- <ul class="links">
224
- <li><a href="http://www.rubyonrails.org/">Ruby on Rails</a></li>
225
- <li><a href="http://weblog.rubyonrails.org/">Official weblog</a></li>
226
- <li><a href="http://wiki.rubyonrails.org/">Wiki</a></li>
227
- </ul>
228
- </li>
229
-
230
213
  <li>
231
214
  <h3>Browse the documentation</h3>
232
215
  <ul class="links">
@@ -1,5 +1,5 @@
1
- /* Prototype JavaScript framework, version 1.6.1
2
- * (c) 2005-2009 Sam Stephenson
1
+ /* Prototype JavaScript framework, version 1.7_rc2
2
+ * (c) 2005-2010 Sam Stephenson
3
3
  *
4
4
  * Prototype is freely distributable under the terms of an MIT-style license.
5
5
  * For details, see the Prototype web site: http://www.prototypejs.org/
@@ -7,7 +7,8 @@
7
7
  *--------------------------------------------------------------------------*/
8
8
 
9
9
  var Prototype = {
10
- Version: '1.6.1',
10
+
11
+ Version: '1.7_rc2',
11
12
 
12
13
  Browser: (function(){
13
14
  var ua = navigator.userAgent;
@@ -17,13 +18,15 @@ var Prototype = {
17
18
  Opera: isOpera,
18
19
  WebKit: ua.indexOf('AppleWebKit/') > -1,
19
20
  Gecko: ua.indexOf('Gecko') > -1 && ua.indexOf('KHTML') === -1,
20
- MobileSafari: /Apple.*Mobile.*Safari/.test(ua)
21
+ MobileSafari: /Apple.*Mobile/.test(ua)
21
22
  }
22
23
  })(),
23
24
 
24
25
  BrowserFeatures: {
25
26
  XPath: !!document.evaluate,
27
+
26
28
  SelectorsAPI: !!document.querySelector,
29
+
27
30
  ElementExtensions: (function() {
28
31
  var constructor = window.Element || window.HTMLElement;
29
32
  return !!(constructor && constructor.prototype);
@@ -32,9 +35,9 @@ var Prototype = {
32
35
  if (typeof window.HTMLDivElement !== 'undefined')
33
36
  return true;
34
37
 
35
- var div = document.createElement('div');
36
- var form = document.createElement('form');
37
- var isSupported = false;
38
+ var div = document.createElement('div'),
39
+ form = document.createElement('form'),
40
+ isSupported = false;
38
41
 
39
42
  if (div['__proto__'] && (div['__proto__'] !== form['__proto__'])) {
40
43
  isSupported = true;
@@ -50,6 +53,7 @@ var Prototype = {
50
53
  JSONFilter: /^\/\*-secure-([\s\S]*)\*\/\s*$/,
51
54
 
52
55
  emptyFunction: function() { },
56
+
53
57
  K: function(x) { return x }
54
58
  };
55
59
 
@@ -79,6 +83,14 @@ var Try = {
79
83
  /* Based on Alex Arnell's inheritance implementation. */
80
84
 
81
85
  var Class = (function() {
86
+
87
+ var IS_DONTENUM_BUGGY = (function(){
88
+ for (var p in { toString: 1 }) {
89
+ if (p === 'toString') return false;
90
+ }
91
+ return true;
92
+ })();
93
+
82
94
  function subclass() {};
83
95
  function create() {
84
96
  var parent = null, properties = $A(arguments);
@@ -99,7 +111,7 @@ var Class = (function() {
99
111
  parent.subclasses.push(klass);
100
112
  }
101
113
 
102
- for (var i = 0; i < properties.length; i++)
114
+ for (var i = 0, length = properties.length; i < length; i++)
103
115
  klass.addMethods(properties[i]);
104
116
 
105
117
  if (!klass.prototype.initialize)
@@ -110,10 +122,10 @@ var Class = (function() {
110
122
  }
111
123
 
112
124
  function addMethods(source) {
113
- var ancestor = this.superclass && this.superclass.prototype;
114
- var properties = Object.keys(source);
125
+ var ancestor = this.superclass && this.superclass.prototype,
126
+ properties = Object.keys(source);
115
127
 
116
- if (!Object.keys({ toString: true }).length) {
128
+ if (IS_DONTENUM_BUGGY) {
117
129
  if (source.toString != Object.prototype.toString)
118
130
  properties.push("toString");
119
131
  if (source.valueOf != Object.prototype.valueOf)
@@ -123,7 +135,7 @@ var Class = (function() {
123
135
  for (var i = 0, length = properties.length; i < length; i++) {
124
136
  var property = properties[i], value = source[property];
125
137
  if (ancestor && Object.isFunction(value) &&
126
- value.argumentNames().first() == "$super") {
138
+ value.argumentNames()[0] == "$super") {
127
139
  var method = value;
128
140
  value = (function(m) {
129
141
  return function() { return ancestor[m].apply(this, arguments); };
@@ -147,7 +159,35 @@ var Class = (function() {
147
159
  })();
148
160
  (function() {
149
161
 
150
- var _toString = Object.prototype.toString;
162
+ var _toString = Object.prototype.toString,
163
+ NULL_TYPE = 'Null',
164
+ UNDEFINED_TYPE = 'Undefined',
165
+ BOOLEAN_TYPE = 'Boolean',
166
+ NUMBER_TYPE = 'Number',
167
+ STRING_TYPE = 'String',
168
+ OBJECT_TYPE = 'Object',
169
+ BOOLEAN_CLASS = '[object Boolean]',
170
+ NUMBER_CLASS = '[object Number]',
171
+ STRING_CLASS = '[object String]',
172
+ ARRAY_CLASS = '[object Array]',
173
+ NATIVE_JSON_STRINGIFY_SUPPORT = window.JSON &&
174
+ typeof JSON.stringify === 'function' &&
175
+ JSON.stringify(0) === '0' &&
176
+ typeof JSON.stringify(Prototype.K) === 'undefined';
177
+
178
+ function Type(o) {
179
+ switch(o) {
180
+ case null: return NULL_TYPE;
181
+ case (void 0): return UNDEFINED_TYPE;
182
+ }
183
+ var type = typeof o;
184
+ switch(type) {
185
+ case 'boolean': return BOOLEAN_TYPE;
186
+ case 'number': return NUMBER_TYPE;
187
+ case 'string': return STRING_TYPE;
188
+ }
189
+ return OBJECT_TYPE;
190
+ }
151
191
 
152
192
  function extend(destination, source) {
153
193
  for (var property in source)
@@ -166,27 +206,70 @@ var Class = (function() {
166
206
  }
167
207
  }
168
208
 
169
- function toJSON(object) {
170
- var type = typeof object;
171
- switch (type) {
172
- case 'undefined':
173
- case 'function':
174
- case 'unknown': return;
175
- case 'boolean': return object.toString();
209
+ function toJSON(value) {
210
+ return Str('', { '': value }, []);
211
+ }
212
+
213
+ function Str(key, holder, stack) {
214
+ var value = holder[key],
215
+ type = typeof value;
216
+
217
+ if (Type(value) === OBJECT_TYPE && typeof value.toJSON === 'function') {
218
+ value = value.toJSON(key);
176
219
  }
177
220
 
178
- if (object === null) return 'null';
179
- if (object.toJSON) return object.toJSON();
180
- if (isElement(object)) return;
221
+ var _class = _toString.call(value);
181
222
 
182
- var results = [];
183
- for (var property in object) {
184
- var value = toJSON(object[property]);
185
- if (!isUndefined(value))
186
- results.push(property.toJSON() + ': ' + value);
223
+ switch (_class) {
224
+ case NUMBER_CLASS:
225
+ case BOOLEAN_CLASS:
226
+ case STRING_CLASS:
227
+ value = value.valueOf();
228
+ }
229
+
230
+ switch (value) {
231
+ case null: return 'null';
232
+ case true: return 'true';
233
+ case false: return 'false';
234
+ }
235
+
236
+ type = typeof value;
237
+ switch (type) {
238
+ case 'string':
239
+ return value.inspect(true);
240
+ case 'number':
241
+ return isFinite(value) ? String(value) : 'null';
242
+ case 'object':
243
+
244
+ for (var i = 0, length = stack.length; i < length; i++) {
245
+ if (stack[i] === value) { throw new TypeError(); }
246
+ }
247
+ stack.push(value);
248
+
249
+ var partial = [];
250
+ if (_class === ARRAY_CLASS) {
251
+ for (var i = 0, length = value.length; i < length; i++) {
252
+ var str = Str(i, value, stack);
253
+ partial.push(typeof str === 'undefined' ? 'null' : str);
254
+ }
255
+ partial = '[' + partial.join(',') + ']';
256
+ } else {
257
+ var keys = Object.keys(value);
258
+ for (var i = 0, length = keys.length; i < length; i++) {
259
+ var key = keys[i], str = Str(key, value, stack);
260
+ if (typeof str !== "undefined") {
261
+ partial.push(key.inspect(true)+ ':' + str);
262
+ }
263
+ }
264
+ partial = '{' + partial.join(',') + '}';
265
+ }
266
+ stack.pop();
267
+ return partial;
187
268
  }
269
+ }
188
270
 
189
- return '{' + results.join(', ') + '}';
271
+ function stringify(object) {
272
+ return JSON.stringify(object);
190
273
  }
191
274
 
192
275
  function toQueryString(object) {
@@ -198,9 +281,13 @@ var Class = (function() {
198
281
  }
199
282
 
200
283
  function keys(object) {
284
+ if (Type(object) !== OBJECT_TYPE) { throw new TypeError(); }
201
285
  var results = [];
202
- for (var property in object)
203
- results.push(property);
286
+ for (var property in object) {
287
+ if (object.hasOwnProperty(property)) {
288
+ results.push(property);
289
+ }
290
+ }
204
291
  return results;
205
292
  }
206
293
 
@@ -220,9 +307,15 @@ var Class = (function() {
220
307
  }
221
308
 
222
309
  function isArray(object) {
223
- return _toString.call(object) == "[object Array]";
310
+ return _toString.call(object) === ARRAY_CLASS;
224
311
  }
225
312
 
313
+ var hasNativeIsArray = (typeof Array.isArray == 'function')
314
+ && Array.isArray([]) && !Array.isArray({});
315
+
316
+ if (hasNativeIsArray) {
317
+ isArray = Array.isArray;
318
+ }
226
319
 
227
320
  function isHash(object) {
228
321
  return object instanceof Hash;
@@ -233,11 +326,11 @@ var Class = (function() {
233
326
  }
234
327
 
235
328
  function isString(object) {
236
- return _toString.call(object) == "[object String]";
329
+ return _toString.call(object) === STRING_CLASS;
237
330
  }
238
331
 
239
332
  function isNumber(object) {
240
- return _toString.call(object) == "[object Number]";
333
+ return _toString.call(object) === NUMBER_CLASS;
241
334
  }
242
335
 
243
336
  function isUndefined(object) {
@@ -247,10 +340,10 @@ var Class = (function() {
247
340
  extend(Object, {
248
341
  extend: extend,
249
342
  inspect: inspect,
250
- toJSON: toJSON,
343
+ toJSON: NATIVE_JSON_STRINGIFY_SUPPORT ? stringify : toJSON,
251
344
  toQueryString: toQueryString,
252
345
  toHTML: toHTML,
253
- keys: keys,
346
+ keys: Object.keys || keys,
254
347
  values: values,
255
348
  clone: clone,
256
349
  isElement: isElement,
@@ -311,7 +404,7 @@ Object.extend(Function.prototype, (function() {
311
404
 
312
405
  function delay(timeout) {
313
406
  var __method = this, args = slice.call(arguments, 1);
314
- timeout = timeout * 1000
407
+ timeout = timeout * 1000;
315
408
  return window.setTimeout(function() {
316
409
  return __method.apply(__method, args);
317
410
  }, timeout);
@@ -352,14 +445,28 @@ Object.extend(Function.prototype, (function() {
352
445
  })());
353
446
 
354
447
 
355
- Date.prototype.toJSON = function() {
356
- return '"' + this.getUTCFullYear() + '-' +
357
- (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
358
- this.getUTCDate().toPaddedString(2) + 'T' +
359
- this.getUTCHours().toPaddedString(2) + ':' +
360
- this.getUTCMinutes().toPaddedString(2) + ':' +
361
- this.getUTCSeconds().toPaddedString(2) + 'Z"';
362
- };
448
+
449
+ (function(proto) {
450
+
451
+
452
+ function toISOString() {
453
+ return this.getUTCFullYear() + '-' +
454
+ (this.getUTCMonth() + 1).toPaddedString(2) + '-' +
455
+ this.getUTCDate().toPaddedString(2) + 'T' +
456
+ this.getUTCHours().toPaddedString(2) + ':' +
457
+ this.getUTCMinutes().toPaddedString(2) + ':' +
458
+ this.getUTCSeconds().toPaddedString(2) + 'Z';
459
+ }
460
+
461
+
462
+ function toJSON() {
463
+ return this.toISOString();
464
+ }
465
+
466
+ if (!proto.toISOString) proto.toISOString = toISOString;
467
+ if (!proto.toJSON) proto.toJSON = toJSON;
468
+
469
+ })(Date.prototype);
363
470
 
364
471
 
365
472
  RegExp.prototype.match = RegExp.prototype.test;
@@ -418,6 +525,9 @@ Object.extend(String, {
418
525
  });
419
526
 
420
527
  Object.extend(String.prototype, (function() {
528
+ var NATIVE_JSON_PARSE_SUPPORT = window.JSON &&
529
+ typeof JSON.parse === 'function' &&
530
+ JSON.parse('{"test": true}').test;
421
531
 
422
532
  function prepareReplacement(replacement) {
423
533
  if (Object.isFunction(replacement)) return replacement;
@@ -484,8 +594,8 @@ Object.extend(String.prototype, (function() {
484
594
  }
485
595
 
486
596
  function extractScripts() {
487
- var matchAll = new RegExp(Prototype.ScriptFragment, 'img');
488
- var matchOne = new RegExp(Prototype.ScriptFragment, 'im');
597
+ var matchAll = new RegExp(Prototype.ScriptFragment, 'img'),
598
+ matchOne = new RegExp(Prototype.ScriptFragment, 'im');
489
599
  return (this.match(matchAll) || []).map(function(scriptTag) {
490
600
  return (scriptTag.match(matchOne) || ['', ''])[1];
491
601
  });
@@ -510,8 +620,9 @@ Object.extend(String.prototype, (function() {
510
620
 
511
621
  return match[1].split(separator || '&').inject({ }, function(hash, pair) {
512
622
  if ((pair = pair.split('='))[0]) {
513
- var key = decodeURIComponent(pair.shift());
514
- var value = pair.length > 1 ? pair.join('=') : pair[0];
623
+ var key = decodeURIComponent(pair.shift()),
624
+ value = pair.length > 1 ? pair.join('=') : pair[0];
625
+
515
626
  if (value != undefined) value = decodeURIComponent(value);
516
627
 
517
628
  if (key in hash) {
@@ -538,17 +649,9 @@ Object.extend(String.prototype, (function() {
538
649
  }
539
650
 
540
651
  function camelize() {
541
- var parts = this.split('-'), len = parts.length;
542
- if (len == 1) return parts[0];
543
-
544
- var camelized = this.charAt(0) == '-'
545
- ? parts[0].charAt(0).toUpperCase() + parts[0].substring(1)
546
- : parts[0];
547
-
548
- for (var i = 1; i < len; i++)
549
- camelized += parts[i].charAt(0).toUpperCase() + parts[i].substring(1);
550
-
551
- return camelized;
652
+ return this.replace(/-+(.)?/g, function(match, chr) {
653
+ return chr ? chr.toUpperCase() : '';
654
+ });
552
655
  }
553
656
 
554
657
  function capitalize() {
@@ -578,10 +681,6 @@ Object.extend(String.prototype, (function() {
578
681
  return "'" + escapedString.replace(/'/g, '\\\'') + "'";
579
682
  }
580
683
 
581
- function toJSON() {
582
- return this.inspect(true);
583
- }
584
-
585
684
  function unfilterJSON(filter) {
586
685
  return this.replace(filter || Prototype.JSONFilter, '$1');
587
686
  }
@@ -589,29 +688,42 @@ Object.extend(String.prototype, (function() {
589
688
  function isJSON() {
590
689
  var str = this;
591
690
  if (str.blank()) return false;
592
- str = this.replace(/\\./g, '@').replace(/"[^"\\\n\r]*"/g, '');
593
- return (/^[,:{}\[\]0-9.\-+Eaeflnr-u \n\r\t]*$/).test(str);
691
+ str = str.replace(/\\(?:["\\\/bfnrt]|u[0-9a-fA-F]{4})/g, '@');
692
+ str = str.replace(/"[^"\\\n\r]*"|true|false|null|-?\d+(?:\.\d*)?(?:[eE][+\-]?\d+)?/g, ']');
693
+ str = str.replace(/(?:^|:|,)(?:\s*\[)+/g, '');
694
+ return (/^[\],:{}\s]*$/).test(str);
594
695
  }
595
696
 
596
697
  function evalJSON(sanitize) {
597
- var json = this.unfilterJSON();
698
+ var json = this.unfilterJSON(),
699
+ cx = /[\u0000\u00ad\u0600-\u0604\u070f\u17b4\u17b5\u200c-\u200f\u2028-\u202f\u2060-\u206f\ufeff\ufff0-\uffff]/g;
700
+ if (cx.test(json)) {
701
+ json = json.replace(cx, function (a) {
702
+ return '\\u' + ('0000' + a.charCodeAt(0).toString(16)).slice(-4);
703
+ });
704
+ }
598
705
  try {
599
706
  if (!sanitize || json.isJSON()) return eval('(' + json + ')');
600
707
  } catch (e) { }
601
708
  throw new SyntaxError('Badly formed JSON string: ' + this.inspect());
602
709
  }
603
710
 
711
+ function parseJSON() {
712
+ var json = this.unfilterJSON();
713
+ return JSON.parse(json);
714
+ }
715
+
604
716
  function include(pattern) {
605
717
  return this.indexOf(pattern) > -1;
606
718
  }
607
719
 
608
720
  function startsWith(pattern) {
609
- return this.indexOf(pattern) === 0;
721
+ return this.lastIndexOf(pattern, 0) === 0;
610
722
  }
611
723
 
612
724
  function endsWith(pattern) {
613
725
  var d = this.length - pattern.length;
614
- return d >= 0 && this.lastIndexOf(pattern) === d;
726
+ return d >= 0 && this.indexOf(pattern, d) === d;
615
727
  }
616
728
 
617
729
  function empty() {
@@ -631,7 +743,7 @@ Object.extend(String.prototype, (function() {
631
743
  sub: sub,
632
744
  scan: scan,
633
745
  truncate: truncate,
634
- strip: String.prototype.trim ? String.prototype.trim : strip,
746
+ strip: String.prototype.trim || strip,
635
747
  stripTags: stripTags,
636
748
  stripScripts: stripScripts,
637
749
  extractScripts: extractScripts,
@@ -648,10 +760,9 @@ Object.extend(String.prototype, (function() {
648
760
  underscore: underscore,
649
761
  dasherize: dasherize,
650
762
  inspect: inspect,
651
- toJSON: toJSON,
652
763
  unfilterJSON: unfilterJSON,
653
764
  isJSON: isJSON,
654
- evalJSON: evalJSON,
765
+ evalJSON: NATIVE_JSON_PARSE_SUPPORT ? parseJSON : evalJSON,
655
766
  include: include,
656
767
  startsWith: startsWith,
657
768
  endsWith: endsWith,
@@ -677,8 +788,9 @@ var Template = Class.create({
677
788
  var before = match[1] || '';
678
789
  if (before == '\\') return match[2];
679
790
 
680
- var ctx = object, expr = match[3];
681
- var pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
791
+ var ctx = object, expr = match[3],
792
+ pattern = /^([^.[]+|\[((?:.*?[^\\])?)\])(\.|\[|$)/;
793
+
682
794
  match = pattern.exec(expr);
683
795
  if (match == null) return before;
684
796
 
@@ -943,6 +1055,7 @@ var Enumerable = (function() {
943
1055
  find: detect
944
1056
  };
945
1057
  })();
1058
+
946
1059
  function $A(iterable) {
947
1060
  if (!iterable) return [];
948
1061
  if ('toArray' in Object(iterable)) return iterable.toArray();
@@ -951,6 +1064,7 @@ function $A(iterable) {
951
1064
  return results;
952
1065
  }
953
1066
 
1067
+
954
1068
  function $w(string) {
955
1069
  if (!Object.isString(string)) return [];
956
1070
  string = string.strip();
@@ -1007,7 +1121,7 @@ Array.from = $A;
1007
1121
  }
1008
1122
 
1009
1123
  function reverse(inline) {
1010
- return (inline !== false ? this : this.toArray())._reverse();
1124
+ return (inline === false ? this.toArray() : this)._reverse();
1011
1125
  }
1012
1126
 
1013
1127
  function uniq(sorted) {
@@ -1037,15 +1151,6 @@ Array.from = $A;
1037
1151
  return '[' + this.map(Object.inspect).join(', ') + ']';
1038
1152
  }
1039
1153
 
1040
- function toJSON() {
1041
- var results = [];
1042
- this.each(function(object) {
1043
- var value = Object.toJSON(object);
1044
- if (!Object.isUndefined(value)) results.push(value);
1045
- });
1046
- return '[' + results.join(', ') + ']';
1047
- }
1048
-
1049
1154
  function indexOf(item, i) {
1050
1155
  i || (i = 0);
1051
1156
  var length = this.length;
@@ -1094,8 +1199,7 @@ Array.from = $A;
1094
1199
  clone: clone,
1095
1200
  toArray: clone,
1096
1201
  size: size,
1097
- inspect: inspect,
1098
- toJSON: toJSON
1202
+ inspect: inspect
1099
1203
  });
1100
1204
 
1101
1205
  var CONCAT_ARGUMENTS_BUGGY = (function() {
@@ -1116,6 +1220,7 @@ var Hash = Class.create(Enumerable, (function() {
1116
1220
  this._object = Object.isHash(object) ? object.toObject() : Object.clone(object);
1117
1221
  }
1118
1222
 
1223
+
1119
1224
  function _each(iterator) {
1120
1225
  for (var key in this._object) {
1121
1226
  var value = this._object[key], pair = [key, value];
@@ -1144,6 +1249,8 @@ var Hash = Class.create(Enumerable, (function() {
1144
1249
  return Object.clone(this._object);
1145
1250
  }
1146
1251
 
1252
+
1253
+
1147
1254
  function keys() {
1148
1255
  return this.pluck('key');
1149
1256
  }
@@ -1193,10 +1300,6 @@ var Hash = Class.create(Enumerable, (function() {
1193
1300
  }).join(', ') + '}>';
1194
1301
  }
1195
1302
 
1196
- function toJSON() {
1197
- return Object.toJSON(this.toObject());
1198
- }
1199
-
1200
1303
  function clone() {
1201
1304
  return new Hash(this);
1202
1305
  }
@@ -1216,7 +1319,7 @@ var Hash = Class.create(Enumerable, (function() {
1216
1319
  update: update,
1217
1320
  toQueryString: toQueryString,
1218
1321
  inspect: inspect,
1219
- toJSON: toJSON,
1322
+ toJSON: toObject,
1220
1323
  clone: clone
1221
1324
  };
1222
1325
  })());
@@ -1241,10 +1344,6 @@ Object.extend(Number.prototype, (function() {
1241
1344
  return '0'.times(length - string.length) + string;
1242
1345
  }
1243
1346
 
1244
- function toJSON() {
1245
- return isFinite(this) ? this.toString() : 'null';
1246
- }
1247
-
1248
1347
  function abs() {
1249
1348
  return Math.abs(this);
1250
1349
  }
@@ -1266,7 +1365,6 @@ Object.extend(Number.prototype, (function() {
1266
1365
  succ: succ,
1267
1366
  times: times,
1268
1367
  toPaddedString: toPaddedString,
1269
- toJSON: toJSON,
1270
1368
  abs: abs,
1271
1369
  round: round,
1272
1370
  ceil: ceil,
@@ -1558,14 +1656,14 @@ Ajax.Response = Class.create({
1558
1656
  var transport = this.transport = request.transport,
1559
1657
  readyState = this.readyState = transport.readyState;
1560
1658
 
1561
- if((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1659
+ if ((readyState > 2 && !Prototype.Browser.IE) || readyState == 4) {
1562
1660
  this.status = this.getStatus();
1563
1661
  this.statusText = this.getStatusText();
1564
1662
  this.responseText = String.interpret(transport.responseText);
1565
1663
  this.headerJSON = this._getHeaderJSON();
1566
1664
  }
1567
1665
 
1568
- if(readyState == 4) {
1666
+ if (readyState == 4) {
1569
1667
  var xml = transport.responseXML;
1570
1668
  this.responseXML = Object.isUndefined(xml) ? null : xml;
1571
1669
  this.responseJSON = this._getResponseJSON();
@@ -1705,7 +1803,6 @@ Ajax.PeriodicalUpdater = Class.create(Ajax.Base, {
1705
1803
  });
1706
1804
 
1707
1805
 
1708
-
1709
1806
  function $(element) {
1710
1807
  if (arguments.length > 1) {
1711
1808
  for (var i = 0, elements = [], length = arguments.length; i < length; i++)
@@ -1730,7 +1827,7 @@ if (Prototype.BrowserFeatures.XPath) {
1730
1827
 
1731
1828
  /*--------------------------------------------------------------------------*/
1732
1829
 
1733
- if (!window.Node) var Node = { };
1830
+ if (!Node) var Node = { };
1734
1831
 
1735
1832
  if (!Node.ELEMENT_NODE) {
1736
1833
  Object.extend(Node, {
@@ -1750,29 +1847,26 @@ if (!Node.ELEMENT_NODE) {
1750
1847
  }
1751
1848
 
1752
1849
 
1850
+
1753
1851
  (function(global) {
1754
1852
 
1755
- var SETATTRIBUTE_IGNORES_NAME = (function(){
1756
- var elForm = document.createElement("form");
1757
- var elInput = document.createElement("input");
1758
- var root = document.documentElement;
1759
- elInput.setAttribute("name", "test");
1760
- elForm.appendChild(elInput);
1761
- root.appendChild(elForm);
1762
- var isBuggy = elForm.elements
1763
- ? (typeof elForm.elements.test == "undefined")
1764
- : null;
1765
- root.removeChild(elForm);
1766
- elForm = elInput = null;
1767
- return isBuggy;
1853
+ var HAS_EXTENDED_CREATE_ELEMENT_SYNTAX = (function(){
1854
+ try {
1855
+ var el = document.createElement('<input name="x">');
1856
+ return el.tagName.toLowerCase() === 'input' && el.name === 'x';
1857
+ }
1858
+ catch(err) {
1859
+ return false;
1860
+ }
1768
1861
  })();
1769
1862
 
1770
1863
  var element = global.Element;
1864
+
1771
1865
  global.Element = function(tagName, attributes) {
1772
1866
  attributes = attributes || { };
1773
1867
  tagName = tagName.toLowerCase();
1774
1868
  var cache = Element.cache;
1775
- if (SETATTRIBUTE_IGNORES_NAME && attributes.name) {
1869
+ if (HAS_EXTENDED_CREATE_ELEMENT_SYNTAX && attributes.name) {
1776
1870
  tagName = '<' + tagName + ' name="' + attributes.name + '">';
1777
1871
  delete attributes.name;
1778
1872
  return Element.writeAttribute(document.createElement(tagName), attributes);
@@ -1780,12 +1874,23 @@ if (!Node.ELEMENT_NODE) {
1780
1874
  if (!cache[tagName]) cache[tagName] = Element.extend(document.createElement(tagName));
1781
1875
  return Element.writeAttribute(cache[tagName].cloneNode(false), attributes);
1782
1876
  };
1877
+
1783
1878
  Object.extend(global.Element, element || { });
1784
1879
  if (element) global.Element.prototype = element.prototype;
1880
+
1785
1881
  })(this);
1786
1882
 
1787
- Element.cache = { };
1788
1883
  Element.idCounter = 1;
1884
+ Element.cache = { };
1885
+
1886
+ function purgeElement(element) {
1887
+ var uid = element._prototypeUID;
1888
+ if (uid) {
1889
+ Element.stopObserving(element);
1890
+ element._prototypeUID = void 0;
1891
+ delete Element.Storage[uid];
1892
+ }
1893
+ }
1789
1894
 
1790
1895
  Element.Methods = {
1791
1896
  visible: function(element) {
@@ -1798,7 +1903,6 @@ Element.Methods = {
1798
1903
  return element;
1799
1904
  },
1800
1905
 
1801
-
1802
1906
  hide: function(element) {
1803
1907
  element = $(element);
1804
1908
  element.style.display = 'none';
@@ -1861,6 +1965,10 @@ Element.Methods = {
1861
1965
  function update(element, content) {
1862
1966
  element = $(element);
1863
1967
 
1968
+ var descendants = element.getElementsByTagName('*'),
1969
+ i = descendants.length;
1970
+ while (i--) purgeElement(descendants[i]);
1971
+
1864
1972
  if (content && content.toElement)
1865
1973
  content = content.toElement();
1866
1974
 
@@ -1967,19 +2075,26 @@ Element.Methods = {
1967
2075
  element = $(element);
1968
2076
  var result = '<' + element.tagName.toLowerCase();
1969
2077
  $H({'id': 'id', 'className': 'class'}).each(function(pair) {
1970
- var property = pair.first(), attribute = pair.last();
1971
- var value = (element[property] || '').toString();
2078
+ var property = pair.first(),
2079
+ attribute = pair.last(),
2080
+ value = (element[property] || '').toString();
1972
2081
  if (value) result += ' ' + attribute + '=' + value.inspect(true);
1973
2082
  });
1974
2083
  return result + '>';
1975
2084
  },
1976
2085
 
1977
- recursivelyCollect: function(element, property) {
2086
+ recursivelyCollect: function(element, property, maximumLength) {
1978
2087
  element = $(element);
2088
+ maximumLength = maximumLength || -1;
1979
2089
  var elements = [];
1980
- while (element = element[property])
2090
+
2091
+ while (element = element[property]) {
1981
2092
  if (element.nodeType == 1)
1982
2093
  elements.push(Element.extend(element));
2094
+ if (elements.length == maximumLength)
2095
+ break;
2096
+ }
2097
+
1983
2098
  return elements;
1984
2099
  },
1985
2100
 
@@ -1998,13 +2113,17 @@ Element.Methods = {
1998
2113
  },
1999
2114
 
2000
2115
  immediateDescendants: function(element) {
2001
- if (!(element = $(element).firstChild)) return [];
2002
- while (element && element.nodeType != 1) element = element.nextSibling;
2003
- if (element) return [element].concat($(element).nextSiblings());
2004
- return [];
2116
+ var results = [], child = $(element).firstChild;
2117
+ while (child) {
2118
+ if (child.nodeType === 1) {
2119
+ results.push(Element.extend(child));
2120
+ }
2121
+ child = child.nextSibling;
2122
+ }
2123
+ return results;
2005
2124
  },
2006
2125
 
2007
- previousSiblings: function(element) {
2126
+ previousSiblings: function(element, maximumLength) {
2008
2127
  return Element.recursivelyCollect(element, 'previousSibling');
2009
2128
  },
2010
2129
 
@@ -2019,9 +2138,10 @@ Element.Methods = {
2019
2138
  },
2020
2139
 
2021
2140
  match: function(element, selector) {
2141
+ element = $(element);
2022
2142
  if (Object.isString(selector))
2023
- selector = new Selector(selector);
2024
- return selector.match($(element));
2143
+ return Prototype.Selector.match(element, selector);
2144
+ return selector.match(element);
2025
2145
  },
2026
2146
 
2027
2147
  up: function(element, expression, index) {
@@ -2029,7 +2149,7 @@ Element.Methods = {
2029
2149
  if (arguments.length == 1) return $(element.parentNode);
2030
2150
  var ancestors = Element.ancestors(element);
2031
2151
  return Object.isNumber(expression) ? ancestors[expression] :
2032
- Selector.findElement(ancestors, expression, index);
2152
+ Prototype.Selector.find(ancestors, expression, index);
2033
2153
  },
2034
2154
 
2035
2155
  down: function(element, expression, index) {
@@ -2041,29 +2161,40 @@ Element.Methods = {
2041
2161
 
2042
2162
  previous: function(element, expression, index) {
2043
2163
  element = $(element);
2044
- if (arguments.length == 1) return $(Selector.handlers.previousElementSibling(element));
2045
- var previousSiblings = Element.previousSiblings(element);
2046
- return Object.isNumber(expression) ? previousSiblings[expression] :
2047
- Selector.findElement(previousSiblings, expression, index);
2164
+ if (Object.isNumber(expression)) index = expression, expression = false;
2165
+ if (!Object.isNumber(index)) index = 0;
2166
+
2167
+ if (expression) {
2168
+ return Prototype.Selector.find(element.previousSiblings(), expression, index);
2169
+ } else {
2170
+ return element.recursivelyCollect("previousSibling", index + 1)[index];
2171
+ }
2048
2172
  },
2049
2173
 
2050
2174
  next: function(element, expression, index) {
2051
2175
  element = $(element);
2052
- if (arguments.length == 1) return $(Selector.handlers.nextElementSibling(element));
2053
- var nextSiblings = Element.nextSiblings(element);
2054
- return Object.isNumber(expression) ? nextSiblings[expression] :
2055
- Selector.findElement(nextSiblings, expression, index);
2176
+ if (Object.isNumber(expression)) index = expression, expression = false;
2177
+ if (!Object.isNumber(index)) index = 0;
2178
+
2179
+ if (expression) {
2180
+ return Prototype.Selector.find(element.nextSiblings(), expression, index);
2181
+ } else {
2182
+ var maximumLength = Object.isNumber(index) ? index + 1 : 1;
2183
+ return element.recursivelyCollect("nextSibling", index + 1)[index];
2184
+ }
2056
2185
  },
2057
2186
 
2058
2187
 
2059
2188
  select: function(element) {
2060
- var args = Array.prototype.slice.call(arguments, 1);
2061
- return Selector.findChildElements(element, args);
2189
+ element = $(element);
2190
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2191
+ return Prototype.Selector.select(expressions, element);
2062
2192
  },
2063
2193
 
2064
2194
  adjacent: function(element) {
2065
- var args = Array.prototype.slice.call(arguments, 1);
2066
- return Selector.findChildElements(element.parentNode, args).without(element);
2195
+ element = $(element);
2196
+ var expressions = Array.prototype.slice.call(arguments, 1).join(', ');
2197
+ return Prototype.Selector.select(expressions, element.parentNode).without(element);
2067
2198
  },
2068
2199
 
2069
2200
  identify: function(element) {
@@ -2227,28 +2358,6 @@ Element.Methods = {
2227
2358
  return element;
2228
2359
  },
2229
2360
 
2230
- getDimensions: function(element) {
2231
- element = $(element);
2232
- var display = Element.getStyle(element, 'display');
2233
- if (display != 'none' && display != null) // Safari bug
2234
- return {width: element.offsetWidth, height: element.offsetHeight};
2235
-
2236
- var els = element.style;
2237
- var originalVisibility = els.visibility;
2238
- var originalPosition = els.position;
2239
- var originalDisplay = els.display;
2240
- els.visibility = 'hidden';
2241
- if (originalPosition != 'fixed') // Switching fixed to absolute causes issues in Safari
2242
- els.position = 'absolute';
2243
- els.display = 'block';
2244
- var originalWidth = element.clientWidth;
2245
- var originalHeight = element.clientHeight;
2246
- els.display = originalDisplay;
2247
- els.position = originalPosition;
2248
- els.visibility = originalVisibility;
2249
- return {width: originalWidth, height: originalHeight};
2250
- },
2251
-
2252
2361
  makePositioned: function(element) {
2253
2362
  element = $(element);
2254
2363
  var pos = Element.getStyle(element, 'position');
@@ -2295,11 +2404,13 @@ Element.Methods = {
2295
2404
 
2296
2405
  cumulativeOffset: function(element) {
2297
2406
  var valueT = 0, valueL = 0;
2298
- do {
2299
- valueT += element.offsetTop || 0;
2300
- valueL += element.offsetLeft || 0;
2301
- element = element.offsetParent;
2302
- } while (element);
2407
+ if (element.parentNode) {
2408
+ do {
2409
+ valueT += element.offsetTop || 0;
2410
+ valueL += element.offsetLeft || 0;
2411
+ element = element.offsetParent;
2412
+ } while (element);
2413
+ }
2303
2414
  return Element._returnOffset(valueL, valueT);
2304
2415
  },
2305
2416
 
@@ -2322,11 +2433,11 @@ Element.Methods = {
2322
2433
  element = $(element);
2323
2434
  if (Element.getStyle(element, 'position') == 'absolute') return element;
2324
2435
 
2325
- var offsets = Element.positionedOffset(element);
2326
- var top = offsets[1];
2327
- var left = offsets[0];
2328
- var width = element.clientWidth;
2329
- var height = element.clientHeight;
2436
+ var offsets = Element.positionedOffset(element),
2437
+ top = offsets[1],
2438
+ left = offsets[0],
2439
+ width = element.clientWidth,
2440
+ height = element.clientHeight;
2330
2441
 
2331
2442
  element._originalLeft = left - parseFloat(element.style.left || 0);
2332
2443
  element._originalTop = top - parseFloat(element.style.top || 0);
@@ -2346,8 +2457,8 @@ Element.Methods = {
2346
2457
  if (Element.getStyle(element, 'position') == 'relative') return element;
2347
2458
 
2348
2459
  element.style.position = 'relative';
2349
- var top = parseFloat(element.style.top || 0) - (element._originalTop || 0);
2350
- var left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
2460
+ var top = parseFloat(element.style.top || 0) - (element._originalTop || 0),
2461
+ left = parseFloat(element.style.left || 0) - (element._originalLeft || 0);
2351
2462
 
2352
2463
  element.style.top = top + 'px';
2353
2464
  element.style.left = left + 'px';
@@ -2378,9 +2489,10 @@ Element.Methods = {
2378
2489
  },
2379
2490
 
2380
2491
  viewportOffset: function(forElement) {
2381
- var valueT = 0, valueL = 0;
2492
+ var valueT = 0,
2493
+ valueL = 0,
2494
+ element = forElement;
2382
2495
 
2383
- var element = forElement;
2384
2496
  do {
2385
2497
  valueT += element.offsetTop || 0;
2386
2498
  valueL += element.offsetLeft || 0;
@@ -2412,11 +2524,10 @@ Element.Methods = {
2412
2524
  }, arguments[2] || { });
2413
2525
 
2414
2526
  source = $(source);
2415
- var p = Element.viewportOffset(source);
2527
+ var p = Element.viewportOffset(source), delta = [0, 0], parent = null;
2416
2528
 
2417
2529
  element = $(element);
2418
- var delta = [0, 0];
2419
- var parent = null;
2530
+
2420
2531
  if (Element.getStyle(element, 'position') == 'absolute') {
2421
2532
  parent = Element.getOffsetParent(element);
2422
2533
  delta = Element.viewportOffset(parent);
@@ -2495,8 +2606,7 @@ else if (Prototype.Browser.IE) {
2495
2606
  Element.Methods.getOffsetParent = Element.Methods.getOffsetParent.wrap(
2496
2607
  function(proceed, element) {
2497
2608
  element = $(element);
2498
- try { element.offsetParent }
2499
- catch(e) { return $(document.body) }
2609
+ if (!element.parentNode) return $(document.body);
2500
2610
  var position = element.getStyle('position');
2501
2611
  if (position !== 'static') return proceed(element);
2502
2612
  element.setStyle({ position: 'relative' });
@@ -2510,8 +2620,7 @@ else if (Prototype.Browser.IE) {
2510
2620
  Element.Methods[method] = Element.Methods[method].wrap(
2511
2621
  function(proceed, element) {
2512
2622
  element = $(element);
2513
- try { element.offsetParent }
2514
- catch(e) { return Element._returnOffset(0,0) }
2623
+ if (!element.parentNode) return Element._returnOffset(0, 0);
2515
2624
  var position = element.getStyle('position');
2516
2625
  if (position !== 'static') return proceed(element);
2517
2626
  var offsetParent = element.getOffsetParent();
@@ -2525,14 +2634,6 @@ else if (Prototype.Browser.IE) {
2525
2634
  );
2526
2635
  });
2527
2636
 
2528
- Element.Methods.cumulativeOffset = Element.Methods.cumulativeOffset.wrap(
2529
- function(proceed, element) {
2530
- try { element.offsetParent }
2531
- catch(e) { return Element._returnOffset(0,0) }
2532
- return proceed(element);
2533
- }
2534
- );
2535
-
2536
2637
  Element.Methods.getStyle = function(element, style) {
2537
2638
  element = $(element);
2538
2639
  style = (style == 'float' || style == 'cssFloat') ? 'styleFloat' : style.camelize();
@@ -2576,10 +2677,9 @@ else if (Prototype.Browser.IE) {
2576
2677
 
2577
2678
  Element._attributeTranslations = (function(){
2578
2679
 
2579
- var classProp = 'className';
2580
- var forProp = 'for';
2581
-
2582
- var el = document.createElement('div');
2680
+ var classProp = 'className',
2681
+ forProp = 'for',
2682
+ el = document.createElement('div');
2583
2683
 
2584
2684
  el.setAttribute(classProp, 'x');
2585
2685
 
@@ -2622,10 +2722,9 @@ else if (Prototype.Browser.IE) {
2622
2722
  },
2623
2723
  _getEv: (function(){
2624
2724
 
2625
- var el = document.createElement('div');
2725
+ var el = document.createElement('div'), f;
2626
2726
  el.onclick = Prototype.emptyFunction;
2627
2727
  var value = el.getAttribute('onclick');
2628
- var f;
2629
2728
 
2630
2729
  if (String(value).indexOf('{') > -1) {
2631
2730
  f = function(element, attribute) {
@@ -2753,7 +2852,7 @@ else if (Prototype.Browser.WebKit) {
2753
2852
  (value < 0.00001) ? 0 : value;
2754
2853
 
2755
2854
  if (value == 1)
2756
- if(element.tagName.toUpperCase() == 'IMG' && element.width) {
2855
+ if (element.tagName.toUpperCase() == 'IMG' && element.width) {
2757
2856
  element.width++; element.width--;
2758
2857
  } else try {
2759
2858
  var n = document.createTextNode(' ');
@@ -2793,8 +2892,8 @@ if ('outerHTML' in document.documentElement) {
2793
2892
  var parent = element.parentNode, tagName = parent.tagName.toUpperCase();
2794
2893
 
2795
2894
  if (Element._insertionTranslations.tags[tagName]) {
2796
- var nextSibling = element.next();
2797
- var fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2895
+ var nextSibling = element.next(),
2896
+ fragments = Element._getContentFromAnonymousElement(tagName, content.stripScripts());
2798
2897
  parent.removeChild(element);
2799
2898
  if (nextSibling)
2800
2899
  fragments.each(function(node) { parent.insertBefore(node, nextSibling) });
@@ -2816,11 +2915,17 @@ Element._returnOffset = function(l, t) {
2816
2915
  };
2817
2916
 
2818
2917
  Element._getContentFromAnonymousElement = function(tagName, html) {
2819
- var div = new Element('div'), t = Element._insertionTranslations.tags[tagName];
2918
+ var div = new Element('div'),
2919
+ t = Element._insertionTranslations.tags[tagName];
2820
2920
  if (t) {
2821
2921
  div.innerHTML = t[0] + html + t[1];
2822
- t[2].times(function() { div = div.firstChild });
2823
- } else div.innerHTML = html;
2922
+ for (var i = t[2]; i--; ) {
2923
+ div = div.firstChild;
2924
+ }
2925
+ }
2926
+ else {
2927
+ div.innerHTML = html;
2928
+ }
2824
2929
  return $A(div.childNodes);
2825
2930
  };
2826
2931
 
@@ -2877,7 +2982,7 @@ Object.extend(Element, Element.Methods);
2877
2982
 
2878
2983
  div = null;
2879
2984
 
2880
- })(document.createElement('div'))
2985
+ })(document.createElement('div'));
2881
2986
 
2882
2987
  Element.extend = (function() {
2883
2988
 
@@ -2885,8 +2990,8 @@ Element.extend = (function() {
2885
2990
  if (typeof window.Element != 'undefined') {
2886
2991
  var proto = window.Element.prototype;
2887
2992
  if (proto) {
2888
- var id = '_' + (Math.random()+'').slice(2);
2889
- var el = document.createElement(tagName);
2993
+ var id = '_' + (Math.random()+'').slice(2),
2994
+ el = document.createElement(tagName);
2890
2995
  proto[id] = 'x';
2891
2996
  var isBuggy = (el[id] !== 'x');
2892
2997
  delete proto[id];
@@ -2953,10 +3058,14 @@ Element.extend = (function() {
2953
3058
  return extend;
2954
3059
  })();
2955
3060
 
2956
- Element.hasAttribute = function(element, attribute) {
2957
- if (element.hasAttribute) return element.hasAttribute(attribute);
2958
- return Element.Methods.Simulated.hasAttribute(element, attribute);
2959
- };
3061
+ if (document.documentElement.hasAttribute) {
3062
+ Element.hasAttribute = function(element, attribute) {
3063
+ return element.hasAttribute(attribute);
3064
+ };
3065
+ }
3066
+ else {
3067
+ Element.hasAttribute = Element.Methods.Simulated.hasAttribute;
3068
+ }
2960
3069
 
2961
3070
  Element.addMethods = function(methods) {
2962
3071
  var F = Prototype.BrowserFeatures, T = Element.Methods.ByTag;
@@ -3020,8 +3129,9 @@ Element.addMethods = function(methods) {
3020
3129
  klass = 'HTML' + tagName.capitalize() + 'Element';
3021
3130
  if (window[klass]) return window[klass];
3022
3131
 
3023
- var element = document.createElement(tagName);
3024
- var proto = element['__proto__'] || element.constructor.prototype;
3132
+ var element = document.createElement(tagName),
3133
+ proto = element['__proto__'] || element.constructor.prototype;
3134
+
3025
3135
  element = null;
3026
3136
  return proto;
3027
3137
  }
@@ -3104,8 +3214,8 @@ Element.addMethods({
3104
3214
  uid = 0;
3105
3215
  } else {
3106
3216
  if (typeof element._prototypeUID === "undefined")
3107
- element._prototypeUID = [Element.Storage.UID++];
3108
- uid = element._prototypeUID[0];
3217
+ element._prototypeUID = Element.Storage.UID++;
3218
+ uid = element._prototypeUID;
3109
3219
  }
3110
3220
 
3111
3221
  if (!Element.Storage[uid])
@@ -3150,770 +3260,1698 @@ Element.addMethods({
3150
3260
  }
3151
3261
  }
3152
3262
  return Element.extend(clone);
3153
- }
3154
- });
3155
- /* Portions of the Selector class are derived from Jack Slocum's DomQuery,
3156
- * part of YUI-Ext version 0.40, distributed under the terms of an MIT-style
3157
- * license. Please see http://www.yui-ext.com/ for more information. */
3158
-
3159
- var Selector = Class.create({
3160
- initialize: function(expression) {
3161
- this.expression = expression.strip();
3162
-
3163
- if (this.shouldUseSelectorsAPI()) {
3164
- this.mode = 'selectorsAPI';
3165
- } else if (this.shouldUseXPath()) {
3166
- this.mode = 'xpath';
3167
- this.compileXPathMatcher();
3168
- } else {
3169
- this.mode = "normal";
3170
- this.compileMatcher();
3171
- }
3172
-
3173
3263
  },
3174
3264
 
3175
- shouldUseXPath: (function() {
3176
-
3177
- var IS_DESCENDANT_SELECTOR_BUGGY = (function(){
3178
- var isBuggy = false;
3179
- if (document.evaluate && window.XPathResult) {
3180
- var el = document.createElement('div');
3181
- el.innerHTML = '<ul><li></li></ul><div><ul><li></li></ul></div>';
3182
-
3183
- var xpath = ".//*[local-name()='ul' or local-name()='UL']" +
3184
- "//*[local-name()='li' or local-name()='LI']";
3185
-
3186
- var result = document.evaluate(xpath, el, null,
3187
- XPathResult.ORDERED_NODE_SNAPSHOT_TYPE, null);
3188
-
3189
- isBuggy = (result.snapshotLength !== 2);
3190
- el = null;
3191
- }
3192
- return isBuggy;
3193
- })();
3265
+ purge: function(element) {
3266
+ if (!(element = $(element))) return;
3267
+ purgeElement(element);
3194
3268
 
3195
- return function() {
3196
- if (!Prototype.BrowserFeatures.XPath) return false;
3269
+ var descendants = element.getElementsByTagName('*'),
3270
+ i = descendants.length;
3197
3271
 
3198
- var e = this.expression;
3272
+ while (i--) purgeElement(descendants[i]);
3199
3273
 
3200
- if (Prototype.Browser.WebKit &&
3201
- (e.include("-of-type") || e.include(":empty")))
3202
- return false;
3274
+ return null;
3275
+ }
3276
+ });
3203
3277
 
3204
- if ((/(\[[\w-]*?:|:checked)/).test(e))
3205
- return false;
3278
+ (function() {
3206
3279
 
3207
- if (IS_DESCENDANT_SELECTOR_BUGGY) return false;
3280
+ function toDecimal(pctString) {
3281
+ var match = pctString.match(/^(\d+)%?$/i);
3282
+ if (!match) return null;
3283
+ return (Number(match[1]) / 100);
3284
+ }
3208
3285
 
3209
- return true;
3286
+ function getPixelValue(value, property) {
3287
+ if (Object.isElement(value)) {
3288
+ element = value;
3289
+ value = element.getStyle(property);
3210
3290
  }
3211
-
3212
- })(),
3213
-
3214
- shouldUseSelectorsAPI: function() {
3215
- if (!Prototype.BrowserFeatures.SelectorsAPI) return false;
3216
-
3217
- if (Selector.CASE_INSENSITIVE_CLASS_NAMES) return false;
3218
-
3219
- if (!Selector._div) Selector._div = new Element('div');
3220
-
3221
- try {
3222
- Selector._div.querySelector(this.expression);
3223
- } catch(e) {
3224
- return false;
3291
+ if (value === null) {
3292
+ return null;
3225
3293
  }
3226
3294
 
3227
- return true;
3228
- },
3295
+ if ((/^(?:-)?\d+(\.\d+)?(px)?$/i).test(value)) {
3296
+ return window.parseFloat(value);
3297
+ }
3229
3298
 
3230
- compileMatcher: function() {
3231
- var e = this.expression, ps = Selector.patterns, h = Selector.handlers,
3232
- c = Selector.criteria, le, p, m, len = ps.length, name;
3299
+ if (/\d/.test(value) && element.runtimeStyle) {
3300
+ var style = element.style.left, rStyle = element.runtimeStyle.left;
3301
+ element.runtimeStyle.left = element.currentStyle.left;
3302
+ element.style.left = value || 0;
3303
+ value = element.style.pixelLeft;
3304
+ element.style.left = style;
3305
+ element.runtimeStyle.left = rStyle;
3233
3306
 
3234
- if (Selector._cache[e]) {
3235
- this.matcher = Selector._cache[e];
3236
- return;
3307
+ return value;
3237
3308
  }
3238
3309
 
3239
- this.matcher = ["this.matcher = function(root) {",
3240
- "var r = root, h = Selector.handlers, c = false, n;"];
3241
-
3242
- while (e && le != e && (/\S/).test(e)) {
3243
- le = e;
3244
- for (var i = 0; i<len; i++) {
3245
- p = ps[i].re;
3246
- name = ps[i].name;
3247
- if (m = e.match(p)) {
3248
- this.matcher.push(Object.isFunction(c[name]) ? c[name](m) :
3249
- new Template(c[name]).evaluate(m));
3250
- e = e.replace(m[0], '');
3251
- break;
3252
- }
3310
+ if (value.include('%')) {
3311
+ var decimal = toDecimal(value);
3312
+ var whole;
3313
+ if (property.include('left') || property.include('right') ||
3314
+ property.include('width')) {
3315
+ whole = $(element.parentNode).measure('width');
3316
+ } else if (property.include('top') || property.include('bottom') ||
3317
+ property.include('height')) {
3318
+ whole = $(element.parentNode).measure('height');
3253
3319
  }
3254
- }
3255
3320
 
3256
- this.matcher.push("return h.unique(n);\n}");
3257
- eval(this.matcher.join('\n'));
3258
- Selector._cache[this.expression] = this.matcher;
3259
- },
3321
+ return whole * decimal;
3322
+ }
3260
3323
 
3261
- compileXPathMatcher: function() {
3262
- var e = this.expression, ps = Selector.patterns,
3263
- x = Selector.xpath, le, m, len = ps.length, name;
3324
+ return 0;
3325
+ }
3264
3326
 
3265
- if (Selector._cache[e]) {
3266
- this.xpath = Selector._cache[e]; return;
3327
+ function toCSSPixels(number) {
3328
+ if (Object.isString(number) && number.endsWith('px')) {
3329
+ return number;
3267
3330
  }
3331
+ return number + 'px';
3332
+ }
3268
3333
 
3269
- this.matcher = ['.//*'];
3270
- while (e && le != e && (/\S/).test(e)) {
3271
- le = e;
3272
- for (var i = 0; i<len; i++) {
3273
- name = ps[i].name;
3274
- if (m = e.match(ps[i].re)) {
3275
- this.matcher.push(Object.isFunction(x[name]) ? x[name](m) :
3276
- new Template(x[name]).evaluate(m));
3277
- e = e.replace(m[0], '');
3278
- break;
3279
- }
3334
+ function isDisplayed(element) {
3335
+ var originalElement = element;
3336
+ while (element && element.parentNode) {
3337
+ var display = element.getStyle('display');
3338
+ if (display === 'none') {
3339
+ return false;
3280
3340
  }
3341
+ element = $(element.parentNode);
3281
3342
  }
3343
+ return true;
3344
+ }
3282
3345
 
3283
- this.xpath = this.matcher.join('');
3284
- Selector._cache[this.expression] = this.xpath;
3285
- },
3346
+ var hasLayout = Prototype.K;
3347
+ if ('currentStyle' in document.documentElement) {
3348
+ hasLayout = function(element) {
3349
+ if (!element.currentStyle.hasLayout) {
3350
+ element.style.zoom = 1;
3351
+ }
3352
+ return element;
3353
+ };
3354
+ }
3286
3355
 
3287
- findElements: function(root) {
3288
- root = root || document;
3289
- var e = this.expression, results;
3356
+ function cssNameFor(key) {
3357
+ if (key.include('border')) key = key + '-width';
3358
+ return key.camelize();
3359
+ }
3290
3360
 
3291
- switch (this.mode) {
3292
- case 'selectorsAPI':
3293
- if (root !== document) {
3294
- var oldId = root.id, id = $(root).identify();
3295
- id = id.replace(/([\.:])/g, "\\$1");
3296
- e = "#" + id + " " + e;
3297
- }
3361
+ Element.Layout = Class.create(Hash, {
3362
+ initialize: function($super, element, preCompute) {
3363
+ $super();
3364
+ this.element = $(element);
3298
3365
 
3299
- results = $A(root.querySelectorAll(e)).map(Element.extend);
3300
- root.id = oldId;
3366
+ Element.Layout.PROPERTIES.each( function(property) {
3367
+ this._set(property, null);
3368
+ }, this);
3301
3369
 
3302
- return results;
3303
- case 'xpath':
3304
- return document._getElementsByXPath(this.xpath, root);
3305
- default:
3306
- return this.matcher(root);
3307
- }
3308
- },
3370
+ if (preCompute) {
3371
+ this._preComputing = true;
3372
+ this._begin();
3373
+ Element.Layout.PROPERTIES.each( this._compute, this );
3374
+ this._end();
3375
+ this._preComputing = false;
3376
+ }
3377
+ },
3378
+
3379
+ _set: function(property, value) {
3380
+ return Hash.prototype.set.call(this, property, value);
3381
+ },
3309
3382
 
3310
- match: function(element) {
3311
- this.tokens = [];
3383
+ set: function(property, value) {
3384
+ throw "Properties of Element.Layout are read-only.";
3385
+ },
3312
3386
 
3313
- var e = this.expression, ps = Selector.patterns, as = Selector.assertions;
3314
- var le, p, m, len = ps.length, name;
3387
+ get: function($super, property) {
3388
+ var value = $super(property);
3389
+ return value === null ? this._compute(property) : value;
3390
+ },
3315
3391
 
3316
- while (e && le !== e && (/\S/).test(e)) {
3317
- le = e;
3318
- for (var i = 0; i<len; i++) {
3319
- p = ps[i].re;
3320
- name = ps[i].name;
3321
- if (m = e.match(p)) {
3322
- if (as[name]) {
3323
- this.tokens.push([name, Object.clone(m)]);
3324
- e = e.replace(m[0], '');
3325
- } else {
3326
- return this.findElements(document).include(element);
3327
- }
3328
- }
3329
- }
3330
- }
3392
+ _begin: function() {
3393
+ if (this._prepared) return;
3331
3394
 
3332
- var match = true, name, matches;
3333
- for (var i = 0, token; token = this.tokens[i]; i++) {
3334
- name = token[0], matches = token[1];
3335
- if (!Selector.assertions[name](element, matches)) {
3336
- match = false; break;
3395
+ var element = this.element;
3396
+ if (isDisplayed(element)) {
3397
+ this._prepared = true;
3398
+ return;
3337
3399
  }
3338
- }
3339
3400
 
3340
- return match;
3341
- },
3401
+ var originalStyles = {
3402
+ position: element.style.position || '',
3403
+ width: element.style.width || '',
3404
+ visibility: element.style.visibility || '',
3405
+ display: element.style.display || ''
3406
+ };
3342
3407
 
3343
- toString: function() {
3344
- return this.expression;
3345
- },
3408
+ element.store('prototype_original_styles', originalStyles);
3346
3409
 
3347
- inspect: function() {
3348
- return "#<Selector:" + this.expression.inspect() + ">";
3349
- }
3350
- });
3410
+ var position = element.getStyle('position'),
3411
+ width = element.getStyle('width');
3351
3412
 
3352
- if (Prototype.BrowserFeatures.SelectorsAPI &&
3353
- document.compatMode === 'BackCompat') {
3354
- Selector.CASE_INSENSITIVE_CLASS_NAMES = (function(){
3355
- var div = document.createElement('div'),
3356
- span = document.createElement('span');
3357
-
3358
- div.id = "prototype_test_id";
3359
- span.className = 'Test';
3360
- div.appendChild(span);
3361
- var isIgnored = (div.querySelector('#prototype_test_id .test') !== null);
3362
- div = span = null;
3363
- return isIgnored;
3364
- })();
3365
- }
3413
+ element.setStyle({
3414
+ position: 'absolute',
3415
+ visibility: 'hidden',
3416
+ display: 'block'
3417
+ });
3366
3418
 
3367
- Object.extend(Selector, {
3368
- _cache: { },
3369
-
3370
- xpath: {
3371
- descendant: "//*",
3372
- child: "/*",
3373
- adjacent: "/following-sibling::*[1]",
3374
- laterSibling: '/following-sibling::*',
3375
- tagName: function(m) {
3376
- if (m[1] == '*') return '';
3377
- return "[local-name()='" + m[1].toLowerCase() +
3378
- "' or local-name()='" + m[1].toUpperCase() + "']";
3379
- },
3380
- className: "[contains(concat(' ', @class, ' '), ' #{1} ')]",
3381
- id: "[@id='#{1}']",
3382
- attrPresence: function(m) {
3383
- m[1] = m[1].toLowerCase();
3384
- return new Template("[@#{1}]").evaluate(m);
3385
- },
3386
- attr: function(m) {
3387
- m[1] = m[1].toLowerCase();
3388
- m[3] = m[5] || m[6];
3389
- return new Template(Selector.xpath.operators[m[2]]).evaluate(m);
3390
- },
3391
- pseudo: function(m) {
3392
- var h = Selector.xpath.pseudos[m[1]];
3393
- if (!h) return '';
3394
- if (Object.isFunction(h)) return h(m);
3395
- return new Template(Selector.xpath.pseudos[m[1]]).evaluate(m);
3396
- },
3397
- operators: {
3398
- '=': "[@#{1}='#{3}']",
3399
- '!=': "[@#{1}!='#{3}']",
3400
- '^=': "[starts-with(@#{1}, '#{3}')]",
3401
- '$=': "[substring(@#{1}, (string-length(@#{1}) - string-length('#{3}') + 1))='#{3}']",
3402
- '*=': "[contains(@#{1}, '#{3}')]",
3403
- '~=': "[contains(concat(' ', @#{1}, ' '), ' #{3} ')]",
3404
- '|=': "[contains(concat('-', @#{1}, '-'), '-#{3}-')]"
3405
- },
3406
- pseudos: {
3407
- 'first-child': '[not(preceding-sibling::*)]',
3408
- 'last-child': '[not(following-sibling::*)]',
3409
- 'only-child': '[not(preceding-sibling::* or following-sibling::*)]',
3410
- 'empty': "[count(*) = 0 and (count(text()) = 0)]",
3411
- 'checked': "[@checked]",
3412
- 'disabled': "[(@disabled) and (@type!='hidden')]",
3413
- 'enabled': "[not(@disabled) and (@type!='hidden')]",
3414
- 'not': function(m) {
3415
- var e = m[6], p = Selector.patterns,
3416
- x = Selector.xpath, le, v, len = p.length, name;
3417
-
3418
- var exclusion = [];
3419
- while (e && le != e && (/\S/).test(e)) {
3420
- le = e;
3421
- for (var i = 0; i<len; i++) {
3422
- name = p[i].name
3423
- if (m = e.match(p[i].re)) {
3424
- v = Object.isFunction(x[name]) ? x[name](m) : new Template(x[name]).evaluate(m);
3425
- exclusion.push("(" + v.substring(1, v.length - 1) + ")");
3426
- e = e.replace(m[0], '');
3427
- break;
3428
- }
3429
- }
3430
- }
3431
- return "[not(" + exclusion.join(" and ") + ")]";
3432
- },
3433
- 'nth-child': function(m) {
3434
- return Selector.xpath.pseudos.nth("(count(./preceding-sibling::*) + 1) ", m);
3435
- },
3436
- 'nth-last-child': function(m) {
3437
- return Selector.xpath.pseudos.nth("(count(./following-sibling::*) + 1) ", m);
3438
- },
3439
- 'nth-of-type': function(m) {
3440
- return Selector.xpath.pseudos.nth("position() ", m);
3441
- },
3442
- 'nth-last-of-type': function(m) {
3443
- return Selector.xpath.pseudos.nth("(last() + 1 - position()) ", m);
3444
- },
3445
- 'first-of-type': function(m) {
3446
- m[6] = "1"; return Selector.xpath.pseudos['nth-of-type'](m);
3447
- },
3448
- 'last-of-type': function(m) {
3449
- m[6] = "1"; return Selector.xpath.pseudos['nth-last-of-type'](m);
3450
- },
3451
- 'only-of-type': function(m) {
3452
- var p = Selector.xpath.pseudos; return p['first-of-type'](m) + p['last-of-type'](m);
3453
- },
3454
- nth: function(fragment, m) {
3455
- var mm, formula = m[6], predicate;
3456
- if (formula == 'even') formula = '2n+0';
3457
- if (formula == 'odd') formula = '2n+1';
3458
- if (mm = formula.match(/^(\d+)$/)) // digit only
3459
- return '[' + fragment + "= " + mm[1] + ']';
3460
- if (mm = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3461
- if (mm[1] == "-") mm[1] = -1;
3462
- var a = mm[1] ? Number(mm[1]) : 1;
3463
- var b = mm[2] ? Number(mm[2]) : 0;
3464
- predicate = "[((#{fragment} - #{b}) mod #{a} = 0) and " +
3465
- "((#{fragment} - #{b}) div #{a} >= 0)]";
3466
- return new Template(predicate).evaluate({
3467
- fragment: fragment, a: a, b: b });
3468
- }
3419
+ var positionedWidth = element.getStyle('width');
3420
+
3421
+ var newWidth;
3422
+ if (width && (positionedWidth === width)) {
3423
+ newWidth = getPixelValue(width);
3424
+ } else if (width && (position === 'absolute' || position === 'fixed')) {
3425
+ newWidth = getPixelValue(width);
3426
+ } else {
3427
+ var parent = element.parentNode, pLayout = $(parent).getLayout();
3428
+
3429
+ newWidth = pLayout.get('width') -
3430
+ this.get('margin-left') -
3431
+ this.get('border-left') -
3432
+ this.get('padding-left') -
3433
+ this.get('padding-right') -
3434
+ this.get('border-right') -
3435
+ this.get('margin-right');
3469
3436
  }
3470
- }
3471
- },
3472
3437
 
3473
- criteria: {
3474
- tagName: 'n = h.tagName(n, r, "#{1}", c); c = false;',
3475
- className: 'n = h.className(n, r, "#{1}", c); c = false;',
3476
- id: 'n = h.id(n, r, "#{1}", c); c = false;',
3477
- attrPresence: 'n = h.attrPresence(n, r, "#{1}", c); c = false;',
3478
- attr: function(m) {
3479
- m[3] = (m[5] || m[6]);
3480
- return new Template('n = h.attr(n, r, "#{1}", "#{3}", "#{2}", c); c = false;').evaluate(m);
3481
- },
3482
- pseudo: function(m) {
3483
- if (m[6]) m[6] = m[6].replace(/"/g, '\\"');
3484
- return new Template('n = h.pseudo(n, "#{1}", "#{6}", r, c); c = false;').evaluate(m);
3438
+ element.setStyle({ width: newWidth + 'px' });
3439
+
3440
+ this._prepared = true;
3485
3441
  },
3486
- descendant: 'c = "descendant";',
3487
- child: 'c = "child";',
3488
- adjacent: 'c = "adjacent";',
3489
- laterSibling: 'c = "laterSibling";'
3490
- },
3491
-
3492
- patterns: [
3493
- { name: 'laterSibling', re: /^\s*~\s*/ },
3494
- { name: 'child', re: /^\s*>\s*/ },
3495
- { name: 'adjacent', re: /^\s*\+\s*/ },
3496
- { name: 'descendant', re: /^\s/ },
3497
-
3498
- { name: 'tagName', re: /^\s*(\*|[\w\-]+)(\b|$)?/ },
3499
- { name: 'id', re: /^#([\w\-\*]+)(\b|$)/ },
3500
- { name: 'className', re: /^\.([\w\-\*]+)(\b|$)/ },
3501
- { name: 'pseudo', re: /^:((first|last|nth|nth-last|only)(-child|-of-type)|empty|checked|(en|dis)abled|not)(\((.*?)\))?(\b|$|(?=\s|[:+~>]))/ },
3502
- { name: 'attrPresence', re: /^\[((?:[\w-]+:)?[\w-]+)\]/ },
3503
- { name: 'attr', re: /\[((?:[\w-]*:)?[\w-]+)\s*(?:([!^$*~|]?=)\s*((['"])([^\4]*?)\4|([^'"][^\]]*?)))?\]/ }
3504
- ],
3505
-
3506
- assertions: {
3507
- tagName: function(element, matches) {
3508
- return matches[1].toUpperCase() == element.tagName.toUpperCase();
3442
+
3443
+ _end: function() {
3444
+ var element = this.element;
3445
+ var originalStyles = element.retrieve('prototype_original_styles');
3446
+ element.store('prototype_original_styles', null);
3447
+ element.setStyle(originalStyles);
3448
+ this._prepared = false;
3509
3449
  },
3510
3450
 
3511
- className: function(element, matches) {
3512
- return Element.hasClassName(element, matches[1]);
3451
+ _compute: function(property) {
3452
+ var COMPUTATIONS = Element.Layout.COMPUTATIONS;
3453
+ if (!(property in COMPUTATIONS)) {
3454
+ throw "Property not found.";
3455
+ }
3456
+ return this._set(property, COMPUTATIONS[property].call(this, this.element));
3513
3457
  },
3514
3458
 
3515
- id: function(element, matches) {
3516
- return element.id === matches[1];
3459
+ toObject: function() {
3460
+ var args = $A(arguments);
3461
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3462
+ args.join(' ').split(' ');
3463
+ var obj = {};
3464
+ keys.each( function(key) {
3465
+ if (!Element.Layout.PROPERTIES.include(key)) return;
3466
+ var value = this.get(key);
3467
+ if (value != null) obj[key] = value;
3468
+ }, this);
3469
+ return obj;
3517
3470
  },
3518
3471
 
3519
- attrPresence: function(element, matches) {
3520
- return Element.hasAttribute(element, matches[1]);
3472
+ toHash: function() {
3473
+ var obj = this.toObject.apply(this, arguments);
3474
+ return new Hash(obj);
3521
3475
  },
3522
3476
 
3523
- attr: function(element, matches) {
3524
- var nodeValue = Element.readAttribute(element, matches[1]);
3525
- return nodeValue && Selector.operators[matches[2]](nodeValue, matches[5] || matches[6]);
3526
- }
3527
- },
3477
+ toCSS: function() {
3478
+ var args = $A(arguments);
3479
+ var keys = (args.length === 0) ? Element.Layout.PROPERTIES :
3480
+ args.join(' ').split(' ');
3481
+ var css = {};
3528
3482
 
3529
- handlers: {
3530
- concat: function(a, b) {
3531
- for (var i = 0, node; node = b[i]; i++)
3532
- a.push(node);
3533
- return a;
3534
- },
3483
+ keys.each( function(key) {
3484
+ if (!Element.Layout.PROPERTIES.include(key)) return;
3485
+ if (Element.Layout.COMPOSITE_PROPERTIES.include(key)) return;
3535
3486
 
3536
- mark: function(nodes) {
3537
- var _true = Prototype.emptyFunction;
3538
- for (var i = 0, node; node = nodes[i]; i++)
3539
- node._countedByPrototype = _true;
3540
- return nodes;
3487
+ var value = this.get(key);
3488
+ if (value != null) css[cssNameFor(key)] = value + 'px';
3489
+ }, this);
3490
+ return css;
3541
3491
  },
3542
3492
 
3543
- unmark: (function(){
3493
+ inspect: function() {
3494
+ return "#<Element.Layout>";
3495
+ }
3496
+ });
3544
3497
 
3545
- var PROPERTIES_ATTRIBUTES_MAP = (function(){
3546
- var el = document.createElement('div'),
3547
- isBuggy = false,
3548
- propName = '_countedByPrototype',
3549
- value = 'x'
3550
- el[propName] = value;
3551
- isBuggy = (el.getAttribute(propName) === value);
3552
- el = null;
3553
- return isBuggy;
3554
- })();
3555
-
3556
- return PROPERTIES_ATTRIBUTES_MAP ?
3557
- function(nodes) {
3558
- for (var i = 0, node; node = nodes[i]; i++)
3559
- node.removeAttribute('_countedByPrototype');
3560
- return nodes;
3561
- } :
3562
- function(nodes) {
3563
- for (var i = 0, node; node = nodes[i]; i++)
3564
- node._countedByPrototype = void 0;
3565
- return nodes;
3566
- }
3567
- })(),
3498
+ Object.extend(Element.Layout, {
3499
+ PROPERTIES: $w('height width top left right bottom border-left border-right border-top border-bottom padding-left padding-right padding-top padding-bottom margin-top margin-bottom margin-left margin-right padding-box-width padding-box-height border-box-width border-box-height margin-box-width margin-box-height'),
3568
3500
 
3569
- index: function(parentNode, reverse, ofType) {
3570
- parentNode._countedByPrototype = Prototype.emptyFunction;
3571
- if (reverse) {
3572
- for (var nodes = parentNode.childNodes, i = nodes.length - 1, j = 1; i >= 0; i--) {
3573
- var node = nodes[i];
3574
- if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3575
- }
3576
- } else {
3577
- for (var i = 0, j = 1, nodes = parentNode.childNodes; node = nodes[i]; i++)
3578
- if (node.nodeType == 1 && (!ofType || node._countedByPrototype)) node.nodeIndex = j++;
3579
- }
3580
- },
3501
+ COMPOSITE_PROPERTIES: $w('padding-box-width padding-box-height margin-box-width margin-box-height border-box-width border-box-height'),
3581
3502
 
3582
- unique: function(nodes) {
3583
- if (nodes.length == 0) return nodes;
3584
- var results = [], n;
3585
- for (var i = 0, l = nodes.length; i < l; i++)
3586
- if (typeof (n = nodes[i])._countedByPrototype == 'undefined') {
3587
- n._countedByPrototype = Prototype.emptyFunction;
3588
- results.push(Element.extend(n));
3589
- }
3590
- return Selector.handlers.unmark(results);
3591
- },
3503
+ COMPUTATIONS: {
3504
+ 'height': function(element) {
3505
+ if (!this._preComputing) this._begin();
3592
3506
 
3593
- descendant: function(nodes) {
3594
- var h = Selector.handlers;
3595
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3596
- h.concat(results, node.getElementsByTagName('*'));
3597
- return results;
3598
- },
3507
+ var bHeight = this.get('border-box-height');
3508
+ if (bHeight <= 0) return 0;
3599
3509
 
3600
- child: function(nodes) {
3601
- var h = Selector.handlers;
3602
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3603
- for (var j = 0, child; child = node.childNodes[j]; j++)
3604
- if (child.nodeType == 1 && child.tagName != '!') results.push(child);
3605
- }
3606
- return results;
3607
- },
3510
+ var bTop = this.get('border-top'),
3511
+ bBottom = this.get('border-bottom');
3608
3512
 
3609
- adjacent: function(nodes) {
3610
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3611
- var next = this.nextElementSibling(node);
3612
- if (next) results.push(next);
3613
- }
3614
- return results;
3615
- },
3513
+ var pTop = this.get('padding-top'),
3514
+ pBottom = this.get('padding-bottom');
3616
3515
 
3617
- laterSibling: function(nodes) {
3618
- var h = Selector.handlers;
3619
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3620
- h.concat(results, Element.nextSiblings(node));
3621
- return results;
3622
- },
3516
+ if (!this._preComputing) this._end();
3623
3517
 
3624
- nextElementSibling: function(node) {
3625
- while (node = node.nextSibling)
3626
- if (node.nodeType == 1) return node;
3627
- return null;
3628
- },
3518
+ return bHeight - bTop - bBottom - pTop - pBottom;
3519
+ },
3629
3520
 
3630
- previousElementSibling: function(node) {
3631
- while (node = node.previousSibling)
3632
- if (node.nodeType == 1) return node;
3633
- return null;
3634
- },
3521
+ 'width': function(element) {
3522
+ if (!this._preComputing) this._begin();
3635
3523
 
3636
- tagName: function(nodes, root, tagName, combinator) {
3637
- var uTagName = tagName.toUpperCase();
3638
- var results = [], h = Selector.handlers;
3639
- if (nodes) {
3640
- if (combinator) {
3641
- if (combinator == "descendant") {
3642
- for (var i = 0, node; node = nodes[i]; i++)
3643
- h.concat(results, node.getElementsByTagName(tagName));
3644
- return results;
3645
- } else nodes = this[combinator](nodes);
3646
- if (tagName == "*") return nodes;
3647
- }
3648
- for (var i = 0, node; node = nodes[i]; i++)
3649
- if (node.tagName.toUpperCase() === uTagName) results.push(node);
3650
- return results;
3651
- } else return root.getElementsByTagName(tagName);
3652
- },
3524
+ var bWidth = this.get('border-box-width');
3525
+ if (bWidth <= 0) return 0;
3653
3526
 
3654
- id: function(nodes, root, id, combinator) {
3655
- var targetNode = $(id), h = Selector.handlers;
3527
+ var bLeft = this.get('border-left'),
3528
+ bRight = this.get('border-right');
3656
3529
 
3657
- if (root == document) {
3658
- if (!targetNode) return [];
3659
- if (!nodes) return [targetNode];
3660
- } else {
3661
- if (!root.sourceIndex || root.sourceIndex < 1) {
3662
- var nodes = root.getElementsByTagName('*');
3663
- for (var j = 0, node; node = nodes[j]; j++) {
3664
- if (node.id === id) return [node];
3665
- }
3666
- }
3530
+ var pLeft = this.get('padding-left'),
3531
+ pRight = this.get('padding-right');
3532
+
3533
+ if (!this._preComputing) this._end();
3534
+
3535
+ return bWidth - bLeft - bRight - pLeft - pRight;
3536
+ },
3537
+
3538
+ 'padding-box-height': function(element) {
3539
+ var height = this.get('height'),
3540
+ pTop = this.get('padding-top'),
3541
+ pBottom = this.get('padding-bottom');
3542
+
3543
+ return height + pTop + pBottom;
3544
+ },
3545
+
3546
+ 'padding-box-width': function(element) {
3547
+ var width = this.get('width'),
3548
+ pLeft = this.get('padding-left'),
3549
+ pRight = this.get('padding-right');
3550
+
3551
+ return width + pLeft + pRight;
3552
+ },
3553
+
3554
+ 'border-box-height': function(element) {
3555
+ return element.offsetHeight;
3556
+ },
3557
+
3558
+ 'border-box-width': function(element) {
3559
+ return element.offsetWidth;
3560
+ },
3561
+
3562
+ 'margin-box-height': function(element) {
3563
+ var bHeight = this.get('border-box-height'),
3564
+ mTop = this.get('margin-top'),
3565
+ mBottom = this.get('margin-bottom');
3566
+
3567
+ if (bHeight <= 0) return 0;
3568
+
3569
+ return bHeight + mTop + mBottom;
3570
+ },
3571
+
3572
+ 'margin-box-width': function(element) {
3573
+ var bWidth = this.get('border-box-width'),
3574
+ mLeft = this.get('margin-left'),
3575
+ mRight = this.get('margin-right');
3576
+
3577
+ if (bWidth <= 0) return 0;
3578
+
3579
+ return bWidth + mLeft + mRight;
3580
+ },
3581
+
3582
+ 'top': function(element) {
3583
+ var offset = element.positionedOffset();
3584
+ return offset.top;
3585
+ },
3586
+
3587
+ 'bottom': function(element) {
3588
+ var offset = element.positionedOffset(),
3589
+ parent = element.getOffsetParent(),
3590
+ pHeight = parent.measure('height');
3591
+
3592
+ var mHeight = this.get('border-box-height');
3593
+
3594
+ return pHeight - mHeight - offset.top;
3595
+ },
3596
+
3597
+ 'left': function(element) {
3598
+ var offset = element.positionedOffset();
3599
+ return offset.left;
3600
+ },
3601
+
3602
+ 'right': function(element) {
3603
+ var offset = element.positionedOffset(),
3604
+ parent = element.getOffsetParent(),
3605
+ pWidth = parent.measure('width');
3606
+
3607
+ var mWidth = this.get('border-box-width');
3608
+
3609
+ return pWidth - mWidth - offset.left;
3610
+ },
3611
+
3612
+ 'padding-top': function(element) {
3613
+ return getPixelValue(element, 'paddingTop');
3614
+ },
3615
+
3616
+ 'padding-bottom': function(element) {
3617
+ return getPixelValue(element, 'paddingBottom');
3618
+ },
3619
+
3620
+ 'padding-left': function(element) {
3621
+ return getPixelValue(element, 'paddingLeft');
3622
+ },
3623
+
3624
+ 'padding-right': function(element) {
3625
+ return getPixelValue(element, 'paddingRight');
3626
+ },
3627
+
3628
+ 'border-top': function(element) {
3629
+ return Object.isNumber(element.clientTop) ? element.clientTop :
3630
+ getPixelValue(element, 'borderTopWidth');
3631
+ },
3632
+
3633
+ 'border-bottom': function(element) {
3634
+ return Object.isNumber(element.clientBottom) ? element.clientBottom :
3635
+ getPixelValue(element, 'borderBottomWidth');
3636
+ },
3637
+
3638
+ 'border-left': function(element) {
3639
+ return Object.isNumber(element.clientLeft) ? element.clientLeft :
3640
+ getPixelValue(element, 'borderLeftWidth');
3641
+ },
3642
+
3643
+ 'border-right': function(element) {
3644
+ return Object.isNumber(element.clientRight) ? element.clientRight :
3645
+ getPixelValue(element, 'borderRightWidth');
3646
+ },
3647
+
3648
+ 'margin-top': function(element) {
3649
+ return getPixelValue(element, 'marginTop');
3650
+ },
3651
+
3652
+ 'margin-bottom': function(element) {
3653
+ return getPixelValue(element, 'marginBottom');
3654
+ },
3655
+
3656
+ 'margin-left': function(element) {
3657
+ return getPixelValue(element, 'marginLeft');
3658
+ },
3659
+
3660
+ 'margin-right': function(element) {
3661
+ return getPixelValue(element, 'marginRight');
3667
3662
  }
3663
+ }
3664
+ });
3668
3665
 
3669
- if (nodes) {
3670
- if (combinator) {
3671
- if (combinator == 'child') {
3672
- for (var i = 0, node; node = nodes[i]; i++)
3673
- if (targetNode.parentNode == node) return [targetNode];
3674
- } else if (combinator == 'descendant') {
3675
- for (var i = 0, node; node = nodes[i]; i++)
3676
- if (Element.descendantOf(targetNode, node)) return [targetNode];
3677
- } else if (combinator == 'adjacent') {
3678
- for (var i = 0, node; node = nodes[i]; i++)
3679
- if (Selector.handlers.previousElementSibling(targetNode) == node)
3680
- return [targetNode];
3681
- } else nodes = h[combinator](nodes);
3682
- }
3683
- for (var i = 0, node; node = nodes[i]; i++)
3684
- if (node == targetNode) return [targetNode];
3685
- return [];
3666
+ if ('getBoundingClientRect' in document.documentElement) {
3667
+ Object.extend(Element.Layout.COMPUTATIONS, {
3668
+ 'right': function(element) {
3669
+ var parent = hasLayout(element.getOffsetParent());
3670
+ var rect = element.getBoundingClientRect(),
3671
+ pRect = parent.getBoundingClientRect();
3672
+
3673
+ return (pRect.right - rect.right).round();
3674
+ },
3675
+
3676
+ 'bottom': function(element) {
3677
+ var parent = hasLayout(element.getOffsetParent());
3678
+ var rect = element.getBoundingClientRect(),
3679
+ pRect = parent.getBoundingClientRect();
3680
+
3681
+ return (pRect.bottom - rect.bottom).round();
3686
3682
  }
3687
- return (targetNode && Element.descendantOf(targetNode, root)) ? [targetNode] : [];
3688
- },
3683
+ });
3684
+ }
3689
3685
 
3690
- className: function(nodes, root, className, combinator) {
3691
- if (nodes && combinator) nodes = this[combinator](nodes);
3692
- return Selector.handlers.byClassName(nodes, root, className);
3686
+ Element.Offset = Class.create({
3687
+ initialize: function(left, top) {
3688
+ this.left = left.round();
3689
+ this.top = top.round();
3690
+
3691
+ this[0] = this.left;
3692
+ this[1] = this.top;
3693
3693
  },
3694
3694
 
3695
- byClassName: function(nodes, root, className) {
3696
- if (!nodes) nodes = Selector.handlers.descendant([root]);
3697
- var needle = ' ' + className + ' ';
3698
- for (var i = 0, results = [], node, nodeClassName; node = nodes[i]; i++) {
3699
- nodeClassName = node.className;
3700
- if (nodeClassName.length == 0) continue;
3701
- if (nodeClassName == className || (' ' + nodeClassName + ' ').include(needle))
3702
- results.push(node);
3703
- }
3704
- return results;
3695
+ relativeTo: function(offset) {
3696
+ return new Element.Offset(
3697
+ this.left - offset.left,
3698
+ this.top - offset.top
3699
+ );
3705
3700
  },
3706
3701
 
3707
- attrPresence: function(nodes, root, attr, combinator) {
3708
- if (!nodes) nodes = root.getElementsByTagName("*");
3709
- if (nodes && combinator) nodes = this[combinator](nodes);
3710
- var results = [];
3711
- for (var i = 0, node; node = nodes[i]; i++)
3712
- if (Element.hasAttribute(node, attr)) results.push(node);
3713
- return results;
3702
+ inspect: function() {
3703
+ return "#<Element.Offset left: #{left} top: #{top}>".interpolate(this);
3714
3704
  },
3715
3705
 
3716
- attr: function(nodes, root, attr, value, operator, combinator) {
3717
- if (!nodes) nodes = root.getElementsByTagName("*");
3718
- if (nodes && combinator) nodes = this[combinator](nodes);
3719
- var handler = Selector.operators[operator], results = [];
3720
- for (var i = 0, node; node = nodes[i]; i++) {
3721
- var nodeValue = Element.readAttribute(node, attr);
3722
- if (nodeValue === null) continue;
3723
- if (handler(nodeValue, value)) results.push(node);
3724
- }
3725
- return results;
3706
+ toString: function() {
3707
+ return "[#{left}, #{top}]".interpolate(this);
3726
3708
  },
3727
3709
 
3728
- pseudo: function(nodes, name, value, root, combinator) {
3729
- if (nodes && combinator) nodes = this[combinator](nodes);
3730
- if (!nodes) nodes = root.getElementsByTagName("*");
3731
- return Selector.pseudos[name](nodes, value, root);
3710
+ toArray: function() {
3711
+ return [this.left, this.top];
3732
3712
  }
3733
- },
3713
+ });
3734
3714
 
3735
- pseudos: {
3736
- 'first-child': function(nodes, value, root) {
3737
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3738
- if (Selector.handlers.previousElementSibling(node)) continue;
3739
- results.push(node);
3740
- }
3741
- return results;
3742
- },
3743
- 'last-child': function(nodes, value, root) {
3744
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3745
- if (Selector.handlers.nextElementSibling(node)) continue;
3746
- results.push(node);
3747
- }
3748
- return results;
3749
- },
3750
- 'only-child': function(nodes, value, root) {
3751
- var h = Selector.handlers;
3752
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3753
- if (!h.previousElementSibling(node) && !h.nextElementSibling(node))
3754
- results.push(node);
3755
- return results;
3756
- },
3757
- 'nth-child': function(nodes, formula, root) {
3758
- return Selector.pseudos.nth(nodes, formula, root);
3759
- },
3760
- 'nth-last-child': function(nodes, formula, root) {
3761
- return Selector.pseudos.nth(nodes, formula, root, true);
3762
- },
3763
- 'nth-of-type': function(nodes, formula, root) {
3764
- return Selector.pseudos.nth(nodes, formula, root, false, true);
3765
- },
3766
- 'nth-last-of-type': function(nodes, formula, root) {
3767
- return Selector.pseudos.nth(nodes, formula, root, true, true);
3768
- },
3769
- 'first-of-type': function(nodes, formula, root) {
3770
- return Selector.pseudos.nth(nodes, "1", root, false, true);
3771
- },
3772
- 'last-of-type': function(nodes, formula, root) {
3773
- return Selector.pseudos.nth(nodes, "1", root, true, true);
3774
- },
3775
- 'only-of-type': function(nodes, formula, root) {
3776
- var p = Selector.pseudos;
3777
- return p['last-of-type'](p['first-of-type'](nodes, formula, root), formula, root);
3778
- },
3715
+ function getLayout(element, preCompute) {
3716
+ return new Element.Layout(element, preCompute);
3717
+ }
3779
3718
 
3780
- getIndices: function(a, b, total) {
3781
- if (a == 0) return b > 0 ? [b] : [];
3782
- return $R(1, total).inject([], function(memo, i) {
3783
- if (0 == (i - b) % a && (i - b) / a >= 0) memo.push(i);
3784
- return memo;
3785
- });
3786
- },
3719
+ function measure(element, property) {
3720
+ return $(element).getLayout().get(property);
3721
+ }
3787
3722
 
3788
- nth: function(nodes, formula, root, reverse, ofType) {
3789
- if (nodes.length == 0) return [];
3790
- if (formula == 'even') formula = '2n+0';
3791
- if (formula == 'odd') formula = '2n+1';
3792
- var h = Selector.handlers, results = [], indexed = [], m;
3793
- h.mark(nodes);
3794
- for (var i = 0, node; node = nodes[i]; i++) {
3795
- if (!node.parentNode._countedByPrototype) {
3796
- h.index(node.parentNode, reverse, ofType);
3797
- indexed.push(node.parentNode);
3798
- }
3723
+ function getDimensions(element) {
3724
+ var layout = $(element).getLayout();
3725
+ return {
3726
+ width: layout.get('width'),
3727
+ height: layout.get('height')
3728
+ };
3729
+ }
3730
+
3731
+ function getOffsetParent(element) {
3732
+ if (isDetached(element)) return $(document.body);
3733
+
3734
+ var isInline = (Element.getStyle(element, 'display') === 'inline');
3735
+ if (!isInline && element.offsetParent) return $(element.offsetParent);
3736
+ if (element === document.body) return $(element);
3737
+
3738
+ while ((element = element.parentNode) && element !== document.body) {
3739
+ if (Element.getStyle(element, 'position') !== 'static') {
3740
+ return (element.nodeName === 'HTML') ? $(document.body) : $(element);
3799
3741
  }
3800
- if (formula.match(/^\d+$/)) { // just a number
3801
- formula = Number(formula);
3802
- for (var i = 0, node; node = nodes[i]; i++)
3803
- if (node.nodeIndex == formula) results.push(node);
3804
- } else if (m = formula.match(/^(-?\d*)?n(([+-])(\d+))?/)) { // an+b
3805
- if (m[1] == "-") m[1] = -1;
3806
- var a = m[1] ? Number(m[1]) : 1;
3807
- var b = m[2] ? Number(m[2]) : 0;
3808
- var indices = Selector.pseudos.getIndices(a, b, nodes.length);
3809
- for (var i = 0, node, l = indices.length; node = nodes[i]; i++) {
3810
- for (var j = 0; j < l; j++)
3811
- if (node.nodeIndex == indices[j]) results.push(node);
3812
- }
3742
+ }
3743
+
3744
+ return $(document.body);
3745
+ }
3746
+
3747
+
3748
+ function cumulativeOffset(element) {
3749
+ var valueT = 0, valueL = 0;
3750
+ do {
3751
+ valueT += element.offsetTop || 0;
3752
+ valueL += element.offsetLeft || 0;
3753
+ element = element.offsetParent;
3754
+ } while (element);
3755
+ return new Element.Offset(valueL, valueT);
3756
+ }
3757
+
3758
+ function positionedOffset(element) {
3759
+ var layout = element.getLayout();
3760
+
3761
+ var valueT = 0, valueL = 0;
3762
+ do {
3763
+ valueT += element.offsetTop || 0;
3764
+ valueL += element.offsetLeft || 0;
3765
+ element = element.offsetParent;
3766
+ if (element) {
3767
+ if (isBody(element)) break;
3768
+ var p = Element.getStyle(element, 'position');
3769
+ if (p !== 'static') break;
3813
3770
  }
3814
- h.unmark(nodes);
3815
- h.unmark(indexed);
3816
- return results;
3817
- },
3771
+ } while (element);
3772
+
3773
+ valueL -= layout.get('margin-top');
3774
+ valueT -= layout.get('margin-left');
3775
+
3776
+ return new Element.Offset(valueL, valueT);
3777
+ }
3778
+
3779
+ function cumulativeScrollOffset(element) {
3780
+ var valueT = 0, valueL = 0;
3781
+ do {
3782
+ valueT += element.scrollTop || 0;
3783
+ valueL += element.scrollLeft || 0;
3784
+ element = element.parentNode;
3785
+ } while (element);
3786
+ return new Element.Offset(valueL, valueT);
3787
+ }
3818
3788
 
3819
- 'empty': function(nodes, value, root) {
3820
- for (var i = 0, results = [], node; node = nodes[i]; i++) {
3821
- if (node.tagName == '!' || node.firstChild) continue;
3822
- results.push(node);
3789
+ function viewportOffset(forElement) {
3790
+ var valueT = 0, valueL = 0, docBody = document.body;
3791
+
3792
+ var element = forElement;
3793
+ do {
3794
+ valueT += element.offsetTop || 0;
3795
+ valueL += element.offsetLeft || 0;
3796
+ if (element.offsetParent == docBody &&
3797
+ Element.getStyle(element, 'position') == 'absolute') break;
3798
+ } while (element = element.offsetParent);
3799
+
3800
+ element = forElement;
3801
+ do {
3802
+ if (element != docBody) {
3803
+ valueT -= element.scrollTop || 0;
3804
+ valueL -= element.scrollLeft || 0;
3823
3805
  }
3824
- return results;
3825
- },
3806
+ } while (element = element.parentNode);
3807
+ return new Element.Offset(valueL, valueT);
3808
+ }
3826
3809
 
3827
- 'not': function(nodes, selector, root) {
3828
- var h = Selector.handlers, selectorType, m;
3829
- var exclusions = new Selector(selector).findElements(root);
3830
- h.mark(exclusions);
3831
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3832
- if (!node._countedByPrototype) results.push(node);
3833
- h.unmark(exclusions);
3834
- return results;
3835
- },
3810
+ function absolutize(element) {
3811
+ element = $(element);
3836
3812
 
3837
- 'enabled': function(nodes, value, root) {
3838
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3839
- if (!node.disabled && (!node.type || node.type !== 'hidden'))
3840
- results.push(node);
3841
- return results;
3842
- },
3813
+ if (Element.getStyle(element, 'position') === 'absolute') {
3814
+ return element;
3815
+ }
3843
3816
 
3844
- 'disabled': function(nodes, value, root) {
3845
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3846
- if (node.disabled) results.push(node);
3847
- return results;
3848
- },
3817
+ var offsetParent = getOffsetParent(element);
3818
+ var eOffset = element.viewportOffset(),
3819
+ pOffset = offsetParent.viewportOffset();
3849
3820
 
3850
- 'checked': function(nodes, value, root) {
3851
- for (var i = 0, results = [], node; node = nodes[i]; i++)
3852
- if (node.checked) results.push(node);
3853
- return results;
3821
+ var offset = eOffset.relativeTo(pOffset);
3822
+ var layout = element.getLayout();
3823
+
3824
+ element.store('prototype_absolutize_original_styles', {
3825
+ left: element.getStyle('left'),
3826
+ top: element.getStyle('top'),
3827
+ width: element.getStyle('width'),
3828
+ height: element.getStyle('height')
3829
+ });
3830
+
3831
+ element.setStyle({
3832
+ position: 'absolute',
3833
+ top: offset.top + 'px',
3834
+ left: offset.left + 'px',
3835
+ width: layout.get('width') + 'px',
3836
+ height: layout.get('height') + 'px'
3837
+ });
3838
+
3839
+ return element;
3840
+ }
3841
+
3842
+ function relativize(element) {
3843
+ element = $(element);
3844
+ if (Element.getStyle(element, 'position') === 'relative') {
3845
+ return element;
3854
3846
  }
3855
- },
3856
3847
 
3857
- operators: {
3858
- '=': function(nv, v) { return nv == v; },
3859
- '!=': function(nv, v) { return nv != v; },
3860
- '^=': function(nv, v) { return nv == v || nv && nv.startsWith(v); },
3861
- '$=': function(nv, v) { return nv == v || nv && nv.endsWith(v); },
3862
- '*=': function(nv, v) { return nv == v || nv && nv.include(v); },
3863
- '~=': function(nv, v) { return (' ' + nv + ' ').include(' ' + v + ' '); },
3864
- '|=': function(nv, v) { return ('-' + (nv || "").toUpperCase() +
3865
- '-').include('-' + (v || "").toUpperCase() + '-'); }
3866
- },
3848
+ var originalStyles =
3849
+ element.retrieve('prototype_absolutize_original_styles');
3850
+
3851
+ if (originalStyles) element.setStyle(originalStyles);
3852
+ return element;
3853
+ }
3854
+
3855
+ Element.addMethods({
3856
+ getLayout: getLayout,
3857
+ measure: measure,
3858
+ getDimensions: getDimensions,
3859
+ getOffsetParent: getOffsetParent,
3860
+ cumulativeOffset: cumulativeOffset,
3861
+ positionedOffset: positionedOffset,
3862
+ cumulativeScrollOffset: cumulativeScrollOffset,
3863
+ viewportOffset: viewportOffset,
3864
+ absolutize: absolutize,
3865
+ relativize: relativize
3866
+ });
3867
+
3868
+ function isBody(element) {
3869
+ return element.nodeName.toUpperCase() === 'BODY';
3870
+ }
3871
+
3872
+ function isDetached(element) {
3873
+ return element !== document.body &&
3874
+ !Element.descendantOf(element, document.body);
3875
+ }
3876
+
3877
+ if ('getBoundingClientRect' in document.documentElement) {
3878
+ Element.addMethods({
3879
+ viewportOffset: function(element) {
3880
+ element = $(element);
3881
+ if (isDetached(element)) return new Element.Offset(0, 0);
3867
3882
 
3868
- split: function(expression) {
3869
- var expressions = [];
3870
- expression.scan(/(([\w#:.~>+()\s-]+|\*|\[.*?\])+)\s*(,|$)/, function(m) {
3871
- expressions.push(m[1].strip());
3883
+ var rect = element.getBoundingClientRect(),
3884
+ docEl = document.documentElement;
3885
+ return new Element.Offset(rect.left - docEl.clientLeft,
3886
+ rect.top - docEl.clientTop);
3887
+ },
3888
+
3889
+ positionedOffset: function(element) {
3890
+ element = $(element);
3891
+ var parent = element.getOffsetParent();
3892
+ if (isDetached(element)) return new Element.Offset(0, 0);
3893
+
3894
+ if (element.offsetParent &&
3895
+ element.offsetParent.nodeName.toUpperCase() === 'HTML') {
3896
+ return positionedOffset(element);
3897
+ }
3898
+
3899
+ var eOffset = element.viewportOffset(),
3900
+ pOffset = isBody(parent) ? viewportOffset(parent) :
3901
+ parent.viewportOffset();
3902
+ var retOffset = eOffset.relativeTo(pOffset);
3903
+
3904
+ var layout = element.getLayout();
3905
+ var top = retOffset.top - layout.get('margin-top');
3906
+ var left = retOffset.left - layout.get('margin-left');
3907
+
3908
+ return new Element.Offset(left, top);
3909
+ }
3872
3910
  });
3873
- return expressions;
3874
- },
3911
+ }
3912
+ })();
3913
+ window.$$ = function() {
3914
+ var expression = $A(arguments).join(', ');
3915
+ return Prototype.Selector.select(expression, document);
3916
+ };
3875
3917
 
3876
- matchElements: function(elements, expression) {
3877
- var matches = $$(expression), h = Selector.handlers;
3878
- h.mark(matches);
3879
- for (var i = 0, results = [], element; element = elements[i]; i++)
3880
- if (element._countedByPrototype) results.push(element);
3881
- h.unmark(matches);
3882
- return results;
3883
- },
3918
+ Prototype.Selector = (function() {
3884
3919
 
3885
- findElement: function(elements, expression, index) {
3886
- if (Object.isNumber(expression)) {
3887
- index = expression; expression = false;
3920
+ function select() {
3921
+ throw new Error('Method "Prototype.Selector.select" must be defined.');
3922
+ }
3923
+
3924
+ function match() {
3925
+ throw new Error('Method "Prototype.Selector.match" must be defined.');
3926
+ }
3927
+
3928
+ function find(elements, expression, index) {
3929
+ index = index || 0;
3930
+ var match = Prototype.Selector.match, length = elements.length, matchIndex = 0, i;
3931
+
3932
+ for (i = 0; i < length; i++) {
3933
+ if (match(elements[i], expression) && index == matchIndex++) {
3934
+ return Element.extend(elements[i]);
3935
+ }
3888
3936
  }
3889
- return Selector.matchElements(elements, expression || '*')[index || 0];
3890
- },
3937
+ }
3891
3938
 
3892
- findChildElements: function(element, expressions) {
3893
- expressions = Selector.split(expressions.join(','));
3894
- var results = [], h = Selector.handlers;
3895
- for (var i = 0, l = expressions.length, selector; i < l; i++) {
3896
- selector = new Selector(expressions[i].strip());
3897
- h.concat(results, selector.findElements(element));
3939
+ function extendElements(elements) {
3940
+ for (var i = 0, length = elements.length; i < length; i++) {
3941
+ Element.extend(elements[i]);
3898
3942
  }
3899
- return (l > 1) ? h.unique(results) : results;
3943
+ return elements;
3900
3944
  }
3945
+
3946
+
3947
+ var K = Prototype.K;
3948
+
3949
+ return {
3950
+ select: select,
3951
+ match: match,
3952
+ find: find,
3953
+ extendElements: (Element.extend === K) ? K : extendElements,
3954
+ extendElement: Element.extend
3955
+ };
3956
+ })();
3957
+ Prototype._original_property = window.Sizzle;
3958
+ /*!
3959
+ * Sizzle CSS Selector Engine - v1.0
3960
+ * Copyright 2009, The Dojo Foundation
3961
+ * Released under the MIT, BSD, and GPL Licenses.
3962
+ * More information: http://sizzlejs.com/
3963
+ */
3964
+ (function(){
3965
+
3966
+ var chunker = /((?:\((?:\([^()]+\)|[^()]+)+\)|\[(?:\[[^[\]]*\]|['"][^'"]*['"]|[^[\]'"]+)+\]|\\.|[^ >+~,(\[\\]+)+|[>+~])(\s*,\s*)?((?:.|\r|\n)*)/g,
3967
+ done = 0,
3968
+ toString = Object.prototype.toString,
3969
+ hasDuplicate = false,
3970
+ baseHasDuplicate = true;
3971
+
3972
+ [0, 0].sort(function(){
3973
+ baseHasDuplicate = false;
3974
+ return 0;
3901
3975
  });
3902
3976
 
3903
- if (Prototype.Browser.IE) {
3904
- Object.extend(Selector.handlers, {
3905
- concat: function(a, b) {
3906
- for (var i = 0, node; node = b[i]; i++)
3907
- if (node.tagName !== "!") a.push(node);
3908
- return a;
3909
- }
3910
- });
3977
+ var Sizzle = function(selector, context, results, seed) {
3978
+ results = results || [];
3979
+ var origContext = context = context || document;
3980
+
3981
+ if ( context.nodeType !== 1 && context.nodeType !== 9 ) {
3982
+ return [];
3983
+ }
3984
+
3985
+ if ( !selector || typeof selector !== "string" ) {
3986
+ return results;
3987
+ }
3988
+
3989
+ var parts = [], m, set, checkSet, check, mode, extra, prune = true, contextXML = isXML(context),
3990
+ soFar = selector;
3991
+
3992
+ while ( (chunker.exec(""), m = chunker.exec(soFar)) !== null ) {
3993
+ soFar = m[3];
3994
+
3995
+ parts.push( m[1] );
3996
+
3997
+ if ( m[2] ) {
3998
+ extra = m[3];
3999
+ break;
4000
+ }
4001
+ }
4002
+
4003
+ if ( parts.length > 1 && origPOS.exec( selector ) ) {
4004
+ if ( parts.length === 2 && Expr.relative[ parts[0] ] ) {
4005
+ set = posProcess( parts[0] + parts[1], context );
4006
+ } else {
4007
+ set = Expr.relative[ parts[0] ] ?
4008
+ [ context ] :
4009
+ Sizzle( parts.shift(), context );
4010
+
4011
+ while ( parts.length ) {
4012
+ selector = parts.shift();
4013
+
4014
+ if ( Expr.relative[ selector ] )
4015
+ selector += parts.shift();
4016
+
4017
+ set = posProcess( selector, set );
4018
+ }
4019
+ }
4020
+ } else {
4021
+ if ( !seed && parts.length > 1 && context.nodeType === 9 && !contextXML &&
4022
+ Expr.match.ID.test(parts[0]) && !Expr.match.ID.test(parts[parts.length - 1]) ) {
4023
+ var ret = Sizzle.find( parts.shift(), context, contextXML );
4024
+ context = ret.expr ? Sizzle.filter( ret.expr, ret.set )[0] : ret.set[0];
4025
+ }
4026
+
4027
+ if ( context ) {
4028
+ var ret = seed ?
4029
+ { expr: parts.pop(), set: makeArray(seed) } :
4030
+ Sizzle.find( parts.pop(), parts.length === 1 && (parts[0] === "~" || parts[0] === "+") && context.parentNode ? context.parentNode : context, contextXML );
4031
+ set = ret.expr ? Sizzle.filter( ret.expr, ret.set ) : ret.set;
4032
+
4033
+ if ( parts.length > 0 ) {
4034
+ checkSet = makeArray(set);
4035
+ } else {
4036
+ prune = false;
4037
+ }
4038
+
4039
+ while ( parts.length ) {
4040
+ var cur = parts.pop(), pop = cur;
4041
+
4042
+ if ( !Expr.relative[ cur ] ) {
4043
+ cur = "";
4044
+ } else {
4045
+ pop = parts.pop();
4046
+ }
4047
+
4048
+ if ( pop == null ) {
4049
+ pop = context;
4050
+ }
4051
+
4052
+ Expr.relative[ cur ]( checkSet, pop, contextXML );
4053
+ }
4054
+ } else {
4055
+ checkSet = parts = [];
4056
+ }
4057
+ }
4058
+
4059
+ if ( !checkSet ) {
4060
+ checkSet = set;
4061
+ }
4062
+
4063
+ if ( !checkSet ) {
4064
+ throw "Syntax error, unrecognized expression: " + (cur || selector);
4065
+ }
4066
+
4067
+ if ( toString.call(checkSet) === "[object Array]" ) {
4068
+ if ( !prune ) {
4069
+ results.push.apply( results, checkSet );
4070
+ } else if ( context && context.nodeType === 1 ) {
4071
+ for ( var i = 0; checkSet[i] != null; i++ ) {
4072
+ if ( checkSet[i] && (checkSet[i] === true || checkSet[i].nodeType === 1 && contains(context, checkSet[i])) ) {
4073
+ results.push( set[i] );
4074
+ }
4075
+ }
4076
+ } else {
4077
+ for ( var i = 0; checkSet[i] != null; i++ ) {
4078
+ if ( checkSet[i] && checkSet[i].nodeType === 1 ) {
4079
+ results.push( set[i] );
4080
+ }
4081
+ }
4082
+ }
4083
+ } else {
4084
+ makeArray( checkSet, results );
4085
+ }
4086
+
4087
+ if ( extra ) {
4088
+ Sizzle( extra, origContext, results, seed );
4089
+ Sizzle.uniqueSort( results );
4090
+ }
4091
+
4092
+ return results;
4093
+ };
4094
+
4095
+ Sizzle.uniqueSort = function(results){
4096
+ if ( sortOrder ) {
4097
+ hasDuplicate = baseHasDuplicate;
4098
+ results.sort(sortOrder);
4099
+
4100
+ if ( hasDuplicate ) {
4101
+ for ( var i = 1; i < results.length; i++ ) {
4102
+ if ( results[i] === results[i-1] ) {
4103
+ results.splice(i--, 1);
4104
+ }
4105
+ }
4106
+ }
4107
+ }
4108
+
4109
+ return results;
4110
+ };
4111
+
4112
+ Sizzle.matches = function(expr, set){
4113
+ return Sizzle(expr, null, null, set);
4114
+ };
4115
+
4116
+ Sizzle.find = function(expr, context, isXML){
4117
+ var set, match;
4118
+
4119
+ if ( !expr ) {
4120
+ return [];
4121
+ }
4122
+
4123
+ for ( var i = 0, l = Expr.order.length; i < l; i++ ) {
4124
+ var type = Expr.order[i], match;
4125
+
4126
+ if ( (match = Expr.leftMatch[ type ].exec( expr )) ) {
4127
+ var left = match[1];
4128
+ match.splice(1,1);
4129
+
4130
+ if ( left.substr( left.length - 1 ) !== "\\" ) {
4131
+ match[1] = (match[1] || "").replace(/\\/g, "");
4132
+ set = Expr.find[ type ]( match, context, isXML );
4133
+ if ( set != null ) {
4134
+ expr = expr.replace( Expr.match[ type ], "" );
4135
+ break;
4136
+ }
4137
+ }
4138
+ }
4139
+ }
4140
+
4141
+ if ( !set ) {
4142
+ set = context.getElementsByTagName("*");
4143
+ }
4144
+
4145
+ return {set: set, expr: expr};
4146
+ };
4147
+
4148
+ Sizzle.filter = function(expr, set, inplace, not){
4149
+ var old = expr, result = [], curLoop = set, match, anyFound,
4150
+ isXMLFilter = set && set[0] && isXML(set[0]);
4151
+
4152
+ while ( expr && set.length ) {
4153
+ for ( var type in Expr.filter ) {
4154
+ if ( (match = Expr.match[ type ].exec( expr )) != null ) {
4155
+ var filter = Expr.filter[ type ], found, item;
4156
+ anyFound = false;
4157
+
4158
+ if ( curLoop == result ) {
4159
+ result = [];
4160
+ }
4161
+
4162
+ if ( Expr.preFilter[ type ] ) {
4163
+ match = Expr.preFilter[ type ]( match, curLoop, inplace, result, not, isXMLFilter );
4164
+
4165
+ if ( !match ) {
4166
+ anyFound = found = true;
4167
+ } else if ( match === true ) {
4168
+ continue;
4169
+ }
4170
+ }
4171
+
4172
+ if ( match ) {
4173
+ for ( var i = 0; (item = curLoop[i]) != null; i++ ) {
4174
+ if ( item ) {
4175
+ found = filter( item, match, i, curLoop );
4176
+ var pass = not ^ !!found;
4177
+
4178
+ if ( inplace && found != null ) {
4179
+ if ( pass ) {
4180
+ anyFound = true;
4181
+ } else {
4182
+ curLoop[i] = false;
4183
+ }
4184
+ } else if ( pass ) {
4185
+ result.push( item );
4186
+ anyFound = true;
4187
+ }
4188
+ }
4189
+ }
4190
+ }
4191
+
4192
+ if ( found !== undefined ) {
4193
+ if ( !inplace ) {
4194
+ curLoop = result;
4195
+ }
4196
+
4197
+ expr = expr.replace( Expr.match[ type ], "" );
4198
+
4199
+ if ( !anyFound ) {
4200
+ return [];
4201
+ }
4202
+
4203
+ break;
4204
+ }
4205
+ }
4206
+ }
4207
+
4208
+ if ( expr == old ) {
4209
+ if ( anyFound == null ) {
4210
+ throw "Syntax error, unrecognized expression: " + expr;
4211
+ } else {
4212
+ break;
4213
+ }
4214
+ }
4215
+
4216
+ old = expr;
4217
+ }
4218
+
4219
+ return curLoop;
4220
+ };
4221
+
4222
+ var Expr = Sizzle.selectors = {
4223
+ order: [ "ID", "NAME", "TAG" ],
4224
+ match: {
4225
+ ID: /#((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4226
+ CLASS: /\.((?:[\w\u00c0-\uFFFF-]|\\.)+)/,
4227
+ NAME: /\[name=['"]*((?:[\w\u00c0-\uFFFF-]|\\.)+)['"]*\]/,
4228
+ ATTR: /\[\s*((?:[\w\u00c0-\uFFFF-]|\\.)+)\s*(?:(\S?=)\s*(['"]*)(.*?)\3|)\s*\]/,
4229
+ TAG: /^((?:[\w\u00c0-\uFFFF\*-]|\\.)+)/,
4230
+ CHILD: /:(only|nth|last|first)-child(?:\((even|odd|[\dn+-]*)\))?/,
4231
+ POS: /:(nth|eq|gt|lt|first|last|even|odd)(?:\((\d*)\))?(?=[^-]|$)/,
4232
+ PSEUDO: /:((?:[\w\u00c0-\uFFFF-]|\\.)+)(?:\((['"]*)((?:\([^\)]+\)|[^\2\(\)]*)+)\2\))?/
4233
+ },
4234
+ leftMatch: {},
4235
+ attrMap: {
4236
+ "class": "className",
4237
+ "for": "htmlFor"
4238
+ },
4239
+ attrHandle: {
4240
+ href: function(elem){
4241
+ return elem.getAttribute("href");
4242
+ }
4243
+ },
4244
+ relative: {
4245
+ "+": function(checkSet, part, isXML){
4246
+ var isPartStr = typeof part === "string",
4247
+ isTag = isPartStr && !/\W/.test(part),
4248
+ isPartStrNotTag = isPartStr && !isTag;
4249
+
4250
+ if ( isTag && !isXML ) {
4251
+ part = part.toUpperCase();
4252
+ }
4253
+
4254
+ for ( var i = 0, l = checkSet.length, elem; i < l; i++ ) {
4255
+ if ( (elem = checkSet[i]) ) {
4256
+ while ( (elem = elem.previousSibling) && elem.nodeType !== 1 ) {}
4257
+
4258
+ checkSet[i] = isPartStrNotTag || elem && elem.nodeName === part ?
4259
+ elem || false :
4260
+ elem === part;
4261
+ }
4262
+ }
4263
+
4264
+ if ( isPartStrNotTag ) {
4265
+ Sizzle.filter( part, checkSet, true );
4266
+ }
4267
+ },
4268
+ ">": function(checkSet, part, isXML){
4269
+ var isPartStr = typeof part === "string";
4270
+
4271
+ if ( isPartStr && !/\W/.test(part) ) {
4272
+ part = isXML ? part : part.toUpperCase();
4273
+
4274
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4275
+ var elem = checkSet[i];
4276
+ if ( elem ) {
4277
+ var parent = elem.parentNode;
4278
+ checkSet[i] = parent.nodeName === part ? parent : false;
4279
+ }
4280
+ }
4281
+ } else {
4282
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4283
+ var elem = checkSet[i];
4284
+ if ( elem ) {
4285
+ checkSet[i] = isPartStr ?
4286
+ elem.parentNode :
4287
+ elem.parentNode === part;
4288
+ }
4289
+ }
4290
+
4291
+ if ( isPartStr ) {
4292
+ Sizzle.filter( part, checkSet, true );
4293
+ }
4294
+ }
4295
+ },
4296
+ "": function(checkSet, part, isXML){
4297
+ var doneName = done++, checkFn = dirCheck;
4298
+
4299
+ if ( !/\W/.test(part) ) {
4300
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
4301
+ checkFn = dirNodeCheck;
4302
+ }
4303
+
4304
+ checkFn("parentNode", part, doneName, checkSet, nodeCheck, isXML);
4305
+ },
4306
+ "~": function(checkSet, part, isXML){
4307
+ var doneName = done++, checkFn = dirCheck;
4308
+
4309
+ if ( typeof part === "string" && !/\W/.test(part) ) {
4310
+ var nodeCheck = part = isXML ? part : part.toUpperCase();
4311
+ checkFn = dirNodeCheck;
4312
+ }
4313
+
4314
+ checkFn("previousSibling", part, doneName, checkSet, nodeCheck, isXML);
4315
+ }
4316
+ },
4317
+ find: {
4318
+ ID: function(match, context, isXML){
4319
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
4320
+ var m = context.getElementById(match[1]);
4321
+ return m ? [m] : [];
4322
+ }
4323
+ },
4324
+ NAME: function(match, context, isXML){
4325
+ if ( typeof context.getElementsByName !== "undefined" ) {
4326
+ var ret = [], results = context.getElementsByName(match[1]);
4327
+
4328
+ for ( var i = 0, l = results.length; i < l; i++ ) {
4329
+ if ( results[i].getAttribute("name") === match[1] ) {
4330
+ ret.push( results[i] );
4331
+ }
4332
+ }
4333
+
4334
+ return ret.length === 0 ? null : ret;
4335
+ }
4336
+ },
4337
+ TAG: function(match, context){
4338
+ return context.getElementsByTagName(match[1]);
4339
+ }
4340
+ },
4341
+ preFilter: {
4342
+ CLASS: function(match, curLoop, inplace, result, not, isXML){
4343
+ match = " " + match[1].replace(/\\/g, "") + " ";
4344
+
4345
+ if ( isXML ) {
4346
+ return match;
4347
+ }
4348
+
4349
+ for ( var i = 0, elem; (elem = curLoop[i]) != null; i++ ) {
4350
+ if ( elem ) {
4351
+ if ( not ^ (elem.className && (" " + elem.className + " ").indexOf(match) >= 0) ) {
4352
+ if ( !inplace )
4353
+ result.push( elem );
4354
+ } else if ( inplace ) {
4355
+ curLoop[i] = false;
4356
+ }
4357
+ }
4358
+ }
4359
+
4360
+ return false;
4361
+ },
4362
+ ID: function(match){
4363
+ return match[1].replace(/\\/g, "");
4364
+ },
4365
+ TAG: function(match, curLoop){
4366
+ for ( var i = 0; curLoop[i] === false; i++ ){}
4367
+ return curLoop[i] && isXML(curLoop[i]) ? match[1] : match[1].toUpperCase();
4368
+ },
4369
+ CHILD: function(match){
4370
+ if ( match[1] == "nth" ) {
4371
+ var test = /(-?)(\d*)n((?:\+|-)?\d*)/.exec(
4372
+ match[2] == "even" && "2n" || match[2] == "odd" && "2n+1" ||
4373
+ !/\D/.test( match[2] ) && "0n+" + match[2] || match[2]);
4374
+
4375
+ match[2] = (test[1] + (test[2] || 1)) - 0;
4376
+ match[3] = test[3] - 0;
4377
+ }
4378
+
4379
+ match[0] = done++;
4380
+
4381
+ return match;
4382
+ },
4383
+ ATTR: function(match, curLoop, inplace, result, not, isXML){
4384
+ var name = match[1].replace(/\\/g, "");
4385
+
4386
+ if ( !isXML && Expr.attrMap[name] ) {
4387
+ match[1] = Expr.attrMap[name];
4388
+ }
4389
+
4390
+ if ( match[2] === "~=" ) {
4391
+ match[4] = " " + match[4] + " ";
4392
+ }
4393
+
4394
+ return match;
4395
+ },
4396
+ PSEUDO: function(match, curLoop, inplace, result, not){
4397
+ if ( match[1] === "not" ) {
4398
+ if ( ( chunker.exec(match[3]) || "" ).length > 1 || /^\w/.test(match[3]) ) {
4399
+ match[3] = Sizzle(match[3], null, null, curLoop);
4400
+ } else {
4401
+ var ret = Sizzle.filter(match[3], curLoop, inplace, true ^ not);
4402
+ if ( !inplace ) {
4403
+ result.push.apply( result, ret );
4404
+ }
4405
+ return false;
4406
+ }
4407
+ } else if ( Expr.match.POS.test( match[0] ) || Expr.match.CHILD.test( match[0] ) ) {
4408
+ return true;
4409
+ }
4410
+
4411
+ return match;
4412
+ },
4413
+ POS: function(match){
4414
+ match.unshift( true );
4415
+ return match;
4416
+ }
4417
+ },
4418
+ filters: {
4419
+ enabled: function(elem){
4420
+ return elem.disabled === false && elem.type !== "hidden";
4421
+ },
4422
+ disabled: function(elem){
4423
+ return elem.disabled === true;
4424
+ },
4425
+ checked: function(elem){
4426
+ return elem.checked === true;
4427
+ },
4428
+ selected: function(elem){
4429
+ elem.parentNode.selectedIndex;
4430
+ return elem.selected === true;
4431
+ },
4432
+ parent: function(elem){
4433
+ return !!elem.firstChild;
4434
+ },
4435
+ empty: function(elem){
4436
+ return !elem.firstChild;
4437
+ },
4438
+ has: function(elem, i, match){
4439
+ return !!Sizzle( match[3], elem ).length;
4440
+ },
4441
+ header: function(elem){
4442
+ return /h\d/i.test( elem.nodeName );
4443
+ },
4444
+ text: function(elem){
4445
+ return "text" === elem.type;
4446
+ },
4447
+ radio: function(elem){
4448
+ return "radio" === elem.type;
4449
+ },
4450
+ checkbox: function(elem){
4451
+ return "checkbox" === elem.type;
4452
+ },
4453
+ file: function(elem){
4454
+ return "file" === elem.type;
4455
+ },
4456
+ password: function(elem){
4457
+ return "password" === elem.type;
4458
+ },
4459
+ submit: function(elem){
4460
+ return "submit" === elem.type;
4461
+ },
4462
+ image: function(elem){
4463
+ return "image" === elem.type;
4464
+ },
4465
+ reset: function(elem){
4466
+ return "reset" === elem.type;
4467
+ },
4468
+ button: function(elem){
4469
+ return "button" === elem.type || elem.nodeName.toUpperCase() === "BUTTON";
4470
+ },
4471
+ input: function(elem){
4472
+ return /input|select|textarea|button/i.test(elem.nodeName);
4473
+ }
4474
+ },
4475
+ setFilters: {
4476
+ first: function(elem, i){
4477
+ return i === 0;
4478
+ },
4479
+ last: function(elem, i, match, array){
4480
+ return i === array.length - 1;
4481
+ },
4482
+ even: function(elem, i){
4483
+ return i % 2 === 0;
4484
+ },
4485
+ odd: function(elem, i){
4486
+ return i % 2 === 1;
4487
+ },
4488
+ lt: function(elem, i, match){
4489
+ return i < match[3] - 0;
4490
+ },
4491
+ gt: function(elem, i, match){
4492
+ return i > match[3] - 0;
4493
+ },
4494
+ nth: function(elem, i, match){
4495
+ return match[3] - 0 == i;
4496
+ },
4497
+ eq: function(elem, i, match){
4498
+ return match[3] - 0 == i;
4499
+ }
4500
+ },
4501
+ filter: {
4502
+ PSEUDO: function(elem, match, i, array){
4503
+ var name = match[1], filter = Expr.filters[ name ];
4504
+
4505
+ if ( filter ) {
4506
+ return filter( elem, i, match, array );
4507
+ } else if ( name === "contains" ) {
4508
+ return (elem.textContent || elem.innerText || "").indexOf(match[3]) >= 0;
4509
+ } else if ( name === "not" ) {
4510
+ var not = match[3];
4511
+
4512
+ for ( var i = 0, l = not.length; i < l; i++ ) {
4513
+ if ( not[i] === elem ) {
4514
+ return false;
4515
+ }
4516
+ }
4517
+
4518
+ return true;
4519
+ }
4520
+ },
4521
+ CHILD: function(elem, match){
4522
+ var type = match[1], node = elem;
4523
+ switch (type) {
4524
+ case 'only':
4525
+ case 'first':
4526
+ while ( (node = node.previousSibling) ) {
4527
+ if ( node.nodeType === 1 ) return false;
4528
+ }
4529
+ if ( type == 'first') return true;
4530
+ node = elem;
4531
+ case 'last':
4532
+ while ( (node = node.nextSibling) ) {
4533
+ if ( node.nodeType === 1 ) return false;
4534
+ }
4535
+ return true;
4536
+ case 'nth':
4537
+ var first = match[2], last = match[3];
4538
+
4539
+ if ( first == 1 && last == 0 ) {
4540
+ return true;
4541
+ }
4542
+
4543
+ var doneName = match[0],
4544
+ parent = elem.parentNode;
4545
+
4546
+ if ( parent && (parent.sizcache !== doneName || !elem.nodeIndex) ) {
4547
+ var count = 0;
4548
+ for ( node = parent.firstChild; node; node = node.nextSibling ) {
4549
+ if ( node.nodeType === 1 ) {
4550
+ node.nodeIndex = ++count;
4551
+ }
4552
+ }
4553
+ parent.sizcache = doneName;
4554
+ }
4555
+
4556
+ var diff = elem.nodeIndex - last;
4557
+ if ( first == 0 ) {
4558
+ return diff == 0;
4559
+ } else {
4560
+ return ( diff % first == 0 && diff / first >= 0 );
4561
+ }
4562
+ }
4563
+ },
4564
+ ID: function(elem, match){
4565
+ return elem.nodeType === 1 && elem.getAttribute("id") === match;
4566
+ },
4567
+ TAG: function(elem, match){
4568
+ return (match === "*" && elem.nodeType === 1) || elem.nodeName === match;
4569
+ },
4570
+ CLASS: function(elem, match){
4571
+ return (" " + (elem.className || elem.getAttribute("class")) + " ")
4572
+ .indexOf( match ) > -1;
4573
+ },
4574
+ ATTR: function(elem, match){
4575
+ var name = match[1],
4576
+ result = Expr.attrHandle[ name ] ?
4577
+ Expr.attrHandle[ name ]( elem ) :
4578
+ elem[ name ] != null ?
4579
+ elem[ name ] :
4580
+ elem.getAttribute( name ),
4581
+ value = result + "",
4582
+ type = match[2],
4583
+ check = match[4];
4584
+
4585
+ return result == null ?
4586
+ type === "!=" :
4587
+ type === "=" ?
4588
+ value === check :
4589
+ type === "*=" ?
4590
+ value.indexOf(check) >= 0 :
4591
+ type === "~=" ?
4592
+ (" " + value + " ").indexOf(check) >= 0 :
4593
+ !check ?
4594
+ value && result !== false :
4595
+ type === "!=" ?
4596
+ value != check :
4597
+ type === "^=" ?
4598
+ value.indexOf(check) === 0 :
4599
+ type === "$=" ?
4600
+ value.substr(value.length - check.length) === check :
4601
+ type === "|=" ?
4602
+ value === check || value.substr(0, check.length + 1) === check + "-" :
4603
+ false;
4604
+ },
4605
+ POS: function(elem, match, i, array){
4606
+ var name = match[2], filter = Expr.setFilters[ name ];
4607
+
4608
+ if ( filter ) {
4609
+ return filter( elem, i, match, array );
4610
+ }
4611
+ }
4612
+ }
4613
+ };
4614
+
4615
+ var origPOS = Expr.match.POS;
4616
+
4617
+ for ( var type in Expr.match ) {
4618
+ Expr.match[ type ] = new RegExp( Expr.match[ type ].source + /(?![^\[]*\])(?![^\(]*\))/.source );
4619
+ Expr.leftMatch[ type ] = new RegExp( /(^(?:.|\r|\n)*?)/.source + Expr.match[ type ].source );
4620
+ }
4621
+
4622
+ var makeArray = function(array, results) {
4623
+ array = Array.prototype.slice.call( array, 0 );
4624
+
4625
+ if ( results ) {
4626
+ results.push.apply( results, array );
4627
+ return results;
4628
+ }
4629
+
4630
+ return array;
4631
+ };
4632
+
4633
+ try {
4634
+ Array.prototype.slice.call( document.documentElement.childNodes, 0 );
4635
+
4636
+ } catch(e){
4637
+ makeArray = function(array, results) {
4638
+ var ret = results || [];
4639
+
4640
+ if ( toString.call(array) === "[object Array]" ) {
4641
+ Array.prototype.push.apply( ret, array );
4642
+ } else {
4643
+ if ( typeof array.length === "number" ) {
4644
+ for ( var i = 0, l = array.length; i < l; i++ ) {
4645
+ ret.push( array[i] );
4646
+ }
4647
+ } else {
4648
+ for ( var i = 0; array[i]; i++ ) {
4649
+ ret.push( array[i] );
4650
+ }
4651
+ }
4652
+ }
4653
+
4654
+ return ret;
4655
+ };
4656
+ }
4657
+
4658
+ var sortOrder;
4659
+
4660
+ if ( document.documentElement.compareDocumentPosition ) {
4661
+ sortOrder = function( a, b ) {
4662
+ if ( !a.compareDocumentPosition || !b.compareDocumentPosition ) {
4663
+ if ( a == b ) {
4664
+ hasDuplicate = true;
4665
+ }
4666
+ return 0;
4667
+ }
4668
+
4669
+ var ret = a.compareDocumentPosition(b) & 4 ? -1 : a === b ? 0 : 1;
4670
+ if ( ret === 0 ) {
4671
+ hasDuplicate = true;
4672
+ }
4673
+ return ret;
4674
+ };
4675
+ } else if ( "sourceIndex" in document.documentElement ) {
4676
+ sortOrder = function( a, b ) {
4677
+ if ( !a.sourceIndex || !b.sourceIndex ) {
4678
+ if ( a == b ) {
4679
+ hasDuplicate = true;
4680
+ }
4681
+ return 0;
4682
+ }
4683
+
4684
+ var ret = a.sourceIndex - b.sourceIndex;
4685
+ if ( ret === 0 ) {
4686
+ hasDuplicate = true;
4687
+ }
4688
+ return ret;
4689
+ };
4690
+ } else if ( document.createRange ) {
4691
+ sortOrder = function( a, b ) {
4692
+ if ( !a.ownerDocument || !b.ownerDocument ) {
4693
+ if ( a == b ) {
4694
+ hasDuplicate = true;
4695
+ }
4696
+ return 0;
4697
+ }
4698
+
4699
+ var aRange = a.ownerDocument.createRange(), bRange = b.ownerDocument.createRange();
4700
+ aRange.setStart(a, 0);
4701
+ aRange.setEnd(a, 0);
4702
+ bRange.setStart(b, 0);
4703
+ bRange.setEnd(b, 0);
4704
+ var ret = aRange.compareBoundaryPoints(Range.START_TO_END, bRange);
4705
+ if ( ret === 0 ) {
4706
+ hasDuplicate = true;
4707
+ }
4708
+ return ret;
4709
+ };
4710
+ }
4711
+
4712
+ (function(){
4713
+ var form = document.createElement("div"),
4714
+ id = "script" + (new Date).getTime();
4715
+ form.innerHTML = "<a name='" + id + "'/>";
4716
+
4717
+ var root = document.documentElement;
4718
+ root.insertBefore( form, root.firstChild );
4719
+
4720
+ if ( !!document.getElementById( id ) ) {
4721
+ Expr.find.ID = function(match, context, isXML){
4722
+ if ( typeof context.getElementById !== "undefined" && !isXML ) {
4723
+ var m = context.getElementById(match[1]);
4724
+ return m ? m.id === match[1] || typeof m.getAttributeNode !== "undefined" && m.getAttributeNode("id").nodeValue === match[1] ? [m] : undefined : [];
4725
+ }
4726
+ };
4727
+
4728
+ Expr.filter.ID = function(elem, match){
4729
+ var node = typeof elem.getAttributeNode !== "undefined" && elem.getAttributeNode("id");
4730
+ return elem.nodeType === 1 && node && node.nodeValue === match;
4731
+ };
4732
+ }
4733
+
4734
+ root.removeChild( form );
4735
+ root = form = null; // release memory in IE
4736
+ })();
4737
+
4738
+ (function(){
4739
+
4740
+ var div = document.createElement("div");
4741
+ div.appendChild( document.createComment("") );
4742
+
4743
+ if ( div.getElementsByTagName("*").length > 0 ) {
4744
+ Expr.find.TAG = function(match, context){
4745
+ var results = context.getElementsByTagName(match[1]);
4746
+
4747
+ if ( match[1] === "*" ) {
4748
+ var tmp = [];
4749
+
4750
+ for ( var i = 0; results[i]; i++ ) {
4751
+ if ( results[i].nodeType === 1 ) {
4752
+ tmp.push( results[i] );
4753
+ }
4754
+ }
4755
+
4756
+ results = tmp;
4757
+ }
4758
+
4759
+ return results;
4760
+ };
4761
+ }
4762
+
4763
+ div.innerHTML = "<a href='#'></a>";
4764
+ if ( div.firstChild && typeof div.firstChild.getAttribute !== "undefined" &&
4765
+ div.firstChild.getAttribute("href") !== "#" ) {
4766
+ Expr.attrHandle.href = function(elem){
4767
+ return elem.getAttribute("href", 2);
4768
+ };
4769
+ }
4770
+
4771
+ div = null; // release memory in IE
4772
+ })();
4773
+
4774
+ if ( document.querySelectorAll ) (function(){
4775
+ var oldSizzle = Sizzle, div = document.createElement("div");
4776
+ div.innerHTML = "<p class='TEST'></p>";
4777
+
4778
+ if ( div.querySelectorAll && div.querySelectorAll(".TEST").length === 0 ) {
4779
+ return;
4780
+ }
4781
+
4782
+ Sizzle = function(query, context, extra, seed){
4783
+ context = context || document;
4784
+
4785
+ if ( !seed && context.nodeType === 9 && !isXML(context) ) {
4786
+ try {
4787
+ return makeArray( context.querySelectorAll(query), extra );
4788
+ } catch(e){}
4789
+ }
4790
+
4791
+ return oldSizzle(query, context, extra, seed);
4792
+ };
4793
+
4794
+ for ( var prop in oldSizzle ) {
4795
+ Sizzle[ prop ] = oldSizzle[ prop ];
4796
+ }
4797
+
4798
+ div = null; // release memory in IE
4799
+ })();
4800
+
4801
+ if ( document.getElementsByClassName && document.documentElement.getElementsByClassName ) (function(){
4802
+ var div = document.createElement("div");
4803
+ div.innerHTML = "<div class='test e'></div><div class='test'></div>";
4804
+
4805
+ if ( div.getElementsByClassName("e").length === 0 )
4806
+ return;
4807
+
4808
+ div.lastChild.className = "e";
4809
+
4810
+ if ( div.getElementsByClassName("e").length === 1 )
4811
+ return;
4812
+
4813
+ Expr.order.splice(1, 0, "CLASS");
4814
+ Expr.find.CLASS = function(match, context, isXML) {
4815
+ if ( typeof context.getElementsByClassName !== "undefined" && !isXML ) {
4816
+ return context.getElementsByClassName(match[1]);
4817
+ }
4818
+ };
4819
+
4820
+ div = null; // release memory in IE
4821
+ })();
4822
+
4823
+ function dirNodeCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4824
+ var sibDir = dir == "previousSibling" && !isXML;
4825
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4826
+ var elem = checkSet[i];
4827
+ if ( elem ) {
4828
+ if ( sibDir && elem.nodeType === 1 ){
4829
+ elem.sizcache = doneName;
4830
+ elem.sizset = i;
4831
+ }
4832
+ elem = elem[dir];
4833
+ var match = false;
4834
+
4835
+ while ( elem ) {
4836
+ if ( elem.sizcache === doneName ) {
4837
+ match = checkSet[elem.sizset];
4838
+ break;
4839
+ }
4840
+
4841
+ if ( elem.nodeType === 1 && !isXML ){
4842
+ elem.sizcache = doneName;
4843
+ elem.sizset = i;
4844
+ }
4845
+
4846
+ if ( elem.nodeName === cur ) {
4847
+ match = elem;
4848
+ break;
4849
+ }
4850
+
4851
+ elem = elem[dir];
4852
+ }
4853
+
4854
+ checkSet[i] = match;
4855
+ }
4856
+ }
3911
4857
  }
3912
4858
 
3913
- function $$() {
3914
- return Selector.findChildElements(document, $A(arguments));
4859
+ function dirCheck( dir, cur, doneName, checkSet, nodeCheck, isXML ) {
4860
+ var sibDir = dir == "previousSibling" && !isXML;
4861
+ for ( var i = 0, l = checkSet.length; i < l; i++ ) {
4862
+ var elem = checkSet[i];
4863
+ if ( elem ) {
4864
+ if ( sibDir && elem.nodeType === 1 ) {
4865
+ elem.sizcache = doneName;
4866
+ elem.sizset = i;
4867
+ }
4868
+ elem = elem[dir];
4869
+ var match = false;
4870
+
4871
+ while ( elem ) {
4872
+ if ( elem.sizcache === doneName ) {
4873
+ match = checkSet[elem.sizset];
4874
+ break;
4875
+ }
4876
+
4877
+ if ( elem.nodeType === 1 ) {
4878
+ if ( !isXML ) {
4879
+ elem.sizcache = doneName;
4880
+ elem.sizset = i;
4881
+ }
4882
+ if ( typeof cur !== "string" ) {
4883
+ if ( elem === cur ) {
4884
+ match = true;
4885
+ break;
4886
+ }
4887
+
4888
+ } else if ( Sizzle.filter( cur, [elem] ).length > 0 ) {
4889
+ match = elem;
4890
+ break;
4891
+ }
4892
+ }
4893
+
4894
+ elem = elem[dir];
4895
+ }
4896
+
4897
+ checkSet[i] = match;
4898
+ }
4899
+ }
3915
4900
  }
3916
4901
 
4902
+ var contains = document.compareDocumentPosition ? function(a, b){
4903
+ return a.compareDocumentPosition(b) & 16;
4904
+ } : function(a, b){
4905
+ return a !== b && (a.contains ? a.contains(b) : true);
4906
+ };
4907
+
4908
+ var isXML = function(elem){
4909
+ return elem.nodeType === 9 && elem.documentElement.nodeName !== "HTML" ||
4910
+ !!elem.ownerDocument && elem.ownerDocument.documentElement.nodeName !== "HTML";
4911
+ };
4912
+
4913
+ var posProcess = function(selector, context){
4914
+ var tmpSet = [], later = "", match,
4915
+ root = context.nodeType ? [context] : context;
4916
+
4917
+ while ( (match = Expr.match.PSEUDO.exec( selector )) ) {
4918
+ later += match[0];
4919
+ selector = selector.replace( Expr.match.PSEUDO, "" );
4920
+ }
4921
+
4922
+ selector = Expr.relative[selector] ? selector + "*" : selector;
4923
+
4924
+ for ( var i = 0, l = root.length; i < l; i++ ) {
4925
+ Sizzle( selector, root[i], tmpSet );
4926
+ }
4927
+
4928
+ return Sizzle.filter( later, tmpSet );
4929
+ };
4930
+
4931
+
4932
+ window.Sizzle = Sizzle;
4933
+
4934
+ })();
4935
+
4936
+ ;(function(engine) {
4937
+ var extendElements = Prototype.Selector.extendElements;
4938
+
4939
+ function select(selector, scope) {
4940
+ return extendElements(engine(selector, scope || document));
4941
+ }
4942
+
4943
+ function match(element, selector) {
4944
+ return engine.matches(selector, [element]).length == 1;
4945
+ }
4946
+
4947
+ Prototype.Selector.engine = engine;
4948
+ Prototype.Selector.select = select;
4949
+ Prototype.Selector.match = match;
4950
+ })(Sizzle);
4951
+
4952
+ window.Sizzle = Prototype._original_property;
4953
+ delete Prototype._original_property;
4954
+
3917
4955
  var Form = {
3918
4956
  reset: function(form) {
3919
4957
  form = $(form);
@@ -4334,8 +5372,12 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4334
5372
  function findElement(event, expression) {
4335
5373
  var element = Event.element(event);
4336
5374
  if (!expression) return element;
4337
- var elements = [element].concat(element.ancestors());
4338
- return Selector.findElement(elements, expression, 0);
5375
+ while (element) {
5376
+ if (Object.isElement(element) && Prototype.Selector.match(element, expression)) {
5377
+ return Element.extend(element);
5378
+ }
5379
+ element = element.parentNode;
5380
+ }
4339
5381
  }
4340
5382
 
4341
5383
  function pointer(event) {
@@ -4504,12 +5546,12 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4504
5546
  window.addEventListener('unload', Prototype.emptyFunction, false);
4505
5547
 
4506
5548
 
4507
- var _getDOMEventName = Prototype.K;
5549
+ var _getDOMEventName = Prototype.K,
5550
+ translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
4508
5551
 
4509
5552
  if (!MOUSEENTER_MOUSELEAVE_EVENTS_SUPPORTED) {
4510
5553
  _getDOMEventName = function(eventName) {
4511
- var translations = { mouseenter: "mouseover", mouseleave: "mouseout" };
4512
- return eventName in translations ? translations[eventName] : eventName;
5554
+ return (translations[eventName] || eventName);
4513
5555
  };
4514
5556
  }
4515
5557
 
@@ -4543,38 +5585,29 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4543
5585
  element = $(element);
4544
5586
 
4545
5587
  var registry = Element.retrieve(element, 'prototype_event_registry');
5588
+ if (!registry) return element;
4546
5589
 
4547
- if (Object.isUndefined(registry)) return element;
4548
-
4549
- if (eventName && !handler) {
4550
- var responders = registry.get(eventName);
4551
-
4552
- if (Object.isUndefined(responders)) return element;
4553
-
4554
- responders.each( function(r) {
4555
- Element.stopObserving(element, eventName, r.handler);
4556
- });
4557
- return element;
4558
- } else if (!eventName) {
5590
+ if (!eventName) {
4559
5591
  registry.each( function(pair) {
4560
- var eventName = pair.key, responders = pair.value;
4561
-
4562
- responders.each( function(r) {
4563
- Element.stopObserving(element, eventName, r.handler);
4564
- });
5592
+ var eventName = pair.key;
5593
+ stopObserving(element, eventName);
4565
5594
  });
4566
5595
  return element;
4567
5596
  }
4568
5597
 
4569
5598
  var responders = registry.get(eventName);
5599
+ if (!responders) return element;
4570
5600
 
4571
- if (!responders) return;
5601
+ if (!handler) {
5602
+ responders.each(function(r) {
5603
+ stopObserving(element, eventName, r.handler);
5604
+ });
5605
+ return element;
5606
+ }
4572
5607
 
4573
5608
  var responder = responders.find( function(r) { return r.handler === handler; });
4574
5609
  if (!responder) return element;
4575
5610
 
4576
- var actualEventName = _getDOMEventName(eventName);
4577
-
4578
5611
  if (eventName.include(':')) {
4579
5612
  if (element.removeEventListener)
4580
5613
  element.removeEventListener("dataavailable", responder, false);
@@ -4583,6 +5616,7 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4583
5616
  element.detachEvent("onfilterchange", responder);
4584
5617
  }
4585
5618
  } else {
5619
+ var actualEventName = _getDOMEventName(eventName);
4586
5620
  if (element.removeEventListener)
4587
5621
  element.removeEventListener(actualEventName, responder, false);
4588
5622
  else
@@ -4623,13 +5657,47 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4623
5657
  return Event.extend(event);
4624
5658
  }
4625
5659
 
5660
+ Event.Handler = Class.create({
5661
+ initialize: function(element, eventName, selector, callback) {
5662
+ this.element = $(element);
5663
+ this.eventName = eventName;
5664
+ this.selector = selector;
5665
+ this.callback = callback;
5666
+ this.handler = this.handleEvent.bind(this);
5667
+ },
5668
+
5669
+ start: function() {
5670
+ Event.observe(this.element, this.eventName, this.handler);
5671
+ return this;
5672
+ },
5673
+
5674
+ stop: function() {
5675
+ Event.stopObserving(this.element, this.eventName, this.handler);
5676
+ return this;
5677
+ },
5678
+
5679
+ handleEvent: function(event) {
5680
+ var element = event.findElement(this.selector);
5681
+ if (element) this.callback.call(this.element, event, element);
5682
+ }
5683
+ });
5684
+
5685
+ function on(element, eventName, selector, callback) {
5686
+ element = $(element);
5687
+ if (Object.isFunction(selector) && Object.isUndefined(callback)) {
5688
+ callback = selector, selector = null;
5689
+ }
5690
+
5691
+ return new Event.Handler(element, eventName, selector, callback).start();
5692
+ }
4626
5693
 
4627
5694
  Object.extend(Event, Event.Methods);
4628
5695
 
4629
5696
  Object.extend(Event, {
4630
5697
  fire: fire,
4631
5698
  observe: observe,
4632
- stopObserving: stopObserving
5699
+ stopObserving: stopObserving,
5700
+ on: on
4633
5701
  });
4634
5702
 
4635
5703
  Element.addMethods({
@@ -4637,7 +5705,9 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4637
5705
 
4638
5706
  observe: observe,
4639
5707
 
4640
- stopObserving: stopObserving
5708
+ stopObserving: stopObserving,
5709
+
5710
+ on: on
4641
5711
  });
4642
5712
 
4643
5713
  Object.extend(document, {
@@ -4647,6 +5717,8 @@ Form.EventObserver = Class.create(Abstract.EventObserver, {
4647
5717
 
4648
5718
  stopObserving: stopObserving.methodize(),
4649
5719
 
5720
+ on: on.methodize(),
5721
+
4650
5722
  loaded: false
4651
5723
  });
4652
5724
 
@@ -4872,3 +5944,58 @@ Element.ClassNames.prototype = {
4872
5944
  Object.extend(Element.ClassNames.prototype, Enumerable);
4873
5945
 
4874
5946
  /*--------------------------------------------------------------------------*/
5947
+
5948
+ (function() {
5949
+ window.Selector = Class.create({
5950
+ initialize: function(expression) {
5951
+ this.expression = expression.strip();
5952
+ },
5953
+
5954
+ findElements: function(rootElement) {
5955
+ return Prototype.Selector.select(this.expression, rootElement);
5956
+ },
5957
+
5958
+ match: function(element) {
5959
+ return Prototype.Selector.match(element, this.expression);
5960
+ },
5961
+
5962
+ toString: function() {
5963
+ return this.expression;
5964
+ },
5965
+
5966
+ inspect: function() {
5967
+ return "#<Selector: " + this.expression + ">";
5968
+ }
5969
+ });
5970
+
5971
+ Object.extend(Selector, {
5972
+ matchElements: function(elements, expression) {
5973
+ var match = Prototype.Selector.match,
5974
+ results = [];
5975
+
5976
+ for (var i = 0, length = elements.length; i < length; i++) {
5977
+ var element = elements[i];
5978
+ if (match(element, expression)) {
5979
+ results.push(Element.extend(element));
5980
+ }
5981
+ }
5982
+ return results;
5983
+ },
5984
+
5985
+ findElement: function(elements, expression, index) {
5986
+ index = index || 0;
5987
+ var matchIndex = 0, element;
5988
+ for (var i = 0, length = elements.length; i < length; i++) {
5989
+ element = elements[i];
5990
+ if (Prototype.Selector.match(element, expression) && index === matchIndex++) {
5991
+ return Element.extend(element);
5992
+ }
5993
+ }
5994
+ },
5995
+
5996
+ findChildElements: function(element, expressions) {
5997
+ var selector = expressions.toArray().join(', ');
5998
+ return Prototype.Selector.select(selector, element || document);
5999
+ }
6000
+ });
6001
+ })();