Ver Fonte

autolinting for src

Adam Shaw há 8 anos atrás
pai
commit
a84b3c517f
93 ficheiros alterados com 4614 adições e 4837 exclusões
  1. 268 285
      src/Calendar.ts
  2. 94 101
      src/Constraints.ts
  3. 110 118
      src/DateProfileGenerator.ts
  4. 39 42
      src/OptionsManager.ts
  5. 69 76
      src/Toolbar.ts
  6. 203 210
      src/View.ts
  7. 4 4
      src/ViewRegistry.ts
  8. 58 58
      src/ViewSpecManager.ts
  9. 111 115
      src/agenda/AgendaView.ts
  10. 186 189
      src/agenda/TimeGrid.ts
  11. 115 118
      src/agenda/TimeGridEventRenderer.ts
  12. 11 13
      src/agenda/TimeGridFillRenderer.ts
  13. 9 9
      src/agenda/TimeGridHelperRenderer.ts
  14. 3 3
      src/agenda/config.ts
  15. 74 76
      src/basic/BasicView.ts
  16. 6 6
      src/basic/BasicViewDateProfileGenerator.ts
  17. 232 240
      src/basic/DayGrid.ts
  18. 99 101
      src/basic/DayGridEventRenderer.ts
  19. 24 25
      src/basic/DayGridFillRenderer.ts
  20. 17 18
      src/basic/DayGridHelperRenderer.ts
  21. 3 3
      src/basic/MonthView.ts
  22. 7 7
      src/basic/MonthViewDateProfileGenerator.ts
  23. 4 4
      src/basic/config.ts
  24. 4 4
      src/common/Class.ts
  25. 76 76
      src/common/CoordCache.ts
  26. 117 126
      src/common/DragListener.ts
  27. 18 18
      src/common/EmitterMixin.ts
  28. 43 43
      src/common/GlobalEmitter.ts
  29. 54 55
      src/common/HitDragListener.ts
  30. 5 5
      src/common/Iterator.ts
  31. 8 9
      src/common/ListenerMixin.ts
  32. 4 4
      src/common/Mixin.ts
  33. 108 114
      src/common/Model.ts
  34. 46 48
      src/common/MouseFollower.ts
  35. 19 21
      src/common/ParsableModelMixin.ts
  36. 51 54
      src/common/Popover.ts
  37. 22 22
      src/common/Promise.ts
  38. 36 38
      src/common/RenderQueue.ts
  39. 23 23
      src/common/Scroller.ts
  40. 22 22
      src/common/TaskQueue.ts
  41. 8 8
      src/component/Component.ts
  42. 181 188
      src/component/DateComponent.ts
  43. 125 138
      src/component/DayTableMixin.ts
  44. 64 65
      src/component/InteractiveDateComponent.ts
  45. 21 21
      src/component/interactions/DateClicking.ts
  46. 42 44
      src/component/interactions/DateSelecting.ts
  47. 105 110
      src/component/interactions/EventDragging.ts
  48. 14 14
      src/component/interactions/EventPointing.ts
  49. 74 77
      src/component/interactions/EventResizing.ts
  50. 74 78
      src/component/interactions/ExternalDropping.ts
  51. 3 3
      src/component/interactions/Interaction.ts
  52. 1 1
      src/component/interactions/StandardInteractionsMixin.ts
  53. 17 17
      src/component/renderers/BusinessHourRenderer.ts
  54. 124 128
      src/component/renderers/EventRenderer.ts
  55. 29 30
      src/component/renderers/FillRenderer.ts
  56. 22 22
      src/component/renderers/HelperRenderer.ts
  57. 117 129
      src/date-formatting.ts
  58. 3 3
      src/exports.ts
  59. 4 4
      src/list/ListEventPointing.ts
  60. 23 28
      src/list/ListEventRenderer.ts
  61. 50 50
      src/list/ListView.ts
  62. 5 5
      src/list/config.ts
  63. 45 46
      src/locale.ts
  64. 26 32
      src/main.ts
  65. 26 28
      src/models/BusinessHourGenerator.ts
  66. 3 3
      src/models/ComponentFootprint.ts
  67. 87 88
      src/models/EventManager.ts
  68. 105 109
      src/models/EventPeriod.ts
  69. 46 48
      src/models/UnzonedRange.ts
  70. 23 24
      src/models/event-source/ArrayEventSource.ts
  71. 27 28
      src/models/event-source/EventSource.ts
  72. 6 6
      src/models/event-source/EventSourceParser.ts
  73. 16 17
      src/models/event-source/FuncEventSource.ts
  74. 45 48
      src/models/event-source/JsonFeedEventSource.ts
  75. 3 3
      src/models/event-source/config.ts
  76. 28 29
      src/models/event/EventDateProfile.ts
  77. 52 54
      src/models/event/EventDef.ts
  78. 55 64
      src/models/event/EventDefDateMutation.ts
  79. 43 47
      src/models/event/EventDefMutation.ts
  80. 3 4
      src/models/event/EventDefParser.ts
  81. 4 4
      src/models/event/EventFootprint.ts
  82. 7 7
      src/models/event/EventInstance.ts
  83. 22 24
      src/models/event/EventInstanceGroup.ts
  84. 3 3
      src/models/event/EventRange.ts
  85. 31 32
      src/models/event/RecurringEventDef.ts
  86. 17 18
      src/models/event/SingleEventDef.ts
  87. 8 8
      src/models/event/util.ts
  88. 95 103
      src/moment-ext.ts
  89. 10 10
      src/options.ts
  90. 21 22
      src/theme/Theme.ts
  91. 9 11
      src/theme/ThemeRegistry.ts
  92. 7 7
      src/theme/config.ts
  93. 233 244
      src/util.ts

Diff do ficheiro suprimidas por serem muito extensas
+ 268 - 285
src/Calendar.ts


+ 94 - 101
src/Constraints.ts

@@ -17,13 +17,13 @@ export default class Constraints {
 
 
   constructor(eventManager, _calendar) {
-    this.eventManager = eventManager;
-    this._calendar = _calendar;
+    this.eventManager = eventManager
+    this._calendar = _calendar
   }
 
 
   opt(name) {
-    return this._calendar.opt(name);
+    return this._calendar.opt(name)
   }
 
 
@@ -32,18 +32,18 @@ export default class Constraints {
   in relation to other EVENTS and business hours.
   */
   isEventInstanceGroupAllowed(eventInstanceGroup) {
-    var eventDef = eventInstanceGroup.getEventDef();
-    var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
-    var i;
+    let eventDef = eventInstanceGroup.getEventDef()
+    let eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges())
+    let i
 
-    var peerEventInstances = this.getPeerEventInstances(eventDef);
-    var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
-    var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
+    let peerEventInstances = this.getPeerEventInstances(eventDef)
+    let peerEventRanges = peerEventInstances.map(eventInstanceToEventRange)
+    let peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges)
 
-    var constraintVal = eventDef.getConstraint();
-    var overlapVal = eventDef.getOverlap();
+    let constraintVal = eventDef.getConstraint()
+    let overlapVal = eventDef.getOverlap()
 
-    var eventAllowFunc = this.opt('eventAllow');
+    let eventAllowFunc = this.opt('eventAllow')
 
     for (i = 0; i < eventFootprints.length; i++) {
       if (
@@ -55,7 +55,7 @@ export default class Constraints {
           eventFootprints[i].eventInstance
         )
       ) {
-        return false;
+        return false
       }
     }
 
@@ -67,26 +67,26 @@ export default class Constraints {
             eventFootprints[i].getEventLegacy()
           ) === false
         ) {
-          return false;
+          return false
         }
       }
     }
 
-    return true;
+    return true
   }
 
 
   getPeerEventInstances(eventDef) {
-    return this.eventManager.getEventInstancesWithoutId(eventDef.id);
+    return this.eventManager.getEventInstancesWithoutId(eventDef.id)
   }
 
 
   isSelectionFootprintAllowed(componentFootprint) {
-    var peerEventInstances = this.eventManager.getEventInstances();
-    var peerEventRanges = peerEventInstances.map(eventInstanceToEventRange);
-    var peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges);
+    let peerEventInstances = this.eventManager.getEventInstances()
+    let peerEventRanges = peerEventInstances.map(eventInstanceToEventRange)
+    let peerEventFootprints = this.eventRangesToEventFootprints(peerEventRanges)
 
-    var selectAllowFunc;
+    let selectAllowFunc
 
     if (
       this.isFootprintAllowed(
@@ -96,17 +96,16 @@ export default class Constraints {
         this.opt('selectOverlap')
       )
     ) {
-      selectAllowFunc = this.opt('selectAllow');
+      selectAllowFunc = this.opt('selectAllow')
 
       if (selectAllowFunc) {
-        return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false;
-      }
-      else {
-        return true;
+        return selectAllowFunc(componentFootprint.toLegacy(this._calendar)) !== false
+      } else {
+        return true
       }
     }
 
-    return false;
+    return false
   }
 
 
@@ -117,37 +116,36 @@ export default class Constraints {
     overlapVal,
     subjectEventInstance? // optional
   ) {
-    var constraintFootprints; // ComponentFootprint[]
-    var overlapEventFootprints; // EventFootprint[]
+    let constraintFootprints // ComponentFootprint[]
+    let overlapEventFootprints // EventFootprint[]
 
     if (constraintVal != null) {
-      constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay);
+      constraintFootprints = this.constraintValToFootprints(constraintVal, componentFootprint.isAllDay)
 
       if (!this.isFootprintWithinConstraints(componentFootprint, constraintFootprints)) {
-        return false;
+        return false
       }
     }
 
-    overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint);
+    overlapEventFootprints = this.collectOverlapEventFootprints(peerEventFootprints, componentFootprint)
 
     if (overlapVal === false) {
       if (overlapEventFootprints.length) {
-        return false;
+        return false
       }
-    }
-    else if (typeof overlapVal === 'function') {
+    } else if (typeof overlapVal === 'function') {
       if (!isOverlapsAllowedByFunc(overlapEventFootprints, overlapVal, subjectEventInstance)) {
-        return false;
+        return false
       }
     }
 
     if (subjectEventInstance) {
       if (!isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance)) {
-        return false;
+        return false
       }
     }
 
-    return true;
+    return true
   }
 
 
@@ -156,38 +154,35 @@ export default class Constraints {
 
 
   isFootprintWithinConstraints(componentFootprint, constraintFootprints) {
-    var i;
+    let i
 
     for (i = 0; i < constraintFootprints.length; i++) {
       if (this.footprintContainsFootprint(constraintFootprints[i], componentFootprint)) {
-        return true;
+        return true
       }
     }
 
-    return false;
+    return false
   }
 
 
   constraintValToFootprints(constraintVal, isAllDay) {
-    var eventInstances;
+    let eventInstances
 
     if (constraintVal === 'businessHours') {
-      return this.buildCurrentBusinessFootprints(isAllDay);
-    }
-    else if (typeof constraintVal === 'object') {
-      eventInstances = this.parseEventDefToInstances(constraintVal); // handles recurring events
+      return this.buildCurrentBusinessFootprints(isAllDay)
+    } else if (typeof constraintVal === 'object') {
+      eventInstances = this.parseEventDefToInstances(constraintVal) // handles recurring events
 
       if (!eventInstances) { // invalid input. fallback to parsing footprint directly
-        return this.parseFootprints(constraintVal);
-      }
-      else {
-        return this.eventInstancesToFootprints(eventInstances);
+        return this.parseFootprints(constraintVal)
+      } else {
+        return this.eventInstancesToFootprints(eventInstances)
       }
-    }
-    else if (constraintVal != null) { // an ID
-      eventInstances = this.eventManager.getEventInstancesWithId(constraintVal);
+    } else if (constraintVal != null) { // an ID
+      eventInstances = this.eventManager.getEventInstancesWithId(constraintVal)
 
-      return this.eventInstancesToFootprints(eventInstances);
+      return this.eventInstancesToFootprints(eventInstances)
     }
   }
 
@@ -195,26 +190,25 @@ export default class Constraints {
   // returns ComponentFootprint[]
   // uses current view's range
   buildCurrentBusinessFootprints(isAllDay) {
-    var view = this._calendar.view;
-    var businessHourGenerator = view.get('businessHourGenerator');
-    var unzonedRange = view.dateProfile.activeUnzonedRange;
-    var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange);
+    let view = this._calendar.view
+    let businessHourGenerator = view.get('businessHourGenerator')
+    let unzonedRange = view.dateProfile.activeUnzonedRange
+    let eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(isAllDay, unzonedRange)
 
     if (eventInstanceGroup) {
-      return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances);
-    }
-    else {
-      return [];
+      return this.eventInstancesToFootprints(eventInstanceGroup.eventInstances)
+    } else {
+      return []
     }
   }
 
 
   // conversion util
   eventInstancesToFootprints(eventInstances) {
-    var eventRanges = eventInstances.map(eventInstanceToEventRange);
-    var eventFootprints = this.eventRangesToEventFootprints(eventRanges);
+    let eventRanges = eventInstances.map(eventInstanceToEventRange)
+    let eventFootprints = this.eventRangesToEventFootprints(eventRanges)
 
-    return eventFootprints.map(eventFootprintToComponentFootprint);
+    return eventFootprints.map(eventFootprintToComponentFootprint)
   }
 
 
@@ -223,8 +217,8 @@ export default class Constraints {
 
 
   collectOverlapEventFootprints(peerEventFootprints, targetFootprint) {
-    var overlapEventFootprints = [];
-    var i;
+    let overlapEventFootprints = []
+    let i
 
     for (i = 0; i < peerEventFootprints.length; i++) {
       if (
@@ -233,11 +227,11 @@ export default class Constraints {
           peerEventFootprints[i].componentFootprint
         )
       ) {
-        overlapEventFootprints.push(peerEventFootprints[i]);
+        overlapEventFootprints.push(peerEventFootprints[i])
       }
     }
 
-    return overlapEventFootprints;
+    return overlapEventFootprints
   }
 
 
@@ -253,34 +247,34 @@ export default class Constraints {
   Returns false on invalid input.
   */
   parseEventDefToInstances(eventInput) {
-    var eventManager = this.eventManager;
-    var eventDef = EventDefParser.parse(eventInput, new EventSource(this._calendar));
+    let eventManager = this.eventManager
+    let eventDef = EventDefParser.parse(eventInput, new EventSource(this._calendar))
 
     if (!eventDef) { // invalid
-      return false;
+      return false
     }
 
-    return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange);
+    return eventDef.buildInstances(eventManager.currentPeriod.unzonedRange)
   }
 
 
   eventRangesToEventFootprints(eventRanges) {
-    var i;
-    var eventFootprints = [];
+    let i
+    let eventFootprints = []
 
     for (i = 0; i < eventRanges.length; i++) {
       eventFootprints.push.apply( // footprints
         eventFootprints,
         this.eventRangeToEventFootprints(eventRanges[i])
-      );
+      )
     }
 
-    return eventFootprints;
+    return eventFootprints
   }
 
 
   eventRangeToEventFootprints(eventRange): EventFootprint[] {
-    return [ eventRangeToEventFootprint(eventRange) ];
+    return [ eventRangeToEventFootprint(eventRange) ]
   }
 
 
@@ -289,21 +283,21 @@ export default class Constraints {
   Very similar to EventDateProfile::parse :(
   */
   parseFootprints(rawInput) {
-    var start, end;
+    let start, end
 
     if (rawInput.start) {
-      start = this._calendar.moment(rawInput.start);
+      start = this._calendar.moment(rawInput.start)
 
       if (!start.isValid()) {
-        start = null;
+        start = null
       }
     }
 
     if (rawInput.end) {
-      end = this._calendar.moment(rawInput.end);
+      end = this._calendar.moment(rawInput.end)
 
       if (!end.isValid()) {
-        end = null;
+        end = null
       }
     }
 
@@ -312,7 +306,7 @@ export default class Constraints {
         new UnzonedRange(start, end),
         (start && !start.hasTime()) || (end && !end.hasTime()) // isAllDay
       )
-    ];
+    ]
   }
 
 
@@ -321,12 +315,12 @@ export default class Constraints {
 
 
   footprintContainsFootprint(outerFootprint, innerFootprint) {
-    return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange);
+    return outerFootprint.unzonedRange.containsRange(innerFootprint.unzonedRange)
   }
 
 
   footprintsIntersect(footprint0, footprint1) {
-    return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange);
+    return footprint0.unzonedRange.intersectsWith(footprint1.unzonedRange)
   }
 
 }
@@ -334,7 +328,7 @@ export default class Constraints {
 
 // optional subjectEventInstance
 function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEventInstance) {
-  var i;
+  let i
 
   for (i = 0; i < overlapEventFootprints.length; i++) {
     if (
@@ -343,44 +337,43 @@ function isOverlapsAllowedByFunc(overlapEventFootprints, overlapFunc, subjectEve
         subjectEventInstance ? subjectEventInstance.toLegacy() : null
       )
     ) {
-      return false;
+      return false
     }
   }
 
-  return true;
+  return true
 }
 
 
 function isOverlapEventInstancesAllowed(overlapEventFootprints, subjectEventInstance) {
-  var subjectLegacyInstance = subjectEventInstance.toLegacy();
-  var i;
-  var overlapEventInstance;
-  var overlapEventDef;
-  var overlapVal;
+  let subjectLegacyInstance = subjectEventInstance.toLegacy()
+  let i
+  let overlapEventInstance
+  let overlapEventDef
+  let overlapVal
 
   for (i = 0; i < overlapEventFootprints.length; i++) {
-    overlapEventInstance = overlapEventFootprints[i].eventInstance;
-    overlapEventDef = overlapEventInstance.def;
+    overlapEventInstance = overlapEventFootprints[i].eventInstance
+    overlapEventDef = overlapEventInstance.def
 
     // don't need to pass in calendar, because don't want to consider global eventOverlap property,
     // because we already considered that earlier in the process.
-    overlapVal = overlapEventDef.getOverlap();
+    overlapVal = overlapEventDef.getOverlap()
 
     if (overlapVal === false) {
-      return false;
-    }
-    else if (typeof overlapVal === 'function') {
+      return false
+    } else if (typeof overlapVal === 'function') {
       if (
         !overlapVal(
           overlapEventInstance.toLegacy(),
           subjectLegacyInstance
         )
       ) {
-        return false;
+        return false
       }
     }
   }
 
-  return true;
+  return true
 }
 

+ 110 - 118
src/DateProfileGenerator.ts

@@ -9,22 +9,22 @@ export default class DateProfileGenerator {
 
 
   constructor(_view) {
-    this._view = _view;
+    this._view = _view
   }
 
 
   opt(name) {
-    return this._view.opt(name);
+    return this._view.opt(name)
   }
 
 
   trimHiddenDays(unzonedRange) {
-    return this._view.trimHiddenDays(unzonedRange);
+    return this._view.trimHiddenDays(unzonedRange)
   }
 
 
   msToUtcMoment(ms, forceAllDay) {
-    return this._view.calendar.msToUtcMoment(ms, forceAllDay);
+    return this._view.calendar.msToUtcMoment(ms, forceAllDay)
   }
 
 
@@ -34,77 +34,77 @@ export default class DateProfileGenerator {
 
   // Builds a structure with info about what the dates/ranges will be for the "prev" view.
   buildPrev(currentDateProfile) {
-    var prevDate = currentDateProfile.date.clone()
+    let prevDate = currentDateProfile.date.clone()
       .startOf(currentDateProfile.currentRangeUnit)
-      .subtract(currentDateProfile.dateIncrement);
+      .subtract(currentDateProfile.dateIncrement)
 
-    return this.build(prevDate, -1);
+    return this.build(prevDate, -1)
   }
 
 
   // Builds a structure with info about what the dates/ranges will be for the "next" view.
   buildNext(currentDateProfile) {
-    var nextDate = currentDateProfile.date.clone()
+    let nextDate = currentDateProfile.date.clone()
       .startOf(currentDateProfile.currentRangeUnit)
-      .add(currentDateProfile.dateIncrement);
+      .add(currentDateProfile.dateIncrement)
 
-    return this.build(nextDate, 1);
+    return this.build(nextDate, 1)
   }
 
 
   // Builds a structure holding dates/ranges for rendering around the given date.
   // Optional direction param indicates whether the date is being incremented/decremented
   // from its previous value. decremented = -1, incremented = 1 (default).
-  build(date, direction, forceToValid=false) {
-    var isDateAllDay = !date.hasTime();
-    var validUnzonedRange;
-    var minTime = null;
-    var maxTime = null;
-    var currentInfo;
-    var isRangeAllDay;
-    var renderUnzonedRange;
-    var activeUnzonedRange;
-    var isValid;
-
-    validUnzonedRange = this.buildValidRange();
-    validUnzonedRange = this.trimHiddenDays(validUnzonedRange);
+  build(date, direction, forceToValid= false) {
+    let isDateAllDay = !date.hasTime()
+    let validUnzonedRange
+    let minTime = null
+    let maxTime = null
+    let currentInfo
+    let isRangeAllDay
+    let renderUnzonedRange
+    let activeUnzonedRange
+    let isValid
+
+    validUnzonedRange = this.buildValidRange()
+    validUnzonedRange = this.trimHiddenDays(validUnzonedRange)
 
     if (forceToValid) {
       date = this.msToUtcMoment(
         validUnzonedRange.constrainDate(date), // returns MS
         isDateAllDay
-      );
+      )
     }
 
-    currentInfo = this.buildCurrentRangeInfo(date, direction);
-    isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit);
+    currentInfo = this.buildCurrentRangeInfo(date, direction)
+    isRangeAllDay = /^(year|month|week|day)$/.test(currentInfo.unit)
     renderUnzonedRange = this.buildRenderRange(
       this.trimHiddenDays(currentInfo.unzonedRange),
       currentInfo.unit,
       isRangeAllDay
-    );
-    renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange);
-    activeUnzonedRange = renderUnzonedRange.clone();
+    )
+    renderUnzonedRange = this.trimHiddenDays(renderUnzonedRange)
+    activeUnzonedRange = renderUnzonedRange.clone()
 
     if (!this.opt('showNonCurrentDates')) {
-      activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange);
+      activeUnzonedRange = activeUnzonedRange.intersect(currentInfo.unzonedRange)
     }
 
-    minTime = moment.duration(this.opt('minTime'));
-    maxTime = moment.duration(this.opt('maxTime'));
-    activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime);
-    activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange); // might return null
+    minTime = moment.duration(this.opt('minTime'))
+    maxTime = moment.duration(this.opt('maxTime'))
+    activeUnzonedRange = this.adjustActiveRange(activeUnzonedRange, minTime, maxTime)
+    activeUnzonedRange = activeUnzonedRange.intersect(validUnzonedRange) // might return null
 
     if (activeUnzonedRange) {
       date = this.msToUtcMoment(
         activeUnzonedRange.constrainDate(date), // returns MS
         isDateAllDay
-      );
+      )
     }
 
     // it's invalid if the originally requested date is not contained,
     // or if the range is completely outside of the valid range.
-    isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange);
+    isValid = currentInfo.unzonedRange.intersectsWith(validUnzonedRange)
 
     return {
       // constraint for where prev/next operations can go and where events can be dragged/resized to.
@@ -141,7 +141,7 @@ export default class DateProfileGenerator {
       // how far the current date will move for a prev/next operation
       dateIncrement: this.buildDateIncrement(currentInfo.duration)
         // pass a fallback (might be null) ^
-    };
+    }
   }
 
 
@@ -150,7 +150,7 @@ export default class DateProfileGenerator {
   // not responsible for trimming hidden days.
   buildValidRange() {
     return this._view.getUnzonedRangeOption('validRange', this._view.calendar.getNow()) ||
-      new UnzonedRange(); // completely open-ended
+      new UnzonedRange() // completely open-ended
   }
 
 
@@ -160,57 +160,54 @@ export default class DateProfileGenerator {
   // Guaranteed to have `range` and `unit` properties. `duration` is optional.
   // TODO: accept a MS-time instead of a moment `date`?
   buildCurrentRangeInfo(date, direction) {
-    var viewSpec = this._view.viewSpec;
-    var duration = null;
-    var unit = null;
-    var unzonedRange = null;
-    var dayCount;
+    let viewSpec = this._view.viewSpec
+    let duration = null
+    let unit = null
+    let unzonedRange = null
+    let dayCount
 
     if (viewSpec.duration) {
-      duration = viewSpec.duration;
-      unit = viewSpec.durationUnit;
-      unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
-    }
-    else if ((dayCount = this.opt('dayCount'))) {
-      unit = 'day';
-      unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount);
-    }
-    else if ((unzonedRange = this.buildCustomVisibleRange(date))) {
-      unit = computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd());
-    }
-    else {
-      duration = this.getFallbackDuration();
-      unit = computeGreatestUnit(duration);
-      unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit);
+      duration = viewSpec.duration
+      unit = viewSpec.durationUnit
+      unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit)
+    } else if ((dayCount = this.opt('dayCount'))) {
+      unit = 'day'
+      unzonedRange = this.buildRangeFromDayCount(date, direction, dayCount)
+    } else if ((unzonedRange = this.buildCustomVisibleRange(date))) {
+      unit = computeGreatestUnit(unzonedRange.getStart(), unzonedRange.getEnd())
+    } else {
+      duration = this.getFallbackDuration()
+      unit = computeGreatestUnit(duration)
+      unzonedRange = this.buildRangeFromDuration(date, direction, duration, unit)
     }
 
-    return { duration: duration, unit: unit, unzonedRange: unzonedRange };
+    return { duration: duration, unit: unit, unzonedRange: unzonedRange }
   }
 
 
   getFallbackDuration() {
-    return moment.duration({ days: 1 });
+    return moment.duration({ days: 1 })
   }
 
 
   // Returns a new activeUnzonedRange to have time values (un-ambiguate)
   // minTime or maxTime causes the range to expand.
   adjustActiveRange(unzonedRange, minTime, maxTime) {
-    var start = unzonedRange.getStart();
-    var end = unzonedRange.getEnd();
+    let start = unzonedRange.getStart()
+    let end = unzonedRange.getEnd()
 
     if (this._view.usesMinMaxTime) {
 
       if (minTime < 0) {
-        start.time(0).add(minTime);
+        start.time(0).add(minTime)
       }
 
       if (maxTime > 24 * 60 * 60 * 1000) { // beyond 24 hours?
-        end.time(maxTime - (24 * 60 * 60 * 1000));
+        end.time(maxTime - (24 * 60 * 60 * 1000))
       }
     }
 
-    return new UnzonedRange(start, end);
+    return new UnzonedRange(start, end)
   }
 
 
@@ -218,83 +215,81 @@ export default class DateProfileGenerator {
   // `unit` is the already-computed computeGreatestUnit value of duration.
   // TODO: accept a MS-time instead of a moment `date`?
   buildRangeFromDuration(date, direction, duration, unit) {
-    var alignment = this.opt('dateAlignment');
-    var dateIncrementInput;
-    var dateIncrementDuration;
-    var start;
-    var end;
-    var res;
+    let alignment = this.opt('dateAlignment')
+    let dateIncrementInput
+    let dateIncrementDuration
+    let start
+    let end
+    let res
 
     // compute what the alignment should be
     if (!alignment) {
-      dateIncrementInput = this.opt('dateIncrement');
+      dateIncrementInput = this.opt('dateIncrement')
 
       if (dateIncrementInput) {
-        dateIncrementDuration = moment.duration(dateIncrementInput);
+        dateIncrementDuration = moment.duration(dateIncrementInput)
 
         // use the smaller of the two units
         if (dateIncrementDuration < duration) {
-          alignment = computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput);
-        }
-        else {
-          alignment = unit;
+          alignment = computeDurationGreatestUnit(dateIncrementDuration, dateIncrementInput)
+        } else {
+          alignment = unit
         }
-      }
-      else {
-        alignment = unit;
+      } else {
+        alignment = unit
       }
     }
 
     // if the view displays a single day or smaller
     if (duration.as('days') <= 1) {
       if (this._view.isHiddenDay(start)) {
-        start = this._view.skipHiddenDays(start, direction);
-        start.startOf('day');
+        start = this._view.skipHiddenDays(start, direction)
+        start.startOf('day')
       }
     }
 
     function computeRes() {
-      start = date.clone().startOf(alignment);
-      end = start.clone().add(duration);
-      res = new UnzonedRange(start, end);
+      start = date.clone().startOf(alignment)
+      end = start.clone().add(duration)
+      res = new UnzonedRange(start, end)
     }
 
-    computeRes();
+    computeRes()
 
     // if range is completely enveloped by hidden days, go past the hidden days
     if (!this.trimHiddenDays(res)) {
-      date = this._view.skipHiddenDays(date, direction);
-      computeRes();
+      date = this._view.skipHiddenDays(date, direction)
+      computeRes()
     }
 
-    return res;
+    return res
   }
 
 
   // Builds the "current" range when a dayCount is specified.
   // TODO: accept a MS-time instead of a moment `date`?
   buildRangeFromDayCount(date, direction, dayCount) {
-    var customAlignment = this.opt('dateAlignment');
-    var runningCount = 0;
-    var start = date.clone();
-    var end;
+    let customAlignment = this.opt('dateAlignment')
+    let runningCount = 0
+    let start = date.clone()
+    let end
 
     if (customAlignment) {
-      start.startOf(customAlignment);
+      start.startOf(customAlignment)
     }
 
-    start.startOf('day');
-    start = this._view.skipHiddenDays(start, direction);
+    start.startOf('day')
+    start = this._view.skipHiddenDays(start, direction)
 
-    end = start.clone();
+    end = start.clone()
     do {
-      end.add(1, 'day');
+      end.add(1, 'day')
       if (!this._view.isHiddenDay(end)) {
-        runningCount++;
+        runningCount++
       }
-    } while (runningCount < dayCount);
+    } while (runningCount < dayCount)
 
-    return new UnzonedRange(start, end);
+    return new UnzonedRange(start, end)
   }
 
 
@@ -302,16 +297,16 @@ export default class DateProfileGenerator {
   // which is a way to define the currentUnzonedRange and activeUnzonedRange at the same time.
   // TODO: accept a MS-time instead of a moment `date`?
   buildCustomVisibleRange(date) {
-    var visibleUnzonedRange = this._view.getUnzonedRangeOption(
+    let visibleUnzonedRange = this._view.getUnzonedRangeOption(
       'visibleRange',
       this._view.calendar.applyTimezone(date) // correct zone. also generates new obj that avoids mutations
-    );
+    )
 
     if (visibleUnzonedRange && (visibleUnzonedRange.startMs == null || visibleUnzonedRange.endMs == null)) {
-      return null;
+      return null
     }
 
-    return visibleUnzonedRange;
+    return visibleUnzonedRange
   }
 
 
@@ -319,27 +314,24 @@ export default class DateProfileGenerator {
   // but which may have voided days/times.
   // not responsible for trimming hidden days.
   buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
-    return currentUnzonedRange.clone();
+    return currentUnzonedRange.clone()
   }
 
 
   // Compute the duration value that should be added/substracted to the current date
   // when a prev/next operation happens.
   buildDateIncrement(fallback) {
-    var dateIncrementInput = this.opt('dateIncrement');
-    var customAlignment;
+    let dateIncrementInput = this.opt('dateIncrement')
+    let customAlignment
 
     if (dateIncrementInput) {
-      return moment.duration(dateIncrementInput);
-    }
-    else if ((customAlignment = this.opt('dateAlignment'))) {
-      return moment.duration(1, customAlignment);
-    }
-    else if (fallback) {
-      return fallback;
-    }
-    else {
-      return moment.duration({ days: 1 });
+      return moment.duration(dateIncrementInput)
+    } else if ((customAlignment = this.opt('dateAlignment'))) {
+      return moment.duration(1, customAlignment)
+    } else if (fallback) {
+      return fallback
+    } else {
+      return moment.duration({ days: 1 })
     }
   }
 

+ 39 - 42
src/OptionsManager.ts

@@ -16,69 +16,66 @@ export default class OptionsManager extends Model {
 
   constructor(_calendar, overrides) {
     super()
-    this._calendar = _calendar;
-    this.overrides = $.extend({}, overrides); // make a copy
-    this.dynamicOverrides = {};
-    this.compute();
+    this._calendar = _calendar
+    this.overrides = $.extend({}, overrides) // make a copy
+    this.dynamicOverrides = {}
+    this.compute()
   }
 
 
   add(newOptionHash) {
-    var optionCnt = 0;
-    var optionName;
+    let optionCnt = 0
+    let optionName
 
-    this.recordOverrides(newOptionHash); // will trigger this model's watchers
+    this.recordOverrides(newOptionHash) // will trigger this model's watchers
 
     for (optionName in newOptionHash) {
-      optionCnt++;
+      optionCnt++
     }
 
     // special-case handling of single option change.
     // if only one option change, `optionName` will be its name.
     if (optionCnt === 1) {
       if (optionName === 'height' || optionName === 'contentHeight' || optionName === 'aspectRatio') {
-        this._calendar.updateViewSize(true); // isResize=true
-        return;
-      }
-      else if (optionName === 'defaultDate') {
-        return; // can't change date this way. use gotoDate instead
-      }
-      else if (optionName === 'businessHours') {
-        return; // this model already reacts to this
-      }
-      else if (optionName === 'timezone') {
-        this._calendar.view.flash('initialEvents');
-        return;
+        this._calendar.updateViewSize(true) // isResize=true
+        return
+      } else if (optionName === 'defaultDate') {
+        return // can't change date this way. use gotoDate instead
+      } else if (optionName === 'businessHours') {
+        return // this model already reacts to this
+      } else if (optionName === 'timezone') {
+        this._calendar.view.flash('initialEvents')
+        return
       }
     }
 
     // catch-all. rerender the header and footer and rebuild/rerender the current view
-    this._calendar.renderHeader();
-    this._calendar.renderFooter();
+    this._calendar.renderHeader()
+    this._calendar.renderFooter()
 
     // even non-current views will be affected by this option change. do before rerender
     // TODO: detangle
-    this._calendar.viewsByType = {};
+    this._calendar.viewsByType = {}
 
-    this._calendar.reinitView();
+    this._calendar.reinitView()
   }
 
 
   // Computes the flattened options hash for the calendar and assigns to `this.options`.
   // Assumes this.overrides and this.dynamicOverrides have already been initialized.
   compute() {
-    var locale, localeDefaults;
-    var isRTL, dirDefaults;
-    var rawOptions;
+    let locale, localeDefaults
+    let isRTL, dirDefaults
+    let rawOptions
 
     locale = firstDefined( // explicit locale option given?
       this.dynamicOverrides.locale,
       this.overrides.locale
-    );
-    localeDefaults = localeOptionHash[locale];
+    )
+    localeDefaults = localeOptionHash[locale]
     if (!localeDefaults) { // explicit locale option not given or invalid?
-      locale = globalDefaults.locale;
-      localeDefaults = localeOptionHash[locale] || {};
+      locale = globalDefaults.locale
+      localeDefaults = localeOptionHash[locale] || {}
     }
 
     isRTL = firstDefined( // based on options computed so far, is direction RTL?
@@ -86,11 +83,11 @@ export default class OptionsManager extends Model {
       this.overrides.isRTL,
       localeDefaults.isRTL,
       globalDefaults.isRTL
-    );
-    dirDefaults = isRTL ? rtlDefaults : {};
+    )
+    dirDefaults = isRTL ? rtlDefaults : {}
 
-    this.dirDefaults = dirDefaults;
-    this.localeDefaults = localeDefaults;
+    this.dirDefaults = dirDefaults
+    this.localeDefaults = localeDefaults
 
     rawOptions = mergeOptions([ // merge defaults and overrides. lowest to highest precedence
       globalDefaults, // global defaults
@@ -98,23 +95,23 @@ export default class OptionsManager extends Model {
       localeDefaults,
       this.overrides,
       this.dynamicOverrides
-    ]);
-    populateInstanceComputableOptions(rawOptions); // fill in gaps with computed options
+    ])
+    populateInstanceComputableOptions(rawOptions) // fill in gaps with computed options
 
-    this.reset(rawOptions);
+    this.reset(rawOptions)
   }
 
 
   // stores the new options internally, but does not rerender anything.
   recordOverrides(newOptionHash) {
-    var optionName;
+    let optionName
 
     for (optionName in newOptionHash) {
-      this.dynamicOverrides[optionName] = newOptionHash[optionName];
+      this.dynamicOverrides[optionName] = newOptionHash[optionName]
     }
 
-    this._calendar.viewSpecManager.clearCache(); // the dynamic override invalidates the options in this cache, so just clear it
-    this.compute(); // this.options needs to be recomputed after the dynamic override
+    this._calendar.viewSpecManager.clearCache() // the dynamic override invalidates the options in this cache, so just clear it
+    this.compute() // this.options needs to be recomputed after the dynamic override
   }
 
 

+ 69 - 76
src/Toolbar.ts

@@ -21,7 +21,7 @@ export default class Toolbar {
 
   // method to update toolbar-specific options, not calendar-wide options
   setToolbarOptions(newToolbarOptions) {
-    this.toolbarOptions = newToolbarOptions;
+    this.toolbarOptions = newToolbarOptions
   }
 
 
@@ -32,89 +32,84 @@ export default class Toolbar {
 
     if (sections) {
       if (!el) {
-        el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'/>");
-      }
-      else {
-        el.empty();
+        el = this.el = $("<div class='fc-toolbar " + this.toolbarOptions.extraClasses + "'/>")
+      } else {
+        el.empty()
       }
       el.append(this.renderSection('left'))
         .append(this.renderSection('right'))
         .append(this.renderSection('center'))
-        .append('<div class="fc-clear"/>');
-    }
-    else {
-      this.removeElement();
+        .append('<div class="fc-clear"/>')
+    } else {
+      this.removeElement()
     }
   }
 
 
   removeElement() {
     if (this.el) {
-      this.el.remove();
-      this.el = null;
+      this.el.remove()
+      this.el = null
     }
   }
 
 
   renderSection(position) {
-    var calendar = this.calendar
-    var theme = calendar.theme;
-    var optionsManager = calendar.optionsManager;
-    var viewSpecManager = calendar.viewSpecManager;
-    var sectionEl = $('<div class="fc-' + position + '"/>');
-    var buttonStr = this.toolbarOptions.layout[position];
-    var calendarCustomButtons = optionsManager.get('customButtons') || {};
-    var calendarButtonTextOverrides = optionsManager.overrides.buttonText || {};
-    var calendarButtonText = optionsManager.get('buttonText') || {};
+    let calendar = this.calendar
+    let theme = calendar.theme
+    let optionsManager = calendar.optionsManager
+    let viewSpecManager = calendar.viewSpecManager
+    let sectionEl = $('<div class="fc-' + position + '"/>')
+    let buttonStr = this.toolbarOptions.layout[position]
+    let calendarCustomButtons = optionsManager.get('customButtons') || {}
+    let calendarButtonTextOverrides = optionsManager.overrides.buttonText || {}
+    let calendarButtonText = optionsManager.get('buttonText') || {}
 
     if (buttonStr) {
       $.each(buttonStr.split(' '), (i, buttonGroupStr) => {
-        var groupChildren = $();
-        var isOnlyButtons = true;
-        var groupEl;
+        let groupChildren = $()
+        let isOnlyButtons = true
+        let groupEl
 
         $.each(buttonGroupStr.split(','), (j, buttonName) => {
-          var customButtonProps;
-          var viewSpec;
-          var buttonClick;
-          var buttonIcon; // only one of these will be set
-          var buttonText; // "
-          var buttonInnerHtml;
-          var buttonClasses;
-          var buttonEl;
+          let customButtonProps
+          let viewSpec
+          let buttonClick
+          let buttonIcon // only one of these will be set
+          let buttonText // "
+          let buttonInnerHtml
+          let buttonClasses
+          let buttonEl
 
           if (buttonName == 'title') {
-            groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')); // we always want it to take up height
-            isOnlyButtons = false;
-          }
-          else {
+            groupChildren = groupChildren.add($('<h2>&nbsp;</h2>')) // we always want it to take up height
+            isOnlyButtons = false
+          } else {
 
             if ((customButtonProps = calendarCustomButtons[buttonName])) {
               buttonClick = function(ev) {
                 if (customButtonProps.click) {
-                  customButtonProps.click.call(buttonEl[0], ev);
+                  customButtonProps.click.call(buttonEl[0], ev)
                 }
               };
               (buttonIcon = theme.getCustomButtonIconClass(customButtonProps)) ||
               (buttonIcon = theme.getIconClass(buttonName)) ||
-              (buttonText = customButtonProps.text);
-            }
-            else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) {
-              this.viewsWithButtons.push(buttonName);
+              (buttonText = customButtonProps.text)
+            } else if ((viewSpec = viewSpecManager.getViewSpec(buttonName))) {
+              this.viewsWithButtons.push(buttonName)
               buttonClick = function() {
-                calendar.changeView(buttonName);
+                calendar.changeView(buttonName)
               };
               (buttonText = viewSpec.buttonTextOverride) ||
               (buttonIcon = theme.getIconClass(buttonName)) ||
-              (buttonText = viewSpec.buttonTextDefault);
-            }
-            else if (calendar[buttonName]) { // a calendar method
+              (buttonText = viewSpec.buttonTextDefault)
+            } else if (calendar[buttonName]) { // a calendar method
               buttonClick = function() {
-                calendar[buttonName]();
+                calendar[buttonName]()
               };
               (buttonText = calendarButtonTextOverrides[buttonName]) ||
               (buttonIcon = theme.getIconClass(buttonName)) ||
-              (buttonText = calendarButtonText[buttonName]);
+              (buttonText = calendarButtonText[buttonName])
               //            ^ everything else is considered default
             }
 
@@ -124,13 +119,12 @@ export default class Toolbar {
                 'fc-' + buttonName + '-button',
                 theme.getClass('button'),
                 theme.getClass('stateDefault')
-              ];
+              ]
 
               if (buttonText) {
-                buttonInnerHtml = htmlEscape(buttonText);
-              }
-              else if (buttonIcon) {
-                buttonInnerHtml = "<span class='" + buttonIcon + "'></span>";
+                buttonInnerHtml = htmlEscape(buttonText)
+              } else if (buttonIcon) {
+                buttonInnerHtml = "<span class='" + buttonIcon + "'></span>"
               }
 
               buttonEl = $( // type="button" so that it doesn't submit a form
@@ -142,7 +136,7 @@ export default class Toolbar {
                   // don't process clicks for disabled buttons
                   if (!buttonEl.hasClass(theme.getClass('stateDisabled'))) {
 
-                    buttonClick(ev);
+                    buttonClick(ev)
 
                     // after the click action, if the button becomes the "active" tab, or disabled,
                     // it should never have a hover class, so remove it now.
@@ -150,7 +144,7 @@ export default class Toolbar {
                       buttonEl.hasClass(theme.getClass('stateActive')) ||
                       buttonEl.hasClass(theme.getClass('stateDisabled'))
                     ) {
-                      buttonEl.removeClass(theme.getClass('stateHover'));
+                      buttonEl.removeClass(theme.getClass('stateHover'))
                     }
                   }
                 })
@@ -160,11 +154,11 @@ export default class Toolbar {
                   buttonEl
                     .not('.' + theme.getClass('stateActive'))
                     .not('.' + theme.getClass('stateDisabled'))
-                    .addClass(theme.getClass('stateDown'));
+                    .addClass(theme.getClass('stateDown'))
                 })
                 .mouseup(function() {
                   // undo the *down* effect
-                  buttonEl.removeClass(theme.getClass('stateDown'));
+                  buttonEl.removeClass(theme.getClass('stateDown'))
                 })
                 .hover(
                   function() {
@@ -173,48 +167,47 @@ export default class Toolbar {
                     buttonEl
                       .not('.' + theme.getClass('stateActive'))
                       .not('.' + theme.getClass('stateDisabled'))
-                      .addClass(theme.getClass('stateHover'));
+                      .addClass(theme.getClass('stateHover'))
                   },
                   function() {
                     // undo the *hover* effect
                     buttonEl
                       .removeClass(theme.getClass('stateHover'))
-                      .removeClass(theme.getClass('stateDown')); // if mouseleave happens before mouseup
+                      .removeClass(theme.getClass('stateDown')) // if mouseleave happens before mouseup
                   }
-                );
+                )
 
-              groupChildren = groupChildren.add(buttonEl);
+              groupChildren = groupChildren.add(buttonEl)
             }
           }
-        });
+        })
 
         if (isOnlyButtons) {
           groupChildren
             .first().addClass(theme.getClass('cornerLeft')).end()
-            .last().addClass(theme.getClass('cornerRight')).end();
+            .last().addClass(theme.getClass('cornerRight')).end()
         }
 
         if (groupChildren.length > 1) {
-          groupEl = $('<div/>');
+          groupEl = $('<div/>')
           if (isOnlyButtons) {
-            groupEl.addClass(theme.getClass('buttonGroup'));
+            groupEl.addClass(theme.getClass('buttonGroup'))
           }
-          groupEl.append(groupChildren);
-          sectionEl.append(groupEl);
-        }
-        else {
-          sectionEl.append(groupChildren); // 1 or 0 children
+          groupEl.append(groupChildren)
+          sectionEl.append(groupEl)
+        } else {
+          sectionEl.append(groupChildren) // 1 or 0 children
         }
-      });
+      })
     }
 
-    return sectionEl;
+    return sectionEl
   }
 
 
   updateTitle(text) {
     if (this.el) {
-      this.el.find('h2').text(text);
+      this.el.find('h2').text(text)
     }
   }
 
@@ -222,7 +215,7 @@ export default class Toolbar {
   activateButton(buttonName) {
     if (this.el) {
       this.el.find('.fc-' + buttonName + '-button')
-        .addClass(this.calendar.theme.getClass('stateActive'));
+        .addClass(this.calendar.theme.getClass('stateActive'))
     }
   }
 
@@ -230,7 +223,7 @@ export default class Toolbar {
   deactivateButton(buttonName) {
     if (this.el) {
       this.el.find('.fc-' + buttonName + '-button')
-        .removeClass(this.calendar.theme.getClass('stateActive'));
+        .removeClass(this.calendar.theme.getClass('stateActive'))
     }
   }
 
@@ -239,7 +232,7 @@ export default class Toolbar {
     if (this.el) {
       this.el.find('.fc-' + buttonName + '-button')
         .prop('disabled', true)
-        .addClass(this.calendar.theme.getClass('stateDisabled'));
+        .addClass(this.calendar.theme.getClass('stateDisabled'))
     }
   }
 
@@ -248,13 +241,13 @@ export default class Toolbar {
     if (this.el) {
       this.el.find('.fc-' + buttonName + '-button')
         .prop('disabled', false)
-        .removeClass(this.calendar.theme.getClass('stateDisabled'));
+        .removeClass(this.calendar.theme.getClass('stateDisabled'))
     }
   }
 
 
   getViewsWithButtons() {
-    return this.viewsWithButtons;
+    return this.viewsWithButtons
   }
 
 }

Diff do ficheiro suprimidas por serem muito extensas
+ 203 - 210
src/View.ts


+ 4 - 4
src/ViewRegistry.ts

@@ -1,15 +1,15 @@
-import * as exportHooks from './exports';
+import * as exportHooks from './exports'
 
 
 export const viewHash = {};
-(exportHooks as any).views = viewHash;
+(exportHooks as any).views = viewHash
 
 
 export function defineView(viewName, viewConfig) {
-  viewHash[viewName] = viewConfig;
+  viewHash[viewName] = viewConfig
 }
 
 
 export function getViewConfig(viewName) {
-  return viewHash[viewName];
+  return viewHash[viewName]
 }

+ 58 - 58
src/ViewSpecManager.ts

@@ -14,46 +14,46 @@ export default class ViewSpecManager {
 
 
   constructor(optionsManager, _calendar) {
-    this.optionsManager = optionsManager;
-    this._calendar = _calendar;
+    this.optionsManager = optionsManager
+    this._calendar = _calendar
 
-    this.clearCache();
+    this.clearCache()
   }
 
 
   clearCache() {
-    this.viewSpecCache = {};
+    this.viewSpecCache = {}
   }
 
 
   // Gets information about how to create a view. Will use a cache.
   getViewSpec(viewType) {
-    var cache = this.viewSpecCache;
+    let cache = this.viewSpecCache
 
-    return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType));
+    return cache[viewType] || (cache[viewType] = this.buildViewSpec(viewType))
   }
 
 
   // Given a duration singular unit, like "week" or "day", finds a matching view spec.
   // Preference is given to views that have corresponding buttons.
   getUnitViewSpec(unit) {
-    var viewTypes;
-    var i;
-    var spec;
+    let viewTypes
+    let i
+    let spec
 
     if ($.inArray(unit, unitsDesc) != -1) {
 
       // put views that have buttons first. there will be duplicates, but oh well
-      viewTypes = this._calendar.header.getViewsWithButtons(); // TODO: include footer as well?
+      viewTypes = this._calendar.header.getViewsWithButtons() // TODO: include footer as well?
       $.each(viewHash, function(viewType) { // all views
-        viewTypes.push(viewType);
-      });
+        viewTypes.push(viewType)
+      })
 
       for (i = 0; i < viewTypes.length; i++) {
-        spec = this.getViewSpec(viewTypes[i]);
+        spec = this.getViewSpec(viewTypes[i])
         if (spec) {
           if (spec.singleUnit == unit) {
-            return spec;
+            return spec
           }
         }
       }
@@ -63,84 +63,84 @@ export default class ViewSpecManager {
 
   // Builds an object with information on how to create a given view
   buildViewSpec(requestedViewType) {
-    var viewOverrides = this.optionsManager.overrides.views || {};
-    var specChain = []; // for the view. lowest to highest priority
-    var defaultsChain = []; // for the view. lowest to highest priority
-    var overridesChain = []; // for the view. lowest to highest priority
-    var viewType = requestedViewType;
-    var spec; // for the view
-    var overrides; // for the view
-    var durationInput;
-    var duration;
-    var unit;
+    let viewOverrides = this.optionsManager.overrides.views || {}
+    let specChain = [] // for the view. lowest to highest priority
+    let defaultsChain = [] // for the view. lowest to highest priority
+    let overridesChain = [] // for the view. lowest to highest priority
+    let viewType = requestedViewType
+    let spec // for the view
+    let overrides // for the view
+    let durationInput
+    let duration
+    let unit
 
     // iterate from the specific view definition to a more general one until we hit an actual View class
     while (viewType) {
-      spec = viewHash[viewType];
-      overrides = viewOverrides[viewType];
-      viewType = null; // clear. might repopulate for another iteration
+      spec = viewHash[viewType]
+      overrides = viewOverrides[viewType]
+      viewType = null // clear. might repopulate for another iteration
 
       if (typeof spec === 'function') { // TODO: deprecate
-        spec = { 'class': spec };
+        spec = { 'class': spec }
       }
 
       if (spec) {
-        specChain.unshift(spec);
-        defaultsChain.unshift(spec.defaults || {});
-        durationInput = durationInput || spec.duration;
-        viewType = viewType || spec.type;
+        specChain.unshift(spec)
+        defaultsChain.unshift(spec.defaults || {})
+        durationInput = durationInput || spec.duration
+        viewType = viewType || spec.type
       }
 
       if (overrides) {
-        overridesChain.unshift(overrides); // view-specific option hashes have options at zero-level
-        durationInput = durationInput || overrides.duration;
-        viewType = viewType || overrides.type;
+        overridesChain.unshift(overrides) // view-specific option hashes have options at zero-level
+        durationInput = durationInput || overrides.duration
+        viewType = viewType || overrides.type
       }
     }
 
-    spec = mergeProps(specChain);
-    spec.type = requestedViewType;
+    spec = mergeProps(specChain)
+    spec.type = requestedViewType
     if (!spec['class']) {
-      return false;
+      return false
     }
 
     // fall back to top-level `duration` option
     durationInput = durationInput ||
       this.optionsManager.dynamicOverrides.duration ||
-      this.optionsManager.overrides.duration;
+      this.optionsManager.overrides.duration
 
     if (durationInput) {
-      duration = moment.duration(durationInput);
+      duration = moment.duration(durationInput)
 
       if (duration.valueOf()) { // valid?
 
-        unit = computeDurationGreatestUnit(duration, durationInput);
+        unit = computeDurationGreatestUnit(duration, durationInput)
 
-        spec.duration = duration;
-        spec.durationUnit = unit;
+        spec.duration = duration
+        spec.durationUnit = unit
 
         // view is a single-unit duration, like "week" or "day"
         // incorporate options for this. lowest priority
         if (duration.as(unit) === 1) {
-          spec.singleUnit = unit;
-          overridesChain.unshift(viewOverrides[unit] || {});
+          spec.singleUnit = unit
+          overridesChain.unshift(viewOverrides[unit] || {})
         }
       }
     }
 
-    spec.defaults = mergeOptions(defaultsChain);
-    spec.overrides = mergeOptions(overridesChain);
+    spec.defaults = mergeOptions(defaultsChain)
+    spec.overrides = mergeOptions(overridesChain)
 
-    this.buildViewSpecOptions(spec);
-    this.buildViewSpecButtonText(spec, requestedViewType);
+    this.buildViewSpecOptions(spec)
+    this.buildViewSpecButtonText(spec, requestedViewType)
 
-    return spec;
+    return spec
   }
 
 
   // Builds and assigns a view spec's options object from its already-assigned defaults and overrides
   buildViewSpecOptions(spec) {
-    var optionsManager = this.optionsManager;
+    let optionsManager = this.optionsManager
 
     spec.options = mergeOptions([ // lowest to highest priority
       globalDefaults,
@@ -150,31 +150,31 @@ export default class ViewSpecManager {
       optionsManager.overrides, // calendar's overrides (options given to constructor)
       spec.overrides, // view's overrides (view-specific options)
       optionsManager.dynamicOverrides // dynamically set via setter. highest precedence
-    ]);
-    populateInstanceComputableOptions(spec.options);
+    ])
+    populateInstanceComputableOptions(spec.options)
   }
 
 
   // Computes and assigns a view spec's buttonText-related options
   buildViewSpecButtonText(spec, requestedViewType) {
-    var optionsManager = this.optionsManager;
+    let optionsManager = this.optionsManager
 
     // given an options object with a possible `buttonText` hash, lookup the buttonText for the
     // requested view, falling back to a generic unit entry like "week" or "day"
     function queryButtonText(options) {
-      var buttonText = options.buttonText || {};
+      let buttonText = options.buttonText || {}
       return buttonText[requestedViewType] ||
         // view can decide to look up a certain key
         (spec.buttonTextKey ? buttonText[spec.buttonTextKey] : null) ||
         // a key like "month"
-        (spec.singleUnit ? buttonText[spec.singleUnit] : null);
+        (spec.singleUnit ? buttonText[spec.singleUnit] : null)
     }
 
     // highest to lowest priority
     spec.buttonTextOverride =
       queryButtonText(optionsManager.dynamicOverrides) ||
       queryButtonText(optionsManager.overrides) || // constructor-specified buttonText lookup hash takes precedence
-      spec.overrides.buttonText; // `buttonText` for view-specific options is a string
+      spec.overrides.buttonText // `buttonText` for view-specific options is a string
 
     // highest to lowest priority. mirrors buildViewSpecOptions
     spec.buttonTextDefault =
@@ -183,7 +183,7 @@ export default class ViewSpecManager {
       spec.defaults.buttonText || // a single string. from ViewSubclass.defaults
       queryButtonText(globalDefaults) ||
       (spec.duration ? this._calendar.humanizeDuration(spec.duration) : null) || // like "3 days"
-      requestedViewType; // fall back to given view name
+      requestedViewType // fall back to given view name
   }
 
 }

+ 111 - 115
src/agenda/AgendaView.ts

@@ -12,7 +12,7 @@ import View from '../View'
 import TimeGrid from './TimeGrid'
 import DayGrid from '../basic/DayGrid'
 
-const AGENDA_ALL_DAY_EVENT_LIMIT = 5;
+const AGENDA_ALL_DAY_EVENT_LIMIT = 5
 
 
 /* An abstract class for all agenda-related views. Displays one more columns with time slots running vertically.
@@ -35,36 +35,36 @@ export default class AgendaView extends View {
 
 
   constructor(calendar, viewSpec) {
-    super(calendar, viewSpec);
+    super(calendar, viewSpec)
 
-    this.timeGrid = this.instantiateTimeGrid();
-    this.addChild(this.timeGrid);
+    this.timeGrid = this.instantiateTimeGrid()
+    this.addChild(this.timeGrid)
 
     if (this.opt('allDaySlot')) { // should we display the "all-day" area?
-      this.dayGrid = this.instantiateDayGrid(); // the all-day subcomponent of this view
-      this.addChild(this.dayGrid);
+      this.dayGrid = this.instantiateDayGrid() // the all-day subcomponent of this view
+      this.addChild(this.dayGrid)
     }
 
     this.scroller = new Scroller({
       overflowX: 'hidden',
       overflowY: 'auto'
-    });
+    })
   }
 
 
   // Instantiates the TimeGrid object this view needs. Draws from this.timeGridClass
   instantiateTimeGrid() {
-    var SubClass: any = makeTimeGridSubclass(this.timeGridClass);
+    let SubClass: any = makeTimeGridSubclass(this.timeGridClass)
 
-    return new SubClass(this);
+    return new SubClass(this)
   }
 
 
   // Instantiates the DayGrid object this view might need. Draws from this.dayGridClass
   instantiateDayGrid() {
-    var SubClass: any = makeDayGridSubclass(this.dayGridClass);
+    let SubClass: any = makeDayGridSubclass(this.dayGridClass)
 
-    return new SubClass(this);
+    return new SubClass(this)
   }
 
 
@@ -73,45 +73,45 @@ export default class AgendaView extends View {
 
 
   renderSkeleton() {
-    var timeGridWrapEl;
-    var timeGridEl;
+    let timeGridWrapEl
+    let timeGridEl
 
-    this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml());
+    this.el.addClass('fc-agenda-view').html(this.renderSkeletonHtml())
 
-    this.scroller.render();
+    this.scroller.render()
 
-    timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container');
-    timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl);
+    timeGridWrapEl = this.scroller.el.addClass('fc-time-grid-container')
+    timeGridEl = $('<div class="fc-time-grid" />').appendTo(timeGridWrapEl)
 
-    this.el.find('.fc-body > tr > td').append(timeGridWrapEl);
+    this.el.find('.fc-body > tr > td').append(timeGridWrapEl)
 
-    this.timeGrid.headContainerEl = this.el.find('.fc-head-container');
-    this.timeGrid.setElement(timeGridEl);
+    this.timeGrid.headContainerEl = this.el.find('.fc-head-container')
+    this.timeGrid.setElement(timeGridEl)
 
     if (this.dayGrid) {
-      this.dayGrid.setElement(this.el.find('.fc-day-grid'));
+      this.dayGrid.setElement(this.el.find('.fc-day-grid'))
 
       // have the day-grid extend it's coordinate area over the <hr> dividing the two grids
-      this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight();
+      this.dayGrid.bottomCoordPadding = this.dayGrid.el.next('hr').outerHeight()
     }
   }
 
 
   unrenderSkeleton() {
-    this.timeGrid.removeElement();
+    this.timeGrid.removeElement()
 
     if (this.dayGrid) {
-      this.dayGrid.removeElement();
+      this.dayGrid.removeElement()
     }
 
-    this.scroller.destroy();
+    this.scroller.destroy()
   }
 
 
   // Builds the HTML skeleton for the view.
   // The day-grid and time-grid components will render inside containers defined by this HTML.
   renderSkeletonHtml() {
-    var theme = this.calendar.theme;
+    let theme = this.calendar.theme
 
     return '' +
       '<table class="' + theme.getClass('tableGrid') + '">' +
@@ -134,16 +134,16 @@ export default class AgendaView extends View {
             '</td>' +
           '</tr>' +
         '</tbody>' +
-      '</table>';
+      '</table>'
   }
 
 
   // Generates an HTML attribute string for setting the width of the axis, if it is known
   axisStyleAttr() {
     if (this.axisWidth != null) {
-      return 'style="width:' + this.axisWidth + 'px"';
+      return 'style="width:' + this.axisWidth + 'px"'
     }
-    return '';
+    return ''
   }
 
 
@@ -152,7 +152,7 @@ export default class AgendaView extends View {
 
 
   getNowIndicatorUnit() {
-    return this.timeGrid.getNowIndicatorUnit();
+    return this.timeGrid.getNowIndicatorUnit()
   }
 
 
@@ -162,70 +162,70 @@ export default class AgendaView extends View {
 
   // Adjusts the vertical dimensions of the view to the specified values
   updateSize(totalHeight, isAuto, isResize) {
-    var eventLimit;
-    var scrollerHeight;
-    var scrollbarWidths;
+    let eventLimit
+    let scrollerHeight
+    let scrollbarWidths
 
-    super.updateSize(totalHeight, isAuto, isResize);
+    super.updateSize(totalHeight, isAuto, isResize)
 
     // make all axis cells line up, and record the width so newly created axis cells will have it
-    this.axisWidth = matchCellWidths(this.el.find('.fc-axis'));
+    this.axisWidth = matchCellWidths(this.el.find('.fc-axis'))
 
     // hack to give the view some height prior to timeGrid's columns being rendered
     // TODO: separate setting height from scroller VS timeGrid.
     if (!this.timeGrid.colEls) {
       if (!isAuto) {
-        scrollerHeight = this.computeScrollerHeight(totalHeight);
-        this.scroller.setHeight(scrollerHeight);
+        scrollerHeight = this.computeScrollerHeight(totalHeight)
+        this.scroller.setHeight(scrollerHeight)
       }
-      return;
+      return
     }
 
     // set of fake row elements that must compensate when scroller has scrollbars
-    var noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)');
+    let noScrollRowEls = this.el.find('.fc-row:not(.fc-scroller *)')
 
     // reset all dimensions back to the original state
-    this.timeGrid.bottomRuleEl.hide(); // .show() will be called later if this <hr> is necessary
-    this.scroller.clear(); // sets height to 'auto' and clears overflow
-    uncompensateScroll(noScrollRowEls);
+    this.timeGrid.bottomRuleEl.hide() // .show() will be called later if this <hr> is necessary
+    this.scroller.clear() // sets height to 'auto' and clears overflow
+    uncompensateScroll(noScrollRowEls)
 
     // limit number of events in the all-day area
     if (this.dayGrid) {
-      this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
+      this.dayGrid.removeSegPopover() // kill the "more" popover if displayed
 
-      eventLimit = this.opt('eventLimit');
+      eventLimit = this.opt('eventLimit')
       if (eventLimit && typeof eventLimit !== 'number') {
-        eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT; // make sure "auto" goes to a real number
+        eventLimit = AGENDA_ALL_DAY_EVENT_LIMIT // make sure "auto" goes to a real number
       }
       if (eventLimit) {
-        this.dayGrid.limitRows(eventLimit);
+        this.dayGrid.limitRows(eventLimit)
       }
     }
 
     if (!isAuto) { // should we force dimensions of the scroll container?
 
-      scrollerHeight = this.computeScrollerHeight(totalHeight);
-      this.scroller.setHeight(scrollerHeight);
-      scrollbarWidths = this.scroller.getScrollbarWidths();
+      scrollerHeight = this.computeScrollerHeight(totalHeight)
+      this.scroller.setHeight(scrollerHeight)
+      scrollbarWidths = this.scroller.getScrollbarWidths()
 
       if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
 
         // make the all-day and header rows lines up
-        compensateScroll(noScrollRowEls, scrollbarWidths);
+        compensateScroll(noScrollRowEls, scrollbarWidths)
 
         // the scrollbar compensation might have changed text flow, which might affect height, so recalculate
         // and reapply the desired height to the scroller.
-        scrollerHeight = this.computeScrollerHeight(totalHeight);
-        this.scroller.setHeight(scrollerHeight);
+        scrollerHeight = this.computeScrollerHeight(totalHeight)
+        this.scroller.setHeight(scrollerHeight)
       }
 
       // guarantees the same scrollbar widths
-      this.scroller.lockOverflow(scrollbarWidths);
+      this.scroller.lockOverflow(scrollbarWidths)
 
       // if there's any space below the slats, show the horizontal rule.
       // this won't cause any new overflow, because lockOverflow already called.
       if (this.timeGrid.getTotalSlatHeight() < scrollerHeight) {
-        this.timeGrid.bottomRuleEl.show();
+        this.timeGrid.bottomRuleEl.show()
       }
     }
   }
@@ -234,7 +234,7 @@ export default class AgendaView extends View {
   // given a desired total height of the view, returns what the height of the scroller should be
   computeScrollerHeight(totalHeight) {
     return totalHeight -
-      subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+      subtractInnerElHeight(this.el, this.scroller.el) // everything that's NOT the scroller
   }
 
 
@@ -244,28 +244,28 @@ export default class AgendaView extends View {
 
   // Computes the initial pre-configured scroll state prior to allowing the user to change it
   computeInitialDateScroll() {
-    var scrollTime = moment.duration(this.opt('scrollTime'));
-    var top = this.timeGrid.computeTimeTop(scrollTime);
+    let scrollTime = moment.duration(this.opt('scrollTime'))
+    let top = this.timeGrid.computeTimeTop(scrollTime)
 
     // zoom can give weird floating-point values. rather scroll a little bit further
-    top = Math.ceil(top);
+    top = Math.ceil(top)
 
     if (top) {
-      top++; // to overcome top border that slots beyond the first have. looks better
+      top++ // to overcome top border that slots beyond the first have. looks better
     }
 
-    return { top: top };
+    return { top: top }
   }
 
 
   queryDateScroll() {
-    return { top: this.scroller.getScrollTop() };
+    return { top: this.scroller.getScrollTop() }
   }
 
 
   applyDateScroll(scroll) {
     if (scroll.top !== undefined) {
-      this.scroller.setScrollTop(scroll.top);
+      this.scroller.setScrollTop(scroll.top)
     }
   }
 
@@ -277,13 +277,13 @@ export default class AgendaView extends View {
 
   getHitFootprint(hit) {
     // TODO: hit.component is set as a hack to identify where the hit came from
-    return hit.component.getHitFootprint(hit);
+    return hit.component.getHitFootprint(hit)
   }
 
 
   getHitEl(hit) {
     // TODO: hit.component is set as a hack to identify where the hit came from
-    return hit.component.getHitEl(hit);
+    return hit.component.getHitEl(hit)
   }
 
 
@@ -292,26 +292,25 @@ export default class AgendaView extends View {
 
 
   executeEventRender(eventsPayload) {
-    var dayEventsPayload = {};
-    var timedEventsPayload = {};
-    var id, eventInstanceGroup;
+    let dayEventsPayload = {}
+    let timedEventsPayload = {}
+    let id, eventInstanceGroup
 
     // separate the events into all-day and timed
     for (id in eventsPayload) {
-      eventInstanceGroup = eventsPayload[id];
+      eventInstanceGroup = eventsPayload[id]
 
       if (eventInstanceGroup.getEventDef().isAllDay()) {
-        dayEventsPayload[id] = eventInstanceGroup;
-      }
-      else {
-        timedEventsPayload[id] = eventInstanceGroup;
+        dayEventsPayload[id] = eventInstanceGroup
+      } else {
+        timedEventsPayload[id] = eventInstanceGroup
       }
     }
 
-    this.timeGrid.executeEventRender(timedEventsPayload);
+    this.timeGrid.executeEventRender(timedEventsPayload)
 
     if (this.dayGrid) {
-      this.dayGrid.executeEventRender(dayEventsPayload);
+      this.dayGrid.executeEventRender(dayEventsPayload)
     }
   }
 
@@ -322,26 +321,26 @@ export default class AgendaView extends View {
 
   // A returned value of `true` signals that a mock "helper" event has been rendered.
   renderDrag(eventFootprints, seg, isTouch) {
-    var groups = groupEventFootprintsByAllDay(eventFootprints);
-    var renderedHelper = false;
+    let groups = groupEventFootprintsByAllDay(eventFootprints)
+    let renderedHelper = false
 
-    renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch);
+    renderedHelper = this.timeGrid.renderDrag(groups.timed, seg, isTouch)
 
     if (this.dayGrid) {
-      renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper;
+      renderedHelper = this.dayGrid.renderDrag(groups.allDay, seg, isTouch) || renderedHelper
     }
 
-    return renderedHelper;
+    return renderedHelper
   }
 
 
   renderEventResize(eventFootprints, seg, isTouch) {
-    var groups = groupEventFootprintsByAllDay(eventFootprints);
+    let groups = groupEventFootprintsByAllDay(eventFootprints)
 
-    this.timeGrid.renderEventResize(groups.timed, seg, isTouch);
+    this.timeGrid.renderEventResize(groups.timed, seg, isTouch)
 
     if (this.dayGrid) {
-      this.dayGrid.renderEventResize(groups.allDay, seg, isTouch);
+      this.dayGrid.renderEventResize(groups.allDay, seg, isTouch)
     }
   }
 
@@ -353,18 +352,17 @@ export default class AgendaView extends View {
   // Renders a visual indication of a selection
   renderSelectionFootprint(componentFootprint) {
     if (!componentFootprint.isAllDay) {
-      this.timeGrid.renderSelectionFootprint(componentFootprint);
-    }
-    else if (this.dayGrid) {
-      this.dayGrid.renderSelectionFootprint(componentFootprint);
+      this.timeGrid.renderSelectionFootprint(componentFootprint)
+    } else if (this.dayGrid) {
+      this.dayGrid.renderSelectionFootprint(componentFootprint)
     }
   }
 
 }
 
 
-AgendaView.prototype.timeGridClass = TimeGrid;
-AgendaView.prototype.dayGridClass = DayGrid;
+AgendaView.prototype.timeGridClass = TimeGrid
+AgendaView.prototype.dayGridClass = DayGrid
 
 
 // Will customize the rendering behavior of the AgendaView's timeGrid
@@ -374,13 +372,13 @@ function makeTimeGridSubclass(SuperClass) {
 
     // Generates the HTML that will go before the day-of week header cells
     renderHeadIntroHtml() {
-      var view = this.view;
-      var calendar = view.calendar;
-      var weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true);
-      var weekText;
+      let view = this.view
+      let calendar = view.calendar
+      let weekStart = calendar.msToUtcMoment(this.dateProfile.renderUnzonedRange.startMs, true)
+      let weekText
 
       if (this.opt('weekNumbers')) {
-        weekText = weekStart.format(this.opt('smallWeekFormat'));
+        weekText = weekStart.format(this.opt('smallWeekFormat'))
 
         return '' +
           '<th class="fc-axis fc-week-number ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '>' +
@@ -388,32 +386,31 @@ function makeTimeGridSubclass(SuperClass) {
               { date: weekStart, type: 'week', forceOff: this.colCnt > 1 },
               htmlEscape(weekText) // inner HTML
             ) +
-          '</th>';
-      }
-      else {
-        return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>';
+          '</th>'
+      } else {
+        return '<th class="fc-axis ' + calendar.theme.getClass('widgetHeader') + '" ' + view.axisStyleAttr() + '></th>'
       }
     }
 
 
     // Generates the HTML that goes before the bg of the TimeGrid slot area. Long vertical column.
     renderBgIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
-      return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>';
+      return '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '></td>'
     }
 
 
     // Generates the HTML that goes before all other types of cells.
     // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
     renderIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
-      return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
+      return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'
     }
 
   }
-};
+}
 
 
 // Will customize the rendering behavior of the AgendaView's dayGrid
@@ -423,42 +420,41 @@ function makeDayGridSubclass(SuperClass) {
 
     // Generates the HTML that goes before the all-day cells
     renderBgIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
       return '' +
         '<td class="fc-axis ' + view.calendar.theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
           '<span>' + // needed for matchCellWidths
             view.getAllDayHtml() +
           '</span>' +
-        '</td>';
+        '</td>'
     }
 
 
     // Generates the HTML that goes before all other types of cells.
     // Affects content-skeleton, helper-skeleton, highlight-skeleton for both the time-grid and day-grid.
     renderIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
-      return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>';
+      return '<td class="fc-axis" ' + view.axisStyleAttr() + '></td>'
     }
 
   }
-};
+}
 
 
 function groupEventFootprintsByAllDay(eventFootprints) {
-  var allDay = [];
-  var timed = [];
-  var i;
+  let allDay = []
+  let timed = []
+  let i
 
   for (i = 0; i < eventFootprints.length; i++) {
     if (eventFootprints[i].componentFootprint.isAllDay) {
-      allDay.push(eventFootprints[i]);
-    }
-    else {
-      timed.push(eventFootprints[i]);
+      allDay.push(eventFootprints[i])
+    } else {
+      timed.push(eventFootprints[i])
     }
   }
 
-  return { allDay: allDay, timed: timed };
+  return { allDay: allDay, timed: timed }
 }

+ 186 - 189
src/agenda/TimeGrid.ts

@@ -18,13 +18,13 @@ import TimeGridFillRenderer from './TimeGridFillRenderer'
 
 // potential nice values for the slot-duration and interval-duration
 // from largest to smallest
-var AGENDA_STOCK_SUB_DURATIONS = [
+let AGENDA_STOCK_SUB_DURATIONS = [
   { hours: 1 },
   { minutes: 30 },
   { minutes: 15 },
   { seconds: 30 },
   { seconds: 15 }
-];
+]
 
 export default class TimeGrid extends InteractiveDateComponent {
 
@@ -74,26 +74,25 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   constructor(view) {
-    super(view);
-    this.processOptions();
+    super(view)
+    this.processOptions()
   }
 
 
   // Slices up the given span (unzoned start/end with other misc data) into an array of segments
   componentFootprintToSegs(componentFootprint) {
-    var segs = this.sliceRangeByTimes(componentFootprint.unzonedRange);
-    var i;
+    let segs = this.sliceRangeByTimes(componentFootprint.unzonedRange)
+    let i
 
     for (i = 0; i < segs.length; i++) {
       if (this.isRTL) {
-        segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex;
-      }
-      else {
-        segs[i].col = segs[i].dayIndex;
+        segs[i].col = this.daysPerRow - 1 - segs[i].dayIndex
+      } else {
+        segs[i].col = segs[i].dayIndex
       }
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -102,13 +101,13 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   sliceRangeByTimes(unzonedRange) {
-    var segs = [];
-    var segRange;
-    var dayIndex;
+    let segs = []
+    let segRange
+    let dayIndex
 
     for (dayIndex = 0; dayIndex < this.daysPerRow; dayIndex++) {
 
-      segRange = unzonedRange.intersect(this.dayRanges[dayIndex]);
+      segRange = unzonedRange.intersect(this.dayRanges[dayIndex])
 
       if (segRange) {
         segs.push({
@@ -117,11 +116,11 @@ export default class TimeGrid extends InteractiveDateComponent {
           isStart: segRange.isStart,
           isEnd: segRange.isEnd,
           dayIndex: dayIndex
-        });
+        })
       }
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -131,50 +130,50 @@ export default class TimeGrid extends InteractiveDateComponent {
 
   // Parses various options into properties of this object
   processOptions() {
-    var slotDuration = this.opt('slotDuration');
-    var snapDuration = this.opt('snapDuration');
-    var input;
+    let slotDuration = this.opt('slotDuration')
+    let snapDuration = this.opt('snapDuration')
+    let input
 
-    slotDuration = moment.duration(slotDuration);
-    snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration;
+    slotDuration = moment.duration(slotDuration)
+    snapDuration = snapDuration ? moment.duration(snapDuration) : slotDuration
 
-    this.slotDuration = slotDuration;
-    this.snapDuration = snapDuration;
-    this.snapsPerSlot = slotDuration / snapDuration; // TODO: ensure an integer multiple?
+    this.slotDuration = slotDuration
+    this.snapDuration = snapDuration
+    this.snapsPerSlot = slotDuration / snapDuration // TODO: ensure an integer multiple?
 
     // might be an array value (for TimelineView).
     // if so, getting the most granular entry (the last one probably).
-    input = this.opt('slotLabelFormat');
+    input = this.opt('slotLabelFormat')
     if ($.isArray(input)) {
-      input = input[input.length - 1];
+      input = input[input.length - 1]
     }
 
     this.labelFormat = input ||
-      this.opt('smallTimeFormat'); // the computed default
+      this.opt('smallTimeFormat') // the computed default
 
-    input = this.opt('slotLabelInterval');
+    input = this.opt('slotLabelInterval')
     this.labelInterval = input ?
       moment.duration(input) :
-      this.computeLabelInterval(slotDuration);
+      this.computeLabelInterval(slotDuration)
   }
 
 
   // Computes an automatic value for slotLabelInterval
   computeLabelInterval(slotDuration) {
-    var i;
-    var labelInterval;
-    var slotsPerLabel;
+    let i
+    let labelInterval
+    let slotsPerLabel
 
     // find the smallest stock label interval that results in more than one slots-per-label
     for (i = AGENDA_STOCK_SUB_DURATIONS.length - 1; i >= 0; i--) {
-      labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i]);
-      slotsPerLabel = divideDurationByDuration(labelInterval, slotDuration);
+      labelInterval = moment.duration(AGENDA_STOCK_SUB_DURATIONS[i])
+      slotsPerLabel = divideDurationByDuration(labelInterval, slotDuration)
       if (isInt(slotsPerLabel) && slotsPerLabel > 1) {
-        return labelInterval;
+        return labelInterval
       }
     }
 
-    return moment.duration(slotDuration); // fall back. clone
+    return moment.duration(slotDuration) // fall back. clone
   }
 
 
@@ -183,69 +182,69 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   renderDates(dateProfile) {
-    this.dateProfile = dateProfile;
-    this.updateDayTable();
-    this.renderSlats();
-    this.renderColumns();
+    this.dateProfile = dateProfile
+    this.updateDayTable()
+    this.renderSlats()
+    this.renderColumns()
   }
 
 
   unrenderDates() {
     //this.unrenderSlats(); // don't need this because repeated .html() calls clear
-    this.unrenderColumns();
+    this.unrenderColumns()
   }
 
 
   renderSkeleton() {
-    var theme = this.view.calendar.theme;
+    let theme = this.view.calendar.theme
 
     this.el.html(
       '<div class="fc-bg"></div>' +
       '<div class="fc-slats"></div>' +
       '<hr class="fc-divider ' + theme.getClass('widgetHeader') + '" style="display:none" />'
-    );
+    )
 
-    this.bottomRuleEl = this.el.find('hr');
+    this.bottomRuleEl = this.el.find('hr')
   }
 
 
   renderSlats() {
-    var theme = this.view.calendar.theme;
+    let theme = this.view.calendar.theme
 
     this.slatContainerEl = this.el.find('> .fc-slats')
       .html( // avoids needing ::unrenderSlats()
         '<table class="' + theme.getClass('tableGrid') + '">' +
           this.renderSlatRowHtml() +
         '</table>'
-      );
+      )
 
-    this.slatEls = this.slatContainerEl.find('tr');
+    this.slatEls = this.slatContainerEl.find('tr')
 
     this.slatCoordCache = new CoordCache({
       els: this.slatEls,
       isVertical: true
-    });
+    })
   }
 
 
   // Generates the HTML for the horizontal "slats" that run width-wise. Has a time axis on a side. Depends on RTL.
   renderSlatRowHtml() {
-    var view = this.view;
-    var calendar = view.calendar;
-    var theme = calendar.theme;
-    var isRTL = this.isRTL;
-    var dateProfile = this.dateProfile;
-    var html = '';
-    var slotTime = moment.duration(+dateProfile.minTime); // wish there was .clone() for durations
-    var slotIterator = moment.duration(0);
-    var slotDate; // will be on the view's first day, but we only care about its time
-    var isLabeled;
-    var axisHtml;
+    let view = this.view
+    let calendar = view.calendar
+    let theme = calendar.theme
+    let isRTL = this.isRTL
+    let dateProfile = this.dateProfile
+    let html = ''
+    let slotTime = moment.duration(+dateProfile.minTime) // wish there was .clone() for durations
+    let slotIterator = moment.duration(0)
+    let slotDate // will be on the view's first day, but we only care about its time
+    let isLabeled
+    let axisHtml
 
     // Calculate the time for each slot
     while (slotTime < dateProfile.maxTime) {
-      slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime);
-      isLabeled = isInt(divideDurationByDuration(slotIterator, this.labelInterval));
+      slotDate = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs).time(slotTime)
+      isLabeled = isInt(divideDurationByDuration(slotIterator, this.labelInterval))
 
       axisHtml =
         '<td class="fc-axis fc-time ' + theme.getClass('widgetContent') + '" ' + view.axisStyleAttr() + '>' +
@@ -255,7 +254,7 @@ export default class TimeGrid extends InteractiveDateComponent {
             '</span>' :
             ''
             ) +
-        '</td>';
+        '</td>'
 
       html +=
         '<tr data-time="' + slotDate.format('HH:mm:ss') + '"' +
@@ -264,50 +263,50 @@ export default class TimeGrid extends InteractiveDateComponent {
           (!isRTL ? axisHtml : '') +
           '<td class="' + theme.getClass('widgetContent') + '"/>' +
           (isRTL ? axisHtml : '') +
-        "</tr>";
+        '</tr>'
 
-      slotTime.add(this.slotDuration);
-      slotIterator.add(this.slotDuration);
+      slotTime.add(this.slotDuration)
+      slotIterator.add(this.slotDuration)
     }
 
-    return html;
+    return html
   }
 
 
   renderColumns() {
-    var dateProfile = this.dateProfile;
-    var theme = this.view.calendar.theme;
+    let dateProfile = this.dateProfile
+    let theme = this.view.calendar.theme
 
     this.dayRanges = this.dayDates.map(function(dayDate) {
       return new UnzonedRange(
         dayDate.clone().add(dateProfile.minTime),
         dayDate.clone().add(dateProfile.maxTime)
-      );
-    });
+      )
+    })
 
     if (this.headContainerEl) {
-      this.headContainerEl.html(this.renderHeadHtml());
+      this.headContainerEl.html(this.renderHeadHtml())
     }
 
     this.el.find('> .fc-bg').html(
       '<table class="' + theme.getClass('tableGrid') + '">' +
         this.renderBgTrHtml(0) + // row=0
       '</table>'
-    );
+    )
 
-    this.colEls = this.el.find('.fc-day, .fc-disabled-day');
+    this.colEls = this.el.find('.fc-day, .fc-disabled-day')
 
     this.colCoordCache = new CoordCache({
       els: this.colEls,
       isHorizontal: true
-    });
+    })
 
-    this.renderContentSkeleton();
+    this.renderContentSkeleton()
   }
 
 
   unrenderColumns() {
-    this.unrenderContentSkeleton();
+    this.unrenderContentSkeleton()
   }
 
 
@@ -317,9 +316,9 @@ export default class TimeGrid extends InteractiveDateComponent {
 
   // Renders the DOM that the view's content will live in
   renderContentSkeleton() {
-    var cellHtml = '';
-    var i;
-    var skeletonEl;
+    let cellHtml = ''
+    let i
+    let skeletonEl
 
     for (i = 0; i < this.colCnt; i++) {
       cellHtml +=
@@ -331,7 +330,7 @@ export default class TimeGrid extends InteractiveDateComponent {
             '<div class="fc-bgevent-container"></div>' +
             '<div class="fc-business-container"></div>' +
           '</div>' +
-        '</td>';
+        '</td>'
     }
 
     skeletonEl = this.contentSkeletonEl = $(
@@ -340,61 +339,61 @@ export default class TimeGrid extends InteractiveDateComponent {
           '<tr>' + cellHtml + '</tr>' +
         '</table>' +
       '</div>'
-    );
+    )
 
-    this.colContainerEls = skeletonEl.find('.fc-content-col');
-    this.helperContainerEls = skeletonEl.find('.fc-helper-container');
-    this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)');
-    this.bgContainerEls = skeletonEl.find('.fc-bgevent-container');
-    this.highlightContainerEls = skeletonEl.find('.fc-highlight-container');
-    this.businessContainerEls = skeletonEl.find('.fc-business-container');
+    this.colContainerEls = skeletonEl.find('.fc-content-col')
+    this.helperContainerEls = skeletonEl.find('.fc-helper-container')
+    this.fgContainerEls = skeletonEl.find('.fc-event-container:not(.fc-helper-container)')
+    this.bgContainerEls = skeletonEl.find('.fc-bgevent-container')
+    this.highlightContainerEls = skeletonEl.find('.fc-highlight-container')
+    this.businessContainerEls = skeletonEl.find('.fc-business-container')
 
-    this.bookendCells(skeletonEl.find('tr')); // TODO: do this on string level
-    this.el.append(skeletonEl);
+    this.bookendCells(skeletonEl.find('tr')) // TODO: do this on string level
+    this.el.append(skeletonEl)
   }
 
 
   unrenderContentSkeleton() {
-    this.contentSkeletonEl.remove();
-    this.contentSkeletonEl = null;
-    this.colContainerEls = null;
-    this.helperContainerEls = null;
-    this.fgContainerEls = null;
-    this.bgContainerEls = null;
-    this.highlightContainerEls = null;
-    this.businessContainerEls = null;
+    this.contentSkeletonEl.remove()
+    this.contentSkeletonEl = null
+    this.colContainerEls = null
+    this.helperContainerEls = null
+    this.fgContainerEls = null
+    this.bgContainerEls = null
+    this.highlightContainerEls = null
+    this.businessContainerEls = null
   }
 
 
   // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's col
   groupSegsByCol(segs) {
-    var segsByCol = [];
-    var i;
+    let segsByCol = []
+    let i
 
     for (i = 0; i < this.colCnt; i++) {
-      segsByCol.push([]);
+      segsByCol.push([])
     }
 
     for (i = 0; i < segs.length; i++) {
-      segsByCol[segs[i].col].push(segs[i]);
+      segsByCol[segs[i].col].push(segs[i])
     }
 
-    return segsByCol;
+    return segsByCol
   }
 
 
   // Given segments grouped by column, insert the segments' elements into a parallel array of container
   // elements, each living within a column.
   attachSegsByCol(segsByCol, containerEls) {
-    var col;
-    var segs;
-    var i;
+    let col
+    let segs
+    let i
 
     for (col = 0; col < this.colCnt; col++) { // iterate each column grouping
-      segs = segsByCol[col];
+      segs = segsByCol[col]
 
       for (i = 0; i < segs.length; i++) {
-        containerEls.eq(col).append(segs[i].el);
+        containerEls.eq(col).append(segs[i].el)
       }
     }
   }
@@ -405,7 +404,7 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   getNowIndicatorUnit() {
-    return 'minute'; // will refresh on the minute
+    return 'minute' // will refresh on the minute
   }
 
 
@@ -413,43 +412,43 @@ export default class TimeGrid extends InteractiveDateComponent {
 
     // HACK: if date columns not ready for some reason (scheduler)
     if (!this.colContainerEls) {
-      return;
+      return
     }
 
     // seg system might be overkill, but it handles scenario where line needs to be rendered
     //  more than once because of columns with the same date (resources columns for example)
-    var segs = this.componentFootprintToSegs(
+    let segs = this.componentFootprintToSegs(
       new ComponentFootprint(
         new UnzonedRange(date, date.valueOf() + 1), // protect against null range
         false // all-day
       )
-    );
-    var top = this.computeDateTop(date, date);
-    var nodes = [];
-    var i;
+    )
+    let top = this.computeDateTop(date, date)
+    let nodes = []
+    let i
 
     // render lines within the columns
     for (i = 0; i < segs.length; i++) {
       nodes.push($('<div class="fc-now-indicator fc-now-indicator-line"></div>')
         .css('top', top)
-        .appendTo(this.colContainerEls.eq(segs[i].col))[0]);
+        .appendTo(this.colContainerEls.eq(segs[i].col))[0])
     }
 
     // render an arrow over the axis
     if (segs.length > 0) { // is the current time in view?
       nodes.push($('<div class="fc-now-indicator fc-now-indicator-arrow"></div>')
         .css('top', top)
-        .appendTo(this.el.find('.fc-content-skeleton'))[0]);
+        .appendTo(this.el.find('.fc-content-skeleton'))[0])
     }
 
-    this.nowIndicatorEls = $(nodes);
+    this.nowIndicatorEls = $(nodes)
   }
 
 
   unrenderNowIndicator() {
     if (this.nowIndicatorEls) {
-      this.nowIndicatorEls.remove();
-      this.nowIndicatorEls = null;
+      this.nowIndicatorEls.remove()
+      this.nowIndicatorEls = null
     }
   }
 
@@ -459,20 +458,20 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   updateSize(totalHeight, isAuto, isResize) {
-    super.updateSize(totalHeight, isAuto, isResize);
+    super.updateSize(totalHeight, isAuto, isResize)
 
-    this.slatCoordCache.build();
+    this.slatCoordCache.build()
 
     if (isResize) {
       this.updateSegVerticals(
         [].concat(this.eventRenderer.getSegs(), this.businessSegs || [])
-      );
+      )
     }
   }
 
 
   getTotalSlatHeight() {
-    return this.slatContainerEl.outerHeight();
+    return this.slatContainerEl.outerHeight()
   }
 
 
@@ -484,61 +483,61 @@ export default class TimeGrid extends InteractiveDateComponent {
       moment.duration(
         ms - startOfDayDate.clone().stripTime()
       )
-    );
+    )
   }
 
 
   // Computes the top coordinate, relative to the bounds of the grid, of the given time (a Duration).
   computeTimeTop(time) {
-    var len = this.slatEls.length;
-    var dateProfile = this.dateProfile;
-    var slatCoverage = (time - dateProfile.minTime) / this.slotDuration; // floating-point value of # of slots covered
-    var slatIndex;
-    var slatRemainder;
+    let len = this.slatEls.length
+    let dateProfile = this.dateProfile
+    let slatCoverage = (time - dateProfile.minTime) / this.slotDuration // floating-point value of # of slots covered
+    let slatIndex
+    let slatRemainder
 
     // compute a floating-point number for how many slats should be progressed through.
     // from 0 to number of slats (inclusive)
     // constrained because minTime/maxTime might be customized.
-    slatCoverage = Math.max(0, slatCoverage);
-    slatCoverage = Math.min(len, slatCoverage);
+    slatCoverage = Math.max(0, slatCoverage)
+    slatCoverage = Math.min(len, slatCoverage)
 
     // an integer index of the furthest whole slat
     // from 0 to number slats (*exclusive*, so len-1)
-    slatIndex = Math.floor(slatCoverage);
-    slatIndex = Math.min(slatIndex, len - 1);
+    slatIndex = Math.floor(slatCoverage)
+    slatIndex = Math.min(slatIndex, len - 1)
 
     // how much further through the slatIndex slat (from 0.0-1.0) must be covered in addition.
     // could be 1.0 if slatCoverage is covering *all* the slots
-    slatRemainder = slatCoverage - slatIndex;
+    slatRemainder = slatCoverage - slatIndex
 
     return this.slatCoordCache.getTopPosition(slatIndex) +
-      this.slatCoordCache.getHeight(slatIndex) * slatRemainder;
+      this.slatCoordCache.getHeight(slatIndex) * slatRemainder
   }
 
 
   // Refreshes the CSS top/bottom coordinates for each segment element.
   // Works when called after initial render, after a window resize/zoom for example.
   updateSegVerticals(segs) {
-    this.computeSegVerticals(segs);
-    this.assignSegVerticals(segs);
+    this.computeSegVerticals(segs)
+    this.assignSegVerticals(segs)
   }
 
 
   // For each segment in an array, computes and assigns its top and bottom properties
   computeSegVerticals(segs) {
-    var eventMinHeight = this.opt('agendaEventMinHeight');
-    var i, seg;
-    var dayDate;
+    let eventMinHeight = this.opt('agendaEventMinHeight')
+    let i, seg
+    let dayDate
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
-      dayDate = this.dayDates[seg.dayIndex];
+      seg = segs[i]
+      dayDate = this.dayDates[seg.dayIndex]
 
-      seg.top = this.computeDateTop(seg.startMs, dayDate);
+      seg.top = this.computeDateTop(seg.startMs, dayDate)
       seg.bottom = Math.max(
         seg.top + eventMinHeight,
         this.computeDateTop(seg.endMs, dayDate)
-      );
+      )
     }
   }
 
@@ -546,11 +545,11 @@ export default class TimeGrid extends InteractiveDateComponent {
   // Given segments that already have their top/bottom properties computed, applies those values to
   // the segments' elements.
   assignSegVerticals(segs) {
-    var i, seg;
+    let i, seg
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
-      seg.el.css(this.generateSegVerticalCss(seg));
+      seg = segs[i]
+      seg.el.css(this.generateSegVerticalCss(seg))
     }
   }
 
@@ -560,7 +559,7 @@ export default class TimeGrid extends InteractiveDateComponent {
     return {
       top: seg.top,
       bottom: -seg.bottom // flipped because needs to be space beyond bottom edge of event container
-    };
+    }
   }
 
 
@@ -569,34 +568,34 @@ export default class TimeGrid extends InteractiveDateComponent {
 
 
   prepareHits() {
-    this.colCoordCache.build();
-    this.slatCoordCache.build();
+    this.colCoordCache.build()
+    this.slatCoordCache.build()
   }
 
 
   releaseHits() {
-    this.colCoordCache.clear();
+    this.colCoordCache.clear()
     // NOTE: don't clear slatCoordCache because we rely on it for computeTimeTop
   }
 
 
   queryHit(leftOffset, topOffset): any {
-    var snapsPerSlot = this.snapsPerSlot;
-    var colCoordCache = this.colCoordCache;
-    var slatCoordCache = this.slatCoordCache;
+    let snapsPerSlot = this.snapsPerSlot
+    let colCoordCache = this.colCoordCache
+    let slatCoordCache = this.slatCoordCache
 
     if (colCoordCache.isLeftInBounds(leftOffset) && slatCoordCache.isTopInBounds(topOffset)) {
-      var colIndex = colCoordCache.getHorizontalIndex(leftOffset);
-      var slatIndex = slatCoordCache.getVerticalIndex(topOffset);
+      let colIndex = colCoordCache.getHorizontalIndex(leftOffset)
+      let slatIndex = slatCoordCache.getVerticalIndex(topOffset)
 
       if (colIndex != null && slatIndex != null) {
-        var slatTop = slatCoordCache.getTopOffset(slatIndex);
-        var slatHeight = slatCoordCache.getHeight(slatIndex);
-        var partial = (topOffset - slatTop) / slatHeight; // floating point number between 0 and 1
-        var localSnapIndex = Math.floor(partial * snapsPerSlot); // the snap # relative to start of slat
-        var snapIndex = slatIndex * snapsPerSlot + localSnapIndex;
-        var snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight;
-        var snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight;
+        let slatTop = slatCoordCache.getTopOffset(slatIndex)
+        let slatHeight = slatCoordCache.getHeight(slatIndex)
+        let partial = (topOffset - slatTop) / slatHeight // floating point number between 0 and 1
+        let localSnapIndex = Math.floor(partial * snapsPerSlot) // the snap # relative to start of slat
+        let snapIndex = slatIndex * snapsPerSlot + localSnapIndex
+        let snapTop = slatTop + (localSnapIndex / snapsPerSlot) * slatHeight
+        let snapBottom = slatTop + ((localSnapIndex + 1) / snapsPerSlot) * slatHeight
 
         return {
           col: colIndex,
@@ -606,35 +605,35 @@ export default class TimeGrid extends InteractiveDateComponent {
           right: colCoordCache.getRightOffset(colIndex),
           top: snapTop,
           bottom: snapBottom
-        };
+        }
       }
     }
   }
 
 
   getHitFootprint(hit) {
-    var start = this.getCellDate(0, hit.col); // row=0
-    var time = this.computeSnapTime(hit.snap); // pass in the snap-index
-    var end;
+    let start = this.getCellDate(0, hit.col) // row=0
+    let time = this.computeSnapTime(hit.snap) // pass in the snap-index
+    let end
 
-    start.time(time);
-    end = start.clone().add(this.snapDuration);
+    start.time(time)
+    end = start.clone().add(this.snapDuration)
 
     return new ComponentFootprint(
       new UnzonedRange(start, end),
       false // all-day?
-    );
+    )
   }
 
 
   // Given a row number of the grid, representing a "snap", returns a time (Duration) from its start-of-day
   computeSnapTime(snapIndex) {
-    return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex);
+    return moment.duration(this.dateProfile.minTime + this.snapDuration * snapIndex)
   }
 
 
   getHitEl(hit) {
-    return this.colEls.eq(hit.col);
+    return this.colEls.eq(hit.col)
   }
 
 
@@ -645,21 +644,20 @@ export default class TimeGrid extends InteractiveDateComponent {
   // Renders a visual indication of an event being dragged over the specified date(s).
   // A returned value of `true` signals that a mock "helper" event has been rendered.
   renderDrag(eventFootprints, seg, isTouch) {
-    var i;
+    let i
 
     if (seg) { // if there is event information for this drag, render a helper event
 
       if (eventFootprints.length) {
-        this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
+        this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch)
 
         // signal that a helper has been rendered
-        return true;
+        return true
       }
-    }
-    else { // otherwise, just render a highlight
+    } else { // otherwise, just render a highlight
 
       for (i = 0; i < eventFootprints.length; i++) {
-        this.renderHighlight(eventFootprints[i].componentFootprint);
+        this.renderHighlight(eventFootprints[i].componentFootprint)
       }
     }
   }
@@ -667,8 +665,8 @@ export default class TimeGrid extends InteractiveDateComponent {
 
   // Unrenders any visual indication of an event being dragged
   unrenderDrag() {
-    this.unrenderHighlight();
-    this.helperRenderer.unrender();
+    this.unrenderHighlight()
+    this.helperRenderer.unrender()
   }
 
 
@@ -678,13 +676,13 @@ export default class TimeGrid extends InteractiveDateComponent {
 
   // Renders a visual indication of an event being resized
   renderEventResize(eventFootprints, seg, isTouch) {
-    this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
+    this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch)
   }
 
 
   // Unrenders any visual indication of an event being resized
   unrenderEventResize() {
-    this.helperRenderer.unrender();
+    this.helperRenderer.unrender()
   }
 
 
@@ -695,18 +693,17 @@ export default class TimeGrid extends InteractiveDateComponent {
   // Renders a visual indication of a selection. Overrides the default, which was to simply render a highlight.
   renderSelectionFootprint(componentFootprint) {
     if (this.opt('selectHelper')) { // this setting signals that a mock helper event should be rendered
-      this.helperRenderer.renderComponentFootprint(componentFootprint);
-    }
-    else {
-      this.renderHighlight(componentFootprint);
+      this.helperRenderer.renderComponentFootprint(componentFootprint)
+    } else {
+      this.renderHighlight(componentFootprint)
     }
   }
 
 
   // Unrenders any visual indication of a selection
   unrenderSelection() {
-    this.helperRenderer.unrender();
-    this.unrenderHighlight();
+    this.helperRenderer.unrender()
+    this.unrenderHighlight()
   }
 
 }

+ 115 - 118
src/agenda/TimeGridEventRenderer.ts

@@ -11,70 +11,70 @@ export default class TimeGridEventRenderer extends EventRenderer {
 
 
   constructor(timeGrid, fillRenderer) {
-    super(timeGrid, fillRenderer);
-    this.timeGrid = timeGrid;
+    super(timeGrid, fillRenderer)
+    this.timeGrid = timeGrid
   }
 
 
   renderFgSegs(segs) {
-    this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls);
+    this.renderFgSegsIntoContainers(segs, this.timeGrid.fgContainerEls)
   }
 
 
   // Given an array of foreground segments, render a DOM element for each, computes position,
   // and attaches to the column inner-container elements.
   renderFgSegsIntoContainers(segs, containerEls) {
-    var segsByCol;
-    var col;
+    let segsByCol
+    let col
 
-    segsByCol = this.timeGrid.groupSegsByCol(segs);
+    segsByCol = this.timeGrid.groupSegsByCol(segs)
 
     for (col = 0; col < this.timeGrid.colCnt; col++) {
-      this.updateFgSegCoords(segsByCol[col]);
+      this.updateFgSegCoords(segsByCol[col])
     }
 
-    this.timeGrid.attachSegsByCol(segsByCol, containerEls);
+    this.timeGrid.attachSegsByCol(segsByCol, containerEls)
   }
 
 
   unrenderFgSegs() {
     if (this.fgSegs) { // hack
       this.fgSegs.forEach(function(seg) {
-        seg.el.remove();
-      });
+        seg.el.remove()
+      })
     }
   }
 
 
   // Computes a default event time formatting string if `timeFormat` is not explicitly defined
   computeEventTimeFormat() {
-    return this.opt('noMeridiemTimeFormat'); // like "6:30" (no AM/PM)
+    return this.opt('noMeridiemTimeFormat') // like "6:30" (no AM/PM)
   }
 
 
   // Computes a default `displayEventEnd` value if one is not expliclty defined
   computeDisplayEventEnd() {
-    return true;
+    return true
   }
 
 
   // Renders the HTML for a single event segment's default rendering
   fgSegHtml(seg, disableResizing) {
-    var view = this.view;
-    var calendar = view.calendar;
-    var componentFootprint = seg.footprint.componentFootprint;
-    var isAllDay = componentFootprint.isAllDay;
-    var eventDef = seg.footprint.eventDef;
-    var isDraggable = view.isEventDefDraggable(eventDef);
-    var isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef);
-    var isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
-    var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
-    var skinCss = cssToStr(this.getSkinCss(eventDef));
-    var timeText;
-    var fullTimeText; // more verbose time text. for the print stylesheet
-    var startTimeText; // just the start time text
-
-    classes.unshift('fc-time-grid-event', 'fc-v-event');
+    let view = this.view
+    let calendar = view.calendar
+    let componentFootprint = seg.footprint.componentFootprint
+    let isAllDay = componentFootprint.isAllDay
+    let eventDef = seg.footprint.eventDef
+    let isDraggable = view.isEventDefDraggable(eventDef)
+    let isResizableFromStart = !disableResizing && seg.isStart && view.isEventDefResizableFromStart(eventDef)
+    let isResizableFromEnd = !disableResizing && seg.isEnd && view.isEventDefResizableFromEnd(eventDef)
+    let classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd)
+    let skinCss = cssToStr(this.getSkinCss(eventDef))
+    let timeText
+    let fullTimeText // more verbose time text. for the print stylesheet
+    let startTimeText // just the start time text
+
+    classes.unshift('fc-time-grid-event', 'fc-v-event')
 
     // if the event appears to span more than one day...
     if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
@@ -82,18 +82,17 @@ export default class TimeGridEventRenderer extends EventRenderer {
       // That would appear as midnight-midnight and would look dumb.
       // Otherwise, display the time text for the *segment's* times (like 6pm-midnight or midnight-10am)
       if (seg.isStart || seg.isEnd) {
-        var zonedStart = calendar.msToMoment(seg.startMs);
-        var zonedEnd = calendar.msToMoment(seg.endMs);
-        timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay);
-        fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT');
-        startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false); // displayEnd=false
+        let zonedStart = calendar.msToMoment(seg.startMs)
+        let zonedEnd = calendar.msToMoment(seg.endMs)
+        timeText = this._getTimeText(zonedStart, zonedEnd, isAllDay)
+        fullTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, 'LT')
+        startTimeText = this._getTimeText(zonedStart, zonedEnd, isAllDay, null, false) // displayEnd=false
       }
-    }
-    else {
+    } else {
       // Display the normal time text for the *event's* times
-      timeText = this.getTimeText(seg.footprint);
-      fullTimeText = this.getTimeText(seg.footprint, 'LT');
-      startTimeText = this.getTimeText(seg.footprint, null, false); // displayEnd=false
+      timeText = this.getTimeText(seg.footprint)
+      fullTimeText = this.getTimeText(seg.footprint, 'LT')
+      startTimeText = this.getTimeText(seg.footprint, null, false) // displayEnd=false
     }
 
     return '<a class="' + classes.join(' ') + '"' +
@@ -134,39 +133,39 @@ export default class TimeGridEventRenderer extends EventRenderer {
           '<div class="fc-resizer fc-end-resizer" />' :
           ''
           ) +
-      '</a>';
+      '</a>'
   }
 
 
   // Given segments that are assumed to all live in the *same column*,
   // compute their verical/horizontal coordinates and assign to their elements.
   updateFgSegCoords(segs) {
-    this.timeGrid.computeSegVerticals(segs); // horizontals relies on this
-    this.computeFgSegHorizontals(segs); // compute horizontal coordinates, z-index's, and reorder the array
-    this.timeGrid.assignSegVerticals(segs);
-    this.assignFgSegHorizontals(segs);
+    this.timeGrid.computeSegVerticals(segs) // horizontals relies on this
+    this.computeFgSegHorizontals(segs) // compute horizontal coordinates, z-index's, and reorder the array
+    this.timeGrid.assignSegVerticals(segs)
+    this.assignFgSegHorizontals(segs)
   }
 
 
   // Given an array of segments that are all in the same column, sets the backwardCoord and forwardCoord on each.
   // NOTE: Also reorders the given array by date!
   computeFgSegHorizontals(segs) {
-    var levels;
-    var level0;
-    var i;
+    let levels
+    let level0
+    let i
 
-    this.sortEventSegs(segs); // order by certain criteria
-    levels = buildSlotSegLevels(segs);
-    computeForwardSlotSegs(levels);
+    this.sortEventSegs(segs) // order by certain criteria
+    levels = buildSlotSegLevels(segs)
+    computeForwardSlotSegs(levels)
 
     if ((level0 = levels[0])) {
 
       for (i = 0; i < level0.length; i++) {
-        computeSlotSegPressures(level0[i]);
+        computeSlotSegPressures(level0[i])
       }
 
       for (i = 0; i < level0.length; i++) {
-        this.computeFgSegForwardBack(level0[i], 0, 0);
+        this.computeFgSegForwardBack(level0[i], 0, 0)
       }
     }
   }
@@ -181,43 +180,42 @@ export default class TimeGridEventRenderer extends EventRenderer {
   // segments behind this one in the current series, and `seriesBackwardCoord` is the starting
   // coordinate of the first segment in the series.
   computeFgSegForwardBack(seg, seriesBackwardPressure, seriesBackwardCoord) {
-    var forwardSegs = seg.forwardSegs;
-    var i;
+    let forwardSegs = seg.forwardSegs
+    let i
 
     if (seg.forwardCoord === undefined) { // not already computed
 
       if (!forwardSegs.length) {
 
         // if there are no forward segments, this segment should butt up against the edge
-        seg.forwardCoord = 1;
-      }
-      else {
+        seg.forwardCoord = 1
+      } else {
 
         // sort highest pressure first
-        this.sortForwardSegs(forwardSegs);
+        this.sortForwardSegs(forwardSegs)
 
         // this segment's forwardCoord will be calculated from the backwardCoord of the
         // highest-pressure forward segment.
-        this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord);
-        seg.forwardCoord = forwardSegs[0].backwardCoord;
+        this.computeFgSegForwardBack(forwardSegs[0], seriesBackwardPressure + 1, seriesBackwardCoord)
+        seg.forwardCoord = forwardSegs[0].backwardCoord
       }
 
       // calculate the backwardCoord from the forwardCoord. consider the series
       seg.backwardCoord = seg.forwardCoord -
         (seg.forwardCoord - seriesBackwardCoord) / // available width for series
-        (seriesBackwardPressure + 1); // # of segments in the series
+        (seriesBackwardPressure + 1) // # of segments in the series
 
       // use this segment's coordinates to computed the coordinates of the less-pressurized
       // forward segments
-      for (i=0; i<forwardSegs.length; i++) {
-        this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord);
+      for (i = 0; i < forwardSegs.length; i++) {
+        this.computeFgSegForwardBack(forwardSegs[i], 0, seg.forwardCoord)
       }
     }
   }
 
 
   sortForwardSegs(forwardSegs) {
-    forwardSegs.sort(proxy(this, 'compareForwardSegs'));
+    forwardSegs.sort(proxy(this, 'compareForwardSegs'))
   }
 
 
@@ -228,22 +226,22 @@ export default class TimeGridEventRenderer extends EventRenderer {
       // put segments that are closer to initial edge first (and favor ones with no coords yet)
       (seg1.backwardCoord || 0) - (seg2.backwardCoord || 0) ||
       // do normal sorting...
-      this.compareEventSegs(seg1, seg2);
+      this.compareEventSegs(seg1, seg2)
   }
 
 
   // Given foreground event segments that have already had their position coordinates computed,
   // assigns position-related CSS values to their elements.
   assignFgSegHorizontals(segs) {
-    var i, seg;
+    let i, seg
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
-      seg.el.css(this.generateFgSegHorizontalCss(seg));
+      seg = segs[i]
+      seg.el.css(this.generateFgSegHorizontalCss(seg))
 
       // if the height is short, add a className for alternate styling
       if (seg.bottom - seg.top < 30) {
-        seg.el.addClass('fc-short');
+        seg.el.addClass('fc-short')
       }
     }
   }
@@ -252,38 +250,37 @@ export default class TimeGridEventRenderer extends EventRenderer {
   // Generates an object with CSS properties/values that should be applied to an event segment element.
   // Contains important positioning-related properties that should be applied to any event element, customized or not.
   generateFgSegHorizontalCss(seg) {
-    var shouldOverlap = this.opt('slotEventOverlap');
-    var backwardCoord = seg.backwardCoord; // the left side if LTR. the right side if RTL. floating-point
-    var forwardCoord = seg.forwardCoord; // the right side if LTR. the left side if RTL. floating-point
-    var props = this.timeGrid.generateSegVerticalCss(seg); // get top/bottom first
-    var isRTL = this.timeGrid.isRTL;
-    var left; // amount of space from left edge, a fraction of the total width
-    var right; // amount of space from right edge, a fraction of the total width
+    let shouldOverlap = this.opt('slotEventOverlap')
+    let backwardCoord = seg.backwardCoord // the left side if LTR. the right side if RTL. floating-point
+    let forwardCoord = seg.forwardCoord // the right side if LTR. the left side if RTL. floating-point
+    let props = this.timeGrid.generateSegVerticalCss(seg) // get top/bottom first
+    let isRTL = this.timeGrid.isRTL
+    let left // amount of space from left edge, a fraction of the total width
+    let right // amount of space from right edge, a fraction of the total width
 
     if (shouldOverlap) {
       // double the width, but don't go beyond the maximum forward coordinate (1.0)
-      forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2);
+      forwardCoord = Math.min(1, backwardCoord + (forwardCoord - backwardCoord) * 2)
     }
 
     if (isRTL) {
-      left = 1 - forwardCoord;
-      right = backwardCoord;
-    }
-    else {
-      left = backwardCoord;
-      right = 1 - forwardCoord;
+      left = 1 - forwardCoord
+      right = backwardCoord
+    } else {
+      left = backwardCoord
+      right = 1 - forwardCoord
     }
 
-    props.zIndex = seg.level + 1; // convert from 0-base to 1-based
-    props.left = left * 100 + '%';
-    props.right = right * 100 + '%';
+    props.zIndex = seg.level + 1 // convert from 0-base to 1-based
+    props.left = left * 100 + '%'
+    props.right = right * 100 + '%'
 
     if (shouldOverlap && seg.forwardPressure) {
       // add padding to the edge so that forward stacked events don't cover the resizer's icon
-      props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2; // 10 is a guesstimate of the icon's width
+      props[isRTL ? 'marginLeft' : 'marginRight'] = 10 * 2 // 10 is a guesstimate of the icon's width
     }
 
-    return props;
+    return props
   }
 
 }
@@ -292,45 +289,45 @@ export default class TimeGridEventRenderer extends EventRenderer {
 // Builds an array of segments "levels". The first level will be the leftmost tier of segments if the calendar is
 // left-to-right, or the rightmost if the calendar is right-to-left. Assumes the segments are already ordered by date.
 function buildSlotSegLevels(segs) {
-  var levels = [];
-  var i, seg;
-  var j;
+  let levels = []
+  let i, seg
+  let j
 
-  for (i=0; i<segs.length; i++) {
-    seg = segs[i];
+  for (i = 0; i < segs.length; i++) {
+    seg = segs[i]
 
     // go through all the levels and stop on the first level where there are no collisions
-    for (j=0; j<levels.length; j++) {
+    for (j = 0; j < levels.length; j++) {
       if (!computeSlotSegCollisions(seg, levels[j]).length) {
-        break;
+        break
       }
     }
 
     seg.level = j;
 
-    (levels[j] || (levels[j] = [])).push(seg);
+    (levels[j] || (levels[j] = [])).push(seg)
   }
 
-  return levels;
+  return levels
 }
 
 
 // For every segment, figure out the other segments that are in subsequent
 // levels that also occupy the same vertical space. Accumulate in seg.forwardSegs
 function computeForwardSlotSegs(levels) {
-  var i, level;
-  var j, seg;
-  var k;
+  let i, level
+  let j, seg
+  let k
 
-  for (i=0; i<levels.length; i++) {
-    level = levels[i];
+  for (i = 0; i < levels.length; i++) {
+    level = levels[i]
 
-    for (j=0; j<level.length; j++) {
-      seg = level[j];
+    for (j = 0; j < level.length; j++) {
+      seg = level[j]
 
-      seg.forwardSegs = [];
-      for (k=i+1; k<levels.length; k++) {
-        computeSlotSegCollisions(seg, levels[k], seg.forwardSegs);
+      seg.forwardSegs = []
+      for (k = i + 1; k < levels.length; k++) {
+        computeSlotSegCollisions(seg, levels[k], seg.forwardSegs)
       }
     }
   }
@@ -340,46 +337,46 @@ function computeForwardSlotSegs(levels) {
 // Figure out which path forward (via seg.forwardSegs) results in the longest path until
 // the furthest edge is reached. The number of segments in this path will be seg.forwardPressure
 function computeSlotSegPressures(seg) {
-  var forwardSegs = seg.forwardSegs;
-  var forwardPressure = 0;
-  var i, forwardSeg;
+  let forwardSegs = seg.forwardSegs
+  let forwardPressure = 0
+  let i, forwardSeg
 
   if (seg.forwardPressure === undefined) { // not already computed
 
-    for (i=0; i<forwardSegs.length; i++) {
-      forwardSeg = forwardSegs[i];
+    for (i = 0; i < forwardSegs.length; i++) {
+      forwardSeg = forwardSegs[i]
 
       // figure out the child's maximum forward path
-      computeSlotSegPressures(forwardSeg);
+      computeSlotSegPressures(forwardSeg)
 
       // either use the existing maximum, or use the child's forward pressure
       // plus one (for the forwardSeg itself)
       forwardPressure = Math.max(
         forwardPressure,
         1 + forwardSeg.forwardPressure
-      );
+      )
     }
 
-    seg.forwardPressure = forwardPressure;
+    seg.forwardPressure = forwardPressure
   }
 }
 
 
 // Find all the segments in `otherSegs` that vertically collide with `seg`.
 // Append into an optionally-supplied `results` array and return.
-function computeSlotSegCollisions(seg, otherSegs, results=[]) {
+function computeSlotSegCollisions(seg, otherSegs, results= []) {
 
-  for (var i=0; i<otherSegs.length; i++) {
+  for (let i = 0; i < otherSegs.length; i++) {
     if (isSlotSegCollision(seg, otherSegs[i])) {
-      results.push(otherSegs[i]);
+      results.push(otherSegs[i])
     }
   }
 
-  return results;
+  return results
 }
 
 
 // Do these segments occupy the same vertical space?
 function isSlotSegCollision(seg1, seg2) {
-  return seg1.bottom > seg2.top && seg1.top < seg2.bottom;
+  return seg1.bottom > seg2.top && seg1.top < seg2.bottom
 }

+ 11 - 13
src/agenda/TimeGridFillRenderer.ts

@@ -4,26 +4,24 @@ import FillRenderer from '../component/renderers/FillRenderer'
 export default class TimeGridFillRenderer extends FillRenderer {
 
   attachSegEls(type, segs) {
-    var timeGrid = this.component;
-    var containerEls;
+    let timeGrid = this.component
+    let containerEls
 
     // TODO: more efficient lookup
     if (type === 'bgEvent') {
-      containerEls = timeGrid.bgContainerEls;
-    }
-    else if (type === 'businessHours') {
-      containerEls = timeGrid.businessContainerEls;
-    }
-    else if (type === 'highlight') {
-      containerEls = timeGrid.highlightContainerEls;
+      containerEls = timeGrid.bgContainerEls
+    } else if (type === 'businessHours') {
+      containerEls = timeGrid.businessContainerEls
+    } else if (type === 'highlight') {
+      containerEls = timeGrid.highlightContainerEls
     }
 
-    timeGrid.updateSegVerticals(segs);
-    timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls);
+    timeGrid.updateSegVerticals(segs)
+    timeGrid.attachSegsByCol(timeGrid.groupSegsByCol(segs), containerEls)
 
     return segs.map(function(seg) {
-      return seg.el[0];
-    });
+      return seg.el[0]
+    })
   }
 
 }

+ 9 - 9
src/agenda/TimeGridHelperRenderer.ts

@@ -5,34 +5,34 @@ import HelperRenderer from '../component/renderers/HelperRenderer'
 export default class TimeGridHelperRenderer extends HelperRenderer {
 
   renderSegs(segs, sourceSeg) {
-    var helperNodes = [];
-    var i, seg;
-    var sourceEl;
+    let helperNodes = []
+    let i, seg
+    let sourceEl
 
     // TODO: not good to call eventRenderer this way
     this.eventRenderer.renderFgSegsIntoContainers(
       segs,
       this.component.helperContainerEls
-    );
+    )
 
     // Try to make the segment that is in the same row as sourceSeg look the same
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
+      seg = segs[i]
 
       if (sourceSeg && sourceSeg.col === seg.col) {
-        sourceEl = sourceSeg.el;
+        sourceEl = sourceSeg.el
         seg.el.css({
           left: sourceEl.css('left'),
           right: sourceEl.css('right'),
           'margin-left': sourceEl.css('margin-left'),
           'margin-right': sourceEl.css('margin-right')
-        });
+        })
       }
 
-      helperNodes.push(seg.el[0]);
+      helperNodes.push(seg.el[0])
     }
 
-    return $(helperNodes); // must return the elements rendered
+    return $(helperNodes) // must return the elements rendered
   }
 
 }

+ 3 - 3
src/agenda/config.ts

@@ -8,14 +8,14 @@ defineView('agenda', {
     slotDuration: '00:30:00',
     slotEventOverlap: true // a bad name. confused with overlap/constraint system
   }
-});
+})
 
 defineView('agendaDay', {
   type: 'agenda',
   duration: { days: 1 }
-});
+})
 
 defineView('agendaWeek', {
   type: 'agenda',
   duration: { weeks: 1 }
-});
+})

+ 74 - 76
src/basic/BasicView.ts

@@ -32,28 +32,27 @@ export default class BasicView extends View {
 
 
   constructor(calendar, viewSpec) {
-    super(calendar, viewSpec);
+    super(calendar, viewSpec)
 
-    this.dayGrid = this.instantiateDayGrid();
-    this.dayGrid.isRigid = this.hasRigidRows();
+    this.dayGrid = this.instantiateDayGrid()
+    this.dayGrid.isRigid = this.hasRigidRows()
 
     if (this.opt('weekNumbers')) {
       if (this.opt('weekNumbersWithinDays')) {
-        this.dayGrid.cellWeekNumbersVisible = true;
-        this.dayGrid.colWeekNumbersVisible = false;
+        this.dayGrid.cellWeekNumbersVisible = true
+        this.dayGrid.colWeekNumbersVisible = false
+      } else {
+        this.dayGrid.cellWeekNumbersVisible = false
+        this.dayGrid.colWeekNumbersVisible = true
       }
-      else {
-        this.dayGrid.cellWeekNumbersVisible = false;
-        this.dayGrid.colWeekNumbersVisible = true;
-      };
     }
 
-    this.addChild(this.dayGrid);
+    this.addChild(this.dayGrid)
 
     this.scroller = new Scroller({
       overflowX: 'hidden',
       overflowY: 'auto'
-    });
+    })
   }
 
 
@@ -61,47 +60,47 @@ export default class BasicView extends View {
   instantiateDayGrid() {
     // generate a subclass on the fly with BasicView-specific behavior
     // TODO: cache this subclass
-    var subclass: any = makeDayGridSubclass(this.dayGridClass)
+    let subclass: any = makeDayGridSubclass(this.dayGridClass)
 
-    return new subclass(this);
+    return new subclass(this)
   }
 
 
   executeDateRender(dateProfile) {
-    this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit);
+    this.dayGrid.breakOnWeeks = /year|month|week/.test(dateProfile.currentRangeUnit)
 
-    super.executeDateRender(dateProfile);
+    super.executeDateRender(dateProfile)
   }
 
 
   renderSkeleton() {
-    var dayGridContainerEl;
-    var dayGridEl;
+    let dayGridContainerEl
+    let dayGridEl
 
-    this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml());
+    this.el.addClass('fc-basic-view').html(this.renderSkeletonHtml())
 
-    this.scroller.render();
+    this.scroller.render()
 
-    dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container');
-    dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl);
+    dayGridContainerEl = this.scroller.el.addClass('fc-day-grid-container')
+    dayGridEl = $('<div class="fc-day-grid" />').appendTo(dayGridContainerEl)
 
-    this.el.find('.fc-body > tr > td').append(dayGridContainerEl);
+    this.el.find('.fc-body > tr > td').append(dayGridContainerEl)
 
-    this.dayGrid.headContainerEl = this.el.find('.fc-head-container');
-    this.dayGrid.setElement(dayGridEl);
+    this.dayGrid.headContainerEl = this.el.find('.fc-head-container')
+    this.dayGrid.setElement(dayGridEl)
   }
 
 
   unrenderSkeleton() {
-    this.dayGrid.removeElement();
-    this.scroller.destroy();
+    this.dayGrid.removeElement()
+    this.scroller.destroy()
   }
 
 
   // Builds the HTML skeleton for the view.
   // The day-grid component will render inside of a container defined by this HTML.
   renderSkeletonHtml() {
-    var theme = this.calendar.theme;
+    let theme = this.calendar.theme
 
     return '' +
       '<table class="' + theme.getClass('tableGrid') + '">' +
@@ -118,24 +117,24 @@ export default class BasicView extends View {
             '<td class="' + theme.getClass('widgetContent') + '"></td>' +
           '</tr>' +
         '</tbody>' +
-      '</table>';
+      '</table>'
   }
 
 
   // Generates an HTML attribute string for setting the width of the week number column, if it is known
   weekNumberStyleAttr() {
     if (this.weekNumberWidth != null) {
-      return 'style="width:' + this.weekNumberWidth + 'px"';
+      return 'style="width:' + this.weekNumberWidth + 'px"'
     }
-    return '';
+    return ''
   }
 
 
   // Determines whether each row should have a constant height
   hasRigidRows() {
-    var eventLimit = this.opt('eventLimit');
+    let eventLimit = this.opt('eventLimit')
 
-    return eventLimit && typeof eventLimit !== 'number';
+    return eventLimit && typeof eventLimit !== 'number'
   }
 
 
@@ -145,68 +144,68 @@ export default class BasicView extends View {
 
   // Refreshes the horizontal dimensions of the view
   updateSize(totalHeight, isAuto, isResize) {
-    var eventLimit = this.opt('eventLimit');
-    var headRowEl = this.dayGrid.headContainerEl.find('.fc-row');
-    var scrollerHeight;
-    var scrollbarWidths;
+    let eventLimit = this.opt('eventLimit')
+    let headRowEl = this.dayGrid.headContainerEl.find('.fc-row')
+    let scrollerHeight
+    let scrollbarWidths
 
     // hack to give the view some height prior to dayGrid's columns being rendered
     // TODO: separate setting height from scroller VS dayGrid.
     if (!this.dayGrid.rowEls) {
       if (!isAuto) {
-        scrollerHeight = this.computeScrollerHeight(totalHeight);
-        this.scroller.setHeight(scrollerHeight);
+        scrollerHeight = this.computeScrollerHeight(totalHeight)
+        this.scroller.setHeight(scrollerHeight)
       }
-      return;
+      return
     }
 
-    super.updateSize(totalHeight, isAuto, isResize);
+    super.updateSize(totalHeight, isAuto, isResize)
 
     if (this.dayGrid.colWeekNumbersVisible) {
       // Make sure all week number cells running down the side have the same width.
       // Record the width for cells created later.
       this.weekNumberWidth = matchCellWidths(
         this.el.find('.fc-week-number')
-      );
+      )
     }
 
     // reset all heights to be natural
-    this.scroller.clear();
-    uncompensateScroll(headRowEl);
+    this.scroller.clear()
+    uncompensateScroll(headRowEl)
 
-    this.dayGrid.removeSegPopover(); // kill the "more" popover if displayed
+    this.dayGrid.removeSegPopover() // kill the "more" popover if displayed
 
     // is the event limit a constant level number?
     if (eventLimit && typeof eventLimit === 'number') {
-      this.dayGrid.limitRows(eventLimit); // limit the levels first so the height can redistribute after
+      this.dayGrid.limitRows(eventLimit) // limit the levels first so the height can redistribute after
     }
 
     // distribute the height to the rows
     // (totalHeight is a "recommended" value if isAuto)
-    scrollerHeight = this.computeScrollerHeight(totalHeight);
-    this.setGridHeight(scrollerHeight, isAuto);
+    scrollerHeight = this.computeScrollerHeight(totalHeight)
+    this.setGridHeight(scrollerHeight, isAuto)
 
     // is the event limit dynamically calculated?
     if (eventLimit && typeof eventLimit !== 'number') {
-      this.dayGrid.limitRows(eventLimit); // limit the levels after the grid's row heights have been set
+      this.dayGrid.limitRows(eventLimit) // limit the levels after the grid's row heights have been set
     }
 
     if (!isAuto) { // should we force dimensions of the scroll container?
 
-      this.scroller.setHeight(scrollerHeight);
-      scrollbarWidths = this.scroller.getScrollbarWidths();
+      this.scroller.setHeight(scrollerHeight)
+      scrollbarWidths = this.scroller.getScrollbarWidths()
 
       if (scrollbarWidths.left || scrollbarWidths.right) { // using scrollbars?
 
-        compensateScroll(headRowEl, scrollbarWidths);
+        compensateScroll(headRowEl, scrollbarWidths)
 
         // doing the scrollbar compensation might have created text overflow which created more height. redo
-        scrollerHeight = this.computeScrollerHeight(totalHeight);
-        this.scroller.setHeight(scrollerHeight);
+        scrollerHeight = this.computeScrollerHeight(totalHeight)
+        this.scroller.setHeight(scrollerHeight)
       }
 
       // guarantees the same scrollbar widths
-      this.scroller.lockOverflow(scrollbarWidths);
+      this.scroller.lockOverflow(scrollbarWidths)
     }
   }
 
@@ -214,17 +213,16 @@ export default class BasicView extends View {
   // given a desired total height of the view, returns what the height of the scroller should be
   computeScrollerHeight(totalHeight) {
     return totalHeight -
-      subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+      subtractInnerElHeight(this.el, this.scroller.el) // everything that's NOT the scroller
   }
 
 
   // Sets the height of just the DayGrid component in this view
   setGridHeight(height, isAuto) {
     if (isAuto) {
-      undistributeHeight(this.dayGrid.rowEls); // let the rows be their natural height with no expanding
-    }
-    else {
-      distributeHeight(this.dayGrid.rowEls, height, true); // true = compensate for height-hogging rows
+      undistributeHeight(this.dayGrid.rowEls) // let the rows be their natural height with no expanding
+    } else {
+      distributeHeight(this.dayGrid.rowEls, height, true) // true = compensate for height-hogging rows
     }
   }
 
@@ -234,18 +232,18 @@ export default class BasicView extends View {
 
 
   computeInitialDateScroll() {
-    return { top: 0 };
+    return { top: 0 }
   }
 
 
   queryDateScroll() {
-    return { top: this.scroller.getScrollTop() };
+    return { top: this.scroller.getScrollTop() }
   }
 
 
   applyDateScroll(scroll) {
     if (scroll.top !== undefined) {
-      this.scroller.setScrollTop(scroll.top);
+      this.scroller.setScrollTop(scroll.top)
     }
   }
 
@@ -266,7 +264,7 @@ function makeDayGridSubclass(SuperClass) {
 
     // Generates the HTML that will go before the day-of week header cells
     renderHeadIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
       if (this.colWeekNumbersVisible) {
         return '' +
@@ -274,17 +272,17 @@ function makeDayGridSubclass(SuperClass) {
             '<span>' + // needed for matchCellWidths
               htmlEscape(this.opt('weekNumberTitle')) +
             '</span>' +
-          '</th>';
+          '</th>'
       }
 
-      return '';
+      return ''
     }
 
 
     // Generates the HTML that will go before content-skeleton cells that display the day/week numbers
     renderNumberIntroHtml(row) {
-      var view = this.view;
-      var weekStart = this.getCellDate(row, 0);
+      let view = this.view
+      let weekStart = this.getCellDate(row, 0)
 
       if (this.colWeekNumbersVisible) {
         return '' +
@@ -293,41 +291,41 @@ function makeDayGridSubclass(SuperClass) {
               { date: weekStart, type: 'week', forceOff: this.colCnt === 1 },
               weekStart.format('w') // inner HTML
             ) +
-          '</td>';
+          '</td>'
       }
 
-      return '';
+      return ''
     }
 
 
     // Generates the HTML that goes before the day bg cells for each day-row
     renderBgIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
       if (this.colWeekNumbersVisible) {
         return '<td class="fc-week-number ' + view.calendar.theme.getClass('widgetContent') + '" ' +
-          view.weekNumberStyleAttr() + '></td>';
+          view.weekNumberStyleAttr() + '></td>'
       }
 
-      return '';
+      return ''
     }
 
 
     // Generates the HTML that goes before every other type of row generated by DayGrid.
     // Affects helper-skeleton and highlight-skeleton rows.
     renderIntroHtml() {
-      var view = this.view;
+      let view = this.view
 
       if (this.colWeekNumbersVisible) {
-        return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>';
+        return '<td class="fc-week-number" ' + view.weekNumberStyleAttr() + '></td>'
       }
 
-      return '';
+      return ''
     }
 
 
     getIsNumbersVisible() {
-      return DayGrid.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible;
+      return DayGrid.prototype.getIsNumbersVisible.apply(this, arguments) || this.colWeekNumbersVisible
     }
 
   }

+ 6 - 6
src/basic/BasicViewDateProfileGenerator.ts

@@ -6,21 +6,21 @@ export default class BasicViewDateProfileGenerator extends DateProfileGenerator
 
   // Computes the date range that will be rendered.
   buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
-    var renderUnzonedRange = super.buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay); // an UnzonedRange
-    var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
-    var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
+    let renderUnzonedRange = super.buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay) // an UnzonedRange
+    let start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay)
+    let end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay)
 
     // year and month views should be aligned with weeks. this is already done for week
     if (/^(year|month)$/.test(currentRangeUnit)) {
-      start.startOf('week');
+      start.startOf('week')
 
       // make end-of-week if not already
       if (end.weekday()) {
-        end.add(1, 'week').startOf('week'); // exclusively move backwards
+        end.add(1, 'week').startOf('week') // exclusively move backwards
       }
     }
 
-    return new UnzonedRange(start, end);
+    return new UnzonedRange(start, end)
   }
 
 }

+ 232 - 240
src/basic/DayGrid.ts

@@ -62,23 +62,22 @@ export default class DayGrid extends InteractiveDateComponent {
 
   // Slices up the given span (unzoned start/end with other misc data) into an array of segments
   componentFootprintToSegs(componentFootprint) {
-    var segs = this.sliceRangeByRow(componentFootprint.unzonedRange);
-    var i, seg;
+    let segs = this.sliceRangeByRow(componentFootprint.unzonedRange)
+    let i, seg
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
+      seg = segs[i]
 
       if (this.isRTL) {
-        seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex;
-        seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex;
-      }
-      else {
-        seg.leftCol = seg.firstRowDayIndex;
-        seg.rightCol = seg.lastRowDayIndex;
+        seg.leftCol = this.daysPerRow - 1 - seg.lastRowDayIndex
+        seg.rightCol = this.daysPerRow - 1 - seg.firstRowDayIndex
+      } else {
+        seg.leftCol = seg.firstRowDayIndex
+        seg.rightCol = seg.lastRowDayIndex
       }
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -87,46 +86,46 @@ export default class DayGrid extends InteractiveDateComponent {
 
 
   renderDates(dateProfile) {
-    this.dateProfile = dateProfile;
-    this.updateDayTable();
-    this.renderGrid();
+    this.dateProfile = dateProfile
+    this.updateDayTable()
+    this.renderGrid()
   }
 
 
   unrenderDates() {
-    this.removeSegPopover();
+    this.removeSegPopover()
   }
 
 
   // Renders the rows and columns into the component's `this.el`, which should already be assigned.
   renderGrid() {
-    var view = this.view;
-    var rowCnt = this.rowCnt;
-    var colCnt = this.colCnt;
-    var html = '';
-    var row;
-    var col;
+    let view = this.view
+    let rowCnt = this.rowCnt
+    let colCnt = this.colCnt
+    let html = ''
+    let row
+    let col
 
     if (this.headContainerEl) {
-      this.headContainerEl.html(this.renderHeadHtml());
+      this.headContainerEl.html(this.renderHeadHtml())
     }
 
     for (row = 0; row < rowCnt; row++) {
-      html += this.renderDayRowHtml(row, this.isRigid);
+      html += this.renderDayRowHtml(row, this.isRigid)
     }
-    this.el.html(html);
+    this.el.html(html)
 
-    this.rowEls = this.el.find('.fc-row');
-    this.cellEls = this.el.find('.fc-day, .fc-disabled-day');
+    this.rowEls = this.el.find('.fc-row')
+    this.cellEls = this.el.find('.fc-day, .fc-disabled-day')
 
     this.rowCoordCache = new CoordCache({
       els: this.rowEls,
       isVertical: true
-    });
+    })
     this.colCoordCache = new CoordCache({
       els: this.cellEls.slice(0, this.colCnt), // only the first row
       isHorizontal: true
-    });
+    })
 
     // trigger dayRender with each cell's element
     for (row = 0; row < rowCnt; row++) {
@@ -138,7 +137,7 @@ export default class DayGrid extends InteractiveDateComponent {
             this.getCellEl(row, col),
             view
           ]
-        });
+        })
       }
     }
   }
@@ -147,11 +146,11 @@ export default class DayGrid extends InteractiveDateComponent {
   // Generates the HTML for a single row, which is a div that wraps a table.
   // `row` is the row number.
   renderDayRowHtml(row, isRigid) {
-    var theme = this.view.calendar.theme;
-    var classes = [ 'fc-row', 'fc-week', theme.getClass('dayRow') ];
+    let theme = this.view.calendar.theme
+    let classes = [ 'fc-row', 'fc-week', theme.getClass('dayRow') ]
 
     if (isRigid) {
-      classes.push('fc-rigid');
+      classes.push('fc-rigid')
     }
 
     return '' +
@@ -171,17 +170,17 @@ export default class DayGrid extends InteractiveDateComponent {
               ) +
           '</table>' +
         '</div>' +
-      '</div>';
+      '</div>'
   }
 
 
   getIsNumbersVisible() {
-    return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible;
+    return this.getIsDayNumbersVisible() || this.cellWeekNumbersVisible
   }
 
 
   getIsDayNumbersVisible() {
-    return this.rowCnt > 1;
+    return this.rowCnt > 1
   }
 
 
@@ -195,45 +194,45 @@ export default class DayGrid extends InteractiveDateComponent {
         (this.isRTL ? '' : this.renderNumberIntroHtml(row)) +
         this.renderNumberCellsHtml(row) +
         (this.isRTL ? this.renderNumberIntroHtml(row) : '') +
-      '</tr>';
+      '</tr>'
   }
 
 
   renderNumberIntroHtml(row) {
-    return this.renderIntroHtml();
+    return this.renderIntroHtml()
   }
 
 
   renderNumberCellsHtml(row) {
-    var htmls = [];
-    var col, date;
+    let htmls = []
+    let col, date
 
     for (col = 0; col < this.colCnt; col++) {
-      date = this.getCellDate(row, col);
-      htmls.push(this.renderNumberCellHtml(date));
+      date = this.getCellDate(row, col)
+      htmls.push(this.renderNumberCellHtml(date))
     }
 
-    return htmls.join('');
+    return htmls.join('')
   }
 
 
   // Generates the HTML for the <td>s of the "number" row in the DayGrid's content skeleton.
   // The number row will only exist if either day numbers or week numbers are turned on.
   renderNumberCellHtml(date) {
-    var view = this.view;
-    var html = '';
-    var isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
-    var isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid;
-    var classes;
-    var weekCalcFirstDoW;
+    let view = this.view
+    let html = ''
+    let isDateValid = this.dateProfile.activeUnzonedRange.containsDate(date) // TODO: called too frequently. cache somehow.
+    let isDayNumberVisible = this.getIsDayNumbersVisible() && isDateValid
+    let classes
+    let weekCalcFirstDoW
 
     if (!isDayNumberVisible && !this.cellWeekNumbersVisible) {
       // no numbers in day cell (week number must be along the side)
-      return '<td/>'; //  will create an empty space above events :(
+      return '<td/>' //  will create an empty space above events :(
     }
 
-    classes = this.getDayClasses(date);
-    classes.unshift('fc-day-top');
+    classes = this.getDayClasses(date)
+    classes.unshift('fc-day-top')
 
     if (this.cellWeekNumbersVisible) {
       // To determine the day of week number change under ISO, we cannot
@@ -242,10 +241,9 @@ export default class DayGrid extends InteractiveDateComponent {
       // our firstDay option), which may not be Monday. We cannot change
       // dow, because that would affect the calendar start day as well.
       if (date._locale._fullCalendar_weekCalc === 'ISO') {
-        weekCalcFirstDoW = 1;  // Monday by ISO 8601 definition
-      }
-      else {
-        weekCalcFirstDoW = date._locale.firstDayOfWeek();
+        weekCalcFirstDoW = 1  // Monday by ISO 8601 definition
+      } else {
+        weekCalcFirstDoW = date._locale.firstDayOfWeek()
       }
     }
 
@@ -254,14 +252,14 @@ export default class DayGrid extends InteractiveDateComponent {
         ' data-date="' + date.format() + '"' :
         ''
         ) +
-      '>';
+      '>'
 
     if (this.cellWeekNumbersVisible && (date.day() == weekCalcFirstDoW)) {
       html += view.buildGotoAnchorHtml(
         { date: date, type: 'week' },
         { 'class': 'fc-week-number' },
         date.format('w') // inner HTML
-      );
+      )
     }
 
     if (isDayNumberVisible) {
@@ -269,12 +267,12 @@ export default class DayGrid extends InteractiveDateComponent {
         date,
         { 'class': 'fc-day-number' },
         date.date() // inner HTML
-      );
+      )
     }
 
-    html += '</td>';
+    html += '</td>'
 
-    return html;
+    return html
   }
 
 
@@ -283,42 +281,42 @@ export default class DayGrid extends InteractiveDateComponent {
 
 
   prepareHits() {
-    this.colCoordCache.build();
-    this.rowCoordCache.build();
-    this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding; // hack
+    this.colCoordCache.build()
+    this.rowCoordCache.build()
+    this.rowCoordCache.bottoms[this.rowCnt - 1] += this.bottomCoordPadding // hack
   }
 
 
   releaseHits() {
-    this.colCoordCache.clear();
-    this.rowCoordCache.clear();
+    this.colCoordCache.clear()
+    this.rowCoordCache.clear()
   }
 
 
   queryHit(leftOffset, topOffset) {
     if (this.colCoordCache.isLeftInBounds(leftOffset) && this.rowCoordCache.isTopInBounds(topOffset)) {
-      var col = this.colCoordCache.getHorizontalIndex(leftOffset);
-      var row = this.rowCoordCache.getVerticalIndex(topOffset);
+      let col = this.colCoordCache.getHorizontalIndex(leftOffset)
+      let row = this.rowCoordCache.getVerticalIndex(topOffset)
 
       if (row != null && col != null) {
-        return this.getCellHit(row, col);
+        return this.getCellHit(row, col)
       }
     }
   }
 
 
   getHitFootprint(hit) {
-    var range = this.getCellRange(hit.row, hit.col);
+    let range = this.getCellRange(hit.row, hit.col)
 
     return new ComponentFootprint(
       new UnzonedRange(range.start, range.end),
       true // all-day?
-    );
+    )
   }
 
 
   getHitEl(hit) {
-    return this.getCellEl(hit.row, hit.col);
+    return this.getCellEl(hit.row, hit.col)
   }
 
 
@@ -336,12 +334,12 @@ export default class DayGrid extends InteractiveDateComponent {
       right: this.colCoordCache.getRightOffset(col),
       top: this.rowCoordCache.getTopOffset(row),
       bottom: this.rowCoordCache.getBottomOffset(row)
-    };
+    }
   }
 
 
   getCellEl(row, col) {
-    return this.cellEls.eq(row * this.colCnt + col);
+    return this.cellEls.eq(row * this.colCnt + col)
   }
 
 
@@ -351,15 +349,15 @@ export default class DayGrid extends InteractiveDateComponent {
 
   // Unrenders all events currently rendered on the grid
   executeEventUnrender() {
-    this.removeSegPopover(); // removes the "more.." events popover
-    super.executeEventUnrender();
+    this.removeSegPopover() // removes the "more.." events popover
+    super.executeEventUnrender()
   }
 
 
   // Retrieves all rendered segment objects currently rendered on the grid
   getOwnEventSegs() {
     // append the segments from the "more..." popover
-    return super.getOwnEventSegs().concat(this.popoverSegs || []);
+    return super.getOwnEventSegs().concat(this.popoverSegs || [])
   }
 
 
@@ -370,25 +368,25 @@ export default class DayGrid extends InteractiveDateComponent {
   // Renders a visual indication of an event or external element being dragged.
   // `eventLocation` has zoned start and end (optional)
   renderDrag(eventFootprints, seg, isTouch) {
-    var i;
+    let i
 
     for (i = 0; i < eventFootprints.length; i++) {
-      this.renderHighlight(eventFootprints[i].componentFootprint);
+      this.renderHighlight(eventFootprints[i].componentFootprint)
     }
 
     // render drags from OTHER components as helpers
     if (eventFootprints.length && seg && seg.component !== this) {
-      this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch);
+      this.helperRenderer.renderEventDraggingFootprints(eventFootprints, seg, isTouch)
 
-      return true; // signal helpers rendered
+      return true // signal helpers rendered
     }
   }
 
 
   // Unrenders any visual indication of a hovering event
   unrenderDrag() {
-    this.unrenderHighlight();
-    this.helperRenderer.unrender();
+    this.unrenderHighlight()
+    this.helperRenderer.unrender()
   }
 
 
@@ -398,20 +396,20 @@ export default class DayGrid extends InteractiveDateComponent {
 
   // Renders a visual indication of an event being resized
   renderEventResize(eventFootprints, seg, isTouch) {
-    var i;
+    let i
 
     for (i = 0; i < eventFootprints.length; i++) {
-      this.renderHighlight(eventFootprints[i].componentFootprint);
+      this.renderHighlight(eventFootprints[i].componentFootprint)
     }
 
-    this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch);
+    this.helperRenderer.renderEventResizingFootprints(eventFootprints, seg, isTouch)
   }
 
 
   // Unrenders a visual indication of an event being resized
   unrenderEventResize() {
-    this.unrenderHighlight();
-    this.helperRenderer.unrender();
+    this.unrenderHighlight()
+    this.helperRenderer.unrender()
   }
 
 
@@ -421,7 +419,7 @@ export default class DayGrid extends InteractiveDateComponent {
 
   removeSegPopover() {
     if (this.segPopover) {
-      this.segPopover.hide(); // in handler, will call segPopover's removeElement
+      this.segPopover.hide() // in handler, will call segPopover's removeElement
     }
   }
 
@@ -429,25 +427,23 @@ export default class DayGrid extends InteractiveDateComponent {
   // Limits the number of "levels" (vertically stacking layers of events) for each row of the grid.
   // `levelLimit` can be false (don't limit), a number, or true (should be computed).
   limitRows(levelLimit) {
-    var rowStructs = this.eventRenderer.rowStructs || [];
-    var row; // row #
-    var rowLevelLimit;
+    let rowStructs = this.eventRenderer.rowStructs || []
+    let row // row #
+    let rowLevelLimit
 
     for (row = 0; row < rowStructs.length; row++) {
-      this.unlimitRow(row);
+      this.unlimitRow(row)
 
       if (!levelLimit) {
-        rowLevelLimit = false;
-      }
-      else if (typeof levelLimit === 'number') {
-        rowLevelLimit = levelLimit;
-      }
-      else {
-        rowLevelLimit = this.computeRowLevelLimit(row);
+        rowLevelLimit = false
+      } else if (typeof levelLimit === 'number') {
+        rowLevelLimit = levelLimit
+      } else {
+        rowLevelLimit = this.computeRowLevelLimit(row)
       }
 
       if (rowLevelLimit !== false) {
-        this.limitRow(row, rowLevelLimit);
+        this.limitRow(row, rowLevelLimit)
       }
     }
   }
@@ -457,31 +453,31 @@ export default class DayGrid extends InteractiveDateComponent {
   // Assumes the row is "rigid" (maintains a constant height regardless of what is inside).
   // `row` is the row number.
   computeRowLevelLimit(row): (number | false) {
-    var rowEl = this.rowEls.eq(row); // the containing "fake" row div
-    var rowHeight = rowEl.height(); // TODO: cache somehow?
-    var trEls = this.eventRenderer.rowStructs[row].tbodyEl.children();
-    var i, trEl;
-    var trHeight;
+    let rowEl = this.rowEls.eq(row) // the containing "fake" row div
+    let rowHeight = rowEl.height() // TODO: cache somehow?
+    let trEls = this.eventRenderer.rowStructs[row].tbodyEl.children()
+    let i, trEl
+    let trHeight
 
     function iterInnerHeights(i, childNode) {
-      trHeight = Math.max(trHeight, $(childNode).outerHeight());
+      trHeight = Math.max(trHeight, $(childNode).outerHeight())
     }
 
     // Reveal one level <tr> at a time and stop when we find one out of bounds
     for (i = 0; i < trEls.length; i++) {
-      trEl = trEls.eq(i).removeClass('fc-limited'); // reset to original state (reveal)
+      trEl = trEls.eq(i).removeClass('fc-limited') // reset to original state (reveal)
 
       // with rowspans>1 and IE8, trEl.outerHeight() would return the height of the largest cell,
       // so instead, find the tallest inner content element.
-      trHeight = 0;
-      trEl.find('> td > :first-child').each(iterInnerHeights);
+      trHeight = 0
+      trEl.find('> td > :first-child').each(iterInnerHeights)
 
       if (trEl.position().top + trHeight > rowHeight) {
-        return i;
+        return i
       }
     }
 
-    return false; // should not limit at all
+    return false // should not limit at all
   }
 
 
@@ -489,86 +485,86 @@ export default class DayGrid extends InteractiveDateComponent {
   // `row` is the row number.
   // `levelLimit` is a number for the maximum (inclusive) number of levels allowed.
   limitRow(row, levelLimit) {
-    var rowStruct = this.eventRenderer.rowStructs[row];
-    var moreNodes = []; // array of "more" <a> links and <td> DOM nodes
-    var col = 0; // col #, left-to-right (not chronologically)
-    var levelSegs; // array of segment objects in the last allowable level, ordered left-to-right
-    var cellMatrix; // a matrix (by level, then column) of all <td> jQuery elements in the row
-    var limitedNodes; // array of temporarily hidden level <tr> and segment <td> DOM nodes
-    var i, seg;
-    var segsBelow; // array of segment objects below `seg` in the current `col`
-    var totalSegsBelow; // total number of segments below `seg` in any of the columns `seg` occupies
-    var colSegsBelow; // array of segment arrays, below seg, one for each column (offset from segs's first column)
-    var td, rowspan;
-    var segMoreNodes; // array of "more" <td> cells that will stand-in for the current seg's cell
-    var j;
-    var moreTd, moreWrap, moreLink;
+    let rowStruct = this.eventRenderer.rowStructs[row]
+    let moreNodes = [] // array of "more" <a> links and <td> DOM nodes
+    let col = 0 // col #, left-to-right (not chronologically)
+    let levelSegs // array of segment objects in the last allowable level, ordered left-to-right
+    let cellMatrix // a matrix (by level, then column) of all <td> jQuery elements in the row
+    let limitedNodes // array of temporarily hidden level <tr> and segment <td> DOM nodes
+    let i, seg
+    let segsBelow // array of segment objects below `seg` in the current `col`
+    let totalSegsBelow // total number of segments below `seg` in any of the columns `seg` occupies
+    let colSegsBelow // array of segment arrays, below seg, one for each column (offset from segs's first column)
+    let td, rowspan
+    let segMoreNodes // array of "more" <td> cells that will stand-in for the current seg's cell
+    let j
+    let moreTd, moreWrap, moreLink
 
     // Iterates through empty level cells and places "more" links inside if need be
-    var emptyCellsUntil = (endCol) => { // goes from current `col` to `endCol`
+    let emptyCellsUntil = (endCol) => { // goes from current `col` to `endCol`
       while (col < endCol) {
-        segsBelow = this.getCellSegs(row, col, levelLimit);
+        segsBelow = this.getCellSegs(row, col, levelLimit)
         if (segsBelow.length) {
-          td = cellMatrix[levelLimit - 1][col];
-          moreLink = this.renderMoreLink(row, col, segsBelow);
-          moreWrap = $('<div/>').append(moreLink);
-          td.append(moreWrap);
-          moreNodes.push(moreWrap[0]);
+          td = cellMatrix[levelLimit - 1][col]
+          moreLink = this.renderMoreLink(row, col, segsBelow)
+          moreWrap = $('<div/>').append(moreLink)
+          td.append(moreWrap)
+          moreNodes.push(moreWrap[0])
         }
-        col++;
+        col++
       }
     }
 
     if (levelLimit && levelLimit < rowStruct.segLevels.length) { // is it actually over the limit?
-      levelSegs = rowStruct.segLevels[levelLimit - 1];
-      cellMatrix = rowStruct.cellMatrix;
+      levelSegs = rowStruct.segLevels[levelLimit - 1]
+      cellMatrix = rowStruct.cellMatrix
 
       limitedNodes = rowStruct.tbodyEl.children().slice(levelLimit) // get level <tr> elements past the limit
-        .addClass('fc-limited').get(); // hide elements and get a simple DOM-nodes array
+        .addClass('fc-limited').get() // hide elements and get a simple DOM-nodes array
 
       // iterate though segments in the last allowable level
       for (i = 0; i < levelSegs.length; i++) {
-        seg = levelSegs[i];
-        emptyCellsUntil(seg.leftCol); // process empty cells before the segment
+        seg = levelSegs[i]
+        emptyCellsUntil(seg.leftCol) // process empty cells before the segment
 
         // determine *all* segments below `seg` that occupy the same columns
-        colSegsBelow = [];
-        totalSegsBelow = 0;
+        colSegsBelow = []
+        totalSegsBelow = 0
         while (col <= seg.rightCol) {
-          segsBelow = this.getCellSegs(row, col, levelLimit);
-          colSegsBelow.push(segsBelow);
-          totalSegsBelow += segsBelow.length;
-          col++;
+          segsBelow = this.getCellSegs(row, col, levelLimit)
+          colSegsBelow.push(segsBelow)
+          totalSegsBelow += segsBelow.length
+          col++
         }
 
         if (totalSegsBelow) { // do we need to replace this segment with one or many "more" links?
-          td = cellMatrix[levelLimit - 1][seg.leftCol]; // the segment's parent cell
-          rowspan = td.attr('rowspan') || 1;
-          segMoreNodes = [];
+          td = cellMatrix[levelLimit - 1][seg.leftCol] // the segment's parent cell
+          rowspan = td.attr('rowspan') || 1
+          segMoreNodes = []
 
           // make a replacement <td> for each column the segment occupies. will be one for each colspan
           for (j = 0; j < colSegsBelow.length; j++) {
-            moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan);
-            segsBelow = colSegsBelow[j];
+            moreTd = $('<td class="fc-more-cell"/>').attr('rowspan', rowspan)
+            segsBelow = colSegsBelow[j]
             moreLink = this.renderMoreLink(
               row,
               seg.leftCol + j,
               [ seg ].concat(segsBelow) // count seg as hidden too
-            );
-            moreWrap = $('<div/>').append(moreLink);
-            moreTd.append(moreWrap);
-            segMoreNodes.push(moreTd[0]);
-            moreNodes.push(moreTd[0]);
+            )
+            moreWrap = $('<div/>').append(moreLink)
+            moreTd.append(moreWrap)
+            segMoreNodes.push(moreTd[0])
+            moreNodes.push(moreTd[0])
           }
 
-          td.addClass('fc-limited').after($(segMoreNodes)); // hide original <td> and inject replacements
-          limitedNodes.push(td[0]);
+          td.addClass('fc-limited').after($(segMoreNodes)) // hide original <td> and inject replacements
+          limitedNodes.push(td[0])
         }
       }
 
-      emptyCellsUntil(this.colCnt); // finish off the level
-      rowStruct.moreEls = $(moreNodes); // for easy undoing later
-      rowStruct.limitedEls = $(limitedNodes); // for easy undoing later
+      emptyCellsUntil(this.colCnt) // finish off the level
+      rowStruct.moreEls = $(moreNodes) // for easy undoing later
+      rowStruct.limitedEls = $(limitedNodes) // for easy undoing later
     }
   }
 
@@ -576,16 +572,16 @@ export default class DayGrid extends InteractiveDateComponent {
   // Reveals all levels and removes all "more"-related elements for a grid's row.
   // `row` is a row number.
   unlimitRow(row) {
-    var rowStruct = this.eventRenderer.rowStructs[row];
+    let rowStruct = this.eventRenderer.rowStructs[row]
 
     if (rowStruct.moreEls) {
-      rowStruct.moreEls.remove();
-      rowStruct.moreEls = null;
+      rowStruct.moreEls.remove()
+      rowStruct.moreEls = null
     }
 
     if (rowStruct.limitedEls) {
-      rowStruct.limitedEls.removeClass('fc-limited');
-      rowStruct.limitedEls = null;
+      rowStruct.limitedEls.removeClass('fc-limited')
+      rowStruct.limitedEls = null
     }
   }
 
@@ -593,22 +589,22 @@ export default class DayGrid extends InteractiveDateComponent {
   // Renders an <a> element that represents hidden event element for a cell.
   // Responsible for attaching click handler as well.
   renderMoreLink(row, col, hiddenSegs) {
-    var view = this.view;
+    let view = this.view
 
     return $('<a class="fc-more"/>')
       .text(
         this.getMoreLinkText(hiddenSegs.length)
       )
       .on('click', (ev) => {
-        var clickOption = this.opt('eventLimitClick');
-        var date = this.getCellDate(row, col);
-        var moreEl = $(ev.currentTarget);
-        var dayEl = this.getCellEl(row, col);
-        var allSegs = this.getCellSegs(row, col);
+        let clickOption = this.opt('eventLimitClick')
+        let date = this.getCellDate(row, col)
+        let moreEl = $(ev.currentTarget)
+        let dayEl = this.getCellEl(row, col)
+        let allSegs = this.getCellSegs(row, col)
 
         // rescope the segments to be within the cell's date
-        var reslicedAllSegs = this.resliceDaySegs(allSegs, date);
-        var reslicedHiddenSegs = this.resliceDaySegs(hiddenSegs, date);
+        let reslicedAllSegs = this.resliceDaySegs(allSegs, date)
+        let reslicedHiddenSegs = this.resliceDaySegs(hiddenSegs, date)
 
         if (typeof clickOption === 'function') {
           // the returned value can be an atomic option
@@ -625,31 +621,29 @@ export default class DayGrid extends InteractiveDateComponent {
               ev,
               view
             ]
-          });
+          })
         }
 
         if (clickOption === 'popover') {
-          this.showSegPopover(row, col, moreEl, reslicedAllSegs);
+          this.showSegPopover(row, col, moreEl, reslicedAllSegs)
+        } else if (typeof clickOption === 'string') { // a view name
+          view.calendar.zoomTo(date, clickOption)
         }
-        else if (typeof clickOption === 'string') { // a view name
-          view.calendar.zoomTo(date, clickOption);
-        }
-      });
+      })
   }
 
 
   // Reveals the popover that displays all events within a cell
   showSegPopover(row, col, moreLink, segs) {
-    var view = this.view;
-    var moreWrap = moreLink.parent(); // the <div> wrapper around the <a>
-    var topEl; // the element we want to match the top coordinate of
-    var options;
+    let view = this.view
+    let moreWrap = moreLink.parent() // the <div> wrapper around the <a>
+    let topEl // the element we want to match the top coordinate of
+    let options
 
     if (this.rowCnt == 1) {
-      topEl = view.el; // will cause the popover to cover any sort of header
-    }
-    else {
-      topEl = this.rowEls.eq(row); // will align with top of row
+      topEl = view.el // will cause the popover to cover any sort of header
+    } else {
+      topEl = this.rowEls.eq(row) // will align with top of row
     }
 
     options = {
@@ -663,40 +657,39 @@ export default class DayGrid extends InteractiveDateComponent {
         // kill everything when the popover is hidden
         // notify events to be removed
         if (this.popoverSegs) {
-          this.triggerBeforeEventSegsDestroyed(this.popoverSegs);
+          this.triggerBeforeEventSegsDestroyed(this.popoverSegs)
         }
-        this.segPopover.removeElement();
-        this.segPopover = null;
-        this.popoverSegs = null;
+        this.segPopover.removeElement()
+        this.segPopover = null
+        this.popoverSegs = null
       }
-    };
+    }
 
     // Determine horizontal coordinate.
     // We use the moreWrap instead of the <td> to avoid border confusion.
     if (this.isRTL) {
-      options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1; // +1 to be over cell border
-    }
-    else {
-      options.left = moreWrap.offset().left - 1; // -1 to be over cell border
+      options.right = moreWrap.offset().left + moreWrap.outerWidth() + 1 // +1 to be over cell border
+    } else {
+      options.left = moreWrap.offset().left - 1 // -1 to be over cell border
     }
 
-    this.segPopover = new Popover(options);
-    this.segPopover.show();
+    this.segPopover = new Popover(options)
+    this.segPopover.show()
 
     // the popover doesn't live within the grid's container element, and thus won't get the event
     // delegated-handlers for free. attach event-related handlers to the popover.
-    this.bindAllSegHandlersToEl(this.segPopover.el);
+    this.bindAllSegHandlersToEl(this.segPopover.el)
 
-    this.triggerAfterEventSegsRendered(segs);
+    this.triggerAfterEventSegsRendered(segs)
   }
 
 
   // Builds the inner DOM contents of the segment popover
   renderSegPopoverContent(row, col, segs) {
-    var view = this.view;
-    var theme = view.calendar.theme;
-    var title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat'));
-    var content = $(
+    let view = this.view
+    let theme = view.calendar.theme
+    let title = this.getCellDate(row, col).format(this.opt('dayPopoverFormat'))
+    let content = $(
       '<div class="fc-header ' + theme.getClass('popoverHeader') + '">' +
         '<span class="fc-close ' + theme.getIconClass('close') + '"></span>' +
         '<span class="fc-title">' +
@@ -707,41 +700,41 @@ export default class DayGrid extends InteractiveDateComponent {
       '<div class="fc-body ' + theme.getClass('popoverContent') + '">' +
         '<div class="fc-event-container"></div>' +
       '</div>'
-    );
-    var segContainer = content.find('.fc-event-container');
-    var i;
+    )
+    let segContainer = content.find('.fc-event-container')
+    let i
 
     // render each seg's `el` and only return the visible segs
-    segs = this.eventRenderer.renderFgSegEls(segs, true); // disableResizing=true
-    this.popoverSegs = segs;
+    segs = this.eventRenderer.renderFgSegEls(segs, true) // disableResizing=true
+    this.popoverSegs = segs
 
     for (i = 0; i < segs.length; i++) {
 
       // because segments in the popover are not part of a grid coordinate system, provide a hint to any
       // grids that want to do drag-n-drop about which cell it came from
-      this.hitsNeeded();
-      segs[i].hit = this.getCellHit(row, col);
-      this.hitsNotNeeded();
+      this.hitsNeeded()
+      segs[i].hit = this.getCellHit(row, col)
+      this.hitsNotNeeded()
 
-      segContainer.append(segs[i].el);
+      segContainer.append(segs[i].el)
     }
 
-    return content;
+    return content
   }
 
 
   // Given the events within an array of segment objects, reslice them to be in a single day
   resliceDaySegs(segs, dayDate) {
-    var dayStart = dayDate.clone();
-    var dayEnd = dayStart.clone().add(1, 'days');
-    var dayRange = new UnzonedRange(dayStart, dayEnd);
-    var newSegs = [];
-    var i, seg;
-    var slicedRange;
+    let dayStart = dayDate.clone()
+    let dayEnd = dayStart.clone().add(1, 'days')
+    let dayRange = new UnzonedRange(dayStart, dayEnd)
+    let newSegs = []
+    let i, seg
+    let slicedRange
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
-      slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange);
+      seg = segs[i]
+      slicedRange = seg.footprint.componentFootprint.unzonedRange.intersect(dayRange)
 
       if (slicedRange) {
         newSegs.push(
@@ -757,27 +750,26 @@ export default class DayGrid extends InteractiveDateComponent {
             isStart: seg.isStart && slicedRange.isStart,
             isEnd: seg.isEnd && slicedRange.isEnd
           })
-        );
+        )
       }
     }
 
     // force an order because eventsToSegs doesn't guarantee one
     // TODO: research if still needed
-    this.eventRenderer.sortEventSegs(newSegs);
+    this.eventRenderer.sortEventSegs(newSegs)
 
-    return newSegs;
+    return newSegs
   }
 
 
   // Generates the text that should be inside a "more" link, given the number of events it represents
   getMoreLinkText(num) {
-    var opt = this.opt('eventLimitText');
+    let opt = this.opt('eventLimitText')
 
     if (typeof opt === 'function') {
-      return opt(num);
-    }
-    else {
-      return '+' + num + ' ' + opt;
+      return opt(num)
+    } else {
+      return '+' + num + ' ' + opt
     }
   }
 
@@ -785,28 +777,28 @@ export default class DayGrid extends InteractiveDateComponent {
   // Returns segments within a given cell.
   // If `startLevel` is specified, returns only events including and below that level. Otherwise returns all segs.
   getCellSegs(row, col, startLevel?) {
-    var segMatrix = this.eventRenderer.rowStructs[row].segMatrix;
-    var level = startLevel || 0;
-    var segs = [];
-    var seg;
+    let segMatrix = this.eventRenderer.rowStructs[row].segMatrix
+    let level = startLevel || 0
+    let segs = []
+    let seg
 
     while (level < segMatrix.length) {
-      seg = segMatrix[level][col];
+      seg = segMatrix[level][col]
       if (seg) {
-        segs.push(seg);
+        segs.push(seg)
       }
-      level++;
+      level++
     }
 
-    return segs;
+    return segs
   }
 
 }
 
-DayGrid.prototype.eventRendererClass = DayGridEventRenderer;
-DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer;
-DayGrid.prototype.helperRendererClass = DayGridHelperRenderer;
-DayGrid.prototype.fillRendererClass = DayGridFillRenderer;
+DayGrid.prototype.eventRendererClass = DayGridEventRenderer
+DayGrid.prototype.businessHourRendererClass = BusinessHourRenderer
+DayGrid.prototype.helperRendererClass = DayGridHelperRenderer
+DayGrid.prototype.fillRendererClass = DayGridFillRenderer
 
 StandardInteractionsMixin.mixInto(DayGrid)
 DayTableMixin.mixInto(DayGrid)

+ 99 - 101
src/basic/DayGridEventRenderer.ts

@@ -13,44 +13,44 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 
   constructor(dayGrid, fillRenderer) {
-    super(dayGrid, fillRenderer);
-    this.dayGrid = dayGrid;
+    super(dayGrid, fillRenderer)
+    this.dayGrid = dayGrid
   }
 
 
   renderBgRanges(eventRanges) {
     // don't render timed background events
-    eventRanges = $.grep(eventRanges, function(eventRange:any) {
-      return eventRange.eventDef.isAllDay();
-    });
+    eventRanges = $.grep(eventRanges, function(eventRange: any) {
+      return eventRange.eventDef.isAllDay()
+    })
 
-    super.renderBgRanges(eventRanges);
+    super.renderBgRanges(eventRanges)
   }
 
 
   // Renders the given foreground event segments onto the grid
   renderFgSegs(segs) {
-    var rowStructs = this.rowStructs = this.renderSegRows(segs);
+    let rowStructs = this.rowStructs = this.renderSegRows(segs)
 
     // append to each row's content skeleton
     this.dayGrid.rowEls.each(function(i, rowNode) {
       $(rowNode).find('.fc-content-skeleton > table').append(
         rowStructs[i].tbodyEl
-      );
-    });
+      )
+    })
   }
 
 
   // Unrenders all currently rendered foreground event segments
   unrenderFgSegs() {
-    var rowStructs = this.rowStructs || [];
-    var rowStruct;
+    let rowStructs = this.rowStructs || []
+    let rowStruct
 
     while ((rowStruct = rowStructs.pop())) {
-      rowStruct.tbodyEl.remove();
+      rowStruct.tbodyEl.remove()
     }
 
-    this.rowStructs = null;
+    this.rowStructs = null
   }
 
 
@@ -58,20 +58,20 @@ export default class DayGridEventRenderer extends EventRenderer {
   // Returns an array of rowStruct objects (see the bottom of `renderSegRow`).
   // PRECONDITION: each segment shoud already have a rendered and assigned `.el`
   renderSegRows(segs) {
-    var rowStructs = [];
-    var segRows;
-    var row;
+    let rowStructs = []
+    let segRows
+    let row
 
-    segRows = this.groupSegRows(segs); // group into nested arrays
+    segRows = this.groupSegRows(segs) // group into nested arrays
 
     // iterate each row of segment groupings
     for (row = 0; row < segRows.length; row++) {
       rowStructs.push(
         this.renderSegRow(row, segRows[row])
-      );
+      )
     }
 
-    return rowStructs;
+    return rowStructs
   }
 
 
@@ -79,79 +79,77 @@ export default class DayGridEventRenderer extends EventRenderer {
   // the segments. Returns object with a bunch of internal data about how the render was calculated.
   // NOTE: modifies rowSegs
   renderSegRow(row, rowSegs) {
-    var colCnt = this.dayGrid.colCnt;
-    var segLevels = this.buildSegLevels(rowSegs); // group into sub-arrays of levels
-    var levelCnt = Math.max(1, segLevels.length); // ensure at least one level
-    var tbody = $('<tbody/>');
-    var segMatrix = []; // lookup for which segments are rendered into which level+col cells
-    var cellMatrix = []; // lookup for all <td> elements of the level+col matrix
-    var loneCellMatrix = []; // lookup for <td> elements that only take up a single column
-    var i, levelSegs;
-    var col;
-    var tr;
-    var j, seg;
-    var td;
+    let colCnt = this.dayGrid.colCnt
+    let segLevels = this.buildSegLevels(rowSegs) // group into sub-arrays of levels
+    let levelCnt = Math.max(1, segLevels.length) // ensure at least one level
+    let tbody = $('<tbody/>')
+    let segMatrix = [] // lookup for which segments are rendered into which level+col cells
+    let cellMatrix = [] // lookup for all <td> elements of the level+col matrix
+    let loneCellMatrix = [] // lookup for <td> elements that only take up a single column
+    let i, levelSegs
+    let col
+    let tr
+    let j, seg
+    let td
 
     // populates empty cells from the current column (`col`) to `endCol`
     function emptyCellsUntil(endCol) {
       while (col < endCol) {
         // try to grab a cell from the level above and extend its rowspan. otherwise, create a fresh cell
-        td = (loneCellMatrix[i - 1] || [])[col];
+        td = (loneCellMatrix[i - 1] || [])[col]
         if (td) {
           td.attr(
             'rowspan',
             parseInt(td.attr('rowspan') || 1, 10) + 1
-          );
+          )
+        } else {
+          td = $('<td/>')
+          tr.append(td)
         }
-        else {
-          td = $('<td/>');
-          tr.append(td);
-        }
-        cellMatrix[i][col] = td;
-        loneCellMatrix[i][col] = td;
-        col++;
+        cellMatrix[i][col] = td
+        loneCellMatrix[i][col] = td
+        col++
       }
     }
 
     for (i = 0; i < levelCnt; i++) { // iterate through all levels
-      levelSegs = segLevels[i];
-      col = 0;
-      tr = $('<tr/>');
+      levelSegs = segLevels[i]
+      col = 0
+      tr = $('<tr/>')
 
-      segMatrix.push([]);
-      cellMatrix.push([]);
-      loneCellMatrix.push([]);
+      segMatrix.push([])
+      cellMatrix.push([])
+      loneCellMatrix.push([])
 
       // levelCnt might be 1 even though there are no actual levels. protect against this.
       // this single empty row is useful for styling.
       if (levelSegs) {
         for (j = 0; j < levelSegs.length; j++) { // iterate through segments in level
-          seg = levelSegs[j];
+          seg = levelSegs[j]
 
-          emptyCellsUntil(seg.leftCol);
+          emptyCellsUntil(seg.leftCol)
 
           // create a container that occupies or more columns. append the event element.
-          td = $('<td class="fc-event-container"/>').append(seg.el);
+          td = $('<td class="fc-event-container"/>').append(seg.el)
           if (seg.leftCol != seg.rightCol) {
-            td.attr('colspan', seg.rightCol - seg.leftCol + 1);
-          }
-          else { // a single-column segment
-            loneCellMatrix[i][col] = td;
+            td.attr('colspan', seg.rightCol - seg.leftCol + 1)
+          } else { // a single-column segment
+            loneCellMatrix[i][col] = td
           }
 
           while (col <= seg.rightCol) {
-            cellMatrix[i][col] = td;
-            segMatrix[i][col] = seg;
-            col++;
+            cellMatrix[i][col] = td
+            segMatrix[i][col] = seg
+            col++
           }
 
-          tr.append(td);
+          tr.append(td)
         }
       }
 
-      emptyCellsUntil(colCnt); // finish off the row
-      this.dayGrid.bookendCells(tr);
-      tbody.append(tr);
+      emptyCellsUntil(colCnt) // finish off the row
+      this.dayGrid.bookendCells(tr)
+      tbody.append(tr)
     }
 
     return { // a "rowStruct"
@@ -161,105 +159,105 @@ export default class DayGridEventRenderer extends EventRenderer {
       segMatrix: segMatrix,
       segLevels: segLevels,
       segs: rowSegs
-    };
+    }
   }
 
 
   // Stacks a flat array of segments, which are all assumed to be in the same row, into subarrays of vertical levels.
   // NOTE: modifies segs
   buildSegLevels(segs) {
-    var levels = [];
-    var i, seg;
-    var j;
+    let levels = []
+    let i, seg
+    let j
 
     // Give preference to elements with certain criteria, so they have
     // a chance to be closer to the top.
-    this.sortEventSegs(segs);
+    this.sortEventSegs(segs)
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
+      seg = segs[i]
 
       // loop through levels, starting with the topmost, until the segment doesn't collide with other segments
       for (j = 0; j < levels.length; j++) {
         if (!isDaySegCollision(seg, levels[j])) {
-          break;
+          break
         }
       }
       // `j` now holds the desired subrow index
       seg.level = j;
 
       // create new level array if needed and append segment
-      (levels[j] || (levels[j] = [])).push(seg);
+      (levels[j] || (levels[j] = [])).push(seg)
     }
 
     // order segments left-to-right. very important if calendar is RTL
     for (j = 0; j < levels.length; j++) {
-      levels[j].sort(compareDaySegCols);
+      levels[j].sort(compareDaySegCols)
     }
 
-    return levels;
+    return levels
   }
 
 
   // Given a flat array of segments, return an array of sub-arrays, grouped by each segment's row
   groupSegRows(segs) {
-    var segRows = [];
-    var i;
+    let segRows = []
+    let i
 
     for (i = 0; i < this.dayGrid.rowCnt; i++) {
-      segRows.push([]);
+      segRows.push([])
     }
 
     for (i = 0; i < segs.length; i++) {
-      segRows[segs[i].row].push(segs[i]);
+      segRows[segs[i].row].push(segs[i])
     }
 
-    return segRows;
+    return segRows
   }
 
 
   // Computes a default event time formatting string if `timeFormat` is not explicitly defined
   computeEventTimeFormat() {
-    return this.opt('extraSmallTimeFormat'); // like "6p" or "6:30p"
+    return this.opt('extraSmallTimeFormat') // like "6p" or "6:30p"
   }
 
 
   // Computes a default `displayEventEnd` value if one is not expliclty defined
   computeDisplayEventEnd() {
-    return this.dayGrid.colCnt === 1; // we'll likely have space if there's only one day
+    return this.dayGrid.colCnt === 1 // we'll likely have space if there's only one day
   }
 
 
   // Builds the HTML to be used for the default element for an individual segment
   fgSegHtml(seg, disableResizing) {
-    var view = this.view;
-    var eventDef = seg.footprint.eventDef;
-    var isAllDay = seg.footprint.componentFootprint.isAllDay;
-    var isDraggable = view.isEventDefDraggable(eventDef);
-    var isResizableFromStart = !disableResizing && isAllDay &&
-      seg.isStart && view.isEventDefResizableFromStart(eventDef);
-    var isResizableFromEnd = !disableResizing && isAllDay &&
-      seg.isEnd && view.isEventDefResizableFromEnd(eventDef);
-    var classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd);
-    var skinCss = cssToStr(this.getSkinCss(eventDef));
-    var timeHtml = '';
-    var timeText;
-    var titleHtml;
-
-    classes.unshift('fc-day-grid-event', 'fc-h-event');
+    let view = this.view
+    let eventDef = seg.footprint.eventDef
+    let isAllDay = seg.footprint.componentFootprint.isAllDay
+    let isDraggable = view.isEventDefDraggable(eventDef)
+    let isResizableFromStart = !disableResizing && isAllDay &&
+      seg.isStart && view.isEventDefResizableFromStart(eventDef)
+    let isResizableFromEnd = !disableResizing && isAllDay &&
+      seg.isEnd && view.isEventDefResizableFromEnd(eventDef)
+    let classes = this.getSegClasses(seg, isDraggable, isResizableFromStart || isResizableFromEnd)
+    let skinCss = cssToStr(this.getSkinCss(eventDef))
+    let timeHtml = ''
+    let timeText
+    let titleHtml
+
+    classes.unshift('fc-day-grid-event', 'fc-h-event')
 
     // Only display a timed events time if it is the starting segment
     if (seg.isStart) {
-      timeText = this.getTimeText(seg.footprint);
+      timeText = this.getTimeText(seg.footprint)
       if (timeText) {
-        timeHtml = '<span class="fc-time">' + htmlEscape(timeText) + '</span>';
+        timeHtml = '<span class="fc-time">' + htmlEscape(timeText) + '</span>'
       }
     }
 
     titleHtml =
       '<span class="fc-title">' +
         (htmlEscape(eventDef.title || '') || '&nbsp;') + // we always want one line of height
-      '</span>';
+      '</span>'
 
     return '<a class="' + classes.join(' ') + '"' +
         (eventDef.url ?
@@ -285,7 +283,7 @@ export default class DayGridEventRenderer extends EventRenderer {
           '<div class="fc-resizer fc-end-resizer" />' :
           ''
           ) +
-      '</a>';
+      '</a>'
   }
 
 }
@@ -293,24 +291,24 @@ export default class DayGridEventRenderer extends EventRenderer {
 
 // Computes whether two segments' columns collide. They are assumed to be in the same row.
 function isDaySegCollision(seg, otherSegs) {
-  var i, otherSeg;
+  let i, otherSeg
 
   for (i = 0; i < otherSegs.length; i++) {
-    otherSeg = otherSegs[i];
+    otherSeg = otherSegs[i]
 
     if (
       otherSeg.leftCol <= seg.rightCol &&
       otherSeg.rightCol >= seg.leftCol
     ) {
-      return true;
+      return true
     }
   }
 
-  return false;
+  return false
 }
 
 
 // A cmp function for determining the leftmost event
 function compareDaySegCols(a, b) {
-  return a.leftCol - b.leftCol;
+  return a.leftCol - b.leftCol
 }

+ 24 - 25
src/basic/DayGridFillRenderer.ts

@@ -8,59 +8,58 @@ export default class DayGridFillRenderer extends FillRenderer {
 
 
   attachSegEls(type, segs) {
-    var nodes = [];
-    var i, seg;
-    var skeletonEl;
+    let nodes = []
+    let i, seg
+    let skeletonEl
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
-      skeletonEl = this.renderFillRow(type, seg);
-      this.component.rowEls.eq(seg.row).append(skeletonEl);
-      nodes.push(skeletonEl[0]);
+      seg = segs[i]
+      skeletonEl = this.renderFillRow(type, seg)
+      this.component.rowEls.eq(seg.row).append(skeletonEl)
+      nodes.push(skeletonEl[0])
     }
 
-    return nodes;
+    return nodes
   }
 
 
   // Generates the HTML needed for one row of a fill. Requires the seg's el to be rendered.
   renderFillRow(type, seg) {
-    var colCnt = this.component.colCnt;
-    var startCol = seg.leftCol;
-    var endCol = seg.rightCol + 1;
-    var className;
-    var skeletonEl;
-    var trEl;
+    let colCnt = this.component.colCnt
+    let startCol = seg.leftCol
+    let endCol = seg.rightCol + 1
+    let className
+    let skeletonEl
+    let trEl
 
     if (type === 'businessHours') {
-      className = 'bgevent';
-    }
-    else {
-      className = type.toLowerCase();
+      className = 'bgevent'
+    } else {
+      className = type.toLowerCase()
     }
 
     skeletonEl = $(
       '<div class="fc-' + className + '-skeleton">' +
         '<table><tr/></table>' +
       '</div>'
-    );
-    trEl = skeletonEl.find('tr');
+    )
+    trEl = skeletonEl.find('tr')
 
     if (startCol > 0) {
-      trEl.append('<td colspan="' + startCol + '"/>');
+      trEl.append('<td colspan="' + startCol + '"/>')
     }
 
     trEl.append(
       seg.el.attr('colspan', endCol - startCol)
-    );
+    )
 
     if (endCol < colCnt) {
-      trEl.append('<td colspan="' + (colCnt - endCol) + '"/>');
+      trEl.append('<td colspan="' + (colCnt - endCol) + '"/>')
     }
 
-    this.component.bookendCells(trEl);
+    this.component.bookendCells(trEl)
 
-    return skeletonEl;
+    return skeletonEl
   }
 
 }

+ 17 - 18
src/basic/DayGridHelperRenderer.ts

@@ -6,41 +6,40 @@ export default class DayGridHelperRenderer extends HelperRenderer {
 
   // Renders a mock "helper" event. `sourceSeg` is the associated internal segment object. It can be null.
   renderSegs(segs, sourceSeg) {
-    var helperNodes = [];
-    var rowStructs;
+    let helperNodes = []
+    let rowStructs
 
     // TODO: not good to call eventRenderer this way
-    rowStructs = this.eventRenderer.renderSegRows(segs);
+    rowStructs = this.eventRenderer.renderSegRows(segs)
 
     // inject each new event skeleton into each associated row
     this.component.rowEls.each(function(row, rowNode) {
-      var rowEl = $(rowNode); // the .fc-row
-      var skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>'); // will be absolutely positioned
-      var skeletonTopEl;
-      var skeletonTop;
+      let rowEl = $(rowNode) // the .fc-row
+      let skeletonEl = $('<div class="fc-helper-skeleton"><table/></div>') // will be absolutely positioned
+      let skeletonTopEl
+      let skeletonTop
 
       // If there is an original segment, match the top position. Otherwise, put it at the row's top level
       if (sourceSeg && sourceSeg.row === row) {
-        skeletonTop = sourceSeg.el.position().top;
-      }
-      else {
-        skeletonTopEl = rowEl.find('.fc-content-skeleton tbody');
+        skeletonTop = sourceSeg.el.position().top
+      } else {
+        skeletonTopEl = rowEl.find('.fc-content-skeleton tbody')
         if (!skeletonTopEl.length) { // when no events
-          skeletonTopEl = rowEl.find('.fc-content-skeleton table');
+          skeletonTopEl = rowEl.find('.fc-content-skeleton table')
         }
 
-        skeletonTop = skeletonTopEl.position().top;
+        skeletonTop = skeletonTopEl.position().top
       }
 
       skeletonEl.css('top', skeletonTop)
         .find('table')
-          .append(rowStructs[row].tbodyEl);
+          .append(rowStructs[row].tbodyEl)
 
-      rowEl.append(skeletonEl);
-      helperNodes.push(skeletonEl[0]);
-    });
+      rowEl.append(skeletonEl)
+      helperNodes.push(skeletonEl[0])
+    })
 
-    return $(helperNodes); // must return the elements rendered
+    return $(helperNodes) // must return the elements rendered
   }
 
 }

+ 3 - 3
src/basic/MonthView.ts

@@ -14,15 +14,15 @@ export default class MonthView extends BasicView {
 
     // if auto, make the height of each row the height that it would be if there were 6 weeks
     if (isAuto) {
-      height *= this.dayGrid.rowCnt / 6;
+      height *= this.dayGrid.rowCnt / 6
     }
 
-    distributeHeight(this.dayGrid.rowEls, height, !isAuto); // if auto, don't compensate for height-hogging rows
+    distributeHeight(this.dayGrid.rowEls, height, !isAuto) // if auto, don't compensate for height-hogging rows
   }
 
 
   isDateInOtherMonth(date, dateProfile) {
-    return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month(); // TODO: optimize
+    return date.month() !== moment.utc(dateProfile.currentUnzonedRange.startMs).month() // TODO: optimize
   }
 
 }

+ 7 - 7
src/basic/MonthViewDateProfileGenerator.ts

@@ -6,20 +6,20 @@ export default class MonthViewDateProfileGenerator extends BasicViewDateProfileG
 
   // Computes the date range that will be rendered.
   buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay) {
-    var renderUnzonedRange = super.buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay);
-    var start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay);
-    var end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay);
-    var rowCnt;
+    let renderUnzonedRange = super.buildRenderRange(currentUnzonedRange, currentRangeUnit, isRangeAllDay)
+    let start = this.msToUtcMoment(renderUnzonedRange.startMs, isRangeAllDay)
+    let end = this.msToUtcMoment(renderUnzonedRange.endMs, isRangeAllDay)
+    let rowCnt
 
     // ensure 6 weeks
     if (this.opt('fixedWeekCount')) {
       rowCnt = Math.ceil( // could be partial weeks due to hiddenDays
         end.diff(start, 'weeks', true) // dontRound=true
-      );
-      end.add(6 - rowCnt, 'weeks');
+      )
+      end.add(6 - rowCnt, 'weeks')
     }
 
-    return new UnzonedRange(start, end);
+    return new UnzonedRange(start, end)
   }
 
 }

+ 4 - 4
src/basic/config.ts

@@ -4,17 +4,17 @@ import MonthView from './MonthView'
 
 defineView('basic', {
   'class': BasicView
-});
+})
 
 defineView('basicDay', {
   type: 'basic',
   duration: { days: 1 }
-});
+})
 
 defineView('basicWeek', {
   type: 'basic',
   duration: { weeks: 1 }
-});
+})
 
 defineView('month', {
   'class': MonthView,
@@ -22,4 +22,4 @@ defineView('month', {
   defaults: {
     fixedWeekCount: true
   }
-});
+})

+ 4 - 4
src/common/Class.ts

@@ -7,17 +7,17 @@ export default class Class {
   // Called on a class to create a subclass.
   // LIMITATION: cannot provide a constructor!
   static extend(members): any {
-    class SubClass extends this {};
+    class SubClass extends this {}
 
-    copyOwnProps(members, SubClass.prototype);
+    copyOwnProps(members, SubClass.prototype)
 
-    return SubClass;
+    return SubClass
   }
 
 
   // Adds new member variables/methods to the class's prototype.
   // Can be called with another class, or a plain object hash containing new members.
   static mixin(members) {
-    copyOwnProps(members, this.prototype);
+    copyOwnProps(members, this.prototype)
   }
 }

+ 76 - 76
src/common/CoordCache.ts

@@ -27,106 +27,106 @@ export default class CoordCache {
 
 
   constructor(options) {
-    this.els = $(options.els);
-    this.isHorizontal = options.isHorizontal;
-    this.isVertical = options.isVertical;
-    this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null;
+    this.els = $(options.els)
+    this.isHorizontal = options.isHorizontal
+    this.isVertical = options.isVertical
+    this.forcedOffsetParentEl = options.offsetParent ? $(options.offsetParent) : null
   }
 
 
   // Queries the els for coordinates and stores them.
   // Call this method before using and of the get* methods below.
   build() {
-    var offsetParentEl = this.forcedOffsetParentEl;
+    let offsetParentEl = this.forcedOffsetParentEl
     if (!offsetParentEl && this.els.length > 0) {
-      offsetParentEl = this.els.eq(0).offsetParent();
+      offsetParentEl = this.els.eq(0).offsetParent()
     }
 
     this.origin = offsetParentEl ?
       offsetParentEl.offset() :
-      null;
+      null
 
-    this.boundingRect = this.queryBoundingRect();
+    this.boundingRect = this.queryBoundingRect()
 
     if (this.isHorizontal) {
-      this.buildElHorizontals();
+      this.buildElHorizontals()
     }
     if (this.isVertical) {
-      this.buildElVerticals();
+      this.buildElVerticals()
     }
   }
 
 
   // Destroys all internal data about coordinates, freeing memory
   clear() {
-    this.origin = null;
-    this.boundingRect = null;
-    this.lefts = null;
-    this.rights = null;
-    this.tops = null;
-    this.bottoms = null;
+    this.origin = null
+    this.boundingRect = null
+    this.lefts = null
+    this.rights = null
+    this.tops = null
+    this.bottoms = null
   }
 
 
   // When called, if coord caches aren't built, builds them
   ensureBuilt() {
     if (!this.origin) {
-      this.build();
+      this.build()
     }
   }
 
 
   // Populates the left/right internal coordinate arrays
   buildElHorizontals() {
-    var lefts = [];
-    var rights = [];
+    let lefts = []
+    let rights = []
 
     this.els.each(function(i, node) {
-      var el = $(node);
-      var left = el.offset().left;
-      var width = el.outerWidth();
+      let el = $(node)
+      let left = el.offset().left
+      let width = el.outerWidth()
 
-      lefts.push(left);
-      rights.push(left + width);
-    });
+      lefts.push(left)
+      rights.push(left + width)
+    })
 
-    this.lefts = lefts;
-    this.rights = rights;
+    this.lefts = lefts
+    this.rights = rights
   }
 
 
   // Populates the top/bottom internal coordinate arrays
   buildElVerticals() {
-    var tops = [];
-    var bottoms = [];
+    let tops = []
+    let bottoms = []
 
     this.els.each(function(i, node) {
-      var el = $(node);
-      var top = el.offset().top;
-      var height = el.outerHeight();
+      let el = $(node)
+      let top = el.offset().top
+      let height = el.outerHeight()
 
-      tops.push(top);
-      bottoms.push(top + height);
-    });
+      tops.push(top)
+      bottoms.push(top + height)
+    })
 
-    this.tops = tops;
-    this.bottoms = bottoms;
+    this.tops = tops
+    this.bottoms = bottoms
   }
 
 
   // Given a left offset (from document left), returns the index of the el that it horizontally intersects.
   // If no intersection is made, returns undefined.
   getHorizontalIndex(leftOffset) {
-    this.ensureBuilt();
+    this.ensureBuilt()
 
-    var lefts = this.lefts;
-    var rights = this.rights;
-    var len = lefts.length;
-    var i;
+    let lefts = this.lefts
+    let rights = this.rights
+    let len = lefts.length
+    let i
 
     for (i = 0; i < len; i++) {
       if (leftOffset >= lefts[i] && leftOffset < rights[i]) {
-        return i;
+        return i
       }
     }
   }
@@ -135,16 +135,16 @@ export default class CoordCache {
   // Given a top offset (from document top), returns the index of the el that it vertically intersects.
   // If no intersection is made, returns undefined.
   getVerticalIndex(topOffset) {
-    this.ensureBuilt();
+    this.ensureBuilt()
 
-    var tops = this.tops;
-    var bottoms = this.bottoms;
-    var len = tops.length;
-    var i;
+    let tops = this.tops
+    let bottoms = this.bottoms
+    let len = tops.length
+    let i
 
     for (i = 0; i < len; i++) {
       if (topOffset >= tops[i] && topOffset < bottoms[i]) {
-        return i;
+        return i
       }
     }
   }
@@ -152,74 +152,74 @@ export default class CoordCache {
 
   // Gets the left offset (from document left) of the element at the given index
   getLeftOffset(leftIndex) {
-    this.ensureBuilt();
-    return this.lefts[leftIndex];
+    this.ensureBuilt()
+    return this.lefts[leftIndex]
   }
 
 
   // Gets the left position (from offsetParent left) of the element at the given index
   getLeftPosition(leftIndex) {
-    this.ensureBuilt();
-    return this.lefts[leftIndex] - this.origin.left;
+    this.ensureBuilt()
+    return this.lefts[leftIndex] - this.origin.left
   }
 
 
   // Gets the right offset (from document left) of the element at the given index.
   // This value is NOT relative to the document's right edge, like the CSS concept of "right" would be.
   getRightOffset(leftIndex) {
-    this.ensureBuilt();
-    return this.rights[leftIndex];
+    this.ensureBuilt()
+    return this.rights[leftIndex]
   }
 
 
   // Gets the right position (from offsetParent left) of the element at the given index.
   // This value is NOT relative to the offsetParent's right edge, like the CSS concept of "right" would be.
   getRightPosition(leftIndex) {
-    this.ensureBuilt();
-    return this.rights[leftIndex] - this.origin.left;
+    this.ensureBuilt()
+    return this.rights[leftIndex] - this.origin.left
   }
 
 
   // Gets the width of the element at the given index
   getWidth(leftIndex) {
-    this.ensureBuilt();
-    return this.rights[leftIndex] - this.lefts[leftIndex];
+    this.ensureBuilt()
+    return this.rights[leftIndex] - this.lefts[leftIndex]
   }
 
 
   // Gets the top offset (from document top) of the element at the given index
   getTopOffset(topIndex) {
-    this.ensureBuilt();
-    return this.tops[topIndex];
+    this.ensureBuilt()
+    return this.tops[topIndex]
   }
 
 
   // Gets the top position (from offsetParent top) of the element at the given position
   getTopPosition(topIndex) {
-    this.ensureBuilt();
-    return this.tops[topIndex] - this.origin.top;
+    this.ensureBuilt()
+    return this.tops[topIndex] - this.origin.top
   }
 
   // Gets the bottom offset (from the document top) of the element at the given index.
   // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
   getBottomOffset(topIndex) {
-    this.ensureBuilt();
-    return this.bottoms[topIndex];
+    this.ensureBuilt()
+    return this.bottoms[topIndex]
   }
 
 
   // Gets the bottom position (from the offsetParent top) of the element at the given index.
   // This value is NOT relative to the offsetParent's bottom edge, like the CSS concept of "bottom" would be.
   getBottomPosition(topIndex) {
-    this.ensureBuilt();
-    return this.bottoms[topIndex] - this.origin.top;
+    this.ensureBuilt()
+    return this.bottoms[topIndex] - this.origin.top
   }
 
 
   // Gets the height of the element at the given index
   getHeight(topIndex) {
-    this.ensureBuilt();
-    return this.bottoms[topIndex] - this.tops[topIndex];
+    this.ensureBuilt()
+    return this.bottoms[topIndex] - this.tops[topIndex]
   }
 
 
@@ -230,29 +230,29 @@ export default class CoordCache {
   // Right now, only returns a rectangle if constrained by an overflow:scroll element.
   // Returns null if there are no elements
   queryBoundingRect() {
-    var scrollParentEl;
+    let scrollParentEl
 
     if (this.els.length > 0) {
-      scrollParentEl = getScrollParent(this.els.eq(0));
+      scrollParentEl = getScrollParent(this.els.eq(0))
 
       if (!scrollParentEl.is(document)) {
-        return getClientRect(scrollParentEl);
+        return getClientRect(scrollParentEl)
       }
     }
 
-    return null;
+    return null
   }
 
   isPointInBounds(leftOffset, topOffset) {
-    return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset);
+    return this.isLeftInBounds(leftOffset) && this.isTopInBounds(topOffset)
   }
 
   isLeftInBounds(leftOffset) {
-    return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right);
+    return !this.boundingRect || (leftOffset >= this.boundingRect.left && leftOffset < this.boundingRect.right)
   }
 
   isTopInBounds(topOffset) {
-    return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom);
+    return !this.boundingRect || (topOffset >= this.boundingRect.top && topOffset < this.boundingRect.bottom)
   }
 
 }

+ 117 - 126
src/common/DragListener.ts

@@ -65,7 +65,7 @@ export default class DragListener {
 
 
   constructor(options) {
-    this.options = options || {};
+    this.options = options || {}
   }
 
 
@@ -73,78 +73,76 @@ export default class DragListener {
   // -----------------------------------------------------------------------------------------------------------------
 
 
-  startInteraction(ev, extraOptions:any={}) {
+  startInteraction(ev, extraOptions: any= {}) {
 
     if (ev.type === 'mousedown') {
       if (GlobalEmitter.get().shouldIgnoreMouse()) {
-        return;
-      }
-      else if (!isPrimaryMouseButton(ev)) {
-        return;
-      }
-      else {
-        ev.preventDefault(); // prevents native selection in most browsers
+        return
+      } else if (!isPrimaryMouseButton(ev)) {
+        return
+      } else {
+        ev.preventDefault() // prevents native selection in most browsers
       }
     }
 
     if (!this.isInteracting) {
 
       // process options
-      this.delay = firstDefined(extraOptions.delay, this.options.delay, 0);
-      this.minDistance = firstDefined(extraOptions.distance, this.options.distance, 0);
-      this.subjectEl = this.options.subjectEl;
+      this.delay = firstDefined(extraOptions.delay, this.options.delay, 0)
+      this.minDistance = firstDefined(extraOptions.distance, this.options.distance, 0)
+      this.subjectEl = this.options.subjectEl
 
-      preventSelection($('body'));
+      preventSelection($('body'))
 
-      this.isInteracting = true;
-      this.isTouch = getEvIsTouch(ev);
-      this.isGeneric = ev.type === 'dragstart';
-      this.isDelayEnded = false;
-      this.isDistanceSurpassed = false;
+      this.isInteracting = true
+      this.isTouch = getEvIsTouch(ev)
+      this.isGeneric = ev.type === 'dragstart'
+      this.isDelayEnded = false
+      this.isDistanceSurpassed = false
 
-      this.originX = getEvX(ev);
-      this.originY = getEvY(ev);
-      this.scrollEl = getScrollParent($(ev.target));
+      this.originX = getEvX(ev)
+      this.originY = getEvY(ev)
+      this.scrollEl = getScrollParent($(ev.target))
 
-      this.bindHandlers();
-      this.initAutoScroll();
-      this.handleInteractionStart(ev);
-      this.startDelay(ev);
+      this.bindHandlers()
+      this.initAutoScroll()
+      this.handleInteractionStart(ev)
+      this.startDelay(ev)
 
       if (!this.minDistance) {
-        this.handleDistanceSurpassed(ev);
+        this.handleDistanceSurpassed(ev)
       }
     }
   }
 
 
   handleInteractionStart(ev) {
-    this.trigger('interactionStart', ev);
+    this.trigger('interactionStart', ev)
   }
 
 
   endInteraction(ev, isCancelled) {
     if (this.isInteracting) {
-      this.endDrag(ev);
+      this.endDrag(ev)
 
       if (this.delayTimeoutId) {
-        clearTimeout(this.delayTimeoutId);
-        this.delayTimeoutId = null;
+        clearTimeout(this.delayTimeoutId)
+        this.delayTimeoutId = null
       }
 
-      this.destroyAutoScroll();
-      this.unbindHandlers();
+      this.destroyAutoScroll()
+      this.unbindHandlers()
 
-      this.isInteracting = false;
-      this.handleInteractionEnd(ev, isCancelled);
+      this.isInteracting = false
+      this.handleInteractionEnd(ev, isCancelled)
 
-      allowSelection($('body'));
+      allowSelection($('body'))
     }
   }
 
 
   handleInteractionEnd(ev, isCancelled) {
-    this.trigger('interactionEnd', ev, isCancelled || false);
+    this.trigger('interactionEnd', ev, isCancelled || false)
   }
 
 
@@ -155,38 +153,36 @@ export default class DragListener {
   bindHandlers() {
     // some browsers (Safari in iOS 10) don't allow preventDefault on touch events that are bound after touchstart,
     // so listen to the GlobalEmitter singleton, which is always bound, instead of the document directly.
-    var globalEmitter = GlobalEmitter.get();
+    let globalEmitter = GlobalEmitter.get()
 
     if (this.isGeneric) {
       this.listenTo($(document), { // might only work on iOS because of GlobalEmitter's bind :(
         drag: this.handleMove,
         dragstop: this.endInteraction
-      });
-    }
-    else if (this.isTouch) {
+      })
+    } else if (this.isTouch) {
       this.listenTo(globalEmitter, {
         touchmove: this.handleTouchMove,
         touchend: this.endInteraction,
         scroll: this.handleTouchScroll
-      });
-    }
-    else {
+      })
+    } else {
       this.listenTo(globalEmitter, {
         mousemove: this.handleMouseMove,
         mouseup: this.endInteraction
-      });
+      })
     }
 
     this.listenTo(globalEmitter, {
       selectstart: preventDefault, // don't allow selection while dragging
       contextmenu: preventDefault // long taps would open menu on Chrome dev tools
-    });
+    })
   }
 
 
   unbindHandlers() {
-    this.stopListeningTo(GlobalEmitter.get());
-    this.stopListeningTo($(document)); // for isGeneric
+    this.stopListeningTo(GlobalEmitter.get())
+    this.stopListeningTo($(document)) // for isGeneric
   }
 
 
@@ -196,56 +192,56 @@ export default class DragListener {
 
   // extraOptions ignored if drag already started
   startDrag(ev, extraOptions?) {
-    this.startInteraction(ev, extraOptions); // ensure interaction began
+    this.startInteraction(ev, extraOptions) // ensure interaction began
 
     if (!this.isDragging) {
-      this.isDragging = true;
-      this.handleDragStart(ev);
+      this.isDragging = true
+      this.handleDragStart(ev)
     }
   }
 
 
   handleDragStart(ev) {
-    this.trigger('dragStart', ev);
+    this.trigger('dragStart', ev)
   }
 
 
   handleMove(ev) {
-    var dx = getEvX(ev) - this.originX;
-    var dy = getEvY(ev) - this.originY;
-    var minDistance = this.minDistance;
-    var distanceSq; // current distance from the origin, squared
+    let dx = getEvX(ev) - this.originX
+    let dy = getEvY(ev) - this.originY
+    let minDistance = this.minDistance
+    let distanceSq // current distance from the origin, squared
 
     if (!this.isDistanceSurpassed) {
-      distanceSq = dx * dx + dy * dy;
+      distanceSq = dx * dx + dy * dy
       if (distanceSq >= minDistance * minDistance) { // use pythagorean theorem
-        this.handleDistanceSurpassed(ev);
+        this.handleDistanceSurpassed(ev)
       }
     }
 
     if (this.isDragging) {
-      this.handleDrag(dx, dy, ev);
+      this.handleDrag(dx, dy, ev)
     }
   }
 
 
   // Called while the mouse is being moved and when we know a legitimate drag is taking place
   handleDrag(dx, dy, ev) {
-    this.trigger('drag', dx, dy, ev);
-    this.updateAutoScroll(ev); // will possibly cause scrolling
+    this.trigger('drag', dx, dy, ev)
+    this.updateAutoScroll(ev) // will possibly cause scrolling
   }
 
 
   endDrag(ev) {
     if (this.isDragging) {
-      this.isDragging = false;
-      this.handleDragEnd(ev);
+      this.isDragging = false
+      this.handleDragEnd(ev)
     }
   }
 
 
   handleDragEnd(ev) {
-    this.trigger('dragEnd', ev);
+    this.trigger('dragEnd', ev)
   }
 
 
@@ -256,20 +252,19 @@ export default class DragListener {
   startDelay(initialEv) {
     if (this.delay) {
       this.delayTimeoutId = setTimeout(() => {
-        this.handleDelayEnd(initialEv);
-      }, this.delay);
-    }
-    else {
-      this.handleDelayEnd(initialEv);
+        this.handleDelayEnd(initialEv)
+      }, this.delay)
+    } else {
+      this.handleDelayEnd(initialEv)
     }
   }
 
 
   handleDelayEnd(initialEv) {
-    this.isDelayEnded = true;
+    this.isDelayEnded = true
 
     if (this.isDistanceSurpassed) {
-      this.startDrag(initialEv);
+      this.startDrag(initialEv)
     }
   }
 
@@ -279,10 +274,10 @@ export default class DragListener {
 
 
   handleDistanceSurpassed(ev) {
-    this.isDistanceSurpassed = true;
+    this.isDistanceSurpassed = true
 
     if (this.isDelayEnded) {
-      this.startDrag(ev);
+      this.startDrag(ev)
     }
   }
 
@@ -295,15 +290,15 @@ export default class DragListener {
 
     // prevent inertia and touchmove-scrolling while dragging
     if (this.isDragging && this.shouldCancelTouchScroll) {
-      ev.preventDefault();
+      ev.preventDefault()
     }
 
-    this.handleMove(ev);
+    this.handleMove(ev)
   }
 
 
   handleMouseMove(ev) {
-    this.handleMove(ev);
+    this.handleMove(ev)
   }
 
 
@@ -315,7 +310,7 @@ export default class DragListener {
     // if the drag is being initiated by touch, but a scroll happens before
     // the drag-initiating delay is over, cancel the drag
     if (!this.isDragging || this.scrollAlwaysKills) {
-      this.endInteraction(ev, true); // isCancelled=true
+      this.endInteraction(ev, true) // isCancelled=true
     }
   }
 
@@ -328,11 +323,11 @@ export default class DragListener {
   // Arguments beyond the first `name` are forwarded on.
   trigger(name, ...args) {
     if (this.options[name]) {
-      this.options[name].apply(this, args);
+      this.options[name].apply(this, args)
     }
     // makes _methods callable by event name. TODO: kill this
     if (this['_' + name]) {
-      this['_' + name].apply(this, args);
+      this['_' + name].apply(this, args)
     }
   }
 
@@ -342,27 +337,27 @@ export default class DragListener {
 
 
   initAutoScroll() {
-    var scrollEl = this.scrollEl;
+    let scrollEl = this.scrollEl
 
     this.isAutoScroll =
       this.options.scroll &&
       scrollEl &&
       !scrollEl.is(window) &&
-      !scrollEl.is(document);
+      !scrollEl.is(document)
 
     if (this.isAutoScroll) {
       // debounce makes sure rapid calls don't happen
-      this.listenTo(scrollEl, 'scroll', debounce(this.handleDebouncedScroll, 100));
+      this.listenTo(scrollEl, 'scroll', debounce(this.handleDebouncedScroll, 100))
     }
   }
 
 
   destroyAutoScroll() {
-    this.endAutoScroll(); // kill any animation loop
+    this.endAutoScroll() // kill any animation loop
 
     // remove the scroll handler if there is a scrollEl
     if (this.isAutoScroll) {
-      this.stopListeningTo(this.scrollEl, 'scroll'); // will probably get removed by unbindHandlers too :(
+      this.stopListeningTo(this.scrollEl, 'scroll') // will probably get removed by unbindHandlers too :(
     }
   }
 
@@ -370,7 +365,7 @@ export default class DragListener {
   // Computes and stores the bounding rectangle of scrollEl
   computeScrollBounds() {
     if (this.isAutoScroll) {
-      this.scrollBounds = getOuterRect(this.scrollEl);
+      this.scrollBounds = getOuterRect(this.scrollEl)
       // TODO: use getClientRect in future. but prevents auto scrolling when on top of scrollbars
     }
   }
@@ -378,84 +373,80 @@ export default class DragListener {
 
   // Called when the dragging is in progress and scrolling should be updated
   updateAutoScroll(ev) {
-    var sensitivity = this.scrollSensitivity;
-    var bounds = this.scrollBounds;
-    var topCloseness, bottomCloseness;
-    var leftCloseness, rightCloseness;
-    var topVel = 0;
-    var leftVel = 0;
+    let sensitivity = this.scrollSensitivity
+    let bounds = this.scrollBounds
+    let topCloseness, bottomCloseness
+    let leftCloseness, rightCloseness
+    let topVel = 0
+    let leftVel = 0
 
     if (bounds) { // only scroll if scrollEl exists
 
       // compute closeness to edges. valid range is from 0.0 - 1.0
-      topCloseness = (sensitivity - (getEvY(ev) - bounds.top)) / sensitivity;
-      bottomCloseness = (sensitivity - (bounds.bottom - getEvY(ev))) / sensitivity;
-      leftCloseness = (sensitivity - (getEvX(ev) - bounds.left)) / sensitivity;
-      rightCloseness = (sensitivity - (bounds.right - getEvX(ev))) / sensitivity;
+      topCloseness = (sensitivity - (getEvY(ev) - bounds.top)) / sensitivity
+      bottomCloseness = (sensitivity - (bounds.bottom - getEvY(ev))) / sensitivity
+      leftCloseness = (sensitivity - (getEvX(ev) - bounds.left)) / sensitivity
+      rightCloseness = (sensitivity - (bounds.right - getEvX(ev))) / sensitivity
 
       // translate vertical closeness into velocity.
       // mouse must be completely in bounds for velocity to happen.
       if (topCloseness >= 0 && topCloseness <= 1) {
-        topVel = topCloseness * this.scrollSpeed * -1; // negative. for scrolling up
-      }
-      else if (bottomCloseness >= 0 && bottomCloseness <= 1) {
-        topVel = bottomCloseness * this.scrollSpeed;
+        topVel = topCloseness * this.scrollSpeed * -1 // negative. for scrolling up
+      } else if (bottomCloseness >= 0 && bottomCloseness <= 1) {
+        topVel = bottomCloseness * this.scrollSpeed
       }
 
       // translate horizontal closeness into velocity
       if (leftCloseness >= 0 && leftCloseness <= 1) {
-        leftVel = leftCloseness * this.scrollSpeed * -1; // negative. for scrolling left
-      }
-      else if (rightCloseness >= 0 && rightCloseness <= 1) {
-        leftVel = rightCloseness * this.scrollSpeed;
+        leftVel = leftCloseness * this.scrollSpeed * -1 // negative. for scrolling left
+      } else if (rightCloseness >= 0 && rightCloseness <= 1) {
+        leftVel = rightCloseness * this.scrollSpeed
       }
     }
 
-    this.setScrollVel(topVel, leftVel);
+    this.setScrollVel(topVel, leftVel)
   }
 
 
   // Sets the speed-of-scrolling for the scrollEl
   setScrollVel(topVel, leftVel) {
 
-    this.scrollTopVel = topVel;
-    this.scrollLeftVel = leftVel;
+    this.scrollTopVel = topVel
+    this.scrollLeftVel = leftVel
 
-    this.constrainScrollVel(); // massages into realistic values
+    this.constrainScrollVel() // massages into realistic values
 
     // if there is non-zero velocity, and an animation loop hasn't already started, then START
     if ((this.scrollTopVel || this.scrollLeftVel) && !this.scrollIntervalId) {
       this.scrollIntervalId = setInterval(
         proxy(this, 'scrollIntervalFunc'), // scope to `this`
         this.scrollIntervalMs
-      );
+      )
     }
   }
 
 
   // Forces scrollTopVel and scrollLeftVel to be zero if scrolling has already gone all the way
   constrainScrollVel() {
-    var el = this.scrollEl;
+    let el = this.scrollEl
 
     if (this.scrollTopVel < 0) { // scrolling up?
       if (el.scrollTop() <= 0) { // already scrolled all the way up?
-        this.scrollTopVel = 0;
+        this.scrollTopVel = 0
       }
-    }
-    else if (this.scrollTopVel > 0) { // scrolling down?
+    } else if (this.scrollTopVel > 0) { // scrolling down?
       if (el.scrollTop() + el[0].clientHeight >= el[0].scrollHeight) { // already scrolled all the way down?
-        this.scrollTopVel = 0;
+        this.scrollTopVel = 0
       }
     }
 
     if (this.scrollLeftVel < 0) { // scrolling left?
       if (el.scrollLeft() <= 0) { // already scrolled all the left?
-        this.scrollLeftVel = 0;
+        this.scrollLeftVel = 0
       }
-    }
-    else if (this.scrollLeftVel > 0) { // scrolling right?
+    } else if (this.scrollLeftVel > 0) { // scrolling right?
       if (el.scrollLeft() + el[0].clientWidth >= el[0].scrollWidth) { // already scrolled all the way right?
-        this.scrollLeftVel = 0;
+        this.scrollLeftVel = 0
       }
     }
   }
@@ -463,22 +454,22 @@ export default class DragListener {
 
   // This function gets called during every iteration of the scrolling animation loop
   scrollIntervalFunc() {
-    var el = this.scrollEl;
-    var frac = this.scrollIntervalMs / 1000; // considering animation frequency, what the vel should be mult'd by
+    let el = this.scrollEl
+    let frac = this.scrollIntervalMs / 1000 // considering animation frequency, what the vel should be mult'd by
 
     // change the value of scrollEl's scroll
     if (this.scrollTopVel) {
-      el.scrollTop(el.scrollTop() + this.scrollTopVel * frac);
+      el.scrollTop(el.scrollTop() + this.scrollTopVel * frac)
     }
     if (this.scrollLeftVel) {
-      el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac);
+      el.scrollLeft(el.scrollLeft() + this.scrollLeftVel * frac)
     }
 
-    this.constrainScrollVel(); // since the scroll values changed, recompute the velocities
+    this.constrainScrollVel() // since the scroll values changed, recompute the velocities
 
     // if scrolled all the way, which causes the vels to be zero, stop the animation loop
     if (!this.scrollTopVel && !this.scrollLeftVel) {
-      this.endAutoScroll();
+      this.endAutoScroll()
     }
   }
 
@@ -486,10 +477,10 @@ export default class DragListener {
   // Kills any existing scrolling animation loop
   endAutoScroll() {
     if (this.scrollIntervalId) {
-      clearInterval(this.scrollIntervalId);
-      this.scrollIntervalId = null;
+      clearInterval(this.scrollIntervalId)
+      this.scrollIntervalId = null
 
-      this.handleScrollEnd();
+      this.handleScrollEnd()
     }
   }
 
@@ -498,7 +489,7 @@ export default class DragListener {
   handleDebouncedScroll() {
     // recompute all coordinates, but *only* if this is *not* part of our scrolling animation
     if (!this.scrollIntervalId) {
-      this.handleScrollEnd();
+      this.handleScrollEnd()
     }
   }
 

+ 18 - 18
src/common/EmitterMixin.ts

@@ -31,14 +31,14 @@ export default class EmitterMixin extends Mixin implements EmitterInterface {
 
 
   on(types, handler) {
-    $(this).on(types, this._prepareIntercept(handler));
-    return this; // for chaining
+    $(this).on(types, this._prepareIntercept(handler))
+    return this // for chaining
   }
 
 
   one(types, handler) {
-    $(this).one(types, this._prepareIntercept(handler));
-    return this; // for chaining
+    $(this).one(types, this._prepareIntercept(handler))
+    return this // for chaining
   }
 
 
@@ -46,38 +46,38 @@ export default class EmitterMixin extends Mixin implements EmitterInterface {
     // handlers are always called with an "event" object as their first param.
     // sneak the `this` context and arguments into the extra parameter object
     // and forward them on to the original handler.
-    var intercept = function(ev, extra) {
+    let intercept = function(ev, extra) {
       return handler.apply(
         extra.context || this,
         extra.args || []
-      );
-    };
+      )
+    }
 
     // mimick jQuery's internal "proxy" system (risky, I know)
     // causing all functions with the same .guid to appear to be the same.
     // https://github.com/jquery/jquery/blob/2.2.4/src/core.js#L448
     // this is needed for calling .off with the original non-intercept handler.
     if (!handler.guid) {
-      handler.guid = ($ as any).guid++;
+      handler.guid = ($ as any).guid++
     }
-    (intercept as any).guid = handler.guid;
+    (intercept as any).guid = handler.guid
 
-    return intercept;
+    return intercept
   }
 
 
   off(types, handler) {
-    $(this).off(types, handler);
+    $(this).off(types, handler)
 
-    return this; // for chaining
+    return this // for chaining
   }
 
 
   trigger(types, ...args) {
     // pass in "extra" info to the intercept
-    $(this).triggerHandler(types, { args: args });
+    $(this).triggerHandler(types, { args: args })
 
-    return this; // for chaining
+    return this // for chaining
   }
 
 
@@ -85,16 +85,16 @@ export default class EmitterMixin extends Mixin implements EmitterInterface {
 
     // `triggerHandler` is less reliant on the DOM compared to `trigger`.
     // pass in "extra" info to the intercept.
-    $(this).triggerHandler(types, { context: context, args: args });
+    $(this).triggerHandler(types, { context: context, args: args })
 
-    return this; // for chaining
+    return this // for chaining
   }
 
 
   hasHandlers(type) {
-    var hash = ($ as any)._data(this, 'events'); // http://blog.jquery.com/2012/08/09/jquery-1-8-released/
+    let hash = ($ as any)._data(this, 'events') // http://blog.jquery.com/2012/08/09/jquery-1-8-released/
 
-    return hash && hash[type] && hash[type].length > 0;
+    return hash && hash[type] && hash[type].length > 0
   }
 
 }

+ 43 - 43
src/common/GlobalEmitter.ts

@@ -3,10 +3,10 @@ import * as exportHooks from '../exports'
 import { default as EmitterMixin, EmitterInterface } from './EmitterMixin'
 import { default as ListenerMixin, ListenerInterface } from './ListenerMixin'
 
-(exportHooks as any).touchMouseIgnoreWait = 500;
+(exportHooks as any).touchMouseIgnoreWait = 500
 
-var globalEmitter = null;
-var neededCount = 0;
+let globalEmitter = null
+let neededCount = 0
 
 /*
 Listens to document and window-level user-interaction events, like touch events and mouse events,
@@ -30,8 +30,8 @@ export default class GlobalEmitter {
 
   isTouching: boolean = false
   mouseIgnoreDepth: number = 0
-  handleScrollProxy: (ev) => void;
-  handleTouchMoveProxy: (ev) => void;
+  handleScrollProxy: (ev) => void
+  handleTouchMoveProxy: (ev) => void
 
 
   bind() {
@@ -45,7 +45,7 @@ export default class GlobalEmitter {
       click: this.handleClick,
       selectstart: this.handleSelectStart,
       contextmenu: this.handleContextMenu
-    });
+    })
 
     // because we need to call preventDefault
     // because https://www.chromestatus.com/features/5093566007214080
@@ -53,10 +53,10 @@ export default class GlobalEmitter {
     window.addEventListener(
       'touchmove',
       this.handleTouchMoveProxy = (ev) => {
-        this.handleTouchMove($.Event(ev));
+        this.handleTouchMove($.Event(ev))
       },
       { passive: false } as any // allows preventDefault()
-    );
+    )
 
     // attach a handler to get called when ANY scroll action happens on the page.
     // this was impossible to do with normal on/off because 'scroll' doesn't bubble.
@@ -64,25 +64,25 @@ export default class GlobalEmitter {
     window.addEventListener(
       'scroll',
       this.handleScrollProxy = (ev) => {
-        this.handleScroll($.Event(ev));
+        this.handleScroll($.Event(ev))
       },
       true // useCapture
-    );
+    )
   }
 
   unbind() {
-    this.stopListeningTo($(document));
+    this.stopListeningTo($(document))
 
     window.removeEventListener(
       'touchmove',
       this.handleTouchMoveProxy
-    );
+    )
 
     window.removeEventListener(
       'scroll',
       this.handleScrollProxy,
       true // useCapture
-    );
+    )
   }
 
 
@@ -93,30 +93,30 @@ export default class GlobalEmitter {
 
     // if a previous touch interaction never ended with a touchend, then implicitly end it,
     // but since a new touch interaction is about to begin, don't start the mouse ignore period.
-    this.stopTouch(ev, true); // skipMouseIgnore=true
+    this.stopTouch(ev, true) // skipMouseIgnore=true
 
-    this.isTouching = true;
-    this.trigger('touchstart', ev);
+    this.isTouching = true
+    this.trigger('touchstart', ev)
   }
 
   handleTouchMove(ev) {
     if (this.isTouching) {
-      this.trigger('touchmove', ev);
+      this.trigger('touchmove', ev)
     }
   }
 
   handleTouchCancel(ev) {
     if (this.isTouching) {
-      this.trigger('touchcancel', ev);
+      this.trigger('touchcancel', ev)
 
       // Have touchcancel fire an artificial touchend. That way, handlers won't need to listen to both.
       // If touchend fires later, it won't have any effect b/c isTouching will be false.
-      this.stopTouch(ev);
+      this.stopTouch(ev)
     }
   }
 
   handleTouchEnd(ev) {
-    this.stopTouch(ev);
+    this.stopTouch(ev)
   }
 
 
@@ -125,25 +125,25 @@ export default class GlobalEmitter {
 
   handleMouseDown(ev) {
     if (!this.shouldIgnoreMouse()) {
-      this.trigger('mousedown', ev);
+      this.trigger('mousedown', ev)
     }
   }
 
   handleMouseMove(ev) {
     if (!this.shouldIgnoreMouse()) {
-      this.trigger('mousemove', ev);
+      this.trigger('mousemove', ev)
     }
   }
 
   handleMouseUp(ev) {
     if (!this.shouldIgnoreMouse()) {
-      this.trigger('mouseup', ev);
+      this.trigger('mouseup', ev)
     }
   }
 
   handleClick(ev) {
     if (!this.shouldIgnoreMouse()) {
-      this.trigger('click', ev);
+      this.trigger('click', ev)
     }
   }
 
@@ -156,41 +156,41 @@ export default class GlobalEmitter {
   }
 
   handleContextMenu(ev) {
-    this.trigger('contextmenu', ev);
+    this.trigger('contextmenu', ev)
   }
 
   handleScroll(ev) {
-    this.trigger('scroll', ev);
+    this.trigger('scroll', ev)
   }
 
 
   // Utils
   // -----------------------------------------------------------------------------------------------------------------
 
-  stopTouch(ev, skipMouseIgnore=false) {
+  stopTouch(ev, skipMouseIgnore= false) {
     if (this.isTouching) {
-      this.isTouching = false;
-      this.trigger('touchend', ev);
+      this.isTouching = false
+      this.trigger('touchend', ev)
 
       if (!skipMouseIgnore) {
-        this.startTouchMouseIgnore();
+        this.startTouchMouseIgnore()
       }
     }
   }
 
   startTouchMouseIgnore() {
-    var wait = (exportHooks as any).touchMouseIgnoreWait;
+    let wait = (exportHooks as any).touchMouseIgnoreWait
 
     if (wait) {
-      this.mouseIgnoreDepth++;
+      this.mouseIgnoreDepth++
       setTimeout(() => {
-        this.mouseIgnoreDepth--;
-      }, wait);
+        this.mouseIgnoreDepth--
+      }, wait)
     }
   }
 
   shouldIgnoreMouse() {
-    return this.isTouching || Boolean(this.mouseIgnoreDepth);
+    return this.isTouching || Boolean(this.mouseIgnoreDepth)
   }
 
 
@@ -201,28 +201,28 @@ export default class GlobalEmitter {
   // gets the singleton
   static get() {
     if (!globalEmitter) {
-      globalEmitter = new GlobalEmitter();
-      globalEmitter.bind();
+      globalEmitter = new GlobalEmitter()
+      globalEmitter.bind()
     }
 
-    return globalEmitter;
+    return globalEmitter
   }
 
 
   // called when an object knows it will need a GlobalEmitter in the near future.
   static needed() {
-    GlobalEmitter.get(); // ensures globalEmitter
-    neededCount++;
+    GlobalEmitter.get() // ensures globalEmitter
+    neededCount++
   }
 
 
   // called when the object that originally called needed() doesn't need a GlobalEmitter anymore.
   static unneeded() {
-    neededCount--;
+    neededCount--
 
     if (!neededCount) { // nobody else needs it
-      globalEmitter.unbind();
-      globalEmitter = null;
+      globalEmitter.unbind()
+      globalEmitter = null
     }
   }
 

+ 54 - 55
src/common/HitDragListener.ts

@@ -28,32 +28,32 @@ export default class HitDragListener extends DragListener {
 
 
   constructor(component, options) {
-    super(options);
-    this.component = component;
+    super(options)
+    this.component = component
   }
 
   // Called when drag listening starts (but a real drag has not necessarily began).
   // ev might be undefined if dragging was started manually.
   handleInteractionStart(ev) {
-    var subjectEl = this.subjectEl;
-    var subjectRect;
-    var origPoint;
-    var point;
+    let subjectEl = this.subjectEl
+    let subjectRect
+    let origPoint
+    let point
 
-    this.component.hitsNeeded();
-    this.computeScrollBounds(); // for autoscroll
+    this.component.hitsNeeded()
+    this.computeScrollBounds() // for autoscroll
 
     if (ev) {
-      origPoint = { left: getEvX(ev), top: getEvY(ev) };
-      point = origPoint;
+      origPoint = { left: getEvX(ev), top: getEvY(ev) }
+      point = origPoint
 
       // constrain the point to bounds of the element being dragged
       if (subjectEl) {
-        subjectRect = getOuterRect(subjectEl); // used for centering as well
-        point = constrainPoint(point, subjectRect);
+        subjectRect = getOuterRect(subjectEl) // used for centering as well
+        point = constrainPoint(point, subjectRect)
       }
 
-      this.origHit = this.queryHit(point.left, point.top);
+      this.origHit = this.queryHit(point.left, point.top)
 
       // treat the center of the subject as the collision point?
       if (subjectEl && this.options.subjectCenter) {
@@ -62,55 +62,54 @@ export default class HitDragListener extends DragListener {
         // TODO: skip this if hit didn't supply left/right/top/bottom
         if (this.origHit) {
           subjectRect = intersectRects(this.origHit, subjectRect) ||
-            subjectRect; // in case there is no intersection
+            subjectRect // in case there is no intersection
         }
 
-        point = getRectCenter(subjectRect);
+        point = getRectCenter(subjectRect)
       }
 
-      this.coordAdjust = diffPoints(point, origPoint); // point - origPoint
-    }
-    else {
-      this.origHit = null;
-      this.coordAdjust = null;
+      this.coordAdjust = diffPoints(point, origPoint) // point - origPoint
+    } else {
+      this.origHit = null
+      this.coordAdjust = null
     }
 
     // call the super-method. do it after origHit has been computed
-    super.handleInteractionStart(ev);
+    super.handleInteractionStart(ev)
   }
 
 
   // Called when the actual drag has started
   handleDragStart(ev) {
-    var hit;
+    let hit
 
-    super.handleDragStart(ev);
+    super.handleDragStart(ev)
 
     // might be different from this.origHit if the min-distance is large
-    hit = this.queryHit(getEvX(ev), getEvY(ev));
+    hit = this.queryHit(getEvX(ev), getEvY(ev))
 
     // report the initial hit the mouse is over
     // especially important if no min-distance and drag starts immediately
     if (hit) {
-      this.handleHitOver(hit);
+      this.handleHitOver(hit)
     }
   }
 
 
   // Called when the drag moves
   handleDrag(dx, dy, ev) {
-    var hit;
+    let hit
 
-    super.handleDrag(dx, dy, ev);
+    super.handleDrag(dx, dy, ev)
 
-    hit = this.queryHit(getEvX(ev), getEvY(ev));
+    hit = this.queryHit(getEvX(ev), getEvY(ev))
 
     if (!isHitsEqual(hit, this.hit)) { // a different hit than before?
       if (this.hit) {
-        this.handleHitOut();
+        this.handleHitOut()
       }
       if (hit) {
-        this.handleHitOver(hit);
+        this.handleHitOver(hit)
       }
     }
   }
@@ -118,27 +117,27 @@ export default class HitDragListener extends DragListener {
 
   // Called when dragging has been stopped
   handleDragEnd(ev) {
-    this.handleHitDone();
-    super.handleDragEnd(ev);
+    this.handleHitDone()
+    super.handleDragEnd(ev)
   }
 
 
   // Called when a the mouse has just moved over a new hit
   handleHitOver(hit) {
-    var isOrig = isHitsEqual(hit, this.origHit);
+    let isOrig = isHitsEqual(hit, this.origHit)
 
-    this.hit = hit;
+    this.hit = hit
 
-    this.trigger('hitOver', this.hit, isOrig, this.origHit);
+    this.trigger('hitOver', this.hit, isOrig, this.origHit)
   }
 
 
   // Called when the mouse has just moved out of a hit
   handleHitOut() {
     if (this.hit) {
-      this.trigger('hitOut', this.hit);
-      this.handleHitDone();
-      this.hit = null;
+      this.trigger('hitOut', this.hit)
+      this.handleHitDone()
+      this.hit = null
     }
   }
 
@@ -146,31 +145,31 @@ export default class HitDragListener extends DragListener {
   // Called after a hitOut. Also called before a dragStop
   handleHitDone() {
     if (this.hit) {
-      this.trigger('hitDone', this.hit);
+      this.trigger('hitDone', this.hit)
     }
   }
 
 
   // Called when the interaction ends, whether there was a real drag or not
   handleInteractionEnd(ev, isCancelled) {
-    super.handleInteractionEnd(ev, isCancelled);
+    super.handleInteractionEnd(ev, isCancelled)
 
-    this.origHit = null;
-    this.hit = null;
+    this.origHit = null
+    this.hit = null
 
-    this.component.hitsNotNeeded();
+    this.component.hitsNotNeeded()
   }
 
 
   // Called when scrolling has stopped, whether through auto scroll, or the user scrolling
   handleScrollEnd() {
-    super.handleScrollEnd();
+    super.handleScrollEnd()
 
     // hits' absolute positions will be in new places after a user's scroll.
     // HACK for recomputing.
     if (this.isDragging) {
-      this.component.releaseHits();
-      this.component.prepareHits();
+      this.component.releaseHits()
+      this.component.prepareHits()
     }
   }
 
@@ -179,11 +178,11 @@ export default class HitDragListener extends DragListener {
   queryHit(left, top) {
 
     if (this.coordAdjust) {
-      left += this.coordAdjust.left;
-      top += this.coordAdjust.top;
+      left += this.coordAdjust.left
+      top += this.coordAdjust.top
     }
 
-    return this.component.queryHit(left, top);
+    return this.component.queryHit(left, top)
   }
 
 }
@@ -194,27 +193,27 @@ export default class HitDragListener extends DragListener {
 function isHitsEqual(hit0, hit1) {
 
   if (!hit0 && !hit1) {
-    return true;
+    return true
   }
 
   if (hit0 && hit1) {
     return hit0.component === hit1.component &&
       isHitPropsWithin(hit0, hit1) &&
-      isHitPropsWithin(hit1, hit0); // ensures all props are identical
+      isHitPropsWithin(hit1, hit0) // ensures all props are identical
   }
 
-  return false;
+  return false
 }
 
 
 // Returns true if all of subHit's non-standard properties are within superHit
 function isHitPropsWithin(subHit, superHit) {
-  for (var propName in subHit) {
+  for (let propName in subHit) {
     if (!/^(component|left|right|top|bottom)$/.test(propName)) {
       if (subHit[propName] !== superHit[propName]) {
-        return false;
+        return false
       }
     }
   }
-  return true;
+  return true
 }

+ 5 - 5
src/common/Iterator.ts

@@ -4,18 +4,18 @@ export default class Iterator {
   items: any
 
   constructor(items) {
-    this.items = items || [];
+    this.items = items || []
   }
 
   /* Calls a method on every item passing the arguments through */
   proxyCall(methodName, ...args) {
-    var results = [];
+    let results = []
 
     this.items.forEach(function(item) {
-      results.push(item[methodName].apply(item, args));
-    });
+      results.push(item[methodName].apply(item, args))
+    })
 
-    return results;
+    return results
   }
 
 }

+ 8 - 9
src/common/ListenerMixin.ts

@@ -19,7 +19,7 @@ export interface ListenerInterface {
   stopListeningTo(other, eventName?)
 }
 
-let guid = 0;
+let guid = 0
 
 export default class ListenerMixin extends Mixin implements ListenerInterface {
 
@@ -38,19 +38,18 @@ export default class ListenerMixin extends Mixin implements ListenerInterface {
   */
   listenTo(other, arg, callback?) {
     if (typeof arg === 'object') { // given dictionary of callbacks
-      for (var eventName in arg) {
+      for (let eventName in arg) {
         if (arg.hasOwnProperty(eventName)) {
-          this.listenTo(other, eventName, arg[eventName]);
+          this.listenTo(other, eventName, arg[eventName])
         }
       }
-    }
-    else if (typeof arg === 'string') {
+    } else if (typeof arg === 'string') {
       other.on(
         arg + '.' + this.getListenerNamespace(), // use event namespacing to identify this object
         $.proxy(callback, this) // always use `this` context
           // the usually-undesired jQuery guid behavior doesn't matter,
           // because we always unbind via namespace
-      );
+      )
     }
   }
 
@@ -59,7 +58,7 @@ export default class ListenerMixin extends Mixin implements ListenerInterface {
   `eventName` is optional. If omitted, will stop listening to ALL events on `other`.
   */
   stopListeningTo(other, eventName?) {
-    other.off((eventName || '') + '.' + this.getListenerNamespace());
+    other.off((eventName || '') + '.' + this.getListenerNamespace())
   }
 
   /*
@@ -67,9 +66,9 @@ export default class ListenerMixin extends Mixin implements ListenerInterface {
   */
   getListenerNamespace() {
     if (this.listenerId == null) {
-      this.listenerId = guid++;
+      this.listenerId = guid++
     }
-    return '_listener' + this.listenerId;
+    return '_listener' + this.listenerId
   }
 
 }

+ 4 - 4
src/common/Mixin.ts

@@ -4,9 +4,9 @@ export default class Mixin {
   static mixInto(destClass) {
     Object.getOwnPropertyNames(this.prototype).forEach((name) => { // copy methods
       if (!destClass.prototype[name]) { // if destination class doesn't already define it
-        destClass.prototype[name] = this.prototype[name];
+        destClass.prototype[name] = this.prototype[name]
       }
-    });
+    })
   }
 
   /*
@@ -15,8 +15,8 @@ export default class Mixin {
   */
   static mixOver(destClass) {
     Object.getOwnPropertyNames(this.prototype).forEach((name) => { // copy methods
-      destClass.prototype[name] = this.prototype[name];
-    });
+      destClass.prototype[name] = this.prototype[name]
+    })
   }
 
 }

+ 108 - 114
src/common/Model.ts

@@ -20,10 +20,10 @@ export default class Model extends Class {
 
   constructor() {
     super()
-    this._watchers = {};
-    this._props = {};
-    this.applyGlobalWatchers();
-    this.constructed();
+    this._watchers = {}
+    this._props = {}
+    this.applyGlobalWatchers()
+    this.constructed()
   }
 
   // useful for monkeypatching. TODO: BaseClass?
@@ -31,82 +31,80 @@ export default class Model extends Class {
   }
 
   applyGlobalWatchers() {
-    var map = this._globalWatchArgs;
-    var name;
+    let map = this._globalWatchArgs
+    let name
 
     for (name in map) {
-      this.watch.apply(this, [ name ].concat(map[name]));
+      this.watch.apply(this, [ name ].concat(map[name]))
     }
   }
 
   has(name) {
-    return name in this._props;
+    return name in this._props
   }
 
   get(name) {
     if (name === undefined) {
-      return this._props;
+      return this._props
     }
 
-    return this._props[name];
+    return this._props[name]
   }
 
   set(name, val) {
-    var newProps;
+    let newProps
 
     if (typeof name === 'string') {
-      newProps = {};
-      newProps[name] = val === undefined ? null : val;
-    }
-    else {
-      newProps = name;
+      newProps = {}
+      newProps[name] = val === undefined ? null : val
+    } else {
+      newProps = name
     }
 
-    this.setProps(newProps);
+    this.setProps(newProps)
   }
 
   reset(newProps) {
-    var oldProps = this._props;
-    var changeset = {}; // will have undefined's to signal unsets
-    var name;
+    let oldProps = this._props
+    let changeset = {} // will have undefined's to signal unsets
+    let name
 
     for (name in oldProps) {
-      changeset[name] = undefined;
+      changeset[name] = undefined
     }
 
     for (name in newProps) {
-      changeset[name] = newProps[name];
+      changeset[name] = newProps[name]
     }
 
-    this.setProps(changeset);
+    this.setProps(changeset)
   }
 
   unset(name) { // accepts a string or array of strings
-    var newProps = {};
-    var names;
-    var i;
+    let newProps = {}
+    let names
+    let i
 
     if (typeof name === 'string') {
-      names = [ name ];
-    }
-    else {
-      names = name;
+      names = [ name ]
+    } else {
+      names = name
     }
 
     for (i = 0; i < names.length; i++) {
-      newProps[names[i]] = undefined;
+      newProps[names[i]] = undefined
     }
 
-    this.setProps(newProps);
+    this.setProps(newProps)
   }
 
   setProps(newProps) {
-    var changedProps = {};
-    var changedCnt = 0;
-    var name, val;
+    let changedProps = {}
+    let changedCnt = 0
+    let name, val
 
     for (name in newProps) {
-      val = newProps[name];
+      val = newProps[name]
 
       // a change in value?
       // if an object, don't check equality, because might have been mutated internally.
@@ -115,88 +113,86 @@ export default class Model extends Class {
         typeof val === 'object' ||
         val !== this._props[name]
       ) {
-        changedProps[name] = val;
-        changedCnt++;
+        changedProps[name] = val
+        changedCnt++
       }
     }
 
     if (changedCnt) {
 
-      this.trigger('before:batchChange', changedProps);
+      this.trigger('before:batchChange', changedProps)
 
       for (name in changedProps) {
-        val = changedProps[name];
+        val = changedProps[name]
 
-        this.trigger('before:change', name, val);
-        this.trigger('before:change:' + name, val);
+        this.trigger('before:change', name, val)
+        this.trigger('before:change:' + name, val)
       }
 
       for (name in changedProps) {
-        val = changedProps[name];
+        val = changedProps[name]
 
         if (val === undefined) {
-          delete this._props[name];
-        }
-        else {
-          this._props[name] = val;
+          delete this._props[name]
+        } else {
+          this._props[name] = val
         }
 
-        this.trigger('change:' + name, val);
-        this.trigger('change', name, val);
+        this.trigger('change:' + name, val)
+        this.trigger('change', name, val)
       }
 
-      this.trigger('batchChange', changedProps);
+      this.trigger('batchChange', changedProps)
     }
   }
 
   watch(name, depList, startFunc, stopFunc) {
-    this.unwatch(name);
+    this.unwatch(name)
 
     this._watchers[name] = this._watchDeps(depList, (deps) => {
-      var res = startFunc.call(this, deps);
+      let res = startFunc.call(this, deps)
 
       if (res && res.then) {
-        this.unset(name); // put in an unset state while resolving
+        this.unset(name) // put in an unset state while resolving
         res.then((val) => {
-          this.set(name, val);
-        });
-      }
-      else {
-        this.set(name, res);
+          this.set(name, val)
+        })
+      } else {
+        this.set(name, res)
       }
     }, (deps) => {
-      this.unset(name);
+      this.unset(name)
 
       if (stopFunc) {
-        stopFunc.call(this, deps);
+        stopFunc.call(this, deps)
       }
-    });
+    })
   }
 
   unwatch(name) {
-    var watcher = this._watchers[name];
+    let watcher = this._watchers[name]
 
     if (watcher) {
-      delete this._watchers[name];
-      watcher.teardown();
+      delete this._watchers[name]
+      watcher.teardown()
     }
   }
 
   _watchDeps(depList, startFunc, stopFunc) {
-    var queuedChangeCnt = 0;
-    var depCnt = depList.length;
-    var satisfyCnt = 0;
-    var values = {}; // what's passed as the `deps` arguments
-    var bindTuples = []; // array of [ eventName, handlerFunc ] arrays
-    var isCallingStop = false;
+    let queuedChangeCnt = 0
+    let depCnt = depList.length
+    let satisfyCnt = 0
+    let values = {} // what's passed as the `deps` arguments
+    let bindTuples = [] // array of [ eventName, handlerFunc ] arrays
+    let isCallingStop = false
 
     const onBeforeDepChange = (depName, val, isOptional) => {
-      queuedChangeCnt++;
+      queuedChangeCnt++
       if (queuedChangeCnt === 1) { // first change to cause a "stop" ?
         if (satisfyCnt === depCnt) { // all deps previously satisfied?
-          isCallingStop = true;
-          stopFunc(values);
-          isCallingStop = false;
+          isCallingStop = true
+          stopFunc(values)
+          isCallingStop = false
         }
       }
     }
@@ -207,22 +203,21 @@ export default class Model extends Class {
 
         // required dependency that was previously set?
         if (!isOptional && values[depName] !== undefined) {
-          satisfyCnt--;
+          satisfyCnt--
         }
 
-        delete values[depName];
-      }
-      else { // setting a value?
+        delete values[depName]
+      } else { // setting a value?
 
         // required dependency that was previously unset?
         if (!isOptional && values[depName] === undefined) {
-          satisfyCnt++;
+          satisfyCnt++
         }
 
-        values[depName] = val;
+        values[depName] = val
       }
 
-      queuedChangeCnt--;
+      queuedChangeCnt--
       if (!queuedChangeCnt) { // last change to cause a "start"?
 
         // now finally satisfied or satisfied all along?
@@ -231,7 +226,7 @@ export default class Model extends Class {
           // if the stopFunc initiated another value change, ignore it.
           // it will be processed by another change event anyway.
           if (!isCallingStop) {
-            startFunc(values);
+            startFunc(values)
           }
         }
       }
@@ -239,78 +234,77 @@ export default class Model extends Class {
 
     // intercept for .on() that remembers handlers
     const bind = (eventName, handler) => {
-      this.on(eventName, handler);
-      bindTuples.push([ eventName, handler ]);
+      this.on(eventName, handler)
+      bindTuples.push([ eventName, handler ])
     }
 
     // listen to dependency changes
     depList.forEach((depName) => {
-      var isOptional = false;
+      let isOptional = false
 
       if (depName.charAt(0) === '?') { // TODO: more DRY
-        depName = depName.substring(1);
-        isOptional = true;
+        depName = depName.substring(1)
+        isOptional = true
       }
 
       bind('before:change:' + depName, function(val) {
-        onBeforeDepChange(depName, val, isOptional);
-      });
+        onBeforeDepChange(depName, val, isOptional)
+      })
 
       bind('change:' + depName, function(val) {
-        onDepChange(depName, val, isOptional);
-      });
-    });
+        onDepChange(depName, val, isOptional)
+      })
+    })
 
     // process current dependency values
     depList.forEach((depName) => {
-      var isOptional = false;
+      let isOptional = false
 
       if (depName.charAt(0) === '?') { // TODO: more DRY
-        depName = depName.substring(1);
-        isOptional = true;
+        depName = depName.substring(1)
+        isOptional = true
       }
 
       if (this.has(depName)) {
-        values[depName] = this.get(depName);
-        satisfyCnt++;
-      }
-      else if (isOptional) {
-        satisfyCnt++;
+        values[depName] = this.get(depName)
+        satisfyCnt++
+      } else if (isOptional) {
+        satisfyCnt++
       }
-    });
+    })
 
     // initially satisfied
     if (satisfyCnt === depCnt) {
-      startFunc(values);
+      startFunc(values)
     }
 
     return {
       teardown: () => {
         // remove all handlers
-        for (var i = 0; i < bindTuples.length; i++) {
-          this.off(bindTuples[i][0], bindTuples[i][1]);
+        for (let i = 0; i < bindTuples.length; i++) {
+          this.off(bindTuples[i][0], bindTuples[i][1])
         }
-        bindTuples = null;
+        bindTuples = null
 
         // was satisfied, so call stopFunc
         if (satisfyCnt === depCnt) {
-          stopFunc();
+          stopFunc()
         }
       },
       flash: () => {
         if (satisfyCnt === depCnt) {
-          stopFunc();
-          startFunc(values);
+          stopFunc()
+          startFunc(values)
         }
       }
-    };
+    }
   }
 
   flash(name) {
-    var watcher = this._watchers[name];
+    let watcher = this._watchers[name]
 
     if (watcher) {
-      watcher.flash();
+      watcher.flash()
     }
   }
 
@@ -319,14 +313,14 @@ export default class Model extends Class {
     // subclasses should make a masked-copy of the superclass's map
     // TODO: write test
     if (!this.prototype.hasOwnProperty('_globalWatchArgs')) {
-      this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs);
+      this.prototype._globalWatchArgs = Object.create(this.prototype._globalWatchArgs)
     }
 
-    this.prototype._globalWatchArgs[name] = args;
+    this.prototype._globalWatchArgs[name] = args
   }
 }
 
-Model.prototype._globalWatchArgs = {}; // mutation protection in Model.watch
+Model.prototype._globalWatchArgs = {} // mutation protection in Model.watch
 
 EmitterMixin.mixInto(Model)
 ListenerMixin.mixInto(Model)

+ 46 - 48
src/common/MouseFollower.ts

@@ -38,31 +38,30 @@ export default class MouseFollower {
 
 
   constructor(sourceEl, options) {
-    this.options = options = options || {};
-    this.sourceEl = sourceEl;
-    this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent(); // default to sourceEl's parent
+    this.options = options = options || {}
+    this.sourceEl = sourceEl
+    this.parentEl = options.parentEl ? $(options.parentEl) : sourceEl.parent() // default to sourceEl's parent
   }
 
 
   // Causes the element to start following the mouse
   start(ev) {
     if (!this.isFollowing) {
-      this.isFollowing = true;
+      this.isFollowing = true
 
-      this.y0 = getEvY(ev);
-      this.x0 = getEvX(ev);
-      this.topDelta = 0;
-      this.leftDelta = 0;
+      this.y0 = getEvY(ev)
+      this.x0 = getEvX(ev)
+      this.topDelta = 0
+      this.leftDelta = 0
 
       if (!this.isHidden) {
-        this.updatePosition();
+        this.updatePosition()
       }
 
       if (getEvIsTouch(ev)) {
-        this.listenTo($(document), 'touchmove', this.handleMove);
-      }
-      else {
-        this.listenTo($(document), 'mousemove', this.handleMove);
+        this.listenTo($(document), 'touchmove', this.handleMove)
+      } else {
+        this.listenTo($(document), 'mousemove', this.handleMove)
       }
     }
   }
@@ -71,36 +70,35 @@ export default class MouseFollower {
   // Causes the element to stop following the mouse. If shouldRevert is true, will animate back to original position.
   // `callback` gets invoked when the animation is complete. If no animation, it is invoked immediately.
   stop(shouldRevert, callback) {
-    var revertDuration = this.options.revertDuration;
+    let revertDuration = this.options.revertDuration
 
     const complete = () => { // might be called by .animate(), which might change `this` context
-      this.isAnimating = false;
-      this.removeElement();
+      this.isAnimating = false
+      this.removeElement()
 
-      this.top0 = this.left0 = null; // reset state for future updatePosition calls
+      this.top0 = this.left0 = null // reset state for future updatePosition calls
 
       if (callback) {
-        callback();
+        callback()
       }
     }
 
     if (this.isFollowing && !this.isAnimating) { // disallow more than one stop animation at a time
-      this.isFollowing = false;
+      this.isFollowing = false
 
-      this.stopListeningTo($(document));
+      this.stopListeningTo($(document))
 
       if (shouldRevert && revertDuration && !this.isHidden) { // do a revert animation?
-        this.isAnimating = true;
+        this.isAnimating = true
         this.el.animate({
           top: this.top0,
           left: this.left0
         }, {
           duration: revertDuration,
           complete: complete
-        });
-      }
-      else {
-        complete();
+        })
+      } else {
+        complete()
       }
     }
   }
@@ -108,7 +106,7 @@ export default class MouseFollower {
 
   // Gets the tracking element. Create it if necessary
   getEl() {
-    var el = this.el;
+    let el = this.el
 
     if (!el) {
       el = this.el = this.sourceEl.clone()
@@ -124,57 +122,57 @@ export default class MouseFollower {
           height: this.sourceEl.height(), // explicit width in case there was a 'bottom' value
           opacity: this.options.opacity || '',
           zIndex: this.options.zIndex
-        });
+        })
 
       // we don't want long taps or any mouse interaction causing selection/menus.
       // would use preventSelection(), but that prevents selectstart, causing problems.
-      el.addClass('fc-unselectable');
+      el.addClass('fc-unselectable')
 
-      el.appendTo(this.parentEl);
+      el.appendTo(this.parentEl)
     }
 
-    return el;
+    return el
   }
 
 
   // Removes the tracking element if it has already been created
   removeElement() {
     if (this.el) {
-      this.el.remove();
-      this.el = null;
+      this.el.remove()
+      this.el = null
     }
   }
 
 
   // Update the CSS position of the tracking element
   updatePosition() {
-    var sourceOffset;
-    var origin;
+    let sourceOffset
+    let origin
 
-    this.getEl(); // ensure this.el
+    this.getEl() // ensure this.el
 
     // make sure origin info was computed
     if (this.top0 == null) {
-      sourceOffset = this.sourceEl.offset();
-      origin = this.el.offsetParent().offset();
-      this.top0 = sourceOffset.top - origin.top;
-      this.left0 = sourceOffset.left - origin.left;
+      sourceOffset = this.sourceEl.offset()
+      origin = this.el.offsetParent().offset()
+      this.top0 = sourceOffset.top - origin.top
+      this.left0 = sourceOffset.left - origin.left
     }
 
     this.el.css({
       top: this.top0 + this.topDelta,
       left: this.left0 + this.leftDelta
-    });
+    })
   }
 
 
   // Gets called when the user moves the mouse
   handleMove(ev) {
-    this.topDelta = getEvY(ev) - this.y0;
-    this.leftDelta = getEvX(ev) - this.x0;
+    this.topDelta = getEvY(ev) - this.y0
+    this.leftDelta = getEvX(ev) - this.x0
 
     if (!this.isHidden) {
-      this.updatePosition();
+      this.updatePosition()
     }
   }
 
@@ -182,9 +180,9 @@ export default class MouseFollower {
   // Temporarily makes the tracking element invisible. Can be called before following starts
   hide() {
     if (!this.isHidden) {
-      this.isHidden = true;
+      this.isHidden = true
       if (this.el) {
-        this.el.hide();
+        this.el.hide()
       }
     }
   }
@@ -193,9 +191,9 @@ export default class MouseFollower {
   // Show the tracking element after it has been temporarily hidden
   show() {
     if (this.isHidden) {
-      this.isHidden = false;
-      this.updatePosition();
-      this.getEl().show();
+      this.isHidden = false
+      this.updatePosition()
+      this.getEl().show()
     }
   }
 

+ 19 - 21
src/common/ParsableModelMixin.ts

@@ -31,26 +31,24 @@ export default class ParsableModelMixin extends Mixin implements ParsableModelIn
   Meant to be only called ONCE, at object creation.
   */
   applyProps(rawProps) {
-    var standardPropMap = this.standardPropMap;
-    var manualProps = {};
-    var miscProps = {};
-    var propName;
+    let standardPropMap = this.standardPropMap
+    let manualProps = {}
+    let miscProps = {}
+    let propName
 
     for (propName in rawProps) {
       if (standardPropMap[propName] === true) { // copy verbatim
-        this[propName] = rawProps[propName];
-      }
-      else if (standardPropMap[propName] === false) {
-        manualProps[propName] = rawProps[propName];
-      }
-      else {
-        miscProps[propName] = rawProps[propName];
+        this[propName] = rawProps[propName]
+      } else if (standardPropMap[propName] === false) {
+        manualProps[propName] = rawProps[propName]
+      } else {
+        miscProps[propName] = rawProps[propName]
       }
     }
 
-    this.applyMiscProps(miscProps);
+    this.applyMiscProps(miscProps)
 
-    return this.applyManualStandardProps(manualProps);
+    return this.applyManualStandardProps(manualProps)
   }
 
 
@@ -59,7 +57,7 @@ export default class ParsableModelMixin extends Mixin implements ParsableModelIn
   Meant to be only called ONCE, at object creation.
   */
   applyManualStandardProps(rawProps) {
-    return true;
+    return true
   }
 
 
@@ -75,31 +73,31 @@ export default class ParsableModelMixin extends Mixin implements ParsableModelIn
   TODO: why is this a method when defineStandardProps is static
   */
   isStandardProp(propName) {
-    return propName in this.standardPropMap;
+    return propName in this.standardPropMap
   }
 
 
   static defineStandardProps(propDefs) {
-    var proto = this.prototype;
+    let proto = this.prototype
 
     if (!proto.hasOwnProperty('standardPropMap')) {
-      proto.standardPropMap = Object.create(proto.standardPropMap);
+      proto.standardPropMap = Object.create(proto.standardPropMap)
     }
 
-    copyOwnProps(propDefs, proto.standardPropMap);
+    copyOwnProps(propDefs, proto.standardPropMap)
   }
 
 
   static copyVerbatimStandardProps(src, dest) {
-    var map = this.prototype.standardPropMap;
-    var propName;
+    let map = this.prototype.standardPropMap
+    let propName
 
     for (propName in map) {
       if (
         src[propName] != null && // in the src object?
         map[propName] === true // false means "copy verbatim"
       ) {
-        dest[propName] = src[propName];
+        dest[propName] = src[propName]
       }
     }
   }

+ 51 - 54
src/common/Popover.ts

@@ -30,7 +30,7 @@ export default class Popover {
 
 
   constructor(options) {
-    this.options = options || {};
+    this.options = options || {}
   }
 
 
@@ -38,12 +38,12 @@ export default class Popover {
   show() {
     if (this.isHidden) {
       if (!this.el) {
-        this.render();
+        this.render()
       }
-      this.el.show();
-      this.position();
-      this.isHidden = false;
-      this.trigger('show');
+      this.el.show()
+      this.position()
+      this.isHidden = false
+      this.trigger('show')
     }
   }
 
@@ -51,16 +51,16 @@ export default class Popover {
   // Hides the popover, through CSS, but does not remove it from the DOM
   hide() {
     if (!this.isHidden) {
-      this.el.hide();
-      this.isHidden = true;
-      this.trigger('hide');
+      this.el.hide()
+      this.isHidden = true
+      this.trigger('hide')
     }
   }
 
 
   // Creates `this.el` and renders content inside of it
   render() {
-    var options = this.options;
+    let options = this.options
 
     this.el = $('<div class="fc-popover"/>')
       .addClass(options.className || '')
@@ -70,15 +70,15 @@ export default class Popover {
         left: 0
       })
       .append(options.content)
-      .appendTo(options.parentEl);
+      .appendTo(options.parentEl)
 
     // when a click happens on anything inside with a 'fc-close' className, hide the popover
     this.el.on('click', '.fc-close', () => {
-      this.hide();
-    });
+      this.hide()
+    })
 
     if (options.autoHide) {
-      this.listenTo($(document), 'mousedown', this.documentMousedown);
+      this.listenTo($(document), 'mousedown', this.documentMousedown)
     }
   }
 
@@ -87,77 +87,74 @@ export default class Popover {
   documentMousedown(ev) {
     // only hide the popover if the click happened outside the popover
     if (this.el && !$(ev.target).closest(this.el).length) {
-      this.hide();
+      this.hide()
     }
   }
 
 
   // Hides and unregisters any handlers
   removeElement() {
-    this.hide();
+    this.hide()
 
     if (this.el) {
-      this.el.remove();
-      this.el = null;
+      this.el.remove()
+      this.el = null
     }
 
-    this.stopListeningTo($(document), 'mousedown');
+    this.stopListeningTo($(document), 'mousedown')
   }
 
 
   // Positions the popover optimally, using the top/left/right options
   position() {
-    var options = this.options;
-    var origin = this.el.offsetParent().offset();
-    var width = this.el.outerWidth();
-    var height = this.el.outerHeight();
-    var windowEl = $(window);
-    var viewportEl = getScrollParent(this.el);
-    var viewportTop;
-    var viewportLeft;
-    var viewportOffset;
-    var top; // the "position" (not "offset") values for the popover
-    var left; //
+    let options = this.options
+    let origin = this.el.offsetParent().offset()
+    let width = this.el.outerWidth()
+    let height = this.el.outerHeight()
+    let windowEl = $(window)
+    let viewportEl = getScrollParent(this.el)
+    let viewportTop
+    let viewportLeft
+    let viewportOffset
+    let top // the "position" (not "offset") values for the popover
+    let left //
 
     // compute top and left
-    top = options.top || 0;
+    top = options.top || 0
     if (options.left !== undefined) {
-      left = options.left;
-    }
-    else if (options.right !== undefined) {
-      left = options.right - width; // derive the left value from the right value
-    }
-    else {
-      left = 0;
+      left = options.left
+    } else if (options.right !== undefined) {
+      left = options.right - width // derive the left value from the right value
+    } else {
+      left = 0
     }
 
     if (viewportEl.is(window) || viewportEl.is(document)) { // normalize getScrollParent's result
-      viewportEl = windowEl;
-      viewportTop = 0; // the window is always at the top left
-      viewportLeft = 0; // (and .offset() won't work if called here)
-    }
-    else {
-      viewportOffset = viewportEl.offset();
-      viewportTop = viewportOffset.top;
-      viewportLeft = viewportOffset.left;
+      viewportEl = windowEl
+      viewportTop = 0 // the window is always at the top left
+      viewportLeft = 0 // (and .offset() won't work if called here)
+    } else {
+      viewportOffset = viewportEl.offset()
+      viewportTop = viewportOffset.top
+      viewportLeft = viewportOffset.left
     }
 
     // if the window is scrolled, it causes the visible area to be further down
-    viewportTop += windowEl.scrollTop();
-    viewportLeft += windowEl.scrollLeft();
+    viewportTop += windowEl.scrollTop()
+    viewportLeft += windowEl.scrollLeft()
 
     // constrain to the view port. if constrained by two edges, give precedence to top/left
     if (options.viewportConstrain !== false) {
-      top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin);
-      top = Math.max(top, viewportTop + this.margin);
-      left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin);
-      left = Math.max(left, viewportLeft + this.margin);
+      top = Math.min(top, viewportTop + viewportEl.outerHeight() - height - this.margin)
+      top = Math.max(top, viewportTop + this.margin)
+      left = Math.min(left, viewportLeft + viewportEl.outerWidth() - width - this.margin)
+      left = Math.max(left, viewportLeft + this.margin)
     }
 
     this.el.css({
       top: top - origin.top,
       left: left - origin.left
-    });
+    })
   }
 
 
@@ -166,7 +163,7 @@ export default class Popover {
   // TODO: better code reuse for this. Repeat code
   trigger(name) {
     if (this.options[name]) {
-      this.options[name].apply(this, Array.prototype.slice.call(arguments, 1));
+      this.options[name].apply(this, Array.prototype.slice.call(arguments, 1))
     }
   }
 

+ 22 - 22
src/common/Promise.ts

@@ -4,41 +4,41 @@ import * as $ from 'jquery'
 const PromiseStub = {
 
   construct: function(executor) {
-    var deferred = $.Deferred();
-    var promise = deferred.promise();
+    let deferred = $.Deferred()
+    let promise = deferred.promise()
 
     if (typeof executor === 'function') {
       executor(
         function(val) { // resolve
-          deferred.resolve(val);
-          attachImmediatelyResolvingThen(promise, val);
+          deferred.resolve(val)
+          attachImmediatelyResolvingThen(promise, val)
         },
         function() { // reject
-          deferred.reject();
-          attachImmediatelyRejectingThen(promise);
+          deferred.reject()
+          attachImmediatelyRejectingThen(promise)
         }
-      );
+      )
     }
 
-    return promise;
+    return promise
   },
 
   resolve: function(val) {
-    var deferred = $.Deferred().resolve(val);
-    var promise = deferred.promise();
+    let deferred = $.Deferred().resolve(val)
+    let promise = deferred.promise()
 
-    attachImmediatelyResolvingThen(promise, val);
+    attachImmediatelyResolvingThen(promise, val)
 
-    return promise;
+    return promise
   },
 
   reject: function() {
-    var deferred = $.Deferred().reject();
-    var promise = deferred.promise();
+    let deferred = $.Deferred().reject()
+    let promise = deferred.promise()
 
-    attachImmediatelyRejectingThen(promise);
+    attachImmediatelyRejectingThen(promise)
 
-    return promise;
+    return promise
   }
 
 }
@@ -49,18 +49,18 @@ export default PromiseStub
 function attachImmediatelyResolvingThen(promise, val) {
   promise.then = function(onResolve) {
     if (typeof onResolve === 'function') {
-      return PromiseStub.resolve(onResolve(val));
+      return PromiseStub.resolve(onResolve(val))
     }
-    return promise;
-  };
+    return promise
+  }
 }
 
 
 function attachImmediatelyRejectingThen(promise) {
   promise.then = function(onResolve, onReject) {
     if (typeof onReject === 'function') {
-      onReject();
+      onReject()
     }
-    return promise;
-  };
+    return promise
+  }
 }

+ 36 - 38
src/common/RenderQueue.ts

@@ -10,76 +10,74 @@ export default class RenderQueue extends TaskQueue {
 
   constructor(waitsByNamespace) {
     super()
-    this.waitsByNamespace = waitsByNamespace || {};
+    this.waitsByNamespace = waitsByNamespace || {}
   }
 
 
   queue(taskFunc, namespace, type) {
-    var task = {
+    let task = {
       func: taskFunc,
       namespace: namespace,
       type: type
-    };
-    var waitMs;
+    }
+    let waitMs
 
     if (namespace) {
-      waitMs = this.waitsByNamespace[namespace];
+      waitMs = this.waitsByNamespace[namespace]
     }
 
     if (this.waitNamespace) {
       if (namespace === this.waitNamespace && waitMs != null) {
-        this.delayWait(waitMs);
-      }
-      else {
-        this.clearWait();
-        this.tryStart();
+        this.delayWait(waitMs)
+      } else {
+        this.clearWait()
+        this.tryStart()
       }
     }
 
     if (this.compoundTask(task)) { // appended to queue?
 
       if (!this.waitNamespace && waitMs != null) {
-        this.startWait(namespace, waitMs);
-      }
-      else {
-        this.tryStart();
+        this.startWait(namespace, waitMs)
+      } else {
+        this.tryStart()
       }
     }
   }
 
 
   startWait(namespace, waitMs) {
-    this.waitNamespace = namespace;
-    this.spawnWait(waitMs);
+    this.waitNamespace = namespace
+    this.spawnWait(waitMs)
   }
 
 
   delayWait(waitMs) {
-    clearTimeout(this.waitId);
-    this.spawnWait(waitMs);
+    clearTimeout(this.waitId)
+    this.spawnWait(waitMs)
   }
 
 
   spawnWait(waitMs) {
     this.waitId = setTimeout(() => {
-      this.waitNamespace = null;
-      this.tryStart();
-    }, waitMs);
+      this.waitNamespace = null
+      this.tryStart()
+    }, waitMs)
   }
 
 
   clearWait() {
     if (this.waitNamespace) {
-      clearTimeout(this.waitId);
-      this.waitId = null;
-      this.waitNamespace = null;
+      clearTimeout(this.waitId)
+      this.waitId = null
+      this.waitNamespace = null
     }
   }
 
 
   canRunNext() {
     if (!super.canRunNext()) {
-      return false;
+      return false
     }
 
     // waiting for a certain namespace to stop receiving tasks?
@@ -88,52 +86,52 @@ export default class RenderQueue extends TaskQueue {
       // if there was a different namespace task in the meantime,
       // that forces all previously-waiting tasks to suddenly execute.
       // TODO: find a way to do this in constant time.
-      for (var q = this.q, i = 0; i < q.length; i++) {
+      for (let q = this.q, i = 0; i < q.length; i++) {
         if (q[i].namespace !== this.waitNamespace) {
-          return true; // allow execution
+          return true // allow execution
         }
       }
 
-      return false;
+      return false
     }
 
-    return true;
+    return true
   }
 
 
   runTask(task) {
-    task.func();
+    task.func()
   }
 
 
   compoundTask(newTask) {
-    var q = this.q;
-    var shouldAppend = true;
-    var i, task;
+    let q = this.q
+    let shouldAppend = true
+    let i, task
 
     if (newTask.namespace && newTask.type === 'destroy') {
 
       // remove all init/add/remove ops with same namespace, regardless of order
       for (i = q.length - 1; i >= 0; i--) {
-        task = q[i];
+        task = q[i]
 
         switch (task.type) {
           case 'init':
-            shouldAppend = false;
+            shouldAppend = false
             // the latest destroy is cancelled out by not doing the init
             // and fallthrough....
           case 'add':
           case 'remove':
-            q.splice(i, 1); // remove task
+            q.splice(i, 1) // remove task
         }
       }
     }
 
     if (shouldAppend) {
-      q.push(newTask);
+      q.push(newTask)
     }
 
-    return shouldAppend;
+    return shouldAppend
   }
 
 }

+ 23 - 23
src/common/Scroller.ts

@@ -14,33 +14,33 @@ export default class Scroller extends Class {
 
 
   constructor(options?) {
-    super();
-    options = options || {};
-    this.overflowX = options.overflowX || options.overflow || 'auto';
-    this.overflowY = options.overflowY || options.overflow || 'auto';
+    super()
+    options = options || {}
+    this.overflowX = options.overflowX || options.overflow || 'auto'
+    this.overflowY = options.overflowY || options.overflow || 'auto'
   }
 
 
   render() {
-    this.el = this.renderEl();
-    this.applyOverflow();
+    this.el = this.renderEl()
+    this.applyOverflow()
   }
 
 
   renderEl() {
-    return (this.scrollEl = $('<div class="fc-scroller"></div>'));
+    return (this.scrollEl = $('<div class="fc-scroller"></div>'))
   }
 
 
   // sets to natural height, unlocks overflow
   clear() {
-    this.setHeight('auto');
-    this.applyOverflow();
+    this.setHeight('auto')
+    this.applyOverflow()
   }
 
 
   destroy() {
-    this.el.remove();
+    this.el.remove()
   }
 
 
@@ -52,7 +52,7 @@ export default class Scroller extends Class {
     this.scrollEl.css({
       'overflow-x': this.overflowX,
       'overflow-y': this.overflowY
-    });
+    })
   }
 
 
@@ -60,10 +60,10 @@ export default class Scroller extends Class {
   // Useful for preserving scrollbar widths regardless of future resizes.
   // Can pass in scrollbarWidths for optimization.
   lockOverflow(scrollbarWidths) {
-    var overflowX = this.overflowX;
-    var overflowY = this.overflowY;
+    let overflowX = this.overflowX
+    let overflowY = this.overflowY
 
-    scrollbarWidths = scrollbarWidths || this.getScrollbarWidths();
+    scrollbarWidths = scrollbarWidths || this.getScrollbarWidths()
 
     if (overflowX === 'auto') {
       overflowX = (
@@ -71,7 +71,7 @@ export default class Scroller extends Class {
           // OR scrolling pane with massless scrollbars?
           this.scrollEl[0].scrollWidth - 1 > this.scrollEl[0].clientWidth
             // subtract 1 because of IE off-by-one issue
-        ) ? 'scroll' : 'hidden';
+        ) ? 'scroll' : 'hidden'
     }
 
     if (overflowY === 'auto') {
@@ -80,10 +80,10 @@ export default class Scroller extends Class {
           // OR scrolling pane with massless scrollbars?
           this.scrollEl[0].scrollHeight - 1 > this.scrollEl[0].clientHeight
             // subtract 1 because of IE off-by-one issue
-        ) ? 'scroll' : 'hidden';
+        ) ? 'scroll' : 'hidden'
     }
 
-    this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY });
+    this.scrollEl.css({ 'overflow-x': overflowX, 'overflow-y': overflowY })
   }
 
 
@@ -92,32 +92,32 @@ export default class Scroller extends Class {
 
 
   setHeight(height) {
-    this.scrollEl.height(height);
+    this.scrollEl.height(height)
   }
 
 
   getScrollTop() {
-    return this.scrollEl.scrollTop();
+    return this.scrollEl.scrollTop()
   }
 
 
   setScrollTop(top) {
-    this.scrollEl.scrollTop(top);
+    this.scrollEl.scrollTop(top)
   }
 
 
   getClientWidth() {
-    return this.scrollEl[0].clientWidth;
+    return this.scrollEl[0].clientWidth
   }
 
 
   getClientHeight() {
-    return this.scrollEl[0].clientHeight;
+    return this.scrollEl[0].clientHeight
   }
 
 
   getScrollbarWidths() {
-    return getScrollbarWidths(this.scrollEl);
+    return getScrollbarWidths(this.scrollEl)
   }
 
 }

+ 22 - 22
src/common/TaskQueue.ts

@@ -15,69 +15,69 @@ export default class TaskQueue {
 
 
   queue(...args) {
-    this.q.push.apply(this.q, args); // append
-    this.tryStart();
+    this.q.push.apply(this.q, args) // append
+    this.tryStart()
   }
 
 
   pause() {
-    this.isPaused = true;
+    this.isPaused = true
   }
 
 
   resume() {
-    this.isPaused = false;
-    this.tryStart();
+    this.isPaused = false
+    this.tryStart()
   }
 
 
   getIsIdle() {
-    return !this.isRunning && !this.isPaused;
+    return !this.isRunning && !this.isPaused
   }
 
 
   tryStart() {
     if (!this.isRunning && this.canRunNext()) {
-      this.isRunning = true;
-      this.trigger('start');
-      this.runRemaining();
+      this.isRunning = true
+      this.trigger('start')
+      this.runRemaining()
     }
   }
 
 
   canRunNext() {
-    return !this.isPaused && this.q.length;
+    return !this.isPaused && this.q.length
   }
 
 
   runRemaining() { // assumes at least one task in queue. does not check canRunNext for first task.
-    var task;
-    var res;
+    let task
+    let res
 
     do {
-      task = this.q.shift(); // always freshly reference q. might have been reassigned.
-      res = this.runTask(task);
+      task = this.q.shift() // always freshly reference q. might have been reassigned.
+      res = this.runTask(task)
 
       if (res && res.then) {
         res.then(() => {
           if (this.canRunNext()) {
-            this.runRemaining();
+            this.runRemaining()
           }
-        });
-        return; // prevent marking as stopped
+        })
+        return // prevent marking as stopped
       }
-    } while (this.canRunNext());
+    } while (this.canRunNext())
 
-    this.trigger('stop'); // not really a 'stop' ... more of a 'drained'
-    this.isRunning = false;
+    this.trigger('stop') // not really a 'stop' ... more of a 'drained'
+    this.isRunning = false
 
     // if 'stop' handler added more tasks.... TODO: write test for this
-    this.tryStart();
+    this.tryStart()
   }
 
 
   runTask(task) {
-    return task(); // task *is* the function, but subclasses can change the format of a task
+    return task() // task *is* the function, but subclasses can change the format of a task
   }
 
 }

+ 8 - 8
src/component/Component.ts

@@ -6,19 +6,19 @@ export default class Component extends Model {
 
 
   setElement(el) {
-    this.el = el;
-    this.bindGlobalHandlers();
-    this.renderSkeleton();
-    this.set('isInDom', true);
+    this.el = el
+    this.bindGlobalHandlers()
+    this.renderSkeleton()
+    this.set('isInDom', true)
   }
 
 
   removeElement() {
-    this.unset('isInDom');
-    this.unrenderSkeleton();
-    this.unbindGlobalHandlers();
+    this.unset('isInDom')
+    this.unrenderSkeleton()
+    this.unbindGlobalHandlers()
 
-    this.el.remove();
+    this.el.remove()
     // NOTE: don't null-out this.el in case the View was destroyed within an API callback.
     // We don't null-out the View's other jQuery element references upon destroy,
     //  so we shouldn't kill this.el either.

+ 181 - 188
src/component/DateComponent.ts

@@ -46,56 +46,56 @@ export default abstract class DateComponent extends Component {
       this['options'] = _options
     }
 
-    this.uid = String(DateComponent.guid++);
-    this.childrenByUid = {};
+    this.uid = String(DateComponent.guid++)
+    this.childrenByUid = {}
 
-    this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));
-    this.isRTL = this.opt('isRTL');
+    this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'))
+    this.isRTL = this.opt('isRTL')
 
     if (this.fillRendererClass) {
-      this.fillRenderer = new this.fillRendererClass(this);
+      this.fillRenderer = new this.fillRendererClass(this)
     }
 
     if (this.eventRendererClass) { // fillRenderer is optional -----v
-      this.eventRenderer = new this.eventRendererClass(this, this.fillRenderer);
+      this.eventRenderer = new this.eventRendererClass(this, this.fillRenderer)
     }
 
     if (this.helperRendererClass && this.eventRenderer) {
-      this.helperRenderer = new this.helperRendererClass(this, this.eventRenderer);
+      this.helperRenderer = new this.helperRendererClass(this, this.eventRenderer)
     }
 
     if (this.businessHourRendererClass && this.fillRenderer) {
-      this.businessHourRenderer = new this.businessHourRendererClass(this, this.fillRenderer);
+      this.businessHourRenderer = new this.businessHourRendererClass(this, this.fillRenderer)
     }
   }
 
 
   addChild(child) {
     if (!this.childrenByUid[child.uid]) {
-      this.childrenByUid[child.uid] = child;
+      this.childrenByUid[child.uid] = child
 
-      return true;
+      return true
     }
 
-    return false;
+    return false
   }
 
 
   removeChild(child) {
     if (this.childrenByUid[child.uid]) {
-      delete this.childrenByUid[child.uid];
+      delete this.childrenByUid[child.uid]
 
-      return true;
+      return true
     }
 
-    return false;
+    return false
   }
 
 
   // TODO: only do if isInDom?
   // TODO: make part of Component, along with children/batch-render system?
   updateSize(totalHeight, isAuto, isResize) {
-    this.callChildren('updateSize', arguments);
+    this.callChildren('updateSize', arguments)
   }
 
 
@@ -104,21 +104,21 @@ export default abstract class DateComponent extends Component {
 
 
   opt(name) {
-    return this._getView().opt(name); // default implementation
+    return this._getView().opt(name) // default implementation
   }
 
 
   publiclyTrigger(...args) {
-    var calendar = this._getCalendar();
+    let calendar = this._getCalendar()
 
-    return calendar.publiclyTrigger.apply(calendar, args);
+    return calendar.publiclyTrigger.apply(calendar, args)
   }
 
 
   hasPublicHandlers(...args) {
-    var calendar = this._getCalendar();
+    let calendar = this._getCalendar()
 
-    return calendar.hasPublicHandlers.apply(calendar, args);
+    return calendar.hasPublicHandlers.apply(calendar, args)
   }
 
 
@@ -127,18 +127,18 @@ export default abstract class DateComponent extends Component {
 
 
   executeDateRender(dateProfile) {
-    this.dateProfile = dateProfile; // for rendering
-    this.renderDates(dateProfile);
-    this.isDatesRendered = true;
-    this.callChildren('executeDateRender', arguments);
+    this.dateProfile = dateProfile // for rendering
+    this.renderDates(dateProfile)
+    this.isDatesRendered = true
+    this.callChildren('executeDateRender', arguments)
   }
 
 
   executeDateUnrender() { // wrapper
-    this.callChildren('executeDateUnrender', arguments);
-    this.dateProfile = null;
-    this.unrenderDates();
-    this.isDatesRendered = false;
+    this.callChildren('executeDateUnrender', arguments)
+    this.dateProfile = null
+    this.unrenderDates()
+    this.isDatesRendered = false
   }
 
 
@@ -167,13 +167,13 @@ export default abstract class DateComponent extends Component {
 
   // Renders a current time indicator at the given datetime
   renderNowIndicator(date) {
-    this.callChildren('renderNowIndicator', arguments);
+    this.callChildren('renderNowIndicator', arguments)
   }
 
 
   // Undoes the rendering actions from renderNowIndicator
   unrenderNowIndicator() {
-    this.callChildren('unrenderNowIndicator', arguments);
+    this.callChildren('unrenderNowIndicator', arguments)
   }
 
 
@@ -183,19 +183,19 @@ export default abstract class DateComponent extends Component {
 
   renderBusinessHours(businessHourGenerator) {
     if (this.businessHourRenderer) {
-      this.businessHourRenderer.render(businessHourGenerator);
+      this.businessHourRenderer.render(businessHourGenerator)
     }
 
-    this.callChildren('renderBusinessHours', arguments);
+    this.callChildren('renderBusinessHours', arguments)
   }
 
 
   // Unrenders previously-rendered business-hours
   unrenderBusinessHours() {
-    this.callChildren('unrenderBusinessHours', arguments);
+    this.callChildren('unrenderBusinessHours', arguments)
 
     if (this.businessHourRenderer) {
-      this.businessHourRenderer.unrender();
+      this.businessHourRenderer.unrender()
     }
   }
 
@@ -206,66 +206,64 @@ export default abstract class DateComponent extends Component {
 
   executeEventRender(eventsPayload) {
     if (this.eventRenderer) {
-      this.eventRenderer.rangeUpdated(); // poorly named now
-      this.eventRenderer.render(eventsPayload);
-    }
-    else if (this['renderEvents']) { // legacy
-      this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload));
+      this.eventRenderer.rangeUpdated() // poorly named now
+      this.eventRenderer.render(eventsPayload)
+    } else if (this['renderEvents']) { // legacy
+      this['renderEvents'](convertEventsPayloadToLegacyArray(eventsPayload))
     }
 
-    this.callChildren('executeEventRender', arguments);
+    this.callChildren('executeEventRender', arguments)
   }
 
 
   executeEventUnrender() {
-    this.callChildren('executeEventUnrender', arguments);
+    this.callChildren('executeEventUnrender', arguments)
 
     if (this.eventRenderer) {
-      this.eventRenderer.unrender();
-    }
-    else if (this['destroyEvents']) { // legacy
-      this['destroyEvents']();
+      this.eventRenderer.unrender()
+    } else if (this['destroyEvents']) { // legacy
+      this['destroyEvents']()
     }
   }
 
 
   getBusinessHourSegs() { // recursive
-    var segs = this.getOwnBusinessHourSegs();
+    let segs = this.getOwnBusinessHourSegs()
 
     this.iterChildren(function(child) {
-      segs.push.apply(segs, child.getBusinessHourSegs());
-    });
+      segs.push.apply(segs, child.getBusinessHourSegs())
+    })
 
-    return segs;
+    return segs
   }
 
 
   getOwnBusinessHourSegs() {
     if (this.businessHourRenderer) {
-      return this.businessHourRenderer.getSegs();
+      return this.businessHourRenderer.getSegs()
     }
 
-    return [];
+    return []
   }
 
 
   getEventSegs() { // recursive
-    var segs = this.getOwnEventSegs();
+    let segs = this.getOwnEventSegs()
 
     this.iterChildren(function(child) {
-      segs.push.apply(segs, child.getEventSegs());
-    });
+      segs.push.apply(segs, child.getEventSegs())
+    })
 
-    return segs;
+    return segs
   }
 
 
   getOwnEventSegs() { // just for itself
     if (this.eventRenderer) {
-      return this.eventRenderer.getSegs();
+      return this.eventRenderer.getSegs()
     }
 
-    return [];
+    return []
   }
 
 
@@ -276,12 +274,12 @@ export default abstract class DateComponent extends Component {
   triggerAfterEventsRendered() {
     this.triggerAfterEventSegsRendered(
       this.getEventSegs()
-    );
+    )
 
     this.publiclyTrigger('eventAfterAllRender', {
       context: this,
       args: [ this ]
-    });
+    })
   }
 
 
@@ -289,17 +287,17 @@ export default abstract class DateComponent extends Component {
     // an optimization, because getEventLegacy is expensive
     if (this.hasPublicHandlers('eventAfterRender')) {
       segs.forEach((seg) => {
-        var legacy;
+        let legacy
 
         if (seg.el) { // necessary?
-          legacy = seg.footprint.getEventLegacy();
+          legacy = seg.footprint.getEventLegacy()
 
           this.publiclyTrigger('eventAfterRender', {
             context: legacy,
             args: [ legacy, seg.el, this ]
-          });
+          })
         }
-      });
+      })
     }
   }
 
@@ -307,24 +305,24 @@ export default abstract class DateComponent extends Component {
   triggerBeforeEventsDestroyed() {
     this.triggerBeforeEventSegsDestroyed(
       this.getEventSegs()
-    );
+    )
   }
 
 
   triggerBeforeEventSegsDestroyed(segs) {
     if (this.hasPublicHandlers('eventDestroy')) {
       segs.forEach((seg) => {
-        var legacy;
+        let legacy
 
         if (seg.el) { // necessary?
-          legacy = seg.footprint.getEventLegacy();
+          legacy = seg.footprint.getEventLegacy()
 
           this.publiclyTrigger('eventDestroy', {
             context: legacy,
             args: [ legacy, seg.el, this ]
-          });
+          })
         }
-      });
+      })
     }
   }
 
@@ -342,11 +340,11 @@ export default abstract class DateComponent extends Component {
         seg.footprint.eventDef.id === eventDefId &&
         seg.el // necessary?
       ) {
-        seg.el.css('visibility', '');
+        seg.el.css('visibility', '')
       }
-    });
+    })
 
-    this.callChildren('showEventsWithId', arguments);
+    this.callChildren('showEventsWithId', arguments)
   }
 
 
@@ -359,11 +357,11 @@ export default abstract class DateComponent extends Component {
         seg.footprint.eventDef.id === eventDefId &&
         seg.el // necessary?
       ) {
-        seg.el.css('visibility', 'hidden');
+        seg.el.css('visibility', 'hidden')
       }
-    });
+    })
 
-    this.callChildren('hideEventsWithId', arguments);
+    this.callChildren('hideEventsWithId', arguments)
   }
 
 
@@ -375,21 +373,21 @@ export default abstract class DateComponent extends Component {
   // If an external-element, seg will be `null`.
   // Must return elements used for any mock events.
   renderDrag(eventFootprints, seg, isTouch) {
-    var renderedHelper = false;
+    let renderedHelper = false
 
     this.iterChildren(function(child) {
       if (child.renderDrag(eventFootprints, seg, isTouch)) {
-        renderedHelper = true;
+        renderedHelper = true
       }
-    });
+    })
 
-    return renderedHelper;
+    return renderedHelper
   }
 
 
   // Unrenders a visual indication of an event or external-element being dragged.
   unrenderDrag() {
-    this.callChildren('unrenderDrag', arguments);
+    this.callChildren('unrenderDrag', arguments)
   }
 
 
@@ -399,13 +397,13 @@ export default abstract class DateComponent extends Component {
 
   // Renders a visual indication of an event being resized.
   renderEventResize(eventFootprints, seg, isTouch) {
-    this.callChildren('renderEventResize', arguments);
+    this.callChildren('renderEventResize', arguments)
   }
 
 
   // Unrenders a visual indication of an event being resized.
   unrenderEventResize() {
-    this.callChildren('unrenderEventResize', arguments);
+    this.callChildren('unrenderEventResize', arguments)
   }
 
 
@@ -416,17 +414,17 @@ export default abstract class DateComponent extends Component {
   // Renders a visual indication of the selection
   // TODO: rename to `renderSelection` after legacy is gone
   renderSelectionFootprint(componentFootprint) {
-    this.renderHighlight(componentFootprint);
+    this.renderHighlight(componentFootprint)
 
-    this.callChildren('renderSelectionFootprint', arguments);
+    this.callChildren('renderSelectionFootprint', arguments)
   }
 
 
   // Unrenders a visual indication of selection
   unrenderSelection() {
-    this.unrenderHighlight();
+    this.unrenderHighlight()
 
-    this.callChildren('unrenderSelection', arguments);
+    this.callChildren('unrenderSelection', arguments)
   }
 
 
@@ -442,23 +440,23 @@ export default abstract class DateComponent extends Component {
         componentFootprint,
         {
           getClasses() {
-            return [ 'fc-highlight' ];
+            return [ 'fc-highlight' ]
           }
         }
-      );
+      )
     }
 
-    this.callChildren('renderHighlight', arguments);
+    this.callChildren('renderHighlight', arguments)
   }
 
 
   // Unrenders the emphasis on a date range
   unrenderHighlight() {
     if (this.fillRenderer) {
-      this.fillRenderer.unrender('highlight');
+      this.fillRenderer.unrender('highlight')
     }
 
-    this.callChildren('unrenderHighlight', arguments);
+    this.callChildren('unrenderHighlight', arguments)
   }
 
 
@@ -470,19 +468,19 @@ export default abstract class DateComponent extends Component {
 
   hitsNeeded() {
     if (!(this.hitsNeededDepth++)) {
-      this.prepareHits();
+      this.prepareHits()
     }
 
-    this.callChildren('hitsNeeded', arguments);
+    this.callChildren('hitsNeeded', arguments)
   }
 
 
   hitsNotNeeded() {
     if (this.hitsNeededDepth && !(--this.hitsNeededDepth)) {
-      this.releaseHits();
+      this.releaseHits()
     }
 
-    this.callChildren('hitsNotNeeded', arguments);
+    this.callChildren('hitsNotNeeded', arguments)
   }
 
 
@@ -501,30 +499,30 @@ export default abstract class DateComponent extends Component {
   // Must have a `grid` property, a reference to this current grid. TODO: avoid this
   // The returned object will be processed by getHitFootprint and getHitEl.
   queryHit(leftOffset, topOffset) {
-    var childrenByUid = this.childrenByUid;
-    var uid;
-    var hit;
+    let childrenByUid = this.childrenByUid
+    let uid
+    let hit
 
     for (uid in childrenByUid) {
-      hit = childrenByUid[uid].queryHit(leftOffset, topOffset);
+      hit = childrenByUid[uid].queryHit(leftOffset, topOffset)
 
       if (hit) {
-        break;
+        break
       }
     }
 
-    return hit;
+    return hit
   }
 
 
   getSafeHitFootprint(hit) {
-    var footprint = this.getHitFootprint(hit);
+    let footprint = this.getHitFootprint(hit)
 
     if (!this.dateProfile.activeUnzonedRange.containsRange(footprint.unzonedRange)) {
-      return null;
+      return null
     }
 
-    return footprint;
+    return footprint
   }
 
 
@@ -545,22 +543,22 @@ export default abstract class DateComponent extends Component {
 
 
   eventRangesToEventFootprints(eventRanges) {
-    var eventFootprints = [];
-    var i;
+    let eventFootprints = []
+    let i
 
     for (i = 0; i < eventRanges.length; i++) {
       eventFootprints.push.apply( // append
         eventFootprints,
         this.eventRangeToEventFootprints(eventRanges[i])
-      );
+      )
     }
 
-    return eventFootprints;
+    return eventFootprints
   }
 
 
   eventRangeToEventFootprints(eventRange): EventFootprint[] {
-    return [ eventRangeToEventFootprint(eventRange) ];
+    return [ eventRangeToEventFootprint(eventRange) ]
   }
 
 
@@ -569,16 +567,16 @@ export default abstract class DateComponent extends Component {
 
 
   eventFootprintsToSegs(eventFootprints) {
-    var segs = [];
-    var i;
+    let segs = []
+    let i
 
     for (i = 0; i < eventFootprints.length; i++) {
       segs.push.apply(segs,
         this.eventFootprintToSegs(eventFootprints[i])
-      );
+      )
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -586,32 +584,32 @@ export default abstract class DateComponent extends Component {
   // slices into segments and attaches event-derived properties to them.
   // eventSpan - { start, end, isStart, isEnd, otherthings... }
   eventFootprintToSegs(eventFootprint) {
-    var unzonedRange = eventFootprint.componentFootprint.unzonedRange;
-    var segs;
-    var i, seg;
+    let unzonedRange = eventFootprint.componentFootprint.unzonedRange
+    let segs
+    let i, seg
 
-    segs = this.componentFootprintToSegs(eventFootprint.componentFootprint);
+    segs = this.componentFootprintToSegs(eventFootprint.componentFootprint)
 
     for (i = 0; i < segs.length; i++) {
-      seg = segs[i];
+      seg = segs[i]
 
       if (!unzonedRange.isStart) {
-        seg.isStart = false;
+        seg.isStart = false
       }
       if (!unzonedRange.isEnd) {
-        seg.isEnd = false;
+        seg.isEnd = false
       }
 
-      seg.footprint = eventFootprint;
+      seg.footprint = eventFootprint
       // TODO: rename to seg.eventFootprint
     }
 
-    return segs;
+    return segs
   }
 
 
   componentFootprintToSegs(componentFootprint) {
-    return [];
+    return []
   }
 
 
@@ -621,34 +619,34 @@ export default abstract class DateComponent extends Component {
 
   callChildren(methodName, args) {
     this.iterChildren(function(child) {
-      child[methodName].apply(child, args);
-    });
+      child[methodName].apply(child, args)
+    })
   }
 
 
   iterChildren(func) {
-    var childrenByUid = this.childrenByUid;
-    var uid;
+    let childrenByUid = this.childrenByUid
+    let uid
 
     for (uid in childrenByUid) {
-      func(childrenByUid[uid]);
+      func(childrenByUid[uid])
     }
   }
 
 
   _getCalendar() { // TODO: strip out. move to generic parent.
     let t = (this as any)
-    return t.calendar || t.view.calendar;
+    return t.calendar || t.view.calendar
   }
 
 
   _getView() { // TODO: strip out. move to generic parent.
-    return (this as any).view;
+    return (this as any).view
   }
 
 
   _getDateProfile() {
-    return this._getView().get('dateProfile');
+    return this._getView().get('dateProfile')
   }
 
 
@@ -659,85 +657,80 @@ export default abstract class DateComponent extends Component {
   // `type` is a view-type like "day" or "week". default value is "day".
   // `attrs` and `innerHtml` are use to generate the rest of the HTML tag.
   buildGotoAnchorHtml(gotoOptions, attrs, innerHtml) {
-    var date, type, forceOff;
-    var finalOptions;
+    let date, type, forceOff
+    let finalOptions
 
     if ($.isPlainObject(gotoOptions)) {
-      date = gotoOptions.date;
-      type = gotoOptions.type;
-      forceOff = gotoOptions.forceOff;
+      date = gotoOptions.date
+      type = gotoOptions.type
+      forceOff = gotoOptions.forceOff
+    } else {
+      date = gotoOptions // a single moment input
     }
-    else {
-      date = gotoOptions; // a single moment input
-    }
-    date = momentExt(date); // if a string, parse it
+    date = momentExt(date) // if a string, parse it
 
     finalOptions = { // for serialization into the link
       date: date.format('YYYY-MM-DD'),
       type: type || 'day'
-    };
+    }
 
     if (typeof attrs === 'string') {
-      innerHtml = attrs;
-      attrs = null;
+      innerHtml = attrs
+      attrs = null
     }
 
-    attrs = attrs ? ' ' + attrsToStr(attrs) : ''; // will have a leading space
-    innerHtml = innerHtml || '';
+    attrs = attrs ? ' ' + attrsToStr(attrs) : '' // will have a leading space
+    innerHtml = innerHtml || ''
 
     if (!forceOff && this.opt('navLinks')) {
       return '<a' + attrs +
         ' data-goto="' + htmlEscape(JSON.stringify(finalOptions)) + '">' +
         innerHtml +
-        '</a>';
-    }
-    else {
+        '</a>'
+    } else {
       return '<span' + attrs + '>' +
         innerHtml +
-        '</span>';
+        '</span>'
     }
   }
 
 
   getAllDayHtml() {
-    return this.opt('allDayHtml') || htmlEscape(this.opt('allDayText'));
+    return this.opt('allDayHtml') || htmlEscape(this.opt('allDayText'))
   }
 
 
   // Computes HTML classNames for a single-day element
   getDayClasses(date, noThemeHighlight?) {
-    var view = this._getView();
-    var classes = [];
-    var today;
+    let view = this._getView()
+    let classes = []
+    let today
 
     if (!this.dateProfile.activeUnzonedRange.containsDate(date)) {
-      classes.push('fc-disabled-day'); // TODO: jQuery UI theme?
-    }
-    else {
-      classes.push('fc-' + dayIDs[date.day()]);
+      classes.push('fc-disabled-day') // TODO: jQuery UI theme?
+    } else {
+      classes.push('fc-' + dayIDs[date.day()])
 
       if (view.isDateInOtherMonth(date, this.dateProfile)) { // TODO: use DateComponent subclass somehow
-        classes.push('fc-other-month');
+        classes.push('fc-other-month')
       }
 
-      today = view.calendar.getNow();
+      today = view.calendar.getNow()
 
       if (date.isSame(today, 'day')) {
-        classes.push('fc-today');
+        classes.push('fc-today')
 
         if (noThemeHighlight !== true) {
-          classes.push(view.calendar.theme.getClass('today'));
+          classes.push(view.calendar.theme.getClass('today'))
         }
-      }
-      else if (date < today) {
-        classes.push('fc-past');
-      }
-      else {
-        classes.push('fc-future');
+      } else if (date < today) {
+        classes.push('fc-past')
+      } else {
+        classes.push('fc-future')
       }
     }
 
-    return classes;
+    return classes
   }
 
 
@@ -745,53 +738,53 @@ export default abstract class DateComponent extends Component {
   // Displays all-day ranges naturally, with an inclusive end. Takes the current isRTL into account.
   // The timezones of the dates within `range` will be respected.
   formatRange(range, isAllDay, formatStr, separator) {
-    var end = range.end;
+    let end = range.end
 
     if (isAllDay) {
-      end = end.clone().subtract(1); // convert to inclusive. last ms of previous day
+      end = end.clone().subtract(1) // convert to inclusive. last ms of previous day
     }
 
-    return formatRange(range.start, end, formatStr, separator, this.isRTL);
+    return formatRange(range.start, end, formatStr, separator, this.isRTL)
   }
 
 
   // Compute the number of the give units in the "current" range.
   // Will return a floating-point number. Won't round.
   currentRangeAs(unit) {
-    return this._getDateProfile().currentUnzonedRange.as(unit);
+    return this._getDateProfile().currentUnzonedRange.as(unit)
   }
 
 
   // Returns the date range of the full days the given range visually appears to occupy.
   // Returns a plain object with start/end, NOT an UnzonedRange!
   computeDayRange(unzonedRange) {
-    var calendar = this._getCalendar();
-    var startDay = calendar.msToUtcMoment(unzonedRange.startMs, true); // the beginning of the day the range starts
-    var end = calendar.msToUtcMoment(unzonedRange.endMs);
-    var endTimeMS = +end.time(); // # of milliseconds into `endDay`
-    var endDay = end.clone().stripTime(); // the beginning of the day the range exclusively ends
+    let calendar = this._getCalendar()
+    let startDay = calendar.msToUtcMoment(unzonedRange.startMs, true) // the beginning of the day the range starts
+    let end = calendar.msToUtcMoment(unzonedRange.endMs)
+    let endTimeMS = +end.time() // # of milliseconds into `endDay`
+    let endDay = end.clone().stripTime() // the beginning of the day the range exclusively ends
 
     // If the end time is actually inclusively part of the next day and is equal to or
     // beyond the next day threshold, adjust the end to be the exclusive end of `endDay`.
     // Otherwise, leaving it as inclusive will cause it to exclude `endDay`.
     if (endTimeMS && endTimeMS >= this.nextDayThreshold) {
-      endDay.add(1, 'days');
+      endDay.add(1, 'days')
     }
 
     // If end is within `startDay` but not past nextDayThreshold, assign the default duration of one day.
     if (endDay <= startDay) {
-      endDay = startDay.clone().add(1, 'days');
+      endDay = startDay.clone().add(1, 'days')
     }
 
-    return { start: startDay, end: endDay };
+    return { start: startDay, end: endDay }
   }
 
 
   // Does the given range visually appear to occupy more than one day?
   isMultiDayRange(unzonedRange) {
-    var dayRange = this.computeDayRange(unzonedRange);
+    let dayRange = this.computeDayRange(unzonedRange)
 
-    return dayRange.end.diff(dayRange.start, 'days') > 1;
+    return dayRange.end.diff(dayRange.start, 'days') > 1
   }
 
 }
@@ -800,20 +793,20 @@ export default abstract class DateComponent extends Component {
 // legacy
 
 function convertEventsPayloadToLegacyArray(eventsPayload) {
-  var eventDefId;
-  var eventInstances;
-  var legacyEvents = [];
-  var i;
+  let eventDefId
+  let eventInstances
+  let legacyEvents = []
+  let i
 
   for (eventDefId in eventsPayload) {
-    eventInstances = eventsPayload[eventDefId].eventInstances;
+    eventInstances = eventsPayload[eventDefId].eventInstances
 
     for (i = 0; i < eventInstances.length; i++) {
       legacyEvents.push(
         eventInstances[i].toLegacy()
-      );
+      )
     }
   }
 
-  return legacyEvents;
+  return legacyEvents
 }

+ 125 - 138
src/component/DayTableMixin.ts

@@ -34,67 +34,65 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
 
   // Populates internal variables used for date calculation and rendering
   updateDayTable() {
-    var t = (this as any);
-    var view = t.view;
-    var calendar = view.calendar;
-    var date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true);
-    var end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true);
-    var dayIndex = -1;
-    var dayIndices = [];
-    var dayDates = [];
-    var daysPerRow;
-    var firstDay;
-    var rowCnt;
+    let t = (this as any)
+    let view = t.view
+    let calendar = view.calendar
+    let date = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.startMs, true)
+    let end = calendar.msToUtcMoment(t.dateProfile.renderUnzonedRange.endMs, true)
+    let dayIndex = -1
+    let dayIndices = []
+    let dayDates = []
+    let daysPerRow
+    let firstDay
+    let rowCnt
 
     while (date.isBefore(end)) { // loop each day from start to end
       if (view.isHiddenDay(date)) {
-        dayIndices.push(dayIndex + 0.5); // mark that it's between indices
+        dayIndices.push(dayIndex + 0.5) // mark that it's between indices
+      } else {
+        dayIndex++
+        dayIndices.push(dayIndex)
+        dayDates.push(date.clone())
       }
-      else {
-        dayIndex++;
-        dayIndices.push(dayIndex);
-        dayDates.push(date.clone());
-      }
-      date.add(1, 'days');
+      date.add(1, 'days')
     }
 
     if (this.breakOnWeeks) {
       // count columns until the day-of-week repeats
-      firstDay = dayDates[0].day();
+      firstDay = dayDates[0].day()
       for (daysPerRow = 1; daysPerRow < dayDates.length; daysPerRow++) {
         if (dayDates[daysPerRow].day() == firstDay) {
-          break;
+          break
         }
       }
-      rowCnt = Math.ceil(dayDates.length / daysPerRow);
-    }
-    else {
-      rowCnt = 1;
-      daysPerRow = dayDates.length;
+      rowCnt = Math.ceil(dayDates.length / daysPerRow)
+    } else {
+      rowCnt = 1
+      daysPerRow = dayDates.length
     }
 
-    this.dayDates = dayDates;
-    this.dayIndices = dayIndices;
-    this.daysPerRow = daysPerRow;
-    this.rowCnt = rowCnt;
+    this.dayDates = dayDates
+    this.dayIndices = dayIndices
+    this.daysPerRow = daysPerRow
+    this.rowCnt = rowCnt
 
-    this.updateDayTableCols();
+    this.updateDayTableCols()
   }
 
 
   // Computes and assigned the colCnt property and updates any options that may be computed from it
   updateDayTableCols() {
-    this.colCnt = this.computeColCnt();
+    this.colCnt = this.computeColCnt()
     this.colHeadFormat =
       (this as any).opt('columnHeaderFormat') ||
       (this as any).opt('columnFormat') || // deprecated
-      this.computeColHeadFormat();
+      this.computeColHeadFormat()
   }
 
 
   // Determines how many columns there should be in the table
   computeColCnt() {
-    return this.daysPerRow;
+    return this.daysPerRow
   }
 
 
@@ -102,32 +100,31 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
   getCellDate(row, col) {
     return this.dayDates[
         this.getCellDayIndex(row, col)
-      ].clone();
+      ].clone()
   }
 
 
   // Computes the ambiguously-timed date range for the given cell
   getCellRange(row, col) {
-    var start = this.getCellDate(row, col);
-    var end = start.clone().add(1, 'days');
+    let start = this.getCellDate(row, col)
+    let end = start.clone().add(1, 'days')
 
-    return { start: start, end: end };
+    return { start: start, end: end }
   }
 
 
   // Returns the number of day cells, chronologically, from the first of the grid (0-based)
   getCellDayIndex(row, col) {
-    return row * this.daysPerRow + this.getColDayIndex(col);
+    return row * this.daysPerRow + this.getColDayIndex(col)
   }
 
 
   // Returns the numner of day cells, chronologically, from the first cell in *any given row*
   getColDayIndex(col) {
     if ((this as any).isRTL) {
-      return this.colCnt - 1 - col;
-    }
-    else {
-      return col;
+      return this.colCnt - 1 - col
+    } else {
+      return col
     }
   }
 
@@ -138,17 +135,15 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
   // If after the last offset, returns an offset past the last cell offset.
   // Only works for *start* dates of cells. Will not work for exclusive end dates for cells.
   getDateDayIndex(date) {
-    var dayIndices = this.dayIndices;
-    var dayOffset = date.diff(this.dayDates[0], 'days');
+    let dayIndices = this.dayIndices
+    let dayOffset = date.diff(this.dayDates[0], 'days')
 
     if (dayOffset < 0) {
-      return dayIndices[0] - 1;
-    }
-    else if (dayOffset >= dayIndices.length) {
-      return dayIndices[dayIndices.length - 1] + 1;
-    }
-    else {
-      return dayIndices[dayOffset];
+      return dayIndices[0] - 1
+    } else if (dayOffset >= dayIndices.length) {
+      return dayIndices[dayIndices.length - 1] + 1
+    } else {
+      return dayIndices[dayOffset]
     }
   }
 
@@ -162,15 +157,11 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
     // if more than one week row, or if there are a lot of columns with not much space,
     // put just the day numbers will be in each cell
     if (this.rowCnt > 1 || this.colCnt > 10) {
-      return 'ddd'; // "Sat"
-    }
-    // multiple days, so full single date string WON'T be in title text
-    else if (this.colCnt > 1) {
-      return (this as any).opt('dayOfMonthFormat'); // "Sat 12/10"
-    }
-    // single day, so full single date string will probably be in title text
-    else {
-      return 'dddd'; // "Saturday"
+      return 'ddd' // "Sat"
+    } else if (this.colCnt > 1) {
+      return (this as any).opt('dayOfMonthFormat') // "Sat 12/10"
+    } else {
+      return 'dddd' // "Saturday"
     }
   }
 
@@ -181,26 +172,26 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
 
   // Slices up a date range into a segment for every week-row it intersects with
   sliceRangeByRow(unzonedRange) {
-    var daysPerRow = this.daysPerRow;
-    var normalRange = (this as any).view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
-    var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
-    var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
-    var segs = [];
-    var row;
-    var rowFirst, rowLast; // inclusive day-index range for current row
-    var segFirst, segLast; // inclusive day-index range for segment
+    let daysPerRow = this.daysPerRow
+    let normalRange = (this as any).view.computeDayRange(unzonedRange) // make whole-day range, considering nextDayThreshold
+    let rangeFirst = this.getDateDayIndex(normalRange.start) // inclusive first index
+    let rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')) // inclusive last index
+    let segs = []
+    let row
+    let rowFirst, rowLast // inclusive day-index range for current row
+    let segFirst, segLast // inclusive day-index range for segment
 
     for (row = 0; row < this.rowCnt; row++) {
-      rowFirst = row * daysPerRow;
-      rowLast = rowFirst + daysPerRow - 1;
+      rowFirst = row * daysPerRow
+      rowLast = rowFirst + daysPerRow - 1
 
       // intersect segment's offset range with the row's
-      segFirst = Math.max(rangeFirst, rowFirst);
-      segLast = Math.min(rangeLast, rowLast);
+      segFirst = Math.max(rangeFirst, rowFirst)
+      segLast = Math.min(rangeLast, rowLast)
 
       // deal with in-between indices
-      segFirst = Math.ceil(segFirst); // in-between starts round to next cell
-      segLast = Math.floor(segLast); // in-between ends round to prev cell
+      segFirst = Math.ceil(segFirst) // in-between starts round to next cell
+      segLast = Math.floor(segLast) // in-between ends round to prev cell
 
       if (segFirst <= segLast) { // was there any intersection with the current row?
         segs.push({
@@ -213,40 +204,40 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
           // must be matching integers to be the segment's start/end
           isStart: segFirst === rangeFirst,
           isEnd: segLast === rangeLast
-        });
+        })
       }
     }
 
-    return segs;
+    return segs
   }
 
 
   // Slices up a date range into a segment for every day-cell it intersects with.
   // TODO: make more DRY with sliceRangeByRow somehow.
   sliceRangeByDay(unzonedRange) {
-    var daysPerRow = this.daysPerRow;
-    var normalRange = (this as any).view.computeDayRange(unzonedRange); // make whole-day range, considering nextDayThreshold
-    var rangeFirst = this.getDateDayIndex(normalRange.start); // inclusive first index
-    var rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')); // inclusive last index
-    var segs = [];
-    var row;
-    var rowFirst, rowLast; // inclusive day-index range for current row
-    var i;
-    var segFirst, segLast; // inclusive day-index range for segment
+    let daysPerRow = this.daysPerRow
+    let normalRange = (this as any).view.computeDayRange(unzonedRange) // make whole-day range, considering nextDayThreshold
+    let rangeFirst = this.getDateDayIndex(normalRange.start) // inclusive first index
+    let rangeLast = this.getDateDayIndex(normalRange.end.clone().subtract(1, 'days')) // inclusive last index
+    let segs = []
+    let row
+    let rowFirst, rowLast // inclusive day-index range for current row
+    let i
+    let segFirst, segLast // inclusive day-index range for segment
 
     for (row = 0; row < this.rowCnt; row++) {
-      rowFirst = row * daysPerRow;
-      rowLast = rowFirst + daysPerRow - 1;
+      rowFirst = row * daysPerRow
+      rowLast = rowFirst + daysPerRow - 1
 
       for (i = rowFirst; i <= rowLast; i++) {
 
         // intersect segment's offset range with the row's
-        segFirst = Math.max(rangeFirst, i);
-        segLast = Math.min(rangeLast, i);
+        segFirst = Math.max(rangeFirst, i)
+        segLast = Math.min(rangeLast, i)
 
         // deal with in-between indices
-        segFirst = Math.ceil(segFirst); // in-between starts round to next cell
-        segLast = Math.floor(segLast); // in-between ends round to prev cell
+        segFirst = Math.ceil(segFirst) // in-between starts round to next cell
+        segLast = Math.floor(segLast) // in-between ends round to prev cell
 
         if (segFirst <= segLast) { // was there any intersection with the current row?
           segs.push({
@@ -259,12 +250,12 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
             // must be matching integers to be the segment's start/end
             isStart: segFirst === rangeFirst,
             isEnd: segLast === rangeLast
-          });
+          })
         }
       }
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -273,7 +264,7 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
 
 
   renderHeadHtml() {
-    var theme = (this as any).view.calendar.theme;
+    let theme = (this as any).view.calendar.theme
 
     return '' +
       '<div class="fc-row ' + theme.getClass('headerRow') + '">' +
@@ -282,12 +273,12 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
             this.renderHeadTrHtml() +
           '</thead>' +
         '</table>' +
-      '</div>';
+      '</div>'
   }
 
 
   renderHeadIntroHtml() {
-    return this.renderIntroHtml(); // fall back to generic
+    return this.renderIntroHtml() // fall back to generic
   }
 
 
@@ -297,43 +288,41 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
         ((this as any).isRTL ? '' : this.renderHeadIntroHtml()) +
         this.renderHeadDateCellsHtml() +
         ((this as any).isRTL ? this.renderHeadIntroHtml() : '') +
-      '</tr>';
+      '</tr>'
   }
 
 
   renderHeadDateCellsHtml() {
-    var htmls = [];
-    var col, date;
+    let htmls = []
+    let col, date
 
     for (col = 0; col < this.colCnt; col++) {
-      date = this.getCellDate(0, col);
-      htmls.push((this as any).renderHeadDateCellHtml(date));
+      date = this.getCellDate(0, col)
+      htmls.push((this as any).renderHeadDateCellHtml(date))
     }
 
-    return htmls.join('');
+    return htmls.join('')
   }
 
 
   // TODO: when internalApiVersion, accept an object for HTML attributes
   // (colspan should be no different)
   renderHeadDateCellHtml(date, colspan, otherAttrs) {
-    var t = (this as any);
-    var view = t.view;
-    var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
-    var classNames = [
+    let t = (this as any)
+    let view = t.view
+    let isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date) // TODO: called too frequently. cache somehow.
+    let classNames = [
       'fc-day-header',
       view.calendar.theme.getClass('widgetHeader')
-    ];
-    var innerHtml;
+    ]
+    let innerHtml
 
     if (typeof t.opt('columnHeaderHtml') === 'function') {
-      innerHtml = t.opt('columnHeaderHtml')(date);
-    }
-    else if (typeof t.opt('columnHeaderText') === 'function') {
-      innerHtml = htmlEscape(t.opt('columnHeaderText')(date));
-    }
-    else {
-      innerHtml = htmlEscape(date.format(t.colHeadFormat));
+      innerHtml = t.opt('columnHeaderHtml')(date)
+    } else if (typeof t.opt('columnHeaderText') === 'function') {
+      innerHtml = htmlEscape(t.opt('columnHeaderText')(date))
+    } else {
+      innerHtml = htmlEscape(date.format(t.colHeadFormat))
     }
 
     // if only one row of days, the classNames on the header can represent the specific days beneath
@@ -342,10 +331,9 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
         // includes the day-of-week class
         // noThemeHighlight=true (don't highlight the header)
         t.getDayClasses(date, true)
-      );
-    }
-    else {
-      classNames.push('fc-' + dayIDs[date.day()]); // only add the day-of-week class
+      )
+    } else {
+      classNames.push('fc-' + dayIDs[date.day()]) // only add the day-of-week class
     }
 
     return '' +
@@ -369,7 +357,7 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
           // if not valid, display text, but no link
           innerHtml
         ) +
-      '</th>';
+      '</th>'
   }
 
 
@@ -383,35 +371,35 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
         ((this as any).isRTL ? '' : this.renderBgIntroHtml(row)) +
         this.renderBgCellsHtml(row) +
         ((this as any).isRTL ? this.renderBgIntroHtml(row) : '') +
-      '</tr>';
+      '</tr>'
   }
 
 
   renderBgIntroHtml(row) {
-    return this.renderIntroHtml(); // fall back to generic
+    return this.renderIntroHtml() // fall back to generic
   }
 
 
   renderBgCellsHtml(row) {
-    var htmls = [];
-    var col, date;
+    let htmls = []
+    let col, date
 
     for (col = 0; col < this.colCnt; col++) {
-      date = this.getCellDate(row, col);
-      htmls.push((this as any).renderBgCellHtml(date));
+      date = this.getCellDate(row, col)
+      htmls.push((this as any).renderBgCellHtml(date))
     }
 
-    return htmls.join('');
+    return htmls.join('')
   }
 
 
   renderBgCellHtml(date, otherAttrs) {
-    var t = (this as any);
-    var view = t.view;
-    var isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date); // TODO: called too frequently. cache somehow.
-    var classes = t.getDayClasses(date);
+    let t = (this as any)
+    let view = t.view
+    let isDateValid = t.dateProfile.activeUnzonedRange.containsDate(date) // TODO: called too frequently. cache somehow.
+    let classes = t.getDayClasses(date)
 
-    classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent'));
+    classes.unshift('fc-day', view.calendar.theme.getClass('widgetContent'))
 
     return '<td class="' + classes.join(' ') + '"' +
       (isDateValid ?
@@ -420,7 +408,7 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
       (otherAttrs ?
         ' ' + otherAttrs :
         '') +
-      '></td>';
+      '></td>'
   }
 
 
@@ -445,14 +433,13 @@ export default class DayTableMixin extends Mixin implements DayTableInterface {
   // Applies the generic "intro" and "outro" HTML to the given cells.
   // Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
   bookendCells(trEl) {
-    var introHtml = this.renderIntroHtml();
+    let introHtml = this.renderIntroHtml()
 
     if (introHtml) {
       if ((this as any).isRTL) {
-        trEl.append(introHtml);
-      }
-      else {
-        trEl.prepend(introHtml);
+        trEl.append(introHtml)
+      } else {
+        trEl.prepend(introHtml)
       }
     }
   }

+ 64 - 65
src/component/InteractiveDateComponent.ts

@@ -34,27 +34,27 @@ export default abstract class InteractiveDateComponent extends DateComponent {
     super(_view, _options)
 
     if (this.dateSelectingClass) {
-      this.dateClicking = new this.dateClickingClass(this);
+      this.dateClicking = new this.dateClickingClass(this)
     }
 
     if (this.dateSelectingClass) {
-      this.dateSelecting = new this.dateSelectingClass(this);
+      this.dateSelecting = new this.dateSelectingClass(this)
     }
 
     if (this.eventPointingClass) {
-      this.eventPointing = new this.eventPointingClass(this);
+      this.eventPointing = new this.eventPointingClass(this)
     }
 
     if (this.eventDraggingClass && this.eventPointing) {
-      this.eventDragging = new this.eventDraggingClass(this, this.eventPointing);
+      this.eventDragging = new this.eventDraggingClass(this, this.eventPointing)
     }
 
     if (this.eventResizingClass && this.eventPointing) {
-      this.eventResizing = new this.eventResizingClass(this, this.eventPointing);
+      this.eventResizing = new this.eventResizingClass(this, this.eventPointing)
     }
 
     if (this.externalDroppingClass) {
-      this.externalDropping = new this.externalDroppingClass(this);
+      this.externalDropping = new this.externalDroppingClass(this)
     }
   }
 
@@ -65,45 +65,45 @@ export default abstract class InteractiveDateComponent extends DateComponent {
     super.setElement(el)
 
     if (this.dateClicking) {
-      this.dateClicking.bindToEl(el);
+      this.dateClicking.bindToEl(el)
     }
 
     if (this.dateSelecting) {
-      this.dateSelecting.bindToEl(el);
+      this.dateSelecting.bindToEl(el)
     }
 
-    this.bindAllSegHandlersToEl(el);
+    this.bindAllSegHandlersToEl(el)
   }
 
 
   removeElement() {
-    this.endInteractions();
+    this.endInteractions()
 
-    super.removeElement();
+    super.removeElement()
   }
 
 
   executeEventUnrender() {
-    this.endInteractions();
+    this.endInteractions()
 
     super.executeEventUnrender()
   }
 
 
   bindGlobalHandlers() {
-    super.bindGlobalHandlers();
+    super.bindGlobalHandlers()
 
     if (this.externalDropping) {
-      this.externalDropping.bindToDocument();
+      this.externalDropping.bindToDocument()
     }
   }
 
 
   unbindGlobalHandlers() {
-    super.unbindGlobalHandlers();
+    super.unbindGlobalHandlers()
 
     if (this.externalDropping) {
-      this.externalDropping.unbindFromDocument();
+      this.externalDropping.unbindFromDocument()
     }
   }
 
@@ -120,9 +120,9 @@ export default abstract class InteractiveDateComponent extends DateComponent {
           'a[data-goto]' // a clickable nav link
         )
       ) {
-        return handler.call(this, ev);
+        return handler.call(this, ev)
       }
-    });
+    })
   }
 
 
@@ -133,45 +133,45 @@ export default abstract class InteractiveDateComponent extends DateComponent {
       this.eventResizing
     ].forEach(function(eventInteraction) {
       if (eventInteraction) {
-        eventInteraction.bindToEl(el);
+        eventInteraction.bindToEl(el)
       }
-    });
+    })
   }
 
 
   bindSegHandlerToEl(el, name, handler) {
     el.on(name, this.segSelector, (ev) => {
-      var seg = $(ev.currentTarget).data('fc-seg'); // grab segment data. put there by View::renderEventsPayload
+      let seg = $(ev.currentTarget).data('fc-seg') // grab segment data. put there by View::renderEventsPayload
 
       if (seg && !this.shouldIgnoreEventPointing()) {
-        return handler.call(this, seg, ev); // context will be the Grid
+        return handler.call(this, seg, ev) // context will be the Grid
       }
-    });
+    })
   }
 
 
   shouldIgnoreMouse() {
     // HACK
     // This will still work even though bindDateHandlerToEl doesn't use GlobalEmitter.
-    return GlobalEmitter.get().shouldIgnoreMouse();
+    return GlobalEmitter.get().shouldIgnoreMouse()
   }
 
 
   shouldIgnoreTouch() {
-    var view = this._getView();
+    let view = this._getView()
 
     // On iOS (and Android?) when a new selection is initiated overtop another selection,
     // the touchend never fires because the elements gets removed mid-touch-interaction (my theory).
     // HACK: simply don't allow this to happen.
     // ALSO: prevent selection when an *event* is already raised.
-    return view.isSelected || view.selectedEvent;
+    return view.isSelected || view.selectedEvent
   }
 
 
   shouldIgnoreEventPointing() {
     // only call the handlers if there is not a drag/resize in progress
     return (this.eventDragging && this.eventDragging.isDragging) ||
-      (this.eventResizing && this.eventResizing.isResizing);
+      (this.eventResizing && this.eventResizing.isResizing)
   }
 
 
@@ -179,23 +179,23 @@ export default abstract class InteractiveDateComponent extends DateComponent {
     return getEvIsTouch(ev) &&
       !this.canStartResize(seg, ev) &&
       (this.isEventDefDraggable(seg.footprint.eventDef) ||
-        this.isEventDefResizable(seg.footprint.eventDef));
+        this.isEventDefResizable(seg.footprint.eventDef))
   }
 
 
   canStartDrag(seg, ev) {
     return !this.canStartResize(seg, ev) &&
-      this.isEventDefDraggable(seg.footprint.eventDef);
+      this.isEventDefDraggable(seg.footprint.eventDef)
   }
 
 
   canStartResize(seg, ev) {
-    var view = this._getView();
-    var eventDef = seg.footprint.eventDef;
+    let view = this._getView()
+    let eventDef = seg.footprint.eventDef
 
     return (!getEvIsTouch(ev) || view.isEventDefSelected(eventDef)) &&
       this.isEventDefResizable(eventDef) &&
-      $(ev.target).is('.fc-resizer');
+      $(ev.target).is('.fc-resizer')
   }
 
 
@@ -211,9 +211,9 @@ export default abstract class InteractiveDateComponent extends DateComponent {
       this.eventResizing
     ].forEach(function(interaction) {
       if (interaction) {
-        interaction.end();
+        interaction.end()
       }
-    });
+    })
   }
 
 
@@ -223,33 +223,33 @@ export default abstract class InteractiveDateComponent extends DateComponent {
 
   // Computes if the given event is allowed to be dragged by the user
   isEventDefDraggable(eventDef) {
-    return this.isEventDefStartEditable(eventDef);
+    return this.isEventDefStartEditable(eventDef)
   }
 
 
   isEventDefStartEditable(eventDef) {
-    var isEditable = eventDef.isStartExplicitlyEditable();
+    let isEditable = eventDef.isStartExplicitlyEditable()
 
     if (isEditable == null) {
-      isEditable = this.opt('eventStartEditable');
+      isEditable = this.opt('eventStartEditable')
 
       if (isEditable == null) {
-        isEditable = this.isEventDefGenerallyEditable(eventDef);
+        isEditable = this.isEventDefGenerallyEditable(eventDef)
       }
     }
 
-    return isEditable;
+    return isEditable
   }
 
 
   isEventDefGenerallyEditable(eventDef) {
-    var isEditable = eventDef.isExplicitlyEditable();
+    let isEditable = eventDef.isExplicitlyEditable()
 
     if (isEditable == null) {
-      isEditable = this.opt('editable');
+      isEditable = this.opt('editable')
     }
 
-    return isEditable;
+    return isEditable
   }
 
 
@@ -259,28 +259,28 @@ export default abstract class InteractiveDateComponent extends DateComponent {
 
   // Computes if the given event is allowed to be resized from its starting edge
   isEventDefResizableFromStart(eventDef) {
-    return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef);
+    return this.opt('eventResizableFromStart') && this.isEventDefResizable(eventDef)
   }
 
 
   // Computes if the given event is allowed to be resized from its ending edge
   isEventDefResizableFromEnd(eventDef) {
-    return this.isEventDefResizable(eventDef);
+    return this.isEventDefResizable(eventDef)
   }
 
 
   // Computes if the given event is allowed to be resized by the user at all
   isEventDefResizable(eventDef) {
-    var isResizable = eventDef.isDurationExplicitlyEditable();
+    let isResizable = eventDef.isDurationExplicitlyEditable()
 
     if (isResizable == null) {
-      isResizable = this.opt('eventDurationEditable');
+      isResizable = this.opt('eventDurationEditable')
 
       if (isResizable == null) {
-        isResizable = this.isEventDefGenerallyEditable(eventDef);
+        isResizable = this.isEventDefGenerallyEditable(eventDef)
       }
     }
-    return isResizable;
+    return isResizable
   }
 
 
@@ -292,10 +292,9 @@ export default abstract class InteractiveDateComponent extends DateComponent {
   // TODO: port isTimeScale into this system?
   diffDates(a, b): moment.Duration {
     if (this.largeUnit) {
-      return diffByUnit(a, b, this.largeUnit);
-    }
-    else {
-      return diffDayTime(a, b);
+      return diffByUnit(a, b, this.largeUnit)
+    } else {
+      return diffDayTime(a, b)
     }
   }
 
@@ -303,33 +302,33 @@ export default abstract class InteractiveDateComponent extends DateComponent {
   // is it allowed, in relation to the view's validRange?
   // NOTE: very similar to isExternalInstanceGroupAllowed
   isEventInstanceGroupAllowed(eventInstanceGroup) {
-    var view = this._getView();
-    var dateProfile = this.dateProfile;
-    var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
-    var i;
+    let view = this._getView()
+    let dateProfile = this.dateProfile
+    let eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges())
+    let i
 
     for (i = 0; i < eventFootprints.length; i++) {
       // TODO: just use getAllEventRanges directly
       if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
-        return false;
+        return false
       }
     }
 
-    return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup);
+    return view.calendar.constraints.isEventInstanceGroupAllowed(eventInstanceGroup)
   }
 
 
   // NOTE: very similar to isEventInstanceGroupAllowed
   // when it's a completely anonymous external drag, no event.
   isExternalInstanceGroupAllowed(eventInstanceGroup) {
-    var view = this._getView();
-    var dateProfile = this.dateProfile;
-    var eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges());
-    var i;
+    let view = this._getView()
+    let dateProfile = this.dateProfile
+    let eventFootprints = this.eventRangesToEventFootprints(eventInstanceGroup.getAllEventRanges())
+    let i
 
     for (i = 0; i < eventFootprints.length; i++) {
       if (!dateProfile.validUnzonedRange.containsRange(eventFootprints[i].componentFootprint.unzonedRange)) {
-        return false;
+        return false
       }
     }
 
@@ -339,11 +338,11 @@ export default abstract class InteractiveDateComponent extends DateComponent {
       //  because we don't want calendar's constraint system to depend on a component's
       //  determination of footprints.
       if (!view.calendar.constraints.isSelectionFootprintAllowed(eventFootprints[i].componentFootprint)) {
-        return false;
+        return false
       }
     }
 
-    return true;
+    return true
   }
 
 }

+ 21 - 21
src/component/interactions/DateClicking.ts

@@ -15,72 +15,72 @@ export default class DateClicking extends Interaction {
   */
   constructor(component) {
     super(component)
-    this.dragListener = this.buildDragListener();
+    this.dragListener = this.buildDragListener()
   }
 
 
   end() {
-    this.dragListener.endInteraction();
+    this.dragListener.endInteraction()
   }
 
 
   bindToEl(el) {
-    var component = this.component;
-    var dragListener = this.dragListener;
+    let component = this.component
+    let dragListener = this.dragListener
 
     component.bindDateHandlerToEl(el, 'mousedown', function(ev) {
       if (!component.shouldIgnoreMouse()) {
-        dragListener.startInteraction(ev);
+        dragListener.startInteraction(ev)
       }
-    });
+    })
 
     component.bindDateHandlerToEl(el, 'touchstart', function(ev) {
       if (!component.shouldIgnoreTouch()) {
-        dragListener.startInteraction(ev);
+        dragListener.startInteraction(ev)
       }
-    });
+    })
   }
 
 
   // Creates a listener that tracks the user's drag across day elements, for day clicking.
   buildDragListener() {
-    var component = this.component;
-    var dayClickHit; // null if invalid dayClick
+    let component = this.component
+    let dayClickHit // null if invalid dayClick
 
-    var dragListener = new HitDragListener(component, {
+    let dragListener = new HitDragListener(component, {
       scroll: this.opt('dragScroll'),
       interactionStart: () => {
-        dayClickHit = dragListener.origHit;
+        dayClickHit = dragListener.origHit
       },
       hitOver: (hit, isOrig, origHit) => {
         // if user dragged to another cell at any point, it can no longer be a dayClick
         if (!isOrig) {
-          dayClickHit = null;
+          dayClickHit = null
         }
       },
       hitOut: () => { // called before mouse moves to a different hit OR moved out of all hits
-        dayClickHit = null;
+        dayClickHit = null
       },
       interactionEnd: (ev, isCancelled) => {
-        var componentFootprint;
+        let componentFootprint
 
         if (!isCancelled && dayClickHit) {
-          componentFootprint = component.getSafeHitFootprint(dayClickHit);
+          componentFootprint = component.getSafeHitFootprint(dayClickHit)
 
           if (componentFootprint) {
-            this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev);
+            this.view.triggerDayClick(componentFootprint, component.getHitEl(dayClickHit), ev)
           }
         }
       }
-    });
+    })
 
     // because dragListener won't be called with any time delay, "dragging" will begin immediately,
     // which will kill any touchmoving/scrolling. Prevent this.
-    dragListener.shouldCancelTouchScroll = false;
+    dragListener.shouldCancelTouchScroll = false
 
-    dragListener.scrollAlwaysKills = true;
+    dragListener.scrollAlwaysKills = true
 
-    return dragListener;
+    return dragListener
   }
 
 }

+ 42 - 44
src/component/interactions/DateSelecting.ts

@@ -18,104 +18,102 @@ export default class DateSelecting extends Interaction {
     - unrenderHighlight
   */
   constructor(component) {
-    super(component);
-    this.dragListener = this.buildDragListener();
+    super(component)
+    this.dragListener = this.buildDragListener()
   }
 
 
   end() {
-    this.dragListener.endInteraction();
+    this.dragListener.endInteraction()
   }
 
 
   getDelay() {
-    var delay = this.opt('selectLongPressDelay');
+    let delay = this.opt('selectLongPressDelay')
 
     if (delay == null) {
-      delay = this.opt('longPressDelay'); // fallback
+      delay = this.opt('longPressDelay') // fallback
     }
 
-    return delay;
+    return delay
   }
 
 
   bindToEl(el) {
-    var component = this.component;
-    var dragListener = this.dragListener;
+    let component = this.component
+    let dragListener = this.dragListener
 
     component.bindDateHandlerToEl(el, 'mousedown', (ev) => {
       if (this.opt('selectable') && !component.shouldIgnoreMouse()) {
         dragListener.startInteraction(ev, {
           distance: this.opt('selectMinDistance')
-        });
+        })
       }
-    });
+    })
 
     component.bindDateHandlerToEl(el, 'touchstart', (ev) => {
       if (this.opt('selectable') && !component.shouldIgnoreTouch()) {
         dragListener.startInteraction(ev, {
           delay: this.getDelay()
-        });
+        })
       }
-    });
+    })
 
-    preventSelection(el);
+    preventSelection(el)
   }
 
 
   // Creates a listener that tracks the user's drag across day elements, for day selecting.
   buildDragListener() {
-    var component = this.component;
-    var selectionFootprint; // null if invalid selection
+    let component = this.component
+    let selectionFootprint // null if invalid selection
 
-    var dragListener = new HitDragListener(component, {
+    let dragListener = new HitDragListener(component, {
       scroll: this.opt('dragScroll'),
       interactionStart: () => {
-        selectionFootprint = null;
+        selectionFootprint = null
       },
       dragStart: (ev) => {
-        this.view.unselect(ev); // since we could be rendering a new selection, we want to clear any old one
+        this.view.unselect(ev) // since we could be rendering a new selection, we want to clear any old one
       },
       hitOver: (hit, isOrig, origHit) => {
-        var origHitFootprint;
-        var hitFootprint;
+        let origHitFootprint
+        let hitFootprint
 
         if (origHit) { // click needs to have started on a hit
 
-          origHitFootprint = component.getSafeHitFootprint(origHit);
-          hitFootprint = component.getSafeHitFootprint(hit);
+          origHitFootprint = component.getSafeHitFootprint(origHit)
+          hitFootprint = component.getSafeHitFootprint(hit)
 
           if (origHitFootprint && hitFootprint) {
-            selectionFootprint = this.computeSelection(origHitFootprint, hitFootprint);
-          }
-          else {
-            selectionFootprint = null;
+            selectionFootprint = this.computeSelection(origHitFootprint, hitFootprint)
+          } else {
+            selectionFootprint = null
           }
 
           if (selectionFootprint) {
-            component.renderSelectionFootprint(selectionFootprint);
-          }
-          else if (selectionFootprint === false) {
-            disableCursor();
+            component.renderSelectionFootprint(selectionFootprint)
+          } else if (selectionFootprint === false) {
+            disableCursor()
           }
         }
       },
       hitOut: () => { // called before mouse moves to a different hit OR moved out of all hits
-        selectionFootprint = null;
-        component.unrenderSelection();
+        selectionFootprint = null
+        component.unrenderSelection()
       },
       hitDone: () => { // called after a hitOut OR before a dragEnd
-        enableCursor();
+        enableCursor()
       },
       interactionEnd: (ev, isCancelled) => {
         if (!isCancelled && selectionFootprint) {
           // the selection will already have been rendered. just report it
-          this.view.reportSelection(selectionFootprint, ev);
+          this.view.reportSelection(selectionFootprint, ev)
         }
       }
-    });
+    })
 
-    return dragListener;
+    return dragListener
   }
 
 
@@ -124,13 +122,13 @@ export default class DateSelecting extends Interaction {
   // Will return false if the selection is invalid and this should be indicated to the user.
   // Will return null/undefined if a selection invalid but no error should be reported.
   computeSelection(footprint0, footprint1) {
-    var wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1);
+    let wholeFootprint = this.computeSelectionFootprint(footprint0, footprint1)
 
     if (wholeFootprint && !this.isSelectionFootprintAllowed(wholeFootprint)) {
-      return false;
+      return false
     }
 
-    return wholeFootprint;
+    return wholeFootprint
   }
 
 
@@ -138,25 +136,25 @@ export default class DateSelecting extends Interaction {
   // TODO: do this separation of concerns (combining VS validation) for event dnd/resize too.
   // Assumes both footprints are non-open-ended.
   computeSelectionFootprint(footprint0, footprint1) {
-    var ms = [
+    let ms = [
       footprint0.unzonedRange.startMs,
       footprint0.unzonedRange.endMs,
       footprint1.unzonedRange.startMs,
       footprint1.unzonedRange.endMs
-    ];
+    ]
 
-    ms.sort(compareNumbers);
+    ms.sort(compareNumbers)
 
     return new ComponentFootprint(
       new UnzonedRange(ms[0], ms[3]),
       footprint0.isAllDay
-    );
+    )
   }
 
 
   isSelectionFootprintAllowed(componentFootprint) {
     return this.component.dateProfile.validUnzonedRange.containsRange(componentFootprint.unzonedRange) &&
-      this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint);
+      this.view.calendar.constraints.isSelectionFootprintAllowed(componentFootprint)
   }
 
 }

+ 105 - 110
src/component/interactions/EventDragging.ts

@@ -24,55 +24,54 @@ export default class EventDragging extends Interaction {
   */
   constructor(component, eventPointing) {
     super(component)
-    this.eventPointing = eventPointing;
+    this.eventPointing = eventPointing
   }
 
 
   end() {
     if (this.dragListener) {
-      this.dragListener.endInteraction();
+      this.dragListener.endInteraction()
     }
   }
 
 
   getSelectionDelay() {
-    var delay = this.opt('eventLongPressDelay');
+    let delay = this.opt('eventLongPressDelay')
 
     if (delay == null) {
-      delay = this.opt('longPressDelay'); // fallback
+      delay = this.opt('longPressDelay') // fallback
     }
 
-    return delay;
+    return delay
   }
 
 
   bindToEl(el) {
-    var component = this.component;
+    let component = this.component
 
-    component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this));
-    component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
+    component.bindSegHandlerToEl(el, 'mousedown', this.handleMousedown.bind(this))
+    component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this))
   }
 
 
   handleMousedown(seg, ev) {
     if (this.component.canStartDrag(seg, ev)) {
-      this.buildDragListener(seg).startInteraction(ev, { distance: 5 });
+      this.buildDragListener(seg).startInteraction(ev, { distance: 5 })
     }
   }
 
 
   handleTouchStart(seg, ev) {
-    var component = this.component;
-    var settings = {
+    let component = this.component
+    let settings = {
       delay: this.view.isEventDefSelected(seg.footprint.eventDef) ? // already selected?
         0 : this.getSelectionDelay()
-    };
+    }
 
     if (component.canStartDrag(seg, ev)) {
-      this.buildDragListener(seg).startInteraction(ev, settings);
-    }
-    else if (component.canStartSelection(seg, ev)) {
-      this.buildSelectListener(seg).startInteraction(ev, settings);
+      this.buildDragListener(seg).startInteraction(ev, settings)
+    } else if (component.canStartSelection(seg, ev)) {
+      this.buildSelectListener(seg).startInteraction(ev, settings)
     }
   }
 
@@ -81,15 +80,15 @@ export default class EventDragging extends Interaction {
   // simply for the delay, so it can be selected.
   // Has side effect of setting/unsetting `dragListener`
   buildSelectListener(seg) {
-    var view = this.view;
-    var eventDef = seg.footprint.eventDef;
-    var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
+    let view = this.view
+    let eventDef = seg.footprint.eventDef
+    let eventInstance = seg.footprint.eventInstance // null for inverse-background events
 
     if (this.dragListener) {
-      return this.dragListener;
+      return this.dragListener
     }
 
-    var dragListener = this.dragListener = new DragListener({
+    let dragListener = this.dragListener = new DragListener({
       dragStart: (ev) => {
         if (
           dragListener.isTouch &&
@@ -97,15 +96,15 @@ export default class EventDragging extends Interaction {
           eventInstance
         ) {
           // if not previously selected, will fire after a delay. then, select the event
-          view.selectEventInstance(eventInstance);
+          view.selectEventInstance(eventInstance)
         }
       },
       interactionEnd: (ev) => {
-        this.dragListener = null;
+        this.dragListener = null
       }
-    });
+    })
 
-    return dragListener;
+    return dragListener
   }
 
 
@@ -113,39 +112,39 @@ export default class EventDragging extends Interaction {
   // Generic enough to work with any type of Grid.
   // Has side effect of setting/unsetting `dragListener`
   buildDragListener(seg) {
-    var component = this.component;
-    var view = this.view;
-    var calendar = view.calendar;
-    var eventManager = calendar.eventManager;
-    var el = seg.el;
-    var eventDef = seg.footprint.eventDef;
-    var eventInstance = seg.footprint.eventInstance; // null for inverse-background events
-    var isDragging;
-    var mouseFollower; // A clone of the original element that will move with the mouse
-    var eventDefMutation;
+    let component = this.component
+    let view = this.view
+    let calendar = view.calendar
+    let eventManager = calendar.eventManager
+    let el = seg.el
+    let eventDef = seg.footprint.eventDef
+    let eventInstance = seg.footprint.eventInstance // null for inverse-background events
+    let isDragging
+    let mouseFollower // A clone of the original element that will move with the mouse
+    let eventDefMutation
 
     if (this.dragListener) {
-      return this.dragListener;
+      return this.dragListener
     }
 
     // Tracks mouse movement over the *view's* coordinate map. Allows dragging and dropping between subcomponents
     // of the view.
-    var dragListener = this.dragListener = new HitDragListener(view, {
+    let dragListener = this.dragListener = new HitDragListener(view, {
       scroll: this.opt('dragScroll'),
       subjectEl: el,
       subjectCenter: true,
       interactionStart: (ev) => {
-        seg.component = component; // for renderDrag
-        isDragging = false;
+        seg.component = component // for renderDrag
+        isDragging = false
         mouseFollower = new MouseFollower(seg.el, {
           additionalClass: 'fc-dragging',
           parentEl: view.el,
           opacity: dragListener.isTouch ? null : this.opt('dragOpacity'),
           revertDuration: this.opt('dragRevertDuration'),
           zIndex: 2 // one above the .fc-view
-        });
-        mouseFollower.hide(); // don't show until we know this is a real drag
-        mouseFollower.start(ev);
+        })
+        mouseFollower.hide() // don't show until we know this is a real drag
+        mouseFollower.start(ev)
       },
       dragStart: (ev) => {
         if (
@@ -154,52 +153,50 @@ export default class EventDragging extends Interaction {
           eventInstance
         ) {
           // if not previously selected, will fire after a delay. then, select the event
-          view.selectEventInstance(eventInstance);
+          view.selectEventInstance(eventInstance)
         }
-        isDragging = true;
+        isDragging = true
 
         // ensure a mouseout on the manipulated event has been reported
-        this.eventPointing.handleMouseout(seg, ev);
+        this.eventPointing.handleMouseout(seg, ev)
 
-        this.segDragStart(seg, ev);
-        view.hideEventsWithId(seg.footprint.eventDef.id);
+        this.segDragStart(seg, ev)
+        view.hideEventsWithId(seg.footprint.eventDef.id)
       },
       hitOver: (hit, isOrig, origHit) => {
-        var isAllowed = true;
-        var origFootprint;
-        var footprint;
-        var mutatedEventInstanceGroup;
+        let isAllowed = true
+        let origFootprint
+        let footprint
+        let mutatedEventInstanceGroup
 
         // starting hit could be forced (DayGrid.limit)
         if (seg.hit) {
-          origHit = seg.hit;
+          origHit = seg.hit
         }
 
         // hit might not belong to this grid, so query origin grid
-        origFootprint = origHit.component.getSafeHitFootprint(origHit);
-        footprint = hit.component.getSafeHitFootprint(hit);
+        origFootprint = origHit.component.getSafeHitFootprint(origHit)
+        footprint = hit.component.getSafeHitFootprint(hit)
 
         if (origFootprint && footprint) {
-          eventDefMutation = this.computeEventDropMutation(origFootprint, footprint, eventDef);
+          eventDefMutation = this.computeEventDropMutation(origFootprint, footprint, eventDef)
 
           if (eventDefMutation) {
             mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(
               eventDef.id,
               eventDefMutation
-            );
-            isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
-          }
-          else {
-            isAllowed = false;
+            )
+            isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup)
+          } else {
+            isAllowed = false
           }
-        }
-        else {
-          isAllowed = false;
+        } else {
+          isAllowed = false
         }
 
         if (!isAllowed) {
-          eventDefMutation = null;
-          disableCursor();
+          eventDefMutation = null
+          disableCursor()
         }
 
         // if a valid drop location, have the subclass render a visual indication
@@ -213,54 +210,53 @@ export default class EventDragging extends Interaction {
             dragListener.isTouch
           )
         ) {
-          mouseFollower.hide(); // if the subclass is already using a mock event "helper", hide our own
-        }
-        else {
-          mouseFollower.show(); // otherwise, have the helper follow the mouse (no snapping)
+          mouseFollower.hide() // if the subclass is already using a mock event "helper", hide our own
+        } else {
+          mouseFollower.show() // otherwise, have the helper follow the mouse (no snapping)
         }
 
         if (isOrig) {
           // needs to have moved hits to be a valid drop
-          eventDefMutation = null;
+          eventDefMutation = null
         }
       },
       hitOut: () => { // called before mouse moves to a different hit OR moved out of all hits
-        view.unrenderDrag(seg); // unrender whatever was done in renderDrag
-        mouseFollower.show(); // show in case we are moving out of all hits
-        eventDefMutation = null;
+        view.unrenderDrag(seg) // unrender whatever was done in renderDrag
+        mouseFollower.show() // show in case we are moving out of all hits
+        eventDefMutation = null
       },
       hitDone: () => { // Called after a hitOut OR before a dragEnd
-        enableCursor();
+        enableCursor()
       },
       interactionEnd: (ev) => {
-        delete seg.component; // prevent side effects
+        delete seg.component // prevent side effects
 
         // do revert animation if hasn't changed. calls a callback when finished (whether animation or not)
         mouseFollower.stop(!eventDefMutation, () => {
           if (isDragging) {
-            view.unrenderDrag(seg);
-            this.segDragStop(seg, ev);
+            view.unrenderDrag(seg)
+            this.segDragStop(seg, ev)
           }
 
-          view.showEventsWithId(seg.footprint.eventDef.id);
+          view.showEventsWithId(seg.footprint.eventDef.id)
 
           if (eventDefMutation) {
             // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
-            view.reportEventDrop(eventInstance, eventDefMutation, el, ev);
+            view.reportEventDrop(eventInstance, eventDefMutation, el, ev)
           }
-        });
+        })
 
-        this.dragListener = null;
+        this.dragListener = null
       }
-    });
+    })
 
-    return dragListener;
+    return dragListener
   }
 
 
   // Called before event segment dragging starts
   segDragStart(seg, ev) {
-    this.isDragging = true;
+    this.isDragging = true
     this.component.publiclyTrigger('eventDragStart', {
       context: seg.el[0],
       args: [
@@ -269,13 +265,13 @@ export default class EventDragging extends Interaction {
         {}, // jqui dummy
         this.view
       ]
-    });
+    })
   }
 
 
   // Called after event segment dragging stops
   segDragStop(seg, ev) {
-    this.isDragging = false;
+    this.isDragging = false
     this.component.publiclyTrigger('eventDragStop', {
       context: seg.el[0],
       args: [
@@ -284,52 +280,51 @@ export default class EventDragging extends Interaction {
         {}, // jqui dummy
         this.view
       ]
-    });
+    })
   }
 
 
   // DOES NOT consider overlap/constraint
   computeEventDropMutation(startFootprint, endFootprint, eventDef) {
-    var eventDefMutation = new EventDefMutation();
+    let eventDefMutation = new EventDefMutation()
 
     eventDefMutation.setDateMutation(
       this.computeEventDateMutation(startFootprint, endFootprint)
-    );
+    )
 
-    return eventDefMutation;
+    return eventDefMutation
   }
 
 
   computeEventDateMutation(startFootprint, endFootprint) {
-    var date0 = startFootprint.unzonedRange.getStart();
-    var date1 = endFootprint.unzonedRange.getStart();
-    var clearEnd = false;
-    var forceTimed = false;
-    var forceAllDay = false;
-    var dateDelta;
-    var dateMutation;
+    let date0 = startFootprint.unzonedRange.getStart()
+    let date1 = endFootprint.unzonedRange.getStart()
+    let clearEnd = false
+    let forceTimed = false
+    let forceAllDay = false
+    let dateDelta
+    let dateMutation
 
     if (startFootprint.isAllDay !== endFootprint.isAllDay) {
-      clearEnd = true;
+      clearEnd = true
 
       if (endFootprint.isAllDay) {
-        forceAllDay = true;
-        date0.stripTime();
-      }
-      else {
-        forceTimed = true;
+        forceAllDay = true
+        date0.stripTime()
+      } else {
+        forceTimed = true
       }
     }
 
-    dateDelta = this.component.diffDates(date1, date0);
+    dateDelta = this.component.diffDates(date1, date0)
 
-    dateMutation = new EventDefDateMutation();
-    dateMutation.clearEnd = clearEnd;
-    dateMutation.forceTimed = forceTimed;
-    dateMutation.forceAllDay = forceAllDay;
-    dateMutation.setDateDelta(dateDelta);
+    dateMutation = new EventDefDateMutation()
+    dateMutation.clearEnd = clearEnd
+    dateMutation.forceTimed = forceTimed
+    dateMutation.forceAllDay = forceAllDay
+    dateMutation.setDateDelta(dateDelta)
 
-    return dateMutation;
+    return dateMutation
   }
 
 }

+ 14 - 14
src/component/interactions/EventPointing.ts

@@ -14,22 +14,22 @@ export default class EventPointing extends Interaction {
 
 
   bindToEl(el) {
-    var component = this.component;
+    let component = this.component
 
-    component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this));
-    component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this));
-    component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this));
+    component.bindSegHandlerToEl(el, 'click', this.handleClick.bind(this))
+    component.bindSegHandlerToEl(el, 'mouseenter', this.handleMouseover.bind(this))
+    component.bindSegHandlerToEl(el, 'mouseleave', this.handleMouseout.bind(this))
   }
 
 
   handleClick(seg, ev) {
-    var res = this.component.publiclyTrigger('eventClick', { // can return `false` to cancel
+    let res = this.component.publiclyTrigger('eventClick', { // can return `false` to cancel
       context: seg.el[0],
       args: [ seg.footprint.getEventLegacy(), ev, this.view ]
-    });
+    })
 
     if (res === false) {
-      ev.preventDefault();
+      ev.preventDefault()
     }
   }
 
@@ -40,17 +40,17 @@ export default class EventPointing extends Interaction {
       !GlobalEmitter.get().shouldIgnoreMouse() &&
       !this.mousedOverSeg
     ) {
-      this.mousedOverSeg = seg;
+      this.mousedOverSeg = seg
 
       // TODO: move to EventSelecting's responsibility
       if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
-        seg.el.addClass('fc-allow-mouse-resize');
+        seg.el.addClass('fc-allow-mouse-resize')
       }
 
       this.component.publiclyTrigger('eventMouseover', {
         context: seg.el[0],
         args: [ seg.footprint.getEventLegacy(), ev, this.view ]
-      });
+      })
     }
   }
 
@@ -59,11 +59,11 @@ export default class EventPointing extends Interaction {
   // Can be given no arguments, in which case it will mouseout the segment that was previously moused over.
   handleMouseout(seg, ev?) {
     if (this.mousedOverSeg) {
-      this.mousedOverSeg = null;
+      this.mousedOverSeg = null
 
       // TODO: move to EventSelecting's responsibility
       if (this.view.isEventDefResizable(seg.footprint.eventDef)) {
-        seg.el.removeClass('fc-allow-mouse-resize');
+        seg.el.removeClass('fc-allow-mouse-resize')
       }
 
       this.component.publiclyTrigger('eventMouseout', {
@@ -73,14 +73,14 @@ export default class EventPointing extends Interaction {
           ev || {}, // if given no arg, make a mock mouse event
           this.view
         ]
-      });
+      })
     }
   }
 
 
   end() {
     if (this.mousedOverSeg) {
-      this.handleMouseout(this.mousedOverSeg);
+      this.handleMouseout(this.mousedOverSeg)
     }
   }
 

+ 74 - 77
src/component/interactions/EventResizing.ts

@@ -25,30 +25,30 @@ export default class EventResizing extends Interaction {
 
 
   constructor(component, eventPointing) {
-    super(component);
-    this.eventPointing = eventPointing;
+    super(component)
+    this.eventPointing = eventPointing
   }
 
 
   end() {
     if (this.dragListener) {
-      this.dragListener.endInteraction();
+      this.dragListener.endInteraction()
     }
   }
 
 
   bindToEl(el) {
-    var component = this.component;
+    let component = this.component
 
-    component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this));
-    component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this));
+    component.bindSegHandlerToEl(el, 'mousedown', this.handleMouseDown.bind(this))
+    component.bindSegHandlerToEl(el, 'touchstart', this.handleTouchStart.bind(this))
   }
 
 
   handleMouseDown(seg, ev) {
     if (this.component.canStartResize(seg, ev)) {
       this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
-        .startInteraction(ev, { distance: 5 });
+        .startInteraction(ev, { distance: 5 })
     }
   }
 
@@ -56,7 +56,7 @@ export default class EventResizing extends Interaction {
   handleTouchStart(seg, ev) {
     if (this.component.canStartResize(seg, ev)) {
       this.buildDragListener(seg, $(ev.target).is('.fc-start-resizer'))
-        .startInteraction(ev);
+        .startInteraction(ev)
     }
   }
 
@@ -64,105 +64,102 @@ export default class EventResizing extends Interaction {
   // Creates a listener that tracks the user as they resize an event segment.
   // Generic enough to work with any type of Grid.
   buildDragListener(seg, isStart) {
-    var component = this.component;
-    var view = this.view;
-    var calendar = view.calendar;
-    var eventManager = calendar.eventManager;
-    var el = seg.el;
-    var eventDef = seg.footprint.eventDef;
-    var eventInstance = seg.footprint.eventInstance;
-    var isDragging;
-    var resizeMutation; // zoned event date properties. falsy if invalid resize
+    let component = this.component
+    let view = this.view
+    let calendar = view.calendar
+    let eventManager = calendar.eventManager
+    let el = seg.el
+    let eventDef = seg.footprint.eventDef
+    let eventInstance = seg.footprint.eventInstance
+    let isDragging
+    let resizeMutation // zoned event date properties. falsy if invalid resize
 
     // Tracks mouse movement over the *grid's* coordinate map
-    var dragListener = this.dragListener = new HitDragListener(component, {
+    let dragListener = this.dragListener = new HitDragListener(component, {
       scroll: this.opt('dragScroll'),
       subjectEl: el,
       interactionStart: () => {
-        isDragging = false;
+        isDragging = false
       },
       dragStart: (ev) => {
-        isDragging = true;
+        isDragging = true
 
         // ensure a mouseout on the manipulated event has been reported
-        this.eventPointing.handleMouseout(seg, ev);
+        this.eventPointing.handleMouseout(seg, ev)
 
-        this.segResizeStart(seg, ev);
+        this.segResizeStart(seg, ev)
       },
       hitOver: (hit, isOrig, origHit) => {
-        var isAllowed = true;
-        var origHitFootprint = component.getSafeHitFootprint(origHit);
-        var hitFootprint = component.getSafeHitFootprint(hit);
-        var mutatedEventInstanceGroup;
+        let isAllowed = true
+        let origHitFootprint = component.getSafeHitFootprint(origHit)
+        let hitFootprint = component.getSafeHitFootprint(hit)
+        let mutatedEventInstanceGroup
 
         if (origHitFootprint && hitFootprint) {
           resizeMutation = isStart ?
             this.computeEventStartResizeMutation(origHitFootprint, hitFootprint, seg.footprint) :
-            this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint);
+            this.computeEventEndResizeMutation(origHitFootprint, hitFootprint, seg.footprint)
 
           if (resizeMutation) {
             mutatedEventInstanceGroup = eventManager.buildMutatedEventInstanceGroup(
               eventDef.id,
               resizeMutation
-            );
-            isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup);
+            )
+            isAllowed = component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup)
+          } else {
+            isAllowed = false
           }
-          else {
-            isAllowed = false;
-          }
-        }
-        else {
-          isAllowed = false;
+        } else {
+          isAllowed = false
         }
 
         if (!isAllowed) {
-          resizeMutation = null;
-          disableCursor();
-        }
-        else if (resizeMutation.isEmpty()) {
+          resizeMutation = null
+          disableCursor()
+        } else if (resizeMutation.isEmpty()) {
           // no change. (FYI, event dates might have zones)
-          resizeMutation = null;
+          resizeMutation = null
         }
 
         if (resizeMutation) {
-          view.hideEventsWithId(seg.footprint.eventDef.id);
+          view.hideEventsWithId(seg.footprint.eventDef.id)
           view.renderEventResize(
             component.eventRangesToEventFootprints(
               mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, calendar)
             ),
             seg
-          );
+          )
         }
       },
       hitOut: () => { // called before mouse moves to a different hit OR moved out of all hits
-        resizeMutation = null;
+        resizeMutation = null
       },
       hitDone: () => { // resets the rendering to show the original event
-        view.unrenderEventResize(seg);
-        view.showEventsWithId(seg.footprint.eventDef.id);
-        enableCursor();
+        view.unrenderEventResize(seg)
+        view.showEventsWithId(seg.footprint.eventDef.id)
+        enableCursor()
       },
       interactionEnd: (ev) => {
         if (isDragging) {
-          this.segResizeStop(seg, ev);
+          this.segResizeStop(seg, ev)
         }
 
         if (resizeMutation) { // valid date to resize to?
           // no need to re-show original, will rerender all anyways. esp important if eventRenderWait
-          view.reportEventResize(eventInstance, resizeMutation, el, ev);
+          view.reportEventResize(eventInstance, resizeMutation, el, ev)
         }
 
-        this.dragListener = null;
+        this.dragListener = null
       }
-    });
+    })
 
-    return dragListener;
+    return dragListener
   }
 
 
   // Called before event segment resizing starts
   segResizeStart(seg, ev) {
-    this.isResizing = true;
+    this.isResizing = true
     this.component.publiclyTrigger('eventResizeStart', {
       context: seg.el[0],
       args: [
@@ -171,13 +168,13 @@ export default class EventResizing extends Interaction {
         {}, // jqui dummy
         this.view
       ]
-    });
+    })
   }
 
 
   // Called after event segment resizing stops
   segResizeStop(seg, ev) {
-    this.isResizing = false;
+    this.isResizing = false
     this.component.publiclyTrigger('eventResizeStop', {
       context: seg.el[0],
       args: [
@@ -186,57 +183,57 @@ export default class EventResizing extends Interaction {
         {}, // jqui dummy
         this.view
       ]
-    });
+    })
   }
 
 
   // Returns new date-information for an event segment being resized from its start
   computeEventStartResizeMutation(startFootprint, endFootprint, origEventFootprint) {
-    var origRange = origEventFootprint.componentFootprint.unzonedRange;
-    var startDelta = this.component.diffDates(
+    let origRange = origEventFootprint.componentFootprint.unzonedRange
+    let startDelta = this.component.diffDates(
       endFootprint.unzonedRange.getStart(),
       startFootprint.unzonedRange.getStart()
-    );
-    var dateMutation;
-    var eventDefMutation;
+    )
+    let dateMutation
+    let eventDefMutation
 
     if (origRange.getStart().add(startDelta) < origRange.getEnd()) {
 
-      dateMutation = new EventDefDateMutation();
-      dateMutation.setStartDelta(startDelta);
+      dateMutation = new EventDefDateMutation()
+      dateMutation.setStartDelta(startDelta)
 
-      eventDefMutation = new EventDefMutation();
-      eventDefMutation.setDateMutation(dateMutation);
+      eventDefMutation = new EventDefMutation()
+      eventDefMutation.setDateMutation(dateMutation)
 
-      return eventDefMutation;
+      return eventDefMutation
     }
 
-    return false;
+    return false
   }
 
 
   // Returns new date-information for an event segment being resized from its end
   computeEventEndResizeMutation(startFootprint, endFootprint, origEventFootprint) {
-    var origRange = origEventFootprint.componentFootprint.unzonedRange;
-    var endDelta = this.component.diffDates(
+    let origRange = origEventFootprint.componentFootprint.unzonedRange
+    let endDelta = this.component.diffDates(
       endFootprint.unzonedRange.getEnd(),
       startFootprint.unzonedRange.getEnd()
-    );
-    var dateMutation;
-    var eventDefMutation;
+    )
+    let dateMutation
+    let eventDefMutation
 
     if (origRange.getEnd().add(endDelta) > origRange.getStart()) {
 
-      dateMutation = new EventDefDateMutation();
-      dateMutation.setEndDelta(endDelta);
+      dateMutation = new EventDefDateMutation()
+      dateMutation.setEndDelta(endDelta)
 
-      eventDefMutation = new EventDefMutation();
-      eventDefMutation.setDateMutation(dateMutation);
+      eventDefMutation = new EventDefMutation()
+      eventDefMutation.setDateMutation(dateMutation)
 
-      return eventDefMutation;
+      return eventDefMutation
     }
 
-    return false;
+    return false
   }
 
 }

+ 74 - 78
src/component/interactions/ExternalDropping.ts

@@ -32,7 +32,7 @@ export default class ExternalDropping extends Interaction {
 
   end() {
     if (this.dragListener) {
-      this.dragListener.endInteraction();
+      this.dragListener.endInteraction()
     }
   }
 
@@ -41,29 +41,29 @@ export default class ExternalDropping extends Interaction {
     this.listenTo($(document), {
       dragstart: this.handleDragStart, // jqui
       sortstart: this.handleDragStart // jqui
-    });
+    })
   }
 
 
   unbindFromDocument() {
-    this.stopListeningTo($(document));
+    this.stopListeningTo($(document))
   }
 
 
   // Called when a jQuery UI drag is initiated anywhere in the DOM
   handleDragStart(ev, ui) {
-    var el;
-    var accept;
+    let el
+    let accept
 
     if (this.opt('droppable')) { // only listen if this setting is on
-      el = $((ui ? ui.item : null) || ev.target);
+      el = $((ui ? ui.item : null) || ev.target)
 
       // Test that the dragged element passes the dropAccept selector or filter function.
       // FYI, the default is "*" (matches all)
-      accept = this.opt('dropAccept');
+      accept = this.opt('dropAccept')
       if ($.isFunction(accept) ? accept.call(el[0], el) : el.is(accept)) {
         if (!this.isDragging) { // prevent double-listening if fired twice
-          this.listenToExternalDrag(el, ev, ui);
+          this.listenToExternalDrag(el, ev, ui)
         }
       }
     }
@@ -72,43 +72,41 @@ export default class ExternalDropping extends Interaction {
 
   // Called when a jQuery UI drag starts and it needs to be monitored for dropping
   listenToExternalDrag(el, ev, ui) {
-    var component = this.component;
-    var view = this.view;
-    var meta = getDraggedElMeta(el); // extra data about event drop, including possible event to create
-    var singleEventDef; // a null value signals an unsuccessful drag
+    let component = this.component
+    let view = this.view
+    let meta = getDraggedElMeta(el) // extra data about event drop, including possible event to create
+    let singleEventDef // a null value signals an unsuccessful drag
 
     // listener that tracks mouse movement over date-associated pixel regions
-    var dragListener = this.dragListener = new HitDragListener(component, {
+    let dragListener = this.dragListener = new HitDragListener(component, {
       interactionStart: () => {
-        this.isDragging = true;
+        this.isDragging = true
       },
       hitOver: (hit) => {
-        var isAllowed = true;
-        var hitFootprint = hit.component.getSafeHitFootprint(hit); // hit might not belong to this grid
-        var mutatedEventInstanceGroup;
+        let isAllowed = true
+        let hitFootprint = hit.component.getSafeHitFootprint(hit) // hit might not belong to this grid
+        let mutatedEventInstanceGroup
 
         if (hitFootprint) {
-          singleEventDef = this.computeExternalDrop(hitFootprint, meta);
+          singleEventDef = this.computeExternalDrop(hitFootprint, meta)
 
           if (singleEventDef) {
             mutatedEventInstanceGroup = new EventInstanceGroup(
               singleEventDef.buildInstances()
-            );
+            )
             isAllowed = meta.eventProps ? // isEvent?
               component.isEventInstanceGroupAllowed(mutatedEventInstanceGroup) :
-              component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup);
-          }
-          else {
-            isAllowed = false;
+              component.isExternalInstanceGroupAllowed(mutatedEventInstanceGroup)
+          } else {
+            isAllowed = false
           }
-        }
-        else {
-          isAllowed = false;
+        } else {
+          isAllowed = false
         }
 
         if (!isAllowed) {
-          singleEventDef = null;
-          disableCursor();
+          singleEventDef = null
+          disableCursor()
         }
 
         if (singleEventDef) {
@@ -116,15 +114,15 @@ export default class ExternalDropping extends Interaction {
             component.eventRangesToEventFootprints(
               mutatedEventInstanceGroup.sliceRenderRanges(component.dateProfile.renderUnzonedRange, view.calendar)
             )
-          );
+          )
         }
       },
       hitOut: () => {
-        singleEventDef = null; // signal unsuccessful
+        singleEventDef = null // signal unsuccessful
       },
       hitDone: () => { // Called after a hitOut OR before a dragEnd
-        enableCursor();
-        component.unrenderDrag();
+        enableCursor()
+        component.unrenderDrag()
       },
       interactionEnd: (ev) => {
 
@@ -134,15 +132,15 @@ export default class ExternalDropping extends Interaction {
             Boolean(meta.eventProps), // isEvent
             Boolean(meta.stick), // isSticky
             el, ev, ui
-          );
+          )
         }
 
-        this.isDragging = false;
-        this.dragListener = null;
+        this.isDragging = false
+        this.dragListener = null
       }
-    });
+    })
 
-    dragListener.startDrag(ev); // start listening immediately
+    dragListener.startDrag(ev) // start listening immediately
   }
 
 
@@ -152,29 +150,28 @@ export default class ExternalDropping extends Interaction {
   // DOES NOT consider overlap/constraint.
   // Assumes both footprints are non-open-ended.
   computeExternalDrop(componentFootprint, meta) {
-    var calendar = this.view.calendar;
-    var start = momentExt.utc(componentFootprint.unzonedRange.startMs).stripZone();
-    var end;
-    var eventDef;
+    let calendar = this.view.calendar
+    let start = momentExt.utc(componentFootprint.unzonedRange.startMs).stripZone()
+    let end
+    let eventDef
 
     if (componentFootprint.isAllDay) {
       // if dropped on an all-day span, and element's metadata specified a time, set it
       if (meta.startTime) {
-        start.time(meta.startTime);
-      }
-      else {
-        start.stripTime();
+        start.time(meta.startTime)
+      } else {
+        start.stripTime()
       }
     }
 
     if (meta.duration) {
-      end = start.clone().add(meta.duration);
+      end = start.clone().add(meta.duration)
     }
 
-    start = calendar.applyTimezone(start);
+    start = calendar.applyTimezone(start)
 
     if (end) {
-      end = calendar.applyTimezone(end);
+      end = calendar.applyTimezone(end)
     }
 
     eventDef = SingleEventDef.parse(
@@ -183,9 +180,9 @@ export default class ExternalDropping extends Interaction {
         end: end
       }),
       new EventSource(calendar)
-    );
+    )
 
-    return eventDef;
+    return eventDef
   }
 
 }
@@ -198,50 +195,49 @@ ListenerMixin.mixInto(ExternalDropping);
 
 // Require all HTML5 data-* attributes used by FullCalendar to have this prefix.
 // A value of '' will query attributes like data-event. A value of 'fc' will query attributes like data-fc-event.
-(exportHooks as any).dataAttrPrefix = '';
+(exportHooks as any).dataAttrPrefix = ''
 
 // Given a jQuery element that might represent a dragged FullCalendar event, returns an intermediate data structure
 // to be used for Event Object creation.
 // A defined `.eventProps`, even when empty, indicates that an event should be created.
 function getDraggedElMeta(el) {
-  var prefix = (exportHooks as any).dataAttrPrefix;
-  var eventProps; // properties for creating the event, not related to date/time
-  var startTime; // a Duration
-  var duration;
-  var stick;
+  let prefix = (exportHooks as any).dataAttrPrefix
+  let eventProps // properties for creating the event, not related to date/time
+  let startTime // a Duration
+  let duration
+  let stick
 
-  if (prefix) { prefix += '-'; }
-  eventProps = el.data(prefix + 'event') || null;
+  if (prefix) { prefix += '-' }
+  eventProps = el.data(prefix + 'event') || null
 
   if (eventProps) {
     if (typeof eventProps === 'object') {
-      eventProps = $.extend({}, eventProps); // make a copy
-    }
-    else { // something like 1 or true. still signal event creation
-      eventProps = {};
+      eventProps = $.extend({}, eventProps) // make a copy
+    } else { // something like 1 or true. still signal event creation
+      eventProps = {}
     }
 
     // pluck special-cased date/time properties
-    startTime = eventProps.start;
-    if (startTime == null) { startTime = eventProps.time; } // accept 'time' as well
-    duration = eventProps.duration;
-    stick = eventProps.stick;
-    delete eventProps.start;
-    delete eventProps.time;
-    delete eventProps.duration;
-    delete eventProps.stick;
+    startTime = eventProps.start
+    if (startTime == null) { startTime = eventProps.time } // accept 'time' as well
+    duration = eventProps.duration
+    stick = eventProps.stick
+    delete eventProps.start
+    delete eventProps.time
+    delete eventProps.duration
+    delete eventProps.stick
   }
 
   // fallback to standalone attribute values for each of the date/time properties
-  if (startTime == null) { startTime = el.data(prefix + 'start'); }
-  if (startTime == null) { startTime = el.data(prefix + 'time'); } // accept 'time' as well
-  if (duration == null) { duration = el.data(prefix + 'duration'); }
-  if (stick == null) { stick = el.data(prefix + 'stick'); }
+  if (startTime == null) { startTime = el.data(prefix + 'start') }
+  if (startTime == null) { startTime = el.data(prefix + 'time') } // accept 'time' as well
+  if (duration == null) { duration = el.data(prefix + 'duration') }
+  if (stick == null) { stick = el.data(prefix + 'stick') }
 
   // massage into correct data types
-  startTime = startTime != null ? moment.duration(startTime) : null;
-  duration = duration != null ? moment.duration(duration) : null;
-  stick = Boolean(stick);
+  startTime = startTime != null ? moment.duration(startTime) : null
+  duration = duration != null ? moment.duration(duration) : null
+  stick = Boolean(stick)
 
-  return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick };
+  return { eventProps: eventProps, startTime: startTime, duration: duration, stick: stick }
 }

+ 3 - 3
src/component/interactions/Interaction.ts

@@ -6,13 +6,13 @@ export default class Interaction {
 
 
   constructor(component) {
-    this.view = component._getView();
-    this.component = component;
+    this.view = component._getView()
+    this.component = component
   }
 
 
   opt(name) {
-    return this.view.opt(name);
+    return this.view.opt(name)
   }
 
 

+ 1 - 1
src/component/interactions/StandardInteractionsMixin.ts

@@ -14,4 +14,4 @@ export default class StandardInteractionsMixin extends Mixin {
 (StandardInteractionsMixin as any).prototype.eventPointingClass = EventPointing;
 (StandardInteractionsMixin as any).prototype.eventDraggingClass = EventDragging;
 (StandardInteractionsMixin as any).prototype.eventResizingClass = EventResizing;
-(StandardInteractionsMixin as any).prototype.externalDroppingClass = ExternalDropping;
+(StandardInteractionsMixin as any).prototype.externalDroppingClass = ExternalDropping

+ 17 - 17
src/component/renderers/BusinessHourRenderer.ts

@@ -12,35 +12,35 @@ export default class BusinessHourRenderer {
     - eventFootprintsToSegs
   */
   constructor(component, fillRenderer) {
-    this.component = component;
-    this.fillRenderer = fillRenderer;
+    this.component = component
+    this.fillRenderer = fillRenderer
   }
 
 
   render(businessHourGenerator) {
-    var component = this.component;
-    var unzonedRange = component._getDateProfile().activeUnzonedRange;
+    let component = this.component
+    let unzonedRange = component._getDateProfile().activeUnzonedRange
 
-    var eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(
+    let eventInstanceGroup = businessHourGenerator.buildEventInstanceGroup(
       component.hasAllDayBusinessHours,
       unzonedRange
-    );
+    )
 
-    var eventFootprints = eventInstanceGroup ?
+    let eventFootprints = eventInstanceGroup ?
       component.eventRangesToEventFootprints(
         eventInstanceGroup.sliceRenderRanges(unzonedRange)
       ) :
-      [];
+      []
 
-    this.renderEventFootprints(eventFootprints);
+    this.renderEventFootprints(eventFootprints)
   }
 
 
   renderEventFootprints(eventFootprints) {
-    var segs = this.component.eventFootprintsToSegs(eventFootprints);
+    let segs = this.component.eventFootprintsToSegs(eventFootprints)
 
-    this.renderSegs(segs);
-    this.segs = segs;
+    this.renderSegs(segs)
+    this.segs = segs
   }
 
 
@@ -48,24 +48,24 @@ export default class BusinessHourRenderer {
     if (this.fillRenderer) {
       this.fillRenderer.renderSegs('businessHours', segs, {
         getClasses(seg) {
-          return [ 'fc-nonbusiness', 'fc-bgevent' ];
+          return [ 'fc-nonbusiness', 'fc-bgevent' ]
         }
-      });
+      })
     }
   }
 
 
   unrender() {
     if (this.fillRenderer) {
-      this.fillRenderer.unrender('businessHours');
+      this.fillRenderer.unrender('businessHours')
     }
 
-    this.segs = null;
+    this.segs = null
   }
 
 
   getSegs() {
-    return this.segs || [];
+    return this.segs || []
   }
 
 }

+ 124 - 128
src/component/renderers/EventRenderer.ts

@@ -17,123 +17,122 @@ export default class EventRenderer {
 
 
   constructor(component, fillRenderer) { // fillRenderer is optional
-    this.view = component._getView();
-    this.component = component;
-    this.fillRenderer = fillRenderer;
+    this.view = component._getView()
+    this.component = component
+    this.fillRenderer = fillRenderer
   }
 
 
   opt(name) {
-    return this.view.opt(name);
+    return this.view.opt(name)
   }
 
 
   // Updates values that rely on options and also relate to range
   rangeUpdated() {
-    var displayEventTime;
-    var displayEventEnd;
+    let displayEventTime
+    let displayEventEnd
 
     this.eventTimeFormat =
       this.opt('eventTimeFormat') ||
       this.opt('timeFormat') || // deprecated
-      this.computeEventTimeFormat();
+      this.computeEventTimeFormat()
 
-    displayEventTime = this.opt('displayEventTime');
+    displayEventTime = this.opt('displayEventTime')
     if (displayEventTime == null) {
-      displayEventTime = this.computeDisplayEventTime(); // might be based off of range
+      displayEventTime = this.computeDisplayEventTime() // might be based off of range
     }
 
-    displayEventEnd = this.opt('displayEventEnd');
+    displayEventEnd = this.opt('displayEventEnd')
     if (displayEventEnd == null) {
-      displayEventEnd = this.computeDisplayEventEnd(); // might be based off of range
+      displayEventEnd = this.computeDisplayEventEnd() // might be based off of range
     }
 
-    this.displayEventTime = displayEventTime;
-    this.displayEventEnd = displayEventEnd;
+    this.displayEventTime = displayEventTime
+    this.displayEventEnd = displayEventEnd
   }
 
 
   render(eventsPayload) {
-    var dateProfile = this.component._getDateProfile();
-    var eventDefId;
-    var instanceGroup;
-    var eventRanges;
-    var bgRanges = [];
-    var fgRanges = [];
+    let dateProfile = this.component._getDateProfile()
+    let eventDefId
+    let instanceGroup
+    let eventRanges
+    let bgRanges = []
+    let fgRanges = []
 
     for (eventDefId in eventsPayload) {
-      instanceGroup = eventsPayload[eventDefId];
+      instanceGroup = eventsPayload[eventDefId]
 
       eventRanges = instanceGroup.sliceRenderRanges(
         dateProfile.activeUnzonedRange
-      );
+      )
 
       if (instanceGroup.getEventDef().hasBgRendering()) {
-        bgRanges.push.apply(bgRanges, eventRanges);
-      }
-      else {
-        fgRanges.push.apply(fgRanges, eventRanges);
+        bgRanges.push.apply(bgRanges, eventRanges)
+      } else {
+        fgRanges.push.apply(fgRanges, eventRanges)
       }
     }
 
-    this.renderBgRanges(bgRanges);
-    this.renderFgRanges(fgRanges);
+    this.renderBgRanges(bgRanges)
+    this.renderFgRanges(fgRanges)
   }
 
 
   unrender() {
-    this.unrenderBgRanges();
-    this.unrenderFgRanges();
+    this.unrenderBgRanges()
+    this.unrenderFgRanges()
   }
 
 
   renderFgRanges(eventRanges) {
-    var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
-    var segs = this.component.eventFootprintsToSegs(eventFootprints);
+    let eventFootprints = this.component.eventRangesToEventFootprints(eventRanges)
+    let segs = this.component.eventFootprintsToSegs(eventFootprints)
 
     // render an `.el` on each seg
     // returns a subset of the segs. segs that were actually rendered
-    segs = this.renderFgSegEls(segs);
+    segs = this.renderFgSegEls(segs)
 
     if (this.renderFgSegs(segs) !== false) { // no failure?
-      this.fgSegs = segs;
+      this.fgSegs = segs
     }
   }
 
 
   unrenderFgRanges() {
-    this.unrenderFgSegs(this.fgSegs || []);
-    this.fgSegs = null;
+    this.unrenderFgSegs(this.fgSegs || [])
+    this.fgSegs = null
   }
 
 
   renderBgRanges(eventRanges) {
-    var eventFootprints = this.component.eventRangesToEventFootprints(eventRanges);
-    var segs = this.component.eventFootprintsToSegs(eventFootprints);
+    let eventFootprints = this.component.eventRangesToEventFootprints(eventRanges)
+    let segs = this.component.eventFootprintsToSegs(eventFootprints)
 
     if (this.renderBgSegs(segs) !== false) { // no failure?
-      this.bgSegs = segs;
+      this.bgSegs = segs
     }
   }
 
 
   unrenderBgRanges() {
-    this.unrenderBgSegs();
-    this.bgSegs = null;
+    this.unrenderBgSegs()
+    this.bgSegs = null
   }
 
 
   getSegs() {
-    return (this.bgSegs || []).concat(this.fgSegs || []);
+    return (this.bgSegs || []).concat(this.fgSegs || [])
   }
 
 
   // Renders foreground event segments onto the grid
-  renderFgSegs(segs): (boolean|void) {
+  renderFgSegs(segs): (boolean | void) {
     // subclasses must implement
     // segs already has rendered els, and has been filtered.
 
-    return false; // signal failure if not implemented
+    return false // signal failure if not implemented
   }
 
 
@@ -147,66 +146,65 @@ export default class EventRenderer {
     if (this.fillRenderer) {
       this.fillRenderer.renderSegs('bgEvent', segs, {
         getClasses: (seg) => {
-          return this.getBgClasses(seg.footprint.eventDef);
+          return this.getBgClasses(seg.footprint.eventDef)
         },
         getCss: (seg) => {
           return {
             'background-color': this.getBgColor(seg.footprint.eventDef)
-          };
+          }
         },
         filterEl: (seg, el) => {
-          return this.filterEventRenderEl(seg.footprint, el);
+          return this.filterEventRenderEl(seg.footprint, el)
         }
-      });
-    }
-    else {
-      return false; // signal failure if no fillRenderer
+      })
+    } else {
+      return false // signal failure if no fillRenderer
     }
   }
 
 
   unrenderBgSegs() {
     if (this.fillRenderer) {
-      this.fillRenderer.unrender('bgEvent');
+      this.fillRenderer.unrender('bgEvent')
     }
   }
 
 
   // Renders and assigns an `el` property for each foreground event segment.
   // Only returns segments that successfully rendered.
-  renderFgSegEls(segs, disableResizing=false) {
-    var hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender');
-    var html = '';
-    var renderedSegs = [];
-    var i;
+  renderFgSegEls(segs, disableResizing= false) {
+    let hasEventRenderHandlers = this.view.hasPublicHandlers('eventRender')
+    let html = ''
+    let renderedSegs = []
+    let i
 
     if (segs.length) { // don't build an empty html string
 
       // build a large concatenation of event segment HTML
       for (i = 0; i < segs.length; i++) {
-        this.beforeFgSegHtml(segs[i]);
-        html += this.fgSegHtml(segs[i], disableResizing);
+        this.beforeFgSegHtml(segs[i])
+        html += this.fgSegHtml(segs[i], disableResizing)
       }
 
       // Grab individual elements from the combined HTML string. Use each as the default rendering.
       // Then, compute the 'el' for each segment. An el might be null if the eventRender callback returned false.
       $(html).each((i, node) => {
-        var seg = segs[i];
-        var el = $(node);
+        let seg = segs[i]
+        let el = $(node)
 
         if (hasEventRenderHandlers) { // optimization
-          el = this.filterEventRenderEl(seg.footprint, el);
+          el = this.filterEventRenderEl(seg.footprint, el)
         }
 
         if (el) {
-          el.data('fc-seg', seg); // used by handlers
-          seg.el = el;
-          renderedSegs.push(seg);
+          el.data('fc-seg', seg) // used by handlers
+          seg.el = el
+          renderedSegs.push(seg)
         }
-      });
+      })
     }
 
-    return renderedSegs;
+    return renderedSegs
   }
 
 
@@ -222,46 +220,45 @@ export default class EventRenderer {
 
   // Generic utility for generating the HTML classNames for an event segment's element
   getSegClasses(seg, isDraggable, isResizable) {
-    var classes = [
+    let classes = [
       'fc-event',
       seg.isStart ? 'fc-start' : 'fc-not-start',
       seg.isEnd ? 'fc-end' : 'fc-not-end'
-    ].concat(this.getClasses(seg.footprint.eventDef));
+    ].concat(this.getClasses(seg.footprint.eventDef))
 
     if (isDraggable) {
-      classes.push('fc-draggable');
+      classes.push('fc-draggable')
     }
     if (isResizable) {
-      classes.push('fc-resizable');
+      classes.push('fc-resizable')
     }
 
     // event is currently selected? attach a className.
     if (this.view.isEventDefSelected(seg.footprint.eventDef)) {
-      classes.push('fc-selected');
+      classes.push('fc-selected')
     }
 
-    return classes;
+    return classes
   }
 
 
   // Given an event and the default element used for rendering, returns the element that should actually be used.
   // Basically runs events and elements through the eventRender hook.
   filterEventRenderEl(eventFootprint, el) {
-    var legacy = eventFootprint.getEventLegacy();
+    let legacy = eventFootprint.getEventLegacy()
 
-    var custom = this.view.publiclyTrigger('eventRender', {
+    let custom = this.view.publiclyTrigger('eventRender', {
       context: legacy,
       args: [ legacy, el, this.view ]
-    });
+    })
 
     if (custom === false) { // means don't render at all
-      el = null;
-    }
-    else if (custom && custom !== true) {
-      el = $(custom);
+      el = null
+    } else if (custom && custom !== true) {
+      el = $(custom)
     }
 
-    return el;
+    return el
   }
 
 
@@ -277,17 +274,17 @@ export default class EventRenderer {
       eventFootprint.componentFootprint.isAllDay,
       formatStr,
       displayEnd
-    );
+    )
   }
 
 
   _getTimeText(start, end, isAllDay, formatStr?, displayEnd?) {
     if (formatStr == null) {
-      formatStr = this.eventTimeFormat;
+      formatStr = this.eventTimeFormat
     }
 
     if (displayEnd == null) {
-      displayEnd = this.displayEventEnd;
+      displayEnd = this.displayEventEnd
     }
 
     if (this.displayEventTime && !isAllDay) {
@@ -296,52 +293,51 @@ export default class EventRenderer {
           { start: start, end: end },
           false, // allDay
           formatStr
-        );
-      }
-      else {
-        return start.format(formatStr);
+        )
+      } else {
+        return start.format(formatStr)
       }
     }
 
-    return '';
+    return ''
   }
 
 
   computeEventTimeFormat() {
-    return this.opt('smallTimeFormat');
+    return this.opt('smallTimeFormat')
   }
 
 
   computeDisplayEventTime() {
-    return true;
+    return true
   }
 
 
   computeDisplayEventEnd() {
-    return true;
+    return true
   }
 
 
   getBgClasses(eventDef) {
-    var classNames = this.getClasses(eventDef);
-    classNames.push('fc-bgevent');
-    return classNames;
+    let classNames = this.getClasses(eventDef)
+    classNames.push('fc-bgevent')
+    return classNames
   }
 
 
   getClasses(eventDef) {
-    var objs = this.getStylingObjs(eventDef);
-    var i;
-    var classNames = [];
+    let objs = this.getStylingObjs(eventDef)
+    let i
+    let classNames = []
 
     for (i = 0; i < objs.length; i++) {
       classNames.push.apply( // append
         classNames,
         objs[i].eventClassName || objs[i].className || []
-      );
+      )
     }
 
-    return classNames;
+    return classNames
   }
 
 
@@ -351,90 +347,90 @@ export default class EventRenderer {
       'background-color': this.getBgColor(eventDef),
       'border-color': this.getBorderColor(eventDef),
       color: this.getTextColor(eventDef)
-    };
+    }
   }
 
 
   // Queries for caller-specified color, then falls back to default
   getBgColor(eventDef) {
-    var objs = this.getStylingObjs(eventDef);
-    var i;
-    var val;
+    let objs = this.getStylingObjs(eventDef)
+    let i
+    let val
 
     for (i = 0; i < objs.length && !val; i++) {
       val = objs[i].eventBackgroundColor || objs[i].eventColor ||
-        objs[i].backgroundColor || objs[i].color;
+        objs[i].backgroundColor || objs[i].color
     }
 
     if (!val) {
-      val = this.opt('eventBackgroundColor') || this.opt('eventColor');
+      val = this.opt('eventBackgroundColor') || this.opt('eventColor')
     }
 
-    return val;
+    return val
   }
 
 
   // Queries for caller-specified color, then falls back to default
   getBorderColor(eventDef) {
-    var objs = this.getStylingObjs(eventDef);
-    var i;
-    var val;
+    let objs = this.getStylingObjs(eventDef)
+    let i
+    let val
 
     for (i = 0; i < objs.length && !val; i++) {
       val = objs[i].eventBorderColor || objs[i].eventColor ||
-        objs[i].borderColor || objs[i].color;
+        objs[i].borderColor || objs[i].color
     }
 
     if (!val) {
-      val = this.opt('eventBorderColor') || this.opt('eventColor');
+      val = this.opt('eventBorderColor') || this.opt('eventColor')
     }
 
-    return val;
+    return val
   }
 
 
   // Queries for caller-specified color, then falls back to default
   getTextColor(eventDef) {
-    var objs = this.getStylingObjs(eventDef);
-    var i;
-    var val;
+    let objs = this.getStylingObjs(eventDef)
+    let i
+    let val
 
     for (i = 0; i < objs.length && !val; i++) {
       val = objs[i].eventTextColor ||
-        objs[i].textColor;
+        objs[i].textColor
     }
 
     if (!val) {
-      val = this.opt('eventTextColor');
+      val = this.opt('eventTextColor')
     }
 
-    return val;
+    return val
   }
 
 
   getStylingObjs(eventDef) {
-    var objs = this.getFallbackStylingObjs(eventDef);
-    objs.unshift(eventDef);
-    return objs;
+    let objs = this.getFallbackStylingObjs(eventDef)
+    objs.unshift(eventDef)
+    return objs
   }
 
 
   getFallbackStylingObjs(eventDef) {
-    return [ eventDef.source ];
+    return [ eventDef.source ]
   }
 
 
   sortEventSegs(segs) {
-    segs.sort(proxy(this, 'compareEventSegs'));
+    segs.sort(proxy(this, 'compareEventSegs'))
   }
 
 
   // A cmp function for determining which segments should take visual priority
   compareEventSegs(seg1, seg2) {
-    var f1 = seg1.footprint.componentFootprint;
-    var r1 = f1.unzonedRange;
-    var f2 = seg2.footprint.componentFootprint;
-    var r2 = f2.unzonedRange;
+    let f1 = seg1.footprint.componentFootprint
+    let r1 = f1.unzonedRange
+    let f2 = seg2.footprint.componentFootprint
+    let r2 = f2.unzonedRange
 
     return r1.startMs - r2.startMs || // earlier events go first
       (r2.endMs - r2.startMs) - (r1.endMs - r1.startMs) || // tie? longer events go first
@@ -443,7 +439,7 @@ export default class EventRenderer {
         seg1.footprint.eventDef,
         seg2.footprint.eventDef,
         this.view.eventOrderSpecs
-      );
+      )
   }
 
 }

+ 29 - 30
src/component/renderers/FillRenderer.ts

@@ -10,8 +10,8 @@ export default class FillRenderer { // use for highlight, background events, bus
 
 
   constructor(component) {
-    this.component = component;
-    this.elsByFill = {};
+    this.component = component
+    this.elsByFill = {}
   }
 
 
@@ -20,31 +20,31 @@ export default class FillRenderer { // use for highlight, background events, bus
       type,
       this.component.componentFootprintToSegs(componentFootprint),
       props
-    );
+    )
   }
 
 
   renderSegs(type, segs, props) {
-    var els;
+    let els
 
-    segs = this.buildSegEls(type, segs, props); // assignes `.el` to each seg. returns successfully rendered segs
-    els = this.attachSegEls(type, segs);
+    segs = this.buildSegEls(type, segs, props) // assignes `.el` to each seg. returns successfully rendered segs
+    els = this.attachSegEls(type, segs)
 
     if (els) {
-      this.reportEls(type, els);
+      this.reportEls(type, els)
     }
 
-    return segs;
+    return segs
   }
 
 
   // Unrenders a specific type of fill that is currently rendered on the grid
   unrender(type) {
-    var el = this.elsByFill[type];
+    let el = this.elsByFill[type]
 
     if (el) {
-      el.remove();
-      delete this.elsByFill[type];
+      el.remove()
+      delete this.elsByFill[type]
     }
   }
 
@@ -52,54 +52,54 @@ export default class FillRenderer { // use for highlight, background events, bus
   // Renders and assigns an `el` property for each fill segment. Generic enough to work with different types.
   // Only returns segments that successfully rendered.
   buildSegEls(type, segs, props) {
-    var html = '';
-    var renderedSegs = [];
-    var i;
+    let html = ''
+    let renderedSegs = []
+    let i
 
     if (segs.length) {
 
       // build a large concatenation of segment HTML
       for (i = 0; i < segs.length; i++) {
-        html += this.buildSegHtml(type, segs[i], props);
+        html += this.buildSegHtml(type, segs[i], props)
       }
 
       // Grab individual elements from the combined HTML string. Use each as the default rendering.
       // Then, compute the 'el' for each segment.
       $(html).each((i, node) => {
-        var seg = segs[i];
-        var el = $(node);
+        let seg = segs[i]
+        let el = $(node)
 
         // allow custom filter methods per-type
         if (props.filterEl) {
-          el = props.filterEl(seg, el);
+          el = props.filterEl(seg, el)
         }
 
         if (el) { // custom filters did not cancel the render
-          el = $(el); // allow custom filter to return raw DOM node
+          el = $(el) // allow custom filter to return raw DOM node
 
           // correct element type? (would be bad if a non-TD were inserted into a table for example)
           if (el.is(this.fillSegTag)) {
-            seg.el = el;
-            renderedSegs.push(seg);
+            seg.el = el
+            renderedSegs.push(seg)
           }
         }
-      });
+      })
     }
 
-    return renderedSegs;
+    return renderedSegs
   }
 
 
   // Builds the HTML needed for one fill segment. Generic enough to work with different types.
   buildSegHtml(type, seg, props) {
     // custom hooks per-type
-    var classes = props.getClasses ? props.getClasses(seg) : [];
-    var css = cssToStr(props.getCss ? props.getCss(seg) : {});
+    let classes = props.getClasses ? props.getClasses(seg) : []
+    let css = cssToStr(props.getCss ? props.getCss(seg) : {})
 
     return '<' + this.fillSegTag +
       (classes.length ? ' class="' + classes.join(' ') + '"' : '') +
       (css ? ' style="' + css + '"' : '') +
-      ' />';
+      ' />'
   }
 
 
@@ -111,10 +111,9 @@ export default class FillRenderer { // use for highlight, background events, bus
 
   reportEls(type, nodes) {
     if (this.elsByFill[type]) {
-      this.elsByFill[type] = this.elsByFill[type].add(nodes);
-    }
-    else {
-      this.elsByFill[type] = $(nodes);
+      this.elsByFill[type] = this.elsByFill[type].add(nodes)
+    } else {
+      this.elsByFill[type] = $(nodes)
     }
   }
 

+ 22 - 22
src/component/renderers/HelperRenderer.ts

@@ -12,16 +12,16 @@ export default class HelperRenderer {
 
 
   constructor(component, eventRenderer) {
-    this.view = component._getView();
-    this.component = component;
-    this.eventRenderer = eventRenderer;
+    this.view = component._getView()
+    this.component = component
+    this.eventRenderer = eventRenderer
   }
 
 
   renderComponentFootprint(componentFootprint) {
     this.renderEventFootprints([
       this.fabricateEventFootprint(componentFootprint)
-    ]);
+    ])
   }
 
 
@@ -31,7 +31,7 @@ export default class HelperRenderer {
       sourceSeg,
       'fc-dragging',
       isTouch ? null : this.view.opt('dragOpacity')
-    );
+    )
   }
 
 
@@ -40,29 +40,29 @@ export default class HelperRenderer {
       eventFootprints,
       sourceSeg,
       'fc-resizing'
-    );
+    )
   }
 
 
   renderEventFootprints(eventFootprints, sourceSeg?, extraClassNames?, opacity?) {
-    var segs = this.component.eventFootprintsToSegs(eventFootprints);
-    var classNames = 'fc-helper ' + (extraClassNames || '');
-    var i;
+    let segs = this.component.eventFootprintsToSegs(eventFootprints)
+    let classNames = 'fc-helper ' + (extraClassNames || '')
+    let i
 
     // assigns each seg's el and returns a subset of segs that were rendered
-    segs = this.eventRenderer.renderFgSegEls(segs);
+    segs = this.eventRenderer.renderFgSegEls(segs)
 
     for (i = 0; i < segs.length; i++) {
-      segs[i].el.addClass(classNames);
+      segs[i].el.addClass(classNames)
     }
 
     if (opacity != null) {
       for (i = 0; i < segs.length; i++) {
-        segs[i].el.css('opacity', opacity);
+        segs[i].el.css('opacity', opacity)
       }
     }
 
-    this.helperEls = this.renderSegs(segs, sourceSeg);
+    this.helperEls = this.renderSegs(segs, sourceSeg)
   }
 
 
@@ -76,22 +76,22 @@ export default class HelperRenderer {
 
   unrender() {
     if (this.helperEls) {
-      this.helperEls.remove();
-      this.helperEls = null;
+      this.helperEls.remove()
+      this.helperEls = null
     }
   }
 
 
   fabricateEventFootprint(componentFootprint) {
-    var calendar = this.view.calendar;
-    var eventDateProfile = calendar.footprintToDateProfile(componentFootprint);
-    var dummyEvent = new SingleEventDef(new EventSource(calendar));
-    var dummyInstance;
+    let calendar = this.view.calendar
+    let eventDateProfile = calendar.footprintToDateProfile(componentFootprint)
+    let dummyEvent = new SingleEventDef(new EventSource(calendar))
+    let dummyInstance
 
-    dummyEvent.dateProfile = eventDateProfile;
-    dummyInstance = dummyEvent.buildInstance();
+    dummyEvent.dateProfile = eventDateProfile
+    dummyInstance = dummyEvent.buildInstance()
 
-    return new EventFootprint(componentFootprint, dummyEvent, dummyInstance);
+    return new EventFootprint(componentFootprint, dummyEvent, dummyInstance)
   }
 
 }

+ 117 - 129
src/date-formatting.ts

@@ -12,44 +12,44 @@ import {
 newMomentProto.format = function() {
 
   if (this._fullCalendar && arguments[0]) { // an enhanced moment? and a format string provided?
-    return formatDate(this, arguments[0]); // our extended formatting
+    return formatDate(this, arguments[0]) // our extended formatting
   }
   if (this._ambigTime) {
-    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
+    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD')
   }
   if (this._ambigZone) {
-    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
+    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss')
   }
   if (this._fullCalendar) { // enhanced non-ambig moment?
     // moment.format() doesn't ensure english, but we want to.
-    return oldMomentFormat(englishMoment(this));
+    return oldMomentFormat(englishMoment(this))
   }
 
-  return oldMomentProto.format.apply(this, arguments);
-};
+  return oldMomentProto.format.apply(this, arguments)
+}
 
 newMomentProto.toISOString = function() {
 
   if (this._ambigTime) {
-    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD');
+    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD')
   }
   if (this._ambigZone) {
-    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss');
+    return oldMomentFormat(englishMoment(this), 'YYYY-MM-DD[T]HH:mm:ss')
   }
   if (this._fullCalendar) { // enhanced non-ambig moment?
     // depending on browser, moment might not output english. ensure english.
     // https://github.com/moment/moment/blob/2.18.1/src/lib/moment/format.js#L22
-    return oldMomentProto.toISOString.apply(englishMoment(this), arguments);
+    return oldMomentProto.toISOString.apply(englishMoment(this), arguments)
   }
 
-  return oldMomentProto.toISOString.apply(this, arguments);
-};
+  return oldMomentProto.toISOString.apply(this, arguments)
+}
 
 function englishMoment(mom) {
   if (mom.locale() !== 'en') {
-    return mom.clone().locale('en');
+    return mom.clone().locale('en')
   }
-  return mom;
+  return mom
 }
 
 
@@ -61,46 +61,46 @@ Inserted between chunks in the fake ("intermediate") formatting string.
 Important that it passes as whitespace (\s) because moment often identifies non-standalone months
 via a regexp with an \s.
 */
-var PART_SEPARATOR = '\u000b'; // vertical tab
+let PART_SEPARATOR = '\u000b' // vertical tab
 
 /*
 Inserted as the first character of a literal-text chunk to indicate that the literal text is not actually literal text,
 but rather, a "special" token that has custom rendering (see specialTokens map).
 */
-var SPECIAL_TOKEN_MARKER = '\u001f'; // information separator 1
+let SPECIAL_TOKEN_MARKER = '\u001f' // information separator 1
 
 /*
 Inserted at the beginning and end of a span of text that must have non-zero numeric characters.
 Handling of these markers is done in a post-processing step at the very end of text rendering.
 */
-var MAYBE_MARKER = '\u001e'; // information separator 2
-var MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g'); // must be global
+let MAYBE_MARKER = '\u001e' // information separator 2
+let MAYBE_REGEXP = new RegExp(MAYBE_MARKER + '([^' + MAYBE_MARKER + ']*)' + MAYBE_MARKER, 'g') // must be global
 
 /*
 Addition formatting tokens we want recognized
 */
-var specialTokens = {
+let specialTokens = {
   t: function(date) { // "a" or "p"
-    return oldMomentFormat(date, 'a').charAt(0);
+    return oldMomentFormat(date, 'a').charAt(0)
   },
   T: function(date) { // "A" or "P"
-    return oldMomentFormat(date, 'A').charAt(0);
+    return oldMomentFormat(date, 'A').charAt(0)
   }
-};
+}
 
 /*
 The first characters of formatting tokens for units that are 1 day or larger.
 `value` is for ranking relative size (lower means bigger).
 `unit` is a normalized unit, used for comparing moments.
 */
-var largeTokenMap = {
+let largeTokenMap = {
   Y: { value: 1, unit: 'year' },
   M: { value: 2, unit: 'month' },
   W: { value: 3, unit: 'week' }, // ISO week
   w: { value: 3, unit: 'week' }, // local week
   D: { value: 4, unit: 'day' }, // day of month
   d: { value: 4, unit: 'day' } // day of week
-};
+}
 
 
 // Single Date Formatting
@@ -113,7 +113,7 @@ export function formatDate(date, formatStr) {
   return renderFakeFormatString(
     getParsedFormatString(formatStr).fakeFormatString,
     date
-  );
+  )
 }
 
 
@@ -128,17 +128,17 @@ If the dates are the same as far as the format string is concerned, just return
 rendering of one date, without any separator.
 */
 export function formatRange(date1, date2, formatStr, separator, isRTL) {
-  var localeData;
+  let localeData
 
-  date1 = momentExt.parseZone(date1);
-  date2 = momentExt.parseZone(date2);
+  date1 = momentExt.parseZone(date1)
+  date2 = momentExt.parseZone(date2)
 
-  localeData = date1.localeData();
+  localeData = date1.localeData()
 
   // Expand localized format strings, like "LL" -> "MMMM D YYYY".
   // BTW, this is not important for `formatDate` because it is impossible to put custom tokens
   // or non-zero areas in Moment's localized format strings.
-  formatStr = localeData.longDateFormat(formatStr) || formatStr;
+  formatStr = localeData.longDateFormat(formatStr) || formatStr
 
   return renderParsedFormat(
     getParsedFormatString(formatStr),
@@ -146,28 +146,28 @@ export function formatRange(date1, date2, formatStr, separator, isRTL) {
     date2,
     separator || ' - ',
     isRTL
-  );
+  )
 }
 
 /*
 Renders a range with an already-parsed format string.
 */
 function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
-  var sameUnits = parsedFormat.sameUnits;
-  var unzonedDate1 = date1.clone().stripZone(); // for same-unit comparisons
-  var unzonedDate2 = date2.clone().stripZone(); // "
-
-  var renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1);
-  var renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2);
-
-  var leftI;
-  var leftStr = '';
-  var rightI;
-  var rightStr = '';
-  var middleI;
-  var middleStr1 = '';
-  var middleStr2 = '';
-  var middleStr = '';
+  let sameUnits = parsedFormat.sameUnits
+  let unzonedDate1 = date1.clone().stripZone() // for same-unit comparisons
+  let unzonedDate2 = date2.clone().stripZone() // "
+
+  let renderedParts1 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date1)
+  let renderedParts2 = renderFakeFormatStringParts(parsedFormat.fakeFormatString, date2)
+
+  let leftI
+  let leftStr = ''
+  let rightI
+  let rightStr = ''
+  let middleI
+  let middleStr1 = ''
+  let middleStr2 = ''
+  let middleStr = ''
 
   // Start at the leftmost side of the formatting string and continue until you hit a token
   // that is not the same between dates.
@@ -176,7 +176,7 @@ function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
     leftI < sameUnits.length && (!sameUnits[leftI] || unzonedDate1.isSame(unzonedDate2, sameUnits[leftI]));
     leftI++
   ) {
-    leftStr += renderedParts1[leftI];
+    leftStr += renderedParts1[leftI]
   }
 
   // Similarly, start at the rightmost side of the formatting string and move left
@@ -189,45 +189,44 @@ function renderParsedFormat(parsedFormat, date1, date2, separator, isRTL) {
     // date-formatting postfix character, then don't consume it. Consider it unique date-content.
     // TODO: make configurable
     if (rightI - 1 === leftI && renderedParts1[rightI] === '.') {
-      break;
+      break
     }
 
-    rightStr = renderedParts1[rightI] + rightStr;
+    rightStr = renderedParts1[rightI] + rightStr
   }
 
   // The area in the middle is different for both of the dates.
   // Collect them distinctly so we can jam them together later.
   for (middleI = leftI; middleI <= rightI; middleI++) {
-    middleStr1 += renderedParts1[middleI];
-    middleStr2 += renderedParts2[middleI];
+    middleStr1 += renderedParts1[middleI]
+    middleStr2 += renderedParts2[middleI]
   }
 
   if (middleStr1 || middleStr2) {
     if (isRTL) {
-      middleStr = middleStr2 + separator + middleStr1;
-    }
-    else {
-      middleStr = middleStr1 + separator + middleStr2;
+      middleStr = middleStr2 + separator + middleStr1
+    } else {
+      middleStr = middleStr1 + separator + middleStr2
     }
   }
 
   return processMaybeMarkers(
     leftStr + middleStr + rightStr
-  );
+  )
 }
 
 
 // Format String Parsing
 // ---------------------------------------------------------------------------------------------------------------------
 
-var parsedFormatStrCache = {};
+let parsedFormatStrCache = {}
 
 /*
 Returns a parsed format string, leveraging a cache.
 */
 function getParsedFormatString(formatStr) {
   return parsedFormatStrCache[formatStr] ||
-    (parsedFormatStrCache[formatStr] = parseFormatString(formatStr));
+    (parsedFormatStrCache[formatStr] = parseFormatString(formatStr))
 }
 
 /*
@@ -239,12 +238,12 @@ Parses a format string into the following:
   Always a flat array (not nested liked "chunks").
 */
 function parseFormatString(formatStr) {
-  var chunks = chunkFormatString(formatStr);
+  let chunks = chunkFormatString(formatStr)
 
   return {
     fakeFormatString: buildFakeFormatString(chunks),
     sameUnits: buildSameUnits(chunks)
-  };
+  }
 }
 
 /*
@@ -252,33 +251,30 @@ Break the formatting string into an array of chunks.
 A 'maybe' chunk will have nested chunks.
 */
 function chunkFormatString(formatStr) {
-  var chunks = [];
-  var match;
+  let chunks = []
+  let match
 
   // TODO: more descrimination
   // \4 is a backreference to the first character of a multi-character set.
-  var chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g;
+  let chunker = /\[([^\]]*)\]|\(([^\)]*)\)|(LTS|LT|(\w)\4*o?)|([^\w\[\(]+)/g
 
   while ((match = chunker.exec(formatStr))) {
     if (match[1]) { // a literal string inside [ ... ]
       chunks.push.apply(chunks, // append
         splitStringLiteral(match[1])
-      );
-    }
-    else if (match[2]) { // non-zero formatting inside ( ... )
-      chunks.push({ maybe: chunkFormatString(match[2]) });
-    }
-    else if (match[3]) { // a formatting token
-      chunks.push({ token: match[3] });
-    }
-    else if (match[5]) { // an unenclosed literal string
+      )
+    } else if (match[2]) { // non-zero formatting inside ( ... )
+      chunks.push({ maybe: chunkFormatString(match[2]) })
+    } else if (match[3]) { // a formatting token
+      chunks.push({ token: match[3] })
+    } else if (match[5]) { // an unenclosed literal string
       chunks.push.apply(chunks, // append
         splitStringLiteral(match[5])
-      );
+      )
     }
   }
 
-  return chunks;
+  return chunks
 }
 
 /*
@@ -286,10 +282,9 @@ Potentially splits a literal-text string into multiple parts. For special cases.
 */
 function splitStringLiteral(s) {
   if (s === '. ') {
-    return [ '.', ' ' ]; // for locales with periods bound to the end of each year/month/date
-  }
-  else {
-    return [ s ];
+    return [ '.', ' ' ] // for locales with periods bound to the end of each year/month/date
+  } else {
+    return [ s ]
   }
 }
 
@@ -298,36 +293,33 @@ Given chunks parsed from a real format string, generate a fake (aka "intermediat
 characters that will eventually be given to moment for formatting, and then post-processed.
 */
 function buildFakeFormatString(chunks) {
-  var parts = [];
-  var i, chunk;
+  let parts = []
+  let i, chunk
 
   for (i = 0; i < chunks.length; i++) {
-    chunk = chunks[i];
+    chunk = chunks[i]
 
     if (typeof chunk === 'string') {
-      parts.push('[' + chunk + ']');
-    }
-    else if (chunk.token) {
+      parts.push('[' + chunk + ']')
+    } else if (chunk.token) {
       if (chunk.token in specialTokens) {
         parts.push(
           SPECIAL_TOKEN_MARKER + // useful during post-processing
           '[' + chunk.token + ']' // preserve as literal text
-        );
+        )
+      } else {
+        parts.push(chunk.token) // unprotected text implies a format string
       }
-      else {
-        parts.push(chunk.token); // unprotected text implies a format string
-      }
-    }
-    else if (chunk.maybe) {
+    } else if (chunk.maybe) {
       parts.push(
         MAYBE_MARKER + // useful during post-processing
         buildFakeFormatString(chunk.maybe) +
         MAYBE_MARKER
-      );
+      )
     }
   }
 
-  return parts.join(PART_SEPARATOR);
+  return parts.join(PART_SEPARATOR)
 }
 
 /*
@@ -336,28 +328,26 @@ in which regard two dates must be similar in order to share range formatting tex
 The `chunks` can be nested (because of "maybe" chunks), however, the returned array will be flat.
 */
 function buildSameUnits(chunks) {
-  var units = [];
-  var i, chunk;
-  var tokenInfo;
+  let units = []
+  let i, chunk
+  let tokenInfo
 
   for (i = 0; i < chunks.length; i++) {
-    chunk = chunks[i];
+    chunk = chunks[i]
 
     if (chunk.token) {
-      tokenInfo = largeTokenMap[chunk.token.charAt(0)];
-      units.push(tokenInfo ? tokenInfo.unit : 'second'); // default to a very strict same-second
-    }
-    else if (chunk.maybe) {
+      tokenInfo = largeTokenMap[chunk.token.charAt(0)]
+      units.push(tokenInfo ? tokenInfo.unit : 'second') // default to a very strict same-second
+    } else if (chunk.maybe) {
       units.push.apply(units, // append
         buildSameUnits(chunk.maybe)
-      );
-    }
-    else {
-      units.push(null);
+      )
+    } else {
+      units.push(null)
     }
   }
 
-  return units;
+  return units
 }
 
 
@@ -370,34 +360,33 @@ Formats a date with a fake format string, post-processes the control characters,
 function renderFakeFormatString(fakeFormatString, date) {
   return processMaybeMarkers(
     renderFakeFormatStringParts(fakeFormatString, date).join('')
-  );
+  )
 }
 
 /*
 Formats a date into parts that will have been post-processed, EXCEPT for the "maybe" markers.
 */
 function renderFakeFormatStringParts(fakeFormatString, date) {
-  var parts = [];
-  var fakeRender = oldMomentFormat(date, fakeFormatString);
-  var fakeParts = fakeRender.split(PART_SEPARATOR);
-  var i, fakePart;
+  let parts = []
+  let fakeRender = oldMomentFormat(date, fakeFormatString)
+  let fakeParts = fakeRender.split(PART_SEPARATOR)
+  let i, fakePart
 
   for (i = 0; i < fakeParts.length; i++) {
-    fakePart = fakeParts[i];
+    fakePart = fakeParts[i]
 
     if (fakePart.charAt(0) === SPECIAL_TOKEN_MARKER) {
       parts.push(
         // the literal string IS the token's name.
         // call special token's registered function.
         specialTokens[fakePart.substring(1)](date)
-      );
-    }
-    else {
-      parts.push(fakePart);
+      )
+    } else {
+      parts.push(fakePart)
     }
   }
 
-  return parts;
+  return parts
 }
 
 /*
@@ -406,12 +395,11 @@ Accepts an almost-finally-formatted string and processes the "maybe" control cha
 function processMaybeMarkers(s) {
   return s.replace(MAYBE_REGEXP, function(m0, m1) { // regex assumed to have 'g' flag
     if (m1.match(/[1-9]/)) { // any non-zero numeric characters?
-      return m1;
-    }
-    else {
-      return '';
+      return m1
+    } else {
+      return ''
     }
-  });
+  })
 }
 
 
@@ -422,27 +410,27 @@ function processMaybeMarkers(s) {
 Returns a unit string, either 'year', 'month', 'day', or null for the most granular formatting token in the string.
 */
 export function queryMostGranularFormatUnit(formatStr) {
-  var chunks = chunkFormatString(formatStr);
-  var i, chunk;
-  var candidate;
-  var best;
+  let chunks = chunkFormatString(formatStr)
+  let i, chunk
+  let candidate
+  let best
 
   for (i = 0; i < chunks.length; i++) {
-    chunk = chunks[i];
+    chunk = chunks[i]
 
     if (chunk.token) {
-      candidate = largeTokenMap[chunk.token.charAt(0)];
+      candidate = largeTokenMap[chunk.token.charAt(0)]
       if (candidate) {
         if (!best || candidate.value > best.value) {
-          best = candidate;
+          best = candidate
         }
       }
     }
   }
 
   if (best) {
-    return best.unit;
+    return best.unit
   }
 
-  return null;
+  return null
 }

+ 3 - 3
src/exports.ts

@@ -1,10 +1,10 @@
 
-export const version = "<%= version %>";
+export const version = '<%= version %>'
 
 // When introducing internal API incompatibilities (where fullcalendar plugins would break),
 // the minor version of the calendar should be upped (ex: 2.7.2 -> 2.8.0)
 // and the below integer should be incremented.
-export const internalApiVersion = 12;
+export const internalApiVersion = 12
 
 export {
   applyAll,
@@ -45,7 +45,7 @@ export {
   locale
 } from './locale'
 
-export { default as moment } from './moment-ext';
+export { default as moment } from './moment-ext'
 export { default as EmitterMixin, EmitterInterface } from './common/EmitterMixin'
 export { default as ListenerMixin, ListenerInterface } from './common/ListenerMixin'
 export { default as Model } from './common/Model'

+ 4 - 4
src/list/ListEventPointing.ts

@@ -7,16 +7,16 @@ export default class ListEventPointing extends EventPointing {
   // for events with a url, the whole <tr> should be clickable,
   // but it's impossible to wrap with an <a> tag. simulate this.
   handleClick(seg, ev) {
-    var url;
+    let url
 
-    super.handleClick(seg, ev); // might prevent the default action
+    super.handleClick(seg, ev) // might prevent the default action
 
     // not clicking on or within an <a> with an href
     if (!$(ev.target).closest('a[href]').length) {
-      url = seg.footprint.eventDef.url;
+      url = seg.footprint.eventDef.url
 
       if (url && !ev.isDefaultPrevented()) { // jsEvent not cancelled in handler
-        window.location.href = url; // simulate link click
+        window.location.href = url // simulate link click
       }
     }
   }

+ 23 - 28
src/list/ListEventRenderer.ts

@@ -5,49 +5,44 @@ export default class ListEventRenderer extends EventRenderer {
 
   renderFgSegs(segs) {
     if (!segs.length) {
-      this.component.renderEmptyMessage();
-    }
-    else {
-      this.component.renderSegList(segs);
+      this.component.renderEmptyMessage()
+    } else {
+      this.component.renderSegList(segs)
     }
   }
 
   // generates the HTML for a single event row
   fgSegHtml(seg) {
-    var view = this.view;
-    var calendar = view.calendar;
-    var theme = calendar.theme;
-    var eventFootprint = seg.footprint;
-    var eventDef = eventFootprint.eventDef;
-    var componentFootprint = eventFootprint.componentFootprint;
-    var url = eventDef.url;
-    var classes = [ 'fc-list-item' ].concat(this.getClasses(eventDef));
-    var bgColor = this.getBgColor(eventDef);
-    var timeHtml;
+    let view = this.view
+    let calendar = view.calendar
+    let theme = calendar.theme
+    let eventFootprint = seg.footprint
+    let eventDef = eventFootprint.eventDef
+    let componentFootprint = eventFootprint.componentFootprint
+    let url = eventDef.url
+    let classes = [ 'fc-list-item' ].concat(this.getClasses(eventDef))
+    let bgColor = this.getBgColor(eventDef)
+    let timeHtml
 
     if (componentFootprint.isAllDay) {
-      timeHtml = view.getAllDayHtml();
-    }
-    // if the event appears to span more than one day
-    else if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
+      timeHtml = view.getAllDayHtml()
+    } else if (view.isMultiDayRange(componentFootprint.unzonedRange)) {
       if (seg.isStart || seg.isEnd) { // outer segment that probably lasts part of the day
         timeHtml = htmlEscape(this._getTimeText(
           calendar.msToMoment(seg.startMs),
           calendar.msToMoment(seg.endMs),
           componentFootprint.isAllDay
-        ));
+        ))
+      } else { // inner segment that lasts the whole day
+        timeHtml = view.getAllDayHtml()
       }
-      else { // inner segment that lasts the whole day
-        timeHtml = view.getAllDayHtml();
-      }
-    }
-    else {
+    } else {
       // Display the normal time text for the *event's* times
-      timeHtml = htmlEscape(this.getTimeText(eventFootprint));
+      timeHtml = htmlEscape(this.getTimeText(eventFootprint))
     }
 
     if (url) {
-      classes.push('fc-has-url');
+      classes.push('fc-has-url')
     }
 
     return '<tr class="' + classes.join(' ') + '">' +
@@ -68,13 +63,13 @@ export default class ListEventRenderer extends EventRenderer {
           htmlEscape(eventDef.title || '') +
         '</a>' +
       '</td>' +
-    '</tr>';
+    '</tr>'
   }
 
 
   // like "4:00am"
   computeEventTimeFormat() {
-    return this.opt('mediumTimeFormat');
+    return this.opt('mediumTimeFormat')
   }
 
 }

+ 50 - 50
src/list/ListView.ts

@@ -25,12 +25,12 @@ export default class ListView extends View {
 
 
   constructor(calendar, viewSpec) {
-    super(calendar, viewSpec);
+    super(calendar, viewSpec)
 
     this.scroller = new Scroller({
       overflowX: 'hidden',
       overflowY: 'auto'
-    });
+    })
   }
 
 
@@ -38,52 +38,52 @@ export default class ListView extends View {
     this.el.addClass(
       'fc-list-view ' +
       this.calendar.theme.getClass('listView')
-    );
+    )
 
-    this.scroller.render();
-    this.scroller.el.appendTo(this.el);
+    this.scroller.render()
+    this.scroller.el.appendTo(this.el)
 
-    this.contentEl = this.scroller.scrollEl; // shortcut
+    this.contentEl = this.scroller.scrollEl // shortcut
   }
 
 
   unrenderSkeleton() {
-    this.scroller.destroy(); // will remove the Grid too
+    this.scroller.destroy() // will remove the Grid too
   }
 
 
   updateSize(totalHeight, isAuto, isResize) {
-    this.scroller.setHeight(this.computeScrollerHeight(totalHeight));
+    this.scroller.setHeight(this.computeScrollerHeight(totalHeight))
   }
 
 
   computeScrollerHeight(totalHeight) {
     return totalHeight -
-      subtractInnerElHeight(this.el, this.scroller.el); // everything that's NOT the scroller
+      subtractInnerElHeight(this.el, this.scroller.el) // everything that's NOT the scroller
   }
 
 
   renderDates(dateProfile) {
-    var calendar = this.calendar;
-    var dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true);
-    var viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true);
-    var dayDates = [];
-    var dayRanges = [];
+    let calendar = this.calendar
+    let dayStart = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.startMs, true)
+    let viewEnd = calendar.msToUtcMoment(dateProfile.renderUnzonedRange.endMs, true)
+    let dayDates = []
+    let dayRanges = []
 
     while (dayStart < viewEnd) {
 
-      dayDates.push(dayStart.clone());
+      dayDates.push(dayStart.clone())
 
       dayRanges.push(new UnzonedRange(
         dayStart,
         dayStart.clone().add(1, 'day')
-      ));
+      ))
 
-      dayStart.add(1, 'day');
+      dayStart.add(1, 'day')
     }
 
-    this.dayDates = dayDates;
-    this.dayRanges = dayRanges;
+    this.dayDates = dayDates
+    this.dayRanges = dayRanges
 
     // all real rendering happens in EventRenderer
   }
@@ -91,14 +91,14 @@ export default class ListView extends View {
 
   // slices by day
   componentFootprintToSegs(footprint) {
-    var dayRanges = this.dayRanges;
-    var dayIndex;
-    var segRange;
-    var seg;
-    var segs = [];
+    let dayRanges = this.dayRanges
+    let dayIndex
+    let segRange
+    let seg
+    let segs = []
 
     for (dayIndex = 0; dayIndex < dayRanges.length; dayIndex++) {
-      segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex]);
+      segRange = footprint.unzonedRange.intersect(dayRanges[dayIndex])
 
       if (segRange) {
         seg = {
@@ -107,9 +107,9 @@ export default class ListView extends View {
           isStart: segRange.isStart,
           isEnd: segRange.isEnd,
           dayIndex: dayIndex
-        };
+        }
 
-        segs.push(seg);
+        segs.push(seg)
 
         // detect when footprint won't go fully into the next day,
         // and mutate the latest seg to the be the end.
@@ -118,14 +118,14 @@ export default class ListView extends View {
           dayIndex + 1 < dayRanges.length &&
           footprint.unzonedRange.endMs < dayRanges[dayIndex + 1].startMs + this.nextDayThreshold
         ) {
-          seg.endMs = footprint.unzonedRange.endMs;
-          seg.isEnd = true;
-          break;
+          seg.endMs = footprint.unzonedRange.endMs
+          seg.isEnd = true
+          break
         }
       }
     }
 
-    return segs;
+    return segs
   }
 
 
@@ -138,58 +138,58 @@ export default class ListView extends View {
       '</div>' +
       '</div>' +
       '</div>'
-    );
+    )
   }
 
 
   // render the event segments in the view
   renderSegList(allSegs) {
-    var segsByDay = this.groupSegsByDay(allSegs); // sparse array
-    var dayIndex;
-    var daySegs;
-    var i;
-    var tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody/></table>');
-    var tbodyEl = tableEl.find('tbody');
+    let segsByDay = this.groupSegsByDay(allSegs) // sparse array
+    let dayIndex
+    let daySegs
+    let i
+    let tableEl = $('<table class="fc-list-table ' + this.calendar.theme.getClass('tableList') + '"><tbody/></table>')
+    let tbodyEl = tableEl.find('tbody')
 
     for (dayIndex = 0; dayIndex < segsByDay.length; dayIndex++) {
-      daySegs = segsByDay[dayIndex];
+      daySegs = segsByDay[dayIndex]
 
       if (daySegs) { // sparse array, so might be undefined
 
         // append a day header
-        tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex]));
+        tbodyEl.append(this.dayHeaderHtml(this.dayDates[dayIndex]))
 
-        this.eventRenderer.sortEventSegs(daySegs);
+        this.eventRenderer.sortEventSegs(daySegs)
 
         for (i = 0; i < daySegs.length; i++) {
-          tbodyEl.append(daySegs[i].el); // append event row
+          tbodyEl.append(daySegs[i].el) // append event row
         }
       }
     }
 
-    this.contentEl.empty().append(tableEl);
+    this.contentEl.empty().append(tableEl)
   }
 
 
   // Returns a sparse array of arrays, segs grouped by their dayIndex
   groupSegsByDay(segs) {
-    var segsByDay = []; // sparse array
-    var i, seg;
+    let segsByDay = [] // sparse array
+    let i, seg
 
     for (i = 0; i < segs.length; i++) {
       seg = segs[i];
       (segsByDay[seg.dayIndex] || (segsByDay[seg.dayIndex] = []))
-        .push(seg);
+        .push(seg)
     }
 
-    return segsByDay;
+    return segsByDay
   }
 
 
   // generates the HTML for the day headers that live amongst the event rows
   dayHeaderHtml(dayDate) {
-    var mainFormat = this.opt('listDayFormat');
-    var altFormat = this.opt('listDayAltFormat');
+    let mainFormat = this.opt('listDayFormat')
+    let altFormat = this.opt('listDayAltFormat')
 
     return '<tr class="fc-list-heading" data-date="' + dayDate.format('YYYY-MM-DD') + '">' +
       '<td class="' + this.calendar.theme.getClass('widgetHeader') + '" colspan="3">' +
@@ -208,7 +208,7 @@ export default class ListView extends View {
           ) :
           '') +
       '</td>' +
-    '</tr>';
+    '</tr>'
   }
 
 }

+ 5 - 5
src/list/config.ts

@@ -9,7 +9,7 @@ defineView('list', {
     listDayFormat: 'LL', // like "January 1, 2016"
     noEventsMessage: 'No events to display'
   }
-});
+})
 
 defineView('listDay', {
   type: 'list',
@@ -17,7 +17,7 @@ defineView('listDay', {
   defaults: {
     listDayFormat: 'dddd' // day-of-week is all we need. full date is probably in header
   }
-});
+})
 
 defineView('listWeek', {
   type: 'list',
@@ -26,7 +26,7 @@ defineView('listWeek', {
     listDayFormat: 'dddd', // day-of-week is more important
     listDayAltFormat: 'LL'
   }
-});
+})
 
 defineView('listMonth', {
   type: 'list',
@@ -34,7 +34,7 @@ defineView('listMonth', {
   defaults: {
     listDayAltFormat: 'dddd' // day-of-week is nice-to-have
   }
-});
+})
 
 defineView('listYear', {
   type: 'list',
@@ -42,4 +42,4 @@ defineView('listYear', {
   defaults: {
     listDayAltFormat: 'dddd' // day-of-week is nice-to-have
   }
-});
+})

+ 45 - 46
src/locale.ts

@@ -5,25 +5,25 @@ import { mergeOptions, globalDefaults, englishDefaults } from './options'
 import { stripHtmlEntities } from './util'
 
 export const localeOptionHash = {};
-(exportHooks as any).locales = localeOptionHash;
+(exportHooks as any).locales = localeOptionHash
 
 // Initialize jQuery UI datepicker translations while using some of the translations
 // Will set this as the default locales for datepicker.
 export function datepickerLocale(localeCode, dpLocaleCode, dpOptions) {
 
   // get the FullCalendar internal option hash for this locale. create if necessary
-  var fcOptions = localeOptionHash[localeCode] || (localeOptionHash[localeCode] = {});
+  let fcOptions = localeOptionHash[localeCode] || (localeOptionHash[localeCode] = {})
 
   // transfer some simple options from datepicker to fc
-  fcOptions.isRTL = dpOptions.isRTL;
-  fcOptions.weekNumberTitle = dpOptions.weekHeader;
+  fcOptions.isRTL = dpOptions.isRTL
+  fcOptions.weekNumberTitle = dpOptions.weekHeader
 
   // compute some more complex options from datepicker
   $.each(dpComputableOptions, function(name, func) {
-    fcOptions[name] = func(dpOptions);
-  });
+    fcOptions[name] = func(dpOptions)
+  })
 
-  var jqDatePicker = ($ as any).datepicker;
+  let jqDatePicker = ($ as any).datepicker
 
   // is jQuery UI Datepicker is on the page?
   if (jqDatePicker) {
@@ -34,48 +34,48 @@ export function datepickerLocale(localeCode, dpLocaleCode, dpOptions) {
     // Make an alias so the locale can be referenced either way.
     jqDatePicker.regional[dpLocaleCode] =
       jqDatePicker.regional[localeCode] = // alias
-        dpOptions;
+        dpOptions
 
     // Alias 'en' to the default locale data. Do this every time.
-    jqDatePicker.regional.en = jqDatePicker.regional[''];
+    jqDatePicker.regional.en = jqDatePicker.regional['']
 
     // Set as Datepicker's global defaults.
-    jqDatePicker.setDefaults(dpOptions);
+    jqDatePicker.setDefaults(dpOptions)
   }
 }
 
 
 // Sets FullCalendar-specific translations. Will set the locales as the global default.
 export function locale(localeCode, newFcOptions) {
-  var fcOptions;
-  var momOptions;
+  let fcOptions
+  let momOptions
 
   // get the FullCalendar internal option hash for this locale. create if necessary
-  fcOptions = localeOptionHash[localeCode] || (localeOptionHash[localeCode] = {});
+  fcOptions = localeOptionHash[localeCode] || (localeOptionHash[localeCode] = {})
 
   // provided new options for this locales? merge them in
   if (newFcOptions) {
-    fcOptions = localeOptionHash[localeCode] = mergeOptions([ fcOptions, newFcOptions ]);
+    fcOptions = localeOptionHash[localeCode] = mergeOptions([ fcOptions, newFcOptions ])
   }
 
   // compute locale options that weren't defined.
   // always do this. newFcOptions can be undefined when initializing from i18n file,
   // so no way to tell if this is an initialization or a default-setting.
-  momOptions = getMomentLocaleData(localeCode); // will fall back to en
+  momOptions = getMomentLocaleData(localeCode) // will fall back to en
   $.each(momComputableOptions, function(name, func) {
     if (fcOptions[name] == null) {
-      fcOptions[name] = (func as any)(momOptions, fcOptions);
+      fcOptions[name] = (func)(momOptions, fcOptions)
     }
-  });
+  })
 
   // set it as the default locale for FullCalendar
-  globalDefaults.locale = localeCode;
-};
+  globalDefaults.locale = localeCode
+}
 
 
 // NOTE: can't guarantee any of these computations will run because not every locale has datepicker
 // configs, so make sure there are English fallbacks for these in the defaults file.
-var dpComputableOptions = {
+let dpComputableOptions = {
 
   buttonText: function(dpOptions) {
     return {
@@ -83,40 +83,39 @@ var dpComputableOptions = {
       prev: stripHtmlEntities(dpOptions.prevText),
       next: stripHtmlEntities(dpOptions.nextText),
       today: stripHtmlEntities(dpOptions.currentText)
-    };
+    }
   },
 
   // Produces format strings like "MMMM YYYY" -> "September 2014"
   monthYearFormat: function(dpOptions) {
     return dpOptions.showMonthAfterYear ?
       'YYYY[' + dpOptions.yearSuffix + '] MMMM' :
-      'MMMM YYYY[' + dpOptions.yearSuffix + ']';
+      'MMMM YYYY[' + dpOptions.yearSuffix + ']'
   }
 
-};
+}
 
-var momComputableOptions = {
+let momComputableOptions = {
 
   // Produces format strings like "ddd M/D" -> "Fri 9/15"
   dayOfMonthFormat: function(momOptions, fcOptions) {
-    var format = momOptions.longDateFormat('l'); // for the format like "M/D/YYYY"
+    let format = momOptions.longDateFormat('l') // for the format like "M/D/YYYY"
 
     // strip the year off the edge, as well as other misc non-whitespace chars
-    format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '');
+    format = format.replace(/^Y+[^\w\s]*|[^\w\s]*Y+$/g, '')
 
     if (fcOptions.isRTL) {
-      format += ' ddd'; // for RTL, add day-of-week to end
+      format += ' ddd' // for RTL, add day-of-week to end
+    } else {
+      format = 'ddd ' + format // for LTR, add day-of-week to beginning
     }
-    else {
-      format = 'ddd ' + format; // for LTR, add day-of-week to beginning
-    }
-    return format;
+    return format
   },
 
   // Produces format strings like "h:mma" -> "6:00pm"
   mediumTimeFormat: function(momOptions) { // can't be called `timeFormat` because collides with option
     return momOptions.longDateFormat('LT')
-      .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
+      .replace(/\s*a$/i, 'a') // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
   },
 
   // Produces format strings like "h(:mm)a" -> "6pm" / "6:30pm"
@@ -124,7 +123,7 @@ var momComputableOptions = {
     return momOptions.longDateFormat('LT')
       .replace(':mm', '(:mm)')
       .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
-      .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
+      .replace(/\s*a$/i, 'a') // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
   },
 
   // Produces format strings like "h(:mm)t" -> "6p" / "6:30p"
@@ -132,7 +131,7 @@ var momComputableOptions = {
     return momOptions.longDateFormat('LT')
       .replace(':mm', '(:mm)')
       .replace(/(\Wmm)$/, '($1)') // like above, but for foreign locales
-      .replace(/\s*a$/i, 't'); // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
+      .replace(/\s*a$/i, 't') // convert to AM/PM/am/pm to lowercase one-letter. remove any spaces beforehand
   },
 
   // Produces format strings like "ha" / "H" -> "6pm" / "18"
@@ -140,62 +139,62 @@ var momComputableOptions = {
     return momOptions.longDateFormat('LT')
       .replace(':mm', '')
       .replace(/(\Wmm)$/, '') // like above, but for foreign locales
-      .replace(/\s*a$/i, 'a'); // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
+      .replace(/\s*a$/i, 'a') // convert AM/PM/am/pm to lowercase. remove any spaces beforehand
   },
 
   // Produces format strings like "h:mm" -> "6:30" (with no AM/PM)
   noMeridiemTimeFormat: function(momOptions) {
     return momOptions.longDateFormat('LT')
-      .replace(/\s*a$/i, ''); // remove trailing AM/PM
+      .replace(/\s*a$/i, '') // remove trailing AM/PM
   }
 
-};
+}
 
 
 // options that should be computed off live calendar options (considers override options)
 // TODO: best place for this? related to locale?
 // TODO: flipping text based on isRTL is a bad idea because the CSS `direction` might want to handle it
-var instanceComputableOptions = {
+let instanceComputableOptions = {
 
   // Produces format strings for results like "Mo 16"
   smallDayDateFormat: function(options) {
     return options.isRTL ?
       'D dd' :
-      'dd D';
+      'dd D'
   },
 
   // Produces format strings for results like "Wk 5"
   weekFormat: function(options) {
     return options.isRTL ?
       'w[ ' + options.weekNumberTitle + ']' :
-      '[' + options.weekNumberTitle + ' ]w';
+      '[' + options.weekNumberTitle + ' ]w'
   },
 
   // Produces format strings for results like "Wk5"
   smallWeekFormat: function(options) {
     return options.isRTL ?
       'w[' + options.weekNumberTitle + ']' :
-      '[' + options.weekNumberTitle + ']w';
+      '[' + options.weekNumberTitle + ']w'
   }
 
-};
+}
 
 // TODO: make these computable properties in optionsManager
 export function populateInstanceComputableOptions(options) {
   $.each(instanceComputableOptions, function(name, func) {
     if (options[name] == null) {
-      options[name] = func(options);
+      options[name] = func(options)
     }
-  });
+  })
 }
 
 
 // Returns moment's internal locale data. If doesn't exist, returns English.
 export function getMomentLocaleData(localeCode) {
-  return moment.localeData(localeCode) || moment.localeData('en');
+  return moment.localeData(localeCode) || moment.localeData('en')
 }
 
 
 // Initialize English by forcing computation of moment-derived options.
 // Also, sets it as the default.
-locale('en', englishDefaults);
+locale('en', englishDefaults)

+ 26 - 32
src/main.ts

@@ -22,57 +22,51 @@ declare global {
 }
 
 
-($ as JQueryStatic).fullCalendar = exportHooks;
-export = exportHooks;
+($).fullCalendar = exportHooks
+export = exportHooks
 
 
 $.fn.fullCalendar = function(options?): (JQuery | any) {
-  var args = Array.prototype.slice.call(arguments, 1); // for a possible method call
-  var res = this; // what this function will return (this jQuery object by default)
+  let args = Array.prototype.slice.call(arguments, 1) // for a possible method call
+  let res = this // what this function will return (this jQuery object by default)
 
   this.each(function(i, _element) { // loop each DOM element involved
-    var element = $(_element);
-    var calendar = element.data('fullCalendar'); // get the existing calendar object (if any)
-    var singleRes; // the returned value of this single method call
+    let element = $(_element)
+    let calendar = element.data('fullCalendar') // get the existing calendar object (if any)
+    let singleRes // the returned value of this single method call
 
     // a method call
     if (typeof options === 'string') {
 
       if (options === 'getCalendar') {
         if (!i) { // first element only
-          res = calendar;
+          res = calendar
         }
-      }
-      else if (options === 'destroy') { // don't warn if no calendar object
+      } else if (options === 'destroy') { // don't warn if no calendar object
         if (calendar) {
-          calendar.destroy();
-          element.removeData('fullCalendar');
+          calendar.destroy()
+          element.removeData('fullCalendar')
         }
-      }
-      else if (!calendar) {
-        warn("Attempting to call a FullCalendar method on an element with no calendar.");
-      }
-      else if ($.isFunction(calendar[options])) {
-        singleRes = calendar[options].apply(calendar, args);
+      } else if (!calendar) {
+        warn('Attempting to call a FullCalendar method on an element with no calendar.')
+      } else if ($.isFunction(calendar[options])) {
+        singleRes = calendar[options].apply(calendar, args)
 
         if (!i) {
-          res = singleRes; // record the first method call result
+          res = singleRes // record the first method call result
         }
         if (options === 'destroy') { // for the destroy method, must remove Calendar object data
-          element.removeData('fullCalendar');
+          element.removeData('fullCalendar')
         }
+      } else {
+        warn("'" + options + "' is an unknown FullCalendar method.")
       }
-      else {
-        warn("'" + options + "' is an unknown FullCalendar method.");
-      }
-    }
-    // a new calendar initialization
-    else if (!calendar) { // don't initialize twice
-      calendar = new Calendar(element, options);
-      element.data('fullCalendar', calendar);
-      calendar.render();
+    } else if (!calendar) { // don't initialize twice
+      calendar = new Calendar(element, options)
+      element.data('fullCalendar', calendar)
+      calendar.render()
     }
-  });
+  })
 
-  return res;
-};
+  return res
+}

+ 26 - 28
src/models/BusinessHourGenerator.ts

@@ -5,13 +5,13 @@ import RecurringEventDef from './event/RecurringEventDef'
 import EventSource from './event-source/EventSource'
 
 
-var BUSINESS_HOUR_EVENT_DEFAULTS = {
+let BUSINESS_HOUR_EVENT_DEFAULTS = {
   start: '09:00',
   end: '17:00',
   dow: [ 1, 2, 3, 4, 5 ], // monday - friday
   rendering: 'inverse-background'
   // classNames are defined in businessHoursSegClasses
-};
+}
 
 
 export default class BusinessHourGenerator {
@@ -21,70 +21,68 @@ export default class BusinessHourGenerator {
 
 
   constructor(rawComplexDef, calendar) {
-    this.rawComplexDef = rawComplexDef;
-    this.calendar = calendar;
+    this.rawComplexDef = rawComplexDef
+    this.calendar = calendar
   }
 
 
   buildEventInstanceGroup(isAllDay, unzonedRange) {
-    var eventDefs = this.buildEventDefs(isAllDay);
-    var eventInstanceGroup;
+    let eventDefs = this.buildEventDefs(isAllDay)
+    let eventInstanceGroup
 
     if (eventDefs.length) {
       eventInstanceGroup = new EventInstanceGroup(
         eventDefsToEventInstances(eventDefs, unzonedRange)
-      );
+      )
 
       // so that inverse-background rendering can happen even when no eventRanges in view
-      eventInstanceGroup.explicitEventDef = eventDefs[0];
+      eventInstanceGroup.explicitEventDef = eventDefs[0]
 
-      return eventInstanceGroup;
+      return eventInstanceGroup
     }
   }
 
 
   buildEventDefs(isAllDay) {
-    var rawComplexDef = this.rawComplexDef;
-    var rawDefs = [];
-    var requireDow = false;
-    var i;
-    var defs = [];
+    let rawComplexDef = this.rawComplexDef
+    let rawDefs = []
+    let requireDow = false
+    let i
+    let defs = []
 
     if (rawComplexDef === true) {
-      rawDefs = [ {} ]; // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
-    }
-    else if ($.isPlainObject(rawComplexDef)) {
-      rawDefs = [ rawComplexDef ];
-    }
-    else if ($.isArray(rawComplexDef)) {
-      rawDefs = rawComplexDef;
-      requireDow = true; // every sub-definition NEEDS a day-of-week
+      rawDefs = [ {} ] // will get BUSINESS_HOUR_EVENT_DEFAULTS verbatim
+    } else if ($.isPlainObject(rawComplexDef)) {
+      rawDefs = [ rawComplexDef ]
+    } else if ($.isArray(rawComplexDef)) {
+      rawDefs = rawComplexDef
+      requireDow = true // every sub-definition NEEDS a day-of-week
     }
 
     for (i = 0; i < rawDefs.length; i++) {
       if (!requireDow || rawDefs[i].dow) {
         defs.push(
           this.buildEventDef(isAllDay, rawDefs[i])
-        );
+        )
       }
     }
 
-    return defs;
+    return defs
   }
 
 
   buildEventDef(isAllDay, rawDef) {
-    var fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef);
+    let fullRawDef = $.extend({}, BUSINESS_HOUR_EVENT_DEFAULTS, rawDef)
 
     if (isAllDay) {
-      fullRawDef.start = null;
-      fullRawDef.end = null;
+      fullRawDef.start = null
+      fullRawDef.end = null
     }
 
     return RecurringEventDef.parse(
       fullRawDef,
       new EventSource(this.calendar) // dummy source
-    );
+    )
   }
 
 }

+ 3 - 3
src/models/ComponentFootprint.ts

@@ -9,8 +9,8 @@ export default class ComponentFootprint {
 
 
   constructor(unzonedRange, isAllDay) {
-    this.unzonedRange = unzonedRange;
-    this.isAllDay = isAllDay;
+    this.unzonedRange = unzonedRange
+    this.isAllDay = isAllDay
   }
 
 
@@ -21,7 +21,7 @@ export default class ComponentFootprint {
     return {
       start: calendar.msToMoment(this.unzonedRange.startMs, this.isAllDay),
       end: calendar.msToMoment(this.unzonedRange.endMs, this.isAllDay)
-    };
+    }
   }
 
 }

+ 87 - 88
src/models/EventManager.ts

@@ -29,9 +29,9 @@ export default class EventManager {
 
 
   constructor(calendar) {
-    this.calendar = calendar;
-    this.stickySource = new ArrayEventSource(calendar);
-    this.otherSources = [];
+    this.calendar = calendar
+    this.stickySource = new ArrayEventSource(calendar)
+    this.otherSources = []
   }
 
 
@@ -44,10 +44,10 @@ export default class EventManager {
     ) {
       this.setPeriod( // will change this.currentPeriod
         new EventPeriod(start, end, timezone)
-      );
+      )
     }
 
-    return this.currentPeriod.whenReleased();
+    return this.currentPeriod.whenReleased()
   }
 
 
@@ -56,28 +56,28 @@ export default class EventManager {
 
 
   addSource(eventSource) {
-    this.otherSources.push(eventSource);
+    this.otherSources.push(eventSource)
 
     if (this.currentPeriod) {
-      this.currentPeriod.requestSource(eventSource); // might release
+      this.currentPeriod.requestSource(eventSource) // might release
     }
   }
 
 
   removeSource(doomedSource) {
-    removeExact(this.otherSources, doomedSource);
+    removeExact(this.otherSources, doomedSource)
 
     if (this.currentPeriod) {
-      this.currentPeriod.purgeSource(doomedSource); // might release
+      this.currentPeriod.purgeSource(doomedSource) // might release
     }
   }
 
 
   removeAllSources() {
-    this.otherSources = [];
+    this.otherSources = []
 
     if (this.currentPeriod) {
-      this.currentPeriod.purgeAllSources(); // might release
+      this.currentPeriod.purgeAllSources() // might release
     }
   }
 
@@ -87,25 +87,25 @@ export default class EventManager {
 
 
   refetchSource(eventSource) {
-    var currentPeriod = this.currentPeriod;
+    let currentPeriod = this.currentPeriod
 
     if (currentPeriod) {
-      currentPeriod.freeze();
-      currentPeriod.purgeSource(eventSource);
-      currentPeriod.requestSource(eventSource);
-      currentPeriod.thaw();
+      currentPeriod.freeze()
+      currentPeriod.purgeSource(eventSource)
+      currentPeriod.requestSource(eventSource)
+      currentPeriod.thaw()
     }
   }
 
 
   refetchAllSources() {
-    var currentPeriod = this.currentPeriod;
+    let currentPeriod = this.currentPeriod
 
     if (currentPeriod) {
-      currentPeriod.freeze();
-      currentPeriod.purgeAllSources();
-      currentPeriod.requestSources(this.getSources());
-      currentPeriod.thaw();
+      currentPeriod.freeze()
+      currentPeriod.purgeAllSources()
+      currentPeriod.requestSources(this.getSources())
+      currentPeriod.thaw()
     }
   }
 
@@ -115,7 +115,7 @@ export default class EventManager {
 
 
   getSources() {
-    return [ this.stickySource ].concat(this.otherSources);
+    return [ this.stickySource ].concat(this.otherSources)
   }
 
 
@@ -124,55 +124,54 @@ export default class EventManager {
 
     // coerce into an array
     if (!matchInputs) {
-      matchInputs = [];
-    }
-    else if (!$.isArray(matchInputs)) {
-      matchInputs = [ matchInputs ];
+      matchInputs = []
+    } else if (!$.isArray(matchInputs)) {
+      matchInputs = [ matchInputs ]
     }
 
-    var matchingSources = [];
-    var i;
+    let matchingSources = []
+    let i
 
     // resolve raw inputs to real event source objects
     for (i = 0; i < matchInputs.length; i++) {
       matchingSources.push.apply( // append
         matchingSources,
         this.querySources(matchInputs[i])
-      );
+      )
     }
 
-    return matchingSources;
+    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.
   querySources(matchInput) {
-    var sources = this.otherSources;
-    var i, source;
+    let sources = this.otherSources
+    let i, source
 
     // given a proper event source object
     for (i = 0; i < sources.length; i++) {
-      source = sources[i];
+      source = sources[i]
 
       if (source === matchInput) {
-        return [ source ];
+        return [ source ]
       }
     }
 
     // an ID match
-    source = this.getSourceById(EventSource.normalizeId(matchInput));
+    source = this.getSourceById(EventSource.normalizeId(matchInput))
     if (source) {
-      return [ source ];
+      return [ source ]
     }
 
     // parse as an event source
-    matchInput = EventSourceParser.parse(matchInput, this.calendar);
+    matchInput = EventSourceParser.parse(matchInput, this.calendar)
     if (matchInput) {
 
       return $.grep(sources, function(source) {
-        return isSourcesEquivalent(matchInput, source);
-      });
+        return isSourcesEquivalent(matchInput, source)
+      })
     }
   }
 
@@ -181,9 +180,9 @@ export default class EventManager {
   ID assumed to already be normalized
   */
   getSourceById(id) {
-    return $.grep(this.otherSources, function(source:any) {
-      return source.id && source.id === id;
-    })[0];
+    return $.grep(this.otherSources, function(source: any) {
+      return source.id && source.id === id
+    })[0]
   }
 
 
@@ -193,26 +192,26 @@ export default class EventManager {
 
   setPeriod(eventPeriod) {
     if (this.currentPeriod) {
-      this.unbindPeriod(this.currentPeriod);
-      this.currentPeriod = null;
+      this.unbindPeriod(this.currentPeriod)
+      this.currentPeriod = null
     }
 
-    this.currentPeriod = eventPeriod;
-    this.bindPeriod(eventPeriod);
+    this.currentPeriod = eventPeriod
+    this.bindPeriod(eventPeriod)
 
-    eventPeriod.requestSources(this.getSources());
+    eventPeriod.requestSources(this.getSources())
   }
 
 
   bindPeriod(eventPeriod) {
     this.listenTo(eventPeriod, 'release', function(eventsPayload) {
-      this.trigger('release', eventsPayload);
-    });
+      this.trigger('release', eventsPayload)
+    })
   }
 
 
   unbindPeriod(eventPeriod) {
-    this.stopListeningTo(eventPeriod);
+    this.stopListeningTo(eventPeriod)
   }
 
 
@@ -222,40 +221,40 @@ export default class EventManager {
 
   getEventDefByUid(uid) {
     if (this.currentPeriod) {
-      return this.currentPeriod.getEventDefByUid(uid);
+      return this.currentPeriod.getEventDefByUid(uid)
     }
   }
 
 
   addEventDef(eventDef, isSticky) {
     if (isSticky) {
-      this.stickySource.addEventDef(eventDef);
+      this.stickySource.addEventDef(eventDef)
     }
 
     if (this.currentPeriod) {
-      this.currentPeriod.addEventDef(eventDef); // might release
+      this.currentPeriod.addEventDef(eventDef) // might release
     }
   }
 
 
   removeEventDefsById(eventId) {
     this.getSources().forEach(function(eventSource) {
-      eventSource.removeEventDefsById(eventId);
-    });
+      eventSource.removeEventDefsById(eventId)
+    })
 
     if (this.currentPeriod) {
-      this.currentPeriod.removeEventDefsById(eventId); // might release
+      this.currentPeriod.removeEventDefsById(eventId) // might release
     }
   }
 
 
   removeAllEventDefs() {
     this.getSources().forEach(function(eventSource) {
-      eventSource.removeAllEventDefs();
-    });
+      eventSource.removeAllEventDefs()
+    })
 
     if (this.currentPeriod) {
-      this.currentPeriod.removeAllEventDefs();
+      this.currentPeriod.removeAllEventDefs()
     }
   }
 
@@ -268,38 +267,38 @@ export default class EventManager {
   Returns an undo function.
   */
   mutateEventsWithId(eventDefId, eventDefMutation) {
-    var currentPeriod = this.currentPeriod;
-    var eventDefs;
-    var undoFuncs = [];
+    let currentPeriod = this.currentPeriod
+    let eventDefs
+    let undoFuncs = []
 
     if (currentPeriod) {
 
-      currentPeriod.freeze();
+      currentPeriod.freeze()
 
-      eventDefs = currentPeriod.getEventDefsById(eventDefId);
+      eventDefs = currentPeriod.getEventDefsById(eventDefId)
       eventDefs.forEach(function(eventDef) {
         // add/remove esp because id might change
-        currentPeriod.removeEventDef(eventDef);
-        undoFuncs.push(eventDefMutation.mutateSingle(eventDef));
-        currentPeriod.addEventDef(eventDef);
-      });
+        currentPeriod.removeEventDef(eventDef)
+        undoFuncs.push(eventDefMutation.mutateSingle(eventDef))
+        currentPeriod.addEventDef(eventDef)
+      })
 
-      currentPeriod.thaw();
+      currentPeriod.thaw()
 
       return function() {
-        currentPeriod.freeze();
+        currentPeriod.freeze()
 
-        for (var i = 0; i < eventDefs.length; i++) {
-          currentPeriod.removeEventDef(eventDefs[i]);
-          undoFuncs[i]();
-          currentPeriod.addEventDef(eventDefs[i]);
+        for (let i = 0; i < eventDefs.length; i++) {
+          currentPeriod.removeEventDef(eventDefs[i])
+          undoFuncs[i]()
+          currentPeriod.addEventDef(eventDefs[i])
         }
 
-        currentPeriod.thaw();
-      };
+        currentPeriod.thaw()
+      }
     }
 
-    return function() { };
+    return function() { }
   }
 
 
@@ -307,24 +306,24 @@ export default class EventManager {
   copies and then mutates
   */
   buildMutatedEventInstanceGroup(eventDefId, eventDefMutation) {
-    var eventDefs = this.getEventDefsById(eventDefId);
-    var i;
-    var defCopy;
-    var allInstances = [];
+    let eventDefs = this.getEventDefsById(eventDefId)
+    let i
+    let defCopy
+    let allInstances = []
 
     for (i = 0; i < eventDefs.length; i++) {
-      defCopy = eventDefs[i].clone();
+      defCopy = eventDefs[i].clone()
 
       if (defCopy instanceof SingleEventDef) {
-        eventDefMutation.mutateSingle(defCopy);
+        eventDefMutation.mutateSingle(defCopy)
 
         allInstances.push.apply(allInstances, // append
           defCopy.buildInstances()
-        );
+        )
       }
     }
 
-    return new EventInstanceGroup(allInstances);
+    return new EventInstanceGroup(allInstances)
   }
 
 
@@ -334,14 +333,14 @@ export default class EventManager {
 
   freeze() {
     if (this.currentPeriod) {
-      this.currentPeriod.freeze();
+      this.currentPeriod.freeze()
     }
   }
 
 
   thaw() {
     if (this.currentPeriod) {
-      this.currentPeriod.thaw();
+      this.currentPeriod.thaw()
     }
   }
 
@@ -372,5 +371,5 @@ ListenerMixin.mixInto(EventManager)
 
 
 function isSourcesEquivalent(source0, source1) {
-  return source0.getPrimitive() == source1.getPrimitive();
+  return source0.getPrimitive() == source1.getPrimitive()
 }

+ 105 - 109
src/models/EventPeriod.ts

@@ -34,25 +34,25 @@ export default class EventPeriod {
 
 
   constructor(start, end, timezone) {
-    this.start = start;
-    this.end = end;
-    this.timezone = timezone;
+    this.start = start
+    this.end = end
+    this.timezone = timezone
 
     this.unzonedRange = new UnzonedRange(
       start.clone().stripZone(),
       end.clone().stripZone()
-    );
+    )
 
-    this.requestsByUid = {};
-    this.eventDefsByUid = {};
-    this.eventDefsById = {};
-    this.eventInstanceGroupsById = {};
+    this.requestsByUid = {}
+    this.eventDefsByUid = {}
+    this.eventDefsById = {}
+    this.eventInstanceGroupsById = {}
   }
 
 
   isWithinRange(start, end) {
     // TODO: use a range util function?
-    return !start.isBefore(this.start) && !end.isAfter(this.end);
+    return !start.isBefore(this.start) && !end.isAfter(this.end)
   }
 
 
@@ -61,81 +61,79 @@ export default class EventPeriod {
 
 
   requestSources(sources) {
-    this.freeze();
+    this.freeze()
 
-    for (var i = 0; i < sources.length; i++) {
-      this.requestSource(sources[i]);
+    for (let i = 0; i < sources.length; i++) {
+      this.requestSource(sources[i])
     }
 
-    this.thaw();
+    this.thaw()
   }
 
 
   requestSource(source) {
-    var request = { source: source, status: 'pending', eventDefs: null };
+    let request = { source: source, status: 'pending', eventDefs: null }
 
-    this.requestsByUid[source.uid] = request;
-    this.pendingCnt += 1;
+    this.requestsByUid[source.uid] = request
+    this.pendingCnt += 1
 
     source.fetch(this.start, this.end, this.timezone).then((eventDefs) => {
       if (request.status !== 'cancelled') {
-        request.status = 'completed';
-        request.eventDefs = eventDefs;
+        request.status = 'completed'
+        request.eventDefs = eventDefs
 
-        this.addEventDefs(eventDefs);
-        this.pendingCnt--;
-        this.tryRelease();
+        this.addEventDefs(eventDefs)
+        this.pendingCnt--
+        this.tryRelease()
       }
     }, () => { // failure
       if (request.status !== 'cancelled') {
-        request.status = 'failed';
+        request.status = 'failed'
 
-        this.pendingCnt--;
-        this.tryRelease();
+        this.pendingCnt--
+        this.tryRelease()
       }
-    });
+    })
   }
 
 
   purgeSource(source) {
-    var request = this.requestsByUid[source.uid];
+    let request = this.requestsByUid[source.uid]
 
     if (request) {
-      delete this.requestsByUid[source.uid];
+      delete this.requestsByUid[source.uid]
 
       if (request.status === 'pending') {
-        request.status = 'cancelled';
-        this.pendingCnt--;
-        this.tryRelease();
-      }
-      else if (request.status === 'completed') {
-        request.eventDefs.forEach(this.removeEventDef.bind(this));
+        request.status = 'cancelled'
+        this.pendingCnt--
+        this.tryRelease()
+      } else if (request.status === 'completed') {
+        request.eventDefs.forEach(this.removeEventDef.bind(this))
       }
     }
   }
 
 
   purgeAllSources() {
-    var requestsByUid = this.requestsByUid;
-    var uid, request;
-    var completedCnt = 0;
+    let requestsByUid = this.requestsByUid
+    let uid, request
+    let completedCnt = 0
 
     for (uid in requestsByUid) {
-      request = requestsByUid[uid];
+      request = requestsByUid[uid]
 
       if (request.status === 'pending') {
-        request.status = 'cancelled';
-      }
-      else if (request.status === 'completed') {
-        completedCnt++;
+        request.status = 'cancelled'
+      } else if (request.status === 'completed') {
+        completedCnt++
       }
     }
 
-    this.requestsByUid = {};
-    this.pendingCnt = 0;
+    this.requestsByUid = {}
+    this.pendingCnt = 0
 
     if (completedCnt) {
-      this.removeAllEventDefs(); // might release
+      this.removeAllEventDefs() // might release
     }
   }
 
@@ -145,79 +143,79 @@ export default class EventPeriod {
 
 
   getEventDefByUid(eventDefUid) {
-    return this.eventDefsByUid[eventDefUid];
+    return this.eventDefsByUid[eventDefUid]
   }
 
 
   getEventDefsById(eventDefId) {
-    var a = this.eventDefsById[eventDefId];
+    let a = this.eventDefsById[eventDefId]
 
     if (a) {
-      return a.slice(); // clone
+      return a.slice() // clone
     }
 
-    return [];
+    return []
   }
 
 
   addEventDefs(eventDefs) {
-    for (var i = 0; i < eventDefs.length; i++) {
-      this.addEventDef(eventDefs[i]);
+    for (let i = 0; i < eventDefs.length; i++) {
+      this.addEventDef(eventDefs[i])
     }
   }
 
 
   addEventDef(eventDef) {
-    var eventDefsById = this.eventDefsById;
-    var eventDefId = eventDef.id;
-    var eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = []);
-    var eventInstances = eventDef.buildInstances(this.unzonedRange);
-    var i;
+    let eventDefsById = this.eventDefsById
+    let eventDefId = eventDef.id
+    let eventDefs = eventDefsById[eventDefId] || (eventDefsById[eventDefId] = [])
+    let eventInstances = eventDef.buildInstances(this.unzonedRange)
+    let i
 
-    eventDefs.push(eventDef);
+    eventDefs.push(eventDef)
 
-    this.eventDefsByUid[eventDef.uid] = eventDef;
+    this.eventDefsByUid[eventDef.uid] = eventDef
 
     for (i = 0; i < eventInstances.length; i++) {
-      this.addEventInstance(eventInstances[i], eventDefId);
+      this.addEventInstance(eventInstances[i], eventDefId)
     }
   }
 
 
   removeEventDefsById(eventDefId) {
     this.getEventDefsById(eventDefId).forEach((eventDef) => {
-      this.removeEventDef(eventDef);
-    });
+      this.removeEventDef(eventDef)
+    })
   }
 
 
   removeAllEventDefs() {
-    var isEmpty = $.isEmptyObject(this.eventDefsByUid);
+    let isEmpty = $.isEmptyObject(this.eventDefsByUid)
 
-    this.eventDefsByUid = {};
-    this.eventDefsById = {};
-    this.eventInstanceGroupsById = {};
+    this.eventDefsByUid = {}
+    this.eventDefsById = {}
+    this.eventInstanceGroupsById = {}
 
     if (!isEmpty) {
-      this.tryRelease();
+      this.tryRelease()
     }
   }
 
 
   removeEventDef(eventDef) {
-    var eventDefsById = this.eventDefsById;
-    var eventDefs = eventDefsById[eventDef.id];
+    let eventDefsById = this.eventDefsById
+    let eventDefs = eventDefsById[eventDef.id]
 
-    delete this.eventDefsByUid[eventDef.uid];
+    delete this.eventDefsByUid[eventDef.uid]
 
     if (eventDefs) {
-      removeExact(eventDefs, eventDef);
+      removeExact(eventDefs, eventDef)
 
       if (!eventDefs.length) {
-        delete eventDefsById[eventDef.id];
+        delete eventDefsById[eventDef.id]
       }
 
-      this.removeEventInstancesForDef(eventDef);
+      this.removeEventInstancesForDef(eventDef)
     }
   }
 
@@ -227,75 +225,75 @@ export default class EventPeriod {
 
 
   getEventInstances() { // TODO: consider iterator
-    var eventInstanceGroupsById = this.eventInstanceGroupsById;
-    var eventInstances = [];
-    var id;
+    let eventInstanceGroupsById = this.eventInstanceGroupsById
+    let eventInstances = []
+    let id
 
     for (id in eventInstanceGroupsById) {
       eventInstances.push.apply(eventInstances, // append
         eventInstanceGroupsById[id].eventInstances
-      );
+      )
     }
 
-    return eventInstances;
+    return eventInstances
   }
 
 
   getEventInstancesWithId(eventDefId) {
-    var eventInstanceGroup = this.eventInstanceGroupsById[eventDefId];
+    let eventInstanceGroup = this.eventInstanceGroupsById[eventDefId]
 
     if (eventInstanceGroup) {
-      return eventInstanceGroup.eventInstances.slice(); // clone
+      return eventInstanceGroup.eventInstances.slice() // clone
     }
 
-    return [];
+    return []
   }
 
 
   getEventInstancesWithoutId(eventDefId) { // TODO: consider iterator
-    var eventInstanceGroupsById = this.eventInstanceGroupsById;
-    var matchingInstances = [];
-    var id;
+    let eventInstanceGroupsById = this.eventInstanceGroupsById
+    let matchingInstances = []
+    let id
 
     for (id in eventInstanceGroupsById) {
       if (id !== eventDefId) {
         matchingInstances.push.apply(matchingInstances, // append
           eventInstanceGroupsById[id].eventInstances
-        );
+        )
       }
     }
 
-    return matchingInstances;
+    return matchingInstances
   }
 
 
   addEventInstance(eventInstance, eventDefId) {
-    var eventInstanceGroupsById = this.eventInstanceGroupsById;
-    var eventInstanceGroup = eventInstanceGroupsById[eventDefId] ||
-      (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup());
+    let eventInstanceGroupsById = this.eventInstanceGroupsById
+    let eventInstanceGroup = eventInstanceGroupsById[eventDefId] ||
+      (eventInstanceGroupsById[eventDefId] = new EventInstanceGroup())
 
-    eventInstanceGroup.eventInstances.push(eventInstance);
+    eventInstanceGroup.eventInstances.push(eventInstance)
 
-    this.tryRelease();
+    this.tryRelease()
   }
 
 
   removeEventInstancesForDef(eventDef) {
-    var eventInstanceGroupsById = this.eventInstanceGroupsById;
-    var eventInstanceGroup = eventInstanceGroupsById[eventDef.id];
-    var removeCnt;
+    let eventInstanceGroupsById = this.eventInstanceGroupsById
+    let eventInstanceGroup = eventInstanceGroupsById[eventDef.id]
+    let removeCnt
 
     if (eventInstanceGroup) {
       removeCnt = removeMatching(eventInstanceGroup.eventInstances, function(currentEventInstance) {
-        return currentEventInstance.def === eventDef;
-      });
+        return currentEventInstance.def === eventDef
+      })
 
       if (!eventInstanceGroup.eventInstances.length) {
-        delete eventInstanceGroupsById[eventDef.id];
+        delete eventInstanceGroupsById[eventDef.id]
       }
 
       if (removeCnt) {
-        this.tryRelease();
+        this.tryRelease()
       }
     }
   }
@@ -308,43 +306,41 @@ export default class EventPeriod {
   tryRelease() {
     if (!this.pendingCnt) {
       if (!this.freezeDepth) {
-        this.release();
-      }
-      else {
-        this.stuntedReleaseCnt++;
+        this.release()
+      } else {
+        this.stuntedReleaseCnt++
       }
     }
   }
 
 
   release() {
-    this.releaseCnt++;
-    this.trigger('release', this.eventInstanceGroupsById);
+    this.releaseCnt++
+    this.trigger('release', this.eventInstanceGroupsById)
   }
 
 
   whenReleased() {
     if (this.releaseCnt) {
-      return Promise.resolve(this.eventInstanceGroupsById);
-    }
-    else {
+      return Promise.resolve(this.eventInstanceGroupsById)
+    } else {
       return Promise.construct((onResolve) => {
-        this.one('release', onResolve);
-      });
+        this.one('release', onResolve)
+      })
     }
   }
 
 
   freeze() {
     if (!(this.freezeDepth++)) {
-      this.stuntedReleaseCnt = 0;
+      this.stuntedReleaseCnt = 0
     }
   }
 
 
   thaw() {
     if (!(--this.freezeDepth) && this.stuntedReleaseCnt && !this.pendingCnt) {
-      this.release();
+      this.release()
     }
   }
 

+ 46 - 48
src/models/UnzonedRange.ts

@@ -14,73 +14,71 @@ export default class UnzonedRange {
   constructor(startInput?, endInput?) {
 
     if (moment.isMoment(startInput)) {
-      startInput = (startInput.clone() as any).stripZone();
+      startInput = (startInput.clone() as any).stripZone()
     }
 
     if (moment.isMoment(endInput)) {
-      endInput = (endInput.clone() as any).stripZone();
+      endInput = (endInput.clone() as any).stripZone()
     }
 
     if (startInput) {
-      this.startMs = startInput.valueOf();
+      this.startMs = startInput.valueOf()
     }
 
     if (endInput) {
-      this.endMs = endInput.valueOf();
+      this.endMs = endInput.valueOf()
     }
   }
 
   intersect(otherRange) {
-    var startMs = this.startMs;
-    var endMs = this.endMs;
-    var newRange = null;
+    let startMs = this.startMs
+    let endMs = this.endMs
+    let newRange = null
 
     if (otherRange.startMs != null) {
       if (startMs == null) {
-        startMs = otherRange.startMs;
-      }
-      else {
-        startMs = Math.max(startMs, otherRange.startMs);
+        startMs = otherRange.startMs
+      } else {
+        startMs = Math.max(startMs, otherRange.startMs)
       }
     }
 
     if (otherRange.endMs != null) {
       if (endMs == null) {
-        endMs = otherRange.endMs;
-      }
-      else {
-        endMs = Math.min(endMs, otherRange.endMs);
+        endMs = otherRange.endMs
+      } else {
+        endMs = Math.min(endMs, otherRange.endMs)
       }
     }
 
     if (startMs == null || endMs == null || startMs < endMs) {
-      newRange = new UnzonedRange(startMs, endMs);
-      newRange.isStart = this.isStart && startMs === this.startMs;
-      newRange.isEnd = this.isEnd && endMs === this.endMs;
+      newRange = new UnzonedRange(startMs, endMs)
+      newRange.isStart = this.isStart && startMs === this.startMs
+      newRange.isEnd = this.isEnd && endMs === this.endMs
     }
 
-    return newRange;
+    return newRange
   }
 
 
   intersectsWith(otherRange) {
     return (this.endMs == null || otherRange.startMs == null || this.endMs > otherRange.startMs) &&
-      (this.startMs == null || otherRange.endMs == null || this.startMs < otherRange.endMs);
+      (this.startMs == null || otherRange.endMs == null || this.startMs < otherRange.endMs)
   }
 
 
   containsRange(innerRange) {
     return (this.startMs == null || (innerRange.startMs != null && innerRange.startMs >= this.startMs)) &&
-      (this.endMs == null || (innerRange.endMs != null && innerRange.endMs <= this.endMs));
+      (this.endMs == null || (innerRange.endMs != null && innerRange.endMs <= this.endMs))
   }
 
 
   // `date` can be a moment, a Date, or a millisecond time.
   containsDate(date) {
-    var ms = date.valueOf();
+    let ms = date.valueOf()
 
     return (this.startMs == null || ms >= this.startMs) &&
-      (this.endMs == null || ms < this.endMs);
+      (this.endMs == null || ms < this.endMs)
   }
 
 
@@ -89,32 +87,32 @@ export default class UnzonedRange {
   // `date` can be a moment, a Date, or a millisecond time.
   // Returns a MS-time.
   constrainDate(date) {
-    var ms = date.valueOf();
+    let ms = date.valueOf()
 
     if (this.startMs != null && ms < this.startMs) {
-      ms = this.startMs;
+      ms = this.startMs
     }
 
     if (this.endMs != null && ms >= this.endMs) {
-      ms = this.endMs - 1;
+      ms = this.endMs - 1
     }
 
-    return ms;
+    return ms
   }
 
 
   equals(otherRange) {
-    return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs;
+    return this.startMs === otherRange.startMs && this.endMs === otherRange.endMs
   }
 
 
   clone() {
-    var range = new UnzonedRange(this.startMs, this.endMs);
+    let range = new UnzonedRange(this.startMs, this.endMs)
 
-    range.isStart = this.isStart;
-    range.isEnd = this.isEnd;
+    range.isStart = this.isStart
+    range.isEnd = this.isEnd
 
-    return range;
+    return range
   }
 
 
@@ -123,9 +121,9 @@ export default class UnzonedRange {
   // Formatting and start-of-week will be default.
   getStart() {
     if (this.startMs != null) {
-      return momentExt.utc(this.startMs).stripZone();
+      return momentExt.utc(this.startMs).stripZone()
     }
-    return null;
+    return null
   }
 
   // Returns an ambig-zoned moment from startMs.
@@ -133,9 +131,9 @@ export default class UnzonedRange {
   // Formatting and start-of-week will be default.
   getEnd() {
     if (this.endMs != null) {
-      return momentExt.utc(this.endMs).stripZone();
+      return momentExt.utc(this.endMs).stripZone()
     }
-    return null;
+    return null
   }
 
 
@@ -144,7 +142,7 @@ export default class UnzonedRange {
       moment.utc(this.startMs),
       unit,
       true
-    );
+    )
   }
 
 
@@ -154,26 +152,26 @@ export default class UnzonedRange {
   Only works for non-open-ended ranges.
   */
   static invertRanges(ranges, constraintRange) {
-    var invertedRanges = [];
-    var startMs = constraintRange.startMs; // the end of the previous range. the start of the new range
-    var i;
-    var dateRange;
+    let invertedRanges = []
+    let startMs = constraintRange.startMs // the end of the previous range. the start of the new range
+    let i
+    let dateRange
 
     // ranges need to be in order. required for our date-walking algorithm
-    ranges.sort(compareUnzonedRanges);
+    ranges.sort(compareUnzonedRanges)
 
     for (i = 0; i < ranges.length; i++) {
-      dateRange = ranges[i];
+      dateRange = ranges[i]
 
       // add the span of time before the event (if there is any)
       if (dateRange.startMs > startMs) { // compare millisecond time (skip any ambig logic)
         invertedRanges.push(
           new UnzonedRange(startMs, dateRange.startMs)
-        );
+        )
       }
 
       if (dateRange.endMs > startMs) {
-        startMs = dateRange.endMs;
+        startMs = dateRange.endMs
       }
     }
 
@@ -181,10 +179,10 @@ export default class UnzonedRange {
     if (startMs < constraintRange.endMs) { // compare millisecond time (skip any ambig logic)
       invertedRanges.push(
         new UnzonedRange(startMs, constraintRange.endMs)
-      );
+      )
     }
 
-    return invertedRanges;
+    return invertedRanges
   }
 
 }
@@ -194,5 +192,5 @@ export default class UnzonedRange {
 Only works for non-open-ended ranges.
 */
 function compareUnzonedRanges(range1, range2) {
-  return range1.startMs - range2.startMs; // earlier ranges go first
+  return range1.startMs - range2.startMs // earlier ranges go first
 }

+ 23 - 24
src/models/event-source/ArrayEventSource.ts

@@ -14,19 +14,19 @@ export default class ArrayEventSource extends EventSource {
 
   constructor(calendar) {
     super(calendar)
-    this.eventDefs = []; // for if setRawEventDefs is never called
+    this.eventDefs = [] // for if setRawEventDefs is never called
   }
 
 
   setRawEventDefs(rawEventDefs) {
-    this.rawEventDefs = rawEventDefs;
-    this.eventDefs = this.parseEventDefs(rawEventDefs);
+    this.rawEventDefs = rawEventDefs
+    this.eventDefs = this.parseEventDefs(rawEventDefs)
   }
 
 
   fetch(start, end, timezone) {
-    var eventDefs = this.eventDefs;
-    var i;
+    let eventDefs = this.eventDefs
+    let i
 
     if (
       this.currentTimezone != null &&
@@ -34,19 +34,19 @@ export default class ArrayEventSource extends EventSource {
     ) {
       for (i = 0; i < eventDefs.length; i++) {
         if (eventDefs[i] instanceof SingleEventDef) {
-          eventDefs[i].rezone();
+          eventDefs[i].rezone()
         }
       }
     }
 
-    this.currentTimezone = timezone;
+    this.currentTimezone = timezone
 
-    return Promise.resolve(eventDefs);
+    return Promise.resolve(eventDefs)
   }
 
 
   addEventDef(eventDef) {
-    this.eventDefs.push(eventDef);
+    this.eventDefs.push(eventDef)
   }
 
 
@@ -55,46 +55,45 @@ export default class ArrayEventSource extends EventSource {
   */
   removeEventDefsById(eventDefId) {
     return removeMatching(this.eventDefs, function(eventDef) {
-      return eventDef.id === eventDefId;
-    });
+      return eventDef.id === eventDefId
+    })
   }
 
 
   removeAllEventDefs() {
-    this.eventDefs = [];
+    this.eventDefs = []
   }
 
 
   getPrimitive() {
-    return this.rawEventDefs;
+    return this.rawEventDefs
   }
 
 
   applyManualStandardProps(rawProps) {
-    var superSuccess = super.applyManualStandardProps(rawProps);
+    let superSuccess = super.applyManualStandardProps(rawProps)
 
-    this.setRawEventDefs(rawProps.events);
+    this.setRawEventDefs(rawProps.events)
 
-    return superSuccess;
+    return superSuccess
   }
 
 
   static parse(rawInput, calendar) {
-    var rawProps;
+    let rawProps
 
     // normalize raw input
     if ($.isArray(rawInput.events)) { // extended form
-      rawProps = rawInput;
-    }
-    else if ($.isArray(rawInput)) { // short form
-      rawProps = { events: rawInput };
+      rawProps = rawInput
+    } else if ($.isArray(rawInput)) { // short form
+      rawProps = { events: rawInput }
     }
 
     if (rawProps) {
-      return EventSource.parse.call(this, rawProps, calendar);
+      return EventSource.parse.call(this, rawProps, calendar)
     }
 
-    return false;
+    return false
   }
 
 }
@@ -102,4 +101,4 @@ export default class ArrayEventSource extends EventSource {
 
 ArrayEventSource.defineStandardProps({
   events: false // don't automatically transfer
-});
+})

+ 27 - 28
src/models/event-source/EventSource.ts

@@ -36,10 +36,10 @@ export default class EventSource extends Class {
   // can we do away with calendar? at least for the abstract?
   // useful for buildEventDef
   constructor(calendar) {
-    super();
-    this.calendar = calendar;
-    this.className = [];
-    this.uid = String(EventSource.uuid++);
+    super()
+    this.calendar = calendar
+    this.className = []
+    this.uid = String(EventSource.uuid++)
   }
 
 
@@ -67,52 +67,51 @@ export default class EventSource extends Class {
 
 
   parseEventDefs(rawEventDefs) {
-    var i;
-    var eventDef;
-    var eventDefs = [];
+    let i
+    let eventDef
+    let eventDefs = []
 
     for (i = 0; i < rawEventDefs.length; i++) {
-      eventDef = this.parseEventDef(rawEventDefs[i]);
+      eventDef = this.parseEventDef(rawEventDefs[i])
 
       if (eventDef) {
-        eventDefs.push(eventDef);
+        eventDefs.push(eventDef)
       }
     }
 
-    return eventDefs;
+    return eventDefs
   }
 
 
   parseEventDef(rawInput) {
-    var calendarTransform = this.calendar.opt('eventDataTransform');
-    var sourceTransform = this.eventDataTransform;
+    let calendarTransform = this.calendar.opt('eventDataTransform')
+    let sourceTransform = this.eventDataTransform
 
     if (calendarTransform) {
-      rawInput = calendarTransform(rawInput);
+      rawInput = calendarTransform(rawInput)
     }
     if (sourceTransform) {
-      rawInput = sourceTransform(rawInput);
+      rawInput = sourceTransform(rawInput)
     }
 
-    return EventDefParser.parse(rawInput, this);
+    return EventDefParser.parse(rawInput, this)
   }
 
 
   applyManualStandardProps(rawProps) {
 
     if (rawProps.id != null) {
-      this.id = EventSource.normalizeId(rawProps.id);
+      this.id = EventSource.normalizeId(rawProps.id)
     }
 
     // TODO: converge with EventDef
     if ($.isArray(rawProps.className)) {
-      this.className = rawProps.className;
-    }
-    else if (typeof rawProps.className === 'string') {
-      this.className = rawProps.className.split(/\s+/);
+      this.className = rawProps.className
+    } else if (typeof rawProps.className === 'string') {
+      this.className = rawProps.className.split(/\s+/)
     }
 
-    return true;
+    return true
   }
 
 
@@ -120,15 +119,15 @@ export default class EventSource extends Class {
   rawInput can be any data type!
   */
   static parse(rawInput, calendar) {
-    var source = new this(calendar);
+    let source = new this(calendar)
 
     if (typeof rawInput === 'object') {
       if (source.applyProps(rawInput)) {
-        return source;
+        return source
       }
     }
 
-    return false;
+    return false
   }
 
 
@@ -140,15 +139,15 @@ export default class EventSource extends Class {
 
   static normalizeId(id) {
     if (id) {
-      return String(id);
+      return String(id)
     }
 
-    return null;
+    return null
   }
 
 }
 
-ParsableModelMixin.mixInto(EventSource);
+ParsableModelMixin.mixInto(EventSource)
 
 
 // Parsing
@@ -173,4 +172,4 @@ EventSource.defineStandardProps({
   constraint: true,
   allDayDefault: true,
   eventDataTransform: true
-});
+})

+ 6 - 6
src/models/event-source/EventSourceParser.ts

@@ -5,20 +5,20 @@ export default {
 
 
   registerClass: function(EventSourceClass) {
-    this.sourceClasses.unshift(EventSourceClass); // give highest priority
+    this.sourceClasses.unshift(EventSourceClass) // give highest priority
   },
 
 
   parse: function(rawInput, calendar) {
-    var sourceClasses = this.sourceClasses;
-    var i;
-    var eventSource;
+    let sourceClasses = this.sourceClasses
+    let i
+    let eventSource
 
     for (i = 0; i < sourceClasses.length; i++) {
-      eventSource = sourceClasses[i].parse(rawInput, calendar);
+      eventSource = sourceClasses[i].parse(rawInput, calendar)
 
       if (eventSource) {
-        return eventSource;
+        return eventSource
       }
     }
   }

+ 16 - 17
src/models/event-source/FuncEventSource.ts

@@ -9,7 +9,7 @@ export default class FuncEventSource extends EventSource {
 
 
   fetch(start, end, timezone) {
-    this.calendar.pushLoading();
+    this.calendar.pushLoading()
 
     return Promise.construct((onResolve) => {
       this.func.call(
@@ -18,49 +18,48 @@ export default class FuncEventSource extends EventSource {
         end.clone(),
         timezone,
         (rawEventDefs) => {
-          this.calendar.popLoading();
+          this.calendar.popLoading()
 
-          onResolve(this.parseEventDefs(rawEventDefs));
+          onResolve(this.parseEventDefs(rawEventDefs))
         }
-      );
-    });
+      )
+    })
   }
 
 
   getPrimitive() {
-    return this.func;
+    return this.func
   }
 
 
   applyManualStandardProps(rawProps) {
-    var superSuccess = super.applyManualStandardProps(rawProps);
+    let superSuccess = super.applyManualStandardProps(rawProps)
 
-    this.func = rawProps.events;
+    this.func = rawProps.events
 
-    return superSuccess;
+    return superSuccess
   }
 
 
   static parse(rawInput, calendar) {
-    var rawProps;
+    let rawProps
 
     // normalize raw input
     if ($.isFunction(rawInput.events)) { // extended form
-      rawProps = rawInput;
-    }
-    else if ($.isFunction(rawInput)) { // short form
-      rawProps = { events: rawInput };
+      rawProps = rawInput
+    } else if ($.isFunction(rawInput)) { // short form
+      rawProps = { events: rawInput }
     }
 
     if (rawProps) {
-      return EventSource.parse.call(this, rawProps, calendar);
+      return EventSource.parse.call(this, rawProps, calendar)
     }
 
-    return false;
+    return false
   }
 
 }
 
 FuncEventSource.defineStandardProps({
   events: false // don't automatically transfer
-});
+})

+ 45 - 48
src/models/event-source/JsonFeedEventSource.ts

@@ -20,16 +20,16 @@ export default class JsonFeedEventSource extends EventSource {
 
 
   fetch(start, end, timezone) {
-    var ajaxSettings = this.ajaxSettings;
-    var onSuccess = ajaxSettings.success;
-    var onError = ajaxSettings.error;
-    var requestParams = this.buildRequestParams(start, end, timezone);
+    let ajaxSettings = this.ajaxSettings
+    let onSuccess = ajaxSettings.success
+    let onError = ajaxSettings.error
+    let requestParams = this.buildRequestParams(start, end, timezone)
 
     // todo: eventually handle the promise's then,
     // don't intercept success/error
     // tho will be a breaking API change
 
-    this.calendar.pushLoading();
+    this.calendar.pushLoading()
 
     return Promise.construct((onResolve, onReject) => {
       $.ajax($.extend(
@@ -40,106 +40,103 @@ export default class JsonFeedEventSource extends EventSource {
           url: this.url,
           data: requestParams,
           success: (rawEventDefs, status, xhr) => {
-            var callbackRes;
+            let callbackRes
 
-            this.calendar.popLoading();
+            this.calendar.popLoading()
 
             if (rawEventDefs) {
-              callbackRes = applyAll(onSuccess, this, [ rawEventDefs, status, xhr ]); // redirect `this`
+              callbackRes = applyAll(onSuccess, this, [ rawEventDefs, status, xhr ]) // redirect `this`
 
               if ($.isArray(callbackRes)) {
-                rawEventDefs = callbackRes;
+                rawEventDefs = callbackRes
               }
 
-              onResolve(this.parseEventDefs(rawEventDefs));
-            }
-            else {
-              onReject();
+              onResolve(this.parseEventDefs(rawEventDefs))
+            } else {
+              onReject()
             }
           },
           error: (xhr, statusText, errorThrown) => {
-            this.calendar.popLoading();
+            this.calendar.popLoading()
 
-            applyAll(onError, this, [ xhr, statusText, errorThrown ]); // redirect `this`
-            onReject();
+            applyAll(onError, this, [ xhr, statusText, errorThrown ]) // redirect `this`
+            onReject()
           }
         }
-      ));
-    });
+      ))
+    })
   }
 
 
   buildRequestParams(start, end, timezone) {
-    var calendar = this.calendar;
-    var ajaxSettings = this.ajaxSettings;
-    var startParam, endParam, timezoneParam;
-    var customRequestParams;
-    var params = {};
+    let calendar = this.calendar
+    let ajaxSettings = this.ajaxSettings
+    let startParam, endParam, timezoneParam
+    let customRequestParams
+    let params = {}
 
-    startParam = this.startParam;
+    startParam = this.startParam
     if (startParam == null) {
-      startParam = calendar.opt('startParam');
+      startParam = calendar.opt('startParam')
     }
 
-    endParam = this.endParam;
+    endParam = this.endParam
     if (endParam == null) {
-      endParam = calendar.opt('endParam');
+      endParam = calendar.opt('endParam')
     }
 
-    timezoneParam = this.timezoneParam;
+    timezoneParam = this.timezoneParam
     if (timezoneParam == null) {
-      timezoneParam = calendar.opt('timezoneParam');
+      timezoneParam = calendar.opt('timezoneParam')
     }
 
     // retrieve any outbound GET/POST $.ajax data from the options
     if ($.isFunction(ajaxSettings.data)) {
       // supplied as a function that returns a key/value object
-      customRequestParams = ajaxSettings.data();
-    }
-    else {
+      customRequestParams = ajaxSettings.data()
+    } else {
       // probably supplied as a straight key/value object
-      customRequestParams = ajaxSettings.data || {};
+      customRequestParams = ajaxSettings.data || {}
     }
 
-    $.extend(params, customRequestParams);
+    $.extend(params, customRequestParams)
 
-    params[startParam] = start.format();
-    params[endParam] = end.format();
+    params[startParam] = start.format()
+    params[endParam] = end.format()
 
     if (timezone && timezone !== 'local') {
-      params[timezoneParam] = timezone;
+      params[timezoneParam] = timezone
     }
 
-    return params;
+    return params
   }
 
 
   getPrimitive() {
-    return this.url;
+    return this.url
   }
 
 
   applyMiscProps(rawProps) {
-    this.ajaxSettings = rawProps;
+    this.ajaxSettings = rawProps
   }
 
 
   static parse(rawInput, calendar) {
-    var rawProps;
+    let rawProps
 
     // normalize raw input
     if (typeof rawInput.url === 'string') { // extended form
-      rawProps = rawInput;
-    }
-    else if (typeof rawInput === 'string') { // short form
-      rawProps = { url: rawInput };
+      rawProps = rawInput
+    } else if (typeof rawInput === 'string') { // short form
+      rawProps = { url: rawInput }
     }
 
     if (rawProps) {
-      return EventSource.parse.call(this, rawProps, calendar);
+      return EventSource.parse.call(this, rawProps, calendar)
     }
 
-    return false;
+    return false
   }
 
 }
@@ -151,4 +148,4 @@ JsonFeedEventSource.defineStandardProps({
   startParam: true,
   endParam: true,
   timezoneParam: true
-});
+})

+ 3 - 3
src/models/event-source/config.ts

@@ -5,6 +5,6 @@ import ArrayEventSource from './ArrayEventSource'
 import FuncEventSource from './FuncEventSource'
 import JsonFeedEventSource from './JsonFeedEventSource'
 
-EventSourceParser.registerClass(ArrayEventSource);
-EventSourceParser.registerClass(FuncEventSource);
-EventSourceParser.registerClass(JsonFeedEventSource);
+EventSourceParser.registerClass(ArrayEventSource)
+EventSourceParser.registerClass(FuncEventSource)
+EventSourceParser.registerClass(JsonFeedEventSource)

+ 28 - 29
src/models/event/EventDateProfile.ts

@@ -11,14 +11,14 @@ export default class EventDateProfile {
 
 
   constructor(start, end, calendar) {
-    this.start = start;
-    this.end = end || null;
-    this.unzonedRange = this.buildUnzonedRange(calendar);
+    this.start = start
+    this.end = end || null
+    this.unzonedRange = this.buildUnzonedRange(calendar)
   }
 
 
   isAllDay() { // why recompute this every time?
-    return !(this.start.hasTime() || (this.end && this.end.hasTime()));
+    return !(this.start.hasTime() || (this.end && this.end.hasTime()))
   }
 
 
@@ -26,10 +26,10 @@ export default class EventDateProfile {
   Needs a Calendar object
   */
   buildUnzonedRange(calendar) {
-    var startMs = this.start.clone().stripZone().valueOf();
-    var endMs = this.getEnd(calendar).stripZone().valueOf();
+    let startMs = this.start.clone().stripZone().valueOf()
+    let endMs = this.getEnd(calendar).stripZone().valueOf()
 
-    return new UnzonedRange(startMs, endMs);
+    return new UnzonedRange(startMs, endMs)
   }
 
 
@@ -43,12 +43,12 @@ export default class EventDateProfile {
       calendar.getDefaultEventEnd(
         this.isAllDay(),
         this.start
-      );
+      )
   }
 
 
   static isStandardProp(propName) {
-    return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay';
+    return propName === 'start' || propName === 'date' || propName === 'end' || propName === 'allDay'
   }
 
 
@@ -56,54 +56,53 @@ export default class EventDateProfile {
   Needs an EventSource object
   */
   static parse(rawProps, source) {
-    var startInput = rawProps.start || rawProps.date;
-    var endInput = rawProps.end;
+    let startInput = rawProps.start || rawProps.date
+    let endInput = rawProps.end
 
     if (!startInput) {
-      return false;
+      return false
     }
 
-    var calendar = source.calendar;
-    var start = calendar.moment(startInput);
-    var end = endInput ? calendar.moment(endInput) : null;
-    var forcedAllDay = rawProps.allDay;
-    var forceEventDuration = calendar.opt('forceEventDuration');
+    let calendar = source.calendar
+    let start = calendar.moment(startInput)
+    let end = endInput ? calendar.moment(endInput) : null
+    let forcedAllDay = rawProps.allDay
+    let forceEventDuration = calendar.opt('forceEventDuration')
 
     if (!start.isValid()) {
-      return false;
+      return false
     }
 
     if (end && (!end.isValid() || !end.isAfter(start))) {
-      end = null;
+      end = null
     }
 
     if (forcedAllDay == null) {
-      forcedAllDay = source.allDayDefault;
+      forcedAllDay = source.allDayDefault
       if (forcedAllDay == null) {
-        forcedAllDay = calendar.opt('allDayDefault');
+        forcedAllDay = calendar.opt('allDayDefault')
       }
     }
 
     if (forcedAllDay === true) {
-      start.stripTime();
+      start.stripTime()
       if (end) {
-        end.stripTime();
+        end.stripTime()
       }
-    }
-    else if (forcedAllDay === false) {
+    } else if (forcedAllDay === false) {
       if (!start.hasTime()) {
-        start.time(0);
+        start.time(0)
       }
       if (end && !end.hasTime()) {
-        end.time(0);
+        end.time(0)
       }
     }
 
     if (!end && forceEventDuration) {
-      end = calendar.getDefaultEventEnd(!start.hasTime(), start);
+      end = calendar.getDefaultEventEnd(!start.hasTime(), start)
     }
 
-    return new EventDateProfile(start, end, calendar);
+    return new EventDateProfile(start, end, calendar)
   }
 
 }

+ 52 - 54
src/models/event/EventDef.ts

@@ -37,9 +37,9 @@ export default abstract class EventDef {
 
 
   constructor(source) {
-    this.source = source;
-    this.className = [];
-    this.miscProps = {};
+    this.source = source
+    this.className = []
+    this.miscProps = {}
   }
 
 
@@ -50,154 +50,152 @@ export default abstract class EventDef {
 
 
   clone() {
-    var copy = new (this.constructor as any)(this.source);
+    let copy = new (this.constructor as any)(this.source)
 
-    copy.id = this.id;
-    copy.rawId = this.rawId;
-    copy.uid = this.uid; // not really unique anymore :(
+    copy.id = this.id
+    copy.rawId = this.rawId
+    copy.uid = this.uid // not really unique anymore :(
 
-    EventDef.copyVerbatimStandardProps(this, copy);
+    EventDef.copyVerbatimStandardProps(this, copy)
 
-    copy.className = this.className.slice(); // copy
-    copy.miscProps = $.extend({}, this.miscProps);
+    copy.className = this.className.slice() // copy
+    copy.miscProps = $.extend({}, this.miscProps)
 
-    return copy;
+    return copy
   }
 
 
   hasInverseRendering() {
-    return this.getRendering() === 'inverse-background';
+    return this.getRendering() === 'inverse-background'
   }
 
 
   hasBgRendering() {
-    var rendering = this.getRendering();
+    let rendering = this.getRendering()
 
-    return rendering === 'inverse-background' || rendering === 'background';
+    return rendering === 'inverse-background' || rendering === 'background'
   }
 
 
   getRendering() {
     if (this.rendering != null) {
-      return this.rendering;
+      return this.rendering
     }
 
-    return this.source.rendering;
+    return this.source.rendering
   }
 
 
   getConstraint() {
     if (this.constraint != null) {
-      return this.constraint;
+      return this.constraint
     }
 
     if (this.source.constraint != null) {
-      return this.source.constraint;
+      return this.source.constraint
     }
 
-    return this.source.calendar.opt('eventConstraint'); // what about View option?
+    return this.source.calendar.opt('eventConstraint') // what about View option?
   }
 
 
   getOverlap() {
     if (this.overlap != null) {
-      return this.overlap;
+      return this.overlap
     }
 
     if (this.source.overlap != null) {
-      return this.source.overlap;
+      return this.source.overlap
     }
 
-    return this.source.calendar.opt('eventOverlap'); // what about View option?
+    return this.source.calendar.opt('eventOverlap') // what about View option?
   }
 
 
   isStartExplicitlyEditable() {
     if (this.startEditable != null) {
-      return this.startEditable;
+      return this.startEditable
     }
 
-    return this.source.startEditable;
+    return this.source.startEditable
   }
 
 
   isDurationExplicitlyEditable() {
     if (this.durationEditable != null) {
-      return this.durationEditable;
+      return this.durationEditable
     }
 
-    return this.source.durationEditable;
+    return this.source.durationEditable
   }
 
 
   isExplicitlyEditable() {
     if (this.editable != null) {
-      return this.editable;
+      return this.editable
     }
 
-    return this.source.editable;
+    return this.source.editable
   }
 
 
   toLegacy() {
-    var obj = $.extend({}, this.miscProps);
+    let obj = $.extend({}, this.miscProps)
 
-    obj._id = this.uid;
-    obj.source = this.source;
-    obj.className = this.className.slice(); // copy
-    obj.allDay = this.isAllDay();
+    obj._id = this.uid
+    obj.source = this.source
+    obj.className = this.className.slice() // copy
+    obj.allDay = this.isAllDay()
 
     if (this.rawId != null) {
-      obj.id = this.rawId;
+      obj.id = this.rawId
     }
 
-    EventDef.copyVerbatimStandardProps(this, obj);
+    EventDef.copyVerbatimStandardProps(this, obj)
 
-    return obj;
+    return obj
   }
 
 
   applyManualStandardProps(rawProps) {
 
     if (rawProps.id != null) {
-      this.id = EventDef.normalizeId((this.rawId = rawProps.id));
-    }
-    else {
-      this.id = EventDef.generateId();
+      this.id = EventDef.normalizeId((this.rawId = rawProps.id))
+    } else {
+      this.id = EventDef.generateId()
     }
 
     if (rawProps._id != null) { // accept this prop, even tho somewhat internal
-      this.uid = String(rawProps._id);
-    }
-    else {
-      this.uid = EventDef.generateId();
+      this.uid = String(rawProps._id)
+    } else {
+      this.uid = EventDef.generateId()
     }
 
     // TODO: converge with EventSource
     if ($.isArray(rawProps.className)) {
-      this.className = rawProps.className;
+      this.className = rawProps.className
     }
     if (typeof rawProps.className === 'string') {
-      this.className = rawProps.className.split(/\s+/);
+      this.className = rawProps.className.split(/\s+/)
     }
 
-    return true;
+    return true
   }
 
 
   applyMiscProps(rawProps) {
-    $.extend(this.miscProps, rawProps);
+    $.extend(this.miscProps, rawProps)
   }
 
 
   static parse(rawInput, source) {
-    var def = new (this as any)(source);
+    let def = new (this as any)(source)
 
     if (def.applyProps(rawInput)) {
-      return def;
+      return def
     }
 
-    return false;
+    return false
   }
 
 
@@ -210,12 +208,12 @@ export default abstract class EventDef {
 
 
   static normalizeId(id) {
-    return String(id);
+    return String(id)
   }
 
 
   static generateId() {
-    return '_fc' + (EventDef.uuid++);
+    return '_fc' + (EventDef.uuid++)
   }
 
 }
@@ -247,4 +245,4 @@ EventDef.defineStandardProps({
   backgroundColor: true,
   borderColor: true,
   textColor: true
-});
+})

+ 55 - 64
src/models/event/EventDefDateMutation.ts

@@ -19,158 +19,149 @@ export default class EventDefDateMutation {
   returns an undo function.
   */
   buildNewDateProfile(eventDateProfile, calendar) {
-    var start = eventDateProfile.start.clone();
-    var end = null;
-    var shouldRezone = false;
+    let start = eventDateProfile.start.clone()
+    let end = null
+    let shouldRezone = false
 
     if (eventDateProfile.end && !this.clearEnd) {
-      end = eventDateProfile.end.clone();
-    }
-    // if there will be an end-date mutation, guarantee an end,
-    // ambigously-zoned according to the original allDay
-    else if (this.endDelta && !end) {
-      end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
+      end = eventDateProfile.end.clone()
+    } else if (this.endDelta && !end) {
+      end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start)
     }
 
     if (this.forceTimed) {
-      shouldRezone = true;
+      shouldRezone = true
 
       if (!start.hasTime()) {
-        start.time(0);
+        start.time(0)
       }
 
       if (end && !end.hasTime()) {
-        end.time(0);
+        end.time(0)
       }
-    }
-    else if (this.forceAllDay) {
+    } else if (this.forceAllDay) {
 
       if (start.hasTime()) {
-        start.stripTime();
+        start.stripTime()
       }
 
       if (end && end.hasTime()) {
-        end.stripTime();
+        end.stripTime()
       }
     }
 
     if (this.dateDelta) {
-      shouldRezone = true;
+      shouldRezone = true
 
-      start.add(this.dateDelta);
+      start.add(this.dateDelta)
 
       if (end) {
-        end.add(this.dateDelta);
+        end.add(this.dateDelta)
       }
     }
 
     // do this before adding startDelta to start, so we can work off of start
     if (this.endDelta) {
-      shouldRezone = true;
+      shouldRezone = true
 
-      end.add(this.endDelta);
+      end.add(this.endDelta)
     }
 
     if (this.startDelta) {
-      shouldRezone = true;
+      shouldRezone = true
 
-      start.add(this.startDelta);
+      start.add(this.startDelta)
     }
 
     if (shouldRezone) {
-      start = calendar.applyTimezone(start);
+      start = calendar.applyTimezone(start)
 
       if (end) {
-        end = calendar.applyTimezone(end);
+        end = calendar.applyTimezone(end)
       }
     }
 
     // TODO: okay to access calendar option?
     if (!end && calendar.opt('forceEventDuration')) {
-      end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start);
+      end = calendar.getDefaultEventEnd(eventDateProfile.isAllDay(), start)
     }
 
-    return new EventDateProfile(start, end, calendar);
+    return new EventDateProfile(start, end, calendar)
   }
 
 
   setDateDelta(dateDelta) {
     if (dateDelta && dateDelta.valueOf()) {
-      this.dateDelta = dateDelta;
-    }
-    else {
-      this.dateDelta = null;
+      this.dateDelta = dateDelta
+    } else {
+      this.dateDelta = null
     }
   }
 
 
   setStartDelta(startDelta) {
     if (startDelta && startDelta.valueOf()) {
-      this.startDelta = startDelta;
-    }
-    else {
-      this.startDelta = null;
+      this.startDelta = startDelta
+    } else {
+      this.startDelta = null
     }
   }
 
 
   setEndDelta(endDelta) {
     if (endDelta && endDelta.valueOf()) {
-      this.endDelta = endDelta;
-    }
-    else {
-      this.endDelta = null;
+      this.endDelta = endDelta
+    } else {
+      this.endDelta = null
     }
   }
 
 
   isEmpty() {
     return !this.clearEnd && !this.forceTimed && !this.forceAllDay &&
-      !this.dateDelta && !this.startDelta && !this.endDelta;
+      !this.dateDelta && !this.startDelta && !this.endDelta
   }
 
 
   static createFromDiff(dateProfile0, dateProfile1, largeUnit) {
-    var clearEnd = dateProfile0.end && !dateProfile1.end;
-    var forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay();
-    var forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay();
-    var dateDelta;
-    var endDiff;
-    var endDelta;
-    var mutation;
+    let clearEnd = dateProfile0.end && !dateProfile1.end
+    let forceTimed = dateProfile0.isAllDay() && !dateProfile1.isAllDay()
+    let forceAllDay = !dateProfile0.isAllDay() && dateProfile1.isAllDay()
+    let dateDelta
+    let endDiff
+    let endDelta
+    let mutation
 
     // subtracts the dates in the appropriate way, returning a duration
     function subtractDates(date1, date0) { // date1 - date0
       if (largeUnit) {
-        return diffByUnit(date1, date0, largeUnit); // poorly named
-      }
-      else if (dateProfile1.isAllDay()) {
-        return diffDay(date1, date0); // poorly named
-      }
-      else {
-        return diffDayTime(date1, date0); // poorly named
+        return diffByUnit(date1, date0, largeUnit) // poorly named
+      } else if (dateProfile1.isAllDay()) {
+        return diffDay(date1, date0) // poorly named
+      } else {
+        return diffDayTime(date1, date0) // poorly named
       }
     }
 
-    dateDelta = subtractDates(dateProfile1.start, dateProfile0.start);
+    dateDelta = subtractDates(dateProfile1.start, dateProfile0.start)
 
     if (dateProfile1.end) {
       // use unzonedRanges because dateProfile0.end might be null
       endDiff = subtractDates(
         dateProfile1.unzonedRange.getEnd(),
         dateProfile0.unzonedRange.getEnd()
-      );
-      endDelta = endDiff.subtract(dateDelta);
+      )
+      endDelta = endDiff.subtract(dateDelta)
     }
 
-    mutation = new EventDefDateMutation();
-    mutation.clearEnd = clearEnd;
-    mutation.forceTimed = forceTimed;
-    mutation.forceAllDay = forceAllDay;
-    mutation.setDateDelta(dateDelta);
-    mutation.setEndDelta(endDelta);
+    mutation = new EventDefDateMutation()
+    mutation.clearEnd = clearEnd
+    mutation.forceTimed = forceTimed
+    mutation.forceAllDay = forceAllDay
+    mutation.setDateDelta(dateDelta)
+    mutation.setEndDelta(endDelta)
 
-    return mutation;
+    return mutation
   }
 
 }

+ 43 - 47
src/models/event/EventDefMutation.ts

@@ -24,27 +24,27 @@ export default class EventDefMutation {
   returns an undo function.
   */
   mutateSingle(eventDef) {
-    var origDateProfile;
+    let origDateProfile
 
     if (this.dateMutation) {
-      origDateProfile = eventDef.dateProfile;
+      origDateProfile = eventDef.dateProfile
 
       eventDef.dateProfile = this.dateMutation.buildNewDateProfile(
         origDateProfile,
         eventDef.source.calendar
-      );
+      )
     }
 
     // can't undo
     // TODO: more DRY with EventDef::applyManualStandardProps
     if (this.eventDefId != null) {
-      eventDef.id = EventDef.normalizeId((eventDef.rawId = this.eventDefId));
+      eventDef.id = EventDef.normalizeId((eventDef.rawId = this.eventDefId))
     }
 
     // can't undo
     // TODO: more DRY with EventDef::applyManualStandardProps
     if (this.className) {
-      eventDef.className = this.className;
+      eventDef.className = this.className
     }
 
     // can't undo
@@ -52,99 +52,95 @@ export default class EventDefMutation {
       SingleEventDef.copyVerbatimStandardProps(
         this.verbatimStandardProps, // src
         eventDef // dest
-      );
+      )
     }
 
     // can't undo
     if (this.miscProps) {
-      eventDef.applyMiscProps(this.miscProps);
+      eventDef.applyMiscProps(this.miscProps)
     }
 
     if (origDateProfile) {
       return function() {
-        eventDef.dateProfile = origDateProfile;
-      };
-    }
-    else {
-      return function() { };
+        eventDef.dateProfile = origDateProfile
+      }
+    } else {
+      return function() { }
     }
   }
 
 
   setDateMutation(dateMutation) {
     if (dateMutation && !dateMutation.isEmpty()) {
-      this.dateMutation = dateMutation;
-    }
-    else {
-      this.dateMutation = null;
+      this.dateMutation = dateMutation
+    } else {
+      this.dateMutation = null
     }
   }
 
 
   isEmpty() {
-    return !this.dateMutation;
+    return !this.dateMutation
   }
 
 
   static createFromRawProps(eventInstance, rawProps, largeUnit) {
-    var eventDef = eventInstance.def;
-    var dateProps: any = {};
-    var standardProps: any = {};
-    var miscProps: any = {};
-    var verbatimStandardProps: any = {};
-    var eventDefId = null;
-    var className = null;
-    var propName;
-    var dateProfile;
-    var dateMutation;
-    var defMutation;
+    let eventDef = eventInstance.def
+    let dateProps: any = {}
+    let standardProps: any = {}
+    let miscProps: any = {}
+    let verbatimStandardProps: any = {}
+    let eventDefId = null
+    let className = null
+    let propName
+    let dateProfile
+    let dateMutation
+    let defMutation
 
     for (propName in rawProps) {
       if (EventDateProfile.isStandardProp(propName)) {
-        dateProps[propName] = rawProps[propName];
-      }
-      else if (eventDef.isStandardProp(propName)) {
-        standardProps[propName] = rawProps[propName];
-      }
-      else if (eventDef.miscProps[propName] !== rawProps[propName]) { // only if changed
-        miscProps[propName] = rawProps[propName];
+        dateProps[propName] = rawProps[propName]
+      } else if (eventDef.isStandardProp(propName)) {
+        standardProps[propName] = rawProps[propName]
+      } else if (eventDef.miscProps[propName] !== rawProps[propName]) { // only if changed
+        miscProps[propName] = rawProps[propName]
       }
     }
 
-    dateProfile = EventDateProfile.parse(dateProps, eventDef.source);
+    dateProfile = EventDateProfile.parse(dateProps, eventDef.source)
 
     if (dateProfile) { // no failure?
       dateMutation = EventDefDateMutation.createFromDiff(
         eventInstance.dateProfile,
         dateProfile,
         largeUnit
-      );
+      )
     }
 
     if (standardProps.id !== eventDef.id) {
-      eventDefId = standardProps.id; // only apply if there's a change
+      eventDefId = standardProps.id // only apply if there's a change
     }
 
     if (!isArraysEqual(standardProps.className, eventDef.className)) {
-      className = standardProps.className; // only apply if there's a change
+      className = standardProps.className // only apply if there's a change
     }
 
     EventDef.copyVerbatimStandardProps(
       standardProps, // src
       verbatimStandardProps // dest
-    );
+    )
 
-    defMutation = new EventDefMutation();
-    defMutation.eventDefId = eventDefId;
-    defMutation.className = className;
-    defMutation.verbatimStandardProps = verbatimStandardProps;
-    defMutation.miscProps = miscProps;
+    defMutation = new EventDefMutation()
+    defMutation.eventDefId = eventDefId
+    defMutation.className = className
+    defMutation.verbatimStandardProps = verbatimStandardProps
+    defMutation.miscProps = miscProps
 
     if (dateMutation) {
-      defMutation.dateMutation = dateMutation;
+      defMutation.dateMutation = dateMutation
     }
 
-    return defMutation;
+    return defMutation
   }
 
 }

+ 3 - 4
src/models/event/EventDefParser.ts

@@ -11,10 +11,9 @@ export default {
       isTimeString(eventInput.start) || moment.isDuration(eventInput.start) ||
       isTimeString(eventInput.end) || moment.isDuration(eventInput.end)
     ) {
-      return RecurringEventDef.parse(eventInput, source);
-    }
-    else {
-      return SingleEventDef.parse(eventInput, source);
+      return RecurringEventDef.parse(eventInput, source)
+    } else {
+      return SingleEventDef.parse(eventInput, source)
     }
   }
 

+ 4 - 4
src/models/event/EventFootprint.ts

@@ -7,17 +7,17 @@ export default class EventFootprint {
 
 
   constructor(componentFootprint, eventDef, eventInstance) {
-    this.componentFootprint = componentFootprint;
-    this.eventDef = eventDef;
+    this.componentFootprint = componentFootprint
+    this.eventDef = eventDef
 
     if (eventInstance) {
-      this.eventInstance = eventInstance;
+      this.eventInstance = eventInstance
     }
   }
 
 
   getEventLegacy() {
-    return (this.eventInstance || this.eventDef).toLegacy();
+    return (this.eventInstance || this.eventDef).toLegacy()
   }
 
 }

+ 7 - 7
src/models/event/EventInstance.ts

@@ -6,19 +6,19 @@ export default class EventInstance {
 
 
   constructor(def, dateProfile) {
-    this.def = def;
-    this.dateProfile = dateProfile;
+    this.def = def
+    this.dateProfile = dateProfile
   }
 
 
   toLegacy() {
-    var dateProfile = this.dateProfile;
-    var obj = this.def.toLegacy();
+    let dateProfile = this.dateProfile
+    let obj = this.def.toLegacy()
 
-    obj.start = dateProfile.start.clone();
-    obj.end = dateProfile.end ? dateProfile.end.clone() : null;
+    obj.start = dateProfile.start.clone()
+    obj.end = dateProfile.end ? dateProfile.end.clone() : null
 
-    return obj;
+    return obj
   }
 
 }

+ 22 - 24
src/models/event/EventInstanceGroup.ts

@@ -13,40 +13,38 @@ export default class EventInstanceGroup {
 
 
   constructor(eventInstances?) {
-    this.eventInstances = eventInstances || [];
+    this.eventInstances = eventInstances || []
   }
 
 
   getAllEventRanges(constraintRange) {
     if (constraintRange) {
-      return this.sliceNormalRenderRanges(constraintRange);
-    }
-    else {
-      return this.eventInstances.map(eventInstanceToEventRange);
+      return this.sliceNormalRenderRanges(constraintRange)
+    } else {
+      return this.eventInstances.map(eventInstanceToEventRange)
     }
   }
 
 
   sliceRenderRanges(constraintRange) {
     if (this.isInverse()) {
-      return this.sliceInverseRenderRanges(constraintRange);
-    }
-    else {
-      return this.sliceNormalRenderRanges(constraintRange);
+      return this.sliceInverseRenderRanges(constraintRange)
+    } else {
+      return this.sliceNormalRenderRanges(constraintRange)
     }
   }
 
 
   sliceNormalRenderRanges(constraintRange) {
-    var eventInstances = this.eventInstances;
-    var i, eventInstance;
-    var slicedRange;
-    var slicedEventRanges = [];
+    let eventInstances = this.eventInstances
+    let i, eventInstance
+    let slicedRange
+    let slicedEventRanges = []
 
     for (i = 0; i < eventInstances.length; i++) {
-      eventInstance = eventInstances[i];
+      eventInstance = eventInstances[i]
 
-      slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange);
+      slicedRange = eventInstance.dateProfile.unzonedRange.intersect(constraintRange)
 
       if (slicedRange) {
         slicedEventRanges.push(
@@ -55,33 +53,33 @@ export default class EventInstanceGroup {
             eventInstance.def,
             eventInstance
           )
-        );
+        )
       }
     }
 
-    return slicedEventRanges;
+    return slicedEventRanges
   }
 
 
   sliceInverseRenderRanges(constraintRange) {
-    var unzonedRanges = this.eventInstances.map(eventInstanceToUnzonedRange);
-    var ownerDef = this.getEventDef();
+    let unzonedRanges = this.eventInstances.map(eventInstanceToUnzonedRange)
+    let ownerDef = this.getEventDef()
 
-    unzonedRanges = UnzonedRange.invertRanges(unzonedRanges, constraintRange);
+    unzonedRanges = UnzonedRange.invertRanges(unzonedRanges, constraintRange)
 
     return unzonedRanges.map(function(unzonedRange) {
-      return new EventRange(unzonedRange, ownerDef); // don't give an EventInstance
-    });
+      return new EventRange(unzonedRange, ownerDef) // don't give an EventInstance
+    })
   }
 
 
   isInverse() {
-    return this.getEventDef().hasInverseRendering();
+    return this.getEventDef().hasInverseRendering()
   }
 
 
   getEventDef() {
-    return this.explicitEventDef || this.eventInstances[0].def;
+    return this.explicitEventDef || this.eventInstances[0].def
   }
 
 }

+ 3 - 3
src/models/event/EventRange.ts

@@ -7,11 +7,11 @@ export default class EventRange {
 
 
   constructor(unzonedRange, eventDef, eventInstance?) {
-    this.unzonedRange = unzonedRange;
-    this.eventDef = eventDef;
+    this.unzonedRange = unzonedRange
+    this.eventDef = eventDef
 
     if (eventInstance) {
-      this.eventInstance = eventInstance;
+      this.eventInstance = eventInstance
     }
   }
 

+ 31 - 32
src/models/event/RecurringEventDef.ts

@@ -13,36 +13,35 @@ export default class RecurringEventDef extends EventDef {
 
 
   isAllDay() {
-    return !this.startTime && !this.endTime;
+    return !this.startTime && !this.endTime
   }
 
 
   buildInstances(unzonedRange) {
-    var calendar = this.source.calendar;
-    var unzonedDate = unzonedRange.getStart();
-    var unzonedEnd = unzonedRange.getEnd();
-    var zonedDayStart;
-    var instanceStart, instanceEnd;
-    var instances = [];
+    let calendar = this.source.calendar
+    let unzonedDate = unzonedRange.getStart()
+    let unzonedEnd = unzonedRange.getEnd()
+    let zonedDayStart
+    let instanceStart, instanceEnd
+    let instances = []
 
     while (unzonedDate.isBefore(unzonedEnd)) {
 
       // if everyday, or this particular day-of-week
       if (!this.dowHash || this.dowHash[unzonedDate.day()]) {
 
-        zonedDayStart = calendar.applyTimezone(unzonedDate);
-        instanceStart = zonedDayStart.clone();
-        instanceEnd = null;
+        zonedDayStart = calendar.applyTimezone(unzonedDate)
+        instanceStart = zonedDayStart.clone()
+        instanceEnd = null
 
         if (this.startTime) {
-          instanceStart.time(this.startTime);
-        }
-        else {
-          instanceStart.stripTime();
+          instanceStart.time(this.startTime)
+        } else {
+          instanceStart.stripTime()
         }
 
         if (this.endTime) {
-          instanceEnd = zonedDayStart.clone().time(this.endTime);
+          instanceEnd = zonedDayStart.clone().time(this.endTime)
         }
 
         instances.push(
@@ -50,44 +49,44 @@ export default class RecurringEventDef extends EventDef {
             this, // definition
             new EventDateProfile(instanceStart, instanceEnd, calendar)
           )
-        );
+        )
       }
 
-      unzonedDate.add(1, 'days');
+      unzonedDate.add(1, 'days')
     }
 
-    return instances;
+    return instances
   }
 
 
   setDow(dowNumbers) {
 
     if (!this.dowHash) {
-      this.dowHash = {};
+      this.dowHash = {}
     }
 
-    for (var i = 0; i < dowNumbers.length; i++) {
-      this.dowHash[dowNumbers[i]] = true;
+    for (let i = 0; i < dowNumbers.length; i++) {
+      this.dowHash[dowNumbers[i]] = true
     }
   }
 
 
   clone() {
-    var def = super.clone();
+    let def = super.clone()
 
     if (def.startTime) {
-      def.startTime = moment.duration(this.startTime);
+      def.startTime = moment.duration(this.startTime)
     }
 
     if (def.endTime) {
-      def.endTime = moment.duration(this.endTime);
+      def.endTime = moment.duration(this.endTime)
     }
 
     if (this.dowHash) {
-      def.dowHash = $.extend({}, this.dowHash);
+      def.dowHash = $.extend({}, this.dowHash)
     }
 
-    return def;
+    return def
   }
 
 }
@@ -98,21 +97,21 @@ HACK to work with TypeScript mixins
 NOTE: if super-method fails, should still attempt to apply
 */
 RecurringEventDef.prototype.applyProps = function(rawProps) {
-  var superSuccess = EventDef.prototype.applyProps.call(this, rawProps);
+  let superSuccess = EventDef.prototype.applyProps.call(this, rawProps)
 
   if (rawProps.start) {
-    this.startTime = moment.duration(rawProps.start);
+    this.startTime = moment.duration(rawProps.start)
   }
 
   if (rawProps.end) {
-    this.endTime = moment.duration(rawProps.end);
+    this.endTime = moment.duration(rawProps.end)
   }
 
   if (rawProps.dow) {
-    this.setDow(rawProps.dow);
+    this.setDow(rawProps.dow)
   }
 
-  return superSuccess;
+  return superSuccess
 }
 
 
@@ -124,4 +123,4 @@ RecurringEventDef.defineStandardProps({ // false = manually process
   start: false,
   end: false,
   dow: false
-});
+})

+ 17 - 18
src/models/event/SingleEventDef.ts

@@ -12,7 +12,7 @@ export default class SingleEventDef extends EventDef {
   Will receive start/end params, but will be ignored.
   */
   buildInstances() {
-    return [ this.buildInstance() ];
+    return [ this.buildInstance() ]
   }
 
 
@@ -20,33 +20,33 @@ export default class SingleEventDef extends EventDef {
     return new EventInstance(
       this, // definition
       this.dateProfile
-    );
+    )
   }
 
 
   isAllDay() {
-    return this.dateProfile.isAllDay();
+    return this.dateProfile.isAllDay()
   }
 
 
   clone() {
-    var def = super.clone();
+    let def = super.clone()
 
-    def.dateProfile = this.dateProfile;
+    def.dateProfile = this.dateProfile
 
-    return def;
+    return def
   }
 
 
   rezone() {
-    var calendar = this.source.calendar;
-    var dateProfile = this.dateProfile;
+    let calendar = this.source.calendar
+    let dateProfile = this.dateProfile
 
     this.dateProfile = new EventDateProfile(
       calendar.moment(dateProfile.start),
       dateProfile.end ? calendar.moment(dateProfile.end) : null,
       calendar
-    );
+    )
   }
 
 
@@ -54,21 +54,20 @@ export default class SingleEventDef extends EventDef {
   NOTE: if super-method fails, should still attempt to apply
   */
   applyManualStandardProps(rawProps) {
-    var superSuccess = super.applyManualStandardProps(rawProps);
-    var dateProfile = EventDateProfile.parse(rawProps, this.source); // returns null on failure
+    let superSuccess = super.applyManualStandardProps(rawProps)
+    let dateProfile = EventDateProfile.parse(rawProps, this.source) // returns null on failure
 
     if (dateProfile) {
-      this.dateProfile = dateProfile;
+      this.dateProfile = dateProfile
 
       // make sure `date` shows up in the legacy event objects as-is
       if (rawProps.date != null) {
-        this.miscProps.date = rawProps.date;
+        this.miscProps.date = rawProps.date
       }
 
-      return superSuccess;
-    }
-    else {
-      return false;
+      return superSuccess
+    } else {
+      return false
     }
   }
 
@@ -84,4 +83,4 @@ SingleEventDef.defineStandardProps({ // false = manually process
   date: false, // alias for 'start'
   end: false,
   allDay: false
-});
+})

+ 8 - 8
src/models/event/util.ts

@@ -4,16 +4,16 @@ import ComponentFootprint from '../ComponentFootprint'
 
 
 export function eventDefsToEventInstances(eventDefs, unzonedRange) {
-  var eventInstances = [];
-  var i;
+  let eventInstances = []
+  let i
 
   for (i = 0; i < eventDefs.length; i++) {
     eventInstances.push.apply(eventInstances, // append
       eventDefs[i].buildInstances(unzonedRange)
-    );
+    )
   }
 
-  return eventInstances;
+  return eventInstances
 }
 
 
@@ -22,7 +22,7 @@ export function eventInstanceToEventRange(eventInstance) {
     eventInstance.dateProfile.unzonedRange,
     eventInstance.def,
     eventInstance
-  );
+  )
 }
 
 
@@ -34,15 +34,15 @@ export function eventRangeToEventFootprint(eventRange) {
     ),
     eventRange.eventDef,
     eventRange.eventInstance // might not exist
-  );
+  )
 }
 
 
 export function eventInstanceToUnzonedRange(eventInstance) {
-  return eventInstance.dateProfile.unzonedRange;
+  return eventInstance.dateProfile.unzonedRange
 }
 
 
 export function eventFootprintToComponentFootprint(eventFootprint) {
-  return eventFootprint.componentFootprint;
+  return eventFootprint.componentFootprint
 }

+ 95 - 103
src/moment-ext.ts

@@ -9,23 +9,23 @@ with the NOTABLE EXCEOPTION of start/end dates that live on *Event Objects*.
 Ambiguously-TIMED moments are assumed to be ambiguously-zoned by nature.
 */
 
-var ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/;
-var ambigTimeOrZoneRegex =
-  /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/;
-var newMomentProto: any = moment.fn; // where we will attach our new methods
-var oldMomentProto = $.extend({}, newMomentProto); // copy of original moment methods
+let ambigDateOfMonthRegex = /^\s*\d{4}-\d\d$/
+let ambigTimeOrZoneRegex =
+  /^\s*\d{4}-(?:(\d\d-\d\d)|(W\d\d$)|(W\d\d-\d)|(\d\d\d))((T| )(\d\d(:\d\d(:\d\d(\.\d+)?)?)?)?)?$/
+let newMomentProto: any = moment.fn // where we will attach our new methods
+let oldMomentProto = $.extend({}, newMomentProto) // copy of original moment methods
 
 // tell momentjs to transfer these properties upon clone
-var momentProperties = (moment as any).momentProperties;
-momentProperties.push('_fullCalendar');
-momentProperties.push('_ambigTime');
-momentProperties.push('_ambigZone');
+let momentProperties = (moment as any).momentProperties
+momentProperties.push('_fullCalendar')
+momentProperties.push('_ambigTime')
+momentProperties.push('_ambigZone')
 
 /*
 Call this if you want Moment's original format method to be used
 */
 function oldMomentFormat(mom, formatStr?) {
-  return oldMomentProto.format.call(mom, formatStr); // oldMomentProto defined in moment-ext.js
+  return oldMomentProto.format.call(mom, formatStr) // oldMomentProto defined in moment-ext.js
 }
 
 export { newMomentProto, oldMomentProto, oldMomentFormat }
@@ -39,93 +39,87 @@ export { newMomentProto, oldMomentProto, oldMomentFormat }
 // it will function as a clone (and retain the zone of the moment). Anything else will
 // result in a moment in the local zone.
 const momentExt: any = function() {
-  return makeMoment(arguments);
-};
+  return makeMoment(arguments)
+}
 
 export default momentExt
 
 // Sames as momentExt, but forces the resulting moment to be in the UTC timezone.
 momentExt.utc = function() {
-  var mom = makeMoment(arguments, true);
+  let mom = makeMoment(arguments, true)
 
   // Force it into UTC because makeMoment doesn't guarantee it
   // (if given a pre-existing moment for example)
   if (mom.hasTime()) { // don't give ambiguously-timed moments a UTC zone
-    mom.utc();
+    mom.utc()
   }
 
-  return mom;
-};
+  return mom
+}
 
 // Same as momentExt, but when given an ISO8601 string, the timezone offset is preserved.
 // ISO8601 strings with no timezone offset will become ambiguously zoned.
 momentExt.parseZone = function() {
-  return makeMoment(arguments, true, true);
-};
+  return makeMoment(arguments, true, true)
+}
 
 // Builds an enhanced moment from args. When given an existing moment, it clones. When given a
 // native Date, or called with no arguments (the current time), the resulting moment will be local.
 // Anything else needs to be "parsed" (a string or an array), and will be affected by:
 //    parseAsUTC - if there is no zone information, should we parse the input in UTC?
 //    parseZone - if there is zone information, should we force the zone of the moment?
-function makeMoment(args, parseAsUTC=false, parseZone=false) {
-  var input = args[0];
-  var isSingleString = args.length == 1 && typeof input === 'string';
-  var isAmbigTime;
-  var isAmbigZone;
-  var ambigMatch;
-  var mom;
+function makeMoment(args, parseAsUTC= false, parseZone= false) {
+  let input = args[0]
+  let isSingleString = args.length == 1 && typeof input === 'string'
+  let isAmbigTime
+  let isAmbigZone
+  let ambigMatch
+  let mom
 
   if (moment.isMoment(input) || isNativeDate(input) || input === undefined) {
-    mom = moment.apply(null, args);
-  }
-  else { // "parsing" is required
-    isAmbigTime = false;
-    isAmbigZone = false;
+    mom = moment.apply(null, args)
+  } else { // "parsing" is required
+    isAmbigTime = false
+    isAmbigZone = false
 
     if (isSingleString) {
       if (ambigDateOfMonthRegex.test(input)) {
         // accept strings like '2014-05', but convert to the first of the month
-        input += '-01';
-        args = [ input ]; // for when we pass it on to moment's constructor
-        isAmbigTime = true;
-        isAmbigZone = true;
-      }
-      else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {
-        isAmbigTime = !ambigMatch[5]; // no time part?
-        isAmbigZone = true;
+        input += '-01'
+        args = [ input ] // for when we pass it on to moment's constructor
+        isAmbigTime = true
+        isAmbigZone = true
+      } else if ((ambigMatch = ambigTimeOrZoneRegex.exec(input))) {
+        isAmbigTime = !ambigMatch[5] // no time part?
+        isAmbigZone = true
       }
-    }
-    else if ($.isArray(input)) {
+    } else if ($.isArray(input)) {
       // arrays have no timezone information, so assume ambiguous zone
-      isAmbigZone = true;
+      isAmbigZone = true
     }
     // otherwise, probably a string with a format
 
     if (parseAsUTC || isAmbigTime) {
-      mom = moment.utc.apply(moment, args);
-    }
-    else {
-      mom = moment.apply(null, args);
+      mom = moment.utc.apply(moment, args)
+    } else {
+      mom = moment.apply(null, args)
     }
 
     if (isAmbigTime) {
-      mom._ambigTime = true;
-      mom._ambigZone = true; // ambiguous time always means ambiguous zone
-    }
-    else if (parseZone) { // let's record the inputted zone somehow
+      mom._ambigTime = true
+      mom._ambigZone = true // ambiguous time always means ambiguous zone
+    } else if (parseZone) { // let's record the inputted zone somehow
       if (isAmbigZone) {
-        mom._ambigZone = true;
-      }
-      else if (isSingleString) {
-        mom.utcOffset(input); // if not a valid zone, will assign UTC
+        mom._ambigZone = true
+      } else if (isSingleString) {
+        mom.utcOffset(input) // if not a valid zone, will assign UTC
       }
     }
   }
 
-  mom._fullCalendar = true; // flag for extended functionality
+  mom._fullCalendar = true // flag for extended functionality
 
-  return mom;
+  return mom
 }
 
 
@@ -136,17 +130,16 @@ function makeMoment(args, parseAsUTC=false, parseZone=false) {
 // Returns the week number, considering the locale's custom week number calcuation
 // `weeks` is an alias for `week`
 newMomentProto.week = newMomentProto.weeks = function(input) {
-  var weekCalc = this._locale._fullCalendar_weekCalc;
+  let weekCalc = this._locale._fullCalendar_weekCalc
 
   if (input == null && typeof weekCalc === 'function') { // custom function only works for getter
-    return weekCalc(this);
-  }
-  else if (weekCalc === 'ISO') {
-    return oldMomentProto.isoWeek.apply(this, arguments); // ISO getter/setter
+    return weekCalc(this)
+  } else if (weekCalc === 'ISO') {
+    return oldMomentProto.isoWeek.apply(this, arguments) // ISO getter/setter
   }
 
-  return oldMomentProto.week.apply(this, arguments); // local getter/setter
-};
+  return oldMomentProto.week.apply(this, arguments) // local getter/setter
+}
 
 
 // Time-of-day
@@ -164,7 +157,7 @@ newMomentProto.time = function(time) {
   // Fallback to the original method (if there is one) if this moment wasn't created via FullCalendar.
   // `time` is a generic enough method name where this precaution is necessary to avoid collisions w/ other plugins.
   if (!this._fullCalendar) {
-    return oldMomentProto.time.apply(this, arguments);
+    return oldMomentProto.time.apply(this, arguments)
   }
 
   if (time == null) { // getter
@@ -173,21 +166,20 @@ newMomentProto.time = function(time) {
       minutes: this.minutes(),
       seconds: this.seconds(),
       milliseconds: this.milliseconds()
-    });
-  }
-  else { // setter
+    })
+  } else { // setter
 
-    this._ambigTime = false; // mark that the moment now has a time
+    this._ambigTime = false // mark that the moment now has a time
 
     if (!moment.isDuration(time) && !moment.isMoment(time)) {
-      time = moment.duration(time);
+      time = moment.duration(time)
     }
 
     // The day value should cause overflow (so 24 hours becomes 00:00:00 of next day).
     // Only for Duration times, not Moment times.
-    var dayHours = 0;
+    let dayHours = 0
     if (moment.isDuration(time)) {
-      dayHours = Math.floor(time.asDays()) * 24;
+      dayHours = Math.floor(time.asDays()) * 24
     }
 
     // We need to set the individual fields.
@@ -195,9 +187,9 @@ newMomentProto.time = function(time) {
     return this.hours(dayHours + time.hours())
       .minutes(time.minutes())
       .seconds(time.seconds())
-      .milliseconds(time.milliseconds());
+      .milliseconds(time.milliseconds())
   }
-};
+}
 
 // Converts the moment to UTC, stripping out its time-of-day and timezone offset,
 // but preserving its YMD. A moment with a stripped time will display no time
@@ -206,7 +198,7 @@ newMomentProto.stripTime = function() {
 
   if (!this._ambigTime) {
 
-    this.utc(true); // keepLocalTime=true (for keeping *date* value)
+    this.utc(true) // keepLocalTime=true (for keeping *date* value)
 
     // set time to zero
     this.set({
@@ -214,21 +206,21 @@ newMomentProto.stripTime = function() {
       minutes: 0,
       seconds: 0,
       ms: 0
-    });
+    })
 
     // Mark the time as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
     // which clears all ambig flags.
-    this._ambigTime = true;
-    this._ambigZone = true; // if ambiguous time, also ambiguous timezone offset
+    this._ambigTime = true
+    this._ambigZone = true // if ambiguous time, also ambiguous timezone offset
   }
 
-  return this; // for chaining
-};
+  return this // for chaining
+}
 
 // Returns if the moment has a non-ambiguous time (boolean)
 newMomentProto.hasTime = function() {
-  return !this._ambigTime;
-};
+  return !this._ambigTime
+}
 
 
 // Timezone
@@ -238,29 +230,29 @@ newMomentProto.hasTime = function() {
 // YMD and time-of-day. A moment with a stripped timezone offset will display no
 // timezone offset when .format() is called.
 newMomentProto.stripZone = function() {
-  var wasAmbigTime;
+  let wasAmbigTime
 
   if (!this._ambigZone) {
 
-    wasAmbigTime = this._ambigTime;
+    wasAmbigTime = this._ambigTime
 
-    this.utc(true); // keepLocalTime=true (for keeping date and time values)
+    this.utc(true) // keepLocalTime=true (for keeping date and time values)
 
     // the above call to .utc()/.utcOffset() unfortunately might clear the ambig flags, so restore
-    this._ambigTime = wasAmbigTime || false;
+    this._ambigTime = wasAmbigTime || false
 
     // Mark the zone as ambiguous. This needs to happen after the .utc() call, which might call .utcOffset(),
     // which clears the ambig flags.
-    this._ambigZone = true;
+    this._ambigZone = true
   }
 
-  return this; // for chaining
-};
+  return this // for chaining
+}
 
 // Returns of the moment has a non-ambiguous timezone offset (boolean)
 newMomentProto.hasZone = function() {
-  return !this._ambigZone;
-};
+  return !this._ambigZone
+}
 
 
 // implicitly marks a zone
@@ -268,29 +260,29 @@ newMomentProto.local = function(keepLocalTime) {
 
   // for when converting from ambiguously-zoned to local,
   // keep the time values when converting from UTC -> local
-  oldMomentProto.local.call(this, this._ambigZone || keepLocalTime);
+  oldMomentProto.local.call(this, this._ambigZone || keepLocalTime)
 
   // ensure non-ambiguous
   // this probably already happened via local() -> utcOffset(), but don't rely on Moment's internals
-  this._ambigTime = false;
-  this._ambigZone = false;
+  this._ambigTime = false
+  this._ambigZone = false
 
-  return this; // for chaining
-};
+  return this // for chaining
+}
 
 
 // implicitly marks a zone
 newMomentProto.utc = function(keepLocalTime) {
 
-  oldMomentProto.utc.call(this, keepLocalTime);
+  oldMomentProto.utc.call(this, keepLocalTime)
 
   // ensure non-ambiguous
   // this probably already happened via utc() -> utcOffset(), but don't rely on Moment's internals
-  this._ambigTime = false;
-  this._ambigZone = false;
+  this._ambigTime = false
+  this._ambigZone = false
 
-  return this;
-};
+  return this
+}
 
 
 // implicitly marks a zone (will probably get called upon .utc() and .local())
@@ -299,9 +291,9 @@ newMomentProto.utcOffset = function(tzo) {
   if (tzo != null) { // setter
     // these assignments needs to happen before the original zone method is called.
     // I forget why, something to do with a browser crash.
-    this._ambigTime = false;
-    this._ambigZone = false;
+    this._ambigTime = false
+    this._ambigZone = false
   }
 
-  return oldMomentProto.utcOffset.apply(this, arguments);
-};
+  return oldMomentProto.utcOffset.apply(this, arguments)
+}

+ 10 - 10
src/options.ts

@@ -49,10 +49,10 @@ export const globalDefaults = {
   locale: null,
   isRTL: false,
   buttonText: {
-    prev: "prev",
-    next: "next",
-    prevYear: "prev year",
-    nextYear: "next year",
+    prev: 'prev',
+    next: 'next',
+    prevYear: 'prev year',
+    nextYear: 'next year',
     year: 'year', // TODO: locale files need to specify this
     today: 'today',
     month: 'month',
@@ -94,12 +94,12 @@ export const globalDefaults = {
 
   longPressDelay: 1000
 
-};
+}
 
 
 export const englishDefaults = { // used by locale.js
   dayPopoverFormat: 'dddd, MMMM D'
-};
+}
 
 
 export const rtlDefaults = { // right-to-left defaults
@@ -120,19 +120,19 @@ export const rtlDefaults = { // right-to-left defaults
     nextYear: 'seek-prev',
     prevYear: 'seek-next'
   }
-};
+}
 
 
-var complexOptions = [ // names of options that are objects whose properties should be combined
+let complexOptions = [ // names of options that are objects whose properties should be combined
   'header',
   'footer',
   'buttonText',
   'buttonIcons',
   'themeButtonIcons'
-];
+]
 
 
 // Merges an array of option objects into a single object
 export function mergeOptions(optionObjs) {
-  return mergeProps(optionObjs, complexOptions);
+  return mergeProps(optionObjs, complexOptions)
 }

+ 21 - 22
src/theme/Theme.ts

@@ -15,8 +15,8 @@ export default class Theme {
 
 
   constructor(optionsManager) {
-    this.optionsManager = optionsManager;
-    this.processIconOverride();
+    this.optionsManager = optionsManager
+    this.processIconOverride()
   }
 
 
@@ -24,71 +24,70 @@ export default class Theme {
     if (this.iconOverrideOption) {
       this.setIconOverride(
         this.optionsManager.get(this.iconOverrideOption)
-      );
+      )
     }
   }
 
 
   setIconOverride(iconOverrideHash) {
-    var iconClassesCopy;
-    var buttonName;
+    let iconClassesCopy
+    let buttonName
 
     if ($.isPlainObject(iconOverrideHash)) {
-      iconClassesCopy = $.extend({}, this.iconClasses);
+      iconClassesCopy = $.extend({}, this.iconClasses)
 
       for (buttonName in iconOverrideHash) {
         iconClassesCopy[buttonName] = this.applyIconOverridePrefix(
           iconOverrideHash[buttonName]
-        );
+        )
       }
 
-      this.iconClasses = iconClassesCopy;
-    }
-    else if (iconOverrideHash === false) {
-      this.iconClasses = {};
+      this.iconClasses = iconClassesCopy
+    } else if (iconOverrideHash === false) {
+      this.iconClasses = {}
     }
   }
 
 
   applyIconOverridePrefix(className) {
-    var prefix = this.iconOverridePrefix;
+    let prefix = this.iconOverridePrefix
 
     if (prefix && className.indexOf(prefix) !== 0) { // if not already present
-      className = prefix + className;
+      className = prefix + className
     }
 
-    return className;
+    return className
   }
 
 
   getClass(key) {
-    return this.classes[key] || '';
+    return this.classes[key] || ''
   }
 
 
   getIconClass(buttonName) {
-    var className = this.iconClasses[buttonName];
+    let className = this.iconClasses[buttonName]
 
     if (className) {
-      return this.baseIconClass + ' ' + className;
+      return this.baseIconClass + ' ' + className
     }
 
-    return '';
+    return ''
   }
 
 
   getCustomButtonIconClass(customButtonProps) {
-    var className;
+    let className
 
     if (this.iconOverrideCustomButtonOption) {
-      className = customButtonProps[this.iconOverrideCustomButtonOption];
+      className = customButtonProps[this.iconOverrideCustomButtonOption]
 
       if (className) {
-        return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className);
+        return this.baseIconClass + ' ' + this.applyIconOverridePrefix(className)
       }
     }
 
-    return '';
+    return ''
   }
 
 }

+ 9 - 11
src/theme/ThemeRegistry.ts

@@ -1,23 +1,21 @@
-import StandardTheme from './StandardTheme';
-import JqueryUiTheme from './JqueryUiTheme';
+import StandardTheme from './StandardTheme'
+import JqueryUiTheme from './JqueryUiTheme'
 
 
-const themeClassHash = {} as any;
+const themeClassHash = {} as any
 
 
 export function defineThemeSystem(themeName, themeClass) {
-  themeClassHash[themeName] = themeClass;
+  themeClassHash[themeName] = themeClass
 }
 
 
 export function getThemeSystemClass(themeSetting) {
   if (!themeSetting) {
-    return StandardTheme;
-  }
-  else if (themeSetting === true) {
-    return JqueryUiTheme;
-  }
-  else {
-    return themeClassHash[themeSetting];
+    return StandardTheme
+  } else if (themeSetting === true) {
+    return JqueryUiTheme
+  } else {
+    return themeClassHash[themeSetting]
   }
 }

+ 7 - 7
src/theme/config.ts

@@ -1,10 +1,10 @@
 
-import { defineThemeSystem } from './ThemeRegistry';
+import { defineThemeSystem } from './ThemeRegistry'
 
-import StandardTheme from './StandardTheme';
-import JqueryUiTheme from './JqueryUiTheme';
-import BootstrapTheme from './BootstrapTheme';
+import StandardTheme from './StandardTheme'
+import JqueryUiTheme from './JqueryUiTheme'
+import BootstrapTheme from './BootstrapTheme'
 
-defineThemeSystem('standard', StandardTheme);
-defineThemeSystem('jquery-ui', JqueryUiTheme);
-defineThemeSystem('bootstrap3', BootstrapTheme);
+defineThemeSystem('standard', StandardTheme)
+defineThemeSystem('jquery-ui', JqueryUiTheme)
+defineThemeSystem('bootstrap3', BootstrapTheme)

Diff do ficheiro suprimidas por serem muito extensas
+ 233 - 244
src/util.ts


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff