public
Description: Ruby on Rails
Homepage: http://rubyonrails.org
Clone URL: git://github.com/rails/rails.git
refactor autolink helper. change tests to expect HTML-escaped URLs

Signed-off-by: Michael Koziarski <michael@koziarski.com>
Mislav Marohnić (author)
Wed Nov 12 04:15:57 -0800 2008
NZKoz (committer)
Sat Nov 15 09:30:01 -0800 2008
commit  c6c5cd554110f6e62290de3e3008076b2f69e7cb
tree    8acdf33374ce90a659cd20b75825fcde9e99a4fc
parent  789a3f5b035fd293a9e235672a97b683a56ba0c3
...
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
 
 
 
567
568
569
570
571
 
572
573
574
575
 
 
 
 
 
 
 
 
 
 
 
 
 
 
576
577
578
579
 
 
580
581
582
...
545
546
547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
548
549
550
551
552
553
554
 
555
556
 
 
 
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
 
 
 
572
573
574
575
576
0
@@ -545,38 +545,32 @@ module ActionView
0
         end
0
 
0
         AUTO_LINK_RE = %r{
0
-                        (                          # leading text
0
-                          <\w+.*?>|                # leading HTML tag, or
0
-                          [^=!:'"/]|               # leading punctuation, or
0
-                          ^                        # beginning of line
0
-                        )
0
-                        (
0
-                          (?:https?://)|           # protocol spec, or
0
-                          (?:www\.)                # www.*
0
-                        )
0
-                        (
0
-                          [-\w]+                   # subdomain or domain
0
-                          (?:\.[-\w]+)*            # remaining subdomains or domain
0
-                          (?::\d+)?                # port
0
-                          (?:/(?:[~\w\+@%=\(\)-]|(?:[,.;:'][^\s$]))*)* # path
0
-                          (?:\?[\w\+@%&=.;:-]+)?     # query string
0
-                          (?:\#[\w\-]*)?           # trailing anchor
0
-                        )
0
-                        ([[:punct:]]|<|$|)       # trailing text
0
-                       }x unless const_defined?(:AUTO_LINK_RE)
0
+            ( https?:// | www\. )
0
+            [^\s<]+
0
+          }x unless const_defined?(:AUTO_LINK_RE)
0
 
0
         # Turns all urls into clickable links.  If a block is given, each url
0
         # is yielded and the result is used as the link text.
0
         def auto_link_urls(text, html_options = {})
0
-          extra_options = tag_options(html_options.stringify_keys) || ""
0
+          link_attributes = html_options.stringify_keys
0
           text.gsub(AUTO_LINK_RE) do
0
-            all, a, b, c, d = $&, $1, $2, $3, $4
0
-            if a =~ /<a\s/i # don't replace URL's that are already linked
0
-              all
0
+            href = $&
0
+            # detect already linked URLs
0
+            unless $` =~ /<a\s[^>]*href="$/
0
+              if href =~ /[^\w\/-]$/
0
+                punctuation = href[-1, 1]
0
+                href = href[0, href.length - 1]
0
+              else
0
+                punctuation = ''
0
+              end
0
+
0
+              link_text = block_given?? yield(href) : href
0
+              href = 'http://' + href unless href.index('http') == 0
0
+
0
+              content_tag(:a, h(link_text), link_attributes.merge('href' => href)) + punctuation
0
             else
0
-              text = b + c
0
-              text = yield(text) if block_given?
0
-              %(#{a}<a href="#{b=="www."?"http://www.":b}#{c}"#{extra_options}>#{text}</a>#{d})
0
+              # do not change string; URL is alreay linked
0
+              href
0
             end
0
           end
0
         end
...
225
226
227
228
 
229
230
231
 
 
 
 
 
232
233
234
235
236
237
238
 
239
240
241
 
242
243
 
244
245
 
246
247
 
248
249
 
250
251
 
252
253
 
254
255
 
256
257
 
258
259
260
...
299
300
301
302
 
 
 
 
 
 
 
303
304
305
...
317
318
319
320
 
321
322
323
...
225
226
227
 
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
 
243
244
245
 
246
247
 
248
249
 
250
251
 
252
253
 
254
255
 
256
257
 
258
259
 
260
261
 
262
263
264
265
...
304
305
306
 
307
308
309
310
311
312
313
314
315
316
...
328
329
330
 
331
332
333
334
0
@@ -225,36 +225,41 @@ class TextHelperTest < ActionView::TestCase
0
             )
0
 
0
     urls.each do |url|
0
-      assert_equal %(<a href="#{url}">#{url}</a>), auto_link(url)
0
+      assert_equal %(<a href="#{CGI::escapeHTML url}">#{CGI::escapeHTML url}</a>), auto_link(url)
0
     end
0
   end
0
 
0
+  def generate_result(link_text, href = nil)
0
+    href ||= link_text
0
+    %{<a href="#{CGI::escapeHTML href}">#{CGI::escapeHTML link_text}</a>}
0
+  end
0
+
0
   def test_auto_linking
0
     email_raw    = 'david@loudthinking.com'
0
     email_result = %{<a href="mailto:#{email_raw}">#{email_raw}</a>}
0
     email2_raw    = '+david@loudthinking.com'
0
     email2_result = %{<a href="mailto:#{email2_raw}">#{email2_raw}</a>}
0
     link_raw     = 'http://www.rubyonrails.com'
0
-    link_result  = %{<a href="#{link_raw}">#{link_raw}</a>}
0
+    link_result  = generate_result(link_raw)
0
     link_result_with_options  = %{<a href="#{link_raw}" target="_blank">#{link_raw}</a>}
0
     link2_raw    = 'www.rubyonrails.com'
0
-    link2_result = %{<a href="http://#{link2_raw}">#{link2_raw}</a>}
0
+    link2_result = generate_result(link2_raw, "http://#{link2_raw}")
0
     link3_raw    = 'http://manuals.ruby-on-rails.com/read/chapter.need_a-period/103#page281'
0
-    link3_result = %{<a href="#{link3_raw}">#{link3_raw}</a>}
0
+    link3_result = generate_result(link3_raw)
0
     link4_raw    = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor123'
0
-    link4_result = %{<a href="#{link4_raw}">#{link4_raw}</a>}
0
+    link4_result = generate_result(link4_raw)
0
     link5_raw    = 'http://foo.example.com:3000/controller/action'
0
-    link5_result = %{<a href="#{link5_raw}">#{link5_raw}</a>}
0
+    link5_result = generate_result(link5_raw)
0
     link6_raw    = 'http://foo.example.com:3000/controller/action+pack'
0
-    link6_result = %{<a href="#{link6_raw}">#{link6_raw}</a>}
0
+    link6_result = generate_result(link6_raw)
0
     link7_raw    = 'http://foo.example.com/controller/action?parm=value&p2=v2#anchor-123'
0
-    link7_result = %{<a href="#{link7_raw}">#{link7_raw}</a>}
0
+    link7_result = generate_result(link7_raw)
0
     link8_raw    = 'http://foo.example.com:3000/controller/action.html'
0
-    link8_result = %{<a href="#{link8_raw}">#{link8_raw}</a>}
0
+    link8_result = generate_result(link8_raw)
0
     link9_raw    = 'http://business.timesonline.co.uk/article/0,,9065-2473189,00.html'
0
-    link9_result = %{<a href="#{link9_raw}">#{link9_raw}</a>}
0
+    link9_result = generate_result(link9_raw)
0
     link10_raw    = 'http://www.mail-archive.com/ruby-talk@ruby-lang.org/'
0
-    link10_result = %{<a href="#{link10_raw}">#{link10_raw}</a>}
0
+    link10_result = generate_result(link10_raw)
0
 
0
     assert_equal %(hello #{email_result}), auto_link("hello #{email_raw}", :email_addresses)
0
     assert_equal %(Go to #{link_result}), auto_link("Go to #{link_raw}", :urls)
0
@@ -299,7 +304,13 @@ class TextHelperTest < ActionView::TestCase
0
     assert_equal '', auto_link(nil)
0
     assert_equal '', auto_link('')
0
     assert_equal "#{link_result} #{link_result} #{link_result}", auto_link("#{link_raw} #{link_raw} #{link_raw}")
0
-    assert_equal '<a href="http://www.rubyonrails.com">Ruby On Rails</a>', auto_link('<a href="http://www.rubyonrails.com">Ruby On Rails</a>')
0
+  end
0
+
0
+  def test_auto_link_already_linked
0
+    linked1 = generate_result('Ruby On Rails', 'http://www.rubyonrails.com')
0
+    linked2 = generate_result('www.rubyonrails.com', 'http://www.rubyonrails.com')
0
+    assert_equal linked1, auto_link(linked1)
0
+    assert_equal linked2, auto_link(linked2)
0
   end
0
 
0
   def test_auto_link_at_eol
0
@@ -317,7 +328,7 @@ class TextHelperTest < ActionView::TestCase
0
   end
0
 
0
   def test_auto_link_with_options_hash
0
-    assert_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">me@email.com</a>.',
0
+    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">me@email.com</a>.',
0
       auto_link("Welcome to my new blog at http://www.myblog.com/. Please e-mail me at me@email.com.",
0
                 :link => :all, :html => { :class => "menu", :target => "_blank" })
0
   end

Comments