merge of '38bdad32536cc97eb69bad5515fa682a452c9be6'

and '69348ff83b958e39e8d6bdc38da8a1f1ea4ace1a'

Monotone-Parent: 38bdad32536cc97eb69bad5515fa682a452c9be6
Monotone-Parent: 69348ff83b958e39e8d6bdc38da8a1f1ea4ace1a
Monotone-Revision: 0b152b3b9b68eb80edffbcf7dec3d59fa6a7e76d

Monotone-Author: flachapelle@inverse.ca
Monotone-Date: 2010-01-25T16:03:26
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Francis Lachapelle 2010-01-25 16:03:26 +00:00
commit 8937d26b92
32 changed files with 188 additions and 98 deletions

View file

@ -21,4 +21,4 @@ SOPE/NGCards/samples/CardElement.m
SOPE/NGCards/samples/CardGroup.m SOPE/NGCards/samples/CardGroup.m
SOPE/NGCards/samples/CardVersitRenderer.m SOPE/NGCards/samples/CardVersitRenderer.m
SOPE/NGCards/samples/NGCardsSaxHandler.m SOPE/NGCards/samples/NGCardsSaxHandler.m
Tests/config.py Tests/Integration/config.py

View file

@ -1,3 +1,7 @@
2010-01-24 Ludovic Marcotte <lmarcotte@inverse.ca>
* Reorganized the layout of automated tests.
2010-01-22 Francis Lachapelle <flachapelle@inverse.ca> 2010-01-22 Francis Lachapelle <flachapelle@inverse.ca>
* UI/Contacts/UIxListEditor.m (-references): avoid printing the * UI/Contacts/UIxListEditor.m (-references): avoid printing the
@ -8,6 +12,9 @@
2010-01-22 Wolfgang Sourdeau <wsourdeau@inverse.ca> 2010-01-22 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/WebServerResources/MailerUI.js (composeNewMessage): fixed
potential js error in IE when no mailbox is selected.
* Tools/SOGoToolRestore.m (+initialize): we need to invoke * Tools/SOGoToolRestore.m (+initialize): we need to invoke
[iCalEntityObject+SOGo initializeSOGoExtensions], otherwise the [iCalEntityObject+SOGo initializeSOGoExtensions], otherwise the
extraction of quick records will cause a crash because some global extraction of quick records will cause a crash because some global

View file

