/* This Source Code Form is subject to the terms of the Mozilla Public * 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/. */ import { cal } from "resource:///modules/calendar/calUtils.sys.mjs"; const lazy = {}; ChromeUtils.defineESModuleGetters(lazy, { NetUtil: "resource://gre/modules/NetUtil.sys.mjs", }); ChromeUtils.defineLazyGetter(lazy, "l10n", () => new Localization(["calendar/calendar.ftl"], true)); /** * Calendar HTML Exporter. * * @implements {calIExporter} */ export class CalHtmlExporter { QueryInterface = ChromeUtils.generateQI(["calIExporter"]); classID = Components.ID("{72d9ab35-9b1b-442a-8cd0-ae49f00b159b}"); constructor() { this.wrappedJSObject = this; } getFileTypes() { const wildmat = "*.html; *.htm"; const label = lazy.l10n.formatValueSync("filter-html", { wildmat }); return [ { QueryInterface: ChromeUtils.generateQI(["calIFileType"]), defaultExtension: "html", extensionFilter: wildmat, description: label, }, ]; } /** * Export the items into the stream. * * @param {nsIOutputStream} aStream - The stream to put the data into. * @param {calIItemBase[]} aItems - The items to be exported. * @param {?string} aTitle - Title the exporter can choose to use. */ exportToStream(aStream, aItems, aTitle) { const stream = lazy.NetUtil.newChannel({ uri: "chrome://calendar/content/printing/calHtmlExport.html", loadUsingSystemPrincipal: true, }).open(); const str = lazy.NetUtil.readInputStreamToString(stream, stream.available()); const document = new DOMParser().parseFromString(str, "application/xml"); const itemContainer = document.getElementById("item-container"); document.getElementById("title").textContent = aTitle || lazy.l10n.formatValueSync("html-title"); // Sort aItems aItems.sort((a, b) => { const start_a = a[cal.dtz.startDateProp(a)]; if (!start_a) { return -1; } const start_b = b[cal.dtz.startDateProp(b)]; if (!start_b) { return 1; } return start_a.compare(start_b); }); for (const item of aItems) { const itemNode = document.getElementById("item-template").cloneNode(true); itemNode.removeAttribute("id"); const setupTextRow = function (classKey, propValue, prefixKey) { if (propValue) { const prefix = lazy.l10n.formatValueSync(prefixKey); itemNode.querySelector("." + classKey + "key").textContent = prefix; itemNode.querySelector("." + classKey).textContent = propValue; } else { const row = itemNode.querySelector("." + classKey + "row"); if ( row.nextSibling.nodeType == row.nextSibling.TEXT_NODE || row.nextSibling.nodeType == row.nextSibling.CDATA_SECTION_NODE ) { row.nextSibling.remove(); } row.remove(); } }; const startDate = item[cal.dtz.startDateProp(item)]; const endDate = item[cal.dtz.endDateProp(item)]; if (startDate || endDate) { // This is a task with a start or due date, format accordingly const prefixWhen = lazy.l10n.formatValueSync("html-prefix-when"); itemNode.querySelector(".intervalkey").textContent = prefixWhen; const startNode = itemNode.querySelector(".dtstart"); const dateString = cal.dtz.formatter.formatItemInterval(item); startNode.setAttribute("title", startDate ? startDate.icalString : "none"); startNode.textContent = dateString; } else { const row = itemNode.querySelector(".intervalrow"); row.remove(); if ( row.nextSibling && (row.nextSibling.nodeType == row.nextSibling.TEXT_NODE || row.nextSibling.nodeType == row.nextSibling.CDATA_SECTION_NODE) ) { row.nextSibling.remove(); } } const itemTitle = item.isCompleted ? lazy.l10n.formatValueSync("html-task-completed", { task: item.title }) : item.title; setupTextRow("summary", itemTitle, "html-prefix-title"); setupTextRow("location", item.getProperty("LOCATION"), "html-prefix-location"); setupTextRow("description", item.getProperty("DESCRIPTION"), "html-prefix-description"); itemContainer.appendChild(itemNode); } const templates = document.getElementById("templates"); templates.remove(); // Convert the javascript string to an array of bytes, using the utf8 encoder const convStream = Cc["@mozilla.org/intl/converter-output-stream;1"].createInstance( Ci.nsIConverterOutputStream ); convStream.init(aStream, "UTF-8"); convStream.writeString(cal.xml.serializeDOM(document)); } }