author | Gregor Wagner <anygregor@gmail.com> |
Mon, 02 Apr 2012 16:39:57 -0700 | |
changeset 90877 | 3ad6cc527d5c7f293d1a9978998d46ff751eeb5a |
parent 90876 | 9cc500d2e6c8196edddcee609a7de4fc519ccac4 |
child 90878 | b1a9e8a536bfdd7857d6e3648efa8768ca7fb7dc |
push id | 22394 |
push user | Ms2ger@gmail.com |
push date | Tue, 03 Apr 2012 07:22:53 +0000 |
treeherder | mozilla-central@9894cd999781 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | bent |
bugs | 734198 |
milestone | 14.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/dom/contacts/ContactManager.js +++ b/dom/contacts/ContactManager.js @@ -14,17 +14,17 @@ else const Cc = Components.classes; const Ci = Components.interfaces; const Cu = Components.utils; Cu.import("resource://gre/modules/XPCOMUtils.jsm"); Cu.import("resource://gre/modules/Services.jsm"); Cu.import("resource://gre/modules/DOMRequestHelper.jsm"); -XPCOMUtils.defineLazyGetter(Services, "rs", function() { +XPCOMUtils.defineLazyGetter(Services, "DOMRequest", function() { return Cc["@mozilla.org/dom/dom-request-service;1"].getService(Ci.nsIDOMRequestService); }); XPCOMUtils.defineLazyGetter(this, "cpmm", function() { return Cc["@mozilla.org/childprocessmessagemanager;1"].getService(Ci.nsIFrameMessageManager); }); const nsIClassInfo = Ci.nsIClassInfo; @@ -74,26 +74,17 @@ ContactAddress.prototype = { } //ContactFindOptions const CONTACTFINDOPTIONS_CONTRACTID = "@mozilla.org/contactFindOptions;1"; const CONTACTFINDOPTIONS_CID = Components.ID("{e31daea0-0cb6-11e1-be50-0800200c9a66}"); const nsIDOMContactFindOptions = Components.interfaces.nsIDOMContactFindOptions; -function ContactFindOptions(aFilterValue, aFilterBy, aFilterOp, aFilterLimit) { - this.filterValue = aFilterValue || ''; - - this.filterBy = new Array(); - for (let field in aFilterBy) - this.filterBy.push(field); - - this.filterOp = aFilterOp || ''; - this.filterLimit = aFilterLimit || 0; -}; +function ContactFindOptions() { }; ContactFindOptions.prototype = { classID : CONTACTFINDOPTIONS_CID, classInfo : XPCOMUtils.generateCI({classID: CONTACTFINDOPTIONS_CID, contractID: CONTACTFINDOPTIONS_CONTRACTID, classDescription: "ContactFindOptions", interfaces: [nsIDOMContactFindOptions], @@ -277,35 +268,35 @@ ContactManager.prototype = { let contacts = msg.contacts; switch (aMessage.name) { case "Contacts:Find:Return:OK": let req = this.getRequest(msg.requestID); if (req) { let result = this._convertContactsArray(contacts); debug("result: " + JSON.stringify(result)); - Services.rs.fireSuccess(req, result); + Services.DOMRequest.fireSuccess(req, result); } else { debug("no request stored!" + msg.requestID); } break; case "Contact:Save:Return:OK": case "Contacts:Clear:Return:OK": case "Contact:Remove:Return:OK": req = this.getRequest(msg.requestID); if (req) - Services.rs.fireSuccess(req, null); + Services.DOMRequest.fireSuccess(req, null); break; case "Contacts:Find:Return:KO": case "Contact:Save:Return:KO": case "Contact:Remove:Return:KO": case "Contacts:Clear:Return:KO": req = this.getRequest(msg.requestID); if (req) - Services.rs.fireError(req, msg.errorMsg); + Services.DOMRequest.fireError(req, msg.errorMsg); break; default: debug("Wrong message: " + aMessage.name); } this.removeRequest(msg.requestID); }, find: function(aOptions) {
--- a/dom/contacts/fallback/ContactDB.jsm +++ b/dom/contacts/fallback/ContactDB.jsm @@ -372,49 +372,53 @@ ContactDB.prototype = { // lookup for all keys if (options.filterBy.length == 0) { debug("search in all fields!" + JSON.stringify(store.indexNames)); for(let myIndex = 0; myIndex < store.indexNames.length; myIndex++) { fields = Array.concat(fields, store.indexNames[myIndex]) } } + // Sorting functions takes care of limit if set. + let limit = options.sortBy === 'undefined' ? options.filterLimit : null; + let filter_keys = fields.slice(); for (let key = filter_keys.shift(); key; key = filter_keys.shift()) { let request; if (key == "id") { // store.get would return an object and not an array request = store.getAll(options.filterValue); } else if (options.filterOp == "equals") { debug("Getting index: " + key); // case sensitive let index = store.index(key); - request = index.getAll(options.filterValue, options.filterLimit); + request = index.getAll(options.filterValue, limit); } else { // not case sensitive let tmp = options.filterValue.toLowerCase(); let range = this._global.IDBKeyRange.bound(tmp, tmp + "\uFFFF"); let index = store.index(key + "LowerCase"); - request = index.getAll(range, options.filterLimit); + request = index.getAll(range, limit); } if (!txn.result) txn.result = {}; request.onsuccess = function (event) { debug("Request successful. Record count:" + event.target.result.length); for (let i in event.target.result) txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]); }.bind(this); } }, _findAll: function _findAll(txn, store, options) { debug("ContactDB:_findAll: " + JSON.stringify(options)); if (!txn.result) txn.result = {}; - - store.getAll(null, options.filterLimit).onsuccess = function (event) { + // Sorting functions takes care of limit if set. + let limit = options.sortBy === 'undefined' ? options.filterLimit : null; + store.getAll(null, limit).onsuccess = function (event) { debug("Request successful. Record count:", event.target.result.length); for (let i in event.target.result) txn.result[event.target.result[i].id] = this.makeExport(event.target.result[i]); }.bind(this); } };
--- a/dom/contacts/fallback/ContactService.jsm +++ b/dom/contacts/fallback/ContactService.jsm @@ -59,25 +59,42 @@ let DOMContactManager = { Services.obs.removeObserver(this, "profile-before-change"); ppmm = null; this._messages = null; if (this._db) this._db.close(); }, receiveMessage: function(aMessage) { + function sortfunction(a, b){ + let x, y; + if (a.properties[msg.findOptions.sortBy]) + x = a.properties[msg.findOptions.sortBy][0].toLowerCase(); + if (b.properties[msg.findOptions.sortBy]) + y = b.properties[msg.findOptions.sortBy][0].toLowerCase(); + if (msg.findOptions == 'ascending') + return ((x < y) ? -1 : ((x > y) ? 1 : 0)); + return ((x < y) ? 1 : ((x > y) ? -1 : 0)); + } debug("Fallback DOMContactManager::receiveMessage " + aMessage.name); let msg = aMessage.json; switch (aMessage.name) { case "Contacts:Find": let result = new Array(); this._db.find( function(contacts) { for (let i in contacts) result.push(contacts[i]); + if (msg.findOptions.sortOrder !== 'undefined' && msg.findOptions.sortBy !== 'undefined') { + debug('sortBy: ' + msg.findOptions.sortBy + ', sortOrder: ' + msg.findOptions.sortOrder ); + result.sort(sortfunction); + if (msg.findOptions.filterLimit) + result = result.slice(0, msg.findOptions.filterLimit); + } + debug("result:" + JSON.stringify(result)); ppmm.sendAsyncMessage("Contacts:Find:Return:OK", {requestID: msg.requestID, contacts: result}); }.bind(this), function(aErrorMsg) { ppmm.sendAsyncMessage("Contacts:Find:Return:KO", { requestID: msg.requestID, errorMsg: aErrorMsg }) }.bind(this), msg.findOptions); break; case "Contact:Save": this._db.saveContact(msg.contact, function() { ppmm.sendAsyncMessage("Contact:Save:Return:OK", { requestID: msg.requestID }); }.bind(this),
--- a/dom/contacts/tests/test_contacts_basics.html +++ b/dom/contacts/tests/test_contacts_basics.html @@ -23,16 +23,45 @@ https://bugzilla.mozilla.org/show_bug.cg netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect"); Components.classes["@mozilla.org/permissionmanager;1"] .getService(Components.interfaces.nsIPermissionManager) .add(SpecialPowers.getDocumentURIObject(window.document), "webcontacts-manage", Components.interfaces.nsIPermissionManager.ALLOW_ACTION); +// For Sorting +var c1 = { + name: "a", + familyName: ["a"], + givenName: ["a"], +}; + +var c2 = { + name: "b", + familyName: ["b"], + givenName: ["b"], +}; + +var c3 = { + name: "c", + familyName: ["c","x"], + givenName: ["c","x"], +}; + +var c4 = { + name: "d", + familyName: ["d","e"], + givenName: ["d","e"], +}; + +var c5 = { + name: "empty" +}; + var adr1 = { streetAddress: "street 1", locality: "locality 1", region: "region 1", postalCode: "postal code 1", countryName: "country 1" }; @@ -636,16 +665,28 @@ var steps = [ req = mozContacts.find(options); req.onsuccess = function () { ok(req.result.length == 10, "10 Entries."); next(); } req.onerror = onFailure; }, function () { + ok(true, "Retrieving all contacts with limit 10 and sorted"); + var options = { filterLimit: 10, + sortBy: 'FamilyName', + sortOrder: 'descending' }; + req = mozContacts.find(options); + req.onsuccess = function () { + ok(req.result.length == 10, "10 Entries."); + next(); + } + req.onerror = onFailure; + }, + function () { ok(true, "Retrieving all contacts2"); var options = {filterBy: ["name"], filterOp: "contains", filterValue: properties1.name[0].substring(0, 4)}; req = mozContacts.find(options); req.onsuccess = function () { ok(req.result.length == 100, "100 Entries."); checkContacts(createResult1, req.result[99]); @@ -739,16 +780,131 @@ var steps = [ req = mozContacts.clear() req.onsuccess = function () { ok(true, "Deleted the database"); next(); } req.onerror = onFailure; }, function () { + ok(true, "Test sorting"); + createResult1 = new mozContact(); + createResult1.init(c3); + req = navigator.mozContacts.save(createResult1); + req.onsuccess = function () { + ok(createResult1.id, "The contact now has an ID."); + checkContacts(c3, createResult1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + createResult1 = new mozContact(); + createResult1.init(c2); + req = navigator.mozContacts.save(createResult1); + req.onsuccess = function () { + ok(createResult1.id, "The contact now has an ID."); + checkContacts(c2, createResult1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + createResult1 = new mozContact(); + createResult1.init(c4); + req = navigator.mozContacts.save(createResult1); + req.onsuccess = function () { + ok(createResult1.id, "The contact now has an ID."); + checkContacts(c4, createResult1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + createResult1 = new mozContact(); + createResult1.init(c1); + req = navigator.mozContacts.save(createResult1); + req.onsuccess = function () { + ok(createResult1.id, "The contact now has an ID."); + checkContacts(c1, createResult1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + var options = {sortBy: "familyName", + sortOrder: "ascending"}; + req = navigator.mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 4, "4 results"); + checkContacts(req.result[0], c1); + checkContacts(req.result[1], c2); + checkContacts(req.result[2], c3); + checkContacts(req.result[3], c4); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + var options = {sortBy: "familyName", + sortOrder: "descending"}; + req = navigator.mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 4, "4 results"); + checkContacts(req.result[0], c4); + checkContacts(req.result[1], c3); + checkContacts(req.result[2], c2); + checkContacts(req.result[3], c1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting"); + createResult1 = new mozContact(); + createResult1.init(c5); + req = navigator.mozContacts.save(createResult1); + req.onsuccess = function () { + ok(createResult1.id, "The contact now has an ID."); + checkContacts(c5, createResult1); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Test sorting with empty string"); + var options = {sortBy: "familyName", + sortOrder: "ascending"}; + req = navigator.mozContacts.find(options); + req.onsuccess = function () { + is(req.result.length, 5, "5 results"); + checkContacts(req.result[0], c5); + checkContacts(req.result[1], c1); + checkContacts(req.result[2], c2); + checkContacts(req.result[3], c3); + checkContacts(req.result[4], c4); + next(); + }; + req.onerror = onFailure; + }, + function () { + ok(true, "Deleting database"); + req = mozContacts.clear() + req.onsuccess = function () { + ok(true, "Deleted the database"); + next(); + } + req.onerror = onFailure; + }, + function () { ok(true, "all done!\n"); clearTemps(); SimpleTest.finish(); } ]; function next() {
--- a/dom/interfaces/contacts/nsIDOMContactProperties.idl +++ b/dom/interfaces/contacts/nsIDOMContactProperties.idl @@ -18,16 +18,18 @@ interface nsIDOMContactAddress : nsISupp }; [scriptable, uuid(e31daea0-0cb6-11e1-be50-0800200c9a66)] interface nsIDOMContactFindOptions : nsISupports { attribute DOMString filterValue; // e.g. "Tom" attribute DOMString filterOp; // e.g. "contains" attribute jsval filterBy; // DOMString[], e.g. ["givenName", "nickname"] + attribute DOMString sortBy; // e.g. "givenName" + attribute DOMString sortOrder; // e.g. "descending" attribute unsigned long filterLimit; }; [scriptable, uuid(53ed7c20-ceda-11e0-9572-0800200c9a66)] interface nsIDOMContactProperties : nsISupports { attribute jsval name; // DOMString[] attribute jsval honorificPrefix; // DOMString[]