Sync vCard itemref loop handling with spec
[microdatajs:microdatajs.git] / jquery.microdata.vevent.js
1 /* -*- mode: js; js-indent-level: 2; indent-tabs-mode: nil -*- */
2
3 // http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html#conversion-to-icalendar
4 jQuery.microdata.ical = function(selector) {
5   var $ = jQuery;
6
7   var veventURI = 'http://microformats.org/profile/hcalendar#vevent';
8   var $events = selector ?
9     $(selector).filter(function() {
10       var $this = $(this);
11       return $this.itemScope() && $this.itemType() == veventURI;
12     }) :
13     $(document).items(veventURI);
14   if ($events.length == 0)
15     return;
16
17   var output = '';
18   // http://www.whatwg.org/specs/web-apps/current-work/multipage/microdata.html#add-an-icalendar-line
19   function addLine(type, value, annotation) {
20     var line = '';
21     line += type.toUpperCase();
22     if (annotation)
23       line += ';'+annotation;
24     line += ':';
25     line += value.replace(/([\\,;])/g, '\\$1').replace(/\r\n|\r|\n/g, '\\n');
26     var maxLen = 75;
27     while (line.length > maxLen) {
28       output += line.substr(0, maxLen);
29       line = line.substr(maxLen);
30       output += '\r\n ';
31       maxLen = 74;
32     }
33     output += line+'\r\n';
34   }
35   addLine('BEGIN', 'VCALENDAR');
36   addLine('PRODID', 'jQuery Microdata');
37   addLine('VERSION', '2.0');
38   $events.each(function() {
39     var $event = $(this);
40     addLine('BEGIN', 'VEVENT');
41     function zp(n) { return (n < 10 ? '0' : '') + n; }
42     var stamp = new Date();
43     var stampString = '' + stamp.getUTCFullYear() + zp(stamp.getUTCMonth() + 1) +
44         zp(stamp.getUTCDate()) + 'T' + zp(stamp.getUTCHours()) +
45         zp(stamp.getUTCMinutes()) + zp(stamp.getUTCSeconds()) + 'Z';
46     addLine('DTSTAMP', stampString, 'VALUE=DATE-TIME');
47     if ($event.itemId())
48       addLine('UID', $event.itemId());
49     $event.properties().each(function() {
50       var $elem = $(this);
51       if ($elem.itemScope())
52         return;
53       $elem.itemProp().each(function() {
54         var name = this;
55         if ($elem.get(0).tagName.toUpperCase() == 'TIME') {
56           var value = $elem.itemValue().replace(/[-:]/g, '');
57           if ($.microdata.isValidDateString($elem.itemValue())) {
58             addLine(name, value, "VALUE=DATE");
59           } else if ($.microdata.isValidGlobalDateAndTimeString($elem.itemValue())) {
60             addLine(name, value, "VALUE=DATE-TIME");
61           }
62         } else {
63           addLine(name, $elem.itemValue());
64         }
65       });
66     });
67     addLine('END', 'VEVENT');
68   });
69   addLine('END', 'VCALENDAR');
70   return output;
71 };