Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

git-svn-id: http://svn.danwebb.net/external/microformat@177 a686c101-…

…5f17-0410-80e1-b267258107f6
  • Loading branch information...
commit 1324dd9b8fe55814d0ff1536c15cf011fe827d42 1 parent 0d661c8
danwebb authored
Showing with 99 additions and 37 deletions.
  1. +11 −1 hcard.js
  2. +5 −0 hreview.js
  3. +56 −34 microformat.js
  4. +27 −2 test/test.html
View
12 hcard.js
@@ -1,11 +1,21 @@
var HCard = Microformat.define('vcard', {
- one : ['fn', 'bday', 'tz', 'sort-string', 'uid', 'class', {
+ one : ['bday', 'tz', 'sort-string', 'uid', 'class', {
'n' : {
one : ['family-name', 'given-name', 'additional-name'],
many : ['honorific-prefix', 'honorific-suffix']
},
'geo' : {
one : ['latitude', 'longitude']
+ },
+ // inferred n from fn special case
+ 'fn' : function(node, data) {
+ var fn = this._extractData(node, 'simple');
+ if (m = fn.match(/^(\w+) (\w+)$/)) {
+ data.n = data.n || {};
+ data.n.givenName = data.n.givenName || m[1];
+ data.n.familyName = data.n.familyName || m[2];
+ }
+ return fn;
}
}],
many : ['label', 'sound', 'title', 'role', 'key', 'mailer', 'rev', 'nickname', 'category', 'note', {
View
5 hreview.js
@@ -0,0 +1,5 @@
+HReview = Microformat.define('hreview', {
+ one : ['version', 'summary', 'type', 'dtreviewed', 'rating', 'description', { 'reviewer' : HCard }, {
+ item : { one : ['fn'] }
+ }]
+});
View
90 microformat.js
@@ -1,3 +1,18 @@
+// Generic Microformat Parser v0.1 Dan Webb (dan@danwebb.net)
+// Licenced under the MIT Licence
+//
+// var people = HCard.discover();
+// people[0].fn => 'Dan Webb'
+// people[0].urlList => ['http://danwebb.net', 'http://eventwax.com']
+//
+// TODO
+//
+// Fix _propFor to work with old safari
+// Find and use unit testing framework on microformats.org test cases
+// More formats: HFeed, HEntry, HAtom, RelTag, XFN?
+
+
+// JavaScript 1.6 Iterators and generics cross-browser
if (!Array.prototype.forEach) {
Array.prototype.forEach = function(func, scope) {
scope = scope || this;
@@ -32,6 +47,7 @@ if (!Array.prototype.filter) {
}
});
+// Main Microformat namespace
Microformat = {
define : function(name, spec) {
var mf = function(node, data) {
@@ -56,51 +72,54 @@ Microformat = {
},
_parse : function(format, node) {
var data = {};
- Microformat.extend(data, this._parseOne(format, node));
- Microformat.extend(data, this._parseMany(format, node));
+ this._process(data, format.one, node, true);
+ this._process(data, format.many, node);
return data;
},
- _parseOne : function(format, context) {
- var ones = {}, node;
- format.one.forEach(function(item) {
- if (typeof item == 'string') {
- if (node = Microformat.$$(item, context)[0])
- ones[this._propFor(item)] = this._extractData(node, 'simple');
- } else {
- for (var cls in item)
- if (node = Microformat.$$(cls, context)[0]) {
- ones[this._propFor(cls)] = this._extractData(node, item[cls]);
- }
- }
- }, this);
- return ones;
- },
- _parseMany : function(format, context) {
- var manies = {}, nodes;
- format.many.forEach(function(item) {
+ _process : function(data, format, context, firstOnly) {
+ var selection, first;
+ format = format || [];
+ format.forEach(function(item) {
if (typeof item == 'string') {
- nodes = Microformat.$$(item, context);
- if (nodes.length > 0) manies[this._propFor(item) + 'List'] = nodes.map(function(node) {
- return this._extractData(node, 'simple');
- }, this);
- } else {
- nodes = Microformat.$$(cls, context);
- for (var cls in item) {
- nodes = Microformat.$$(item[cls], context);
- if (nodes.length > 0) manies[this._propFor(cls + 'List')] = nodes.map(function(node) {
- return this._extractData(node, item[cls]);
+ selection = Microformat.$$(item, context);
+
+ if (firstOnly && (first = selection[0])) {
+ data[this._propFor(item)] = this._extractData(first, 'simple', data);
+ } else if (selection.length > 0) {
+ data[this._propFor(item) + 'List'] = selection.map(function(node) {
+ return this._extractData(node, 'simple', data);
}, this);
}
+
+ } else {
+
+ for (var cls in item) {
+ selection = Microformat.$$(cls, context);
+
+ if (firstOnly && (first = selection[0])) {
+ data[this._propFor(cls)] = this._extractData(first, item[cls], data);
+ } else if (selection.length > 0) {
+ data[this._propFor(cls + 'List')] = selection.map(function(node) {
+ return this._extractData(node, item[cls], data);
+ }, this);
+ }
+ }
+
}
+
}, this);
- return manies;
+ return data;
},
- _extractData : function(node, dataType) {
+ _extractData : function(node, dataType, data) {
+ if (typeof dataType == 'function') return dataType.call(this, node, data);
+
switch (dataType) {
case 'simple': return this._extractSimple(node);
case 'url': return this._extractURL(node);
}
- return this._parse(dataType, node);
+
+ if (dataType._parse) return dataType._parse(dataType.format, node);
+ else return this._parse(dataType, node);
},
_extractURL : function(node) {
var href;
@@ -112,7 +131,7 @@ Microformat = {
case 'object': href = node.data;
}
if (href) {
- if (href.indexOf('mailto:') == 1)
+ if (href.indexOf('mailto:') == 0)
href = href.replace(/^mailto:/, '').replace(/\?.*$/, '');
return href;
}
@@ -153,6 +172,7 @@ Microformat = {
if (this.handlers[prop]) this.handlers[prop].call(this, item, data);
}
},
+ // In built getElementsByClassName
$$ : function(className, context) {
context = context || document;
var nodeList;
@@ -171,9 +191,11 @@ Microformat = {
var re = new RegExp('(^|\\s)' + className + '(\\s|$)');
return Array.filter(nodeList, function(node) { return node.className.match(re) });
},
+ // In built Object.extend equivilent
extend : function(dest, source) {
for (var prop in source) dest[prop] = source[prop];
return dest;
},
+ // methods available to all instances of a microformat
Base : {}
};
View
29 test/test.html
@@ -9,19 +9,24 @@
<script src="../microformat.js"></script>
<script src="../hcard.js"></script>
<script src="../hcalendar.js"></script>
+ <script src="../hreview.js"></script>
</head>
<body>
<h1>Thing</h1>
<div id="bung">
+<h1>Microformat Parsing Tests</h1>
+
+ <h2>hCards</h2>
<div class="vcard">
- <h2><a href="http://danwebb.net" class="fn n url"><span class="given-name">Dan</span> <span class="family-name">Webb</span></a> <em class="role">Developer</em> <em class="role">Director</em></h2>
+ <h3><a href="http://danwebb.net" class="fn n url"><span class="given-name">Dan</span> <span class="family-name">Webb</span></a> <em class="role">Developer</em> <em class="role">Director</em></h3>
</div>
<div class="vcard">
- <h2><a href="http://bob.net" class="fn url">Bob Fucker</a> <em class="role">Underling</em></h2>
+ <h3><a href="http://bob.net" class="fn url">Bob Fucker</a> <em class="role">Underling</em></h3>
</div>
+ <h2>HCalendars</h2>
<ul class="ll">
<li class="vevent"><a href="http://upcoming.org/event/144326" class="url summary">London Ruby User Group (LRUG) February Meeting</a>, <span class="location">London</span> <abbr title="2007-02-12" class="dtstart">12 FEB</abbr> - <abbr title="2007-02-06" class="dtend">06 FEB</abbr>.</li>
@@ -53,6 +58,26 @@
</ul>
+
+ <h2>HReviews</h2>
+
+ <div class="hreview">
+ <span><span class="rating">5</span> out of 5 stars</span>
+ <h4 class="summary">Crepes on Cole is awesome</h4>
+ <span class="reviewer vcard">Reviewer: <span class="fn">Tantek</span> -
+ <abbr class="dtreviewed" title="20050418T2300-0700">April 18, 2005</abbr></span>
+ <div class="description item vcard"><p>
+ <span class="fn org">Crepes on Cole</span> is one of the best little
+ creperies in <span class="adr"><span class="locality">San Francisco</span></span>.
+ Excellent food and service. Plenty of tables in a variety of sizes
+ for parties large and small. Window seating makes for excellent
+ people watching to/from the N-Judah which stops right outside.
+ I've had many fun social gatherings here, as well as gotten
+ plenty of work done thanks to neighborhood WiFi.
+ </p></div>
+ <p>Visit date: <span>April 2005</span></p>
+ <p>Food eaten: <span>Florentine crepe</span></p>
+ </div>
</div>
</body>
</html>
Please sign in to comment.
Something went wrong with that request. Please try again.