The Device APIs Working Group is currently not pursuing the approach outlined in this draft, so it should be considered historical. Please treat this document with caution and do not reference it or use it as the basis for implementation. The domain covered by this document is still within the scope of the Working Group as defined in its Charter. The Working Group may pursue an alternative API design that is based on the current Web browser security model.

The Calendar API defines the high-level interfaces required to obtain read access to a user's calendaring service.

This API includes the following key interfaces:

The approach proposed for this API is very similar to the one taken in the Contacts API. The known issues in the document are highlighted below, and concern in particular the management of timezones and recurrence.

Introduction

The Calendar API defines a high-level interface to access Calendar information such as events, reminders, alarms and other calendar information.

The API itself is designed to be agnostic of any underlying calendaring service sources.

A set of Security and Privacy Considerations are presented for the discretion of both implementors of the Calendar API and recipients of calendaring information (i.e. web pages). This specification provides a set of non-normative User Interaction Guidelines demonstrating an example user experience that is compliant with the Security and Privacy Considerations provided herein.

This specification also provides informative examples illustrating how to add and update calendar events, utilising existing web platform APIs.

Scope

The requirements for this set of interfaces are listed in the Device API Requirements document [[DAP-REQS]].

The API provided in this specification is limited to providing a programmatic way to retrieve Calendar information.

The scope of this specification does not include the ability to attach Contacts to Calendar Events or vice versa. This denotes cross-API dependency and the intention of this specification is to provide a standalone API for the provision and management of Calendar Event information.

This specification requires that formatting for all dates and times be applied according to the definition of valid date and time string in [[!HTML5]].

Usage Example

The following code illustrates how to obtain calendaring information from a user's calendar:

function success (events) {
    // do something with resulting list of objects
    for (var i in events) alert(events[i].id);
}

function error (err) {
    // do something with resulting errors
    alert(err.code);
}

// Perform an calendar search. Initially filter the list to Calendar records starting 
// before April 9, 2011 @ 5pm (UTC).
navigator.calendar.findEvents( success, error, { filter: { startBefore: '2011-04-10T05:00:00+12:00' } });

This specification defines conformance criteria that apply to a single product: the user agent that implements the interfaces that it contains.

Implementations that use ECMAScript to implement the APIs defined in this specification must implement them in a manner consistent with the ECMAScript Bindings defined in the Web IDL specification [[!WEBIDL]], as this specification uses that specification’s terminology.

Terminology

The terms document base URL, browsing context, event handler attributes, event handler event type, task, task source and task queues are defined by the HTML5 specification [[!HTML5]].

The task source used by this specification is the device task source.

To dispatch a success event means that an event with the name success, which does not bubble and is not cancelable, and which uses the Event interface, is to be dispatched at the CalendarEventSuccessCB object.

To dispatch an error event means that an event with the name error, which does not bubble and is not cancelable, and which uses the Event interface, is to be dispatched at the CalendarErrorCB object.

Security and Privacy Considerations

The overall architecture for addressing privacy in DAP is still under construction. As it is finalized, there may be changes made to this API to reflect requirements or support for privacy-related functionality.

The API defined in this specification can be used to create, retrieve, update and remove calendar event information from a user's calendar. All API methods disclose information related to a user's calendars such as events, schedules and reminders and other personally identifying information. The distribution of this information could potentially compromise the user's privacy. A conforming implementation of this specification MUST provide a mechanism that protects the user's privacy and this mechanism should ensure that no calendar information is creatable, retrivable, updateable or removable without the user's express permission.

Privacy considerations for implementors of the Calendar API

A user agent must not create, retrieve, update or delete calendar information to Web sites without the express permission of the user. A user agent must acquire permission through a user interface, unless they have prearranged trust relationships with users, as described below. The user interface must include the URI of the document origin, as defined in [[HTML5]]. Those permissions that are acquired through the user interface and that are preserved beyond the current browsing session (i.e. beyond the time when the browsing context, as defined in [[HTML5]], is navigated to another URL) MUST be revocable and a user agent must respect revoked permissions.

Obtaining the user's express permission to access one API method does not imply the user has granted permission for the same Web site to access other methods provided by this API, or to access the same method with a different set of arguments, as part of the same permission context. If a user has expressed permission for an implementation to, e.g. find a set of existing calendar events, the implementation must seek the user's express permission if and when any additional create, find, update or remove function is called on this API.

