diff --git a/UI/MailPartViewers/UIxMailPartAlternativeViewer.m b/UI/MailPartViewers/UIxMailPartAlternativeViewer.m index 07185c8e4..44aa0d0e3 100644 --- a/UI/MailPartViewers/UIxMailPartAlternativeViewer.m +++ b/UI/MailPartViewers/UIxMailPartAlternativeViewer.m @@ -48,16 +48,34 @@ */ @interface UIxMailPartAlternativeViewer : UIxMailPartMixedViewer +{ + BOOL rawContent; +} @end @implementation UIxMailPartAlternativeViewer +- (id) init +{ + if ((self = [super init])) + { + rawContent = NO; + } + + return self; +} + - (void) dealloc { [super dealloc]; } +- (void)activateRawContent +{ + rawContent = YES; +} + /* part selection */ - (NSArray *) childPartTypes @@ -206,6 +224,9 @@ [viewer setAttachmentIds: attachmentIds]; if ([self decodedFlatContent]) [viewer setDecodedContent: [parts objectAtIndex: i]]; + + if ([viewer isKindOfClass:NSClassFromString(@"UIxMailPartHTMLViewer")] && rawContent) + [viewer activateRawContent]; [renderedParts addObject: [viewer renderedPart]]; } diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.h b/UI/MailPartViewers/UIxMailPartHTMLViewer.h index 420ea75c7..b6130b036 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.h +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.h @@ -27,9 +27,11 @@ { id handler; NSException *ex; + BOOL rawContent; } - (NSString *) flatContentAsString; +- (void)activateRawContent; @end diff --git a/UI/MailPartViewers/UIxMailPartHTMLViewer.m b/UI/MailPartViewers/UIxMailPartHTMLViewer.m index 07a36f446..6b0edac64 100644 --- a/UI/MailPartViewers/UIxMailPartHTMLViewer.m +++ b/UI/MailPartViewers/UIxMailPartHTMLViewer.m @@ -128,9 +128,11 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) BOOL inCSSDeclaration; BOOL hasEmbeddedCSS; xmlCharEncoding contentEncoding; + BOOL rawContent; } - (NSString *) result; +- (void) activateRawContent; @end @@ -161,6 +163,7 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) ignoreTag = nil; attachmentIds = nil; contentEncoding = XML_CHAR_ENCODING_UTF8; + rawContent = NO; } return self; @@ -174,6 +177,11 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) [super dealloc]; } +- (void)activateRawContent +{ + rawContent = YES; +} + - (void) setContentEncoding: (xmlCharEncoding) newContentEncoding { contentEncoding = newContentEncoding; @@ -376,7 +384,8 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) (*(currentChar-7) == 'p' || *(currentChar-7) == 'P') && (*(currentChar-8) == 'm' || *(currentChar-8) == 'M') && (*(currentChar-9) == 'i' || *(currentChar-9) == 'I') && - *(currentChar-10) == '!')) + *(currentChar-10) == '!') + && !rawContent) { length = (currentChar - start); [declaration appendFormat: @"%@ !important;", @@ -759,11 +768,17 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) { handler = nil; ex = nil; + rawContent = NO; } return self; } +- (void)activateRawContent +{ + rawContent = YES; +} + - (void) dealloc { [handler release]; @@ -805,6 +820,8 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) createXMLReaderForMimeType: @"text/html"]; handler = [_UIxHTMLMailContentHandler new]; + if (rawContent) + [handler activateRawContent]; [handler setAttachmentIds: attachmentIds]; // Some broken email messages have some additionnal content outside the main HTML tags which are @@ -920,6 +937,9 @@ static NSString *_sanitizeHtmlForDisplay(NSString *content) if (!handler) [self _parseContent]; + if (rawContent) + return [handler result]; + return _sanitizeHtmlForDisplay([handler result]); } diff --git a/UI/MailerUI/English.lproj/Localizable.strings b/UI/MailerUI/English.lproj/Localizable.strings index 919bab383..7095b54e4 100644 --- a/UI/MailerUI/English.lproj/Localizable.strings +++ b/UI/MailerUI/English.lproj/Localizable.strings @@ -256,6 +256,7 @@ "Save As..." = "Save As..."; "Print Preview" = "Print Preview"; "View Message Source" = "View Message Source"; +"View raw message" = "View raw message"; /* Message view "more" menu: create an event from message */ "Convert To Event" = "Convert To Event"; diff --git a/UI/MailerUI/French.lproj/Localizable.strings b/UI/MailerUI/French.lproj/Localizable.strings index dda729eab..fa8b8cec9 100644 --- a/UI/MailerUI/French.lproj/Localizable.strings +++ b/UI/MailerUI/French.lproj/Localizable.strings @@ -256,6 +256,7 @@ "Save As..." = "Télécharger"; "Print Preview" = "Aperçu avant impression"; "View Message Source" = "Voir le code source"; +"View raw message" = "Voir le message brut"; /* Message view "more" menu: create an event from message */ "Convert To Event" = "Convertir en événement"; diff --git a/UI/MailerUI/UIxMailView.m b/UI/MailerUI/UIxMailView.m index 8fd53d8c2..f52829a38 100644 --- a/UI/MailerUI/UIxMailView.m +++ b/UI/MailerUI/UIxMailView.m @@ -274,6 +274,16 @@ static NSString *mailETag = nil; /* actions */ - (id ) defaultAction +{ + return [self view: NO]; +} + +- (id ) viewRawAction +{ + return [self view: YES]; +} + +- (id ) view: (BOOL)raw { WOResponse *response; NSMutableDictionary *data; @@ -336,6 +346,12 @@ static NSString *mailETag = nil; } viewer = [self contentViewerComponent]; // set attachmentIds for common parts + + if (raw && ([viewer isKindOfClass: NSClassFromString(@"UIxMailPartHTMLViewer")] + || [viewer isKindOfClass: NSClassFromString(@"UIxMailPartAlternativeViewer")])) { + // In this case, disable html mail content modification by SOGo + [viewer activateRawContent]; + } renderedPart = [viewer renderedPart]; // set attachmentIds for encrypted & TNEF parts data = [NSMutableDictionary dictionaryWithObjectsAndKeys: diff --git a/UI/MailerUI/product.plist b/UI/MailerUI/product.plist index 0f9b4ae45..fd1d96fe6 100644 --- a/UI/MailerUI/product.plist +++ b/UI/MailerUI/product.plist @@ -218,6 +218,11 @@ pageName = "UIxMailView"; actionName = "default"; }; + viewRaw = { + protectedBy = "View"; + pageName = "UIxMailView"; + actionName = "viewRaw"; + }; sendMDN = { protectedBy = "View"; pageName = "UIxMailView"; diff --git a/UI/Templates/MailerUI/UIxMailViewTemplate.wox b/UI/Templates/MailerUI/UIxMailViewTemplate.wox index 4b532b203..d9b4d5455 100644 --- a/UI/Templates/MailerUI/UIxMailViewTemplate.wox +++ b/UI/Templates/MailerUI/UIxMailViewTemplate.wox @@ -117,6 +117,12 @@ + + + + + diff --git a/UI/WebServerResources/js/Mailer/Mailer.popup.js b/UI/WebServerResources/js/Mailer/Mailer.popup.js index 8a16a377f..14e9ec9d8 100644 --- a/UI/WebServerResources/js/Mailer/Mailer.popup.js +++ b/UI/WebServerResources/js/Mailer/Mailer.popup.js @@ -68,6 +68,19 @@ stateMessage: stateMessage } }) + .state('mail.account.mailbox.messageRaw', { + url: '/:messageId/viewRaw', + views: { + 'message@': { + templateUrl: 'UIxMailViewTemplate', // UI/Templates/MailerUI/UIxMailViewTemplate.wox + controller: 'MessageController', + controllerAs: 'viewer' + } + }, + resolve: { + stateMessage: stateMessageRaw + } + }) .state('mail.account.mailbox.message.edit', { url: '/edit', views: { @@ -254,6 +267,18 @@ } } + /** + * @ngInject + */ + stateMessageRaw.$inject = ['encodeUriFilter', '$stateParams', 'stateMailbox', 'Message']; + function stateMessageRaw(encodeUriFilter, $stateParams, stateMailbox, Message) { + var data, message; + + data = { uid: $stateParams.messageId.toString() }; + message = new Message(stateMailbox.$account.id, stateMailbox, data); + return message.$reload({ useCache: false, raw: true }); + } + /** * @ngInject */ diff --git a/UI/WebServerResources/js/Mailer/Message.service.js b/UI/WebServerResources/js/Mailer/Message.service.js index 6bca2ef0f..dd852deee 100644 --- a/UI/WebServerResources/js/Mailer/Message.service.js +++ b/UI/WebServerResources/js/Mailer/Message.service.js @@ -792,7 +792,7 @@ * @function $reload * @memberof Message.prototype * @desc Fetch the viewable message body along with other metadata such as the list of attachments. - * @param {object} [options] - set {useCache: true} to use already fetched data + * @param {object} [options] - set {useCache: true} to use already fetched data, {raw: true} to remove web mail alteration * @returns a promise of the HTTP operation */ Message.prototype.$reload = function (options) { @@ -813,7 +813,10 @@ return this; } - futureMessageData = Message.$$resource.fetch(this.$absolutePath(options), 'view'); + if (options && options.raw) + futureMessageData = Message.$$resource.fetch(this.$absolutePath(options), 'viewRaw'); + else + futureMessageData = Message.$$resource.fetch(this.$absolutePath(options), 'view'); return this.$unwrap(futureMessageData); }; diff --git a/UI/WebServerResources/js/Mailer/MessageController.js b/UI/WebServerResources/js/Mailer/MessageController.js index c652730d8..b6e4d9af0 100644 --- a/UI/WebServerResources/js/Mailer/MessageController.js +++ b/UI/WebServerResources/js/Mailer/MessageController.js @@ -544,6 +544,10 @@ } }; + this.activateRawContent = function ($event) { + this.openInPopup('viewRaw'); + }; + this.print = function($event) { $window.print(); };