Monotone-Parent: a164259525f718f804b625a9f09b4c3b3c9e83f8

Monotone-Revision: 11f4bdac420d36e45b12ca5d1d393ec34f43c609

Monotone-Author: wsourdeau@inverse.ca
Monotone-Date: 2007-11-10T00:02:30
Monotone-Branch: ca.inverse.sogo
This commit is contained in:
Wolfgang Sourdeau 2007-11-10 00:02:30 +00:00
parent aebac17d01
commit 1eda040e84
13 changed files with 563 additions and 416 deletions

View file

@ -1,5 +1,21 @@
2007-11-09 Wolfgang Sourdeau <wsourdeau@inverse.ca>
* UI/MailPartViewers/UIxMailPartICalViewer.m
([UIxMailPartICalViewer -acceptLink])
([UIxMailPartICalViewer -declineLink])
([UIxMailPartICalViewer -tentativeLink]): removed useless methods.
* UI/MailPartViewers/UIxMailPartICalAction.m ([UIxMailPartICalAction -addToCalendarAction])
([UIxMailPartICalAction -deleteFromCalendarAction]): new stub
methods.
* SoObjects/Mailer/SOGoMailObject.m ([SOGoMailObject
-lookupImap4BodyPartKey:]): make use of the new method below.
* SoObjects/Mailer/SOGoMailBodyPart.m ([SOGoMailBodyPart
+bodyPartClassForMimeType:mimeTypeinContext:_ctx]): new method
that returns an appropriate Class depending on a given mime type.
* UI/SOGoUI/UIxComponent.m ([UIxComponent -canCreateOrModify]):
new boolean accessor that determines whether someone can create
(i.e. modify a new entry) or modify an existing entry.

View file

@ -62,6 +62,8 @@
+ (Class) bodyPartClassForKey: (NSString *) _key
inContext: (id) _ctx;
+ (Class) bodyPartClassForMimeType: (NSString *) mimeType
inContext: (id) _ctx;
@end

View file

