Add links to download one or all attachments
Also removed the contextual menu over file attachments and changed the label color when moving over the file attachments.pull/17/head
parent
dc21c723f6
commit
5f369f201d
1
NEWS
1
NEWS
|
@ -6,6 +6,7 @@ New features
|
|||
using SOGoCalendarDefaultReminder
|
||||
- select multiple files to attach to a message or drag'n'drop files onto the
|
||||
mail editor; will also now display progress of uploads
|
||||
- new popup menu to download all attachments of a mail
|
||||
|
||||
Enhancements
|
||||
- we now automatically convert <img src=data...> into file attachments
|
||||
|
|
|
@ -97,11 +97,11 @@
|
|||
"Reply-To" = "Reply-To";
|
||||
"Add address" = "Add address";
|
||||
|
||||
"Attachments:" = "Attachments:";
|
||||
"Open" = "Open";
|
||||
"Select All" = "Select All";
|
||||
"Attach Web Page..." = "Attach Web Page...";
|
||||
"Attach File(s)..." = "Attach File(s)...";
|
||||
"file" = "file";
|
||||
"files" = "files";
|
||||
|
||||
"to" = "To";
|
||||
"cc" = "Cc";
|
||||
|
|
|
@ -163,6 +163,11 @@ static NSArray *infoKeys = nil;
|
|||
return item;
|
||||
}
|
||||
|
||||
- (NSString *) uid
|
||||
{
|
||||
return [[self clientObject] nameInContainer];
|
||||
}
|
||||
|
||||
- (NSArray *) priorityClasses
|
||||
{
|
||||
static NSArray *priorities = nil;
|
||||
|
@ -382,16 +387,16 @@ static NSArray *infoKeys = nil;
|
|||
ASSIGN (attachment, newAttachment);
|
||||
}
|
||||
|
||||
- (NSFormatter *) sizeFormatter
|
||||
{
|
||||
return [UIxMailSizeFormatter sharedMailSizeFormatter];
|
||||
}
|
||||
|
||||
- (NSDictionary *) attachment
|
||||
{
|
||||
return attachment;
|
||||
}
|
||||
|
||||
- (NSFormatter *) sizeFormatter
|
||||
{
|
||||
return [UIxMailSizeFormatter sharedMailSizeFormatter];
|
||||
}
|
||||
|
||||
/* from addresses */
|
||||
|
||||
- (NSArray *) fromEMails
|
||||
|
@ -672,11 +677,6 @@ static NSArray *infoKeys = nil;
|
|||
return [[self attachmentAttrs] count] > 0 ? YES : NO;
|
||||
}
|
||||
|
||||
- (NSString *) uid
|
||||
{
|
||||
return [[self clientObject] nameInContainer];
|
||||
}
|
||||
|
||||
- (id) defaultAction
|
||||
{
|
||||
SOGoDraftObject *co;
|
||||
|
|
|
@ -47,11 +47,12 @@
|
|||
#import <SOGo/SOGoUser.h>
|
||||
#import <SOGo/SOGoUserDefaults.h>
|
||||
#import <SOGo/SOGoUserManager.h>
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
#import <Mailer/SOGoMailObject.h>
|
||||
#import <Mailer/SOGoMailAccount.h>
|
||||
#import <Mailer/SOGoMailFolder.h>
|
||||
#import <SOGoUI/UIxComponent.h>
|
||||
#import <MailPartViewers/UIxMailRenderingContext.h> // cyclic
|
||||
#import <MailPartViewers/UIxMailSizeFormatter.h>
|
||||
|
||||
#import "WOContext+UIxMailer.h"
|
||||
|
||||
|
@ -60,6 +61,8 @@
|
|||
id currentAddress;
|
||||
NSString *shouldAskReceipt;
|
||||
NSString *matchingIdentityEMail;
|
||||
NSDictionary *attachment;
|
||||
NSArray *attachmentAttrs;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -80,6 +83,8 @@ static NSString *mailETag = nil;
|
|||
- (void) dealloc
|
||||
{
|
||||
[matchingIdentityEMail release];
|
||||
[attachment release];
|
||||
[attachmentAttrs release];
|
||||
[super dealloc];
|
||||
}
|
||||
|
||||
|
@ -111,6 +116,16 @@ static NSString *mailETag = nil;
|
|||
[self messageSubject]];
|
||||
}
|
||||
|
||||
- (void) setAttachment: (NSDictionary *) newAttachment
|
||||
{
|
||||
ASSIGN (attachment, newAttachment);
|
||||
}
|
||||
|
||||
- (NSDictionary *) attachment
|
||||
{
|
||||
return attachment;
|
||||
}
|
||||
|
||||
/* links (DUP to UIxMailPartViewer!) */
|
||||
|
||||
- (NSString *) linkToEnvelopeAddress: (NGImap4EnvelopeAddress *) _address
|
||||
|
@ -146,6 +161,36 @@ static NSString *mailETag = nil;
|
|||
return [[[self clientObject] replyToEnvelopeAddresses] count] > 0 ? YES : NO;
|
||||
}
|
||||
|
||||
/* attachment helper */
|
||||
|
||||
- (NSArray *) attachmentAttrs
|
||||
{
|
||||
if (!attachmentAttrs)
|
||||
{
|
||||
ASSIGN (attachmentAttrs, [[self clientObject] fetchFileAttachmentKeys]);
|
||||
}
|
||||
|
||||
return attachmentAttrs;
|
||||
}
|
||||
|
||||
- (BOOL) hasAttachments
|
||||
{
|
||||
return [[self attachmentAttrs] count] > 0 ? YES : NO;
|
||||
}
|
||||
|
||||
- (NSFormatter *) sizeFormatter
|
||||
{
|
||||
return [UIxMailSizeFormatter sharedMailSizeFormatter];
|
||||
}
|
||||
|
||||
- (NSString *) attachmentsText
|
||||
{
|
||||
if ([[self attachmentAttrs] count] > 1)
|
||||
return [self labelForKey: @"files"];
|
||||
else
|
||||
return [self labelForKey: @"file"];
|
||||
}
|
||||
|
||||
/* viewers */
|
||||
|
||||
- (id) contentViewerComponent
|
||||
|
|
|
@ -211,12 +211,6 @@
|
|||
</ul>
|
||||
</div>
|
||||
|
||||
<div class="menu" id="attachmentMenu">
|
||||
<ul>
|
||||
<li id="save_attachment"><var:string label:value="Save Attachment"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<div id="leftPanel">
|
||||
<div class="titlediv"><var:string label:value="Folders" /></div>
|
||||
<div id="folderTreeContent"><!-- space --></div>
|
||||
|
|
|
@ -13,9 +13,7 @@
|
|||
var messageName = '<var:string value="clientObject.relativeImap4Name"/>';
|
||||
var mailboxName = '/<var:string value="clientObject.container.container.nameInContainer"/>/<var:string value="clientObject.container.nameInContainer"/>';
|
||||
</script>
|
||||
<span id="messageContent">
|
||||
<var:component className="UIxMailView" />
|
||||
</span>
|
||||
<div class="menu" id="addressMenu">
|
||||
<ul>
|
||||
<li id="add_to_addressbook"><var:string label:value="Add to Address Book..."/></li>
|
||||
|
@ -27,10 +25,5 @@
|
|||
<ul>
|
||||
<li id="save_image"><var:string label:value="Save Image"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="menu" id="attachmentMenu">
|
||||
<ul>
|
||||
<li id="save_attachment"><var:string label:value="Save Attachment"/></li>
|
||||
</ul>
|
||||
</div>
|
||||
</var:component>
|
||||
|
|
|
@ -5,14 +5,25 @@
|
|||
xmlns:uix="OGo:uix"
|
||||
xmlns:rsrc="OGo:url"
|
||||
xmlns:label="OGo:label">
|
||||
<var:if condition="clientObject.hasAttachment">
|
||||
<div class="menu" const:id="attachmentsMenu">
|
||||
<ul>
|
||||
<li><var:string label:value="Save all"/></li>
|
||||
<li class="separator"><!-- separator --></li
|
||||
><var:foreach list="attachmentAttrs" item="attachment">
|
||||
<li var:data-url="attachment.urlAsAttachment"><img rsrc:src="attachment.gif"/><var:string value="attachment.filename"
|
||||
/> <span class="muted">(<var:string value="attachment.size" formatter="sizeFormatter"/>)</span></li>
|
||||
</var:foreach
|
||||
></ul>
|
||||
</div>
|
||||
</var:if>
|
||||
<span id="messageContent">
|
||||
<input type="hidden" const:id="shouldAskReceipt" var:value="shouldAskReceipt"/>
|
||||
<var:if var:condition="mailIsDraft"
|
||||
><input const:name="editDraftButton" const:id="editDraftButton"
|
||||
type="button" class="button" label:value="Edit Draft..."
|
||||
/></var:if>
|
||||
<input const:name="loadImagesButton" const:id="loadImagesButton"
|
||||
type="button" class="button" label:value="Load Images"
|
||||
/>
|
||||
><a href="#" const:id="editDraftButton" class="button"><span><var:string label:value="Edit Draft..."/></span></a
|
||||
></var:if>
|
||||
<a href="#" const:name="loadImagesButton" const:id="loadImagesButton"
|
||||
class="button"><span><var:string label:value="Load Images"/></span></a>
|
||||
<table class="mailer_fieldtable">
|
||||
<tr class="mailer_fieldrow">
|
||||
<td class="mailer_fieldname" ><var:string label:value="Subject"/>:</td>
|
||||
|
@ -93,11 +104,19 @@
|
|||
</td>
|
||||
</tr>
|
||||
</var:if>
|
||||
<var:if condition="clientObject.hasAttachment">
|
||||
<tr class="mailer_fieldrow">
|
||||
<td class="mailer_fieldname"><img rsrc:src="title_attachment_14x14.png"/></td>
|
||||
<td class="mailer_fieldvalue">
|
||||
<a href="#" const:id="attachmentsHref"><var:string value="attachmentAttrs.count"/> <var:string value="attachmentsText"/></a>
|
||||
</td>
|
||||
</tr>
|
||||
</var:if>
|
||||
</table>
|
||||
|
||||
<div class="mailer_mailcontent">
|
||||
<var:component value="contentViewerComponent"
|
||||
bodyInfo="clientObject.bodyStructure" />
|
||||
</div>
|
||||
|
||||
</span>
|
||||
</container>
|
||||
|
|
|
@ -374,21 +374,21 @@ TR.mailer_listcell_regular TD A
|
|||
}
|
||||
|
||||
/* mail viewer */
|
||||
INPUT#editDraftButton
|
||||
#editDraftButton
|
||||
{
|
||||
position: absolute;
|
||||
top: 2.5em;
|
||||
right: 1em;
|
||||
}
|
||||
|
||||
INPUT#loadImagesButton
|
||||
#loadImagesButton
|
||||
{
|
||||
position: absolute;
|
||||
top: 2.5em;
|
||||
right: 1em;
|
||||
}
|
||||
|
||||
.popup INPUT#loadImagesButton
|
||||
.popup #loadImagesButton
|
||||
{
|
||||
top: 9.0em;
|
||||
right: 1em;
|
||||
|
@ -434,7 +434,8 @@ DIV.mailer_mailcontent TABLE
|
|||
}
|
||||
|
||||
/* collapsable header */
|
||||
TD.mailer_fieldname IMG
|
||||
TD.mailer_fieldname IMG.collapse,
|
||||
TD.mailer_fieldname IMG.expand
|
||||
{ cursor: pointer;
|
||||
padding-right: 5px; }
|
||||
TD.mailer_fieldvalue SPAN.collapse
|
||||
|
@ -577,7 +578,7 @@ DIV.linked_attachment_meta
|
|||
{
|
||||
color: #444444;
|
||||
border-width: 0;
|
||||
padding: 2px;
|
||||
padding: 2px 4px;
|
||||
}
|
||||
|
||||
TABLE.linked_attachment_meta
|
||||
|
@ -585,6 +586,25 @@ TABLE.linked_attachment_meta
|
|||
color: #444444;
|
||||
}
|
||||
|
||||
.linked_attachment_body a:hover
|
||||
{
|
||||
text-decoration: none;
|
||||
}
|
||||
|
||||
.linked_attachment_body a:hover .linked_attachment_meta
|
||||
{
|
||||
background-color: #9ABCD8;
|
||||
color: #fff;
|
||||
-webkit-border-radius: 5px;
|
||||
-moz-border-radius: 5px;
|
||||
border-radius: 5px;
|
||||
}
|
||||
|
||||
.linked_attachment_body a:hover .muted
|
||||
{
|
||||
color: #fff !important;
|
||||
}
|
||||
|
||||
DIV.linked_attachment_body HR
|
||||
{
|
||||
border: 0px;
|
||||
|
|
|
@ -1357,13 +1357,27 @@ function configureLinksInMessage() {
|
|||
anchor.observe("contextmenu", onEmailAddressClick);
|
||||
anchor.writeAttribute("moz-do-not-send", false);
|
||||
}
|
||||
else
|
||||
else if (!anchor.id)
|
||||
anchor.observe("click", onMessageAnchorClick);
|
||||
}
|
||||
|
||||
var attachments = messageDiv.select ("DIV.linked_attachment_body");
|
||||
for (var i = 0; i < attachments.length; i++)
|
||||
$(attachments[i]).observe("contextmenu", onAttachmentClick);
|
||||
var attachmentsMenu = $("attachmentsMenu");
|
||||
if (attachmentsMenu) {
|
||||
var options = attachmentsMenu.select("li");
|
||||
var callbacks = [];
|
||||
for (var i = 0; i < options.length; i++) {
|
||||
if (options[i].className == 'separator')
|
||||
callbacks.push(null);
|
||||
else
|
||||
callbacks.push(saveAttachment);
|
||||
}
|
||||
initMenu(attachmentsMenu, callbacks);
|
||||
$("attachmentsHref").on("click", function (event) {
|
||||
popupMenu(event, 'attachmentsMenu', this);
|
||||
preventDefault(event);
|
||||
return false;
|
||||
});
|
||||
}
|
||||
|
||||
var images = messageDiv.select("IMG.mailer_imagecontent");
|
||||
for (var i = 0; i < images.length; i++)
|
||||
|
@ -1371,12 +1385,11 @@ function configureLinksInMessage() {
|
|||
|
||||
var editDraftButton = $("editDraftButton");
|
||||
if (editDraftButton)
|
||||
editDraftButton.observe("click",
|
||||
onMessageEditDraft.bindAsEventListener(editDraftButton));
|
||||
editDraftButton.on("click", onMessageEditDraft);
|
||||
|
||||
var loadImagesButton = $("loadImagesButton");
|
||||
if (loadImagesButton)
|
||||
$(loadImagesButton).observe("click", onMessageLoadImages);
|
||||
loadImagesButton.on("click", onMessageLoadImages);
|
||||
|
||||
configureiCalLinksInMessage();
|
||||
}
|
||||
|
@ -1562,12 +1575,13 @@ function onMessageContentMenu(event) {
|
|||
}
|
||||
|
||||
function onMessageEditDraft(event) {
|
||||
Event.stop(event);
|
||||
return openMessageWindowsForSelection("edit", true);
|
||||
}
|
||||
|
||||
function onMessageLoadImages(event) {
|
||||
loadRemoteImages();
|
||||
Event.stop(event);
|
||||
loadRemoteImages();
|
||||
}
|
||||
|
||||
function loadRemoteImages() {
|
||||
|
@ -1613,12 +1627,6 @@ function onImageClick(event) {
|
|||
return false;
|
||||
}
|
||||
|
||||
function onAttachmentClick (event) {
|
||||
popupMenu (event, 'attachmentMenu', this);
|
||||
preventDefault (event);
|
||||
return false;
|
||||
}
|
||||
|
||||
function handleReturnReceipt() {
|
||||
var input = $("shouldAskReceipt");
|
||||
if (input) {
|
||||
|
@ -1773,13 +1781,29 @@ function saveImage(event) {
|
|||
window.location.href = urlAsAttachment;
|
||||
}
|
||||
|
||||
function saveAttachment(event) {
|
||||
var div = document.menuTarget;
|
||||
var link = div.select ("a").first ();
|
||||
var url = link.getAttribute("href");
|
||||
var urlAsAttachment = url.replace(/(\/[^\/]*)$/,"/asAttachment$1");
|
||||
/* Download a file using a temporary iframe that we delete once the download is started */
|
||||
function download(url) {
|
||||
var form = createElement('form', null, 'hidden', { action: url, method: 'GET'});
|
||||
$(document.body).appendChild(form);
|
||||
var div = AIM.submit(form);
|
||||
form.submit();
|
||||
setTimeout(function () {
|
||||
form.remove();
|
||||
div.remove();
|
||||
}, 2000);
|
||||
}
|
||||
|
||||
window.location.href = urlAsAttachment;
|
||||
function saveAttachment(event) {
|
||||
var url = $(this).readAttribute('data-url');
|
||||
if (url) {
|
||||
download(url);
|
||||
}
|
||||
else {
|
||||
$(this).up('ul').select('li[data-url]').each(function (item) {
|
||||
url = $(item).readAttribute('data-url');
|
||||
download(url);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
/* contacts */
|
||||
|
@ -2820,7 +2844,6 @@ function getMenus() {
|
|||
saveAs, null, null,
|
||||
onMenuDeleteMessage ],
|
||||
imageMenu: [ saveImage ],
|
||||
attachmentMenu: [ saveAttachment ],
|
||||
messageContentMenu: [ onMenuReplyToSender,
|
||||
onMenuReplyToAll,
|
||||
onMenuForwardMessage,
|
||||
|
|
|
@ -251,7 +251,8 @@ DIV.contactSelector DIV.contactList
|
|||
padding-bottom: .15em;
|
||||
margin: 0px;
|
||||
width: auto;
|
||||
white-space: nowrap; }
|
||||
white-space: nowrap;
|
||||
cursor: pointer; }
|
||||
|
||||
.menu LI.disabled,
|
||||
.popuMenu LI.disabled,
|
||||
|
@ -283,10 +284,11 @@ UL.choiceMenu LI._chosen:hover
|
|||
{ list-style-image: url("menu-check-hover.gif"); }
|
||||
|
||||
.menu LI:hover,
|
||||
.menu LI:hover .muted,
|
||||
.menu LI.selected,
|
||||
.menu LI.submenu-selected
|
||||
{ background-color: #9ABCD8;
|
||||
color: #fff; }
|
||||
color: #fff !important; }
|
||||
|
||||
.menu LI.disabled:hover
|
||||
{ background-color: inherit; }
|
||||
|
|
|
@ -1925,7 +1925,7 @@ AIM = {
|
|||
d.innerHTML = '<iframe class="hidden" src="about:blank" id="'
|
||||
+ n + '" name="' + n + '" onload="AIM.loaded(\'' + n + '\')"></iframe>';
|
||||
document.body.appendChild(d);
|
||||
var i = $(n); // TODO: useful?
|
||||
var i = $(n);
|
||||
if (c && typeof(c.onComplete) == 'function')
|
||||
i.onComplete = c.onComplete;
|
||||
return n;
|
||||
|
@ -1936,27 +1936,28 @@ AIM = {
|
|||
},
|
||||
|
||||
submit: function(f, c) {
|
||||
AIM.form(f, AIM.frame(c));
|
||||
var id = AIM.frame(c);
|
||||
AIM.form(f, id);
|
||||
if (c && typeof(c.onStart) == 'function')
|
||||
return c.onStart();
|
||||
else
|
||||
return true;
|
||||
return $(id);
|
||||
},
|
||||
|
||||
loaded: function(id) {
|
||||
var i = $(id);
|
||||
var d;
|
||||
if (i.contentDocument) {
|
||||
var d = i.contentDocument;
|
||||
d = i.contentDocument;
|
||||
}
|
||||
else if (i.contentWindow) {
|
||||
var d = i.contentWindow.document;
|
||||
d = i.contentWindow.document;
|
||||
}
|
||||
else {
|
||||
var d = window.frames[id].document;
|
||||
d = window.frames[id].document;
|
||||
}
|
||||
if (d.location.href == "about:blank")
|
||||
return;
|
||||
|
||||
if (typeof(i.onComplete) == 'function') {
|
||||
i.onComplete(Element.allTextContent(d.body));
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue