зеркало из https://github.com/mozilla/gecko-dev.git
improved error handling, added getCalendarProperties, added item filters, fixed task complete status, more wcap error codes, revised free-busy listener
This commit is contained in:
Родитель
791743405c
Коммит
99eaaaada9
|
@ -131,7 +131,7 @@ calWcapCachedCalendar.prototype = {
|
|||
// xxx todo: better eoncoding?
|
||||
var key = this.getCalKey();
|
||||
var cal = g_localCals[key];
|
||||
if (! cal) {
|
||||
if (!cal) {
|
||||
this.log( "creating cache calendar for calId " + this.calId );
|
||||
var uri;
|
||||
if (CACHE == "memory") { // in-memory caching
|
||||
|
|
|
@ -118,18 +118,7 @@ calWcapCalendar.prototype = {
|
|||
logError:
|
||||
function( err, context )
|
||||
{
|
||||
var str = "error: ";
|
||||
if (err instanceof Error) {
|
||||
str += err.message;
|
||||
}
|
||||
else {
|
||||
try {
|
||||
str += getWcapErrorCodeString(err);
|
||||
}
|
||||
catch (exc) {
|
||||
str += ("[" + err + "] Unknown error code.");
|
||||
}
|
||||
}
|
||||
var str = ("error: " + errorToString(err));
|
||||
Components.utils.reportError( this.log( str, context ) );
|
||||
return str;
|
||||
},
|
||||
|
@ -251,44 +240,36 @@ calWcapCalendar.prototype = {
|
|||
},
|
||||
|
||||
issueRequest:
|
||||
function( url, issueFunc, dataConvFunc, receiverFunc, ignoredWcapErrors )
|
||||
function( url, issueFunc, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var sessionId = this.session.getSessionId();
|
||||
if (sessionId == null)
|
||||
return; // return silently, ignore error
|
||||
|
||||
var this_ = this;
|
||||
issueFunc(
|
||||
url + ("&id=" + sessionId),
|
||||
function( utf8Data ) {
|
||||
function( data ) {
|
||||
var wcapResponse = new WcapResponse();
|
||||
try {
|
||||
var errno = dataConvFunc( utf8Data, wcapResponse );
|
||||
if (errno == 1) {
|
||||
sessionId = this_.session.getSessionId(
|
||||
sessionId /* timed-out session */ );
|
||||
if (sessionId != null) {
|
||||
try {
|
||||
wcapResponse.data = dataConvFunc(
|
||||
data, wcapResponse );
|
||||
}
|
||||
catch (exc) {
|
||||
if (exc == Components.interfaces.
|
||||
calIWcapErrors.WCAP_LOGIN_FAILED) /* timeout */ {
|
||||
// getting a new session will throw any exception in
|
||||
// this block, thus it is notified into receiverFunc
|
||||
this_.session.getSessionId(
|
||||
sessionId /* (old) timed-out session */ );
|
||||
// try again:
|
||||
this_.issueRequest(
|
||||
url, issueFunc, dataConvFunc,
|
||||
receiverFunc, ignoredWcapErrors );
|
||||
url, issueFunc, dataConvFunc, receiverFunc );
|
||||
return;
|
||||
} // else notify error
|
||||
}
|
||||
else if (ignoredWcapErrors) {
|
||||
for each ( var err in ignoredWcapErrors ) {
|
||||
if (err == errno) {
|
||||
errno = 0; // patch to OK
|
||||
break;
|
||||
}
|
||||
}
|
||||
throw exc; // rethrow
|
||||
}
|
||||
checkWcapErrno( errno );
|
||||
}
|
||||
catch (exc) {
|
||||
this_.logError(
|
||||
"issueRequest(): exception occured upon response\n" +
|
||||
utf8Data );
|
||||
// setting the request's exception will rethrow exception
|
||||
// when request's data is retrieved.
|
||||
wcapResponse.exception = exc;
|
||||
|
@ -297,24 +278,24 @@ calWcapCalendar.prototype = {
|
|||
} );
|
||||
},
|
||||
issueAsyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc, ignoredWcapErrors )
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
this.issueRequest( url, issueAsyncUtf8Request,
|
||||
dataConvFunc, receiverFunc, ignoredWcapErrors );
|
||||
this.issueRequest(
|
||||
url, issueAsyncRequest, dataConvFunc, receiverFunc );
|
||||
},
|
||||
issueSyncRequest:
|
||||
function( url, dataConvFunc, receiverFunc, ignoredWcapErrors )
|
||||
function( url, dataConvFunc, receiverFunc )
|
||||
{
|
||||
var ret;
|
||||
var ret = null;
|
||||
this.issueRequest(
|
||||
url, issueSyncUtf8Request,
|
||||
url, issueSyncRequest,
|
||||
dataConvFunc,
|
||||
function( wcapResponse ) {
|
||||
ret = wcapResponse;
|
||||
if (receiverFunc) {
|
||||
receiverFunc( wcapResponse );
|
||||
}
|
||||
}, ignoredWcapErrors );
|
||||
ret = wcapResponse.data; // may throw
|
||||
} );
|
||||
return ret;
|
||||
},
|
||||
|
||||
|
@ -331,7 +312,7 @@ calWcapCalendar.prototype = {
|
|||
getWcapErrorString:
|
||||
function( rc )
|
||||
{
|
||||
return getWcapErrorCodeString(rc);
|
||||
return wcapErrorToString(rc);
|
||||
},
|
||||
|
||||
// xxx todo: which userId is used when for offline scheduling?
|
||||
|
@ -352,61 +333,64 @@ calWcapCalendar.prototype = {
|
|||
this.calId.indexOf(this.userId + ":") == 0);
|
||||
},
|
||||
|
||||
ensureOnline:
|
||||
function()
|
||||
{
|
||||
if (getIoService().offline) {
|
||||
// Cannot perform operation, because user is offline.
|
||||
// This has been taken from netwerk/base/public/nsNetError.h
|
||||
// and ought to be defined in IDL.
|
||||
throw ((1<<31) | ((6+0x45)<<16) | 16);
|
||||
}
|
||||
},
|
||||
|
||||
createCalendar:
|
||||
function( calId, name, bAllowDoubleBooking, bSetCalProps, bAddToSubscribed )
|
||||
{
|
||||
this.ensureOnline();
|
||||
var url = this.getCommandUrl( "createcalendar" );
|
||||
url += ("&allowdoublebook=" + (bAllowDoubleBooking ? "1" : "0"));
|
||||
url += ("&set_calprops=" + (bSetCalProps ? "1" : "0"));
|
||||
url += ("&subscribe=" + (bAddToSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
url += ("&name=" + encodeURIComponent(name)); // xxx todo: undocumented!
|
||||
// xxx todo: what about categories param???
|
||||
var xml = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml ).data;
|
||||
return (this.userId + ":" + calId);
|
||||
try {
|
||||
var url = this.getCommandUrl( "createcalendar" );
|
||||
url += ("&allowdoublebook=" + (bAllowDoubleBooking ? "1" : "0"));
|
||||
url += ("&set_calprops=" + (bSetCalProps ? "1" : "0"));
|
||||
url += ("&subscribe=" + (bAddToSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
// xxx todo: name undocumented!
|
||||
url += ("&name=" + encodeURIComponent(name));
|
||||
// xxx todo: what about categories param???
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
return (this.userId + ":" + calId);
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
deleteCalendar:
|
||||
function( calId, bRemoveFromSubscribed )
|
||||
{
|
||||
this.ensureOnline();
|
||||
var url = this.getCommandUrl( "deletecalendar" );
|
||||
url += ("&unsubscribe=" + (bRemoveFromSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml ).data;
|
||||
try {
|
||||
var url = this.getCommandUrl( "deletecalendar" );
|
||||
url += ("&unsubscribe=" + (bRemoveFromSubscribed ? "1" : "0"));
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
getCalIds:
|
||||
function( out_count, bGetOwnedCals )
|
||||
{
|
||||
this.ensureOnline();
|
||||
var url = this.getCommandUrl(
|
||||
bGetOwnedCals ? "list" : "list_subscribed" );
|
||||
var ret = [];
|
||||
var xml = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml ).data;
|
||||
var nodeList = xml.getElementsByTagName(
|
||||
bGetOwnedCals ? "X-S1CS-CALPROPS-OWNED-CALENDAR"
|
||||
: "X-S1CS-CALPROPS-SUBSCRIBED-CALENDAR" );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
try {
|
||||
var url = this.getCommandUrl(
|
||||
bGetOwnedCals ? "list" : "list_subscribed" );
|
||||
var ret = [];
|
||||
var xml = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
var nodeList = xml.getElementsByTagName(
|
||||
bGetOwnedCals ? "X-S1CS-CALPROPS-OWNED-CALENDAR"
|
||||
: "X-S1CS-CALPROPS-SUBSCRIBED-CALENDAR" );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
},
|
||||
|
||||
getOwnedCalendars:
|
||||
|
@ -424,18 +408,22 @@ calWcapCalendar.prototype = {
|
|||
modifyCalendarSubscriptions:
|
||||
function( calIds, bSubscribe )
|
||||
{
|
||||
this.ensureOnline();
|
||||
var url = this.getCommandUrl(
|
||||
bSubscribe ? "subscribe_calendars" : "unsubscribe_calendars" );
|
||||
var calId = "";
|
||||
for ( var i = 0; i < calIds.length; ++i ) {
|
||||
if (i > 0)
|
||||
calId += ";";
|
||||
calId += encodeURIComponent(calIds[i]);
|
||||
try {
|
||||
var url = this.getCommandUrl(
|
||||
bSubscribe ? "subscribe_calendars" : "unsubscribe_calendars" );
|
||||
var calId = "";
|
||||
for ( var i = 0; i < calIds.length; ++i ) {
|
||||
if (i > 0)
|
||||
calId += ";";
|
||||
calId += encodeURIComponent(calIds[i]);
|
||||
}
|
||||
url += ("&calid=" + calId);
|
||||
this.issueSyncRequest( url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
throw exc;
|
||||
}
|
||||
url += ("&calid=" + calId);
|
||||
var xml = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml ).data;
|
||||
},
|
||||
|
||||
subscribeToCalendars:
|
||||
|
@ -455,9 +443,7 @@ calWcapCalendar.prototype = {
|
|||
{
|
||||
try {
|
||||
var xml = wcapResponse.data; // first statement, may throw
|
||||
// don't notify if one of ignored errors: 28, 29
|
||||
var errno = getWcapXmlErrno(xml);
|
||||
if (errno == 0 && iListener != null) {
|
||||
if (iListener != null) {
|
||||
var ret = [];
|
||||
var nodeList = xml.getElementsByTagName("FB");
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
|
@ -478,6 +464,7 @@ calWcapCalendar.prototype = {
|
|||
ret.push( entry );
|
||||
}
|
||||
iListener.onGetFreeBusyTimes(
|
||||
Components.results.NS_OK,
|
||||
requestId, calId, ret.length, ret );
|
||||
}
|
||||
if (LOG_LEVEL > 0) {
|
||||
|
@ -486,7 +473,20 @@ calWcapCalendar.prototype = {
|
|||
}
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
const calIWcapErrors = Components.interfaces.calIWcapErrors;
|
||||
switch (exc) {
|
||||
case calIWcapErrors.WCAP_NO_ERRNO: // workaround
|
||||
case calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR:
|
||||
case calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST:
|
||||
this.log( "getFreeBusyTimes_resp() ignored: " +
|
||||
errorToString(exc) ); // no error
|
||||
break;
|
||||
default:
|
||||
this.notifyError( exc );
|
||||
break;
|
||||
}
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -494,21 +494,21 @@ calWcapCalendar.prototype = {
|
|||
function( calId, rangeStart, rangeEnd, bBusyOnly, iListener,
|
||||
bAsync, requestId )
|
||||
{
|
||||
this.ensureOnline();
|
||||
// assure DATETIMEs:
|
||||
if (rangeStart != null && rangeStart.isDate) {
|
||||
rangeStart = rangeStart.clone();
|
||||
rangeStart.isDate = false;
|
||||
}
|
||||
if (rangeEnd != null && rangeEnd.isDate) {
|
||||
rangeEnd = rangeEnd.clone();
|
||||
rangeEnd.isDate = false;
|
||||
}
|
||||
var zRangeStart = getIcalUTC(rangeStart);
|
||||
var zRangeEnd = getIcalUTC(rangeEnd);
|
||||
this.log( "getFreeBusyTimes():\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd );
|
||||
try {
|
||||
// assure DATETIMEs:
|
||||
if (rangeStart != null && rangeStart.isDate) {
|
||||
rangeStart = rangeStart.clone();
|
||||
rangeStart.isDate = false;
|
||||
}
|
||||
if (rangeEnd != null && rangeEnd.isDate) {
|
||||
rangeEnd = rangeEnd.clone();
|
||||
rangeEnd.isDate = false;
|
||||
}
|
||||
var zRangeStart = getIcalUTC(rangeStart);
|
||||
var zRangeEnd = getIcalUTC(rangeEnd);
|
||||
this.log( "getFreeBusyTimes():\n\trangeStart=" + zRangeStart +
|
||||
",\n\trangeEnd=" + zRangeEnd );
|
||||
|
||||
var url = this.getCommandUrl( "get_freebusy" );
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
url += ("&busyonly=" + (bBusyOnly ? "1" : "0"));
|
||||
|
@ -521,18 +521,42 @@ calWcapCalendar.prototype = {
|
|||
this_.getFreeBusyTimes_resp(
|
||||
wcapResponse, calId, iListener, requestId );
|
||||
}
|
||||
if (bAsync) {
|
||||
this.issueAsyncRequest(
|
||||
url, utf8ToXml, resp,
|
||||
[28 /* ignore ACCESS_DENIED_TO_CALENDAR */,
|
||||
29 /* ignore CALENDAR_DOES_NOT_EXIST */] );
|
||||
if (bAsync)
|
||||
this.issueAsyncRequest( url, stringToXml, resp );
|
||||
else
|
||||
this.issueSyncRequest( url, stringToXml, resp );
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
if (iListener != null)
|
||||
iListener.onGetFreeBusyTimes( exc, requestId, calId, 0, [] );
|
||||
throw exc;
|
||||
}
|
||||
},
|
||||
|
||||
m_calProps: null,
|
||||
m_calPropsCalid: null,
|
||||
getCalendarProperties:
|
||||
function( propName, calId, out_count )
|
||||
{
|
||||
try {
|
||||
if (calId.length == 0) {
|
||||
calId = this.calId;
|
||||
}
|
||||
else {
|
||||
this.issueSyncRequest(
|
||||
url, utf8ToXml, resp,
|
||||
[28 /* ignore ACCESS_DENIED_TO_CALENDAR */,
|
||||
29 /* ignore CALENDAR_DOES_NOT_EXIST */] );
|
||||
if (this.m_calPropsCalid != calId) {
|
||||
var url = this.getCommandUrl( "get_calprops" );
|
||||
url += ("&calid=" + encodeURIComponent(calId));
|
||||
this.m_calProps = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", stringToXml );
|
||||
this.m_calPropsCalid = calId;
|
||||
}
|
||||
var ret = [];
|
||||
var nodeList = this.m_calProps.getElementsByTagName( propName );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
}
|
||||
out_count.value = ret.length;
|
||||
return ret;
|
||||
}
|
||||
catch (exc) {
|
||||
this.notifyError( exc );
|
||||
|
@ -540,27 +564,8 @@ calWcapCalendar.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
// xxx todo: opt, need to separate by calId
|
||||
m_calProps: null,
|
||||
getCalProp:
|
||||
function( name )
|
||||
{
|
||||
this.ensureOnline();
|
||||
if (! this.m_calProps) {
|
||||
var url = this.getCommandUrl( "get_calprops" );
|
||||
this.m_calProps = this.issueSyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml ).data;
|
||||
}
|
||||
var ret = [];
|
||||
var nodeList = this.m_calProps.getElementsByTagName( name );
|
||||
for ( var i = 0; i < nodeList.length; ++i ) {
|
||||
ret.push( nodeList.item(i).textContent );
|
||||
}
|
||||
return ret;
|
||||
},
|
||||
|
||||
get defaultTimezone() {
|
||||
var tzid = this.getCalProp("X-NSCP-CALPROPS-TZID");
|
||||
var tzid = this.getCalendarProperties("X-NSCP-CALPROPS-TZID", "", {});
|
||||
if (tzid.length < 1) {
|
||||
return "UTC"; // fallback
|
||||
}
|
||||
|
@ -570,7 +575,6 @@ calWcapCalendar.prototype = {
|
|||
// set defaultTimezone( tzid ) {
|
||||
// if (this.readOnly)
|
||||
// throw Components.interfaces.calIErrors.CAL_IS_READONLY;
|
||||
// this.ensureOnline();
|
||||
// // xxx todo:
|
||||
// throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
// },
|
||||
|
|
|
@ -39,7 +39,7 @@
|
|||
|
||||
// xxx todo: just to avoid registration errors, how to do better?
|
||||
var calWcapCalendar;
|
||||
if (! calWcapCalendar) {
|
||||
if (!calWcapCalendar) {
|
||||
calWcapCalendar = {};
|
||||
calWcapCalendar.prototype = {};
|
||||
}
|
||||
|
@ -210,20 +210,22 @@ calWcapCalendar.prototype.getStoreUrl = function( item )
|
|||
url += ("&priority=" + item.priority);
|
||||
url += "&replace=1"; // (update) don't append to any lists
|
||||
url += ("&icsClass="+ ((item.privacy != null && item.privacy != "")
|
||||
? item.privacy
|
||||
: "PUBLIC"));
|
||||
url += "&status=";
|
||||
if (item.status != null) {
|
||||
? item.privacy : "PUBLIC"));
|
||||
if (!bIsEvent && item.isCompleted) {
|
||||
url += "&status=4"; // force to COMPLETED
|
||||
}
|
||||
else {
|
||||
switch (item.status) {
|
||||
case "CONFIRMED": url += "0"; break;
|
||||
case "CANCELLED": url += "1"; break;
|
||||
case "TENTATIVE": url += "2"; break;
|
||||
case "NEEDS-ACTION": url += "3"; break;
|
||||
case "COMPLETED": url += "4"; break;
|
||||
case "IN-PROCESS": url += "5"; break;
|
||||
case "DRAFT": url += "6"; break;
|
||||
case "FINAL": url += "7"; break;
|
||||
case "CONFIRMED": url += "&status=0"; break;
|
||||
case "CANCELLED": url += "&status=1"; break;
|
||||
case "TENTATIVE": url += "&status=2"; break;
|
||||
case "NEEDS-ACTION": url += "&status=3"; break;
|
||||
case "COMPLETED": url += "&status=4"; break;
|
||||
case "IN-PROCESS": url += "&status=5"; break;
|
||||
case "DRAFT": url += "&status=6"; break;
|
||||
case "FINAL": url += "&status=7"; break;
|
||||
default:
|
||||
url += "&status=3"; // NEEDS-ACTION
|
||||
this.logError( "getStoreUrl(): unexpected item status=" +
|
||||
item.status );
|
||||
break;
|
||||
|
@ -322,12 +324,12 @@ calWcapCalendar.prototype.getStoreUrl = function( item )
|
|||
// dtstart and due are mandatory for cs, so if those are
|
||||
// undefined, assume an allDay todo:
|
||||
dtstart = item.entryDate;
|
||||
if (! dtstart) {
|
||||
if (!dtstart) {
|
||||
dtstart = getTime();
|
||||
dtstart.isDate = true; // => all day
|
||||
}
|
||||
dtend = item.dueDate;
|
||||
if (! dtend) {
|
||||
if (!dtend) {
|
||||
// xxx todo:
|
||||
this.logError( "getStoreUrl(): no sensible default for due date!" );
|
||||
dtend = dtstart; // is due today
|
||||
|
@ -338,10 +340,18 @@ calWcapCalendar.prototype.getStoreUrl = function( item )
|
|||
// xxx todo: missing duration
|
||||
if (dtstart.isDate)
|
||||
url += "&isAllDay=1";
|
||||
url += ("&percent=" + item.percentComplete);
|
||||
url += "&complete=";
|
||||
if (item.isCompleted)
|
||||
url += "&percent=100";
|
||||
else
|
||||
url += ("&percent=" +
|
||||
(item.percentComplete ? item.percentComplete : "0"));
|
||||
url += "&completed=";
|
||||
if (item.completedDate != null)
|
||||
url += getIcalUTC(item.completedDate);
|
||||
else if (item.isCompleted)
|
||||
url += getIcalUTC(getTime()); // repair missing completedDate
|
||||
else
|
||||
url += "0"; // not yet completed
|
||||
// xxx todo: sentBy sentUID fields in cs: missing in cal api
|
||||
}
|
||||
|
||||
|
@ -419,11 +429,11 @@ calWcapCalendar.prototype.adoptItem_resp = function( wcapResponse, iListener )
|
|||
Components.interfaces.calICalendar.ITEM_FILTER_ALL_ITEMS,
|
||||
0, null, null );
|
||||
if (items.length < 1)
|
||||
throw new Error("no ical data!");
|
||||
throw new Error("empty VCALENDAR returned!");
|
||||
if (items.length > 1)
|
||||
this.notifyError( "unexpected number of items: " + items.length );
|
||||
item = items[0];
|
||||
|
||||
|
||||
this.log( "item.id=" + item.id );
|
||||
if (iListener != null) {
|
||||
iListener.onOperationComplete(
|
||||
|
@ -469,7 +479,7 @@ calWcapCalendar.prototype.adoptItem = function( item, iListener )
|
|||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", utf8ToIcal,
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.adoptItem_resp( wcapResponse, iListener );
|
||||
} );
|
||||
|
@ -492,9 +502,9 @@ calWcapCalendar.prototype.addItem = function( item, iListener )
|
|||
};
|
||||
|
||||
calWcapCalendar.prototype.modifyItem_resp = function(
|
||||
wcapResponse, oldItem, iListener )
|
||||
wcapResponse, newItem_, oldItem, iListener )
|
||||
{
|
||||
var item = null;
|
||||
var newItem = null;
|
||||
try {
|
||||
var icalRootComp = wcapResponse.data; // first statement, may throw
|
||||
|
||||
|
@ -504,17 +514,24 @@ calWcapCalendar.prototype.modifyItem_resp = function(
|
|||
0, null, null );
|
||||
if (items.length > 1)
|
||||
this.notifyError( "unexpected number of items: " + items.length );
|
||||
if (items.length < 1)
|
||||
throw new Error("empty VCALENDAR returned!");
|
||||
item = items[0];
|
||||
if (items.length < 1) {
|
||||
// however, sometimes socs just returns an empty calendar when
|
||||
// nothing has changed, although fetch=1.
|
||||
// This also occurs when the event organizer is in the attendees
|
||||
// list and switches its PARTSTAT too often... WTF.
|
||||
this.log( "empty VCALENDAR returned!" );
|
||||
newItem = newItem_; // fallback, assuming item has been written
|
||||
}
|
||||
else
|
||||
newItem = items[0];
|
||||
|
||||
if (iListener != null) {
|
||||
iListener.onOperationComplete(
|
||||
this.superCalendar, Components.results.NS_OK,
|
||||
Components.interfaces.calIOperationListener.MODIFY,
|
||||
item.id, item );
|
||||
newItem.id, newItem );
|
||||
}
|
||||
this.notifyObservers( "onModifyItem", [item, oldItem] );
|
||||
this.notifyObservers( "onModifyItem", [newItem, oldItem] );
|
||||
// xxx todo: maybe log request status
|
||||
}
|
||||
catch (exc) {
|
||||
|
@ -522,7 +539,7 @@ calWcapCalendar.prototype.modifyItem_resp = function(
|
|||
iListener.onOperationComplete(
|
||||
this.superCalendar, Components.results.NS_ERROR_FAILURE,
|
||||
Components.interfaces.calIOperationListener.MODIFY,
|
||||
item == null ? null : item.id, exc );
|
||||
newItem == null ? null : newItem.id, exc );
|
||||
}
|
||||
this.notifyError( exc );
|
||||
}
|
||||
|
@ -536,7 +553,7 @@ calWcapCalendar.prototype.modifyItem = function(
|
|||
throw Components.interfaces.calIErrors.CAL_IS_READONLY;
|
||||
|
||||
try {
|
||||
if (! newItem.id)
|
||||
if (!newItem.id)
|
||||
throw new Error("new item has no id!");
|
||||
|
||||
var url = this.getStoreUrl( newItem );
|
||||
|
@ -557,9 +574,10 @@ calWcapCalendar.prototype.modifyItem = function(
|
|||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", utf8ToIcal,
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.modifyItem_resp( wcapResponse, oldItem, iListener );
|
||||
this_.modifyItem_resp( wcapResponse,
|
||||
newItem, oldItem, iListener );
|
||||
} );
|
||||
}
|
||||
catch (exc) {
|
||||
|
@ -636,7 +654,7 @@ calWcapCalendar.prototype.deleteItem = function( item, iListener )
|
|||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fxml", utf8ToXml,
|
||||
url + "&fmt-out=text%2Fxml", stringToXml,
|
||||
function( wcapResponse ) {
|
||||
this_.deleteItem_resp( wcapResponse, item, iListener );
|
||||
} );
|
||||
|
@ -709,7 +727,7 @@ calWcapCalendar.prototype.parseItems = function(
|
|||
{
|
||||
case Components.interfaces.calICalendar
|
||||
.ITEM_FILTER_COMPLETED_YES:
|
||||
if (! item.isCompleted) {
|
||||
if (!item.isCompleted) {
|
||||
delete item;
|
||||
item = null;
|
||||
}
|
||||
|
@ -825,6 +843,71 @@ calWcapCalendar.prototype.parseItems = function(
|
|||
return items;
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getItem = function( id, iListener )
|
||||
{
|
||||
// xxx todo: test
|
||||
// xxx todo: howto detect whether to call
|
||||
// fetchevents_by_id ot fetchtodos_by_id?
|
||||
// currently drag/drop is implemented for events only,
|
||||
// try events first, fallback to todos... in the future...
|
||||
this.log( ">>>>>>>>>>>>>>>> getItem() call!");
|
||||
try {
|
||||
var this_ = this;
|
||||
var syncResponseFunc = function( wcapResponse ) {
|
||||
var icalRootComp = wcapResponse.data; // first statement, may throw
|
||||
var items = this_.parseItems(
|
||||
icalRootComp,
|
||||
Components.interfaces.calICalendar.ITEM_FILTER_ALL_ITEMS,
|
||||
1, null, null );
|
||||
if (items.length < 1)
|
||||
throw new Error("no such item!");
|
||||
if (items.length > 1) {
|
||||
this_.notifyError(
|
||||
"unexpected number of items: " + items.length );
|
||||
}
|
||||
item = items[0];
|
||||
if (iListener != null) {
|
||||
iListener.onGetResult(
|
||||
this_.superCalendar, Components.results.NS_OK,
|
||||
Components.interfaces.calIItemBase,
|
||||
this_.log( "getItems_resp(): success." ),
|
||||
items.length, items );
|
||||
iListener.onOperationComplete(
|
||||
this_.superCalendar, Components.results.NS_OK,
|
||||
Components.interfaces.calIOperationListener.GET,
|
||||
items.length == 1 ? items[0].id : null, null );
|
||||
}
|
||||
this_.log( "item delivered." );
|
||||
};
|
||||
|
||||
var params = "&compressed=1&recurring=1&fmt-out=text%2Fcalendar";
|
||||
params += ("&calid=" + encodeURIComponent(this.calId));
|
||||
params += ("&uid=" + id);
|
||||
try {
|
||||
// most common: event
|
||||
this.issueSyncRequest(
|
||||
this.getCommandUrl( "fetchevents_by_id" ) + params,
|
||||
stringToIcal, syncResponseFunc );
|
||||
}
|
||||
catch (exc) {
|
||||
// try again, may be a task:
|
||||
this.issueSyncRequest(
|
||||
this.getCommandUrl( "fetchtodos_by_id" ) + params,
|
||||
stringToIcal, syncResponseFunc );
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
if (iListener != null) {
|
||||
iListener.onOperationComplete(
|
||||
this.superCalendar, Components.results.NS_ERROR_FAILURE,
|
||||
Components.interfaces.calIOperationListener.GET,
|
||||
null, exc );
|
||||
}
|
||||
this.notifyError( exc );
|
||||
}
|
||||
this.log( "getItem() returning." );
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getItems_resp = function(
|
||||
wcapResponse,
|
||||
itemFilter, maxResult, rangeStart, rangeEnd, iListener )
|
||||
|
@ -858,48 +941,6 @@ calWcapCalendar.prototype.getItems_resp = function(
|
|||
}
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getItem = function( id, iListener )
|
||||
{
|
||||
// xxx todo: test
|
||||
// xxx todo: howto detect whether to call
|
||||
// fetchevents_by_id ot fetchtodos_by_id?
|
||||
// currently drag/drop is implemented for events only,
|
||||
// try events first, fallback to todos... in the future...
|
||||
this.log( ">>>>>>>>>>>>>>>> getItem() call!");
|
||||
try {
|
||||
var this_ = this;
|
||||
var respFunc = function( wcapResponse ) {
|
||||
this_.getItems_resp( wcapResponse,
|
||||
0, 1, null, null, iListener );
|
||||
};
|
||||
var params = "&compressed=1&recurring=1&fmt-out=text%2Fcalendar";
|
||||
params += ("&calid=" + encodeURIComponent(this.calId));
|
||||
params += ("&uid=" + id);
|
||||
try {
|
||||
// most common: event
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetchevents_by_id" ) + params,
|
||||
utf8ToIcal, respFunc );
|
||||
}
|
||||
catch (exc) {
|
||||
// try again, may be a task:
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetchtodos_by_id" ) + params,
|
||||
utf8ToIcal, respFunc );
|
||||
}
|
||||
}
|
||||
catch (exc) {
|
||||
if (iListener != null) {
|
||||
iListener.onOperationComplete(
|
||||
this.superCalendar, Components.results.NS_ERROR_FAILURE,
|
||||
Components.interfaces.calIOperationListener.GET,
|
||||
null, exc );
|
||||
}
|
||||
this.notifyError( exc );
|
||||
}
|
||||
this.log( "getItem() returning." );
|
||||
};
|
||||
|
||||
calWcapCalendar.prototype.getItems = function(
|
||||
itemFilter, maxResult, rangeStart, rangeEnd, iListener )
|
||||
{
|
||||
|
@ -931,6 +972,25 @@ calWcapCalendar.prototype.getItems = function(
|
|||
url += "&component-type=event"; break;
|
||||
}
|
||||
|
||||
const calIWcapCalendar = Components.interfaces.calIWcapCalendar;
|
||||
var compstate = "";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REPLY_DECLINED)
|
||||
compstate += ";REPLY-DECLINED";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REPLY_ACCEPTED)
|
||||
compstate += ";REPLY-ACCEPTED";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REQUEST_COMPLETED)
|
||||
compstate += ";REQUEST-COMPLETED";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REQUEST_NEEDS_ACTION)
|
||||
compstate += ";REQUEST-NEEDS-ACTION";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REQUEST_NEEDSNOACTION)
|
||||
compstate += ";REQUEST-NEEDSNOACTION";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REQUEST_PENDING)
|
||||
compstate += ";REQUEST-PENDING";
|
||||
if (itemFilter & calIWcapCalendar.ITEM_FILTER_REQUEST_WAITFORREPLY)
|
||||
compstate += ";REQUEST-WAITFORREPLY";
|
||||
if (compstate.length > 0)
|
||||
url += ("&compstate=" + compstate.substr(1));
|
||||
|
||||
if (maxResult > 0)
|
||||
url += ("&maxResult=" + maxResult);
|
||||
// xxx todo: correctly normalized dates to zulu time?
|
||||
|
@ -939,7 +999,7 @@ calWcapCalendar.prototype.getItems = function(
|
|||
|
||||
var this_ = this;
|
||||
this.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", utf8ToIcal,
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.getItems_resp( wcapResponse,
|
||||
itemFilter, maxResult,
|
||||
|
@ -953,7 +1013,12 @@ calWcapCalendar.prototype.getItems = function(
|
|||
Components.interfaces.calIOperationListener.GET,
|
||||
null, exc );
|
||||
}
|
||||
this.notifyError( exc );
|
||||
if (exc == Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED) {
|
||||
// silently ignore login failed, no calIObserver UI:
|
||||
this.log( "getItems_resp() ignored: " + errorToString(exc) );
|
||||
}
|
||||
else
|
||||
this.notifyError( exc );
|
||||
}
|
||||
this.log( "getItems() returning." );
|
||||
};
|
||||
|
@ -980,12 +1045,13 @@ SyncState.prototype = {
|
|||
}
|
||||
},
|
||||
|
||||
checkAborted: function() { if (this.m_exc) throw this.m_exc; },
|
||||
checkAborted: function() {
|
||||
if (this.m_exc)
|
||||
throw this.m_exc;
|
||||
},
|
||||
get hasAborted() { return this.m_exc != null; },
|
||||
abort:
|
||||
function( exc )
|
||||
{
|
||||
if (! this.hasAborted) // store only first error that has occurred
|
||||
abort: function( exc ) {
|
||||
if (!this.hasAborted) // store only first error that has occurred
|
||||
this.m_exc = exc;
|
||||
this.m_abortFunc( exc );
|
||||
}
|
||||
|
@ -1096,9 +1162,9 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
|||
syncState.acquire();
|
||||
var url = this.getCommandUrl( "fetchcomponents_by_range" );
|
||||
url += ("&compressed=1&recurring=1&calid=" +
|
||||
encodeURIComponent(this.calId));
|
||||
encodeURIComponent(this.calId));
|
||||
this.issueAsyncRequest(
|
||||
url + "&fmt-out=text%2Fcalendar", utf8ToIcal,
|
||||
url + "&fmt-out=text%2Fcalendar", stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
wcapResponse, syncState, iListener,
|
||||
|
@ -1122,7 +1188,7 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
|||
syncState.acquire();
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetchcomponents_by_lastmod" ) + params,
|
||||
utf8ToIcal,
|
||||
stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
wcapResponse, syncState, iListener,
|
||||
|
@ -1151,7 +1217,7 @@ calWcapCalendar.prototype.syncChangesTo = function(
|
|||
syncState.acquire();
|
||||
this.issueAsyncRequest(
|
||||
this.getCommandUrl( "fetch_deletedcomponents" ) + params,
|
||||
utf8ToIcal,
|
||||
stringToIcal,
|
||||
function( wcapResponse ) {
|
||||
this_.syncChangesTo_resp(
|
||||
wcapResponse, syncState, iListener,
|
||||
|
|
|
@ -61,7 +61,7 @@ var calWcapCalendarModule = {
|
|||
getClassObject:
|
||||
function( compMgr, cid, iid )
|
||||
{
|
||||
if (! this.m_scriptsLoaded) {
|
||||
if (!this.m_scriptsLoaded) {
|
||||
this.m_scriptsLoaded = true;
|
||||
// load scripts:
|
||||
const scripts = [ "calWcapUtils.js", "calWcapErrors.js",
|
||||
|
@ -83,9 +83,9 @@ var calWcapCalendarModule = {
|
|||
init(); // init first time
|
||||
}
|
||||
|
||||
if (! cid.equals( calWcapCalendar.prototype.classID ))
|
||||
if (!cid.equals( calWcapCalendar.prototype.classID ))
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
if (! iid.equals( Components.interfaces.nsIFactory ))
|
||||
if (!iid.equals( Components.interfaces.nsIFactory ))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
return {
|
||||
|
|
|
@ -37,6 +37,11 @@
|
|||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
// Cannot perform operation, because user is offline.
|
||||
// This has been taken from netwerk/base/public/nsNetError.h
|
||||
// and ought to be defined in IDL. xxx todo
|
||||
const NS_ERROR_OFFLINE = ((1<<31) | ((6+0x45)<<16) | 16);
|
||||
|
||||
//
|
||||
// WCAP error handling helpers
|
||||
//
|
||||
|
@ -44,7 +49,7 @@
|
|||
const g_wcapErrorCodes = [
|
||||
/* -1 */ Components.results.NS_OK, "Logout successful.",
|
||||
/* 0 */ Components.results.NS_OK, "Command successful.",
|
||||
/* 1 */ Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED, "Login failed, session ID timed out. Invalid session ID.",
|
||||
/* 1 */ Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED, "Login failed. Invalid session ID.",
|
||||
/* 2 */ Components.interfaces.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.",
|
||||
/* 4 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
|
@ -125,12 +130,20 @@ const g_wcapErrorCodes = [
|
|||
/* 79 */ Components.interfaces.calIWcapErrors.WCAP_ATTENDEE_NOT_ALLOWED_TO_REQUEST_ON_MODIFY, "Attendee is not allowed to modify an event with method=request.",
|
||||
/* 80 */ Components.interfaces.calIWcapErrors.WCAP_TRANSP_RESOURCE_NOT_ALLOWED, "Resources do not permit the transparency parameter.",
|
||||
/* 81 */ Components.interfaces.calIWcapErrors.WCAP_RECURRING_COMPONENT_NOT_FOUND, "Recurring component not found. Only happens when recurring=1 is passed in by fetch commands. This code is returned if part of the recurring series (either the master or an exception) is missing.",
|
||||
/* 82 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 83 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 84 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 85 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 86 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 87 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* new by WCAP 4.0: */
|
||||
/* 82 */ Components.interfaces.calIWcapErrors.WCAP_BAD_MIME_TYPE,
|
||||
"The mime headers supplied while storing the attachment using storeevents.wcap/storetodos.wcap is malformatted.",
|
||||
/* 83 */ Components.interfaces.calIWcapErrors.WCAP_MISSING_BOUNDARY,
|
||||
"While supplying attachments to the storeveents/storetodos commands the mime boundary was not found.",
|
||||
/* 84 */ Components.interfaces.calIWcapErrors.WCAP_INVALID_ATTACHMENT,
|
||||
"The attachment supplied to be stored on the server is malformatted.",
|
||||
/* 85 */ Components.interfaces.calIWcapErrors.WCAP_ATTACH_DELETE_SUCCESS,
|
||||
"All the attachments requested to be deleted from the server by supplying deleteattach were deleted successsfully.",
|
||||
/* 86 */ Components.interfaces.calIWcapErrors.WCAP_ATTACH_DELETE_PARTIAL,
|
||||
"Of All attachments requested to be deleted from the server by supplying deleteattach , only few were deleted successfully.",
|
||||
/* 87 */ Components.interfaces.calIWcapErrors.WCAP_ATTACHMENT_NOT_FOUND,
|
||||
"The attachent requested to be fetched or deleted from the server was not found.",
|
||||
/* / new by WCAP 4.0 */
|
||||
/* 88 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 89 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
/* 90 */ Components.results.NS_ERROR_INVALID_ARG, "No WCAP error code.",
|
||||
|
@ -154,7 +167,47 @@ const g_wcapErrorCodes = [
|
|||
/* 11008 */ Components.interfaces.calIWcapErrors.WCAP_CDWP_ERR_CHECKVERSION_FAILED, "DWP version check failed."
|
||||
];
|
||||
|
||||
function getWcapErrorIndex( errno )
|
||||
function wcapErrorToString( rc )
|
||||
{
|
||||
if (rc == Components.interfaces.calIWcapErrors.WCAP_NO_ERRNO)
|
||||
return "No WCAP errno (missing X-NSCP-WCAP-ERRNO).";
|
||||
|
||||
var index = (rc - Components.interfaces.calIWcapErrors.WCAP_ERROR_BASE + 1);
|
||||
if (index >= 1 && index <= 108 &&
|
||||
g_wcapErrorCodes[index * 2] != Components.results.NS_ERROR_INVALID_ARG)
|
||||
{
|
||||
return g_wcapErrorCodes[(index * 2) + 1];
|
||||
}
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
function errorToString( err )
|
||||
{
|
||||
if (err instanceof Error)
|
||||
return err.message;
|
||||
switch (err) {
|
||||
case NS_ERROR_OFFLINE:
|
||||
return "NS_ERROR_OFFLINE";
|
||||
// xxx todo: there may be a more comprehensive API for these:
|
||||
case Components.results.NS_ERROR_INVALID_ARG:
|
||||
return "NS_ERROR_INVALID_ARG";
|
||||
case Components.results.NS_ERROR_NO_INTERFACE:
|
||||
return "NS_ERROR_NO_INTERFACE";
|
||||
case Components.results.NS_ERROR_NOT_IMPLEMENTED:
|
||||
return "NS_ERROR_NOT_IMPLEMENTED";
|
||||
case Components.results.NS_ERROR_FAILURE:
|
||||
return "NS_ERROR_FAILURE";
|
||||
default: // probe for WCAP error:
|
||||
try {
|
||||
return wcapErrorToString(err);
|
||||
}
|
||||
catch (exc) {
|
||||
return ("[" + err + "] Unknown error code.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function getWcapErrorCode( errno )
|
||||
{
|
||||
var index = -1;
|
||||
if (errno >= -1 && errno <= 81)
|
||||
|
@ -164,72 +217,38 @@ function getWcapErrorIndex( errno )
|
|||
if (index >= 0 &&
|
||||
g_wcapErrorCodes[index * 2] != Components.results.NS_ERROR_INVALID_ARG)
|
||||
{
|
||||
return index;
|
||||
return g_wcapErrorCodes[index * 2];
|
||||
}
|
||||
else
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
function getWcapErrorIndexByErrorCode( rc )
|
||||
{
|
||||
var index = (rc - Components.interfaces.calIWcapErrors.WCAP_ERROR_BASE + 1);
|
||||
if (index >= 1 && index <= 108 &&
|
||||
g_wcapErrorCodes[index * 2] != Components.results.NS_ERROR_INVALID_ARG)
|
||||
{
|
||||
return index;
|
||||
}
|
||||
else
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
function getWcapErrorCodeString( rc )
|
||||
{
|
||||
return g_wcapErrorCodes[(getWcapErrorIndexByErrorCode(rc) * 2) + 1];
|
||||
}
|
||||
|
||||
function getWcapErrorCode( errno )
|
||||
{
|
||||
return g_wcapErrorCodes[getWcapErrorIndex(errno) * 2];
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
}
|
||||
|
||||
function getWcapXmlErrno( xml )
|
||||
{
|
||||
if (xml == undefined)
|
||||
throw new Error("no XML!");
|
||||
var item = xml.getElementsByTagName("X-NSCP-WCAP-ERRNO").item(0);
|
||||
if (item)
|
||||
return parseInt(item.textContent);
|
||||
else {
|
||||
// xxx todo: throw new Eror("missing element X-NSCP-WCAP-ERRNO!");
|
||||
// cs currently may forget to send X-NSCP-WCAP-ERRNO on
|
||||
// some commands, maybe fixed in later versions. WTF.
|
||||
return 0;
|
||||
var elem = xml.getElementsByTagName( "X-NSCP-WCAP-ERRNO" );
|
||||
if (elem) {
|
||||
elem = elem.item(0);
|
||||
if (elem)
|
||||
return parseInt(elem.textContent);
|
||||
}
|
||||
// some commands just respond with an empty calendar, no errno. WTF.
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_NO_ERRNO;
|
||||
}
|
||||
|
||||
function getWcapIcalErrno( icalRootComp )
|
||||
{
|
||||
if (icalRootComp == undefined)
|
||||
throw new Error("no VCALENDAR root component!");
|
||||
var prop = icalRootComp.getFirstProperty( "X-NSCP-WCAP-ERRNO" );
|
||||
if (prop)
|
||||
return parseInt(prop.value);
|
||||
else {
|
||||
// xxx todo: throw new Eror("missing element X-NSCP-WCAP-ERRNO!");
|
||||
// cs currently may forget to send X-NSCP-WCAP-ERRNO on
|
||||
// some commands, maybe fixed in later versions. WTF.
|
||||
return 0;
|
||||
}
|
||||
// some commands just respond with an empty calendar, no errno. WTF.
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_NO_ERRNO;
|
||||
}
|
||||
|
||||
function checkWcapErrno( errno, expectedErrno )
|
||||
{
|
||||
if (expectedErrno == undefined) {
|
||||
expectedErrno = 0;
|
||||
}
|
||||
if (errno != expectedErrno) {
|
||||
if (expectedErrno == undefined)
|
||||
expectedErrno = 0; // i.e. Command successful.
|
||||
if (errno != expectedErrno)
|
||||
throw getWcapErrorCode(errno);
|
||||
}
|
||||
}
|
||||
|
||||
function checkWcapXmlErrno( xml, expectedErrno )
|
||||
|
|
|
@ -73,80 +73,95 @@ WcapResponse.prototype = {
|
|||
}
|
||||
};
|
||||
|
||||
function utf8ToIcal( utf8Data, wcapResponse )
|
||||
function stringToIcal( data )
|
||||
{
|
||||
if (!utf8Data || utf8Data == "")
|
||||
return 1; // assuming session timeout
|
||||
var icalRootComp = getIcsService().parseICS( utf8Data );
|
||||
wcapResponse.data = icalRootComp;
|
||||
return getWcapIcalErrno( icalRootComp );
|
||||
if (!data || data == "") // assuming time-out
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED;
|
||||
var icalRootComp = getIcsService().parseICS( data );
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
return icalRootComp;
|
||||
}
|
||||
|
||||
function utf8ToXml( utf8Data, wcapResponse )
|
||||
function stringToXml( data )
|
||||
{
|
||||
if (!utf8Data || utf8Data == "")
|
||||
return 1; // assuming session timeout
|
||||
var xml = getDomParser().parseFromString( utf8Data, "text/xml");
|
||||
wcapResponse.data = xml;
|
||||
return getWcapXmlErrno( xml );
|
||||
if (!data || data == "") // assuming time-out
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED;
|
||||
var xml = getDomParser().parseFromString( data, "text/xml" );
|
||||
checkWcapXmlErrno( xml );
|
||||
return xml;
|
||||
}
|
||||
|
||||
function Utf8Reader( url, receiverFunc ) {
|
||||
function UnicharReader( receiverFunc ) {
|
||||
this.wrappedJSObject = this;
|
||||
this.m_url = url;
|
||||
this.m_receiverFunc = receiverFunc;
|
||||
}
|
||||
Utf8Reader.prototype = {
|
||||
m_url: null,
|
||||
UnicharReader.prototype = {
|
||||
m_receiverFunc: null,
|
||||
|
||||
// nsIUnicharStreamLoaderObserver:
|
||||
onDetermineCharset:
|
||||
function( loader, context, firstSegment, length )
|
||||
{
|
||||
return "UTF-8";
|
||||
var charset = loader.channel.contentCharset;
|
||||
if (!charset || charset == "")
|
||||
charset = "UTF-8";
|
||||
return charset;
|
||||
},
|
||||
|
||||
onStreamComplete:
|
||||
function( loader, context, status, /* nsIUnicharInputStream */ unicharData )
|
||||
{
|
||||
if (status == Components.results.NS_OK) {
|
||||
if (LOG_LEVEL > 2) {
|
||||
logMessage( "issueAsyncRequest( \"" +
|
||||
loader.channel.URI.spec + "\" )",
|
||||
"received stream." );
|
||||
}
|
||||
var str = "";
|
||||
var str_ = {};
|
||||
while (unicharData.readString( -1, str_ )) {
|
||||
str += str_.value;
|
||||
if (unicharData) {
|
||||
var str_ = {};
|
||||
while (unicharData.readString( -1, str_ )) {
|
||||
str += str_.value;
|
||||
}
|
||||
}
|
||||
if (LOG_LEVEL > 1) {
|
||||
logMessage( "issueAsyncUtf8Request( \"" + this.m_url + "\" )",
|
||||
"request result: " + str );
|
||||
logMessage( "issueAsyncRequest( \"" +
|
||||
loader.channel.URI.spec + "\" )",
|
||||
"contentCharset = " + loader.channel.contentCharset+
|
||||
"\nrequest result:\n" + str );
|
||||
}
|
||||
this.m_receiverFunc( str );
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function issueAsyncUtf8Request( url, receiverFunc )
|
||||
function issueAsyncRequest( url, receiverFunc )
|
||||
{
|
||||
var reader = null;
|
||||
if (receiverFunc != null) {
|
||||
reader = new Utf8Reader( url, receiverFunc );
|
||||
reader = new UnicharReader( receiverFunc );
|
||||
}
|
||||
var loader =
|
||||
Components.classes["@mozilla.org/network/unichar-stream-loader;1"]
|
||||
.createInstance(Components.interfaces.nsIUnicharStreamLoader);
|
||||
logMessage( "issueAsyncUtf8Request( \"" + url + "\" )", "opening channel.");
|
||||
logMessage( "issueAsyncRequest( \"" + url + "\" )", "opening channel." );
|
||||
var channel = getIoService().newChannel(
|
||||
url, "UTF-8" /* charset */, null /* baseURI */ );
|
||||
url, "" /* charset */, null /* baseURI */ );
|
||||
loader.init( channel, reader, null /* context */, 0 /* segment size */ );
|
||||
}
|
||||
|
||||
function streamToUtf8String( inStream )
|
||||
function streamToString( inStream, charset )
|
||||
{
|
||||
// byte-array to utf8 string:
|
||||
if (LOG_LEVEL > 2) {
|
||||
logMessage( "streamToString()",
|
||||
"inStream.available() = " + inStream.available() +
|
||||
", charset = " + charset );
|
||||
}
|
||||
// byte-array to string:
|
||||
var convStream =
|
||||
Components.classes["@mozilla.org/intl/converter-input-stream;1"]
|
||||
.createInstance(Components.interfaces.nsIConverterInputStream);
|
||||
convStream.init( inStream, "UTF-8", 0, 0x0000 );
|
||||
convStream.init( inStream, charset, 0, 0x0000 );
|
||||
var str = "";
|
||||
var str_ = {};
|
||||
while (convStream.readString( -1, str_ )) {
|
||||
|
@ -155,47 +170,53 @@ function streamToUtf8String( inStream )
|
|||
return str;
|
||||
}
|
||||
|
||||
function issueSyncUtf8Request( url, receiverFunc, bLogging )
|
||||
function issueSyncRequest( url, receiverFunc, bLogging )
|
||||
{
|
||||
if (bLogging == undefined)
|
||||
bLogging = true;
|
||||
if (bLogging && LOG_LEVEL > 0) {
|
||||
logMessage( "issueSyncUtf8Request( \"" + url + "\" )",
|
||||
logMessage( "issueSyncRequest( \"" + url + "\" )",
|
||||
"opening channel." );
|
||||
}
|
||||
var channel = getIoService().newChannel(
|
||||
url, "UTF-8" /* charset */, null /* baseURI */ );
|
||||
url, "" /* charset */, null /* baseURI */ );
|
||||
var stream = channel.open();
|
||||
if (bLogging && LOG_LEVEL > 1) {
|
||||
logMessage( "issueSyncRequest( \"" + url + "\" )",
|
||||
"contentCharset = " + channel.contentCharset +
|
||||
", contentLength = " + channel.contentLength +
|
||||
", contentType = " + channel.contentType );
|
||||
}
|
||||
var status = channel.status;
|
||||
if (status == Components.results.NS_OK) {
|
||||
var str = streamToUtf8String( stream );
|
||||
var charset = channel.contentCharset;
|
||||
if (!charset || charset == "")
|
||||
charset = "UTF-8";
|
||||
var str = streamToString( stream, charset );
|
||||
if (bLogging && LOG_LEVEL > 1) {
|
||||
logMessage( "issueSyncUtf8Request( \"" + url + "\" )",
|
||||
logMessage( "issueSyncRequest( \"" + url + "\" )",
|
||||
"returned: " + str );
|
||||
}
|
||||
if (receiverFunc != null) {
|
||||
if (receiverFunc) {
|
||||
receiverFunc( str );
|
||||
}
|
||||
return str;
|
||||
}
|
||||
else if (bLogging && LOG_LEVEL > 0) {
|
||||
logMessage( "issueSyncUtf8Request( \"" + url + "\" )",
|
||||
logMessage( "issueSyncRequest( \"" + url + "\" )",
|
||||
"failed: " + status );
|
||||
}
|
||||
return null;
|
||||
throw status;
|
||||
}
|
||||
|
||||
function issueSyncXMLRequest( url, receiverFunc, bLogging )
|
||||
{
|
||||
var str = issueSyncUtf8Request( url, null, bLogging );
|
||||
if (str != null) {
|
||||
var xml = getDomParser().parseFromString( str, "text/xml" );
|
||||
if (receiverFunc != null) {
|
||||
receiverFunc( xml );
|
||||
}
|
||||
return xml;
|
||||
var str = issueSyncRequest( url, null, bLogging );
|
||||
var xml = getDomParser().parseFromString( str, "text/xml" );
|
||||
if (receiverFunc) {
|
||||
receiverFunc( xml );
|
||||
}
|
||||
return null;
|
||||
return xml;
|
||||
}
|
||||
|
||||
// response object for Calendar.issueRequest()
|
||||
|
|
|
@ -137,12 +137,10 @@ calWcapSession.prototype = {
|
|||
var url = this.uri.spec +
|
||||
"get_all_timezones.wcap?appid=mozilla-lightning" +
|
||||
"&fmt-out=text%2Fcalendar&id=" + this.m_sessionId;
|
||||
var str = issueSyncUtf8Request( url );
|
||||
if (str == null)
|
||||
throw new Error("request failed!");
|
||||
var str = issueSyncRequest( url );
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
if (icalRootComp == null)
|
||||
throw new Error("invalid data!");
|
||||
throw new Error("invalid data, expected ical!");
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
var tzids = [];
|
||||
var this_ = this;
|
||||
|
@ -186,12 +184,10 @@ calWcapSession.prototype = {
|
|||
"&fmt-out=text%2Fcalendar&id=" + this.m_sessionId;
|
||||
// xxx todo: this is no solution!
|
||||
var localTime = getTime();
|
||||
var str = issueSyncUtf8Request( url );
|
||||
if (str == null)
|
||||
throw new Error("request failed!");
|
||||
var str = issueSyncRequest( url );
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
if (icalRootComp == null)
|
||||
throw new Error("invalid data!");
|
||||
throw new Error("invalid data, expected ical!");
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
var serverTime = getDatetimeFromIcalProp(
|
||||
icalRootComp.getFirstProperty( "X-NSCP-WCAPTIME" ) );
|
||||
|
@ -228,11 +224,11 @@ calWcapSession.prototype = {
|
|||
{
|
||||
if (this.m_bNoLoginsAnymore) {
|
||||
this.log( "login has failed, no logins anymore for this user." );
|
||||
return null;
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED;
|
||||
}
|
||||
if (getIoService().offline) {
|
||||
this.log( "in offline mode." );
|
||||
return null;
|
||||
throw NS_ERROR_OFFLINE;
|
||||
}
|
||||
|
||||
if (this.m_sessionId == null || this.m_sessionId == timedOutSessionId) {
|
||||
|
@ -257,7 +253,7 @@ calWcapSession.prototype = {
|
|||
this.log( "session timeout; prompting to reconnect." );
|
||||
var prompt = getWindowWatcher().getNewPrompter(null);
|
||||
var bundle = getBundle();
|
||||
if (! prompt.confirm(
|
||||
if (!prompt.confirm(
|
||||
bundle.GetStringFromName(
|
||||
"reconnectConfirmation.label" ),
|
||||
bundle.formatStringFromName(
|
||||
|
@ -266,7 +262,7 @@ calWcapSession.prototype = {
|
|||
this.m_bNoLoginsAnymore = true;
|
||||
}
|
||||
}
|
||||
if (! this.m_bNoLoginsAnymore)
|
||||
if (!this.m_bNoLoginsAnymore)
|
||||
this.getSessionId_();
|
||||
|
||||
this.getSupportedTimezones( true /* refresh */ );
|
||||
|
@ -279,6 +275,9 @@ calWcapSession.prototype = {
|
|||
}
|
||||
eventQueueService.popThreadEventQueue( eventQueue );
|
||||
}
|
||||
if (this.m_sessionId == null) {
|
||||
throw Components.interfaces.calIWcapErrors.WCAP_LOGIN_FAILED;
|
||||
}
|
||||
return this.m_sessionId;
|
||||
},
|
||||
getSessionId_:
|
||||
|
@ -319,7 +318,7 @@ calWcapSession.prototype = {
|
|||
else {
|
||||
// user has specified a specific port, but no https:
|
||||
// => leave it to her whether to connect...
|
||||
if (! confirmUnsecureLogin( loginUri )) {
|
||||
if (!confirmUnsecureLogin( loginUri )) {
|
||||
this.m_bNoLoginsAnymore = true;
|
||||
this.log( "user rejected unsecure login." );
|
||||
return null;
|
||||
|
@ -450,13 +449,11 @@ calWcapSession.prototype = {
|
|||
try {
|
||||
// currently, xml parsing at an early stage during process startup
|
||||
// does not work reliably, so use libical parsing for now:
|
||||
var str = issueSyncUtf8Request(
|
||||
var str = issueSyncRequest(
|
||||
uri.spec + "version.wcap?fmt-out=text%2Fcalendar" );
|
||||
if (str == null)
|
||||
throw new Error("request failed!");
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
if (icalRootComp == null)
|
||||
throw new Error("invalid data!");
|
||||
throw new Error("invalid data, expected ical!");
|
||||
var prop = icalRootComp.getFirstProperty( "PRODID" );
|
||||
if (prop == null)
|
||||
throw new Error("missing PRODID!");
|
||||
|
@ -507,12 +504,10 @@ calWcapSession.prototype = {
|
|||
}
|
||||
// currently, xml parsing at an early stage during process startup
|
||||
// does not work reliably, so use libical parsing for now:
|
||||
var str = issueSyncUtf8Request(
|
||||
var str = issueSyncRequest(
|
||||
loginUri.spec + "login.wcap?fmt-out=text%2Fcalendar&user=" +
|
||||
encodeURIComponent(user) + "&password=" + encodeURIComponent(pw),
|
||||
null /* receiverFunc */, false /* no logging */ );
|
||||
if (str == null)
|
||||
throw new Error("request failed!");
|
||||
var icalRootComp = getIcsService().parseICS( str );
|
||||
checkWcapIcalErrno( icalRootComp );
|
||||
var prop = icalRootComp.getFirstProperty( "X-NSCP-WCAP-SESSION-ID" );
|
||||
|
@ -540,7 +535,8 @@ calWcapSession.prototype = {
|
|||
var url = (this.uri.spec +
|
||||
"logout.wcap?fmt-out=text%2Fxml&id=" + this.m_sessionId);
|
||||
try {
|
||||
checkWcapXmlErrno( issueSyncXMLRequest(url), -1 );
|
||||
checkWcapXmlErrno( issueSyncXMLRequest(url),
|
||||
-1 /* logout successfull */ );
|
||||
this.log( "WCAP logout succeeded." );
|
||||
}
|
||||
catch (exc) {
|
||||
|
@ -583,7 +579,7 @@ g_sessions = {};
|
|||
function getSession( uri )
|
||||
{
|
||||
var session = g_sessions[uri.spec];
|
||||
if (! session) {
|
||||
if (!session) {
|
||||
logMessage( "getSession()", "entering session for uri=" + uri.spec );
|
||||
var session = new calWcapSession( uri );
|
||||
g_sessions[uri.spec] = session;
|
||||
|
|
|
@ -178,7 +178,7 @@ function init()
|
|||
}
|
||||
CACHE_DIR = cacheDir;
|
||||
logMessage( "calendar.wcap.cache_dir", CACHE_DIR.path );
|
||||
if (! CACHE_DIR.exists()) {
|
||||
if (!CACHE_DIR.exists()) {
|
||||
CACHE_DIR.create(
|
||||
Components.interfaces.nsIFile.DIRECTORY_TYPE,
|
||||
0700 /* read, write, execute/search by owner */ );
|
||||
|
@ -308,7 +308,7 @@ function getTime()
|
|||
|
||||
function getIcalUTC( dt )
|
||||
{
|
||||
if (! dt)
|
||||
if (!dt)
|
||||
return "0";
|
||||
else {
|
||||
var dtz = dt.timezone;
|
||||
|
@ -321,7 +321,7 @@ function getIcalUTC( dt )
|
|||
|
||||
function getDatetimeFromIcalProp( prop )
|
||||
{
|
||||
if (! prop)
|
||||
if (!prop)
|
||||
return null;
|
||||
var val = prop.valueAsIcalString;
|
||||
if (val.length == 0 || val == "0")
|
||||
|
|
|
@ -66,18 +66,34 @@ interface calIWcapCalendar : calICalendar
|
|||
* Gets or sets this calendar's (calId) default timezone.
|
||||
*/
|
||||
readonly attribute string defaultTimezone;
|
||||
|
||||
/**
|
||||
* Gets calendar properties for specified calId.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param propName property name (e.g. X-S1CS-CALPROPS-COMMON-NAME)
|
||||
* @param calId a calid, "mailto:rfc822addr" or
|
||||
* empty string (=> current user's calId)
|
||||
* @return array of property values
|
||||
*/
|
||||
void getCalendarProperties(
|
||||
in string propName,
|
||||
in string calId,
|
||||
out unsigned long count,
|
||||
[array, size_is(count), retval] out string properties );
|
||||
|
||||
/**
|
||||
* Gets a text for an error code.
|
||||
*
|
||||
* @param rc error code defined in calIWcapErrors
|
||||
* @return error string
|
||||
* @exception Components.results.NS_ERROR_INVALID_ARG
|
||||
* @exception NS_ERROR_INVALID_ARG
|
||||
*/
|
||||
string getWcapErrorString( in unsigned long rc );
|
||||
|
||||
/**
|
||||
* Creates a new calendar for user.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId calendar's calId (portion);
|
||||
* without user's id, e.g. "test-cal".
|
||||
|
@ -106,6 +122,7 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/**
|
||||
* Deletes a calendar.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param calId full calId (incl. "<user>:")
|
||||
* @param bRemoveFromSubscribed whether calendar ought to be removed
|
||||
|
@ -117,6 +134,7 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/**
|
||||
* Gets own calendars.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return owned calendars (string array of "calId1$Description1", ...)
|
||||
*/
|
||||
|
@ -126,6 +144,7 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/**
|
||||
* Gets subscribed calendars.
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @return subscribed calendars (string array of "calId1$Description1",...)
|
||||
*/
|
||||
|
@ -135,6 +154,7 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/**
|
||||
* Subscribe to calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
|
@ -145,6 +165,7 @@ interface calIWcapCalendar : calICalendar
|
|||
|
||||
/**
|
||||
* Unsubscribe from calendar(s).
|
||||
* An error is notified to all registered calIObservers, then thrown.
|
||||
*
|
||||
* @param count number of calIds
|
||||
* @param calIds array of calIds (calid or "mailto:rfc822addr")
|
||||
|
@ -156,8 +177,10 @@ interface calIWcapCalendar : calICalendar
|
|||
/**
|
||||
* Gets free-busy entries for calid.
|
||||
* Results are notifies to passed listener instance.
|
||||
* Errors are always notified to all registered calIObservers,
|
||||
* and rethrown in calling thread (only).
|
||||
* An error is notified to all registered calIObservers and
|
||||
* to calIWcapFreeBusyListener::onGetFreeBusyTimes with rc != NS_OK.
|
||||
* Additionally, when an error occurs within getFreeBusyTimes,
|
||||
* the error is also thrown.
|
||||
*
|
||||
* @param calId a calid or "mailto:rfc822addr"
|
||||
* @param dtRangeStart start time of free-busy search
|
||||
|
@ -179,6 +202,53 @@ interface calIWcapCalendar : calICalendar
|
|||
/** xxx todo: to be moved to calIOperationListener?
|
||||
*/
|
||||
const unsigned long SYNC = 5;
|
||||
|
||||
/* xxx todo: additional filters sensible for calICalendar, too?
|
||||
claiming bits 24-30 for now.
|
||||
*/
|
||||
/**
|
||||
* Scope: Attendee
|
||||
* The event or todo is an invitation from another
|
||||
* user and the current user has declined the invitation.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REPLY_DECLINED = 1 << 24;
|
||||
/**
|
||||
* Scope: Attendee
|
||||
* The event or todo is an invitation from another
|
||||
* user and the current user has accepted the invitation.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REPLY_ACCEPTED = 1 << 25;
|
||||
/**
|
||||
* Scope: Organizer
|
||||
* The event or todo is an invitation from the current
|
||||
* user to other invitees, and all invitees have replied.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REQUEST_COMPLETED = 1 << 26;
|
||||
/**
|
||||
* Scope: Attendee
|
||||
* The event or todo is an invitation from another
|
||||
* user and the current user has not replied to it yet.
|
||||
* */
|
||||
const unsigned long ITEM_FILTER_REQUEST_NEEDS_ACTION = 1 << 27;
|
||||
/**
|
||||
* Scope: Attendee
|
||||
* The event or todo is an invitation from another
|
||||
* user and the current user is not required to reply.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REQUEST_NEEDSNOACTION = 1 << 28;
|
||||
/**
|
||||
* Scope: Organizer
|
||||
* The event or todo is an invitation from the current
|
||||
* user to other invitees, and is currently in the
|
||||
* process of sending out invitations.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REQUEST_PENDING = 1 << 29;
|
||||
/**
|
||||
* Scope: Organizer
|
||||
* The event or todo is an invitation from the current
|
||||
* user to other invitees, and is currently awaiting.
|
||||
*/
|
||||
const unsigned long ITEM_FILTER_REQUEST_WAITFORREPLY = 1 << 30;
|
||||
|
||||
/**
|
||||
* Syncs in changes since time <code>dtFrom</code>.
|
||||
|
|
|
@ -44,6 +44,9 @@
|
|||
[scriptable, uuid(2ADC008C-A7A6-4f9a-91C8-A99742B68F3D)]
|
||||
interface calIWcapErrors : calIErrors
|
||||
{
|
||||
const unsigned long WCAP_NO_ERRNO = WCAP_ERROR_BASE + 0;
|
||||
|
||||
/* errno: */
|
||||
/* 1 */ const unsigned long WCAP_LOGIN_FAILED =
|
||||
WCAP_ERROR_BASE + 1;
|
||||
/* 2 */ const unsigned long WCAP_LOGIN_OK_DEFAULT_CALENDAR_NOT_FOUND =
|
||||
|
@ -198,6 +201,22 @@ interface calIWcapErrors : calIErrors
|
|||
WCAP_ERROR_BASE + 80;
|
||||
/* 81 */ const unsigned long WCAP_RECURRING_COMPONENT_NOT_FOUND =
|
||||
WCAP_ERROR_BASE + 81;
|
||||
|
||||
/* new by WCAP 4.0: */
|
||||
/* 82 */ const unsigned long WCAP_BAD_MIME_TYPE =
|
||||
WCAP_ERROR_BASE + 82;
|
||||
/* 83 */ const unsigned long WCAP_MISSING_BOUNDARY =
|
||||
WCAP_ERROR_BASE + 83;
|
||||
/* 84 */ const unsigned long WCAP_INVALID_ATTACHMENT =
|
||||
WCAP_ERROR_BASE + 84;
|
||||
/* 85 */ const unsigned long WCAP_ATTACH_DELETE_SUCCESS =
|
||||
WCAP_ERROR_BASE + 85;
|
||||
/* 86 */ const unsigned long WCAP_ATTACH_DELETE_PARTIAL =
|
||||
WCAP_ERROR_BASE + 86;
|
||||
/* 87 */ const unsigned long WCAP_ATTACHMENT_NOT_FOUND =
|
||||
WCAP_ERROR_BASE + 87;
|
||||
/* / new by WCAP 4.0 */
|
||||
|
||||
/* 11000 */ const unsigned long WCAP_CDWP_ERR_MAX_CONNECTION_REACHED =
|
||||
WCAP_ERROR_BASE + 100;
|
||||
/* 11001 */ const unsigned long WCAP_CDWP_ERR_CANNOT_CONNECT =
|
||||
|
|
|
@ -45,12 +45,15 @@ interface calIWcapFreeBusyListener : nsISupports
|
|||
/**
|
||||
* Callback receiving free-busy entries.
|
||||
*
|
||||
* @param rc result code,
|
||||
* e.g. NS_OK or calIWcapErrors.WCAP_CALENDAR_DOES_NOT_EXIST
|
||||
* @param requestId request id to distinguish asynchronous requests
|
||||
* @param calId a calid or "mailto:rfc822addr"
|
||||
* @param count number of free-busy entries
|
||||
* @param entries free-busy entries
|
||||
*/
|
||||
void onGetFreeBusyTimes(
|
||||
in nsresult rc,
|
||||
in unsigned long requestId,
|
||||
in string calId,
|
||||
in unsigned long count,
|
||||
|
|
Загрузка…
Ссылка в новой задаче