Bug 1049591 - Fix lots of Calendar strict warnings. r=redDragon
This commit is contained in:
Родитель
631a4702a1
Коммит
cbf6efceb0
|
@ -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¬ify=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);
|
||||
|
|
Загрузка…
Ссылка в новой задаче