Skip to content

Commit cab2185

Browse files
committed
Allow the extension to opt-in to sending invitations and responses
1 parent 1b490da commit cab2185

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

calendar/experiments/calendar/parent/ext-calendar-provider.js

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,12 @@
55
var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
66
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
77
var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
8+
var { jsmime } = ChromeUtils.import("resource:///modules/jsmime.jsm");
89

910
var { ExtensionAPI, EventManager } = ExtensionCommon;
1011

1112
class ExtCalendarProvider extends cal.provider.BaseClass {
12-
QueryInterface = ChromeUtils.generateQI(["calICalendar", "calIChangeLog", "calISchedulingSupport"]);
13+
QueryInterface = ChromeUtils.generateQI(["calICalendar", "calIChangeLog", "calISchedulingSupport", "calIItipTransport"]);
1314

1415
static register(extension) {
1516
let calmgr = cal.getCalendarManager();
@@ -116,11 +117,49 @@ class ExtCalendarProvider extends cal.provider.BaseClass {
116117
: ["unsubscribe"];
117118
case "requiresNetwork":
118119
return !(this.capabilities.requires_network === false);
120+
case "itip.transport":
121+
if (this.extension.emitter.has("calendar.provider.onSend")) {
122+
return this;
123+
}
124+
break;
119125
}
120126

121127
return super.getProperty(name);
122128
}
123129

130+
scheme = "mailto";
131+
132+
async sendItems(aRecipients, aItipItem) {
133+
let method = aItipItem.responseMethod;
134+
let transport = super.getProperty("itip.transport").wrappedJSObject;
135+
let { subject, body } = transport._prepareItems(aItipItem);
136+
let serializer = Cc["@mozilla.org/calendar/ics-serializer;1"].createInstance(Ci.calIIcsSerializer);
137+
let itemList = aItipItem.getItemList();
138+
serializer.addItems(itemList, itemList.length);
139+
let methodProp = cal.getIcsService().createIcalProperty("METHOD");
140+
methodProp.value = method;
141+
serializer.addProperty(methodProp);
142+
let icsText = serializer.serializeToString();
143+
let boundary = Array.from({ length: 24 }, () => Math.floor(Math.random() * 16).toString(16)).join("");
144+
let headers = new Map();
145+
headers.set("Date", [new Date()]);
146+
headers.set("Subject", [subject]);
147+
headers.set("To", aRecipients.map(attendee => ({ name: attendee.commonName, email: attendee.id.replace(/^mailto:/, "")})));
148+
headers.set("Content-Type", ["multipart/mixed; boundary=\"" + boundary + "\""]);
149+
let mimeContent = jsmime.headeremitter.emitStructuredHeaders(headers, { hardMargin: 800 }) + "\r\n";
150+
mimeContent += "--" + boundary + "\r\n";
151+
mimeContent += "Content-Type: text/plain; charset=UTF-8\r\n\r\n";
152+
mimeContent += body + "\r\n";
153+
mimeContent += "--" + boundary + "\r\n";
154+
mimeContent += "Content-Type: text/calendar; method=" + aItipItem.responseMethod + "; charset=UTF-8\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n";
155+
mimeContent += icsText;
156+
mimeContent += "--" + boundary + "\r\n";
157+
mimeContent += "Content-Type: application/ics; name=\"invite.ics\"\r\nContent-Disposition: attachment; filename=\"invite.ics\"\r\nContent-Transfer-Encoding: 8BIT\r\n\r\n";
158+
mimeContent += icsText;
159+
mimeContent += "--" + boundary + "--\r\n";
160+
await this.extension.emit("calendar.provider.onSend", this, mimeContent, aRecipients.map(attendee => attendee.id.replace(/^mailto:/, "")));
161+
}
162+
124163
addItem(aItem, aListener) {
125164
return this.adoptItem(aItem.clone(), aListener);
126165
}
@@ -409,6 +448,21 @@ this.calendar_provider = class extends ExtensionAPI {
409448
};
410449
},
411450
}).api(),
451+
452+
onSend: new EventManager({
453+
context,
454+
name: "calendar.provider.onSend",
455+
register: fire => {
456+
let listener = (event, calendar, content) => {
457+
return fire.async(convertCalendar(context.extension, calendar), content);
458+
};
459+
460+
context.extension.on("calendar.provider.onSend", listener);
461+
return () => {
462+
context.extension.off("calendar.provider.onSend", listener);
463+
};
464+
},
465+
}).api(),
412466
},
413467
},
414468
};

calendar/experiments/calendar/schema/calendar-provider.json

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@
8686
"parameters": [
8787
{ "name": "calendar", "$ref": "calendar.calendars.Calendar" }
8888
]
89+
},
90+
{
91+
"name": "onSend",
92+
"type": "function",
93+
"parameters": [
94+
{ "name": "calendar", "$ref": "calendar.calendars.Calendar" },
95+
{ "name": "mimeContent", "type": "string" }
96+
]
8997
}
9098
]
9199
}

0 commit comments

Comments
 (0)