mootools-rails 0.4 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/Gemfile CHANGED
@@ -1,4 +1,9 @@
1
1
  source :gemcutter
2
2
 
3
- # Specify your gem's dependencies in mootols-rails.gemspec
3
+ # Specify your gem's dependencies in mootools-rails.gemspec
4
4
  gemspec
5
+ # Rails is already being pulled in through gemspec
6
+ # gem "rails", :git => "git://github.com/rails/rails.git"
7
+ gem "rack", :git => "git://github.com/rack/rack.git"
8
+ gem "sprockets", :git => "git://github.com/sstephenson/sprockets.git"
9
+ gem "i18n", "0.6.0beta1"
@@ -1,7 +1,22 @@
1
+ GIT
2
+ remote: git://github.com/rack/rack.git
3
+ revision: a9beb476b27914794743d0677b327d5bafb5e8a3
4
+ specs:
5
+ rack (1.2.1)
6
+
7
+ GIT
8
+ remote: git://github.com/sstephenson/sprockets.git
9
+ revision: c4800417792744c11eb1fb888bbe9a3a82859952
10
+ specs:
11
+ sprockets (2.0.0.beta.2)
12
+ hike (~> 1.0)
13
+ rack (~> 1.0)
14
+ tilt (~> 1.0)
15
+
1
16
  PATH
2
17
  remote: .
3
18
  specs:
4
- mootools-rails (0.4)
19
+ mootools-rails (1.0.0)
5
20
  railties (~> 3.0)
6
21
  thor (~> 0.14)
7
22
 
@@ -9,72 +24,77 @@ GEM
9
24
  remote: http://rubygems.org/
10
25
  specs:
11
26
  abstract (1.0.0)
12
- actionmailer (3.0.7)
13
- actionpack (= 3.0.7)
27
+ actionmailer (3.0.5)
28
+ actionpack (= 3.0.5)
14
29
  mail (~> 2.2.15)
15
- actionpack (3.0.7)
16
- activemodel (= 3.0.7)
17
- activesupport (= 3.0.7)
30
+ actionpack (3.0.5)
31
+ activemodel (= 3.0.5)
32
+ activesupport (= 3.0.5)
18
33
  builder (~> 2.1.2)
19
34
  erubis (~> 2.6.6)
20
- i18n (~> 0.5.0)
35
+ i18n (~> 0.4)
21
36
  rack (~> 1.2.1)
22
- rack-mount (~> 0.6.14)
37
+ rack-mount (~> 0.6.13)
23
38
  rack-test (~> 0.5.7)
24
39
  tzinfo (~> 0.3.23)
25
- activemodel (3.0.7)
26
- activesupport (= 3.0.7)
40
+ activemodel (3.0.5)
41
+ activesupport (= 3.0.5)
27
42
  builder (~> 2.1.2)
28
- i18n (~> 0.5.0)
29
- activerecord (3.0.7)
30
- activemodel (= 3.0.7)
31
- activesupport (= 3.0.7)
43
+ i18n (~> 0.4)
44
+ activerecord (3.0.5)
45
+ activemodel (= 3.0.5)
46
+ activesupport (= 3.0.5)
32
47
  arel (~> 2.0.2)
33
48
  tzinfo (~> 0.3.23)
34
- activeresource (3.0.7)
35
- activemodel (= 3.0.7)
36
- activesupport (= 3.0.7)
37
- activesupport (3.0.7)
49
+ activeresource (3.0.5)
50
+ activemodel (= 3.0.5)
51
+ activesupport (= 3.0.5)
52
+ activesupport (3.0.5)
38
53
  arel (2.0.10)
39
54
  builder (2.1.2)
40
55
  erubis (2.6.6)
41
56
  abstract (>= 1.0.0)
42
- i18n (0.5.0)
57
+ hike (1.0.0)
58
+ i18n (0.6.0beta1)
43
59
  mail (2.2.19)
44
60
  activesupport (>= 2.3.6)
45
61
  i18n (>= 0.4.0)
46
62
  mime-types (~> 1.16)
47
63
  treetop (~> 1.4.8)
48
- mime-types (1.16)
49
- polyglot (0.3.1)
50
- rack (1.2.3)
64
+ mime-types (1.17.2)
65
+ polyglot (0.3.3)
51
66
  rack-mount (0.6.14)
52
67
  rack (>= 1.0.0)
53
68
  rack-test (0.5.7)
54
69
  rack (>= 1.0)
55
- rails (3.0.7)
56
- actionmailer (= 3.0.7)
57
- actionpack (= 3.0.7)
58
- activerecord (= 3.0.7)
59
- activeresource (= 3.0.7)
60
- activesupport (= 3.0.7)
70
+ rails (3.0.5)
71
+ actionmailer (= 3.0.5)
72
+ actionpack (= 3.0.5)
73
+ activerecord (= 3.0.5)
74
+ activeresource (= 3.0.5)
75
+ activesupport (= 3.0.5)
61
76
  bundler (~> 1.0)
62
- railties (= 3.0.7)
63
- railties (3.0.7)
64
- actionpack (= 3.0.7)
65
- activesupport (= 3.0.7)
77
+ railties (= 3.0.5)
78
+ railties (3.0.5)
79
+ actionpack (= 3.0.5)
80
+ activesupport (= 3.0.5)
66
81
  rake (>= 0.8.7)
67
82
  thor (~> 0.14.4)
68
- rake (0.9.0)
83
+ rake (0.9.2.2)
69
84
  thor (0.14.6)
70
- treetop (1.4.9)
85
+ tilt (1.3)
86
+ treetop (1.4.10)
87
+ polyglot
71
88
  polyglot (>= 0.3.1)
72
- tzinfo (0.3.27)
89
+ tzinfo (0.3.30)
73
90
 
74
91
  PLATFORMS
75
92
  ruby
76
93
 
77
94
  DEPENDENCIES
78
95
  bundler (~> 1.0.0)
96
+ i18n (= 0.6.0beta1)
79
97
  mootools-rails!
98
+ rack!
80
99
  rails (~> 3.0)
100
+ sprockets!
data/README.md CHANGED
@@ -1,15 +1,19 @@
1
- # MooTools-rails
1
+ # Mootools-rails
2
+
3
+ MooTools! For Rails! So great.
4
+
5
+ Also provided is Sam Ruby's modified assert_select_jquery function for MooTools, which is automatically included for use in tests.
2
6
 
3
7
  ## Rails 3.1
4
8
 
5
- This gem vendors MooTools 1.3.2 and the latest MooTools UJS adapter for Rails 3.1 and greater. The files will be added to the asset pipeline and available for you to use. These two lines will be added to the file `app/assets/javascripts/application.js` by default:
9
+ This gem vendors MooTools 1.4.1 and the latest MooTools UJS adapter for Rails 3.1 and greater. The files will be added to the asset pipeline and available for you to use. These two lines will be added to the file `app/assets/javascripts/application.js` by default:
6
10
 
7
11
  //= require mootools
8
12
  //= require mootools_ujs
9
13
 
10
14
  If you wish to use MooTools More as well, you can add this line to `application.js`:
11
15
 
12
- //= require mootools-more
16
+ //= require mootools-ui
13
17
 
14
18
  ### Installation
15
19
 
@@ -17,11 +21,11 @@ When you generate a new Rails 3.1 app, pass the `-j mootools` option, like this:
17
21
 
18
22
  rails new myapp -j mootools
19
23
 
20
- Then run `bundle install`. You're done!
24
+ You're done!
21
25
 
22
26
  ## Rails 3.0
23
27
 
24
- This gem adds a single generator to Rails 3, mootools:install. Running the generator will remove any Prototype JS files you may happen to have, fetch MooTools and the MooTools UJS driver for Rails, and (optionally) fetch MooTools More.
28
+ This gem adds a single generator to Rails 3, mootools:install. Running the generator will remove any Prototype JS files you may happen to have, fetch MooTools and the MooTools-ujs driver for Rails, and (optionally) fetch MooTools More.
25
29
 
26
30
  The gem will also hook into the Rails configuration process, removing Prototype and adding MooTools to the javascript files included by the `javascript_include_tag(:defaults)` call. While the plugin downloads minified and un-minified versions of MooTools and MooTools More, only the minified versions are included in :default.
27
31
 
@@ -29,7 +33,7 @@ The gem will also hook into the Rails configuration process, removing Prototype
29
33
 
30
34
  In your Gemfile, add this line:
31
35
 
32
- gem 'mootools-rails'
36
+ gem "mootools-rails"
33
37
 
34
38
  Then, run `bundle install`. To invoke the generator, run:
35
39
 
data/Rakefile CHANGED
@@ -1,2 +1,10 @@
1
1
  require 'bundler'
2
2
  Bundler::GemHelper.install_tasks
3
+
4
+ # require "spec/rake/spectask"
5
+ # desc "Run all examples"
6
+ # Spec::Rake::SpecTask.new(:spec) do |t|
7
+ # t.ruby_opts = ['-r test/unit']
8
+ # t.spec_opts = %w[--color]
9
+ # end
10
+ task :default => :spec
@@ -1,42 +1,56 @@
1
1
  require 'rails'
2
2
 
