mirror of
https://codeberg.org/streams/streams.git
synced 2024-09-19 21:55:15 +00:00
update fullcalendar to version 2.8.0
This commit is contained in:
parent
7d7f43c205
commit
aff58934c0
10 changed files with 267 additions and 71 deletions
|
@ -1,4 +1,24 @@
|
|||
|
||||
v2.8.0 (2016-06-19)
|
||||
-------------------
|
||||
|
||||
- getEventSources method (#3103, #2433)
|
||||
- getEventSourceById method (#3223)
|
||||
- refetchEventSources method (#3103, #1328, #254)
|
||||
- removeEventSources method (#3165, #948)
|
||||
- prevent flicker when refetchEvents is called (#3123, #2558)
|
||||
- fix for removing event sources that share same URL (#3209)
|
||||
- jQuery 3 support (#3197, #3124)
|
||||
- Travis CI integration (#3218)
|
||||
- EditorConfig for promoting consistent code style (#141)
|
||||
- use en dash when formatting ranges (#3077)
|
||||
- height:auto always shows scrollbars in month view on FF (#3202)
|
||||
- new languages:
|
||||
- Basque (#2992)
|
||||
- Galician (#194)
|
||||
- Luxembourgish (#2979)
|
||||
|
||||
|
||||
v2.7.3 (2016-06-02)
|
||||
-------------------
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* FullCalendar v2.7.3 Stylesheet
|
||||
* FullCalendar v2.8.0 Stylesheet
|
||||
* Docs & License: http://fullcalendar.io/
|
||||
* (c) 2016 Adam Shaw
|
||||
*/
|
||||
|
@ -367,6 +367,7 @@ hr.fc-divider {
|
|||
|
||||
.fc table {
|
||||
width: 100%;
|
||||
box-sizing: border-box; /* fix scrollbar issue in firefox */
|
||||
table-layout: fixed;
|
||||
border-collapse: collapse;
|
||||
border-spacing: 0;
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* FullCalendar v2.7.3
|
||||
* FullCalendar v2.8.0
|
||||
* Docs & License: http://fullcalendar.io/
|
||||
* (c) 2016 Adam Shaw
|
||||
*/
|
||||
|
@ -19,7 +19,7 @@
|
|||
;;
|
||||
|
||||
var FC = $.fullCalendar = {
|
||||
version: "2.7.3",
|
||||
version: "2.8.0",
|
||||
internalApiVersion: 4
|
||||
};
|
||||
var fcViews = FC.views = {};
|
||||
|
@ -1054,6 +1054,20 @@ function debounce(func, wait, immediate) {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
// HACK around jQuery's now A+ promises: execute callback synchronously if already resolved.
|
||||
// thenFunc shouldn't accept args.
|
||||
// similar to whenResources in Scheduler plugin.
|
||||
function syncThen(promise, thenFunc) {
|
||||
// not a promise, or an already-resolved promise?
|
||||
if (!promise || !promise.then || promise.state() === 'resolved') {
|
||||
return $.when(thenFunc()); // resolve immediately
|
||||
}
|
||||
else if (thenFunc) {
|
||||
return promise.then(thenFunc);
|
||||
}
|
||||
}
|
||||
|
||||
;;
|
||||
|
||||
var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
|
||||
|
@ -3960,7 +3974,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
|
|||
fillSegTag: 'div', // subclasses can override
|
||||
|
||||
|
||||
// Builds the HTML needed for one fill segment. Generic enought o work with different types.
|
||||
// Builds the HTML needed for one fill segment. Generic enough to work with different types.
|
||||
fillSegHtml: function(type, seg) {
|
||||
|
||||
// custom hooks per-type
|
||||
|
@ -8106,11 +8120,10 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|||
|
||||
this.calendar.freezeContentHeight();
|
||||
|
||||
return this.clear().then(function() { // clear the content first (async)
|
||||
return syncThen(this.clear(), function() { // clear the content first
|
||||
return (
|
||||
_this.displaying =
|
||||
$.when(_this.displayView(date)) // displayView might return a promise
|
||||
.then(function() {
|
||||
syncThen(_this.displayView(date), function() { // displayView might return a promise
|
||||
_this.forceScroll(_this.computeInitialScroll(scrollState));
|
||||
_this.calendar.unfreezeContentHeight();
|
||||
_this.triggerRender();
|
||||
|
@ -8128,7 +8141,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|||
var displaying = this.displaying;
|
||||
|
||||
if (displaying) { // previously displayed, or in the process of being displayed?
|
||||
return displaying.then(function() { // wait for the display to finish
|
||||
return syncThen(displaying, function() { // wait for the display to finish
|
||||
_this.displaying = null;
|
||||
_this.clearEvents();
|
||||
return _this.clearView(); // might return a promise. chain it
|
||||
|
@ -9321,6 +9334,7 @@ function Calendar_constructor(element, overrides) {
|
|||
t.render = render;
|
||||
t.destroy = destroy;
|
||||
t.refetchEvents = refetchEvents;
|
||||
t.refetchEventSources = refetchEventSources;
|
||||
t.reportEvents = reportEvents;
|
||||
t.reportEventChange = reportEventChange;
|
||||
t.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method
|
||||
|
@ -9511,6 +9525,7 @@ function Calendar_constructor(element, overrides) {
|
|||
EventManager.call(t, options);
|
||||
var isFetchNeeded = t.isFetchNeeded;
|
||||
var fetchEvents = t.fetchEvents;
|
||||
var fetchEventSources = t.fetchEventSources;
|
||||
|
||||
|
||||
|
||||
|
@ -9750,11 +9765,16 @@ function Calendar_constructor(element, overrides) {
|
|||
|
||||
|
||||
function refetchEvents() { // can be called as an API method
|
||||
destroyEvents(); // so that events are cleared before user starts waiting for AJAX
|
||||
fetchAndRenderEvents();
|
||||
}
|
||||
|
||||
|
||||
// TODO: move this into EventManager?
|
||||
function refetchEventSources(matchInputs) {
|
||||
fetchEventSources(t.getEventSourcesByMatchArray(matchInputs));
|
||||
}
|
||||
|
||||
|
||||
function renderEvents() { // destroys old events if previously rendered
|
||||
if (elementVisible()) {
|
||||
freezeContentHeight();
|
||||
|
@ -9764,13 +9784,6 @@ function Calendar_constructor(element, overrides) {
|
|||
}
|
||||
|
||||
|
||||
function destroyEvents() {
|
||||
freezeContentHeight();
|
||||
currentView.clearEvents();
|
||||
unfreezeContentHeight();
|
||||
}
|
||||
|
||||
|
||||
function getAndRenderEvents() {
|
||||
if (!options.lazyFetching || isFetchNeeded(currentView.start, currentView.end)) {
|
||||
fetchAndRenderEvents();
|
||||
|
@ -9979,7 +9992,7 @@ function Calendar_constructor(element, overrides) {
|
|||
|
||||
Calendar.defaults = {
|
||||
|
||||
titleRangeSeparator: ' \u2014 ', // emphasized dash
|
||||
titleRangeSeparator: ' \u2013 ', // en dash
|
||||
monthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option
|
||||
|
||||
defaultTimedEventDuration: '02:00:00',
|
||||
|
@ -10528,14 +10541,14 @@ function Header(calendar, options) {
|
|||
|
||||
function disableButton(buttonName) {
|
||||
el.find('.fc-' + buttonName + '-button')
|
||||
.attr('disabled', 'disabled')
|
||||
.prop('disabled', true)
|
||||
.addClass(tm + '-state-disabled');
|
||||
}
|
||||
|
||||
|
||||
function enableButton(buttonName) {
|
||||
el.find('.fc-' + buttonName + '-button')
|
||||
.removeAttr('disabled')
|
||||
.prop('disabled', false)
|
||||
.removeClass(tm + '-state-disabled');
|
||||
}
|
||||
|
||||
|
@ -10566,8 +10579,14 @@ function EventManager(options) { // assumed to be a calendar
|
|||
// exports
|
||||
t.isFetchNeeded = isFetchNeeded;
|
||||
t.fetchEvents = fetchEvents;
|
||||
t.fetchEventSources = fetchEventSources;
|
||||
t.getEventSources = getEventSources;
|
||||
t.getEventSourceById = getEventSourceById;
|
||||
t.getEventSourcesByMatchArray = getEventSourcesByMatchArray;
|
||||
t.getEventSourcesByMatch = getEventSourcesByMatch;
|
||||
t.addEventSource = addEventSource;
|
||||
t.removeEventSource = removeEventSource;
|
||||
t.removeEventSources = removeEventSources;
|
||||
t.updateEvent = updateEvent;
|
||||
t.renderEvent = renderEvent;
|
||||
t.removeEvents = removeEvents;
|
||||
|
@ -10585,8 +10604,7 @@ function EventManager(options) { // assumed to be a calendar
|
|||
var stickySource = { events: [] };
|
||||
var sources = [ stickySource ];
|
||||
var rangeStart, rangeEnd;
|
||||
var currentFetchID = 0;
|
||||
var pendingSourceCnt = 0;
|
||||
var pendingSourceCnt = 0; // outstanding fetch requests, max one per source
|
||||
var cache = []; // holds events that have already been expanded
|
||||
|
||||
|
||||
|
@ -10616,23 +10634,58 @@ function EventManager(options) { // assumed to be a calendar
|
|||
function fetchEvents(start, end) {
|
||||
rangeStart = start;
|
||||
rangeEnd = end;
|
||||
fetchEventSources(sources, 'reset');
|
||||
}
|
||||
|
||||
|
||||
// expects an array of event source objects (the originals, not copies)
|
||||
// `specialFetchType` is an optimization parameter that affects purging of the event cache.
|
||||
function fetchEventSources(specificSources, specialFetchType) {
|
||||
var i, source;
|
||||
|
||||
if (specialFetchType === 'reset') {
|
||||
cache = [];
|
||||
var fetchID = ++currentFetchID;
|
||||
var len = sources.length;
|
||||
pendingSourceCnt = len;
|
||||
for (var i=0; i<len; i++) {
|
||||
fetchEventSource(sources[i], fetchID);
|
||||
}
|
||||
else if (specialFetchType !== 'add') {
|
||||
cache = excludeEventsBySources(cache, specificSources);
|
||||
}
|
||||
|
||||
for (i = 0; i < specificSources.length; i++) {
|
||||
source = specificSources[i];
|
||||
|
||||
// already-pending sources have already been accounted for in pendingSourceCnt
|
||||
if (source._status !== 'pending') {
|
||||
pendingSourceCnt++;
|
||||
}
|
||||
|
||||
source._fetchId = (source._fetchId || 0) + 1;
|
||||
source._status = 'pending';
|
||||
}
|
||||
|
||||
for (i = 0; i < specificSources.length; i++) {
|
||||
source = specificSources[i];
|
||||
|
||||
tryFetchEventSource(source, source._fetchId);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function fetchEventSource(source, fetchID) {
|
||||
// fetches an event source and processes its result ONLY if it is still the current fetch.
|
||||
// caller is responsible for incrementing pendingSourceCnt first.
|
||||
function tryFetchEventSource(source, fetchId) {
|
||||
_fetchEventSource(source, function(eventInputs) {
|
||||
var isArraySource = $.isArray(source.events);
|
||||
var i, eventInput;
|
||||
var abstractEvent;
|
||||
|
||||
if (fetchID == currentFetchID) {
|
||||
if (
|
||||
// is this the source's most recent fetch?
|
||||
// if not, rely on an upcoming fetch of this source to decrement pendingSourceCnt
|
||||
fetchId === source._fetchId &&
|
||||
// event source no longer valid?
|
||||
source._status !== 'rejected'
|
||||
) {
|
||||
source._status = 'resolved';
|
||||
|
||||
if (eventInputs) {
|
||||
for (i = 0; i < eventInputs.length; i++) {
|
||||
|
@ -10654,13 +10707,29 @@ function EventManager(options) { // assumed to be a calendar
|
|||
}
|
||||
}
|
||||
|
||||
decrementPendingSourceCnt();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function rejectEventSource(source) {
|
||||
var wasPending = source._status === 'pending';
|
||||
|
||||
source._status = 'rejected';
|
||||
|
||||
if (wasPending) {
|
||||
decrementPendingSourceCnt();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function decrementPendingSourceCnt() {
|
||||
pendingSourceCnt--;
|
||||
if (!pendingSourceCnt) {
|
||||
reportEvents(cache);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function _fetchEventSource(source, callback) {
|
||||
|
@ -10782,8 +10851,7 @@ function EventManager(options) { // assumed to be a calendar
|
|||
var source = buildEventSource(sourceInput);
|
||||
if (source) {
|
||||
sources.push(source);
|
||||
pendingSourceCnt++;
|
||||
fetchEventSource(source, currentFetchID); // will eventually call reportEvents
|
||||
fetchEventSources([ source ], 'add'); // will eventually call reportEvents
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10833,19 +10901,120 @@ function EventManager(options) { // assumed to be a calendar
|
|||
}
|
||||
|
||||
|
||||
function removeEventSource(source) {
|
||||
sources = $.grep(sources, function(src) {
|
||||
return !isSourcesEqual(src, source);
|
||||
});
|
||||
// remove all client events from that source
|
||||
cache = $.grep(cache, function(e) {
|
||||
return !isSourcesEqual(e.source, source);
|
||||
function removeEventSource(matchInput) {
|
||||
removeSpecificEventSources(
|
||||
getEventSourcesByMatch(matchInput)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
// if called with no arguments, removes all.
|
||||
function removeEventSources(matchInputs) {
|
||||
if (matchInputs == null) {
|
||||
removeSpecificEventSources(sources, true); // isAll=true
|
||||
}
|
||||
else {
|
||||
removeSpecificEventSources(
|
||||
getEventSourcesByMatchArray(matchInputs)
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function removeSpecificEventSources(targetSources, isAll) {
|
||||
var i;
|
||||
|
||||
// cancel pending requests
|
||||
for (i = 0; i < targetSources.length; i++) {
|
||||
rejectEventSource(targetSources[i]);
|
||||
}
|
||||
|
||||
if (isAll) { // an optimization
|
||||
sources = [];
|
||||
cache = [];
|
||||
}
|
||||
else {
|
||||
// remove from persisted source list
|
||||
sources = $.grep(sources, function(source) {
|
||||
for (i = 0; i < targetSources.length; i++) {
|
||||
if (source === targetSources[i]) {
|
||||
return false; // exclude
|
||||
}
|
||||
}
|
||||
return true; // include
|
||||
});
|
||||
|
||||
cache = excludeEventsBySources(cache, targetSources);
|
||||
}
|
||||
|
||||
reportEvents(cache);
|
||||
}
|
||||
|
||||
|
||||
function isSourcesEqual(source1, source2) {
|
||||
function getEventSources() {
|
||||
return sources.slice(1); // returns a shallow copy of sources with stickySource removed
|
||||
}
|
||||
|
||||
|
||||
function getEventSourceById(id) {
|
||||
return $.grep(sources, function(source) {
|
||||
return source.id && source.id === id;
|
||||
})[0];
|
||||
}
|
||||
|
||||
|
||||
// like getEventSourcesByMatch, but accepts multple match criteria (like multiple IDs)
|
||||
function getEventSourcesByMatchArray(matchInputs) {
|
||||
|
||||
// coerce into an array
|
||||
if (!matchInputs) {
|
||||
matchInputs = [];
|
||||
}
|
||||
else if (!$.isArray(matchInputs)) {
|
||||
matchInputs = [ matchInputs ];
|
||||
}
|
||||
|
||||
var matchingSources = [];
|
||||
var i;
|
||||
|
||||
// resolve raw inputs to real event source objects
|
||||
for (i = 0; i < matchInputs.length; i++) {
|
||||
matchingSources.push.apply( // append
|
||||
matchingSources,
|
||||
getEventSourcesByMatch(matchInputs[i])
|
||||
);
|
||||
}
|
||||
|
||||
return matchingSources;
|
||||
}
|
||||
|
||||
|
||||
// matchInput can either by a real event source object, an ID, or the function/URL for the source.
|
||||
// returns an array of matching source objects.
|
||||
function getEventSourcesByMatch(matchInput) {
|
||||
var i, source;
|
||||
|
||||
// given an proper event source object
|
||||
for (i = 0; i < sources.length; i++) {
|
||||
source = sources[i];
|
||||
if (source === matchInput) {
|
||||
return [ source ];
|
||||
}
|
||||
}
|
||||
|
||||
// an ID match
|
||||
source = getEventSourceById(matchInput);
|
||||
if (source) {
|
||||
return [ source ];
|
||||
}
|
||||
|
||||
return $.grep(sources, function(source) {
|
||||
return isSourcesEquivalent(matchInput, source);
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
function isSourcesEquivalent(source1, source2) {
|
||||
return source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2);
|
||||
}
|
||||
|
||||
|
@ -10860,6 +11029,20 @@ function EventManager(options) { // assumed to be a calendar
|
|||
}
|
||||
|
||||
|
||||
// util
|
||||
// returns a filtered array without events that are part of any of the given sources
|
||||
function excludeEventsBySources(specificEvents, specificSources) {
|
||||
return $.grep(specificEvents, function(event) {
|
||||
for (var i = 0; i < specificSources.length; i++) {
|
||||
if (event.source === specificSources[i]) {
|
||||
return false; // exclude
|
||||
}
|
||||
}
|
||||
return true; // keep
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Manipulation
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
|
4
library/fullcalendar/fullcalendar.min.css
vendored
4
library/fullcalendar/fullcalendar.min.css
vendored
File diff suppressed because one or more lines are too long
10
library/fullcalendar/fullcalendar.min.js
vendored
10
library/fullcalendar/fullcalendar.min.js
vendored
File diff suppressed because one or more lines are too long
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* FullCalendar v2.7.3 Print Stylesheet
|
||||
* FullCalendar v2.8.0 Print Stylesheet
|
||||
* Docs & License: http://fullcalendar.io/
|
||||
* (c) 2016 Adam Shaw
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*!
|
||||
* FullCalendar v2.7.3 Google Calendar Plugin
|
||||
* FullCalendar v2.8.0 Google Calendar Plugin
|
||||
* Docs & License: http://fullcalendar.io/
|
||||
* (c) 2016 Adam Shaw
|
||||
*/
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -1,7 +1,3 @@
|
|||
.fc-scroller {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* fix borders */
|
||||
|
||||
.fc th:first-child,
|
||||
|
|
|
@ -1,7 +1,3 @@
|
|||
.fc-scroller {
|
||||
overflow: hidden !important;
|
||||
}
|
||||
|
||||
/* fix borders */
|
||||
|
||||
.fc th:first-child,
|
||||
|
|
Loading…
Reference in a new issue