Skip to content

Instantly share code, notes, and snippets.

@julik
Created December 7, 2014 01:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save julik/4155e885ca53d4b7aec6 to your computer and use it in GitHub Desktop.
Save julik/4155e885ca53d4b7aec6 to your computer and use it in GitHub Desktop.
require 'uri'
module Julik
module AbsolutizeHelper
def canonicalize_hyperlinks(htmlcontent, root, host = nil, prot = nil)
htmlcontent.gsub(/(<(img|a)\b[^>]*(src|href)=)(["'])(.*?)\4/) do
md = $~
prefix = (host && prot) ? (prot + host) : ''
prefix.gsub!(/\/$/, '')
begin
url = URI.parse CGI.unescapeHTML(md[5])
prefix = '' if (md[5].include?(prefix) && prefix.length > 0)
if url.relative? && url.path !~ /^\//
absolutized = File.expand_path(File.join(root, md[5], md[4]))
# Clean the trailing slash but leave the quote
absolutized.gsub!(/(\/)(["'])$/) { $2 }
md[1] + md[4] + prefix + absolutized
else
md[1] + md[4] + prefix + md[5] + md[4]
end
rescue URI::InvalidURIError
md[0]
end
end
end
def canonicalize_hyperlinks_in_context(html)
host = request.host
proto = request.protocol
# honor substandard port
host += ":#{request.port}" unless request.port == '80'
canonicalize_hyperlinks(html, '/', request.host, request.protocol)
end
def markdown_with_canonic_links(text)
canonicalize_hyperlinks_in_context(markdown(text))
end
def textilize_with_canonic_links(text)
canonicalize_hyperlinks_in_context(textilize(text))
end
end
end
require 'rubygems'
require 'action_pack'
require 'action_controller'
require 'action_controller/test_process'
require File.dirname(__FILE__) + '/../init'
# Re-raise errors caught by the controller.
class SomeController < ActionController::Base
def absolute_action_with_markdown
render :inline => "<%= markdown_with_canonic_links('And [a link](../some/stuff)') %>"
end
def absolute_action_with_textile
render :inline => "<%= textilize_with_canonic_links('And \"a link\":../some/stuff') %>"
end
def rescue_action(e)
raise e
end
end
ActionController::Routing::Routes.draw do |map|
map.connect ':controller/:action/:id'
end
class AbsolutizerTest < Test::Unit::TestCase
include Julik::AbsolutizeHelper
def setup
@request = ActionController::TestRequest.new
@response = ActionController::TestResponse.new
@controller = SomeController.new
end
def test_basisc
stuff = "Here is <a href='http://site.net/link'>stuffed</a> and \
<a href='/some/interesting url to check out'>some ad uri</a> and \
<a href='/some_link'>link</a> and <a href='../things'>another</a>"
result = "Here is <a href='http://site.net/link'>stuffed</a> and \
<a href='/some/interesting url to check out'>some ad uri</a> and \
<a href='http://site.net/some_link'>link</a> and <a href='http://site.net/stuff/bla/things'>another</a>"
assert_equal result, canonicalize_hyperlinks(stuff, '/stuff/bla/badaboum', 'site.net', 'http://')
assert_equal result, canonicalize_hyperlinks(stuff, '/stuff/bla/badaboum/', 'site.net', 'http://')
stuff = 'And <a href="/this/link">is a root link</a> as we know'
result_without_host = 'And <a href="/this/link">is a root link</a> as we know'
result_with_host = 'And <a href="https://host.com:3030/this/link">is a root link</a> as we know'
assert_equal result_without_host, canonicalize_hyperlinks(stuff, '/')
assert_equal result_with_host, canonicalize_hyperlinks(stuff, '/', 'host.com:3030', 'https://')
expectation = '<p>And <a href="http://test.host/some/stuff">a link</a></p>'
get :absolute_action_with_markdown
assert_equal expectation, @response.body
get :absolute_action_with_textile
assert_equal expectation, @response.body
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment