Skip to content

Commit

Permalink
Update calendar experiment to Thunderbird 128
Browse files Browse the repository at this point in the history
  • Loading branch information
kewisch committed Aug 7, 2024
1 parent b7362f7 commit ac81225
Show file tree
Hide file tree
Showing 12 changed files with 361 additions and 314 deletions.
2 changes: 1 addition & 1 deletion calendar/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,5 +12,5 @@ reliable API documentation please see the relevant [schema files](./schema/).
| ------------- | --------
| Description | Experiment and add-on for calendar-related APIs in Thunderbird.
| Status | Draft
| Compatibility | Thunderbird 91 (possibly Thunderbird 78)
| Compatibility | Thunderbird 128
| Tracking | [bug 1627205](https://bugzilla.mozilla.org/show_bug.cgi?id=1627205)
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,10 @@
* 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/. */

var EXPORTED_SYMBOLS = ["CalendarProviderChild"];

class CalendarProviderChild extends JSWindowActorChild {
export class CalendarProviderChild extends JSWindowActorChild {
receiveMessage(msg) {
if (msg.name == "postMessage") {
this.contentWindow.postMessage(msg.data.message, msg.data.origin)
this.contentWindow.postMessage(msg.data.message, msg.data.origin);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,52 +2,22 @@
* 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/. */

var EXPORTED_SYMBOLS = [
"isOwnCalendar",
"unwrapCalendar",
"getResolvedCalendarById",
"getCachedCalendar",
"isCachedCalendar",
"convertCalendar",
"propsToItem",
"convertItem",
"convertAlarm",
"setupE10sBrowser",
];

var { XPCOMUtils } = ChromeUtils.import("resource://gre/modules/XPCOMUtils.jsm");

XPCOMUtils.defineLazyModuleGetters(this, {
cal: "resource:///modules/calendar/calUtils.jsm",
ICAL: "resource:///modules/calendar/Ical.jsm",
CalEvent: "resource:///modules/CalEvent.jsm",
CalTodo: "resource:///modules/CalTodo.jsm",
ExtensionParent: "resource://gre/modules/ExtensionParent.jsm",
});

var { ExtensionError, promiseEvent } = ChromeUtils.import(
"resource://gre/modules/ExtensionUtils.jsm"
).ExtensionUtils;

XPCOMUtils.defineLazyGetter(this, "standaloneStylesheets", () => {
let stylesheets = [];
let { AppConstants } = ChromeUtils.import("resource://gre/modules/AppConstants.jsm");

if (AppConstants.platform === "macosx") {
stylesheets.push("chrome://browser/content/extension-mac-panel.css");
} else if (AppConstants.platform === "win") {
stylesheets.push("chrome://browser/content/extension-win-panel.css");
} else if (AppConstants.platform === "linux") {
stylesheets.push("chrome://browser/content/extension-linux-panel.css");
}
return stylesheets;
});
var {
ExtensionUtils: { ExtensionError, promiseEvent }
} = ChromeUtils.importESModule("resource://gre/modules/ExtensionUtils.sys.mjs");

var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");
var { CalEvent } = ChromeUtils.importESModule("resource:///modules/CalEvent.sys.mjs");
var { CalTodo } = ChromeUtils.importESModule("resource:///modules/CalTodo.sys.mjs");
var { ExtensionParent } = ChromeUtils.importESModule("resource://gre/modules/ExtensionParent.sys.mjs");

var { default: ICAL } = ChromeUtils.importESModule("resource:///modules/calendar/Ical.sys.mjs");

function isOwnCalendar(calendar, extension) {
export function isOwnCalendar(calendar, extension) {
return calendar.superCalendar.type == "ext-" + extension.id;
}

function unwrapCalendar(calendar) {
export function unwrapCalendar(calendar) {
let unwrapped = calendar.wrappedJSObject;

if (unwrapped.mUncachedCalendar) {
Expand All @@ -57,7 +27,7 @@ function unwrapCalendar(calendar) {
return unwrapped;
}

function getResolvedCalendarById(extension, id) {
export function getResolvedCalendarById(extension, id) {
let calendar;
if (id.endsWith("#cache")) {
let cached = cal.manager.getCalendarById(id.substring(0, id.length - 6));
Expand All @@ -72,16 +42,16 @@ function getResolvedCalendarById(extension, id) {
return calendar;
}

function getCachedCalendar(calendar) {
export function getCachedCalendar(calendar) {
return calendar.wrappedJSObject.mCachedCalendar || calendar;
}

function isCachedCalendar(id) {
export function isCachedCalendar(id) {
// TODO make this better
return id.endsWith("#cache");
}

function convertCalendar(extension, calendar) {
export function convertCalendar(extension, calendar) {
if (!calendar) {
return null;
}
Expand All @@ -105,7 +75,7 @@ function convertCalendar(extension, calendar) {
return props;
}

function propsToItem(props, baseItem) {
export function propsToItem(props, baseItem) {
let item;
if (baseItem) {
item = baseItem;
Expand All @@ -122,7 +92,18 @@ function propsToItem(props, baseItem) {
if (props.formats?.use == "ical") {
item.icalString = props.formats.ical;
} else if (props.formats?.use == "jcal") {
item.icalString = ICAL.stringify(props.formats.jcal);
try {
item.icalString = ICAL.stringify(props.formats.jcal);
} catch (e) {
let jsonstring;
try {
jsonstring = JSON.stringify(props.formats.jcal, null, 2);
} catch {
jsonstring = props.formats.jcal;
}

throw new ExtensionError("Could not parse jCal: " + e + "\n" + jsonstring);
}
} else {
if (props.id) {
item.id = props.id;
Expand Down Expand Up @@ -155,7 +136,7 @@ function propsToItem(props, baseItem) {
return item;
}

function convertItem(item, options, extension) {
export function convertItem(item, options, extension) {
if (!item) {
return null;
}
Expand All @@ -181,7 +162,7 @@ function convertItem(item, options, extension) {
try {
// TODO This is a sync operation. Not great. Can we optimize this?
props.metadata = JSON.parse(cache.getMetaData(item.id)) ?? {};
} catch (e) {
} catch {
// Ignore json parse errors
}
}
Expand Down Expand Up @@ -218,7 +199,7 @@ function convertItem(item, options, extension) {
return props;
}

function convertAlarm(item, alarm) {
export function convertAlarm(item, alarm) {
const ALARM_RELATED_MAP = {
[Ci.calIAlarm.ALARM_RELATED_ABSOLUTE]: "absolute",
[Ci.calIAlarm.ALARM_RELATED_START]: "start",
Expand All @@ -234,7 +215,7 @@ function convertAlarm(item, alarm) {
};
}

async function setupE10sBrowser(extension, browser, parent, initOptions={}) {
export async function setupE10sBrowser(extension, browser, parent, initOptions={}) {
browser.setAttribute("type", "content");
browser.setAttribute("disableglobalhistory", "true");
browser.setAttribute("messagemanagergroup", "webext-browsers");
Expand Down Expand Up @@ -267,9 +248,10 @@ async function setupE10sBrowser(extension, browser, parent, initOptions={}) {
let sheets = [];
if (initOptions.browser_style) {
delete initOptions.browser_style;
sheets.push(...ExtensionParent.extensionStylesheets);
sheets.push("chrome://browser/content/extension.css");
}
sheets.push(...standaloneStylesheets);
sheets.push("chrome://browser/content/extension-popup-panel.css");


const initBrowser = () => {
ExtensionParent.apiManager.emit("extension-browser-inserted", browser);
Expand Down
31 changes: 21 additions & 10 deletions calendar/experiments/calendar/parent/ext-calendar-calendars.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,14 @@
* 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/. */

var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
var { ExtensionUtils } = ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
var {
ExtensionCommon: { ExtensionAPI, EventManager }
} = ChromeUtils.importESModule("resource://gre/modules/ExtensionCommon.sys.mjs");
var {
ExtensionUtils: { ExtensionError }
} = ChromeUtils.importESModule("resource://gre/modules/ExtensionUtils.sys.mjs");

var { ExtensionAPI, EventManager } = ExtensionCommon;
var { ExtensionError } = ExtensionUtils;

var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");

this.calendar_calendars = class extends ExtensionAPI {
getAPI(context) {
Expand All @@ -18,7 +18,7 @@ this.calendar_calendars = class extends ExtensionAPI {
getResolvedCalendarById,
isOwnCalendar,
convertCalendar,
} = ChromeUtils.import("resource://experiment-calendar/experiments/calendar/ext-calendar-utils.jsm");
} = ChromeUtils.importESModule("resource://tb-experiments-calendar/experiments/calendar/ext-calendar-utils.sys.mjs");

return {
calendar: {
Expand All @@ -30,7 +30,7 @@ this.calendar_calendars = class extends ExtensionAPI {
if (url) {
try {
pattern = new MatchPattern(url, { restrictSchemes: false });
} catch (e) {
} catch {
throw new ExtensionError(`Invalid url pattern: ${url}`);
}
}
Expand Down Expand Up @@ -127,7 +127,18 @@ this.calendar_calendars = class extends ExtensionAPI {

if (updateProperties.capabilities) {
// TODO validate capability names
calendar.capabilities = Object.assign({}, calendar.capabilities, updateProperties.capabilities);
let unwrappedCalendar = calendar.wrappedJSObject.mUncachedCalendar.wrappedJSObject;
unwrappedCalendar.capabilities = Object.assign({}, unwrappedCalendar.capabilities, updateProperties.capabilities);
}

if (updateProperties.lastError !== undefined) {
if (updateProperties.lastError === null) {
calendar.setProperty("currentStatus", Cr.NS_ERROR_FAILURE);
calendar.setProperty("lastErrorMessage", updateProperties.lastError);
} else {
calendar.setProperty("currentStatus", Cr.NS_OK);
calendar.setProperty("lastErrorMessage", "");
}
}
},
remove: async function(id) {
Expand Down
25 changes: 12 additions & 13 deletions calendar/experiments/calendar/parent/ext-calendar-items.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,14 @@
* 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/. */

var { ExtensionCommon } = ChromeUtils.import("resource://gre/modules/ExtensionCommon.jsm");
var { ExtensionUtils } = ChromeUtils.import("resource://gre/modules/ExtensionUtils.jsm");
var { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm");
var {
ExtensionCommon: { ExtensionAPI, EventManager }
} = ChromeUtils.importESModule("resource://gre/modules/ExtensionCommon.sys.mjs");
var {
ExtensionUtils: { ExtensionError }
} = ChromeUtils.importESModule("resource://gre/modules/ExtensionUtils.sys.mjs");

var { ExtensionAPI, EventManager } = ExtensionCommon;
var { ExtensionError } = ExtensionUtils;
var { cal } = ChromeUtils.importESModule("resource:///modules/calendar/calUtils.sys.mjs");

this.calendar_items = class extends ExtensionAPI {
getAPI(context) {
Expand All @@ -19,13 +21,12 @@ this.calendar_items = class extends ExtensionAPI {
propsToItem,
convertItem,
convertAlarm,
} = ChromeUtils.import("resource://experiment-calendar/experiments/calendar/ext-calendar-utils.jsm");
} = ChromeUtils.importESModule("resource://tb-experiments-calendar/experiments/calendar/ext-calendar-utils.sys.mjs");

return {
calendar: {
items: {
query: async function(queryProps) {
console.log(queryProps);
let calendars = [];
if (typeof queryProps.calendarId == "string") {
calendars = [getResolvedCalendarById(context.extension, queryProps.calendarId)];
Expand All @@ -38,9 +39,7 @@ this.calendar_items = class extends ExtensionAPI {

let calendarItems;
if (queryProps.id) {
calendarItems = await Promise.all(calendars.map(calendar => {
return calendar.getItem(queryProps.id);
}));
calendarItems = await Promise.all(calendars.map(calendar => calendar.getItem(queryProps.id)));
} else {
calendarItems = await Promise.all(calendars.map(async calendar => {
let filter = Ci.calICalendar.ITEM_FILTER_COMPLETED_ALL;
Expand All @@ -58,17 +57,16 @@ this.calendar_items = class extends ExtensionAPI {

let rangeStart = queryProps.rangeStart ? cal.createDateTime(queryProps.rangeStart) : null;
let rangeEnd = queryProps.rangeEnd ? cal.createDateTime(queryProps.rangeEnd) : null;

return calendar.getItemsAsArray(filter, queryProps.limit ?? 0, rangeStart, rangeEnd);
}));
calendarItems = calendarItems.flat();
}

return calendarItems.map(item => convertItem(item, queryProps, context.extension));
return calendarItems.flat().map(item => convertItem(item, queryProps, context.extension));
},
get: async function(calendarId, id, options) {
let calendar = getResolvedCalendarById(context.extension, calendarId);
let item = await calendar.getItem(id);

return convertItem(item, options, context.extension);
},
create: async function(calendarId, createProperties) {
Expand Down Expand Up @@ -139,6 +137,7 @@ this.calendar_items = class extends ExtensionAPI {
},
remove: async function(calendarId, id) {
let calendar = getResolvedCalendarById(context.extension, calendarId);

let item = await calendar.getItem(id);
if (!item) {
throw new ExtensionError("Could not find item " + id);
Expand Down
Loading

0 comments on commit ac81225

Please sign in to comment.