This file is indexed.

/usr/lib/thunderbird-addons/extensions/{e2fda1a4-762b-4020-b5ad-a41df1933103}/calendar-js/calMonthGridPrinter.js is in xul-ext-lightning 1:24.4.0+build1-0ubuntu1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
/* 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://gre/modules/XPCOMUtils.jsm");

Components.utils.import("resource://calendar/modules/calUtils.jsm");
Components.utils.import("resource://calendar/modules/calXMLUtils.jsm");
Components.utils.import("resource://calendar/modules/calPrintUtils.jsm");

/**
 * Prints a rough month-grid of events/tasks
 */
function calMonthPrinter() {
    this.wrappedJSObject = this;
}

const calMonthPrinterClassID = Components.ID("{f42d5132-92c4-487b-b5c8-38bf292d74c1}");
const calMonthPrinterInterfaces = [Components.interfaces.calIPrintFormatter];
calMonthPrinter.prototype = {
    classID: calMonthPrinterClassID,
    QueryInterface: XPCOMUtils.generateQI(calMonthPrinterInterfaces),

    classInfo: XPCOMUtils.generateCI({
        classID: calMonthPrinterClassID,
        contractID: "@mozilla.org/calendar/printformatter;1?type=monthgrid",
        classDescription: "Calendar Month Grid Print Formatter",
        interfaces: calMonthPrinterInterfaces
    }),

    get name() cal.calGetString("calendar", "monthPrinterName"),

    formatToHtml: function monthPrint_format(aStream, aStart, aEnd, aCount, aItems, aTitle) {
        let document = cal.xml.parseFile("chrome://calendar/skin/printing/calMonthGridPrinter.html");

        // Set page title
        document.getElementById("title").textContent = aTitle;

        // Table that maps YYYY-MM-DD to the DOM node container where items are to be added
        let dayTable = {};

        // Make sure to create tables from start to end, if passed
        if (aStart && aEnd) {
            let startDate = this.normalizeStartDate(aStart);
            let endDate = this.normalizeEndDate(aEnd);
            let weekInfoService = cal.getWeekInfoService();

            // Now set up all the months we need to
            for (let current = startDate.clone();
                 weekInfoService.getEndOfWeek(current.endOfMonth).compare(endDate) < 0;
                 current.month += 1)
            {
                this.setupMonth(document, current, dayTable);
            }
        }

        for each (let item in aItems) {
            let itemStartDate = item[cal.calGetStartDateProp(item)] || item[cal.calGetEndDateProp(item)];
            let itemEndDate = item[cal.calGetEndDateProp(item)] || item[cal.calGetStartDateProp(item)];

            if (!itemStartDate && !itemEndDate) {
                cal.print.addItemToDayboxNodate(document, item);
                continue;
            }

            let boxDate = itemStartDate.clone();
            boxDate.isDate = true;
            for (boxDate; boxDate.compare(itemEndDate) < (itemEndDate.isDate ? 0 : 1); boxDate.day++) {
                // Ignore items outside of the range, i.e tasks without start date
                // where the end date is somewhere else.
                if (aStart && aEnd && boxDate &&
                    (boxDate.compare(aStart) < 0 || boxDate.compare(aEnd) >= 0)) {
                    continue;
                }

                let boxDateKey = cal.print.getDateKey(boxDate);

                if (!(boxDateKey in dayTable)) {
                    // Doesn't exist, we need to create a new table for it
                    let startOfMonth = boxDate.startOfMonth;
                    this.setupMonth(document, startOfMonth, dayTable);
                }

                let dayBoxes = dayTable[boxDateKey];
                let addSingleItem = cal.print.addItemToDaybox.bind(cal.print, document, item);

                if (Array.isArray(dayBoxes)) {
                    dayBoxes.forEach(addSingleItem);
                } else {
                    addSingleItem(dayBoxes);
                }
            }
        }

        // Remove templates from HTML, no longer needed
        let templates = document.getElementById("templates");
        templates.parentNode.removeChild(templates);

        // Stream out the resulting HTML
        let html = cal.xml.serializeDOM(document);
        let convStream = Components.classes["@mozilla.org/intl/converter-output-stream;1"]
                                   .createInstance(Components.interfaces.nsIConverterOutputStream);
        convStream.init(aStream, 'UTF-8', 0, 0x0000);
        convStream.writeString(html);
    },

    normalizeStartDate: function monthPrint_normalizeStartDate(aStart) {
        // Make sure the start date is really a date.
        let startDate = aStart.clone();
        startDate.isDate = true;

        // Find out if the start date is also shown in the first week of the
        // following month. This means we can spare a month printout.
        let firstDayOfNextMonth = startDate.clone();
        firstDayOfNextMonth.day = 1;
        firstDayOfNextMonth.month++;
        if (cal.getWeekInfoService().getStartOfWeek(firstDayOfNextMonth).compare(startDate) <= 0) {
            startDate = firstDayOfNextMonth;
        } else {
            startDate = startDate.startOfMonth;
        }
        return startDate;
    },

    normalizeEndDate: function monthPrint_normalizeEndDate(aEnd) {
        // Copy end date, which is exclusive. For our calculations, we will
        // only be handling dates and the formatToHtml() code is much cleaner with
        // the range being inclusive.
        let endDate = aEnd.clone();
        endDate.isDate = true;

        // Find out if the end date is also shown in the last week of the
        // previous month. This also means we can spare a month printout.
        lastDayOfPreviousMonth = endDate.clone();
        lastDayOfPreviousMonth.month--;
        lastDayOfPreviousMonth = lastDayOfPreviousMonth.endOfMonth;
        if (cal.getWeekInfoService().getEndOfWeek(lastDayOfPreviousMonth).compare(endDate) >= 0) {
            endDate = lastDayOfPreviousMonth;
        }

        return endDate;
    },

    setupMonth: function monthPrint_setupMonth(document, startOfMonth, dayTable) {
        let monthTemplate = document.getElementById("month-template");
        let monthContainer = document.getElementById("month-container");

        // Clone the template month and make sure it doesn't have an id
        let currentMonth = monthTemplate.cloneNode(true);
        currentMonth.removeAttribute("id");
        currentMonth.item = startOfMonth.clone();

        // Set up the month title
        let monthName = cal.formatMonth(startOfMonth.month + 1, "calendar", "monthInYear");
        let monthTitle = cal.calGetString("calendar", "monthInYear", [monthName, startOfMonth.year]);
        currentMonth.querySelector(".month-name").textContent = monthTitle;

        // Set up the weekday titles
        let wkst = cal.getPrefSafe("calendar.week.start", 0);
        for (let i = 1; i <= 7; i++) {
            let dayNumber = ((i + wkst - 1) % 7) + 1;
            let dayTitle = currentMonth.querySelector(".day" + i + "-title");
            dayTitle.textContent = cal.calGetString("dateFormat", "day." + dayNumber + ".Mmm");
        }

        // Set up each week
        let weekInfoService = cal.getWeekInfoService();
        let endOfMonthView = weekInfoService.getEndOfWeek(startOfMonth.endOfMonth);
        let startOfMonthView = weekInfoService.getStartOfWeek(startOfMonth);
        let mainMonth = startOfMonth.month;
        let weekContainer = currentMonth.querySelector(".week-container");

        for (let weekStart = startOfMonthView; weekStart.compare(endOfMonthView) < 0; weekStart.day += 7) {
            this.setupWeek(document, weekContainer, weekStart, mainMonth, dayTable);
        }

        // Now insert the month into the page container, sorting by date (and therefore by month)
        function compareDates(a, b) {
            if (!a || !b) return -1;
            let res = a.compare(b);
            return res;
        }

        cal.binaryInsertNode(monthContainer, currentMonth, currentMonth.item, compareDates);
    },

    setupWeek: function monthPrint_setupWeek(document, weekContainer, startOfWeek, mainMonth, dayTable) {
        const weekdayMap = ["sunday", "monday", "tuesday", "wednesday", "thursday", "friday", "saturday"];
        let weekTemplate = document.getElementById("week-template");

        // Clone the template week and make sure it doesn't have an id
        let currentWeek = weekTemplate.cloneNode(true);
        currentWeek.removeAttribute("id");

        // Set up day numbers for all days in this week
        let currentDate = startOfWeek.clone();
        for (let i = 1; i <= 7; i++) {
            let dayNumber = currentWeek.querySelector(".day" + i + "-number");
            let dayContainer =  currentWeek.querySelector(".day" + i + "-container");
            let dayBox = currentWeek.querySelector(".day" + i + "-box");
            let dateKey = cal.print.getDateKey(currentDate);
            dayNumber.textContent = currentDate.day;

            // We need to support adding multiple boxes, since the months have
            // overlapping days.
            if (dateKey in dayTable) {
                if (Array.isArray(dayTable[dateKey])) {
                    dayTable[dateKey].push(dayContainer);
                } else {
                    dayTable[dateKey] = [dayTable[dateKey], dayContainer];
                }
            } else {
                dayTable[dateKey] = dayContainer;
            }

            let weekDay = currentDate.weekday;
            let dayOffPrefName = "calendar.week.d" + weekDay + weekdayMap[weekDay] + "soff";
            if (cal.getPrefSafe(dayOffPrefName, false)) {
                dayBox.className += " day-off";
            }

            if (currentDate.month != mainMonth) {
                dayBox.className += " out-of-month";
            }
            currentDate.day++;
        }

        // No need for sorting, setupWeek will be called in sequence
        weekContainer.appendChild(currentWeek);
    }
};