Bug 1554646 - [de-xbl] convert calendar-editable-item binding and derivatives to custom elements. r=pmorris
This commit is contained in:
Родитель
90fbaeb677
Коммит
d6b527b5c5
|
@ -163,10 +163,12 @@
|
|||
let multiDayImage = this.querySelector(".agenda-multiDayEvent-image");
|
||||
multiDayImage.setAttribute("type", iconType);
|
||||
// class wrap causes allday items to wrap its text in today-pane
|
||||
let addWrap = document.getAnonymousElementByAttribute(this.mAllDayItem, "anonid", "eventbox");
|
||||
addWrap.classList.add("wrap");
|
||||
addWrap = document.getAnonymousElementByAttribute(this.mAllDayItem, "anonid", "event-detail-box");
|
||||
addWrap.classList.add("wrap");
|
||||
let eventBoxContainer = this.mAllDayItem.querySelector(".calendar-event-box-container");
|
||||
eventBoxContainer.classList.add("wrap");
|
||||
let eventDetailBox = this.mAllDayItem.querySelector("event-detail-box");
|
||||
if (eventDetailBox) {
|
||||
eventDetailBox.classList.add("wrap");
|
||||
}
|
||||
allDayDateLabel.value = date;
|
||||
}
|
||||
get occurrence() {
|
||||
|
|
|
@ -0,0 +1,424 @@
|
|||
/* 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/. */
|
||||
|
||||
/* global MozElements, MozXULElement, setBooleanAttribute, onMouseOverItem
|
||||
invokeEventDragSession, setElementValue */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Wrap in a block to prevent leaking to window scope.
|
||||
{
|
||||
var { cal } = ChromeUtils.import("resource://calendar/modules/calUtils.jsm");
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
/**
|
||||
* The MozCalendarEditableItem widget is used as a full day event item in the
|
||||
* Day and Week views of the calendar. It displays the event name, alarm icon
|
||||
* and the category type color. It gets displayed in the header container of
|
||||
* the respective view of the calendar.
|
||||
*
|
||||
* @extends MozXULElement
|
||||
*/
|
||||
class MozCalendarEditableItem extends MozXULElement {
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
".calendar-event-box-container": "readonly,flashing,alarm,allday,priority,progress,status,calendar,categories",
|
||||
".calendar-category-box": "categories",
|
||||
".alarm-icons-box": "flashing",
|
||||
".calendar-event-details > vbox": "context",
|
||||
};
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
|
||||
this.mOccurrence = null;
|
||||
|
||||
this.mSelected = false;
|
||||
|
||||
this.mCalendarView = null;
|
||||
|
||||
this.addEventListener("contextmenu", (event) => {
|
||||
// If the middle/right button was used for click just select the item.
|
||||
if (!this.selected) {
|
||||
this.select(event);
|
||||
}
|
||||
}, true);
|
||||
|
||||
this.addEventListener("click", (event) => {
|
||||
if (event.button != 0 || this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the left button was used and the item is already selected
|
||||
// and there are no multiple items selected start
|
||||
// the 'single click edit' timeout. Otherwise select the item too.
|
||||
// Also, check if the calendar is readOnly or we are offline.
|
||||
|
||||
if (this.selected && !(event.ctrlKey || event.metaKey) &&
|
||||
cal.acl.isCalendarWritable(this.mOccurrence.calendar)) {
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
}
|
||||
this.editingTimer = setTimeout(() => this.startEditing(), 350);
|
||||
} else {
|
||||
this.select(event);
|
||||
if (!this.closest("richlistitem")) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("dblclick", (event) => {
|
||||
if (event.button != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
// Stop 'single click edit' timeout (if started).
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
this.editingTimer = null;
|
||||
}
|
||||
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
let item = event.ctrlKey ? this.mOccurrence.parentItem : this.mOccurrence;
|
||||
this.calendarView.controller.modifyOccurrence(item);
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("mouseover", (event) => {
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
event.stopPropagation();
|
||||
onMouseOverItem(event);
|
||||
}
|
||||
});
|
||||
|
||||
// We have two event listeners for dragstart. This event listener is for the capturing phase.
|
||||
this.addEventListener("dragstart", (event) => {
|
||||
if (document.monthDragEvent.localName == "calendar-event-box") {
|
||||
return;
|
||||
}
|
||||
let item = this.occurrence;
|
||||
let isInvitation = item.calendar instanceof Ci.calISchedulingSupport && item.calendar.isInvitation(item);
|
||||
if (!cal.acl.isCalendarWritable(item.calendar) || !cal.acl.userCanModifyItem(item) || isInvitation) {
|
||||
return;
|
||||
}
|
||||
if (!this.selected) {
|
||||
this.select(event);
|
||||
}
|
||||
invokeEventDragSession(item, this);
|
||||
});
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.delayConnectedCallback() || this.hasChildNodes()) {
|
||||
return;
|
||||
}
|
||||
this.appendChild(MozXULElement.parseXULToFragment(`
|
||||
<vbox flex="1">
|
||||
<hbox>
|
||||
<box class="calendar-color-box"
|
||||
flex="1">
|
||||
<box class="calendar-event-selection"
|
||||
orient="horizontal"
|
||||
flex="1">
|
||||
<stack class="calendar-event-box-container"
|
||||
flex="1">
|
||||
<hbox class="calendar-event-details">
|
||||
<vbox align="left"
|
||||
flex="1">
|
||||
<label class="event-name-label"
|
||||
crop="end"
|
||||
style="margin: 0;">
|
||||
</label>
|
||||
<textbox class="calendar-event-details-core title-desc"
|
||||
hidden="true"
|
||||
style="background: transparent !important;"
|
||||
wrap="true">
|
||||
</textbox>
|
||||
<label crop="end"
|
||||
class="calendar-event-details-core location-desc">
|
||||
</label>
|
||||
<spacer flex="1">
|
||||
</spacer>
|
||||
</vbox>
|
||||
<stack>
|
||||
<hbox class="calendar-category-box category-color-box calendar-event-selection"
|
||||
flex="1" pack="end">
|
||||
<image class="calendar-category-box-gradient">
|
||||
</image>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<hbox class="alarm-icons-box"
|
||||
align="center">
|
||||
</hbox>
|
||||
<image class="item-classification-box"
|
||||
pack="end">
|
||||
</image>
|
||||
</hbox>
|
||||
</stack>
|
||||
</hbox>
|
||||
</stack>
|
||||
</box>
|
||||
</box>
|
||||
</hbox>
|
||||
</vbox>
|
||||
`));
|
||||
|
||||
// We have two event listeners for dragstart. This event listener is for the bubbling phase
|
||||
// where we are setting up the document.monthDragEvent which will be used in the event listener
|
||||
// in the capturing phase.
|
||||
this.addEventListener("dragstart", (event) => {
|
||||
document.monthDragEvent = this;
|
||||
}, true);
|
||||
|
||||
this.setAttribute("mousethrough", "never");
|
||||
this.setAttribute("tooltip", "itemTooltip");
|
||||
this.setAttribute("tabindex", "-1");
|
||||
this.addEventNameTextboxListener();
|
||||
this.initializeAttributeInheritance();
|
||||
}
|
||||
|
||||
set parentBox(val) {
|
||||
this.mParentBox = val;
|
||||
}
|
||||
|
||||
get parentBox() {
|
||||
return this.mParentBox;
|
||||
}
|
||||
|
||||
set selected(val) {
|
||||
if (val && !this.mSelected) {
|
||||
this.mSelected = true;
|
||||
this.setAttribute("selected", "true");
|
||||
} else if (!val && this.mSelected) {
|
||||
this.mSelected = false;
|
||||
this.removeAttribute("selected");
|
||||
}
|
||||
return val;
|
||||
}
|
||||
|
||||
get selected() {
|
||||
return this.mSelected;
|
||||
}
|
||||
|
||||
set calendarView(val) {
|
||||
this.mCalendarView = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
get calendarView() {
|
||||
return this.mCalendarView;
|
||||
}
|
||||
|
||||
set occurrence(val) {
|
||||
this.mOccurrence = val;
|
||||
this.setEditableLabel();
|
||||
this.setLocationLabel();
|
||||
this.setCSSClasses();
|
||||
return val;
|
||||
}
|
||||
|
||||
get occurrence() {
|
||||
return this.mOccurrence;
|
||||
}
|
||||
|
||||
get eventNameLabel() {
|
||||
return this.querySelector(".event-name-label");
|
||||
}
|
||||
|
||||
get eventNameTextbox() {
|
||||
return this.querySelector(".title-desc");
|
||||
}
|
||||
|
||||
addEventNameTextboxListener() {
|
||||
let stopPropagationIfEditing = (event) => {
|
||||
if (this.mEditing) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
// While editing, single click positions cursor, so don't propagate.
|
||||
this.eventNameTextbox.onclick = stopPropagationIfEditing;
|
||||
// While editing, double click selects words, so don't propagate.
|
||||
this.eventNameTextbox.ondblclick = stopPropagationIfEditing;
|
||||
// While editing, don't propagate mousedown/up (selects calEvent).
|
||||
this.eventNameTextbox.onmousedown = stopPropagationIfEditing;
|
||||
this.eventNameTextbox.onmouseup = stopPropagationIfEditing;
|
||||
this.eventNameTextbox.onblur = () => {
|
||||
this.stopEditing(true);
|
||||
};
|
||||
this.eventNameTextbox.onkeypress = (event) => {
|
||||
if (event.key == "Enter") { // Save on enter.
|
||||
this.stopEditing(true);
|
||||
} else if (event.key == "Escape") { // Abort on escape.
|
||||
this.stopEditing(false);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
setEditableLabel() {
|
||||
let label = this.eventNameLabel;
|
||||
let item = this.mOccurrence;
|
||||
label.value = item.title ? item.title.replace(/\n/g, " ")
|
||||
: cal.l10n.getCalString("eventUntitled");
|
||||
}
|
||||
|
||||
setLocationLabel() {
|
||||
let locationLabel = this.querySelector(".location-desc");
|
||||
let location = this.mOccurrence.getProperty("LOCATION");
|
||||
let showLocation = Services.prefs.getBoolPref("calendar.view.showLocation", false);
|
||||
|
||||
locationLabel.value = (showLocation && location) ? location : "";
|
||||
setBooleanAttribute(locationLabel, "hidden", !showLocation || !location);
|
||||
}
|
||||
|
||||
setCSSClasses() {
|
||||
let item = this.mOccurrence;
|
||||
let cssSafeId = cal.view.formatStringForCSSRule(item.calendar.id);
|
||||
this.style.setProperty("--item-backcolor", `var(--calendar-${cssSafeId}-backcolor)`);
|
||||
this.style.setProperty("--item-forecolor", `var(--calendar-${cssSafeId}-forecolor)`);
|
||||
let categoriesArray = item.getCategories({});
|
||||
if (categoriesArray.length > 0) {
|
||||
let cssClassesArray = categoriesArray.map(cal.view.formatStringForCSSRule);
|
||||
this.setAttribute("categories", cssClassesArray.join(" "));
|
||||
let categoriesBox = this.querySelector(".calendar-category-box");
|
||||
categoriesBox.style.backgroundColor = `var(--category-${cssClassesArray[0]}-color)`;
|
||||
}
|
||||
|
||||
// Add alarm icons as needed.
|
||||
let alarms = item.getAlarms({});
|
||||
if (alarms.length && Services.prefs.getBoolPref("calendar.alarms.indicator.show", true)) {
|
||||
let iconsBox = this.querySelector(".alarm-icons-box");
|
||||
cal.alarms.addReminderImages(iconsBox, alarms);
|
||||
|
||||
// Set suppressed status on the icons box.
|
||||
setElementValue(iconsBox,
|
||||
item.calendar.getProperty("suppressAlarms") || false,
|
||||
"suppressed");
|
||||
}
|
||||
|
||||
// Item classification / privacy.
|
||||
let classificationBox = this.querySelector(".item-classification-box");
|
||||
if (classificationBox) {
|
||||
classificationBox.setAttribute("classification", item.privacy || "PUBLIC");
|
||||
}
|
||||
|
||||
// Set up event box attributes for use in css selectors. Note if
|
||||
// something is added here, it should also be inherited correctly
|
||||
// in the <content> section of this custom element, and all that inherit it.
|
||||
|
||||
// Event type specific properties.
|
||||
if (cal.item.isEvent(item)) {
|
||||
if (item.startDate.isDate) {
|
||||
this.setAttribute("allday", "true");
|
||||
}
|
||||
this.setAttribute("itemType", "event");
|
||||
} else if (cal.item.isToDo(item)) {
|
||||
// Progress attribute.
|
||||
this.setAttribute("progress", cal.item.getProgressAtom(item));
|
||||
// Attribute for tasks and tasks image.
|
||||
this.setAttribute("itemType", "todo");
|
||||
if (item.entryDate && !item.dueDate) {
|
||||
this.setAttribute("todoType", "start");
|
||||
} else if (!item.entryDate && item.dueDate) {
|
||||
this.setAttribute("todoType", "end");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.calendarView &&
|
||||
item.hashId in this.calendarView.mFlashingEvents) {
|
||||
this.setAttribute("flashing", "true");
|
||||
}
|
||||
|
||||
if (alarms.length) {
|
||||
this.setAttribute("alarm", "true");
|
||||
}
|
||||
|
||||
// Priority.
|
||||
if (item.priority > 0 && item.priority < 5) {
|
||||
this.setAttribute("priority", "high");
|
||||
} else if (item.priority > 5 && item.priority < 10) {
|
||||
this.setAttribute("priority", "low");
|
||||
}
|
||||
|
||||
// Status attribute.
|
||||
if (item.status) {
|
||||
this.setAttribute("status", item.status.toUpperCase());
|
||||
}
|
||||
|
||||
// Item class.
|
||||
if (item.hasProperty("CLASS")) {
|
||||
this.setAttribute("itemclass", item.getProperty("CLASS"));
|
||||
}
|
||||
|
||||
// Calendar name.
|
||||
this.setAttribute("calendar", item.calendar.name.toLowerCase());
|
||||
|
||||
// Invitation.
|
||||
if (cal.itip.isInvitation(item)) {
|
||||
this.setAttribute("invitation-status", cal.itip.getInvitedAttendee(item).participationStatus);
|
||||
this.setAttribute("readonly", "true");
|
||||
} else if (!cal.acl.isCalendarWritable(item.calendar)) {
|
||||
this.setAttribute("readonly", "true");
|
||||
}
|
||||
}
|
||||
|
||||
startEditing() {
|
||||
this.editingTimer = null;
|
||||
this.mOriginalTextLabel = this.mOccurrence.title;
|
||||
|
||||
this.eventNameLabel.setAttribute("hidden", "true");
|
||||
|
||||
this.mEditing = true;
|
||||
|
||||
this.eventNameTextbox.value = this.mOriginalTextLabel;
|
||||
this.eventNameTextbox.removeAttribute("hidden");
|
||||
this.eventNameTextbox.select();
|
||||
}
|
||||
|
||||
select(event) {
|
||||
if (!this.calendarView) {
|
||||
return;
|
||||
}
|
||||
let items = this.calendarView.mSelectedItems.slice();
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (this.selected) {
|
||||
let pos = items.indexOf(this.mOccurrence);
|
||||
items.splice(pos, 1);
|
||||
} else {
|
||||
items.push(this.mOccurrence);
|
||||
}
|
||||
} else {
|
||||
items = [this.mOccurrence];
|
||||
}
|
||||
this.calendarView.setSelectedItems(items.length, items);
|
||||
}
|
||||
|
||||
stopEditing(saveChanges) {
|
||||
if (!this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.mEditing = false;
|
||||
|
||||
if (saveChanges && (this.eventNameTextbox.value != this.mOriginalTextLabel)) {
|
||||
this.calendarView.controller.modifyOccurrence(this.mOccurrence,
|
||||
null, null,
|
||||
this.eventNameTextbox.value);
|
||||
|
||||
// Note that as soon as we do the modifyItem, this element ceases to exist,
|
||||
// so don't bother trying to modify anything further here! ('this' exists,
|
||||
// because it's being kept alive, but our child content etc. is all gone).
|
||||
return;
|
||||
}
|
||||
|
||||
this.eventNameTextbox.setAttribute("hidden", "true");
|
||||
this.eventNameLabel.removeAttribute("hidden");
|
||||
}
|
||||
}
|
||||
|
||||
MozElements.MozCalendarEditableItem = MozCalendarEditableItem;
|
||||
|
||||
customElements.define("calendar-editable-item", MozCalendarEditableItem);
|
||||
}
|
|
@ -56,7 +56,7 @@
|
|||
});
|
||||
|
||||
this.addEventListener("click", (event) => {
|
||||
if (event.button != 0 || event.button != 2) {
|
||||
if (event.button != 0 && event.button != 2) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -622,7 +622,6 @@
|
|||
chunkBox.setAttribute("context",
|
||||
this.getAttribute("item-context") ||
|
||||
this.getAttribute("context"));
|
||||
chunkBox.setAttribute("orient", orient);
|
||||
|
||||
// Set the gripBars visibility in the chunk. Keep it
|
||||
// hidden for tasks with only entry date OR due date.
|
||||
|
@ -642,6 +641,7 @@
|
|||
}
|
||||
|
||||
innerColumn.appendChild(chunkBox);
|
||||
chunkBox.setAttribute("orient", orient);
|
||||
chunkBox.calendarView = this.calendarView;
|
||||
chunkBox.occurrence = chunk.event;
|
||||
chunkBox.parentColumn = this;
|
||||
|
@ -1208,7 +1208,7 @@
|
|||
// rotated), calculate the difference and start accelerating the
|
||||
// scrollbar.
|
||||
let diffStart, diffEnd;
|
||||
let orient = event.target.getAttribute("orient");
|
||||
let orient = document.calendarEventColumnDragging.getAttribute("orient");
|
||||
let scrollbox = currentView().scrollbox;
|
||||
let boundingRect = scrollbox.getBoundingClientRect();
|
||||
if (orient == "vertical") {
|
||||
|
@ -1262,7 +1262,7 @@
|
|||
// If we leave the view, then stop our internal sweeping and start a
|
||||
// real drag session. Someday we need to fix the sweep to soely be a
|
||||
// drag session, no sweeping.
|
||||
let boundingRect = event.target.getBoundingClientRect();
|
||||
let boundingRect = currentView().scrollbox.getBoundingClientRect();
|
||||
if (event.clientX < (boundingRect.x) ||
|
||||
event.clientX > (boundingRect.x + boundingRect.width) ||
|
||||
event.clientY < (boundingRect.y) ||
|
||||
|
@ -1279,7 +1279,7 @@
|
|||
document.calendarEventColumnDragging = null;
|
||||
col.mDragState = null;
|
||||
|
||||
var item = dragState.dragOccurrence;
|
||||
let item = dragState.dragOccurrence;
|
||||
|
||||
// The multiday view currently exhibits a less than optimal strategy
|
||||
// in terms of item selection. items don't get automatically selected
|
||||
|
@ -1456,8 +1456,6 @@
|
|||
window.removeEventListener("mouseup", col.onEventSweepMouseUp);
|
||||
window.removeEventListener("keypress", col.onEventSweepKeypress);
|
||||
|
||||
document.calendarEventColumnDragging = null;
|
||||
|
||||
// If the user didn't sweep out at least a few pixels, ignore
|
||||
// unless we're in a different column.
|
||||
if (dragState.origColumn == col) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 currentView MozElements MozXULElement */
|
||||
/* globals currentView MozElements MozXULElement onMouseOverItem invokeEventDragSession */
|
||||
|
||||
/* import-globals-from calendar-ui-utils.js */
|
||||
|
||||
|
@ -256,4 +256,140 @@
|
|||
}
|
||||
}
|
||||
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.
|
||||
*
|
||||
* @extends {MozElements.MozCalendarEditableItem}
|
||||
*/
|
||||
class MozCalendarMonthDayBoxItem extends MozElements.MozCalendarEditableItem {
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
".calendar-event-box-container": "readonly,flashing,alarm,allday,priority,progress,status,calendar,categories",
|
||||
".calendar-item-image": "progress,allday,itemType,todoType",
|
||||
".calendar-month-day-box-item-label": "context",
|
||||
".event-name-label-container": "context",
|
||||
".alarm-icons-box": "flashing",
|
||||
".calendar-category-box": "categories",
|
||||
};
|
||||
}
|
||||
connectedCallback() {
|
||||
if (this.delayConnectedCallback() || this.hasChildNodes()) {
|
||||
return;
|
||||
}
|
||||
this.appendChild(MozXULElement.parseXULToFragment(`
|
||||
<vbox flex="1">
|
||||
<hbox>
|
||||
<box class="calendar-color-box"
|
||||
flex="1">
|
||||
<box class="calendar-event-selection"
|
||||
orient="horizontal"
|
||||
flex="1">
|
||||
<stack class="calendar-event-box-container"
|
||||
flex="1">
|
||||
<hbox class="calendar-event-details">
|
||||
<vbox pack="center">
|
||||
<image class="calendar-item-image"></image>
|
||||
</vbox>
|
||||
<label class="calendar-month-day-box-item-label"></label>
|
||||
<vbox class="event-name-label-container"
|
||||
align="left" flex="1">
|
||||
<label class="event-name-label"
|
||||
crop="end"
|
||||
flex="1"
|
||||
style="margin: 0;">
|
||||
</label>
|
||||
<textbox class="plain calendar-event-name-textbox title-desc"
|
||||
crop="end"
|
||||
hidden="true"
|
||||
wrap="true">
|
||||
</textbox>
|
||||
<spacer flex="1"></spacer>
|
||||
</vbox>
|
||||
<stack class="category-box-stack">
|
||||
<hbox class="calendar-category-box category-color-box calendar-event-selection"
|
||||
flex="1"
|
||||
pack="end">
|
||||
<image class="calendar-category-box-gradient"></image>
|
||||
</hbox>
|
||||
<hbox align="center">
|
||||
<hbox class="alarm-icons-box"
|
||||
pack="end"
|
||||
align="top">
|
||||
</hbox>
|
||||
<image class="item-classification-box"
|
||||
pack="end">
|
||||
</image>
|
||||
</hbox>
|
||||
</stack>
|
||||
</hbox>
|
||||
</stack>
|
||||
</box>
|
||||
</box>
|
||||
</hbox>
|
||||
</vbox>
|
||||
`));
|
||||
|
||||
// We have two event listeners for dragstart. This event listener is for the bubbling phase
|
||||
// where we are setting up the document.monthDragEvent which will be used in the event listener
|
||||
// in the capturing phase which is set up in the calendar-editable-item.
|
||||
this.addEventListener("dragstart", (event) => {
|
||||
document.monthDragEvent = this;
|
||||
}, true);
|
||||
|
||||
this.setAttribute("mousethrough", "never");
|
||||
this.setAttribute("tooltip", "itemTooltip");
|
||||
this.addEventNameTextboxListener();
|
||||
this.initializeAttributeInheritance();
|
||||
}
|
||||
|
||||
set occurrence(val) {
|
||||
cal.ASSERT(!this.mOccurrence, "Code changes needed to set the occurrence twice", true);
|
||||
this.mOccurrence = val;
|
||||
if (cal.item.isEvent(val) && !val.startDate.isDate) {
|
||||
let icon = this.querySelector(".calendar-item-image");
|
||||
let label = this.querySelector(".calendar-month-day-box-item-label");
|
||||
let formatter = Cc["@mozilla.org/calendar/datetime-formatter;1"]
|
||||
.getService(Ci.calIDateTimeFormatter);
|
||||
let timezone = this.calendarView ? this.calendarView.mTimezone
|
||||
: cal.dtz.defaultTimezone;
|
||||
let parentDate = this.parentBox.date;
|
||||
let parentTime = cal.createDateTime();
|
||||
parentTime.resetTo(parentDate.year, parentDate.month, parentDate.day, 0, 0, 0, timezone);
|
||||
let startTime = val.startDate.getInTimezone(timezone);
|
||||
let endTime = val.endDate.getInTimezone(timezone);
|
||||
let nextDay = parentTime.clone();
|
||||
nextDay.day++;
|
||||
let comp = endTime.compare(nextDay);
|
||||
if (startTime.compare(parentTime) == -1) {
|
||||
if (comp == 1) {
|
||||
icon.setAttribute("type", "continue");
|
||||
} else if (comp == 0) {
|
||||
icon.setAttribute("type", "start");
|
||||
} else {
|
||||
icon.setAttribute("type", "end");
|
||||
label.value = formatter.formatTime(endTime);
|
||||
}
|
||||
} else if (comp == 1) {
|
||||
icon.setAttribute("type", "start");
|
||||
label.value = formatter.formatTime(startTime);
|
||||
} else {
|
||||
label.value = formatter.formatTime(startTime);
|
||||
}
|
||||
label.setAttribute("time", "true");
|
||||
}
|
||||
|
||||
this.setEditableLabel();
|
||||
this.setCSSClasses();
|
||||
return val;
|
||||
}
|
||||
|
||||
get occurrence() {
|
||||
return this.mOccurrence;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("calendar-month-day-box-item", MozCalendarMonthDayBoxItem);
|
||||
}
|
||||
|
|
|
@ -1,128 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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-globals-from calendar-views-utils.js -->
|
||||
|
||||
<!DOCTYPE bindings SYSTEM "chrome://global/locale/global.dtd" >
|
||||
|
||||
<bindings id="calendar-month-view-bindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="calendar-month-day-box-item" extends="chrome://calendar/content/calendar-view-core.xml#calendar-editable-item">
|
||||
<content mousethrough="never" tooltip="itemTooltip">
|
||||
<xul:vbox flex="1">
|
||||
<xul:hbox>
|
||||
<xul:box anonid="event-container"
|
||||
class="calendar-color-box"
|
||||
flex="1">
|
||||
<xul:box class="calendar-event-selection" orient="horizontal" flex="1">
|
||||
<xul:stack anonid="eventbox"
|
||||
class="calendar-event-box-container"
|
||||
xbl:inherits="readonly,flashing,alarm,allday,priority,progress,status,calendar,categories"
|
||||
flex="1">
|
||||
<xul:hbox anonid="event-detail-box"
|
||||
class="calendar-event-details">
|
||||
<xul:vbox pack="center">
|
||||
<xul:image anonid="item-icon"
|
||||
class="calendar-item-image"
|
||||
xbl:inherits="progress,allday,itemType,todoType"/>
|
||||
</xul:vbox>
|
||||
<xul:label anonid="item-label"
|
||||
class="calendar-month-day-box-item-label"
|
||||
xbl:inherits="context"/>
|
||||
<xul:vbox align="left"
|
||||
flex="1"
|
||||
xbl:inherits="context">
|
||||
<xul:label anonid="event-name"
|
||||
crop="end"
|
||||
flex="1"
|
||||
style="margin: 0;"/>
|
||||
<xul:textbox anonid="event-name-textbox"
|
||||
class="plain calendar-event-name-textbox"
|
||||
crop="end"
|
||||
hidden="true"
|
||||
wrap="true"/>
|
||||
<xul:spacer flex="1"/>
|
||||
</xul:vbox>
|
||||
<xul:stack anonid="category-box-stack">
|
||||
<xul:hbox anonid="category-box"
|
||||
class="calendar-category-box category-color-box calendar-event-selection"
|
||||
xbl:inherits="categories"
|
||||
flex="1"
|
||||
pack="end">
|
||||
<xul:image class="calendar-category-box-gradient"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:hbox anonid="alarm-icons-box"
|
||||
class="alarm-icons-box"
|
||||
pack="end"
|
||||
align="top"
|
||||
xbl:inherits="flashing"/>
|
||||
<xul:image anonid="item-classification-box"
|
||||
class="item-classification-box"
|
||||
pack="end"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</xul:box>
|
||||
</xul:box>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
<implementation>
|
||||
<property name="occurrence">
|
||||
<getter><![CDATA[
|
||||
return this.mOccurrence;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
cal.ASSERT(!this.mOccurrence, "Code changes needed to set the occurrence twice", true);
|
||||
this.mOccurrence = val;
|
||||
if (cal.item.isEvent(val)) {
|
||||
if (!val.startDate.isDate) {
|
||||
let icon = document.getAnonymousElementByAttribute(this, "anonid", "item-icon");
|
||||
let label = document.getAnonymousElementByAttribute(this, "anonid", "item-label");
|
||||
let formatter = Cc["@mozilla.org/calendar/datetime-formatter;1"]
|
||||
.getService(Ci.calIDateTimeFormatter);
|
||||
let timezone = this.calendarView ? this.calendarView.mTimezone
|
||||
: cal.dtz.defaultTimezone;
|
||||
let parentDate = this.parentBox.date;
|
||||
let parentTime = cal.createDateTime();
|
||||
parentTime.resetTo(parentDate.year, parentDate.month, parentDate.day, 0, 0, 0, timezone);
|
||||
let startTime = val.startDate.getInTimezone(timezone);
|
||||
let endTime = val.endDate.getInTimezone(timezone);
|
||||
let nextDay = parentTime.clone();
|
||||
nextDay.day++;
|
||||
let comp = endTime.compare(nextDay);
|
||||
if (startTime.compare(parentTime) == -1) {
|
||||
if (comp == 1) {
|
||||
icon.setAttribute("type", "continue");
|
||||
} else if (comp == 0) {
|
||||
icon.setAttribute("type", "start");
|
||||
} else {
|
||||
icon.setAttribute("type", "end");
|
||||
label.value = formatter.formatTime(endTime);
|
||||
}
|
||||
} else if (comp == 1) {
|
||||
icon.setAttribute("type", "start");
|
||||
label.value = formatter.formatTime(startTime);
|
||||
} else {
|
||||
label.value = formatter.formatTime(startTime);
|
||||
}
|
||||
label.setAttribute("time", "true");
|
||||
}
|
||||
}
|
||||
|
||||
this.setEditableLabel();
|
||||
this.setCSSClasses();
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
</implementation>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -872,14 +872,15 @@
|
|||
for (const item of this.mSelectedItems) {
|
||||
for (const occ of this.getItemOccurrencesInView(item)) {
|
||||
const cols = this.findColumnsForItem(occ);
|
||||
if (cols.length > 0) {
|
||||
const start = item.startDate || item.entryDate || item.dueDate;
|
||||
for (const col of cols) {
|
||||
if (start.isDate) {
|
||||
col.header.selectOccurrence(occ);
|
||||
} else {
|
||||
col.column.selectOccurrence(occ);
|
||||
}
|
||||
if (cols.length == 0) {
|
||||
continue;
|
||||
}
|
||||
const start = item.startDate || item.entryDate || item.dueDate;
|
||||
for (const col of cols) {
|
||||
if (start.isDate) {
|
||||
col.header.selectOccurrence(occ);
|
||||
} else {
|
||||
col.column.selectOccurrence(occ);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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 currentView MozElements MozXULElement */
|
||||
/* globals currentView, MozElements, MozXULElement, onMouseOverItem */
|
||||
|
||||
/* import-globals-from calendar-ui-utils.js */
|
||||
|
||||
|
@ -152,4 +152,247 @@
|
|||
}
|
||||
}
|
||||
customElements.define("calendar-header-container", CalendarHeaderContainer);
|
||||
|
||||
/**
|
||||
* The MozCalendarMonthDayBoxItem widget is used as event item in the
|
||||
* Day and Week views of the calendar. It displays the event name,
|
||||
* alarm icon and the category type color. It also displays the gripbar
|
||||
* components on hovering over the event. It is used to change the event
|
||||
* timings.
|
||||
*
|
||||
* @extends {MozElements.MozCalendarEditableItem}
|
||||
*/
|
||||
class MozCalendarEventBox extends MozElements.MozCalendarEditableItem {
|
||||
static get inheritedAttributes() {
|
||||
return {
|
||||
".calendar-color-box": "orient,readonly,flashing,alarm,allday,priority,progress,status,calendar,categories,todoType",
|
||||
".calendar-event-box": "orient,width,height",
|
||||
".calendar-event-box-container": "context,parentorient=orient,readonly,flashing,alarm,allday,priority,progress,status,calendar,categories",
|
||||
".calendar-item-image": "progress,allday,itemType,todoType",
|
||||
".alarm-icons-box": "flashing",
|
||||
".category-color-box": "categories",
|
||||
".calendar-event-box-grippy-top": "parentorient=orient",
|
||||
".calendar-event-box-grippy-bottom": "parentorient=orient",
|
||||
".calendar-event-gripbar-container": "orient",
|
||||
};
|
||||
}
|
||||
constructor() {
|
||||
super();
|
||||
this.mParentColumn = null;
|
||||
this.addEventListener("mousedown", (event) => {
|
||||
if (event.button != 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
event.stopPropagation();
|
||||
|
||||
if (this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parentColumn.calendarView.selectedDay = this.parentColumn.mDate;
|
||||
this.mMouseX = event.screenX;
|
||||
this.mMouseY = event.screenY;
|
||||
|
||||
let whichside = event.whichside;
|
||||
if (whichside) {
|
||||
this.calendarView.setSelectedItems(1, [event.ctrlKey ? this.mOccurrence.parentItem : this.mOccurrence]);
|
||||
|
||||
let snapIntMin = (event.shiftKey &&
|
||||
!event.ctrlKey &&
|
||||
!event.altKey &&
|
||||
!event.metaKey) ? 1 : 15;
|
||||
// Start edge resize drag
|
||||
this.parentColumn.startSweepingToModifyEvent(this, this.mOccurrence, whichside,
|
||||
event.screenX, event.screenY,
|
||||
snapIntMin);
|
||||
} else {
|
||||
// May be click or drag,
|
||||
// So wait for mousemove (or mouseout if fast) to start item move drag.
|
||||
this.mInMouseDown = true;
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("mousemove", (event) => {
|
||||
if (!this.mInMouseDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
let deltaX = Math.abs(event.screenX - this.mMouseX);
|
||||
let deltaY = Math.abs(event.screenY - this.mMouseY);
|
||||
// More than a 3 pixel move?
|
||||
const movedMoreThan3Pixels = (deltaX * deltaX + deltaY * deltaY) > 9;
|
||||
if (movedMoreThan3Pixels && this.parentColumn) {
|
||||
this.startItemDrag();
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("mouseout", (event) => {
|
||||
if (!this.mEditing && this.mInMouseDown && this.parentColumn) {
|
||||
this.startItemDrag();
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("mouseup", (event) => {
|
||||
if (!this.mEditing) {
|
||||
this.mInMouseDown = false;
|
||||
}
|
||||
});
|
||||
|
||||
this.addEventListener("mouseover", (event) => {
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
event.stopPropagation();
|
||||
onMouseOverItem(event);
|
||||
}
|
||||
});
|
||||
|
||||
// We have two event listeners for dragstart. This event listener is for the bubbling phase
|
||||
// where we are setting up the document.monthDragEvent which will be used in the event listener
|
||||
// in the capturing phase which is set up in the calendar-editable-item.
|
||||
this.addEventListener("dragstart", (event) => {
|
||||
document.monthDragEvent = this;
|
||||
}, true);
|
||||
}
|
||||
|
||||
connectedCallback() {
|
||||
if (this.delayConnectedCallback() || this.hasChildNodes()) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.appendChild(MozXULElement.parseXULToFragment(`
|
||||
<box class="calendar-event-box"
|
||||
flex="1">
|
||||
<box class="calendar-color-box"
|
||||
flex="1">
|
||||
<box class="calendar-event-selection"
|
||||
orient="horizontal"
|
||||
flex="1">
|
||||
<stack class="calendar-event-box-container"
|
||||
flex="1">
|
||||
<hbox class="calendar-event-details"
|
||||
align="start">
|
||||
<image class="calendar-item-image">
|
||||
</image>
|
||||
<vbox flex="1">
|
||||
<label class="calendar-event-details-core event-name-label"
|
||||
crop="end">
|
||||
</label>
|
||||
<textbox class="plain calendar-event-details-core calendar-event-name-textbox title-desc"
|
||||
hidden="true"
|
||||
wrap="true">
|
||||
</textbox>
|
||||
<label class="calendar-event-details-core location-desc"
|
||||
crop="end">
|
||||
</label>
|
||||
</vbox>
|
||||
<hbox class="alarm-icons-box"
|
||||
align="top">
|
||||
</hbox>
|
||||
<image class="item-classification-box">
|
||||
</image>
|
||||
</hbox>
|
||||
<stack mousethrough="always"
|
||||
class="calendar-category-box-stack">
|
||||
<hbox class="calendar-category-box category-color-box calendar-event-selection"
|
||||
flex="1"
|
||||
pack="end">
|
||||
<image class="calendar-category-box-gradient">
|
||||
</image>
|
||||
</hbox>
|
||||
</stack>
|
||||
<box class="calendar-event-gripbar-container">
|
||||
<calendar-event-gripbar class="calendar-event-box-grippy-top"
|
||||
mousethrough="never"
|
||||
whichside="start">
|
||||
</calendar-event-gripbar>
|
||||
<spacer mousethrough="always"
|
||||
flex="1">
|
||||
</spacer>
|
||||
<calendar-event-gripbar class="calendar-event-box-grippy-bottom"
|
||||
mousethrough="never"
|
||||
whichside="end">
|
||||
</calendar-event-gripbar>
|
||||
</box>
|
||||
</stack>
|
||||
</box>
|
||||
</box>
|
||||
</box>
|
||||
`));
|
||||
|
||||
this.setAttribute("mousethrough", "never");
|
||||
this.setAttribute("tooltip", "itemTooltip");
|
||||
|
||||
this.orient = this.getAttribute("orient");
|
||||
this.addEventNameTextboxListener();
|
||||
this.initializeAttributeInheritance();
|
||||
}
|
||||
|
||||
set parentColumn(val) {
|
||||
this.mParentColumn = val;
|
||||
return val;
|
||||
}
|
||||
|
||||
get parentColumn() {
|
||||
return this.mParentColumn;
|
||||
}
|
||||
|
||||
get startMinute() {
|
||||
if (!this.mOccurrence) {
|
||||
return 0;
|
||||
}
|
||||
let startDate = this.mOccurrence.startDate || this.mOccurrence.entryDate;
|
||||
return startDate.hour * 60 + startDate.minute;
|
||||
}
|
||||
|
||||
get endMinute() {
|
||||
if (!this.mOccurrence) {
|
||||
return 0;
|
||||
}
|
||||
let endDate = this.mOccurrence.endDate || this.mOccurrence.dueDate;
|
||||
return endDate.hour * 60 + endDate.minute;
|
||||
}
|
||||
|
||||
getOptimalMinSize() {
|
||||
if (this.getAttribute("orient") == "vertical") {
|
||||
let minHeight = getOptimalMinimumHeight(this.eventNameLabel) +
|
||||
getSummarizedStyleValues(this.querySelector(".calendar-event-box-container"), ["margin-bottom", "margin-top"]) +
|
||||
getSummarizedStyleValues(this, ["border-bottom-width", "border-top-width"]);
|
||||
this.setAttribute("minheight", minHeight);
|
||||
this.setAttribute("minwidth", "1");
|
||||
return minHeight;
|
||||
}
|
||||
this.eventNameLabel.setAttribute("style", "min-width: 2em");
|
||||
let minWidth = getOptimalMinimumWidth(this.eventNameLabel);
|
||||
this.setAttribute("minwidth", minWidth);
|
||||
this.setAttribute("minheight", "1");
|
||||
return minWidth;
|
||||
}
|
||||
|
||||
setEditableLabel() {
|
||||
let label = this.eventNameLabel;
|
||||
let item = this.mOccurrence;
|
||||
|
||||
label.textContent = item.title || cal.l10n.getCalString("eventUntitled");
|
||||
|
||||
let gripbar = this.querySelector(".calendar-event-box-grippy-top").getBoundingClientRect().height;
|
||||
let height = this.querySelector(".calendar-event-box-container").getBoundingClientRect().height;
|
||||
label.setAttribute("style", "max-height: " + Math.max(0, height - gripbar * 2) + "px");
|
||||
}
|
||||
|
||||
startItemDrag() {
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
this.editingTimer = null;
|
||||
}
|
||||
|
||||
this.calendarView.setSelectedItems(1, [this.mOccurrence]);
|
||||
|
||||
this.mEditing = false;
|
||||
|
||||
this.parentColumn.startSweepingToModifyEvent(this, this.mOccurrence, "middle", this.mMouseX, this.mMouseY);
|
||||
this.mInMouseDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("calendar-event-box", MozCalendarEventBox);
|
||||
}
|
||||
|
|
|
@ -1,274 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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-globals-from ../../resources/content/mouseoverPreviews.js -->
|
||||
<!-- import-globals-from calendar-dnd-listener.js -->
|
||||
<!-- import-globals-from calendar-ui-utils.js -->
|
||||
<!-- import-globals-from calendar-views-utils.js -->
|
||||
|
||||
<!DOCTYPE bindings SYSTEM "chrome://global/locale/global.dtd" >
|
||||
|
||||
<bindings id="calendar-multiday-view-bindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<!--
|
||||
- An individual event box, to be inserted into a column.
|
||||
-->
|
||||
<binding id="calendar-event-box" extends="chrome://calendar/content/calendar-view-core.xml#calendar-editable-item">
|
||||
<content mousethrough="never" tooltip="itemTooltip">
|
||||
<xul:box xbl:inherits="orient,width,height" flex="1">
|
||||
<xul:box anonid="event-container"
|
||||
class="calendar-color-box"
|
||||
xbl:inherits="orient,readonly,flashing,alarm,allday,priority,progress,
|
||||
status,calendar,categories,todoType"
|
||||
flex="1">
|
||||
<xul:box class="calendar-event-selection" orient="horizontal" flex="1">
|
||||
<xul:stack anonid="eventbox"
|
||||
class="calendar-event-box-container"
|
||||
flex="1"
|
||||
xbl:inherits="context,parentorient=orient,readonly,flashing,alarm,allday,priority,progress,status,calendar,categories">
|
||||
<xul:hbox class="calendar-event-details"
|
||||
anonid="calendar-event-details"
|
||||
align="start">
|
||||
<xul:image anonid="item-icon"
|
||||
class="calendar-item-image"
|
||||
xbl:inherits="progress,allday,itemType,todoType"/>
|
||||
<xul:vbox flex="1">
|
||||
<xul:label anonid="event-name" class="calendar-event-details-core title-desc" crop="end"/>
|
||||
<xul:textbox anonid="event-name-textbox"
|
||||
class="plain calendar-event-details-core calendar-event-name-textbox"
|
||||
hidden="true"
|
||||
wrap="true"/>
|
||||
<xul:label anonid="event-location" class="calendar-event-details-core location-desc" crop="end"/>
|
||||
</xul:vbox>
|
||||
<xul:hbox anonid="alarm-icons-box"
|
||||
class="alarm-icons-box"
|
||||
align="top"
|
||||
xbl:inherits="flashing"/>
|
||||
<xul:image anonid="item-classification-box"
|
||||
class="item-classification-box"/>
|
||||
</xul:hbox>
|
||||
<xul:stack mousethrough="always" class="calendar-category-box-stack">
|
||||
<xul:hbox anonid="category-box"
|
||||
class="calendar-category-box category-color-box calendar-event-selection"
|
||||
xbl:inherits="categories"
|
||||
flex="1"
|
||||
pack="end">
|
||||
<xul:image class="calendar-category-box-gradient"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
<xul:box xbl:inherits="orient">
|
||||
<xul:calendar-event-gripbar anonid="gripbar1"
|
||||
class="calendar-event-box-grippy-top"
|
||||
mousethrough="never"
|
||||
whichside="start"
|
||||
xbl:inherits="parentorient=orient"/>
|
||||
<xul:spacer mousethrough="always" flex="1"/>
|
||||
<xul:calendar-event-gripbar anonid="gripbar2"
|
||||
class="calendar-event-box-grippy-bottom"
|
||||
mousethrough="never"
|
||||
whichside="end"
|
||||
xbl:inherits="parentorient=orient"/>
|
||||
</xul:box>
|
||||
<!-- Do not insert anything here, otherwise the event boxes will
|
||||
not be resizable using the gripbars. If you want to insert
|
||||
additional elements, do so above the box with the gripbars. -->
|
||||
</xul:stack>
|
||||
</xul:box>
|
||||
</xul:box>
|
||||
</xul:box>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<constructor><![CDATA[
|
||||
this.orient = this.getAttribute("orient");
|
||||
]]></constructor>
|
||||
|
||||
<!-- fields -->
|
||||
<field name="mParentColumn">null</field>
|
||||
|
||||
<!-- methods/properties -->
|
||||
<method name="setAttribute">
|
||||
<parameter name="aAttr"/>
|
||||
<parameter name="aVal"/>
|
||||
<body><![CDATA[
|
||||
let needsrelayout = false;
|
||||
if (aAttr == "orient") {
|
||||
if (this.getAttribute("orient") != aVal) {
|
||||
needsrelayout = true;
|
||||
}
|
||||
}
|
||||
|
||||
// this should be done using lookupMethod(), see bug 286629
|
||||
let ret = XULElement.prototype.setAttribute.call(this, aAttr, aVal);
|
||||
|
||||
if (needsrelayout) {
|
||||
let eventbox = document.getAnonymousElementByAttribute(this, "anonid", "eventbox");
|
||||
eventbox.setAttribute("orient", aVal);
|
||||
let gb1 = document.getAnonymousElementByAttribute(this, "anonid", "gripbar1");
|
||||
gb1.parentorient = aVal;
|
||||
let gb2 = document.getAnonymousElementByAttribute(this, "anonid", "gripbar2");
|
||||
gb2.parentorient = aVal;
|
||||
}
|
||||
|
||||
return ret;
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="getOptimalMinSize">
|
||||
<body><![CDATA[
|
||||
if (this.getAttribute("orient") == "vertical") {
|
||||
let minHeight = getOptimalMinimumHeight(this.eventNameLabel) +
|
||||
getSummarizedStyleValues(document.getAnonymousElementByAttribute(this, "anonid", "eventbox"), ["margin-bottom", "margin-top"]) +
|
||||
getSummarizedStyleValues(this, ["border-bottom-width", "border-top-width"]);
|
||||
this.setAttribute("minheight", minHeight);
|
||||
this.setAttribute("minwidth", "1");
|
||||
return minHeight;
|
||||
} else {
|
||||
this.eventNameLabel.setAttribute("style", "min-width: 2em");
|
||||
let minWidth = getOptimalMinimumWidth(this.eventNameLabel);
|
||||
this.setAttribute("minwidth", minWidth);
|
||||
this.setAttribute("minheight", "1");
|
||||
return minWidth;
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<property name="parentColumn"
|
||||
onget="return this.mParentColumn;"
|
||||
onset="return (this.mParentColumn = val);"/>
|
||||
|
||||
<property name="startMinute" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (!this.mOccurrence) {
|
||||
return 0;
|
||||
}
|
||||
let startDate = this.mOccurrence.startDate || this.mOccurrence.entryDate;
|
||||
return startDate.hour * 60 + startDate.minute;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<property name="endMinute" readonly="true">
|
||||
<getter><![CDATA[
|
||||
if (!this.mOccurrence) {
|
||||
return 0;
|
||||
}
|
||||
let endDate = this.mOccurrence.endDate || this.mOccurrence.dueDate;
|
||||
return endDate.hour * 60 + endDate.minute;
|
||||
]]></getter>
|
||||
</property>
|
||||
|
||||
<method name="setEditableLabel">
|
||||
<body><![CDATA[
|
||||
let evl = this.eventNameLabel;
|
||||
let item = this.mOccurrence;
|
||||
|
||||
if (item.title && item.title != "") {
|
||||
// Use <description> textContent so it can wrap.
|
||||
evl.textContent = item.title;
|
||||
} else {
|
||||
evl.textContent = cal.l10n.getCalString("eventUntitled");
|
||||
}
|
||||
|
||||
let gripbar = document.getAnonymousElementByAttribute(this, "anonid", "gripbar1").getBoundingClientRect().height;
|
||||
let height = document.getAnonymousElementByAttribute(this, "anonid", "eventbox").getBoundingClientRect().height;
|
||||
evl.setAttribute("style", "max-height: " + Math.max(0, height-gripbar * 2) + "px");
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="mousedown" button="0"><![CDATA[
|
||||
event.stopPropagation();
|
||||
|
||||
if (this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.parentColumn.calendarView.selectedDay = this.parentColumn.mDate;
|
||||
this.mMouseX = event.screenX;
|
||||
this.mMouseY = event.screenY;
|
||||
|
||||
let whichside = event.whichside;
|
||||
if (whichside) {
|
||||
this.calendarView.setSelectedItems(1,
|
||||
[event.ctrlKey ? this.mOccurrence.parentItem : this.mOccurrence]);
|
||||
|
||||
let snapIntMin = (event.shiftKey &&
|
||||
!event.ctrlKey &&
|
||||
!event.altKey &&
|
||||
!event.metaKey) ? 1 : 15;
|
||||
// start edge resize drag
|
||||
this.parentColumn.startSweepingToModifyEvent(this, this.mOccurrence, whichside,
|
||||
event.screenX, event.screenY,
|
||||
snapIntMin);
|
||||
} else {
|
||||
// may be click or drag,
|
||||
// so wait for mousemove (or mouseout if fast) to start item move drag
|
||||
this.mInMouseDown = true;
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="mousemove"><![CDATA[
|
||||
if (!this.mInMouseDown) {
|
||||
return;
|
||||
}
|
||||
|
||||
let deltaX = Math.abs(event.screenX - this.mMouseX);
|
||||
let deltaY = Math.abs(event.screenY - this.mMouseY);
|
||||
// more than a 3 pixel move?
|
||||
if ((deltaX * deltaX + deltaY * deltaY) > 9) {
|
||||
if (this.parentColumn) {
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
this.editingTimer = null;
|
||||
}
|
||||
|
||||
this.calendarView.setSelectedItems(1, [this.mOccurrence]);
|
||||
|
||||
this.mEditing = false;
|
||||
|
||||
this.parentColumn.startSweepingToModifyEvent(this, this.mOccurrence, "middle", this.mMouseX, this.mMouseY);
|
||||
this.mInMouseDown = false;
|
||||
}
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="mouseout"><![CDATA[
|
||||
if (!this.mEditing && this.mInMouseDown && this.parentColumn) {
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
this.editingTimer = null;
|
||||
}
|
||||
|
||||
this.calendarView.setSelectedItems(1, [this.mOccurrence]);
|
||||
|
||||
this.mEditing = false;
|
||||
|
||||
this.parentColumn.startSweepingToModifyEvent(this, this.mOccurrence, "middle", this.mMouseX, this.mMouseY);
|
||||
this.mInMouseDown = false;
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="mouseup"><![CDATA[
|
||||
if (this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.mInMouseDown = false;
|
||||
]]></handler>
|
||||
|
||||
<handler event="mouseover"><![CDATA[
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
event.stopPropagation();
|
||||
onMouseOverItem(event);
|
||||
}
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -1,28 +0,0 @@
|
|||
/* 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/. */
|
||||
|
||||
@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
|
||||
|
||||
calendar-event-box {
|
||||
-moz-binding: url(chrome://calendar/content/calendar-multiday-view.xml#calendar-event-box);
|
||||
}
|
||||
|
||||
calendar-day-label {
|
||||
display: -moz-box;
|
||||
}
|
||||
|
||||
/* Month View */
|
||||
|
||||
calendar-month-day-box-item {
|
||||
-moz-binding: url(chrome://calendar/content/calendar-month-view.xml#calendar-month-day-box-item);
|
||||
}
|
||||
|
||||
/* View core */
|
||||
calendar-editable-item {
|
||||
-moz-binding: url(chrome://calendar/content/calendar-view-core.xml#calendar-editable-item);
|
||||
}
|
||||
|
||||
calendar-shadow-box {
|
||||
-moz-binding: url(chrome://calendar/content/calendar-view-core.xml#calendar-shadow-box);
|
||||
}
|
|
@ -1,388 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!-- 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-globals-from ../../resources/content/mouseoverPreviews.js -->
|
||||
<!-- import-globals-from calendar-dnd-listener.js -->
|
||||
<!-- import-globals-from calendar-views-utils.js -->
|
||||
|
||||
<bindings id="calendar-core-view-bindings"
|
||||
xmlns="http://www.mozilla.org/xbl"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns:xul="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:xbl="http://www.mozilla.org/xbl">
|
||||
|
||||
<binding id="calendar-editable-item">
|
||||
<content mousethrough="never"
|
||||
tooltip="itemTooltip"
|
||||
tabindex="-1">
|
||||
<xul:vbox flex="1">
|
||||
<xul:hbox>
|
||||
<xul:box anonid="event-container"
|
||||
class="calendar-color-box"
|
||||
flex="1">
|
||||
<xul:box class="calendar-event-selection" orient="horizontal" flex="1">
|
||||
<xul:stack anonid="eventbox"
|
||||
class="calendar-event-box-container"
|
||||
flex="1"
|
||||
xbl:inherits="readonly,flashing,alarm,allday,priority,progress,status,calendar,categories">
|
||||
<xul:hbox class="calendar-event-details">
|
||||
<xul:vbox align="left" flex="1" xbl:inherits="context">
|
||||
<xul:label anonid="event-name" crop="end" style="margin: 0;"/>
|
||||
<xul:textbox anonid="event-name-textbox"
|
||||
class="calendar-event-details-core title-desc"
|
||||
hidden="true"
|
||||
style="background: transparent !important;"
|
||||
wrap="true"/>
|
||||
<xul:label anonid="event-location"
|
||||
crop="end"
|
||||
class="calendar-event-details-core location-desc"/>
|
||||
<xul:spacer flex="1"/>
|
||||
</xul:vbox>
|
||||
<xul:stack>
|
||||
<xul:hbox anonid="category-box"
|
||||
class="calendar-category-box category-color-box calendar-event-selection"
|
||||
xbl:inherits="categories"
|
||||
flex="1"
|
||||
pack="end">
|
||||
<xul:image class="calendar-category-box-gradient"/>
|
||||
</xul:hbox>
|
||||
<xul:hbox align="center">
|
||||
<xul:hbox anonid="alarm-icons-box"
|
||||
class="alarm-icons-box"
|
||||
align="center"
|
||||
xbl:inherits="flashing"/>
|
||||
<xul:image anonid="item-classification-box"
|
||||
class="item-classification-box"
|
||||
pack="end"/>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</xul:hbox>
|
||||
</xul:stack>
|
||||
</xul:box>
|
||||
</xul:box>
|
||||
</xul:hbox>
|
||||
</xul:vbox>
|
||||
</content>
|
||||
|
||||
<implementation>
|
||||
<constructor><![CDATA[
|
||||
this.eventNameTextbox.onblur = () => {
|
||||
this.stopEditing(true);
|
||||
};
|
||||
this.eventNameTextbox.onkeypress = (event) => {
|
||||
// save on enter
|
||||
if (event.key == "Enter") {
|
||||
this.stopEditing(true);
|
||||
// abort on escape
|
||||
} else if (event.key == "Escape") {
|
||||
this.stopEditing(false);
|
||||
}
|
||||
};
|
||||
let stopPropagationIfEditing = (event) => {
|
||||
if (this.mEditing) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
};
|
||||
// while editing, single click positions cursor, so don't propagate.
|
||||
this.eventNameTextbox.onclick = stopPropagationIfEditing;
|
||||
// while editing, double click selects words, so don't propagate.
|
||||
this.eventNameTextbox.ondblclick = stopPropagationIfEditing;
|
||||
// while editing, don't propagate mousedown/up (selects calEvent).
|
||||
this.eventNameTextbox.onmousedown = stopPropagationIfEditing;
|
||||
this.eventNameTextbox.onmouseup = stopPropagationIfEditing;
|
||||
]]></constructor>
|
||||
|
||||
<field name="mOccurrence">null</field>
|
||||
<field name="mSelected">false</field>
|
||||
<field name="mCalendarView">null</field>
|
||||
|
||||
<property name="parentBox"
|
||||
onget="return this.mParentBox;"
|
||||
onset="this.mParentBox = val;"/>
|
||||
|
||||
<property name="selected">
|
||||
<getter><![CDATA[
|
||||
return this.mSelected;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
if (val && !this.mSelected) {
|
||||
this.mSelected = true;
|
||||
this.setAttribute("selected", "true");
|
||||
} else if (!val && this.mSelected) {
|
||||
this.mSelected = false;
|
||||
this.removeAttribute("selected");
|
||||
}
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
<property name="calendarView">
|
||||
<getter><![CDATA[
|
||||
return this.mCalendarView;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
this.mCalendarView = val;
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<property name="occurrence">
|
||||
<getter><![CDATA[
|
||||
return this.mOccurrence;
|
||||
]]></getter>
|
||||
<setter><![CDATA[
|
||||
this.mOccurrence = val;
|
||||
this.setEditableLabel();
|
||||
this.setLocationLabel();
|
||||
this.setCSSClasses();
|
||||
return val;
|
||||
]]></setter>
|
||||
</property>
|
||||
|
||||
<property name="eventNameLabel" readonly="true"
|
||||
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'event-name');"/>
|
||||
<property name="eventNameTextbox" readonly="true"
|
||||
onget="return document.getAnonymousElementByAttribute(this, 'anonid', 'event-name-textbox');"/>
|
||||
|
||||
<method name="setEditableLabel">
|
||||
<body><![CDATA[
|
||||
let evl = this.eventNameLabel;
|
||||
let item = this.mOccurrence;
|
||||
evl.value = (item.title ? item.title.replace(/\n/g, " ")
|
||||
: cal.l10n.getCalString("eventUntitled"));
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="setLocationLabel">
|
||||
<body><![CDATA[
|
||||
let locationLabel = document.getAnonymousElementByAttribute(this, "anonid", "event-location");
|
||||
let location = this.mOccurrence.getProperty("LOCATION");
|
||||
let showLocation = Services.prefs.getBoolPref("calendar.view.showLocation", false);
|
||||
|
||||
locationLabel.value = showLocation && location ? location : "";
|
||||
setBooleanAttribute(locationLabel, "hidden", !showLocation || !location);
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="setCSSClasses">
|
||||
<body><![CDATA[
|
||||
let item = this.mOccurrence;
|
||||
let cssSafeId = cal.view.formatStringForCSSRule(item.calendar.id);
|
||||
this.style.setProperty("--item-backcolor", `var(--calendar-${cssSafeId}-backcolor)`);
|
||||
this.style.setProperty("--item-forecolor", `var(--calendar-${cssSafeId}-forecolor)`);
|
||||
let categoriesArray = item.getCategories({});
|
||||
if (categoriesArray.length > 0) {
|
||||
let cssClassesArray = categoriesArray.map(cal.view.formatStringForCSSRule);
|
||||
this.setAttribute("categories", cssClassesArray.join(" "));
|
||||
let categoriesBox = document.getAnonymousElementByAttribute(this, "anonid", "category-box");
|
||||
categoriesBox.style.backgroundColor = `var(--category-${cssClassesArray[0]}-color)`;
|
||||
}
|
||||
|
||||
// Add alarm icons as needed.
|
||||
let alarms = item.getAlarms({});
|
||||
if (alarms.length && Services.prefs.getBoolPref("calendar.alarms.indicator.show", true)) {
|
||||
let iconsBox = document.getAnonymousElementByAttribute(this, "anonid", "alarm-icons-box");
|
||||
cal.alarms.addReminderImages(iconsBox, alarms);
|
||||
|
||||
// Set suppressed status on the icons box
|
||||
setElementValue(iconsBox,
|
||||
item.calendar.getProperty("suppressAlarms") || false,
|
||||
"suppressed");
|
||||
}
|
||||
|
||||
// Item classification / privacy
|
||||
let classificationBox = document.getAnonymousElementByAttribute(this, "anonid", "item-classification-box");
|
||||
if (classificationBox) {
|
||||
classificationBox.setAttribute("classification", item.privacy || "PUBLIC");
|
||||
}
|
||||
|
||||
// Set up event box attributes for use in css selectors. Note if
|
||||
// something is added here, it should also be xbl:inherited correctly
|
||||
// in the <content> section of this binding, and all that inherit it.
|
||||
|
||||
// Event type specific properties
|
||||
if (cal.item.isEvent(item)) {
|
||||
if (item.startDate.isDate) {
|
||||
this.setAttribute("allday", "true");
|
||||
}
|
||||
this.setAttribute("itemType", "event");
|
||||
} else if (cal.item.isToDo(item)) {
|
||||
// progress attribute
|
||||
this.setAttribute("progress", cal.item.getProgressAtom(item));
|
||||
// Attribute for tasks and tasks image.
|
||||
this.setAttribute("itemType", "todo");
|
||||
if (item.entryDate && !item.dueDate) {
|
||||
this.setAttribute("todoType", "start");
|
||||
} else if (!item.entryDate && item.dueDate) {
|
||||
this.setAttribute("todoType", "end");
|
||||
}
|
||||
}
|
||||
|
||||
if (this.calendarView &&
|
||||
item.hashId in this.calendarView.mFlashingEvents) {
|
||||
this.setAttribute("flashing", "true");
|
||||
}
|
||||
|
||||
if (alarms.length) {
|
||||
this.setAttribute("alarm", "true");
|
||||
}
|
||||
|
||||
// priority
|
||||
if (item.priority > 0 && item.priority < 5) {
|
||||
this.setAttribute("priority", "high");
|
||||
} else if (item.priority > 5 && item.priority < 10) {
|
||||
this.setAttribute("priority", "low");
|
||||
}
|
||||
|
||||
// status attribute
|
||||
if (item.status) {
|
||||
this.setAttribute("status", item.status.toUpperCase());
|
||||
}
|
||||
|
||||
// item class
|
||||
if (item.hasProperty("CLASS")) {
|
||||
this.setAttribute("itemclass", item.getProperty("CLASS"));
|
||||
}
|
||||
|
||||
// calendar name
|
||||
this.setAttribute("calendar", item.calendar.name.toLowerCase());
|
||||
|
||||
// Invitation
|
||||
if (cal.itip.isInvitation(item)) {
|
||||
this.setAttribute("invitation-status", cal.itip.getInvitedAttendee(item).participationStatus);
|
||||
this.setAttribute("readonly", "true");
|
||||
} else if (!cal.acl.isCalendarWritable(item.calendar)) {
|
||||
this.setAttribute("readonly", "true");
|
||||
}
|
||||
]]></body>
|
||||
</method>
|
||||
|
||||
<method name="startEditing">
|
||||
<body><![CDATA[
|
||||
this.editingTimer = null;
|
||||
this.mOriginalTextLabel = this.mOccurrence.title;
|
||||
|
||||
this.eventNameLabel.setAttribute("hidden", "true");
|
||||
|
||||
this.mEditing = true;
|
||||
|
||||
this.eventNameTextbox.value = this.mOriginalTextLabel;
|
||||
this.eventNameTextbox.removeAttribute("hidden");
|
||||
this.eventNameTextbox.select();
|
||||
]]></body>
|
||||
</method>
|
||||
<method name="select">
|
||||
<parameter name="event"/>
|
||||
<body><![CDATA[
|
||||
if (!this.calendarView) {
|
||||
return;
|
||||
}
|
||||
let items = this.calendarView.mSelectedItems.slice();
|
||||
if (event.ctrlKey || event.metaKey) {
|
||||
if (this.selected) {
|
||||
let pos = items.indexOf(this.mOccurrence);
|
||||
items.splice(pos, 1);
|
||||
} else {
|
||||
items.push(this.mOccurrence);
|
||||
}
|
||||
} else {
|
||||
items = [this.mOccurrence];
|
||||
}
|
||||
this.calendarView.setSelectedItems(items.length, items);
|
||||
]]></body>
|
||||
</method>
|
||||
<method name="stopEditing">
|
||||
<parameter name="saveChanges"/>
|
||||
<body><![CDATA[
|
||||
if (!this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.mEditing = false;
|
||||
|
||||
if (saveChanges && (this.eventNameTextbox.value != this.mOriginalTextLabel)) {
|
||||
this.calendarView.controller.modifyOccurrence(this.mOccurrence,
|
||||
null, null,
|
||||
this.eventNameTextbox.value);
|
||||
|
||||
// Note that as soon as we do the modifyItem, this element ceases to exist,
|
||||
// so don't bother trying to modify anything further here! ('this' exists,
|
||||
// because it's being kept alive, but our child content etc. is all gone)
|
||||
return;
|
||||
}
|
||||
|
||||
this.eventNameTextbox.setAttribute("hidden", "true");
|
||||
this.eventNameLabel.removeAttribute("hidden");
|
||||
]]></body>
|
||||
</method>
|
||||
</implementation>
|
||||
|
||||
<handlers>
|
||||
<handler event="contextmenu" phase="capturing"><![CDATA[
|
||||
// If the middle/right button was used for click just select the item.
|
||||
if (!this.selected) {
|
||||
this.select(event);
|
||||
}
|
||||
]]></handler>
|
||||
<handler event="click" button="0"><![CDATA[
|
||||
if (this.mEditing) {
|
||||
return;
|
||||
}
|
||||
|
||||
// If the left button was used and the item is already selected
|
||||
// and there are no multiple items selected start
|
||||
// the 'single click edit' timeout. Otherwise select the item too.
|
||||
// Also, check if the calendar is readOnly or we are offline.
|
||||
|
||||
if (this.selected && !(event.ctrlKey || event.metaKey) &&
|
||||
cal.acl.isCalendarWritable(this.mOccurrence.calendar)) {
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
}
|
||||
this.editingTimer = setTimeout(() => this.startEditing(), 350);
|
||||
} else {
|
||||
this.select(event);
|
||||
if (!this.closest("richlistitem")) {
|
||||
event.stopPropagation();
|
||||
}
|
||||
}
|
||||
]]></handler>
|
||||
|
||||
<handler event="dblclick" button="0"><![CDATA[
|
||||
event.stopPropagation();
|
||||
|
||||
// stop 'single click edit' timeout (if started)
|
||||
if (this.editingTimer) {
|
||||
clearTimeout(this.editingTimer);
|
||||
this.editingTimer = null;
|
||||
}
|
||||
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
let item = event.ctrlKey ? this.mOccurrence.parentItem : this.mOccurrence;
|
||||
this.calendarView.controller.modifyOccurrence(item);
|
||||
}
|
||||
]]></handler>
|
||||
<handler event="mouseover"><![CDATA[
|
||||
if (this.calendarView && this.calendarView.controller) {
|
||||
event.stopPropagation();
|
||||
onMouseOverItem(event);
|
||||
}
|
||||
]]></handler>
|
||||
<handler event="dragstart"><![CDATA[
|
||||
if (event.target.localName == "calendar-event-box") {
|
||||
return;
|
||||
}
|
||||
let item = this.occurrence;
|
||||
let isInvitation = item.calendar instanceof Ci.calISchedulingSupport && item.calendar.isInvitation(item);
|
||||
if (!cal.acl.isCalendarWritable(item.calendar) || !cal.acl.userCanModifyItem(item) || isInvitation) {
|
||||
return;
|
||||
}
|
||||
if (!this.selected) {
|
||||
this.select(event);
|
||||
}
|
||||
invokeEventDragSession(item, this);
|
||||
]]></handler>
|
||||
</handlers>
|
||||
</binding>
|
||||
</bindings>
|
|
@ -2,7 +2,7 @@
|
|||
* 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/. */
|
||||
|
||||
/* global MozElements, MozXULElement, Services, timeIndicator */
|
||||
/* global MozElements, MozXULElement, timeIndicator */
|
||||
|
||||
"use strict";
|
||||
|
||||
|
@ -17,6 +17,7 @@
|
|||
// Wrap in a block to prevent leaking to window scope.
|
||||
{
|
||||
var { cal } = ChromeUtils.import("resource://calendar/modules/calUtils.jsm");
|
||||
var { Services } = ChromeUtils.import("resource://gre/modules/Services.jsm");
|
||||
/**
|
||||
* The calendar view for viewing a single day.
|
||||
*
|
||||
|
@ -31,7 +32,7 @@
|
|||
super.connectedCallback();
|
||||
}
|
||||
|
||||
// calICalendarView Methods and Properties
|
||||
// calICalendarView Methods and Properties.
|
||||
|
||||
get observerID() {
|
||||
return "day-view-observer";
|
||||
|
@ -61,7 +62,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// End calICalendarView Methods and Properties
|
||||
// End calICalendarView Methods and Properties.
|
||||
}
|
||||
|
||||
MozXULElement.implementCustomInterface(CalendarDayView, [Ci.calICalendarView]);
|
||||
|
@ -101,7 +102,7 @@
|
|||
}, { once: true });
|
||||
}
|
||||
|
||||
// calICalendarView Methods and Properties
|
||||
// calICalendarView Methods and Properties.
|
||||
|
||||
get observerID() {
|
||||
return "week-view-observer";
|
||||
|
@ -132,7 +133,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// End calICalendarView Methods and Properties
|
||||
// End calICalendarView Methods and Properties.
|
||||
}
|
||||
|
||||
MozXULElement.implementCustomInterface(CalendarWeekView, [Ci.calICalendarView]);
|
||||
|
@ -166,7 +167,7 @@
|
|||
return this.mWeeksInView;
|
||||
}
|
||||
|
||||
// calICalendarView Methods and Properties
|
||||
// calICalendarView Methods and Properties.
|
||||
|
||||
get supportsZoom() {
|
||||
return true;
|
||||
|
@ -236,7 +237,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// End calICalendarView Methods and Properties
|
||||
// End calICalendarView Methods and Properties.
|
||||
}
|
||||
|
||||
MozXULElement.implementCustomInterface(CalendarMultiweekView, [Ci.calICalendarView]);
|
||||
|
@ -257,7 +258,7 @@
|
|||
super.connectedCallback();
|
||||
}
|
||||
|
||||
// calICalendarView Methods and Properties
|
||||
// calICalendarView Methods and Properties.
|
||||
|
||||
get observerID() {
|
||||
return "month-view-observer";
|
||||
|
@ -312,7 +313,7 @@
|
|||
}
|
||||
}
|
||||
|
||||
// End calICalendarView Methods and Properties
|
||||
// End calICalendarView Methods and Properties.
|
||||
}
|
||||
|
||||
MozXULElement.implementCustomInterface(CalendarMonthView, [Ci.calICalendarView]);
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
class CalendarDnDContainer extends MozXULElement {
|
||||
constructor() {
|
||||
super();
|
||||
this.addEventListener("dragstart", this.onDragStart, true);
|
||||
this.addEventListener("dragstart", this.onDragStart);
|
||||
this.addEventListener("dragover", this.onDragOver);
|
||||
this.addEventListener("dragenter", this.onDragEnter);
|
||||
this.addEventListener("drop", this.onDrop);
|
||||
|
@ -134,8 +134,8 @@
|
|||
}
|
||||
|
||||
onDragStart(event) {
|
||||
let draggedDOMNode = event.target;
|
||||
if (!draggedDOMNode || (draggedDOMNode.parentNode != this &&
|
||||
let draggedDOMNode = document.monthDragEvent || event.target;
|
||||
if (!draggedDOMNode || !draggedDOMNode.parentNode || (draggedDOMNode.parentNode != this &&
|
||||
!draggedDOMNode.parentNode.classList.contains("calendar-day-items"))) {
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -27,10 +27,8 @@ calendar.jar:
|
|||
content/calendar-menus.js (content/calendar-menus.js)
|
||||
content/calendar-month-base-view.js (content/calendar-month-base-view.js)
|
||||
content/calendar-month-view.js (content/calendar-month-view.js)
|
||||
content/calendar-month-view.xml (content/calendar-month-view.xml)
|
||||
content/calendar-multiday-base-view.js (content/calendar-multiday-base-view.js)
|
||||
content/calendar-multiday-view.js (content/calendar-multiday-view.js)
|
||||
content/calendar-multiday-view.xml (content/calendar-multiday-view.xml)
|
||||
content/calendar-statusbar.js (content/calendar-statusbar.js)
|
||||
content/calendar-task-editing.js (content/calendar-task-editing.js)
|
||||
content/calendar-task-tree-utils.js (content/calendar-task-tree-utils.js)
|
||||
|
@ -43,10 +41,9 @@ calendar.jar:
|
|||
content/calendar-unifinder-todo.xul (content/calendar-unifinder-todo.xul)
|
||||
content/calendar-unifinder.js (content/calendar-unifinder.js)
|
||||
content/calendar-unifinder.xul (content/calendar-unifinder.xul)
|
||||
content/calendar-view-bindings.css (content/calendar-view-bindings.css)
|
||||
content/calendar-view-core.xml (content/calendar-view-core.xml)
|
||||
content/calendar-views-utils.js (content/calendar-views-utils.js)
|
||||
content/calendar-views.js (content/calendar-views.js)
|
||||
content/calendar-editable-item.js (content/calendar-editable-item.js)
|
||||
content/calendar-views.xul (content/calendar-views.xul)
|
||||
content/calendar-alarm-dialog.js (content/dialogs/calendar-alarm-dialog.js)
|
||||
content/calendar-alarm-dialog.xul (content/dialogs/calendar-alarm-dialog.xul)
|
||||
|
|
|
@ -53,11 +53,12 @@
|
|||
<script src="chrome://calendar/content/calendar-base-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-month-base-view.js"/>
|
||||
<script src="chrome://calendar/content/widgets/calendar-dnd-widgets.js"/>
|
||||
<script src="chrome://calendar/content/calendar-month-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-event-column.js"/>
|
||||
<script src="chrome://calendar/content/calendar-multiday-base-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-multiday-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-views.js"/>
|
||||
<script src="chrome://calendar/content/calendar-editable-item.js"/>
|
||||
<script src="chrome://calendar/content/calendar-month-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-multiday-view.js"/>
|
||||
<script src="chrome://calendar/content/calendar-event-column.js"/>
|
||||
|
||||
<script src="chrome://calendar/content/calendar-creation.js"/>
|
||||
<script src="chrome://calendar/content/calendar-dnd-listener.js"/>
|
||||
|
|
|
@ -66,8 +66,8 @@ var EVENTPATH = `
|
|||
`;
|
||||
// Used after "${EVENTPATH}/${getEventDetails([view])}/".
|
||||
var ALARM_ICON_PATH = `
|
||||
anon({"anonid":"category-box-stack"})/anon({"align":"center"})/
|
||||
anon({"anonid":"alarm-icons-box"})/anon({"class":"reminder-icon"})
|
||||
anon({"class":"category-box-stack"})/anon({"align":"center"})/
|
||||
anon({"class":"alarm-icons-box"})/anon({"class":"reminder-icon"})
|
||||
`;
|
||||
|
||||
var plan_for_modal_dialog, wait_for_modal_dialog, close_window;
|
||||
|
@ -387,14 +387,14 @@ function getEventBoxPath(controller, view, option, row, column, hour) {
|
|||
function getEventDetails(view) {
|
||||
if (view == "day" || view == "week") {
|
||||
return `
|
||||
anon({"flex":"1"})/anon({"anonid":"event-container"})/
|
||||
{"class":"calendar-event-selection"}/anon({"anonid":"eventbox"})/
|
||||
anon({"flex":"1"})/anon({"class":"calendar-color-box"})/
|
||||
{"class":"calendar-event-selection"}/anon({"class":"calendar-event-box-container"})/
|
||||
{"class":"calendar-event-details"}
|
||||
`;
|
||||
} else {
|
||||
return `
|
||||
anon({"flex":"1"})/[0]/anon({"anonid":"event-container"})/
|
||||
{"class":"calendar-event-selection"}/anon({"anonid":"eventbox"})/
|
||||
anon({"flex":"1"})/[0]/anon({"class":"calendar-color-box"})/
|
||||
{"class":"calendar-event-selection"}/anon({"class":"calendar-event-box-container"})/
|
||||
{"class":"calendar-event-details"}
|
||||
`;
|
||||
}
|
||||
|
|
|
@ -95,7 +95,8 @@ function testDayView() {
|
|||
|
||||
// Check if name was saved.
|
||||
let eventName = lookupEventBox("day", EVENT_BOX, null, 1, null,
|
||||
`${EVENTPATH}/${getEventDetails("day")}/anon({"flex":"1"})/anon({"anonid":"event-name"})`
|
||||
`${EVENTPATH}/${getEventDetails("day")}/anon({"flex":"1"})/
|
||||
anon({"class":"calendar-event-details-core event-name-label"})`
|
||||
);
|
||||
controller.waitForElement(eventName);
|
||||
controller.assertJSProperty(eventName, "textContent", TITLE2);
|
||||
|
|
|
@ -102,7 +102,7 @@ function testMonthView() {
|
|||
|
||||
// Check if name was saved.
|
||||
let eventName = lookupEventBox("month", CANVAS_BOX, 1, 5, null,
|
||||
`${EVENTPATH}/${getEventDetails("month")}/anon({"flex":"1"})/anon({"anonid":"event-name"})`
|
||||
`${EVENTPATH}/${getEventDetails("month")}/anon({"flex":"1"})/anon({"class":"event-name-label"})`
|
||||
);
|
||||
|
||||
controller.waitForElement(eventName);
|
||||
|
|
|
@ -103,7 +103,7 @@ function testMultiWeekView() {
|
|||
// Check if name was saved.
|
||||
let eventName = lookupEventBox("multiweek", CANVAS_BOX, 1, 5, null,
|
||||
`${EVENTPATH}/${getEventDetails("multiweek")}/anon({"flex":"1"})/
|
||||
anon({"anonid":"event-name"})`
|
||||
anon({"class":"event-name-label"})`
|
||||
);
|
||||
|
||||
controller.waitForElement(eventName);
|
||||
|
|
|
@ -100,7 +100,8 @@ function testWeekView() {
|
|||
|
||||
// Check if name was saved.
|
||||
let eventName = lookupEventBox("week", EVENT_BOX, null, 5, null,
|
||||
`${EVENTPATH}/${getEventDetails("week")}/anon({"flex":"1"})/anon({"anonid":"event-name"})`
|
||||
`${EVENTPATH}/${getEventDetails("week")}/anon({"flex":"1"})/
|
||||
anon({"class":"calendar-event-details-core event-name-label"})`
|
||||
);
|
||||
controller.waitForElement(eventName);
|
||||
controller.assertJSProperty(eventName, "textContent", TITLE2);
|
||||
|
|
Загрузка…
Ссылка в новой задаче