diff --git a/UI/Templates/MailerUI/UIxMailViewTemplate.wox b/UI/Templates/MailerUI/UIxMailViewTemplate.wox index 630283369..8e82049ef 100644 --- a/UI/Templates/MailerUI/UIxMailViewTemplate.wox +++ b/UI/Templates/MailerUI/UIxMailViewTemplate.wox @@ -107,9 +107,9 @@
-
-
+
+
+
diff --git a/UI/WebServerResources/js/Common/sgCompile.directive.js b/UI/WebServerResources/js/Common/sgCompile.directive.js new file mode 100644 index 000000000..912d6a933 --- /dev/null +++ b/UI/WebServerResources/js/Common/sgCompile.directive.js @@ -0,0 +1,47 @@ +/* -*- Mode: javascript; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ + +(function() { + 'use strict'; + + /* + * sgCompile - Assign an expression to a DOM element and compile it. + * @memberof SOGo.Common + * @restrict attribute + * @param {object} sgCompile - the expression to compile + * @ngInject + * @example: + +
+ */ + sgCompile.$inject = ['$compile']; + function sgCompile($compile) { + return { + restrict: 'A', + link: sgCompileLink + }; + + function sgCompileLink(scope, element, attrs) { + var ensureCompileRunsOnce = scope.$watch( + function(scope) { + // Watch the sg-compile expression for changes + return scope.$eval(attrs.sgCompile); + }, + function(value) { + // When the sg-compile expression changes, assign it into the current DOM + element.html(value); + + // Compile the new DOM and link it to the current scope. + // NOTE: we only compile .childNodes so that we don't get into infinite loop compiling ourselves + $compile(element.contents())(scope); + + // Use un-watch feature to ensure compilation happens only once. + ensureCompileRunsOnce(); + } + ); + } + } + + angular + .module('SOGo.Common') + .directive('sgCompile', sgCompile); +})(); diff --git a/UI/WebServerResources/js/Mailer/Message.service.js b/UI/WebServerResources/js/Mailer/Message.service.js index 4aca0c30b..9d0f8d72b 100644 --- a/UI/WebServerResources/js/Mailer/Message.service.js +++ b/UI/WebServerResources/js/Mailer/Message.service.js @@ -166,7 +166,7 @@ var _this = this, parts = [], _visit = function(part) { - if (part.type == "UIxMailPartAlternativeViewer") { + if (part.type == 'UIxMailPartAlternativeViewer') { _visit(_.find(part.content, function(alternatePart) { return part.preferredPart == alternatePart.contentType; })); @@ -182,7 +182,8 @@ part.safeContent = part.content; _this.$hasUnsafeContent = (part.safeContent.indexOf(' unsafe-') > -1); } - if (part.type == "UIxMailPartHTMLViewer") { + if (part.type == 'UIxMailPartHTMLViewer') { + part.html = true; if (_this.$loadUnsafeContent) { if (angular.isUndefined(part.unsafeContent)) { part.unsafeContent = document.createElement('div'); @@ -207,7 +208,14 @@ } parts.push(part); } + else if (part.type == 'UIxMailPartICalViewer' || + part.type == 'UIxMailPartLinkViewer') { + // Trusted content that can be compiled (Angularly-speaking) + part.compile = true; + parts.push(part); + } else { + part.html = true; part.content = Message.$sce.trustAs('html', part.safeContent); parts.push(part); }