1 /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 *
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
9 *
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
13 * License.
14 *
15 * The Original Code is Lightning code.
16 *
17 * The Initial Developer of the Original Code is Oracle Corporation
18 * Portions created by the Initial Developer are Copyright (C) 2005
19 * the Initial Developer. All Rights Reserved.
20 *
21 * Contributor(s):
22 * Mike Shaver <shaver@mozilla.org>
23 * Clint Talbert <ctalbert.moz@gmail.com>
24 * Matthew Willis <lilmatt@mozilla.com>
25 * Mauro Cicognini <mcicogni@libero.it>
26 *
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
38 *
39 * ***** END LICENSE BLOCK ***** */
40
41 function makeTableRow(val) {
42 return "<tr><td>" + val[0] + "</td><td>" + val[1] + "</td></tr>\n";
43 }
44
45 function getLightningStringBundle()
46 {
47 var svc = Components.classes["@mozilla.org/intl/stringbundle;1"].
48 getService(Components.interfaces.nsIStringBundleService);
49 return svc.createBundle("chrome://lightning/locale/lightning.properties");
50 }
51
52 function createHtmlTableSection(label, text)
53 {
54 var tblRow = <tr>
55 <td class="description">
56 <p>{label}</p>
57 </td>
58 <td class="content">
59 <p>{text}</p>
60 </td>
61 </tr>;
62 return tblRow;
63 }
64
65 function createHtml(event)
66 {
67 // Creates HTML using the Node strings in the properties file
68 var stringBundle = getLightningStringBundle();
69 var html;
70 if (stringBundle) {
71 // Using e4x javascript support here
72 html =
73 <html>
74 <head>
75 <meta http-equiv='Content-Type' content='text/html; charset=utf-8'/>
76 <link rel='stylesheet' type='text/css' href='chrome://lightning/skin/imip.css'/>
77 </head>
78 <body>
79 <table>
80 </table>
81 </body>
82 </html>;
83 // Create header row
84 var labelText = stringBundle.GetStringFromName("imipHtml.header");
85 html.body.table.appendChild(
86 <tr>
87 <td colspan="3" class="header">
88 <p class="header">{labelText}</p>
89 </td>
90 </tr>
91 );
92 if (event.title) {
93 labelText = stringBundle.GetStringFromName("imipHtml.summary");
94 html.body.table.appendChild(createHtmlTableSection(labelText,
95 event.title));
96 }
97
98 var eventLocation = event.getProperty("LOCATION");
99 if (eventLocation) {
100 labelText = stringBundle.GetStringFromName("imipHtml.location");
101 html.body.table.appendChild(createHtmlTableSection(labelText,
102 eventLocation));
103 }
104
105 var dateFormatter = Components.classes["@mozilla.org/calendar/datetime-formatter;1"]
106 .getService(Components.interfaces.calIDateTimeFormatter);
107 var startString = new Object();
108 var endString = new Object();
109 dateFormatter.formatInterval(event.startDate.getInTimezone(calendarDefaultTimezone()),
110 event.endDate.getInTimezone(calendarDefaultTimezone()),
111 startString, endString);
112 var dateString = startString.value + " - " + endString.value;
113
114 var labelText = stringBundle.GetStringFromName("imipHtml.when");
115 html.body.table.appendChild(createHtmlTableSection(labelText,
116 dateString));
117
118 if (event.organizer &&
119 (event.organizer.commonName || event.organizer.id))
120 {
121 labelText = stringBundle.GetStringFromName("imipHtml.organizer");
122 // Trim any instances of "mailto:" for better readibility.
123 var orgname = event.organizer.commonName ||
124 event.organizer.id.replace(/mailto:/ig, "");
125 html.body.table.appendChild(createHtmlTableSection(labelText, orgname));
126 }
127
128 var eventDescription = event.getProperty("DESCRIPTION");
129 if (eventDescription) {
130 // Remove the useless "Outlookism" squiggle.
131 var desc = eventDescription.replace("*~*~*~*~*~*~*~*~*~*", "");
132
133 labelText = stringBundle.GetStringFromName("imipHtml.description");
134 html.body.table.appendChild(createHtmlTableSection(labelText,desc));
135 }
136
137 var eventComment = event.getProperty("COMMENT");
138 if (eventComment) {
139 labelText = stringBundle.GetStringFromName("imipHtml.Comment");
140 html.body.table.appendChild(createHtmlTableSection(labelText,eventComment));
141 }
142 }
143
144 return html;
145 }
146
147 function ltnMimeConverter() { }
148
149 ltnMimeConverter.prototype = {
150 QueryInterface: function QI(aIID) {
151 if (!aIID.equals(Components.interfaces.nsISupports) &&
152 !aIID.equals(Components.interfaces.nsISimpleMimeConverter))
153 {
154 throw Components.results.NS_ERROR_NO_INTERFACE;
155 }
156
157 return this;
158 },
159
160 mUri: null,
161 get uri() {
162 return this.mUri;
163 },
164 set uri(aUri) {
165 return (this.mUri = aUri);
166 },
167
168 convertToHTML: function lmcCTH(contentType, data) {
169 var event = Components.classes["@mozilla.org/calendar/event;1"].
170 createInstance(Components.interfaces.calIEvent);
171 event.icalString = data;
172 var html = createHtml(event);
173
174 try {
175 var itipItem = Components.classes["@mozilla.org/calendar/itip-item;1"].
176 createInstance(Components.interfaces.calIItipItem);
177 itipItem.init(data);
178
179 // this.mUri is the message URL that we are processing.
180 // We use it to get the nsMsgHeaderSink to store the calItipItem.
181 if (this.mUri) {
182 var msgUrl = this.mUri.QueryInterface(Components.interfaces.nsIMsgMailNewsUrl);
183 var sinkProps = msgUrl.msgWindow.msgHeaderSink.properties;
184 sinkProps.setPropertyAsInterface("itipItem", itipItem);
185
186 // Notify the observer that the itipItem is available
187 var observer = Components.classes["@mozilla.org/observer-service;1"].
188 getService(Components.interfaces.nsIObserverService);
189 observer.notifyObservers(null, "onItipItemCreation", 0);
190 } else {
191 // Thunderbird 1.5.x case: We have no choice but to try
192 // sending the iTIP item directly with the notification
193 var observer = Components.classes["@mozilla.org/observer-service;1"].
194 getService(Components.interfaces.nsIObserverService);
195 observer.notifyObservers(itipItem, "onItipItemCreation", 0);
196 }
197
198 } catch (e) {
199 Components.utils.reportError("convertToHTML: " +
200 "Cannot create itipItem: " + e);
201 }
202
203 return html;
204 }
205 };
206
207 var myModule = {
208 registerSelf: function RS(aCompMgr, aFileSpec, aLocation, aType) {
209 debug("*** Registering Lightning text/calendar handler\n");
210 var compMgr = aCompMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
211 compMgr.registerFactoryLocation(this.myCID,
212 "Lightning text/calendar handler",
213 this.myContractID,
214 aFileSpec,
215 aLocation,
216 aType);
217
218 var catman = Components.classes["@mozilla.org/categorymanager;1"]
219 .getService(Components.interfaces.nsICategoryManager);
220
221 catman.addCategoryEntry("simple-mime-converters", "text/calendar",
222 this.myContractID, true, true);
223 },
224
225 mScriptsLoaded: false,
226 getClassObject: function GCO(aCompMgr, aCid, aIid) {
227 if (!this.mScriptsLoaded) {
228 // loading extra scripts from ../js:
229 const scripts = [ "calUtils.js" ];
230 var scriptLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"]
231 .createInstance(Components.interfaces.mozIJSSubScriptLoader);
232 var ioService = Components.classes["@mozilla.org/network/io-service;1"]
233 .getService(Components.interfaces.nsIIOService);
234 var baseDir = __LOCATION__.parent.parent;
235 baseDir.append("js");
236 for each (var script in scripts) {
237 var scriptFile = baseDir.clone();
238 scriptFile.append(script);
239 scriptLoader.loadSubScript(ioService.newFileURI(scriptFile).spec, null);
240 }
241 this.mScriptsLoaded = true;
242 }
243
244 if (!aCid.equals(this.myCID)) {
245 throw Components.results.NS_ERROR_NO_INTERFACE;
246 }
247 if (!aIid.equals(Components.interfaces.nsIFactory)) {
248 throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
249 }
250 return this.myFactory;
251 },
252
253 myCID: Components.ID("{c70acb08-464e-4e55-899d-b2c84c5409fa}"),
254
255 myContractID: "@mozilla.org/lightning/mime-converter;1",
256
257 myFactory: {
258 createInstance: function mfCI(aOuter, aIid) {
259 if (aOuter != null) {
260 throw Components.results.NS_ERROR_NO_AGGREGATION;
261 }
262 return (new ltnMimeConverter()).QueryInterface(aIid);
263 }
264 },
265
266 canUnload: function CU(aCompMgr) {
267 return true;
268 }
269 };
270
271 function NSGetModule(compMgr, fileSpec) {
272 return myModule;
273 }