diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 00000000..d559f422
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,32 @@
+sudo: false
+cache: bundler
+language: ruby
+rvm:
+ - 1.9.3
+ - 2.0.0
+ - 2.1.10
+ - 2.2.9
+ - 2.3.6
+ - 2.4.10
+ - 2.5.8
+ - 2.6.6
+ - 2.7.1
+ - jruby
+ - ruby-head
+matrix:
+ fast_finish: true
+ allow_failures:
+ - rvm: jruby
+ - rvm: ruby-head
+notifications:
+ email: false
+ irc:
+ on_success: change
+ on_failure: always
+ channels:
+ - "irc.freenode.org#rails-contrib"
+ campfire:
+ on_success: change
+ on_failure: always
+ rooms:
+ - secure: "p58t43P+64c1g0Av88DNM9XxMnmXM/PzRFU4yeo53i7lDY77PqKOVY+swc8eibn6cMgfyw2vqI7UFri4WLxwdN5jN5QaByHtXT2STFaJV4ORyyOBqQLuJTFWzMn8+Zil3rW/0Xv6tHoeAjsToZyYFefyjM3qemAmUqI8jLqU1sM="
diff --git a/CHANGELOG.md b/CHANGELOG.md
index ec0da36c..c1fd4b2a 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,111 @@
+## 4.6.1
+
+- update jquery to 3.7.1
+
+## 4.6.0
+
+- update jquery to 3.7.0
+
+## 4.5.1
+
+- update jquery to 3.6.1
+- update jquery-ujs to 1.2.3
+
+## 4.5.0
+
+- update jquery to 3.6.0
+
+## 4.4.0
+
+- update jquery to 3.5.1 (note: [3.5.0 contains important security updates](https://github.com/advisories/GHSA-jpcq-cgw6-v4j6))
+- unescape dollar signs and backticks in `assert_select_jquery` to match
+ Rails updated behavior.
+
+## 4.3.5
+
+- update jquery to 3.4.1
+
+## 4.3.4
+
+- update jquery to 3.4.0
+
+## 4.3.3
+
+- update jquery to 3.3.1
+
+## 4.3.2
+
+- update jquery to 3.3.0
+- Add possibility to test HTML: all, attribute prefix, attribute contains,
+ attribute ends with, child, and class selectors
+- Fix matching multiple calls for the same selector/function exception
+
+## 4.3.1
+
+- update jquery to 3.2.1
+
+## 4.3.0
+
+- update jquery to 3.2.0
+- Add possibility to test HTML attribute selectors
+
+## 4.2.2
+
+- update jquery to 3.1.1
+
+## 4.2.1
+
+- update jquery to 3.1.0
+
+## 4.2.0
+
+- Support jQuery 3.x
+- Update jquery-ujs to 1.2.2
+- Update jQuery to 1.12.4 and 2.2.4
+
+## 4.1.1
+
+- Update jQuery to 1.12.1 and 2.2.1
+- Update jquery-ujs to 1.2.1
+
+## 4.1.0
+
+- Update jQuery to 1.12.0 and 2.2.0
+- Update jquery-ujs to 1.2.0
+
+## 4.0.5
+
+- Specify that Ruby version 1.9.3+ is required
+- Test on Ruby 2.2
+- Update jquery-ujs from 1.0.4 to 1.1.0
+
+## 4.0.4
+
+ - Fix CSP bypass vulnerability. CVE-2015-1840
+
+## 4.0.1
+
+ - Fix RubyGems permission problem.
+
+## 4.0.0
+
+ - Minimum dependency set to Rails 4.2
+ - Updated to jquery-ujs 1.0.2
+ - Support jQuery 1.x and 2.x
+
+## 3.1.3 (16 June 2015)
+
+ - Fix CSP bypass vulnerability. CVE-2015-1840
+
+## 3.1.2 (1 September 2014)
+
+ - Updated to jquery-ujs 1.0.1
+
+## 3.1.1 (23 June 2014)
+
+ - Updated to jQuery 1.11.1
+ - Updated to jquery-ujs 1.0.0
+
## 3.1.0 (29 January 2014)
- Updated to jQuery 1.11.0
@@ -7,7 +115,7 @@
## 3.0.4 (10 July 2013)
- Fixed jQuery source map
-
+
## 3.0.3 (10 July 2013)
- Updated to jQuery 1.10.2
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 0c3f40e4..b1e9ca12 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -1,17 +1,53 @@
-Thanks for taking the time to contribute to jquery-rails! Please
-take a moment to read the following brief guidelines to help streamline
-the merging process.
+Contributing to jquery-rails
+=====================
-## Updating jQuery
+[](https://travis-ci.org/rails/jquery-rails)
+
+jquery-rails is work of [many contributors](https://github.com/rails/jquery-rails/graphs/contributors). You're encouraged to submit [pull requests](https://github.com/rails/jquery-rails/pulls), [propose features and discuss issues](https://github.com/rails/jquery-rails/issues).
+
+#### Updating jQuery
If the jquery or jquery-ui scripts are outdated (i.e. maybe a new version of jquery was released yesterday), feel free to open an issue and prod us to get that thing updated. However, for security reasons, we won't be accepting pull requests with updated jquery or jquery-ui scripts.
-## Changes to jquery_ujs.js
+#### Changes to jquery_ujs.js
**If it's an issue pertaining to the jquery-ujs javascript, please
report it to the [rails/jquery-ujs project](https://github.com/rails/jquery-ujs/issues).**
-## Tests
+#### Fork the Project
+
+Fork the [project on Github](https://github.com/rails/jquery-rails) and check out your copy.
+
+```
+git clone https://github.com/contributor/jquery-rails.git
+cd jquery-rails
+git remote add upstream https://github.com/rails/jquery-rails.git
+```
+
+#### Create a Topic Branch
+
+Make sure your fork is up-to-date and create a topic branch for your feature or bug fix.
+
+```
+git checkout master
+git pull upstream master
+git checkout -b my-feature-branch
+```
+
+#### Bundle Install and Test
+
+Ensure that you can build the project and run tests.
+
+```
+bundle install
+bundle exec rake test
+```
+
+#### Write Tests
+
+Try to write a test that reproduces the problem you're trying to fix or describes a feature that you want to build. Add to [test](test).
+
+#### Testing
This is a gem that simply includes jQuery and jQuery UJS into the Rails
asset pipeline. The asset pipeline functionality is well tested within the
@@ -29,8 +65,68 @@ If you're making changes to the actual gem, run the tests as follows:
2. Install the gems: `bundle install`
3. Change the jquery-rails gem in the Gemfile to use your local
-version of the gem with your updates: `gem 'rspec-rails', :path => '../path/to/jquery-rails'`
+version of the gem with your updates: `gem 'jquery-rails', :path => '../path/to/jquery-rails'`
4. Update your bundled jquery-rails gem: `bundle update jquery-rails`
5. Run the tests: `bundle exec rspec spec/`
+
+We definitely appreciate pull requests that highlight or reproduce a problem, even without a fix.
+
+#### Write Code
+
+Implement your feature or bug fix.
+
+Make sure that `bundle exec rake test` completes without errors.
+
+#### Write Documentation
+
+Document any external behavior in the [README](README.md).
+
+#### Commit Changes
+
+Make sure git knows your name and email address:
+
+```
+git config --global user.name "Your Name"
+git config --global user.email "contributor@example.com"
+```
+
+Writing good commit logs is important. A commit log should describe what changed and why.
+
+```
+git add ...
+git commit
+```
+
+#### Push
+
+```
+git push origin my-feature-branch
+```
+
+#### Make a Pull Request
+
+Go to https://github.com/contributor/jquery-rails and select your feature branch. Click the 'Pull Request' button and fill out the form. Pull requests are usually reviewed within a few days.
+
+#### Rebase
+
+If you've been working on a change for a while, rebase with upstream/master.
+
+```
+git fetch upstream
+git rebase upstream/master
+git push origin my-feature-branch -f
+```
+
+#### Check on Your Pull Request
+
+Go back to your pull request after a few minutes and see whether it passed muster with Travis-CI. Everything should look green, otherwise fix issues and amend your commit as described above.
+
+#### Be Patient
+
+It's likely that your change will not be merged and that the nitpicky maintainers will ask you to do more, or fix seemingly benign problems. Hang on there!
+
+#### Thank You
+
+Please do know that we really appreciate and value your time and work. We love you, really.
diff --git a/Gemfile b/Gemfile
index a21b0de6..9aaa1739 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,4 +1,22 @@
source 'https://rubygems.org'
+gem "mime-types", "< 3", group: :test
+
+if RUBY_VERSION >= '2.2.2'
+ gem 'rails'
+ gem 'rack'
+ gem 'json', '>= 2'
+else
+ gem 'rails', '~> 4.2.0'
+ gem 'rack', '~>1.6'
+ gem 'json', '~> 1.8.0'
+end
+
+if RUBY_VERSION >= '2.1'
+ gem 'nokogiri'
+else
+ gem 'nokogiri', '~> 1.6.0'
+end
+
# Specify your gem's dependencies in jquery-rails.gemspec
gemspec
diff --git a/LICENSE b/MIT-LICENSE
similarity index 95%
rename from LICENSE
rename to MIT-LICENSE
index d4c1838a..4412bd7b 100644
--- a/LICENSE
+++ b/MIT-LICENSE
@@ -1,6 +1,6 @@
The MIT License
-Copyright (c) 2010 Andre Arko
+Copyright (c) 2010-2016 Andre Arko
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
-THE SOFTWARE.
\ No newline at end of file
+THE SOFTWARE.
diff --git a/README.md b/README.md
index 57f16370..ca076e0a 100644
--- a/README.md
+++ b/README.md
@@ -4,19 +4,19 @@ jQuery! For Rails! So great.
This gem provides:
- * jQuery 1.11.0
+ * jQuery 1, 2 and 3
* the jQuery UJS adapter
* assert_select_jquery to test jQuery responses in Ruby tests
## Versions
Starting with v2.1, the jquery-rails gem follows these version guidelines
-to provide more control over your app's jquery version from your Gemfile:
+to provide more control over your app's jQuery version from your Gemfile:
```
-patch version bump = updates to jquery-ujs, jquery-rails, and patch-level updates to jquery
-minor version bump = minor-level updates to jquery
-major version bump = major-level updates to jquery and updates to rails which may be backwards-incompatible
+patch version bump = updates to jquery-ujs, jquery-rails, and patch-level updates to jQuery
+minor version bump = minor-level updates to jQuery
+major version bump = major-level updates to jQuery and updates to Rails which may be backwards-incompatible
```
See [VERSIONS.md](VERSIONS.md) to see which versions of jquery-rails bundle which
@@ -24,23 +24,11 @@ versions of jQuery.
## Installation
-Apps generated with Rails 3.1 or later include jquery-rails in the Gemfile by default. So just make a new app:
-
-```sh
-rails new myapp
+Add
```
-
-If upgrading from an older version of rails, or for rails 3.0 apps,
-add the jquery-rails gem to your Gemfile.
-
-```ruby
-gem "jquery-rails"
+gem 'jquery-rails'
```
-
-And run `bundle install`. The rest of the installation depends on
-whether the asset pipeline is being used.
-
-### Rails 3.1 or greater (with asset pipeline *enabled*)
+to your Gemfile.
The jquery and jquery-ujs files will be added to the asset pipeline and available for you to use. If they're not already in `app/assets/javascripts/application.js` by default, add these lines:
@@ -49,38 +37,45 @@ The jquery and jquery-ujs files will be added to the asset pipeline and availabl
//= require jquery_ujs
```
-For jQuery UI, we recommend the [jquery-ui-rails](https://github.com/joliss/jquery-ui-rails) gem, as it includes the jquery-ui css and allows easier customization.
-
-*As of v3.0, jquery-rails no longer includes jQuery UI. Use the
-jquery-ui-rails gem above.*
+If you are running Rails 5.1 and up, and if you have included `//= require rails-ujs`, then `jquery_ujs` is not needed anymore. You can just add:
-### Rails 3.0 (or greater with asset pipeline *disabled*)
+```js
+//= require jquery
+```
-This gem adds a single generator: `jquery:install`. Running the generator will remove any Prototype JS files you may happen to have, and copy jQuery and the jQuery-ujs driver for Rails to the `public/javascripts` directory.
+If you want to use jQuery 2, you can require `jquery2` instead:
-This gem will also hook into the Rails configuration process, removing Prototype and adding jQuery to the javascript files included by the `javascript_include_tag(:defaults)` call. While this gem contains the minified and un-minified versions of jQuery, only the minified versions will be included in the `:defaults` when Rails is run in `production` or `test` mode (un-minified versions will be included when Rails is run in `development` mode).
+```js
+//= require jquery2
+//= require jquery_ujs
+```
-To invoke the generator, run:
+And if you want to use jQuery 3, you can require `jquery3`:
-```sh
-rails generate jquery:install
+```js
+//= require jquery3
+//= require jquery_ujs
```
-You're done!
+For jQuery UI, we recommend the [jquery-ui-rails](https://github.com/joliss/jquery-ui-rails) gem, as it includes the jquery-ui css and allows easier customization.
-*As of v3.0, jquery-rails no longer includes jQuery UI, you will need to
-install it by yourself as needed.*
+*As of v3.0, jquery-rails no longer includes jQuery UI. Use the
+jquery-ui-rails gem above.*
-## Contributing
+## Contributing to jquery-rails
-Feel free to open an issue ticket if you find something that could be improved. A couple notes:
+jquery-rails is work of many contributors. You're encouraged to submit pull requests, propose
+features and discuss issues.
* If it's an issue pertaining to the jquery-ujs javascript, please report it to the [jquery-ujs project](https://github.com/rails/jquery-ujs).
-* If the jquery scripts are outdated (i.e. maybe a new version of jquery was released yesterday), feel free to open an issue and prod us to get that thing updated. However, for security reasons, we won't be accepting pull requests with updated jquery scripts.
+* If the jQuery scripts are outdated (i.e. maybe a new version of jquery was released yesterday), feel free to open an issue and prod us to get that thing updated. However, for security reasons, we won't be accepting pull requests with updated jQuery scripts.
-## Acknowledgements
+See [CONTRIBUTING](CONTRIBUTING.md).
-Many thanks are due to all of [the jquery-rails contributors](https://github.com/rails/jquery-rails/graphs/contributors). Special thanks to [JangoSteve](http://github.com/JangoSteve) for tirelessly answering questions and accepting patches, and the [Rails Core Team](https://github.com/organizations/rails/teams/617) for making jquery-rails an official part of Rails 3.1.
+## License
+jquery-rails is released under the [MIT License](MIT-LICENSE).
+
+## Acknowledgements
-Copyright [André Arko](http://arko.net), released under the MIT License.
+Many thanks are due to all of [the jquery-rails contributors](https://github.com/rails/jquery-rails/graphs/contributors). Special thanks to [JangoSteve](http://github.com/JangoSteve) for tirelessly answering questions and accepting patches, and the [Rails Core Team](https://github.com/orgs/rails/people) for making jquery-rails an official part of Rails 3.1.
diff --git a/Rakefile b/Rakefile
index 7b17de96..69df601b 100644
--- a/Rakefile
+++ b/Rakefile
@@ -1,6 +1,16 @@
require 'bundler'
+require 'rake/testtask'
Bundler::GemHelper.install_tasks
+task default: :test
+
+Rake::TestTask.new(:test) do |t|
+ t.libs << 'lib'
+ t.pattern = 'test/**/*_test.rb'
+ t.warning = true
+ t.verbose = true
+end
+
# Check if versions are correct between VERSION constants and .js files
#
task :release => [:guard_version]
@@ -9,7 +19,7 @@ task :guard_version do
def check_version(file, pattern, constant)
body = File.read("vendor/assets/javascripts/#{file}")
match = body.match(pattern) or abort "Version check failed: no pattern matched in #{file}"
- file_version = body.match(pattern)[1]
+ file_version = match[1]
constant_version = Jquery::Rails.const_get(constant)
unless constant_version == file_version
@@ -18,31 +28,32 @@ task :guard_version do
end
check_version('jquery.js', /jQuery JavaScript Library v([\S]+)/, 'JQUERY_VERSION')
+ check_version('jquery2.js', /jQuery JavaScript Library v([\S]+)/, 'JQUERY_2_VERSION')
+ check_version('jquery3.js', /jQuery JavaScript Library v([\S]+)/, 'JQUERY_3_VERSION')
end
+desc "Update jQuery versions"
task :update_jquery do
- puts "Downloading jquery.js"
- puts `curl -o vendor/assets/javascripts/jquery.js http://code.jquery.com/jquery.js`
- puts "Downloading jquery.min.js"
- puts `curl -o vendor/assets/javascripts/jquery.min.js http://code.jquery.com/jquery.min.js`
- puts "Downloading jquery.min.map"
- puts `curl -o vendor/assets/javascripts/jquery.min.map http://code.jquery.com/jquery.min.map`
-
- puts "Updating version.rb"
- version = false
- File.foreach('vendor/assets/javascripts/jquery.js') do |line|
- version = line.match(/jQuery JavaScript Library v([\S]+)/)
- version = version && version[1]
- break if version
+ def download_jquery(filename, version)
+ suffix = "-#{version}"
+
+ puts "Downloading #{filename}.js"
+ puts `curl -o vendor/assets/javascripts/#{filename}.js https://code.jquery.com/jquery#{suffix}.js`
+ puts "Downloading #{filename}.min.js"
+ puts `curl -o vendor/assets/javascripts/#{filename}.min.js https://code.jquery.com/jquery#{suffix}.min.js`
+ puts "Downloading #{filename}.min.map"
+ puts `curl -o vendor/assets/javascripts/#{filename}.min.map https://code.jquery.com/jquery#{suffix}.min.map`
end
- version_path = 'lib/jquery/rails/version.rb'
- lines = IO.readlines(version_path).map do |line|
- line.gsub(/JQUERY_VERSION = "([\d\.]+)"/, "JQUERY_VERSION = \"#{version}\"")
- end
- File.open(version_path, 'w') do |file|
- file.puts lines
- end
+ download_jquery('jquery', Jquery::Rails::JQUERY_VERSION)
+ download_jquery('jquery2', Jquery::Rails::JQUERY_2_VERSION)
+ download_jquery('jquery3', Jquery::Rails::JQUERY_3_VERSION)
+ puts "\e[32mDone!\e[0m"
+end
+desc "Update jQuery UJS version"
+task :update_jquery_ujs do
+ puts "Downloading jquery_ujs.js"
+ puts `curl -o vendor/assets/javascripts/jquery_ujs.js https://raw.githubusercontent.com/rails/jquery-ujs/v#{Jquery::Rails::JQUERY_UJS_VERSION}/src/rails.js`
puts "\e[32mDone!\e[0m"
end
diff --git a/VERSIONS.md b/VERSIONS.md
index 4c6312f3..2ba46a11 100644
--- a/VERSIONS.md
+++ b/VERSIONS.md
@@ -1,43 +1,69 @@
# Bundled Versions
-| Gem | jQuery | jQuery UI |
-|--------|--------|-----------|
-| 3.0.5 | 1.11.0 | - |
-| 3.0.4 | ↾ | - |
-| 3.0.3 | 1.10.2 | - |
-| 3.0.2 | ↾ | - |
-| 3.0.1 | 1.10.1 | - |
-| 3.0.0 | ↾ | - |
-| 2.3.0 | 1.10.0 | 1.10.3 |
-| 2.2.2 | ↾ | ↾ |
-| 2.2.1 | 1.9.1 | ↾ |
-| 2.2.0 | 1.9.0 | ↾ |
-| 2.1.4 | 1.8.3 | 1.9.2 |
-| 2.1.3 | 1.8.2 | ↾ |
-| 2.1.2 | 1.8.1 | ↾ |
-| 2.1.1 | ↾ | ↾ |
-| 2.1.0 | 1.8.0 | 1.8.23 |
-| 2.0.3 | ↾ | ↾ |
-| 2.0.2 | 1.7.2 | 1.8.18 |
-| 2.0.1 | ↾ | ↾ |
-| 2.0.0 | ↾ | ↾ |
-| 1.0.19 | 1.7.1 | ↾ |
-| 1.0.18 | ↾ | ↾ |
-| 1.0.17 | 1.7.0 | ↾ |
-| 1.0.16 | 1.6.4 | 1.8.16 |
-| 1.0.15 | ↾ | ↾ |
-| 1.0.14 | ↾ | ↾ |
-| 1.0.13 | 1.6.2 | 1.8.14 |
-| 1.0.12 | ↾ | ↾ |
-| 1.0.11 | ↾ | ↾ |
-| 1.0.10 | ↾ | ↾ |
-| 1.0.9 | ↾ | ↾ |
-| 1.0.8 | ↾ | ↾ |
-| 1.0.7 | ↾ | ↾ |
-| 1.0.6 | ↾ | ↾ |
-| 1.0.5 | ↾ | ↾ |
-| 1.0.4 | ↾ | ↾ |
-| 1.0.3 | 1.6.1 | ↾ |
-| 1.0.2 | ↾ | ↾ |
-| 1.0.1 | ↾ | 1.8.12 |
-| 1.0.0 | 1.6.0 | - |
+| Gem | jQuery | jQuery UJS | jQuery UI |
+|--------|--------|------------| ----------|
+| 4.6.1 | 1.12.4 & 2.2.4 & 3.7.1 | 1.2.3 | - |
+| 4.6.0 | 1.12.4 & 2.2.4 & 3.7.0 | 1.2.3 | - |
+| 4.5.1 | 1.12.4 & 2.2.4 & 3.6.1 | 1.2.3 | - |
+| 4.5.0 | 1.12.4 & 2.2.4 & 3.6.0 | 1.2.2 | - |
+| 4.4.0 | 1.12.4 & 2.2.4 & 3.5.1 | 1.2.2 | - |
+| 4.3.5 | 1.12.4 & 2.2.4 & 3.4.1 | 1.2.2 | - |
+| 4.3.4 | 1.12.4 & 2.2.4 & 3.4.0 | 1.2.2 | - |
+| 4.3.3 | 1.12.4 & 2.2.4 & 3.3.1 | 1.2.2 | - |
+| 4.3.2 | 1.12.4 & 2.2.4 & 3.3.0 | 1.2.2 | - |
+| 4.3.1 | 1.12.4 & 2.2.4 & 3.2.1 | 1.2.2 | - |
+| 4.3.0 | 1.12.4 & 2.2.4 & 3.2.0 | 1.2.2 | - |
+| 4.2.2 | 1.12.4 & 2.2.4 & 3.1.1 | 1.2.2 | - |
+| 4.2.1 | 1.12.4 & 2.2.4 & 3.1.0 | 1.2.2 | - |
+| 4.2.0 | 1.12.4 & 2.2.4 & 3.0.0 | 1.2.2 | - |
+| 4.1.1 | 1.12.1 & 2.2.1 | 1.2.1 | - |
+| 4.1.0 | 1.12.0 & 2.2.0 | 1.2.0 | - |
+| 4.0.5 | 1.11.3 & 2.1.4 | 1.1.0 | - |
+| 4.0.4 | 1.11.2 & 2.1.3 | 1.0.4 | - |
+| 4.0.3 | 1.11.2 & 2.1.3 | 1.0.3 | - |
+| 4.0.2 | - | - | - |
+| 4.0.1 | - | - | - |
+| 4.0.0 | 1.11.1 & 2.1.1 | 1.0.2 | - |
+| 3.1.3 | 1.11.1 | 1.0.4 | - |
+| 3.1.2 | 1.11.1 | 1.0.1 | - |
+| 3.1.1 | 1.11.1 | 1.0.0 | - |
+| 3.1.0 | 1.11.0 | - | - |
+| 3.0.5 | 1.11.0 | - | - |
+| 3.0.4 | ↾ | - | - |
+| 3.0.3 | 1.10.2 | - | - |
+| 3.0.2 | ↾ | - | - |
+| 3.0.1 | 1.10.1 | - | - |
+| 3.0.0 | ↾ | - | - |
+| 2.3.0 | 1.10.0 | - | 1.10.3 |
+| 2.2.2 | ↾ | - | ↾ |
+| 2.2.1 | 1.9.1 | - | ↾ |
+| 2.2.0 | 1.9.0 | - | ↾ |
+| 2.1.4 | 1.8.3 | - | 1.9.2 |
+| 2.1.3 | 1.8.2 | - | ↾ |
+| 2.1.2 | 1.8.1 | - | ↾ |
+| 2.1.1 | ↾ | - | ↾ |
+| 2.1.0 | 1.8.0 | - | 1.8.23 |
+| 2.0.3 | ↾ | - | ↾ |
+| 2.0.2 | 1.7.2 | - | 1.8.18 |
+| 2.0.1 | ↾ | - | ↾ |
+| 2.0.0 | ↾ | - | ↾ |
+| 1.0.19 | 1.7.1 | - | ↾ |
+| 1.0.18 | ↾ | - | ↾ |
+| 1.0.17 | 1.7.0 | - | ↾ |
+| 1.0.16 | 1.6.4 | - | 1.8.16 |
+| 1.0.15 | ↾ | - | ↾ |
+| 1.0.14 | ↾ | - | ↾ |
+| 1.0.13 | 1.6.2 | - | 1.8.14 |
+| 1.0.12 | ↾ | - | ↾ |
+| 1.0.11 | ↾ | - | ↾ |
+| 1.0.10 | ↾ | - | ↾ |
+| 1.0.9 | ↾ | - | ↾ |
+| 1.0.8 | ↾ | - | ↾ |
+| 1.0.7 | ↾ | - | ↾ |
+| 1.0.6 | ↾ | - | ↾ |
+| 1.0.5 | ↾ | - | ↾ |
+| 1.0.4 | ↾ | - | ↾ |
+| 1.0.3 | 1.6.1 | - | ↾ |
+| 1.0.2 | ↾ | - | ↾ |
+| 1.0.1 | ↾ | - | 1.8.12 |
+| 1.0.0 | 1.6.0 | - | - |
diff --git a/jquery-rails.gemspec b/jquery-rails.gemspec
index fc3d2c40..3e7ed276 100644
--- a/jquery-rails.gemspec
+++ b/jquery-rails.gemspec
@@ -7,17 +7,19 @@ Gem::Specification.new do |s|
s.platform = Gem::Platform::RUBY
s.authors = ["André Arko"]
s.email = ["andre@arko.net"]
- s.homepage = "http://rubygems.org/gems/jquery-rails"
- s.summary = "Use jQuery with Rails 3"
- s.description = "This gem provides jQuery and the jQuery-ujs driver for your Rails 3 application."
+ s.homepage = "https://github.com/rails/jquery-rails"
+ s.summary = "Use jQuery with Rails 4+"
+ s.description = "This gem provides jQuery and the jQuery-ujs driver for your Rails 4+ application."
s.license = "MIT"
+ s.required_ruby_version = ">= 1.9.3"
s.required_rubygems_version = ">= 1.3.6"
- s.rubyforge_project = "jquery-rails"
- s.add_dependency "railties", ">= 3.0", "< 5.0"
+ s.add_dependency "railties", ">= 4.2.0"
s.add_dependency "thor", ">= 0.14", "< 2.0"
+ s.add_dependency "rails-dom-testing", ">= 1", "< 3"
+
s.files = `git ls-files`.split("\n")
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
s.require_path = 'lib'
diff --git a/lib/generators/jquery/install/install_generator.rb b/lib/generators/jquery/install/install_generator.rb
deleted file mode 100644
index 39c0cbd3..00000000
--- a/lib/generators/jquery/install/install_generator.rb
+++ /dev/null
@@ -1,50 +0,0 @@
-require 'rails'
-
-# Supply generator for Rails 3.0.x or if asset pipeline is not enabled
-if ::Rails.version < "3.1" || !::Rails.application.config.assets.enabled
- module Jquery
- module Generators
- class InstallGenerator < ::Rails::Generators::Base
-
- desc "This generator installs jQuery #{Jquery::Rails::JQUERY_VERSION} and jQuery-ujs"
- source_root File.expand_path('../../../../../vendor/assets/javascripts', __FILE__)
-
- def remove_prototype
- Rails::PROTOTYPE_JS.each do |name|
- remove_file "public/javascripts/#{name}.js"
- end
- end
-
- def copy_jquery
- say_status("copying", "jQuery (#{Jquery::Rails::JQUERY_VERSION})", :green)
- copy_file "jquery.js", "public/javascripts/jquery.js"
- copy_file "jquery.min.js", "public/javascripts/jquery.min.js"
- end
-
- def copy_ujs_driver
- say_status("copying", "jQuery UJS adapter (#{Jquery::Rails::JQUERY_UJS_VERSION[0..5]})", :green)
- remove_file "public/javascripts/rails.js"
- copy_file "jquery_ujs.js", "public/javascripts/jquery_ujs.js"
- end
-
- end
- end
- end
-else
- module Jquery
- module Generators
- class InstallGenerator < ::Rails::Generators::Base
- desc "Just show instructions so people will know what to do when mistakenly using generator for Rails 3.1 apps"
-
- def do_nothing
- say_status("deprecated", "You are using Rails 3.1 with the asset pipeline enabled, so this generator is not needed.")
- say_status("", "The necessary files are already in your asset pipeline.")
- say_status("", "Just add `//= require jquery` and `//= require jquery_ujs` to your app/assets/javascripts/application.js")
- say_status("", "If you upgraded your app from Rails 3.0 and still have jquery.js, rails.js, or jquery_ujs.js in your javascripts, be sure to remove them.")
- say_status("", "If you do not want the asset pipeline enabled, you may turn it off in application.rb and re-run this generator.")
- # ok, nothing
- end
- end
- end
- end
-end
diff --git a/lib/jquery/assert_select.rb b/lib/jquery/assert_select.rb
index 7cdf8fdc..1d82fb53 100644
--- a/lib/jquery/assert_select.rb
+++ b/lib/jquery/assert_select.rb
@@ -1,99 +1,151 @@
-module ActionDispatch
- module Assertions
- module SelectorAssertions
- # Selects content from a JQuery response. Patterned loosely on
- # assert_select_rjs.
- #
- # === Narrowing down
- #
- # With no arguments, asserts that one or more method calls are made.
- #
- # Use the +method+ argument to narrow down the assertion to only
- # statements that call that specific method.
- #
- # Use the +opt+ argument to narrow down the assertion to only statements
- # that pass +opt+ as the first argument.
- #
- # Use the +id+ argument to narrow down the assertion to only statements
- # that invoke methods on the result of using that identifier as a
- # selector.
- #
- # === Using blocks
- #
- # Without a block, +assert_select_jquery_ merely asserts that the
- # response contains one or more statements that match the conditions
- # specified above
- #
- # With a block +assert_select_jquery_ also asserts that the method call
- # passes a javascript escaped string containing HTML. All such HTML
- # fragments are selected and passed to the block. Nested assertions are
- # supported.
- #
- # === Examples
- #
- # # asserts that the #notice element is hidden
- # assert_select :hide, '#notice'
- #
- # # asserts that the #cart element is shown with a blind parameter
- # assert_select :show, :blind, '#cart'
- #
- # # asserts that #cart content contains a #current_item
- # assert_select :html, '#cart' do
- # assert_select '#current_item'
- # end
-
- PATTERN_HTML = "\"((\\\\\"|[^\"])*)\""
- PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
-
- def assert_select_jquery(*args, &block)
- jquery_method = args.first.is_a?(Symbol) ? args.shift : nil
- jquery_opt = args.first.is_a?(Symbol) ? args.shift : nil
- id = args.first.is_a?(String) ? args.shift : nil
-
- pattern = "\\.#{jquery_method || '\\w+'}\\("
- pattern = "#{pattern}['\"]#{jquery_opt}['\"],?\\s*" if jquery_opt
- pattern = "#{pattern}#{PATTERN_HTML}"
- pattern = "(?:jQuery|\\$)\\(['\"]#{id}['\"]\\)#{pattern}" if id
-
- fragments = []
- response.body.scan(Regexp.new(pattern)).each do |match|
- doc = HTML::Document.new(unescape_js(match.first))
- doc.root.children.each do |child|
- fragments.push child if child.tag?
- end
- end
+require 'rails/dom/testing/assertions/selector_assertions'
- if fragments.empty?
- opts = [jquery_method, jquery_opt, id].compact
- flunk "No JQuery call matches #{opts.inspect}"
- end
+module Rails::Dom::Testing::Assertions::SelectorAssertions
+ # Selects content from a JQuery response. Patterned loosely on
+ # assert_select_rjs.
+ #
+ # === Narrowing down
+ #
+ # With no arguments, asserts that one or more method calls are made.
+ #
+ # Use the +method+ argument to narrow down the assertion to only
+ # statements that call that specific method.
+ #
+ # Use the +opt+ argument to narrow down the assertion to only statements
+ # that pass +opt+ as the first argument.
+ #
+ # Use the +id+ argument to narrow down the assertion to only statements
+ # that invoke methods on the result of using that identifier as a
+ # selector.
+ #
+ # === Using blocks
+ #
+ # Without a block, +assert_select_jquery_ merely asserts that the
+ # response contains one or more statements that match the conditions
+ # specified above
+ #
+ # With a block +assert_select_jquery_ also asserts that the method call
+ # passes a javascript escaped string containing HTML. All such HTML
+ # fragments are selected and passed to the block. Nested assertions are
+ # supported.
+ #
+ # === Examples
+ #
+ # # asserts that the #notice element is hidden
+ # assert_select :hide, '#notice'
+ #
+ # # asserts that the #cart element is shown with a blind parameter
+ # assert_select :show, :blind, '#cart'
+ #
+ # # asserts that #cart content contains a #current_item
+ # assert_select :html, '#cart' do
+ # assert_select '#current_item'
+ # end
+ #
+ # # asserts that #product append to a #product_list
+ # assert_select_jquery :appendTo, '#product_list' do
+ # assert_select '.product'
+ # end
+
+ PATTERN_HTML = "['\"]((\\\\\"|\\\\'|[^\"'])*)['\"]"
+ PATTERN_UNICODE_ESCAPED_CHAR = /\\u([0-9a-zA-Z]{4})/
+ SKELETAL_PATTERN = "(?:jQuery|\\$)\\(%s\\)\\.%s\\(%s\\)[;]?"
+
+ def assert_select_jquery(*args, &block)
+ jquery_method = args.first.is_a?(Symbol) ? args.shift : nil
+ jquery_opt = args.first.is_a?(Symbol) ? args.shift : nil
+ id = args.first.is_a?(String) ? escape_id(args.shift) : nil
+
+ target_pattern = "['\"]#{id || '.*'}['\"]"
+ method_pattern = "#{jquery_method || '\\w+'}"
+ argument_pattern = jquery_opt ? "['\"]#{jquery_opt}['\"].*" : PATTERN_HTML
+
+ # $("#id").show('blind', 1000);
+ # $("#id").html("
a";
// IE strips leading whitespace when .innerHTML is used
support.leadingWhitespace = div.firstChild.nodeType === 3;
@@ -4175,65 +4494,267 @@ var rcheckableType = (/^(?:checkbox|radio)$/i);
// #11217 - WebKit loses check when the name is after the checked attribute
fragment.appendChild( div );
- div.innerHTML = "";
+
+ // Support: Windows Web Apps (WWA)
+ // `name` and `type` must use .setAttribute for WWA (#14901)
+ input = document.createElement( "input" );
+ input.setAttribute( "type", "radio" );
+ input.setAttribute( "checked", "checked" );
+ input.setAttribute( "name", "t" );
+
+ div.appendChild( input );
// Support: Safari 5.1, iOS 5.1, Android 4.x, Android 2.3
// old WebKit doesn't clone checked state correctly in fragments
support.checkClone = div.cloneNode( true ).cloneNode( true ).lastChild.checked;
// Support: IE<9
- // Opera does not clone events (and typeof div.attachEvent === undefined).
- // IE9-10 clones events bound via attachEvent, but they don't trigger with .click()
- support.noCloneEvent = true;
- if ( div.attachEvent ) {
- div.attachEvent( "onclick", function() {
- support.noCloneEvent = false;
- });
+ // Cloned elements keep attachEvent handlers, we use addEventListener on IE9+
+ support.noCloneEvent = !!div.addEventListener;
+
+ // Support: IE<9
+ // Since attributes and properties are the same in IE,
+ // cleanData must set properties to undefined rather than use removeAttribute
+ div[ jQuery.expando ] = 1;
+ support.attributes = !div.getAttribute( jQuery.expando );
+} )();
+
+
+// We have to close these tags to support XHTML (#13200)
+var wrapMap = {
+ option: [ 1, "" ],
+ legend: [ 1, "" ],
+ area: [ 1, "" ],
+
+ // Support: IE8
+ param: [ 1, "" ],
+ thead: [ 1, "
", "
" ],
+ tr: [ 2, "
", "
" ],
+ col: [ 2, "
", "
" ],
+ td: [ 3, "
", "
" ],
+
+ // IE6-8 can't serialize link, script, style, or any html5 (NoScope) tags,
+ // unless wrapped in a div with non-breaking characters in front of it.
+ _default: support.htmlSerialize ? [ 0, "", "" ] : [ 1, "X
", "
" ]
+};
+
+// Support: IE8-IE9
+wrapMap.optgroup = wrapMap.option;
+
+wrapMap.tbody = wrapMap.tfoot = wrapMap.colgroup = wrapMap.caption = wrapMap.thead;
+wrapMap.th = wrapMap.td;
+
+
+function getAll( context, tag ) {
+ var elems, elem,
+ i = 0,
+ found = typeof context.getElementsByTagName !== "undefined" ?
+ context.getElementsByTagName( tag || "*" ) :
+ typeof context.querySelectorAll !== "undefined" ?
+ context.querySelectorAll( tag || "*" ) :
+ undefined;
- div.cloneNode( true ).click();
+ if ( !found ) {
+ for ( found = [], elems = context.childNodes || context;
+ ( elem = elems[ i ] ) != null;
+ i++
+ ) {
+ if ( !tag || jQuery.nodeName( elem, tag ) ) {
+ found.push( elem );
+ } else {
+ jQuery.merge( found, getAll( elem, tag ) );
+ }
+ }
}
- // Execute the test only if not already executed in another module.
- if (support.deleteExpando == null) {
- // Support: IE<9
- support.deleteExpando = true;
- try {
- delete div.test;
- } catch( e ) {
- support.deleteExpando = false;
+ return tag === undefined || tag && jQuery.nodeName( context, tag ) ?
+ jQuery.merge( [ context ], found ) :
+ found;
+}
+
+
+// Mark scripts as having already been evaluated
+function setGlobalEval( elems, refElements ) {
+ var elem,
+ i = 0;
+ for ( ; ( elem = elems[ i ] ) != null; i++ ) {
+ jQuery._data(
+ elem,
+ "globalEval",
+ !refElements || jQuery._data( refElements[ i ], "globalEval" )
+ );
+ }
+}
+
+
+var rhtml = /<|?\w+;/,
+ rtbody = /< l; i++ ) {
+ elem = elems[ i ];
+
+ if ( elem || elem === 0 ) {
+
+ // Add nodes directly
+ if ( jQuery.type( elem ) === "object" ) {
+ jQuery.merge( nodes, elem.nodeType ? [ elem ] : elem );
+
+ // Convert non-html into a text node
+ } else if ( !rhtml.test( elem ) ) {
+ nodes.push( context.createTextNode( elem ) );
+
+ // Convert html into DOM nodes
+ } else {
+ tmp = tmp || safe.appendChild( context.createElement( "div" ) );
+
+ // Deserialize a standard representation
+ tag = ( rtagName.exec( elem ) || [ "", "" ] )[ 1 ].toLowerCase();
+ wrap = wrapMap[ tag ] || wrapMap._default;
+
+ tmp.innerHTML = wrap[ 1 ] + jQuery.htmlPrefilter( elem ) + wrap[ 2 ];
+
+ // Descend through wrappers to the right content
+ j = wrap[ 0 ];
+ while ( j-- ) {
+ tmp = tmp.lastChild;
+ }
+
+ // Manually add leading whitespace removed by IE
+ if ( !support.leadingWhitespace && rleadingWhitespace.test( elem ) ) {
+ nodes.push( context.createTextNode( rleadingWhitespace.exec( elem )[ 0 ] ) );
+ }
+
+ // Remove IE's autoinserted from table fragments
+ if ( !support.tbody ) {
+
+ // String was a
, *may* have spurious
+ elem = tag === "table" && !rtbody.test( elem ) ?
+ tmp.firstChild :
+
+ // String was a bare or
+ wrap[ 1 ] === "
" && !rtbody.test( elem ) ?
+ tmp :
+ 0;
+
+ j = elem && elem.childNodes.length;
+ while ( j-- ) {
+ if ( jQuery.nodeName( ( tbody = elem.childNodes[ j ] ), "tbody" ) &&
+ !tbody.childNodes.length ) {
+
+ elem.removeChild( tbody );
+ }
+ }
+ }
+
+ jQuery.merge( nodes, tmp.childNodes );
+
+ // Fix #12392 for WebKit and IE > 9
+ tmp.textContent = "";
+
+ // Fix #12392 for oldIE
+ while ( tmp.firstChild ) {
+ tmp.removeChild( tmp.firstChild );
+ }
+
+ // Remember the top-level container for proper cleanup
+ tmp = safe.lastChild;
+ }
}
}
- // Null elements to avoid leaks in IE.
- fragment = div = input = null;
-})();
+ // Fix #11356: Clear elements from fragment
+ if ( tmp ) {
+ safe.removeChild( tmp );
+ }
+
+ // Reset defaultChecked for any radios and checkboxes
+ // about to be appended to the DOM in IE 6/7 (#8060)
+ if ( !support.appendChecked ) {
+ jQuery.grep( getAll( nodes, "input" ), fixDefaultChecked );
+ }
+
+ i = 0;
+ while ( ( elem = nodes[ i++ ] ) ) {
+
+ // Skip elements already in the context collection (trac-4087)
+ if ( selection && jQuery.inArray( elem, selection ) > -1 ) {
+ if ( ignored ) {
+ ignored.push( elem );
+ }
+
+ continue;
+ }
+
+ contains = jQuery.contains( elem.ownerDocument, elem );
+ // Append to fragment
+ tmp = getAll( safe.appendChild( elem ), "script" );
-(function() {
+ // Preserve script evaluation history
+ if ( contains ) {
+ setGlobalEval( tmp );
+ }
+
+ // Capture executables
+ if ( scripts ) {
+ j = 0;
+ while ( ( elem = tmp[ j++ ] ) ) {
+ if ( rscriptType.test( elem.type || "" ) ) {
+ scripts.push( elem );
+ }
+ }
+ }
+ }
+
+ tmp = null;
+
+ return safe;
+}
+
+
+( function() {
var i, eventName,
div = document.createElement( "div" );
- // Support: IE<9 (lack submit/change bubble), Firefox 23+ (lack focusin event)
- for ( i in { submit: true, change: true, focusin: true }) {
+ // Support: IE<9 (lack submit/change bubble), Firefox (lack focus(in | out) events)
+ for ( i in { submit: true, change: true, focusin: true } ) {
eventName = "on" + i;
- if ( !(support[ i + "Bubbles" ] = eventName in window) ) {
+ if ( !( support[ i ] = eventName in window ) ) {
+
// Beware of CSP restrictions (https://developer.mozilla.org/en/Security/CSP)
div.setAttribute( eventName, "t" );
- support[ i + "Bubbles" ] = div.attributes[ eventName ].expando === false;
+ support[ i ] = div.attributes[ eventName ].expando === false;
}
}
// Null elements to avoid leaks in IE.
div = null;
-})();
+} )();
var rformElems = /^(?:input|select|textarea)$/i,
rkeyEvent = /^key/,
- rmouseEvent = /^(?:mouse|contextmenu)|click/,
+ rmouseEvent = /^(?:mouse|pointer|contextmenu|drag|drop)|click/,
rfocusMorph = /^(?:focusinfocus|focusoutblur)$/,
- rtypenamespace = /^([^.]*)(?:\.(.+)|)$/;
+ rtypenamespace = /^([^.]*)(?:\.(.+)|)/;
function returnTrue() {
return true;
@@ -4243,14 +4764,77 @@ function returnFalse() {
return false;
}
+// Support: IE9
+// See #13393 for more info
function safeActiveElement() {
try {
return document.activeElement;
} catch ( err ) { }
}
-/*
- * Helper functions for managing events -- not part of the public interface.
+function on( elem, types, selector, data, fn, one ) {
+ var origFn, type;
+
+ // Types can be a map of types/handlers
+ if ( typeof types === "object" ) {
+
+ // ( types-Object, selector, data )
+ if ( typeof selector !== "string" ) {
+
+ // ( types-Object, data )
+ data = data || selector;
+ selector = undefined;
+ }
+ for ( type in types ) {
+ on( elem, type, selector, data, types[ type ], one );
+ }
+ return elem;
+ }
+
+ if ( data == null && fn == null ) {
+
+ // ( types, fn )
+ fn = selector;
+ data = selector = undefined;
+ } else if ( fn == null ) {
+ if ( typeof selector === "string" ) {
+
+ // ( types, selector, fn )
+ fn = data;
+ data = undefined;
+ } else {
+
+ // ( types, data, fn )
+ fn = data;
+ data = selector;
+ selector = undefined;
+ }
+ }
+ if ( fn === false ) {
+ fn = returnFalse;
+ } else if ( !fn ) {
+ return elem;
+ }
+
+ if ( one === 1 ) {
+ origFn = fn;
+ fn = function( event ) {
+
+ // Can use an empty set, since event contains the info
+ jQuery().off( event );
+ return origFn.apply( this, arguments );
+ };
+
+ // Use same guid so caller can remove using origFn
+ fn.guid = origFn.guid || ( origFn.guid = jQuery.guid++ );
+ }
+ return elem.each( function() {
+ jQuery.event.add( this, types, fn, data, selector );
+ } );
+}
+
+/*
+ * Helper functions for managing events -- not part of the public interface.
* Props to Dean Edwards' addEvent library for many of the ideas.
*/
jQuery.event = {
@@ -4281,18 +4865,22 @@ jQuery.event = {
}
// Init the element's event structure and main handler, if this is the first
- if ( !(events = elemData.events) ) {
+ if ( !( events = elemData.events ) ) {
events = elemData.events = {};
}
- if ( !(eventHandle = elemData.handle) ) {
+ if ( !( eventHandle = elemData.handle ) ) {
eventHandle = elemData.handle = function( e ) {
+
// Discard the second event of a jQuery.event.trigger() and
// when an event is called after a page has unloaded
- return typeof jQuery !== strundefined && (!e || jQuery.event.triggered !== e.type) ?
+ return typeof jQuery !== "undefined" &&
+ ( !e || jQuery.event.triggered !== e.type ) ?
jQuery.event.dispatch.apply( eventHandle.elem, arguments ) :
undefined;
};
- // Add elem as a property of the handle fn to prevent a memory leak with IE non-native events
+
+ // Add elem as a property of the handle fn to prevent a memory leak
+ // with IE non-native events
eventHandle.elem = elem;
}
@@ -4300,9 +4888,9 @@ jQuery.event = {
types = ( types || "" ).match( rnotwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
// There *must* be a type, no attaching namespace-only handlers
if ( !type ) {
@@ -4319,7 +4907,7 @@ jQuery.event = {
special = jQuery.event.special[ type ] || {};
// handleObj is passed to all event handlers
- handleObj = jQuery.extend({
+ handleObj = jQuery.extend( {
type: type,
origType: origType,
data: data,
@@ -4327,16 +4915,18 @@ jQuery.event = {
guid: handler.guid,
selector: selector,
needsContext: selector && jQuery.expr.match.needsContext.test( selector ),
- namespace: namespaces.join(".")
+ namespace: namespaces.join( "." )
}, handleObjIn );
// Init the event handler queue if we're the first
- if ( !(handlers = events[ type ]) ) {
+ if ( !( handlers = events[ type ] ) ) {
handlers = events[ type ] = [];
handlers.delegateCount = 0;
// Only use addEventListener/attachEvent if the special events handler returns false
- if ( !special.setup || special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+ if ( !special.setup ||
+ special.setup.call( elem, data, namespaces, eventHandle ) === false ) {
+
// Bind the global event handler to the element
if ( elem.addEventListener ) {
elem.addEventListener( type, eventHandle, false );
@@ -4378,7 +4968,7 @@ jQuery.event = {
namespaces, origType,
elemData = jQuery.hasData( elem ) && jQuery._data( elem );
- if ( !elemData || !(events = elemData.events) ) {
+ if ( !elemData || !( events = elemData.events ) ) {
return;
}
@@ -4386,9 +4976,9 @@ jQuery.event = {
types = ( types || "" ).match( rnotwhite ) || [ "" ];
t = types.length;
while ( t-- ) {
- tmp = rtypenamespace.exec( types[t] ) || [];
- type = origType = tmp[1];
- namespaces = ( tmp[2] || "" ).split( "." ).sort();
+ tmp = rtypenamespace.exec( types[ t ] ) || [];
+ type = origType = tmp[ 1 ];
+ namespaces = ( tmp[ 2 ] || "" ).split( "." ).sort();
// Unbind all events (on this namespace, if provided) for the element
if ( !type ) {
@@ -4401,7 +4991,8 @@ jQuery.event = {
special = jQuery.event.special[ type ] || {};
type = ( selector ? special.delegateType : special.bindType ) || type;
handlers = events[ type ] || [];
- tmp = tmp[2] && new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" );
+ tmp = tmp[ 2 ] &&
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" );
// Remove matching events
origCount = j = handlers.length;
@@ -4411,7 +5002,8 @@ jQuery.event = {
if ( ( mappedTypes || origType === handleObj.origType ) &&
( !handler || handler.guid === handleObj.guid ) &&
( !tmp || tmp.test( handleObj.namespace ) ) &&
- ( !selector || selector === handleObj.selector || selector === "**" && handleObj.selector ) ) {
+ ( !selector || selector === handleObj.selector ||
+ selector === "**" && handleObj.selector ) ) {
handlers.splice( j, 1 );
if ( handleObj.selector ) {
@@ -4426,7 +5018,9 @@ jQuery.event = {
// Remove generic event handler if we removed something and no more handlers exist
// (avoids potential for endless recursion during removal of special event handlers)
if ( origCount && !handlers.length ) {
- if ( !special.teardown || special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+ if ( !special.teardown ||
+ special.teardown.call( elem, namespaces, elemData.handle ) === false ) {
+
jQuery.removeEvent( elem, type, elemData.handle );
}
@@ -4449,7 +5043,7 @@ jQuery.event = {
bubbleType, special, tmp, i,
eventPath = [ elem || document ],
type = hasOwn.call( event, "type" ) ? event.type : event,
- namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split(".") : [];
+ namespaces = hasOwn.call( event, "namespace" ) ? event.namespace.split( "." ) : [];
cur = tmp = elem = elem || document;
@@ -4463,13 +5057,14 @@ jQuery.event = {
return;
}
- if ( type.indexOf(".") >= 0 ) {
+ if ( type.indexOf( "." ) > -1 ) {
+
// Namespaced trigger; create a regexp to match event type in handle()
- namespaces = type.split(".");
+ namespaces = type.split( "." );
type = namespaces.shift();
namespaces.sort();
}
- ontype = type.indexOf(":") < 0 && "on" + type;
+ ontype = type.indexOf( ":" ) < 0 && "on" + type;
// Caller can pass in a jQuery.Event object, Object, or just an event type string
event = event[ jQuery.expando ] ?
@@ -4478,9 +5073,9 @@ jQuery.event = {
// Trigger bitmask: & 1 for native handlers; & 2 for jQuery (always true)
event.isTrigger = onlyHandlers ? 2 : 3;
- event.namespace = namespaces.join(".");
- event.namespace_re = event.namespace ?
- new RegExp( "(^|\\.)" + namespaces.join("\\.(?:.*\\.|)") + "(\\.|$)" ) :
+ event.namespace = namespaces.join( "." );
+ event.rnamespace = event.namespace ?
+ new RegExp( "(^|\\.)" + namespaces.join( "\\.(?:.*\\.|)" ) + "(\\.|$)" ) :
null;
// Clean up the event in case it is being reused
@@ -4514,28 +5109,30 @@ jQuery.event = {
}
// Only add window if we got to document (e.g., not plain obj or detached DOM)
- if ( tmp === (elem.ownerDocument || document) ) {
+ if ( tmp === ( elem.ownerDocument || document ) ) {
eventPath.push( tmp.defaultView || tmp.parentWindow || window );
}
}
// Fire handlers on the event path
i = 0;
- while ( (cur = eventPath[i++]) && !event.isPropagationStopped() ) {
+ while ( ( cur = eventPath[ i++ ] ) && !event.isPropagationStopped() ) {
event.type = i > 1 ?
bubbleType :
special.bindType || type;
// jQuery handler
- handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] && jQuery._data( cur, "handle" );
+ handle = ( jQuery._data( cur, "events" ) || {} )[ event.type ] &&
+ jQuery._data( cur, "handle" );
+
if ( handle ) {
handle.apply( cur, data );
}
// Native handler
handle = ontype && cur[ ontype ];
- if ( handle && handle.apply && jQuery.acceptData( cur ) ) {
+ if ( handle && handle.apply && acceptData( cur ) ) {
event.result = handle.apply( cur, data );
if ( event.result === false ) {
event.preventDefault();
@@ -4547,8 +5144,11 @@ jQuery.event = {
// If nobody prevented the default action, do it now
if ( !onlyHandlers && !event.isDefaultPrevented() ) {
- if ( (!special._default || special._default.apply( eventPath.pop(), data ) === false) &&
- jQuery.acceptData( elem ) ) {
+ if (
+ ( !special._default ||
+ special._default.apply( eventPath.pop(), data ) === false
+ ) && acceptData( elem )
+ ) {
// Call a native DOM method on the target with the same name name as the event.
// Can't use an .isFunction() check here because IE6/7 fails that test.
@@ -4567,6 +5167,7 @@ jQuery.event = {
try {
elem[ type ]();
} catch ( e ) {
+
// IE<9 dies on focus/blur to hidden element (#1486,#12518)
// only reproducible on winXP IE8 native, not IE9 in IE8 mode
}
@@ -4587,14 +5188,14 @@ jQuery.event = {
// Make a writable jQuery.Event from the native event object
event = jQuery.event.fix( event );
- var i, ret, handleObj, matched, j,
+ var i, j, ret, matched, handleObj,
handlerQueue = [],
args = slice.call( arguments ),
handlers = ( jQuery._data( this, "events" ) || {} )[ event.type ] || [],
special = jQuery.event.special[ event.type ] || {};
// Use the fix-ed jQuery.Event rather than the (read-only) native event
- args[0] = event;
+ args[ 0 ] = event;
event.delegateTarget = this;
// Call the preDispatch hook for the mapped type, and let it bail if desired
@@ -4607,24 +5208,25 @@ jQuery.event = {
// Run delegates first; they may want to stop propagation beneath us
i = 0;
- while ( (matched = handlerQueue[ i++ ]) && !event.isPropagationStopped() ) {
+ while ( ( matched = handlerQueue[ i++ ] ) && !event.isPropagationStopped() ) {
event.currentTarget = matched.elem;
j = 0;
- while ( (handleObj = matched.handlers[ j++ ]) && !event.isImmediatePropagationStopped() ) {
+ while ( ( handleObj = matched.handlers[ j++ ] ) &&
+ !event.isImmediatePropagationStopped() ) {
- // Triggered event must either 1) have no namespace, or
- // 2) have namespace(s) a subset or equal to those in the bound event (both can have no namespace).
- if ( !event.namespace_re || event.namespace_re.test( handleObj.namespace ) ) {
+ // Triggered event must either 1) have no namespace, or 2) have namespace(s)
+ // a subset or equal to those in the bound event (both can have no namespace).
+ if ( !event.rnamespace || event.rnamespace.test( handleObj.namespace ) ) {
event.handleObj = handleObj;
event.data = handleObj.data;
- ret = ( (jQuery.event.special[ handleObj.origType ] || {}).handle || handleObj.handler )
- .apply( matched.elem, args );
+ ret = ( ( jQuery.event.special[ handleObj.origType ] || {} ).handle ||
+ handleObj.handler ).apply( matched.elem, args );
if ( ret !== undefined ) {
- if ( (event.result = ret) === false ) {
+ if ( ( event.result = ret ) === false ) {
event.preventDefault();
event.stopPropagation();
}
@@ -4642,15 +5244,19 @@ jQuery.event = {
},
handlers: function( event, handlers ) {
- var sel, handleObj, matches, i,
+ var i, matches, sel, handleObj,
handlerQueue = [],
delegateCount = handlers.delegateCount,
cur = event.target;
+ // Support (at least): Chrome, IE9
// Find delegate handlers
// Black-hole SVG