A user agent may have prearranged trust relationships that do not require such user interfaces. For example, while a Web browser will present a user interface when a Web site performs a calendar request, a Widget Runtime MAY have a prearranged, delegated security relationship with the user and, as such, a suitable alternative security and privacy mechanism with which to authorize the creation, retrieval, update and/or removal of calendar event information.

Privacy considerations for recipients of calendar information

Recipients should take care to only request calendar information when necessary, and only use the calendar information for the task for which it was provided to them. Recipients are invited to dispose of calendar information once that task is completed, unless expressly permitted to retain it by the user, and to take measures to protect this information against unauthorized access. If calendar information is stored, users should be allowed to update and delete this information.

The recipient of calendar information should not retransmit the calendar information without the user’s express permission. Care should be taken when retransmitting and use of encryption is encouraged.

Recipients should clearly and conspicuously disclose the fact that they are collecting calendar data, the purpose for the collection, how long the data is retained, how the data is secured, how the data is shared if it is shared, how users can access, update and delete the data, and any other choices that users have with respect to the data. This disclosure should include an explanation of any exceptions to the guidelines listed above.

Additional implementation considerations

Further to the requirements listed in the previous section, implementors of the Calendar API are also advised to consider the following aspects that can negatively affect the privacy of their users: in certain cases, users can inadvertently grant permission to the User Agent to disclose their calendar items to Web sites. In other cases, the content hosted at a certain URL changes in such a way that the previously granted calendar permissions no longer apply as far as the user is concerned. Or the users might simply change their minds.

Predicting or preventing these situations is inherently difficult. Mitigation and in-depth defensive measures are an implementation responsibility and not prescribed by this specification. However, in designing these measures, implementers are advised to enable user awareness of calendar sharing, and to provide easy access to interfaces that enable revocation of permissions.

API Description

ServiceCalendar interface

The ServiceCalendar interface is exposed on the Navigator interface [[NAVIGATOR]].

readonly attribute Calendar calendar
The root node from which the calendar functionality can be accessed.

Calendar interface

The Calendar interface provides a method to retrieve calendaring information from a user's calendar.

caller void findEvents ()

Find calendar event items in the calendar based on an CalendarEventFilter object.

This method takes between one and three arguments. When called, it immediately returns, and then asynchronously start a find calendar event items process defined as follows:

  1. If there are any tasks from the device task source in one of the task queues (i.e. an existing findEvents() operation is still pending a response), and the current method was invoked with a non-null errorCB argument, dispatch an error event with a PENDING_OPERATION_ERROR code value.
  2. Search for calendar event items in the calendar according to the calendar item search processing rules.
  3. If the attempt was successful, dispatch a success event. If the attempt fails, and the method was invoked with a non-null errorCB argument, this method must dispatch an error event with the code attribute set according to the type of failure that has occurred.
CalendarEventSuccessCB successCB
Function to call when the asynchronous operation completes
optional CalendarErrorCB errorCB
Function to call when the asynchronous operation fails.
optional CalendarFindOptions options
The options to apply to the output of this method.

CalendarEvent interface

The CalendarEvent interface captures a calendar event object.

The current use of DOMString for dates and times is known to be insufficient for representing events with timezones. The group is working on addressing that limitation, looking at the development of TZDate object that would address this.
readonly attribute DOMString id

A globally unique identifier for the given CalendarEvent object. Each CalendarEvent referenced from Calendar MUST include a non-empty id value.

An implementation MUST maintain this globally unique resource identifier when a calendar event is added to, or present within, a Calendar.

An implementation MAY use an IANA registered identifier format. The value can also be a non-standard format.

attribute DOMString description

A description of the event.

{description: "Meeting with Joe's team"}
attribute DOMString? location

A plain text description of the location of the event.

{location: 'Conf call #+4402000000001'}
attribute DOMString? summary

A summary of the event.

{summary: "Agenda:\n\n\t* Introductions\n\t* AoB"}
attribute DOMString start

The start date and time of the event as a valid date or time string.

{start: '2011-03-24T09:00-08:00'} // Event starts on March 24, 2011 @ 5pm (UTC)
attribute DOMString? end

The end date and time of the event as a valid date or time string.

{end: '2011-03-24T10:00:00-08:00'} // Event ends on March 24, 2011 @ 6pm (UTC)
attribute DOMString? status

An indication of the user's status of the event.

This parameter may be set to one of the following constants:

'pending', 'tentative', 'confirmed', 'cancelled'.
{status: 'pending'} // Event is awaiting user action
attribute DOMString? transparency

An indication of the display status to set for the event.

This parameter may be set to one of the following constants:

'transparent', 'opaque'.
{freebusy: 'transparent'} // Mark event as transparent in Calendar
attribute CalendarRepeatRule recurrence

The recurrence or repetition rule for this event

{recurrence: {frequency: 'daily'}}     // Event occurs every day and never expires
{recurrence: {frequency: 'weekly',     // Event occurs weekly...
              daysInWeek: [2, 4],      // ...every Tuesday and Thursday
              expires: '2011-06-11T12:00:00-04:00'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'weekly',     // Event occurs weekly...on every Wednesday
                                       // (if we say the 'start' attribute is March 24, 2011 @ 2pm (Wednesday) as  
                                       // shown above and no daysInWeek attribute is provided)
              expires: '2011-06-11T11:00:00-05:00'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'monthly',    // Event occurs monthly...
              daysInMonth: [-5],       // ...5 days before the end of each month 
              expires: '2011-06-11T20:00:00+04:00'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'monthly',    // Event occurs monthly...on the 24th day of every month
                                       // (if we say the 'start' attribute is March 24, 2011 @ 2pm as  
                                       // shown above and no daysInMonth attribute is provided)
              expires: '2011-06-11T20:00:00+04:00'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'yearly',     // Event occurs yearly...on the 24th day of every March
                                       // (if we say the 'start' attribute is March 24, 2011 @ 2pm as  
                                       // shown above and no daysInMonth attribute is provided)
              expires: '2011-06-11T16:00:00+00:00'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'yearly',     // Event occurs yearly...
              daysInMonth: [24],       // ...every 24th day... 
              monthsInYear: [3, 6],    // ...in every March and June
              expires: '2011-06-11T16:00:00Z'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
{recurrence: {frequency: 'yearly',     // Event occurs yearly...
              daysInYear: [168],       // ...every 168th day of each year 
              expires: '2011-06-11T21:45:00+05:45'}} // Event expires on or before June 11, 2011 @ 4pm (UTC)
attribute DOMString? reminder

A reminder for the event.

This attribute can be specified as a positive valid date or time string.

, denoting a one-time reminder or as a negative value in milliseconds denoting a relative relationship to the start time of the calendar event.

A relative reminder is recommended for setting a reminder for recurrent events.

{reminder: '2011-03-24T13:00:00+00:00'}  // Remind ONCE on March 24, 2011 @ 1pm (UTC)
{reminder: '-3600000'}       // Remind 1 hour before every occurrence of this event

CalendarRepeatRule interface

The CalendarRepeatRule interface captures the recurrence of a calendar event item.

This interface has known limitations for capturing recurrent events that will be addressed in a next revision of the document.
attribute DOMString? frequency

The frequency of the CalendarRepeatRule.

This parameter must be set to one of the following constants:

'daily', 'weekly', 'monthly', 'yearly'.

Additional values must be ignored for this attribute.

{frequency: 'monthly'}  // Event repeats on a monthly basis
attribute unsigned short? interval

A positive integer defining how often the recurrence rule MUST repeat.

For interval N, recurrence rule repeats every Nth frequency. Default interval value is 1, that is every day for a daily, every week for a weekly, every month for a monthly and every year for a yearly.

If this parameter is set to null the event item does not have any fixed interval and the event interal should be derived from the other CalendarRepeatRule attributes.

{interval: 1}
attribute DOMString? expires

The date and time to which the CalendarRepeatRule applies as a valid date or time string.

If this parameter is set to null the event item does not have any fixed expiry date and the event is scheduled to continue indefintely.

{expires: '2011-08-01T01:00:00+01:00'} // Event repeats until August 1, 2011 @ 12am (UTC)
attribute DOMString[] exceptionDates

One or more dates and times to which the CalendarRepeatRule does not apply as valid date or time string strings.

If this parameter is set to null the event item does not have any exception dates and/or times.

{exceptionDates: ['2011-12-22', '2011-12-29']} // Event does not occur on December 22, 2011 and December 29, 2011
attribute short[] daysInWeek

The day or days of the week for which the CalendarRepeatRule applies. If this attribute is set to null then the day of the CalendarEvent.start value is used to derive the recurrent dates.

NOTE: This property only applies to weekly occurrences. If CalendarRepeatRule.frequency is not set to 'weekly' this property must be ignored.

The possible values are:

  • 0 (Sunday)
  • 1 (Monday)
  • 2 (Tuesday)
  • 3 (Wednesday)
  • 4 (Thursday)
  • 5 (Friday)
  • 6 (Saturday)
{daysInWeek: [0, 6]} // A weekly event repeats every Sunday and Saturday
attribute short[] daysInMonth

The day or days of the month for which the CalendarRepeatRule applies. If this attribute is set to null then the day of the month of the CalendarEvent.start value is used to derive the recurrent dates.

NOTE: This property only applies to monthly occurrences. If CalendarRepeatRule.frequency is not set to 'monthly' this property must be ignored.

The possible values are:

  • [1..31] (number of days from the first day of the month)
  • [0..-30] (number of days before the last day of the month)
{daysInMonth: [4, -10]} // A monthly event repeats on the 4th and 10th to last day of each month.
attribute short[] daysInYear

The day or days of the month for which the CalendarRepeatRule applies. If this attribute is set to null then the day of the year of the CalendarEvent.start value is used to derive the recurrent dates.

NOTE: This property only applies to yearly occurrences. If CalendarRepeatRule.frequency is not set to 'yearly' this property must be ignored.

The possible values are:

  • [1..365] (number of days from the first day of the year)
  • [0..-364] (number of days before the last day of the year)
{daysInYear: [262, -102]} // A yearly event repeats on day 262 and 102 days before the last day of each year.
attribute short[] weeksInMonth

The week or weeks of the month for which the CalendarRepeatRule applies. If this attribute is set to null then the week of the month of the CalendarEvent.start value is used to derive the recurrent dates.

NOTE: This property only applies to monthly occurrences. If CalendarRepeatRule.frequency is not set to 'monthly' this property must be ignored.

The possible values are:

  • [1..4] (number of weeks from the first week of the month)
  • [0..-3] (number of weeks before the last week of the month)
{weeksInMonth: [1, -1]} // A monthly event repeats on the first and last week of each month.
attribute short[] monthsInYear

The month or months of the year for which the CalendarRepeatRule applies. If this attribute is set to null then the month of the year of the CalendarEvent.start value is used to derive the recurrent dates.

NOTE: This property only applies to yearly occurrences. If CalendarRepeatRule.frequency is not set to 'yearly' this property must be ignored.

The possible values are:

  • 1 (January)
  • 2 (February)
  • 3 (March)
  • 4 (April)
  • 5 (May)
  • 6 (June)
  • 7 (July)
  • 8 (August)
  • 9 (September)
  • 10 (October)
  • 11 (November)
  • 12 (December)
{monthsInYear: [4, 10]} // A yearly event repeats in April and October each year.

CalendarFindOptions interface

The CalendarFindOptions interface describes the options that can be applied to calendar searching.

attribute CalendarEventFilter filter
A search filter with which to search and initially filter the Calendar database.
attribute boolean? multiple
A boolean value to indicate whether multiple Calendar objects are returnable as part of the associated Calendar findEvents() operation.

By default this option is set to true.

CalendarEventFilter interface

The CalendarEventFilter interface captures the searchable parameters for finding calendar event items.

attribute DOMString startBefore
Search for Calendar Events that start before the time provided as a valid date or time string..
attribute DOMString startAfter
Search for Calendar Events that start after the time provided as a valid date or time string..
attribute DOMString endBefore
Search for Calendar Events that end before the time provided as a valid date or time string..
attribute DOMString endAfter
Search for Calendar Events that end after the time provided as a valid date or time string..

CalendarEventSuccessCB interface

void onSuccess ()
sequence<CalendarEvent> eventObjs
The resulting sequence of CalendarEvent objects resulting from a successful search operation.

Event Handler Attributes

The following is the event handler attribute (and its corresponding event handler event type) that MUST be supported as a DOM attribute by the CalendarEventSuccessCB object.

event handler attribute event handler event type
onsuccess success

CalendarErrorCB interface

void onError ()
CalendarError error
The Calendar API related error object of an unsuccessful asynchronous operation.

Event Handler Attributes

The following is the event handler attribute (and its corresponding event handler event type) that MUST be supported as a DOM attribute by the CalendarErrorCB object.

event handler attribute event handler event type
onerror error

CalendarError interface

The CalendarError interface encapsulates all errors in the manipulation of CalendarEvent objects in the Calendar API.

const unsigned short UNKNOWN_ERROR = 0
An unknown error occurred.
const unsigned short INVALID_ARGUMENT_ERROR = 1
An invalid parameter was provided when the requested method was invoked.
const unsigned short TIMEOUT_ERROR = 2
The requested method timed out before it could be completed.
const unsigned short PENDING_OPERATION_ERROR = 3
If the user agent is currently waiting for a callback on a current findEvents() operation, as defined in this specification.
const unsigned short IO_ERROR = 4
An error occurred in communication with the underlying implementation that meant the requested method could not complete.
const unsigned short NOT_SUPPORTED_ERROR = 5
The requested method is not supported by the current implementation.
const unsigned short PERMISSION_DENIED_ERROR = 20
Access to the requested method was denied at the implementation or by the user.
readonly attribute unsigned short code
An error code assigned by an implementation when an error has occurred in Calendar API processing.

Calendar Item Search Processing Rules

The Calendar interface findEvents() method provides a method to search for calendar items according to the input of a CalendarEventFilter object.

All fields within a CalendarEventFilter object provided to this method represent a logical UNION of value matching. Fields provided with a null value are considered to match anything.

For example, the following CalendarEventFilter object is supplied for Calendar Event searching:

navigator.calendar.findEvents(
  function(eventItems) { },
  function(error) { },
  { filter: { 
      startBefore: '2011-08-26', // All events before August 26, 2011 
      status: 'confirmed'
    }
  }
);
The above example logically implies: "find calendar event items that contain a start date before August 26, 2011 AND a status of 'confirmed'".

We need to be a lot clearer about partial matching included below. It might just be simpler to use pass RegExp objects around. Then again it might not...

All calendar item searching SHOULD apply a loose-matching policy. If a CalendarEventFilter attribute being searched in Calendar partially matches the input filter value, a CalendarEvent object representing the calendar item SHOULD be returned as part of the resulting CalendarEventSuccessCB.

The rules for processing filter combinations is defined below and is always provided with an input parameter and, an optional options parameter. Its behaviour depends on the type of input:

Let calendaritemsset be initially the set of all known calendar items
If input is an Object object
  1. Let singlefilter be the input parameter being parsed.
  2. Let item be the next enumerable property in singlefilter. If there are no more enumerable properties, go to step 6.
  3. If the value of item is null, go to step 2.
  4. Let calendaritemsset be the subset of calendaritemsset whose elements have the item value set to the value of item.
  5. Go to step 2.
  6. If the value of options is not null. apply the provided options to calendaritemsset.
  7. Return calendaritemsset.
If input is another native object type

Return a null value.

Extended Calendar Properties and Parameters

The properties and parameters defined on the CalendarEvent interface MAY be extended by implementors of this specification.

Non-standard, private properties and parameters SHOULD have a prefixed name starting with X (U+0058 LATIN CAPTIAL LETTER X) or use a vendor-specific prefix. Extended properties and parameters can be defined bilaterally between user agents without outside registration or standardization.

It is RECOMMENDED that authors define both a formal iCalendar grammar [[RFC5545]] and a WebIDL grammar [[WEBIDL]] for their proposed extension to ensure interoperability between iCalendar databases and other non-standard Calendar databases and formats. It is also RECOMMENDED that authors provide documentation of their extension properties and parameters within the public domain.

A new parameter is required by Company X to provide a distinct indication that a Calendar Event is all-day.

The [[WEBIDL]] syntax for this parameter is defined as follows:

attribute boolean Xallday
Set to true if the given event is an all-day event.

The corresponding iCalendar [[RFC5545]] notation for this parameter is defined as follows:

   The following ABNF grammar extends the grammar found in [[RFC5545]] (Section 4).
   
   X-ALLDAY
   
   Purpose:  To specify whether the event is an all day occurance.

   Value type:  A single boolean value.

   Cardinality:  (0,1)

   Special notes:  ...
      
   ABNF:
   
     X-ALLDAY-value = boolean

This parameter will be used within the Calendar API as follows:

   var calendarEvent = ...; // ...obtain individual calendar event object
   alert(calendarEvent.Xallday);

This parameter will be used within the iCalendar format [[RFC5545]]] as follows:

   X-ALLDAY;true

API Invocation via DOM Events

The API contained in this document can be invoked either programmatically (for example, inline within a general script) or resulting from the interaction of a user.

The interaction of a user is when a user invokes the API from an HTMLElement [[HTML5]] within the current browsing context via a valid auto-invocation event.

A valid auto-invocation event includes any of the following event types, as defined in [[!DOM-LEVEL-3-EVENTS]]:

The findEvents() method on Calendar should, if the method was invoked by an interaction of a user (as opposed to having been created and executed in general script), display the Calendar Picker directly.

Adding and Updating Calendar Events

The ability to add and update calendar event information is not a function of the API provided in this specification. Instead, the intention is to reuse existing web platform APIs and paradigms in order to acheive add and update functionality.

In this section we show how the existing web platform would be used to provide add and update writeback functionality to allow users to add new calendar events or update existing calendar events from a web page to their calendar.

A valid Calendar resource is a web resource with a .ical, .ics, .ifb or .icalendar filename extension or a web resource with a MIME-type matching a valid media type.

To handle the saving of a new Calendar Event, a user agent SHOULD register as the default handler for any valid Calendar resource.

A valid media type will be the following web resource MIME type:

On invocation of a valid Calendar resource, the user agent SHOULD, on successful download of the valid Calendar resource, store the given resource in the user's calendar according to the rule for storing a Calendar resource. As part of this standard download process, the user agent MAY present a dialog to the user allowing them to select a different application with which to handle the given resource, thereby overriding the use of the unified calendar for the storage of the data contained therein and bypassing the rule for storing a Calendar resource.

The rule for storing a Calendar resource is defined as follows:

Let Event be the parsed key/value pairs contained in the valid Calendar resource.

  1. If Calendar contains a UID key then process the valid Calendar resource as follows.
    1. Let MatchedEvent be the result of obtaining a Calendar Event object from the user's unified calendar that matches exactly the value of the UID provided.
    2. If a MatchedEvent has been found (i.e MatchedEvent is not-null) then update the contents of MatchedEvent with the contents of Event and exit this rule.
  2. Save the contents of Event in the user's unified calendar as a new Calendar Event object.

As part of the rule for storing a Calendar resource, the user agent MAY provide additional dialogs to the user after successful completion of the download and before the Calendar Event information is saved to the unified calendar, such as to show a preview of the Calendar information contained therein as it will be stored in the user's calendar. The user MAY be able to override the information provided before accepting the additions and permanently storing the given data in their unified calendar.

Adding a new Calendar Event

A web page can dynamically generate an iCalendar object on the client side for download to the user's unified calendar via the [[FILE-WRITER]] and [[FILE-API]] interfaces. The following example shows the process in which a web site may create an iCalendar object dynamically and then present this to the user. The user may then save this information by clicking on the presented information, download the dynamically generated iCalendar object and invoke a suitable application with which to handle the dynamic resource.

<a id="ical">Save our Event in your Calendar</a>

<script type="text/javascript">
  // obtain an ArrayBuffer consisting of valid iCalendar syntax (out of scope)
  var iCalObj = getICalendar( /* ... */ );
            
  // create a new iCalendar Blob [[FILE-WRITER]]
  var calendarEventBlobBuilder = new BlobBuilder();
  calendarEventBlobBuilder.append( iCalObj );
  var calendarEventBlob = calendarEventBlobBuilder.getBlob( "text/calendar" );

  // obtain an iCalendar Blob URL [[FILE-API]]
  var calendarEventBlobURL = window.URL.createObjectUrl( calendarEventBlob );

  // assign iCalendar Blob URL to an anchor element for presentation and download by the user
  document.getElementById('ical').href = calendarEventBlobURL; 
</script>

Updating an existing Calendar Event

To update an existing Calendar Event, the user must have already shared the event information to edit with the current web page via the findEvents() operation of the Calendar interface. This section assumes that the user is already sharing some calendar event information with the current web page via this process.

If this existing Calendar Event information is to be updated in the user's unified calendar then the developer will assign the id attribute, as returned in the CalendarEvent object, as the UID property of any resulting iCalendar object to be processed by the user agent according to the rule for storing a Calendar resource.

The example below shows how to update an existing Calendar Event in the user's unified calendar by maintaining a valid UID property while changing other parameters of the Calendar Event. The user is then required to click on the resulting anchor element to download the modified Calendar resource.

<a id="vcard">Update our Event in your Calendar</a>

<script type="text/javascript">
  // Obtain a single existing Calendar Event object resulting from navigator.calendar.findEvents()
  var existingCalendarEventObj = ...;
  
  // Modify some parameters as required. e.g. add a new phone number
  existingCalendarEventObj.location = 'Conf call number change: #XXX';
  
  // With the existing Calendar Event object, create an ArrayBuffer consisting of valid iCalendar 
  // syntax (out of scope) making sure to set the resulting iCalendar UID property to 
  // the id parameter returned in the existing Calendar Event object
  var iCalObj = getICalendar( existingCalendarEventObj );

  // create a new iCalendar Blob [[FILE-WRITER]]
  var calendarEventBlobBuilder = new BlobBuilder();
  calendarEventBlobBuilder.append( iCalObj );
  var calendarEventBlob = calendarEventBlobBuilder.getBlob( "text/calendar" );

  // obtain an iCalendar Blob URL [[FILE-API]]
  var calendarEventBlobURL = window.URL.createObjectUrl( calendarEventBlob );

  // assign iCalendar Blob URL to an anchor element for presentation and download by the user
  document.getElementById('ical').href = calendarEventBlobURL; 
</script>

User Interaction Guidelines

@ to be included

Use Cases and Requirements

Use Cases

Use Case 1: A web application would like to access the device calendar

A Web Application on behalf of the user would like to access the user’s device calendar so it can be presented to the user in the context of browsing a Web Application. For example, the user is in the process of completing an online flight reservation and would like to view the device calendar to check his/her schedule.

Use Case 2: A user would like to create/modify/delete a Calendar appointment

A user of the Web Application would like to create a new Calendar appointment with details (e.g. subject, location, start/end time, description, and note) and add it to his/her device calendar. Later the user may wish to modify the existing appointment with new details and save it, or may decide to delete it after the event has occurred or is no longer valid.

Use Case 3: A user would like to enter a birthday of his friend with a recurrence event

A user of the Web Application meets his/her close friend and learns about his/her birth date, and would like to enter it to the device calendar with the ability to set a recurrence appointment such that he/she is reminded of the birthday every year. This will allow the user to take an action such as send a greeting card, a phone call to wish his/her friend, etc.

Use Case 4: A user would like to set a reminder for upcoming events.

A user of the Web Application is shopping online (e.g. auction site) and would like to be reminded 5 minutes prior to the auction is closed so he may wish to change his bid price. Or the user has a meeting with his doctor and would like to be reminded one hour prior to the appointment that may allow him to prepare for the appointment.

Requirements

This interface:

Features for Future Consideration

This is a list of features that have been discussed with respect to this version of the API but for which it has been decided that if they are included it will be in a future revision.

The current specification suggests support for only Calendar Events. However Andrew McMillan makes the following point [1]:

"Given that the differences between [iCalendar ]VEVENT & VTODO are trivial in comparison to the complexity of their common elements, and that VJOURNAL is entirely a subset of those, it seems to me there is very little to gain by removing VTODO and VJOURNAL from this specification. Removal might restrict clients from implementing some potentially useful functionality. The other supporting components of the specification like VALARM and VTIMEZONE seem to me so essential in any reasonable implementation of VEVENT that they don't even merit discussion."

Acknowledgements

The editors would like to thank the input from the PhoneGap, Nokia, and OMTP BONDI groups and the feedback received from W3C DAP members to date ...