fullcalendar.io-rails 2.7.3.0 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: edca9dfd59fd275f3204a717462b018935f9d9b0
4
- data.tar.gz: 508cb4c158ebcc8c2e6b82e8b65ffc711ce8a43e
3
+ metadata.gz: 97c1c9f136922333dd29691a912b6177fee23405
4
+ data.tar.gz: 92a2a4efc4388a10ceeaca3df3be51fa28346931
5
5
  SHA512:
6
- metadata.gz: 237729fcf2f2c587b529ed32d36226017ff6b3bf347aa2a519f1f1978f0ba5710e405db0b20408d3d5a87390612dd1aa55992b5127b7db0fb2d128d80a721b5c
7
- data.tar.gz: 3a617b5a0537d9ffd6d73215616fb900a0b47ad811a031ca6cddd43a1c9a6c2643580bcbf455943334b82d0a3864674b3d4735f055717568a1873a8c05b980e1
6
+ metadata.gz: e508564ee09050aea7351c7bd31d2122d41e8adae7a99ee05f6678692f988afd1793160e5a8fc16c8cc1f7e2e4e0119962dad3a89e94d509e47a926c34233e02
7
+ data.tar.gz: 2dc54784ae31c0b61b8c2099acd570ea283ff0b79804f41c597cd01030347700074c780fb3b1bf5cc03ad4ff7f1e8ae13ae9b245e1c2b2a61a3064fcd6057be9
@@ -1,5 +1,5 @@
1
1
  module Fullcalendario
2
2
  module Rails
3
- VERSION = "2.7.3.0"
3
+ VERSION = "2.8.0"
4
4
  end
5
5
  end
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * FullCalendar v2.7.3
2
+ * FullCalendar v2.8.0
3
3
  * Docs & License: http://fullcalendar.io/
4
4
  * (c) 2016 Adam Shaw
5
5
  */
@@ -19,7 +19,7 @@
19
19
  ;;
20
20
 
21
21
  var FC = $.fullCalendar = {
22
- version: "2.7.3",
22
+ version: "2.8.0",
23
23
  internalApiVersion: 4
24
24
  };
25
25
  var fcViews = FC.views = {};
@@ -1054,6 +1054,20 @@ function debounce(func, wait, immediate) {
1054
1054
  };
1055
1055
  }
1056
1056
 
1057
+
1058
+ // HACK around jQuery's now A+ promises: execute callback synchronously if already resolved.
1059
+ // thenFunc shouldn't accept args.
1060
+ // similar to whenResources in Scheduler plugin.
1061
+ function syncThen(promise, thenFunc) {
1062
+ // not a promise, or an already-resolved promise?
1063
+ if (!promise || !promise.then || promise.state() === 'resolved') {
1064
+ return $.when(thenFunc()); // resolve immediately
1065
+ }
1066
+ else if (thenFunc) {
1067
+ return promise.then(thenFunc);
1068
+ }
1069
+ }
1070
+
1057
1071
  ;;
1058
1072
 
1059
1073
  var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
@@ -3960,7 +3974,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
3960
3974
  fillSegTag: 'div', // subclasses can override
3961
3975
 
3962
3976
 
