<img src=data...> conversion to file attachments + CIDs.

pull/17/merge
Ludovic Marcotte 2013-11-20 08:56:29 -05:00
parent 6587f4f193
commit e4aedbac08
7 changed files with 336 additions and 57 deletions

13
NEWS
View File

@ -1,3 +1,16 @@
2.1.2 (2013-11-XX)
------------------
New features
-
Enhancements
- we now automatically convert <img src=data...> into file attachments
using CIDs. This prevents Outlook issues.
Bug fixes
-
2.1.1 (2013-11-19) 2.1.1 (2013-11-19)
------------------ ------------------

View File

@ -21,12 +21,16 @@
#ifndef NSSTRING_MAIL_H #ifndef NSSTRING_MAIL_H
#define NSSTRING_MAIL_H #define NSSTRING_MAIL_H
#import <Foundation/NSArray.h>
#import <Foundation/NSString.h> #import <Foundation/NSString.h>
@interface NSString (SOGoExtension) @interface NSString (SOGoExtension)
- (NSString *) htmlToText; - (NSString *) htmlToText;
- (NSString *) htmlByExtractingImages: (NSMutableArray *) theImages;
- (NSString *) stringByConvertingCRLNToHTML; - (NSString *) stringByConvertingCRLNToHTML;
- (int) indexOf: (unichar) _c
fromIndex: (int) start;
- (int) indexOf: (unichar) _c; - (int) indexOf: (unichar) _c;
- (NSString *) decodedHeader; - (NSString *) decodedHeader;

View File

@ -22,19 +22,25 @@
#import <Foundation/NSDictionary.h> #import <Foundation/NSDictionary.h>
#import <Foundation/NSObject.h> #import <Foundation/NSObject.h>
#import <Foundation/NSException.h> #import <Foundation/NSException.h>
#import <Foundation/NSValue.h>
#import <SaxObjC/SaxAttributes.h> #import <SaxObjC/SaxAttributes.h>
#import <SaxObjC/SaxContentHandler.h> #import <SaxObjC/SaxContentHandler.h>
#import <SaxObjC/SaxLexicalHandler.h> #import <SaxObjC/SaxLexicalHandler.h>
#import <SaxObjC/SaxXMLReader.h> #import <SaxObjC/SaxXMLReader.h>
#import <SaxObjC/SaxXMLReaderFactory.h> #import <SaxObjC/SaxXMLReaderFactory.h>
#import <NGExtensions/NGHashMap.h>
#import <NGExtensions/NGQuotedPrintableCoding.h> #import <NGExtensions/NGQuotedPrintableCoding.h>
#import <NGExtensions/NSString+misc.h> #import <NGExtensions/NSString+misc.h>
#import <NGExtensions/NSObject+Logs.h> #import <NGExtensions/NSObject+Logs.h>
#import <NGMime/NGMimeBodyPart.h>
#import <NGMime/NGMimeFileData.h>
#include <libxml/encoding.h> #include <libxml/encoding.h>
#import "NSString+Mail.h" #import "NSString+Mail.h"
#import "NSData+Mail.h" #import "NSData+Mail.h"
#import "../SOGo/SOGoObject.h"
#if 0 #if 0
#define showWhoWeAre() \ #define showWhoWeAre() \
@ -43,11 +49,15 @@
#define showWhoWeAre() {} #define showWhoWeAre() {}
#endif #endif
@interface _SOGoHTMLToTextContentHandler : NSObject <SaxContentHandler, SaxLexicalHandler> #define paddingBuffer 8192
@interface _SOGoHTMLContentHandler : NSObject <SaxContentHandler, SaxLexicalHandler>
{ {
NSMutableArray *images;
NSArray *ignoreContentTags; NSArray *ignoreContentTags;
NSArray *specialTreatmentTags; NSArray *specialTreatmentTags;
BOOL ignoreContent; BOOL ignoreContent;
BOOL orderedList; BOOL orderedList;
BOOL unorderedList; BOOL unorderedList;
@ -57,32 +67,26 @@
} }
+ (id) htmlToTextContentHandler; + (id) htmlToTextContentHandler;
+ (id) sanitizerContentHandler;
- (NSString *) result; - (NSString *) result;
- (void) setIgnoreContentTags: (NSArray *) theTags;
- (void) setSpecialTreatmentTags: (NSArray *) theTags;
- (void) setImages: (NSMutableArray *) theImages;
@end @end
@implementation _SOGoHTMLToTextContentHandler @implementation _SOGoHTMLContentHandler
+ (id) htmlToTextContentHandler
{
static id htmlToTextContentHandler;
if (!htmlToTextContentHandler)
htmlToTextContentHandler = [self new];
return htmlToTextContentHandler;
}
- (id) init - (id) init
{ {
if ((self = [super init])) if ((self = [super init]))
{ {
ignoreContentTags = [NSArray arrayWithObjects: @"head", @"script", images = nil;
@"style", nil];
specialTreatmentTags = [NSArray arrayWithObjects: @"body", @"p", @"ul", ignoreContentTags = nil;
@"li", @"table", @"tr", @"td", @"th", specialTreatmentTags = nil;
@"br", @"hr", @"dt", @"dd", nil];
[ignoreContentTags retain]; [ignoreContentTags retain];
[specialTreatmentTags retain]; [specialTreatmentTags retain];
@ -97,6 +101,32 @@
return self; return self;
} }
+ (id) htmlToTextContentHandler
{
static id htmlToTextContentHandler;
if (!htmlToTextContentHandler)
htmlToTextContentHandler = [self new];
[htmlToTextContentHandler setIgnoreContentTags: [NSArray arrayWithObjects: @"head", @"script",
@"style", nil]];
[htmlToTextContentHandler setSpecialTreatmentTags: [NSArray arrayWithObjects: @"body", @"p", @"ul",
@"li", @"table", @"tr", @"td", @"th",
@"br", @"hr", @"dt", @"dd", nil]];
return htmlToTextContentHandler;
}
+ (id) sanitizerContentHandler
{
static id sanitizerContentHandler;
if (!sanitizerContentHandler)
sanitizerContentHandler = [self new];
return sanitizerContentHandler;
}
- (xmlCharEncoding) contentEncoding - (xmlCharEncoding) contentEncoding
{ {
return XML_CHAR_ENCODING_UTF8; return XML_CHAR_ENCODING_UTF8;
@ -121,6 +151,25 @@
return newResult; return newResult;
} }
- (void) setIgnoreContentTags: (NSArray *) theTags
{
ASSIGN(ignoreContentTags, theTags);
}
- (void) setSpecialTreatmentTags: (NSArray *) theTags
{
ASSIGN(specialTreatmentTags, theTags);
}
//
// We MUST NOT retain the array here
//
- (void) setImages: (NSMutableArray *) theImages
{
images = theImages;
}
/* SaxContentHandler */ /* SaxContentHandler */
- (void) startDocument - (void) startDocument
{ {
@ -210,14 +259,89 @@
showWhoWeAre(); showWhoWeAre();
if (!ignoreContent) tagName = [rawName lowercaseString];
if (!ignoreContent && ignoreContentTags && specialTreatmentTags)
{ {
tagName = [rawName lowercaseString];
if ([ignoreContentTags containsObject: tagName]) if ([ignoreContentTags containsObject: tagName])
ignoreContent = YES; ignoreContent = YES;
else if ([specialTreatmentTags containsObject: tagName]) else if ([specialTreatmentTags containsObject: tagName])
[self _startSpecialTreatment: tagName]; [self _startSpecialTreatment: tagName];
} }
else if ([tagName isEqualToString: @"img"])
{
NSString *value;
value = [attributes valueForRawName: @"src"];
//
// Check for Data URI Scheme
//
// data:[<MIME-type>][;charset=<encoding>][;base64],<data>
//
if ([value length] > 5 && [[value substringToIndex: 5] caseInsensitiveCompare: @"data:"] == NSOrderedSame)
{
NSString *uniqueId, *mimeType, *encoding, *charset;
NGMimeBodyPart *bodyPart;
NGMutableHashMap *map;
NSData *data;
id body;
int i, j, k;
i = [value indexOf: ';'];
j = [value indexOf: ';' fromIndex: i+1];
k = [value indexOf: ','];
// We try to get the MIME type
mimeType = nil;
if (i > 5 && i < k)
{
mimeType = [value substringWithRange: NSMakeRange(5, i-5)];
}
else
i = 5;
// We might get a stupid value. We discard anything that doesn't have a / in it
if ([mimeType indexOf: '/'] < 0)
mimeType = @"image/jpeg";
// We check and skip the charset
if (j > i)
charset = [value substringWithRange: NSMakeRange(i+1, j-i-1)];
else
j = i;
// We check the encoding and we completely ignore it
encoding = [value substringWithRange: NSMakeRange(j+1, k-j-1)];
if (![encoding length])
encoding = @"base64";
data = [[value substringFromIndex: k+1] dataUsingEncoding: NSASCIIStringEncoding];
uniqueId = [SOGoObject globallyUniqueObjectId];
map = [[[NGMutableHashMap alloc] initWithCapacity:5] autorelease];
[map setObject: encoding forKey: @"content-transfer-encoding"];
[map setObject:[NSNumber numberWithInt:[data length]] forKey: @"content-length"];
[map setObject: [NSString stringWithFormat: @"inline; filename=\"%@\"", uniqueId] forKey: @"content-disposition"];
[map setObject: [NSString stringWithFormat: @"%@; name=\"%@\"", mimeType, uniqueId] forKey: @"content-type"];
[map setObject: [NSString stringWithFormat: @"<%@>", uniqueId] forKey: @"content-id"];
body = [[NGMimeFileData alloc] initWithBytes: [data bytes] length: [data length]];
bodyPart = [[[NGMimeBodyPart alloc] initWithHeader:map] autorelease];
[bodyPart setBody: body];
[body release];
[images addObject: bodyPart];
[result appendFormat: @"<img src=\"cid:%@\" type=\"%@\">", uniqueId, mimeType];
}
}
} }
- (void) endElement: (NSString *) element - (void) endElement: (NSString *) element
@ -228,7 +352,7 @@
showWhoWeAre(); showWhoWeAre();
if (ignoreContent) if (ignoreContent && ignoreContentTags && specialTreatmentTags)
{ {
tagName = [rawName lowercaseString]; tagName = [rawName lowercaseString];
if ([ignoreContentTags containsObject: tagName]) if ([ignoreContentTags containsObject: tagName])
@ -345,13 +469,13 @@
- (NSString *) htmlToText - (NSString *) htmlToText
{ {
_SOGoHTMLToTextContentHandler *handler; _SOGoHTMLContentHandler *handler;
id <NSObject, SaxXMLReader> parser; id <NSObject, SaxXMLReader> parser;
NSData *d; NSData *d;
parser = [[SaxXMLReaderFactory standardXMLReaderFactory] parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType: @"text/html"]; createXMLReaderForMimeType: @"text/html"];
handler = [_SOGoHTMLToTextContentHandler htmlToTextContentHandler]; handler = [_SOGoHTMLContentHandler htmlToTextContentHandler];
[parser setContentHandler: handler]; [parser setContentHandler: handler];
d = [self dataUsingEncoding: NSUTF8StringEncoding]; d = [self dataUsingEncoding: NSUTF8StringEncoding];
@ -360,7 +484,24 @@
return [handler result]; return [handler result];
} }
#define paddingBuffer 8192 - (NSString *) htmlByExtractingImages: (NSMutableArray *) theImages
{
_SOGoHTMLContentHandler *handler;
id <NSObject, SaxXMLReader> parser;
NSData *d;
parser = [[SaxXMLReaderFactory standardXMLReaderFactory]
createXMLReaderForMimeType: @"text/html"];
handler = [_SOGoHTMLContentHandler sanitizerContentHandler];
[handler setImages: theImages];
[parser setContentHandler: handler];
d = [self dataUsingEncoding: NSUTF8StringEncoding];
[parser parseFromSource: d];
return [handler result];
}
static inline char * static inline char *
convertChars (const char *oldString, unsigned int oldLength, convertChars (const char *oldString, unsigned int oldLength,
@ -434,18 +575,29 @@ convertChars (const char *oldString, unsigned int oldLength,
return convertedString; return convertedString;
} }
- (int) indexOf: (unichar) _c - (int) indexOf: (unichar) _c
fromIndex: (int) start
{ {
int i, len; int i, len;
len = [self length]; len = [self length];
for (i = 0; i < len; i++) if (start < 0 || start >= len)
start = 0;
for (i = start; i < len; i++)
{ {
if ([self characterAtIndex: i] == _c) return i; if ([self characterAtIndex: i] == _c) return i;
} }
return -1; return -1;
}
- (int) indexOf: (unichar) _c
{
return [self indexOf: _c fromIndex: 0];
} }
- (NSString *) decodedHeader - (NSString *) decodedHeader

View File

@ -1,5 +1,5 @@
/* /*
Copyright (C) 2007-2012 Inverse inc. Copyright (C) 2007-2013 Inverse inc.
Copyright (C) 2004-2005 SKYRIX Software AG Copyright (C) 2004-2005 SKYRIX Software AG
This file is part of SOGo. This file is part of SOGo.
@ -395,11 +395,17 @@ static NSString *userAgent = nil;
[self setSourceFolder: [paths componentsJoinedByString: @"/"]]; [self setSourceFolder: [paths componentsJoinedByString: @"/"]];
} }
//
//
//
- (NSString *) sourceFolder - (NSString *) sourceFolder
{ {
return sourceFolder; return sourceFolder;
} }
//
//
//
- (NSException *) storeInfo - (NSException *) storeInfo
{ {
NSMutableDictionary *infos; NSMutableDictionary *infos;
@ -446,6 +452,9 @@ static NSString *userAgent = nil;
return error; return error;
} }
//
//
//
- (void) _loadInfosFromDictionary: (NSDictionary *) infoDict - (void) _loadInfosFromDictionary: (NSDictionary *) infoDict
{ {
id value; id value;
@ -478,11 +487,17 @@ static NSString *userAgent = nil;
[self setInReplyTo: value]; [self setInReplyTo: value];
} }
//
//
//
- (NSString *) relativeImap4Name - (NSString *) relativeImap4Name
{ {
return [NSString stringWithFormat: @"%d", IMAP4ID]; return [NSString stringWithFormat: @"%d", IMAP4ID];
} }
//
//
//
- (void) fetchInfo - (void) fetchInfo
{ {
NSString *p; NSString *p;
@ -504,16 +519,25 @@ static NSString *userAgent = nil;
[self debugWithFormat: @"Note: info object does not yet exist: %@", p]; [self debugWithFormat: @"Note: info object does not yet exist: %@", p];
} }
//
//
//
- (void) setIMAP4ID: (int) newIMAP4ID - (void) setIMAP4ID: (int) newIMAP4ID
{ {
IMAP4ID = newIMAP4ID; IMAP4ID = newIMAP4ID;
} }
//
//
//
- (int) IMAP4ID - (int) IMAP4ID
{ {
return IMAP4ID; return IMAP4ID;
} }
//
//
//
- (NSException *) save - (NSException *) save
{ {
NGImap4Client *client; NGImap4Client *client;
@ -552,6 +576,9 @@ static NSString *userAgent = nil;
return error; return error;
} }
//
//
//
- (void) _addEMailsOfAddresses: (NSArray *) _addrs - (void) _addEMailsOfAddresses: (NSArray *) _addrs
toArray: (NSMutableArray *) _ma toArray: (NSMutableArray *) _ma
{ {
@ -564,6 +591,9 @@ static NSString *userAgent = nil;
[_ma addObject: [currentAddress email]]; [_ma addObject: [currentAddress email]];
} }
//
//
//
- (void) _addRecipients: (NSArray *) recipients - (void) _addRecipients: (NSArray *) recipients
toArray: (NSMutableArray *) array toArray: (NSMutableArray *) array
{ {
@ -576,6 +606,9 @@ static NSString *userAgent = nil;
[array addObject: [currentAddress baseEMail]]; [array addObject: [currentAddress baseEMail]];
} }
//
//
//
- (void) _purgeRecipients: (NSArray *) recipients - (void) _purgeRecipients: (NSArray *) recipients
fromAddresses: (NSMutableArray *) addresses fromAddresses: (NSMutableArray *) addresses
{ {
@ -602,6 +635,9 @@ static NSString *userAgent = nil;
} }
} }
//
//
//
- (void) _fillInReplyAddresses: (NSMutableDictionary *) _info - (void) _fillInReplyAddresses: (NSMutableDictionary *) _info
replyToAll: (BOOL) _replyToAll replyToAll: (BOOL) _replyToAll
envelope: (NGImap4Envelope *) _envelope envelope: (NGImap4Envelope *) _envelope
@ -711,6 +747,9 @@ static NSString *userAgent = nil;
} }
} }
//
//
//
- (NSArray *) _attachmentBodiesFromPaths: (NSArray *) paths - (NSArray *) _attachmentBodiesFromPaths: (NSArray *) paths
fromResponseFetch: (NSDictionary *) fetch; fromResponseFetch: (NSDictionary *) fetch;
{ {
@ -731,6 +770,9 @@ static NSString *userAgent = nil;
return bodies; return bodies;
} }
//
//
//
- (void) _fetchAttachments: (NSArray *) parts - (void) _fetchAttachments: (NSArray *) parts
fromMail: (SOGoMailObject *) sourceMail fromMail: (SOGoMailObject *) sourceMail
{ {
@ -758,6 +800,9 @@ static NSString *userAgent = nil;
} }
} }
//
//
//
- (void) fetchMailForEditing: (SOGoMailObject *) sourceMail - (void) fetchMailForEditing: (SOGoMailObject *) sourceMail
{ {
NSString *subject, *msgid; NSString *subject, *msgid;
@ -804,6 +849,9 @@ static NSString *userAgent = nil;
[self storeInfo]; [self storeInfo];
} }
//
//
//
- (void) fetchMailForReplying: (SOGoMailObject *) sourceMail - (void) fetchMailForReplying: (SOGoMailObject *) sourceMail
toAll: (BOOL) toAll toAll: (BOOL) toAll
{ {
@ -1255,6 +1303,9 @@ static NSString *userAgent = nil;
return bodyPart; return bodyPart;
} }
//
//
//
- (NSArray *) bodyPartsForAllAttachments - (NSArray *) bodyPartsForAllAttachments
{ {
/* returns nil on error */ /* returns nil on error */
@ -1276,6 +1327,9 @@ static NSString *userAgent = nil;
return bodyParts; return bodyParts;
} }
//
//
//
- (NGMimeBodyPart *) mimeMultipartAlternative - (NGMimeBodyPart *) mimeMultipartAlternative
{ {
NGMimeMultipartBody *textParts; NGMimeMultipartBody *textParts;
@ -1301,6 +1355,9 @@ static NSString *userAgent = nil;
return part; return part;
} }
//
//
//
- (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map - (NGMimeMessage *) mimeMultiPartMessageWithHeaderMap: (NGMutableHashMap *) map
andBodyParts: (NSArray *) _bodyParts andBodyParts: (NSArray *) _bodyParts
{ {
@ -1340,6 +1397,9 @@ static NSString *userAgent = nil;
return message; return message;
} }
//
//
//
- (void) _addHeaders: (NSDictionary *) _h - (void) _addHeaders: (NSDictionary *) _h
toHeaderMap: (NGMutableHashMap *) _map toHeaderMap: (NGMutableHashMap *) _map
{ {
@ -1511,48 +1571,59 @@ static NSString *userAgent = nil;
return map; return map;
} }
//
//
//
- (NGMimeMessage *) mimeMessageWithHeaders: (NSDictionary *) _headers - (NGMimeMessage *) mimeMessageWithHeaders: (NSDictionary *) _headers
excluding: (NSArray *) _exclude excluding: (NSArray *) _exclude
{ {
NGMutableHashMap *map; NSMutableArray *bodyParts;
NSArray *bodyParts; NGMimeMessage *message;
NGMimeMessage *message; NGMutableHashMap *map;
NSString *newText;
message = nil; message = nil;
bodyParts = [NSMutableArray array];
newText = [text htmlByExtractingImages: bodyParts];
if ([bodyParts count])
[self setText: newText];
map = [self mimeHeaderMapWithHeaders: _headers map = [self mimeHeaderMapWithHeaders: _headers
excluding: _exclude]; excluding: _exclude];
if (map) if (map)
{ {
//[self debugWithFormat: @"MIME Envelope: %@", map]; //[self debugWithFormat: @"MIME Envelope: %@", map];
bodyParts = [self bodyPartsForAllAttachments]; [bodyParts addObjectsFromArray: [self bodyPartsForAllAttachments]];
if (bodyParts)
{ //[self debugWithFormat: @"attachments: %@", bodyParts];
//[self debugWithFormat: @"attachments: %@", bodyParts];
if ([bodyParts count] == 0)
if ([bodyParts count] == 0) /* no attachments */
/* no attachments */ message = [self mimeMessageForContentWithHeaderMap: map];
message = [self mimeMessageForContentWithHeaderMap: map];
else
/* attachments, create multipart/mixed */
message = [self mimeMultiPartMessageWithHeaderMap: map
andBodyParts: bodyParts];
//[self debugWithFormat: @"message: %@", message];
}
else else
[self errorWithFormat: /* attachments, create multipart/mixed */
@"could not create body parts for attachments!"]; message = [self mimeMultiPartMessageWithHeaderMap: map
andBodyParts: bodyParts];
//[self debugWithFormat: @"message: %@", message];
} }
return message; return message;
} }
//
//
//
- (NGMimeMessage *) mimeMessage - (NGMimeMessage *) mimeMessage
{ {
return [self mimeMessageWithHeaders: nil excluding: nil]; return [self mimeMessageWithHeaders: nil excluding: nil];
} }
//
//
//
- (NSData *) mimeMessageAsData - (NSData *) mimeMessageAsData
{ {
NGMimeMessageGenerator *generator; NGMimeMessageGenerator *generator;
@ -1565,6 +1636,9 @@ static NSString *userAgent = nil;
return message; return message;
} }
//
//
//
- (NSArray *) allRecipients - (NSArray *) allRecipients
{ {
NSMutableArray *allRecipients; NSMutableArray *allRecipients;
@ -1584,6 +1658,9 @@ static NSString *userAgent = nil;
return allRecipients; return allRecipients;
} }
//
//
//
- (NSArray *) allBareRecipients - (NSArray *) allBareRecipients
{ {
NSMutableArray *bareRecipients; NSMutableArray *bareRecipients;
@ -1599,11 +1676,17 @@ static NSString *userAgent = nil;
return bareRecipients; return bareRecipients;
} }
//
//
//
- (NSException *) sendMail - (NSException *) sendMail
{ {
return [self sendMailAndCopyToSent: YES]; return [self sendMailAndCopyToSent: YES];
} }
//
//
//
- (NSException *) sendMailAndCopyToSent: (BOOL) copyToSent - (NSException *) sendMailAndCopyToSent: (BOOL) copyToSent
{ {
NSMutableData *cleaned_message; NSMutableData *cleaned_message;

View File

@ -42,6 +42,9 @@
#define maxFilenameLength 64 #define maxFilenameLength 64
//
//
//
@implementation SOGoMailObject (SOGoDraftObjectExtensions) @implementation SOGoMailObject (SOGoDraftObjectExtensions)
- (NSString *) subjectForReply - (NSString *) subjectForReply
@ -77,6 +80,9 @@
return newSubject; return newSubject;
} }
//
//
//
- (NSString *) _convertRawContentForEditing: (NSString *) raw - (NSString *) _convertRawContentForEditing: (NSString *) raw
rawHtml: (BOOL) html rawHtml: (BOOL) html
{ {
@ -96,6 +102,9 @@
return rc; return rc;
} }
//
//
//
- (NSString *) _contentForEditingFromKeys: (NSArray *) keys - (NSString *) _contentForEditingFromKeys: (NSArray *) keys
{ {
NSArray *types; NSArray *types;
@ -151,6 +160,9 @@
return content; return content;
} }
//
//
//
- (NSString *) contentForEditing - (NSString *) contentForEditing
{ {
NSMutableArray *keys; NSMutableArray *keys;
@ -166,6 +178,9 @@
return [self _contentForEditingFromKeys: keys]; return [self _contentForEditingFromKeys: keys];
} }
//
//
//
- (NSString *) contentForReply - (NSString *) contentForReply
{ {
NSString *pageName; NSString *pageName;
@ -185,6 +200,9 @@
return [[page generateResponse] contentAsString]; return [[page generateResponse] contentAsString];
} }
//
//
//
- (NSString *) filenameForForward - (NSString *) filenameForForward
{ {
NSString *subject; NSString *subject;
@ -218,6 +236,9 @@
return newSubject; return newSubject;
} }
//
//
//
- (NSString *) subjectForForward - (NSString *) subjectForForward
{ {
NSString *subject, *newSubject; NSString *subject, *newSubject;
@ -231,6 +252,9 @@
return newSubject; return newSubject;
} }
//
//
//
- (NSString *) contentForInlineForward - (NSString *) contentForInlineForward
{ {
SOGoUserDefaults *ud; SOGoUserDefaults *ud;
@ -247,6 +271,9 @@
return [[page generateResponse] contentAsString]; return [[page generateResponse] contentAsString];
} }
//
//
//
- (void) _fetchFileAttachmentKey: (NSDictionary *) part - (void) _fetchFileAttachmentKey: (NSDictionary *) part
intoArray: (NSMutableArray *) keys intoArray: (NSMutableArray *) keys
withPath: (NSString *) path withPath: (NSString *) path
@ -291,6 +318,9 @@
} }
} }
//
//
//
- (void) _fetchFileAttachmentKeysInPart: (NSDictionary *) part - (void) _fetchFileAttachmentKeysInPart: (NSDictionary *) part
intoArray: (NSMutableArray *) keys intoArray: (NSMutableArray *) keys
withPath: (NSString *) path withPath: (NSString *) path
@ -325,6 +355,9 @@
} }
} }
//
//
//
#warning we might need to handle parts with a "name" attribute #warning we might need to handle parts with a "name" attribute
- (NSArray *) fetchFileAttachmentKeys - (NSArray *) fetchFileAttachmentKeys
{ {

View File

@ -1,8 +1,6 @@
/* UIxMailPartHTMLViewer.h - this file is part of SOGo /* UIxMailPartHTMLViewer.h - this file is part of SOGo
* *
* Copyright (C) 2007, 2008 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by

View File

@ -1,10 +1,6 @@
/* UIxMailPartHTMLViewer.m - this file is part of SOGo /* UIxMailPartHTMLViewer.m - this file is part of SOGo
* *
* Copyright (C) 2007-2012 Inverse inc. * Copyright (C) 2007-2013 Inverse inc.
*
* Author: Wolfgang Sourdeau <wsourdeau@inverse.ca>
* Ludovic Marcotte <lmarcotte@inverse.ca>
* Francis Lachapelle <flachapelle@inverse.ca>
* *
* This file is free software; you can redistribute it and/or modify * 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 * it under the terms of the GNU General Public License as published by