WebAPI/ContactsAPI: Difference between revisions

no edit summary
(→‎Contacts API specification: change PREF from integer to boolean, simpler, keeps vCard3 compat, specify vCard4 equivalent)
No edit summary
 
(27 intermediate revisions by 7 users not shown)
Line 1: Line 1:
'''This page is targeted at Firefox OS/Gecko developers. If you're a Web developer who wants to know how to use the Contacts API, check [https://developer.mozilla.org/en-US/docs/WebAPI/Contacts the MDN page].'''
<div class="h-entry">
<div class="h-entry">
= <span class="p-name">Contacts API specification</span> =
= <span class="p-name">Contacts API specification</span> =
Line 17: Line 19:
__TOC__
__TOC__


== Example ==
== Basic Examples ==
Example use of the API:
 
=== Create contact example ===


  var contact = new mozContact();
  var contact = new mozContact({name: ["John Doe"], givenName: ["John"], familyName: ["Doe"]});
contact.init({name: "Tom"}); // Bug 723206
  var request = navigator.mozContacts.save(contact);
  var request = navigator.mozContacts.save(contact);
  request.onsuccess = function() {alert("success");};
  request.onerror = function() {alert("error")};
request.onsuccess = function() {
    alert("Success saving contact. New contact ID: " + contact.id);
};
request.onerror = function() {
    alert("Error saving contact.");
};
 
=== Update contact example ===
 
// "contact" is the same contact object as in the save example above. The contact must have its ID field set to update it.
// Note that when updating array fields (like telephones) all the phone numbers must be specified, not just the one you want to update.
contact.tel = [{type: ["home"], value: "8675309", carrier: "myCarrier", pref: 1}, {type: ["home", "custom type"], value: "1234567", pref: 0}];
var request = navigator.mozContacts.save(contact2);
request.onsuccess = function() {
    alert("Success updating contact.");
};
request.onerror = function() {
    alert("Error updating contact.");
};
 
=== Remove/delete contact example ===
 
// "contact" is the same contact as in the create and update examples. A contact object must have its ID property set in order to remove it.
var request = navigator.mozContacts.remove(contact);
  request.onsuccess = function() {
    alert("Success removing contact.");
};
  request.onerror = function() {
    alert("Error removing contact.");
};
 
=== Find contacts example ===
 
var options = {filterBy: ["givenName"],
                filterOp: "equals",
                filterValue: "John",
                sortBy: "familyName",
                sortOrder: "ascending"
};
var request = navigator.mozContacts.find(options);
request.onsuccess = function() {
    if(request.result.length > 0) {
        alert("Found " + request.result.length + " contacts");
        for (var i=0; i<request.result.length; i++) {
            for (var j=0; j<request.result[i].name.length; j++) {
                alert("Found contact with name: " + request.result[i].name[j]);
            }
        }
    } else {
        alert("No contacts found.");
    }
};
request.onerror = function() {
    alert("Error finding contacts.");
};
 
=== Get all contacts example ===
 
var cursor = navigator.mozContacts.getAll({});
cursor.onsuccess = function() {
    if (cursor.result) {
        alert("Got contact with name: " + cursor.result.name.join(" "));
        cursor.continue();
    } else {
        alert("Done!");
    }
};
cursor.onerror = function() {
    alert("Error getting contacts");
};
 
=== Get contacts count example ===
 
var request = navigator.mozContacts.getCount();
request.onsuccess = function() {
    alert("Number of contacts: " + request.result);
};
request.onerror = function() {
    alert("Error getting contacts count.");
};
cursor.onerror = function() {
    alert("Error getting all contacts.");
};
 
=== Clear (delete all) contacts examples ===
 
var request = navigator.mozContacts.clear();
request.onsuccess = function() {
    alert("Contacts cleared.");
};
request.onerror = function() {
    alert("Error clearing contacts.");
};