3963
- // Builds the HTML needed for one fill segment. Generic enought o work with different types.
3977
+ // Builds the HTML needed for one fill segment. Generic enough to work with different types.
3964
3978
  fillSegHtml: function(type, seg) {
3965
3979
 
3966
3980
  // custom hooks per-type
@@ -8106,15 +8120,14 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
8106
8120
 
8107
8121
  this.calendar.freezeContentHeight();
8108
8122
 
8109
- return this.clear().then(function() { // clear the content first (async)
8123
+ return syncThen(this.clear(), function() { // clear the content first
8110
8124
  return (
8111
8125
  _this.displaying =
8112
- $.when(_this.displayView(date)) // displayView might return a promise
8113
- .then(function() {
8114
- _this.forceScroll(_this.computeInitialScroll(scrollState));
8115
- _this.calendar.unfreezeContentHeight();
8116
- _this.triggerRender();
8117
- })
8126
+ syncThen(_this.displayView(date), function() { // displayView might return a promise
8127
+ _this.forceScroll(_this.computeInitialScroll(scrollState));
8128
+ _this.calendar.unfreezeContentHeight();
8129
+ _this.triggerRender();
8130
+ })
8118
8131
  );
8119
8132
  });
8120
8133
  },
@@ -8128,7 +8141,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
8128
8141
  var displaying = this.displaying;
8129
8142
 
8130
8143
  if (displaying) { // previously displayed, or in the process of being displayed?
8131
- return displaying.then(function() { // wait for the display to finish
8144
+ return syncThen(displaying, function() { // wait for the display to finish
8132
8145
  _this.displaying = null;
8133
8146
  _this.clearEvents();
8134
8147
  return _this.clearView(); // might return a promise. chain it
@@ -9321,6 +9334,7 @@ function Calendar_constructor(element, overrides) {
9321
9334
  t.render = render;
9322
9335
  t.destroy = destroy;
9323
9336
  t.refetchEvents = refetchEvents;
9337
+ t.refetchEventSources = refetchEventSources;
9324
9338
  t.reportEvents = reportEvents;
9325
9339
  t.reportEventChange = reportEventChange;
9326
9340
  t.rerenderEvents = renderEvents; // `renderEvents` serves as a rerender. an API method
@@ -9511,6 +9525,7 @@ function Calendar_constructor(element, overrides) {
9511
9525
  EventManager.call(t, options);
9512
9526
  var isFetchNeeded = t.isFetchNeeded;
9513
9527
  var fetchEvents = t.fetchEvents;
9528
+ var fetchEventSources = t.fetchEventSources;
9514
9529
 
9515
9530
 
9516
9531
 
@@ -9750,11 +9765,16 @@ function Calendar_constructor(element, overrides) {
9750
9765
 
9751
9766
 
9752
9767
  function refetchEvents() { // can be called as an API method
9753
- destroyEvents(); // so that events are cleared before user starts waiting for AJAX
9754
9768
  fetchAndRenderEvents();
9755
9769
  }
9756
9770
 
9757
9771
 
9772
+ // TODO: move this into EventManager?
9773
+ function refetchEventSources(matchInputs) {
9774
+ fetchEventSources(t.getEventSourcesByMatchArray(matchInputs));
9775
+ }
9776
+
9777
+
9758
9778
  function renderEvents() { // destroys old events if previously rendered
9759
9779
  if (elementVisible()) {
9760
9780
  freezeContentHeight();
@@ -9762,13 +9782,6 @@ function Calendar_constructor(element, overrides) {
9762
9782
  unfreezeContentHeight();
9763
9783
  }
9764
9784
  }
9765
-
9766
-
9767
- function destroyEvents() {
9768
- freezeContentHeight();
9769
- currentView.clearEvents();
9770
- unfreezeContentHeight();
9771
- }
9772
9785
 
9773
9786
 
9774
9787
  function getAndRenderEvents() {
@@ -9979,7 +9992,7 @@ function Calendar_constructor(element, overrides) {
9979
9992
 
9980
9993
  Calendar.defaults = {
9981
9994
 
9982
- titleRangeSeparator: ' \u2014 ', // emphasized dash
9995
+ titleRangeSeparator: ' \u2013 ', // en dash
9983
9996
  monthYearFormat: 'MMMM YYYY', // required for en. other languages rely on datepicker computable option
9984
9997
 
9985
9998
  defaultTimedEventDuration: '02:00:00',
@@ -10528,14 +10541,14 @@ function Header(calendar, options) {
10528
10541
 
10529
10542
  function disableButton(buttonName) {
10530
10543
  el.find('.fc-' + buttonName + '-button')
10531
- .attr('disabled', 'disabled')
10544
+ .prop('disabled', true)
10532
10545
  .addClass(tm + '-state-disabled');
10533
10546
  }
10534
10547
 
10535
10548
 
10536
10549
  function enableButton(buttonName) {
10537
10550
  el.find('.fc-' + buttonName + '-button')
10538
- .removeAttr('disabled')
10551
+ .prop('disabled', false)
10539
10552
  .removeClass(tm + '-state-disabled');
10540
10553
  }
10541
10554
 
@@ -10566,8 +10579,14 @@ function EventManager(options) { // assumed to be a calendar
10566
10579
  // exports
10567
10580
  t.isFetchNeeded = isFetchNeeded;
10568
10581
  t.fetchEvents = fetchEvents;
10582
+ t.fetchEventSources = fetchEventSources;
10583
+ t.getEventSources = getEventSources;
10584
+ t.getEventSourceById = getEventSourceById;
10585
+ t.getEventSourcesByMatchArray = getEventSourcesByMatchArray;
10586
+ t.getEventSourcesByMatch = getEventSourcesByMatch;
10569
10587
  t.addEventSource = addEventSource;
10570
10588
  t.removeEventSource = removeEventSource;
10589
+ t.removeEventSources = removeEventSources;
10571
10590
  t.updateEvent = updateEvent;
10572
10591
  t.renderEvent = renderEvent;
10573
10592
  t.removeEvents = removeEvents;
@@ -10585,8 +10604,7 @@ function EventManager(options) { // assumed to be a calendar
10585
10604
  var stickySource = { events: [] };
10586
10605
  var sources = [ stickySource ];
10587
10606
  var rangeStart, rangeEnd;
10588
- var currentFetchID = 0;
10589
- var pendingSourceCnt = 0;
10607
+ var pendingSourceCnt = 0; // outstanding fetch requests, max one per source
10590
10608
  var cache = []; // holds events that have already been expanded
10591
10609
 
10592
10610
 
@@ -10616,23 +10634,58 @@ function EventManager(options) { // assumed to be a calendar
10616
10634
  function fetchEvents(start, end) {
10617
10635
  rangeStart = start;
10618
10636
  rangeEnd = end;
10619
- cache = [];
10620
- var fetchID = ++currentFetchID;
10621
- var len = sources.length;
10622
- pendingSourceCnt = len;
10623
- for (var i=0; i<len; i++) {
10624
- fetchEventSource(sources[i], fetchID);
10637
+ fetchEventSources(sources, 'reset');
10638
+ }
10639
+
10640
+
10641
+ // expects an array of event source objects (the originals, not copies)
10642
+ // `specialFetchType` is an optimization parameter that affects purging of the event cache.
10643
+ function fetchEventSources(specificSources, specialFetchType) {
10644
+ var i, source;
10645
+
10646
+ if (specialFetchType === 'reset') {
10647
+ cache = [];
10648
+ }
10649
+ else if (specialFetchType !== 'add') {
10650
+ cache = excludeEventsBySources(cache, specificSources);
10651
+ }
10652
+
10653
+ for (i = 0; i < specificSources.length; i++) {
10654
+ source = specificSources[i];
10655
+
10656
+ // already-pending sources have already been accounted for in pendingSourceCnt
10657
+ if (source._status !== 'pending') {
10658
+ pendingSourceCnt++;
10659
+ }
10660
+
10661
+ source._fetchId = (source._fetchId || 0) + 1;
10662
+ source._status = 'pending';
10663
+ }
10664
+
10665
+ for (i = 0; i < specificSources.length; i++) {
10666
+ source = specificSources[i];
10667
+
10668
+ tryFetchEventSource(source, source._fetchId);
10625
10669
  }
10626
10670
  }
10627
-
10628
-
10629
- function fetchEventSource(source, fetchID) {
10671
+
10672
+
10673
+ // fetches an event source and processes its result ONLY if it is still the current fetch.
10674
+ // caller is responsible for incrementing pendingSourceCnt first.
10675
+ function tryFetchEventSource(source, fetchId) {
10630
10676
  _fetchEventSource(source, function(eventInputs) {
10631
10677
  var isArraySource = $.isArray(source.events);
10632
10678
  var i, eventInput;
10633
10679
  var abstractEvent;
10634
10680
 
10635
- if (fetchID == currentFetchID) {
10681
+ if (
10682
+ // is this the source's most recent fetch?
10683
+ // if not, rely on an upcoming fetch of this source to decrement pendingSourceCnt
10684
+ fetchId === source._fetchId &&
10685
+ // event source no longer valid?
10686
+ source._status !== 'rejected'
10687
+ ) {
10688
+ source._status = 'resolved';
10636
10689
 
10637
10690
  if (eventInputs) {
10638
10691
  for (i = 0; i < eventInputs.length; i++) {
@@ -10654,13 +10707,29 @@ function EventManager(options) { // assumed to be a calendar
10654
10707
  }
10655
10708
  }
10656
10709
 
10657
- pendingSourceCnt--;
10658
- if (!pendingSourceCnt) {
10659
- reportEvents(cache);
10660
- }
10710
+ decrementPendingSourceCnt();
10661
10711
  }
10662
10712
  });
10663
10713
  }
10714
+
10715
+
10716
+ function rejectEventSource(source) {
10717
+ var wasPending = source._status === 'pending';
10718
+
10719
+ source._status = 'rejected';
10720
+
10721
+ if (wasPending) {
10722
+ decrementPendingSourceCnt();
10723
+ }
10724
+ }
10725
+
10726
+
10727
+ function decrementPendingSourceCnt() {
10728
+ pendingSourceCnt--;
10729
+ if (!pendingSourceCnt) {
10730
+ reportEvents(cache);
10731
+ }
10732
+ }
10664
10733
 
10665
10734
 
10666
10735
  function _fetchEventSource(source, callback) {
@@ -10776,14 +10845,13 @@ function EventManager(options) { // assumed to be a calendar
10776
10845
 
10777
10846
  /* Sources
10778
10847
  -----------------------------------------------------------------------------*/
10779
-
10848
+
10780
10849
 
10781
10850
  function addEventSource(sourceInput) {
10782
10851
  var source = buildEventSource(sourceInput);
10783
10852
  if (source) {
10784
10853
  sources.push(source);
10785
- pendingSourceCnt++;
10786
- fetchEventSource(source, currentFetchID); // will eventually call reportEvents
10854
+ fetchEventSources([ source ], 'add'); // will eventually call reportEvents
10787
10855
  }
10788
10856
  }
10789
10857
 
@@ -10833,19 +10901,120 @@ function EventManager(options) { // assumed to be a calendar
10833
10901
  }
10834
10902
 
10835
10903
 
10836
- function removeEventSource(source) {
10837
- sources = $.grep(sources, function(src) {
10838
- return !isSourcesEqual(src, source);
10839
- });
10840
- // remove all client events from that source
10841
- cache = $.grep(cache, function(e) {
10842
- return !isSourcesEqual(e.source, source);
10843
- });
10904
+ function removeEventSource(matchInput) {
10905
+ removeSpecificEventSources(
10906
+ getEventSourcesByMatch(matchInput)
10907
+ );
10908
+ }
10909
+
10910
+
10911
+ // if called with no arguments, removes all.
10912
+ function removeEventSources(matchInputs) {
10913
+ if (matchInputs == null) {
10914
+ removeSpecificEventSources(sources, true); // isAll=true
10915
+ }
10916
+ else {
10917
+ removeSpecificEventSources(
10918
+ getEventSourcesByMatchArray(matchInputs)
10919
+ );
10920
+ }
10921
+ }
10922
+
10923
+
10924
+ function removeSpecificEventSources(targetSources, isAll) {
10925
+ var i;
10926
+
10927
+ // cancel pending requests
10928
+ for (i = 0; i < targetSources.length; i++) {
10929
+ rejectEventSource(targetSources[i]);
10930
+ }
10931
+
10932
+ if (isAll) { // an optimization
10933
+ sources = [];
10934
+ cache = [];
10935
+ }
10936
+ else {
10937
+ // remove from persisted source list
10938
+ sources = $.grep(sources, function(source) {
10939
+ for (i = 0; i < targetSources.length; i++) {
10940
+ if (source === targetSources[i]) {
10941
+ return false; // exclude
10942
+ }
10943
+ }
10944
+ return true; // include
10945
+ });
10946
+
10947
+ cache = excludeEventsBySources(cache, targetSources);
10948
+ }
10949
+
10844
10950
  reportEvents(cache);
10845
10951
  }
10846
10952
 
10847
10953
 
10848
- function isSourcesEqual(source1, source2) {
10954
+ function getEventSources() {
10955
+ return sources.slice(1); // returns a shallow copy of sources with stickySource removed
10956
+ }
10957
+
10958
+
10959
+ function getEventSourceById(id) {
10960
+ return $.grep(sources, function(source) {
10961
+ return source.id && source.id === id;
10962
+ })[0];
10963
+ }
10964
+
10965
+
10966
+ // like getEventSourcesByMatch, but accepts multple match criteria (like multiple IDs)
10967
+ function getEventSourcesByMatchArray(matchInputs) {
10968
+
10969
+ // coerce into an array
10970
+ if (!matchInputs) {
10971
+ matchInputs = [];
10972
+ }
10973
+ else if (!$.isArray(matchInputs)) {
10974
+ matchInputs = [ matchInputs ];
10975
+ }
10976
+
10977
+ var matchingSources = [];
10978
+ var i;
10979
+
10980
+ // resolve raw inputs to real event source objects
10981
+ for (i = 0; i < matchInputs.length; i++) {
10982
+ matchingSources.push.apply( // append
10983
+ matchingSources,
10984
+ getEventSourcesByMatch(matchInputs[i])
10985
+ );
10986
+ }
10987
+
10988
+ return matchingSources;
10989
+ }
10990
+
10991
+
10992
+ // matchInput can either by a real event source object, an ID, or the function/URL for the source.
10993
+ // returns an array of matching source objects.
10994
+ function getEventSourcesByMatch(matchInput) {
10995
+ var i, source;
10996
+
10997
+ // given an proper event source object
10998
+ for (i = 0; i < sources.length; i++) {
10999
+ source = sources[i];
11000
+ if (source === matchInput) {
11001
+ return [ source ];
11002
+ }
11003
+ }
11004
+
11005
+ // an ID match
11006
+ source = getEventSourceById(matchInput);
11007
+ if (source) {
11008
+ return [ source ];
11009
+ }
11010
+
11011
+ return $.grep(sources, function(source) {
11012
+ return isSourcesEquivalent(matchInput, source);
11013
+ });
11014
+ }
11015
+
11016
+
11017
+ function isSourcesEquivalent(source1, source2) {
10849
11018
  return source1 && source2 && getSourcePrimitive(source1) == getSourcePrimitive(source2);
10850
11019
  }
10851
11020
 
@@ -10858,6 +11027,20 @@ function EventManager(options) { // assumed to be a calendar
10858
11027
  ) ||
10859
11028
  source; // the given argument *is* the primitive
10860
11029
  }
11030
+
11031
+
11032
+ // util
11033
+ // returns a filtered array without events that are part of any of the given sources
11034
+ function excludeEventsBySources(specificEvents, specificSources) {
11035
+ return $.grep(specificEvents, function(event) {
11036
+ for (var i = 0; i < specificSources.length; i++) {
11037
+ if (event.source === specificSources[i]) {
11038
+ return false; // exclude
11039
+ }
11040
+ }
11041
+ return true; // keep
11042
+ });
11043
+ }
10861
11044
 
10862
11045
 
10863
11046