/* -*- mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
(function(){
var $ = jQuery;
$.microdata = {};
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-time-string
function validTimeStringLength(s) {
var m = /^(\d\d):(\d\d)(:(\d\d)(\.\d+)?)?/.exec(s);
if (m && m[1]<=23 && m[2]<=59 && (!m[4] || m[4]<=59))
return m[0].length;
return 0;
}
function isValidTimeString(s) {
return s && validTimeStringLength(s) == s.length;
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#number-of-days-in-month-month-of-year-year
function daysInMonth(year, month) {
if (month==1 || month==3 || month==5 || month==7 ||
month==8 || month==10 || month==12) {
return 31;
} else if (month==4 || month==6 || month==9 || month==11) {
return 30;
} else if (month == 2 && (year%400==0 || (year%4==0 && year%100!=0))) {
return 29;
} else {
return 28;
}
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-date-string
function validDateStringLength(s) {
var m = /^(\d{4,})-(\d\d)-(\d\d)/.exec(s);
if (m && m[1]>=1 && m[2]>=1 && m[2]<=12 && m[3]>=1 && m[3]<=daysInMonth(m[1],m[2]))
return m[0].length;
return 0;
}
function isValidDateString(s) {
return s && validDateStringLength(s) == s.length;
}
// http://www.whatwg.org/specs/web-apps/current-work/multipage/common-microsyntaxes.html#valid-global-date-and-time-string
function isValidGlobalDateAndTimeString(s) {
var skip = validDateStringLength(s);
if (skip && s[skip] == 'T') {
s = s.substr(skip+1);
skip = validTimeStringLength(s);
if (skip) {
s = s.substr(skip);
if (s == 'Z')
return true;
var m = /^[+-](\d\d):(\d\d)$/.exec(s);
if (m && m[1]<=23 && m[2]<=59)
return true;
}
}
return false;
}
$.microdata.isValidGlobalDateAndTimeString = isValidGlobalDateAndTimeString;
$.microdata.isValidDateString = isValidDateString;
function splitTokens(s) {
if (s && /\S/.test(s))
return s.replace(/^\s+|\s+$/g,'').split(/\s+/);
return [];
}
function getItems(types) {
var doc = this[0];
if (doc.getItems)
return $(types ? doc.getItems(types) : doc.getItems());
var selector = $.map(splitTokens(types), function(t) {
return '[itemtype~="'+t.replace(/"/g, '\\"')+'"]';
}).join(',') || '*';
// filter results to only match top-level items.
// because [attr] selector doesn't work in IE we have to
// filter the elements. http://dev.jquery.com/ticket/5637
return $(selector, this).filter(function() {
return (this.getAttribute('itemscope') != null &&
this.getAttribute('itemprop') == null);
});
}
// find the furthest ancestor (usually Document)
function ancestor(node) {
while (node.parentNode)
node = node.parentNode;
return node;
}
function resolve(elm, attr) {
// in order to handle