gr_autolink 1.0.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/.autotest ADDED
@@ -0,0 +1,8 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ Autotest.add_hook :initialize do |at|
6
+ at.testlib = 'minitest/autorun'
7
+ at.find_directories = ARGV unless ARGV.empty?
8
+ end
data/.gemtest ADDED
File without changes
data/CHANGELOG.rdoc ADDED
@@ -0,0 +1,24 @@
1
+ === 1.0.7 / 2012-03-30
2
+
3
+ * forking off into gr_autolink as it will behave differently from parent
4
+ * fixing the bug that makes autolink fail on strings that contain img tags...used to create anchor links in the middle of the img src attributes... :(
5
+ * adding html_safe awareness and escaping of ampersand if incoming string is not html safe
6
+
7
+ === 1.0.6 / 2012-03-12
8
+
9
+ * Added sanitize_options arg
10
+
11
+ === 1.0.5 / 2012-01-27
12
+
13
+ * Update dependency to include rails 3.2.X
14
+
15
+ === 1.0.2 / 2011-06-18
16
+
17
+ * Compatibility with rails 3.1.0.rc4
18
+
19
+ === 1.0.0 / 2011-05-02
20
+
21
+ * 1 major enhancement
22
+
23
+ * Birthday!
24
+
data/Gemfile ADDED
@@ -0,0 +1,7 @@
1
+ source 'http://rubygems.org'
2
+
3
+ gem 'rails'
4
+ gem 'arel'
5
+ gem 'rack'
6
+ gem 'hoe'
7
+ gem 'minitest'
data/Manifest.txt ADDED
@@ -0,0 +1,10 @@
1
+ .autotest
2
+ CHANGELOG.rdoc
3
+ Gemfile
4
+ Manifest.txt
5
+ README.rdoc
6
+ Rakefile
7
+ lib/gr_autolink.rb
8
+ lib/gr_autolink/helpers.rb
9
+ test/test_gr_autolink.rb
10
+ TODO.txt
data/README.rdoc ADDED
@@ -0,0 +1,89 @@
1
+ = gr_autolink
2
+
3
+ * http://github.com/goodreads/gr_autolink
4
+
5
+ == DESCRIPTION:
6
+
7
+ This is an adaptation of the extraction of the `auto_link` method from rails
8
+ that is the rails_autolink gem. The `auto_link`
9
+ method was removed from Rails in version Rails 3.1. This gem is meant to
10
+ bridge the gap for people migrating...and behaves a little differently from the
11
+ parent gem we forked from:
12
+
13
+ * performs html-escaping of characters such as '&' in strings that are getting
14
+ linkified if the incoming string is not html_safe?
15
+ * retains html-safety of incoming string (if input string is unsafe, will return
16
+ unsafe and vice versa)
17
+ * fixes at least one bug:
18
+ (<img src="http://some.u.rl"> => <img src="<a href="http://some.u.rl">http://some.u.rl</a>">)
19
+ though can't imagine this is intended behavior, also have trouble believing that
20
+ this was an open bug in rails...
21
+
22
+ == FEATURES:
23
+
24
+ By default gr_autolink returns retains html-safeness of input strings.
25
+
26
+ This is original gem's behavior and this gem does NOT include this behavio:
27
+
28
+ * This behaviour can be overriden setting the <tt>:sanitize</tt> option to false
29
+ (thus making it insecure if you don't have the content under control).
30
+
31
+ == SYNOPSIS:
32
+
33
+ require 'rails_autolink'
34
+
35
+ auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
36
+ # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
37
+ # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
38
+
39
+ auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
40
+ # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
41
+ # or e-mail david@loudthinking.com"
42
+
43
+ auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
44
+ # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
45
+
46
+ auto_link("Go to http://www.rubyonrails.org <script>Malicious code!</script>")
47
+ # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> "
48
+
49
+ auto_link("Go to http://www.rubyonrails.org <script>alert('Script!')</script>", :sanitize => false)
50
+ # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> <script>alert('Script!')</script>"
51
+
52
+ post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
53
+ auto_link(post_body, :html => { :target => '_blank' }) do |text|
54
+ truncate(text, :length => 15)
55
+ end
56
+ # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
57
+
58
+ == REQUIREMENTS:
59
+
60
+ * rails ~> 3.1
61
+
62
+ == INSTALL:
63
+
64
+ * gem install gr_autolink
65
+
66
+ == LICENSE:
67
+
68
+ (The MIT License)
69
+
70
+ Copyright (c) 2012 Goodreads, Inc.
71
+
72
+ Permission is hereby granted, free of charge, to any person obtaining
73
+ a copy of this software and associated documentation files (the
74
+ 'Software'), to deal in the Software without restriction, including
75
+ without limitation the rights to use, copy, modify, merge, publish,
76
+ distribute, sublicense, and/or sell copies of the Software, and to
77
+ permit persons to whom the Software is furnished to do so, subject to
78
+ the following conditions:
79
+
80
+ The above copyright notice and this permission notice shall be
81
+ included in all copies or substantial portions of the Software.
82
+
83
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
84
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
85
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
86
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
87
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
88
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
89
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1,22 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ Hoe.plugins.delete :rubyforge
7
+ Hoe.plugin :minitest
8
+ Hoe.plugin :gemspec # `gem install hoe-gemspec`
9
+ Hoe.plugin :git # `gem install hoe-git`
10
+
11
+ Hoe.spec 'gr_autolink' do
12
+ developer('Aaron Patterson', 'aaron@tenderlovemaking.com')
13
+ developer('Juanjo Bazan', 'jjbazan@gmail.com')
14
+ developer('Akira Matsuda', 'ronnie@dio.jp')
15
+ developer('Brian Percival', 'bpercival@goodreads.com')
16
+ self.readme_file = 'README.rdoc'
17
+ self.history_file = 'CHANGELOG.rdoc'
18
+ self.extra_rdoc_files = FileList['*.rdoc']
19
+ self.extra_deps << ['rails', '~> 3.1']
20
+ end
21
+
22
+ # vim: syntax=ruby
data/TODO.txt ADDED
@@ -0,0 +1,7 @@
1
+ * fix the README to use new gem name and change any examples that behave
2
+ differently from original gem
3
+ * handle parens better so that we don't take too many in cases like
4
+ (you should take a look at http://www.goodreads.com), in which the
5
+ closing paren is going to be picked up
6
+ ** probably just keep existing regex and then truncate any closing
7
+ punctuation from the href and just tack it on after the </a>
@@ -0,0 +1,162 @@
1
+ module GrAutolink
2
+ require 'active_support/core_ext/object/blank'
3
+ require 'active_support/core_ext/array/extract_options'
4
+ require 'active_support/core_ext/hash/reverse_merge'
5
+ require 'active_support/core_ext/hash/keys'
6
+
7
+ module ::ActionView
8
+ module Helpers # :nodoc:
9
+ module TextHelper
10
+ # Turns all URLs and e-mail addresses into clickable links. The <tt>:link</tt> option
11
+ # will limit what should be linked. You can add HTML attributes to the links using
12
+ # <tt>:html</tt>. Possible values for <tt>:link</tt> are <tt>:all</tt> (default),
13
+ # <tt>:email_addresses</tt>, and <tt>:urls</tt>. If a block is given, each URL and
14
+ # e-mail address is yielded and the result is used as the link text. By default the
15
+ # text given is sanitized, you can override this behaviour setting the
16
+ # <tt>:sanitize</tt> option to false, or you can add options to the sanitization of
17
+ # the text using the <tt>:sanitize_options</tt> option hash.
18
+ #
19
+ # ==== Examples
20
+ # auto_link("Go to http://www.rubyonrails.org and say hello to david@loudthinking.com")
21
+ # # => "Go to <a href=\"http://www.rubyonrails.org\">http://www.rubyonrails.org</a> and
22
+ # # say hello to <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
23
+ #
24
+ # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :urls)
25
+ # # => "Visit <a href=\"http://www.loudthinking.com/\">http://www.loudthinking.com/</a>
26
+ # # or e-mail david@loudthinking.com"
27
+ #
28
+ # auto_link("Visit http://www.loudthinking.com/ or e-mail david@loudthinking.com", :link => :email_addresses)
29
+ # # => "Visit http://www.loudthinking.com/ or e-mail <a href=\"mailto:david@loudthinking.com\">david@loudthinking.com</a>"
30
+ #
31
+ # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
32
+ # auto_link(post_body, :html => { :target => '_blank' }) do |text|
33
+ # truncate(text, :length => 15)
34
+ # end
35
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.m...</a>.
36
+ # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
37
+ #
38
+ #
39
+ # You can still use <tt>auto_link</tt> with the old API that accepts the
40
+ # +link+ as its optional second parameter and the +html_options+ hash
41
+ # as its optional third parameter:
42
+ # post_body = "Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com."
43
+ # auto_link(post_body, :urls)
44
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\">http://www.myblog.com</a>.
45
+ # Please e-mail me at me@email.com."
46
+ #
47
+ # auto_link(post_body, :all, :target => "_blank")
48
+ # # => "Welcome to my new blog at <a href=\"http://www.myblog.com/\" target=\"_blank\">http://www.myblog.com</a>.
49
+ # Please e-mail me at <a href=\"mailto:me@email.com\">me@email.com</a>."
50
+ def auto_link(text, *args, &block)#link = :all, html = {}, &block)
51
+ return ''.html_safe if text.blank?
52
+
53
+ options = args.size == 2 ? {} : args.extract_options! # this is necessary because the old auto_link API has a Hash as its last parameter
54
+ unless args.empty?
55
+ options[:link] = args[0] || :all
56
+ options[:html] = args[1] || {}
57
+ end
58
+ options.reverse_merge!(:link => :all, :html => {})
59
+ sanitize = (options[:sanitize] != false)
60
+ sanitize_options = options[:sanitize_options] || {}
61
+ text = conditional_sanitize(text, sanitize, sanitize_options).to_str
62
+ case options[:link].to_sym
63
+ when :all then conditional_html_safe(auto_link_email_addresses(auto_link_urls(text, options[:html], options, &block), options[:html], &block), sanitize)
64
+ when :email_addresses then conditional_html_safe(auto_link_email_addresses(text, options[:html], &block), sanitize)
65
+ when :urls then conditional_html_safe(auto_link_urls(text, options[:html], options, &block), sanitize)
66
+ end
67
+ end
68
+
69
+ private
70
+
71
+ AUTO_LINK_RE = %r{
72
+ (?: ([0-9A-Za-z+.:-]+:)// | www\. )
73
+ [^\s<>]+
74
+ }x
75
+
76
+ # regexps for determining context, used high-volume
77
+ AUTO_LINK_CRE = [/<[^>]+$/, /^[^>]*>/, /<a\b.*?>/i, /<\/a>/i]
78
+
79
+ AUTO_EMAIL_RE = /[\w.!#\$%+-]+@[\w-]+(?:\.[\w-]+)+/
80
+
81
+ BRACKETS = { ']' => '[', ')' => '(', '}' => '{' }
82
+
83
+ # Turns all urls into clickable links. If a block is given, each url
84
+ # is yielded and the result is used as the link text.
85
+ def auto_link_urls(text, html_options = {}, options = {})
86
+ link_attributes = html_options.stringify_keys
87
+ text.gsub(AUTO_LINK_RE) do
88
+ scheme, href = $1, $&
89
+ punctuation = []
90
+
91
+ if auto_linked?($`, $')
92
+ # do not change string; URL is already linked
93
+ href
94
+ else
95
+ # don't include trailing punctuation character as part of the URL
96
+ while href.sub!(/[^\w\/-]$/, '')
97
+ punctuation.push $&
98
+ if opening = BRACKETS[punctuation.last] and href.scan(opening).size > href.scan(punctuation.last).size
99
+ href << punctuation.pop
100
+ break
101
+ end
102
+ end
103
+
104
+ link_text = if block_given?
105
+ yield(href)
106
+ else
107
+ text.html_safe? ? href : escape_once(href)
108
+ end
109
+
110
+ href = 'http://' + href unless scheme
111
+
112
+ unless options[:sanitize] == false
113
+ link_text = sanitize(link_text)
114
+ href = sanitize(href)
115
+ end
116
+
117
+ unless text.html_safe?
118
+ href = escape_once(href)
119
+ end
120
+
121
+ content_tag(:a, link_text, link_attributes.merge('href' => href), !!options[:sanitize]) + punctuation.reverse.join('')
122
+ end
123
+ end
124
+ end
125
+
126
+ # Turns all email addresses into clickable links. If a block is given,
127
+ # each email is yielded and the result is used as the link text.
128
+ def auto_link_email_addresses(text, html_options = {}, options = {})
129
+ text.gsub(AUTO_EMAIL_RE) do
130
+ text = $&
131
+
132
+ if auto_linked?($`, $')
133
+ text.html_safe
134
+ else
135
+ display_text = (block_given?) ? yield(text) : text
136
+
137
+ unless options[:sanitize] == false
138
+ text = sanitize(text)
139
+ display_text = sanitize(display_text) unless text == display_text
140
+ end
141
+ mail_to text, display_text, html_options
142
+ end
143
+ end
144
+ end
145
+
146
+ # Detects already linked context or position in the middle of a tag
147
+ def auto_linked?(left, right)
148
+ (left =~ AUTO_LINK_CRE[0] and right =~ AUTO_LINK_CRE[1]) or
149
+ (left.rindex(AUTO_LINK_CRE[2]) and $' !~ AUTO_LINK_CRE[3])
150
+ end
151
+
152
+ def conditional_sanitize(target, condition, sanitize_options = {})
153
+ condition ? sanitize(target, sanitize_options) : target
154
+ end
155
+
156
+ def conditional_html_safe(target, condition)
157
+ condition ? target.html_safe : target
158
+ end
159
+ end
160
+ end
161
+ end
162
+ end
@@ -0,0 +1,11 @@
1
+ module GrAutolink
2
+ VERSION = '1.0.7'
3
+
4
+ class Railtie < ::Rails::Railtie
5
+ initializer 'gr_autolink' do |app|
6
+ ActiveSupport.on_load(:action_view) do
7
+ require 'gr_autolink/helpers'
8
+ end
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,342 @@
1
+ # encoding: utf-8
2
+
3
+ require "minitest/autorun"
4
+ require "rails"
5
+ require "gr_autolink/helpers"
6
+ require 'erb'
7
+ require 'cgi'
8
+ require 'active_support/core_ext/class/attribute_accessors'
9
+ require 'action_pack'
10
+ require 'action_view/helpers/capture_helper'
11
+ require 'action_view/helpers/sanitize_helper'
12
+ require 'action_view/helpers/url_helper'
13
+ require 'action_view/helpers/tag_helper'
14
+ require 'active_support/core_ext/module/attribute_accessors'
15
+ require 'active_support/core_ext/string/encoding'
16
+ require 'action_dispatch/testing/assertions'
17
+ require 'action_view/helpers/text_helper'
18
+ require 'action_view/helpers/output_safety_helper'
19
+
20
+ class TestGrAutolink < MiniTest::Unit::TestCase
21
+ include ActionView::Helpers::CaptureHelper
22
+ include ActionView::Helpers::TextHelper
23
+ include ActionView::Helpers::SanitizeHelper
24
+ include ActionView::Helpers::TagHelper
25
+ include ActionView::Helpers::UrlHelper
26
+ include ActionView::Helpers::OutputSafetyHelper
27
+ include ActionDispatch::Assertions::DomAssertions
28
+
29
+ def test_auto_link_within_tags
30
+ link_raw = 'http://www.rubyonrails.org/images/rails.png'
31
+ link_result = %Q(<img src="#{link_raw}" />)
32
+ assert_equal link_result, auto_link(link_result)
33
+ end
34
+
35
+ def test_auto_link_with_brackets
36
+ link1_raw = 'http://en.wikipedia.org/wiki/Sprite_(computer_graphics)'
37
+ link1_result = generate_result(link1_raw)
38
+ assert_equal link1_result, auto_link(link1_raw)
39
+ assert_equal "(link: #{link1_result})", auto_link("(link: #{link1_raw})")
40
+
41
+ link2_raw = 'http://en.wikipedia.org/wiki/Sprite_[computer_graphics]'
42
+ link2_result = generate_result(link2_raw)
43
+ assert_equal link2_result, auto_link(link2_raw)
44
+ assert_equal "[link: #{link2_result}]", auto_link("[link: #{link2_raw}]")
45
+
46
+ link3_raw = 'http://en.wikipedia.org/wiki/Sprite_{computer_graphics}'
47
+ link3_result = generate_result(link3_raw)
48
+ assert_equal link3_result, auto_link(link3_raw)
49
+ assert_equal "{link: #{link3_result}}", auto_link("{link: #{link3_raw}}")
50
+ end
51
+
52
+ def test_auto_link_with_options_hash
53
+ assert_dom_equal 'Welcome to my new blog at <a href="http://www.myblog.com/" class="menu" target="_blank">http://www.myblog.com/</a>. Please e-mail me at <a href="mailto:me@email.com" class="menu" target="_blank">me@email.com</a>.',
54
+ auto_link("Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com.",
55
+ :link => :all, :html => { :class => "menu", :target => "_blank" })
56
+ end
57
+
58
+ def test_auto_link_with_multiple_trailing_punctuations
59
+ url = "http://youtube.com"
60
+ url_result = generate_result(url)
61
+ assert_equal url_result, auto_link(url)
62
+ assert_equal "(link: #{url_result}).", auto_link("(link: #{url}).")
63
+ end
64
+
65
+ def test_auto_link_with_block
66
+ url = "http://api.rubyonrails.com/Foo.html"
67
+ email = "fantabulous@shiznadel.ic"
68
+
69
+ assert_equal %(<p><a href="#{url}">#{url[0...7]}...</a><br /><a href="mailto:#{email}">#{email[0...7]}...</a><br /></p>), auto_link("<p>#{url}<br />#{email}<br /></p>") { |_url| truncate(_url, :length => 10) }
70
+ end
71
+
72
+ def test_auto_link_with_block_with_html
73
+ pic = "http://example.com/pic.png"
74
+ url = "http://example.com/album?a&b=c"
75
+
76
+ assert_equal %(My pic: <a href="#{pic}"><img src="#{pic}" width="160px"></a> -- full album here #{generate_result(url)}), auto_link("My pic: #{pic} -- full album here #{url}") { |link|
77
+ if link =~ /\.(jpg|gif|png|bmp|tif)$/i
78
+ raw %(<img src="#{link}" width="160px">)
79
+ else
80
+ escape_once(link)
81
+ end
82
+ }
83
+ end
84
+
85
+ def test_auto_link_should_sanitize_input_when_sanitize_option_is_not_false
86
+ link_raw = %{http://www.rubyonrails.com?id=1&num=2}
87
+ malicious_script = '<script>alert("malicious!")</script>'
88
+ assert_equal %{<a href="http://www.rubyonrails.com?id=1&amp;num=2">http://www.rubyonrails.com?id=1&amp;num=2</a>}, auto_link("#{link_raw}#{malicious_script}")
89
+ assert auto_link("#{link_raw}#{malicious_script}").html_safe?
90
+ end
91
+
92
+ def test_auto_link_should_sanitize_input_with_sanitize_options
93
+ link_raw = %{http://www.rubyonrails.com?id=1&num=2}
94
+ malicious_script = '<script>alert("malicious!")</script>'
95
+ text_with_attributes = %{<a href="http://ruby-lang-org" target="_blank" data-malicious="inject">Ruby</a>}
96
+
97
+ text_result = %{<a class="big" href="http://www.rubyonrails.com?id=1&amp;num=2">http://www.rubyonrails.com?id=1&amp;num=2</a><a href="http://ruby-lang-org" target="_blank">Ruby</a>}
98
+ assert_equal text_result, auto_link("#{link_raw}#{malicious_script}#{text_with_attributes}",
99
+ :sanitize_options => {:attributes => ["target", "href"]},
100
+ :html => {:class => 'big'})
101
+
102
+ assert auto_link("#{link_raw}#{malicious_script}#{text_with_attributes}",
103
+ :sanitize_options => {:attributes => ["target", "href"]},
104
+ :html => {:class => 'big'}).html_safe?
105
+ end
106
+
107
+ def test_auto_link_should_escape_ampersand_in_url
108
+ link_raw = %{http://www.rubyonrails.com?id=1&num=2}
109
+ assert_equal %{<a href="http://www.rubyonrails.com?id=1&amp;num=2">http://www.rubyonrails.com?id=1&amp;num=2</a>}, auto_link(link_raw)
110
+ end
111
+
112
+ def test_auto_link_should_not_sanitize_input_when_sanitize_option_is_false
113
+ link_raw = %{http://www.rubyonrails.com?id=1&num=2}
114
+ malicious_script = '<script>alert("malicious!")</script>'
115
+
116
+ assert_equal %{<a href="http://www.rubyonrails.com?id=1&amp;num=2">http://www.rubyonrails.com?id=1&amp;num=2</a><script>alert("malicious!")</script>}, auto_link("#{link_raw}#{malicious_script}", :sanitize => false)
117
+ assert !auto_link("#{link_raw}#{malicious_script}", :sanitize => false).html_safe?
118
+ end
119
+
120
+ def test_auto_link_other_protocols
121
+ ftp_raw = 'ftp://example.com/file.txt'
122
+ assert_equal %(Download #{generate_result(ftp_raw)}), auto_link("Download #{ftp_raw}")
123
+
124
+ file_scheme = 'file:///home/username/RomeoAndJuliet.pdf'
125
+ z39_scheme = 'z39.50r://host:696/db'
126
+ chrome_scheme = 'chrome://package/section/path'
127
+ view_source = 'view-source:http://en.wikipedia.org/wiki/URI_scheme'
128
+ assert_equal generate_result(file_scheme), auto_link(file_scheme)
129
+ assert_equal generate_result(z39_scheme), auto_link(z39_scheme)
130
+ assert_equal generate_result(chrome_scheme), auto_link(chrome_scheme)
131
+ assert_equal generate_result(view_source), auto_link(view_source)
132
+ end
133
+
134
+ def test_auto_link_already_linked
135
+ linked1 = generate_result('Ruby On Rails', 'http://www.rubyonrails.com')
136
+ linked2 = %('<a href="http://www.example.com">www.example.com</a>')
137
+ linked3 = %('<a href="http://www.example.com" rel="nofollow">www.example.com</a>')
138
+ linked4 = %('<a href="http://www.example.com"><b>www.example.com</b></a>')
139
+ linked5 = %('<a href="#close">close</a> <a href="http://www.example.com"><b>www.example.com</b></a>')
140
+ linked6 = %('<a href="#close">close</a> <a href="http://www.example.com" target="_blank" data-ruby="ror"><b>www.example.com</b></a>')
141
+ assert_equal linked1, auto_link(linked1)
142
+ assert_equal linked2, auto_link(linked2)
143
+ assert_equal linked3, auto_link(linked3, :sanitize => false)
144
+ assert_equal linked4, auto_link(linked4)
145
+ assert_equal linked5, auto_link(linked5)
146
+ assert_equal linked6, auto_link(linked6, :sanitize_options => {:attributes => ["href", "target", "data-ruby"]})
147
+
148
+ linked_email = %Q(<a href="mailto:david@loudthinking.com">Mail me</a>)
149
+ assert_equal linked_email, auto_link(linked_email)
150
+ end
151
+
152
+
153
+ def test_auto_link_at_eol
154
+ url1 = "http://api.rubyonrails.com/Foo.html"
155
+ url2 = "http://www.ruby-doc.org/core/Bar.html"
156
+
157
+ assert_equal %(<p><a href="#{url1}">#{url1}</a><br /><a href="#{url2}">#{url2}</a><br /></p>), auto_link("<p>#{url1}<br />#{url2}<br /></p>")
158
+ end
159
+
160
+ def test_auto_link_should_be_html_safe
161
+ email_raw = 'santiago@wyeworks.com'
162
+ link_raw = 'http://www.rubyonrails.org'
163
+ malicious_script = '<script>alert("malicious!")</script>'
164
+
165
+ assert auto_link(nil).html_safe?, 'should be html safe'
166
+ assert auto_link('').html_safe?, 'should be html safe'
167
+ assert auto_link("#{link_raw} #{link_raw} #{link_raw}").html_safe?, 'should be html safe'
168
+ assert auto_link("hello #{email_raw}").html_safe?, 'should be html safe'
169
+ assert auto_link("hello #{email_raw} #{malicious_script}").html_safe?, 'should be html safe'
170
+ end
171
+
172
+ def test_auto_link_should_not_be_html_safe_when_sanitize_option_false
173
+ email_raw = 'santiago@wyeworks.com'
174
+ link_raw = 'http://www.rubyonrails.org'
175
+
176
+ assert !auto_link("hello", :sanitize => false).html_safe?, 'should not be html safe'
177
+ assert !auto_link("#{link_raw} #{link_raw} #{link_raw}", :sanitize => false).html_safe?, 'should not be html safe'
178
+ assert !auto_link("hello #{email_raw}", :sanitize => false).html_safe?, 'should not be html safe'
179
+ end
180
+
181
+ def test_auto_link_email_address
182
+ email_raw = 'aaron@tenderlovemaking.com'
183
+ email_result = %{<a href="mailto:#{email_raw}">#{email_raw}</a>}
184
+ assert !auto_link_email_addresses(email_result).html_safe?, 'should not be html safe'
185
+ end
186
+
187
+ def test_auto_link
188
+ email_raw = 'david@loudthinking.com'
189
+ email_result = %{<a href="mailto:#{email_raw}">#{email_raw}</a>}
190
+ link_raw = 'http://www.rubyonrails.com'
191
+ link_result = generate_result(link_raw)
192
+ link_result_with_options = %{<a href="#{link_raw}" target="_blank">#{link_raw}</a>}
193
+
194
+ assert_equal '', auto_link(nil)
195
+ assert_equal '', auto_link('')
196
+ assert_equal "#{link_result} #{link_result} #{link_result}", auto_link("#{link_raw} #{link_raw} #{link_raw}")
197
+
198
+ assert_equal %(hello #{email_result}), auto_link("hello #{email_raw}", :email_addresses)
199
+ assert_equal %(Go to #{link_result}), auto_link("Go to #{link_raw}", :urls)
200
+ assert_equal %(Go to #{link_raw}), auto_link("Go to #{link_raw}", :email_addresses)
201
+ assert_equal %(Go to #{link_result} and say hello to #{email_result}), auto_link("Go to #{link_raw} and say hello to #{email_raw}")
202
+ assert_equal %(<p>Link #{link_result}</p>), auto_link("<p>Link #{link_raw}</p>")
203
+ assert_equal %(<p>#{link_result} Link</p>), auto_link("<p>#{link_raw} Link</p>")
204
+ assert_equal %(<p>Link #{link_result_with_options}</p>), auto_link("<p>Link #{link_raw}</p>", :all, {:target => "_blank"})
205
+ assert_equal %(Go to #{link_result}.), auto_link(%(Go to #{link_raw}.))
206
+ assert_equal %(<p>Go to #{link_result}, then say hello to #{email_result}.</p>), auto_link(%(<p>Go to #{link_raw}, then say hello to #{email_raw}.</p>))
207
+ assert_equal %(#{link_result} #{link_result}), auto_link(%(#{link_result} #{link_raw}))
208
+
209
+ email2_raw = '+david@loudthinking.com'
210
+ email2_result = %{<a href="mailto:#{email2_raw}">#{email2_raw}</a>}
211
+ assert_equal email2_result, auto_link(email2_raw)
212
+
213
+ email3_raw = '+david@loudthinking.com'
214
+ email3_result = %{<a href="&#109;&#97;&#105;&#108;&#116;&#111;&#58;+%64%61%76%69%64@%6c%6f%75%64%74%68%69%6e%6b%69%6e%67.%63%6f%6d">#{email3_raw}</a>}
215
+ assert_equal email3_result, auto_link(email3_raw, :all, :encode => :hex)
216
+ assert_equal email3_result, auto_link(email3_raw, :email_addresses, :encode => :hex)
217
+
218
+ link2_raw = 'www.rubyonrails.com'
219
+ link2_result = generate_result(link2_raw, "http://#{link2_raw}")
220
+ assert_equal %(Go to #{link2_result}), auto_link("Go to #{link2_raw}", :urls)
221
+ assert_equal %(Go to #{link2_raw}), auto_link("Go to #{link2_raw}", :email_addresses)
222
+ assert_equal %(<p>Link #{link2_result}</p>), auto_link("<p>Link #{link2_raw}</p>")
223
+ assert_equal %(<p>#{link2_result} Link</p>), auto_link("<p>#{link2_raw} Link</p>")
224
+ assert_equal %(Go to #{link2_result}.), auto_link(%(Go to #{link2_raw}.))
225
+ assert_equal %(<p>Say hello to #{email_result}, then go to #{link2_result}.</p>), auto_link(%(<p>Say hello to #{email_raw}, then go to #{link2_raw}.</p>))
226
+
227
+ link3_raw = 'http://manuals.ruby-on-rails.com/read/chapter.need_a-period/103#page281'
228
+ link3_result = generate_result(link3_raw)
229
+ assert_equal %(Go to #{link3_result}), auto_link("Go to #{link3_raw}", :urls)
230
+ assert_equal %(Go to #{link3_raw}), auto_link("Go to #{link3_raw}", :email_addresses)
231
+ assert_equal %(<p>Link #{link3_result}</p>), auto_link("<p>Link #{link3_raw}</p>")
232
+ assert_equal %(<p>#{link3_result} Link</p>), auto_link("<p>#{link3_raw} Link</p>")
233
+ assert_equal %(Go to #{link3_result}.), auto_link(%(Go to #{link3_raw}.))
234
+ assert_equal %(<p>Go to #{link3_result}. Seriously, #{link3_result}? I think I'll say hello to #{email_result}. Instead.</p>),
235
+ auto_link(%(<p>Go to #{link3_raw}. Seriously, #{link3_raw}? I think I'll say hello to #{email_raw}. Instead.</p>))
236
+
237
+ link4_raw = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor123'
238
+ link4_result = generate_result(link4_raw)
239
+ assert_equal %(<p>Link #{link4_result}</p>), auto_link("<p>Link #{link4_raw}</p>")
240
+ assert_equal %(<p>#{link4_result} Link</p>), auto_link("<p>#{link4_raw} Link</p>")
241
+
242
+ link5_raw = 'http://foo.example.com:3000/controller/action'
243
+ link5_result = generate_result(link5_raw)
244
+ assert_equal %(<p>#{link5_result} Link</p>), auto_link("<p>#{link5_raw} Link</p>")
245
+
246
+ link6_raw = 'http://foo.example.com:3000/controller/action+pack'
247
+ link6_result = generate_result(link6_raw)
248
+ assert_equal %(<p>#{link6_result} Link</p>), auto_link("<p>#{link6_raw} Link</p>")
249
+
250
+ link7_raw = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor-123'
251
+ link7_result = generate_result(link7_raw)
252
+ assert_equal %(<p>#{link7_result} Link</p>), auto_link("<p>#{link7_raw} Link</p>")
253
+
254
+ link8_raw = 'http://foo.example.com:3000/controller/action.html'
255
+ link8_result = generate_result(link8_raw)
256
+ assert_equal %(Go to #{link8_result}), auto_link("Go to #{link8_raw}", :urls)
257
+ assert_equal %(Go to #{link8_raw}), auto_link("Go to #{link8_raw}", :email_addresses)
258
+ assert_equal %(<p>Link #{link8_result}</p>), auto_link("<p>Link #{link8_raw}</p>")
259
+ assert_equal %(<p>#{link8_result} Link</p>), auto_link("<p>#{link8_raw} Link</p>")
260
+ assert_equal %(Go to #{link8_result}.), auto_link(%(Go to #{link8_raw}.))
261
+ assert_equal %(<p>Go to #{link8_result}. Seriously, #{link8_result}? I think I'll say hello to #{email_result}. Instead.</p>),
262
+ auto_link(%(<p>Go to #{link8_raw}. Seriously, #{link8_raw}? I think I'll say hello to #{email_raw}. Instead.</p>))
263
+
264
+ link9_raw = 'http://business.timesonline.co.uk/article/0,,9065-2473189,00.html'
265
+ link9_result = generate_result(link9_raw)
266
+ assert_equal %(Go to #{link9_result}), auto_link("Go to #{link9_raw}", :urls)
267
+ assert_equal %(Go to #{link9_raw}), auto_link("Go to #{link9_raw}", :email_addresses)
268
+ assert_equal %(<p>Link #{link9_result}</p>), auto_link("<p>Link #{link9_raw}</p>")
269
+ assert_equal %(<p>#{link9_result} Link</p>), auto_link("<p>#{link9_raw} Link</p>")
270
+ assert_equal %(Go to #{link9_result}.), auto_link(%(Go to #{link9_raw}.))
271
+ assert_equal %(<p>Go to #{link9_result}. Seriously, #{link9_result}? I think I'll say hello to #{email_result}. Instead.</p>),
272
+ auto_link(%(<p>Go to #{link9_raw}. Seriously, #{link9_raw}? I think I'll say hello to #{email_raw}. Instead.</p>))
273
+
274
+ link10_raw = 'http://www.mail-archive.com/ruby-talk@ruby-lang.org/'
275
+ link10_result = generate_result(link10_raw)
276
+ assert_equal %(<p>#{link10_result} Link</p>), auto_link("<p>#{link10_raw} Link</p>")
277
+
278
+ link11_raw = 'http://asakusa.rubyist.net/'
279
+ link11_result = generate_result(link11_raw)
280
+ with_kcode 'u' do
281
+ assert_equal %(浅草.rbの公式サイトはこちら#{link11_result}), auto_link("浅草.rbの公式サイトはこちら#{link11_raw}")
282
+ end
283
+ end
284
+
285
+ def test_auto_link_parsing
286
+ urls = %w(
287
+ http://www.rubyonrails.com
288
+ http://www.rubyonrails.com:80
289
+ http://www.rubyonrails.com/~minam
290
+ https://www.rubyonrails.com/~minam
291
+ http://www.rubyonrails.com/~minam/url%20with%20spaces
292
+ http://www.rubyonrails.com/foo.cgi?something=here
293
+ http://www.rubyonrails.com/foo.cgi?something=here&and=here
294
+ http://www.rubyonrails.com/contact;new
295
+ http://www.rubyonrails.com/contact;new%20with%20spaces
296
+ http://www.rubyonrails.com/contact;new?with=query&string=params
297
+ http://www.rubyonrails.com/~minam/contact;new?with=query&string=params
298
+ http://en.wikipedia.org/wiki/Wikipedia:Today%27s_featured_picture_%28animation%29/January_20%2C_2007
299
+ http://www.mail-archive.com/rails@lists.rubyonrails.org/
300
+ http://www.amazon.com/Testing-Equal-Sign-In-Path/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1198861734&sr=8-1
301
+ http://en.wikipedia.org/wiki/Texas_hold'em
302
+ https://www.google.com/doku.php?id=gps:resource:scs:start
303
+ http://connect.oraclecorp.com/search?search[q]=green+france&search[type]=Group
304
+ http://of.openfoundry.org/projects/492/download#4th.Release.3
305
+ http://maps.google.co.uk/maps?f=q&q=the+london+eye&ie=UTF8&ll=51.503373,-0.11939&spn=0.007052,0.012767&z=16&iwloc=A
306
+ )
307
+
308
+ urls.each do |url|
309
+ assert_equal generate_result(url), auto_link(url)
310
+ end
311
+ end
312
+
313
+ private
314
+ def generate_result(link_text, href = nil)
315
+ href ||= link_text
316
+ if !link_text.html_safe?
317
+ %{<a href="#{CGI::escapeHTML href}">#{CGI::escapeHTML link_text}</a>}
318
+ else
319
+ %{<a href="#{href}">#{link_text}</a>}
320
+ end
321
+ end
322
+
323
+ # from ruby core
324
+ def build_message(head, template=nil, *arguments)
325
+ template &&= template.chomp
326
+ template.gsub(/\?/) { mu_pp(arguments.shift) }
327
+ end
328
+
329
+ # Temporarily replaces KCODE for the block
330
+ def with_kcode(kcode)
331
+ if RUBY_VERSION < '1.9'
332
+ old_kcode, $KCODE = $KCODE, kcode
333
+ begin
334
+ yield
335
+ ensure
336
+ $KCODE = old_kcode
337
+ end
338
+ else
339
+ yield
340
+ end
341
+ end
342
+ end
metadata ADDED
@@ -0,0 +1,112 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: gr_autolink
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.7
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Aaron Patterson
9
+ - Juanjo Bazan
10
+ - Akira Matsuda
11
+ - Brian Percival
12
+ autorequire:
13
+ bindir: bin
14
+ cert_chain: []
15
+ date: 2012-03-31 00:00:00.000000000 Z
16
+ dependencies:
17
+ - !ruby/object:Gem::Dependency
18
+ name: rails
19
+ requirement: &2168727060 !ruby/object:Gem::Requirement
20
+ none: false
21
+ requirements:
22
+ - - ~>
23
+ - !ruby/object:Gem::Version
24
+ version: '3.1'
25
+ type: :runtime
26
+ prerelease: false
27
+ version_requirements: *2168727060
28
+ - !ruby/object:Gem::Dependency
29
+ name: rdoc
30
+ requirement: &2168726500 !ruby/object:Gem::Requirement
31
+ none: false
32
+ requirements:
33
+ - - ~>
34
+ - !ruby/object:Gem::Version
35
+ version: '3.10'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: *2168726500
39
+ - !ruby/object:Gem::Dependency
40
+ name: hoe
41
+ requirement: &2168725960 !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ~>
45
+ - !ruby/object:Gem::Version
46
+ version: '2.16'
47
+ type: :development
48
+ prerelease: false
49
+ version_requirements: *2168725960
50
+ description: ! "This is an adaptation of the extraction of the `auto_link` method
51
+ from rails\nthat is the rails_autolink gem. The `auto_link`\nmethod was removed
52
+ from Rails in version Rails 3.1. This gem is meant to\nbridge the gap for people
53
+ migrating...and behaves a little differently from the\nparent gem we forked from:\n\n*
54
+ performs html-escaping of characters such as '&' in strings that are getting\n linkified
55
+ if the incoming string is not html_safe?\n* retains html-safety of incoming string
56
+ (if input string is unsafe, will return\n unsafe and vice versa)\n* fixes at least
57
+ one bug:\n (<img src=\"http://some.u.rl\"> => <img src=\"<a href=\"http://some.u.rl\">http://some.u.rl</a>\">)\n
58
+ \ though can't imagine this is intended behavior, also have trouble believing that\n
59
+ \ this was an open bug in rails..."
60
+ email:
61
+ - aaron@tenderlovemaking.com
62
+ - jjbazan@gmail.com
63
+ - ronnie@dio.jp
64
+ - bpercival@goodreads.com
65
+ executables: []
66
+ extensions: []
67
+ extra_rdoc_files:
68
+ - CHANGELOG.rdoc
69
+ - Manifest.txt
70
+ - README.rdoc
71
+ - TODO.txt
72
+ files:
73
+ - .autotest
74
+ - CHANGELOG.rdoc
75
+ - Gemfile
76
+ - Manifest.txt
77
+ - README.rdoc
78
+ - Rakefile
79
+ - lib/gr_autolink.rb
80
+ - lib/gr_autolink/helpers.rb
81
+ - test/test_gr_autolink.rb
82
+ - TODO.txt
83
+ - .gemtest
84
+ homepage: http://github.com/goodreads/gr_autolink
85
+ licenses: []
86
+ post_install_message:
87
+ rdoc_options:
88
+ - --main
89
+ - README.rdoc
90
+ require_paths:
91
+ - lib
92
+ required_ruby_version: !ruby/object:Gem::Requirement
93
+ none: false
94
+ requirements:
95
+ - - ! '>='
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ required_rubygems_version: !ruby/object:Gem::Requirement
99
+ none: false
100
+ requirements:
101
+ - - ! '>='
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ requirements: []
105
+ rubyforge_project: gr_autolink
106
+ rubygems_version: 1.8.15
107
+ signing_key:
108
+ specification_version: 3
109
+ summary: This is an adaptation of the extraction of the `auto_link` method from rails
110
+ that is the rails_autolink gem
111
+ test_files:
112
+ - test/test_gr_autolink.rb