1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this file,
3 * You can obtain one at http://mozilla.org/MPL/2.0/. */
4
5var EXPORTED_SYMBOLS = ["CalMimeConverter"];
6
7var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
8var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
9
10function CalMimeConverter() {
11  this.wrappedJSObject = this;
12}
13
14CalMimeConverter.prototype = {
15  QueryInterface: ChromeUtils.generateQI(["nsISimpleMimeConverter"]),
16  classID: Components.ID("{c70acb08-464e-4e55-899d-b2c84c5409fa}"),
17
18  uri: null,
19
20  convertToHTML(contentType, data) {
21    let parser = Cc["@mozilla.org/calendar/ics-parser;1"].createInstance(Ci.calIIcsParser);
22    parser.parseString(data);
23    let event = null;
24    for (let item of parser.getItems()) {
25      if (item.isEvent()) {
26        if (item.hasProperty("X-MOZ-FAKED-MASTER")) {
27          // if it's a faked master, take any overridden item to get a real occurrence:
28          let exc = item.recurrenceInfo.getExceptionFor(item.startDate);
29          cal.ASSERT(exc, "unexpected!");
30          if (exc) {
31            item = exc;
32          }
33        }
34        event = item;
35        break;
36      }
37    }
38    if (!event) {
39      return "";
40    }
41
42    let msgWindow = null;
43
44    let itipItem = Cc["@mozilla.org/calendar/itip-item;1"].createInstance(Ci.calIItipItem);
45    itipItem.init(data);
46
47    // this.uri is the message URL that we are processing.
48    // We use it to get the nsMsgHeaderSink to store the calItipItem.
49    if (this.uri) {
50      try {
51        let msgUrl = this.uri.QueryInterface(Ci.nsIMsgMailNewsUrl);
52        msgWindow = msgUrl.msgWindow;
53        itipItem.sender = msgUrl.mimeHeaders.extractHeader("From", false);
54      } catch (exc) {
55        // msgWindow is optional in some scenarios
56        // (e.g. gloda in action, throws NS_ERROR_INVALID_POINTER then)
57      }
58    }
59
60    // msgOverlay needs to be defined irrespectively of the existence of msgWindow to not break
61    // printing of invitation emails
62    let dom = cal.invitation.createInvitationOverlay(event, itipItem);
63    let msgOverlay = cal.xml.serializeDOM(dom);
64
65    if (msgWindow) {
66      let sinkProps = msgWindow.msgHeaderSink.properties;
67      sinkProps.setPropertyAsInterface("itipItem", itipItem);
68
69      // Notify the observer that the itipItem is available
70      Services.obs.notifyObservers(null, "onItipItemCreation");
71    }
72    return msgOverlay;
73  },
74};
75