Merge pull request #20 from G5/normalize-u-property-values
Normalize u-* property values
This commit is contained in:
commit
210e8cf96c
16 changed files with 116 additions and 23 deletions
|
@ -20,10 +20,10 @@ Implemented:
|
||||||
* nested microformat with associated property
|
* nested microformat with associated property
|
||||||
* dynamic creation of properties
|
* dynamic creation of properties
|
||||||
* [rel](http://microformats.org/wiki/rel)
|
* [rel](http://microformats.org/wiki/rel)
|
||||||
|
* [normalize u-* property values](http://microformats.org/wiki/microformats2-parsing-faq#normalizing_u-.2A_property_values)
|
||||||
|
|
||||||
Not Implemented:
|
Not Implemented:
|
||||||
|
|
||||||
* [normalize u-* property values](http://microformats.org/wiki/microformats2-parsing-faq#normalizing_u-.2A_property_values)
|
|
||||||
* nested microformat without associated property
|
* nested microformat without associated property
|
||||||
* [value-class-pattern](http://microformats.org/wiki/value-class-pattern)
|
* [value-class-pattern](http://microformats.org/wiki/value-class-pattern)
|
||||||
* [include-pattern](http://microformats.org/wiki/include-pattern)
|
* [include-pattern](http://microformats.org/wiki/include-pattern)
|
||||||
|
|
|
@ -25,7 +25,7 @@ module Microformats2
|
||||||
end
|
end
|
||||||
|
|
||||||
def all
|
def all
|
||||||
@all ||= FormatParser.parse(@element).each do |format|
|
@all ||= FormatParser.parse(@element, @base).each do |format|
|
||||||
save_format_name(format.method_name)
|
save_format_name(format.method_name)
|
||||||
define_method(format.method_name)
|
define_method(format.method_name)
|
||||||
set_value(format.method_name, format)
|
set_value(format.method_name, format)
|
||||||
|
|
|
@ -4,8 +4,9 @@ module Microformats2
|
||||||
|
|
||||||
attr_reader :method_name
|
attr_reader :method_name
|
||||||
|
|
||||||
def initialize(element)
|
def initialize(element, base)
|
||||||
@element = element
|
@element = element
|
||||||
|
@base = base
|
||||||
@method_name = to_method_name(format_types.first)
|
@method_name = to_method_name(format_types.first)
|
||||||
@property_names = []
|
@property_names = []
|
||||||
end
|
end
|
||||||
|
@ -27,20 +28,20 @@ module Microformats2
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_properties
|
def parse_properties
|
||||||
PropertyParser.parse(@element.children).each do |property|
|
PropertyParser.parse(@element.children, @base).each do |property|
|
||||||
assign_property(property)
|
assign_property(property)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def add_property(property_class, value)
|
def add_property(property_class, value)
|
||||||
property = Property.new(nil, property_class, value)
|
property = Property.new(nil, property_class, value, @base)
|
||||||
assign_property(property)
|
assign_property(property)
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse_implied_properties
|
def parse_implied_properties
|
||||||
ip = []
|
ip = []
|
||||||
ip << ImpliedProperty::Name.new(@element).parse unless property_present?(:name)
|
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 << ImpliedProperty::Photo.new(@element).parse unless property_present?(:photo)
|
||||||
ip.compact.each do |property|
|
ip.compact.each do |property|
|
||||||
save_property_name(property.method_name)
|
save_property_name(property.method_name)
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
class FormatParser
|
class FormatParser
|
||||||
class << self
|
class << self
|
||||||
def parse(element)
|
def parse(element, base=nil)
|
||||||
|
@@base = base
|
||||||
parse_node(element).flatten.compact
|
parse_node(element).flatten.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -31,7 +32,7 @@ module Microformats2
|
||||||
const_name = constant_name(html_class)
|
const_name = constant_name(html_class)
|
||||||
klass = find_or_create_ruby_class(const_name)
|
klass = find_or_create_ruby_class(const_name)
|
||||||
|
|
||||||
klass.new(element).parse
|
klass.new(element, @@base).parse
|
||||||
end
|
end
|
||||||
|
|
||||||
def format_classes(element)
|
def format_classes(element)
|
||||||
|
|
|
@ -2,8 +2,9 @@ module Microformats2
|
||||||
module ImpliedProperty
|
module ImpliedProperty
|
||||||
class Foundation
|
class Foundation
|
||||||
|
|
||||||
def initialize(element)
|
def initialize(element, base=nil)
|
||||||
@element = element
|
@element = element
|
||||||
|
@base = base
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
|
|
|
@ -6,6 +6,22 @@ module Microformats2
|
||||||
"url"
|
"url"
|
||||||
end
|
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
|
protected
|
||||||
|
|
||||||
def name_map
|
def name_map
|
||||||
|
|
|
@ -8,13 +8,13 @@ module Microformats2
|
||||||
"e" => Embedded }
|
"e" => Embedded }
|
||||||
|
|
||||||
class << self
|
class << self
|
||||||
def new(element, property_class, value=nil)
|
def new(element, property_class, value=nil, base=nil)
|
||||||
# p-class-name -> p
|
# p-class-name -> p
|
||||||
prefix = property_class.split("-").first
|
prefix = property_class.split("-").first
|
||||||
# find ruby class for kind of property
|
# find ruby class for kind of property
|
||||||
klass = PREFIX_CLASS_MAP[prefix]
|
klass = PREFIX_CLASS_MAP[prefix]
|
||||||
raise InvalidPropertyPrefix unless klass
|
raise InvalidPropertyPrefix unless klass
|
||||||
klass.new(element, property_class, value)
|
klass.new(element, property_class, value, base)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -3,10 +3,11 @@ module Microformats2
|
||||||
class Foundation
|
class Foundation
|
||||||
attr_reader :method_name
|
attr_reader :method_name
|
||||||
|
|
||||||
def initialize(element, html_class, string_value=nil)
|
def initialize(element, html_class, string_value=nil, base=nil)
|
||||||
@element = element
|
@element = element
|
||||||
@method_name = to_method_name(html_class)
|
@method_name = to_method_name(html_class)
|
||||||
@string_value = string_value
|
@string_value = string_value
|
||||||
|
@base = base
|
||||||
end
|
end
|
||||||
|
|
||||||
def parse
|
def parse
|
||||||
|
|
|
@ -2,6 +2,22 @@ module Microformats2
|
||||||
module Property
|
module Property
|
||||||
class Url < Foundation
|
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
|
protected
|
||||||
|
|
||||||
def attr_map
|
def attr_map
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
module Microformats2
|
module Microformats2
|
||||||
class PropertyParser
|
class PropertyParser
|
||||||
class << self
|
class << self
|
||||||
def parse(element)
|
def parse(element, base)
|
||||||
|
@@base = base
|
||||||
parse_node(element).flatten.compact
|
parse_node(element).flatten.compact
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -26,8 +27,8 @@ module Microformats2
|
||||||
|
|
||||||
def parse_property(element)
|
def parse_property(element)
|
||||||
property_classes(element).map do |property_class|
|
property_classes(element).map do |property_class|
|
||||||
property = Property.new(element, property_class).parse
|
property = Property.new(element, property_class, nil, @@base).parse
|
||||||
properties = format_classes(element).empty? ? PropertyParser.parse(element.children) : []
|
properties = format_classes(element).empty? ? PropertyParser.parse(element.children, @@base) : []
|
||||||
|
|
||||||
[property].concat properties
|
[property].concat properties
|
||||||
end
|
end
|
||||||
|
|
|
@ -35,13 +35,13 @@ describe Microformats2::Collection do
|
||||||
@collection.card.name.should be_kind_of Microformats2::Property::Text
|
@collection.card.name.should be_kind_of Microformats2::Property::Text
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
describe "'.h-card .p-url'" do
|
describe "'.h-card .u-url'" do
|
||||||
it "assigns all urls to HCard#urls" 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
|
@collection.card.urls.map(&:to_s).should == urls
|
||||||
end
|
end
|
||||||
it "assigns then first url to HCard#url" do
|
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
|
end
|
||||||
it "HCard#url is a Property::Url" do
|
it "HCard#url is a Property::Url" do
|
||||||
@collection.card.url.should be_kind_of Microformats2::Property::Url
|
@collection.card.url.should be_kind_of Microformats2::Property::Url
|
||||||
|
|
|
@ -15,6 +15,33 @@ describe Microformats2::ImpliedProperty::Url do
|
||||||
end
|
end
|
||||||
end
|
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
|
describe "url-fail.html" do
|
||||||
html = "spec/support/lib/microformats2/implied_property/url-fail.html"
|
html = "spec/support/lib/microformats2/implied_property/url-fail.html"
|
||||||
collection = Microformats2.parse(html)
|
collection = Microformats2.parse(html)
|
||||||
|
@ -22,8 +49,8 @@ describe Microformats2::ImpliedProperty::Url do
|
||||||
collection.all.length.should == 2
|
collection.all.length.should == 2
|
||||||
end
|
end
|
||||||
collection.all.each_with_index do |format, index|
|
collection.all.each_with_index do |format, index|
|
||||||
it "implies url to be '' in case #{index+1}" do
|
it "does not imply url in case #{index+1}" do
|
||||||
expect {format.url.to_s.should == ""}.to raise_error(NoMethodError)
|
expect {format.url}.to raise_error(NoMethodError)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
<base href="http://example.org/">
|
||||||
|
|
||||||
|
<a class="h-card" href="/" />
|
||||||
|
|
||||||
|
<div class="h-card">
|
||||||
|
<a href="/" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<a class="h-card" href="http://github.com" />
|
||||||
|
|
||||||
|
<div class="h-card">
|
||||||
|
<a href="http://github.com" />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -1,10 +1,14 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
|
<base href="http://example.org/">
|
||||||
<body>
|
<body>
|
||||||
<div class="h-card">
|
<div class="h-card">
|
||||||
<a href="http://flickr.com/jlsuttles" class="u-url p-name">
|
<a href="/" class="u-url p-name">
|
||||||
Jessica Lynn Suttles
|
Jessica Lynn Suttles
|
||||||
</a>
|
</a>
|
||||||
|
<a href="http://flickr.com" class="u-url">
|
||||||
|
@jlsuttles
|
||||||
|
</a>
|
||||||
<a href="http://twitter.com/jlsuttles" class="u-url">
|
<a href="http://twitter.com/jlsuttles" class="u-url">
|
||||||
@jlsuttles
|
@jlsuttles
|
||||||
</a>
|
</a>
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
{ "items": [{
|
{ "items": [{
|
||||||
"type": ["h-card"],
|
"type": ["h-card"],
|
||||||
"properties": {
|
"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"],
|
"name": ["Jessica Lynn Suttles"],
|
||||||
"bday": ["1990-10-15"],
|
"bday": ["1990-10-15"],
|
||||||
"content": ["<p>Vegan. Cat lover. Coder.</p>"]
|
"content": ["<p>Vegan. Cat lover. Coder.</p>"]
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue