merge of '2b69d044a61bdcebe73dd14659a3edfec3fd3530'

and '99cc1bb593f4002d820b712345f3e8c1c9ba44ba'

Monotone-Parent: 2b69d044a61bdcebe73dd14659a3edfec3fd3530
Monotone-Parent: 99cc1bb593f4002d820b712345f3e8c1c9ba44ba
Monotone-Revision: 350058ff37111e646407d97db552b5f4c9e96f90

Monotone-Author: ludovic@Sophos.ca
Monotone-Date: 2008-09-02T22:25:01
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Ludovic Marcotte 2008-09-02 22:25:01 +00:00
commit 5e55bdea7d
18 changed files with 1318 additions and 107 deletions

View file

@ -1,3 +1,51 @@
2008-09-02 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* SoObjects/Mailer/SOGoMailManager.m ([NGImap
-copyMailURL:toFolderURL:password:]): do not compare the urls
based on the instance that NGImap4ConnectionManager returns,
because disabling the pooling will generate a bad result, even
though the host:port pairs are the same.
2008-09-01 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailerUI/UIxMailView.m ([UIxMailView
-appendToResponse:_responseinContext:_ctx]): no longer invoke
[NGImap4Client logout], since this is now handled by the
NGImap4Connection manager (or not).
* UI/MailerUI/UIxMailActions.m ([UIxMailActions
-markMessageUnreadAction]): no longer make use of [SOGoMailFolder
unselect].
([UIxMailActions -markMessageReadAction]): idem.
* SoObjects/Mailer/SOGoMailFolder.m ([-unselect]): removed method
since we no longer need it.
* SoObjects/Mailer/SOGoMailBaseObject.m ([SOGoMailBaseObject
-dealloc]): release "imap4". If the IMAP4 connection pooling is
disabled, the object will otherwise never be released.
* SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount
+initialize]): use the user default "SOGoFallbackIMAP4Server" to
override the value of "serverName" from the actual user settings.
Fallback to "localhost" if value is unset.
* SoObjects/Mailer/SOGoMailAccount.m ([SOGoMailAccount
-imap4URLString]): use the value of SOGoFallbackIMAP4Server, as
mentionne above.
* UI/MailerUI/UIxMailEditor.m ([UIxMailEditor -from]): retain the
initialized value of from, otherwise we create a future zombie.
* SoObjects/SOGo/SOGoObject.m ([SOGoObject
-initWithName:_nameinContainer:_container]): we no longer retain
the context, to avoid making a circular reference.
* SoObjects/SOGo/SOGoUser.m ([SOGoUser
-initWithLogin:newLoginroles:newRoles]): moved the core from init
here.
([-init]): removed method.
2008-08-29 Wolfgang Sourdeau <wsourdeau@inverse.ca> 2008-08-29 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailerUI/UIxMailView.m ([UIxMailView * UI/MailerUI/UIxMailView.m ([UIxMailView

File diff suppressed because it is too large Load diff

View file

@ -57,6 +57,9 @@ static NSString *trashFolderName = nil;
static NSString *sharedFolderName = @""; // TODO: add English default static NSString *sharedFolderName = @""; // TODO: add English default
static NSString *otherUsersFolderName = @""; // TODO: add English default static NSString *otherUsersFolderName = @""; // TODO: add English default
// this is temporary, until we allow users to manage their own accounts
static NSString *fallbackIMAP4Server = nil;
+ (void) initialize + (void) initialize
{ {
NSUserDefaults *ud = [NSUserDefaults standardUserDefaults]; NSUserDefaults *ud = [NSUserDefaults standardUserDefaults];
@ -95,7 +98,16 @@ static NSString *otherUsersFolderName = @""; // TODO: add English default
else else
rootFolderNames = [[NSArray alloc] initWithObjects: rootFolderNames = [[NSArray alloc] initWithObjects:
draftsFolderName, draftsFolderName,
nil]; nil];
if (!fallbackIMAP4Server)
{
fallbackIMAP4Server = [ud stringForKey: @"SOGoFallbackIMAP4Server"];
if (fallbackIMAP4Server)
[fallbackIMAP4Server retain];
else
fallbackIMAP4Server = @"localhost";
}
} }
- (id) init - (id) init
@ -258,8 +270,14 @@ static NSString *otherUsersFolderName = @""; // TODO: add English default
escUsername escUsername
= [[username stringByEscapingURL] stringByReplacingString: @"@" = [[username stringByEscapingURL] stringByReplacingString: @"@"
withString: @"%40"]; withString: @"%40"];
#if 0
// see comment about fallbackIMAP4Server above
hostString = [NSString stringWithFormat: @"%@@%@", escUsername, hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
[mailAccount objectForKey: @"serverName"]]; [mailAccount objectForKey: @"serverName"]];
#else
hostString = [NSString stringWithFormat: @"%@@%@", escUsername,
fallbackIMAP4Server];
#endif
} }
else else
hostString = @"localhost"; hostString = @"localhost";

View file

@ -57,6 +57,7 @@ static BOOL debugOn = YES;
- (void) dealloc - (void) dealloc
{ {
[imap4URL release]; [imap4URL release];
[imap4 release];
[super dealloc]; [super dealloc];
} }
@ -121,7 +122,7 @@ static BOOL debugOn = YES;
imap4 = [[self mailManager] connectionForURL: [self imap4URL] imap4 = [[self mailManager] connectionForURL: [self imap4URL]
password: [self imap4Password]]; password: [self imap4Password]];
if (imap4) if (imap4)
[imap4 retain]; [imap4 retain];
else else
[self errorWithFormat:@"Could not connect IMAP4."]; [self errorWithFormat:@"Could not connect IMAP4."];
} }

View file

@ -64,7 +64,6 @@ typedef enum {
- (void) expungeLastMarkedFolder; - (void) expungeLastMarkedFolder;
- (NSException *) expunge; - (NSException *) expunge;
- (NSException *) unselect;
/* flags */ /* flags */

View file

@ -283,16 +283,6 @@ static BOOL aclConformsToIMAPExt = NO;
return [[self imap4Connection] expungeAtURL: [self imap4URL]]; return [[self imap4Connection] expungeAtURL: [self imap4URL]];
} }
- (NSException *) unselect
{
NGImap4Client *client;
client = [[self imap4Connection] client];
[client unselect];
return nil;
}
- (void) markForExpunge - (void) markForExpunge
{ {
NSUserDefaults *ud; NSUserDefaults *ud;

View file

@ -20,6 +20,8 @@
*/ */
#import <Foundation/NSArray.h> #import <Foundation/NSArray.h>
#import <Foundation/NSURL.h>
#import <Foundation/NSValue.h>
#import <NGObjWeb/NSException+HTTP.h> #import <NGObjWeb/NSException+HTTP.h>
#import <NGExtensions/NSNull+misc.h> #import <NGExtensions/NSNull+misc.h>
@ -194,20 +196,25 @@
password:(NSString *)_pwd password:(NSString *)_pwd
{ {
NGImap4Connection *entry; NGImap4Connection *entry;
NSNumber *destPort, *srcPort;
/* check connection cache */ /* check connection cache */
if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil) if ((entry = [self connectionForURL:_srcurl password:_pwd]) == nil)
return [self errorForMissingEntryAtURL:_srcurl]; return [self errorForMissingEntryAtURL:_srcurl];
/* check whether URLs are on different servers */ /* check whether URLs are on different servers */
srcPort = [_srcurl port];
if ([self connectionForURL:_desturl password:_pwd] != entry) { destPort = [_desturl port];
if (!([[_desturl host] isEqualToString: [_srcurl host]]
&& (srcPort == destPort
|| [destPort isEqualToNumber: srcPort]))) {
// TODO: find a better error code // TODO: find a better error code
return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */ return [NSException exceptionWithHTTPStatus:502 /* Bad Gateway */
reason:@"source and destination on different servers"]; reason:@"source and destination on different servers"];
} }
return [entry copyMailURL:_srcurl toFolderURL:_desturl]; return [entry copyMailURL:_srcurl toFolderURL:_desturl];
} }

View file

@ -87,7 +87,8 @@ static BOOL forceImapLoginWithEmail = NO;
if (sourceID) if (sourceID)
[sources setObject: ldapSource forKey: sourceID]; [sources setObject: ldapSource forKey: sourceID];
else else
NSLog(@"LDAPUserManager.m: WARNING: id field missing in a LDAP source, check the SOGoLDAPSources default"); [self errorWithFormat: @"id field missing in a LDAP source,"
@" check the SOGoLDAPSources defaults"];
metadata = [NSMutableDictionary dictionary]; metadata = [NSMutableDictionary dictionary];
value = [udSource objectForKey: @"canAuthenticate"]; value = [udSource objectForKey: @"canAuthenticate"];
if (value) if (value)
@ -121,6 +122,7 @@ static BOOL forceImapLoginWithEmail = NO;
- (id) init - (id) init
{ {
NSUserDefaults *ud; NSUserDefaults *ud;
NSString *cleanupSetting;
if ((self = [super init])) if ((self = [super init]))
{ {
@ -129,14 +131,24 @@ static BOOL forceImapLoginWithEmail = NO;
sources = nil; sources = nil;
sourcesMetadata = nil; sourcesMetadata = nil;
users = [NSMutableDictionary new]; users = [NSMutableDictionary new];
cleanupInterval cleanupSetting
= [ud integerForKey: @"SOGoLDAPUserManagerCleanupInterval"]; = [ud objectForKey: @"SOGoLDAPUserManagerCleanupInterval"];
if (cleanupInterval) if (cleanupSetting)
cleanupTimer = [NSTimer scheduledTimerWithTimeInterval: cleanupInterval cleanupInterval = [cleanupSetting doubleValue];
target: self else
selector: @selector(cleanupSources) cleanupInterval = 0.0;
userInfo: nil if (cleanupInterval > 0.0)
repeats: YES]; {
cleanupTimer = [NSTimer scheduledTimerWithTimeInterval: cleanupInterval
target: self
selector: @selector (_cleanupSources)
userInfo: nil
repeats: YES];
[self logWithFormat: @"cleanup interval set every %f seconds",
cleanupInterval];
}
else
[self logWithFormat: @"no cleanup interval set: memory usage will grow"];
[self _prepareLDAPSourcesWithDefaults: ud]; [self _prepareLDAPSourcesWithDefaults: ud];
} }
@ -384,12 +396,8 @@ static BOOL forceImapLoginWithEmail = NO;
if (key) if (key)
[users setObject: newUser forKey: key]; [users setObject: newUser forKey: key];
emails = [[newUser objectForKey: @"emails"] objectEnumerator]; emails = [[newUser objectForKey: @"emails"] objectEnumerator];
key = [emails nextObject]; while ((key = [emails nextObject]))
while (key) [users setObject: newUser forKey: key];
{
[users setObject: newUser forKey: key];
key = [emails nextObject];
}
} }
- (NSDictionary *) contactInfosForUserWithUIDorEmail: (NSString *) uid - (NSDictionary *) contactInfosForUserWithUIDorEmail: (NSString *) uid
@ -532,22 +540,32 @@ static BOOL forceImapLoginWithEmail = NO;
matching: filter]; matching: filter];
} }
- (void) cleanupSources - (void) _cleanupSources
{ {
NSEnumerator *userIDs; NSEnumerator *userIDs;
NSString *currentID; NSString *currentID;
NSDictionary *currentUser; NSDictionary *currentUser;
NSDate *now; NSDate *now;
unsigned int count;
now = [NSDate date]; now = [NSDate date];
count = 0;
userIDs = [[users allKeys] objectEnumerator]; userIDs = [[users allKeys] objectEnumerator];
while ((currentID = [userIDs nextObject])) while ((currentID = [userIDs nextObject]))
{ {
currentUser = [users objectForKey: currentID]; currentUser = [users objectForKey: currentID];
if ([now earlierDate: if ([now earlierDate:
[currentUser objectForKey: @"cleanupDate"]] == now) [currentUser objectForKey: @"cleanupDate"]] == now)
[users removeObjectForKey: currentID]; {
[users removeObjectForKey: currentID];
count++;
}
} }
if (count)
[self logWithFormat: @"cleaned %d users records from cache", count];
} }
@end @end

View file

