Bug 1273500 - Attachments are not displayed in the event summary dialog;r=philipp
authormakemyday@gmx-topmail.de
Sat, 12 Nov 2016 15:42:00 +0100
changeset 20809 fcaede61f5c17597a55035feadc6beb7438f388d
parent 20808 79a8ad3930a66444320f89102a45102ccf51186c
child 20810 f125f3719cebe76818e05bae694bdc794af19f77
push id12612
push usermakemyday@gmx-topmail.de
push dateSun, 04 Dec 2016 19:35:24 +0000
treeherdercomm-central@9290eb29cde9 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersphilipp
bugs1273500
Bug 1273500 - Attachments are not displayed in the event summary dialog;r=philipp
calendar/base/content/dialogs/calendar-summary-dialog.js
calendar/base/content/dialogs/calendar-summary-dialog.xul
calendar/base/themes/common/calendar-attendees.css
calendar/base/themes/common/dialogs/calendar-event-dialog.css
calendar/locales/en-US/chrome/calendar/calendar-event-dialog.dtd
--- a/calendar/base/content/dialogs/calendar-summary-dialog.js
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.js
@@ -168,16 +168,43 @@ function onLoad() {
             let textbox = document.getElementById("item-description");
             textbox.value = description;
             textbox.inputField.readOnly = true;
         }
     }
 
     document.title = item.title;
 
+    let attachments = item.getAttachments({});
+    if (attachments.length) {
+        // we only want to display uri type attachments and no ones received inline with the
+        // invitation message (having a CID: prefix results in about:blank) here
+        let attCounter = 0;
+        attachments.forEach(aAttachment => {
+            if (aAttachment.uri && aAttachment.uri.spec != "about:blank") {
+                let attachment = document.getElementById("attachment-template").cloneNode(true);
+                attachment.removeAttribute("id");
+                attachment.removeAttribute("hidden");
+
+                let label = attachment.getElementsByTagName("label")[0];
+                label.setAttribute("value", aAttachment.uri.spec);
+                label.setAttribute("hashid", aAttachment.hashId);
+
+                let icon = attachment.getElementsByTagName("image")[0];
+                let iconSrc = aAttachment.uri.spec.length ? aAttachment.uri.spec : "dummy.html";
+                icon.setAttribute("src", "moz-icon://" + iconSrc);
+
+                document.getElementById("item-attachment-cell").appendChild(attachment);
+                attCounter++;
+            }
+        });
+        if (attCounter > 0) {
+            document.getElementById("attachments-row").removeAttribute("hidden");
+        }
+    }
     // If this item is read only we remove the 'cancel' button as users
     // can't modify anything, thus we go ahead with an 'ok' button only.
     if (window.readOnly) {
         document.documentElement.getButton("cancel").setAttribute("collapsed", "true");
     }
 
     window.focus();
     opener.setCursor("auto");
@@ -348,8 +375,28 @@ function sendMailToOrganizer() {
     let args = window.arguments[0];
     let item = args.calendarEvent;
     let organizer = item.organizer;
     let email = cal.getAttendeeEmail(organizer, true);
     let emailSubject = cal.calGetString("calendar-event-dialog", "emailSubjectReply", [item.title]);
     let identity = item.calendar.getProperty("imip.identity");
     sendMailTo(email, emailSubject, null, identity);
 }
+
+/**
+ * Opens an attachment
+ *
+ * @param {AUTF8String}  aAttachmentId   The hashId of the attachment to open
+ */
+function openAttachment(aAttachmentId) {
+    if (!aAttachmentId) {
+        return;
+    }
+    let args = window.arguments[0];
+    let item = args.calendarEvent;
+    let attachments = item.getAttachments({})
+                          .filter(aAttachment => aAttachment.hashId == aAttachmentId);
+    if (attachments.length && attachments[0].uri && attachments[0].uri.spec != "about:blank") {
+        let externalLoader = Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
+                                       .getService(Components.interfaces.nsIExternalProtocolService);
+        externalLoader.loadUrl(attachments[0].uri);
+    }
+}
--- a/calendar/base/content/dialogs/calendar-summary-dialog.xul
+++ b/calendar/base/content/dialogs/calendar-summary-dialog.xul
@@ -3,17 +3,17 @@
    - License, v. 2.0. If a copy of the MPL was not distributed with this
    - file, You can obtain one at http://mozilla.org/MPL/2.0/.
 -->
 
 <?xml-stylesheet type="text/css" href="chrome://global/skin/global.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-alarms.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/calendar-attendees.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/skin/calendar-event-dialog.css"?>
