fullcalendar.io-rails 2.9.0 → 2.9.1

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: 8d30dd3218499cddafae61a0749e8fb9ca748b74
4
- data.tar.gz: 5c3f5fedc1f56da63e9dc095df5e46924c02e23a
3
+ metadata.gz: c0bebf9a03f44e166f1bb2f582fcdefae588048d
4
+ data.tar.gz: 51203a4a908a30503e0b96986fbd2fb33e5b6d23
5
5
  SHA512:
6
- metadata.gz: 07ed7e3d07243e40f9e8e0c1ddd80eaaaf4f8c25d8e040d701d4236d12bc600f4a40c8d10698a024744d677de5611590a199c54ee76cd62effa9667a71e6463b
7
- data.tar.gz: b93ccf3cf603cfb261b881fd29faa4b1a7309cbad46395afd1a2d594945f6c0170749d3bf5c19bc94630d37dcac010fcdb6a8b1301e0e8ee7fdae66f42c3556c
6
+ metadata.gz: cee3cb8ea1fd78a1661ae39649aee060232fc87dd6b09fb671dc287e0a526761f128f2849a4028060e1c457978c94ac79fc9de348f399ad7af899cf242bec72b
7
+ data.tar.gz: 6fe447d37fcc65e6f1463982e668b1fb93ecb8bf405024e32d981a8c61582ff9884e19730ba407df51c63256bd9c83f80635a3a8637605d2041c9323d8a7f37d
@@ -1,5 +1,5 @@
1
1
  module Fullcalendario
2
2
  module Rails
3
- VERSION = "2.9.0"
3
+ VERSION = "2.9.1"
4
4
  end
5
5
  end
@@ -1,7 +1,7 @@
1
1
  /*!
2
- * FullCalendar v2.9.0
3
- * Docs & License: http://fullcalendar.io/
4
- * (c) 2016 Adam Shaw
2
+ * <%= meta.title %> v<%= meta.version %>
3
+ * Docs & License: <%= meta.homepage %>
4
+ * (c) <%= meta.copyright %>
5
5
  */
6
6
 