@ -270,7 +270,6 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
if ((self = [self init])) if ((self = [self init]))
{ {
context = [[WOApplication application] context]; context = [[WOApplication application] context];
[context retain];
nameInContainer = [_name copy]; nameInContainer = [_name copy];
container = _container; container = _container;
if ([self doesRetainContainer]) if ([self doesRetainContainer])
@ -285,7 +284,6 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
- (void) dealloc - (void) dealloc
{ {
[context release];
[owner release]; [owner release];
if ([self doesRetainContainer]) if ([self doesRetainContainer])
[container release]; [container release];
@ -402,7 +400,7 @@ SEL SOGoSelectorForPropertySetter (NSString *property)
{ {
obj = [[self soClass] lookupKey: lookupName inContext: localContext]; obj = [[self soClass] lookupKey: lookupName inContext: localContext];
if (obj) if (obj)
[obj bindToObject: self inContext: localContext]; obj = [obj bindToObject: self inContext: localContext];
} }
if (obj) if (obj)

View file

@ -201,7 +201,7 @@ _timeValue (NSString *key)
if (user) if (user)
{ {
[user autorelease]; [user autorelease];
[cache registerUser: user]; [cache registerUser: user];
} }
} }
[user setPrimaryRoles: newRoles]; [user setPrimaryRoles: newRoles];
@ -209,25 +209,6 @@ _timeValue (NSString *key)
return user; return user;
} }
- (id) init
{
if ((self = [super init]))
{
userDefaults = nil;
userSettings = nil;
allEmails = nil;
language = nil;
currentPassword = nil;
dateFormatter = nil;
homeFolder = nil;
cn = nil;
userTimeZone = nil;
mailAccounts = nil;
}
return self;
}
- (id) initWithLogin: (NSString *) newLogin - (id) initWithLogin: (NSString *) newLogin
roles: (NSArray *) newRoles roles: (NSArray *) newRoles
{ {
@ -247,7 +228,21 @@ _timeValue (NSString *key)
} }
if ([realUID length]) if ([realUID length])
self = [super initWithLogin: realUID roles: newRoles]; {
if ((self = [super initWithLogin: realUID roles: newRoles]))
{
userDefaults = nil;
userSettings = nil;
allEmails = nil;
language = nil;
currentPassword = nil;
dateFormatter = nil;
homeFolder = nil;
cn = nil;
userTimeZone = nil;
mailAccounts = nil;
}
}
else else
{ {
[self release]; [self release];

View file

@ -151,7 +151,6 @@
if (!response) if (!response)
{ {
mailFolder = [[self clientObject] container]; mailFolder = [[self clientObject] container];
[mailFolder unselect];
response = [self responseWith204]; response = [self responseWith204];
} }
@ -167,7 +166,6 @@
if (!response) if (!response)
{ {
mailFolder = [[self clientObject] container]; mailFolder = [[self clientObject] container];
[mailFolder unselect];
response = [self responseWith204]; response = [self responseWith204];
} }

View file

@ -135,6 +135,7 @@ static NSArray *infoKeys = nil;
{ {
identity = [[context activeUser] primaryIdentity]; identity = [[context activeUser] primaryIdentity];
from = [identity keysWithFormat: @"%{fullName} <%{email}>"]; from = [identity keysWithFormat: @"%{fullName} <%{email}>"];
[from retain];
} }
return from; return from;

View file

@ -211,7 +211,6 @@ static NSString *mailETag = nil;
inContext: (WOContext *) _ctx inContext: (WOContext *) _ctx
{ {
UIxMailRenderingContext *mctx; UIxMailRenderingContext *mctx;
NGImap4Connection *conn;
if (mailETag != nil) if (mailETag != nil)
[[_ctx response] setHeader:mailETag forKey:@"etag"]; [[_ctx response] setHeader:mailETag forKey:@"etag"];
@ -225,9 +224,6 @@ static NSString *mailETag = nil;
[super appendToResponse: _response inContext: _ctx]; [super appendToResponse: _response inContext: _ctx];
[[_ctx popMailRenderingContext] reset]; [[_ctx popMailRenderingContext] reset];
conn = [[self clientObject] imap4Connection];
[[conn client] logout];
} }
@end /* UIxMailView */ @end /* UIxMailView */

View file

@ -130,6 +130,7 @@ static BOOL uixDebugEnabled = NO;
if ((self = [super init])) if ((self = [super init]))
{ {
_selectedDate = nil; _selectedDate = nil;
queryParameters = nil;
} }
return self; return self;

View file

@ -262,7 +262,7 @@ function deleteSelectedMessagesCallback(http) {
if (!nextRow) if (!nextRow)
nextRow = row.previous("tr"); nextRow = row.previous("tr");
// row.addClassName("deleted"); // when we'll offer "mark as deleted" // row.addClassName("deleted"); // when we'll offer "mark as deleted"
if (deleteMessageRequestCount == 0) { if (deleteMessageRequestCount == 0) {
if (nextRow) { if (nextRow) {
Mailer.currentMessages[Mailer.currentMailbox] = nextRow.getAttribute("id").substr(4); Mailer.currentMessages[Mailer.currentMailbox] = nextRow.getAttribute("id").substr(4);
@ -1567,8 +1567,12 @@ function getFoldersStateCallback(http) {
function saveFoldersState() { function saveFoldersState() {
if (mailAccounts.length > 0) { if (mailAccounts.length > 0) {
var foldersState = mailboxTree.getFoldersState(); var foldersState = mailboxTree.getFoldersState();
var urlstr = ApplicationBaseURL + "saveFoldersState" + "?expandedFolders=" + foldersState; var urlstr = ApplicationBaseURL + "saveFoldersState";
triggerAjaxRequest(urlstr, saveFoldersStateCallback); var parameters = "expandedFolders=" + foldersState;
triggerAjaxRequest(urlstr, saveFoldersStateCallback, null, parameters,
{ "Content-type": "application/x-www-form-urlencoded",
"Content-length": parameters.length,
"Connection": "close" });
} }
} }

View file

@ -153,5 +153,5 @@ UL#attachments LI IMG
left: 0em; left: 0em;
right: 0em; right: 0em;
bottom: 0em; bottom: 0em;
top: 13em; top: 999em;
width: 99%; } width: 99%; }

View file

@ -8,7 +8,7 @@ var MailEditor = {
addressBook: null, addressBook: null,
currentField: null, currentField: null,
selectedIndex: -1, selectedIndex: -1,
delay: 500, delay: 750,
delayedSearch: false delayedSearch: false
}; };
@ -273,7 +273,7 @@ function onTextFocus() {
} }
function onTextKeyDown(event) { function onTextKeyDown(event) {
if (event.keyCode == 9) { if (event.keyCode == Event.KEY_TAB) {
if (event.shiftKey) { if (event.shiftKey) {
var nodes = $("subjectRow").childNodesWithTag("input"); var nodes = $("subjectRow").childNodesWithTag("input");
var objectInput = $(nodes[0]); var objectInput = $(nodes[0]);
@ -341,39 +341,39 @@ function onContactKeydown(event) {
this.focussed = true; this.focussed = true;
return; return;
} }
if (event.keyCode == 9) { // Tab if (event.keyCode == Event.KEY_TAB) {
if (this.confirmedValue) if (this.confirmedValue)
this.value = this.confirmedValue; this.value = this.confirmedValue;
if (document.currentPopupMenu) if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu); hideMenu(document.currentPopupMenu);
} }
else if (event.keyCode == 0 else if (event.keyCode == 0
|| event.keyCode == 8 // Backspace || event.keyCode == Event.KEY_BACKSPACE
|| event.keyCode == 32 // Space || event.keyCode == 32 // Space
|| event.keyCode > 47) { || event.keyCode > 47) {
this.confirmedValue = null; this.confirmedValue = null;
MailEditor.selectedIndex = -1; MailEditor.selectedIndex = -1;
MailEditor.currentField = this; MailEditor.currentField = this;
if (this.value.length > 0 && !MailEditor.delayedSearch) { if (this.value.length > 1) {
MailEditor.delayedSearch = true; if (MailEditor.delayedSearch) window.clearTimeout(MailEditor.delayedSearch);
setTimeout("performSearch()", MailEditor.delay); MailEditor.delayedSearch = window.setTimeout("performSearch()", MailEditor.delay);
} }
else if (this.value.length == 0) { else if (this.value.length <= 1) {
if (document.currentPopupMenu) if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu); hideMenu(document.currentPopupMenu);
} }
} }
else if (event.keyCode == 13) { else if (event.keyCode == Event.KEY_RETURN) {
preventDefault(event); preventDefault(event);
if (this.confirmedValue) if (this.confirmedValue)
this.value = this.confirmedValue; this.value = this.confirmedValue;
$(this).selectText(0, this.value.length); $(this).select();
if (document.currentPopupMenu) if (document.currentPopupMenu)
hideMenu(document.currentPopupMenu); hideMenu(document.currentPopupMenu);
MailEditor.selectedIndex = -1; MailEditor.selectedIndex = -1;
} }
else if ($('contactsMenu').getStyle('visibility') == 'visible') { else if ($('contactsMenu').getStyle('visibility') == 'visible') {
if (event.keyCode == 38) { // Up arrow if (event.keyCode == Event.KEY_UP) { // Up arrow
if (MailEditor.selectedIndex > 0) { if (MailEditor.selectedIndex > 0) {
var contacts = $('contactsMenu').select("li"); var contacts = $('contactsMenu').select("li");
contacts[MailEditor.selectedIndex--].removeClassName("selected"); contacts[MailEditor.selectedIndex--].removeClassName("selected");
@ -381,7 +381,7 @@ function onContactKeydown(event) {
contacts[MailEditor.selectedIndex].addClassName("selected"); contacts[MailEditor.selectedIndex].addClassName("selected");
} }
} }
else if (event.keyCode == 40) { // Down arrow else if (event.keyCode == Event.KEY_DOWN) { // Down arrow
var contacts = $('contactsMenu').select("li"); var contacts = $('contactsMenu').select("li");
if (contacts.size() - 1 > MailEditor.selectedIndex) { if (contacts.size() - 1 > MailEditor.selectedIndex) {
if (MailEditor.selectedIndex >= 0) if (MailEditor.selectedIndex >= 0)
@ -402,14 +402,13 @@ function performSearch() {
document.contactLookupAjaxRequest.aborted = true; document.contactLookupAjaxRequest.aborted = true;
document.contactLookupAjaxRequest.abort(); document.contactLookupAjaxRequest.abort();
} }
if (MailEditor.currentField.value.trim().length > 0) { if (MailEditor.currentField.value.trim().length > 1) {
var urlstr = ( UserFolderURL + "Contacts/allContactSearch?search=" var urlstr = ( UserFolderURL + "Contacts/allContactSearch?search="
+ MailEditor.currentField.value ); + MailEditor.currentField.value );
document.contactLookupAjaxRequest = document.contactLookupAjaxRequest =
triggerAjaxRequest(urlstr, performSearchCallback, MailEditor.currentField); triggerAjaxRequest(urlstr, performSearchCallback, MailEditor.currentField);
} }
} }
MailEditor.delayedSearch = false;
} }
function performSearchCallback(http) { function performSearchCallback(http) {
@ -543,7 +542,8 @@ function initMailEditor() {
textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false); textarea.observe(ieEvents[i], onTextIEUpdateCursorPos, false);
} }
initTabIndex($("addressList"), $$("div#subjectRow input").first(), textarea); var subjectField = $$("div#subjectRow input").first();
initTabIndex($("addressList"), subjectField, textarea);
onWindowResize(null); onWindowResize(null);
Event.observe(window, "resize", onWindowResize); Event.observe(window, "resize", onWindowResize);
@ -632,10 +632,11 @@ function onWindowResize(event) {
addresslist.setStyle({ width: ($(this).width() - attachmentswidth - 10) + 'px' }); addresslist.setStyle({ width: ($(this).width() - attachmentswidth - 10) + 'px' });
// Set textarea position // Set textarea position
textarea.setStyle({ 'top': headerarea.select("hr").first().offsetTop + 'px' }); var hr = headerarea.select("hr").first();
textarea.setStyle({ 'top': hr.offsetTop + 'px' });
// Resize the textarea (message content) // Resize the textarea (message content)
textarea.rows = Math.round((window.height() - textarea.offsetTop) / rowheight); textarea.rows = Math.floor((window.height() - textarea.offsetTop) / rowheight);
} }
function onMailEditorClose(event) { function onMailEditorClose(event) {

View file

@ -29,7 +29,8 @@ function onICalendarButtonClick(event) {
function onMenuDeleteMessage(event) { function onMenuDeleteMessage(event) {
if (window.opener && window.opener.open && !window.opener.closed) { if (window.opener && window.opener.open && !window.opener.closed) {
var rowId = window.name.substr(9); var rowId_index = window.name.search(/[0-9]+$/);
var rowId = window.name.substr(rowId_index);
var messageId = window.opener.Mailer.currentMailbox + "/" + rowId; var messageId = window.opener.Mailer.currentMailbox + "/" + rowId;
var url = ApplicationBaseURL + messageId + "/trash"; var url = ApplicationBaseURL + messageId + "/trash";