Bug 1439900 - Move unifinder related functions to calUnifinderUtils.jsm. r=MakeMyDay
MozReview-Commit-ID: Hi53o8AJlv2
This commit is contained in:
Родитель
f36f2d3e07
Коммит
fa37452098
|
@ -485,6 +485,7 @@ module.exports = {
|
|||
files: [
|
||||
"base/modules/calEmailUtils.jsm",
|
||||
"base/modules/calItipUtils.jsm",
|
||||
"base/modules/calUnifinderUtils.jsm",
|
||||
],
|
||||
rules: {
|
||||
"require-jsdoc": [2, { require: { ClassDeclaration: true } }],
|
||||
|
|
|
@ -989,18 +989,11 @@
|
|||
<method name="sortItems">
|
||||
<body><![CDATA[
|
||||
if (this.mTreeView.selectedColumn) {
|
||||
let modifier = (this.mTreeView.sortDirection == "descending" ? -1 : 1);
|
||||
let column = this.mTreeView.selectedColumn;
|
||||
cal.sortEntry.mSortKey = column.getAttribute("sortKey")
|
||||
? column.getAttribute("sortKey")
|
||||
: column.getAttribute("itemproperty");
|
||||
let sortType = cal.getSortTypeForSortKey(cal.sortEntry.mSortKey);
|
||||
let modifier = this.mTreeView.sortDirection == "descending" ? -1 : 1;
|
||||
let sortKey = column.getAttribute("sortKey") || column.getAttribute("itemproperty");
|
||||
|
||||
// sort (key,item) entries
|
||||
cal.sortEntry.mSortStartedDate = cal.dtz.now();
|
||||
let entries = this.mTaskArray.map(cal.sortEntry, cal.sortEntry);
|
||||
entries.sort(cal.sortEntryComparer(sortType, modifier));
|
||||
this.mTaskArray = entries.map(cal.sortEntryItem);
|
||||
cal.unifinder.sortItems(this.mTaskArray, sortKey, modifier);
|
||||
}
|
||||
|
||||
this.recreateHashTable();
|
||||
|
|
|
@ -549,13 +549,8 @@ var unifinderTreeView = {
|
|||
if (this.selectedColumn) {
|
||||
let modifier = (this.sortDirection == "descending" ? -1 : 1);
|
||||
let sortKey = unifinderTreeView.selectedColumn.getAttribute("itemproperty");
|
||||
let sortType = cal.getSortTypeForSortKey(sortKey);
|
||||
// sort (key,item) entries
|
||||
cal.sortEntry.mSortKey = sortKey;
|
||||
cal.sortEntry.mSortStartedDate = cal.dtz.now();
|
||||
let entries = this.eventArray.map(cal.sortEntry, cal.sortEntry);
|
||||
entries.sort(cal.sortEntryComparer(sortType, modifier));
|
||||
this.eventArray = entries.map(cal.sortEntryItem);
|
||||
|
||||
cal.unifinder.sortItems(this.eventArray, sortKey, modifier);
|
||||
}
|
||||
this.calculateIndexMap();
|
||||
},
|
||||
|
|
|
@ -0,0 +1,206 @@
|
|||
/* 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/. */
|
||||
|
||||
ChromeUtils.import("resource:///modules/mailServices.js");
|
||||
ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");
|
||||
|
||||
XPCOMUtils.defineLazyModuleGetter(this, "cal", "resource://calendar/modules/calUtils.jsm", "cal");
|
||||
|
||||
this.EXPORTED_SYMBOLS = ["calunifinder"]; /* exported calunifinder */
|
||||
|
||||
var calunifinder = {
|
||||
/**
|
||||
* Retrieves the value that is used for comparison for the item with the given
|
||||
* property.
|
||||
*
|
||||
* @param {calIItemBaes} aItem The item to retrieve the sort key for
|
||||
* @param {String} aKey The property name that should be sorted
|
||||
* @return {*} The value used in sort comparison
|
||||
*/
|
||||
getItemSortKey: function(aItem, aKey) {
|
||||
const taskStatus = ["NEEDS-ACTION", "IN-PROCESS", "COMPLETED", "CANCELLED"];
|
||||
const eventStatus = ["TENTATIVE", "CONFIRMED", "CANCELLED"];
|
||||
|
||||
switch (aKey) {
|
||||
case "priority":
|
||||
return aItem.priority || 5;
|
||||
|
||||
case "title":
|
||||
return aItem.title || "";
|
||||
|
||||
case "entryDate":
|
||||
case "startDate":
|
||||
case "dueDate":
|
||||
case "endDate":
|
||||
case "completedDate":
|
||||
if (aItem[aKey] == null) {
|
||||
return -62168601600000000; // ns value for (0000/00/00 00:00:00)
|
||||
}
|
||||
return aItem[aKey].nativeTime;
|
||||
|
||||
case "percentComplete":
|
||||
return aItem.percentComplete;
|
||||
|
||||
case "categories":
|
||||
return aItem.getCategories({}).join(", ");
|
||||
|
||||
case "location":
|
||||
return aItem.getProperty("LOCATION") || "";
|
||||
|
||||
case "status": {
|
||||
let statusSet = cal.item.isEvent(aItem) ? eventStatus : taskStatus;
|
||||
return statusSet.indexOf(aItem.status);
|
||||
}
|
||||
case "calendar":
|
||||
return aItem.calendar.name || "";
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Returns a sort function for the given sort type.
|
||||
*
|
||||
* @param {String} aSortKey The sort key to get the compare function for
|
||||
* @return {Function} The function to be used for sorting values of the type
|
||||
*/
|
||||
sortEntryComparer: function(aSortKey) {
|
||||
switch (aSortKey) {
|
||||
case "title":
|
||||
case "categories":
|
||||
case "location":
|
||||
case "calendar":
|
||||
return sortCompare.string;
|
||||
|
||||
// All dates use "date_filled"
|
||||
case "completedDate":
|
||||
case "startDate":
|
||||
case "endDate":
|
||||
case "dueDate":
|
||||
case "entryDate":
|
||||
return sortCompare.date_filled;
|
||||
|
||||
case "priority":
|
||||
case "percentComplete":
|
||||
case "status":
|
||||
return sortCompare.number;
|
||||
default:
|
||||
return sortCompare.unknown;
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort the unifinder items by the given sort key, using the modifier to flip direction. The
|
||||
* items are sorted in place.
|
||||
*
|
||||
* @param {calIItemBase[]} aItems The items to sort
|
||||
* @param {String} aSortKey The item sort key
|
||||
* @param {?Number} aModifier Either 1 or -1, to indicate sort direction
|
||||
*/
|
||||
sortItems: function(aItems, aSortKey, aModifier=1) {
|
||||
let comparer = calunifinder.sortEntryComparer(aSortKey);
|
||||
aItems.sort((a, b) => {
|
||||
let sortvalA = calunifinder.getItemSortKey(a, aSortKey);
|
||||
let sortvalB = calunifinder.getItemSortKey(b, aSortKey);
|
||||
return comparer(sortvalA, sortvalB, aModifier);
|
||||
});
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Sort compare functions that can be used with Array sort(). The modifier can flip the sort
|
||||
* direction by passing -1 or 1.
|
||||
*/
|
||||
const sortCompare = calunifinder.sortEntryComparer._sortCompare = {
|
||||
/**
|
||||
* Compare two things as if they were numbers.
|
||||
*
|
||||
* @param {*} a The first thing to compare
|
||||
* @param {*} b The second thing to compare
|
||||
* @param {Number} modifier -1 to flip direction, or 1
|
||||
* @return {Number} Either -1, 0, or 1
|
||||
*/
|
||||
number: function(a, b, modifier=1) {
|
||||
return sortCompare.general(Number(a), Number(b), modifier);
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare two things as if they were dates.
|
||||
*
|
||||
* @param {*} a The first thing to compare
|
||||
* @param {*} b The second thing to compare
|
||||
* @param {Number} modifier -1 to flip direction, or 1
|
||||
* @return {Number} Either -1, 0, or 1
|
||||
*/
|
||||
date: function(a, b, modifier=1) {
|
||||
return sortCompare.general(a, b, modifier);
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare two things generally, using the typical ((a > b) - (a < b))
|
||||
*
|
||||
* @param {*} a The first thing to compare
|
||||
* @param {*} b The second thing to compare
|
||||
* @param {Number} modifier -1 to flip direction, or 1
|
||||
* @return {Number} Either -1, 0, or 1
|
||||
*/
|
||||
general: function(a, b, modifier=1) {
|
||||
return ((a > b) - (a < b)) * modifier;
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare two dates, keeping the nativeTime zero date in mind.
|
||||
*
|
||||
* @param {*} a The first date to compare
|
||||
* @param {*} b The second date to compare
|
||||
* @param {Number} modifier -1 to flip direction, or 1
|
||||
* @return {Number} Either -1, 0, or 1
|
||||
*/
|
||||
date_filled: function(a, b, modifier=1) {
|
||||
const NULL_DATE = -62168601600000000;
|
||||
|
||||
if (a == b) {
|
||||
return 0;
|
||||
} else if (a == NULL_DATE) {
|
||||
return 1;
|
||||
} else if (b == NULL_DATE) {
|
||||
return -1;
|
||||
} else {
|
||||
return sortCompare.general(a, b, modifier);
|
||||
}
|
||||
},
|
||||
|
||||
/**
|
||||
* Compare two strings, sorting empty values to the end by default
|
||||
*
|
||||
* @param {*} a The first string to compare
|
||||
* @param {*} b The second string to compare
|
||||
* @param {Number} modifier -1 to flip direction, or 1
|
||||
* @return {Number} Either -1, 0, or 1
|
||||
*/
|
||||
string: function(a, b, modifier=1) {
|
||||
if (a.length == 0 || b.length == 0) {
|
||||
// sort empty values to end (so when users first sort by a
|
||||
// column, they can see and find the desired values in that
|
||||
// column without scrolling past all the empty values).
|
||||
return -(a.length - b.length) * modifier;
|
||||
}
|
||||
|
||||
let collator = cal.createLocaleCollator();
|
||||
return collator.compareString(0, a, b) * modifier;
|
||||
},
|
||||
|
||||
/**
|
||||
* Catch-all function to compare two unknown values. Will return 0.
|
||||
*
|
||||
* @param {*} a The first thing to compare
|
||||
* @param {*} b The second thing to compare
|
||||
* @param {Number} modifier Provided for consistency, but unused
|
||||
* @return {Number} Will always return 0
|
||||
*/
|
||||
unknown: function(a, b, modifier=1) {
|
||||
return 0;
|
||||
}
|
||||
};
|
|
@ -50,6 +50,13 @@ var cal = {
|
|||
createRecurrenceInfo: _instance("@mozilla.org/calendar/recurrence-info;1",
|
||||
Components.interfaces.calIRecurrenceInfo,
|
||||
"item"),
|
||||
|
||||
createLocaleCollator: function() {
|
||||
return Components.classes["@mozilla.org/intl/collation-factory;1"]
|
||||
.getService(Components.interfaces.nsICollationFactory)
|
||||
.CreateCollation();
|
||||
},
|
||||
|
||||
getCalendarManager: _service("@mozilla.org/calendar/manager;1",
|
||||
Components.interfaces.calICalendarManager),
|
||||
getIcsService: _service("@mozilla.org/calendar/ics-service;1",
|
||||
|
@ -186,205 +193,6 @@ var cal = {
|
|||
return gCalThreadingEnabled;
|
||||
},
|
||||
|
||||
// The below functions will move to some different place once the
|
||||
// unifinder tress are consolidated.
|
||||
|
||||
compareNativeTime: function(a, b) {
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
compareNativeTimeFilledAsc: function(a, b) {
|
||||
if (a == b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// In this filter, a zero time (not set) is always at the end.
|
||||
if (a == -62168601600000000) { // value for (0000/00/00 00:00:00)
|
||||
return 1;
|
||||
}
|
||||
if (b == -62168601600000000) { // value for (0000/00/00 00:00:00)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (a < b ? -1 : 1);
|
||||
},
|
||||
|
||||
compareNativeTimeFilledDesc: function(a, b) {
|
||||
if (a == b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
// In this filter, a zero time (not set) is always at the end.
|
||||
if (a == -62168601600000000) { // value for (0000/00/00 00:00:00)
|
||||
return 1;
|
||||
}
|
||||
if (b == -62168601600000000) { // value for (0000/00/00 00:00:00)
|
||||
return -1;
|
||||
}
|
||||
|
||||
return (a < b ? 1 : -1);
|
||||
},
|
||||
|
||||
compareNumber: function(a, b) {
|
||||
a = Number(a);
|
||||
b = Number(b);
|
||||
if (a < b) {
|
||||
return -1;
|
||||
} else if (a > b) {
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
},
|
||||
|
||||
sortEntryComparer: function(sortType, modifier) {
|
||||
switch (sortType) {
|
||||
case "number":
|
||||
return function(sortEntryA, sortEntryB) {
|
||||
let nsA = cal.sortEntryKey(sortEntryA);
|
||||
let nsB = cal.sortEntryKey(sortEntryB);
|
||||
return cal.compareNumber(nsA, nsB) * modifier;
|
||||
};
|
||||
case "date":
|
||||
return function(sortEntryA, sortEntryB) {
|
||||
let nsA = cal.sortEntryKey(sortEntryA);
|
||||
let nsB = cal.sortEntryKey(sortEntryB);
|
||||
return cal.compareNativeTime(nsA, nsB) * modifier;
|
||||
};
|
||||
case "date_filled":
|
||||
return function(sortEntryA, sortEntryB) {
|
||||
let nsA = cal.sortEntryKey(sortEntryA);
|
||||
let nsB = cal.sortEntryKey(sortEntryB);
|
||||
if (modifier == 1) {
|
||||
return cal.compareNativeTimeFilledAsc(nsA, nsB);
|
||||
} else {
|
||||
return cal.compareNativeTimeFilledDesc(nsA, nsB);
|
||||
}
|
||||
};
|
||||
case "string":
|
||||
return function(sortEntryA, sortEntryB) {
|
||||
let seA = cal.sortEntryKey(sortEntryA);
|
||||
let seB = cal.sortEntryKey(sortEntryB);
|
||||
if (seA.length == 0 || seB.length == 0) {
|
||||
// sort empty values to end (so when users first sort by a
|
||||
// column, they can see and find the desired values in that
|
||||
// column without scrolling past all the empty values).
|
||||
return -(seA.length - seB.length) * modifier;
|
||||
}
|
||||
let collator = cal.createLocaleCollator();
|
||||
let comparison = collator.compareString(0, seA, seB);
|
||||
return comparison * modifier;
|
||||
};
|
||||
default:
|
||||
return function(sortEntryA, sortEntryB) {
|
||||
return 0;
|
||||
};
|
||||
}
|
||||
},
|
||||
|
||||
getItemSortKey: function(aItem, aKey, aStartTime) {
|
||||
function nativeTime(calDateTime) {
|
||||
if (calDateTime == null) {
|
||||
return -62168601600000000; // ns value for (0000/00/00 00:00:00)
|
||||
}
|
||||
return calDateTime.nativeTime;
|
||||
}
|
||||
|
||||
switch (aKey) {
|
||||
case "priority":
|
||||
return aItem.priority || 5;
|
||||
|
||||
case "title":
|
||||
return aItem.title || "";
|
||||
|
||||
case "entryDate":
|
||||
return nativeTime(aItem.entryDate);
|
||||
|
||||
case "startDate":
|
||||
return nativeTime(aItem.startDate);
|
||||
|
||||
case "dueDate":
|
||||
return nativeTime(aItem.dueDate);
|
||||
|
||||
case "endDate":
|
||||
return nativeTime(aItem.endDate);
|
||||
|
||||
case "completedDate":
|
||||
return nativeTime(aItem.completedDate);
|
||||
|
||||
case "percentComplete":
|
||||
return aItem.percentComplete;
|
||||
|
||||
case "categories":
|
||||
return aItem.getCategories({}).join(", ");
|
||||
|
||||
case "location":
|
||||
return aItem.getProperty("LOCATION") || "";
|
||||
|
||||
case "status":
|
||||
if (cal.item.isToDo(aItem)) {
|
||||
return ["NEEDS-ACTION", "IN-PROCESS", "COMPLETED", "CANCELLED"].indexOf(aItem.status);
|
||||
} else {
|
||||
return ["TENTATIVE", "CONFIRMED", "CANCELLED"].indexOf(aItem.status);
|
||||
}
|
||||
case "calendar":
|
||||
return aItem.calendar.name || "";
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
getSortTypeForSortKey: function(aSortKey) {
|
||||
switch (aSortKey) {
|
||||
case "title":
|
||||
case "categories":
|
||||
case "location":
|
||||
case "calendar":
|
||||
return "string";
|
||||
|
||||
// All dates use "date_filled"
|
||||
case "completedDate":
|
||||
case "startDate":
|
||||
case "endDate":
|
||||
case "dueDate":
|
||||
case "entryDate":
|
||||
return "date_filled";
|
||||
|
||||
case "priority":
|
||||
case "percentComplete":
|
||||
case "status":
|
||||
return "number";
|
||||
default:
|
||||
return "unknown";
|
||||
}
|
||||
},
|
||||
|
||||
sortEntry: function(aItem) {
|
||||
let key = cal.getItemSortKey(aItem, this.mSortKey, this.mSortStartedDate);
|
||||
return { mSortKey: key, mItem: aItem };
|
||||
},
|
||||
|
||||
sortEntryItem: function(sortEntry) {
|
||||
return sortEntry.mItem;
|
||||
},
|
||||
|
||||
sortEntryKey: function(sortEntry) {
|
||||
return sortEntry.mSortKey;
|
||||
},
|
||||
|
||||
createLocaleCollator: function() {
|
||||
return Components.classes["@mozilla.org/intl/collation-factory;1"]
|
||||
.getService(Components.interfaces.nsICollationFactory)
|
||||
.CreateCollation();
|
||||
},
|
||||
|
||||
/**
|
||||
* Sort an array of strings according to the current locale.
|
||||
* Modifies aStringArray, returning it sorted.
|
||||
|
@ -495,6 +303,7 @@ XPCOMUtils.defineLazyModuleGetter(cal, "dtz", "resource://calendar/modules/calDa
|
|||
XPCOMUtils.defineLazyModuleGetter(cal, "email", "resource://calendar/modules/calEmailUtils.jsm", "calemail");
|
||||
XPCOMUtils.defineLazyModuleGetter(cal, "item", "resource://calendar/modules/calItemUtils.jsm", "calitem");
|
||||
XPCOMUtils.defineLazyModuleGetter(cal, "itip", "resource://calendar/modules/calItipUtils.jsm", "calitip");
|
||||
XPCOMUtils.defineLazyModuleGetter(cal, "unifinder", "resource://calendar/modules/calUnifinderUtils.jsm", "calunifinder");
|
||||
XPCOMUtils.defineLazyModuleGetter(cal, "view", "resource://calendar/modules/calViewUtils.jsm", "calview");
|
||||
XPCOMUtils.defineLazyModuleGetter(cal, "window", "resource://calendar/modules/calWindowUtils.jsm", "calwindow");
|
||||
|
||||
|
|
|
@ -83,6 +83,13 @@ var migrations = {
|
|||
getInvitedAttendee: "getInvitedAttendee",
|
||||
getAttendeesBySender: "getAttendeesBySender"
|
||||
},
|
||||
unifinder: {
|
||||
sortEntryComparer: "sortEntryComparer",
|
||||
getItemSortKey: "getItemSortKey",
|
||||
// compareNative*, compareNumber, sortEntry, sortEntryItem, sortEntryKey and
|
||||
// getSortTypeForSortKey are no longer available. There is a new
|
||||
// cal.unifinder.sortItems though that should do everything necessary.
|
||||
},
|
||||
view: {
|
||||
isMouseOverBox: "isMouseOverBox",
|
||||
calRadioGroupSelectItem: "radioGroupSelectItem",
|
||||
|
|
|
@ -20,6 +20,7 @@ EXTRA_JS_MODULES += [
|
|||
'calPrintUtils.jsm',
|
||||
'calProviderUtils.jsm',
|
||||
'calRecurrenceUtils.jsm',
|
||||
'calUnifinderUtils.jsm',
|
||||
'calUtils.jsm',
|
||||
'calUtilsCompat.jsm',
|
||||
'calViewUtils.jsm',
|
||||
|
|
|
@ -2,10 +2,9 @@
|
|||
* 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/. */
|
||||
|
||||
/* exported do_calendar_startup, do_load_calmgr, do_load_timezoneservice,
|
||||
* readJSONFile, ics_unfoldline, compareItemsSpecific, getStorageCal,
|
||||
* getMemoryCal, createTodoFromIcalString, createEventFromIcalString,
|
||||
* createDate, Cc, Ci, Cr, Cu
|
||||
/* exported do_calendar_startup, do_load_calmgr, do_load_timezoneservice, readJSONFile,
|
||||
* ics_unfoldline, dedent, compareItemsSpecific, getStorageCal, getMemoryCal,
|
||||
* createTodoFromIcalString, createEventFromIcalString, createDate, Cc, Ci, Cr, Cu
|
||||
*/
|
||||
|
||||
ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
|
@ -190,6 +189,43 @@ function ics_unfoldline(aLine) {
|
|||
return aLine.replace(/\r?\n[ \t]/g, "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Dedent the template string tagged with this function to make indented data
|
||||
* easier to read. Usage:
|
||||
*
|
||||
* let data = dedent`
|
||||
* This is indented data it will be unindented so that the first line has
|
||||
* no leading spaces and the second is indented by two spaces.
|
||||
* `;
|
||||
*
|
||||
* @param strings The string fragments from the template string
|
||||
* @param ...values The interpolated values
|
||||
* @return The interpolated, dedented string
|
||||
*/
|
||||
function dedent(strings, ...values) {
|
||||
let parts = [];
|
||||
|
||||
// Perform variable interpolation
|
||||
for (let [i, string] of strings.entries()) {
|
||||
parts.push(string);
|
||||
if (i < values.length) {
|
||||
parts.push(values[i]);
|
||||
}
|
||||
}
|
||||
let lines = parts.join("").split("\n");
|
||||
|
||||
// The first and last line is empty as in above example.
|
||||
lines.shift();
|
||||
lines.pop();
|
||||
|
||||
let minIndent = lines.reduce((min, line) => {
|
||||
let match = line.match(/^(\s*)\S*/);
|
||||
return Math.min(min, match[1].length);
|
||||
}, Infinity);
|
||||
|
||||
return lines.map(line => line.substr(minIndent)).join("\n");
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a JSON file and return the JS object
|
||||
*/
|
||||
|
|
|
@ -0,0 +1,112 @@
|
|||
/* 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/. */
|
||||
|
||||
|
||||
function run_test() {
|
||||
test_get_item_sort_key();
|
||||
test_sort_items();
|
||||
}
|
||||
|
||||
|
||||
function test_get_item_sort_key() {
|
||||
let event = cal.createEvent(dedent`
|
||||
BEGIN:VEVENT
|
||||
PRIORITY:8
|
||||
SUMMARY:summary
|
||||
DTSTART:20180102T030405Z
|
||||
DTEND:20180607T080910Z
|
||||
CATEGORIES:a,b,c
|
||||
LOCATION:location
|
||||
STATUS:CONFIRMED
|
||||
END:VEVENT
|
||||
`);
|
||||
|
||||
strictEqual(cal.unifinder.getItemSortKey(event, "nothing"), null);
|
||||
equal(cal.unifinder.getItemSortKey(event, "priority"), 8);
|
||||
equal(cal.unifinder.getItemSortKey(event, "title"), "summary");
|
||||
equal(cal.unifinder.getItemSortKey(event, "startDate"), 1514862245000000);
|
||||
equal(cal.unifinder.getItemSortKey(event, "endDate"), 1528358950000000);
|
||||
equal(cal.unifinder.getItemSortKey(event, "categories"), "a, b, c");
|
||||
equal(cal.unifinder.getItemSortKey(event, "location"), "location");
|
||||
equal(cal.unifinder.getItemSortKey(event, "status"), 1);
|
||||
|
||||
let task = cal.createTodo(dedent`
|
||||
BEGIN:VTODO
|
||||
DTSTART:20180102T030405Z
|
||||
DUE:20180607T080910Z
|
||||
PERCENT-COMPLETE:20
|
||||
STATUS:COMPLETED
|
||||
END:VTODO
|
||||
`);
|
||||
|
||||
equal(cal.unifinder.getItemSortKey(task, "priority"), 5);
|
||||
strictEqual(cal.unifinder.getItemSortKey(task, "title"), "");
|
||||
equal(cal.unifinder.getItemSortKey(task, "entryDate"), 1514862245000000);
|
||||
equal(cal.unifinder.getItemSortKey(task, "dueDate"), 1528358950000000);
|
||||
equal(cal.unifinder.getItemSortKey(task, "completedDate"), -62168601600000000);
|
||||
equal(cal.unifinder.getItemSortKey(task, "percentComplete"), 20);
|
||||
strictEqual(cal.unifinder.getItemSortKey(task, "categories"), "");
|
||||
strictEqual(cal.unifinder.getItemSortKey(task, "location"), "");
|
||||
equal(cal.unifinder.getItemSortKey(task, "status"), 2);
|
||||
|
||||
let task2 = cal.createTodo(dedent`
|
||||
BEGIN:VTODO
|
||||
STATUS:GETTIN' THERE
|
||||
END:VTODO
|
||||
`);
|
||||
equal(cal.unifinder.getItemSortKey(task2, "percentComplete"), 0);
|
||||
equal(cal.unifinder.getItemSortKey(task2, "status"), -1);
|
||||
}
|
||||
|
||||
function test_sort_items() {
|
||||
// string comparison
|
||||
let summaries = ["", "a", "b"];
|
||||
let items = summaries.map(summary => {
|
||||
return cal.createEvent(dedent`
|
||||
BEGIN:VEVENT
|
||||
SUMMARY:${summary}
|
||||
END:VEVENT
|
||||
`);
|
||||
});
|
||||
|
||||
cal.unifinder.sortItems(items, "title", 1);
|
||||
deepEqual(items.map(item => item.title), ["a", "b", null]);
|
||||
|
||||
cal.unifinder.sortItems(items, "title", -1);
|
||||
deepEqual(items.map(item => item.title), [null, "b", "a"]);
|
||||
|
||||
// date comparison
|
||||
let dates = ["20180101T000002Z", "20180101T000000Z", "20180101T000001Z"];
|
||||
items = dates.map(date => {
|
||||
return cal.createEvent(dedent`
|
||||
BEGIN:VEVENT
|
||||
DTSTART:${date}
|
||||
END:VEVENT
|
||||
`);
|
||||
});
|
||||
|
||||
cal.unifinder.sortItems(items, "startDate", 1);
|
||||
deepEqual(items.map(item => item.startDate.icalString),
|
||||
["20180101T000000Z", "20180101T000001Z", "20180101T000002Z"]);
|
||||
|
||||
cal.unifinder.sortItems(items, "startDate", -1);
|
||||
deepEqual(items.map(item => item.startDate.icalString),
|
||||
["20180101T000002Z", "20180101T000001Z", "20180101T000000Z"]);
|
||||
|
||||
// number comparison
|
||||
let percents = [3, 1, 2];
|
||||
items = percents.map(percent => {
|
||||
return cal.createTodo(dedent`
|
||||
BEGIN:VTODO
|
||||
PERCENT-COMPLETE:${percent}
|
||||
END:VTODO
|
||||
`);
|
||||
});
|
||||
|
||||
cal.unifinder.sortItems(items, "percentComplete", 1);
|
||||
deepEqual(items.map(item => item.percentComplete), [1, 2, 3]);
|
||||
|
||||
cal.unifinder.sortItems(items, "percentComplete", -1);
|
||||
deepEqual(items.map(item => item.percentComplete), [3, 2, 1]);
|
||||
}
|
|
@ -47,6 +47,7 @@
|
|||
[test_storage.js]
|
||||
[test_timezone.js]
|
||||
[test_timezone_definition.js]
|
||||
[test_unifinder_utils.js]
|
||||
[test_utils.js]
|
||||
[test_view_utils.js]
|
||||
[test_webcal.js]
|
||||
|
|
Загрузка…
Ссылка в новой задаче