|
@@ -9,6 +9,7 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
title: null, // the text that will be displayed in the header's title
|
|
title: null, // the text that will be displayed in the header's title
|
|
|
|
|
|
|
|
calendar: null, // owner Calendar object
|
|
calendar: null, // owner Calendar object
|
|
|
|
|
+ viewSpec: null,
|
|
|
options: null, // hash containing all options. already merged with view-specific-options
|
|
options: null, // hash containing all options. already merged with view-specific-options
|
|
|
el: null, // the view's containing element. set by Calendar
|
|
el: null, // the view's containing element. set by Calendar
|
|
|
|
|
|
|
@@ -21,32 +22,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
isEventsRendered: false,
|
|
isEventsRendered: false,
|
|
|
eventRenderQueue: null,
|
|
eventRenderQueue: null,
|
|
|
|
|
|
|
|
- viewSpec: null,
|
|
|
|
|
- currentDate: null,
|
|
|
|
|
-
|
|
|
|
|
- // range the view is formally responsible for (moments)
|
|
|
|
|
- // may be different from start/end. for example, a month view might have 1st-31st, excluding padded dates
|
|
|
|
|
- currentRange: null,
|
|
|
|
|
- currentRangeUnit: null, // name of largest unit being displayed, like "month" or "week"
|
|
|
|
|
-
|
|
|
|
|
- dateIncrement: null,
|
|
|
|
|
-
|
|
|
|
|
- // date range with a rendered skeleton
|
|
|
|
|
- // includes not-active days that need some sort of DOM
|
|
|
|
|
- renderRange: null,
|
|
|
|
|
-
|
|
|
|
|
- // active dates that display events and accept drag-nd-drop
|
|
|
|
|
- activeRange: null,
|
|
|
|
|
-
|
|
|
|
|
- // date constraints. defines the "valid range"
|
|
|
|
|
- // TODO: enforce this in prev/next/gotoDate
|
|
|
|
|
- validRange: null,
|
|
|
|
|
-
|
|
|
|
|
- start: null, // DEPRECATED: use activeRange instead
|
|
|
|
|
- end: null, // "
|
|
|
|
|
- intervalStart: null, // DEPRECATED: use currentRange instead
|
|
|
|
|
- intervalEnd: null, // "
|
|
|
|
|
-
|
|
|
|
|
isRTL: false,
|
|
isRTL: false,
|
|
|
isSelected: false, // boolean whether a range of time is user-selected or not
|
|
isSelected: false, // boolean whether a range of time is user-selected or not
|
|
|
selectedEvent: null,
|
|
selectedEvent: null,
|
|
@@ -145,259 +120,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
},
|
|
},
|
|
|
|
|
|
|
|
|
|
|
|
|
- /* Date Computation
|
|
|
|
|
- ------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Updates all internal dates for displaying the given unzoned range.
|
|
|
|
|
- // Will return a boolean about whether there was some sort of change.
|
|
|
|
|
- setRangeFromDate: function(date) {
|
|
|
|
|
-
|
|
|
|
|
- var ranges = this.buildRangeInfo(date);
|
|
|
|
|
-
|
|
|
|
|
- this.validRange = ranges.validRange;
|
|
|
|
|
-
|
|
|
|
|
- if (!this.activeRange || !isRangesEqual(this.activeRange, ranges.activeRange)) {
|
|
|
|
|
- // some sort of change
|
|
|
|
|
-
|
|
|
|
|
- this.currentRange = ranges.currentRange;
|
|
|
|
|
- this.currentRangeUnit = ranges.currentRangeUnit;
|
|
|
|
|
- this.renderRange = ranges.renderRange;
|
|
|
|
|
- this.activeRange = ranges.activeRange;
|
|
|
|
|
- this.dateIncrement = ranges.dateIncrement;
|
|
|
|
|
- this.currentDate = ranges.date;
|
|
|
|
|
-
|
|
|
|
|
- // DEPRECATED, but we need to keep it updated
|
|
|
|
|
- // TODO: run automated tests with this commented out
|
|
|
|
|
- this.start = ranges.activeRange.start;
|
|
|
|
|
- this.end = ranges.activeRange.end;
|
|
|
|
|
- this.intervalStart = ranges.currentRange.start;
|
|
|
|
|
- this.intervalEnd = ranges.currentRange.end;
|
|
|
|
|
-
|
|
|
|
|
- this.updateTitle();
|
|
|
|
|
- this.calendar.updateToolbarButtons();
|
|
|
|
|
-
|
|
|
|
|
- return true;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return false;
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildRangeInfo: function(date, direction) {
|
|
|
|
|
- var validRange = this.buildValidRange();
|
|
|
|
|
- var isDateValid = isDateWithinRange(date, validRange);
|
|
|
|
|
- var currentInfo;
|
|
|
|
|
- var renderRange;
|
|
|
|
|
- var activeRange;
|
|
|
|
|
- var isVisibleRangeValid;
|
|
|
|
|
-
|
|
|
|
|
- date = constrainDate(date, validRange);
|
|
|
|
|
- currentInfo = this.buildCurrentRangeInfo(date, direction);
|
|
|
|
|
- renderRange = this.buildRenderRange(currentInfo.range, currentInfo.unit);
|
|
|
|
|
- activeRange = constrainRange(renderRange, validRange);
|
|
|
|
|
-
|
|
|
|
|
- if (this.opt('disableNonCurrentDates')) {
|
|
|
|
|
- activeRange = constrainRange(activeRange, currentInfo.range);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- date = constrainDate(date, activeRange);
|
|
|
|
|
- isVisibleRangeValid = Boolean(intersectRanges(activeRange, currentInfo.range));
|
|
|
|
|
-
|
|
|
|
|
- return {
|
|
|
|
|
- validRange: validRange,
|
|
|
|
|
- currentRange: currentInfo.range,
|
|
|
|
|
- currentRangeUnit: currentInfo.unit,
|
|
|
|
|
- activeRange: activeRange,
|
|
|
|
|
- renderRange: renderRange,
|
|
|
|
|
- isValid: isDateValid && isVisibleRangeValid,
|
|
|
|
|
- date: date,
|
|
|
|
|
- dateIncrement: this.buildDateIncrement(currentInfo.duration)
|
|
|
|
|
- };
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildValidRange: function() {
|
|
|
|
|
- return this.getRangeOption('validRange', this.calendar.getNow()) || {};
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildCurrentRangeInfo: function(date, direction) {
|
|
|
|
|
- var duration = null;
|
|
|
|
|
- var unit = null;
|
|
|
|
|
- var range = null;
|
|
|
|
|
- var dayCount;
|
|
|
|
|
-
|
|
|
|
|
- if (this.viewSpec.duration) {
|
|
|
|
|
- duration = this.viewSpec.duration;
|
|
|
|
|
- unit = this.viewSpec.durationUnit;
|
|
|
|
|
- range = this.buildRangeFromDuration(date, direction, duration, unit);
|
|
|
|
|
- }
|
|
|
|
|
- else if ((dayCount = this.opt('dayCount'))) {
|
|
|
|
|
- unit = 'day';
|
|
|
|
|
- range = this.buildRangeFromDayCount(date, direction, dayCount);
|
|
|
|
|
- }
|
|
|
|
|
- else if ((range = this.buildCustomVisibleRange(date))) {
|
|
|
|
|
- unit = computeIntervalUnit(range.start, range.end);
|
|
|
|
|
- }
|
|
|
|
|
- else {
|
|
|
|
|
- unit = 'day';
|
|
|
|
|
- duration = moment.duration({ days: 1 });
|
|
|
|
|
- range = this.buildRangeFromDuration(date, direction, duration, unit);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- range = this.filterCurrentRange(range, unit);
|
|
|
|
|
-
|
|
|
|
|
- return { duration: duration, unit: unit, range: range };
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- filterCurrentRange: function(currentRange, unit) {
|
|
|
|
|
-
|
|
|
|
|
- // normalize the range's time-ambiguity
|
|
|
|
|
- if (/^(year|month|week|day)$/.test(unit)) { // whole-days?
|
|
|
|
|
- currentRange.start.stripTime();
|
|
|
|
|
- currentRange.end.stripTime();
|
|
|
|
|
- }
|
|
|
|
|
- else { // needs to have a time?
|
|
|
|
|
- if (!currentRange.start.hasTime()) {
|
|
|
|
|
- currentRange.start.time(0); // give 00:00 time
|
|
|
|
|
- }
|
|
|
|
|
- if (!currentRange.end.hasTime()) {
|
|
|
|
|
- currentRange.end.time(0); // give 00:00 time
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return currentRange;
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildRangeFromDuration: function(date, direction, duration, unit) {
|
|
|
|
|
- var customAlignment = this.opt('dateAlignment');
|
|
|
|
|
- var start = date.clone();
|
|
|
|
|
- var end;
|
|
|
|
|
-
|
|
|
|
|
- // if the view displays a single day or smaller
|
|
|
|
|
- if (duration.as('days') <= 1) {
|
|
|
|
|
- if (this.isHiddenDay(start)) {
|
|
|
|
|
- start = this.skipHiddenDays(start, direction);
|
|
|
|
|
- start.startOf('day');
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- start.startOf(customAlignment || unit);
|
|
|
|
|
- end = start.clone().add(duration);
|
|
|
|
|
-
|
|
|
|
|
- return { start: start, end: end };
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildRangeFromDayCount: function(date, direction, dayCount) {
|
|
|
|
|
- var customAlignment = this.opt('dateAlignment');
|
|
|
|
|
- var runningCount = 0;
|
|
|
|
|
- var start = date.clone();
|
|
|
|
|
- var end;
|
|
|
|
|
-
|
|
|
|
|
- if (customAlignment) {
|
|
|
|
|
- start.startOf(customAlignment);
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- start.startOf('day');
|
|
|
|
|
- start = this.skipHiddenDays(start, direction);
|
|
|
|
|
-
|
|
|
|
|
- end = start.clone();
|
|
|
|
|
- do {
|
|
|
|
|
- end.add(1, 'day');
|
|
|
|
|
- if (!this.isHiddenDay(end)) {
|
|
|
|
|
- runningCount++;
|
|
|
|
|
- }
|
|
|
|
|
- } while (runningCount < dayCount);
|
|
|
|
|
-
|
|
|
|
|
- return { start: start, end: end };
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildCustomVisibleRange: function(date) {
|
|
|
|
|
- var visibleRange = this.getRangeOption('visibleRange', date);
|
|
|
|
|
-
|
|
|
|
|
- if (visibleRange && (!visibleRange.start || !visibleRange.end)) {
|
|
|
|
|
- return null;
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- return visibleRange;
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Computes the date range that will be rendered.
|
|
|
|
|
- buildRenderRange: function(currentRange) {
|
|
|
|
|
- return this.trimHiddenDays(currentRange);
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildDateIncrement: function(fallback) {
|
|
|
|
|
- var dateIncrementInput = this.opt('dateIncrement');
|
|
|
|
|
- var 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(1, 'day');
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildPrevRangeInfo: function(date) {
|
|
|
|
|
- var prevDate = date.clone().startOf(this.currentRangeUnit).subtract(this.dateIncrement);
|
|
|
|
|
-
|
|
|
|
|
- return this.buildRangeInfo(prevDate, -1);
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- buildNextRangeInfo: function(date) {
|
|
|
|
|
- var nextDate = date.clone().startOf(this.currentRangeUnit).add(this.dateIncrement);
|
|
|
|
|
-
|
|
|
|
|
- return this.buildRangeInfo(nextDate, 1);
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- trimHiddenDays: function(inputRange) {
|
|
|
|
|
- return {
|
|
|
|
|
- start: this.skipHiddenDays(inputRange.start),
|
|
|
|
|
- end: this.skipHiddenDays(inputRange.end, -1, true) // exclusively move backwards
|
|
|
|
|
- };
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- currentRangeAs: function(unit) {
|
|
|
|
|
- var currentRange = this.currentRange;
|
|
|
|
|
- return currentRange.end.diff(currentRange.start, unit, true);
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // arguments after name will be forwarded to a hypothetical function value
|
|
|
|
|
- getRangeOption: function(name) {
|
|
|
|
|
- var val = this.opt(name);
|
|
|
|
|
-
|
|
|
|
|
- if (typeof val === 'function') {
|
|
|
|
|
- val = val.apply(
|
|
|
|
|
- null,
|
|
|
|
|
- Array.prototype.slice.call(arguments, 1)
|
|
|
|
|
- );
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (val) {
|
|
|
|
|
- return this.calendar.parseRange(val);
|
|
|
|
|
- }
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
/* Title and Date Formatting
|
|
/* Title and Date Formatting
|
|
|
------------------------------------------------------------------------------------------------------------------*/
|
|
------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
@@ -1605,60 +1327,6 @@ var View = FC.View = Class.extend(EmitterMixin, ListenerMixin, {
|
|
|
------------------------------------------------------------------------------------------------------------------*/
|
|
------------------------------------------------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
|
|
|
|
|
- // Initializes internal variables related to calculating hidden days-of-week
|
|
|
|
|
- initHiddenDays: function() {
|
|
|
|
|
- var hiddenDays = this.opt('hiddenDays') || []; // array of day-of-week indices that are hidden
|
|
|
|
|
- var isHiddenDayHash = []; // is the day-of-week hidden? (hash with day-of-week-index -> bool)
|
|
|
|
|
- var dayCnt = 0;
|
|
|
|
|
- var i;
|
|
|
|
|
-
|
|
|
|
|
- if (this.opt('weekends') === false) {
|
|
|
|
|
- hiddenDays.push(0, 6); // 0=sunday, 6=saturday
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- for (i = 0; i < 7; i++) {
|
|
|
|
|
- if (
|
|
|
|
|
- !(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)
|
|
|
|
|
- ) {
|
|
|
|
|
- dayCnt++;
|
|
|
|
|
- }
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- if (!dayCnt) {
|
|
|
|
|
- throw 'invalid hiddenDays'; // all days were hidden? bad.
|
|
|
|
|
- }
|
|
|
|
|
-
|
|
|
|
|
- this.isHiddenDayHash = isHiddenDayHash;
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Is the current day hidden?
|
|
|
|
|
- // `day` is a day-of-week index (0-6), or a Moment
|
|
|
|
|
- isHiddenDay: function(day) {
|
|
|
|
|
- if (moment.isMoment(day)) {
|
|
|
|
|
- day = day.day();
|
|
|
|
|
- }
|
|
|
|
|
- return this.isHiddenDayHash[day];
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
- // Incrementing the current day until it is no longer a hidden day, returning a copy.
|
|
|
|
|
- // DOES NOT CONSIDER validRange!
|
|
|
|
|
- // If the initial value of `date` is not a hidden day, don't do anything.
|
|
|
|
|
- // Pass `isExclusive` as `true` if you are dealing with an end date.
|
|
|
|
|
- // `inc` defaults to `1` (increment one day forward each time)
|
|
|
|
|
- skipHiddenDays: function(date, inc, isExclusive) {
|
|
|
|
|
- var out = date.clone();
|
|
|
|
|
- inc = inc || 1;
|
|
|
|
|
- while (
|
|
|
|
|
- this.isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]
|
|
|
|
|
- ) {
|
|
|
|
|
- out.add(inc, 'days');
|
|
|
|
|
- }
|
|
|
|
|
- return out;
|
|
|
|
|
- },
|
|
|
|
|
-
|
|
|
|
|
-
|
|
|
|
|
// Returns the date range of the full days the given range visually appears to occupy.
|
|
// Returns the date range of the full days the given range visually appears to occupy.
|
|
|
// Returns a new range object.
|
|
// Returns a new range object.
|
|
|
computeDayRange: function(range) {
|
|
computeDayRange: function(range) {
|