From 9e3c08db40b8916968b9f30096c7be3f00ce9647 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 21 Apr 2024 13:44:51 +0200 Subject: Adding upstream version 1:115.7.0. Signed-off-by: Daniel Baumann --- comm/calendar/base/content/calendar-month-view.js | 1242 +++++++++++++++++++++ 1 file changed, 1242 insertions(+) create mode 100644 comm/calendar/base/content/calendar-month-view.js (limited to 'comm/calendar/base/content/calendar-month-view.js') diff --git a/comm/calendar/base/content/calendar-month-view.js b/comm/calendar/base/content/calendar-month-view.js new file mode 100644 index 0000000000..f4bd93b02d --- /dev/null +++ b/comm/calendar/base/content/calendar-month-view.js @@ -0,0 +1,1242 @@ +/* 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/. */ + +/* globals calendarNavigationBar, MozElements, MozXULElement */ + +/* import-globals-from calendar-ui-utils.js */ + +"use strict"; + +// Wrap in a block to prevent leaking to window scope. +{ + const { cal } = ChromeUtils.import("resource:///modules/calendar/calUtils.jsm"); + + /** + * Implements the Drag and Drop class for the Month Day Box view. + * + * @augments {MozElements.CalendarDnDContainer} + */ + class CalendarMonthDayBox extends MozElements.CalendarDnDContainer { + static get inheritedAttributes() { + return { + ".calendar-month-week-label": "relation,selected", + ".calendar-month-day-label": "relation,selected,text=value", + }; + } + + constructor() { + super(); + this.addEventListener("mousedown", this.onMouseDown); + this.addEventListener("dblclick", this.onDblClick); + this.addEventListener("click", this.onClick); + this.addEventListener("wheel", this.onWheel); + } + + connectedCallback() { + if (this.delayConnectedCallback() || this.hasConnected) { + return; + } + // this.hasConnected is set to true in super.connectedCallback. + super.connectedCallback(); + + this.mDate = null; + this.mItemHash = {}; + this.mShowMonthLabel = false; + + this.setAttribute("orient", "vertical"); + + let monthDayLabels = document.createElement("h2"); + monthDayLabels.classList.add("calendar-month-day-box-dates"); + + let weekLabel = document.createElement("span"); + weekLabel.setAttribute("data-label", "week"); + weekLabel.setAttribute("hidden", "true"); + weekLabel.style.pointerEvents = "none"; + weekLabel.classList.add("calendar-month-day-box-week-label", "calendar-month-week-label"); + + let dayLabel = document.createElement("span"); + dayLabel.setAttribute("data-label", "day"); + dayLabel.style.pointerEvents = "none"; + dayLabel.classList.add("calendar-month-day-box-date-label", "calendar-month-day-label"); + + monthDayLabels.appendChild(weekLabel); + monthDayLabels.appendChild(dayLabel); + + this.dayList = document.createElement("ol"); + this.dayList.classList.add("calendar-month-day-box-list"); + + this.appendChild(monthDayLabels); + this.appendChild(this.dayList); + + this.initializeAttributeInheritance(); + } + + get date() { + return this.mDate; + } + + set date(val) { + this.setDate(val); + } + + get selected() { + let sel = this.getAttribute("selected"); + if (sel && sel == "true") { + return true; + } + + return false; + } + + set selected(val) { + if (val) { + this.setAttribute("selected", "true"); + this.parentNode.setAttribute("selected", "true"); + } else { + this.removeAttribute("selected"); + this.parentNode.removeAttribute("selected"); + } + } + + get showMonthLabel() { + return this.mShowMonthLabel; + } + + set showMonthLabel(val) { + if (this.mShowMonthLabel == val) { + return; + } + this.mShowMonthLabel = val; + + if (!this.mDate) { + return; + } + if (val) { + this.setAttribute("value", cal.dtz.formatter.formatDateWithoutYear(this.mDate)); + } else { + this.setAttribute("value", this.mDate.day); + } + } + + clear() { + // Remove all the old events. + this.mItemHash = {}; + while (this.dayList.lastChild) { + this.dayList.lastChild.remove(); + } + } + + setDate(aDate) { + this.clear(); + + if (this.mDate && aDate && this.mDate.compare(aDate) == 0) { + return; + } + + this.mDate = aDate; + + if (!aDate) { + // Clearing out these attributes isn't strictly necessary but saves some confusion. + this.removeAttribute("year"); + this.removeAttribute("month"); + this.removeAttribute("week"); + this.removeAttribute("day"); + this.removeAttribute("value"); + return; + } + + // Set up DOM attributes for custom CSS coloring. + let weekTitle = cal.weekInfoService.getWeekTitle(aDate); + this.setAttribute("year", aDate.year); + this.setAttribute("month", aDate.month + 1); + this.setAttribute("week", weekTitle); + this.setAttribute("day", aDate.day); + + if (this.mShowMonthLabel) { + this.setAttribute("value", cal.dtz.formatter.formatDateWithoutYear(this.mDate)); + } else { + this.setAttribute("value", aDate.day); + } + } + + addItem(aItem) { + if (aItem.hashId in this.mItemHash) { + this.removeItem(aItem); + } + + let cssSafeId = cal.view.formatStringForCSSRule(aItem.calendar.id); + let box = document.createXULElement("calendar-month-day-box-item"); + let context = this.getAttribute("item-context") || this.getAttribute("context"); + box.setAttribute("context", context); + box.style.setProperty("--item-backcolor", `var(--calendar-${cssSafeId}-backcolor)`); + box.style.setProperty("--item-forecolor", `var(--calendar-${cssSafeId}-forecolor)`); + + let listItemWrapper = document.createElement("li"); + listItemWrapper.classList.add("calendar-month-day-box-list-item"); + listItemWrapper.appendChild(box); + cal.data.binaryInsertNode( + this.dayList, + listItemWrapper, + aItem, + cal.view.compareItems, + false, + // Access the calendar item from a list item wrapper. + wrapper => wrapper.firstChild.item + ); + + box.calendarView = this.calendarView; + box.item = aItem; + box.parentBox = this; + box.occurrence = aItem; + + this.mItemHash[aItem.hashId] = box; + return box; + } + + selectItem(aItem) { + if (aItem.hashId in this.mItemHash) { + this.mItemHash[aItem.hashId].selected = true; + } + } + + unselectItem(aItem) { + if (aItem.hashId in this.mItemHash) { + this.mItemHash[aItem.hashId].selected = false; + } + } + + removeItem(aItem) { + if (aItem.hashId in this.mItemHash) { + // Delete the list item wrapper. + let node = this.mItemHash[aItem.hashId].parentNode; + node.remove(); + delete this.mItemHash[aItem.hashId]; + } + } + + setDropShadow(on) { + let existing = this.dayList.querySelector(".dropshadow"); + if (on) { + if (!existing) { + // Insert an empty list item. + let dropshadow = document.createElement("li"); + dropshadow.classList.add("dropshadow", "calendar-month-day-box-list-item"); + this.dayList.insertBefore(dropshadow, this.dayList.firstElementChild); + } + } else if (existing) { + existing.remove(); + } + } + + onDropItem(aItem) { + // When item's timezone is different than the default one, the + // item might get moved on a day different than the drop day. + // Changing the drop day allows to compensate a possible difference. + + // Figure out if the timezones cause a days difference. + let start = ( + aItem[cal.dtz.startDateProp(aItem)] || aItem[cal.dtz.endDateProp(aItem)] + ).clone(); + let dayboxDate = this.mDate.clone(); + if (start.timezone != dayboxDate.timezone) { + let startInDefaultTz = start.clone().getInTimezone(dayboxDate.timezone); + start.isDate = true; + startInDefaultTz.isDate = true; + startInDefaultTz.timezone = start.timezone; + let dayDiff = start.subtractDate(startInDefaultTz); + // Change the day where to drop the item. + dayboxDate.addDuration(dayDiff); + } + + return cal.item.moveToDate(aItem, dayboxDate); + } + + onMouseDown(event) { + event.stopPropagation(); + if (this.mDate) { + this.calendarView.selectedDay = this.mDate; + } + } + + onDblClick(event) { + event.stopPropagation(); + this.calendarView.controller.createNewEvent(); + } + + onClick(event) { + if (event.button != 0) { + return; + } + + if (!(event.ctrlKey || event.metaKey)) { + this.calendarView.setSelectedItems([]); + } + } + + onWheel(event) { + if (cal.view.getParentNodeOrThisByAttribute(event.target, "data-label", "day") == null) { + if (this.dayList.scrollHeight > this.dayList.clientHeight) { + event.stopPropagation(); + } + } + } + } + + customElements.define("calendar-month-day-box", CalendarMonthDayBox); + + /** + * The MozCalendarMonthDayBoxItem widget is used as event item in the + * Multiweek and Month views of the calendar. It displays the event name, + * alarm icon and the category type color. + * + * @augments {MozElements.MozCalendarEditableItem} + */ + class MozCalendarMonthDayBoxItem extends MozElements.MozCalendarEditableItem { + static get inheritedAttributes() { + return { + ".alarm-icons-box": "flashing", + }; + } + connectedCallback() { + if (this.delayConnectedCallback() || this.hasChildNodes()) { + return; + } + // NOTE: This is the same structure as EditableItem, except this has a + // time label and we are missing the location-desc. + this.appendChild( + MozXULElement.parseXULToFragment(` + + + +