3
- module Mootools
4
- module Generators
5
- class InstallGenerator < ::Rails::Generators::Base
6
- @@mootools_version = "1.3.2"
7
- @@mootools_more_version = '1.3.2.1'
8
- @@mootools_ujs_version = "2c1e98715bc0fc74afa3c79e5d125e55450ba74a"
9
-
10
- desc "This generator installs MooTools #{@@mootools_version}, MooTools-ujs, and (optionally) MooTools More #{@@mootools_more_version}"
11
- class_option :more, :type => :boolean, :default => false, :desc => "Include MooTools More"
12
- source_root File.expand_path('../../../../../vendor/assets/javascripts', __FILE__)
13
-
14
- def remove_prototype
15
- PROTOTYPE_JS.each do |name|
16
- remove_file "public/javascripts/#{name}.js"
3
+ if ::Rails.version < "3.1"
4
+ module Mootools
5
+ module Generators
6
+ class InstallGenerator < ::Rails::Generators::Base
7
+
8
+ desc "This generator installs MooTools #{Mootools::Rails::MOOTOOLS_VERSION}, MooTools-ujs, and (optionally) MooTools More #{Mootools::Rails::MOOTOOLS_MORE_VERSION}"
9
+ class_option :more, :type => :boolean, :default => false, :desc => "Include MooTools More"
10
+ source_root File.expand_path('../../../../../vendor/assets/javascripts', __FILE__)
11
+
12
+ def remove_prototype
13
+ Rails::PROTOTYPE_JS.each do |name|
14
+ remove_file "public/javascripts/#{name}.js"
15
+ end
17
16
  end
18
- end
19
17
 
20
- def copy_mootools
21
- say_status("copying", "MooTools (#{@@mootools_version})", :green)
22
- copy_file "mootools.js", "public/javascripts/mootools.js"
23
- copy_file "mootools.min.js", "public/javascripts/mootools.min.js"
24
- end
18
+ def copy_mootools
19
+ say_status("copying", "MooTools (#{Mootools::Rails::MOOTOOLS_VERSION})", :green)
20
+ copy_file "mootools.js", "public/javascripts/mootools.js"
21
+ copy_file "mootools.min.js", "public/javascripts/mootools.min.js"
22
+ end
25
23
 
26
- def copy_mootools_more
27
- if options.more?
28
- say_status("copying", "MooTools More (#{@@mootools_more_version})", :green)
29
- copy_file "mootools-more.js", "public/javascripts/mootools-more.js"
30
- copy_file "mootools-more.min.js", "public/javascripts/mootools-more.min.js"
24
+ def copy_mootools_more
25
+ if options.ui?
26
+ say_status("copying", "MooTools More (#{Mootools::Rails::MOOTOOLS_MORE_VERSION})", :green)
27
+ copy_file "mootools-more.js", "public/javascripts/mootools-more.js"
28
+ copy_file "mootools-mootools.min.js", "public/javascripts/mootools-more.min.js"
29
+ end
30
+ end
31
+
32
+ def copy_ujs_driver
33
+ say_status("copying", "MooTools UJS adapter (#{Mootools::Rails::MOOTOOLS_UJS_VERSION[0..5]})", :green)
34
+ remove_file "public/javascripts/rails.js"
35
+ copy_file "mootools_ujs.js", "public/javascripts/mootools_ujs.js"
31
36
  end
32
- end
33
37
 
34
- def copy_ujs_driver
35
- say_status("copying", "MooTools UJS adapter (#{@@mootools_ujs_version[0..5]})", :green)
36
- remove_file "public/javascripts/rails.js"
37
- copy_file "mootools_ujs.js", "public/javascripts/mootools_ujs.js"
38
38
  end
39
+ end
40
+ end
41
+ else
42
+ module Mootools
43
+ module Generators
44
+ class InstallGenerator < ::Rails::Generators::Base
45
+ desc "Just show instructions so people will know what to do when mistakenly using generator for Rails 3.1 apps"
39
46
 
47
+ def do_nothing
48
+ say_status("deprecated", "You are using Rails 3.1, so this generator is no longer needed. The necessary files are already in your asset pipeline.")
49
+ say_status("", "Just add `//= require mootools` and `//= require mootools_ujs` to your app/assets/javascripts/application.js")
50
+ say_status("", "If you upgraded your app from Rails 3.0 and still have mootools.js, rails.js, or mootools-more.js in your javascripts, be sure to remove them.")
51
+ # ok, nothing
52
+ end
53
+ end
40
54
  end
41
55
  end
42
- end if ::Rails.version < "3.1"
56
+ end
@@ -1,12 +1 @@
1
- module Mootools
2
- PROTOTYPE_JS = %w{prototype effects dragdrop controls}
3
-
4
- module Rails
5
- if ::Rails.version < "3.1"
6
- require 'mootools-rails/railtie'
7
- else
8
- require 'mootools-rails/engine'
9
- end
10
- end
11
-
12
- end
1
+ require 'mootools/rails'
@@ -20,11 +20,11 @@ module ActionDispatch
20
20
  #
21
21
  # === Using blocks
22
22
  #
23
- # Without a block, +assert_select_jquery_ merely asserts that the
23
+ # Without a block, +assert_select_mootools_ merely asserts that the
24
24
  # response contains one or more statements that match the conditions
25
25
  # specified above
26
26
  #
27
- # With a block +assert_select_jquery_ also asserts that the method call
27
+ # With a block +assert_select_mootools_ also asserts that the method call
28
28
  # passes a javascript escaped string containing HTML. All such HTML
29
29
  # fragments are selected and passed to the block. Nested assertions are
30
30
  # supported.
@@ -52,7 +52,7 @@ module ActionDispatch
52
52
 
53
53
  pattern = "\\.#{mootools_method || '\\w+'}\\("
54
54
  pattern = "#{pattern}['\"]#{mootools_opt}['\"],?\\s*" if mootools_opt
55
- pattern = "#{pattern}#{PATTERN_HTML}" if block
55
+ pattern = "#{pattern}#{PATTERN_HTML}"
56
56
  pattern = "(?:MooTools|\\$)\\(['\"]#{id}['\"]\\)#{pattern}" if id
57
57
 
58
58
  fragments = []
@@ -84,6 +84,7 @@ module ActionDispatch
84
84
  def unescape_js(js_string)
85
85
  # js encodes double quotes and line breaks.
86
86
  unescaped= js_string.gsub('\"', '"')