@ -1772,7 +1772,24 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
static __inline__ NSException *_consumeIfMatch static __inline__ NSException *_consumeIfMatch
(NGImap4ResponseParser *self, unsigned char _m); (NGImap4ResponseParser *self, unsigned char _m);
@@ -488,6 +493,50 @@ @@ -300,6 +305,16 @@
/* those starting with a number '24 ', eg '24 OK Completed' */
endOfCommand = (_parseTaggedResponse(self, result) == _tag);
}
+ else if (l0 == -1) {
+ *ex_ = [self->buffer lastException];
+ if (!*ex_)
+ *ex_
+ = [NSException exceptionWithName:@"UnexpectedEndOfStream"
+ reason:(@"the parsed stream ended"
+ @" unexpectedly")
+ userInfo:nil];
+ endOfCommand = YES;
+ }
}
return result;
}
@@ -488,6 +503,50 @@
return [self _parseDataIntoRAM:size]; return [self _parseDataIntoRAM:size];
} }
@ -1823,7 +1840,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
static int _parseTaggedResponse(NGImap4ResponseParser *self, static int _parseTaggedResponse(NGImap4ResponseParser *self,
NGMutableHashMap *result_) NGMutableHashMap *result_)
{ {
@@ -584,6 +633,10 @@ @@ -584,6 +643,10 @@
break; break;
case 'N': case 'N':
@ -1834,7 +1851,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
if (_parseNoUntaggedResponse(self, result_)) // la: 2 if (_parseNoUntaggedResponse(self, result_)) // la: 2
return; return;
break; break;
@@ -648,14 +701,171 @@ @@ -648,14 +711,171 @@
[result_ addObject:_parseUntil(self, '\n') forKey:@"description"]; [result_ addObject:_parseUntil(self, '\n') forKey:@"description"];
} }
@ -2007,7 +2024,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
- (void)_consumeOptionalSpace { - (void)_consumeOptionalSpace {
if (_la(self, 0) == ' ') _consume(self, 1); if (_la(self, 0) == ' ') _consume(self, 1);
} }
@@ -685,6 +895,10 @@ @@ -685,6 +905,10 @@
name = [self _parseQuotedString]; name = [self _parseQuotedString];
_parseUntil(self, '\n'); _parseUntil(self, '\n');
} }
@ -2018,7 +2035,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
else else
name = _parseUntil(self, '\n'); name = _parseUntil(self, '\n');
@@ -723,6 +937,85 @@ @@ -723,6 +947,85 @@
return YES; return YES;
} }
@ -2104,7 +2121,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
- (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ { - (BOOL)_parseACLResponseIntoHashMap:(NGMutableHashMap *)result_ {
/* /*
21 GETACL INBOX 21 GETACL INBOX
@@ -1030,10 +1323,15 @@ @@ -1030,10 +1333,15 @@
_consume(self, 7); _consume(self, 7);
if (_la(self, 0) == '"') { if (_la(self, 0) == '"') {
@ -2122,7 +2139,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
else { else {
name = _parseUntil(self, ' '); name = _parseUntil(self, ' ');
} }
@@ -1073,51 +1371,6 @@ @@ -1073,51 +1381,6 @@
return YES; return YES;
} }
@ -2174,7 +2191,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
- (id)_decodeQP:(id)_string headerField:(NSString *)_field { - (id)_decodeQP:(id)_string headerField:(NSString *)_field {
if (![_string isNotNull]) if (![_string isNotNull])
return _string; return _string;
@@ -1185,7 +1438,7 @@ @@ -1185,7 +1448,7 @@
route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; route = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace];
mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; mailbox = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace];
host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace]; host = [self _parseQuotedStringOrNIL]; [self _consumeOptionalSpace];
@ -2183,7 +2200,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
if (_la(self, 0) != ')') { if (_la(self, 0) != ')') {
[self logWithFormat:@"WARNING: IMAP4 envelope " [self logWithFormat:@"WARNING: IMAP4 envelope "
@"address not properly closed (c0=%c,c1=%c): %@", @"address not properly closed (c0=%c,c1=%c): %@",
@@ -1197,6 +1450,7 @@ @@ -1197,6 +1460,7 @@
address = [[NGImap4EnvelopeAddress alloc] initWithPersonalName:pname address = [[NGImap4EnvelopeAddress alloc] initWithPersonalName:pname
sourceRoute:route mailbox:mailbox sourceRoute:route mailbox:mailbox
host:host]; host:host];
@ -2191,7 +2208,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
return address; return address;
} }
@@ -1382,7 +1636,15 @@ @@ -1382,7 +1646,15 @@
#if 0 #if 0
[self logWithFormat:@"PARSE KEY: %@", key]; [self logWithFormat:@"PARSE KEY: %@", key];
#endif #endif
@ -2208,7 +2225,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
NSDictionary *content; NSDictionary *content;
if ((content = [self _parseBodyContent]) != nil) if ((content = [self _parseBodyContent]) != nil)
@@ -1594,8 +1856,11 @@ @@ -1594,8 +1866,11 @@
if (_decode) if (_decode)
data = [data decodeQuotedPrintableValueOfMIMEHeaderField:nil]; data = [data decodeQuotedPrintableValueOfMIMEHeaderField:nil];
@ -2222,7 +2239,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
} }
else { else {
str = _parseUntil2(self, ' ', ')'); str = _parseUntil2(self, ' ', ')');
@@ -1620,13 +1885,35 @@ @@ -1620,13 +1895,35 @@
return str; return str;
} }
@ -2259,7 +2276,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self) static NSDictionary *_parseBodyParameterList(NGImap4ResponseParser *self)
{ {
NSMutableDictionary *list; NSMutableDictionary *list;
@@ -1646,7 +1933,7 @@ @@ -1646,7 +1943,7 @@
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
value = _parseBodyDecodeString(self, YES, YES); value = _parseBodyDecodeString(self, YES, YES);
@ -2268,7 +2285,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
} }
_consumeIfMatch(self, ')'); _consumeIfMatch(self, ')');
} }
@@ -1731,13 +2018,14 @@ @@ -1731,13 +2028,14 @@
static NSDictionary *_parseSingleBody(NGImap4ResponseParser *self, static NSDictionary *_parseSingleBody(NGImap4ResponseParser *self,
BOOL isBodyStructure) { BOOL isBodyStructure) {
NSString *type, *subtype, *bodyId, *description, NSString *type, *subtype, *bodyId, *description,
@ -2285,7 +2302,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
parameterList = _parseBodyParameterList(self); parameterList = _parseBodyParameterList(self);
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
@@ -1762,13 +2050,18 @@ @@ -1762,13 +2060,18 @@
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
[dict setObject:_parseBodyString(self, YES) forKey:@"lines"]; [dict setObject:_parseBodyString(self, YES) forKey:@"lines"];
} }
@ -2307,7 +2324,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
[dict setObject:_parseParenthesizedAddressList(self) forKey:@"from"]; [dict setObject:_parseParenthesizedAddressList(self) forKey:@"from"];
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
@@ -1783,14 +2076,20 @@ @@ -1783,14 +2086,20 @@
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
[dict setObject:_parseParenthesizedAddressList(self) forKey:@"bcc"]; [dict setObject:_parseParenthesizedAddressList(self) forKey:@"bcc"];
_consumeIfMatch(self, ' '); _consumeIfMatch(self, ' ');
@ -2331,7 +2348,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
} }
} }
@@ -1805,14 +2104,9 @@ @@ -1805,14 +2114,9 @@
forKey: @"disposition"]; forKey: @"disposition"];
if (_la(self, 0) != ')') { if (_la(self, 0) != ')') {
_consume(self,1); _consume(self,1);
@ -2349,7 +2366,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
if (_la(self, 0) != ')') { if (_la(self, 0) != ')') {
_consume(self,1); _consume(self,1);
[dict setObject: _parseBodyString(self, YES) [dict setObject: _parseBodyString(self, YES)
@@ -1829,6 +2123,7 @@ @@ -1829,6 +2133,7 @@
static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self, static NSDictionary *_parseMultipartBody(NGImap4ResponseParser *self,
BOOL isBodyStructure) { BOOL isBodyStructure) {
NSMutableArray *parts; NSMutableArray *parts;
@ -2357,7 +2374,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
NSString *kind; NSString *kind;
NSMutableDictionary *dict; NSMutableDictionary *dict;
@@ -1854,14 +2149,9 @@ @@ -1854,14 +2159,9 @@
forKey: @"disposition"]; forKey: @"disposition"];
if (_la(self, 0) != ')') { if (_la(self, 0) != ')') {
_consume(self,1); _consume(self,1);
@ -2375,7 +2392,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
if (_la(self, 0) != ')') { if (_la(self, 0) != ')') {
_consume(self,1); _consume(self,1);
[dict setObject: _parseBodyString(self, YES) [dict setObject: _parseBodyString(self, YES)
@@ -2170,6 +2460,21 @@ @@ -2170,6 +2470,21 @@
} }
} }
@ -2397,7 +2414,7 @@ Index: sope-mime/NGImap4/NGImap4ResponseParser.m
- (NSException *)exceptionForFailedMatch:(unsigned char)_match - (NSException *)exceptionForFailedMatch:(unsigned char)_match
got:(unsigned char)_avail got:(unsigned char)_avail
{ {
@@ -2225,9 +2530,9 @@ @@ -2225,9 +2540,9 @@
[s release]; [s release];
if (c == '\n') { if (c == '\n') {
@ -2413,7 +2430,13 @@ Index: sope-mime/NGImap4/ChangeLog
=================================================================== ===================================================================
--- sope-mime/NGImap4/ChangeLog (revision 1664) --- sope-mime/NGImap4/ChangeLog (revision 1664)
+++ sope-mime/NGImap4/ChangeLog (working copy) +++ sope-mime/NGImap4/ChangeLog (working copy)
@@ -1,3 +1,107 @@ @@ -1,3 +1,113 @@
+2010-01-25 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+
+ * NGImap4ResponseParser.m (-parseResponseForTagId:exception:):
+ detect "-1" return code from _la and leave the loop with a proper
+ execption when it occurs.
+
+2010-01-15 Wolfgang Sourdeau <wsourdeau@inverse.ca> +2010-01-15 Wolfgang Sourdeau <wsourdeau@inverse.ca>
+ +
+ * NGImap4Connection.m (-doesMailboxExistAtURL:): sometimes an + * NGImap4Connection.m (-doesMailboxExistAtURL:): sometimes an
@ -3347,7 +3370,29 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
} }
static inline id parseWhiteSpaces(NGMailAddressParser *self, BOOL _guessMode) { static inline id parseWhiteSpaces(NGMailAddressParser *self, BOOL _guessMode) {
@@ -84,7 +84,7 @@ @@ -79,12 +79,29 @@
return returnValue;
}
+static void dumpBadString(unichar *text, int length) {
+ char *bytes;
+ NSMutableString *logString;
+ int count, max;
+ max = length * sizeof (unichar);
+ logString = [NSMutableString stringWithCapacity: max];
+ [logString appendString: @"dumping buggy atom string: "];
+ bytes = (char *) text;
+ for (count = 0; count < max; count++) {
+ [logString appendFormat: @"0x%X", bytes[count]];
+ if (count < (max - 1))
+ [logString appendString: @", "];
+ }
+
+ NSLog (@"%@", logString);
+}
+
static inline id parseAtom(NGMailAddressParser *self, BOOL _guessMode) {
int keepPos = self->dataPos; // keep reference for backtracking int keepPos = self->dataPos; // keep reference for backtracking
id returnValue = nil; id returnValue = nil;
BOOL isAtom = YES; BOOL isAtom = YES;
@ -3356,7 +3401,7 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
int length = 0; // token text length int length = 0; // token text length
BOOL done = NO; BOOL done = NO;
@@ -94,7 +94,7 @@ @@ -94,7 +111,7 @@
done = YES; done = YES;
} }
else { else {
@ -3365,7 +3410,17 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
switch (c) { switch (c) {
case '(' : case ')': case '<': case '>': case '(' : case ')': case '<': case '>':
@@ -162,7 +162,7 @@ @@ -128,6 +145,9 @@
else {
NSCAssert(length > 0, @"no atom with length=0");
returnValue = [mkStrObj(text, length) autorelease];
+ if (!returnValue) {
+ dumpBadString(text, length);
+ }
NSCAssert([returnValue isKindOfClass:StrClass], @"got no string ..");
}
}
@@ -162,7 +182,7 @@
int keepPos = self->dataPos; // keep reference for backtracking int keepPos = self->dataPos; // keep reference for backtracking
id returnValue = nil; id returnValue = nil;
BOOL isQText = YES; BOOL isQText = YES;
@ -3374,7 +3429,7 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
int length = 0; // token text length int length = 0; // token text length
BOOL done = YES; BOOL done = YES;
@@ -172,9 +172,9 @@ @@ -172,9 +192,9 @@
done = YES; done = YES;
} }
else { else {
@ -3386,7 +3441,7 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
case '"' : case '"' :
case '\\': case '\\':
case 13 : case 13 :
@@ -215,7 +215,7 @@ @@ -215,7 +235,7 @@
int keepPos = self->dataPos; // keep reference for backtracking int keepPos = self->dataPos; // keep reference for backtracking
id returnValue = nil; id returnValue = nil;
BOOL isDText = YES; BOOL isDText = YES;
@ -3395,7 +3450,7 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
int length = 0; // token text length int length = 0; // token text length
BOOL done = YES; BOOL done = YES;
@@ -225,9 +225,9 @@ @@ -225,9 +245,9 @@
done = YES; done = YES;
} }
else { else {
@ -3407,7 +3462,7 @@ Index: sope-mime/NGMail/NGMailAddressParser.m
case '[': case ']': case '[': case ']':
case '\\': case 13: case '\\': case 13:
isDText = (length > 0); isDText = (length > 0);
@@ -320,42 +320,47 @@ @@ -320,42 +340,47 @@
/* constructors */ /* constructors */
+ (id)mailAddressParserWithData:(NSData *)_data { + (id)mailAddressParserWithData:(NSData *)_data {

56
Tests/Integration/README Normal file
View file

@ -0,0 +1,56 @@
setup
-----
(you need "python-simplejson", "python-xml", "python-vobject" and "python-m2crypto"
in order to run the scripts on Debian)
1) copy config.py.in to config.py (make sure to never EVER add it to monotone)
2) edit config.py to suit your environment
3) run the test scripts
runnable scripts
----------------
all.py - run all scripts below at once
test-webdavsync.py - explicit
test-davacl.py - dav acl tests for calendar and addressbook modules
other scripts
-------------
propfind.py - a sample implementation of a PROPFIND request using webdavlib
* developers
------------
- Test methods are always prefixed with "test". Sometimes, it's easier to
track down a problem by enabling only one test at a time. One possible method
is to replace "def test" with "def xtest" and replace it back when the
problems are solved.
- Test failures start with "FAIL:". Those are the ones that indicate possible
bugs in the application, if the test is itself known to work.
For example like this:
======================================================================
FAIL: 'modify' PUBLIC, 'view all' PRIVATE, 'view d&t' confidential
----------------------------------------------------------------------
Traceback (most recent call last):
File "./davacl.py", line 75, in testModifyPublicViewAllPrivateViewDConfidential
self._testRights({ "pu": "m", "pr": "v", "co": "d" })
File "./davacl.py", line 119, in _testRights
self._testCreate(rights)
File "./davacl.py", line 165, in _testCreate
exp_code)
File "./davacl.py", line 107, in _putEvent
% (exp_status, put.response["status"]))
AssertionError: event creation/modification: expected status code '403' (received '201')
- Test errors start with "ERRORS" and most likely indicate a bug in the test
code itself.
- Always set a doc string on the test methods, especially for complex test
cases.
- When writing tests, be aware that contrary to unit tests, functional tests
often imply a logical order between the different steps.

View file

@ -1,56 +1,8 @@
setup This directory holds automated tests for SOGo.
-----
(you need "python-simplejson", "python-xml", "python-vobject" and "python-m2crypto" We currrently have:
in order to run the scripts on Debian)
1) copy config.py.in to config.py (make sure to never EVER add it to monotone) - Intregation holds all interated tests that are used to
2) edit config.py to suit your environment validate overall DAV functionality right now
3) run the test scripts
runnable scripts - Unit holds all unit tests
----------------
all.py - run all scripts below at once
test-webdavsync.py - explicit
test-davacl.py - dav acl tests for calendar and addressbook modules
other scripts
-------------
propfind.py - a sample implementation of a PROPFIND request using webdavlib
* developers
------------
- Test methods are always prefixed with "test". Sometimes, it's easier to
track down a problem by enabling only one test at a time. One possible method
is to replace "def test" with "def xtest" and replace it back when the
problems are solved.
- Test failures start with "FAIL:". Those are the ones that indicate possible
bugs in the application, if the test is itself known to work.
For example like this:
======================================================================
FAIL: 'modify' PUBLIC, 'view all' PRIVATE, 'view d&t' confidential
----------------------------------------------------------------------
Traceback (most recent call last):
File "./davacl.py", line 75, in testModifyPublicViewAllPrivateViewDConfidential
self._testRights({ "pu": "m", "pr": "v", "co": "d" })
File "./davacl.py", line 119, in _testRights
self._testCreate(rights)
File "./davacl.py", line 165, in _testCreate
exp_code)
File "./davacl.py", line 107, in _putEvent
% (exp_status, put.response["status"]))
AssertionError: event creation/modification: expected status code '403' (received '201')
- Test errors start with "ERRORS" and most likely indicate a bug in the test
code itself.
- Always set a doc string on the test methods, especially for complex test
cases.
- When writing tests, be aware that contrary to unit tests, functional tests
often imply a logical order between the different steps.

