Skip to content

Commit

Permalink
Add support for base HTML element
Browse files Browse the repository at this point in the history
Add support in the Page's to_absolute method for the base HTML element.
This way it can correctly convert relative links for a given page
document.
  • Loading branch information
brutuscat authored and chriskite committed Jan 20, 2012
1 parent 31a1515 commit 217a22b
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 2 deletions.
17 changes: 16 additions & 1 deletion lib/anemone/page.rb
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,21 @@ def not_found?
404 == @code
end

#
# Base URI from the HTML doc head element
# http://www.w3.org/TR/html4/struct/links.html#edef-BASE
#
def base
@base = if doc
href = doc.search('//head/base/@href')
URI(href.to_s) unless href.nil? rescue nil
end unless @base

return nil if @base && @base.to_s().empty?
@base
end


#
# Converts relative URL *link* into an absolute URL based on the
# location of the page
Expand All @@ -142,7 +157,7 @@ def to_absolute(link)
link = URI.encode(URI.decode(link.to_s.gsub(/#[a-zA-Z0-9_-]*$/,'')))

relative = URI(link)
absolute = @url.merge(relative)
absolute = base ? base.merge(relative) : @url.merge(relative)

absolute.path = '/' if absolute.path.empty?

Expand Down
7 changes: 6 additions & 1 deletion spec/fakeweb_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ def initialize(name = '', options = {})
@hrefs = [options[:hrefs]].flatten if options.has_key?(:hrefs)
@redirect = options[:redirect] if options.has_key?(:redirect)
@auth = options[:auth] if options.has_key?(:auth)
@base = options[:base] if options.has_key?(:base)
@content_type = options[:content_type] || "text/html"
@body = options[:body]

Expand All @@ -33,7 +34,11 @@ def auth_url
private

def create_body
@body = "<html><body>"
if @base
@body = "<html><head><base href=\"#{@base}\"></head><body>"
else
@body = "<html><body>"
end
@links.each{|l| @body += "<a href=\"#{SPEC_DOMAIN}#{l}\"></a>"} if @links
@hrefs.each{|h| @body += "<a href=\"#{h}\"></a>"} if @hrefs
@body += "</body></html>"
Expand Down
47 changes: 47 additions & 0 deletions spec/page_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -126,5 +126,52 @@ module Anemone
end
end

it "should detect, store and expose the base url for the page head" do
base = "#{SPEC_DOMAIN}path/to/base_url/"
page = @http.fetch_page(FakePage.new('body_test', {:base => base}).url)
page.base.should == URI(base)
@page.base.should be_nil
end

it "should have a method to convert a relative url to an absolute one" do
@page.should respond_to(:to_absolute)

# Identity
@page.to_absolute(@page.url).should == @page.url
@page.to_absolute("").should == @page.url

# Root-ness
@page.to_absolute("/").should == URI("#{SPEC_DOMAIN}")

# Relativeness
relative_path = "a/relative/path"
@page.to_absolute(relative_path).should == URI("#{SPEC_DOMAIN}#{relative_path}")

deep_page = @http.fetch_page(FakePage.new('home/deep', :links => '1').url)
upward_relative_path = "../a/relative/path"
deep_page.to_absolute(upward_relative_path).should == URI("#{SPEC_DOMAIN}#{relative_path}")

# The base URL case
base_path = "path/to/base_url/"
base = "#{SPEC_DOMAIN}#{base_path}"
page = @http.fetch_page(FakePage.new('home', {:base => base}).url)

# Identity
page.to_absolute(page.url).should == page.url
# It should revert to the base url
page.to_absolute("").should_not == page.url

# Root-ness
page.to_absolute("/").should == URI("#{SPEC_DOMAIN}")

# Relativeness
relative_path = "a/relative/path"
page.to_absolute(relative_path).should == URI("#{base}#{relative_path}")

upward_relative_path = "../a/relative/path"
upward_base = "#{SPEC_DOMAIN}path/to/"
page.to_absolute(upward_relative_path).should == URI("#{upward_base}#{relative_path}")
end

end
end

0 comments on commit 217a22b

Please sign in to comment.