87
+ unescaped.gsub!('\\\'', "'")
87
88
  unescaped.gsub!(/\\\//, '/')
88
89
  unescaped.gsub!('\n', "\n")
89
90
  unescaped.gsub!('\076', '>')
@@ -0,0 +1,12 @@
1
+ module Mootools
2
+ module Rails
3
+ PROTOTYPE_JS = %w{prototype effects dragdrop controls}
4
+
5
+ if ::Rails.version < "3.1"
6
+ require 'mootools/rails/railtie'
7
+ else
8
+ require 'mootools/rails/engine'
9
+ end
10
+ require 'mootools/rails/version'
11
+ end
12
+ end
@@ -1,10 +1,10 @@
1
- # Configure Rails 3.1 to have assert_select_mootools
1
+ # Configure Rails 3.1 to have assert_select_mootools() in tests
2
2
  module Mootools
3
3
  module Rails
4
4
 
5
5
  class Engine < ::Rails::Engine
6
6
  config.before_configuration do
7
- require "mootools-rails/assert_select_mootools" if ::Rails.env.test?
7
+ require "mootools/assert_select" if ::Rails.env.test?
8
8
  end
9
9
  end
10
10
 
@@ -4,7 +4,7 @@ module Mootools
4
4
 
5
5
  class Railtie < ::Rails::Railtie
6
6
  config.before_configuration do
7
- require "mootools-rails/assert_select_mootools" if ::Rails.env.test?
7
+ require "mootools/assert_select" if ::Rails.env.test?
8
8
 
9
9
  if ::Rails.root.join("public/javascripts/mootools-more.min.js").exist?
10
10
  jq_defaults = %w(mootools mootools-more)
@@ -13,7 +13,7 @@ module Mootools
13
13
  jq_defaults = ::Rails.env.production? ? %w(mootools.min) : %w(mootools)
14
14
  end
15
15
 
16
- # Merge the MooTools scripts, remove the Prototype defaults and finally add 'rails'
16
+ # Merge the MooTools scripts, remove the Prototype defaults and finally add 'mootools_ujs'
17
17
  # at the end, because load order is important
18
18
  config.action_view.javascript_expansions[:defaults] -= PROTOTYPE_JS + ['rails']
19
19
  config.action_view.javascript_expansions[:defaults] |= jq_defaults
@@ -0,0 +1,8 @@
1
+ module Mootools
2
+ module Rails
3
+ VERSION = "1.0.0"
4
+ MOOTOOLS_VERSION = "1.4.1"
5
+ MOOTOOLS_MORE_VERSION = "1.4.0.1"
6
+ MOOTOOLS_UJS_VERSION = "2c1e98715bc0fc74afa3c79e5d125e55450ba74a"
7
+ end
8
+ end
@@ -1,5 +1,5 @@
1
1
  # -*- encoding: utf-8 -*-
2
- require File.expand_path('../lib/mootools-rails/version', __FILE__)
2
+ require File.expand_path('../lib/mootools/rails/version', __FILE__)
3
3
 
4
4
  Gem::Specification.new do |s|
5
5
  s.name = "mootools-rails"
@@ -22,4 +22,4 @@ Gem::Specification.new do |s|
22
22
  s.files = `git ls-files`.split("\n")
23
23
  s.executables = `git ls-files`.split("\n").select{|f| f =~ /^bin/}
24
24
  s.require_path = 'lib'
25
- end
25
+ end
@@ -0,0 +1,3 @@
1
+ require 'spec_helper'
2
+
3
+ it "should probably test something, but I'm damned if I know what"
@@ -0,0 +1,27 @@
1
+ # Set up RSpec
2
+ require 'webmock/rspec'
3
+
4
+ Spec::Runner.configure do |config|
5
+ config.include WebMock::API
6
+ end
7
+
8
+ # Set up generator tests
9
+ require 'rails/all'
10
+ require 'rails/generators'
11
+ require 'rails/generators/test_case'
12
+
13
+ class TestApp < Rails::Application
14
+ config.root = File.dirname(__FILE__)
15
+ end
16
+ Rails.application = TestApp
17
+
18
+ module Rails
19
+ def self.root
20
+ @root ||= File.expand_path("../../tmp/rails", __FILE__)
21
+ end
22
+ end
23
+ Rails.application.config.root = Rails.root
24
+
25
+ # Call configure to load the settings from
26
+ # Rails.application.config.generators to Rails::Generators
27
+ Rails::Generators.configure!
@@ -1,6 +1,6 @@
1
1
  // MooTools: the javascript framework.
2
- // Load this file's selection again by visiting: http://mootools.net/more/9cc6f160bc261365539063600b3d6bfe
3
- // Or build this file again with packager using: packager build More/More More/Events.Pseudos More/Class.Refactor More/Class.Binds More/Class.Occlude More/Chain.Wait More/Array.Extras More/Date More/Date.Extras More/Number.Format More/Object.Extras More/String.Extras More/String.QueryString More/URI More/URI.Relative More/Hash More/Hash.Extras More/Element.Forms More/Elements.From More/Element.Event.Pseudos More/Element.Event.Pseudos.Keys More/Element.Delegation More/Element.Measure More/Element.Pin More/Element.Position More/Element.Shortcuts More/Form.Request More/Form.Request.Append More/Form.Validator More/Form.Validator.Inline More/Form.Validator.Extras More/OverText More/Fx.Elements More/Fx.Accordion More/Fx.Move More/Fx.Reveal More/Fx.Scroll More/Fx.Slide More/Fx.SmoothScroll More/Fx.Sort More/Drag More/Drag.Move More/Slider More/Sortables More/Request.JSONP More/Request.Queue More/Request.Periodical More/Assets More/Color More/Group More/Hash.Cookie More/IframeShim More/Table More/HtmlTable More/HtmlTable.Zebra More/HtmlTable.Sort More/HtmlTable.Select More/Keyboard More/Keyboard.Extras More/Mask More/Scroller More/Tips More/Spinner More/Locale More/Locale.Set.From More/Locale.en-US.Date More/Locale.en-US.Form.Validator More/Locale.en-US.Number More/Locale.ar.Date More/Locale.ar.Form.Validator More/Locale.ca-CA.Date More/Locale.ca-CA.Form.Validator More/Locale.cs-CZ.Date More/Locale.cs-CZ.Form.Validator More/Locale.da-DK.Date More/Locale.da-DK.Form.Validator More/Locale.de-CH.Date More/Locale.de-CH.Form.Validator More/Locale.de-DE.Date More/Locale.de-DE.Form.Validator More/Locale.de-DE.Number More/Locale.en-GB.Date More/Locale.es-AR.Date More/Locale.es-AR.Form.Validator More/Locale.es-ES.Date More/Locale.es-ES.Form.Validator More/Locale.et-EE.Date More/Locale.et-EE.Form.Validator More/Locale.EU.Number More/Locale.fa.Date More/Locale.fa.Form.Validator More/Locale.fi-FI.Date More/Locale.fi-FI.Form.Validator More/Locale.fi-FI.Number More/Locale.fr-FR.Date More/Locale.fr-FR.Form.Validator More/Locale.fr-FR.Number More/Locale.he-IL.Date More/Locale.he-IL.Form.Validator More/Locale.he-IL.Number More/Locale.hu-HU.Date More/Locale.hu-HU.Form.Validator More/Locale.it-IT.Date More/Locale.it-IT.Form.Validator More/Locale.ja-JP.Date More/Locale.ja-JP.Form.Validator More/Locale.ja-JP.Number More/Locale.nl-NL.Date More/Locale.nl-NL.Form.Validator More/Locale.nl-NL.Number More/Locale.no-NO.Date More/Locale.no-NO.Form.Validator More/Locale.pl-PL.Date More/Locale.pl-PL.Form.Validator More/Locale.pt-BR.Date More/Locale.pt-BR.Form.Validator More/Locale.pt-PT.Date More/Locale.pt-PT.Form.Validator More/Locale.ru-RU-unicode.Date More/Locale.ru-RU-unicode.Form.Validator More/Locale.si-SI.Date More/Locale.si-SI.Form.Validator More/Locale.sv-SE.Date More/Locale.sv-SE.Form.Validator More/Locale.uk-UA.Date More/Locale.uk-UA.Form.Validator More/Locale.zh-CH.Date More/Locale.zh-CH.Form.Validator
2
+ // Load this file's selection again by visiting: http://mootools.net/more/065f2f092ece4e3b32bb5214464cf926
3
+ // Or build this file again with packager using: packager build More/More More/Events.Pseudos More/Class.Refactor More/Class.Binds More/Class.Occlude More/Chain.Wait More/Array.Extras More/Date More/Date.Extras More/Number.Format More/Object.Extras More/String.Extras More/String.QueryString More/URI More/URI.Relative More/Hash More/Hash.Extras More/Element.Forms More/Elements.From More/Element.Event.Pseudos More/Element.Event.Pseudos.Keys More/Element.Measure More/Element.Pin More/Element.Position More/Element.Shortcuts More/Form.Request More/Form.Request.Append More/Form.Validator More/Form.Validator.Inline More/Form.Validator.Extras More/OverText More/Fx.Elements More/Fx.Accordion More/Fx.Move More/Fx.Reveal More/Fx.Scroll More/Fx.Slide More/Fx.SmoothScroll More/Fx.Sort More/Drag More/Drag.Move More/Slider More/Sortables More/Request.JSONP More/Request.Queue More/Request.Periodical More/Assets More/Color More/Group More/Hash.Cookie More/IframeShim More/Table More/HtmlTable More/HtmlTable.Zebra More/HtmlTable.Sort More/HtmlTable.Select More/Keyboard More/Keyboard.Extras More/Mask More/Scroller More/Tips More/Spinner More/Locale More/Locale.Set.From More/Locale.en-US.Date More/Locale.en-US.Form.Validator More/Locale.en-US.Number More/Locale.ar.Date More/Locale.ar.Form.Validator More/Locale.ca-CA.Date More/Locale.ca-CA.Form.Validator More/Locale.cs-CZ.Date More/Locale.cs-CZ.Form.Validator More/Locale.da-DK.Date More/Locale.da-DK.Form.Validator More/Locale.de-CH.Date More/Locale.de-CH.Form.Validator More/Locale.de-DE.Date More/Locale.de-DE.Form.Validator More/Locale.de-DE.Number More/Locale.en-GB.Date More/Locale.es-AR.Date More/Locale.es-AR.Form.Validator More/Locale.es-ES.Date More/Locale.es-ES.Form.Validator More/Locale.et-EE.Date More/Locale.et-EE.Form.Validator More/Locale.EU.Number More/Locale.fa.Date More/Locale.fa.Form.Validator More/Locale.fi-FI.Date More/Locale.fi-FI.Form.Validator More/Locale.fi-FI.Number More/Locale.fr-FR.Date More/Locale.fr-FR.Form.Validator More/Locale.fr-FR.Number More/Locale.he-IL.Date More/Locale.he-IL.Form.Validator More/Locale.he-IL.Number More/Locale.hu-HU.Date More/Locale.hu-HU.Form.Validator More/Locale.it-IT.Date More/Locale.it-IT.Form.Validator More/Locale.ja-JP.Date More/Locale.ja-JP.Form.Validator More/Locale.ja-JP.Number More/Locale.nl-NL.Date More/Locale.nl-NL.Form.Validator More/Locale.nl-NL.Number More/Locale.no-NO.Date More/Locale.no-NO.Form.Validator More/Locale.pl-PL.Date More/Locale.pl-PL.Form.Validator More/Locale.pt-BR.Date More/Locale.pt-BR.Form.Validator More/Locale.pt-PT.Date More/Locale.pt-PT.Form.Validator More/Locale.ru-RU-unicode.Date More/Locale.ru-RU-unicode.Form.Validator More/Locale.si-SI.Date More/Locale.si-SI.Form.Validator More/Locale.sv-SE.Date More/Locale.sv-SE.Form.Validator More/Locale.uk-UA.Date More/Locale.uk-UA.Form.Validator More/Locale.zh-CH.Date More/Locale.zh-CH.Form.Validator
4
4
  /*
5
5
  ---
6
6
 
@@ -31,8 +31,8 @@ provides: [MooTools.More]
31
31
  */
32
32
 
33
33
  MooTools.More = {
34
- 'version': '1.3.2.1',
35
- 'build': 'e586bcd2496e9b22acfde32e12f84d49ce09e59d'
34
+ 'version': '1.4.0.1',
35
+ 'build': 'a4244edf2aa97ac8a196fc96082dd35af1abab87'
36
36
  };
37
37
 
38
38
 
@@ -55,22 +55,24 @@ provides: [Events.Pseudos]
55
55
  ...
56
56
  */
57
57
 
58
+ (function(){
59
+
58
60
  Events.Pseudos = function(pseudos, addEvent, removeEvent){
59
61
 
60
- var storeKey = 'monitorEvents:';
62
+ var storeKey = '_monitorEvents:';
61
63
 
62
64
  var storageOf = function(object){
63
65
  return {
64
66
  store: object.store ? function(key, value){
65
67
  object.store(storeKey + key, value);
66
68
  } : function(key, value){
67
- (object.$monitorEvents || (object.$monitorEvents = {}))[key] = value;
69
+ (object._monitorEvents || (object._monitorEvents = {}))[key] = value;
68
70
  },
69
71
  retrieve: object.retrieve ? function(key, dflt){
70
72
  return object.retrieve(storeKey + key, dflt);
71
73
  } : function(key, dflt){
72
- if (!object.$monitorEvents) return dflt;
73
- return object.$monitorEvents[key] || dflt;
74
+ if (!object._monitorEvents) return dflt;
75
+ return object._monitorEvents[key] || dflt;
74
76
  }
75
77
  };
76
78
  };
@@ -83,24 +85,20 @@ Events.Pseudos = function(pseudos, addEvent, removeEvent){
83
85
  l = parsedPseudos.length,
84
86
  splits = [];
85
87
 
86
- while (l--) if (pseudos[parsedPseudos[l].key]){
87
- splits.push({
88
+ while (l--){
89
+ var pseudo = parsedPseudos[l].key,
90
+ listener = pseudos[pseudo];
91
+ if (listener != null) splits.push({
88
92
  event: parsed.tag,
89
93
  value: parsedPseudos[l].value,
90
- pseudo: parsedPseudos[l].key,
91
- original: type
94
+ pseudo: pseudo,
95
+ original: type,
96
+ listener: listener
92
97
  });
93
98
  }
94
-
95
99
  return splits.length ? splits : null;
96
100
  };
97
101
 
98
- var mergePseudoOptions = function(split){
99
- return Object.merge.apply(this, split.map(function(item){
100
- return pseudos[item.pseudo].options || {};
101
- }));
102
- };
103
-
104
102
  return {
105
103
 
106
104
  addEvent: function(type, fn, internal){
@@ -110,30 +108,24 @@ Events.Pseudos = function(pseudos, addEvent, removeEvent){
110
108
  var storage = storageOf(this),
111
109
  events = storage.retrieve(type, []),
112
110
  eventType = split[0].event,
113
- options = mergePseudoOptions(split),
114
- stack = fn,
115
- eventOptions = options[eventType] || {},
116
111
  args = Array.slice(arguments, 2),
117
- self = this,
118
- monitor;
119
-
120
- if (eventOptions.args) args.append(Array.from(eventOptions.args));
121
- if (eventOptions.base) eventType = eventOptions.base;
122
- if (eventOptions.onAdd) eventOptions.onAdd(this);
112
+ stack = fn,
113
+ self = this;
123
114
 
124
115
  split.each(function(item){
125
- var stackFn = stack;
126
- stack = function(){
127
- (eventOptions.listener || pseudos[item.pseudo].listener).call(self, item, stackFn, arguments, monitor, options);
116
+ var listener = item.listener,
117
+ stackFn = stack;
118
+ if (listener == false) eventType += ':' + item.pseudo + '(' + item.value + ')';
119
+ else stack = function(){
120
+ listener.call(self, item, stackFn, arguments, stack);
128
121
  };
129
122
  });
130
- monitor = stack.bind(this);
131
123
 
132
- events.include({event: fn, monitor: monitor});
124
+ events.include({type: eventType, event: fn, monitor: stack});
133
125
  storage.store(type, events);
134
126
 
135
- addEvent.apply(this, [type, fn].concat(args));
136
- return addEvent.apply(this, [eventType, monitor].concat(args));
127
+ if (type != eventType) addEvent.apply(this, [type, fn].concat(args));
128
+ return addEvent.apply(this, [eventType, stack].concat(args));
137
129
  },
138
130
 
139
131
  removeEvent: function(type, fn){
@@ -144,18 +136,11 @@ Events.Pseudos = function(pseudos, addEvent, removeEvent){
144
136
  events = storage.retrieve(type);
145
137
  if (!events) return this;
146
138
 
147
- var eventType = split[0].event,
148
- options = mergePseudoOptions(split),
149
- eventOptions = options[eventType] || {},
150
- args = Array.slice(arguments, 2);
151
-
152
- if (eventOptions.args) args.append(Array.from(eventOptions.args));
153
- if (eventOptions.base) eventType = eventOptions.base;
154
- if (eventOptions.onRemove) eventOptions.onRemove(this);
139
+ var args = Array.slice(arguments, 2);
155
140
 
156
141
  removeEvent.apply(this, [type, fn].concat(args));
157
142
  events.each(function(monitor, i){
158
- if (!fn || monitor.event == fn) removeEvent.apply(this, [eventType, monitor.monitor].concat(args));
143
+ if (!fn || monitor.event == fn) removeEvent.apply(this, [monitor.type, monitor.monitor].concat(args));
159
144
  delete events[i];
160
145
  }, this);
161
146
 
@@ -167,40 +152,32 @@ Events.Pseudos = function(pseudos, addEvent, removeEvent){
167
152
 
168
153
  };
169
154
 
170
- (function(){
171
-
172
155
  var pseudos = {
173
156
 
174
- once: {
175
- listener: function(split, fn, args, monitor){
176
- fn.apply(this, args);
177
- this.removeEvent(split.event, monitor)
178
- .removeEvent(split.original, fn);
179
- }
157
+ once: function(split, fn, args, monitor){
158
+ fn.apply(this, args);
159
+ this.removeEvent(split.event, monitor)
160
+ .removeEvent(split.original, fn);
180
161
  },
181
162
 
182
- throttle: {
183
- listener: function(split, fn, args){
184
- if (!fn._throttled){
185
- fn.apply(this, args);
186
- fn._throttled = setTimeout(function(){
187
- fn._throttled = false;
188
- }, split.value || 250);
189
- }
163
+ throttle: function(split, fn, args){
164
+ if (!fn._throttled){
165
+ fn.apply(this, args);
166
+ fn._throttled = setTimeout(function(){
167
+ fn._throttled = false;
168
+ }, split.value || 250);
190
169
  }
191
170
  },
192
171
 
193
- pause: {
194
- listener: function(split, fn, args){
195
- clearTimeout(fn._pause);
196
- fn._pause = fn.delay(split.value || 250, this, args);
197
- }
172
+ pause: function(split, fn, args){
173
+ clearTimeout(fn._pause);
174
+ fn._pause = fn.delay(split.value || 250, this, args);
198
175
  }
199
176
 
200
177
  };
201
178
 
202
179
  Events.definePseudo = function(key, listener){
203
- pseudos[key] = Type.isFunction(listener) ? {listener: listener} : listener;
180
+ pseudos[key] = listener;
204
181
  return this;
205
182
  };
206
183
 
@@ -1001,19 +978,19 @@ Date.implement({
1001
978
  },
1002
979
 
1003
980
  isValid: function(date){
1004
- return !isNaN((date || this).valueOf());
981
+ if (!date) date = this;
982
+ return typeOf(date) == 'date' && !isNaN(date.valueOf());
1005
983
  },
1006
984
 
1007
- format: function(f){
985
+ format: function(format){
1008
986
  if (!this.isValid()) return 'invalid date';
1009
- if (!f) f = '%x %X';
1010
987
 
1011
- var formatLower = f.toLowerCase();
1012
- if (formatters[formatLower]) return formatters[formatLower](this); // it's a formatter!
1013
- f = formats[formatLower] || f; // replace short-hand with actual format
988
+ if (!format) format = '%x %X';
989
+ if (typeof format == 'string') format = formats[format.toLowerCase()] || format;
990
+ if (typeof format == 'function') return format(this);
1014
991
 
1015
992
  var d = this;
1016
- return f.replace(/%([a-z%])/gi,
993
+ return format.replace(/%([a-z%])/gi,
1017
994
  function($0, $1){
1018
995
  switch ($1){
1019
996
  case 'a': return Date.getMsg('days_abbr')[d.get('day')];
@@ -1060,18 +1037,15 @@ Date.implement({
1060
1037
  strftime: 'format'
1061
1038
  });
1062
1039
 
1063
- var formats = {
1064
- db: '%Y-%m-%d %H:%M:%S',
1065
- compact: '%Y%m%dT%H%M%S',
1066
- 'short': '%d %b %H:%M',
1067
- 'long': '%B %d, %Y %H:%M'
1068
- };
1069
-
1070
1040
  // The day and month abbreviations are standardized, so we cannot use simply %a and %b because they will get localized
1071
1041
  var rfcDayAbbr = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'],
1072
1042
  rfcMonthAbbr = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
1073
1043
 
1074
- var formatters = {
1044
+ var formats = {
1045
+ db: '%Y-%m-%d %H:%M:%S',
1046
+ compact: '%Y%m%dT%H%M%S',
1047
+ 'short': '%d %b %H:%M',
1048
+ 'long': '%B %d, %Y %H:%M',
1075
1049
  rfc822: function(date){
1076
1050
  return rfcDayAbbr[date.get('day')] + date.format(', %d ') + rfcMonthAbbr[date.get('month')] + date.format(' %Y %H:%M:%S %Z');
1077
1051
  },
@@ -1091,7 +1065,6 @@ var formatters = {
1091
1065
  }
1092
1066
  };
1093
1067
 
1094
-
1095
1068
  var parsePatterns = [],
1096
1069
  nativeParse = Date.parse;
1097
1070
 
@@ -1203,11 +1176,6 @@ Date.extend({
1203
1176
  return this;
1204
1177
  },
1205
1178
 
1206
- defineFormats: function(formats){
1207
- for (var name in formats) Date.defineFormat(name, formats[name]);
1208
- return this;
1209
- },
1210
-
1211
1179
 
1212
1180
 
1213
1181
  defineParser: function(pattern){
@@ -1226,6 +1194,8 @@ Date.extend({
1226
1194
  return this;
1227
1195
  }
1228
1196
 
1197
+ }).extend({
1198
+ defineFormats: Date.defineFormat.overloadSetter()
1229
1199
  });
1230
1200
 
1231
1201
  var regexOf = function(type){
@@ -1621,18 +1591,20 @@ Number.implement({
1621
1591
  return value;
1622
1592
  },
1623
1593
 
1624
- formatCurrency: function(){
1594
+ formatCurrency: function(decimals){
1625
1595
  var locale = Locale.get('Number.currency') || {};
1626
1596
  if (locale.scientific == null) locale.scientific = false;
1627
- if (locale.decimals == null) locale.decimals = 2;
1597
+ locale.decimals = decimals != null ? decimals
1598
+ : (locale.decimals == null ? 2 : locale.decimals);
1628
1599
 
1629
1600
  return this.format(locale);
1630
1601
  },
1631
1602
 
1632
- formatPercentage: function(){
1603
+ formatPercentage: function(decimals){
1633
1604
  var locale = Locale.get('Number.percentage') || {};
1634
1605
  if (locale.suffix == null) locale.suffix = '%';
1635
- if (locale.decimals == null) locale.decimals = 2;
1606
+ locale.decimals = decimals != null ? decimals
1607
+ : (locale.decimals == null ? 2 : locale.decimals);
1636
1608
 
1637
1609
  return this.format(locale);
1638
1610
  }
@@ -2473,23 +2445,23 @@ license: MIT-style license
2473
2445
  authors:
2474
2446
  - Arian Stolwijk
2475
2447
 
2476
- requires: [Core/Element.Event, Events.Pseudos]
2448
+ requires: [Core/Element.Event, Core/Element.Delegation, Events.Pseudos]
2477
2449
 
2478
- provides: [Element.Event.Pseudos]
2450
+ provides: [Element.Event.Pseudos, Element.Delegation]
2479
2451
 
2480
2452
  ...
2481
2453
  */
2482
2454
 
2483
2455
  (function(){
2484
2456
 
2485
- var pseudos = {},
2457
+ var pseudos = {relay: false},
2486
2458
  copyFromEvents = ['once', 'throttle', 'pause'],
2487
2459
  count = copyFromEvents.length;
2488
2460
 
2489
2461
  while (count--) pseudos[copyFromEvents[count]] = Events.lookupPseudo(copyFromEvents[count]);
2490
2462
 
2491
- Event.definePseudo = function(key, listener){
2492
- pseudos[key] = Type.isFunction(listener) ? {listener: listener} : listener;
2463
+ DOMEvent.definePseudo = function(key, listener){
2464
+ pseudos[key] = listener;
2493
2465
  return this;
2494
2466
  };
2495
2467
 
@@ -2524,7 +2496,7 @@ var keysStoreKey = '$moo:keys-pressed',
2524
2496
  keysKeyupStoreKey = '$moo:keys-keyup';
2525
2497
 
2526
2498
 
2527
- Event.definePseudo('keys', function(split, fn, args){
2499
+ DOMEvent.definePseudo('keys', function(split, fn, args){
2528
2500
 
2529
2501
  var event = args[0],
2530
2502
  keys = [],
@@ -2555,172 +2527,29 @@ Event.definePseudo('keys', function(split, fn, args){
2555
2527
 
2556
2528
  });
2557
2529
 
2558
- Object.append(Event.Keys, {
2559
- 'shift': 16,
2560
- 'control': 17,
2561
- 'alt': 18,
2562
- 'capslock': 20,
2563
- 'pageup': 33,
2564
- 'pagedown': 34,
2565
- 'end': 35,
2566
- 'home': 36,
2567
- 'numlock': 144,
2568
- 'scrolllock': 145,
2569
- ';': 186,
2570
- '=': 187,
2571
- ',': 188,
2572
- '-': Browser.firefox ? 109 : 189,
2573
- '.': 190,
2574
- '/': 191,
2575
- '`': 192,
2576
- '[': 219,
2577
- '\\': 220,
2578
- ']': 221,
2579
- "'": 222,
2580
- '+': 107
2581
- });
2582
-
2583
- })();
2584
-
2585
-
2586
- /*
2587
- ---
2588
-
2589
- script: Element.Delegation.js
2590
-
2591
- name: Element.Delegation
2592
-
2593
- description: Extends the Element native object to include the delegate method for more efficient event management.
2594
-
2595
- credits:
2596
- - "Event checking based on the work of Daniel Steigerwald. License: MIT-style license. Copyright: Copyright (c) 2008 Daniel Steigerwald, daniel.steigerwald.cz"
2597
-
2598
- license: MIT-style license
2599
-
2600
- authors:
2601
- - Aaron Newton
2602
- - Daniel Steigerwald
2603
-
2604
- requires: [/MooTools.More, Element.Event.Pseudos]
2605
-
2606
- provides: [Element.Delegation]
2607
-
2608
- ...
2609
- */
2610
-
2611
- (function(){
2612
-
2613
- var eventListenerSupport = !(window.attachEvent && !window.addEventListener),
2614
- nativeEvents = Element.NativeEvents;
2615
-
2616
- nativeEvents.focusin = 2;
2617
- nativeEvents.focusout = 2;
2618
-
2619
- var check = function(split, target, event){
2620
- var elementEvent = Element.Events[split.event], condition;
2621
- if (elementEvent) condition = elementEvent.condition;
2622
- return Slick.match(target, split.value) && (!condition || condition.call(target, event));
2623
- };
2624
-
2625
- var bubbleUp = function(split, event, fn){
2626
- for (var target = event.target; target && target != this; target = document.id(target.parentNode)){
2627
- if (target && check(split, target, event)) return fn.call(target, event, target);
2628
- }
2629
- };
2630
-
2631
- var formObserver = function(eventName){
2632
-
2633
- var $delegationKey = '$delegation:';
2634
-
2635
- return {
2636
- base: 'focusin',
2637
-
2638
- onRemove: function(element){
2639
- element.retrieve($delegationKey + 'forms', []).each(function(el){
2640
- el.retrieve($delegationKey + 'listeners', []).each(function(listener){
2641
- el.removeEvent(eventName, listener);
2642
- });
2643
- el.eliminate($delegationKey + eventName + 'listeners')
2644
- .eliminate($delegationKey + eventName + 'originalFn');
2645
- });
2646
- },
2647
-
2648
- listener: function(split, fn, args, monitor, options){
2649
- var event = args[0],
2650
- forms = this.retrieve($delegationKey + 'forms', []),
2651
- target = event.target,
2652
- form = (target.get('tag') == 'form') ? target : event.target.getParent('form');
2653
-
2654
- if (!form) return;
2655
-
2656
- var formEvents = form.retrieve($delegationKey + 'originalFn', []),
2657
- formListeners = form.retrieve($delegationKey + 'listeners', []),
2658
- self = this;
2659
-
2660
- forms.include(form);
2661
- this.store($delegationKey + 'forms', forms);
2662
-
2663
- if (!formEvents.contains(fn)){
2664
- var formListener = function(event){
2665
- bubbleUp.call(self, split, event, fn);
2666
- };
2667
- form.addEvent(eventName, formListener);
2668
-
2669
- formEvents.push(fn);
2670
- formListeners.push(formListener);
2671
-
2672
- form.store($delegationKey + eventName + 'originalFn', formEvents)
2673
- .store($delegationKey + eventName + 'listeners', formListeners);
2674
- }
2675
- }
2676
- };
2677
- };
2678
-
2679
- var inputObserver = function(eventName){
2680
- return {
2681
- base: 'focusin',
2682
- listener: function(split, fn, args){
2683
- var events = {blur: function(){
2684
- this.removeEvents(events);
2685
- }}, self = this;
2686
- events[eventName] = function(event){
2687
- bubbleUp.call(self, split, event, fn);
2688
- };
2689
- args[0].target.addEvents(events);
2690
- }
2691
- };
2692
- };
2693
-
2694
- var eventOptions = {
2695
- mouseenter: {
2696
- base: 'mouseover'
2697
- },
2698
- mouseleave: {
2699
- base: 'mouseout'
2700
- },
2701
- focus: {
2702
- base: 'focus' + (eventListenerSupport ? '' : 'in'),
2703
- args: [true]
2704
- },
2705
- blur: {
2706
- base: eventListenerSupport ? 'blur' : 'focusout',
2707
- args: [true]
2708
- }
2709
- };
2710
-
2711
- if (!eventListenerSupport) Object.append(eventOptions, {
2712
- submit: formObserver('submit'),
2713
- reset: formObserver('reset'),
2714
- change: inputObserver('change'),
2715
- select: inputObserver('select')
2716
- });
2717
-
2718
- Event.definePseudo('relay', {
2719
- listener: function(split, fn, args){
2720
- bubbleUp.call(this, split, args[0], fn);
2721
- },
2722
- options: eventOptions
2723
- });
2530
+ DOMEvent.defineKeys({
2531
+ '16': 'shift',
2532
+ '17': 'control',
2533
+ '18': 'alt',
2534
+ '20': 'capslock',
2535
+ '33': 'pageup',
2536
+ '34': 'pagedown',
2537
+ '35': 'end',
2538
+ '36': 'home',
2539
+ '144': 'numlock',
2540
+ '145': 'scrolllock',
2541
+ '186': ';',
2542
+ '187': '=',
2543
+ '188': ',',
2544
+ '190': '.',
2545
+ '191': '/',
2546
+ '192': '`',
2547
+ '219': '[',
2548
+ '220': '\\',
2549
+ '221': ']',
2550
+ '222': "'",
2551
+ '107': '+'
2552
+ }).defineKey(Browser.firefox ? 109 : 189, '-');
2724
2553
 
2725
2554
  })();
2726
2555
 
@@ -3245,7 +3074,7 @@ var local = Element.Position = {
3245
3074
  Element.implement({
3246
3075
 
3247
3076
  position: function(options){
3248
- if (options && (options.x != null || options.y != null)) {
3077
+ if (options && (options.x != null || options.y != null)){
3249
3078
  return (original ? original.apply(this, arguments) : this);
3250
3079
  }
3251
3080
  var position = this.setStyle('position', 'absolute').calculatePosition(options);
@@ -4094,7 +3923,7 @@ if (!window.Form) window.Form = {};
4094
3923
 
4095
3924
  Element.implement('formUpdate', function(update, options){
4096
3925
  var fq = this.retrieve('form.request');
4097
- if (!fq) {
3926
+ if (!fq){
4098
3927
  fq = new Form.Request(this, update, options);
4099
3928
  } else {
4100
3929
  if (update) fq.setTarget(update);
@@ -4457,6 +4286,7 @@ provides: [Locale.en-US.Form.Validator]
4457
4286
  Locale.define('en-US', 'FormValidator', {
4458
4287
 
4459
4288
  required: 'This field is required.',
4289
+ length: 'Please enter {length} characters (you entered {elLength} characters)',
4460
4290
  minLength: 'Please enter at least {minLength} characters (you entered {length} characters).',
4461
4291
  maxLength: 'Please enter no more than {maxLength} characters (you entered {length} characters).',
4462
4292
  integer: 'Please enter an integer in this field. Numbers with decimals (e.g. 1.25) are not permitted.',
@@ -4846,10 +4676,22 @@ Form.Validator.addAllThese([
4846
4676
  }
4847
4677
  }],
4848
4678
 
4679
+ ['length', {
4680
+ errorMsg: function(element, props){
4681
+ if (typeOf(props.length) != 'null')
4682
+ return Form.Validator.getMsg('length').substitute({length: props.length, elLength: element.get('value').length});
4683
+ else return '';
4684
+ },
4685
+ test: function(element, props){
4686
+ if (typeOf(props.length) != 'null') return (element.get('value').length == props.length || element.get('value').length == 0);
4687
+ else return true;
4688
+ }
4689
+ }],
4690
+
4849
4691
  ['minLength', {
4850
4692
  errorMsg: function(element, props){
4851
4693
  if (typeOf(props.minLength) != 'null')
4852
- return Form.Validator.getMsg('minLength').substitute({minLength:props.minLength,length:element.get('value').length });
4694
+ return Form.Validator.getMsg('minLength').substitute({minLength: props.minLength, length: element.get('value').length});
4853
4695
  else return '';
4854
4696
  },
4855
4697
  test: function(element, props){
@@ -4862,7 +4704,7 @@ Form.Validator.addAllThese([
4862
4704
  errorMsg: function(element, props){
4863
4705
  //props is {maxLength:10}
4864
4706
  if (typeOf(props.maxLength) != 'null')
4865
- return Form.Validator.getMsg('maxLength').substitute({maxLength:props.maxLength,length:element.get('value').length });
4707
+ return Form.Validator.getMsg('maxLength').substitute({maxLength: props.maxLength, length: element.get('value').length});
4866
4708
  else return '';
4867
4709
  },
4868
4710
  test: function(element, props){
@@ -5573,7 +5415,6 @@ var OverText = new Class({
5573
5415
  change: this.assert
5574
5416
  });
5575
5417
  window.addEvent('resize', this.reposition);
5576
- this.assert(true);
5577
5418
  this.reposition();
5578
5419
  return this;
5579
5420
  },
@@ -7456,12 +7297,12 @@ var Sortables = new Class({
7456
7297
  if (
7457
7298
  !this.idle ||
7458
7299
  event.rightClick ||
7459
- ['button', 'input', 'a'].contains(event.target.get('tag'))
7300
+ ['button', 'input', 'a', 'textarea'].contains(event.target.get('tag'))
7460
7301
  ) return;
7461
7302
 
7462
7303
  this.idle = false;
7463
7304
  this.element = element;
7464
- this.opacity = element.get('opacity');
7305
+ this.opacity = element.getStyle('opacity');
7465
7306
  this.list = element.getParent();
7466
7307
  this.clone = this.getClone(event, element);
7467
7308
 
@@ -7472,7 +7313,7 @@ var Sortables = new Class({
7472
7313
  onSnap: function(){
7473
7314
  event.stop();
7474
7315
  this.clone.setStyle('visibility', 'visible');
7475
- this.element.set('opacity', this.options.opacity || 0);
7316
+ this.element.setStyle('opacity', this.options.opacity || 0);
7476
7317
  this.fireEvent('start', [this.element, this.clone]);
7477
7318
  }.bind(this),
7478
7319
  onEnter: this.insert.bind(this),
@@ -7486,7 +7327,7 @@ var Sortables = new Class({
7486
7327
 
7487
7328
  end: function(){
7488
7329
  this.drag.detach();
7489
- this.element.set('opacity', this.opacity);
7330
+ this.element.setStyle('opacity', this.opacity);
7490
7331
  if (this.effect){
7491
7332
  var dim = this.element.getStyles('width', 'height'),
7492
7333
  clone = this.clone,
@@ -7978,23 +7819,23 @@ var Asset = {
7978
7819
 
7979
7820
  var script = new Element('script', {src: source, type: 'text/javascript'}),
7980
7821
  doc = properties.document || document,
7981
- loaded = 0,
7982
- loadEvent = properties.onload || properties.onLoad;
7983
-
7984
- var load = loadEvent ? function(){ // make sure we only call the event once
7985
- if (++loaded == 1) loadEvent.call(this);
7986
- } : function(){};
7822
+ load = properties.onload || properties.onLoad;
7987
7823
 
7988
7824
  delete properties.onload;
7989
7825
  delete properties.onLoad;
7990
7826
  delete properties.document;
7991
7827
 
7992
- return script.addEvents({
7993
- load: load,
7994
- readystatechange: function(){
7995
- if (['loaded', 'complete'].contains(this.readyState)) load.call(this);
7828
+ if (load){
7829
+ if (typeof script.onreadystatechange != 'undefined'){
7830
+ script.addEvent('readystatechange', function(){
7831
+ if (['loaded', 'complete'].contains(this.readyState)) load.call(this);
7832
+ });
7833
+ } else {
7834
+ script.addEvent('load', load);
7996
7835
  }
7997
- }).set(properties).inject(doc.head);
7836
+ }
7837
+
7838
+ return script.set(properties).inject(doc.head);
7998
7839
  },
7999
7840
 
8000
7841
  css: function(source, properties){
@@ -8274,31 +8115,26 @@ this.Group = new Class({
8274
8115
 
8275
8116
  initialize: function(){
8276
8117
  this.instances = Array.flatten(arguments);
8277
- this.events = {};
8278
- this.checker = {};
8279
8118
  },
8280
8119
 
8281
8120
  addEvent: function(type, fn){
8282
- this.checker[type] = this.checker[type] || {};
8283
- this.events[type] = this.events[type] || [];
8284
- if (this.events[type].contains(fn)) return false;
8285
- else this.events[type].push(fn);
8286
- this.instances.each(function(instance, i){
8287
- instance.addEvent(type, this.check.pass([type, instance, i], this));
8288
- }, this);
8289
- return this;
8290
- },
8291
-
8292
- check: function(type, instance, i){
8293
- this.checker[type][i] = true;
8294
- var every = this.instances.every(function(current, j){
8295
- return this.checker[type][j] || false;
8296
- }, this);
8297
- if (!every) return;
8298
- this.checker[type] = {};
8299
- this.events[type].each(function(event){
8300
- event.call(this, this.instances, instance);
8301
- }, this);
8121
+ var instances = this.instances,
8122
+ len = instances.length,
8123
+ togo = len,
8124
+ args = new Array(len),
8125
+ self = this;
8126
+
8127
+ instances.each(function(instance, i){
8128
+ instance.addEvent(type, function(){
8129
+ if (!args[i]) togo--;
8130
+ args[i] = arguments;
8131
+ if (!togo){
8132
+ fn.call(self, instances, instance, args);
8133
+ togo = len;
8134
+ args = new Array(len);
8135
+ }
8136
+ });
8137
+ });
8302
8138
  }
8303
8139
 
8304
8140
  });
@@ -8306,7 +8142,6 @@ this.Group = new Class({
8306
8142
  })();
8307
8143
 
8308
8144
 
8309
-
8310
8145
  /*
8311
8146
  ---
8312
8147
 
@@ -8536,30 +8371,43 @@ var HtmlTable = new Class({
8536
8371
  return this;
8537
8372
  },
8538
8373
 
8539
- push: function(row, rowProperties, target, tag, where){
8540
- if (typeOf(row) == 'element' && row.get('tag') == 'tr'){
8541
- row.inject(target || this.body, where);
8542
- return {
8543
- tr: row,
8544
- tds: row.getChildren('td')
8545
- };
8546
- }
8374
+ update: function(tr, row, tag){
8375
+ var tds = tr.getChildren(tag || 'td'), last = tds.length - 1;
8547
8376
 
8548
- var tds = row.map(function(data){
8549
- var td = new Element(tag || 'td', data ? data.properties : {}),
8377
+ row.each(function(data, index){
8378
+ var td = tds[index] || new Element(tag || 'td').inject(tr),
8550
8379
  content = (data ? data.content : '') || data,
8551
8380
  type = typeOf(content);
8552
8381
 
8553
- if (['element', 'array', 'collection', 'elements'].contains(type)) td.adopt(content);
8382
+ if (data && data.properties) td.set(data.properties);
8383
+ if (/(element(s?)|array|collection)/.test(type)) td.empty().adopt(content);
8554
8384
  else td.set('html', content);
8555
8385
 
8556
- return td;
8386
+ if (index > last) tds.push(td);
8387
+ else tds[index] = td;
8557
8388
  });
8558
8389
 
8559
8390
  return {
8560
- tr: new Element('tr', rowProperties).inject(target || this.body, where).adopt(tds),
8391
+ tr: tr,
8561
8392
  tds: tds
8562
8393
  };
8394
+ },
8395
+
8396
+ push: function(row, rowProperties, target, tag, where){
8397
+ if (typeOf(row) == 'element' && row.get('tag') == 'tr'){
8398
+ row.inject(target || this.body, where);
8399
+ return {
8400
+ tr: row,
8401
+ tds: row.getChildren('td')
8402
+ };
8403
+ }
8404
+ return this.update(new Element('tr', rowProperties).inject(target || this.body, where), row, tag);
8405
+ },
8406
+
8407
+ pushMany: function(rows, rowProperties, target, tag, where){
8408
+ return rows.map(function(row){
8409
+ return this.push(row, rowProperties, target, tag, where);
8410
+ }, this);
8563
8411
  }
8564
8412
 
8565
8413
  });
@@ -8592,6 +8440,7 @@ authors:
8592
8440
 
8593
8441
  requires:
8594
8442
  - /HtmlTable
8443
+ - /Element.Shortcuts
8595
8444
  - /Class.refactor
8596
8445
 
8597
8446
  provides: [HtmlTable.Zebra]
@@ -8603,7 +8452,8 @@ HtmlTable = Class.refactor(HtmlTable, {
8603
8452
 
8604
8453
  options: {
8605
8454
  classZebra: 'table-tr-odd',
8606
- zebra: true
8455
+ zebra: true,
8456
+ zebraOnlyVisibleRows: true
8607
8457
  },
8608
8458
 
8609
8459
  initialize: function(){
@@ -8613,7 +8463,12 @@ HtmlTable = Class.refactor(HtmlTable, {
8613
8463
  },
8614
8464
 
8615
8465
  updateZebras: function(){
8616
- Array.each(this.body.rows, this.zebra, this);
8466
+ var index = 0;
8467
+ Array.each(this.body.rows, function(row){
8468
+ if (!this.options.zebraOnlyVisibleRows || row.isDisplayed()){
8469
+ this.zebra(row, index++);
8470
+ }
8471
+ }, this);
8617
8472
  },
8618
8473
 
8619
8474
  setRowStyle: function(row, i){
@@ -8687,9 +8542,8 @@ HtmlTable = Class.refactor(HtmlTable, {
8687
8542
  this.previous.apply(this, arguments);
8688
8543
  if (this.occluded) return this.occluded;
8689
8544
  this.sorted = {index: null, dir: 1};
8690
- this.bound = {
8691
- headClick: this.headClick.bind(this)
8692
- };
8545
+ if (!this.bound) this.bound = {};
8546
+ this.bound.headClick = this.headClick.bind(this);
8693
8547
  this.sortSpans = new Elements();
8694
8548
  if (this.options.sortable){
8695
8549
  this.enableSort();
@@ -8757,17 +8611,17 @@ HtmlTable = Class.refactor(HtmlTable, {
8757
8611
  return this.sort(Array.indexOf(this.head.getElements(this.options.thSelector).flatten(), el) % this.body.rows[0].cells.length);
8758
8612
  },
8759
8613
 
8760
- serialize: function() {
8614
+ serialize: function(){
8761
8615
  var previousSerialization = this.previous.apply(this, arguments) || {};
8762
- if (this.options.sortable) {
8616
+ if (this.options.sortable){
8763
8617
  previousSerialization.sortIndex = this.sorted.index;
8764
8618
  previousSerialization.sortReverse = this.sorted.reverse;
8765
8619
  }
8766
8620
  return previousSerialization;
8767
8621
  },
8768
8622
 
8769
- restore: function(tableState) {
8770
- if(this.options.sortable && tableState.sortIndex) {
8623
+ restore: function(tableState){
8624
+ if(this.options.sortable && tableState.sortIndex){
8771
8625
  this.sort(tableState.sortIndex, tableState.sortReverse);
8772
8626
  }
8773
8627
  this.previous.apply(this, arguments);
@@ -9378,7 +9232,8 @@ HtmlTable = Class.refactor(HtmlTable, {
9378
9232
  classSelectable: 'table-selectable',
9379
9233
  shiftForMultiSelect: true,
9380
9234
  allowMultiSelect: true,
9381
- selectable: false
9235
+ selectable: false,
9236
+ selectHiddenRows: false
9382
9237
  },
9383
9238
 
9384
9239
  initialize: function(){
@@ -9387,13 +9242,12 @@ HtmlTable = Class.refactor(HtmlTable, {
9387
9242
 
9388
9243
  this.selectedRows = new Elements();
9389
9244
 
9390
- this.bound = {
9391
- mouseleave: this.mouseleave.bind(this),
9392
- clickRow: this.clickRow.bind(this),
9393
- activateKeyboard: function() {
9394
- if (this.keyboard && this.selectEnabled) this.keyboard.activate();
9395
- }.bind(this)
9396
- };
9245
+ if (!this.bound) this.bound = {};
9246
+ this.bound.mouseleave = this.mouseleave.bind(this);
9247
+ this.bound.clickRow = this.clickRow.bind(this);
9248
+ this.bound.activateKeyboard = function(){
9249
+ if (this.keyboard && this.selectEnabled) this.keyboard.activate();
9250
+ }.bind(this);
9397
9251
 
9398
9252
  if (this.options.selectable) this.enableSelect();
9399
9253
  },
@@ -9423,10 +9277,6 @@ HtmlTable = Class.refactor(HtmlTable, {
9423
9277
  return ret;
9424
9278
  },
9425
9279
 
9426
- isSelected: function(row){
9427
- return this.selectedRows.contains(row);
9428
- },
9429
-
9430
9280
  toggleRow: function(row){
9431
9281
  return this[(this.isSelected(row) ? 'de' : '') + 'selectRow'](row);
9432
9282
  },
@@ -9450,23 +9300,31 @@ HtmlTable = Class.refactor(HtmlTable, {
9450
9300
  return this;
9451
9301
  },
9452
9302
 
9303
+ isSelected: function(row){
9304
+ return this.selectedRows.contains(row);
9305
+ },
9306
+
9307
+ getSelected: function(){
9308
+ return this.selectedRows;
9309
+ },
9310
+
9453
9311
  getSelected: function(){
9454
9312
  return this.selectedRows;
9455
9313
  },
9456
9314
 
9457
- serialize: function() {
9315
+ serialize: function(){
9458
9316
  var previousSerialization = this.previous.apply(this, arguments) || {};
9459
- if (this.options.selectable) {
9460
- previousSerialization.selectedRows = this.selectedRows.map(function(row) {
9317
+ if (this.options.selectable){
9318
+ previousSerialization.selectedRows = this.selectedRows.map(function(row){
9461
9319
  return Array.indexOf(this.body.rows, row);
9462
9320
  }.bind(this));
9463
9321
  }
9464
9322
  return previousSerialization;
9465
9323
  },
9466
9324
 
9467
- restore: function(tableState) {
9468
- if(this.options.selectable && tableState.selectedRows) {
9469
- tableState.selectedRows.each(function(index) {
9325
+ restore: function(tableState){
9326
+ if(this.options.selectable && tableState.selectedRows){
9327
+ tableState.selectedRows.each(function(index){
9470
9328
  this.selectRow(this.body.rows[index]);
9471
9329
  }.bind(this));
9472
9330
  }
@@ -9508,7 +9366,9 @@ HtmlTable = Class.refactor(HtmlTable, {
9508
9366
  endRow = tmp;
9509
9367
  }
9510
9368
 
9511
- for (var i = startRow; i <= endRow; i++) this[method](rows[i], true);
9369
+ for (var i = startRow; i <= endRow; i++){
9370
+ if (this.options.selectHiddenRows || rows[i].isDisplayed()) this[method](rows[i], true);
9371
+ }
9512
9372
 
9513
9373
  return this;
9514
9374
  },
@@ -9552,7 +9412,7 @@ HtmlTable = Class.refactor(HtmlTable, {
9552
9412
 
9553
9413
  shiftFocus: function(offset, event){
9554
9414
  if (!this.focused) return this.selectRow(this.body.rows[0], event);
9555
- var to = this.getRowByOffset(offset);
9415
+ var to = this.getRowByOffset(offset, this.options.selectHiddenRows);
9556
9416
  if (to === null || this.focused == this.body.rows[to]) return this;
9557
9417
  this.toggleRow(this.body.rows[to], event);
9558
9418
  },
@@ -9571,14 +9431,25 @@ HtmlTable = Class.refactor(HtmlTable, {
9571
9431
  this.rangeStart = row;
9572
9432
  },
9573
9433
 
9574
- getRowByOffset: function(offset){
9434
+ getRowByOffset: function(offset, includeHiddenRows){
9575
9435
  if (!this.focused) return 0;
9576
- var rows = Array.clone(this.body.rows),
9577
- index = rows.indexOf(this.focused) + offset;
9578
-
9579
- if (index < 0) index = null;
9580
- if (index >= rows.length) index = null;
9581
-
9436
+ var index = Array.indexOf(this.body.rows, this.focused);
9437
+ if ((index == 0 && offset < 0) || (index == this.body.rows.length -1 && offset > 0)) return null;
9438
+ if (includeHiddenRows){
9439
+ index += offset;
9440
+ } else {
9441
+ var limit = 0,
9442
+ count = 0;
9443
+ if (offset > 0){
9444
+ while (count < offset && index < this.body.rows.length -1){
9445
+ if (this.body.rows[++index].isDisplayed()) count++;
9446
+ }
9447
+ } else {
9448
+ while (count > offset && index > 0){
9449
+ if (this.body.rows[--index].isDisplayed()) count--;
9450
+ }
9451
+ }
9452
+ }
9582
9453
  return index;
9583
9454
  },
9584
9455
 
@@ -9598,7 +9469,7 @@ HtmlTable = Class.refactor(HtmlTable, {
9598
9469
 
9599
9470
  if (this.options.useKeyboard || this.keyboard){
9600
9471
  if (!this.keyboard) this.keyboard = new Keyboard();
9601
- if (!this.selectKeysDefined) {
9472
+ if (!this.selectKeysDefined){
9602
9473
  this.selectKeysDefined = true;
9603
9474
  var timer, held;
9604
9475
 
@@ -9606,8 +9477,7 @@ HtmlTable = Class.refactor(HtmlTable, {
9606
9477
  var mover = function(e){
9607
9478
  clearTimeout(timer);
9608
9479
  e.preventDefault();
9609
-
9610
- var to = this.body.rows[this.getRowByOffset(offset)];
9480
+ var to = this.body.rows[this.getRowByOffset(offset, this.options.selectHiddenRows)];
9611
9481
  if (e.shift && to && this.isSelected(to)){
9612
9482
  this.deselectRow(this.focused);
9613
9483
  this.focused = to;
@@ -9634,7 +9504,7 @@ HtmlTable = Class.refactor(HtmlTable, {
9634
9504
  clearTimeout(timer);
9635
9505
  held = false;
9636
9506
  };
9637
-
9507
+
9638
9508
  this.keyboard.addEvents({
9639
9509
  'keydown:shift+up': move(-1),
9640
9510
  'keydown:shift+down': move(1),
@@ -9823,6 +9693,7 @@ this.Tips = new Class({
9823
9693
  Implements: [Events, Options],
9824
9694
 
9825
9695
  options: {/*
9696
+ id: null,
9826
9697
  onAttach: function(element){},
9827
9698
  onDetach: function(element){},
9828
9699
  onBound: function(coords){},*/
@@ -9841,7 +9712,8 @@ this.Tips = new Class({
9841
9712
  className: 'tip-wrap',
9842
9713
  offset: {x: 16, y: 16},
9843
9714
  windowPadding: {x:0, y:0},
9844
- fixed: false
9715
+ fixed: false,
9716
+ waiAria: true
9845
9717
  },
9846
9718
 
9847
9719
  initialize: function(){
@@ -9854,6 +9726,11 @@ this.Tips = new Class({
9854
9726
  this.setOptions(params.options);
9855
9727
  if (params.elements) this.attach(params.elements);
9856
9728
  this.container = new Element('div', {'class': 'tip'});
9729
+
9730
+ if (this.options.id){
9731
+ this.container.set('id', this.options.id);
9732
+ if (this.options.waiAria) this.attachWaiAria();
9733
+ }
9857
9734
  },
9858
9735
 
9859
9736
  toElement: function(){
@@ -9875,6 +9752,33 @@ this.Tips = new Class({
9875
9752
  return this.tip;
9876
9753
  },
9877
9754
 
9755
+ attachWaiAria: function(){
9756
+ var id = this.options.id;
9757
+ this.container.set('role', 'tooltip');
9758
+
9759
+ if (!this.waiAria){
9760
+ this.waiAria = {
9761
+ show: function(element){
9762
+ if (id) element.set('aria-describedby', id);
9763
+ this.container.set('aria-hidden', 'false');
9764
+ },
9765
+ hide: function(element){
9766
+ if (id) element.erase('aria-describedby');
9767
+ this.container.set('aria-hidden', 'true');
9768
+ }
9769
+ };
9770
+ }
9771
+ this.addEvents(this.waiAria);
9772
+ },
9773
+
9774
+ detachWaiAria: function(){
9775
+ if (this.waiAria){
9776
+ this.container.erase('role');
9777
+ this.container.erase('aria-hidden');
9778
+ this.removeEvents(this.waiAria);
9779
+ }
9780
+ },
9781
+
9878
9782
  attach: function(elements){
9879
9783
  $$(elements).each(function(element){
9880
9784
  var title = read(this.options.title, element),
@@ -11525,6 +11429,7 @@ provides: [Locale.fr-FR.Form.Validator]
11525
11429
  Locale.define('fr-FR', 'FormValidator', {
11526
11430
 
11527
11431
  required: 'Ce champ est obligatoire.',
11432
+ length: 'Veuillez saisir {length} caract&egrave;re(s) (vous avez saisi {elLength} caract&egrave;re(s)',
11528
11433
  minLength: 'Veuillez saisir un minimum de {minLength} caract&egrave;re(s) (vous avez saisi {length} caract&egrave;re(s)).',
11529
11434
  maxLength: 'Veuillez saisir un maximum de {maxLength} caract&egrave;re(s) (vous avez saisi {length} caract&egrave;re(s)).',
11530
11435
  integer: 'Veuillez saisir un nombre entier dans ce champ. Les nombres d&eacute;cimaux (ex : "1,25") ne sont pas autoris&eacute;s.',
@@ -11918,6 +11823,12 @@ Locale.define('it-IT', 'Date', {
11918
11823
  hoursAgo: 'circa {delta} ore fa',
11919
11824
  dayAgo: 'circa 1 giorno fa',
11920
11825
  daysAgo: 'circa {delta} giorni fa',
11826
+ weekAgo: 'una settimana fa',
11827
+ weeksAgo: '{delta} settimane fa',
11828
+ monthAgo: 'un mese fa',
11829
+ monthsAgo: '{delta} mesi fa',
11830
+ yearAgo: 'un anno fa',
11831
+ yearsAgo: '{delta} anni fa',
11921
11832
 
11922
11833
  lessThanMinuteUntil: 'tra meno di un minuto',
11923
11834
  minuteUntil: 'tra circa un minuto',
@@ -11925,7 +11836,13 @@ Locale.define('it-IT', 'Date', {
11925
11836
  hourUntil: "tra circa un'ora",
11926
11837
  hoursUntil: 'tra circa {delta} ore',
11927
11838
  dayUntil: 'tra circa un giorno',
11928
- daysUntil: 'tra circa {delta} giorni'
11839
+ daysUntil: 'tra circa {delta} giorni',
11840
+ weekUntil: 'tra una settimana',
11841
+ weeksUntil: 'tra {delta} settimane',
11842
+ monthUntil: 'tra un mese',
11843
+ monthsUntil: 'tra {delta} mesi',
11844
+ yearUntil: 'tra un anno',
11845
+ yearsUntil: 'tra {delta} anni'
11929
11846
 
11930
11847
  });
11931
11848
 
@@ -12240,6 +12157,7 @@ provides: [Locale.nl-NL.Form.Validator]
12240
12157
  Locale.define('nl-NL', 'FormValidator', {
12241
12158
 
12242
12159
  required: 'Dit veld is verplicht.',
12160
+ length: 'Vul precies {length} karakters in (je hebt {elLength} karakters ingevoerd).',
12243
12161
  minLength: 'Vul minimaal {minLength} karakters in (je hebt {length} karakters ingevoerd).',
12244
12162
  maxLength: 'Vul niet meer dan {maxLength} karakters in (je hebt {length} karakters ingevoerd).',
12245
12163
  integer: 'Vul een getal in. Getallen met decimalen (bijvoorbeeld 1.25) zijn niet toegestaan.',