Bug 1049591 - Fix lots of Calendar strict warnings. r=redDragon

This commit is contained in:
Philipp Kewisch 2015-05-09 15:05:42 +02:00
Родитель 631a4702a1
Коммит cbf6efceb0
35 изменённых файлов: 495 добавлений и 535 удалений

Просмотреть файл

@ -49,9 +49,9 @@ calIcalProperty.prototype = {
},
get valueAsIcalString() {
let type = this.innerObject.type;
function stringifyValue(x) ICAL.stringify.value(x.toString(), type);
return this.innerObject.getValues().map(stringifyValue).join(",");
return this.innerObject.getValues().map(v => {
return ICAL.stringify.value(v.toString(), this.innerObject.type);
}).join(",");
},
set valueAsIcalString(val) {
var icalval = ICAL.parse._parseValue(val, this.innerObject.type);
@ -107,31 +107,33 @@ calIcalProperty.prototype = {
// ICAL.js we need to save the value, reset the type and then try to
// set the value again.
if (n == "VALUE") {
function stringifyValue(x) ICAL.stringify.value(x.toString(), type);
function reparseValue(x) ICAL.parse._parseValue(stringifyValue(x), v);
let oldValues;
let type = this.innerObject.type;
let oldValue;
let wasMultiValue = this.innerObject.isMultiValue;
if (wasMultiValue) {
oldValue = this.innerObject.getValues();
oldValues = this.innerObject.getValues();
} else {
oldValue = [this.innerObject.getFirstValue()];
oldValues = [this.innerObject.getFirstValue()];
}
this.innerObject.resetType(v.toLowerCase());
try {
oldValue = oldValue.map(reparseValue);
oldValues = oldValues.map(oldValue => {
let strvalue = ICAL.stringify.value(oldValue.toString(), type);
return ICAL.parse._parseValue(strvalue, v)
});
} catch (e) {
// If there was an error reparsing the value, then just keep it
// empty.
oldValue = null;
oldValues = null;
}
if (oldValue) {
if (oldValues) {
if (wasMultiValue && this.innerObject.isMultiValue) {
this.innerObject.setValues(oldValue);
} else if (oldValue) {
this.innerObject.setValue(oldValue.join(","));
this.innerObject.setValues(oldValues);
} else {
this.innerObject.setValue(oldValues.join(","));
}
}
} else {

Просмотреть файл

@ -399,7 +399,7 @@ function openEventDialog(calendarItem, calendar, mode, callback, job, initialDat
if (mode == "new") {
calendars = calendars.filter(userCanAddItemsToCalendar);
} else { /* modify */
function calendarCanModifyItems(aCalendar) {
calendars = calendars.filter((aCalendar) => {
/* If the calendar is the item calendar, we check that the item
* can be modified. If the calendar is NOT the item calendar, we
* check that the user can remove items from that calendar and
@ -410,8 +410,7 @@ function openEventDialog(calendarItem, calendar, mode, callback, job, initialDat
&& userCanAddItemsToCalendar(aCalendar))
|| ((calendarItem.calendar == aCalendar)
&& userCanModifyItem(calendarItem)));
}
calendars = calendars.filter(calendarCanModifyItems);
});
}
if (mode == "new"

Просмотреть файл

@ -749,7 +749,7 @@
}
for (var j = 0; j < row.childNodes.length; j++) {
var daybox = row.childNodes[j];
var date = dateList[dateBoxes.length];
var dt = dateList[dateBoxes.length];
// Remove the attribute "relation" for all the column headers.
// Consider only the first row index otherwise it will be
@ -765,18 +765,17 @@
// the month being currently shown or not.
var boxClass;
if (this.showFullMonth) {
boxClass = "calendar-month-day-box-" +
(mainMonth == date.month ? "current-month" : "other-month");
boxClass = "calendar-month-day-box-" +
(mainMonth == dt.month ? "current-month" : "other-month");
} else {
boxClass = "calendar-month-day-box-current-month";
}
function matchesDayOff(dayOffNum) { return dayOffNum == date.weekday; }
if (this.mDaysOffArray.some(matchesDayOff)) {
if (this.mDaysOffArray.some(dayOffNum => dayOffNum == dt.weekday)) {
boxClass = "calendar-month-day-box-day-off " + boxClass;
}
// Set up date relations
switch (date.compare(today)) {
switch (dt.compare(today)) {
case -1:
daybox.setAttribute("relation", "past");
break;
@ -791,14 +790,14 @@
daybox.setAttribute("class", boxClass);
daybox.setDate(date);
if (date.day == 1 || date.day == date.endOfMonth.day) {
daybox.setDate(dt);
if (dt.day == 1 || dt.day == dt.endOfMonth.day) {
daybox.showMonthLabel = true;
} else {
daybox.showMonthLabel = false;
}
daybox.calendarView = this;
daybox.date = date;
daybox.date = dt;
dateBoxes.push(daybox);
// If we've now assigned all of our dates, set this to true so we

Просмотреть файл

@ -488,8 +488,7 @@
var occ;
for (var i in this.mEventInfos) {
occ = this.mEventInfos[i].event;
if (occ.hashId == aOccurrence.hashId)
{
if (occ.hashId == aOccurrence.hashId) {
itemIndex = i;
break;
}
@ -497,11 +496,9 @@
if (itemIndex != -1) {
delete this.mSelectedItemIds[occ.hashId];
function isNotItem(a) {
return !a.occurrence || (a.occurrence.hashId != aOccurrence.hashId);
}
this.mSelectedChunks = this.mSelectedChunks.filter(isNotItem);
this.mSelectedChunks = this.mSelectedChunks.filter((item) => {
return !item.occurrence || (item.occurrence.hashId != aOccurrence.hashId);
});
this.mEventInfos.splice(itemIndex, 1);
return true;
} else {
@ -3620,11 +3617,10 @@
if (!cols.length)
return;
function isNotItem(a) {
return (a.hashId != aEvent.hashId);
}
var oldLength = this.mSelectedItems.length;
this.mSelectedItems = this.mSelectedItems.filter(isNotItem);
this.mSelectedItems = this.mSelectedItems.filter((item) => {
return item.hashId != aEvent.hashId;
});
for each (let col in cols) {
let column = col.column;

Просмотреть файл

@ -998,10 +998,7 @@ calFreeBusyListener.prototype = {
onResult: function cFBL_onResult(aRequest, aEntries) {
if (aRequest && !aRequest.isPending) {
// Find request in list of pending requests and remove from queue:
function neq(aOp) {
return (aRequest.id != aOp.id);
}
this.mBinding.mPendingRequests = this.mBinding.mPendingRequests.filter(neq);
this.mBinding.mPendingRequests = this.mBinding.mPendingRequests.filter(aOp => aRequest.id != aOp.id);
}
if (aEntries) {
this.mFbElement.onFreeBusy(aEntries);

Просмотреть файл

@ -3360,58 +3360,55 @@ function updateDateTime() {
* the links will be collapsed.
*/
function updateTimezone() {
function updateTimezoneElement(aTimezone, aId, aDateTime) {
let element = document.getElementById(aId);
if (!element) {
return;
}
if (aTimezone) {
element.removeAttribute('collapsed');
element.value = aTimezone.displayName || aTimezone.tzid;
if (!aDateTime || !aDateTime.isValid || gIsReadOnly || aDateTime.isDate) {
if (element.hasAttribute('class')) {
element.setAttribute('class-on-enabled',
element.getAttribute('class'));
element.removeAttribute('class');
}
if (element.hasAttribute('onclick')) {
element.setAttribute('onclick-on-enabled',
element.getAttribute('onclick'));
element.removeAttribute('onclick');
}
element.setAttribute('disabled', 'true');
} else {
if (element.hasAttribute('class-on-enabled')) {
element.setAttribute('class',
element.getAttribute('class-on-enabled'));
element.removeAttribute('class-on-enabled');
}
if (element.hasAttribute('onclick-on-enabled')) {
element.setAttribute('onclick',
element.getAttribute('onclick-on-enabled'));
element.removeAttribute('onclick-on-enabled');
}
element.removeAttribute('disabled');
}
} else {
element.setAttribute('collapsed', 'true');
}
}
let timezonesEnabled = document.getElementById('cmd_timezone')
.getAttribute('checked') == 'true';
// convert to default timezone if the timezone option
// is *not* checked, otherwise keep the specific timezone
// and display the labels in order to modify the timezone.
if (timezonesEnabled) {
let startTimezone = gStartTimezone;
let endTimezone = gEndTimezone;
function updateTimezoneElement(aTimezone, aId, aDateTime) {
let element = document.getElementById(aId);
if (!element) {
return;
}
if (aTimezone) {
element.removeAttribute('collapsed');
element.value = aTimezone.displayName || aTimezone.tzid;
if (!aDateTime || !aDateTime.isValid || gIsReadOnly || aDateTime.isDate) {
if (element.hasAttribute('class')) {
element.setAttribute('class-on-enabled',
element.getAttribute('class'));
element.removeAttribute('class');
}
if (element.hasAttribute('onclick')) {
element.setAttribute('onclick-on-enabled',
element.getAttribute('onclick'));
element.removeAttribute('onclick');
}
element.setAttribute('disabled', 'true');
} else {
if (element.hasAttribute('class-on-enabled')) {
element.setAttribute('class',
element.getAttribute('class-on-enabled'));
element.removeAttribute('class-on-enabled');
}
if (element.hasAttribute('onclick-on-enabled')) {
element.setAttribute('onclick',
element.getAttribute('onclick-on-enabled'));
element.removeAttribute('onclick-on-enabled');
}
element.removeAttribute('disabled');
}
} else {
element.setAttribute('collapsed', 'true');
}
}
updateTimezoneElement(startTimezone,
updateTimezoneElement(gStartTimezone,
'timezone-starttime',
gStartTime);
updateTimezoneElement(endTimezone,
updateTimezoneElement(gEndTimezone,
'timezone-endtime',
gEndTime);
} else {

Просмотреть файл

@ -461,6 +461,39 @@ var gDataMigrator = {
},
checkWindowsMail: function gdm_windowsMail() {
function doMigrate(aCalendarNodes, aMailDir, aCallback) {
let calManager = cal.getCalendarManager();
for (let node of aCalendarNodes) {
let name = node.getElementsByTagName("Name")[0].textContent;
let color = node.getElementsByTagName("Color")[0].textContent;
let enabled = node.getElementsByTagName("Enabled")[0].textContent == "True";
// The name is quoted, and the color also contains an alpha
// value. Lets just ignore the alpha value and take the
// color part.
name = name.replace(/(^'|'$)/g, "");
color = color.replace(/0x[0-9a-fA-F]{2}([0-9a-fA-F]{4})/, "#$1");
let calfile = aMailDir.clone();
calfile.append(name + ".ics");
if (calfile.exists()) {
let storage = gDataMigrator.importICSToStorage(calfile)
storage.name = name;
if (color) {
storage.setProperty("color", color);
}
calManager.registerCalendar(storage);
if (enabled) {
getCompositeCalendar().addCalendar(storage);
}
}
}
aCallback();
}
if (!this.dirService.has("LocalAppData")) {
// We are probably not on windows
@ -476,60 +509,27 @@ var gDataMigrator = {
let settingsxml = maildir.clone();
settingsxml.append("Settings.xml");
if (!settingsxml || !settingsxml.exists()) {
// No Settings.xml, maybe Windows Calendar was never started?
return [];
}
let settingsXmlUri = Services.io.newFileURI(settingsxml);
let req = new XMLHttpRequest();
req.open("GET", settingsXmlUri.spec, false);
req.send(null);
if (req.status == 0) {
// The file was found, it seems we are on windows vista.
let doc = req.responseXML;
let root = doc.documentElement;
let migrators = [];
if (settingsxml.exists()) {
let settingsXmlUri = Services.io.newFileURI(settingsxml);
// Get all calendar property tags and return the migrator.
let calendars = doc.getElementsByTagName("VCalendar");
function doMigrate(aCallback) {
for each (let node in Array.slice(calendars)) {
let name = node.getElementsByTagName("Name")[0].textContent;
let color = node.getElementsByTagName("Color")[0].textContent;
let enabled = node.getElementsByTagName("Enabled")[0].textContent == "True";
let req = new XMLHttpRequest();
req.open("GET", settingsXmlUri.spec, false);
req.send(null);
if (req.status == 0) {
// The file was found, it seems we are on windows vista.
let doc = req.responseXML;
let root = doc.documentElement;
// The name is quoted, and the color also contains an alpha
// value. Lets just ignore the alpha value and take the
// color part.
name = name.replace(/(^'|'$)/g, "");
color = color.replace(/0x[0-9a-fA-F]{2}([0-9a-fA-F]{4})/, "#$1");
let calfile = maildir.clone();
calfile.append(name + ".ics");
if (calfile.exists()) {
let storage = gDataMigrator.importICSToStorage(calfile)
storage.name = name;
if (color) {
storage.setProperty("color", color);
}
let calManager = cal.getCalendarManager();
calManager.registerCalendar(storage);
if (enabled) {
getCompositeCalendar().addCalendar(storage);
}
}
// Get all calendar property tags and return the migrator.
let calendars = doc.getElementsByTagName("VCalendar");
if (calendars.length > 0) {
migrators = [new dataMigrator("Windows Calendar", doMigrate.bind(null, calendars, maildir))];
}
aCallback();
}
if (calendars.length > 0) {
return [new dataMigrator("Windows Calendar", doMigrate)];
}
}
return [];
return migrators;
},
/**

Просмотреть файл

@ -129,20 +129,20 @@ function unsubscribeCalendar() {
}
function initRefreshInterval() {
function createMenuItem(minutes) {
let menuitem = createXULElement("menuitem");
menuitem.setAttribute("value", minutes);
let everyMinuteString = cal.calGetString("calendar", "calendarPropertiesEveryMinute");
let label = PluralForm.get(minutes, everyMinuteString).replace("#1", minutes);
menuitem.setAttribute("label", label);
return menuitem;
}
setBooleanAttribute("calendar-refreshInterval-row", "hidden", !gCalendar.canRefresh);
if (gCalendar.canRefresh) {
function createMenuItem(minutes) {
let menuitem = createXULElement("menuitem");
menuitem.setAttribute("value", minutes);
let everyMinuteString = cal.calGetString("calendar", "calendarPropertiesEveryMinute");
let label = PluralForm.get(minutes, everyMinuteString).replace("#1", minutes);
menuitem.setAttribute("label", label);
return menuitem;
}
let refreshInterval = gCalendar.getProperty("refreshInterval");
if (refreshInterval === null) refreshInterval = 30;

Просмотреть файл

@ -642,6 +642,7 @@
// It seems errors in these functions are not shown, do this
// explicitly.
cal.ERROR("Error getting cell props: " + e);
return "";
}
]]></body>
</method>

Просмотреть файл

@ -5,7 +5,7 @@
Components.utils.import("resource://calendar/modules/calUtils.jsm");
Components.utils.import("resource://gre/modules/Preferences.jsm");
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
cal.alarms = {
/**
* Read default alarm settings from user preferences and apply them to the

Просмотреть файл

@ -10,7 +10,7 @@ Components.utils.import("resource://gre/modules/PromiseUtils.jsm");
* Asynchronous tools for handling calendar operations.
*/
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
const cIOL = Components.interfaces.calIOperationListener;
const cIC = Components.interfaces.calICalendar;

Просмотреть файл

@ -10,7 +10,7 @@ Components.utils.import("resource://gre/modules/Preferences.jsm");
* Authentication helper code
*/
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
cal.auth = {
/**
* Auth prompt implementation - Uses password manager if at all possible.

Просмотреть файл

@ -1085,7 +1085,7 @@ Extractor.prototype = {
let re = /\%(\d)\$S/g;
let match;
let i = 0;
while (match = re.exec(s)) {
while ((match = re.exec(s))) {
i++;
positions[parseInt(match[1], 10)] = i;
}

Просмотреть файл

@ -4,7 +4,7 @@
Components.utils.import("resource://calendar/modules/calUtils.jsm");
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
var EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
/**
* An unsorted array of hashable items with some extra functions to quickly

Просмотреть файл

@ -2,9 +2,10 @@
* 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/. */
var EXPORTED_SYMBOLS = ["itemDiff"];
"use strict";
this.EXPORTED_SYMBOLS = ["itemDiff"];
Components.utils.import("resource://calendar/modules/calHashedArray.jsm");
/**

Просмотреть файл

@ -6,7 +6,7 @@ Components.utils.import("resource://calendar/modules/calUtils.jsm");
Components.utils.import("resource://gre/modules/Services.jsm");
Components.utils.import("resource://gre/modules/Preferences.jsm");
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
/**
* Iterates an array of items, i.e. the passed item including all
@ -120,15 +120,16 @@ cal.ical = {
if (aComponent && aComponent.componentType == "VCALENDAR") {
return cal.ical.subcomponentIterator(aComponent, compType);
} else if (aComponent && aComponent.componentType == "XROOT") {
function calVCALENDARIterator(aWantKeys) {
cal.ASSERT(aWantKeys, "Please use for() on the calendar component iterator");
for (let calComp in cal.ical.subcomponentIterator(aComponent, "VCALENDAR")) {
for (let itemComp in cal.ical.subcomponentIterator(calComp, compType)) {
yield itemComp;
return {
__iterator__: function calVCALENDARIterator(aWantKeys) {
cal.ASSERT(aWantKeys, "Please use for() on the calendar component iterator");
for (let calComp in cal.ical.subcomponentIterator(aComponent, "VCALENDAR")) {
for (let itemComp in cal.ical.subcomponentIterator(calComp, compType)) {
yield itemComp;
}
}
}
};
return { __iterator__: calVCALENDARIterator };
} else if (aComponent && (compType == "ANY" || compType == aComponent.componentType)) {
return {
__iterator__: function singleItemIterator(aWantKeys) {

Просмотреть файл

@ -12,7 +12,7 @@ Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
/**
* Scheduling and iTIP helper code
*/
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
cal.itip = {
/**
* Gets the sequence/revision number, either of the passed item or
@ -175,16 +175,18 @@ cal.itip = {
return cal.calGetString("lightning", strName, param, "lightning");
}
let text = "";
const cIOL = Components.interfaces.calIOperationListener;
if (Components.isSuccessCode(aStatus)) {
switch (aOperationType) {
case cIOL.ADD: return _gs("imipAddedItemToCal");
case cIOL.MODIFY: return _gs("imipUpdatedItem");
case cIOL.DELETE: return _gs("imipCanceledItem");
case cIOL.ADD: text = gs("imipAddedItemToCal"); break;
case cIOL.MODIFY: text = _gs("imipUpdatedItem"); break;
case cIOL.DELETE: text = _gs("imipCanceledItem"); break;
}
} else {
return _gs("imipBarProcessingFailed", [aStatus.toString(16)]);
text = _gs("imipBarProcessingFailed", [aStatus.toString(16)]);
}
return text;
},
/**

Просмотреть файл

@ -13,7 +13,7 @@ Components.utils.import("resource://gre/modules/Preferences.jsm");
* Provider helper code
*/
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
this.EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
/**
* Prepare HTTP channel with standard request headers and upload

Просмотреть файл

@ -4,7 +4,7 @@
Components.utils.import("resource://gre/modules/PluralForm.jsm");
Components.utils.import("resource://calendar/modules/calUtils.jsm");
EXPORTED_SYMBOLS = ["recurrenceRule2String", "splitRecurrenceRules", "checkRecurrenceRule"];
this.EXPORTED_SYMBOLS = ["recurrenceRule2String", "splitRecurrenceRules", "checkRecurrenceRule"];
/**
* This function takes the recurrence info passed as argument and creates a
@ -17,7 +17,31 @@ EXPORTED_SYMBOLS = ["recurrenceRule2String", "splitRecurrenceRules", "checkRecur
* @return A human readable string describing the recurrence.
*/
function recurrenceRule2String(recurrenceInfo, startDate, endDate, allDay) {
function getRString(name, args) cal.calGetString("calendar-event-dialog", name, args);
function getRString(name, args) {
return cal.calGetString("calendar-event-dialog", name, args);
}
function day_of_week(day) {
return Math.abs(day) % 8;
}
function day_position(day) {
return (Math.abs(day) - day_of_week(day)) / 8 * (day < 0 ? -1 : 1);
}
function nounClass(aDayString, aRuleString) {
// Select noun class (grammatical gender) for rule string
let nounClass = getRString(aDayString + "Nounclass");
return aRuleString + nounClass.substr(0, 1).toUpperCase() +
nounClass.substr(1);
}
function pluralWeekday(aDayString) {
let plural = getRString("pluralForWeekdays") == "true";
return (plural ? aDayString + "Plural" : aDayString);
}
function everyWeekDay(aByDay) {
// Checks if aByDay contains only values from 1 to 7 with any order.
let mask = aByDay.reduce((v, c) => v | (1 << c), 1);
return aByDay.length == 7 && mask == Math.pow(2, 8) - 1;
}
// Retrieve a valid recurrence rule from the currently
// set recurrence info. Bail out if there's more
@ -37,29 +61,6 @@ function recurrenceRule2String(recurrenceInfo, startDate, endDate, allDay) {
'BYWEEKNO',
//'BYMONTH',
'BYSETPOS'])) {
function day_of_week(day) {
return Math.abs(day) % 8;
}
function day_position(day) {
let dow = day_of_week(day);
return (Math.abs(day) - dow) / 8 * (day < 0 ? -1 : 1);
}
function nounClass(aDayString, aRuleString) {
// Select noun class (grammatical gender) for rule string
let nounClass = getRString(aDayString + "Nounclass");
return aRuleString + nounClass.substr(0, 1).toUpperCase() +
nounClass.substr(1);
}
function pluralWeekday(aDayString) {
let plural = getRString("pluralForWeekdays") == "true";
return (plural ? aDayString + "Plural" : aDayString);
}
function everyWeekDay(aByDay) {
// Checks if aByDay contains only values from 1 to 7 with any order.
let mask = aByDay.reduce(function(v, c) v | (1 << c), 1);
return aByDay.length == 7 && mask == Math.pow(2, 8) - 1;
}
let dateFormatter = cal.getDateFormatter();
let ruleString;
if (rule.type == 'DAILY') {

Просмотреть файл

@ -15,7 +15,7 @@ Components.utils.import("resource://gre/modules/Preferences.jsm");
// Getting the service here will load if its not already loaded
Components.classes["@mozilla.org/calendar/backend-loader;1"].getService();
EXPORTED_SYMBOLS = ["cal"];
this.EXPORTED_SYMBOLS = ["cal"];
let cal = {
// new code should land here,
// and more code should be moved from calUtils.js into this object to avoid
@ -412,21 +412,19 @@ let cal = {
sortEntryComparer: function cal_sortEntryComparer(sortType, modifier) {
switch (sortType) {
case "number":
function compareNumbers(sortEntryA, sortEntryB) {
return function compareNumbers(sortEntryA, sortEntryB) {
let nsA = cal.sortEntryKey(sortEntryA);
let nsB = cal.sortEntryKey(sortEntryB);
return cal.compareNumber(nsA, nsB) * modifier;
}
return compareNumbers;
};
case "date":
function compareTimes(sortEntryA, sortEntryB) {
return function compareTimes(sortEntryA, sortEntryB) {
let nsA = cal.sortEntryKey(sortEntryA);
let nsB = cal.sortEntryKey(sortEntryB);
return cal.compareNativeTime(nsA, nsB) * modifier;
}
return compareTimes;
};
case "date_filled":
function compareTimesFilled(sortEntryA, sortEntryB) {
return function compareTimesFilled(sortEntryA, sortEntryB) {
let nsA = cal.sortEntryKey(sortEntryA);
let nsB = cal.sortEntryKey(sortEntryB);
if (modifier == 1) {
@ -434,11 +432,9 @@ let cal = {
} else {
return cal.compareNativeTimeFilledDesc(nsA, nsB);
}
}
return compareTimesFilled
};
case "string":
let collator = cal.createLocaleCollator();
function compareStrings(sortEntryA, sortEntryB) {
return function compareStrings(sortEntryA, sortEntryB) {
let sA = cal.sortEntryKey(sortEntryA);
let sB = cal.sortEntryKey(sortEntryB);
if (sA.length == 0 || sB.length == 0) {
@ -447,16 +443,14 @@ let cal = {
// column without scrolling past all the empty values).
return -(sA.length - sB.length) * modifier;
}
let collator = cal.createLocaleCollator();
let comparison = collator.compareString(0, sA, sB);
return comparison * modifier;
}
return compareStrings;
};
default:
function compareOther(sortEntryA, sortEntryB) {
return function compareOther(sortEntryA, sortEntryB) {
return 0;
}
return compareOther;
};
}
},
@ -526,6 +520,8 @@ let cal = {
case "percentComplete":
case "status":
return "number";
default:
return "unknown";
}
},

Просмотреть файл

@ -6,7 +6,7 @@
Components.utils.import("resource://calendar/modules/calUtils.jsm");
EXPORTED_SYMBOLS = ["cal"];
this.EXPORTED_SYMBOLS = ["cal"];
cal.xml = {} || cal.xml;
/**

Просмотреть файл

@ -623,6 +623,16 @@ calAlarm.prototype = {
},
toString: function cA_toString(aItem) {
function getItemBundleStringName(aPrefix) {
if (!aItem || isEvent(aItem)) {
return aPrefix + "Event";
} else if (isToDo(aItem)) {
return aPrefix + "Task";
} else {
return aPrefix;
}
}
if (this.related == ALARM_RELATED_ABSOLUTE && this.mAbsoluteDate) {
// this is an absolute alarm. Use the calendar default timezone and
// format it.
@ -630,15 +640,6 @@ calAlarm.prototype = {
let formatDate = this.mAbsoluteDate.getInTimezone(cal.calendarDefaultTimezone());
return formatter.formatDateTime(formatDate);
} else if (this.related != ALARM_RELATED_ABSOLUTE && this.mOffset) {
function getItemBundleStringName(aPrefix) {
if (!aItem || isEvent(aItem)) {
return aPrefix + "Event";
} else if (isToDo(aItem)) {
return aPrefix + "Task";
} else {
return aPrefix;
}
}
// Relative alarm length
let alarmlen = Math.abs(this.mOffset.inSeconds / 60);

Просмотреть файл

@ -452,7 +452,7 @@ calCalendarManager.prototype = {
case Components.interfaces.calIErrors.STORAGE_UNKNOWN_SCHEMA_ERROR:
// For now we alert and quit on schema errors like we've done before:
this.alertAndQuit();
return;
return null;
case Components.interfaces.calIErrors.STORAGE_UNKNOWN_TIMEZONES_ERROR:
uiMessage = calGetString("calendar", "unknownTimezonesError", [uri.spec]);
break;
@ -946,63 +946,54 @@ calMgrCalendarObserver.prototype = {
// Log warnings in error console.
// Report serious errors in both error console and in prompt window.
var isSerious = (aErrNo == calIErrors.MODIFICATION_FAILED);
if (!isSerious) {
WARN(summary);
} else {
// Write error to console.
if (aErrNo == calIErrors.MODIFICATION_FAILED) {
Components.utils.reportError(summary);
// silently don't do anything if this message already has
// been announced without being acknowledged.
if (this.announcedMessages.some(
function(element, index, array) {
return equalMessage(paramBlock, element);
})) {
return;
}
// this message hasn't been announced recently, remember the
// details of the message for future reference.
this.announcedMessages.push(paramBlock);
// Display in prompt window.
var promptWindow =
Services.ww.openWindow
(null, "chrome://calendar/content/calendar-error-prompt.xul",
"_blank", "chrome,dialog=yes,alwaysRaised=yes",
paramBlock);
// Will remove paramBlock from announced messages when
// promptWindow is closed. (Closing fires unloaded event, but
// promptWindow is also unloaded [to clean it?] before loading,
// so wait for detected load event before detecting unload event
// that signifies user closed this prompt window.)
var observer = this;
function awaitLoad(event) {
// #2 loaded, remove load listener
promptWindow.removeEventListener("load", awaitLoad, false);
function awaitUnload(event) {
// #4 unloaded (user closed prompt window),
// remove paramBlock and unload listener.
try {
// remove the message that has been shown from
// the list of all announced messages.
observer.announcedMessages =
observer.announcedMessages.filter(function(msg) {
return !equalMessage(msg, paramBlock);
});
promptWindow.removeEventListener("unload", awaitUnload,
false);
} catch (e) {
Components.utils.reportError(e);
}
}
// #3 add unload listener (wait for user to close promptWindow)
promptWindow.addEventListener("unload", awaitUnload, false);
}
// #1 add load listener
promptWindow.addEventListener("load", awaitLoad, false);
this.announceParamBlock(paramBlock);
} else {
cal.WARN(summary);
}
},
announceParamBlock: function(paramBlock) {
function awaitLoad(event) {
promptWindow.removeEventListener("load", awaitLoad, false);
promptWindow.addEventListener("unload", awaitUnload, false);
}
let awaitUnload = (event) => {
promptWindow.removeEventListener("unload", awaitUnload, false);
// unloaded (user closed prompt window),
// remove paramBlock and unload listener.
try {
// remove the message that has been shown from
// the list of all announced messages.
this.announcedMessages = this.announcedMessages.filter((msg) => {
return !equalMessage(msg, paramBlock);
});
} catch (e) {
Components.utils.reportError(e);
}
};
// silently don't do anything if this message already has been
// announced without being acknowledged.
if (this.announcedMessages.some(equalMessage.bind(null, paramBlock))) {
return;
}
// this message hasn't been announced recently, remember the details of
// the message for future reference.
this.announcedMessages.push(paramBlock);
// Will remove paramBlock from announced messages when promptWindow is
// closed. (Closing fires unloaded event, but promptWindow is also
// unloaded [to clean it?] before loading, so wait for detected load
// event before detecting unload event that signifies user closed this
// prompt window.)
let promptUrl = "chrome://calendar/content/calendar-error-prompt.xul";
let features = "chrome,dialog=yes,alwaysRaised=yes";
let promptWindow = Services.ww.openWindow(null, url, "_blank",
features, paramBlock);
promptWindow.addEventListener("load", awaitLoad, false);
}
};

Просмотреть файл

@ -289,6 +289,11 @@ function guessSystemTimezone() {
const tzSvc = cal.getTimezoneService();
var continent = "Africa|America|Antarctica|Asia|Australia|Europe";
var ocean = "Arctic|Atlantic|Indian|Pacific";
var tzRegex = new RegExp(".*((?:"+continent+"|"+ocean+")"+
"(?:[/][-A-Z_a-z]+)+)");
function getIcalString(component, property) {
var prop = (component && component.getFirstProperty(property));
return (prop ? prop.valueAsIcalString : null);
@ -481,6 +486,69 @@ function guessSystemTimezone() {
return null;
}
function environmentVariableValue(varName) {
let envSvc = Components.classes["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment);
let value = envSvc.get(varName);
if (!value) return "";
if (!value.match(tzRegex)) return "";
return varName+"="+value;
}
function symbolicLinkTarget(filepath) {
try {
let file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(filepath);
file.QueryInterface(Components.interfaces.nsIFile);
if (!file.exists()) return "";
if (!file.isSymlink()) return "";
if (!file.target.match(tzRegex)) return "";
return filepath +" -> "+file.target;
} catch (ex) {
Components.utils.reportError(filepath+": "+ex);
return "";
}
}
function fileFirstZoneLineString(filepath) {
// return first line of file that matches tzRegex (ZoneInfo id),
// or "" if no file or no matching line.
try {
let file = Components.classes["@mozilla.org/file/local;1"]
.createInstance(Components.interfaces.nsILocalFile);
file.initWithPath(filepath);
file.QueryInterface(Components.interfaces.nsIFile);
if (!file.exists()) return "";
let fileInstream = Components.classes["@mozilla.org/network/file-input-stream;1"]
.createInstance(Components.interfaces.nsIFileInputStream);
const PR_RDONLY = 0x1;
fileInstream.init(file, PR_RDONLY, 0, 0);
fileInstream.QueryInterface(Components.interfaces.nsILineInputStream);
try {
let line = {}, hasMore = true, MAXLINES = 10;
for (let i = 0; hasMore && i < MAXLINES; i++) {
hasMore = fileInstream.readLine(line);
if (line.value && line.value.match(tzRegex)) {
return filepath+": "+line.value;
}
}
return ""; // not found
} finally {
fileInstream.close();
}
} catch (ex) {
Components.utils.reportError(filepath+": "+ex);
return "";
}
}
function weekday(icsDate, tz) {
let calDate = cal.createDateTime(icsDate);
calDate.timezone = tz;
return calDate.jsDate.toLocaleFormat("%a");
}
// Try to find a tz that matches OS/JSDate timezone. If no name match,
// will use first of probable timezone(s) with highest score.
var probableTZId = "floating"; // default fallback tz if no tz matches.
@ -559,74 +627,12 @@ function guessSystemTimezone() {
// the values are similar (but cannot have a leading colon).
// (Note: the OS ZoneInfo database may be a different version from
// the one we use, so still need to check that DST dates match.)
var continent = "Africa|America|Antarctica|Asia|Australia|Europe";
var ocean = "Arctic|Atlantic|Indian|Pacific";
var tzRegex = new RegExp(".*((?:"+continent+"|"+ocean+")"+
"(?:[/][-A-Z_a-z]+)+)");
const CC = Components.classes;
const CI = Components.interfaces;
var envSvc = (CC["@mozilla.org/process/environment;1"]
.getService(Components.interfaces.nsIEnvironment));
function environmentVariableValue(varName) {
var value = envSvc.get(varName);
if (!value) return "";
if (!value.match(tzRegex)) return "";
return varName+"="+value;
}
function symbolicLinkTarget(filepath) {
try {
var file = (CC["@mozilla.org/file/local;1"]
.createInstance(CI.nsILocalFile));
file.initWithPath(filepath);
file.QueryInterface(CI.nsIFile);
if (!file.exists()) return "";
if (!file.isSymlink()) return "";
if (!file.target.match(tzRegex)) return "";
return filepath +" -> "+file.target;
} catch (ex) {
Components.utils.reportError(filepath+": "+ex);
return "";
}
}
function fileFirstZoneLineString(filepath) {
// return first line of file that matches tzRegex (ZoneInfo id),
// or "" if no file or no matching line.
try {
var file = (CC["@mozilla.org/file/local;1"]
.createInstance(CI.nsILocalFile));
file.initWithPath(filepath);
file.QueryInterface(CI.nsIFile);
if (!file.exists()) return "";
var fileInstream =
(CC["@mozilla.org/network/file-input-stream;1"].
createInstance(CI.nsIFileInputStream));
const PR_RDONLY = 0x1;
fileInstream.init(file, PR_RDONLY, 0, 0);
fileInstream.QueryInterface(CI.nsILineInputStream);
try {
var line = {}, hasMore = true, MAXLINES = 10;
for (var i = 0; hasMore && i < MAXLINES; i++) {
hasMore = fileInstream.readLine(line);
if (line.value && line.value.match(tzRegex)) {
return filepath+": "+line.value;
}
}
return ""; // not found
} finally {
fileInstream.close();
}
} catch (ex) {
Components.utils.reportError(filepath+": "+ex);
return "";
}
}
osUserTimeZone = (environmentVariableValue("TZ") ||
symbolicLinkTarget("/etc/localtime") ||
fileFirstZoneLineString("/etc/TIMEZONE") ||
fileFirstZoneLineString("/etc/timezone") ||
fileFirstZoneLineString("/etc/sysconfig/clock"));
var results = osUserTimeZone.match(tzRegex);
let results = osUserTimeZone.match(tzRegex);
if (results) {
zoneInfoIdFromOSUserTimeZone = results[1];
}
@ -749,20 +755,14 @@ function guessSystemTimezone() {
if (probableTZScore == 1) {
// score 1 means has daylight time,
// but transitions start on different weekday from os timezone.
function weekday(icsDate) {
var calDate = cal.createDateTime();
calDate.icalString = icsDate;
calDate.timezone = tz;
return cal.dateTimeToJsDate(calDate).toLocaleFormat("%a");
}
var standardStart = getIcalString(standard, "DTSTART");
var standardStartWeekday = weekday(standardStart);
var standardStartWeekday = weekday(standardStart, tz);
var standardRule = getIcalString(standard, "RRULE");
var standardText =
(" Standard: "+standardStart+" "+standardStartWeekday+"\n"+
" "+standardRule+"\n");
var daylightStart = getIcalString(daylight, "DTSTART");
var daylightStartWeekday = weekday(daylightStart);
var daylightStartWeekday = weekday(daylightStart, tz);
var daylightRule = getIcalString(daylight, "RRULE");
var daylightText =
(" Daylight: "+daylightStart+" "+daylightStartWeekday+"\n"+

Просмотреть файл

@ -51,26 +51,14 @@ calTransactionManager.prototype = {
},
checkWritable: function cTM_checkWritable(transaction) {
if (transaction) {
transaction = transaction.wrappedJSObject;
if (transaction) {
function checkItem(item) {
if (item) {
var calendar = item.calendar;
if (calendar && (!isCalendarWritable(calendar) || !userCanAddItemsToCalendar(calendar))) {
return false;
}
}
return true;
}
if (!checkItem(transaction.mItem) ||
!checkItem(transaction.mOldItem)) {
return false;
}
}
function checkItem(item) {
return item && item.calendar &&
isCalendarWritable(item.calendar) &&
userCanAddItemsToCalendar(item.calendar);
}
return true;
let trans = transaction && transaction.wrappedJSObject;
return trans && checkItem(trans.mItem) && checkItem(trans.mOldItem);
},
undo: function cTM_undo() {

Просмотреть файл

@ -1186,25 +1186,22 @@ calInterfaceBag.prototype = {
add: function calInterfaceBag_add(iface) {
if (iface) {
var iid = this.mIid;
function eq(obj) {
return compareObjects(obj, iface, iid);
}
if (!this.mInterfaces.some(eq)) {
let existing = this.mInterfaces.some(obj => {
return compareObjects(obj, iface, this.mIid);
});
if (!existing) {
this.mInterfaces.push(iface);
return true;
}
return !existing;
}
return false;
},
remove: function calInterfaceBag_remove(iface) {
if (iface) {
var iid = this.mIid;
function neq(obj) {
return !compareObjects(obj, iface, iid);
}
this.mInterfaces = this.mInterfaces.filter(neq);
this.mInterfaces = this.mInterfaces.filter((obj) => {
return !compareObjects(obj, iface, this.mIid);
});
}
},
@ -1287,10 +1284,7 @@ calOperationGroup.prototype = {
remove: function calOperationGroup_remove(op) {
if (op) {
function filterFunc(op_) {
return (op.id != op_.id);
}
this.mSubOperations = this.mSubOperations.filter(filterFunc);
this.mSubOperations = this.mSubOperations.filter(op_ => op.id != op_.id);
}
},
@ -1338,10 +1332,9 @@ calOperationGroup.prototype = {
}
var subOperations = this.mSubOperations;
this.mSubOperations = [];
function forEachFunc(op) {
for (let op of subOperations) {
op.cancel(Components.interfaces.calIErrors.OPERATION_CANCELLED);
}
subOperations.forEach(forEachFunc);
}
}
};

Просмотреть файл

@ -629,13 +629,15 @@ calDavCalendar.prototype = {
}
if (aItem.id == null) {
return notifyListener(Components.results.NS_ERROR_FAILURE,
"Can't set ID on non-mutable item to addItem");
notifyListener(Components.results.NS_ERROR_FAILURE,
"Can't set ID on non-mutable item to addItem");
return;
}
if (!isItemSupported(aItem, this)) {
return notifyListener(Components.results.NS_ERROR_FAILURE,
"Server does not support item type");
notifyListener(Components.results.NS_ERROR_FAILURE,
"Server does not support item type");
return;
}
let parentItem = aItem.parentItem;
@ -747,8 +749,9 @@ calDavCalendar.prototype = {
this[method](aListener, status, cIOL.MODIFY, aNewItem.id, detail);
};
if (aNewItem.id == null) {
return notifyListener(Components.results.NS_ERROR_FAILURE,
"ID for modifyItem doesn't exist or is null");
notifyListener(Components.results.NS_ERROR_FAILURE,
"ID for modifyItem doesn't exist or is null");
return;
}
let wasInboxItem = this.mItemInfoCache[aNewItem.id].isInboxItem;
@ -871,8 +874,9 @@ calDavCalendar.prototype = {
};
if (aItem.id == null) {
return notifyListener(Components.results.NS_ERROR_FAILURE,
"ID doesn't exist for deleteItem");
notifyListener(Components.results.NS_ERROR_FAILURE,
"ID doesn't exist for deleteItem");
return;
}
var eventUri;
@ -885,9 +889,10 @@ calDavCalendar.prototype = {
}
if (eventUri.path == this.calendarUri.path) {
return notifyListener(Components.results.NS_ERROR_FAILURE,
"eventUri and calendarUri paths are the same, " +
"will not go on to delete entire calendar");
notifyListener(Components.results.NS_ERROR_FAILURE,
"eventUri and calendarUri paths are the same, " +
"will not go on to delete entire calendar");
return;
}
var thisCalendar = this;
@ -938,7 +943,7 @@ calDavCalendar.prototype = {
notifyListener(Components.results.NS_ERROR_NOT_AVAILABLE,
"Error preparing http channel");
});
return
return;
} else if (responseStatus >= 500 && responseStatus <= 510) {
listenerStatus = Components.results.NS_ERROR_NOT_AVAILABLE;
listenerDetail = "Server Replied with " + responseStatus;
@ -1395,13 +1400,15 @@ calDavCalendar.prototype = {
} catch (ex) {
cal.LOG("CalDAV: Error without status on checking ctag for calendar " +
thisCalendar.name);
return notifyListener(Components.results.NS_OK);
notifyListener(Components.results.NS_OK);
return;
}
if (request.responseStatus == 404) {
cal.LOG("CalDAV: Disabling calendar " + thisCalendar.name +
" due to 404");
return notifyListener(Components.results.NS_ERROR_FAILURE);
notifyListener(Components.results.NS_ERROR_FAILURE);
return;
} else if (request.responseStatus == 207 && thisCalendar.mDisabled) {
// Looks like the calendar is there again, check its resource
// type first.
@ -1422,7 +1429,8 @@ calDavCalendar.prototype = {
} catch (ex) {
cal.LOG("CalDAV: Failed to get ctag from server for calendar " +
thisCalendar.name);
return notifyListener(Components.results.NS_OK);
notifyListener(Components.results.NS_OK);
return;
}
let ctag = caldavXPathFirst(multistatus, "/D:multistatus/D:response/D:propstat/D:prop/CS:getctag/text()");
@ -1639,16 +1647,14 @@ calDavCalendar.prototype = {
// master password prompt will show just the buttons and
// possibly hang. If we postpone until the window is loaded,
// all is well.
function postpone() {
setTimeout(function postpone() {
let win = cal.getCalendarWindow();
if (!win || win.document.readyState != "complete") {
setTimeout(postpone, 0);
} else {
connect();
}
}
setTimeout(postpone, 0);
}, 0);
}
} else {
authSuccess();
@ -2193,6 +2199,15 @@ calDavCalendar.prototype = {
let chs = thisCalendar.mCalHomeSet;
return normalized == chs.path || normalized == chs.spec;
}
function createBoxUrl(path) {
let url = thisCalendar.mUri.clone();
url.path = thisCalendar.ensureDecodedPath(path);
// Make sure the uri has a / at the end, as we do with the calendarUri.
if (url.path.charAt(url.path.length - 1) != '/') {
url.path += "/";
}
return url;
}
// If there are multiple home sets, we need to match the email addresses for scheduling.
// If there is only one, assume its the right one.
@ -2205,15 +2220,6 @@ calDavCalendar.prototype = {
}
}
function createBoxUrl(path) {
let url = thisCalendar.mUri.clone();
url.path = thisCalendar.ensureDecodedPath(path);
// Make sure the uri has a / at the end, as we do with the calendarUri.
if (url.path.charAt(url.path.length - 1) != '/') {
url.path += "/";
}
return url;
}
let inboxPath = caldavXPathFirst(multistatus, "/D:multistatus/D:response/D:propstat/D:prop/C:schedule-inbox-URL/D:href/text()");
if (!inboxPath) {
@ -2782,7 +2788,7 @@ calDavCalendar.prototype = {
var responseXML = cal.xml.parseString(str);
} catch (ex) {
cal.LOG("CalDAV: Could not parse multistatus response: " + ex + "\n" + str);
return false;
return;
}
var remainingAttendees = [];

Просмотреть файл

@ -97,11 +97,6 @@ calCompositeCalendar.prototype = {
interfaces: calCompositeCalendarInterfaces,
}),
//
// private members
//
mDefaultCalendar: null,
//
// calICalendarProvider interface
//
@ -390,7 +385,7 @@ calCompositeCalendar.prototype = {
calIOperationListener.GET,
null,
null);
return;
return null;
}
if (this.mStatusObserver) {
if (this.mStatusObserver.spinning == Components.interfaces.calIStatusObserver.NO_PROGRESS) {
@ -456,20 +451,18 @@ calCompositeGetListenerHelper.prototype = {
get opGroup() {
if (!this.mOpGroup) {
let this_ = this;
function cancelFunc() { // operation group has been cancelled
let listener = this_.mRealListener;
this_.mRealListener = null;
this.mOpGroup = new cal.calOperationGroup(() => {
let listener = this.mRealListener;
this.mRealListener = null;
if (listener) {
listener.onOperationComplete(
this_, Components.interfaces.calIErrors.OPERATION_CANCELLED,
this, Components.interfaces.calIErrors.OPERATION_CANCELLED,
calIOperationListener.GET, null, null);
if (this_.mCompositeCalendar.statusDisplayed) {
this_.mCompositeCalendar.mStatusObserver.stopMeteors();
if (this.mCompositeCalendar.statusDisplayed) {
this.mCompositeCalendar.mStatusObserver.stopMeteors();
}
}
}
this.mOpGroup = new cal.calOperationGroup(cancelFunc);
});
}
return this.mOpGroup;
},

Просмотреть файл

@ -290,15 +290,14 @@ calGoogleSession.prototype = {
// master password prompt will show just the buttons and
// possibly hang. If we postpone until the window is loaded,
// all is well.
function postpone() {
setTimeout(function postpone() {
let win = cal.getCalendarWindow();
if (!win || win.document.readyState != "complete") {
setTimeout(postpone, 400);
} else {
connect();
}
}
setTimeout(postpone, 0);
}, 0);
}
} catch (e) {
// If something went wrong, reset the login state just in case

Просмотреть файл

@ -262,13 +262,14 @@ function EventToJSON(aItem, aOfflineStorage, aIsImport) {
// Only parse attendees if they are enabled, due to bug 407961
if (Preferences.get("calendar.google.enableAttendees", false)) {
const statusMap = {
"NEEDS-ACTION": "needsAction",
"DECLINED": "declined",
"TENTATIVE": "tentative",
"ACCEPTED": "accepted"
};
function createAttendee(attendee) {
let createAttendee = function(attendee) {
const statusMap = {
"NEEDS-ACTION": "needsAction",
"DECLINED": "declined",
"TENTATIVE": "tentative",
"ACCEPTED": "accepted"
};
let attendeeData = {};
if (aItem.organizer && aItem.organizer.id == attendee.id) {
needsOrganizer = false;
@ -287,7 +288,8 @@ function EventToJSON(aItem, aOfflineStorage, aIsImport) {
setIf(attendeeData, "resource", attendee.userType && attendee.userType != "INDIVIDUAL");
setIf(attendeeData, "additionalGuests", attendee.getProperty("X-NUM-GUESTS"));
return attendeeData;
}
};
let needsOrganizer = true;
let attendees = aItem.getAttendees({});
let attendeeData = [ createAttendee(a) for each (a in attendees) ];

Просмотреть файл

@ -468,6 +468,7 @@ calMemoryCalendar.prototype = {
if (aCount && itemsFound.length >= aCount) {
return cal.forEach.BREAK;
}
return cal.forEach.CONTINUE;
}, () => {
aListener.onGetResult(this.superCalendar,
Components.results.NS_OK,

Просмотреть файл

@ -278,7 +278,7 @@ calStorageCalendar.prototype = {
* @param newCalId The new calendar id to set
* @param oldCalId The old calendar id to look for
*/
function migrateTables(db, newCalId, oldCalId) {
let migrateTables = function(db, newCalId, oldCalId) {
for each (let tbl in ["cal_alarms", "cal_attachments",
"cal_attendees", "cal_events",
"cal_metadata", "cal_properties",
@ -301,7 +301,7 @@ calStorageCalendar.prototype = {
}
}
}
}
};
let id = 0;
let path = this.uri.path;
@ -1561,7 +1561,7 @@ calStorageCalendar.prototype = {
try {
this.prepareStatement(this.mSelectTodosWithRecurrence);
sp = this.mSelectTodosWithRecurrence.params;
let sp = this.mSelectTodosWithRecurrence.params;
while (this.mSelectTodosWithRecurrence.executeStep()) {
var row = this.mSelectTodosWithRecurrence.row;
var item = this.getTodoFromRow(row, {});

Просмотреть файл

@ -254,12 +254,10 @@ function setDbVersionAndCommit(db, version) {
* @return The delegate function for the passed named function.
*/
function createDBDelegate(funcName) {
let func = function(db /* , ... */) {
return function(db, ...args) {
if (db) {
let args = Array.slice(arguments);
args.shift();
try {
return db[funcName].apply(db, args);
return db[funcName](...args);
} catch (e) {
cal.ERROR("Error calling '" + funcName + "' db error: '" +
lastErrorString(db) + "'.\nException: " + e);
@ -267,9 +265,6 @@ function createDBDelegate(funcName) {
}
}
};
func.name = "dbDelegate_" + funcName;
return func;
}
/**
@ -281,12 +276,9 @@ function createDBDelegate(funcName) {
* @return The function that delegates the getter.
*/
function createDBDelegateGetter(getterAttr) {
let func = function(db) {
return function(db) {
return (db ? db[getterAttr] : null);
}
func.name = "dbDelegate_get_" + getterAttr;
return func;
}
// These functions use the db delegate to allow easier calling of common
@ -741,6 +733,11 @@ upgrade.v2 = upgrade.v1 = function upgrade_v2(db, version) {
* p=vlad
*/
upgrade.v3 = function upgrade_v3(db, version) {
function updateSql(tbl, field) {
executeSimpleSQL(db, "UPDATE " + tbl + " SET " + field + "_tz='UTC'" +
" WHERE " + field + " IS NOT NULL");
}
let tbl = upgrade.v2(version < 2 && db, version);
LOGdb(db, "Storage: Upgrading to v3");
@ -788,11 +785,6 @@ upgrade.v3 = function upgrade_v3(db, version) {
// given, since that's what the default was for v2 calendars
// Fix up the new timezone columns
function updateSql(tbl, field) {
executeSimpleSQL(db, "UPDATE " + tbl + " SET " + field + "_tz='UTC'" +
" WHERE " + field + " IS NOT NULL");
}
updateSql("cal_events", "event_start");
updateSql("cal_events", "event_end");
updateSql("cal_todos", "todo_entry");
@ -1535,6 +1527,7 @@ upgrade.v22 = function upgrade_v22(db, version) {
// Update recurrence table to using icalString directly
createFunction(db, "translateRecurrence", 17, {
onFunctionCall: function translateRecurrence(storArgs) {
function parseInt10(x) parseInt(x, 10);
try {
let [aIndex, aType, aIsNegative, aDates, aCount,
aEndDate, aInterval, aSecond, aMinute, aHour,
@ -1585,7 +1578,6 @@ upgrade.v22 = function upgrade_v22(db, version) {
SETPOS: aSetPos
};
function parseInt10(x) parseInt(x, 10);
for (let rtype in rtypes) {
if (rtypes[rtype]) {
let comp = "BY" + rtype;

Просмотреть файл

@ -157,7 +157,7 @@ function calWcapCalendar_getAlarmParams(item) {
alarmStart.addDuration(dur);
} // else only end|due is set, alarm makes little sense though
}
let emails = "";
if (item.hasProperty("alarmEmailAddress")) {
emails = encodeURIComponent(item.getProperty("alarmEmailAddress"));
@ -279,6 +279,51 @@ const METHOD_UPDATE = 256;
calWcapCalendar.prototype.storeItem =
function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
function getOrgId(item) {
return (item && item.organizer && item.organizer.id ? item.organizer.id : null);
}
function encodeAttendees(atts) {
function attendeeSort(one, two) {
one = one.id;
two = two.id;
if (one == two) {
return 0;
}
return (one < two ? -1 : 1);
}
atts = atts.concat([]);
atts.sort(attendeeSort);
return atts.map(this_.encodeAttendee, this_).join(";");
}
function encodeCategories(cats) {
cats = cats.concat([]);
cats.sort();
return cats.join(";");
}
function getPrivacy(item) {
return ((item.privacy && item.privacy != "") ? item.privacy : "PUBLIC");
}
function getAttachments(item) {
var ret;
var attachments = item.attachments;
if (attachments) {
var strings = [];
for each (var att in attachements) {
let wrappedAtt = cal.wrapInstance(att, Components.interfaces.calIAttachment);
if (typeof(att) == "string") {
strings.push(encodeURIComponent(att));
} else if (wrappedAtt && wrappedAtt.uri) {
strings.push(encodeURIComponent(wrappedAtt.uri.spec));
} else { // xxx todo
logError("only URLs supported as attachment, not: " + att, this_);
}
}
strings.sort();
ret = strings.join(";");
}
return ret || "";
}
var this_ = this;
var bIsEvent = isEvent(item);
var bIsParent = isParent(item);
@ -358,10 +403,7 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
params += recParams;
}
}
function getOrgId(item) {
return (item && item.organizer && item.organizer.id ? item.organizer.id : null);
}
var orgCalId = getCalId(item.organizer);
if (!orgCalId) { // new events yet don't have X-S1CS-CALID set on ORGANIZER or this is outbound iTIP
var orgId = getOrgId(item);
@ -369,23 +411,10 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
orgCalId = calId; // own event
} // else outbound
}
var attendees = item.getAttendees({});
if (attendees.length > 0) {
// xxx todo: why ever, X-S1CS-EMAIL is unsupported though documented for calprops... WTF.
function encodeAttendees(atts) {
function attendeeSort(one, two) {
one = one.id;
two = two.id;
if (one == two) {
return 0;
}
return (one < two ? -1 : 1);
}
atts = atts.concat([]);
atts.sort(attendeeSort);
return atts.map(this_.encodeAttendee, this_).join(";");
}
var attParam = encodeAttendees(attendees);
if (!oldItem || attParam != encodeAttendees(oldItem.getAttendees({}))) {
params += ("&attendees=" + attParam);
@ -419,11 +448,6 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
}
let categories = item.getCategories({});
function encodeCategories(cats) {
cats = cats.concat([]);
cats.sort();
return cats.join(";");
}
let catParam = encodeCategories(categories);
if (!oldItem || catParam != encodeCategories(oldItem.getCategories({}))) {
params += ("&categories=" + catParam);
@ -447,9 +471,6 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
params += ("&priority=" + encodeURIComponent(val));
}
function getPrivacy(item) {
return ((item.privacy && item.privacy != "") ? item.privacy : "PUBLIC");
}
var icsClass = getPrivacy(item);
if (!oldItem || icsClass != getPrivacy(oldItem)) {
params += ("&icsClass=" + icsClass);
@ -496,32 +517,12 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
}
// attachment urls:
function getAttachments(item) {
var ret = "";
var attachments = item.attachments;
if (attachments) {
var strings = [];
for each (var att in attachements) {
let wrappedAtt = cal.wrapInstance(att, Components.interfaces.calIAttachment);
if (typeof(att) == "string") {
strings.push(encodeURIComponent(att));
} else if (wrappedAtt && wrappedAtt.uri) {
strings.push(encodeURIComponent(wrappedAtt.uri.spec));
} else { // xxx todo
logError("only URLs supported as attachment, not: " + att, this_);
}
}
strings.sort();
ret += strings.join(";");
}
return ret;
}
var val = getAttachments(item);
if (!oldItem || val != getAttachments(oldItem)) {
params += ("&attachments=" + val);
}
} // PUBLISH, REQUEST
var alarmParams = this.getAlarmParams(item);
if (!oldItem || (this.getAlarmParams(oldItem) != alarmParams)) {
if ((method == METHOD_REQUEST) && params.length == 0) {
@ -566,28 +567,28 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request) {
if (bNoSmtpNotify) {
params += "&smtp=0&smtpNotify=0&notify=0";
}
params += "&replace=1"; // (update) don't append to any lists
params += "&replace=1"; // (update) don't append to any lists
params += "&fetch=1&relativealarm=1&compressed=1&recurring=1";
params += "&emailorcalid=1&fmt-out=text%2Fcalendar";
function netRespFunc(err, icalRootComp) {
let netRespFunc = (err, icalRootComp) => {
if (err) {
throw err;
}
var items = this_.parseItems(icalRootComp, calICalendar.ITEM_FILTER_ALL_ITEMS,
0, null, null, true /* bLeaveMutable */);
var items = this.parseItems(icalRootComp, calICalendar.ITEM_FILTER_ALL_ITEMS,
0, null, null, true /* bLeaveMutable */);
if (items.length != 1) {
this_.notifyError(NS_ERROR_UNEXPECTED,
"unexpected number of items: " + items.length);
this.notifyError(NS_ERROR_UNEXPECTED,
"unexpected number of items: " + items.length);
}
var newItem = items[0];
this_.tunnelXProps(newItem, item);
this.tunnelXProps(newItem, item);
newItem.makeImmutable();
// invalidate cached results:
delete this_.m_cachedResults;
delete this.m_cachedResults;
// xxx todo: may log request status
request.execRespFunc(null, newItem);
}
};
this.issueNetworkRequest(request, netRespFunc, stringToIcal,
bIsEvent ? "storeevents" : "storetodos", params,
calIWcapCalendar.AC_COMP_READ |
@ -944,7 +945,7 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
uid2parent[item.id] = parent;
items.push(parent);
}
if (item.id in fakedParents) {
if (item.id in fakedParents) {
let rdate = Components.classes["@mozilla.org/calendar/recurrence-date;1"]
.createInstance(Components.interfaces.calIRecurrenceDate);
rdate.date = item.recurrenceId;
@ -1063,26 +1064,26 @@ function calWcapCalendar_getItem(id, listener) {
params += "&emailorcalid=1&fmt-out=text%2Fcalendar&uid=";
params += encodeURIComponent(id);
function notifyResult(icalRootComp) {
var items = this_.parseItems(icalRootComp, calICalendar.ITEM_FILTER_ALL_ITEMS, 0, null, null);
if (items.length < 1) {
throw new Components.Exception("no such item!");
}
if (items.length > 1) {
this_.notifyError(NS_ERROR_UNEXPECTED,
"unexpected number of items: " + items.length);
}
if (listener) {
listener.onGetResult(this_.superCalendar, NS_OK,
calIItemBase, log("getItem(): success. id=" + id, this_),
items.length, items);
}
request.execRespFunc(null, items[0]);
};
// most common: try events first
this.issueNetworkRequest(
request,
function fetchEventById_resp(err, icalRootComp) {
function notifyResult(icalRootComp) {
var items = this_.parseItems(icalRootComp, calICalendar.ITEM_FILTER_ALL_ITEMS, 0, null, null);
if (items.length < 1) {
throw new Components.Exception("no such item!");
}
if (items.length > 1) {
this_.notifyError(NS_ERROR_UNEXPECTED,
"unexpected number of items: " + items.length);
}
if (listener) {
listener.onGetResult(this_.superCalendar, NS_OK,
calIItemBase, log("getItem(): success. id=" + id, this_),
items.length, items);
}
request.execRespFunc(null, items[0]);
};
if (err) {
if (!checkErrorCode(err, calIWcapErrors.WCAP_FETCH_EVENTS_BY_ID_FAILED) &&
!checkErrorCode(err, calIWcapErrors.WCAP_COMPONENT_NOT_FOUND)) {
@ -1148,7 +1149,7 @@ function calWcapCalendar_getItems(itemFilter, maxResults, rangeStart, rangeEnd,
rangeEnd = ensureDateTime(rangeEnd);
var zRangeStart = getIcalUTC(rangeStart);
var zRangeEnd = getIcalUTC(rangeEnd);
var this_ = this;
var request = new calWcapRequest(
function getItems_resp(request, err, data) {
@ -1163,7 +1164,7 @@ function calWcapCalendar_getItems(itemFilter, maxResults, rangeStart, rangeEnd,
",\n\tmaxResults=" + maxResults +
",\n\trangeStart=" + zRangeStart +
",\n\trangeEnd=" + zRangeEnd, this));
if (this.aboutToBeUnregistered) {
// limiting the amount of network traffic while unregistering
log("being unregistered, no results.", this);

Просмотреть файл

@ -1058,15 +1058,16 @@ calWcapSession.prototype = {
// called after the calendar is registered
onCalendarRegistered: function calWcapSession_onCalendarRegistered(aCalendar) {
function assureDefault(pref, val) {
if (aCalendar.getProperty(pref) === null) {
aCalendar.setProperty(pref, val);
}
}
try {
// make sure the calendar belongs to this session:
if (this.belongsTo(aCalendar)) {
function assureDefault(pref, val) {
if (aCalendar.getProperty(pref) === null) {
aCalendar.setProperty(pref, val);
}
}
assureDefault("shared_context", this.m_contextId);
assureDefault("name", aCalendar.name);