mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 850430 - Convert the Contacts API to WebIDL. r=bz r=gwagner
--HG-- extra : rebase_source : 9d7a645c0d2fb102d5d498fefebeb817a186720e
This commit is contained in:
parent
e98ada57a9
commit
4d0d3e88a1
@ -187,7 +187,6 @@
|
||||
#endif
|
||||
@BINPATH@/components/dom_camera.xpt
|
||||
@BINPATH@/components/dom_canvas.xpt
|
||||
@BINPATH@/components/dom_contacts.xpt
|
||||
@BINPATH@/components/dom_alarm.xpt
|
||||
@BINPATH@/components/dom_core.xpt
|
||||
@BINPATH@/components/dom_css.xpt
|
||||
|
@ -15,331 +15,210 @@ Cu.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
Cu.import("resource://gre/modules/Services.jsm");
|
||||
Cu.import("resource://gre/modules/DOMRequestHelper.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(Services, "DOMRequest",
|
||||
"@mozilla.org/dom/dom-request-service;1",
|
||||
"nsIDOMRequestService");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "pm",
|
||||
"@mozilla.org/permissionmanager;1",
|
||||
"nsIPermissionManager");
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "cpmm",
|
||||
"@mozilla.org/childprocessmessagemanager;1",
|
||||
"nsIMessageSender");
|
||||
|
||||
const CONTACTS_SENDMORE_MINIMUM = 5;
|
||||
|
||||
function stringOrBust(aObj) {
|
||||
if (typeof aObj != "string") {
|
||||
if (DEBUG) debug("Field is not a string and was ignored.");
|
||||
return undefined;
|
||||
} else {
|
||||
return aObj;
|
||||
}
|
||||
}
|
||||
|
||||
function sanitizeStringArray(aArray) {
|
||||
if (!Array.isArray(aArray)) {
|
||||
aArray = [aArray];
|
||||
}
|
||||
return aArray.map(stringOrBust).filter(function(el) { return el != undefined; });
|
||||
}
|
||||
|
||||
const nsIClassInfo = Ci.nsIClassInfo;
|
||||
const CONTACTPROPERTIES_CID = Components.ID("{35ad8a4e-9486-44b6-883d-550f14635e49}");
|
||||
const nsIContactProperties = Ci.nsIContactProperties;
|
||||
|
||||
// ContactProperties is not directly instantiated. It is used as interface.
|
||||
|
||||
function ContactProperties(aProp) { if (DEBUG) debug("ContactProperties Constructor"); }
|
||||
|
||||
ContactProperties.prototype = {
|
||||
|
||||
classID : CONTACTPROPERTIES_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTPROPERTIES_CID,
|
||||
contractID:"@mozilla.org/contactProperties;1",
|
||||
classDescription: "ContactProperties",
|
||||
interfaces: [nsIContactProperties],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIContactProperties])
|
||||
}
|
||||
|
||||
//ContactAddress
|
||||
|
||||
const CONTACTADDRESS_CONTRACTID = "@mozilla.org/contactAddress;1";
|
||||
const CONTACTADDRESS_CID = Components.ID("{9cbfa81c-bcab-4ca9-b0d2-f4318f295e33}");
|
||||
const nsIContactAddress = Components.interfaces.nsIContactAddress;
|
||||
|
||||
function ContactAddress(aType, aStreetAddress, aLocality, aRegion, aPostalCode, aCountryName, aPref) {
|
||||
this.type = sanitizeStringArray(aType);
|
||||
this.streetAddress = stringOrBust(aStreetAddress);
|
||||
this.locality = stringOrBust(aLocality);
|
||||
this.region = stringOrBust(aRegion);
|
||||
this.postalCode = stringOrBust(aPostalCode);
|
||||
this.countryName = stringOrBust(aCountryName);
|
||||
this.pref = aPref;
|
||||
};
|
||||
function ContactAddress() { }
|
||||
|
||||
ContactAddress.prototype = {
|
||||
__exposedProps__: {
|
||||
type: 'rw',
|
||||
streetAddress: 'rw',
|
||||
locality: 'rw',
|
||||
region: 'rw',
|
||||
postalCode: 'rw',
|
||||
countryName: 'rw',
|
||||
pref: 'rw'
|
||||
},
|
||||
// This function is meant to be called via bindings code for type checking,
|
||||
// don't call it directly. Instead, create a content object and call initialize
|
||||
// on that.
|
||||
initialize: function(aType, aStreetAddress, aLocality, aRegion, aPostalCode, aCountryName, aPref) {
|
||||
this.type = aType;
|
||||
this.streetAddress = aStreetAddress;
|
||||
this.locality = aLocality;
|
||||
this.region = aRegion;
|
||||
this.postalCode = aPostalCode;
|
||||
this.countryName = aCountryName;
|
||||
this.pref = aPref;
|
||||
},
|
||||
|
||||
classID : CONTACTADDRESS_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTADDRESS_CID,
|
||||
contractID: CONTACTADDRESS_CONTRACTID,
|
||||
classDescription: "ContactAddress",
|
||||
interfaces: [nsIContactAddress],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
toJSON: function(excludeExposedProps) {
|
||||
let json = {
|
||||
type: this.type,
|
||||
streetAddress: this.streetAddress,
|
||||
locality: this.locality,
|
||||
region: this.region,
|
||||
postalCode: this.postalCode,
|
||||
countryName: this.countryName,
|
||||
pref: this.pref,
|
||||
};
|
||||
if (!excludeExposedProps) {
|
||||
json.__exposedProps__ = {
|
||||
type: "rw",
|
||||
streetAddress: "rw",
|
||||
locality: "rw",
|
||||
region: "rw",
|
||||
postalCode: "rw",
|
||||
countryName: "rw",
|
||||
pref: "rw",
|
||||
};
|
||||
}
|
||||
return json;
|
||||
},
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIContactAddress])
|
||||
}
|
||||
|
||||
//ContactField
|
||||
|
||||
const CONTACTFIELD_CONTRACTID = "@mozilla.org/contactField;1";
|
||||
const CONTACTFIELD_CID = Components.ID("{ad19a543-69e4-44f0-adfa-37c011556bc1}");
|
||||
const nsIContactField = Components.interfaces.nsIContactField;
|
||||
|
||||
function ContactField(aType, aValue, aPref) {
|
||||
this.type = sanitizeStringArray(aType);
|
||||
this.value = stringOrBust(aValue);
|
||||
this.pref = aPref;
|
||||
classID: Components.ID("{9cbfa81c-bcab-4ca9-b0d2-f4318f295e33}"),
|
||||
contractID: "@mozilla.org/contactAddress;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
};
|
||||
|
||||
function ContactField() { }
|
||||
|
||||
ContactField.prototype = {
|
||||
__exposedProps__: {
|
||||
type: 'rw',
|
||||
value: 'rw',
|
||||
pref: 'rw'
|
||||
},
|
||||
// This function is meant to be called via bindings code for type checking,
|
||||
// don't call it directly. Instead, create a content object and call initialize
|
||||
// on that.
|
||||
initialize: function(aType, aValue, aPref) {
|
||||
this.type = aType;
|
||||
this.value = aValue;
|
||||
this.pref = aPref;
|
||||
},
|
||||
|
||||
classID : CONTACTFIELD_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTFIELD_CID,
|
||||
contractID: CONTACTFIELD_CONTRACTID,
|
||||
classDescription: "ContactField",
|
||||
interfaces: [nsIContactField],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
toJSON: function(excludeExposedProps) {
|
||||
let json = {
|
||||
type: this.type,
|
||||
value: this.value,
|
||||
pref: this.pref,
|
||||
};
|
||||
if (!excludeExposedProps) {
|
||||
json.__exposedProps__ = {
|
||||
type: "rw",
|
||||
value: "rw",
|
||||
pref: "rw",
|
||||
};
|
||||
}
|
||||
return json;
|
||||
},
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIContactField])
|
||||
}
|
||||
|
||||
//ContactTelField
|
||||
|
||||
const CONTACTTELFIELD_CONTRACTID = "@mozilla.org/contactTelField;1";
|
||||
const CONTACTTELFIELD_CID = Components.ID("{4d42c5a9-ea5d-4102-80c3-40cc986367ca}");
|
||||
const nsIContactTelField = Components.interfaces.nsIContactTelField;
|
||||
|
||||
function ContactTelField(aType, aValue, aCarrier, aPref) {
|
||||
this.type = sanitizeStringArray(aType);
|
||||
this.value = stringOrBust(aValue);
|
||||
this.carrier = stringOrBust(aCarrier);
|
||||
this.pref = aPref;
|
||||
classID: Components.ID("{ad19a543-69e4-44f0-adfa-37c011556bc1}"),
|
||||
contractID: "@mozilla.org/contactField;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
};
|
||||
|
||||
function ContactTelField() { }
|
||||
|
||||
ContactTelField.prototype = {
|
||||
__exposedProps__: {
|
||||
type: 'rw',
|
||||
value: 'rw',
|
||||
carrier: 'rw',
|
||||
pref: 'rw'
|
||||
},
|
||||
// This function is meant to be called via bindings code for type checking,
|
||||
// don't call it directly. Instead, create a content object and call initialize
|
||||
// on that.
|
||||
initialize: function(aType, aValue, aCarrier, aPref) {
|
||||
this.type = aType;
|
||||
this.value = aValue;
|
||||
this.carrier = aCarrier;
|
||||
this.pref = aPref;
|
||||
},
|
||||
|
||||
classID : CONTACTTELFIELD_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTTELFIELD_CID,
|
||||
contractID: CONTACTTELFIELD_CONTRACTID,
|
||||
classDescription: "ContactTelField",
|
||||
interfaces: [nsIContactTelField],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
toJSON: function(excludeExposedProps) {
|
||||
let json = {
|
||||
type: this.type,
|
||||
value: this.value,
|
||||
carrier: this.carrier,
|
||||
pref: this.pref,
|
||||
};
|
||||
if (!excludeExposedProps) {
|
||||
json.__exposedProps__ = {
|
||||
type: "rw",
|
||||
value: "rw",
|
||||
carrier: "rw",
|
||||
pref: "rw",
|
||||
};
|
||||
}
|
||||
return json;
|
||||
},
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIContactTelField])
|
||||
}
|
||||
|
||||
//ContactFindSortOptions
|
||||
|
||||
const CONTACTFINDSORTOPTIONS_CONTRACTID = "@mozilla.org/contactFindSortOptions;1"
|
||||
const CONTACTFINDSORTOPTIONS_CID = Components.ID("{0a5b1fab-70da-46dd-b902-619904d920c2}");
|
||||
const nsIContactFindSortOptions = Ci.nsIContactFindSortOptions;
|
||||
|
||||
function ContactFindSortOptions () { }
|
||||
|
||||
ContactFindSortOptions.prototype = {
|
||||
classID: CONTACTFINDSORTOPTIONS_CID,
|
||||
classInfo: XPCOMUtils.generateCI({classID: CONTACTFINDSORTOPTIONS_CID,
|
||||
contractID: CONTACTFINDSORTOPTIONS_CONTRACTID,
|
||||
classDescription: "ContactFindSortOptions",
|
||||
interfaces: [nsIContactFindSortOptions],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
QueryInterface: XPCOMUtils.generateQI([nsIContactFindSortOptions])
|
||||
classID: Components.ID("{4d42c5a9-ea5d-4102-80c3-40cc986367ca}"),
|
||||
contractID: "@mozilla.org/contactTelField;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports]),
|
||||
};
|
||||
|
||||
//ContactFindOptions
|
||||
function validateArrayField(data, createCb) {
|
||||
function isVanillaObj(aObj) {
|
||||
return Object.prototype.toString.call(aObj) == "[object Object]";
|
||||
}
|
||||
|
||||
const CONTACTFINDOPTIONS_CONTRACTID = "@mozilla.org/contactFindOptions;1";
|
||||
const CONTACTFINDOPTIONS_CID = Components.ID("{28ce07d0-45d9-4b7a-8843-521df4edd8bc}");
|
||||
const nsIContactFindOptions = Components.interfaces.nsIContactFindOptions;
|
||||
// We use an array-like Proxy to validate data set by content, since we don't
|
||||
// have WebIDL arrays yet. See bug 851726.
|
||||
|
||||
function ContactFindOptions() { };
|
||||
|
||||
ContactFindOptions.prototype = {
|
||||
|
||||
classID : CONTACTFINDOPTIONS_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTFINDOPTIONS_CID,
|
||||
contractID: CONTACTFINDOPTIONS_CONTRACTID,
|
||||
classDescription: "ContactFindOptions",
|
||||
interfaces: [nsIContactFindSortOptions,
|
||||
nsIContactFindOptions],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIContactFindSortOptions,
|
||||
nsIContactFindOptions])
|
||||
}
|
||||
|
||||
//Contact
|
||||
|
||||
const CONTACT_CONTRACTID = "@mozilla.org/contact;1";
|
||||
const CONTACT_CID = Components.ID("{72a5ee28-81d8-4af8-90b3-ae935396cc66}");
|
||||
const nsIDOMContact = Components.interfaces.nsIDOMContact;
|
||||
|
||||
function checkBlobArray(aBlob) {
|
||||
if (Array.isArray(aBlob)) {
|
||||
for (let i = 0; i < aBlob.length; i++) {
|
||||
if (typeof aBlob != 'object') {
|
||||
return null;
|
||||
// ArrayPropertyExposedPropsProxy is used to return "rw" for any valid index
|
||||
// and "length" in __exposedProps__.
|
||||
const ArrayPropertyExposedPropsProxy = new Proxy({}, {
|
||||
get: function(target, name) {
|
||||
// Test for index access
|
||||
if (String(name >>> 0) === name) {
|
||||
return "rw";
|
||||
}
|
||||
if (!(aBlob[i] instanceof Components.interfaces.nsIDOMBlob)) {
|
||||
return null;
|
||||
if (name === "length") {
|
||||
return "r";
|
||||
}
|
||||
}
|
||||
return aBlob;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
});
|
||||
|
||||
function isVanillaObj(aObj) {
|
||||
return Object.prototype.toString.call(aObj) == "[object Object]";
|
||||
}
|
||||
const ArrayPropertyHandler = {
|
||||
set: function(target, name, val, receiver) {
|
||||
// Test for index access
|
||||
if (String(name >>> 0) === name) {
|
||||
target[name] = createCb(val);
|
||||
}
|
||||
},
|
||||
get: function(target, name) {
|
||||
if (name === "__exposedProps__") {
|
||||
return ArrayPropertyExposedPropsProxy;
|
||||
}
|
||||
return target[name];
|
||||
}
|
||||
};
|
||||
|
||||
function validateArrayField(data, createCb) {
|
||||
if (data) {
|
||||
data = Array.isArray(data) ? data : [data];
|
||||
let filtered = [];
|
||||
for (let obj of data) {
|
||||
if (obj && isVanillaObj(obj)) {
|
||||
if (isVanillaObj(obj)) {
|
||||
filtered.push(createCb(obj));
|
||||
}
|
||||
}
|
||||
return filtered;
|
||||
if (filtered.length === 0) {
|
||||
return undefined;
|
||||
}
|
||||
return new Proxy(filtered, ArrayPropertyHandler);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function Contact() { };
|
||||
// We need this to create a copy of the mozContact object in ContactManager.save
|
||||
// Keep in sync with the interfaces.
|
||||
const PROPERTIES = [
|
||||
"name", "honorificPrefix", "givenName", "additionalName", "familyName",
|
||||
"honorificSuffix", "nickname", "photo", "category", "org", "jobTitle",
|
||||
"bday", "note", "anniversary", "sex", "genderIdentity", "key"
|
||||
];
|
||||
const ADDRESS_PROPERTIES = ["adr"];
|
||||
const FIELD_PROPERTIES = ["email", "url", "impp"];
|
||||
const TELFIELD_PROPERTIES = ["tel"];
|
||||
|
||||
function Contact() { }
|
||||
|
||||
Contact.prototype = {
|
||||
__exposedProps__: {
|
||||
id: 'rw',
|
||||
updated: 'rw',
|
||||
published: 'rw',
|
||||
name: 'rw',
|
||||
honorificPrefix: 'rw',
|
||||
givenName: 'rw',
|
||||
additionalName: 'rw',
|
||||
familyName: 'rw',
|
||||
honorificSuffix: 'rw',
|
||||
nickname: 'rw',
|
||||
email: 'rw',
|
||||
photo: 'rw',
|
||||
url: 'rw',
|
||||
category: 'rw',
|
||||
adr: 'rw',
|
||||
tel: 'rw',
|
||||
org: 'rw',
|
||||
jobTitle: 'rw',
|
||||
bday: 'rw',
|
||||
note: 'rw',
|
||||
impp: 'rw',
|
||||
anniversary: 'rw',
|
||||
sex: 'rw',
|
||||
genderIdentity: 'rw',
|
||||
key: 'rw',
|
||||
},
|
||||
|
||||
set name(aName) {
|
||||
this._name = sanitizeStringArray(aName);
|
||||
},
|
||||
|
||||
get name() {
|
||||
return this._name;
|
||||
},
|
||||
|
||||
set honorificPrefix(aHonorificPrefix) {
|
||||
this._honorificPrefix = sanitizeStringArray(aHonorificPrefix);
|
||||
},
|
||||
|
||||
get honorificPrefix() {
|
||||
return this._honorificPrefix;
|
||||
},
|
||||
|
||||
set givenName(aGivenName) {
|
||||
this._givenName = sanitizeStringArray(aGivenName);
|
||||
},
|
||||
|
||||
get givenName() {
|
||||
return this._givenName;
|
||||
},
|
||||
|
||||
set additionalName(aAdditionalName) {
|
||||
this._additionalName = sanitizeStringArray(aAdditionalName);
|
||||
},
|
||||
|
||||
get additionalName() {
|
||||
return this._additionalName;
|
||||
},
|
||||
|
||||
set familyName(aFamilyName) {
|
||||
this._familyName = sanitizeStringArray(aFamilyName);
|
||||
},
|
||||
|
||||
get familyName() {
|
||||
return this._familyName;
|
||||
},
|
||||
|
||||
set honorificSuffix(aHonorificSuffix) {
|
||||
this._honorificSuffix = sanitizeStringArray(aHonorificSuffix);
|
||||
},
|
||||
|
||||
get honorificSuffix() {
|
||||
return this._honorificSuffix;
|
||||
},
|
||||
|
||||
set nickname(aNickname) {
|
||||
this._nickname = sanitizeStringArray(aNickname);
|
||||
},
|
||||
|
||||
get nickname() {
|
||||
return this._nickname;
|
||||
},
|
||||
|
||||
set photo(aPhoto) {
|
||||
this._photo = checkBlobArray(aPhoto);
|
||||
},
|
||||
|
||||
get photo() {
|
||||
return this._photo;
|
||||
},
|
||||
|
||||
set category(aCategory) {
|
||||
this._category = sanitizeStringArray(aCategory);
|
||||
},
|
||||
|
||||
get category() {
|
||||
return this._category;
|
||||
},
|
||||
|
||||
// We need to create the content interfaces in these setters, otherwise when
|
||||
// we return these objects (e.g. from a find call), the values in the array
|
||||
// will be COW's, and content cannot see the properties.
|
||||
set email(aEmail) {
|
||||
this._email = validateArrayField(aEmail, function(email) {
|
||||
return new ContactField(email.type, email.value, email.pref);
|
||||
});
|
||||
let obj = new this._window.ContactField();
|
||||
obj.initialize(email.type, email.value, email.pref);
|
||||
return obj;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get email() {
|
||||
@ -348,10 +227,12 @@ Contact.prototype = {
|
||||
|
||||
set adr(aAdr) {
|
||||
this._adr = validateArrayField(aAdr, function(adr) {
|
||||
return new ContactAddress(adr.type, adr.streetAddress, adr.locality,
|
||||
adr.region, adr.postalCode, adr.countryName,
|
||||
adr.pref);
|
||||
});
|
||||
let obj = new this._window.ContactAddress();
|
||||
obj.initialize(adr.type, adr.streetAddress, adr.locality,
|
||||
adr.region, adr.postalCode, adr.countryName,
|
||||
adr.pref);
|
||||
return obj;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get adr() {
|
||||
@ -360,8 +241,10 @@ Contact.prototype = {
|
||||
|
||||
set tel(aTel) {
|
||||
this._tel = validateArrayField(aTel, function(tel) {
|
||||
return new ContactTelField(tel.type, tel.value, tel.carrier, tel.pref);
|
||||
});
|
||||
let obj = new this._window.ContactTelField();
|
||||
obj.initialize(tel.type, tel.value, tel.carrier, tel.pref);
|
||||
return obj;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get tel() {
|
||||
@ -370,8 +253,10 @@ Contact.prototype = {
|
||||
|
||||
set impp(aImpp) {
|
||||
this._impp = validateArrayField(aImpp, function(impp) {
|
||||
return new ContactField(impp.type, impp.value, impp.pref);
|
||||
});
|
||||
let obj = new this._window.ContactField();
|
||||
obj.initialize(impp.type, impp.value, impp.pref);
|
||||
return obj;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get impp() {
|
||||
@ -380,95 +265,21 @@ Contact.prototype = {
|
||||
|
||||
set url(aUrl) {
|
||||
this._url = validateArrayField(aUrl, function(url) {
|
||||
return new ContactField(url.type, url.value, url.pref);
|
||||
});
|
||||
let obj = new this._window.ContactField();
|
||||
obj.initialize(url.type, url.value, url.pref);
|
||||
return obj;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
get url() {
|
||||
return this._url;
|
||||
},
|
||||
|
||||
set org(aOrg) {
|
||||
this._org = sanitizeStringArray(aOrg);
|
||||
init: function(aWindow) {
|
||||
this._window = aWindow;
|
||||
},
|
||||
|
||||
get org() {
|
||||
return this._org;
|
||||
},
|
||||
|
||||
set jobTitle(aJobTitle) {
|
||||
this._jobTitle = sanitizeStringArray(aJobTitle);
|
||||
},
|
||||
|
||||
get jobTitle() {
|
||||
return this._jobTitle;
|
||||
},
|
||||
|
||||
set note(aNote) {
|
||||
this._note = sanitizeStringArray(aNote);
|
||||
},
|
||||
|
||||
get note() {
|
||||
return this._note;
|
||||
},
|
||||
|
||||
set bday(aBday) {
|
||||
if (aBday && aBday.constructor.name === "Date") {
|
||||
this._bday = aBday;
|
||||
} else if (typeof aBday === "string" || typeof aBday === "number") {
|
||||
this._bday = new Date(aBday);
|
||||
}
|
||||
},
|
||||
|
||||
get bday() {
|
||||
return this._bday;
|
||||
},
|
||||
|
||||
set anniversary(aAnniversary) {
|
||||
if (aAnniversary && aAnniversary.constructor.name === "Date") {
|
||||
this._anniversary = aAnniversary;
|
||||
} else if (typeof aAnniversary === "string" || typeof aAnniversary === "number") {
|
||||
this._anniversary = new Date(aAnniversary);
|
||||
}
|
||||
},
|
||||
|
||||
get anniversary() {
|
||||
return this._anniversary;
|
||||
},
|
||||
|
||||
set sex(aSex) {
|
||||
if (aSex !== "undefined") {
|
||||
this._sex = aSex;
|
||||
} else {
|
||||
this._sex = null;
|
||||
}
|
||||
},
|
||||
|
||||
get sex() {
|
||||
return this._sex;
|
||||
},
|
||||
|
||||
set genderIdentity(aGenderIdentity) {
|
||||
if (aGenderIdentity !== "undefined") {
|
||||
this._genderIdentity = aGenderIdentity;
|
||||
} else {
|
||||
this._genderIdentity = null;
|
||||
}
|
||||
},
|
||||
|
||||
get genderIdentity() {
|
||||
return this._genderIdentity;
|
||||
},
|
||||
|
||||
set key(aKey) {
|
||||
this._key = sanitizeStringArray(aKey);
|
||||
},
|
||||
|
||||
get key() {
|
||||
return this._key;
|
||||
},
|
||||
|
||||
init: function init(aProp) {
|
||||
__init: function(aProp) {
|
||||
this.name = aProp.name;
|
||||
this.honorificPrefix = aProp.honorificPrefix;
|
||||
this.givenName = aProp.givenName;
|
||||
@ -493,76 +304,105 @@ Contact.prototype = {
|
||||
this.key = aProp.key;
|
||||
},
|
||||
|
||||
get published () {
|
||||
return this._published;
|
||||
setMetadata: function(aId, aPublished, aUpdated) {
|
||||
this.id = aId;
|
||||
if (aPublished) {
|
||||
this.published = aPublished;
|
||||
}
|
||||
if (aUpdated) {
|
||||
this.updated = aUpdated;
|
||||
}
|
||||
},
|
||||
|
||||
set published(aPublished) {
|
||||
this._published = aPublished;
|
||||
toJSON: function() {
|
||||
return {
|
||||
id: this.id,
|
||||
published: this.published,
|
||||
updated: this.updated,
|
||||
|
||||
name: this.name,
|
||||
honorificPrefix: this.honorificPrefix,
|
||||
givenName: this.givenName,
|
||||
additionalName: this.additionalName,
|
||||
familyName: this.familyName,
|
||||
honorificSuffix: this.honorificSuffix,
|
||||
nickname: this.nickname,
|
||||
category: this.category,
|
||||
org: this.org,
|
||||
jobTitle: this.jobTitle,
|
||||
note: this.note,
|
||||
sex: this.sex,
|
||||
genderIdentity: this.genderIdentity,
|
||||
email: this.email,
|
||||
photo: this.photo,
|
||||
adr: this.adr,
|
||||
url: this.url,
|
||||
tel: this.tel,
|
||||
bday: this.bday,
|
||||
impp: this.impp,
|
||||
anniversary: this.anniversary,
|
||||
key: this.key,
|
||||
|
||||
__exposedProps__: {
|
||||
id: "rw",
|
||||
published: "rw",
|
||||
updated: "rw",
|
||||
name: "rw",
|
||||
honorificPrefix: "rw",
|
||||
givenName: "rw",
|
||||
additionalName: "rw",
|
||||
familyName: "rw",
|
||||
honorificSuffix: "rw",
|
||||
nickname: "rw",
|
||||
category: "rw",
|
||||
org: "rw",
|
||||
jobTitle: "rw",
|
||||
note: "rw",
|
||||
sex: "rw",
|
||||
genderIdentity: "rw",
|
||||
email: "rw",
|
||||
photo: "rw",
|
||||
adr: "rw",
|
||||
url: "rw",
|
||||
tel: "rw",
|
||||
bday: "rw",
|
||||
impp: "rw",
|
||||
anniversary: "rw",
|
||||
key: "rw",
|
||||
}
|
||||
};
|
||||
},
|
||||
|
||||
get updated () {
|
||||
return this._updated;
|
||||
},
|
||||
classID: Components.ID("{72a5ee28-81d8-4af8-90b3-ae935396cc66}"),
|
||||
contractID: "@mozilla.org/contact;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupports,
|
||||
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
};
|
||||
|
||||
set updated(aUpdated) {
|
||||
this._updated = aUpdated;
|
||||
},
|
||||
|
||||
classID : CONTACT_CID,
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACT_CID,
|
||||
contractID: CONTACT_CONTRACTID,
|
||||
classDescription: "Contact",
|
||||
interfaces: [nsIDOMContact, nsIContactProperties],
|
||||
flags: nsIClassInfo.DOM_OBJECT}),
|
||||
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMContact, nsIContactProperties])
|
||||
}
|
||||
|
||||
// ContactManager
|
||||
|
||||
const CONTACTMANAGER_CONTRACTID = "@mozilla.org/contactManager;1";
|
||||
const CONTACTMANAGER_CID = Components.ID("{8beb3a66-d70a-4111-b216-b8e995ad3aff}");
|
||||
const nsIDOMContactManager = Components.interfaces.nsIDOMContactManager;
|
||||
|
||||
function ContactManager()
|
||||
{
|
||||
if (DEBUG) debug("Constructor");
|
||||
}
|
||||
function ContactManager() { }
|
||||
|
||||
ContactManager.prototype = {
|
||||
__proto__: DOMRequestIpcHelper.prototype,
|
||||
_oncontactchange: null,
|
||||
hasListenPermission: false,
|
||||
_cachedContacts: [] ,
|
||||
|
||||
set oncontactchange(aCallback) {
|
||||
if (DEBUG) debug("set oncontactchange");
|
||||
let allowCallback = function() {
|
||||
if (!this._oncontactchange) {
|
||||
cpmm.sendAsyncMessage("Contacts:RegisterForMessages");
|
||||
}
|
||||
this._oncontactchange = aCallback;
|
||||
}.bind(this);
|
||||
let cancelCallback = function() {
|
||||
throw Components.results.NS_ERROR_FAILURE;
|
||||
}
|
||||
this.askPermission("listen", null, allowCallback, cancelCallback);
|
||||
set oncontactchange(aHandler) {
|
||||
this.__DOM_IMPL__.setEventHandler("oncontactchange", aHandler);
|
||||
},
|
||||
|
||||
get oncontactchange() {
|
||||
return this._oncontactchange;
|
||||
return this.__DOM_IMPL__.getEventHandler("oncontactchange");
|
||||
},
|
||||
|
||||
_setMetaData: function(aNewContact, aRecord) {
|
||||
aNewContact.id = aRecord.id;
|
||||
aNewContact.published = aRecord.published;
|
||||
aNewContact.updated = aRecord.updated;
|
||||
},
|
||||
|
||||
_convertContact: function CM_convertContact(aContact) {
|
||||
let newContact = new Contact();
|
||||
newContact.init(aContact.properties);
|
||||
this._setMetaData(newContact, aContact);
|
||||
_convertContact: function(aContact) {
|
||||
if (aContact.properties.bday) {
|
||||
aContact.properties.bday = new Date(aContact.properties.bday);
|
||||
}
|
||||
if (aContact.properties.anniversary) {
|
||||
aContact.properties.anniversary = new Date(aContact.properties.anniversary);
|
||||
}
|
||||
let newContact = new this._window.mozContact(aContact.properties);
|
||||
newContact.setMetadata(aContact.id, aContact.published, aContact.updated);
|
||||
return newContact;
|
||||
},
|
||||
|
||||
@ -672,13 +512,11 @@ ContactManager.prototype = {
|
||||
case "Contact:Changed":
|
||||
// Fire oncontactchange event
|
||||
if (DEBUG) debug("Contacts:ContactChanged: " + msg.contactID + ", " + msg.reason);
|
||||
if (this._oncontactchange) {
|
||||
let event = new this._window.MozContactChangeEvent("contactchanged", {
|
||||
contactID: msg.contactID,
|
||||
reason: msg.reason
|
||||
});
|
||||
this._oncontactchange.handleEvent(event);
|
||||
}
|
||||
let event = new this._window.MozContactChangeEvent("contactchange", {
|
||||
contactID: msg.contactID,
|
||||
reason: msg.reason
|
||||
});
|
||||
this.dispatchEvent(event);
|
||||
break;
|
||||
case "Contacts:Revision":
|
||||
if (DEBUG) debug("new revision: " + msg.revision);
|
||||
@ -700,6 +538,12 @@ ContactManager.prototype = {
|
||||
this.removeRequest(msg.requestID);
|
||||
},
|
||||
|
||||
dispatchEvent: function(event) {
|
||||
if (this.hasListenPermission) {
|
||||
this.__DOM_IMPL__.dispatchEvent(event);
|
||||
}
|
||||
},
|
||||
|
||||
askPermission: function (aAccess, aRequest, aAllowCallback, aCancelCallback) {
|
||||
if (DEBUG) debug("askPermission for contacts");
|
||||
let access;
|
||||
@ -757,35 +601,53 @@ ContactManager.prototype = {
|
||||
},
|
||||
|
||||
save: function save(aContact) {
|
||||
if (DEBUG) debug("save: " + JSON.stringify(aContact) + " :" + aContact.id);
|
||||
let newContact = {};
|
||||
newContact.properties = {
|
||||
name: [],
|
||||
honorificPrefix: [],
|
||||
givenName: [],
|
||||
additionalName: [],
|
||||
familyName: [],
|
||||
honorificSuffix: [],
|
||||
nickname: [],
|
||||
email: [],
|
||||
photo: [],
|
||||
url: [],
|
||||
category: [],
|
||||
adr: [],
|
||||
tel: [],
|
||||
org: [],
|
||||
jobTitle: [],
|
||||
bday: null,
|
||||
note: [],
|
||||
impp: [],
|
||||
anniversary: null,
|
||||
sex: null,
|
||||
genderIdentity: null,
|
||||
key: [],
|
||||
};
|
||||
for (let field in newContact.properties) {
|
||||
newContact.properties[field] = aContact[field];
|
||||
// We have to do a deep copy of the contact manually here because
|
||||
// nsFrameMessageManager doesn't know how to create a structured clone of a
|
||||
// mozContact object.
|
||||
let newContact = {properties: {}};
|
||||
|
||||
for (let field of PROPERTIES) {
|
||||
if (aContact[field]) {
|
||||
newContact.properties[field] = aContact[field];
|
||||
}
|
||||
}
|
||||
|
||||
for (let prop of ADDRESS_PROPERTIES) {
|
||||
if (aContact[prop]) {
|
||||
newContact.properties[prop] = [];
|
||||
for (let i of aContact[prop]) {
|
||||
if (i) {
|
||||
let json = ContactAddress.prototype.toJSON.apply(i, [true]);
|
||||
newContact.properties[prop].push(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let prop of FIELD_PROPERTIES) {
|
||||
if (aContact[prop]) {
|
||||
newContact.properties[prop] = [];
|
||||
for (let i of aContact[prop]) {
|
||||
if (i) {
|
||||
let json = ContactField.prototype.toJSON.apply(i, [true]);
|
||||
newContact.properties[prop].push(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (let prop of TELFIELD_PROPERTIES) {
|
||||
if (aContact[prop]) {
|
||||
newContact.properties[prop] = [];
|
||||
for (let i of aContact[prop]) {
|
||||
if (i) {
|
||||
let json = ContactTelField.prototype.toJSON.apply(i, [true]);
|
||||
newContact.properties[prop].push(json);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let request = this.createRequest();
|
||||
let requestID = this.getRequestId({request: request, reason: reason});
|
||||
|
||||
@ -793,7 +655,7 @@ ContactManager.prototype = {
|
||||
if (aContact.id == "undefined") {
|
||||
// for example {25c00f01-90e5-c545-b4d4-21E2ddbab9e0} becomes
|
||||
// 25c00f0190e5c545b4d421E2ddbab9e0
|
||||
aContact.id = this._getRandomId().replace('-', '', 'g').replace('{', '').replace('}', '');
|
||||
aContact.id = this._getRandomId().replace(/[{}-]/g, "");
|
||||
// Cache the contact so that its ID may be updated later if necessary
|
||||
this._cachedContacts[requestID] = aContact;
|
||||
reason = "create";
|
||||
@ -801,8 +663,12 @@ ContactManager.prototype = {
|
||||
reason = "update";
|
||||
}
|
||||
|
||||
this._setMetaData(newContact, aContact);
|
||||
newContact.id = aContact.id;
|
||||
newContact.published = aContact.published;
|
||||
newContact.updated = aContact.updated;
|
||||
|
||||
if (DEBUG) debug("send: " + JSON.stringify(newContact));
|
||||
|
||||
let options = { contact: newContact, reason: reason };
|
||||
let allowCallback = function() {
|
||||
cpmm.sendAsyncMessage("Contact:Save", {requestID: requestID, options: options});
|
||||
@ -878,19 +744,18 @@ ContactManager.prototype = {
|
||||
let options = { id: aRecord.id };
|
||||
let allowCallback = function() {
|
||||
cpmm.sendAsyncMessage("Contact:Remove", {requestID: this.getRequestId({request: request, reason: "remove"}), options: options});
|
||||
}.bind(this)
|
||||
}.bind(this);
|
||||
this.askPermission("remove", request, allowCallback);
|
||||
return request;
|
||||
},
|
||||
|
||||
clear: function() {
|
||||
if (DEBUG) debug("clear");
|
||||
let request;
|
||||
request = this.createRequest();
|
||||
let request = this.createRequest();
|
||||
let options = {};
|
||||
let allowCallback = function() {
|
||||
cpmm.sendAsyncMessage("Contacts:Clear", {requestID: this.getRequestId({request: request, reason: "remove"}), options: options});
|
||||
}.bind(this)
|
||||
}.bind(this);
|
||||
this.askPermission("remove", request, allowCallback);
|
||||
return request;
|
||||
},
|
||||
@ -930,6 +795,7 @@ ContactManager.prototype = {
|
||||
},
|
||||
|
||||
init: function(aWindow) {
|
||||
// DOMRequestIpcHelper.initHelper sets this._window
|
||||
this.initDOMRequestHelper(aWindow, ["Contacts:Find:Return:OK", "Contacts:Find:Return:KO",
|
||||
"Contacts:Clear:Return:OK", "Contacts:Clear:Return:KO",
|
||||
"Contact:Save:Return:OK", "Contact:Save:Return:KO",
|
||||
@ -939,26 +805,22 @@ ContactManager.prototype = {
|
||||
"Contacts:GetAll:Next", "Contacts:GetAll:Return:KO",
|
||||
"Contacts:Count",
|
||||
"Contacts:Revision", "Contacts:GetRevision:Return:KO",]);
|
||||
|
||||
|
||||
let allowCallback = function() {
|
||||
cpmm.sendAsyncMessage("Contacts:RegisterForMessages");
|
||||
this.hasListenPermission = true;
|
||||
}.bind(this);
|
||||
|
||||
this.askPermission("listen", null, allowCallback);
|
||||
},
|
||||
|
||||
// Called from DOMRequestIpcHelper
|
||||
uninit: function uninit() {
|
||||
if (DEBUG) debug("uninit call");
|
||||
if (this._oncontactchange)
|
||||
this._oncontactchange = null;
|
||||
},
|
||||
classID: Components.ID("{8beb3a66-d70a-4111-b216-b8e995ad3aff}"),
|
||||
contractID: "@mozilla.org/contactManager;1",
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsISupportsWeakReference,
|
||||
Ci.nsIDOMGlobalPropertyInitializer]),
|
||||
};
|
||||
|
||||
classID : CONTACTMANAGER_CID,
|
||||
QueryInterface : XPCOMUtils.generateQI([nsIDOMContactManager,
|
||||
Ci.nsIDOMGlobalPropertyInitializer,
|
||||
Ci.nsISupportsWeakReference]),
|
||||
|
||||
classInfo : XPCOMUtils.generateCI({classID: CONTACTMANAGER_CID,
|
||||
contractID: CONTACTMANAGER_CONTRACTID,
|
||||
classDescription: "ContactManager",
|
||||
interfaces: [nsIDOMContactManager],
|
||||
flags: nsIClassInfo.DOM_OBJECT})
|
||||
}
|
||||
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory(
|
||||
[Contact, ContactManager, ContactProperties, ContactAddress, ContactField, ContactTelField, ContactFindSortOptions, ContactFindOptions])
|
||||
this.NSGetFactory = XPCOMUtils.generateNSGetFactory([
|
||||
Contact, ContactManager, ContactAddress, ContactField, ContactTelField
|
||||
]);
|
||||
|
@ -1,6 +1,3 @@
|
||||
component {35ad8a4e-9486-44b6-883d-550f14635e49} ContactManager.js
|
||||
contract @mozilla.org/contactProperties;1 {35ad8a4e-9486-44b6-883d-550f14635e49}
|
||||
|
||||
component {9cbfa81c-bcab-4ca9-b0d2-f4318f295e33} ContactManager.js
|
||||
contract @mozilla.org/contactAddress;1 {9cbfa81c-bcab-4ca9-b0d2-f4318f295e33}
|
||||
|
||||
@ -10,16 +7,8 @@ contract @mozilla.org/contactField;1 {ad19a543-69e4-44f0-adfa-37c011556bc1}
|
||||
component {4d42c5a9-ea5d-4102-80c3-40cc986367ca} ContactManager.js
|
||||
contract @mozilla.org/contactTelField;1 {4d42c5a9-ea5d-4102-80c3-40cc986367ca}
|
||||
|
||||
component {0a5b1fab-70da-46dd-b902-619904d920c2} ContactManager.js
|
||||
contract @mozilla.org/contactFindSortOptions;1 {0a5b1fab-70da-46dd-b902-619904d920c2}
|
||||
|
||||
component {28ce07d0-45d9-4b7a-8843-521df4edd8bc} ContactManager.js
|
||||
contract @mozilla.org/contactFindOptions;1 {28ce07d0-45d9-4b7a-8843-521df4edd8bc}
|
||||
|
||||
component {72a5ee28-81d8-4af8-90b3-ae935396cc66} ContactManager.js
|
||||
contract @mozilla.org/contact;1 {72a5ee28-81d8-4af8-90b3-ae935396cc66}
|
||||
category JavaScript-global-constructor mozContact @mozilla.org/contact;1
|
||||
|
||||
component {8beb3a66-d70a-4111-b216-b8e995ad3aff} ContactManager.js
|
||||
contract @mozilla.org/contactManager;1 {8beb3a66-d70a-4111-b216-b8e995ad3aff}
|
||||
category JavaScript-navigator-property mozContacts @mozilla.org/contactManager;1
|
||||
|
@ -20,7 +20,7 @@ Cu.import("resource://gre/modules/IndexedDBHelper.jsm");
|
||||
Cu.import("resource://gre/modules/PhoneNumberUtils.jsm");
|
||||
|
||||
const DB_NAME = "contacts";
|
||||
const DB_VERSION = 14;
|
||||
const DB_VERSION = 15;
|
||||
const STORE_NAME = "contacts";
|
||||
const SAVED_GETALL_STORE_NAME = "getallcache";
|
||||
const CHUNK_SIZE = 20;
|
||||
@ -28,16 +28,10 @@ const REVISION_STORE = "revision";
|
||||
const REVISION_KEY = "revision";
|
||||
|
||||
function exportContact(aRecord) {
|
||||
let contact = {};
|
||||
contact.properties = aRecord.properties;
|
||||
|
||||
for (let field in aRecord.properties)
|
||||
contact.properties[field] = aRecord.properties[field];
|
||||
|
||||
contact.updated = aRecord.updated;
|
||||
contact.published = aRecord.published;
|
||||
contact.id = aRecord.id;
|
||||
return contact;
|
||||
if (aRecord) {
|
||||
delete aRecord.search;
|
||||
}
|
||||
return aRecord;
|
||||
}
|
||||
|
||||
function ContactDispatcher(aContacts, aFullContacts, aCallback, aNewTxn, aClearDispatcher, aFailureCb) {
|
||||
@ -150,9 +144,7 @@ ContactDB.prototype = {
|
||||
for (let i = 0; i < contacts.length; i++) {
|
||||
let contact = {};
|
||||
contact.properties = contacts[i];
|
||||
contact.id = idService.generateUUID().toString().replace('-', '', 'g')
|
||||
.replace('{', '')
|
||||
.replace('}', '');
|
||||
contact.id = idService.generateUUID().toString().replace(/[{}-]/g, "");
|
||||
contact = this.makeImport(contact);
|
||||
this.updateRecordMetadata(contact);
|
||||
if (DEBUG) debug("import: " + JSON.stringify(contact));
|
||||
@ -544,11 +536,54 @@ ContactDB.prototype = {
|
||||
if (modified || modified2) {
|
||||
cursor.update(cursor.value);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
},
|
||||
function upgrade14to15() {
|
||||
if (DEBUG) debug("Fix array properties saved as scalars");
|
||||
if (!objectStore) {
|
||||
objectStore = aTransaction.objectStore(STORE_NAME);
|
||||
}
|
||||
const ARRAY_PROPERTIES = ["photo", "adr", "email", "url", "impp", "tel",
|
||||
"name", "honorificPrefix", "givenName",
|
||||
"additionalName", "familyName", "honorificSuffix",
|
||||
"nickname", "category", "org", "jobTitle",
|
||||
"note", "key"];
|
||||
const PROPERTIES_WITH_TYPE = ["adr", "email", "url", "impp", "tel"];
|
||||
objectStore.openCursor().onsuccess = function(event) {
|
||||
let cursor = event.target.result;
|
||||
let changed = false;
|
||||
if (cursor) {
|
||||
let props = cursor.value.properties;
|
||||
for (let prop of ARRAY_PROPERTIES) {
|
||||
if (props[prop]) {
|
||||
if (!Array.isArray(props[prop])) {
|
||||
cursor.value.properties[prop] = [props[prop]];
|
||||
changed = true;
|
||||
}
|
||||
if (PROPERTIES_WITH_TYPE.indexOf(prop) !== -1) {
|
||||
let subprop = cursor.value.properties[prop];
|
||||
for (let i = 0; i < subprop.length; ++i) {
|
||||
if (!Array.isArray(subprop[i].type)) {
|
||||
cursor.value.properties[prop][i].type = [subprop[i].type];
|
||||
changed = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (changed) {
|
||||
cursor.update(cursor.value);
|
||||
}
|
||||
cursor.continue();
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
};
|
||||
},
|
||||
];
|
||||
|
||||
let index = aOldVersion;
|
||||
@ -576,31 +611,7 @@ ContactDB.prototype = {
|
||||
},
|
||||
|
||||
makeImport: function makeImport(aContact) {
|
||||
let contact = {};
|
||||
contact.properties = {
|
||||
name: [],
|
||||
honorificPrefix: [],
|
||||
givenName: [],
|
||||
additionalName: [],
|
||||
familyName: [],
|
||||
honorificSuffix: [],
|
||||
nickname: [],
|
||||
email: [],
|
||||
photo: [],
|
||||
url: [],
|
||||
category: [],
|
||||
adr: [],
|
||||
tel: [],
|
||||
org: [],
|
||||
jobTitle: [],
|
||||
bday: null,
|
||||
note: [],
|
||||
impp: [],
|
||||
anniversary: null,
|
||||
sex: null,
|
||||
genderIdentity: null,
|
||||
key: [],
|
||||
};
|
||||
let contact = {properties: {}};
|
||||
|
||||
contact.search = {
|
||||
givenName: [],
|
||||
@ -687,7 +698,6 @@ ContactDB.prototype = {
|
||||
}
|
||||
}
|
||||
}
|
||||
if (DEBUG) debug("contact:" + JSON.stringify(contact));
|
||||
|
||||
contact.updated = aContact.updated;
|
||||
contact.published = aContact.published;
|
||||
|
@ -61,29 +61,30 @@ var c4 = {
|
||||
};
|
||||
|
||||
var c5 = {
|
||||
nickname: "empty"
|
||||
familyName: [],
|
||||
givenName: [],
|
||||
};
|
||||
|
||||
var c6 = {
|
||||
name: "e",
|
||||
name: ["e"],
|
||||
familyName: ["e","e","e"],
|
||||
givenName: ["e","e","e"],
|
||||
};
|
||||
|
||||
var c7 = {
|
||||
name: "e",
|
||||
name: ["e"],
|
||||
familyName: ["e","e","e"],
|
||||
givenName: ["e","e","e"],
|
||||
};
|
||||
|
||||
var c8 = {
|
||||
name: "e",
|
||||
name: ["e"],
|
||||
familyName: ["e","e","e"],
|
||||
givenName: ["e","e","e"],
|
||||
};
|
||||
|
||||
var adr1 = {
|
||||
type: "work",
|
||||
type: ["work"],
|
||||
streetAddress: "street 1",
|
||||
locality: "locality 1",
|
||||
region: "region 1",
|
||||
@ -92,7 +93,7 @@ var adr1 = {
|
||||
};
|
||||
|
||||
var adr2 = {
|
||||
type: "home, fax",
|
||||
type: ["home, fax"],
|
||||
streetAddress: "street2",
|
||||
locality: "locality2",
|
||||
region: "region2",
|
||||
@ -104,34 +105,34 @@ var properties1 = {
|
||||
name: ["Test1 TestFamilyName", "Test2 Wagner"],
|
||||
familyName: ["TestFamilyName","Wagner"],
|
||||
givenName: ["Test1","Test2"],
|
||||
nickname: "nicktest",
|
||||
nickname: ["nicktest"],
|
||||
tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+55 (31) 9876-3456"}, {type: ["home"], value: "+49 451 491934"}],
|
||||
adr: adr1,
|
||||
adr: [adr1],
|
||||
email: [{type: ["work"], value: "x@y.com"}],
|
||||
};
|
||||
|
||||
var properties2 = {
|
||||
name: ["dummyHonorificPrefix dummyGivenName dummyFamilyName dummyHonorificSuffix", "dummyHonorificPrefix2"],
|
||||
familyName: "dummyFamilyName",
|
||||
givenName: "dummyGivenName",
|
||||
familyName: ["dummyFamilyName"],
|
||||
givenName: ["dummyGivenName"],
|
||||
honorificPrefix: ["dummyHonorificPrefix","dummyHonorificPrefix2"],
|
||||
honorificSuffix: "dummyHonorificSuffix",
|
||||
additionalName: "dummyadditionalName",
|
||||
nickname: "dummyNickname",
|
||||
honorificSuffix: ["dummyHonorificSuffix"],
|
||||
additionalName: ["dummyadditionalName"],
|
||||
nickname: ["dummyNickname"],
|
||||
tel: [{type: ["test"], value: "7932012345", carrier: "myCarrier", pref: 1},{type: ["home", "custom"], value: "7932012346", pref: 0}],
|
||||
email: [{type: ["test"], value: "a@b.c"}, {value: "b@c.d", pref: 1}],
|
||||
adr: [adr1, adr2],
|
||||
impp: [{type: ["aim"], value:"im1", pref: 1}, {value: "im2"}],
|
||||
org: ["org1", "org2"],
|
||||
jobTitle: ["boss", "superboss"],
|
||||
note: "test note",
|
||||
note: ["test note"],
|
||||
category: ["cat1", "cat2"],
|
||||
url: [{type: ["work", "work2"], value: "www.1.com", pref: 1}, {value:"www2.com"}],
|
||||
bday: new Date("1980, 12, 01"),
|
||||
anniversary: new Date("2000, 12, 01"),
|
||||
sex: "male",
|
||||
genderIdentity: "test",
|
||||
key: "ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"
|
||||
key: ["ERPJ394GJJWEVJ0349GJ09W3H4FG0WFW80VHW3408GH30WGH348G3H"]
|
||||
};
|
||||
|
||||
var sample_id1;
|
||||
@ -166,20 +167,39 @@ function checkStr(str1, str2, msg) {
|
||||
ok(false, "Expected both strings to be either present or absent");
|
||||
return;
|
||||
}
|
||||
if (!str1 || str1 == "null") {
|
||||
str1 = null;
|
||||
}
|
||||
if (!str2 || str2 == "null") {
|
||||
str2 = null;
|
||||
}
|
||||
is(str1, str2, msg);
|
||||
}
|
||||
|
||||
function checkStrArray(str1, str2, msg) {
|
||||
// comparing /[null(,null)+]/ and undefined should pass
|
||||
function nonNull(e) {
|
||||
return e != null;
|
||||
function normalize_falsy(v) {
|
||||
if (!v || v == "null" || v == "undefined") {
|
||||
return "";
|
||||
}
|
||||
return v;
|
||||
}
|
||||
if ((Array.isArray(str1) && str1.filter(nonNull).length == 0 && str2 == undefined)
|
||||
||(Array.isArray(str2) && str2.filter(nonNull).length == 0 && str1 == undefined)) {
|
||||
ok(true, msg);
|
||||
} else if (str1) {
|
||||
is(JSON.stringify(typeof str1 == "string" ? [str1] : str1), JSON.stringify(typeof str2 == "string" ? [str2] : str2), msg);
|
||||
function optArray(val) {
|
||||
return Array.isArray(val) ? val : [val];
|
||||
}
|
||||
str1 = optArray(str1).map(normalize_falsy).filter(v => v != "");
|
||||
str2 = optArray(str2).map(normalize_falsy).filter(v => v != "");
|
||||
ise(JSON.stringify(str1), JSON.stringify(str2), msg);
|
||||
}
|
||||
|
||||
function checkPref(pref1, pref2) {
|
||||
// If on Android treat one preference as 0 and the other as undefined as matching
|
||||
if (isAndroid) {
|
||||
if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
|
||||
pref1 = false;
|
||||
pref2 = false;
|
||||
}
|
||||
}
|
||||
ise(!!pref1, !!pref2, "Same pref");
|
||||
}
|
||||
|
||||
function checkAddress(adr1, adr2) {
|
||||
@ -188,44 +208,31 @@ function checkAddress(adr1, adr2) {
|
||||
return;
|
||||
}
|
||||
checkStrArray(adr1.type, adr2.type, "Same type");
|
||||
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
|
||||
checkStrArray(adr1.locality, adr2.locality, "Same locality");
|
||||
checkStrArray(adr1.region, adr2.region, "Same region");
|
||||
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
|
||||
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
|
||||
checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
|
||||
checkStr(adr1.locality, adr2.locality, "Same locality");
|
||||
checkStr(adr1.region, adr2.region, "Same region");
|
||||
checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
|
||||
checkStr(adr1.countryName, adr2.countryName, "Same countryName");
|
||||
checkPref(adr1.pref, adr2.pref);
|
||||
}
|
||||
|
||||
function checkTel(tel1, tel2) {
|
||||
if (tel1 ^ tel2) {
|
||||
ok(false, "Expected both tels to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(tel1.type, tel2.type, "Same type");
|
||||
checkStrArray(tel1.value, tel2.value, "Same value");
|
||||
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
|
||||
checkPref(tel1.pref, tel2.pref);
|
||||
}
|
||||
|
||||
function checkField(field1, field2) {
|
||||
if (field1 ^ field2) {
|
||||
ok(false, "Expected both fields to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(field1.type, field2.type, "Same type");
|
||||
checkStrArray(field1.value, field2.value, "Same value");
|
||||
checkStr(field1.value, field2.value, "Same value");
|
||||
checkPref(field1.pref, field2.pref);
|
||||
}
|
||||
|
||||
function checkPref(pref1, pref2) {
|
||||
// If on Android treat one preference as 0 and the other as undefined as matching
|
||||
if (isAndroid) {
|
||||
if ((pref1 == 0 && pref2 == undefined) || (pref1 == undefined && pref2 == 0)) {
|
||||
pref1 = 0;
|
||||
pref2 = 0;
|
||||
}
|
||||
function checkTel(tel1, tel2) {
|
||||
if (tel1 ^ tel2) {
|
||||
ok(false, "Expected both tels to be either present or absent");
|
||||
return;
|
||||
}
|
||||
is(pref1, pref2, "Same pref");
|
||||
checkField(tel1, tel2);
|
||||
checkStr(tel1.carrier, tel2.carrier, "Same carrier");
|
||||
}
|
||||
|
||||
function checkCategory(category1, category2) {
|
||||
@ -239,21 +246,42 @@ function checkCategory(category1, category2) {
|
||||
}
|
||||
|
||||
function removeAndroidDefaultCategory(category) {
|
||||
if (category == undefined) {
|
||||
return;
|
||||
if (!category) {
|
||||
return category;
|
||||
}
|
||||
|
||||
for (var i = 0; i < category.length; i++) {
|
||||
var result = [];
|
||||
|
||||
for (var i of category) {
|
||||
// Some devices may return the full group name (prefixed with "System Group: ")
|
||||
if (category[i] == "My Contacts" || category[i] == "System Group: My Contacts") {
|
||||
category.splice(i, 1);
|
||||
if (i != "My Contacts" && i != "System Group: My Contacts") {
|
||||
result.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return category;
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkArrayField(array1, array2, func, msg) {
|
||||
if (!!array1 ^ !!array2) {
|
||||
ok(false, "Expected both arrays to be either present or absent");
|
||||
return;
|
||||
}
|
||||
if (!array1 && !array2) {
|
||||
ok(true, msg);
|
||||
return;
|
||||
}
|
||||
ise(array1.length, array2.length, "Same length");
|
||||
for (var i = 0; i < array1.length; ++i) {
|
||||
func(array1[i], array2[i], msg);
|
||||
}
|
||||
}
|
||||
|
||||
function checkContacts(contact1, contact2) {
|
||||
if (!!contact1 ^ !!contact2) {
|
||||
ok(false, "Expected both contacts to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(contact1.name, contact2.name, "Same name");
|
||||
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
|
||||
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
|
||||
@ -271,21 +299,11 @@ function checkContacts(contact1, contact2) {
|
||||
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
|
||||
checkStrArray(contact1.key, contact2.key, "Same key");
|
||||
|
||||
for (var i in contact1.email) {
|
||||
checkField(contact1.email[i], contact2.email[i]);
|
||||
}
|
||||
for (var i in contact1.adr) {
|
||||
checkAddress(contact1.adr[i], contact2.adr[i]);
|
||||
}
|
||||
for (var i in contact1.tel) {
|
||||
checkTel(contact1.tel[i], contact2.tel[i]);
|
||||
}
|
||||
for (var i in contact1.url) {
|
||||
checkField(contact1.url[i], contact2.url[i]);
|
||||
}
|
||||
for (var i in contact1.impp) {
|
||||
checkField(contact1.impp[i], contact2.impp[i]);
|
||||
}
|
||||
checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
|
||||
checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
|
||||
checkArrayField(contact1.email, contact2.email, checkField, "Same email");
|
||||
checkArrayField(contact1.url, contact2.url, checkField, "Same url");
|
||||
checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
|
||||
}
|
||||
|
||||
var req;
|
||||
@ -293,6 +311,10 @@ var index = 0;
|
||||
|
||||
var initialRev;
|
||||
|
||||
var defaultOptions = {
|
||||
sortBy: "givenName",
|
||||
};
|
||||
|
||||
function checkRevision(revision, msg, then) {
|
||||
var revReq = mozContacts.getRevision();
|
||||
revReq.onsuccess = function(e) {
|
||||
@ -319,8 +341,6 @@ function checkCount(count, msg, then) {
|
||||
}
|
||||
|
||||
var mozContacts = window.navigator.mozContacts;
|
||||
ok(mozContacts, "mozContacts exists");
|
||||
ok("mozContact" in window, "mozContact exists");
|
||||
var steps = [
|
||||
function() {
|
||||
req = mozContacts.getRevision();
|
||||
@ -354,7 +374,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({});
|
||||
req = mozContacts.find(defaultOptions);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 0, "Empty database.");
|
||||
checkRevision(1, "Revision was not incremented on find", next);
|
||||
@ -363,8 +383,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding empty contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({});
|
||||
createResult1 = new mozContact({});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -377,7 +396,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({});
|
||||
req = mozContacts.find(defaultOptions);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 1, "One contact.");
|
||||
findResult1 = req.result[0];
|
||||
@ -389,7 +408,7 @@ var steps = [
|
||||
ok(true, "Deleting empty contact");
|
||||
req = navigator.mozContacts.remove(findResult1);
|
||||
req.onsuccess = function () {
|
||||
var req2 = mozContacts.find({});
|
||||
var req2 = mozContacts.find(defaultOptions);
|
||||
req2.onsuccess = function () {
|
||||
is(req2.result.length, 0, "Empty Database.");
|
||||
clearTemps();
|
||||
@ -401,8 +420,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact1");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
|
||||
mozContacts.oncontactchange = function(event) {
|
||||
is(event.contactID, createResult1.id, "Same contactID");
|
||||
@ -487,8 +505,7 @@ var steps = [
|
||||
is(event.contactID, createResult2.id, "Same contactID");
|
||||
is(event.reason, "create", "Same reason");
|
||||
}
|
||||
createResult2 = new mozContact();
|
||||
createResult2.init({name: "newName"});
|
||||
createResult2 = new mozContact({name: ["newName"]});
|
||||
req = navigator.mozContacts.save(createResult2);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult2.id, "The contact now has an ID.");
|
||||
@ -573,8 +590,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact with properties1");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
mozContacts.oncontactchange = null;
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
@ -788,14 +804,16 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({});
|
||||
req = mozContacts.find(defaultOptions);
|
||||
req.onsuccess = function() {
|
||||
is(req.result.length, 1, "Found exactly 1 contact.");
|
||||
findResult1 = req.result[0];
|
||||
ok(findResult1.id == sample_id1, "Same ID");
|
||||
checkContacts(createResult1, findResult1);
|
||||
ok(findResult1.updated, "Has updated field");
|
||||
ok(findResult1.published, "Has published field");
|
||||
if (!isAndroid) {
|
||||
ok(findResult1.updated, "Has updated field");
|
||||
ok(findResult1.published, "Has published field");
|
||||
}
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
@ -808,7 +826,7 @@ var steps = [
|
||||
findResult1.impp = properties1.impp = [{value:"phil impp"}];
|
||||
req = navigator.mozContacts.save(findResult1);
|
||||
req.onsuccess = function () {
|
||||
var req2 = mozContacts.find({});
|
||||
var req2 = mozContacts.find(defaultOptions);
|
||||
req2.onsuccess = function() {
|
||||
is(req2.result.length, 1, "Found exactly 1 contact.");
|
||||
findResult2 = req2.result[0];
|
||||
@ -872,7 +890,7 @@ var steps = [
|
||||
findResult1.impp = properties1.impp = [{value: "phil impp"}];
|
||||
req = mozContacts.save(findResult1);
|
||||
req.onsuccess = function () {
|
||||
var req2 = mozContacts.find({});
|
||||
var req2 = mozContacts.find(defaultOptions);
|
||||
req2.onsuccess = function () {
|
||||
is(req2.result.length, 1, "Found exactly 1 contact.");
|
||||
findResult1 = req2.result[0];
|
||||
@ -937,9 +955,8 @@ var steps = [
|
||||
SpecialPowers.executeSoon(next);
|
||||
} else {
|
||||
findResult1.email = [{value: properties1.nickname}];
|
||||
findResult1.nickname = "TEST";
|
||||
var newContact = new mozContact();
|
||||
newContact.init(findResult1);
|
||||
findResult1.nickname = ["TEST"];
|
||||
var newContact = new mozContact(findResult1);
|
||||
req = mozContacts.save(newContact);
|
||||
req.onsuccess = function () {
|
||||
var options = {filterBy: ["email", "givenName"],
|
||||
@ -961,7 +978,7 @@ var steps = [
|
||||
ok(true, "Deleting contact" + findResult1);
|
||||
req = mozContacts.remove(findResult1);
|
||||
req.onsuccess = function () {
|
||||
var req2 = mozContacts.find({});
|
||||
var req2 = mozContacts.find(defaultOptions);
|
||||
req2.onsuccess = function () {
|
||||
is(req2.result.length, 1, "One contact left.");
|
||||
findResult1 = req2.result[0];
|
||||
@ -982,8 +999,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1)
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -994,8 +1010,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact2");
|
||||
createResult2 = new mozContact();
|
||||
createResult2.init(properties2);
|
||||
createResult2 = new mozContact(properties2);
|
||||
req = mozContacts.save(createResult2);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult2.id, "The contact now has an ID.");
|
||||
@ -1006,10 +1021,10 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({sortBy: 'FamilyName',})
|
||||
req = mozContacts.find({sortBy: "familyName"});
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 2, "Found exactly 2 contact.");
|
||||
checkContacts(properties2, req.result[1]);
|
||||
checkContacts(req.result[1], properties1);
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
@ -1086,16 +1101,14 @@ var steps = [
|
||||
function () {
|
||||
ok(true, "Adding 20 contacts");
|
||||
for (var i=0; i<19; i++) {
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
};
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1106,7 +1119,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving all contacts");
|
||||
req = mozContacts.find({});
|
||||
req = mozContacts.find(defaultOptions);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 20, "20 Entries.");
|
||||
next();
|
||||
@ -1152,11 +1165,10 @@ var steps = [
|
||||
ok(true, "Retrieving all contacts3");
|
||||
var options = {filterBy: ["givenName", "tel", "email"],
|
||||
filterOp: "startsWith",
|
||||
filterValue: properties1.givenName[0].substring(0, 4),
|
||||
filterLimit: 15 };
|
||||
filterValue: properties1.givenName[0].substring(0, 4)};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 15, "15 Entries.");
|
||||
is(req.result.length, 20, "20 Entries.");
|
||||
checkContacts(createResult1, req.result[10]);
|
||||
next();
|
||||
}
|
||||
@ -1173,8 +1185,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Testing clone contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1187,14 +1198,14 @@ var steps = [
|
||||
ok(true, "Testing clone contact2");
|
||||
var cloned = new mozContact(createResult1);
|
||||
ok(cloned.id != createResult1.id, "Cloned contact has new ID");
|
||||
cloned.email = {value: "new email!"};
|
||||
cloned.givenName = "Tom";
|
||||
cloned.email = [{value: "new email!"}];
|
||||
cloned.givenName = ["Tom"];
|
||||
req = mozContacts.save(cloned);
|
||||
req.onsuccess = function () {
|
||||
ok(cloned.id, "The contact now has an ID.");
|
||||
ok(cloned.email[0].value == "new email!", "Same Email");
|
||||
ok(createResult1.email != cloned.email, "Clone has different email");
|
||||
ok(cloned.givenName == "Tom", "New Name");
|
||||
is(cloned.email[0].value, "new email!", "Same Email");
|
||||
isnot(createResult1.email[0].value, cloned.email[0].value, "Clone has different email");
|
||||
is(cloned.givenName, "Tom", "New Name");
|
||||
next();
|
||||
}
|
||||
req.onerror = onFailure;
|
||||
@ -1204,7 +1215,7 @@ var steps = [
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "startsWith",
|
||||
filterValue: properties2.givenName[0].substring(0, 4)};
|
||||
req = mozContacts.find({});
|
||||
req = mozContacts.find(defaultOptions);
|
||||
req.onsuccess = function () {
|
||||
is(req.result.length, 2, "2 Entries.");
|
||||
next();
|
||||
@ -1213,11 +1224,14 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Search with redundant fields should only return 1 contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({name: "XXX", givenName: "XXX", email: [{value: "XXX"}], tel: {value: "XXX"}});
|
||||
createResult1 = new mozContact({name: ["XXX"],
|
||||
givenName: ["XXX"],
|
||||
email: [{value: "XXX"}],
|
||||
tel: [{value: "XXX"}]
|
||||
});
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
var options = {filterBy: [],
|
||||
var options = {filterBy: ["givenName", "familyName"],
|
||||
filterOp: "equals",
|
||||
filterValue: "XXX"};
|
||||
var req2 = mozContacts.find(options);
|
||||
@ -1240,8 +1254,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c3);
|
||||
createResult1 = new mozContact(c3);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1252,8 +1265,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c2);
|
||||
createResult1 = new mozContact(c2);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1264,8 +1276,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c4);
|
||||
createResult1 = new mozContact(c4);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1276,8 +1287,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c1);
|
||||
createResult1 = new mozContact(c1);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1318,8 +1328,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c5);
|
||||
createResult1 = new mozContact(c5);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1346,17 +1355,16 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Don't allow to add custom fields");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({givenName: "customTest", yyy: "XXX"});
|
||||
createResult1 = new mozContact({givenName: ["customTest"], yyy: "XXX"});
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
var options = {filterBy: [],
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "equals",
|
||||
filterValue: "customTest"};
|
||||
var req2 = mozContacts.find(options);
|
||||
req2.onsuccess = function() {
|
||||
is(req2.result.length, 1, "1 Entry");
|
||||
checkStrArray(req2.result.givenName, "customTest", "same name");
|
||||
checkStrArray(req2.result[0].givenName, ["customTest"], "same name");
|
||||
ok(req2.result.yyy === undefined, "custom property undefined");
|
||||
next();
|
||||
}
|
||||
@ -1375,8 +1383,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c7);
|
||||
createResult1 = new mozContact(c7);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1387,8 +1394,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c6);
|
||||
createResult1 = new mozContact(c6);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1399,8 +1405,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Test sorting");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(c8);
|
||||
createResult1 = new mozContact(c8);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1430,7 +1435,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
req = mozContacts.clear()
|
||||
req = mozContacts.clear();
|
||||
req.onsuccess = function () {
|
||||
ok(true, "Deleted the database");
|
||||
next();
|
||||
@ -1439,8 +1444,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact with properties2");
|
||||
createResult2 = new mozContact();
|
||||
createResult2.init(properties2);
|
||||
createResult2 = new mozContact(properties2);
|
||||
req = mozContacts.save(createResult2);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult2.id, "The contact now has an ID.");
|
||||
@ -1485,9 +1489,8 @@ var steps = [
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding empty contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({name: "5", givenName: "5"});
|
||||
ok(true, "Adding contact for category search");
|
||||
createResult1 = new mozContact({name: ["5"], givenName: ["5"]});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1522,20 +1525,10 @@ var steps = [
|
||||
ok(true, "Adding contact with invalid data");
|
||||
var input = document.createElement("input");
|
||||
var obj = {
|
||||
name: [1, 2],
|
||||
familyName: 3,
|
||||
givenName: 4,
|
||||
honorificPrefix: [],
|
||||
honorificSuffix: {foo: "bar"},
|
||||
additionalName: 7,
|
||||
nickname: [8, 9],
|
||||
org: [10, 11],
|
||||
jobTitle: [12, 13],
|
||||
note: 14,
|
||||
category: [15, 16],
|
||||
honorificSuffix: [{foo: "bar"}],
|
||||
sex: 17,
|
||||
genderIdentity: 18,
|
||||
key: 4,
|
||||
email: input,
|
||||
adr: input,
|
||||
tel: input,
|
||||
@ -1553,12 +1546,12 @@ var steps = [
|
||||
}
|
||||
}
|
||||
})());
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(obj);
|
||||
createResult1 = new mozContact(obj);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
checkContacts(createResult1, {
|
||||
honorificPrefix: "string",
|
||||
honorificPrefix: ["string"],
|
||||
honorificSuffix: ["[object Object]"],
|
||||
sex: "17",
|
||||
genderIdentity: "18"
|
||||
});
|
||||
@ -1567,8 +1560,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact with no number but carrier");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({ tel: [{type: ["home"], carrier: "myCarrier"} ] });
|
||||
createResult1 = new mozContact({ tel: [{type: ["home"], carrier: "myCarrier"} ] });
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1578,8 +1570,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact with email but no value");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({ email: [{type: ["home"]}] });
|
||||
createResult1 = new mozContact({ email: [{type: ["home"]}] });
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1589,8 +1580,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Testing numbersOnly search 1");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({ name: ["aaaaaaaaa"], givenName: ["aaaaaaaaa"], tel: [{ value: "1234567890"}]});
|
||||
createResult1 = new mozContact({ name: ["aaaaaaaaa"], givenName: ["aaaaaaaaa"], tel: [{ value: "1234567890"}]});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -1670,17 +1660,10 @@ var steps = [
|
||||
},
|
||||
function() {
|
||||
ok(true, "Test setting array properties to scalar values")
|
||||
const DOMStrings = ["name","honorificPrefix","givenName","additionalName",
|
||||
"familyName", "honorificSuffix","nickname","category",
|
||||
"org","jobTitle","note"];
|
||||
const FIELDS = ["email","url","adr","tel","impp"];
|
||||
createResult1 = new mozContact();
|
||||
for (var prop of DOMStrings) {
|
||||
createResult1[prop] = "foo";
|
||||
ok(Array.isArray(createResult1[prop]), prop + " is array");
|
||||
}
|
||||
for (var prop of FIELDS) {
|
||||
createResult1[prop] = {type: "foo"};
|
||||
createResult1[prop] = {type: ["foo"]};
|
||||
ok(Array.isArray(createResult1[prop]), prop + " is array");
|
||||
}
|
||||
next();
|
||||
|
@ -90,14 +90,14 @@ var randomBlob = getRandomBlob(1024);
|
||||
var randomBlob2 = getRandomBlob(1024);
|
||||
|
||||
var properties1 = {
|
||||
name: "xTestname1",
|
||||
givenName: "xTestname1",
|
||||
name: ["xTestname1"],
|
||||
givenName: ["xTestname1"],
|
||||
photo: [randomBlob]
|
||||
};
|
||||
|
||||
var properties2 = {
|
||||
name: "yTestname2",
|
||||
givenName: "yTestname2",
|
||||
name: ["yTestname2"],
|
||||
givenName: ["yTestname2"],
|
||||
photo: [randomBlob, randomBlob2]
|
||||
};
|
||||
|
||||
@ -177,8 +177,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact with photo");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -191,7 +190,7 @@ var steps = [
|
||||
ok(true, "Retrieving by substring");
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "startsWith",
|
||||
filterValue: properties1.givenName.substring(0,3)};
|
||||
filterValue: properties1.givenName[0].substring(0,3)};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "Found exactly 1 contact.");
|
||||
@ -203,8 +202,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact with 2 photos");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties2);
|
||||
createResult1 = new mozContact(properties2);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -217,7 +215,7 @@ var steps = [
|
||||
ok(true, "Retrieving by substring");
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "startsWith",
|
||||
filterValue: properties2.givenName.substring(0,3)};
|
||||
filterValue: properties2.givenName[0].substring(0,3)};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "Found exactly 1 contact.");
|
||||
@ -227,58 +225,6 @@ var steps = [
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding photo as String");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({givenName: "asdf", photo: ["xyz"]});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
sample_id1 = createResult1.id;
|
||||
is(createResult1.photo, null, "No photo")
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding photo as String");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({givenName: "jkl", photo: "xyz"});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
is(createResult1.photo, null, "No photo")
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Retrieving by substring");
|
||||
var options = {filterBy: ["givenName"],
|
||||
filterOp: "startsWith",
|
||||
filterValue: "asdf"};
|
||||
req = mozContacts.find(options);
|
||||
req.onsuccess = function () {
|
||||
ok(req.result.length == 1, "Found exactly 1 contact.");
|
||||
findResult1 = req.result[0];
|
||||
ok(findResult1.id == sample_id1, "Same ID");
|
||||
is(findResult1.photo, null, "No photo");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding photo as Object");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({photo: [{}]});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
is(createResult1.photo, null, "No photo")
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
},
|
||||
function () {
|
||||
ok(true, "Deleting database");
|
||||
req = mozContacts.clear()
|
||||
|
@ -36,7 +36,7 @@ var androidVersion = SpecialPowers.Cc['@mozilla.org/system-info;1']
|
||||
.getProperty('version');
|
||||
|
||||
let adr1 = {
|
||||
type: "work",
|
||||
type: ["work"],
|
||||
streetAddress: "street 1",
|
||||
locality: "locality 1",
|
||||
region: "region 1",
|
||||
@ -48,9 +48,9 @@ let properties1 = {
|
||||
name: ["Testname1 TestFamilyName"],
|
||||
familyName: ["TestFamilyName","Wagner"],
|
||||
givenName: ["Test1","Test2"],
|
||||
nickname: "nicktest",
|
||||
nickname: ["nicktest"],
|
||||
tel: [{type: ["work"], value: "123456", carrier: "testCarrier"} , {type: ["home", "fax"], value: "+9-876-5432"}],
|
||||
adr: adr1,
|
||||
adr: [adr1],
|
||||
email: [{type: ["work"], value: "x@y.com"}]
|
||||
};
|
||||
|
||||
@ -58,102 +58,137 @@ function onFailure() {
|
||||
ok(false, "in on Failure!");
|
||||
next();
|
||||
}
|
||||
|
||||
function checkStr(str1, str2, msg) {
|
||||
// comparing /[null(,null)+]/ and undefined should pass
|
||||
function nonNull(e) {
|
||||
return e != null;
|
||||
if (str1 ^ str2) {
|
||||
ok(false, "Expected both strings to be either present or absent");
|
||||
return;
|
||||
}
|
||||
if ((Array.isArray(str1) && str1.filter(nonNull).length == 0 && str2 == undefined)
|
||||
||(Array.isArray(str2) && str2.filter(nonNull).length == 0 && str1 == undefined)) {
|
||||
ok(true, msg);
|
||||
} else if (str1) {
|
||||
is(JSON.stringify(typeof str1 == "string" ? [str1] : str1), JSON.stringify(typeof str2 == "string" ? [str2] : str2), msg);
|
||||
is(str1, str2, msg);
|
||||
}
|
||||
|
||||
function checkStrArray(str1, str2, msg) {
|
||||
function normalize_falsy(k, v) {
|
||||
if (!v || v == "null" || v == "undefined") {
|
||||
return "";
|
||||
}
|
||||
return v;
|
||||
}
|
||||
ise(JSON.stringify(str1, normalize_falsy), JSON.stringify(str2, normalize_falsy), msg);
|
||||
}
|
||||
|
||||
function checkPref(pref1, pref2) {
|
||||
// If on Android treat one preference as 0 and the other as undefined as matching
|
||||
if (isAndroid) {
|
||||
if ((!pref1 && pref2 == undefined) || (pref1 == undefined && !pref2)) {
|
||||
pref1 = false;
|
||||
pref2 = false;
|
||||
}
|
||||
}
|
||||
ise(!!pref1, !!pref2, "Same pref");
|
||||
}
|
||||
|
||||
function checkAddress(adr1, adr2) {
|
||||
checkStr(adr1.type, adr2.type, "Same type");
|
||||
checkStr(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
|
||||
checkStr(adr1.locality, adr2.locality, "Same locality");
|
||||
checkStr(adr1.region, adr2.region, "Same region");
|
||||
checkStr(adr1.postalCode, adr2.postalCode, "Same postalCode");
|
||||
checkStr(adr1.countryName, adr2.countryName, "Same countryName");
|
||||
}
|
||||
|
||||
function checkTel(tel1, tel2) {
|
||||
checkStr(tel1.type, tel2.type, "Same type");
|
||||
checkStr(tel1.value, tel2.value, "Same value");
|
||||
checkStr(tel1.carrier, tel2.carrier, "Same carrier");
|
||||
if (adr1 ^ adr2) {
|
||||
ok(false, "Expected both adrs to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(adr1.type, adr2.type, "Same type");
|
||||
checkStrArray(adr1.streetAddress, adr2.streetAddress, "Same streetAddress");
|
||||
checkStrArray(adr1.locality, adr2.locality, "Same locality");
|
||||
checkStrArray(adr1.region, adr2.region, "Same region");
|
||||
checkStrArray(adr1.postalCode, adr2.postalCode, "Same postalCode");
|
||||
checkStrArray(adr1.countryName, adr2.countryName, "Same countryName");
|
||||
checkPref(adr1.pref, adr2.pref);
|
||||
}
|
||||
|
||||
function checkField(field1, field2) {
|
||||
checkStr(field1.type, field2.type, "Same type");
|
||||
checkStr(field1.value, field2.value, "Same value");
|
||||
if (field1 ^ field2) {
|
||||
ok(false, "Expected both fields to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(field1.type, field2.type, "Same type");
|
||||
checkStrArray(field1.value, field2.value, "Same value");
|
||||
checkPref(field1.pref, field2.pref);
|
||||
}
|
||||
|
||||
function checkTel(tel1, tel2) {
|
||||
if (tel1 ^ tel2) {
|
||||
ok(false, "Expected both tels to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkField(tel1, tel2);
|
||||
checkStrArray(tel1.carrier, tel2.carrier, "Same carrier");
|
||||
}
|
||||
|
||||
function checkCategory(category1, category2) {
|
||||
// Android adds contacts to the a default category. This should be removed from the
|
||||
// results before comparing them
|
||||
if (isAndroid) {
|
||||
category1 = removeAndroidDefaultCategory(category1);
|
||||
category2 = removeAndroidDefaultCategory(category2);
|
||||
}
|
||||
checkStrArray(category1, category2, "Same Category")
|
||||
}
|
||||
|
||||
function removeAndroidDefaultCategory(category) {
|
||||
if (!category) {
|
||||
return category;
|
||||
}
|
||||
|
||||
var result = [];
|
||||
|
||||
for (var i of category) {
|
||||
// Some devices may return the full group name (prefixed with "System Group: ")
|
||||
if (i != "My Contacts" && i != "System Group: My Contacts") {
|
||||
result.push(i);
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
function checkArrayField(array1, array2, func, msg) {
|
||||
if (!!array1 ^ !!array2) {
|
||||
ok(false, "Expected both arrays to be either present or absent");
|
||||
return;
|
||||
}
|
||||
if (!array1 && !array2) {
|
||||
ok(true, msg);
|
||||
return;
|
||||
}
|
||||
ise(array1.length, array2.length, "Same length");
|
||||
for (var i = 0; i < array1.length; ++i) {
|
||||
func(array1[i], array2[i], msg);
|
||||
}
|
||||
}
|
||||
|
||||
function checkContacts(contact1, contact2) {
|
||||
checkStr(contact1.name, contact2.name, "Same name");
|
||||
checkStr(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
|
||||
checkStr(contact1.givenName, contact2.givenName, "Same givenName");
|
||||
checkStr(contact1.additionalName, contact2.additionalName, "Same additionalName");
|
||||
checkStr(contact1.familyName, contact2.familyName, "Same familyName");
|
||||
checkStr(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
|
||||
checkStr(contact1.nickname, contact2.nickname, "Same nickname");
|
||||
checkStr(contact1.category, contact2.category, "Same category");
|
||||
checkStr(contact1.org, contact2.org, "Same org");
|
||||
checkStr(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
|
||||
if (!!contact1 ^ !!contact2) {
|
||||
ok(false, "Expected both contacts to be either present or absent");
|
||||
return;
|
||||
}
|
||||
checkStrArray(contact1.name, contact2.name, "Same name");
|
||||
checkStrArray(contact1.honorificPrefix, contact2.honorificPrefix, "Same honorificPrefix");
|
||||
checkStrArray(contact1.givenName, contact2.givenName, "Same givenName");
|
||||
checkStrArray(contact1.additionalName, contact2.additionalName, "Same additionalName");
|
||||
checkStrArray(contact1.familyName, contact2.familyName, "Same familyName");
|
||||
checkStrArray(contact1.honorificSuffix, contact2.honorificSuffix, "Same honorificSuffix");
|
||||
checkStrArray(contact1.nickname, contact2.nickname, "Same nickname");
|
||||
checkCategory(contact1.category, contact2.category);
|
||||
checkStrArray(contact1.org, contact2.org, "Same org");
|
||||
checkStrArray(contact1.jobTitle, contact2.jobTitle, "Same jobTitle");
|
||||
is(contact1.bday ? contact1.bday.valueOf() : null, contact2.bday ? contact2.bday.valueOf() : null, "Same birthday");
|
||||
checkStr(contact1.note, contact2.note, "Same note");
|
||||
checkStrArray(contact1.note, contact2.note, "Same note");
|
||||
is(contact1.anniversary ? contact1.anniversary.valueOf() : null , contact2.anniversary ? contact2.anniversary.valueOf() : null, "Same anniversary");
|
||||
is(contact1.sex, contact2.sex, "Same sex");
|
||||
is(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
|
||||
checkStr(contact1.sex, contact2.sex, "Same sex");
|
||||
checkStr(contact1.genderIdentity, contact2.genderIdentity, "Same genderIdentity");
|
||||
checkStrArray(contact1.key, contact2.key, "Same key");
|
||||
|
||||
for (let i in contact1.email) {
|
||||
if (contact1.email) {
|
||||
ok(contact2.email != null, "conatct2.email exists");
|
||||
}
|
||||
if (contact2.email) {
|
||||
ok(contact1.email != null, "conatct1.email exists");
|
||||
}
|
||||
checkField(contact1.email[i], contact2.email[i]);
|
||||
}
|
||||
for (let i in contact1.adr) {
|
||||
if (contact1.adr) {
|
||||
ok(contact2.adr != null, "conatct2.adr exists");
|
||||
}
|
||||
if (contact2.adr) {
|
||||
ok(contact1.adr != null, "conatct1.adr exists");
|
||||
}
|
||||
checkAddress(contact1.adr[i], contact2.adr[i]);
|
||||
}
|
||||
for (let i in contact1.tel) {
|
||||
if (contact1.tel) {
|
||||
ok(contact2.tel != null, "conatct2.tel exists");
|
||||
}
|
||||
if (contact2.tel) {
|
||||
ok(contact1.tel != null, "conatct1.tel exists");
|
||||
}
|
||||
checkTel(contact1.tel[i], contact2.tel[i]);
|
||||
}
|
||||
for (let i in contact1.url) {
|
||||
if (contact1.url) {
|
||||
ok(contact2.url != null, "conatct2.url exists");
|
||||
}
|
||||
if (contact2.url) {
|
||||
ok(contact1.url != null, "conatct1.url exists");
|
||||
}
|
||||
checkField(contact1.url[i], contact2.url[i]);
|
||||
}
|
||||
for (let i in contact1.impp) {
|
||||
if (contact1.impp) {
|
||||
ok(contact2.impp != null, "conatct2.impp exists");
|
||||
}
|
||||
if (contact2.impp) {
|
||||
ok(contact1.impp != null, "conatct1.impp exists");
|
||||
}
|
||||
checkField(contact1.impp[i], contact2.impp[i]);
|
||||
}
|
||||
checkArrayField(contact1.adr, contact2.adr, checkAddress, "Same adr");
|
||||
checkArrayField(contact1.tel, contact2.tel, checkTel, "Same tel");
|
||||
checkArrayField(contact1.email, contact2.email, checkField, "Same email");
|
||||
checkArrayField(contact1.url, contact2.url, checkField, "Same url");
|
||||
checkArrayField(contact1.impp, contact2.impp, checkField, "Same impp");
|
||||
}
|
||||
|
||||
function clearDatabase() {
|
||||
@ -169,24 +204,22 @@ function clearDatabase() {
|
||||
function addContacts() {
|
||||
ok(true, "Adding 40 contacts");
|
||||
for (let i = 0; i < 39; ++i) {
|
||||
createResult1 = new mozContact();
|
||||
properties1.familyName[0] = "Testname" + (i < 10 ? "0" + i : i);
|
||||
properties1.name = properties1.givenName[0] + " " + properties1.familyName[0];
|
||||
createResult1.init(properties1);
|
||||
properties1.name = [properties1.givenName[0] + " " + properties1.familyName[0]];
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
};
|
||||
createResult1 = new mozContact();
|
||||
properties1.familyName[0] = "Testname39";
|
||||
properties1.name = properties1.givenName[0] + " Testname39";
|
||||
createResult1.init(properties1);
|
||||
properties1.name = [properties1.givenName[0] + " Testname39"];
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
ok(createResult1.name == properties1.name, "Same Name");
|
||||
checkStrArray(createResult1.name, properties1.name, "Same Name");
|
||||
next();
|
||||
};
|
||||
req.onerror = onFailure;
|
||||
@ -202,6 +235,7 @@ function getOne(msg) {
|
||||
return function() {
|
||||
ok(true, msg || "Retrieving one contact with getAll");
|
||||
req = mozContacts.getAll({});
|
||||
|
||||
let count = 0;
|
||||
req.onsuccess = function(event) {
|
||||
ok(true, "on success");
|
||||
@ -246,11 +280,14 @@ function getAll(msg) {
|
||||
}
|
||||
|
||||
let steps = [
|
||||
function start() {
|
||||
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_START");
|
||||
next();
|
||||
},
|
||||
clearDatabase,
|
||||
function() {
|
||||
// add a contact
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init({});
|
||||
createResult1 = new mozContact({});
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function() {
|
||||
next();
|
||||
@ -441,6 +478,7 @@ let steps = [
|
||||
|
||||
function() {
|
||||
ok(true, "all done!\n");
|
||||
SpecialPowers.Cc["@mozilla.org/tools/profiler;1"].getService(SpecialPowers.Ci.nsIProfiler).AddMarker("GETALL_END");
|
||||
SimpleTest.finish();
|
||||
}
|
||||
];
|
||||
|
@ -51,13 +51,13 @@ var number2 = {
|
||||
};
|
||||
|
||||
var properties1 = {
|
||||
name: "Testname1",
|
||||
name: ["Testname1"],
|
||||
tel: [{type: ["work"], value: number1.local, carrier: "testCarrier"} , {type: ["home", "fax"], value: number2.local}],
|
||||
};
|
||||
|
||||
var shortNumber = "888";
|
||||
var properties2 = {
|
||||
name: "Testname2",
|
||||
name: ["Testname2"],
|
||||
tel: [{type: ["work"], value: shortNumber, carrier: "testCarrier"}]
|
||||
};
|
||||
|
||||
@ -67,7 +67,7 @@ var number3 = {
|
||||
};
|
||||
|
||||
var properties3 = {
|
||||
name: "Testname2",
|
||||
name: ["Testname2"],
|
||||
tel: [{value: number3.international2}]
|
||||
};
|
||||
|
||||
@ -91,8 +91,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact1");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties1);
|
||||
createResult1 = new mozContact(properties1);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -103,8 +102,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact2");
|
||||
var createResult2 = new mozContact();
|
||||
createResult2.init(properties2);
|
||||
var createResult2 = new mozContact(properties2);
|
||||
req = navigator.mozContacts.save(createResult2);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult2.id, "The contact now has an ID.");
|
||||
@ -249,8 +247,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding a new contact with country code");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(properties3);
|
||||
createResult1 = new mozContact(properties3);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
|
@ -82,8 +82,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop);
|
||||
createResult1 = new mozContact(prop);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -166,8 +165,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop2);
|
||||
createResult1 = new mozContact(prop2);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -259,8 +257,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop3);
|
||||
createResult1 = new mozContact(prop3);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -289,8 +286,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop4);
|
||||
createResult1 = new mozContact(prop4);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
|
@ -73,8 +73,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop);
|
||||
createResult1 = new mozContact(prop);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
@ -112,8 +111,7 @@ var steps = [
|
||||
},
|
||||
function () {
|
||||
ok(true, "Adding contact");
|
||||
createResult1 = new mozContact();
|
||||
createResult1.init(prop2);
|
||||
createResult1 = new mozContact(prop2);
|
||||
req = navigator.mozContacts.save(createResult1);
|
||||
req.onsuccess = function () {
|
||||
ok(createResult1.id, "The contact now has an ID.");
|
||||
|
@ -497,7 +497,7 @@ interface nsIDOMMozIccManager : nsIDOMEventTarget
|
||||
* PIN2 is only required for 'fdn'.
|
||||
*/
|
||||
nsIDOMDOMRequest updateContact(in DOMString contactType,
|
||||
in nsIDOMContact contact,
|
||||
in nsISupports contact,
|
||||
[optional] in DOMString pin2);
|
||||
|
||||
// End of UICC Phonebook Interfaces.
|
||||
|
@ -72,7 +72,7 @@ interface nsIIccProvider : nsISupports
|
||||
|
||||
nsIDOMDOMRequest updateContact(in nsIDOMWindow window,
|
||||
in DOMString contactType,
|
||||
in nsIDOMContact contact,
|
||||
in nsISupports contact,
|
||||
in DOMString pin2);
|
||||
|
||||
/**
|
||||
|
@ -234,7 +234,7 @@ IccManager::ReadContacts(const nsAString& aContactType, nsIDOMDOMRequest** aRequ
|
||||
|
||||
NS_IMETHODIMP
|
||||
IccManager::UpdateContact(const nsAString& aContactType,
|
||||
nsIDOMContact* aContact,
|
||||
nsISupports* aContact,
|
||||
const nsAString& aPin2,
|
||||
nsIDOMDOMRequest** aRequest)
|
||||
{
|
||||
|
@ -15,19 +15,19 @@ function testReadContacts(type) {
|
||||
|
||||
is(Array.isArray(contacts), true);
|
||||
|
||||
is(contacts[0].name, "Mozilla");
|
||||
is(contacts[0].name[0], "Mozilla");
|
||||
is(contacts[0].tel[0].value, "15555218201");
|
||||
is(contacts[0].id, "890141032111185107201");
|
||||
|
||||
is(contacts[1].name, "Saßê黃");
|
||||
is(contacts[1].name[0], "Saßê黃");
|
||||
is(contacts[1].tel[0].value, "15555218202");
|
||||
is(contacts[1].id, "890141032111185107202");
|
||||
|
||||
is(contacts[2].name, "Fire 火");
|
||||
is(contacts[2].name[0], "Fire 火");
|
||||
is(contacts[2].tel[0].value, "15555218203");
|
||||
is(contacts[2].id, "890141032111185107203");
|
||||
|
||||
is(contacts[3].name, "Huang 黃");
|
||||
is(contacts[3].name[0], "Huang 黃");
|
||||
is(contacts[3].tel[0].value, "15555218204");
|
||||
is(contacts[3].id, "890141032111185107204");
|
||||
|
||||
@ -41,10 +41,8 @@ function testReadContacts(type) {
|
||||
};
|
||||
|
||||
function testAddContact(type, pin2) {
|
||||
let contact = new mozContact();
|
||||
|
||||
contact.init({
|
||||
name: "add",
|
||||
let contact = new mozContact({
|
||||
name: ["add"],
|
||||
tel: [{value: "0912345678"}],
|
||||
email:[]
|
||||
});
|
||||
@ -62,7 +60,7 @@ function testAddContact(type, pin2) {
|
||||
// There are 4 SIM contacts which are harded in emulator
|
||||
is(contacts.length, 5);
|
||||
|
||||
is(contacts[4].name, "add");
|
||||
is(contacts[4].name[0], "add");
|
||||
is(contacts[4].tel[0].value, "0912345678");
|
||||
|
||||
runNextTest();
|
||||
|
@ -1,15 +0,0 @@
|
||||
# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
|
||||
# vim: set filetype=python:
|
||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
|
||||
XPIDL_SOURCES += [
|
||||
'nsIContactProperties.idl',
|
||||
'nsIDOMContactManager.idl',
|
||||
]
|
||||
|
||||
XPIDL_MODULE = 'dom_contacts'
|
||||
|
||||
MODULE = 'dom'
|
||||
|
@ -1,74 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
|
||||
[scriptable, uuid(9cbfa81c-bcab-4ca9-b0d2-f4318f295e33)]
|
||||
interface nsIContactAddress : nsISupports
|
||||
{
|
||||
attribute DOMString type;
|
||||
attribute boolean pref; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
|
||||
attribute DOMString streetAddress;
|
||||
attribute DOMString locality;
|
||||
attribute DOMString region;
|
||||
attribute DOMString postalCode;
|
||||
attribute DOMString countryName;
|
||||
};
|
||||
|
||||
[scriptable, uuid(ad19a543-69e4-44f0-adfa-37c011556bc1)]
|
||||
interface nsIContactField : nsISupports
|
||||
{
|
||||
attribute jsval type; // DOMString[], "home", "work", etc.
|
||||
attribute DOMString value;
|
||||
attribute boolean pref; // false = no pref, true = preferred (vCard3 TYPE:PREF; vCard4 PREF:1)
|
||||
};
|
||||
|
||||
[scriptable, uuid(4d42c5a9-ea5d-4102-80c3-40cc986367ca)]
|
||||
interface nsIContactTelField : nsIContactField
|
||||
{
|
||||
attribute DOMString carrier;
|
||||
};
|
||||
|
||||
[scriptable, uuid(0a5b1fab-70da-46dd-b902-619904d920c2)]
|
||||
interface nsIContactFindSortOptions : nsISupports
|
||||
{
|
||||
attribute DOMString sortBy; // "givenName" or "familyName"
|
||||
attribute DOMString sortOrder; // e.g. "descending"
|
||||
};
|
||||
|
||||
[scriptable, uuid(28ce07d0-45d9-4b7a-8843-521df4edd8bc)]
|
||||
interface nsIContactFindOptions : nsIContactFindSortOptions
|
||||
{
|
||||
attribute DOMString filterValue; // e.g. "Tom"
|
||||
attribute DOMString filterOp; // e.g. "startsWith"
|
||||
attribute jsval filterBy; // DOMString[], e.g. ["givenName", "nickname"]
|
||||
attribute unsigned long filterLimit;
|
||||
};
|
||||
|
||||
[scriptable, uuid(35ad8a4e-9486-44b6-883d-550f14635e49)]
|
||||
interface nsIContactProperties : nsISupports
|
||||
{
|
||||
attribute jsval name; // DOMString[]
|
||||
attribute jsval honorificPrefix; // DOMString[]
|
||||
attribute jsval givenName; // DOMString[]
|
||||
attribute jsval additionalName; // DOMString[]
|
||||
attribute jsval familyName; // DOMString[]
|
||||
attribute jsval honorificSuffix; // DOMString[]
|
||||
attribute jsval nickname; // DOMString[]
|
||||
attribute jsval email; // ContactField[]
|
||||
attribute jsval photo; // nsIDOMBlob[]
|
||||
attribute jsval url; // ContactField[]
|
||||
attribute jsval category; // DOMString[]
|
||||
attribute jsval adr; // ContactAddress[]
|
||||
attribute jsval tel; // ContactTelField[]
|
||||
attribute jsval org; // DOMString[]
|
||||
attribute jsval jobTitle; // DOMString[]
|
||||
attribute jsval bday; // Date
|
||||
attribute jsval note; // DOMString[]
|
||||
attribute jsval impp; // ContactField[]
|
||||
attribute jsval anniversary; // Date
|
||||
attribute DOMString sex; // DOMString
|
||||
attribute DOMString genderIdentity; // DOMString
|
||||
attribute jsval key; // DOMString[]
|
||||
};
|
@ -1,41 +0,0 @@
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "domstubs.idl"
|
||||
#include "nsIContactProperties.idl"
|
||||
#include "nsIDOMEventTarget.idl"
|
||||
|
||||
interface nsIArray;
|
||||
interface nsIDOMDOMRequest;
|
||||
interface nsIDOMDOMCursor;
|
||||
|
||||
[scriptable, uuid(72a5ee28-81d8-4af8-90b3-ae935396cc66)]
|
||||
interface nsIDOMContact : nsIContactProperties
|
||||
{
|
||||
attribute DOMString id;
|
||||
readonly attribute jsval published;
|
||||
readonly attribute jsval updated;
|
||||
|
||||
void init(in nsIContactProperties properties); // Workaround BUG 723206
|
||||
};
|
||||
|
||||
[scriptable, uuid(8beb3a66-d70a-4111-b216-b8e995ad3aff)]
|
||||
interface nsIDOMContactManager : nsISupports
|
||||
{
|
||||
nsIDOMDOMRequest find(in nsIContactFindOptions options);
|
||||
|
||||
nsIDOMDOMCursor getAll(in nsIContactFindSortOptions options);
|
||||
|
||||
nsIDOMDOMRequest clear();
|
||||
|
||||
nsIDOMDOMRequest save(in nsIDOMContact contact);
|
||||
|
||||
nsIDOMDOMRequest remove(in nsIDOMContact contact);
|
||||
|
||||
attribute nsIDOMEventListener oncontactchange;
|
||||
|
||||
nsIDOMDOMRequest getRevision();
|
||||
|
||||
nsIDOMDOMRequest getCount();
|
||||
};
|
@ -7,7 +7,6 @@
|
||||
interfaces = [
|
||||
'base',
|
||||
'canvas',
|
||||
'contacts',
|
||||
'core',
|
||||
'html',
|
||||
'events',
|
||||
|
@ -1720,7 +1720,6 @@ RILContentHelper.prototype = {
|
||||
delete this._windowsMap[message.requestId];
|
||||
let contacts = message.contacts;
|
||||
let result = contacts.map(function(c) {
|
||||
let contact = Cc["@mozilla.org/contact;1"].createInstance(Ci.nsIDOMContact);
|
||||
let prop = {name: [c.alphaId], tel: [{value: c.number}]};
|
||||
|
||||
if (c.email) {
|
||||
@ -1733,7 +1732,7 @@ RILContentHelper.prototype = {
|
||||
prop.tel.push({value: c.anr[i]});
|
||||
}
|
||||
|
||||
contact.init(prop);
|
||||
let contact = new window.mozContact(prop);
|
||||
contact.id = message.iccid + c.recordId;
|
||||
return contact;
|
||||
});
|
||||
|
170
dom/webidl/Contacts.webidl
Normal file
170
dom/webidl/Contacts.webidl
Normal file
@ -0,0 +1,170 @@
|
||||
/* -*- Mode: IDL; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
|
||||
* You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||
*/
|
||||
|
||||
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactAddress;1"]
|
||||
interface ContactAddress {
|
||||
attribute object? type; // DOMString[]
|
||||
attribute DOMString? streetAddress;
|
||||
attribute DOMString? locality;
|
||||
attribute DOMString? region;
|
||||
attribute DOMString? postalCode;
|
||||
attribute DOMString? countryName;
|
||||
attribute boolean? pref;
|
||||
|
||||
[ChromeOnly]
|
||||
void initialize(optional sequence<DOMString>? type,
|
||||
optional DOMString streetAddress,
|
||||
optional DOMString locality,
|
||||
optional DOMString region,
|
||||
optional DOMString postalCode,
|
||||
optional DOMString countryName,
|
||||
optional boolean pref);
|
||||
};
|
||||
|
||||
dictionary ContactAddressInit {
|
||||
sequence<DOMString>? type;
|
||||
DOMString? streetAddress;
|
||||
DOMString? locality;
|
||||
DOMString? region;
|
||||
DOMString? postalCode;
|
||||
DOMString? countryName;
|
||||
boolean? pref;
|
||||
};
|
||||
|
||||
|
||||
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactField;1"]
|
||||
interface ContactField {
|
||||
attribute object? type; // DOMString[]
|
||||
attribute DOMString? value;
|
||||
attribute boolean? pref;
|
||||
|
||||
[ChromeOnly]
|
||||
void initialize(optional sequence<DOMString>? type,
|
||||
optional DOMString value,
|
||||
optional boolean pref);
|
||||
};
|
||||
|
||||
dictionary ContactFieldInit {
|
||||
sequence<DOMString>? type;
|
||||
DOMString? value;
|
||||
boolean? pref;
|
||||
};
|
||||
|
||||
|
||||
[ChromeOnly, Constructor, JSImplementation="@mozilla.org/contactTelField;1"]
|
||||
interface ContactTelField : ContactField {
|
||||
attribute DOMString? carrier;
|
||||
|
||||
[ChromeOnly]
|
||||
void initialize(optional sequence<DOMString>? type,
|
||||
optional DOMString value,
|
||||
optional DOMString? carrier,
|
||||
optional boolean pref);
|
||||
};
|
||||
|
||||
dictionary ContactTelFieldInit : ContactFieldInit {
|
||||
DOMString? carrier;
|
||||
};
|
||||
|
||||
|
||||
dictionary ContactProperties {
|
||||
Date? bday;
|
||||
Date? anniversary;
|
||||
|
||||
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;
|
||||
};
|
||||
|
||||
[Constructor(optional ContactProperties properties),
|
||||
JSImplementation="@mozilla.org/contact;1"]
|
||||
interface mozContact {
|
||||
attribute DOMString id;
|
||||
readonly attribute Date? published;
|
||||
readonly attribute Date? updated;
|
||||
|
||||
attribute Date? bday;
|
||||
attribute Date? anniversary;
|
||||
|
||||
attribute DOMString? sex;
|
||||
attribute DOMString? genderIdentity;
|
||||
|
||||
attribute object? photo;
|
||||
|
||||
attribute object? adr;
|
||||
|
||||
attribute object? email;
|
||||
attribute object? url;
|
||||
attribute object? impp;
|
||||
|
||||
attribute object? tel;
|
||||
|
||||
attribute object? name;
|
||||
attribute object? honorificPrefix;
|
||||
attribute object? givenName;
|
||||
attribute object? additionalName;
|
||||
attribute object? familyName;
|
||||
attribute object? honorificSuffix;
|
||||
attribute object? nickname;
|
||||
attribute object? category;
|
||||
attribute object? org;
|
||||
attribute object? jobTitle;
|
||||
attribute object? note;
|
||||
attribute object? key;
|
||||
|
||||
[ChromeOnly]
|
||||
void setMetadata(DOMString id, optional Date published, optional Date updated);
|
||||
|
||||
jsonifier;
|
||||
};
|
||||
|
||||
dictionary ContactFindSortOptions {
|
||||
DOMString sortBy; // "givenName" or "familyName"
|
||||
DOMString sortOrder = "ascending"; // e.g. "descending"
|
||||
};
|
||||
|
||||
dictionary ContactFindOptions : ContactFindSortOptions {
|
||||
DOMString filterValue; // e.g. "Tom"
|
||||
DOMString filterOp; // e.g. "startsWith"
|
||||
any filterBy; // e.g. ["givenName", "nickname"]
|
||||
unsigned long filterLimit;
|
||||
};
|
||||
|
||||
[NoInterfaceObject, NavigatorProperty="mozContacts",
|
||||
JSImplementation="@mozilla.org/contactManager;1"]
|
||||
interface ContactManager : EventTarget {
|
||||
DOMRequest find(optional ContactFindOptions options);
|
||||
DOMCursor getAll(optional ContactFindSortOptions options);
|
||||
DOMRequest clear();
|
||||
DOMRequest save(mozContact contact);
|
||||
DOMRequest remove(mozContact contact);
|
||||
DOMRequest getRevision();
|
||||
DOMRequest getCount();
|
||||
|
||||
attribute EventHandler oncontactchange;
|
||||
};
|
@ -59,6 +59,7 @@ WEBIDL_FILES = [
|
||||
'CommandEvent.webidl',
|
||||
'Comment.webidl',
|
||||
'CompositionEvent.webidl',
|
||||
'Contacts.webidl',
|
||||
'ConvolverNode.webidl',
|
||||
'Coordinates.webidl',
|
||||
'DOMCursor.webidl',
|
||||
|
@ -135,7 +135,6 @@
|
||||
@BINPATH@/components/dom_camera.xpt
|
||||
@BINPATH@/components/dom_canvas.xpt
|
||||
@BINPATH@/components/dom_core.xpt
|
||||
@BINPATH@/components/dom_contacts.xpt
|
||||
@BINPATH@/components/dom_css.xpt
|
||||
@BINPATH@/components/dom_devicestorage.xpt
|
||||
@BINPATH@/components/dom_events.xpt
|
||||
|
Loading…
Reference in New Issue
Block a user