/* 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/. */
Components.utils.import("resource://calendar/modules/calUtils.jsm");
Components.utils.import("resource://gre/modules/Preferences.jsm");
EXPORTED_SYMBOLS = ["cal"]; // even though it's defined in calUtils.jsm, import needs this
cal.print = {
/**
* Returns a simple key in the format YYYY-MM-DD for use in the table of
* dates to day boxes
*
* @param dt The date to translate
* @return YYYY-MM-DD
*/
getDateKey: function getDateKey(dt) {
return dt.year + "-" + dt.month + "-" + dt.day;
},
/**
* Add category styles to the document's "sheet" element. This is needed
* since the HTML created is serialized, so we can't dynamically set the
* styles and can be changed if the print formatter decides to return a
* DOM document instead.
*
* @param document The document that contains .
* @param categories Array of categories to insert rules for.
*/
insertCategoryRules: function insertCategoryRules(document, categories) {
let sheet = document.getElementById("sheet");
sheet.insertedCategoryRules = sheet.insertedCategoryRules || {};
for each (let category in categories) {
let prefName = cal.formatStringForCSSRule(category);
let color = Preferences.get("calendar.category.color." + prefName) || "transparent";
if (!(prefName in sheet.insertedCategoryRules)) {
sheet.insertedCategoryRules[prefName] = true;
let ruleAdd = ' .category-color-box[categories~="' + prefName + '"] { ' +
' border: 2px solid ' + color + '; }' + "\n";
sheet.textContent += ruleAdd;
}
}
},
/**
* Add calendar styles to the document's "sheet" element. This is needed
* since the HTML created is serialized, so we can't dynamically set the
* styles and can be changed if the print formatter decides to return a
* DOM document instead.
*
* @param document The document that contains .
* @param categories The calendar to insert a rule for.
*/
insertCalendarRules: function insertCalendarRules(document, calendar) {
let sheet = document.getElementById("sheet");
let color = calendar.getProperty("color") || "#A8C2E1";
sheet.insertedCalendarRules = sheet.insertedCalendarRules || {};
if (!(calendar.id in sheet.insertedCalendarRules)) {
sheet.insertedCalendarRules[calendar.id] = true;
let formattedId = cal.formatStringForCSSRule(calendar.id);
let ruleAdd = ' .calendar-color-box[calendar-id="' + formattedId + '"] { ' +
' background-color: ' + color + '; ' +
' color: ' + cal.getContrastingTextColor(color) + '; }' + "\n";
sheet.textContent += ruleAdd;
}
},
/**
* Serializes the given item by setting marked nodes to the item's content.
* Has some expectations about the DOM document (in CSS-selector-speak), all
* following nodes MUST exist.
*
* - #item-template will be cloned and filled, and modified:
* - .item-interval gets the time interval of the item.
* - .item-title gets the item title
* - .category-color-box gets a 2px solid border in category color
* - .calendar-color-box gets background color of the calendar
*
* @param document The DOM Document to set things on
* @param item The item to serialize
* @param dayContainer The DOM Node to insert the container in
*/
addItemToDaybox: function addItemToDaybox(document, item, dayContainer) {
// Clone our template
let itemNode = document.getElementById("item-template").cloneNode(true);
itemNode.removeAttribute("id");
itemNode.item = item;
// Fill in details of the item
let itemInterval = cal.print.getItemIntervalString(item);
itemNode.querySelector(".item-interval").textContent = itemInterval;
itemNode.querySelector(".item-title").textContent = item.title;
// Fill in category details
let categoriesArray = item.getCategories({});
if (categoriesArray.length > 0) {
let cssClassesArray = categoriesArray.map(cal.formatStringForCSSRule);
itemNode.querySelector(".category-color-box")
.setAttribute("categories", cssClassesArray.join(" "));
cal.print.insertCategoryRules(document, categoriesArray);
}
// Fill in calendar color
itemNode.querySelector(".calendar-color-box")
.setAttribute("calendar-id", cal.formatStringForCSSRule(item.calendar.id));
cal.print.insertCalendarRules(document, item.calendar);
// Add it to the day container in the right order
cal.binaryInsertNode(dayContainer, itemNode, item, comparePrintItems);
},
/**
* Serializes the given item by setting marked nodes to the item's
* content. Should be used for tasks with no start and due date. Has
* some expectations about the DOM document (in CSS-selector-speak),
* all following nodes MUST exist.
*
* - Nodes will be added to #task-container.
* - #task-list-box will have the "hidden" attribute removed.
* - #task-template will be cloned and filled, and modified:
* - .task-checkbox gets the "checked" attribute set, if completed
* - .task-title gets the item title.
*
* @param document The DOM Document to set things on
* @param item The item to serialize
*/
addItemToDayboxNodate: function addItemToDayboxNodate(document, item) {
let taskContainer = document.getElementById("task-container");
let taskNode = document.getElementById("task-template").cloneNode(true);
taskNode.removeAttribute("id");
taskNode.item = item;
let taskListBox = document.getElementById("tasks-list-box");
if (taskListBox.hasAttribute("hidden")) {
let tasksTitle = document.getElementById("tasks-title");
taskListBox.removeAttribute("hidden");
tasksTitle.textContent = cal.calGetString("calendar","tasksWithNoDueDate");
}
// Fill in details of the task
if (item.isCompleted) {
taskNode.querySelector(".task-checkbox").setAttribute("checked", "checked");
}
taskNode.querySelector(".task-title").textContent = item.title;
let collator = cal.createLocaleCollator();
cal.binaryInsertNode(taskContainer, taskNode, item, function(a, b) collator.compareString(0, a, b), function(node) node.item.title);
},
/**
* Get time interval string for the given item. Returns an empty string for all-day items.
*
* @param aItem The item providing the interval
* @return The string describing the interval
*/
getItemIntervalString: function getItemIntervalString(aItem) {
// omit time label for all-day items
let startDate = aItem[cal.calGetStartDateProp(aItem)]
let endDate = aItem[cal.calGetEndDateProp(aItem)];
if ((startDate && startDate.isDate) || (endDate && endDate.isDate)) {
return "";
}
// Bug 359007: will result in wrong time label for events that span two or more days
return cal.getDateFormatter().formatItemTimeInterval(aItem);
}
}
/**
* Item comparator for inserting items into dayboxes.
*
* TODO This could possibly be replaced with a global item comparator so
* that it matches with the views and such.
*
* @param a The first item
* @param b The second item
* @return The usual -1, 0, 1
*/
function comparePrintItems(a, b) {
if (!a) return -1;
if (!b) return 1;
// Sort tasks before events
if (cal.isEvent(a) && cal.isToDo(b)) {
return 1;
}
if (cal.isToDo(a) && cal.isEvent(b)) {
return -1;
}
if (cal.isEvent(a)) {
let startCompare = a.startDate.compare(b.startDate);
if (startCompare != 0) {
return startCompare;
}
return a.endDate.compare(b.endDate);
}
let dateA = a.entryDate || a.dueDate;
let dateB = b.entryDate || b.dueDate;
return dateA.compare(dateB);
}