зеркало из https://github.com/mozilla/pjs.git
Bug 340949, 368820, 356125: minding signons.rememberSignons, simple caching, using search_calprops, email alarms, misc cleanup
This commit is contained in:
Родитель
e8f0f42c9f
Коммит
145168b40b
|
@ -103,14 +103,14 @@ calWcapCachedCalendar.prototype = {
|
|||
get remoteCal() {
|
||||
return this.m_remoteCal;
|
||||
},
|
||||
set remoteCal( cal ) {
|
||||
set remoteCal(cal) {
|
||||
if (this.m_remoteCal != null)
|
||||
this.m_remoteCal.removeObserver( this.m_observerMultiplexer );
|
||||
if (cal != null) {
|
||||
cal.addObserver( this.m_observerMultiplexer );
|
||||
cal.superCalendar = this;
|
||||
}
|
||||
this.m_remoteCal = cal;
|
||||
return (this.m_remoteCal = cal);
|
||||
},
|
||||
|
||||
getCalKey:
|
||||
|
@ -156,12 +156,12 @@ calWcapCachedCalendar.prototype = {
|
|||
}
|
||||
return this.m_localCal;
|
||||
},
|
||||
set localCal( cal ) {
|
||||
set localCal(cal) {
|
||||
if (cal != null) {
|
||||
cal.suppressAlarms = this.remoteCal.suppressAlarms; // sync setting
|
||||
cal.superCalendar = this;
|
||||
}
|
||||
this.m_localCal = cal;
|
||||
return (this.m_localCal = cal);
|
||||
},
|
||||
|
||||
toString:
|
||||
|
@ -213,9 +213,9 @@ calWcapCachedCalendar.prototype = {
|
|||
get session() { return this.remoteCal.session; },
|
||||
get calId() { return this.remoteCal.calId; },
|
||||
get calId_() { return this.remoteCal.calId_; },
|
||||
set calId( id ) {
|
||||
set calId(id) {
|
||||
this.localCal = null; // disconnect
|
||||
this.remoteCal.calId = id;
|
||||
return (this.remoteCal.calId = id);
|
||||
},
|
||||
get description() { return this.remoteCal.description; },
|
||||
get displayName() { return this.remoteCal.displayName; },
|
||||
|
@ -236,25 +236,26 @@ calWcapCachedCalendar.prototype = {
|
|||
get name() {
|
||||
return getCalendarManager().getCalendarPref( this, "NAME" );
|
||||
},
|
||||
set name( name ) {
|
||||
set name(name) {
|
||||
getCalendarManager().setCalendarPref( this, "NAME", name );
|
||||
return name;
|
||||
},
|
||||
|
||||
get type() { return "wcap"; },
|
||||
|
||||
m_bReadOnly: false,
|
||||
get readOnly() { return (this.m_bReadOnly || this.remoteCal.readOnly); },
|
||||
set readOnly( bReadOnly ) { this.m_bReadOnly = bReadOnly; },
|
||||
set readOnly(bReadOnly) { return (this.m_bReadOnly = bReadOnly); },
|
||||
|
||||
get uri() { return this.remoteCal.uri; },
|
||||
set uri( thatUri ) {
|
||||
set uri(thatUri) {
|
||||
this.localCal = null; // disconnect
|
||||
this.remoteCal.uri = thatUri;
|
||||
return (this.remoteCal.uri = thatUri);
|
||||
},
|
||||
|
||||
m_superCalendar: null,
|
||||
get superCalendar() { return this.m_superCalendar || this; },
|
||||
set superCalendar( cal ) { this.m_superCalendar = cal; },
|
||||
set superCalendar(cal) { return (this.m_superCalendar = cal); },
|
||||
|
||||
m_observers: null,
|
||||
notifyObservers:
|
||||
|
@ -294,7 +295,7 @@ calWcapCachedCalendar.prototype = {
|
|||
get suppressAlarms() { return this.remoteCal.suppressAlarms; },
|
||||
set suppressAlarms( bSuppressAlarms ) {
|
||||
this.remoteCal.suppressAlarms = bSuppressAlarms;
|
||||
this.localCal.suppressAlarms = this.remoteCal.suppressAlarms;
|
||||
return (this.localCal.suppressAlarms = this.remoteCal.suppressAlarms);
|
||||
},
|
||||
|
||||
get canRefresh() { return true; },
|
||||
|
@ -347,10 +348,10 @@ calWcapCachedCalendar.prototype = {
|
|||
},
|
||||
|
||||
getItems:
|
||||
function( itemFilter, maxResult, rangeStart, rangeEnd, listener )
|
||||
function( itemFilter, maxResults, rangeStart, rangeEnd, listener )
|
||||
{
|
||||
this.log( "getItems():\n\titemFilter=" + itemFilter +
|
||||
",\n\tmaxResult=" + maxResult +
|
||||
",\n\tmaxResults=" + maxResults +
|
||||
",\n\trangeStart=" + getIcalUTC(rangeStart) +
|
||||
",\n\trangeEnd=" + getIcalUTC(rangeEnd) );
|
||||
var this_ = this;
|
||||
|
@ -360,11 +361,11 @@ calWcapCachedCalendar.prototype = {
|
|||
function( calendar, status, opType, id, detail )
|
||||
{
|
||||
if (listener != null) {
|
||||
if (status == Components.results.NS_OK) {
|
||||
if (status == NS_OK) {
|
||||
// delegate to local cal:
|
||||
this_.log("begin localCal.getItems().");
|
||||
this_.localCal.getItems(
|
||||
itemFilter, maxResult, rangeStart, rangeEnd,
|
||||
itemFilter, maxResults, rangeStart, rangeEnd,
|
||||
listener );
|
||||
this_.log("end localCal.getItems().");
|
||||
}
|
||||
|
@ -476,7 +477,7 @@ calWcapCachedCalendar.prototype = {
|
|||
function( calendar, status, opType, id, detail )
|
||||
{
|
||||
try {
|
||||
if (status == Components.results.NS_OK) {
|
||||
if (status == NS_OK) {
|
||||
if (opType == SYNC) {
|
||||
// write stamp: only if necessary
|
||||
if (dtFrom == null ||
|
||||
|
@ -486,8 +487,7 @@ calWcapCachedCalendar.prototype = {
|
|||
if (listener != null) {
|
||||
listener.onOperationComplete(
|
||||
this_.superCalendar,
|
||||
Components.results.NS_OK,
|
||||
SYNC, null, null );
|
||||
NS_OK, SYNC, null, null );
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
|
|
@ -123,14 +123,16 @@ calWcapCalendar.prototype = {
|
|||
str += ", default calendar";
|
||||
return str;
|
||||
},
|
||||
notifyError: function calWcapCalendar_notifyError(err)
|
||||
notifyError: function calWcapCalendar_notifyError(err, suppressOnError)
|
||||
{
|
||||
debugger;
|
||||
var msg = logError(err, this);
|
||||
this.notifyObservers(
|
||||
"onError",
|
||||
err instanceof Components.interfaces.nsIException
|
||||
? [err.result, err.message] : [isNaN(err) ? -1 : err, msg] );
|
||||
if (!suppressOnError) {
|
||||
this.notifyObservers(
|
||||
"onError",
|
||||
err instanceof Components.interfaces.nsIException
|
||||
? [err.result, err.message] : [isNaN(err) ? -1 : err, msg]);
|
||||
}
|
||||
},
|
||||
|
||||
// calICalendarProvider:
|
||||
|
@ -156,13 +158,18 @@ calWcapCalendar.prototype = {
|
|||
set name( name ) {
|
||||
getCalendarManager().setCalendarPref(
|
||||
this.session.defaultCalendar, "NAME", name);
|
||||
return name;
|
||||
},
|
||||
|
||||
get type() { return "wcap"; },
|
||||
|
||||
m_superCalendar: null,
|
||||
get superCalendar() { return this.m_superCalendar || this; },
|
||||
set superCalendar( cal ) { this.m_superCalendar = cal; },
|
||||
get superCalendar() {
|
||||
return (this.m_superCalendar || this);
|
||||
},
|
||||
set superCalendar(cal) {
|
||||
return (this.m_superCalendar = cal);
|
||||
},
|
||||
|
||||
m_bReadOnly: false,
|
||||
get readOnly() {
|
||||
|
@ -175,7 +182,7 @@ calWcapCalendar.prototype = {
|
|||
!this.checkAccess(calIWcapCalendar.AC_COMP_WRITE));
|
||||
},
|
||||
set readOnly(bReadOnly) {
|
||||
this.m_bReadOnly = bReadOnly;
|
||||
return (this.m_bReadOnly = bReadOnly);
|
||||
},
|
||||
|
||||
get uri() {
|
||||
|
@ -187,8 +194,8 @@ calWcapCalendar.prototype = {
|
|||
else
|
||||
return this.session.uri;
|
||||
},
|
||||
set uri( thatUri ) {
|
||||
this.session.uri = thatUri;
|
||||
set uri(thatUri) {
|
||||
return (this.session.uri = thatUri);
|
||||
},
|
||||
|
||||
notifyObservers: function calWcapCalendar_notifyObservers(func, args) {
|
||||
|
@ -225,12 +232,14 @@ calWcapCalendar.prototype = {
|
|||
(this.session.isLoggedIn && !this.isOwnedCalendar));
|
||||
},
|
||||
set suppressAlarms(bSuppressAlarms) {
|
||||
this.m_bSuppressAlarms = bSuppressAlarms;
|
||||
return (this.m_bSuppressAlarms = bSuppressAlarms);
|
||||
},
|
||||
|
||||
get canRefresh() { return false; },
|
||||
get canRefresh() { return (this.m_cachedResults != null); },
|
||||
refresh: function calWcapCalendar_refresh() {
|
||||
log("refresh.", this);
|
||||
// invalidate cached results:
|
||||
delete this.m_cachedResults;
|
||||
},
|
||||
|
||||
issueNetworkRequest: function calWcapCalendar_issueNetworkRequest(
|
||||
|
|
|
@ -65,6 +65,51 @@ function calWcapCalendar_encodeAttendee(att)
|
|||
return encodeAttr(att.id, null, params);
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getRecurrenceParams =
|
||||
function calWcapCalendar_getRecurrenceParams(
|
||||
item, out_rrules, out_rdates, out_exrules, out_exdates)
|
||||
{
|
||||
// recurrences:
|
||||
out_rrules.value = [];
|
||||
out_rdates.value = [];
|
||||
out_exrules.value = [];
|
||||
out_exdates.value = [];
|
||||
if (item.recurrenceInfo) {
|
||||
var rItems = item.recurrenceInfo.getRecurrenceItems({});
|
||||
for each (var rItem in rItems) {
|
||||
var isNeg = rItem.isNegative;
|
||||
if (rItem instanceof Components.interfaces.calIRecurrenceRule) {
|
||||
var rule = ("\"" + encodeURIComponent(
|
||||
rItem.icalProperty.valueAsIcalString) +
|
||||
"\"");
|
||||
if (isNeg)
|
||||
out_exrules.value.push(rule);
|
||||
else
|
||||
out_rrules.value.push(rule);
|
||||
}
|
||||
else if (rItem instanceof Components.interfaces.calIRecurrenceDateSet) {
|
||||
var d = rItem.getDates({});
|
||||
for each (var d in rdates) {
|
||||
if (isNeg)
|
||||
out_exdates.value.push( getIcalUTC(d.date) );
|
||||
else
|
||||
out_rdates.value.push( getIcalUTC(d.date) );
|
||||
}
|
||||
}
|
||||
else if (rItem instanceof Components.interfaces.calIRecurrenceDate) {
|
||||
if (isNeg)
|
||||
out_exdates.value.push( getIcalUTC(rItem.date) );
|
||||
else
|
||||
out_rdates.value.push( getIcalUTC(rItem.date) );
|
||||
}
|
||||
else {
|
||||
this.notifyError("don\'t know how to handle this recurrence item: " +
|
||||
rItem.valueAsIcalString);
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.encodeRecurrenceParams =
|
||||
function calWcapCalendar_encodeRecurrenceParams(item, oldItem)
|
||||
{
|
||||
|
@ -95,21 +140,21 @@ function calWcapCalendar_encodeRecurrenceParams(item, oldItem)
|
|||
var exdates_ = {};
|
||||
this.getRecurrenceParams(oldItem, rrules_, rdates_, exrules_, exdates_);
|
||||
|
||||
function sameSet( list, list_ ) {
|
||||
function sameSet(list, list_) {
|
||||
return (list.length == list_.length &&
|
||||
list.every( function(x) {
|
||||
list.every( function everyFunc(x) {
|
||||
return list_.some(
|
||||
function(y) { return x == y; } );
|
||||
function someFunc(y) { return x == y; } );
|
||||
}
|
||||
));
|
||||
}
|
||||
if (sameSet( rrules.value, rrules_.value ))
|
||||
if (sameSet(rrules.value, rrules_.value))
|
||||
rrules.value = null; // don't write
|
||||
if (sameSet( rdates.value, rdates_.value ))
|
||||
if (sameSet(rdates.value, rdates_.value))
|
||||
rdates.value = null; // don't write
|
||||
if (sameSet( exrules.value, exrules.value ))
|
||||
if (sameSet(exrules.value, exrules.value))
|
||||
exrules.value = null; // don't write
|
||||
if (sameSet( exdates.value, exdates_.value ))
|
||||
if (sameSet(exdates.value, exdates_.value))
|
||||
exdates.value = null; // don't write
|
||||
}
|
||||
|
||||
|
@ -123,13 +168,13 @@ function calWcapCalendar_encodeRecurrenceParams(item, oldItem)
|
|||
return ret;
|
||||
}
|
||||
var ret = "";
|
||||
if (rrules.value != null)
|
||||
if (rrules.value)
|
||||
ret += ("&rrules=" + encodeList(rrules.value));
|
||||
if (rdates.value != null)
|
||||
if (rdates.value)
|
||||
ret += ("&rdates=" + encodeList(rdates.value));
|
||||
if (exrules.value != null)
|
||||
if (exrules.value)
|
||||
ret += ("&exrules=" + encodeList(exrules.value));
|
||||
if (exdates.value != null)
|
||||
if (exdates.value)
|
||||
ret += ("&exdates=" + encodeList(exdates.value));
|
||||
return ret;
|
||||
// xxx todo:
|
||||
|
@ -139,52 +184,42 @@ function calWcapCalendar_encodeRecurrenceParams(item, oldItem)
|
|||
// if rchange=0 is set!
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getRecurrenceParams =
|
||||
function calWcapCalendar_getRecurrenceParams(
|
||||
item, out_rrules, out_rdates, out_exrules, out_exdates)
|
||||
calWcapCalendar.prototype.getAlarmParams =
|
||||
function calWcapCalendar_getAlarmParams(item)
|
||||
{
|
||||
// recurrences:
|
||||
out_rrules.value = [];
|
||||
out_rdates.value = [];
|
||||
out_exrules.value = [];
|
||||
out_exdates.value = [];
|
||||
if (item.recurrenceInfo) {
|
||||
var rItems = item.recurrenceInfo.getRecurrenceItems({});
|
||||
for each ( var rItem in rItems ) {
|
||||
var isNeg = rItem.isNegative;
|
||||
// xxx todo: need to QueryInterface() here?
|
||||
if (rItem instanceof Components.interfaces.calIRecurrenceRule) {
|
||||
var rule = ("\"" + encodeURIComponent(
|
||||
rItem.icalProperty.valueAsIcalString) +
|
||||
"\"");
|
||||
if (isNeg)
|
||||
out_exrules.value.push( rule );
|
||||
else
|
||||
out_rrules.value.push( rule );
|
||||
}
|
||||
// xxx todo: need to QueryInterface() here?
|
||||
else if (rItem instanceof Components.interfaces.calIRecurrenceDateSet) {
|
||||
var d = rItem.getDates({});
|
||||
for each ( var d in rdates ) {
|
||||
if (isNeg)
|
||||
out_exdates.value.push( getIcalUTC(d.date) );
|
||||
else
|
||||
out_rdates.value.push( getIcalUTC(d.date) );
|
||||
}
|
||||
}
|
||||
// xxx todo: need to QueryInterface() here?
|
||||
else if (rItem instanceof Components.interfaces.calIRecurrenceDate) {
|
||||
if (isNeg)
|
||||
out_exdates.value.push( getIcalUTC(rItem.date) );
|
||||
else
|
||||
out_rdates.value.push( getIcalUTC(rItem.date) );
|
||||
}
|
||||
else {
|
||||
this.notifyError("don\'t know how to handle this recurrence item: " +
|
||||
rItem.valueAsIcalString);
|
||||
}
|
||||
var params = null;
|
||||
var alarmStart = item.alarmOffset;
|
||||
if (alarmStart) {
|
||||
if (item.alarmRelated == calIItemBase.ALARM_RELATED_END) {
|
||||
// cs does not support explicit RELATED=END when
|
||||
// both start|entry and end|due are written
|
||||
var dur = item.duration;
|
||||
if (dur) { // both given
|
||||
alarmStart = alarmStart.clone();
|
||||
alarmStart.addDuration(dur);
|
||||
} // else only end|due is set, alarm makes little sense though
|
||||
}
|
||||
|
||||
var emails = "";
|
||||
if (item.hasProperty("alarmEmailAddress"))
|
||||
emails = encodeURIComponent(item.getProperty("alarmEmailAddress"));
|
||||
else {
|
||||
this.session.getDefaultAlarmEmails({}).forEach(
|
||||
function forEachFunc(email) {
|
||||
if (emails.length > 0)
|
||||
emails += ";";
|
||||
emails += encodeURIComponent(email);
|
||||
});
|
||||
}
|
||||
if (emails.length > 0) {
|
||||
params = ("&alarmStart=" + alarmStart.icalString);
|
||||
params += ("&alarmEmails=" + emails);
|
||||
}
|
||||
// else popup
|
||||
}
|
||||
if (!params) // clear popup, email alarm:
|
||||
params = "&alarmStart=&alarmPopup=&alarmEmails=";
|
||||
return params;
|
||||
};
|
||||
|
||||
// why ever, X-S1CS-EMAIL is unsupported though documented
|
||||
|
@ -225,15 +260,22 @@ function equalDatetimes(one, two) {
|
|||
return ((!one && !two) || (one && two && one.compare(two) == 0));
|
||||
}
|
||||
|
||||
// @return null if nothing has changed else value to be written
|
||||
function diffProperty(newItem, oldItem, propName) {
|
||||
var val = null;
|
||||
if (newItem.hasProperty(propName))
|
||||
val = newItem.getProperty(propName);
|
||||
if (oldItem && oldItem.hasProperty(propName)) {
|
||||
if (!val) // property has been deleted
|
||||
val = "";
|
||||
else if (val == oldItem.getProperty(propName))
|
||||
val = null;
|
||||
if (oldItem) {
|
||||
if (oldItem.hasProperty(propName)) {
|
||||
if (!val) // property to be deleted
|
||||
val = "";
|
||||
else if (val == oldItem.getProperty(propName))
|
||||
val = null; // property hasn't changed
|
||||
}
|
||||
}
|
||||
else if (!val) {
|
||||
// force value being set when no old item, eg when adding new item:
|
||||
val = "";
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
@ -389,8 +431,8 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
dtstart = item.startDate;
|
||||
var dtend = item.endDate;
|
||||
bIsAllDay = (dtstart.isDate && dtend.isDate);
|
||||
if (!oldItem || !equalDatetimes(dtstart, oldItem.startDate) ||
|
||||
!equalDatetimes(dtend, oldItem.endDate)) {
|
||||
if (!oldItem || !equalDatetimes(dtstart, oldItem.startDate)
|
||||
|| !equalDatetimes(dtend, oldItem.endDate)) {
|
||||
params += ("&dtstart=" + getIcalUTC(dtstart));
|
||||
params += ("&X-NSCP-DTSTART-TZID=" +
|
||||
"X-NSCP-ORIGINAL-OPERATION=X-NSCP-WCAP-PROPERTY-REPLACE^" +
|
||||
|
@ -400,9 +442,6 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
"X-NSCP-ORIGINAL-OPERATION=X-NSCP-WCAP-PROPERTY-REPLACE^" +
|
||||
encodeURIComponent(this.getAlignedTimezone(dtend.timezone)));
|
||||
params += (bIsAllDay ? "&isAllDay=1" : "&isAllDay=0");
|
||||
// // xxx todo: still needed?
|
||||
// params += ("&tzid=" + encodeURIComponent(
|
||||
// this.getAlignedTimezone(dtstart.timezone)));
|
||||
}
|
||||
}
|
||||
else { // calITodo:
|
||||
|
@ -452,11 +491,19 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
}
|
||||
} // PUBLISH, REQUEST
|
||||
|
||||
var alarmParams = this.getAlarmParams(item);
|
||||
if (!oldItem || (this.getAlarmParams(oldItem) != alarmParams)) {
|
||||
if (bOrgRequest && params.length == 0) {
|
||||
// assure no email notifications about this change:
|
||||
params += "&smtp=0&smtpNotify=0";
|
||||
}
|
||||
params += alarmParams;
|
||||
}
|
||||
|
||||
if (params.length == 0) {
|
||||
log("no change at all.", this);
|
||||
if (LOG_LEVEL > 2) {
|
||||
log("old item:\n" + oldItem.icalString + "\n\nnew item:\n" +
|
||||
item.icalString, this);
|
||||
log("old item:\n" + oldItem.icalString + "\n\nnew item:\n" + item.icalString, this);
|
||||
}
|
||||
request.execRespFunc(null, item);
|
||||
}
|
||||
|
@ -468,17 +515,16 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
// WCAP_STORE_TYPE_CREATE, WCAP_STORE_TYPE_MODIFY
|
||||
params += (bAddItem ? "&storetype=1" : "&storetype=2");
|
||||
|
||||
if (bIsParent) // THIS AND ALL INSTANCES:
|
||||
params += "&mod=4";
|
||||
if (bIsParent)
|
||||
params += "&mod=4"; // THIS AND ALL INSTANCES
|
||||
else {
|
||||
// THIS INSTANCE:
|
||||
var rid = item.recurrenceId;
|
||||
if (rid.isDate) {
|
||||
// cs does not accept DATE:
|
||||
rid = rid.clone();
|
||||
rid.isDate = false;
|
||||
}
|
||||
params += ("&mod=1&rid=" + getIcalUTC(rid));
|
||||
params += ("&mod=1&rid=" + getIcalUTC(rid)); // THIS INSTANCE
|
||||
}
|
||||
|
||||
if (bOrgRequest)
|
||||
|
@ -491,11 +537,10 @@ function calWcapCalendar_storeItem(bAddItem, item, oldItem, request, netRespFunc
|
|||
params += "&fetch=1&relativealarm=1&compressed=1&recurring=1";
|
||||
params += "&emailorcalid=1&fmt-out=text%2Fcalendar";
|
||||
|
||||
this.issueNetworkRequest(
|
||||
request, netRespFunc,
|
||||
stringToIcal, bIsEvent ? "storeevents" : "storetodos", params,
|
||||
calIWcapCalendar.AC_COMP_READ |
|
||||
calIWcapCalendar.AC_COMP_WRITE);
|
||||
this.issueNetworkRequest(request, netRespFunc, stringToIcal,
|
||||
bIsEvent ? "storeevents" : "storetodos", params,
|
||||
calIWcapCalendar.AC_COMP_READ |
|
||||
calIWcapCalendar.AC_COMP_WRITE);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -505,15 +550,30 @@ function calWcapCalendar_tunnelXProps(destItem, srcItem)
|
|||
// xxx todo: temp workaround for bug in calItemBase.js
|
||||
if (!isParent(srcItem))
|
||||
return;
|
||||
// tunnel alarm X-MOZ-SNOOZE only if alarm is still set:
|
||||
var alarmOffset = destItem.alarmOffset;
|
||||
var enumerator = srcItem.propertyEnumerator;
|
||||
while (enumerator.hasMoreElements()) {
|
||||
var prop = enumerator.getNext().QueryInterface(
|
||||
Components.interfaces.nsIProperty);
|
||||
var name = prop.name;
|
||||
if (name.indexOf("X-MOZ-") == 0) {
|
||||
if (LOG_LEVEL > 1)
|
||||
log("tunneling " + name, this);
|
||||
destItem.setProperty(name, prop.value);
|
||||
try {
|
||||
var prop = enumerator.getNext().QueryInterface(Components.interfaces.nsIProperty);
|
||||
var name = prop.name;
|
||||
if (name.indexOf("X-MOZ-") == 0) {
|
||||
switch (name) {
|
||||
// keep snooze stamps for occurrences only and if alarm is still set:
|
||||
case "X-MOZ-SNOOZE-TIME":
|
||||
if (!alarmOffset)
|
||||
break; // alarm has been reset
|
||||
// fallthru intended:
|
||||
default:
|
||||
if (LOG_LEVEL > 1)
|
||||
log("tunneling " + name + "=" + prop.value, this);
|
||||
destItem.setProperty(name, prop.value);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
logError(exc, this);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
@ -525,11 +585,11 @@ function calWcapCalendar_adoptItem(item, listener)
|
|||
var request = new calWcapRequest(
|
||||
function adoptItem_resp(request, err, newItem) {
|
||||
if (listener) {
|
||||
listener.onOperationComplete(
|
||||
this_.superCalendar, getResultCode(err),
|
||||
calIOperationListener.ADD,
|
||||
err ? item.id : newItem.id,
|
||||
err ? err : newItem);
|
||||
listener.onOperationComplete(this_.superCalendar,
|
||||
getResultCode(err),
|
||||
calIOperationListener.ADD,
|
||||
err ? item.id : newItem.id,
|
||||
err ? err : newItem);
|
||||
}
|
||||
if (err)
|
||||
this_.notifyError(err);
|
||||
|
@ -554,10 +614,8 @@ function calWcapCalendar_adoptItem(item, listener)
|
|||
0, null, null, true /* bLeaveMutable */);
|
||||
if (items.length < 1)
|
||||
throw new Components.Exception("empty VCALENDAR returned!");
|
||||
if (items.length > 1) {
|
||||
this_.notifyError("unexpected number of items: " +
|
||||
items.length);
|
||||
}
|
||||
if (items.length > 1)
|
||||
this_.notifyError("unexpected number of items: " + items.length);
|
||||
var newItem = items[0];
|
||||
this_.tunnelXProps(newItem, item);
|
||||
item.makeImmutable();
|
||||
|
@ -616,10 +674,8 @@ function calWcapCalendar_modifyItem(newItem, oldItem, listener)
|
|||
0, null, null, true /* bLeaveMutable */);
|
||||
if (items.length < 1)
|
||||
throw new Components.Exception("empty VCALENDAR returned!");
|
||||
if (items.length > 1) {
|
||||
this_.notifyError("unexpected number of items: " +
|
||||
items.length);
|
||||
}
|
||||
if (items.length > 1)
|
||||
this_.notifyError("unexpected number of items: " + items.length);
|
||||
var item = items[0];
|
||||
this_.tunnelXProps(item, newItem);
|
||||
item.makeImmutable();
|
||||
|
@ -685,7 +741,7 @@ function calWcapCalendar_deleteItem(item, listener)
|
|||
};
|
||||
|
||||
calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
||||
icalRootComp, itemFilter, maxResult, rangeStart, rangeEnd, bLeaveMutable)
|
||||
icalRootComp, itemFilter, maxResults, rangeStart, rangeEnd, bLeaveMutable)
|
||||
{
|
||||
var items = [];
|
||||
var unexpandedItems = [];
|
||||
|
@ -749,32 +805,10 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
}
|
||||
break;
|
||||
}
|
||||
// if (item &&
|
||||
// item.alarmOffset && !item.entryDate && !item.dueDate) {
|
||||
// // xxx todo: loss on roundtrip
|
||||
// log( "app currently does not support " +
|
||||
// "absolute alarm trigger datetimes. " +
|
||||
// "Removing alarm from item: " + item.title, this_);
|
||||
if (item) { // xxx todo: todo alarms currently off
|
||||
item.alarmOffset = null;
|
||||
item.alarmLastAck = null;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (item) {
|
||||
// var contactsProp = subComp.getFirstProperty("CONTACT");
|
||||
// if (contactsProp) { // stamp[:lastack]
|
||||
// var ar = contactsProp.value.split(":");
|
||||
// if (ar.length > 1) {
|
||||
// var lastAck = ar[1];
|
||||
// if (lastAck.length > 0) { // shift to alarm comp:
|
||||
// item.alarmLastAck = getDatetimeFromIcalString(
|
||||
// lastAck); // TZID is UTC
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
if (!item.title) {
|
||||
// assumed to look at a subscribed calendar,
|
||||
// so patch title for private items:
|
||||
|
@ -812,7 +846,7 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
unexpandedItems.push(item);
|
||||
uid2parent[item.id] = item;
|
||||
}
|
||||
else if (maxResult == 0 || items.length < maxResult) {
|
||||
else if (maxResults == 0 || items.length < maxResults) {
|
||||
if (LOG_LEVEL > 2) {
|
||||
log("item: " + item.title + "\n" + item.icalString,
|
||||
this_);
|
||||
|
@ -823,15 +857,15 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
}
|
||||
}
|
||||
},
|
||||
maxResult);
|
||||
maxResults);
|
||||
|
||||
// tag "exceptions", i.e. items with rid:
|
||||
for each ( var item in excItems ) {
|
||||
for each (var item in excItems) {
|
||||
var parent = uid2parent[item.id];
|
||||
if (parent) {
|
||||
item.parentItem = parent;
|
||||
item.makeImmutable();
|
||||
parent.recurrenceInfo.modifyException( item );
|
||||
parent.recurrenceInfo.modifyException(item);
|
||||
}
|
||||
else {
|
||||
logError("parseItems(): no parent item for " + item.title +
|
||||
|
@ -849,13 +883,13 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
|
||||
if (itemFilter & calICalendar.ITEM_FILTER_CLASS_OCCURRENCES) {
|
||||
for each ( var item in unexpandedItems ) {
|
||||
if (maxResult != 0 && items.length >= maxResult)
|
||||
if (maxResults != 0 && items.length >= maxResults)
|
||||
break;
|
||||
if (!bLeaveMutable)
|
||||
item.makeImmutable();
|
||||
var occurrences = item.recurrenceInfo.getOccurrences(
|
||||
rangeStart, rangeEnd,
|
||||
maxResult == 0 ? 0 : maxResult - items.length,
|
||||
maxResults == 0 ? 0 : maxResults - items.length,
|
||||
{} );
|
||||
if (LOG_LEVEL > 1) {
|
||||
log("item: " + item.title + " has " +
|
||||
|
@ -871,9 +905,9 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
}
|
||||
}
|
||||
else {
|
||||
if (maxResult != 0 &&
|
||||
(items.length + unexpandedItems.length) > maxResult) {
|
||||
unexpandedItems.length = (maxResult - items.length);
|
||||
if (maxResults != 0 &&
|
||||
(items.length + unexpandedItems.length) > maxResults) {
|
||||
unexpandedItems.length = (maxResults - items.length);
|
||||
}
|
||||
if (!bLeaveMutable) {
|
||||
for each ( var item in unexpandedItems ) {
|
||||
|
@ -920,12 +954,12 @@ calWcapCalendar.prototype.parseItems = function calWcapCalendar_parseItems(
|
|||
// item = items[0];
|
||||
// if (listener) {
|
||||
// listener.onGetResult(
|
||||
// this_.superCalendar, Components.results.NS_OK,
|
||||
// Components.interfaces.calIItemBase,
|
||||
// this_.superCalendar, NS_OK,
|
||||
// calIItemBase,
|
||||
// log("getItem(): success.", this_),
|
||||
// items.length, items );
|
||||
// listener.onOperationComplete(
|
||||
// this_.superCalendar, Components.results.NS_OK,
|
||||
// this_.superCalendar, NS_OK,
|
||||
// calIOperationListener.GET,
|
||||
// items.length == 1 ? items[0].id : null, null );
|
||||
// this_.log( "item delivered." );
|
||||
|
@ -998,7 +1032,7 @@ function getItemFilterParams(itemFilter)
|
|||
}
|
||||
|
||||
calWcapCalendar.prototype.getItems =
|
||||
function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, listener)
|
||||
function calWcapCalendar_getItems(itemFilter, maxResults, rangeStart, rangeEnd, listener)
|
||||
{
|
||||
// assure DATE-TIMEs:
|
||||
if (rangeStart && rangeStart.isDate) {
|
||||
|
@ -1023,9 +1057,7 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
calIOperationListener.GET,
|
||||
null, err);
|
||||
}
|
||||
if (getResultCode(err) != calIWcapErrors.WCAP_LOGIN_FAILED) {
|
||||
this_.notifyError(err);
|
||||
}
|
||||
this_.notifyError(err, request.suppressOnError);
|
||||
}
|
||||
else {
|
||||
log("getItems(): success.", this_);
|
||||
|
@ -1038,10 +1070,13 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
}
|
||||
},
|
||||
log("getItems():\n\titemFilter=0x" + itemFilter.toString(0x10) +
|
||||
",\n\tmaxResult=" + maxResult +
|
||||
",\n\tmaxResults=" + maxResults +
|
||||
",\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd, this));
|
||||
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_SUPPRESS_ONERROR)
|
||||
request.suppressOnError = true;
|
||||
|
||||
if (this.session.aboutToLogout) { // limiting the amount of network traffic:
|
||||
log("about to logout, no results.", this);
|
||||
request.execRespFunc(null, []);
|
||||
|
@ -1063,9 +1098,7 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
log("reusing last getItems() cached data.", this);
|
||||
if (listener) {
|
||||
listener.onGetResult(
|
||||
this.superCalendar,
|
||||
Components.results.NS_OK,
|
||||
Components.interfaces.calIItemBase,
|
||||
this.superCalendar, NS_OK, calIItemBase,
|
||||
"getItems()", entry.results.length, entry.results);
|
||||
}
|
||||
request.execRespFunc(null, entry.results);
|
||||
|
@ -1079,8 +1112,8 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
"&emailorcalid=1&fmt-out=text%2Fcalendar");
|
||||
// setting component-type, compstate filters:
|
||||
params += getItemFilterParams(itemFilter);
|
||||
if (maxResult > 0)
|
||||
params += ("&maxResult=" + maxResult);
|
||||
if (maxResults > 0)
|
||||
params += ("&maxResults=" + maxResults);
|
||||
params += ("&dtstart=" + zRangeStart);
|
||||
params += ("&dtend=" + zRangeEnd);
|
||||
|
||||
|
@ -1102,10 +1135,10 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
if (!request.succeeded)
|
||||
throw request.status;
|
||||
var items = [];
|
||||
for each ( var period in result ) {
|
||||
for each (var period in result) {
|
||||
var item = new CalEvent();
|
||||
item.id = (g_busyPhantomItemUuidPrefix +
|
||||
period.start.icalString);
|
||||
getIcalUTC(period.start));
|
||||
item.calendar = this_.superCalendar;
|
||||
item.title = g_busyItemTitle;
|
||||
item.startDate = period.start;
|
||||
|
@ -1114,9 +1147,7 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
items.push(item);
|
||||
}
|
||||
listener.onGetResult(
|
||||
this_.superCalendar,
|
||||
Components.results.NS_OK,
|
||||
Components.interfaces.calIItemBase,
|
||||
this_.superCalendar, NS_OK, calIItemBase,
|
||||
"getItems()/free-busy", items.length, items);
|
||||
}
|
||||
};
|
||||
|
@ -1131,7 +1162,7 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
}
|
||||
else if (listener) {
|
||||
var items = this_.parseItems(
|
||||
icalRootComp, itemFilter, maxResult,
|
||||
icalRootComp, itemFilter, maxResults,
|
||||
rangeStart, rangeEnd);
|
||||
|
||||
if (CACHE_LAST_RESULTS > 0) {
|
||||
|
@ -1183,15 +1214,14 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
this_.m_cachedResults.length = CACHE_LAST_RESULTS;
|
||||
}
|
||||
|
||||
listener.onGetResult(
|
||||
this_.superCalendar,
|
||||
Components.results.NS_OK,
|
||||
Components.interfaces.calIItemBase,
|
||||
"getItems()", items.length, items);
|
||||
listener.onGetResult(this_.superCalendar, NS_OK, calIItemBase,
|
||||
"getItems()", items.length, items);
|
||||
}
|
||||
},
|
||||
stringToIcal, "fetchcomponents_by_range", params,
|
||||
calIWcapCalendar.AC_COMP_READ);
|
||||
stringToIcal,
|
||||
(itemFilter & calIWcapCalendar.ITEM_FILTER_BY_ALARM_RANGE)
|
||||
? "fetchcomponents_by_alarmrange" : "fetchcomponents_by_range",
|
||||
params, calIWcapCalendar.AC_COMP_READ);
|
||||
}
|
||||
catch (exc) {
|
||||
request.execRespFunc(exc);
|
||||
|
@ -1220,7 +1250,7 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
// function calWcapSyncOperationListener_onOperationComplete(
|
||||
// calendar, status, opType, id, detail)
|
||||
// {
|
||||
// if (status != Components.results.NS_OK) {
|
||||
// if (status != NS_OK) {
|
||||
// this.
|
||||
// this.m_syncState.abort( detail );
|
||||
// }
|
||||
|
@ -1260,6 +1290,10 @@ function calWcapCalendar_getItems(itemFilter, maxResult, rangeStart, rangeEnd, l
|
|||
calWcapCalendar.prototype.syncChangesTo =
|
||||
function calWcapCalendar_syncChangesTo(destCal, itemFilter, dtFrom_, listener)
|
||||
{
|
||||
// xxx todo: move to Thomas
|
||||
// do NOT puke up error box every three minutes!
|
||||
itemFilter |= calIWcapCalendar.ITEM_FILTER_SUPPRESS_ONERROR;
|
||||
|
||||
var now = getTime(); // new stamp for this sync
|
||||
var this_ = this;
|
||||
var request_ = new calWcapRequest(
|
||||
|
@ -1271,15 +1305,13 @@ function calWcapCalendar_syncChangesTo(destCal, itemFilter, dtFrom_, listener)
|
|||
this_.superCalendar, getResultCode(err),
|
||||
calIWcapCalendar.SYNC, null, err);
|
||||
}
|
||||
if (getResultCode(err) != calIWcapErrors.WCAP_LOGIN_FAILED) {
|
||||
this_.notifyError(err);
|
||||
}
|
||||
this_.notifyError(err, request.suppressOnError);
|
||||
}
|
||||
else {
|
||||
log("SYNC succeeded.", this_);
|
||||
if (listener) {
|
||||
listener.onOperationComplete(
|
||||
this_.superCalendar, Components.results.NS_OK,
|
||||
this_.superCalendar, NS_OK,
|
||||
calIWcapCalendar.SYNC, null, now);
|
||||
}
|
||||
}
|
||||
|
@ -1287,15 +1319,10 @@ function calWcapCalendar_syncChangesTo(destCal, itemFilter, dtFrom_, listener)
|
|||
log("syncChangesTo():\n\titemFilter=0x" + itemFilter.toString(0x10) +
|
||||
"\n\tdtFrom_=" + getIcalUTC(dtFrom_), this));
|
||||
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_SUPPRESS_ONERROR)
|
||||
request_.suppressOnError = true;
|
||||
|
||||
try {
|
||||
// xxx todo: better thomas handles this...
|
||||
// do NOT puke up error box every three minutes!
|
||||
// again in a few minutes...
|
||||
if (!this.session.isLoggedIn) {
|
||||
throw new Components.Exception("Login failed. Invalid session ID.",
|
||||
calIWcapErrors.WCAP_LOGIN_FAILED);
|
||||
}
|
||||
|
||||
var dtFrom = dtFrom_;
|
||||
if (dtFrom) {
|
||||
dtFrom = dtFrom.clone();
|
||||
|
|
|
@ -37,26 +37,18 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
var g_ioService = null;
|
||||
function getIoService()
|
||||
{
|
||||
if (!g_ioService) {
|
||||
g_ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
}
|
||||
return g_ioService;
|
||||
}
|
||||
|
||||
//
|
||||
// init code for globals, prefs:
|
||||
//
|
||||
|
||||
// constants:
|
||||
const NS_OK = Components.results.NS_OK;
|
||||
const nsIException = Components.interfaces.nsIException;
|
||||
const calIWcapSession = Components.interfaces.calIWcapSession;
|
||||
const calIWcapCalendar = Components.interfaces.calIWcapCalendar;
|
||||
const calIWcapErrors = Components.interfaces.calIWcapErrors;
|
||||
const calICalendar = Components.interfaces.calICalendar;
|
||||
const calIItemBase = Components.interfaces.calIItemBase;
|
||||
const calIOperationListener = Components.interfaces.calIOperationListener;
|
||||
|
||||
// ctors:
|
||||
|
@ -87,8 +79,17 @@ var CACHE_LAST_RESULTS_INVALIDATE = 120;
|
|||
// logging:
|
||||
var LOG_LEVEL = 0;
|
||||
|
||||
// whether alarms are by default turned on/off:
|
||||
var SUPPRESS_ALARMS = true;
|
||||
// whether alarms are turned on/off:
|
||||
var SUPPRESS_ALARMS = false;
|
||||
|
||||
var g_ioService = null;
|
||||
function getIoService() {
|
||||
if (!g_ioService) {
|
||||
g_ioService = Components.classes["@mozilla.org/network/io-service;1"]
|
||||
.getService(Components.interfaces.nsIIOService);
|
||||
}
|
||||
return g_ioService;
|
||||
}
|
||||
|
||||
function initWcapProvider()
|
||||
{
|
||||
|
@ -123,12 +124,9 @@ function initWcapProvider()
|
|||
initLogging();
|
||||
|
||||
// some string resources:
|
||||
g_privateItemTitle = getWcapBundle().GetStringFromName(
|
||||
"privateItem.title.text");
|
||||
g_confidentialItemTitle = getWcapBundle().GetStringFromName(
|
||||
"confidentialItem.title.text");
|
||||
g_busyItemTitle = getWcapBundle().GetStringFromName(
|
||||
"busyItem.title.text");
|
||||
g_privateItemTitle = getWcapBundle().GetStringFromName("privateItem.title.text");
|
||||
g_confidentialItemTitle = getWcapBundle().GetStringFromName("confidentialItem.title.text");
|
||||
g_busyItemTitle = getWcapBundle().GetStringFromName("busyItem.title.text");
|
||||
g_busyPhantomItemUuidPrefix = ("PHANTOM_uuid" + getTime().icalString);
|
||||
|
||||
SUPPRESS_ALARMS = getPref("calendar.wcap.suppress_alarms", true);
|
||||
|
@ -150,14 +148,13 @@ function initWcapProvider()
|
|||
var dirService = Components.classes["@mozilla.org/file/directory_service;1"]
|
||||
.getService(Components.interfaces.nsIProperties);
|
||||
cacheDir = dirService.get("ProfD", Components.interfaces.nsILocalFile);
|
||||
cacheDir.append( "wcap" );
|
||||
cacheDir.append("wcap");
|
||||
}
|
||||
CACHE_DIR = cacheDir;
|
||||
log(CACHE_DIR.path, "cache dir");
|
||||
if (!CACHE_DIR.exists()) {
|
||||
CACHE_DIR.create(
|
||||
Components.interfaces.nsIFile.DIRECTORY_TYPE,
|
||||
0700 /* read, write, execute/search by owner */ );
|
||||
CACHE_DIR.create(Components.interfaces.nsIFile.DIRECTORY_TYPE,
|
||||
0700 /* read, write, execute/search by owner */);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -65,7 +65,7 @@ function getErrorModule(rc) {
|
|||
const NS_ERROR_OFFLINE = generateNetFailure(16);
|
||||
|
||||
// The async request completed successfully.
|
||||
const NS_BINDING_SUCCEEDED = Components.results.NS_OK;
|
||||
const NS_BINDING_SUCCEEDED = NS_OK;
|
||||
|
||||
const NS_BINDING_FAILED = generateNetFailure(1);
|
||||
const NS_BINDING_ABORTED = generateNetFailure(2);
|
||||
|
@ -136,8 +136,8 @@ function netErrorToString( rc )
|
|||
//
|
||||
|
||||
const g_wcapErrorCodes = [
|
||||
/* -1 */ Components.results.NS_OK, "Logout successful.",
|
||||
/* 0 */ Components.results.NS_OK, "Command successful.",
|
||||
/* -1 */ NS_OK, "Logout successful.",
|
||||
/* 0 */ NS_OK, "Command successful.",
|
||||
/* 1 */ calIWcapErrors.WCAP_LOGIN_FAILED, "Login failed. Invalid session ID.",
|
||||
/* 2 */ calIWcapErrors.WCAP_LOGIN_OK_DEFAULT_CALENDAR_NOT_FOUND, "login.wcap was successful, but the default calendar for this user was not found. A new default calendar set to the userid was created.",
|
||||
/* 3 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
|
@ -338,7 +338,7 @@ function checkWcapIcalErrno(icalRootComp, expectedErrno) {
|
|||
function getResultCode(err)
|
||||
{
|
||||
if (err === undefined || err === null)
|
||||
return Components.results.NS_OK;
|
||||
return NS_OK;
|
||||
if (isNaN(err)) {
|
||||
if (err instanceof nsIException)
|
||||
return err.result;
|
||||
|
@ -364,7 +364,7 @@ function errorToString(err)
|
|||
switch (err) {
|
||||
case undefined:
|
||||
case null:
|
||||
case Components.results.NS_OK:
|
||||
case NS_OK:
|
||||
return "NS_OK";
|
||||
case Components.results.NS_ERROR_INVALID_ARG:
|
||||
return "NS_ERROR_INVALID_ARG";
|
||||
|
|
|
@ -65,7 +65,7 @@ function calWcapRequest(respFunc, logContext) {
|
|||
this.m_logContext = logContext;
|
||||
this.m_id = generateRequestId();
|
||||
this.m_isPending = true;
|
||||
this.m_status = Components.results.NS_OK;
|
||||
this.m_status = NS_OK;
|
||||
this.m_respFunc = respFunc;
|
||||
this.m_attachedRequests = [];
|
||||
}
|
||||
|
@ -74,7 +74,7 @@ calWcapRequest.prototype = {
|
|||
m_parentRequest: null,
|
||||
m_id: 0,
|
||||
m_isPending: true,
|
||||
m_status: Components.results.NS_OK,
|
||||
m_status: NS_OK,
|
||||
m_respFunc: null,
|
||||
m_attachedRequests: null,
|
||||
m_locked: false,
|
||||
|
@ -84,7 +84,7 @@ calWcapRequest.prototype = {
|
|||
if (this.parentRequest)
|
||||
logError("already has parent!", this);
|
||||
this.detachFromParent(); // detach without error
|
||||
this.m_parentRequest = req;
|
||||
return (this.m_parentRequest = req);
|
||||
},
|
||||
|
||||
/** The following locking is necessary when scheduling multiple async
|
||||
|
@ -199,12 +199,10 @@ calWcapRequest.prototype = {
|
|||
return this.m_isPending;
|
||||
},
|
||||
get succeeded() {
|
||||
return (!this.isPending &&
|
||||
getResultCode(this.status) == Components.results.NS_OK);
|
||||
return (!this.isPending && Components.isSuccessCode( getResultCode(this.status) ));
|
||||
},
|
||||
get status() {
|
||||
return (this.m_status === null ? Components.results.NS_OK
|
||||
: this.m_status);
|
||||
return (this.m_status === null ? NS_OK : this.m_status);
|
||||
},
|
||||
|
||||
cancel: function calWcapRequest_cancel(status)
|
||||
|
@ -256,7 +254,7 @@ calWcapNetworkRequest.prototype = {
|
|||
if (this.parentRequest)
|
||||
logError("already has parent!", this);
|
||||
this.detachFromParent(); // detach without error
|
||||
this.m_parentRequest = req;
|
||||
return (this.m_parentRequest = req);
|
||||
},
|
||||
|
||||
get id() {
|
||||
|
|
|
@ -102,31 +102,53 @@ calWcapSession.prototype = {
|
|||
}
|
||||
return str;
|
||||
},
|
||||
notifyError: function calWcapSession_notifyError(err)
|
||||
notifyError: function calWcapSession_notifyError(err, suppressOnError)
|
||||
{
|
||||
debugger;
|
||||
var msg = logError(err, this);
|
||||
this.notifyObservers(
|
||||
"onError",
|
||||
err instanceof Components.interfaces.nsIException
|
||||
? [err.result, err.message] : [isNaN(err) ? -1 : err, msg] );
|
||||
if (!suppressOnError) {
|
||||
this.notifyObservers(
|
||||
"onError",
|
||||
err instanceof Components.interfaces.nsIException
|
||||
? [err.result, err.message] : [isNaN(err) ? -1 : err, msg]);
|
||||
}
|
||||
},
|
||||
|
||||
m_lastOnErrorTime: 0,
|
||||
m_lastOnErrorNo: 0,
|
||||
m_lastOnErrorMsg: null,
|
||||
|
||||
m_observers: null,
|
||||
notifyObservers: function calWcapSession_notifyObservers(func, args)
|
||||
{
|
||||
if (!g_bShutdown) {
|
||||
this.m_observers.forEach(
|
||||
function notifyFunc(obj) {
|
||||
try {
|
||||
obj[func].apply(obj, args);
|
||||
}
|
||||
catch (exc) {
|
||||
// don't call notifyError() here:
|
||||
Components.utils.reportError(exc);
|
||||
}
|
||||
});
|
||||
if (g_bShutdown)
|
||||
return;
|
||||
|
||||
// xxx todo: hack
|
||||
// suppress identical error bursts when multiple similar calls eg on getItems() fail.
|
||||
if (func == "onError") {
|
||||
var now = (new Date()).getTime();
|
||||
if ((now - this.m_lastOnError) < 2000 &&
|
||||
(args[0] == this.m_lastOnErrorNo) &&
|
||||
(args[1] == this.m_lastOnErrorMsg)) {
|
||||
log("suppressing calIObserver::onError.", this);
|
||||
return;
|
||||
}
|
||||
this.m_lastOnError = now;
|
||||
this.m_lastOnErrorNo = args[0];
|
||||
this.m_lastOnErrorMsg = args[1];
|
||||
}
|
||||
|
||||
this.m_observers.forEach(
|
||||
function notifyFunc(obj) {
|
||||
try {
|
||||
obj[func].apply(obj, args);
|
||||
}
|
||||
catch (exc) {
|
||||
// don't call notifyError() here:
|
||||
Components.utils.reportError(exc);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
addObserver: function calWcapSession_addObserver(observer)
|
||||
|
@ -187,7 +209,11 @@ calWcapSession.prototype = {
|
|||
", length: " + this.m_loginQueue.length, this);
|
||||
|
||||
if (this.m_loginLock) {
|
||||
this.m_loginQueue.push(respFunc);
|
||||
var entry = {
|
||||
request: request,
|
||||
respFunc: respFunc
|
||||
};
|
||||
this.m_loginQueue.push(entry);
|
||||
log("login queue: " + this.m_loginQueue.length);
|
||||
}
|
||||
else {
|
||||
|
@ -210,10 +236,7 @@ calWcapSession.prototype = {
|
|||
function getSessionId_resp(err, sessionId) {
|
||||
log("getSessionId_resp(): " + sessionId, this_);
|
||||
if (err) {
|
||||
if (getResultCode(err) == calIWcapErrors.WCAP_LOGIN_FAILED) {
|
||||
// notify login failures once here only:
|
||||
this_.notifyError(err);
|
||||
}
|
||||
this_.notifyError(err, request.suppressOnError);
|
||||
}
|
||||
else {
|
||||
this_.m_sessionId = sessionId;
|
||||
|
@ -224,11 +247,15 @@ calWcapSession.prototype = {
|
|||
this_.m_loginQueue = [];
|
||||
log("unlocked login queue.", this_);
|
||||
|
||||
// first request:
|
||||
respFunc(err, sessionId);
|
||||
// dequeue remaining:
|
||||
if (request.isPending) {
|
||||
// answere first request:
|
||||
respFunc(err, sessionId);
|
||||
}
|
||||
// and any remaining:
|
||||
while (queue.length > 0) {
|
||||
queue.shift()(err, sessionId);
|
||||
var entry = queue.shift();
|
||||
if (entry.request.isPending)
|
||||
entry.respFunc(err, sessionId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -302,8 +329,9 @@ calWcapSession.prototype = {
|
|||
if (prompt.promptUsernameAndPassword(
|
||||
getWcapBundle().GetStringFromName("loginDialog.label"),
|
||||
loginText, outUser, outPW,
|
||||
getWcapBundle().GetStringFromName("loginDialog.check.text"),
|
||||
outSavePW)) {
|
||||
getPref("signon.rememberSignons", true)
|
||||
? getWcapBundle().GetStringFromName("loginDialog.check.text")
|
||||
: null, outSavePW)) {
|
||||
this_.login(request, promptAndLoginLoop_resp,
|
||||
outUser.value, outPW.value);
|
||||
}
|
||||
|
@ -320,13 +348,12 @@ calWcapSession.prototype = {
|
|||
if (outSavePW.value) {
|
||||
// so try to remove old pw from db first:
|
||||
try {
|
||||
passwordManager.removeUser(
|
||||
pwHost, outUser.value);
|
||||
passwordManager.removeUser(pwHost, outUser.value);
|
||||
log("removed from pw db: " + pwHost, this_);
|
||||
}
|
||||
catch (exc) {
|
||||
}
|
||||
try { // save pw under session uri:
|
||||
try { // to save pw under session uri:
|
||||
passwordManager.addUser(pwHost, outUser.value, outPW.value);
|
||||
log("added to pw db: " + pwHost, this_);
|
||||
}
|
||||
|
@ -336,12 +363,11 @@ calWcapSession.prototype = {
|
|||
}
|
||||
this_.credentials.userId = outUser.value;
|
||||
this_.credentials.pw = outPW.value;
|
||||
this_.setupSession(
|
||||
sessionId,
|
||||
request,
|
||||
function setupSession_resp(err) {
|
||||
respFunc(err, sessionId);
|
||||
});
|
||||
this_.setupSession(sessionId,
|
||||
request,
|
||||
function setupSession_resp(err) {
|
||||
respFunc(err, sessionId);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -554,8 +580,8 @@ calWcapSession.prototype = {
|
|||
this_.defaultCalendar.m_calProps = data;
|
||||
log("installed default cal props.", this_);
|
||||
},
|
||||
stringToXml, "get_calprops",
|
||||
"&fmt-out=text%2Fxml&calid=" +
|
||||
stringToXml, "search_calprops",
|
||||
"&fmt-out=text%2Fxml&searchOpts=3&calid=1&search-string=" +
|
||||
encodeURIComponent(this_.defaultCalId),
|
||||
sessionId);
|
||||
if (getPref("calendar.wcap.subscriptions", false))
|
||||
|
@ -634,65 +660,61 @@ calWcapSession.prototype = {
|
|||
// user may have dangling users referred in his subscription list, so
|
||||
// retrieve each by each, don't break:
|
||||
var list = this.getUserPreferences("X-NSCP-WCAP-PREF-icsSubscribed");
|
||||
for each( var item in list ) {
|
||||
var calIds = {};
|
||||
for each (var item in list) {
|
||||
var ar = item.split(',');
|
||||
// ',', '$' are not encoded. ',' can be handled here. WTF.
|
||||
for each ( var a in ar ) {
|
||||
for each (var a in ar) {
|
||||
var dollar = a.indexOf('$');
|
||||
if (dollar >= 0) {
|
||||
var calId = a.substring(0, dollar);
|
||||
if (calId == this.defaultCalId)
|
||||
continue;
|
||||
try {
|
||||
var key = encodeURIComponent(calId);
|
||||
var cal = this_.m_subscribedCals[key];
|
||||
if (!cal) {
|
||||
this.issueNetworkRequest_(
|
||||
request,
|
||||
function calprops_resp(err, xml) {
|
||||
try {
|
||||
if (err)
|
||||
throw err;
|
||||
var cal = createWcapCalendar(this_, xml);
|
||||
this_.m_subscribedCals[encodeURIComponent(cal.calId)] = cal;
|
||||
getCalendarManager().registerCalendar(cal);
|
||||
log("installed subscribed calendar: " + cal.calId, this_);
|
||||
}
|
||||
catch (exc) {
|
||||
// ignore but log any errors on subscribed calendars:
|
||||
logError(exc, this_);
|
||||
}
|
||||
},
|
||||
stringToXml, "get_calprops",
|
||||
"&fmt-out=text%2Fxml&calid=" + key,
|
||||
sessionId);
|
||||
// var listener = {
|
||||
// onRequestResult: function onRequestResult(request, result) {
|
||||
// try {
|
||||
// if (!request.succeeded)
|
||||
// throw request.status;
|
||||
// if (result.length < 1)
|
||||
// throw Components.results.NS_ERROR_UNEXPECTED;
|
||||
// var cal = result[0];
|
||||
// getCalendarManager().registerCalendar(cal);
|
||||
// log("installed subscribed calendar: " + cal.calId,
|
||||
// this_);
|
||||
// }
|
||||
// catch (exc) {
|
||||
// logError(exc, this_);
|
||||
// }
|
||||
// }
|
||||
// };
|
||||
// this.searchForCalendars(
|
||||
// calId,
|
||||
// calIWcapSession.SEARCH_STRING_EXACT |
|
||||
// calIWcapSession.SEARCH_INCLUDE_CALID,
|
||||
// listener);
|
||||
if (calId != this.defaultCalId)
|
||||
calIds[calId] = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
var issuedSearchRequests = {};
|
||||
for (var calId in calIds) {
|
||||
if (!this_.m_subscribedCals[calId]) {
|
||||
var listener = {
|
||||
onRequestResult: function search_onRequestResult(request, result) {
|
||||
try {
|
||||
if (!request.succeeded)
|
||||
throw request.status;
|
||||
if (result.length < 1)
|
||||
throw Components.results.NS_ERROR_UNEXPECTED;
|
||||
for each (var cal in result) {
|
||||
try {
|
||||
var calId = cal.calId;
|
||||
if (calIds[calId] && !this_.m_subscribedCals[calId]) {
|
||||
this_.m_subscribedCals[calId] = cal;
|
||||
getCalendarManager().registerCalendar(cal);
|
||||
log("installed subscribed calendar: " + calId, this_);
|
||||
}
|
||||
}
|
||||
catch (exc) { // ignore but log any errors on subscribed calendars:
|
||||
logError(exc, this_);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (exc) { // ignore but log any errors on subscribed calendars:
|
||||
logError(exc, this_);
|
||||
}
|
||||
}
|
||||
catch (exc) { // ignore but log any errors on subscribed calendars:
|
||||
logError(exc, this);
|
||||
}
|
||||
};
|
||||
|
||||
var colon = calId.indexOf(':');
|
||||
if (colon >= 0) // searching for secondary calendars doesn't work. WTF.
|
||||
calId = calId.substring(0, colon);
|
||||
if (!issuedSearchRequests[calId]) {
|
||||
issuedSearchRequests[calId] = true;
|
||||
this.searchForCalendars(
|
||||
calId,
|
||||
calIWcapSession.SEARCH_STRING_EXACT |
|
||||
calIWcapSession.SEARCH_INCLUDE_CALID |
|
||||
// else searching for secondary calendars doesn't work:
|
||||
calIWcapSession.SEARCH_INCLUDE_OWNER,
|
||||
20, listener);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -789,6 +811,7 @@ calWcapSession.prototype = {
|
|||
log("set uri: " + this.uri.spec, this);
|
||||
}
|
||||
}
|
||||
return thatUri;
|
||||
},
|
||||
|
||||
get userId() { return this.credentials.userId; },
|
||||
|
@ -837,7 +860,7 @@ calWcapSession.prototype = {
|
|||
var ret = [];
|
||||
var ar = this.getUserPreferences("X-NSCP-WCAP-PREF-ceDefaultAlarmEmail");
|
||||
if (ar.length > 0 && ar[0].length > 0) {
|
||||
for each ( var i in ar ) {
|
||||
for each (var i in ar) {
|
||||
ret = ret.concat( i.split(/[;,]/).map(trimString) );
|
||||
}
|
||||
}
|
||||
|
@ -846,7 +869,7 @@ calWcapSession.prototype = {
|
|||
},
|
||||
|
||||
searchForCalendars:
|
||||
function calWcapSession_searchForCalendars(searchString, searchOptions, listener)
|
||||
function calWcapSession_searchForCalendars(searchString, searchOptions, maxResults, listener)
|
||||
{
|
||||
var this_ = this;
|
||||
var request = new calWcapRequest(
|
||||
|
@ -862,6 +885,8 @@ calWcapSession.prototype = {
|
|||
var params = ("&fmt-out=text%2Fxml&search-string=" +
|
||||
encodeURIComponent(searchString));
|
||||
params += ("&searchOpts=" + (searchOptions & 3).toString(10));
|
||||
if (maxResults > 0)
|
||||
params += ("&maxResults=" + maxResults);
|
||||
if (searchOptions & calIWcapSession.SEARCH_INCLUDE_CALID)
|
||||
params += "&calid=1";
|
||||
if (searchOptions & calIWcapSession.SEARCH_INCLUDE_NAME)
|
||||
|
@ -890,7 +915,7 @@ calWcapSession.prototype = {
|
|||
var ar = filterXmlNodes("X-NSCP-CALPROPS-RELATIVE-CALID", node);
|
||||
if (ar.length > 0) {
|
||||
var calId = ar[0];
|
||||
var cal = this_.m_subscribedCals[encodeURIComponent(calId)];
|
||||
var cal = this_.m_subscribedCals[calId];
|
||||
if (!cal) {
|
||||
if (calId == this_.defaultCalId)
|
||||
cal = this_.defaultCalendar;
|
||||
|
@ -943,16 +968,16 @@ calWcapSession.prototype = {
|
|||
var this_ = this;
|
||||
var request = new calWcapRequest(
|
||||
function getFreeBusyTimes_resp(request, err, data) {
|
||||
switch (getResultCode(err)) {
|
||||
case Components.results.NS_OK:
|
||||
break;
|
||||
var rc = getResultCode(err);
|
||||
switch (rc) {
|
||||
case calIWcapErrors.WCAP_NO_ERRNO: // workaround
|
||||
case calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR:
|
||||
case calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST:
|
||||
log("getFreeBusyTimes_resp() error: " + errorToString(err), this_);
|
||||
break;
|
||||
default:
|
||||
this_.notifyError(err);
|
||||
if (!Components.isSuccessCode(rc))
|
||||
this_.notifyError(err);
|
||||
break;
|
||||
}
|
||||
if (listener)
|
||||
|
@ -1069,14 +1094,12 @@ calWcapSession.prototype = {
|
|||
cal = null;
|
||||
}
|
||||
try {
|
||||
// make sure the calendar belongs to this session:
|
||||
if (cal && cal.session.uri.equals(this.uri)) {
|
||||
if (!cal.isDefaultCalendar) {
|
||||
var key = encodeURIComponent(cal.calId);
|
||||
if (!this.m_subscribedCals[key])
|
||||
this.modifySubscriptions(cal, true/*bSubscibe*/);
|
||||
this.m_subscribedCals[key] = cal;
|
||||
}
|
||||
// make sure the calendar belongs to this session and is a subscription:
|
||||
if (cal && cal.session.uri.equals(this.uri) && !cal.isDefaultCalendar) {
|
||||
var calId = cal.calId;
|
||||
if (!this.m_subscribedCals[calId])
|
||||
this.modifySubscriptions(cal, true/*bSubscibe*/);
|
||||
this.m_subscribedCals[calId] = cal;
|
||||
}
|
||||
}
|
||||
catch (exc) { // never break the listener chain
|
||||
|
@ -1094,18 +1117,13 @@ calWcapSession.prototype = {
|
|||
cal = null;
|
||||
}
|
||||
try {
|
||||
// make sure the calendar belongs to this session:
|
||||
if (cal && cal.session.uri.equals(this.uri)) {
|
||||
if (cal.isDefaultCalendar) {
|
||||
// whole account is being removed, so logout before:
|
||||
this.logout(null);
|
||||
}
|
||||
else {
|
||||
var key = encodeURIComponent(cal.calId);
|
||||
if (this.m_subscribedCals[key]) {
|
||||
delete this.m_subscribedCals[key];
|
||||
this.modifySubscriptions(cal, false/*bSubscibe*/);
|
||||
}
|
||||
// don't logout here (even if this is the default calendar): upcoming calls may occur.
|
||||
// make sure the calendar belongs to this session and is a subscription:
|
||||
if (cal && cal.session.uri.equals(this.uri) && !cal.isDefaultCalendar) {
|
||||
var calId = cal.calId;
|
||||
if (this.m_subscribedCals[calId]) {
|
||||
delete this.m_subscribedCals[calId];
|
||||
this.modifySubscriptions(cal, false/*bSubscibe*/);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -244,13 +244,12 @@ function isEvent(item) {
|
|||
|
||||
function isParent(item) {
|
||||
if (item.id != item.parentItem.id) {
|
||||
throw new Components.Exception(
|
||||
"proxy has different id than its parent!");
|
||||
throw new Components.Exception("proxy has different id than its parent!");
|
||||
}
|
||||
return (!item.recurrenceId);
|
||||
}
|
||||
|
||||
function forEachIcalComponent(icalRootComp, componentType, func, maxResult)
|
||||
function forEachIcalComponent(icalRootComp, componentType, func, maxResults)
|
||||
{
|
||||
var itemCount = 0;
|
||||
// libical returns the vcalendar component if there is just
|
||||
|
@ -260,11 +259,11 @@ function forEachIcalComponent(icalRootComp, componentType, func, maxResult)
|
|||
for ( var calComp = (icalRootComp.componentType == "VCALENDAR"
|
||||
? icalRootComp
|
||||
: icalRootComp.getFirstSubcomponent("VCALENDAR"));
|
||||
calComp != null && (!maxResult || itemCount < maxResult);
|
||||
calComp != null && (!maxResults || itemCount < maxResults);
|
||||
calComp = icalRootComp.getNextSubcomponent("VCALENDAR") )
|
||||
{
|
||||
for ( var subComp = calComp.getFirstSubcomponent(componentType);
|
||||
subComp != null && (!maxResult || itemCount < maxResult);
|
||||
subComp != null && (!maxResults || itemCount < maxResults);
|
||||
subComp = calComp.getNextSubcomponent(componentType) )
|
||||
{
|
||||
func( subComp );
|
||||
|
@ -278,7 +277,7 @@ function filterXmlNodes(name, rootNode)
|
|||
var ret = [];
|
||||
if (rootNode) {
|
||||
var nodeList = rootNode.getElementsByTagName(name);
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
for (var i = 0; i < nodeList.length; ++i) {
|
||||
var node = nodeList.item(i);
|
||||
ret.push( trimString(node.textContent) );
|
||||
}
|
||||
|
@ -287,7 +286,7 @@ function filterXmlNodes(name, rootNode)
|
|||
}
|
||||
|
||||
function trimString(str) {
|
||||
return str.replace( /(^\s+|\s+$)/g, "" );
|
||||
return str.replace(/(^\s+|\s+$)/g, "");
|
||||
}
|
||||
|
||||
function getTime() {
|
||||
|
|
|
@ -142,6 +142,13 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/* xxx todo: limit to currently needed ones: NEEDS-ACTION */
|
||||
|
||||
/**
|
||||
* Scope: getItems only
|
||||
* Whether getItems should only return items that have alarms set for the
|
||||
* specified range.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_BY_ALARM_RANGE = 1 << 23;
|
||||
|
||||
// /**
|
||||
// * Scope: Attendee
|
||||
// * The event or todo is an invitation from another
|
||||
|
@ -192,6 +199,7 @@ interface calIWcapCalendar : calICalendar
|
|||
// */
|
||||
// const unsigned long ITEM_FILTER_REQUEST_WAITFORREPLY = 1 << 30;
|
||||
|
||||
const unsigned long ITEM_FILTER_SUPPRESS_ONERROR = 1 << 31;
|
||||
|
||||
/* xxx todo sync feature: separate into own interface? */
|
||||
/** xxx todo: to be moved to calIOperationListener?
|
||||
|
|
|
@ -88,16 +88,17 @@ interface calIWcapSession : nsISupports
|
|||
* Searches for calendars matching the specified searchString.
|
||||
* Results are notified to the passed listener instance as
|
||||
* an array of calendar instances.
|
||||
* The maximum returned count of calendars
|
||||
* (with respect to Sun calendar servers) is limited to 200.
|
||||
*
|
||||
* @param searchString the search string to match
|
||||
* @param searchOptions the search options
|
||||
* @param maxResults maximum number of results
|
||||
* (0 means default, e.g. 200 with respect to Sun calendar servers)
|
||||
* @param listener listener called with an array of calIWcapCalendar objects
|
||||
* @return request object to track operation
|
||||
*/
|
||||
calIWcapRequest searchForCalendars(in string searchString,
|
||||
in unsigned long searchOptions,
|
||||
in unsigned long maxResults,
|
||||
in calIWcapRequestResultListener listener);
|
||||
|
||||
/* xxx todo freebusy: separate into own interface? */
|
||||
|
|
Загрузка…
Ссылка в новой задаче