diff --git a/README.md b/README.md index f073462..c164c56 100644 --- a/README.md +++ b/README.md @@ -20,10 +20,10 @@ Implemented: * nested microformat with associated property * dynamic creation of properties * [rel](http://microformats.org/wiki/rel) +* [normalize u-* property values](http://microformats.org/wiki/microformats2-parsing-faq#normalizing_u-.2A_property_values) Not Implemented: -* [normalize u-* property values](http://microformats.org/wiki/microformats2-parsing-faq#normalizing_u-.2A_property_values) * nested microformat without associated property * [value-class-pattern](http://microformats.org/wiki/value-class-pattern) * [include-pattern](http://microformats.org/wiki/include-pattern) diff --git a/lib/microformats2/collection.rb b/lib/microformats2/collection.rb index 475031c..8469ecc 100644 --- a/lib/microformats2/collection.rb +++ b/lib/microformats2/collection.rb @@ -25,7 +25,7 @@ module Microformats2 end def all - @all ||= FormatParser.parse(@element).each do |format| + @all ||= FormatParser.parse(@element, @base).each do |format| save_format_name(format.method_name) define_method(format.method_name) set_value(format.method_name, format) diff --git a/lib/microformats2/format.rb b/lib/microformats2/format.rb index 0cd352f..74ba975 100644 --- a/lib/microformats2/format.rb +++ b/lib/microformats2/format.rb @@ -4,8 +4,9 @@ module Microformats2 attr_reader :method_name - def initialize(element) + def initialize(element, base) @element = element + @base = base @method_name = to_method_name(format_types.first) @property_names = [] end @@ -27,20 +28,20 @@ module Microformats2 end def parse_properties - PropertyParser.parse(@element.children).each do |property| + PropertyParser.parse(@element.children, @base).each do |property| assign_property(property) end end def add_property(property_class, value) - property = Property.new(nil, property_class, value) + property = Property.new(nil, property_class, value, @base) assign_property(property) end def parse_implied_properties ip = [] ip << ImpliedProperty::Name.new(@element).parse unless property_present?(:name) - ip << ImpliedProperty::Url.new(@element).parse unless property_present?(:url) + ip << ImpliedProperty::Url.new(@element, @base).parse unless property_present?(:url) ip << ImpliedProperty::Photo.new(@element).parse unless property_present?(:photo) ip.compact.each do |property| save_property_name(property.method_name) diff --git a/lib/microformats2/format_parser.rb b/lib/microformats2/format_parser.rb index 0edcb0b..bee2a3e 100644 --- a/lib/microformats2/format_parser.rb +++ b/lib/microformats2/format_parser.rb @@ -1,7 +1,8 @@ module Microformats2 class FormatParser class << self - def parse(element) + def parse(element, base=nil) + @@base = base parse_node(element).flatten.compact end @@ -31,7 +32,7 @@ module Microformats2 const_name = constant_name(html_class) klass = find_or_create_ruby_class(const_name) - klass.new(element).parse + klass.new(element, @@base).parse end def format_classes(element) diff --git a/lib/microformats2/implied_property/foundation.rb b/lib/microformats2/implied_property/foundation.rb index 57bf199..fcd8fa4 100644 --- a/lib/microformats2/implied_property/foundation.rb +++ b/lib/microformats2/implied_property/foundation.rb @@ -2,8 +2,9 @@ module Microformats2 module ImpliedProperty class Foundation - def initialize(element) + def initialize(element, base=nil) @element = element + @base = base end def parse diff --git a/lib/microformats2/implied_property/url.rb b/lib/microformats2/implied_property/url.rb index 1fb3af0..54ae407 100644 --- a/lib/microformats2/implied_property/url.rb +++ b/lib/microformats2/implied_property/url.rb @@ -6,6 +6,22 @@ module Microformats2 "url" end + def to_s + @to_s = absolutize(super.to_s) if super.to_s != "" + end + + # TODO: make dry, repeated in Collection + def absolutize(href) + uri = URI.parse(href) + + if @base && !uri.absolute? + uri = URI.join(@base, href) + end + + uri.normalize! + uri.to_s + end + protected def name_map diff --git a/lib/microformats2/property.rb b/lib/microformats2/property.rb index 44eb9ab..3d35dd9 100644 --- a/lib/microformats2/property.rb +++ b/lib/microformats2/property.rb @@ -8,13 +8,13 @@ module Microformats2 "e" => Embedded } class << self - def new(element, property_class, value=nil) + def new(element, property_class, value=nil, base=nil) # p-class-name -> p prefix = property_class.split("-").first # find ruby class for kind of property klass = PREFIX_CLASS_MAP[prefix] raise InvalidPropertyPrefix unless klass - klass.new(element, property_class, value) + klass.new(element, property_class, value, base) end end end diff --git a/lib/microformats2/property/foundation.rb b/lib/microformats2/property/foundation.rb index 75aa423..8851f8e 100644 --- a/lib/microformats2/property/foundation.rb +++ b/lib/microformats2/property/foundation.rb @@ -3,10 +3,11 @@ module Microformats2 class Foundation attr_reader :method_name - def initialize(element, html_class, string_value=nil) + def initialize(element, html_class, string_value=nil, base=nil) @element = element @method_name = to_method_name(html_class) @string_value = string_value + @base = base end def parse diff --git a/lib/microformats2/property/url.rb b/lib/microformats2/property/url.rb index 1d45522..85847a6 100644 --- a/lib/microformats2/property/url.rb +++ b/lib/microformats2/property/url.rb @@ -2,6 +2,22 @@ module Microformats2 module Property class Url < Foundation + def to_s + @to_s = absolutize(super.to_s) + end + + # TODO: make dry, repeated in Collection + def absolutize(href) + uri = URI.parse(href) + + if @base && !uri.absolute? + uri = URI.join(@base, href) + end + + uri.normalize! + uri.to_s + end + protected def attr_map diff --git a/lib/microformats2/property_parser.rb b/lib/microformats2/property_parser.rb index 62f00d1..003273d 100644 --- a/lib/microformats2/property_parser.rb +++ b/lib/microformats2/property_parser.rb @@ -1,7 +1,8 @@ module Microformats2 class PropertyParser class << self - def parse(element) + def parse(element, base) + @@base = base parse_node(element).flatten.compact end @@ -26,8 +27,8 @@ module Microformats2 def parse_property(element) property_classes(element).map do |property_class| - property = Property.new(element, property_class).parse - properties = format_classes(element).empty? ? PropertyParser.parse(element.children) : [] + property = Property.new(element, property_class, nil, @@base).parse + properties = format_classes(element).empty? ? PropertyParser.parse(element.children, @@base) : [] [property].concat properties end diff --git a/spec/lib/microformats2/collection_spec.rb b/spec/lib/microformats2/collection_spec.rb index 496f9c7..44e5c49 100644 --- a/spec/lib/microformats2/collection_spec.rb +++ b/spec/lib/microformats2/collection_spec.rb @@ -35,13 +35,13 @@ describe Microformats2::Collection do @collection.card.name.should be_kind_of Microformats2::Property::Text end end - describe "'.h-card .p-url'" do + describe "'.h-card .u-url'" do it "assigns all urls to HCard#urls" do - urls = ["http://flickr.com/jlsuttles", "http://twitter.com/jlsuttles"] + urls = ["http://example.org/", "http://flickr.com/", "http://twitter.com/jlsuttles"] @collection.card.urls.map(&:to_s).should == urls end it "assigns then first url to HCard#url" do - @collection.card.url.to_s.should == "http://flickr.com/jlsuttles" + @collection.card.url.to_s.should == "http://example.org/" end it "HCard#url is a Property::Url" do @collection.card.url.should be_kind_of Microformats2::Property::Url @@ -176,7 +176,7 @@ describe Microformats2::Collection do end end end - + describe "rels.html" do before do html = "spec/support/lib/microformats2/rels.html" diff --git a/spec/lib/microformats2/implied_property/url_spec.rb b/spec/lib/microformats2/implied_property/url_spec.rb index 3c736f0..9a99b80 100644 --- a/spec/lib/microformats2/implied_property/url_spec.rb +++ b/spec/lib/microformats2/implied_property/url_spec.rb @@ -15,6 +15,33 @@ describe Microformats2::ImpliedProperty::Url do end end end + + describe "url-relative.html" do + html = "spec/support/lib/microformats2/implied_property/url-relative.html" + collection = Microformats2.parse(html) + it "should have 2 microformats" do + collection.all.length.should == 2 + end + collection.all.each_with_index do |format, index| + it "implies url to be 'http://example.org/' in case #{index+1}" do + format.url.to_s.should == "http://example.org/" + end + end + end + + describe "url-unnormalized.html" do + html = "spec/support/lib/microformats2/implied_property/url-unnormalized.html" + collection = Microformats2.parse(html) + it "should have 2 microformats" do + collection.all.length.should == 2 + end + collection.all.each_with_index do |format, index| + it "implies url to be 'http://github.com/' in case #{index+1}" do + format.url.to_s.should == "http://github.com/" + end + end + end + describe "url-fail.html" do html = "spec/support/lib/microformats2/implied_property/url-fail.html" collection = Microformats2.parse(html) @@ -22,8 +49,8 @@ describe Microformats2::ImpliedProperty::Url do collection.all.length.should == 2 end collection.all.each_with_index do |format, index| - it "implies url to be '' in case #{index+1}" do - expect {format.url.to_s.should == ""}.to raise_error(NoMethodError) + it "does not imply url in case #{index+1}" do + expect {format.url}.to raise_error(NoMethodError) end end end diff --git a/spec/support/lib/microformats2/implied_property/url-relative.html b/spec/support/lib/microformats2/implied_property/url-relative.html new file mode 100644 index 0000000..a382200 --- /dev/null +++ b/spec/support/lib/microformats2/implied_property/url-relative.html @@ -0,0 +1,13 @@ + + + + + + + +
+ +
+ + + diff --git a/spec/support/lib/microformats2/implied_property/url-unnormalized.html b/spec/support/lib/microformats2/implied_property/url-unnormalized.html new file mode 100644 index 0000000..641af02 --- /dev/null +++ b/spec/support/lib/microformats2/implied_property/url-unnormalized.html @@ -0,0 +1,12 @@ + + + + + + +
+ +
+ + + diff --git a/spec/support/lib/microformats2/simple.html b/spec/support/lib/microformats2/simple.html index 42c60bd..551e9a2 100644 --- a/spec/support/lib/microformats2/simple.html +++ b/spec/support/lib/microformats2/simple.html @@ -1,10 +1,14 @@ +
- + Jessica Lynn Suttles + + @jlsuttles + @jlsuttles diff --git a/spec/support/lib/microformats2/simple.js b/spec/support/lib/microformats2/simple.js index c549abf..e36fe70 100644 --- a/spec/support/lib/microformats2/simple.js +++ b/spec/support/lib/microformats2/simple.js @@ -1,7 +1,7 @@ { "items": [{ "type": ["h-card"], "properties": { - "url": ["http://flickr.com/jlsuttles", "http://twitter.com/jlsuttles"], + "url": ["http://example.org/", "http://flickr.com/", "http://twitter.com/jlsuttles"], "name": ["Jessica Lynn Suttles"], "bday": ["1990-10-15"], "content": ["

Vegan. Cat lover. Coder.

"]