aboutsummaryrefslogtreecommitdiffstats
path: root/actionview
diff options
context:
space:
mode:
Diffstat (limited to 'actionview')
-rw-r--r--actionview/CHANGELOG.md11
-rw-r--r--actionview/Rakefile27
-rw-r--r--actionview/app/assets/javascripts/MIT-LICENSE20
-rw-r--r--actionview/app/assets/javascripts/README.md49
-rw-r--r--actionview/app/assets/javascripts/config.coffee13
-rw-r--r--actionview/app/assets/javascripts/features/remote.coffee12
-rw-r--r--actionview/app/assets/javascripts/rails-ujs.coffee9
-rw-r--r--actionview/app/assets/javascripts/utils/event.coffee2
-rw-r--r--actionview/app/assets/javascripts/utils/form.coffee27
-rw-r--r--actionview/coffeelint.json135
-rw-r--r--actionview/lib/action_view/gem_version.rb2
-rw-r--r--actionview/lib/action_view/helpers/sanitize_helper.rb14
-rw-r--r--actionview/lib/action_view/test_case.rb8
-rw-r--r--actionview/package.json4
-rw-r--r--actionview/test/activerecord/polymorphic_routes_test.rb3
-rw-r--r--actionview/test/template/date_helper_test.rb2
-rw-r--r--actionview/test/template/erb/tag_helper_test.rb4
-rw-r--r--actionview/test/template/form_helper_test.rb4
-rw-r--r--actionview/test/template/sanitize_helper_test.rb2
-rw-r--r--actionview/test/ujs/config.ru1
-rw-r--r--actionview/test/ujs/public/test/call-remote-callbacks.js196
-rw-r--r--actionview/test/ujs/public/test/data-remote.js17
-rw-r--r--actionview/test/ujs/public/test/override.js2
-rw-r--r--actionview/test/ujs/public/test/settings.js8
-rw-r--r--actionview/test/ujs/server.rb37
-rw-r--r--actionview/test/ujs/views/layouts/application.html.erb25
-rw-r--r--actionview/test/ujs/views/tests/index.html.erb16
27 files changed, 309 insertions, 341 deletions
diff --git a/actionview/CHANGELOG.md b/actionview/CHANGELOG.md
index b071b260c9..e9e4580f96 100644
--- a/actionview/CHANGELOG.md
+++ b/actionview/CHANGELOG.md
@@ -1,3 +1,14 @@
+* Remove the option `encode_special_chars` misnomer from `strip_tags`
+
+ As of rails-html-sanitizer v1.0.3, the sanitizer will ignore the
+ `encode_special_chars` option.
+
+ Fixes #28060.
+
+ *Andrew Hood*
+
+## Rails 5.1.0.beta1 (February 23, 2017) ##
+
* Change the ERB handler from Erubis to Erubi.
Erubi is an Erubis fork that's svelte, simple, and currently maintained.
diff --git a/actionview/Rakefile b/actionview/Rakefile
index cba4684076..00ab92129d 100644
--- a/actionview/Rakefile
+++ b/actionview/Rakefile
@@ -1,4 +1,5 @@
require "rake/testtask"
+require "fileutils"
desc "Default Task"
task default: :test
@@ -25,6 +26,32 @@ namespace :test do
t.ruby_opts = ["--dev"] if defined?(JRUBY_VERSION)
end
+ task :ujs do
+ begin
+ Dir.mkdir("log")
+ pid = spawn("bundle exec rackup test/ujs/config.ru -p 4567 -s puma > log/test.log 2>&1")
+
+ start_time = Time.now
+
+ loop do
+ break if system("lsof -i :4567 >/dev/null")
+
+ if Time.now - start_time > 5
+ puts "Timed out after 5 seconds"
+ exit 1
+ end
+ end
+
+ system("npm run lint && phantomjs ../ci/phantomjs.js http://localhost:4567/")
+ status = $?.to_i
+ ensure
+ Process.kill("KILL", pid) if pid
+ FileUtils.rm_f("log")
+ end
+
+ exit status
+ end
+
namespace :integration do
desc "ActiveRecord Integration Tests"
Rake::TestTask.new(:active_record) do |t|
diff --git a/actionview/app/assets/javascripts/MIT-LICENSE b/actionview/app/assets/javascripts/MIT-LICENSE
new file mode 100644
index 0000000000..befcbdc7b7
--- /dev/null
+++ b/actionview/app/assets/javascripts/MIT-LICENSE
@@ -0,0 +1,20 @@
+Copyright (c) 2007-2017 Rails Core team
+
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of this software and associated documentation files (the
+"Software"), to deal in the Software without restriction, including
+without limitation the rights to use, copy, modify, merge, publish,
+distribute, sublicense, and/or sell copies of the Software, and to
+permit persons to whom the Software is furnished to do so, subject to
+the following conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+MERCHANTABILITY, 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.
diff --git a/actionview/app/assets/javascripts/README.md b/actionview/app/assets/javascripts/README.md
new file mode 100644
index 0000000000..92f3e8a3b3
--- /dev/null
+++ b/actionview/app/assets/javascripts/README.md
@@ -0,0 +1,49 @@
+Ruby on Rails unobtrusive scripting adapter.
+========================================
+
+This unobtrusive scripting support file is developed for the Ruby on Rails framework, but is not strictly tied to any specific backend. You can drop this into any application to:
+
+- force confirmation dialogs for various actions;
+- make non-GET requests from hyperlinks;
+- make forms or hyperlinks submit data asynchronously with Ajax;
+- have submit buttons become automatically disabled on form submit to prevent double-clicking.
+
+These features are achieved by adding certain ["data" attributes][data] to your HTML markup. In Rails, they are added by the framework's template helpers.
+
+Requirements
+------------
+
+- HTML5 doctype (optional).
+
+If you don't use HTML5, adding "data" attributes to your HTML4 or XHTML pages might make them fail [W3C markup validation][validator]. However, this shouldn't create any issues for web browsers or other user agents.
+
+Installation using npm
+------------
+
+Run `npm install rails-ujs --save` to install the rails-ujs package.
+
+Installation using Yarn
+------------
+
+Run `yarn add rails-ujs` to install the rails-ujs package.
+
+Usage
+------------
+
+Require `rails-ujs` into your application.js manifest.
+
+```javascript
+//= require rails-ujs
+```
+
+How to run tests
+------------
+
+Run `bundle exec rake ujs:server` first, and then run the web tests by visiting [[http://localhost:4567]] in your browser.
+
+## License
+rails-ujs is released under the [MIT License](MIT-LICENSE).
+
+[data]: http://www.w3.org/TR/html5/dom.html#embedding-custom-non-visible-data-with-the-data-*-attributes "Embedding custom non-visible data with the data-* attributes"
+[validator]: http://validator.w3.org/
+[csrf]: http://api.rubyonrails.org/classes/ActionController/RequestForgeryProtection.html
diff --git a/actionview/app/assets/javascripts/config.coffee b/actionview/app/assets/javascripts/config.coffee
index 3d4706b0e1..a93325e903 100644
--- a/actionview/app/assets/javascripts/config.coffee
+++ b/actionview/app/assets/javascripts/config.coffee
@@ -1,21 +1,21 @@
#= export Rails
@Rails =
- # Link elements bound by jquery-ujs
+ # Link elements bound by rails-ujs
linkClickSelector: 'a[data-confirm], a[data-method], a[data-remote]:not([disabled]), a[data-disable-with], a[data-disable]'
- # Button elements bound by jquery-ujs
+ # Button elements bound by rails-ujs
buttonClickSelector:
selector: 'button[data-remote]:not([form]), button[data-confirm]:not([form])'
exclude: 'form button'
- # Select elements bound by jquery-ujs
+ # Select elements bound by rails-ujs
inputChangeSelector: 'select[data-remote], input[data-remote], textarea[data-remote]'
- # Form elements bound by jquery-ujs
+ # Form elements bound by rails-ujs
formSubmitSelector: 'form'
- # Form input elements bound by jquery-ujs
+ # Form input elements bound by rails-ujs
formInputClickSelector: 'form input[type=submit], form input[type=image], form button[type=submit], form button:not([type]), input[type=submit][form], input[type=image][form], button[type=submit][form], button[form]:not([type])'
# Form input elements disabled during form submission
@@ -24,9 +24,6 @@
# Form input elements re-enabled after form submission
formEnableSelector: 'input[data-disable-with]:disabled, button[data-disable-with]:disabled, textarea[data-disable-with]:disabled, input[data-disable]:disabled, button[data-disable]:disabled, textarea[data-disable]:disabled'
- # Form required input elements
- requiredInputSelector: 'input[name][required]:not([disabled]), textarea[name][required]:not([disabled])'
-
# Form file input elements
fileInputSelector: 'input[name][type=file]:not([disabled])'
diff --git a/actionview/app/assets/javascripts/features/remote.coffee b/actionview/app/assets/javascripts/features/remote.coffee
index 30a5dc21fa..852587042c 100644
--- a/actionview/app/assets/javascripts/features/remote.coffee
+++ b/actionview/app/assets/javascripts/features/remote.coffee
@@ -4,7 +4,7 @@
matches, getData, setData
fire, stopEverything
ajax, isCrossDomain
- blankInputs, serializeElement
+ serializeElement
} = Rails
# Checks "data-remote" if true to handle the request through a XHR request.
@@ -71,16 +71,6 @@ Rails.handleRemote = (e) ->
)
stopEverything(e)
-# Check whether any required fields are empty
-# In both ajax mode and normal mode
-Rails.validateForm = (e) ->
- form = this
- return if form.noValidate or getData(form, 'ujs:formnovalidate-button')
- # Skip other logic when required values are missing or file upload is present
- blankRequiredInputs = blankInputs(form, Rails.requiredInputSelector, false)
- if blankRequiredInputs.length > 0 and fire(form, 'ajax:aborted:required', [blankRequiredInputs])
- stopEverything(e)
-
Rails.formSubmitButtonClick = (e) ->
button = this
form = button.form
diff --git a/actionview/app/assets/javascripts/rails-ujs.coffee b/actionview/app/assets/javascripts/rails-ujs.coffee
index f96d2eb6fd..df889ce067 100644
--- a/actionview/app/assets/javascripts/rails-ujs.coffee
+++ b/actionview/app/assets/javascripts/rails-ujs.coffee
@@ -14,7 +14,7 @@
refreshCSRFTokens, CSRFProtection
enableElement, disableElement
handleConfirm
- handleRemote, validateForm, formSubmitButtonClick, handleMetaClick
+ handleRemote, formSubmitButtonClick, handleMetaClick
handleMethod
} = Rails
@@ -25,9 +25,9 @@ if jQuery? and not jQuery.rails
CSRFProtection(xhr) unless options.crossDomain
Rails.start = ->
- # Cut down on the number of issues from people inadvertently including jquery_ujs twice
- # by detecting and raising an error when it happens.
- throw new Error('jquery-ujs has already been loaded!') if window._rails_loaded
+ # Cut down on the number of issues from people inadvertently including
+ # rails-ujs twice by detecting and raising an error when it happens.
+ throw new Error('rails-ujs has already been loaded!') if window._rails_loaded
# This event works the same as the load event, except that it fires every
# time the page is loaded.
@@ -58,7 +58,6 @@ Rails.start = ->
delegate document, Rails.inputChangeSelector, 'change', handleRemote
delegate document, Rails.formSubmitSelector, 'submit', handleConfirm
- delegate document, Rails.formSubmitSelector, 'submit', validateForm
delegate document, Rails.formSubmitSelector, 'submit', handleRemote
# Normal mode submit
# Slight timeout so that the submit button gets properly serialized
diff --git a/actionview/app/assets/javascripts/utils/event.coffee b/actionview/app/assets/javascripts/utils/event.coffee
index d25fe8e546..8d3ff007ea 100644
--- a/actionview/app/assets/javascripts/utils/event.coffee
+++ b/actionview/app/assets/javascripts/utils/event.coffee
@@ -6,7 +6,7 @@
# https://developer.mozilla.org/en-US/docs/Web/API/CustomEvent/CustomEvent#Polyfill
CustomEvent = window.CustomEvent
-if typeof CustomEvent is 'function'
+if typeof CustomEvent isnt 'function'
CustomEvent = (event, params) ->
evt = document.createEvent('CustomEvent')
evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail)
diff --git a/actionview/app/assets/javascripts/utils/form.coffee b/actionview/app/assets/javascripts/utils/form.coffee
index 251113deda..5fa337b518 100644
--- a/actionview/app/assets/javascripts/utils/form.coffee
+++ b/actionview/app/assets/javascripts/utils/form.coffee
@@ -14,7 +14,7 @@ Rails.serializeElement = (element, additionalParam) ->
if matches(input, 'select')
toArray(input.options).forEach (option) ->
params.push(name: input.name, value: option.value) if option.selected
- else if input.type isnt 'radio' and input.type isnt 'checkbox' or input.checked
+ else if input.checked or ['radio', 'checkbox', 'submit'].indexOf(input.type) == -1
params.push(name: input.name, value: input.value)
params.push(additionalParam) if additionalParam
@@ -34,28 +34,3 @@ Rails.formElements = (form, selector) ->
toArray(form.elements).filter (el) -> matches(el, selector)
else
toArray(form.querySelectorAll(selector))
-
-# Helper function which checks for blank inputs in a form that match the specified CSS selector
-Rails.blankInputs = (form, selector, nonBlank) ->
- foundInputs = []
- requiredInputs = toArray(form.querySelectorAll(selector or 'input, textarea'))
- checkedRadioButtonNames = {}
-
- requiredInputs.forEach (input) ->
- if input.type is 'radio'
- # Don't count unchecked required radio as blank if other radio with same name is checked,
- # regardless of whether same-name radio input has required attribute or not. The spec
- # states https://www.w3.org/TR/html5/forms.html#the-required-attribute
- radioName = input.name
- # Skip if we've already seen the radio with this name.
- unless checkedRadioButtonNames[radioName]
- # If none checked
- if form.querySelectorAll("input[type=radio][name='#{radioName}']:checked").length == 0
- radios = form.querySelectorAll("input[type=radio][name='#{radioName}']")
- foundInputs = foundInputs.concat(toArray(radios))
- # We only need to check each name once.
- checkedRadioButtonNames[radioName] = radioName
- else
- valueToCheck = if input.type is 'checkbox' then input.checked else !!input.value
- foundInputs.push(input) if valueToCheck is nonBlank
- foundInputs
diff --git a/actionview/coffeelint.json b/actionview/coffeelint.json
new file mode 100644
index 0000000000..cf8bf2171b
--- /dev/null
+++ b/actionview/coffeelint.json
@@ -0,0 +1,135 @@
+{
+ "arrow_spacing": {
+ "level": "warn"
+ },
+ "braces_spacing": {
+ "level": "warn",
+ "spaces": 1,
+ "empty_object_spaces": 0
+ },
+ "camel_case_classes": {
+ "level": "error"
+ },
+ "coffeescript_error": {
+ "level": "error"
+ },
+ "colon_assignment_spacing": {
+ "level": "warn",
+ "spacing": {
+ "left": 0,
+ "right": 1
+ }
+ },
+ "cyclomatic_complexity": {
+ "level": "warn",
+ "value": 10
+ },
+ "duplicate_key": {
+ "level": "error"
+ },
+ "empty_constructor_needs_parens": {
+ "level": "warn"
+ },
+ "ensure_comprehensions": {
+ "level": "warn"
+ },
+ "eol_last": {
+ "level": "warn"
+ },
+ "indentation": {
+ "value": 2,
+ "level": "error"
+ },
+ "line_endings": {
+ "level": "warn",
+ "value": "unix"
+ },
+ "max_line_length": {
+ "value": 80,
+ "level": "ignore",
+ "limitComments": true
+ },
+ "missing_fat_arrows": {
+ "level": "ignore"
+ },
+ "newlines_after_classes": {
+ "value": 3,
+ "level": "warn"
+ },
+ "no_backticks": {
+ "level": "error"
+ },
+ "no_debugger": {
+ "level": "warn",
+ "console": false
+ },
+ "no_empty_functions": {
+ "level": "warn"
+ },
+ "no_empty_param_list": {
+ "level": "warn"
+ },
+ "no_implicit_braces": {
+ "level": "ignore",
+ "strict": true
+ },
+ "no_implicit_parens": {
+ "level": "ignore",
+ "strict": true
+ },
+ "no_interpolation_in_single_quotes": {
+ "level": "warn"
+ },
+ "no_nested_string_interpolation": {
+ "level": "warn"
+ },
+ "no_plusplus": {
+ "level": "warn"
+ },
+ "no_private_function_fat_arrows": {
+ "level": "warn"
+ },
+ "no_stand_alone_at": {
+ "level": "warn"
+ },
+ "no_tabs": {
+ "level": "error"
+ },
+ "no_this": {
+ "level": "warn"
+ },
+ "no_throwing_strings": {
+ "level": "error"
+ },
+ "no_trailing_semicolons": {
+ "level": "error"
+ },
+ "no_trailing_whitespace": {
+ "level": "error",
+ "allowed_in_comments": false,
+ "allowed_in_empty_lines": true
+ },
+ "no_unnecessary_double_quotes": {
+ "level": "warn"
+ },
+ "no_unnecessary_fat_arrows": {
+ "level": "warn"
+ },
+ "non_empty_constructor_needs_parens": {
+ "level": "warn"
+ },
+ "prefer_english_operator": {
+ "level": "ignore",
+ "doubleNotLevel": "warn"
+ },
+ "space_operators": {
+ "level": "warn"
+ },
+ "spacing_after_comma": {
+ "level": "warn"
+ },
+ "transform_messes_up_line_numbers": {
+ "level": "warn"
+ }
+}
+
diff --git a/actionview/lib/action_view/gem_version.rb b/actionview/lib/action_view/gem_version.rb
index 5fc4f3f1b9..662a85f191 100644
--- a/actionview/lib/action_view/gem_version.rb
+++ b/actionview/lib/action_view/gem_version.rb
@@ -8,7 +8,7 @@ module ActionView
MAJOR = 5
MINOR = 1
TINY = 0
- PRE = "alpha"
+ PRE = "beta1"
STRING = [MAJOR, MINOR, TINY, PRE].compact.join(".")
end
diff --git a/actionview/lib/action_view/helpers/sanitize_helper.rb b/actionview/lib/action_view/helpers/sanitize_helper.rb
index 1e9b813d3d..0abd5bc5dc 100644
--- a/actionview/lib/action_view/helpers/sanitize_helper.rb
+++ b/actionview/lib/action_view/helpers/sanitize_helper.rb
@@ -13,6 +13,7 @@ module ActionView
# It also strips href/src attributes with unsafe protocols like
# <tt>javascript:</tt>, while also protecting against attempts to use Unicode,
# ASCII, and hex character references to work around these protocol filters.
+ # All special characters will be escaped.
#
# The default sanitizer is Rails::Html::WhiteListSanitizer. See {Rails HTML
# Sanitizers}[https://github.com/rails/rails-html-sanitizer] for more information.
@@ -20,8 +21,7 @@ module ActionView
# Custom sanitization rules can also be provided.
#
# Please note that sanitizing user-provided text does not guarantee that the
- # resulting markup is valid or even well-formed. For example, the output may still
- # contain unescaped characters like <tt><</tt>, <tt>></tt>, or <tt>&</tt>.
+ # resulting markup is valid or even well-formed.
#
# ==== Options
#
@@ -86,7 +86,7 @@ module ActionView
self.class.white_list_sanitizer.sanitize_css(style)
end
- # Strips all HTML tags from +html+, including comments.
+ # Strips all HTML tags from +html+, including comments and special characters.
#
# strip_tags("Strip <i>these</i> tags!")
# # => Strip these tags!
@@ -96,8 +96,11 @@ module ActionView
#
# strip_tags("<div id='top-bar'>Welcome to my website!</div>")
# # => Welcome to my website!
+ #
+ # strip_tags("> A quote from Smith & Wesson")
+ # # => &gt; A quote from Smith &amp; Wesson
def strip_tags(html)
- self.class.full_sanitizer.sanitize(html, encode_special_chars: false)
+ self.class.full_sanitizer.sanitize(html)
end
# Strips all link tags from +html+ leaving just the link text.
@@ -110,6 +113,9 @@ module ActionView
#
# strip_links('Blog: <a href="http://www.myblog.com/" class="nav" target=\"_blank\">Visit</a>.')
# # => Blog: Visit.
+ #
+ # strip_links('<<a href="https://example.org">malformed & link</a>')
+ # # => &lt;malformed &amp; link
def strip_links(html)
self.class.link_sanitizer.sanitize(html)
end
diff --git a/actionview/lib/action_view/test_case.rb b/actionview/lib/action_view/test_case.rb
index 2b981caa65..ae4fec4337 100644
--- a/actionview/lib/action_view/test_case.rb
+++ b/actionview/lib/action_view/test_case.rb
@@ -124,6 +124,10 @@ module ActionView
@_rendered_views ||= RenderedViewsCollection.new
end
+ def _routes
+ @controller._routes if @controller.respond_to?(:_routes)
+ end
+
# Need to experiment if this priority is the best one: rendered => output_buffer
class RenderedViewsCollection
def initialize
@@ -258,10 +262,6 @@ module ActionView
end]
end
- def _routes
- @controller._routes if @controller.respond_to?(:_routes)
- end
-
def method_missing(selector, *args)
begin
routes = @controller.respond_to?(:_routes) && @controller._routes
diff --git a/actionview/package.json b/actionview/package.json
index ec3306c299..a1da13315e 100644
--- a/actionview/package.json
+++ b/actionview/package.json
@@ -1,6 +1,6 @@
{
"name": "rails-ujs",
- "version": "0.0.1",
+ "version": "5.1.0-beta1",
"description": "Ruby on Rails unobtrusive scripting adapter",
"main": "lib/assets/compiled/rails-ujs.js",
"files": [
@@ -12,7 +12,7 @@
"scripts": {
"build": "bundle exec blade build",
"test": "echo \"See the README: https://github.com/rails/rails-ujs#how-to-run-tests\" && exit 1",
- "lint": "coffeelint src && eslint test/public/test",
+ "lint": "coffeelint app/assets/javascripts && eslint test/public/test"
},
"repository": {
"type": "git",
diff --git a/actionview/test/activerecord/polymorphic_routes_test.rb b/actionview/test/activerecord/polymorphic_routes_test.rb
index dcad0b424c..e99c769dc2 100644
--- a/actionview/test/activerecord/polymorphic_routes_test.rb
+++ b/actionview/test/activerecord/polymorphic_routes_test.rb
@@ -86,8 +86,7 @@ class PolymorphicRoutesTest < ActionController::TestCase
def test_string
with_test_routes do
- # FIXME: why are these different? Symbol case passes through to
- # `polymorphic_url`, but the String case doesn't.
+ assert_equal "/projects", polymorphic_path("projects")
assert_equal "http://example.com/projects", polymorphic_url("projects")
assert_equal "projects", url_for("projects")
end
diff --git a/actionview/test/template/date_helper_test.rb b/actionview/test/template/date_helper_test.rb
index bfd3ecd6fd..d257147e1f 100644
--- a/actionview/test/template/date_helper_test.rb
+++ b/actionview/test/template/date_helper_test.rb
@@ -832,7 +832,7 @@ class DateHelperTest < ActionView::TestCase
def test_select_date_with_too_big_range_between_start_year_and_end_year
assert_raise(ArgumentError) { select_date(Time.mktime(2003, 8, 16), start_year: 2000, end_year: 20000, prefix: "date[first]", order: [:month, :day, :year]) }
- assert_raise(ArgumentError) { select_date(Time.mktime(2003, 8, 16), start_year: Date.today.year - 100.years, end_year: 2000, prefix: "date[first]", order: [:month, :day, :year]) }
+ assert_raise(ArgumentError) { select_date(Time.mktime(2003, 8, 16), start_year: 100, end_year: 2000, prefix: "date[first]", order: [:month, :day, :year]) }
end
def test_select_date_can_have_more_then_1000_years_interval_if_forced_via_parameter
diff --git a/actionview/test/template/erb/tag_helper_test.rb b/actionview/test/template/erb/tag_helper_test.rb
index 84e328d8be..233f37c48a 100644
--- a/actionview/test/template/erb/tag_helper_test.rb
+++ b/actionview/test/template/erb/tag_helper_test.rb
@@ -18,8 +18,8 @@ module ERBTest
end
test "percent equals works with form tags" do
- expected_output = %r{<form.*action="foo".*method="post">.*hello*</form>}
- assert_match expected_output, render_content("form_tag('foo')", "<%= 'hello' %>")
+ expected_output = %r{<form.*action="/foo".*method="post">.*hello*</form>}
+ assert_match expected_output, render_content("form_tag('/foo')", "<%= 'hello' %>")
end
test "percent equals works with fieldset tags" do
diff --git a/actionview/test/template/form_helper_test.rb b/actionview/test/template/form_helper_test.rb
index 490df5e4d9..b3a180b28a 100644
--- a/actionview/test/template/form_helper_test.rb
+++ b/actionview/test/template/form_helper_test.rb
@@ -257,11 +257,11 @@ class FormHelperTest < ActionView::TestCase
end
def test_label_with_non_active_record_object
- form_for(OpenStruct.new(name: "ok"), as: "person", url: "an_url", html: { id: "create-person" }) do |f|
+ form_for(OpenStruct.new(name: "ok"), as: "person", url: "/an", html: { id: "create-person" }) do |f|
f.label(:name)
end
- expected = whole_form("an_url", "create-person", "new_person", method: "post") do
+ expected = whole_form("/an", "create-person", "new_person", method: "post") do
'<label for="person_name">Name</label>'
end
diff --git a/actionview/test/template/sanitize_helper_test.rb b/actionview/test/template/sanitize_helper_test.rb
index c8963fee9c..11ed55456f 100644
--- a/actionview/test/template/sanitize_helper_test.rb
+++ b/actionview/test/template/sanitize_helper_test.rb
@@ -10,6 +10,7 @@ class SanitizeHelperTest < ActionView::TestCase
assert_equal "on my mind\nall day long", strip_links("<a href='almost'>on my mind</a>\n<A href='almost'>all day long</A>")
assert_equal "Magic", strip_links("<a href='http://www.rubyonrails.com/'>Mag<a href='http://www.ruby-lang.org/'>ic")
assert_equal "My mind\nall <b>day</b> long", strip_links("<a href='almost'>My mind</a>\n<A href='almost'>all <b>day</b> long</A>")
+ assert_equal "&lt;malformed &amp; link", strip_links('<<a href="https://example.org">malformed & link</a>')
end
def test_sanitize_form
@@ -26,6 +27,7 @@ class SanitizeHelperTest < ActionView::TestCase
assert_equal("Dont touch me", strip_tags("Dont touch me"))
assert_equal("This is a test.", strip_tags("<p>This <u>is<u> a <a href='test.html'><strong>test</strong></a>.</p>"))
assert_equal "This has a here.", strip_tags("This has a <!-- comment --> here.")
+ assert_equal("Jekyll &amp; Hyde", strip_tags("Jekyll & Hyde"))
assert_equal "", strip_tags("<script>")
end
diff --git a/actionview/test/ujs/config.ru b/actionview/test/ujs/config.ru
index 414c2063c3..48b7a4b53a 100644
--- a/actionview/test/ujs/config.ru
+++ b/actionview/test/ujs/config.ru
@@ -1,3 +1,4 @@
$LOAD_PATH.unshift File.expand_path("..", __FILE__)
require "server"
+
run UJS::Server
diff --git a/actionview/test/ujs/public/test/call-remote-callbacks.js b/actionview/test/ujs/public/test/call-remote-callbacks.js
index 082d10bfbd..707e21541d 100644
--- a/actionview/test/ujs/public/test/call-remote-callbacks.js
+++ b/actionview/test/ujs/public/test/call-remote-callbacks.js
@@ -108,202 +108,6 @@ asyncTest('stopping the "ajax:beforeSend" event aborts the request', 1, function
})
})
-asyncTest('blank required form input field should abort request and trigger "ajax:aborted:required" event', 5, function() {
- $(document).bind('iframe:loading', function() {
- ok(false, 'form should not get submitted')
- })
-
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .append($('<textarea name="user_bio" required="required"></textarea>'))
- .bindNative('ajax:beforeSend', function() {
- ok(false, 'ajax:beforeSend should not run')
- })
- .bindNative('ajax:aborted:required', function(e, data) {
- data = $(data)
- ok(data.length == 2, 'ajax:aborted:required event is passed all blank required inputs (jQuery objects)')
- ok(data.first().is('input[name="user_name"]'), 'ajax:aborted:required adds blank required input to data')
- ok(data.last().is('textarea[name="user_bio"]'), 'ajax:aborted:required adds blank required textarea to data')
- ok(true, 'ajax:aborted:required should run')
- })
- .triggerNative('submit')
-
- setTimeout(function() {
- form.find('input[required],textarea[required]').val('Tyler')
- form.unbind('ajax:beforeSend')
- submit()
- }, 13)
-})
-
-asyncTest('blank required form input for non-remote form should abort normal submission', 1, function() {
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .removeAttr('data-remote')
- .bindNative('ujs:everythingStopped', function() {
- ok(true, 'ujs:everythingStopped should run')
- })
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('form should be submitted with blank required fields if handler is bound to "ajax:aborted:required" event that returns false', 1, function() {
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .bindNative('ajax:beforeSend', function() {
- ok(true, 'ajax:beforeSend should run')
- })
- .bindNative('ajax:aborted:required', function() {
- return false
- })
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('disabled fields should not be included in blank required check', 2, function() {
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required" disabled="disabled">'))
- .append($('<textarea name="user_bio" required="required" disabled="disabled"></textarea>'))
- .bindNative('ajax:beforeSend', function() {
- ok(true, 'ajax:beforeSend should run')
- })
- .bindNative('ajax:aborted:required', function() {
- ok(false, 'ajax:aborted:required should not run')
- })
-
- submit()
-})
-
-asyncTest('form should be submitted with blank required fields if it has the "novalidate" attribute', 2, function() {
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .attr('novalidate', 'novalidate')
- .bindNative('ajax:beforeSend', function() {
- ok(true, 'ajax:beforeSend should run')
- })
- .bindNative('ajax:aborted:required', function() {
- ok(false, 'ajax:aborted:required should not run')
- })
-
- submit()
-})
-
-asyncTest('form should be submitted with blank required fields if the button has the "formnovalidate" attribute', 2, function() {
- var submit_button = $('<input type="submit" formnovalidate>')
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .append(submit_button)
- .bindNative('ajax:beforeSend', function() {
- ok(true, 'ajax:beforeSend should run')
- })
- .bindNative('ajax:aborted:required', function() {
- ok(false, 'ajax:aborted:required should not run')
- })
-
- submit_with_button(submit_button)
-})
-
-asyncTest('blank required form input for non-remote form with "novalidate" attribute should not abort normal submission', 1, function() {
- $(document).bind('iframe:loading', function() {
- ok(true, 'form should get submitted')
- })
-
- var form = $('form[data-remote]')
- .append($('<input type="text" name="user_name" required="required">'))
- .removeAttr('data-remote')
- .attr('novalidate', 'novalidate')
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('unchecked required checkbox should abort form submission', 1, function() {
- var form = $('form[data-remote]')
- .append($('<input type="checkbox" name="agree" required="required">'))
- .removeAttr('data-remote')
- .bindNative('ujs:everythingStopped', function() {
- ok(true, 'ujs:everythingStopped should run')
- })
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('unchecked required radio should abort form submission', 3, function() {
- var form = $('form[data-remote]')
- .append($('<input type="radio" name="yes_no_none" required="required" value=1>'))
- .append($('<input type="radio" name="yes_no_none" required="required" value=2>'))
- .removeAttr('data-remote')
- .bindNative('ujs:everythingStopped', function() {
- ok(true, 'ujs:everythingStopped should run')
- })
- .bindNative('ajax:aborted:required', function(e, data) {
- data = $(data)
- equal(data.length, 2, 'blankRequiredInputs should include both radios')
- ok(data.first().is('input[type=radio][value=1]'), 'blankRequiredInputs[0] should be the first radio')
- })
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('required radio should only require one to be checked', 1, function() {
- $(document).bind('iframe:loading', function() {
- ok(true, 'form should get submitted')
- })
-
- var form = $('form[data-remote]')
- .append($('<input type="radio" name="yes_no" required="required" value=1 id="checkme">'))
- .append($('<input type="radio" name="yes_no" required="required" value=2>'))
- .removeAttr('data-remote')
- .bindNative('ujs:everythingStopped', function() {
- ok(false, 'ujs:everythingStopped should not run')
- })
- .find('#checkme').prop('checked', true)
- .end()
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
-asyncTest('required radio should only require one to be checked if not all radios are required', 1, function() {
- $(document).bind('iframe:loading', function() {
- ok(true, 'form should get submitted')
- })
-
- var form = $('form[data-remote]')
- // Check the radio that is not required
- .append($('<input type="radio" name="yes_no_maybe" value=1 >'))
- // Check the radio that is not required
- .append($('<input type="radio" name="yes_no_maybe" value=2 id="checkme">'))
- // Only one needs to be required
- .append($('<input type="radio" name="yes_no_maybe" required="required" value=3>'))
- .removeAttr('data-remote')
- .bindNative('ujs:everythingStopped', function() {
- ok(false, 'ujs:everythingStopped should not run')
- })
- .find('#checkme').prop('checked', true)
- .end()
- .triggerNative('submit')
-
- setTimeout(function() {
- start()
- }, 13)
-})
-
function skipIt() {
// This test cannot work due to the security feature in browsers which makes the value
// attribute of file input fields readonly, so it cannot be set with default value.
diff --git a/actionview/test/ujs/public/test/data-remote.js b/actionview/test/ujs/public/test/data-remote.js
index a51aa10417..b756add24e 100644
--- a/actionview/test/ujs/public/test/data-remote.js
+++ b/actionview/test/ujs/public/test/data-remote.js
@@ -73,7 +73,6 @@ asyncTest('clicking on a link with data-remote attribute', 5, function() {
.bindNative('ajax:success', function(e, data, status, xhr) {
App.assertCallbackInvoked('ajax:success')
App.assertRequestPath(data, '/echo')
- console.log(data.params)
equal(data.params.data1, 'value1', 'ajax arguments should have key data1 with right value')
equal(data.params.data2, 'value2', 'ajax arguments should have key data2 with right value')
App.assertGetRequest(data)
@@ -398,3 +397,19 @@ asyncTest('form should be serialized correctly', 6, function() {
})
.triggerNative('submit')
})
+
+asyncTest('form buttons should only be serialized when clicked', 4, function() {
+ $('form')
+ .append('<input type="submit" name="submit1" value="submit1" />')
+ .append('<button name="submit2" value="submit2" />')
+ .append('<button name="submit3" value="submit3" />')
+ .bindNative('ajax:success', function(e, data, status, xhr) {
+ equal(data.params.submit1, undefined)
+ equal(data.params.submit2, 'submit2')
+ equal(data.params.submit3, undefined)
+ equal(data['rack.request.form_vars'], 'user_name=john&submit2=submit2')
+
+ start()
+ })
+ .find('[name=submit2]').triggerNative('click')
+})
diff --git a/actionview/test/ujs/public/test/override.js b/actionview/test/ujs/public/test/override.js
index be6ec7749b..299c7018cc 100644
--- a/actionview/test/ujs/public/test/override.js
+++ b/actionview/test/ujs/public/test/override.js
@@ -46,7 +46,7 @@ asyncTest('the event selector strings are overridable', 1, function() {
start()
})
-asyncTest('including jquery-ujs multiple times throws error', 1, function() {
+asyncTest('including rails-ujs multiple times throws error', 1, function() {
throws(function() {
Rails.start()
}, 'appending rails.js again throws error')
diff --git a/actionview/test/ujs/public/test/settings.js b/actionview/test/ujs/public/test/settings.js
index c68ca24d6a..299c71bb00 100644
--- a/actionview/test/ujs/public/test/settings.js
+++ b/actionview/test/ujs/public/test/settings.js
@@ -63,12 +63,12 @@ $(document).bind('submit', function(e) {
}
})
-var MouseEvent = window.MouseEvent
+var _MouseEvent = window.MouseEvent
try {
- new MouseEvent()
+ new _MouseEvent()
} catch (e) {
- MouseEvent = function(type, options) {
+ _MouseEvent = function(type, options) {
var evt = document.createEvent('MouseEvents')
evt.initMouseEvent(type, options.bubbles, options.cancelable, window, options.detail, 0, 0, 80, 20, options.ctrlKey, options.altKey, options.shiftKey, options.metaKey, 0, null)
return evt
@@ -81,7 +81,7 @@ $.fn.extend({
var el = this[0],
event,
Evt = {
- 'click': MouseEvent,
+ 'click': _MouseEvent,
'change': Event,
'pageshow': PageTransitionEvent,
'submit': Event
diff --git a/actionview/test/ujs/server.rb b/actionview/test/ujs/server.rb
index 25f70baf5f..7deb208af0 100644
--- a/actionview/test/ujs/server.rb
+++ b/actionview/test/ujs/server.rb
@@ -1,11 +1,10 @@
+require "rack"
require "rails"
require "action_controller/railtie"
require "action_view/railtie"
require "blade"
require "json"
-JQUERY_VERSIONS = %w[ 1.8.0 1.8.1 1.8.2 1.8.3 1.9.0 1.9.1 1.10.0 1.10.1 1.10.2 1.11.0 2.0.0 2.1.0].freeze
-
module UJS
class Server < Rails::Application
routes.append do
@@ -18,7 +17,7 @@ module UJS
config.cache_classes = false
config.eager_load = false
config.secret_key_base = "59d7a4dbd349fa3838d79e330e39690fc22b931e7dc17d9162f03d633d526fbb92dfdb2dc9804c8be3e199631b9c1fbe43fc3e4fc75730b515851849c728d5c7"
- config.paths["app/views"].unshift("#{Rails.root / "views"}")
+ config.paths["app/views"].unshift("#{Rails.root}/views")
config.public_file_server.enabled = true
config.logger = Logger.new(STDOUT)
config.log_level = :error
@@ -26,32 +25,6 @@ module UJS
end
module TestsHelper
- def jquery_link(version)
- if params[:version] == version
- "[#{version}]"
- else
- "<a href='/?version=#{version}&cdn=#{params[:cdn]}'>#{version}</a>".html_safe
- end
- end
-
- def cdn_link(cdn)
- if params[:cdn] == cdn
- "[#{cdn}]"
- else
- "<a href='/?version=#{params[:version]}&cdn=#{cdn}'>#{cdn}</a>".html_safe
- end
- end
-
- def jquery_src
- if params[:version] == "edge"
- "/vendor/jquery.js"
- elsif params[:cdn] && params[:cdn] == "googleapis"
- "https://ajax.googleapis.com/ajax/libs/jquery/#{params[:version]}/jquery.min.js"
- else
- "http://code.jquery.com/jquery-#{params[:version]}.js"
- end
- end
-
def test_to(*names)
names = ["/vendor/qunit.js", "settings"] + names
names.map { |name| script_tag name }.join("\n").html_safe
@@ -61,10 +34,6 @@ module TestsHelper
src = "/test/#{src}.js" unless src.index("/")
%(<script src="#{src}" type="text/javascript"></script>).html_safe
end
-
- def jquery_versions
- JQUERY_VERSIONS
- end
end
class TestsController < ActionController::Base
@@ -72,8 +41,6 @@ class TestsController < ActionController::Base
layout "application"
def index
- params[:version] ||= ENV["JQUERY_VERSION"] || "1.11.0"
- params[:cdn] ||= "jquery"
render :index
end
diff --git a/actionview/test/ujs/views/layouts/application.html.erb b/actionview/test/ujs/views/layouts/application.html.erb
index 74fa3bd06d..a69cd2d739 100644
--- a/actionview/test/ujs/views/layouts/application.html.erb
+++ b/actionview/test/ujs/views/layouts/application.html.erb
@@ -3,30 +3,15 @@
<head>
<title><%= @title %></title>
<link href="/vendor/qunit.css" media="screen" rel="stylesheet" type="text/css" media="screen, projection" />
- <style>
- #jquery-cdn, #jquery-version {
- padding: 0 2em .8em 0;
- text-align: right;
- font-family: sans-serif;
- line-height: 1;
- color: #8699A4;
- background-color: #0d3349;
- }
- #jquery-cdn a, #jquery-version a {
- color: white;
- text-decoration: underline;
- }
- </style>
-
- <%= script_tag jquery_src %>
+ <%= script_tag "http://code.jquery.com/jquery-2.2.0.js" %>
<script>
// This is for test in override.js.
- // Must go after jQuery is loaded, but before jquery-ujs.
- $(document).bind('rails:attachBindings', function() {
- $.rails.linkClickSelector += ', a[data-custom-remote-link]';
+ // Must go before rails-ujs.
+ document.addEventListener('rails:attachBindings', function() {
+ window.Rails.linkClickSelector += ', a[data-custom-remote-link]';
// Hijacks link click before ujs binds any handlers
// This is only used for ctrl-clicking test on remote links
- $.rails.delegate(document, '#qunit-fixture a', 'click', function(e) {
+ window.Rails.delegate(document, '#qunit-fixture a', 'click', function(e) {
e.preventDefault();
});
});
diff --git a/actionview/test/ujs/views/tests/index.html.erb b/actionview/test/ujs/views/tests/index.html.erb
index 393a5ee235..8de6cd0695 100644
--- a/actionview/test/ujs/views/tests/index.html.erb
+++ b/actionview/test/ujs/views/tests/index.html.erb
@@ -1,22 +1,8 @@
-<% @title = "jquery-ujs test" %>
+<% @title = "rails-ujs test" %>
<%= test_to 'data-confirm', 'data-remote', 'data-disable', 'data-disable-with', 'call-remote', 'call-remote-callbacks', 'data-method', 'override', 'csrf-refresh', 'csrf-token' %>
<h1 id="qunit-header"><%= @title %></h1>
-<div id="jquery-cdn">
- CDN:
- <%= cdn_link 'jquery' %> •
- <%= cdn_link 'googleapis' %>
-</div>
-<div id="jquery-version">
- jQuery version:
-
- <% jquery_versions.each do |v| %>
- <%= ' • ' if v != jquery_versions.first %>
- <%= jquery_link v %>
- <% end %>
- <%= (' • ' + jquery_link('edge')) if File.exist?(Rails.root + '/public/vendor/jquery.js') %>
-</div>
<h2 id="qunit-banner"></h2>
<div id="qunit-testrunner-toolbar"></div>
<h2 id="qunit-userAgent"></h2>