-<?xml-stylesheet type="text/css" href="chrome://calendar/skin/common/dialogs/calendar-event-dialog.css"?>
+<?xml-stylesheet type="text/css" href="chrome://calendar-common/skin/dialogs/calendar-event-dialog.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/datetimepickers/datetimepickers.css"?>
 <?xml-stylesheet type="text/css" href="chrome://calendar/content/calendar-bindings.css"?>
 
 <!DOCTYPE dialog [
   <!ENTITY % globalDTD SYSTEM "chrome://calendar/locale/global.dtd" >
   <!ENTITY % calendarDTD SYSTEM "chrome://calendar/locale/calendar.dtd" >
   <!ENTITY % dialogDTD SYSTEM "chrome://calendar/locale/calendar-event-dialog.dtd" >
   <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
@@ -47,66 +47,65 @@
           src="chrome://calendar/content/calendar-item-editing.js"/>
   <script type="application/javascript"
           src="chrome://calendar/content/calApplicationUtils.js"/>
 
   <!-- General -->
   <box id="item-general-box" orient="vertical">
     <calendar-caption label="&read.only.general.label;"/>
     <box orient="horizontal">
-      <spacer class="default-spacer"/>
       <grid flex="1">
         <columns>
           <column/>
           <column flex="1"/>
         </columns>
         <rows>
           <row align="top">
-            <label value="&read.only.title.label;" class="headline"/>
+            <label value="&read.only.title.label;"/>
             <label id="item-title" crop="end"/>
           </row>
           <row class="item-date-row"
                id="item-start-row"
                mode="start"
                taskStartLabel="&read.only.task.start.label;"
                eventStartLabel="&read.only.event.start.label;"
                align="start"/>
           <row class="item-date-row"
                id="item-end-row"
                mode="end"
                taskDueLabel="&read.only.task.due.label;"
                eventEndLabel="&read.only.event.end.label;"
                align="start"/>
           <row id="repeat-row" align="top" hidden="true">
-            <label value="&read.only.repeat.label;" class="headline"/>
+            <label value="&read.only.repeat.label;"/>
             <box id="repeat-details" orient="vertical">
               <label/>
             </box>
           </row>
           <row id="location-row" align="top" hidden="true">
-            <label value="&read.only.location.label;" class="headline"/>
+            <label value="&read.only.location.label;"/>
             <label id="item-location" crop="end"/>
           </row>
           <row id="category-row" align="top" hidden="true">
-            <label value="&read.only.category.label;" class="headline"/>
+            <label value="&read.only.category.label;"/>
             <label id="item-category" crop="end"/>
           </row>
           <row id="organizer-row" align="top" hidden="true" class="item-attendees-row">
-            <label value="&read.only.organizer.label;" class="headline"/>
+            <label value="&read.only.organizer.label;"/>
             <hbox class="item-organizer-cell">
               <img class="itip-icon"/>
               <label id="item-organizer"
                      class="text-link item-attendees-cell-label"
                      crop="end"
                      onclick="sendMailToOrganizer()"/>
               <spacer flex="1"/>
             </hbox>
           </row>
           <row id="status-row" align="top" hidden="true">
-            <label value="&task.status.label;" class="headline"/>
+            <label value="&task.status.label;"/>
             <label value="&newevent.status.tentative.label;" hidden="true" status="TENTATIVE"/>
             <label value="&newevent.status.confirmed.label;" hidden="true" status="CONFIRMED"/>
             <label value="&newevent.eventStatus.cancelled.label;" hidden="true" status="CANCELLED"/>
             <label value="&newevent.todoStatus.cancelled.label;" hidden="true" status="CANCELLED"/>
             <label value="&newevent.status.needsaction.label;" hidden="true" status="NEEDS-ACTION"/>
             <label value="&newevent.status.inprogress.label;" hidden="true" status="IN-PROCESS"/>
             <label value="&newevent.status.completed.label;" hidden="true" status="COMPLETED"/>
           </row>
@@ -224,16 +223,36 @@
                          class="text-link"
                          disable-on-readonly="true"
                          flex="1"
                          hyperlink="true"
                          onclick="updateReminder()"/>
                 </hbox>
              </hbox>
           </row>
+          <row id="attachments-row"
+               align="top"
+               hidden="true"
+               class="item-attachments-row">
+            <label value="&read.only.attachments.label;"
+                   control="item-attachment-cell" />
+            <vbox id="item-attachment-cell">
+              <!-- attachment box template -->
+              <hbox id="attachment-template"
+                    hidden="true"
+                    align="center"
+                    disable-on-readonly="true">
+                <image class="attachment-icon"/>
+                <label class="text-link item-attachment-cell-label"
+                       onclick="openAttachment(this.getAttribute('hashid'), event)"
+                       crop="end"
+                       flex="1" />
+              </hbox>
+            </vbox>
+          </row>
         </rows>
       </grid>
     </box>
   </box>
 
   <!-- attendee box template -->
   <vbox id="item-attendees-box-template">
     <hbox flex="1" class="item-attendees-row" equalsize="always" hidden="true">
@@ -245,28 +264,25 @@
     </hbox>
   </vbox>
 
   <!-- Attendees -->
   <box id="item-attendees" orient="vertical" hidden="true" flex="1">
     <spacer class="default-spacer"/>
     <calendar-caption label="&read.only.attendees.label;"
                       control="item-attendees-box"/>
-    <vbox id="item-attendees-box" flex="1">
-      <spacer class="default-spacer"/>
-    </vbox>
+    <vbox id="item-attendees-box" flex="1" />
   </box>
 
   <!-- Description -->
   <box id="item-description-box" hidden="true" orient="vertical" flex="1">
     <spacer class="default-spacer"/>
     <calendar-caption label="&read.only.description.label;"
                       control="item-description"/>
     <box orient="horizontal" flex="1">
-      <spacer class="default-spacer"/>
       <textbox id="item-description"
                multiline="true"
                rows="6"
                flex="1"/>
     </box>
   </box>
 
   <!-- URL link -->
--- a/calendar/base/themes/common/calendar-attendees.css
+++ b/calendar/base/themes/common/calendar-attendees.css
@@ -1,45 +1,29 @@
 /* This Source Code Form is subject to the terms of the Mozilla Public
  * License, v. 2.0. If a copy of the MPL was not distributed with this file,
  * You can obtain one at http://mozilla.org/MPL/2.0/. */
 
-/* Begin: Summary Dialog - this should be moved to
-                           calendar/base/themes/common/dialogs/calendar-event-dialog.css
-                           or a separate file for the summary dialog */
-#calendar-summary-dialog,
-#calendar-event-summary-dialog,
-#calendar-task-summary-dialog {
-    min-width: 35em;
-}
-
-#calendar-summary-dialog #item-description,
-#calendar-event-summary-dialog #item-description,
-#calendar-task-summary-dialog #item-description {
-    min-height: 54px;
-}
-/* End: Summary Dialog */
-
 /* this is for attendee and organizer decoration in summary and event dialog */
 
 #item-attendees-box {
     -moz-appearance: listbox;
     margin: 2px 4px 0;
     overflow-y: auto;
     min-height: 54px; /*at least two rows - otherwise a scrollbar (if required) wouldn't appear*/
 }
 
 #calendar-summary-dialog #item-attendees,
 #calendar-event-summary-dialog #item-attendees,
 #calendar-task-summary-dialog #item-attendees {
     max-height: 135px; /* displays up to four rows of attendees*/
 }
 
 .item-attendees-cell {
-    padding: 3px 0px;
+    padding: 2px;
 }
 
 #calendar-event-dialog-inner .item-attendees-cell {
     -moz-user-focus: normal;
     margin-bottom: 1px;
     margin-inline-end: 1px;
 }
 
