| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Prevents two string allocations per method call for common REST verbs
plus a ~1.5x speedup for :get in particular
```ruby
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update
your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
gem "rails"
end
def allocate_count
GC.disable
before = ObjectSpace.count_objects
yield
after = ObjectSpace.count_objects
after.each { |k,v| after[k] = v - before[k] }
after[:T_HASH] -= 1 # probe effect - we created the before hash.
GC.enable
result = after.reject { |k,v| v == 0 }
GC.start
result
end
@html_options = {}
def master_version
if @method && @method.to_s.downcase != "get" && @html_options["rel".freeze] !~ /nofollow/
@html_options["rel".freeze] = "#{@html_options["rel".freeze]} nofollow".lstrip
end
@html_options["data-method".freeze] = @method
end
def fast_version
if method_not_get_method?(@method) && @html_options["rel".freeze] !~ /nofollow/
@html_options["rel".freeze] = "#{@html_options["rel".freeze]} nofollow".lstrip
end
@html_options["data-method".freeze] = @method
end
STRINGIFIED_COMMON_METHODS = {
get: 'get',
delete: 'delete',
patch: 'patch',
post: 'post',
put: 'put',
}.freeze
def method_not_get_method?(method)
return false unless method
(STRINGIFIED_COMMON_METHODS[method] || method.to_s.downcase) != 'get'
end
puts 'get'
@method = :get
puts "master_version"
puts allocate_count { 1000.times { master_version } }
puts "fast_version"
puts allocate_count { 1000.times { fast_version } }
Benchmark.ips do |x|
x.report("master_version") { master_version }
x.report("fast_version") { fast_version }
x.compare!
end
puts 'delete'
@method = :delete
puts "master_version"
puts allocate_count { 1000.times { master_version } }
puts "fast_version"
puts allocate_count { 1000.times { fast_version } }
Benchmark.ips do |x|
x.report("master_version") { master_version }
x.report("fast_version") { fast_version }
x.compare!
end
```
```
get
master_version
{:FREE=>-1819, :T_STRING=>2052}
fast_version
{:FREE=>-1}
Warming up --------------------------------------
master_version 140.839k i/100ms
fast_version 175.639k i/100ms
Calculating -------------------------------------
master_version 2.683M (± 7.1%) i/s - 13.380M in 5.013447s
fast_version 3.988M (±10.1%) i/s - 19.847M in 5.039580s
Comparison:
fast_version: 3988340.3 i/s
master_version: 2683336.2 i/s - 1.49x slower
delete
master_version
{:FREE=>-5003, :T_STRING=>3003, :T_MATCH=>999, :T_IMEMO=>1000}
fast_version
{:FREE=>-3002, :T_STRING=>1001, :T_MATCH=>1000, :T_IMEMO=>1000}
Warming up --------------------------------------
master_version 47.221k i/100ms
fast_version 44.153k i/100ms
Calculating -------------------------------------
master_version 597.881k (±11.4%) i/s - 2.975M in 5.047200s
fast_version 686.014k (±11.6%) i/s - 3.400M in 5.036564s
Comparison:
fast_version: 686014.5 i/s
master_version: 597881.4 i/s - same-ish: difference falls within error
```
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This allows us to prevent an extra string allocation when there is a rel
argument and performs better/within error of the key check for other
scenarios such as passing in rel: nil
```ruby
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update
your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
gem "rails"
end
def allocate_count
GC.disable
before = ObjectSpace.count_objects
yield
after = ObjectSpace.count_objects
after.each { |k,v| after[k] = v - before[k] }
after[:T_HASH] -= 1 # probe effect - we created the before hash.
GC.enable
result = after.reject { |k,v| v == 0 }
GC.start
result
end
@hash = {}
def master_version
"#{@hash["rel"]} nofollow".lstrip
end
def key_version
if @hash.key?("rel")
"#{@hash["rel"]} nofollow".lstrip
else
"nofollow"
end
end
def present_version
if @hash["rel"].present?
"#{@hash["rel"]} nofollow"
else
"nofollow".freeze
end
end
def nil_version
if @hash["rel"].nil?
"nofollow".freeze
else
"#{@hash["rel"]} nofollow"
end
end
def blank_version
if @hash["rel"].blank?
"nofollow".freeze
else
"#{@hash["rel"]} nofollow"
end
end
def test
puts "master_version"
puts allocate_count { 1000.times { master_version } }
puts "key_version"
puts allocate_count { 1000.times { key_version } }
puts "present_version"
puts allocate_count { 1000.times { present_version } }
puts "nil_version"
puts allocate_count { 1000.times { nil_version } }
puts "blank_version"
puts allocate_count { 1000.times { blank_version } }
Benchmark.ips do |x|
x.report("master_version") { master_version }
x.report("key_version") { key_version }
x.report("present_version") { present_version }
x.report("nil_version") { nil_version }
x.report("blank_version") { blank_version }
x.compare!
end
end
puts 'no rel key'
test
puts 'rel key with real stuff'
@hash['rel'] = 'hi'.freeze
test
puts 'rel key with nil'
@hash['rel'] = nil
test
puts 'rel key with ""'
@hash['rel'] = ""
test
```
```
no rel key
master_version
{:FREE=>-2818, :T_STRING=>3052}
key_version
{:FREE=>-1}
present_version
{:FREE=>-1}
nil_version
{:FREE=>-1}
blank_version
{:FREE=>-1}
Warming up --------------------------------------
master_version 124.677k i/100ms
key_version 227.992k i/100ms
present_version 208.068k i/100ms
nil_version 235.272k i/100ms
blank_version 176.274k i/100ms
Calculating -------------------------------------
master_version 1.968M (±10.8%) i/s - 9.725M in 5.010763s
key_version 7.734M (±11.2%) i/s - 38.075M in 5.001613s
present_version 5.688M (±11.4%) i/s - 28.089M in 5.019560s
nil_version 6.965M (±10.2%) i/s - 34.585M in 5.024806s
blank_version 6.139M (±18.7%) i/s - 29.085M in 5.010919s
Comparison:
key_version: 7734058.3 i/s
nil_version: 6965050.2 i/s - same-ish: difference falls within error
blank_version: 6138744.3 i/s - same-ish: difference falls within error
present_version: 5688248.4 i/s - 1.36x slower
master_version: 1967932.3 i/s - 3.93x slower
rel key with real stuff
master_version
{:FREE=>-2001, :T_STRING=>2000}
key_version
{:FREE=>-2001, :T_STRING=>2000}
present_version
{:FREE=>-1001, :T_STRING=>1000}
nil_version
{:FREE=>-1002, :T_STRING=>1000, :T_IMEMO=>1}
blank_version
{:FREE=>-1001, :T_STRING=>1000}
Warming up --------------------------------------
master_version 93.351k i/100ms
key_version 89.747k i/100ms
present_version 91.963k i/100ms
nil_version 103.370k i/100ms
blank_version 74.845k i/100ms
Calculating -------------------------------------
master_version 2.179M (±21.4%) i/s - 10.362M in 5.044668s
key_version 2.345M (± 9.8%) i/s - 11.667M in 5.030982s
present_version 1.738M (±14.8%) i/s - 8.553M in 5.056406s
nil_version 2.485M (±19.1%) i/s - 11.888M in 5.015940s
blank_version 1.951M (±12.3%) i/s - 9.580M in 5.011932s
Comparison:
nil_version: 2484704.1 i/s
key_version: 2344664.8 i/s - same-ish: difference falls within error
master_version: 2178975.8 i/s - same-ish: difference falls within error
blank_version: 1950532.0 i/s - same-ish: difference falls within error
present_version: 1737866.7 i/s - 1.43x slower
rel key with nil
master_version
{:FREE=>-3001, :T_STRING=>3000}
key_version
{:FREE=>-3001, :T_STRING=>3000}
present_version
{:FREE=>-1}
nil_version
{:FREE=>-1}
blank_version
{:FREE=>-1}
Warming up --------------------------------------
master_version 112.655k i/100ms
key_version 105.048k i/100ms
present_version 136.219k i/100ms
nil_version 192.026k i/100ms
blank_version 184.846k i/100ms
Calculating -------------------------------------
master_version 1.893M (±12.6%) i/s - 9.238M in 5.002621s
key_version 1.672M (±13.5%) i/s - 8.194M in 5.021197s
present_version 4.484M (±20.5%) i/s - 21.114M in 5.002982s
nil_version 5.294M (±18.1%) i/s - 25.155M in 5.020721s
blank_version 5.588M (± 6.7%) i/s - 27.912M in 5.019305s
Comparison:
blank_version: 5588489.6 i/s
nil_version: 5293929.9 i/s - same-ish: difference falls within error
present_version: 4484493.7 i/s - same-ish: difference falls within error
master_version: 1892919.0 i/s - 2.95x slower
key_version: 1672343.9 i/s - 3.34x slower
rel key with ""
master_version
{:FREE=>-2001, :T_STRING=>2000}
key_version
{:FREE=>-2001, :T_STRING=>2000}
present_version
{:FREE=>-1}
nil_version
{:FREE=>-1001, :T_STRING=>1000}
blank_version
{:FREE=>-1}
Warming up --------------------------------------
master_version 140.499k i/100ms
key_version 124.738k i/100ms
present_version 186.659k i/100ms
nil_version 148.063k i/100ms
blank_version 178.707k i/100ms
Calculating -------------------------------------
master_version 1.826M (±24.2%) i/s - 8.289M in 5.026603s
key_version 1.561M (±15.3%) i/s - 7.609M in 5.005662s
present_version 3.622M (±19.9%) i/s - 17.173M in 5.042217s
nil_version 2.438M (±11.5%) i/s - 12.141M in 5.053335s
blank_version 4.911M (±15.5%) i/s - 23.768M in 5.009106s
Comparison:
blank_version: 4910741.1 i/s
present_version: 3622183.5 i/s - same-ish: difference falls within error
nil_version: 2437606.2 i/s - 2.01x slower
master_version: 1825652.2 i/s - 2.69x slower
key_version: 1560530.5 i/s - 3.15x slower
```
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Do a check if the 'rel' argument is passed in, and simply set it to
'nofollow' if 'rel' was not passed in. This prevents three string
allocations for each call to `link_to` in that scenario. In the scenario
where the 'rel' argument is passed in, performance is around the same as
before as the `key?` check is very fast.
```ruby
begin
require "bundler/inline"
rescue LoadError => e
$stderr.puts "Bundler version 1.10 or later is required. Please update
your Bundler"
raise e
end
gemfile(true) do
source "https://rubygems.org"
gem "benchmark-ips"
gem "rails"
end
def allocate_count
GC.disable
before = ObjectSpace.count_objects
yield
after = ObjectSpace.count_objects
after.each { |k,v| after[k] = v - before[k] }
after[:T_HASH] -= 1 # probe effect - we created the before hash.
GC.enable
result = after.reject { |k,v| v == 0 }
GC.start
result
end
@hash = {}
def master_version
"#{@hash['rel'.freeze]} nofollow".lstrip
end
def fast_version
if @hash.key?('rel'.freeze)
"#{@hash["rel"]} nofollow".lstrip
else
"nofollow".freeze
end
end
puts 'no rel key'
puts "master_version"
puts allocate_count { 1000.times { master_version } }
puts "fast_version"
puts allocate_count { 1000.times { fast_version } }
Benchmark.ips do |x|
x.report("master_version") { master_version }
x.report("fast_version") { fast_version }
x.compare!
end
puts 'rel key'
@hash['rel'] = 'hi'.freeze
puts "master_version"
puts allocate_count { 1000.times { master_version } }
puts "fast_version"
puts allocate_count { 1000.times { fast_version } }
Benchmark.ips do |x|
x.report("master_version") { master_version }
x.report("fast_version") { fast_version }
x.compare!
end
```
```
no rel key
master_version
{:FREE=>-2791, :T_STRING=>3052}
fast_version
{:FREE=>-1}
Warming up --------------------------------------
master_version 80.324k i/100ms
fast_version 200.262k i/100ms
Calculating -------------------------------------
master_version 2.049M (±11.9%) i/s - 10.121M in 5.025613s
fast_version 6.645M (±21.3%) i/s - 29.439M in 5.007488s
Comparison:
fast_version: 6644506.3 i/s
master_version: 2048833.0 i/s - 3.24x slower
rel key
master_version
{:FREE=>-2001, :T_STRING=>2000}
fast_version
{:FREE=>-2001, :T_STRING=>2000}
Warming up --------------------------------------
master_version 155.673k i/100ms
fast_version 106.515k i/100ms
Calculating -------------------------------------
master_version 2.652M (±20.4%) i/s - 12.610M in 5.036494s
fast_version 2.237M (±16.8%) i/s - 10.865M in 5.035366s
Comparison:
master_version: 2651702.2 i/s
fast_version: 2237470.6 i/s - same-ish: difference falls within error
```
|
|
|
|
| |
This basically reverts c4d1a4efeec6f0b5b58222993aa0bec85a19b6a8
|
| |
|
| |
|
| |
|
|
|
|
|
|
| |
- `check_parameters` kwargs was added to the `current_page?` method, the implementation was assuming only hashes responds to `delete`. This was causing issues when `current_page?` was called with a Active Model object
- ref https://github.com/rails/rails/pull/27549
- Fixes #28846
|
|
|
|
|
| |
Since this protection is now in Parameters we can use it instead of
reimplementing again.
|
| |
|
|
|
|
| |
(I personally prefer writing one string in one line no matter how long it is, though)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Example:
For "http://www.example.com/shop/checkout?order=desc&page=1"
current_page?('http://www.example.com/shop/checkout')
=> true
current_page?(
'http://www.example.com/shop/checkout',
check_parameters: true
)
=> false
|
| |
|
|
|
|
|
| |
Removed references to `button` in the `link_to` `disable_with` api
description.
|
| |
|
|
|
|
|
|
| |
Regexp#match? should be considered to be part of the Ruby core library. We are
emulating it for < 2.4, but not having to require the extension is part of the
illusion of the emulation.
|
|\
| |
| |
| | |
Convert ActionController::Parameters to a hash in button_to
|
|/
|
|
|
|
|
|
|
|
|
| |
Before, an error would be raised saying that the method `to_param` was
undefined on the instance of `ActionController::Parameters`. Now, we are
checking to see if the `params` object being passed to `button_to`
responds to the `permitted?` method, and if so, we will call `to_h` on it. If it
does not respond to `permitted?`, then the `params` will remain
unchanged.
[Jon Moss, Rafael Mendonça França]
|
|
|
|
|
|
|
|
| |
Style/SpaceBeforeBlockBraces
Style/SpaceInsideBlockBraces
Style/SpaceInsideHashLiteralBraces
Fix all violations in the repository.
|
|
|
|
|
| |
The current code base is not uniform. After some discussion,
we have chosen to go with double quotes by default.
|
|
|
|
|
| |
Where appropriate, prefer the more concise Regexp#match?,
String#include?, String#start_with?, or String#end_with?
|
|
|
|
| |
https://github.com/rails/rails/issues/19472
|
|
|
|
|
| |
reduce string allocation.
- Use freezed empty string instead of create one every time we need to return it
|
|
|
|
|
|
| |
When `button_to 'Botton', url` form was being used the per form token
was not correct because the method that is was being used to generate it
was an empty string.
|
|
|
|
|
| |
We only need action and method so pass them explicitly instead of
merging the hash with HTML options.
|
|
|
|
| |
them up.
|
|
|
|
| |
Fixes #23524
|
|
|
|
|
|
| |
In e6e0579defcfcf94ef1c4c1c7659f374a5335cdb the `params` option was added to the `button_to` helper. However, the patch doesn't support nested hashes so `{a: {b: 'c'}}` for example gets turned into a hidden form input with the name 'a' and the value being the string representation of the `{b: 'c'}` nested hash.
Since Rails supports nested hashes everywhere else (and even in the URL params of link_to and button_to), I believe this to be a bug/unfinished feature.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
`link_to :back` creates a link to whatever was
passed in via the referer header. If an attacker
can alter the referer header, that would create
a cross-site scripting vulnerability on every
page that uses `link_to :back`
This commit restricts the back URL to valid
non-javascript URLs.
https://github.com/rails/rails/issues/14444
|
|
|
|
|
|
|
|
| |
`hfvalue` parts should always be percent encoded, so lets do that!
Revert "use path escaping for email addresses"
This reverts commit 21ffef38a5dc5a6a21f7e841aecab5b51f4fd185.
|
|
|
|
|
|
| |
Due to e25fdad2f147e6f368958f9a06a5ac9d10288408, we are correctly using
path escaping for email addresses. This commit fixes the tests to
expect path escaping.
|
|
|
|
|
|
| |
content_tag's first argument is will generate a string with an html tag so `:a` will generate: `<a></a>`. When this happens, the symbol is implicitly `to_s`-d so a new string is allocated. We can get around that by using a frozen string instead which
This change buys us 74,236 bytes of memory and 1,855 fewer objects per request.
|
|
|
|
|
|
| |
No idea why on earth this hash key isn't already optimized by MRI, but it isn't. :shit:
This change buys us 74,077 bytes of memory and 1,852 fewer objects per request.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
stevenspiel/link_to_if_block_helper_addition"
This reverts commit d459b001b43d25053e7982e96eb8383538a6e358, reversing
changes made to 4d4950fae9e2a6970b5f1793aadc56a0b44e28a3.
:sweat:
The block is not supposed to be passed to `link_to`. It's used for a
customized behavior of the `condtion = false` case. The docs
illustrate that like so:
```
<%=
link_to_if(@current_user.nil?, "Login", { controller: "sessions", action: "new" }) do
link_to(@current_user.login, { controller: "accounts", action: "show", id: @current_user })
end
%>
```
|
|
|
| |
add block to link_to_if when condition is true
|
|\
| |
| | |
[ci skip] remove duplicate doc for current_page?
|
| | |
|
| | |
|
|/ |
|
|
|
|
| |
No need to merge hashes when simply setting options does the job.
|
|
|
|
|
|
|
|
| |
This logic was just doing duplicated work, since the button_to helper
relies on tag/content_tag to generate the button html, which already
handles all boolean attributes it knows about.
The code dates back to 2005: 43c470fae468ef63e0d5c3dc1e202925685fd47b.
|
|\
| |
| |
| | |
mail_to helper method fix
|
| |
| |
| |
| |
| | |
when mail_to generate blank options for any passed options(cc, bcc, body, subject)
then MICROSOFT OUTLOOK treats it differently and set wrong values in different options.
|
| |
| |
| |
| |
| |
| | |
The `link_to` helper generates an HTML anchor element (consisting of opening and closing anchor tags and an element body). The docs currently state the a link tag is generated (which would indicate a tag like `<link>`, which is another valid HTML tag), so this change clarifies that an anchor element is actually generated.
[ci skip]
|
|/ |
|
|
|
|
|
|
|
|
|
|
| |
[ci skip]
89ff1f8 and 1de258e6 removed from the HTML generated by the form helpers
the <div> that was wrapping the field elements inside the <form>.
This commit updates the documentation of the methods to reflect the
two commits above.
|
|
|
|
| |
This is generally unnecessary, since tag handles string quoting, except in one case (utf8_enforcer_tag) where we want to specify the encoding ourselves.
|