aboutsummaryrefslogtreecommitdiffstats
path: root/library/fullcalendar/fullcalendar.js
diff options
context:
space:
mode:
Diffstat (limited to 'library/fullcalendar/fullcalendar.js')
-rw-r--r--library/fullcalendar/fullcalendar.js142
1 files changed, 112 insertions, 30 deletions
diff --git a/library/fullcalendar/fullcalendar.js b/library/fullcalendar/fullcalendar.js
index 33c0c6a38..3c2c380bc 100644
--- a/library/fullcalendar/fullcalendar.js
+++ b/library/fullcalendar/fullcalendar.js
@@ -1,5 +1,5 @@
/*!
- * FullCalendar v3.0.0
+ * FullCalendar v3.0.1
* Docs & License: http://fullcalendar.io/
* (c) 2016 Adam Shaw
*/
@@ -19,7 +19,7 @@
;;
var FC = $.fullCalendar = {
- version: "3.0.0",
+ version: "3.0.1",
internalApiVersion: 6
};
var fcViews = FC.views = {};
@@ -1574,6 +1574,49 @@ function chunkFormatString(formatStr) {
return chunks;
}
+
+// Misc Utils
+// -------------------------------------------------------------------------------------------------
+
+
+// granularity only goes up until day
+// TODO: unify with similarUnitMap
+var tokenGranularities = {
+ Y: { value: 1, unit: 'year' },
+ M: { value: 2, unit: 'month' },
+ W: { value: 3, unit: 'week' },
+ w: { value: 3, unit: 'week' },
+ D: { value: 4, unit: 'day' }, // day of month
+ d: { value: 4, unit: 'day' } // day of week
+};
+
+// returns a unit string, either 'year', 'month', 'day', or null
+// for the most granular formatting token in the string.
+FC.queryMostGranularFormatUnit = function(formatStr) {
+ var chunks = getFormatStringChunks(formatStr);
+ var i, chunk;
+ var candidate;
+ var best;
+
+ for (i = 0; i < chunks.length; i++) {
+ chunk = chunks[i];
+ if (chunk.token) {
+ candidate = tokenGranularities[chunk.token.charAt(0)];
+ if (candidate) {
+ if (!best || candidate.value > best.value) {
+ best = candidate;
+ }
+ }
+ }
+ }
+
+ if (best) {
+ return best.unit;
+ }
+
+ return null;
+};
+
;;
FC.Class = Class; // export
@@ -13214,21 +13257,36 @@ var ListViewGrid = Grid.extend({
// slices by day
spanToSegs: function(span) {
var view = this.view;
- var dayStart = view.start.clone();
- var dayEnd;
+ var dayStart = view.start.clone().time(0); // timed, so segs get times!
+ var dayIndex = 0;
var seg;
var segs = [];
while (dayStart < view.end) {
- dayEnd = dayStart.clone().add(1, 'day');
+
seg = intersectRanges(span, {
start: dayStart,
- end: dayEnd
+ end: dayStart.clone().add(1, 'day')
});
+
if (seg) {
+ seg.dayIndex = dayIndex;
segs.push(seg);
}
- dayStart = dayEnd;
+
+ dayStart.add(1, 'day');
+ dayIndex++;
+
+ // detect when span won't go fully into the next day,
+ // and mutate the latest seg to the be the end.
+ if (
+ seg && !seg.isEnd && span.end.hasTime() &&
+ span.end < dayStart.clone().add(this.view.nextDayThreshold)
+ ) {
+ seg.end = span.end.clone();
+ seg.isEnd = true;
+ break;
+ }
}
return segs;
@@ -13261,11 +13319,12 @@ var ListViewGrid = Grid.extend({
if (!segs.length) {
this.renderEmptyMessage();
- return segs;
}
else {
- return this.renderSegList(segs);
+ this.renderSegList(segs);
}
+
+ return segs;
},
renderEmptyMessage: function() {
@@ -13280,30 +13339,47 @@ var ListViewGrid = Grid.extend({
);
},
- // render the event segments in the view. returns the mutated array.
- renderSegList: function(segs) {
+ // render the event segments in the view
+ renderSegList: function(allSegs) {
+ var segsByDay = this.groupSegsByDay(allSegs); // sparse array
+ var dayIndex;
+ var daySegs;
+ var i;
var tableEl = $('<table class="fc-list-table"><tbody/></table>');
var tbodyEl = tableEl.find('tbody');
- var i, seg;
- var dayDate;
- this.sortEventSegs(segs);
+ for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
+ daySegs = segsByDay[dayIndex];
+ if (daySegs) { // sparse array, so might be undefined
- for (i = 0; i < segs.length; i++) {
- seg = segs[i];
+ // append a day header
+ tbodyEl.append(this.dayHeaderHtml(
+ this.view.start.clone().add(dayIndex, 'days')
+ ));
- // append a day header
- if (!dayDate || !seg.start.isSame(dayDate, 'day')) {
- dayDate = seg.start.clone().stripTime();
- tbodyEl.append(this.dayHeaderHtml(dayDate));
- }
+ this.sortEventSegs(daySegs);
- tbodyEl.append(seg.el); // append event row
+ for (i = 0; i < daySegs.length; i++) {
+ tbodyEl.append(daySegs[i].el); // append event row
+ }
+ }
}
this.el.empty().append(tableEl);
+ },
+
+ // Returns a sparse array of arrays, segs grouped by their dayIndex
+ groupSegsByDay: function(segs) {
+ var segsByDay = []; // sparse array
+ var i, seg;
- return segs; // return the sorted list
+ for (i = 0; i < segs.length; i++) {
+ seg = segs[i];
+ (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
+ .push(seg);
+ }
+
+ return segsByDay;
},
// generates the HTML for the day headers that live amongst the event rows
@@ -13341,13 +13417,20 @@ var ListViewGrid = Grid.extend({
var url = event.url;
var timeHtml;
- if (!seg.start.hasTime()) {
- if (this.displayEventTime) {
+ if (event.allDay) {
+ timeHtml = view.getAllDayHtml();
+ }
+ else if (view.isMultiDayEvent(event)) { // if the event appears to span more than one day
+ if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day
+ timeHtml = htmlEscape(this.getEventTimeText(seg));
+ }
+ else { // inner segment that lasts the whole day
timeHtml = view.getAllDayHtml();
}
}
else {
- timeHtml = htmlEscape(this.getEventTimeText(event)); // might return empty
+ // Display the normal time text for the *event's* times
+ timeHtml = htmlEscape(this.getEventTimeText(event));
}
if (url) {
@@ -13355,9 +13438,9 @@ var ListViewGrid = Grid.extend({
}
return '<tr class="' + classes.join(' ') + '">' +
- (timeHtml ?
+ (this.displayEventTime ?
'<td class="fc-list-item-time ' + view.widgetContentClass + '">' +
- timeHtml +
+ (timeHtml || '') +
'</td>' :
'') +
'<td class="fc-list-item-marker ' + view.widgetContentClass + '">' +
@@ -13369,7 +13452,7 @@ var ListViewGrid = Grid.extend({
'</td>' +
'<td class="fc-list-item-title ' + view.widgetContentClass + '">' +
'<a' + (url ? ' href="' + htmlEscape(url) + '"' : '') + '>' +
- htmlEscape(seg.event.title) +
+ htmlEscape(seg.event.title || '') +
'</a>' +
'</td>' +
'</tr>';
@@ -13384,7 +13467,6 @@ fcViews.list = {
buttonTextKey: 'list', // what to lookup in locale files
defaults: {
buttonText: 'list', // text to display for English
- listTime: true, // show the time column?
listDayFormat: 'LL', // like "January 1, 2016"
noEventsMessage: 'No events to display'
}