Skip to content

Commit f922376

Browse files
committed
Allow the extension to opt-in to sending invitations and responses
1 parent 9f3a75c commit f922376

File tree

2 files changed

+63
-1
lines changed

2 files changed

+63
-1
lines changed

calendar/api/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"]);
13+
QueryInterface = ChromeUtils.generateQI(["calICalendar", "calIChangeLog", "calISchedulingSupport", "calIItipTransport"]);
1314

1415
static register(extension) {
1516
let calmgr = cal.getCalendarManager();
@@ -103,11 +104,49 @@ class ExtCalendarProvider extends cal.provider.BaseClass {
103104
: ["unsubscribe"];
104105
case "requiresNetwork":
105106
return !(this.capabilities.requires_network === false);
107+
case "itip.transport":
108+
if (this.extension.emitter.has("calendar.provider.onSend")) {
109+
return this;
110+
}
111+
break;
106112
}
107113

108114
return super.getProperty(name);
109115
}
110116

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

calendar/api/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)