== API ==
== API ==
There is an object in window.navigator named ''mozContacts'' with the following interface:
There is an object in window.navigator named ''mozContacts'' with the following interface:
   interface <span id="ContactsManager">ContactsManager</span>
 
   {
=== ContactManager ===
     DOMRequest find(in ContactFindOptions options);
   [NoInterfaceObject]
   interface ContactManager : EventTarget {
     DOMRequest find(optional ContactFindOptions options);
    DOMCursor  getAll(optional ContactFindSortOptions options);
     DOMRequest clear();
     DOMRequest clear();
     DOMRequest save(in Contact contact); // Success value is id? Or new Contact?
     DOMRequest save(mozContact contact);
     DOMRequest remove(in Contact contact);
     DOMRequest remove(mozContact contact);
    DOMRequest getRevision();
    DOMRequest getCount();
    attribute  EventHandler oncontactchange;
  };
 
=== ContactFindSortOptions ===
  dictionary ContactFindSortOptions {
    DOMString sortBy;                    // "givenName" or "familyName"
    DOMString sortOrder = "ascending";  // e.g. "descending"
   };
   };


  interface <span id="ContactFindOptions">ContactFindOptions</span> : nsISupports
=== ContactFindOptions ===
  {
  dictionary ContactFindOptions : ContactFindSortOptions {
     attribute DOMString     filterValue;   // e.g. "Tom"
     DOMString     filterValue; // e.g. "Tom"
     attribute DOMString     filterOp;       // e.g. "contains"
     DOMString     filterOp;     // e.g. "startsWith"
     attribute DOMString[]  filterBy;       // e.g. "givenName"
     any            filterBy;    // e.g. ["givenName", "nickname"]
     attribute DOMString    sortBy;        // e.g. "givenName"
     unsigned long filterLimit = 0;
    attribute DOMString    sortOrder;      // e.g. "descending"
     attribute unsigned long filterLimit;
   };
   };


TO DO: Research/document device-specific address book capabilities and represent using methods on the ContactsManager interface.
TO DO: Research/document device-specific address book capabilities and represent using methods on the ContactsManager interface.


TO DO: change find/search API to use cursors (to be written up, Tantek/Gregor).
=== ContactField ===
 