View file

@ -109,7 +109,7 @@
</td> </td>
</tr> </tr>
</table> </table>
<span class="caption"><var:string label:value="Phones" /></span> <span class="caption"><var:string label:value="Phones" /></span>
<table class="frame"> <table class="frame">
<tr> <tr>
<td> <td>

View file

@ -52,13 +52,14 @@
/></label></div> /></label></div>
<var:if condition="mustSynchronize" const:negate="YES" <var:if condition="mustSynchronize" const:negate="YES"
><div><label><var:string ><div><span class="label"><var:string
label:value="Tag:"/><input type="text" label:value="Tag:"/></span
><span class="content"><input type="text"
name="calendarSyncTag" name="calendarSyncTag"
id="calendarSyncTag" id="calendarSyncTag"
class="textField" class="textField"
var:value="calendarSyncTag" var:value="calendarSyncTag"
/></label /></span
><var:if condition="synchronizeCalendar"><input type="hidden" ><var:if condition="synchronizeCalendar"><input type="hidden"
name="originalCalendarSyncTag" name="originalCalendarSyncTag"
id="originalCalendarSyncTag" id="originalCalendarSyncTag"

View file

@ -575,9 +575,17 @@ function onComposeMessage() {
} }
function composeNewMessage() { function composeNewMessage() {
var account = Mailer.currentMailbox.split("/")[1]; var account;
var url = ApplicationBaseURL + "/" + encodeURI(account) + "/compose"; if (Mailer.currentMailbox)
openMailComposeWindow(url); account = Mailer.currentMailbox.split("/")[1];
else if (mailAccounts.length)
account = mailAccounts[0][0];
else
account = null;
if (account) {
var url = ApplicationBaseURL + "/" + encodeURI(account) + "/compose";
openMailComposeWindow(url);
}
} }
function openMailbox(mailbox, reload, idx, updateStatus) { function openMailbox(mailbox, reload, idx, updateStatus) {

View file

@ -1972,7 +1972,7 @@ function onCalendarModify(event) {
var url = ApplicationBaseURL + calendarID + "/properties"; var url = ApplicationBaseURL + calendarID + "/properties";
var windowID = sanitizeWindowName(calendarID + " properties"); var windowID = sanitizeWindowName(calendarID + " properties");
var width = 310; var width = 310;
var height = 260; var height = 266;
var isWebCalendar = false; var isWebCalendar = false;
if (UserSettings['Calendar'] if (UserSettings['Calendar']
&& UserSettings['Calendar']['WebCalendars']) { && UserSettings['Calendar']['WebCalendars']) {
@ -1983,7 +1983,7 @@ function onCalendarModify(event) {
} }
} }
if (isWebCalendar) if (isWebCalendar)
height += 25; height += 21;
else if (calendarID == "/personal") else if (calendarID == "/personal")
height -= 25; height -= 25;

View file

@ -11,23 +11,28 @@ FIELDSET
border-top: 1px solid #909090; border-top: 1px solid #909090;
border-left: 1px solid #909090; } border-left: 1px solid #909090; }
FIELDSET DIV
{ margin-left: 20px;
margin-right: 10px; }
SPAN.label SPAN.label
{ cursor: default; { cursor: default;
width: 10em; width: 60px;
text-align: right; text-align: right;
padding-right: 1em;
line-height: 2em; line-height: 2em;
float: left; float: left;
display: block; } display: block; }
INPUT.checkBox
{ margin-left: 35px; }
SPAN.content SPAN.content
{ display: block; { display: block;
line-height: 1.5em; line-height: 1.5em;
vertical-align: middle; } vertical-align: middle; }
SPAN.content INPUT.textField SPAN.content INPUT.textField
{ width: 50%; } { width: 160px; }
BUTTON#colorButton BUTTON#colorButton
{ display: none; { display: none;
@ -45,6 +50,9 @@ DIV#buttons
INPUT#calendarSyncTag INPUT#calendarSyncTag
{ width: 7em; } { width: 7em; }
LABEL
{ white-space: nowrap; }
#webCalendarUrl SPAN.content #webCalendarUrl SPAN.content
{ white-space: nowrap; { white-space: nowrap;
overflow: hidden; } overflow: hidden; }

View file

@ -331,15 +331,18 @@ TABLE#categoriesList
DIV#windowButtons DIV#windowButtons
{ bottom: 11px; } { bottom: 11px; }
TABLE.frame, TABLE.frame
TABLE.framenocaption
{ margin-top: -4px; } { margin-top: -4px; }
TABLE.framenocaption
{ margin-top: 17px; }
TABLE.frame TBODY TABLE.frame TBODY
{ padding: 20px; } { padding: 20px; }
UL#calendarList UL#calendarList
{ height: 100px; } { margin-top: 2px;
height: 100px; }
A.toolbarButton SPAN, A.toolbarButton SPAN,
A.toolbarButton:hover SPAN { A.toolbarButton:hover SPAN {