--- a/calendar/base/themes/common/dialogs/calendar-event-dialog.css
+++ b/calendar/base/themes/common/dialogs/calendar-event-dialog.css
@@ -500,8 +500,45 @@ freebusy-day > box {
 
 .selection-bar-spacer {
     cursor: grab;
 }
 
 .checkbox-no-label > .checkbox-label-box {
     display: none;
 }
+
+/*--------------------------------------------------------------------
+ *   Event summary dialog
+ *-------------------------------------------------------------------*/
+
+#calendar-summary-dialog,
+#calendar-event-summary-dialog,
+#calendar-task-summary-dialog {
+    min-width: 35em;
+}
+
+#calendar-summary-dialog #item-attachment-cell,
+#calendar-event-summary-dialog #item-attachment-cell,
+#calendar-task-summary-dialog #item-attachment-cell {
+    margin-left: 6px;
+}
+
+#calendar-summary-dialog .item-attachment-cell-label,
+#calendar-event-summary-dialog .item-attachment-cell-label,
+#calendar-task-summary-dialog .item-attachment-cell-label {
+    margin-left: 3px;
+}
+
+#calendar-summary-dialog #item-description,
+#calendar-event-summary-dialog #item-description,
+#calendar-task-summary-dialog #item-description {
+    min-height: 54px;
+}
+
+#calendar-summary-dialog #item-start-row .headline,
+#calendar-event-summary-dialog #item-start-row .headline,
+#calendar-task-summary-dialog #item-start-row .headline,
+#calendar-summary-dialog #item-end-row .headline,
+#calendar-event-summary-dialog #item-end-row .headline,
+#calendar-task-summary-dialog #item-end-row .headline {
+    font-weight: normal;
+}
--- a/calendar/locales/en-US/chrome/calendar/calendar-event-dialog.dtd
+++ b/calendar/locales/en-US/chrome/calendar/calendar-event-dialog.dtd
@@ -384,11 +384,12 @@
 <!ENTITY read.only.category.label        "Category:">
 <!ENTITY read.only.organizer.label       "Organizer:">
 <!ENTITY read.only.reply.label           "Reply:">
 <!ENTITY read.only.accept.label          "I will attend">
 <!ENTITY read.only.decline.label         "I will not attend">
 <!ENTITY read.only.tentative.label       "I might attend">
 <!ENTITY read.only.needs.action.label    "I will confirm later">
 <!ENTITY read.only.reminder.label        "Reminder:">
+<!ENTITY read.only.attachments.label     "Attachments:">
 <!ENTITY read.only.attendees.label       "Attendees">
 <!ENTITY read.only.description.label     "Description">
 <!ENTITY read.only.link.label            "Related Link">