7
7
  (function(factory) {
@@ -19,8 +19,8 @@
19
19
  ;;
20
20
 
21
21
  var FC = $.fullCalendar = {
22
- version: "2.9.0",
23
- internalApiVersion: 4
22
+ version: "<%= meta.version %>",
23
+ internalApiVersion: 5
24
24
  };
25
25
  var fcViews = FC.views = {};
26
26
 
@@ -2263,17 +2263,6 @@ var CoordCache = FC.CoordCache = Class.extend({
2263
2263
  },
2264
2264
 
2265
2265
 
2266
- // Compute and return what the elements' bounding rectangle is, from the user's perspective.
2267
- // Right now, only returns a rectangle if constrained by an overflow:scroll element.
2268
- queryBoundingRect: function() {
2269
- var scrollParentEl = getScrollParent(this.els.eq(0));
2270
-
2271
- if (!scrollParentEl.is(document)) {
2272
- return getClientRect(scrollParentEl);
2273
- }
2274
- },
2275
-
2276
-
2277
2266
  // Populates the left/right internal coordinate arrays
2278
2267
  buildElHorizontals: function() {
2279
2268
  var lefts = [];
@@ -2313,42 +2302,36 @@ var CoordCache = FC.CoordCache = Class.extend({
2313
2302
 
2314
2303
 
2315
2304
  // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
2316
- // If no intersection is made, or outside of the boundingRect, returns undefined.
2305
+ // If no intersection is made, returns undefined.
2317
2306
  getHorizontalIndex: function(leftOffset) {
2318
2307
  this.ensureBuilt();
2319
2308
 
2320
- var boundingRect = this.boundingRect;
2321
2309
  var lefts = this.lefts;
2322
2310
  var rights = this.rights;
2323
2311
  var len = lefts.length;
2324
2312
  var i;
2325
2313
 
2326
- if (!boundingRect || (leftOffset >= boundingRect.left && leftOffset < boundingRect.right)) {
2327
- for (i = 0; i < len; i++) {
2328
- if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
2329
- return i;
2330
- }
2314
+ for (i = 0; i < len; i++) {
2315
+ if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
2316
+ return i;
2331
2317
  }
2332
2318
  }
2333
2319
  },
2334
2320
 
2335
2321
 
2336
2322
  // Given a top offset (from document top), returns the index of the el that it vertically intersects.
2337
- // If no intersection is made, or outside of the boundingRect, returns undefined.
2323
+ // If no intersection is made, returns undefined.
2338
2324
  getVerticalIndex: function(topOffset) {
2339
2325
  this.ensureBuilt();
2340
2326
 
2341
- var boundingRect = this.boundingRect;
2342
2327
  var tops = this.tops;
2343
2328
  var bottoms = this.bottoms;
2344
2329
  var len = tops.length;
2345
2330
  var i;
2346
2331
 
2347
- if (!boundingRect || (topOffset >= boundingRect.top && topOffset < boundingRect.bottom)) {
2348
- for (i = 0; i < len; i++) {
2349
- if (topOffset >= tops[i] && topOffset < bottoms[i]) {
2350
- return i;
2351
- }
2332
+ for (i = 0; i < len; i++) {
2333
+ if (topOffset >= tops[i] && topOffset < bottoms[i]) {
2334
+ return i;
2352
2335
  }
2353
2336
  }
2354
2337
  },
@@ -2424,6 +2407,32 @@ var CoordCache = FC.CoordCache = Class.extend({
2424
2407
  getHeight: function(topIndex) {
2425
2408
  this.ensureBuilt();
2426
2409
  return this.bottoms[topIndex] - this.tops[topIndex];
2410
+ },
2411
+
2412
+
2413
+ // Bounding Rect
2414
+ // TODO: decouple this from CoordCache
2415
+
2416
+ // Compute and return what the elements' bounding rectangle is, from the user's perspective.
2417
+ // Right now, only returns a rectangle if constrained by an overflow:scroll element.
2418
+ queryBoundingRect: function() {
2419
+ var scrollParentEl = getScrollParent(this.els.eq(0));
2420
+
2421
+ if (!scrollParentEl.is(document)) {
2422
+ return getClientRect(scrollParentEl);
2423
+ }
2424
+ },
2425
+
2426
+ isPointInBounds: function(leftOffset, topOffset) {
2427
+ return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset);
2428
+ },
2429
+
2430
+ isLeftInBounds: function(leftOffset) {
2431
+ return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right);
2432
+ },
2433
+
2434
+ isTopInBounds: function(topOffset) {
2435
+ return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom);
2427
2436
  }
2428
2437
 
2429
2438
  });
@@ -3259,11 +3268,11 @@ var MouseFollower = Class.extend(ListenerMixin, {
3259
3268
  var _this = this;
3260
3269
  var revertDuration = this.options.revertDuration;
3261
3270
 
3262
- function complete() {
3263
- this.isAnimating = false;
3271
+ function complete() { // might be called by .animate(), which might change `this` context
3272
+ _this.isAnimating = false;
3264
3273
  _this.removeElement();
3265
3274
 
3266
- this.top0 = this.left0 = null; // reset state for future updatePosition calls
3275
+ _this.top0 = _this.left0 = null; // reset state for future updatePosition calls
3267
3276
 
3268
3277
  if (callback) {
3269
3278
  callback();
@@ -3583,8 +3592,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
3583
3592
  // jQuery will take care of unregistering them when removeElement gets called.
3584
3593
  this.el.on(name, function(ev) {
3585
3594
  if (
3586
- !$(ev.target).is('.fc-event-container *, .fc-more') && // not an an event element, or "more.." link
3587
- !$(ev.target).closest('.fc-popover').length // not on a popover (like the "more.." events one)
3595
+ !$(ev.target).is('.fc-event-container *, .fc-more') // not an an event element, or "more.." link
3588
3596
  ) {
3589
3597
  return handler.call(_this, ev);
3590
3598
  }
@@ -3683,6 +3691,7 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
3683
3691
  scroll: view.opt('dragScroll'),
3684
3692
  interactionStart: function() {
3685
3693
  dayClickHit = dragListener.origHit; // for dayClick, where no dragging happens
3694
+ selectionSpan = null;
3686
3695
  },
3687
3696
  dragStart: function() {
3688
3697
  view.unselect(); // since we could be rendering a new selection, we want to clear any old one
@@ -3709,10 +3718,12 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
3709
3718
  }
3710
3719
  }
3711
3720
  },
3712
- hitOut: function() {
3721
+ hitOut: function() { // called before mouse moves to a different hit OR moved out of all hits
3713
3722
  dayClickHit = null;
3714
3723
  selectionSpan = null;
3715
3724
  _this.unrenderSelection();
3725
+ },
3726
+ hitDone: function() { // called after a hitOut OR before a dragEnd
3716
3727
  enableCursor();
3717
3728
  },
3718
3729
  interactionEnd: function(ev, isCancelled) {
@@ -3731,7 +3742,6 @@ var Grid = FC.Grid = Class.extend(ListenerMixin, MouseIgnorerMixin, {
3731
3742
  // the selection will already have been rendered. just report it
3732
3743
  view.reportSelection(selectionSpan, ev);
3733
3744
  }
3734
- enableCursor();
3735
3745
  }
3736
3746
  }
3737
3747
  });
@@ -4172,7 +4182,7 @@ Grid.mixin({
4172
4182
 
4173
4183
 
4174
4184
  // Generates an array of classNames to be used for the default rendering of a background event.
4175
- // Called by the fill system.
4185
+ // Called by fillSegHtml.
4176
4186
  bgEventSegClasses: function(seg) {
4177
4187
  var event = seg.event;
4178
4188
  var source = event.source || {};
@@ -4185,7 +4195,7 @@ Grid.mixin({
4185
4195
 
4186
4196
 
4187
4197
  // Generates a semicolon-separated CSS string to be used for the default rendering of a background event.
4188
- // Called by the fill system.
4198
+ // Called by fillSegHtml.
4189
4199
  bgEventSegCss: function(seg) {
4190
4200
  return {
4191
4201
  'background-color': this.getSegSkinCss(seg)['background-color']
@@ -4194,32 +4204,68 @@ Grid.mixin({
4194
4204
 
4195
4205
 
4196
4206
  // Generates an array of classNames to be used for the rendering business hours overlay. Called by the fill system.
4207
+ // Called by fillSegHtml.
4197
4208
  businessHoursSegClasses: function(seg) {
4198
4209
  return [ 'fc-nonbusiness', 'fc-bgevent' ];
4199
4210
  },
4200
4211
 
4201
4212
 
4213
+ /* Business Hours
4214
+ ------------------------------------------------------------------------------------------------------------------*/
4215
+
4216
+
4217
+ // Compute business hour segs for the grid's current date range.
4218
+ // Caller must ask if whole-day business hours are needed.
4219
+ buildBusinessHourSegs: function(wholeDay) {
4220
+ var events = this.view.calendar.getCurrentBusinessHourEvents(wholeDay);
4221
+
4222
+ // HACK. Eventually refactor business hours "events" system.
4223
+ // If no events are given, but businessHours is activated, this means the entire visible range should be
4224
+ // marked as *not* business-hours, via inverse-background rendering.
4225
+ if (
4226
+ !events.length &&
4227
+ this.view.calendar.options.businessHours // don't access view option. doesn't update with dynamic options
4228
+ ) {
4229
+ events = [
4230
+ $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, {
4231
+ start: this.view.end, // guaranteed out-of-range
4232
+ end: this.view.end, // "
4233
+ dow: null
4234
+ })
4235
+ ];
4236
+ }
4237
+
4238
+ return this.eventsToSegs(events);
4239
+ },
4240
+
4241
+
4202
4242
  /* Handlers
4203
4243
  ------------------------------------------------------------------------------------------------------------------*/
4204
4244
 
4205
4245
 
4206
- // Attaches event-element-related handlers to the container element and leverage bubbling
4246
+ // Attaches event-element-related handlers for *all* rendered event segments of the view.
4207
4247
  bindSegHandlers: function() {
4208
- this.bindSegHandler('touchstart', this.handleSegTouchStart);
4209
- this.bindSegHandler('touchend', this.handleSegTouchEnd);
4210
- this.bindSegHandler('mouseenter', this.handleSegMouseover);
4211
- this.bindSegHandler('mouseleave', this.handleSegMouseout);
4212
- this.bindSegHandler('mousedown', this.handleSegMousedown);
4213
- this.bindSegHandler('click', this.handleSegClick);
4248
+ this.bindSegHandlersToEl(this.el);
4249
+ },
4250
+
4251
+
4252
+ // Attaches event-element-related handlers to an arbitrary container element. leverages bubbling.
4253
+ bindSegHandlersToEl: function(el) {
4254
+ this.bindSegHandlerToEl(el, 'touchstart', this.handleSegTouchStart);
4255
+ this.bindSegHandlerToEl(el, 'touchend', this.handleSegTouchEnd);
4256
+ this.bindSegHandlerToEl(el, 'mouseenter', this.handleSegMouseover);
4257
+ this.bindSegHandlerToEl(el, 'mouseleave', this.handleSegMouseout);
4258
+ this.bindSegHandlerToEl(el, 'mousedown', this.handleSegMousedown);
4259
+ this.bindSegHandlerToEl(el, 'click', this.handleSegClick);
4214
4260
  },
4215
4261
 
4216
4262
 
4217
4263
  // Executes a handler for any a user-interaction on a segment.
4218
4264
  // Handler gets called with (seg, ev), and with the `this` context of the Grid
4219
- bindSegHandler: function(name, handler) {
4265
+ bindSegHandlerToEl: function(el, name, handler) {
4220
4266
  var _this = this;
4221
4267
 
4222
- this.el.on(name, '.fc-event-container > *', function(ev) {
4268
+ el.on(name, '.fc-event-container > *', function(ev) {
4223
4269
  var seg = $(this).data('fc-seg'); // grab segment data. put there by View::renderEvents
4224
4270
 
4225
4271
  // only call the handlers if there is not a drag/resize in progress
@@ -4353,6 +4399,7 @@ Grid.mixin({
4353
4399
  subjectEl: el,
4354
4400
  subjectCenter: true,
4355
4401
  interactionStart: function(ev) {
4402
+ seg.component = _this; // for renderDrag
4356
4403
  isDragging = false;
4357
4404
  mouseFollower = new MouseFollower(seg.el, {
4358
4405
  additionalClass: 'fc-dragging',
@@ -4421,6 +4468,8 @@ Grid.mixin({
4421
4468
  enableCursor();
4422
4469
  },
4423
4470
  interactionEnd: function(ev) {
4471
+ delete seg.component; // prevent side effects
4472
+
4424
4473
  // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
4425
4474
  mouseFollower.stop(!dropLocation, function() {
4426
4475
  if (isDragging) {
@@ -5656,9 +5705,7 @@ var DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {
5656
5705
 
5657
5706
 
5658
5707
  renderBusinessHours: function() {
5659
- var events = this.view.calendar.getBusinessHoursEvents(true); // wholeDay=true
5660
- var segs = this.eventsToSegs(events);
5661
-
5708
+ var segs = this.buildBusinessHourSegs(true); // wholeDay=true
5662
5709
  this.renderFill('businessHours', segs, 'bgevent');
5663
5710
  },
5664
5711
 
@@ -5814,11 +5861,13 @@ var DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {
5814
5861
 
5815
5862
 
5816
5863
  queryHit: function(leftOffset, topOffset) {
5817
- var col = this.colCoordCache.getHorizontalIndex(leftOffset);
5818
- var row = this.rowCoordCache.getVerticalIndex(topOffset);
5864
+ if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) {
5865
+ var col = this.colCoordCache.getHorizontalIndex(leftOffset);
5866
+ var row = this.rowCoordCache.getVerticalIndex(topOffset);
5819
5867
 
5820
- if (row != null && col != null) {
5821
- return this.getCellHit(row, col);
5868
+ if (row != null && col != null) {
5869
+ return this.getCellHit(row, col);
5870
+ }
5822
5871
  }
5823
5872
  },
5824
5873
 
@@ -5869,8 +5918,7 @@ var DayGrid = FC.DayGrid = Grid.extend(DayTableMixin, {
5869
5918
  this.renderHighlight(this.eventToSpan(eventLocation));
5870
5919
 
5871
5920
  // if a segment from the same calendar but another component is being dragged, render a helper event
5872
- if (seg && !seg.el.closest(this.el).length) {
5873
-
5921
+ if (seg && seg.component !== this) {
5874
5922
  return this.renderEventLocationHelper(eventLocation, seg); // returns mock event elements
5875
5923
  }
5876
5924
  },
@@ -6578,7 +6626,7 @@ DayGrid.mixin({
6578
6626
  options = {
6579
6627
  className: 'fc-more-popover',
6580
6628
  content: this.renderSegPopoverContent(row, col, segs),
6581
- parentEl: this.el,
6629
+ parentEl: this.view.el, // attach to root of view. guarantees outside of scrollbars.
6582
6630
  top: topEl.offset().top,
6583
6631
  autoHide: true, // when the user clicks elsewhere, hide the popover
6584
6632
  viewportConstrain: view.opt('popoverViewportConstrain'),
@@ -6601,6 +6649,10 @@ DayGrid.mixin({
6601
6649
 
6602
6650
  this.segPopover = new Popover(options);
6603
6651
  this.segPopover.show();
6652
+
6653
+ // the popover doesn't live within the grid's container element, and thus won't get the event
6654
+ // delegated-handlers for free. attach event-related handlers to the popover.
6655
+ this.bindSegHandlersToEl(this.segPopover.el);
6604
6656
  },
6605
6657
 
6606
6658
 
@@ -6910,27 +6962,30 @@ var TimeGrid = FC.TimeGrid = Grid.extend(DayTableMixin, {
6910
6962
  var snapsPerSlot = this.snapsPerSlot;
6911
6963
  var colCoordCache = this.colCoordCache;
6912
6964
  var slatCoordCache = this.slatCoordCache;
6913
- var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
6914
- var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
6915
-
6916
- if (colIndex != null && slatIndex != null) {
6917
- var slatTop = slatCoordCache.getTopOffset(slatIndex);
6918
- var slatHeight = slatCoordCache.getHeight(slatIndex);
6919
- var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
6920
- var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
6921
- var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
6922
- var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
6923
- var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
6924
-
6925
- return {
6926
- col: colIndex,
6927
- snap: snapIndex,
6928
- component: this, // needed unfortunately :(
6929
- left: colCoordCache.getLeftOffset(colIndex),
6930
- right: colCoordCache.getRightOffset(colIndex),
6931
- top: snapTop,
6932
- bottom: snapBottom
6933
- };
6965
+
6966
+ if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) {
6967
+ var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
6968
+ var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
6969
+
6970
+ if (colIndex != null && slatIndex != null) {
6971
+ var slatTop = slatCoordCache.getTopOffset(slatIndex);
6972
+ var slatHeight = slatCoordCache.getHeight(slatIndex);
6973
+ var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
6974
+ var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
6975
+ var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
6976
+ var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
6977
+ var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
6978
+
6979
+ return {
6980
+ col: colIndex,
6981
+ snap: snapIndex,
6982
+ component: this, // needed unfortunately :(
6983
+ left: colCoordCache.getLeftOffset(colIndex),
6984
+ right: colCoordCache.getRightOffset(colIndex),
6985
+ top: snapTop,
6986
+ bottom: snapBottom
6987
+ };
6988
+ }
6934
6989
  }
6935
6990
  },
6936
6991
 
@@ -7133,10 +7188,9 @@ var TimeGrid = FC.TimeGrid = Grid.extend(DayTableMixin, {
7133
7188
 
7134
7189
 
7135
7190
  renderBusinessHours: function() {
7136
- var events = this.view.calendar.getBusinessHoursEvents();
7137
- var segs = this.eventsToSegs(events);
7138
-
7139
- this.renderBusinessSegs(segs);
7191
+ this.renderBusinessSegs(
7192
+ this.buildBusinessHourSegs()
7193
+ );
7140
7194
  },
7141
7195
 
7142
7196
 
@@ -9807,16 +9861,33 @@ function Calendar_constructor(element, overrides) {
9807
9861
 
9808
9862
 
9809
9863
  function _calcSize() { // assumes elementVisible
9810
- if (typeof t.options.contentHeight === 'number') { // exists and not 'auto'
9811
- suggestedViewHeight = t.options.contentHeight;
9864
+ var contentHeightInput = t.options.contentHeight;
9865
+ var heightInput = t.options.height;
9866
+
9867
+ if (typeof contentHeightInput === 'number') { // exists and not 'auto'
9868
+ suggestedViewHeight = contentHeightInput;
9869
+ }
9870
+ else if (typeof contentHeightInput === 'function') { // exists and is a function
9871
+ suggestedViewHeight = contentHeightInput();
9872
+ }
9873
+ else if (typeof heightInput === 'number') { // exists and not 'auto'
9874
+ suggestedViewHeight = heightInput - queryHeaderHeight();
9875
+ }
9876
+ else if (typeof heightInput === 'function') { // exists and is a function
9877
+ suggestedViewHeight = heightInput() - queryHeaderHeight();
9812
9878
  }
9813
- else if (typeof t.options.height === 'number') { // exists and not 'auto'
9814
- suggestedViewHeight = t.options.height - (header.el ? header.el.outerHeight(true) : 0);
9879
+ else if (heightInput === 'parent') { // set to height of parent element
9880
+ suggestedViewHeight = element.parent().height() - queryHeaderHeight();
9815
9881
  }
9816
9882
  else {
9817
9883
  suggestedViewHeight = Math.round(content.width() / Math.max(t.options.aspectRatio, .5));
9818
9884
  }
9819
9885
  }
9886
+
9887
+
9888
+ function queryHeaderHeight() {
9889
+ return header.el ? header.el.outerHeight(true) : 0; // includes margin
9890
+ }
9820
9891
 
9821
9892
 
9822
9893
  function windowResize(ev) {
@@ -10272,7 +10343,7 @@ Calendar.defaults = {
10272
10343
  dayPopoverFormat: 'LL',
10273
10344
 
10274
10345
  handleWindowResize: true,
10275
- windowResizeDelay: 200, // milliseconds before an updateSize happens
10346
+ windowResizeDelay: 100, // milliseconds before an updateSize happens
10276
10347
 
10277
10348
  longPressDelay: 1000
10278
10349
 
@@ -11495,6 +11566,7 @@ function EventManager() { // assumed to be a calendar
11495
11566
 
11496
11567
  return out;
11497
11568
  }
11569
+ t.buildEventFromInput = buildEventFromInput;
11498
11570
 
11499
11571
 
11500
11572
  // Normalizes and assigns the given dates to the given partially-formed event object.
@@ -11618,6 +11690,7 @@ function EventManager() { // assumed to be a calendar
11618
11690
 
11619
11691
  return events;
11620
11692
  }
11693
+ t.expandEvent = expandEvent;
11621
11694
 
11622
11695
 
11623
11696
 
@@ -11811,53 +11884,6 @@ function EventManager() { // assumed to be a calendar
11811
11884
  }
11812
11885
 
11813
11886
 
11814
- /* Business Hours
11815
- -----------------------------------------------------------------------------------------*/
11816
-
11817
- t.getBusinessHoursEvents = getBusinessHoursEvents;
11818
-
11819
-
11820
- // Returns an array of events as to when the business hours occur in the given view.
11821
- // Abuse of our event system :(
11822
- function getBusinessHoursEvents(wholeDay) {
11823
- var optionVal = t.options.businessHours;
11824
- var defaultVal = {
11825
- className: 'fc-nonbusiness',
11826
- start: '09:00',
11827
- end: '17:00',
11828
- dow: [ 1, 2, 3, 4, 5 ], // monday - friday
11829
- rendering: 'inverse-background'
11830
- };
11831
- var view = t.getView();
11832
- var eventInput;
11833
-
11834
- if (optionVal) { // `true` (which means "use the defaults") or an override object
11835
- eventInput = $.extend(
11836
- {}, // copy to a new object in either case
11837
- defaultVal,
11838
- typeof optionVal === 'object' ? optionVal : {} // override the defaults
11839
- );
11840
- }
11841
-
11842
- if (eventInput) {
11843
-
11844
- // if a whole-day series is requested, clear the start/end times
11845
- if (wholeDay) {
11846
- eventInput.start = null;
11847
- eventInput.end = null;
11848
- }
11849
-
11850
- return expandEvent(
11851
- buildEventFromInput(eventInput),
11852
- view.start,
11853
- view.end
11854
- );
11855
- }
11856
-
11857
- return [];
11858
- }
11859
-
11860
-
11861
11887
  /* Overlapping / Constraining
11862
11888
  -----------------------------------------------------------------------------------------*/
11863
11889
 
@@ -11929,7 +11955,7 @@ function EventManager() { // assumed to be a calendar
11929
11955
 
11930
11956
  anyContainment = false;
11931
11957
  for (i = 0; i < constraintEvents.length; i++) {
11932
- if (eventContainsRange(constraintEvents[i], span)) {
11958
+ if (t.spanContainsSpan(constraintEvents[i], span)) {
11933
11959
  anyContainment = true;
11934
11960
  break;
11935
11961
  }
@@ -11987,7 +12013,7 @@ function EventManager() { // assumed to be a calendar
11987
12013
  function constraintToEvents(constraintInput) {
11988
12014
 
11989
12015
  if (constraintInput === 'businessHours') {
11990
- return getBusinessHoursEvents();
12016
+ return t.getCurrentBusinessHourEvents();
11991
12017
  }
11992
12018
 
11993
12019
  if (typeof constraintInput === 'object') {
@@ -11998,16 +12024,6 @@ function EventManager() { // assumed to be a calendar
11998
12024
  }
11999
12025
 
12000
12026
 
12001
- // Does the event's date range fully contain the given range?
12002
- // start/end already assumed to have stripped zones :(
12003
- function eventContainsRange(event, range) {
12004
- var eventStart = event.start.clone().stripZone();
12005
- var eventEnd = t.getEventEnd(event).stripZone();
12006
-
12007
- return range.start >= eventStart && range.end <= eventEnd;
12008
- }
12009
-
12010
-
12011
12027
  // Does the event's date range intersect with the given range?
12012
12028
  // start/end already assumed to have stripped zones :(
12013
12029
  function eventIntersectsRange(event, range) {
@@ -12031,6 +12047,16 @@ Calendar.prototype.normalizeEvent = function(event) {
12031
12047
  };
12032
12048
 
12033
12049
 
12050
+ // Does the given span (start, end, and other location information)
12051
+ // fully contain the other?
12052
+ Calendar.prototype.spanContainsSpan = function(outerSpan, innerSpan) {
12053
+ var eventStart = outerSpan.start.clone().stripZone();
12054
+ var eventEnd = this.getEventEnd(outerSpan).stripZone();
12055
+
12056
+ return innerSpan.start >= eventStart && innerSpan.end <= eventEnd;
12057
+ };
12058
+
12059
+
12034
12060
  // Returns a list of events that the given event should be compared against when being considered for a move to
12035
12061
  // the specified span. Attached to the Calendar's prototype because EventManager is a mixin for a Calendar.
12036
12062
  Calendar.prototype.getPeerEvents = function(span, event) {
@@ -12059,6 +12085,76 @@ function backupEventDates(event) {
12059
12085
  event._end = event.end ? event.end.clone() : null;
12060
12086
  }
12061
12087
 
12088
+
12089
+ /* Business Hours
12090
+ -----------------------------------------------------------------------------------------*/
12091
+
12092
+ var BUSINESS_HOUR_EVENT_DEFAULTS = {
12093
+ id: '_fcBusinessHours', // will relate events from different calls to expandEvent
12094
+ start: '09:00',
12095
+ end: '17:00',
12096
+ dow: [ 1, 2, 3, 4, 5 ], // monday - friday
12097
+ rendering: 'inverse-background'
12098
+ // classNames are defined in businessHoursSegClasses
12099
+ };
12100
+
12101
+ // Return events objects for business hours within the current view.
12102
+ // Abuse of our event system :(
12103
+ Calendar.prototype.getCurrentBusinessHourEvents = function(wholeDay) {
12104
+ return this.computeBusinessHourEvents(wholeDay, this.options.businessHours);
12105
+ };
12106
+
12107
+ // Given a raw input value from options, return events objects for business hours within the current view.
12108
+ Calendar.prototype.computeBusinessHourEvents = function(wholeDay, input) {
12109
+ if (input === true) {
12110
+ return this.expandBusinessHourEvents(wholeDay, [ {} ]);
12111
+ }
12112
+ else if ($.isPlainObject(input)) {
12113
+ return this.expandBusinessHourEvents(wholeDay, [ input ]);
12114
+ }
12115
+ else if ($.isArray(input)) {
12116
+ return this.expandBusinessHourEvents(wholeDay, input, true);
12117
+ }
12118
+ else {
12119
+ return [];
12120
+ }
12121
+ };
12122
+
12123
+ // inputs expected to be an array of objects.
12124
+ // if ignoreNoDow is true, will ignore entries that don't specify a day-of-week (dow) key.
12125
+ Calendar.prototype.expandBusinessHourEvents = function(wholeDay, inputs, ignoreNoDow) {
12126
+ var view = this.getView();
12127
+ var events = [];
12128
+ var i, input;
12129
+
12130
+ for (i = 0; i < inputs.length; i++) {
12131
+ input = inputs[i];
12132
+
12133
+ if (ignoreNoDow && !input.dow) {
12134
+ continue;
12135
+ }
12136
+
12137
+ // give defaults. will make a copy
12138
+ input = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, input);
12139
+
12140
+ // if a whole-day series is requested, clear the start/end times
12141
+ if (wholeDay) {
12142
+ input.start = null;
12143
+ input.end = null;
12144
+ }
12145
+
12146
+ events.push.apply(events, // append
12147
+ this.expandEvent(
12148
+ this.buildEventFromInput(input),
12149
+ view.start,
12150
+ view.end
12151
+ )
12152
+ );
12153
+ }
12154
+
12155
+ return events;
12156
+ };
12157
+
12062
12158
  ;;
12063
12159
 
12064
12160
  /* An abstract class for the "basic" views, as well as month view. Renders one or more rows of day cells.
@@ -13099,6 +13195,6 @@ fcViews.agendaWeek = {
13099
13195
  duration: { weeks: 1 }
13100
13196
  };
13101
13197
  ;;
13102
-
13103
- return FC; // export for Node/CommonJS
13198
+
13199
+ return FC; // export for Node/CommonJS
13104
13200
  });