@ -34,6 +34,8 @@
#import <NGExtensions/NGBase64Coding.h>
#import <NGImap4/NGImap4Connection.h>
#import <SoObjects/SOGo/NSDictionary+Utilities.h>
#import "SOGoMailObject.h"
#import "SOGoMailManager.h"
@ -305,7 +307,9 @@ static BOOL debugOn = NO;
/* factory */
+ (Class)bodyPartClassForKey:(NSString *)_key inContext:(id)_ctx {
+ (Class) bodyPartClassForKey: (NSString *) _key
inContext: (id) _ctx
{
NSString *pe;
pe = [_key pathExtension];
@ -335,6 +339,36 @@ static BOOL debugOn = NO;
return self;
}
+ (Class) bodyPartClassForMimeType: (NSString *) mimeType
inContext: (id) _ctx
{
NSString *classString;
Class klazz;
if ([mimeType isEqualToString: @"image/gif"]
|| [mimeType isEqualToString: @"image/png"]
|| [mimeType isEqualToString: @"image/jpg"])
classString = @"SOGoImageMailBodyPart";
else if ([mimeType isEqualToString: @"text/calendar"])
classString = @"SOGoCalendarMailBodyPart";
else if ([mimeType isEqualToString: @"text/x-vcard"])
classString = @"SOGoVCardMailBodyPart";
else if ([mimeType isEqualToString: @"message/rfc822"])
classString = @"SOGoMessageMailBodyPart";
else
{
NSLog (@"unhandled mime type: '%@'", mimeType);
classString = nil;
}
if (classString)
klazz = NSClassFromString (classString);
else
klazz = Nil;
return klazz;
}
/* etag support */
- (id)davEntityTag {

View file

@ -735,8 +735,22 @@ static BOOL debugSoParts = NO;
{
// TODO: we might want to check for existence prior controller creation
Class clazz;
NSArray *parts;
int part;
NSDictionary *partDesc;
NSString *mimeType;
clazz = [SOGoMailBodyPart bodyPartClassForKey:_key inContext:_ctx];
parts = [[self bodyStructure] objectForKey: @"parts"];
part = [_key intValue] - 1;
if (part > -1 && part < [parts count])
{
partDesc = [parts objectAtIndex: part];
mimeType = [[partDesc keysWithFormat: @"%{type}/%{subtype}"] lowercaseString];
clazz = [SOGoMailBodyPart bodyPartClassForMimeType: mimeType
inContext: _ctx];
}
else
clazz = Nil;
return [clazz objectWithName:_key inContainer: self];
}

View file

@ -17,15 +17,17 @@ Organizer = "Organisateur";
Time = "Time";
Attendees = "Attendees";
request_info = "invites you to participate in a meeting.";
do_add_to_cal = "add to calendar";
do_del_from_cal = "delete from calendar";
do_accept = "accept";
do_decline = "decline";
do_tentative = "tentative";
do_update_status = "update status in calendar";
"Add to calendar" = "Add to calendar";
"Delete from calendar" = "Delete from calendar";
Accept = "Accept";
Decline = "Decline";
Tentative = "Tentative";
"Update status in calendar" = "Update status in calendar";
reply_info_no_attendee = "You received a reply to a scheduling event but the sender of the reply is not a participant.";
reply_info = "This is a reply to an event invitation done by you.";
"to" = "to";
"Untitled" = "Untitled";
"Size" = "Size";

View file

@ -17,15 +17,17 @@ Organizer = "Organisateur";
Time = "Date";
Attendees = "Invités";
request_info = "vous invite à une réunion.";
do_add_to_cal = "ajouter à l'agenda";
do_del_from_cal = "effacer de l'agenda";
do_accept = "accepter";
do_decline = "decliner";
do_tentative = "tentative";
do_update_status = "mettre l'agenda à jour";
"Add to calendar" = "Ajouter à l'agenda";
"Delete from calendar" = "Effacer de l'agenda";
Accept = "Accepter";
Decline = "Decliner";
Tentative = "Tentative";
"Update status in calendar" = "Mettre l'agenda à jour";
reply_info_no_attendee = "Vous avez reçu une réponse à un événement mais l'expéditeur n'est pas un invité.";
reply_info = "Ceci est une réponse à un événement que vous avez organisé.";
"to" = "à";
"Untitled" = "Sans titre";
"Size" = "Taille";

View file

@ -17,15 +17,17 @@ Organizer = "Organisateur";
Time = "Time";
Attendees = "Attendees";
request_info = "invites you to participate in a meeting.";
do_add_to_cal = "add to calendar";
do_del_from_cal = "delete from calendar";
do_accept = "accept";
do_decline = "decline";
do_tentative = "tentative";
do_update_status = "update status in calendar";
"Add to calendar" = "Add to calendar";
"Delete from calendar" = "Delete from calendar";
Accept = "Accept";
Decline = "Decline";
Tentative = "Tentative";
"Update status in calendar" = "Update status in calendar";
reply_info_no_attendee = "You received a reply to a scheduling event but the sender of the reply is not a participant.";
reply_info = "This is a reply to an event invitation done by you.";
"to" = "to";
"Untitled" = "Untitled";
"Size" = "Size";

View file

@ -1,76 +1,63 @@
/*
Copyright (C) 2005 SKYRIX Software AG
/* UIxMailPartICalAction.m - this file is part of SOGo
*
* Copyright (C) 2007 Inverse groupe conseil
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
*
* This file is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This file is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*/
This file is part of OpenGroupware.org.
OGo is free software; you can redistribute it and/or modify it under
the terms of the GNU Lesser General Public License as published by the
Free Software Foundation; either version 2, or (at your option) any
later version.
OGo is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
License for more details.
You should have received a copy of the GNU Lesser General Public
License along with OGo; see the file COPYING. If not, write to the
Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.
*/
#import <NGObjWeb/SoObject.h>
#import <NGObjWeb/WOContext.h>
#import <NGObjWeb/WOResponse.h>
#import <Foundation/NSString.h>
#import <NGObjWeb/WODirectAction.h>
#import <NGExtensions/NSNull+misc.h>
#import <NGExtensions/NSString+misc.h>
#import <UI/Common/WODirectAction+SOGo.h>
@interface UIxMailPartICalAction : WODirectAction
@end
@implementation UIxMailPartICalAction
- (id)redirectToViewerWithError:(NSString *)_error {
WOResponse *r;
NSString *viewURL;
id mail;
mail = [[self clientObject] valueForKey:@"mailObject"];
[self logWithFormat:@"MAIL: %@", mail];
viewURL = [mail baseURLInContext:[self context]];
[self logWithFormat:@" url: %@", viewURL];
viewURL = [viewURL stringByAppendingString:
[viewURL hasSuffix:@"/"] ? @"view" : @"/view"];
if ([_error isNotNull] && [_error length] > 0) {
viewURL = [viewURL stringByAppendingString:@"?error="];
viewURL = [viewURL stringByAppendingString:
[_error stringByEscapingURL]];
}
r = [[self context] response];
[r setStatus:302 /* moved */];
[r setHeader:viewURL forKey:@"location"];
return r;
- (WOResponse *) _changePartStatusAction: (NSString *) _newStatus
{
return [self responseWithStatus: 404];
}
- (id)changePartStatusAction:(NSString *)_newStatus {
[self logWithFormat:@"TODO: should %@: %@", _newStatus, [self clientObject]];
return [self redirectToViewerWithError:
[_newStatus stringByAppendingString:@" not implemented!"]];
- (WOResponse *) markAcceptedAction
{
return [self _changePartStatusAction: @"ACCEPTED"];
}
- (id)markAcceptedAction {
return [self changePartStatusAction:@"ACCEPTED"];
- (WOResponse *) markDeclinedAction
{
return [self _changePartStatusAction: @"DECLINED"];
}
- (id)markDeclinedAction {
return [self changePartStatusAction:@"DECLINED"];
- (WOResponse *) markTentativeAction
{
return [self _changePartStatusAction: @"TENTATIVE"];
}
- (id)markTentativeAction {
return [self changePartStatusAction:@"TENTATIVE"];
- (WOResponse *) addToCalendarAction
{
return [self responseWithStatus: 404];
}
- (WOResponse *) deleteFromCalendarAction
{
return [self responseWithStatus: 404];
}
@end /* UIxMailPartICalAction */

View file

@ -46,34 +46,37 @@
@implementation UIxMailPartICalViewer
- (void)dealloc {
[self->storedEventObject release];
[self->storedEvent release];
[self->attendee release];
[self->item release];
[self->inCalendar release];
[self->inEvent release];
[self->dateFormatter release];
- (void) dealloc
{
[storedEventObject release];
[storedEvent release];
[attendee release];
[item release];
[inCalendar release];
[inEvent release];
[dateFormatter release];
[super dealloc];
}
/* maintain caches */
- (void)resetPathCaches {
- (void) resetPathCaches
{
[super resetPathCaches];
[self->inEvent release]; self->inEvent = nil;
[self->inCalendar release]; self->inCalendar = nil;
[self->storedEventObject release]; self->storedEventObject = nil;
[self->storedEvent release]; self->storedEvent = nil;
[inEvent release]; inEvent = nil;
[inCalendar release]; inCalendar = nil;
[storedEventObject release]; storedEventObject = nil;
[storedEvent release]; storedEvent = nil;
/* not strictly path-related, but useless without it anyway: */
[self->attendee release]; self->attendee = nil;
[self->item release]; self->item = nil;
[attendee release]; attendee = nil;
[item release]; item = nil;
}
/* raw content handling */
- (NSStringEncoding)fallbackStringEncoding {
- (NSStringEncoding) fallbackStringEncoding
{
/*
iCalendar invitations sent by Outlook 2002 have the annoying bug that the
mail states an UTF-8 content encoding but the actual iCalendar content is
@ -102,52 +105,66 @@
return inCalendar;
}
- (BOOL)couldParseCalendar {
- (BOOL) couldParseCalendar
{
return [[self inCalendar] isNotNull];
}
- (iCalEvent *)inEvent {
- (iCalEvent *) inEvent
{
NSArray *events;
if (self->inEvent != nil)
return [self->inEvent isNotNull] ? self->inEvent : nil;
if (inEvent)
return [inEvent isNotNull] ? inEvent : nil;
events = [[self inCalendar] events];
if ([events count] > 0) {
self->inEvent = [[events objectAtIndex:0] retain];
return self->inEvent;
inEvent = [[events objectAtIndex:0] retain];
return inEvent;
}
else {
self->inEvent = [[NSNull null] retain];
inEvent = [[NSNull null] retain];
return nil;
}
}
/* formatters */
- (SOGoDateFormatter *)dateFormatter {
if (self->dateFormatter == nil) {
- (SOGoDateFormatter *) dateFormatter
{
if (dateFormatter == nil) {
dateFormatter = [[context activeUser] dateFormatterInContext: context];
[dateFormatter retain];
}
return self->dateFormatter;
return dateFormatter;
}
/* below is copied from UIxAppointmentView, can we avoid that? */
- (void)setAttendee:(id)_attendee {
ASSIGN(self->attendee, _attendee);
- (void) setAttendee: (id) _attendee
{
ASSIGN(attendee, _attendee);
}
- (id)attendee {
return self->attendee;
- (id) attendee
{
return attendee;
}
- (NSString *) _personForDisplay: (iCalPerson *) person
{
return [NSString stringWithFormat: @"%@ <%@>",
[person cnWithoutQuotes],
[person rfc822Email]];
NSString *fn, *email, *result;
fn = [person cnWithoutQuotes];
email = [person rfc822Email];
if ([fn length])
result = [NSString stringWithFormat: @"%@ <%@>",
fn, email];
else
result = email;
return result;
}
- (NSString *) attendeeForDisplay
@ -155,11 +172,14 @@
return [self _personForDisplay: attendee];
}
- (void)setItem:(id)_item {
ASSIGN(self->item, _item);
- (void) setItem: (id) _item
{
ASSIGN(item, _item);
}
- (id)item {
return self->item;
- (id) item
{
return item;
}
- (NSCalendarDate *) startTime
@ -186,10 +206,13 @@
return date;
}
- (BOOL)isEndDateOnSameDay {
- (BOOL) isEndDateOnSameDay
{
return [[self startTime] isDateOnSameDay:[self endTime]];
}
- (NSTimeInterval)duration {
- (NSTimeInterval) duration
{
return [[self endTime] timeIntervalSinceDate:[self startTime]];
}
@ -209,12 +232,13 @@
return [folder lookupName: @"personal" inContext: context acquire: NO];
}
- (id)storedEventObject {
- (id) storedEventObject
{
/* lookup object in the users Calendar */
id calendar;
if (self->storedEventObject != nil)
return [self->storedEventObject isNotNull] ? self->storedEventObject : nil;
if (storedEventObject)
return [storedEventObject isNotNull] ? storedEventObject : nil;
calendar = [self calendarFolder];
if ([calendar isKindOfClass:[NSException class]]) {
@ -224,7 +248,7 @@
NSString *filename;
filename = [calendar resourceNameForEventUID:[[self inEvent] uid]];
if (filename != nil) {
if (filename) {
// TODO: When we get an exception, this might be an auth issue meaning
// that the UID indeed exists but that the user has no access to
// the object.
@ -233,21 +257,23 @@
tmp = [calendar lookupName:filename inContext:[self context] acquire:NO];
if ([tmp isNotNull] && ![tmp isKindOfClass:[NSException class]])
self->storedEventObject = [tmp retain];
storedEventObject = [tmp retain];
}
}
if (self->storedEventObject == nil)
self->storedEventObject = [[NSNull null] retain];
if (storedEventObject == nil)
storedEventObject = [[NSNull null] retain];
return self->storedEventObject;
return storedEventObject;
}
- (BOOL)isEventStoredInCalendar {
- (BOOL) isEventStoredInCalendar
{
return [[self storedEventObject] isNotNull];
}
- (iCalEvent *)storedEvent {
- (iCalEvent *) storedEvent
{
return (iCalEvent *) [(SOGoAppointmentObject *)[self storedEventObject] component: NO];
}
@ -262,14 +288,16 @@
return [identity objectForKey: @"email"];
}
- (iCalEvent *)authorativeEvent {
- (iCalEvent *) authorativeEvent
{
/* DB is considered master, when in DB, ignore mail organizer */
return [self isEventStoredInCalendar]
? [self storedEvent]
: [self inEvent];
}
- (BOOL)isLoggedInUserTheOrganizer {
- (BOOL) isLoggedInUserTheOrganizer
{
NSString *loginEMail;
if ((loginEMail = [self loggedInUserEMail]) == nil) {
@ -280,7 +308,8 @@
return [[self authorativeEvent] isOrganizer:loginEMail];
}
- (BOOL)isLoggedInUserAnAttendee {
- (BOOL) isLoggedInUserAnAttendee
{
NSString *loginEMail;
if ((loginEMail = [self loggedInUserEMail]) == nil) {
@ -309,7 +338,8 @@
/* replies */
- (NGImap4EnvelopeAddress *)replySenderAddress {
- (NGImap4EnvelopeAddress *) replySenderAddress
{
/*
The iMIP reply is the sender of the mail, the 'attendees' are NOT set to
the actual attendees. BUT the attendee field contains the reply-status!
@ -321,14 +351,18 @@
return [tmp objectAtIndex:0];
}
- (NSString *)replySenderEMail {
- (NSString *) replySenderEMail
{
return [[self replySenderAddress] email];
}
- (NSString *)replySenderBaseEMail {
- (NSString *) replySenderBaseEMail
{
return [[self replySenderAddress] baseEMail];
}
- (iCalPerson *)inReplyAttendee {
- (iCalPerson *) inReplyAttendee
{
NSArray *attendees;
attendees = [[self inEvent] attendees];
@ -339,7 +373,9 @@
return [attendees objectAtIndex:0];
}
- (iCalPerson *)storedReplyAttendee {
- (iCalPerson *) storedReplyAttendee
{
/*
TODO: since an attendee can have multiple email addresses, maybe we
should translate the email to an internal uid and then retrieve
@ -350,28 +386,22 @@
iCalEvent *e;
iCalPerson *p;
if ((e = [self storedEvent]) == nil)
return nil;
if ((p = [e findParticipantWithEmail:[self replySenderBaseEMail]]))
p = nil;
e = [self storedEvent];
if (e)
{
p = [e findParticipantWithEmail: [self replySenderBaseEMail]];
if (!p)
p = [e findParticipantWithEmail:[self replySenderEMail]];
}
return p;
if ((p = [e findParticipantWithEmail:[self replySenderEMail]]))
return p;
return nil;
}
- (BOOL)isReplySenderAnAttendee {
- (BOOL) isReplySenderAnAttendee
{
return [[self storedReplyAttendee] isNotNull];
}
/* action URLs */
- (id)acceptLink {
return [[self pathToAttachmentObject] stringByAppendingString:@"/accept"];
}
- (id)declineLink {
return [[self pathToAttachmentObject] stringByAppendingString:@"/decline"];
}
- (id)tentativeLink {
return [[self pathToAttachmentObject] stringByAppendingString:@"/tentative"];
}
@end /* UIxMailPartICalViewer */

View file

@ -25,6 +25,16 @@
actionClass = "UIxMailPartICalAction";
actionName = "markTentative";
};
addToCalendar = {
protectedBy = "View";
actionClass = "UIxMailPartICalAction";
actionName = "addToCalendar";
};
deleteFromCalendar = {
protectedBy = "View";
actionClass = "UIxMailPartICalAction";
actionName = "deleteFromCalendar";
};
};
};
};

View file

@ -1,11 +1,12 @@
<?xml version="1.0" standalone="yes"?>
<!DOCTYPE div>
<div xmlns="http://www.w3.org/1999/xhtml"
xmlns:var="http://www.skyrix.com/od/binding"
xmlns:label="OGo:label"
xmlns:const="http://www.skyrix.com/od/constant"
xmlns:rsrc="OGo:url"
class="linked_attachment_frame"
>
>
<!-- TODO: add iMIP actions -->
<var:if condition="couldParseCalendar" const:negate="1">
@ -32,16 +33,21 @@
</var:if>
</legend>
<!-- var:if condition="inCalendar.method" const:value="REQUEST" -->
<var:if condition="inCalendar.method" const:value="REQUEST">
<!-- sent to attendees to propose or update a meeting -->
<var:if condition="isLoggedInUserAnAttendee">
<p class="uix_ical_toolbar">
<a var:href="acceptLink" label:string="do_accept"/> |
<a var:href="declineLink" label:string="do_decline"/> |
<a var:href="tentativeLink" label:string="do_tentative"/>
<var:if condition="isEventStoredInCalendar" const:negate="1">
| <a var:href="addToCalendarLink" label:string="do_add_to_cal" />
<p class="uix_ical_toolbar" id="iCalendarToolbar">
<input id="iCalendarAttachment" type="hidden"
var:value="pathToAttachmentObject"/>
<input id="iCalendarAccept" class="button"
type="button" label:value="Accept"/>
<input id="iCalendarDecline" class="button"
type="button" label:value="Decline"/>
<input id="iCalendarTentative" class="button"
type="button" label:value="Tentative"/>
<var:if condition="isEventStoredInCalendar" const:negate="YES">
| <input id="iCalendarAddToCalendar" class="button"
type="button" label:value="Add to calendar"/>
</var:if>
</p>
@ -53,7 +59,7 @@
</p>
</var:if>
<var:if condition="isLoggedInUserAnAttendee" const:negate="1">
<var:if condition="isLoggedInUserAnAttendee" const:negate="YES">
<p>
<var:string label:value="Organizer" />
<a var:href="inEvent.organizer.email"
@ -61,7 +67,7 @@
<var:string label:value="request_info_no_attendee" />
</p>
</var:if>
<!-- var:if -->
</var:if>
<var:if condition="inCalendar.method" const:value="REPLY">
@ -90,13 +96,13 @@
</var:if>
</var:if>
<var:if condition="inCalendar.method" const:value="CANCEL">
<!-- sent to attendees to notify of the attendee being removed or the
event being deleted -->
<var:if condition="isEventStoredInCalendar">
<p class="uix_ical_toolbar">
<a var:href="delFromCalendarLink" label:string="do_del_from_cal"/>
<input id="iCalendarDeleteFromCalendar" class="button"
type="button" label:value="Delete from calendar"/>
</p>
</var:if>
@ -148,7 +154,6 @@
<br />
</var:if>
<div class="linked_attachment_meta" style="background-color: white;">
<table border="0" class="linked_attachment_meta">
<tr>
@ -193,11 +198,11 @@
</fieldset>
</var:if><!-- could parse -->
<!--
<!--
<var:string value="appointment" />
<br />
<br />
<br />
-->
-->
<pre style="display: none;"><var:string value="flatContentAsString" /></pre>
</div>

View file

@ -9,7 +9,7 @@ if (typeof textMailAccounts != 'undefined') {
mailAccounts = new Array();
}
var currentMessages = new Array();
var currentMessages = {};
var maxCachedMessages = 20;
var cachedMessages = new Array();
var currentMailbox = null;
@ -743,13 +743,56 @@ function configureLinksInMessage() {
if (editDraftButton)
Event.observe(editDraftButton, "click",
onMessageEditDraft.bindAsEventListener(editDraftButton));
configureiCalLinksInMessage();
}
function configureiCalLinksInMessage() {
var buttons = { "iCalendarAccept": "accept",
"iCalendarDecline": "decline",
"iCalendarTentative": "tentative",
"iCalendarAddToCalendar": "addToCalendar",
"iCalendarDeleteFromCalendar": "deleteFromCalendar" };
for (var key in buttons) {
var button = $(key);
if (button) {
button.action = buttons[key];
Event.observe(button, "click",
onICalendarButtonClick.bindAsEventListener(button));
}
}
}
function onICalendarButtonClick(event) {
var link = $("iCalendarAttachment").value;
if (link) {
var urlstr = link + "/" + this.action;
triggerAjaxRequest(urlstr, ICalendarButtonCallback,
currentMailbox + "/"
+ currentMessages[currentMailbox]);
window.alert(urlstr);
}
}
function ICalendarButtonCallback(http) {
if (http.readyState == 4)
if (isHttpStatus204(http.status)) {
var oldMsg = http.callbackData;
var msg = currentMailbox + "/" + currentMessages[currentMailbox];
if (oldMsg == msg) {
deleteCachedMessage(oldMsg);
loadMessage(currentMessages[currentMailbox]);
}
}
}
function resizeMailContent() {
var headerTable = document.getElementsByClassName('mailer_fieldtable')[0];
var contentDiv = document.getElementsByClassName('mailer_mailcontent')[0];
contentDiv.setStyle({ 'top': (Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
contentDiv.setStyle({ 'top':
(Element.getHeight(headerTable) + headerTable.offsetTop) + 'px' });
}
function onMessageContentMenu(event) {