roundcubemail-plugins-kolab/plugins/calendar/lib/fullcalendar-rc.patch

384 lines
10 KiB
Diff

--- js/fullcalendar.js.orig 2011-06-04 13:45:44.000000000 -0600
+++ js/fullcalendar.js 2011-06-10 09:27:50.000000000 -0600
@@ -47,12 +47,14 @@
titleFormat: {
month: 'MMMM yyyy',
week: "MMM d[ yyyy]{ '—'[ MMM] d yyyy}",
- day: 'dddd, MMM d, yyyy'
+ day: 'dddd, MMM d, yyyy',
+ list: 'MMM d, yyyy'
},
columnFormat: {
month: 'ddd',
week: 'ddd M/d',
- day: 'dddd M/d'
+ day: 'dddd M/d',
+ list: 'dddd, yyyy'
},
timeFormat: { // for event elements
'': 'h(:mm)t' // default
@@ -73,7 +75,20 @@
today: 'today',
month: 'month',
week: 'week',
- day: 'day'
+ day: 'day',
+ list: 'list'
+ },
+ listTexts: {
+ from: 'from',
+ until: 'until',
+ past: 'Past events',
+ today: 'Today',
+ tomorrow: 'Tomorrow',
+ thisWeek: 'This week',
+ nextWeek: 'Next week',
+ thisMonth: 'This month',
+ nextMonth: 'Next month',
+ future: 'Future events'
},
// jquery-ui theming
@@ -500,8 +515,8 @@
}
- function refetchEvents() {
- fetchEvents(currentView.visStart, currentView.visEnd); // will call reportEvents
+ function refetchEvents(source) {
+ fetchEvents(currentView.visStart, currentView.visEnd, source); // will call reportEvents
}
@@ -897,15 +912,16 @@
}
- function fetchEvents(start, end) {
+ function fetchEvents(start, end, src) {
rangeStart = start;
rangeEnd = end;
- cache = [];
+ cache = typeof src != 'undefined' ? $.grep(cache, function(e) { return !isSourcesEqual(e.source, src); }) : [];
var fetchID = ++currentFetchID;
var len = sources.length;
- pendingSourceCnt = len;
+ pendingSourceCnt = typeof src == 'undefined' ? len : 1;
for (var i=0; i<len; i++) {
- fetchEventSource(sources[i], fetchID);
+ if (typeof src == 'undefined' || isSourcesEqual(sources[i], src))
+ fetchEventSource(sources[i], fetchID);
}
}
@@ -5205,4 +5221,309 @@
}
+
+/* Additional view: list (by bruederli@kolabsys.com)
+---------------------------------------------------------------------------------*/
+
+function ListEventRenderer() {
+ var t = this;
+
+ // exports
+ t.renderEvents = renderEvents;
+ t.compileDaySegs = compileSegs; // for DayEventRenderer
+ t.clearEvents = clearEvents;
+
+ // imports
+ DayEventRenderer.call(t);
+ var opt = t.opt;
+ var trigger = t.trigger;
+ var reportEvents = t.reportEvents;
+ var reportEventClear = t.reportEventClear;
+ var reportEventElement = t.reportEventElement;
+ var eventElementHandlers = t.eventElementHandlers;
+ var showEvents = t.showEvents;
+ var hideEvents = t.hideEvents;
+ var getListContainer = t.getDaySegmentContainer;
+ var calendar = t.calendar;
+ var formatDate = calendar.formatDate;
+ var formatDates = calendar.formatDates;
+
+
+ /* Rendering
+ --------------------------------------------------------------------*/
+
+ function clearEvents() {
+ reportEventClear();
+ getListContainer().empty();
+ }
+
+ function renderEvents(events, modifiedEventId) {
+ events.sort(sortCmp);
+ reportEvents(events);
+ renderSegs(compileSegs(events), modifiedEventId);
+ }
+
+ function compileSegs(events) {
+ var segs = [];
+ var colFormat = opt('columnFormat', 'day');
+ var event, i, dd, md, seg, segHash, curSegHash, segDate, curSeg = -1;
+ var today = clearTime(new Date());
+
+ for (i=0; i < events.length; i++) {
+ event = events[i];
+
+ // skip events < t.start
+ if (event.end < t.start)
+ continue;
+
+ // define sections of this event
+ // create smart sections such as today, tomorrow, this week, next week, next month, ect.
+ segDate = cloneDate(event.start < t.start && event.end > t.start ? t.start : event.start, true);
+ dd = dayDiff(segDate, today);
+ md = segDate.getMonth() + ((segDate.getYear() - today.getYear()) * 12) - today.getMonth();
+
+ // past events
+ if (dd < 0) {
+ segHash = opt('listTexts', 'past');
+ }
+ // today
+ else if (dd == 0) {
+ segHash = opt('listTexts', 'today');
+ }
+ else if (dd == 1) {
+ segHash = opt('listTexts', 'tomorrow');
+ }
+ // this week
+ else if (dd < 7) {
+ segHash = opt('listTexts', 'thisWeek');
+ }
+ // next week
+ else if (dd >= 7 && dd < 14 && md == 0) {
+ segHash = opt('listTexts', 'nextWeek');
+ }
+ else if (md == 0) {
+ segHash = opt('listTexts', 'thisMonth');
+ }
+ else if (md == 1) {
+ segHash = opt('listTexts', 'nextMonth');
+ }
+ else {
+ segHash = formatDate(segDate, colFormat);
+ }
+
+ // start new segment
+ if (segHash != curSegHash) {
+ segs[++curSeg] = { events: [], start: segDate, title: segHash, daydiff: dd };
+ curSegHash = segHash;
+ }
+
+ segs[curSeg].events.push(event);
+ }
+
+ return segs;
+ }
+
+ function sortCmp(a, b) {
+ return (a.start.getTime() - b.start.getTime()) + (a.end.getTime() - b.end.getTime());
+ }
+
+ function renderSegs(segs, modifiedEventId) {
+ var tm = opt('theme') ? 'ui' : 'fc';
+ var timeFormat = opt('timeFormat');
+ var dateFormat = opt('titleFormat');
+ var headerClass = tm + "-widget-header";
+ var contentClass = tm + "-widget-content";
+ var i, j, seg, event, duration, s, skinCss, skinCssAttr, classes, time, segHeader, segContainer, eventElements;
+
+ for (j=0; j < segs.length; j++) {
+ seg = segs[j];
+
+ segHeader = $('<div class="fc-list-header ' + headerClass + '">' + htmlEscape(seg.title) + '</div>').appendTo(getListContainer());
+ segContainer = $('<div>').addClass('fc-list-section ' + contentClass).appendTo(getListContainer());
+ s = '';
+
+ for (i=0; i < seg.events.length; i++) {
+ event = seg.events[i];
+
+ skinCss = getSkinCss(event, opt);
+ skinCssAttr = (skinCss ? " style='" + skinCss + "'" : '');
+ classes = ['fc-event', 'fc-event-skin', 'fc-event-vert', 'fc-corner-left', 'fc-corner-right', 'fc-corner-top', 'fc-corner-bottom'];
+ if (event.source && event.source.className) {
+ classes = classes.concat(event.source.className);
+ }
+
+ // event time/date range to display
+ times = [];
+ duration = event.end.getTime() - event.start.getTime();
+ if (event.start < seg.start) {
+ times.push(opt('listTexts', 'until') + ' ' + formatDate(event.end, (event.allDay || event.end.getDate() != seg.start.getDate()) ? dateFormat : timeFormat));
+ } else if (duration > DAY_MS) {
+ times.push(formatDates(event.start, event.end, dateFormat + '[ - ' + dateFormat + ']'));
+ } else if (seg.daydiff > 1 && seg.daydiff < 7) {
+ times.push(formatDate(event.start, 'ddd'));
+ } else if (seg.daydiff > 1 || seg.daydiff < 0) {
+ times.push(formatDate(event.start, dateFormat));
+ }
+
+ if (!times.length && event.allDay) {
+ times.push(opt('allDayText'));
+ } else if (duration < DAY_MS && !event.allDay) {
+ times.push(formatDates(event.start, event.end, timeFormat))
+ }
+
+ s +=
+ "<div class='" + classes.join(' ') + "'" + skinCssAttr + ">" +
+ "<div class='fc-event-inner fc-event-skin'" + skinCssAttr + ">" +
+ "<div class='fc-event-head fc-event-skin'" + skinCssAttr + ">" +
+ "<div class='fc-event-time'>" +
+ htmlEscape(times.join(' ')) +
+ "</div>" +
+ "</div>" +
+ "<div class='fc-event-content'>" +
+ "<div class='fc-event-title'>" +
+ htmlEscape(event.title) +
+ "</div>" +
+ "</div>" +
+ "<div class='fc-event-bg'></div>" +
+ "</div>" + // close inner
+ "</div>"; // close outer
+ }
+
+ segContainer[0].innerHTML = s;
+ eventElements = segContainer.children();
+
+ // retrieve elements, run through eventRender callback, bind event handlers
+ for (i=0; i < seg.events.length; i++) {
+ event = seg.events[i];
+ eventElement = $(eventElements[i]); // faster than eq()
+ triggerRes = trigger('eventRender', event, event, eventElement);
+ if (triggerRes === false) {
+ eventElement.remove();
+ } else {
+ if (triggerRes && triggerRes !== true) {
+ eventElement.remove();
+ eventElement = $(triggerRes).appendTo(segContainer);
+ }
+ if (event._id === modifiedEventId) {
+ bindSeg(event, eventElement, seg);
+ } else {
+ eventElement[0]._fci = i; // for lazySegBind
+ }
+ reportEventElement(event, eventElement);
+ }
+ }
+
+ lazySegBind(segContainer, seg, bindSeg);
+ }
+
+ markFirstLast(getListContainer());
+ }
+
+ function bindSeg(event, eventElement, seg) {
+ eventElementHandlers(event, eventElement);
+ }
+
+ function lazySegBind(container, seg, bindHandlers) {
+ container.unbind('mouseover').mouseover(function(ev) {
+ var parent = ev.target, e = parent, i, event;
+ while (parent != this) {
+ e = parent;
+ parent = parent.parentNode;
+ }
+ if ((i = e._fci) !== undefined) {
+ e._fci = undefined;
+ event = seg.events[i];
+ bindHandlers(event, container.children().eq(i), seg);
+ $(ev.target).trigger(ev);
+ }
+ ev.stopPropagation();
+ });
+ }
+
+}
+
+
+fcViews.list = ListView;
+
+
+function ListView(element, calendar) {
+ var t = this;
+
+ // exports
+ t.render = render;
+ t.select = dummy;
+ t.unselect = dummy;
+ t.getDaySegmentContainer = function(){ return body; };
+
+ // imports
+ View.call(t, element, calendar, 'list');
+ ListEventRenderer.call(t);
+ var opt = t.opt;
+ var trigger = t.trigger;
+ var clearEvents = t.clearEvents;
+ var reportEventClear = t.reportEventClear;
+ var formatDates = calendar.formatDates;
+ var formatDate = calendar.formatDate;
+
+ // overrides
+ t.setWidth = setWidth;
+ t.setHeight = setHeight;
+
+ // locals
+ var body;
+ var firstDay;
+ var nwe;
+ var tm;
+ var colFormat;
+
+
+ function render(date, delta) {
+ if (delta) {
+ addDays(date, delta);
+ if (!opt('weekends')) {
+ skipWeekend(date, delta < 0 ? -1 : 1);
+ }
+ }
+ t.title = opt('listTexts', 'from') + ' ' + formatDate(date, opt('titleFormat'));
+ t.start = t.visStart = cloneDate(date, true);
+ t.end = addDays(cloneDate(t.start), 1);
+ t.visEnd = addMonths(cloneDate(t.start), 1); // show events one month ahead. Enough?
+
+ updateOptions();
+
+ if (!body) {
+ buildSkeleton();
+ } else {
+ clearEvents();
+ }
+ }
+
+
+ function updateOptions() {
+ firstDay = opt('firstDay');
+ nwe = opt('weekends') ? 0 : 1;
+ tm = opt('theme') ? 'ui' : 'fc';
+ colFormat = opt('columnFormat', 'day');
+ }
+
+
+ function buildSkeleton() {
+ body = $('<div>').addClass('fc-list-content').appendTo(element);
+ }
+
+ function setHeight(height, dateChanged) {
+ body.css('height', (height-1)+'px').css('overflow', 'auto');
+ }
+
+ function setWidth(width) {
+ // nothing to be done here
+ }
+
+ function dummy() {
+ // Stub.
+ }
+
+}
+
+
})(jQuery);
\ No newline at end of file