fullcalendar.io-rails 2.9.0 → 2.9.1

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: 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
  });