The following Contact interface is based [[vCard4]]/hCard properties, flattened for the simple/typical case of one address (adr) based on the [http://microformats.org/wiki/microformats-2#h-card microformats 2.0 hCard] iteration.
The following Contact interface is based [[vCard4]]/hCard properties, flattened for the simple/typical case of one address (adr) based on the [http://microformats.org/wiki/microformats-2#h-card microformats 2.0 hCard] iteration.


   interface <span id="ContactField">ContactField</span> : nsISupports
   interface ContactField {
  {
     attribute DOMString[] type; // ["home"], ["work"], etc.
     attribute DOMString[] type;   // "home", "work", etc.
     attribute DOMStringvalue;
     attribute DOMString   value;
     attribute boolean?    [https://bugzilla.mozilla.org/show_bug.cgi?id=860559 pref]; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
     attribute boolean     [https://bugzilla.mozilla.org/show_bug.cgi?id=860559 pref]; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
   };
   };


   interface <span id="ContactTelField">ContactTelField</span> : ContactField
=== ContactTelField ===
  {
   interface ContactTelField : ContactField {
     attribute DOMString carrier; // experimental extension - not in vCard!  
     attribute DOMString? carrier; // experimental extension - not in vCard!
   };
   };


   interface <span id="ContactAddress">ContactAddress</span> {
=== ContactAddress ===
            attribute DOMString[]           type; // "home", "work", etc.
   interface ContactAddress {
            attribute boolean               [https://bugzilla.mozilla.org/show_bug.cgi?id=860559 pref]; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
    attribute DOMString[] type; // ["home"], ["work"], etc.
            attribute DOMString              streetAddress;
    attribute DOMString?  streetAddress;
            attribute DOMString              locality;
    attribute DOMString?  locality;
            attribute DOMString              region;
    attribute DOMString?  region;
            attribute DOMString              postalCode;
    attribute DOMString?  postalCode;
            attribute DOMString              countryName;
    attribute DOMString?  countryName;
    attribute boolean?    [https://bugzilla.mozilla.org/show_bug.cgi?id=860559 pref]; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
   };
   };


   interface <span id="ContactProperties">ContactProperties</span> {
=== mozContact ===
             attribute DOMString[]            name;
  [Constructor(optional ContactProperties properties)]
             attribute DOMString[]            honorificPrefix;
   interface <span id="mozContact">mozContact</span> {
             attribute DOMString[]            givenName;
             attribute DOMString id;
             attribute DOMString[]            additionalName;
    readonly attribute Date? published;
             attribute DOMString[]            familyName;
    readonly attribute Date? updated;
             attribute DOMString[]           honorificSuffix;
 
             attribute DOMString[]           nickname;
             attribute Date? bday;
             attribute ContactField[]         email;
             attribute Date? anniversary; /* new in vCard4 */
             attribute DOMString[]           photo;
 
             attribute ContactField[]         url;
             attribute DOMString? sex; /* new in vCard4, gender sub-component 1 */
             attribute DOMString[]           category;
             attribute DOMString? genderIdentity; /* new in vCard4, gender sub-comp 2 */
             attribute ContactAddress[]       adr;
 
             attribute ContactTelField[]     tel;
             attribute Blob[] photo;
             attribute DOMString[]           org;
 
             attribute DOMString[]           jobTitle; /* 'title' from vCard made specific */
             attribute ContactAddress[] adr;
             attribute Date                  bday;
 
             attribute DOMString[]           note;
             attribute ContactField[] email;
             attribute ContactField[]         impp; /* per RFC 4770, included in vCard4 */
             attribute ContactField[] url;
             attribute Date                  anniversary; /* new in vCard4 */
             attribute ContactField[] impp; /* per RFC 4770, included in vCard4 */
             attribute DOMString              sex; /* new in vCard4, gender sub-component 1 */
 
             attribute DOMstring             genderIdentity; /* new in vCard4, gender sub-comp 2 */
             attribute ContactTelField[] tel;
             attribute DOMString[]           [https://bugzilla.mozilla.org/show_bug.cgi?id=807688 key]; /* takes a key URI per RFC6350 6.8.1 */
 
             attribute DOMString[] name;
             attribute DOMString[] honorificPrefix;
             attribute DOMString[] givenName;
             attribute DOMString[] phoneticGivenName; /* [http://tools.ietf.org/html/draft-fukuda-vcarddav-phonetic-transcription-02 proposed vCard4 addition], [https://bugzilla.mozilla.org/show_bug.cgi?id=909224 bug 909224] */
             attribute DOMString[] additionalName;
             attribute DOMString[] familyName;
             attribute DOMString[] phoneticFamilyName; /* [http://tools.ietf.org/html/draft-fukuda-vcarddav-phonetic-transcription-02 proposed vCard4 addition], [https://bugzilla.mozilla.org/show_bug.cgi?id=909224 bug 909224] */
             attribute DOMString[] honorificSuffix;
             attribute DOMString[] nickname;
             attribute DOMString[] category;
             attribute DOMString[] org;
             attribute DOMString[] jobTitle; /* 'title' from vCard made specific */
             attribute DOMString[] note;
            attribute DOMString[] [https://bugzilla.mozilla.org/show_bug.cgi?id=807688 key]; /* takes a key URI per RFC6350 6.8.1 */
   };
   };


   [Constructor(in ContactProperties properties)]
=== ContactProperties ===
   interface <span id="Contact">Contact</span> : ContactProperties
   dictionary ContactProperties {
   {
    Date?                          bday;
     readonly attribute DOMString id;
    Date?                          anniversary;
     readonly attribute Date      published;
 
     readonly attribute Date      updated;
    DOMString?                    sex;
    DOMString?                    genderIdentity;
    
    sequence<Blob>?                photo;
 
    sequence<ContactAddressInit>?  adr;
 
    sequence<ContactFieldInit>?    email;
    sequence<ContactFieldInit>?    url;
    sequence<ContactFieldInit>?    impp;
 
    sequence<ContactTelFieldInit>? tel;
    
     sequence<DOMString>?          name;
    sequence<DOMString>?          honorificPrefix;
    sequence<DOMString>?          givenName;
    sequence<DOMString>?          additionalName;
    sequence<DOMString>?          familyName;
    sequence<DOMString>?          honorificSuffix;
    sequence<DOMString>?          nickname;
    sequence<DOMString>?          category;
    sequence<DOMString>?          org;
    sequence<DOMString>?          jobTitle;
     sequence<DOMString>?          note;
     sequence<DOMString>?          key;
   };
   };


The integer 'pref' field has been added for compatibility with both vCard3 and vCard4 use of 'pref'.
The boolean 'pref' field has been added for compatibility with both vCard3 and vCard4 use of 'pref'.
* false = no preference, same as if unspecified in vCard3 or vCard4.
* false = no preference, same as if unspecified in vCard3 or vCard4.
* true = preferred, same as TYPE:PREF in vCard3 and PREF:1 in vCard4
* true = preferred, same as TYPE:PREF in vCard3 and PREF:1 in vCard4


Note: despite [[hCard2]] including a flat set of adr properties into the top level h-card object for ease of publishing, this interface always abstracts those properties into a ContactAddress sub-object since typical device address books cluster address information accordingly, e.g. for a home or work address. The interface is able to represent published data.
Note: despite [[hCard2]] including a flat set of adr properties into the top level h-card object for ease of publishing, this interface always abstracts those properties into a ContactAddress sub-object since typical device address books cluster address information accordingly, e.g. for a home or work address. The interface is able to represent published data.
== Android considerations ==
The Firefox for Android implementation of the contacts has a few discrepancies from the specs listed here. They are as follows:
* The "name" field must always be consistent with the "honorificPrefix", "givenName", "familyName", and "honorificSuffix" fields. For example, a contact with the "name" field set to "Dr. John Doe Junior" should have "honorificPrefix" set to "Dr.", "givenName" set to "John", etc.
* The "getRevision()" function is not supported on Android. Calling it will always return an error.
* The "updated" and "published" timestamps are not supported on Android. They will never be set.
* The preferred field for a phone, email, address, etc., if not set to true, will default to false even if the field is omitted completely.
* The photo field is not yet supported.


== Methodology for inclusion ==
== Methodology for inclusion ==
Line 146: Line 318:
* favorite contacts may be implemented as category: "favorite"
* favorite contacts may be implemented as category: "favorite"
* a favorite phone number (iOS feature) for a contact may be implemented as type:"favorite" on the phone number (add to the type array as necessary).
* a favorite phone number (iOS feature) for a contact may be implemented as type:"favorite" on the phone number (add to the type array as necessary).
* pictures may use "blob:" URIs (to be defined) in the 'photo' property
** convert blob photos to "data:" URIs when exporting to vCard, and similarly, convert vCard photo data URIs to blog photos when importing.


=== Priority 1 feature requests ===
=== Priority 1 feature requests ===
Line 200: Line 370:


More Contact attributes (from Address Book UIs of BlackBerry ('''BB'''), iPhone/iTouch ('''iOS'''), MacOS Address Book ('''MOAB''') :
More Contact attributes (from Address Book UIs of BlackBerry ('''BB'''), iPhone/iTouch ('''iOS'''), MacOS Address Book ('''MOAB''') :
* phonetic-given-name (iOS, MOAB) ([http://www.ietf.org/mail-archive/web/vcarddav/current/msg02514.html 2012-080 requested VCARDDAV])
* phonetic-given-name (iOS, MOAB) ([http://www.ietf.org/mail-archive/web/vcarddav/current/msg02514.html 2012-080 requested VCARDDAV], [https://bugzilla.mozilla.org/show_bug.cgi?id=909224 Bugzilla 909224 request for inclusion in ContactsAPI])
* phonetic-family-name (iOS, MOAB) ([http://www.ietf.org/mail-archive/web/vcarddav/current/msg02514.html 2012-080 requested VCARDDAV])
* phonetic-family-name (iOS, MOAB) ([http://www.ietf.org/mail-archive/web/vcarddav/current/msg02514.html 2012-080 requested VCARDDAV], [https://bugzilla.mozilla.org/show_bug.cgi?id=909224 Bugzilla 909224 request for inclusion in ContactsAPI])
* favorite contact (as a native feature rather than workaround with category:favorite)
* favorite contact (as a native feature rather than workaround with category:favorite)
** implemented by Android AB
** implemented by Android AB
Line 312: Line 482:
== Implementation ==
== Implementation ==
* [[B2G]]: <span id="Status">See {{bug|674720}}.</span>
* [[B2G]]: <span id="Status">See {{bug|674720}}.</span>
* [[Android]]: <span id="Status">See {{bug|857730}}.</span>


== Issues ==
== Issues ==
Line 382: Line 553:
* [[WebAPI/Security/Contacts]]
* [[WebAPI/Security/Contacts]]
* [[WebAPI/CalendarAPI]]
* [[WebAPI/CalendarAPI]]
[[Category:Web APIs]]
Confirmed users
1,340

edits