fullcalendar.io-rails 2.7.3.0 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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