Просмотр исходного кода

move closure at bottom of View to real methods

Adam Shaw 11 лет назад
Родитель
Сommit
31d4d046e7
3 измененных файлов с 119 добавлено и 133 удалено
  1. 1 1
      src/agenda/AgendaView.js
  2. 1 1
      src/basic/BasicView.js
  3. 117 131
      src/common/View.js

+ 1 - 1
src/agenda/AgendaView.js

@@ -31,7 +31,7 @@ var AgendaView = fcViews.agenda = View.extend({
 
 
 	constructor: function() {
-		View_constructor.apply(this, arguments); // call the super-constructor
+		View.apply(this, arguments); // call the super-constructor
 
 		this.timeGrid = new TimeGrid(this);
 

+ 1 - 1
src/basic/BasicView.js

@@ -17,7 +17,7 @@ var BasicView = fcViews.basic = View.extend({
 
 
 	constructor: function() {
-		View_constructor.apply(this, arguments); // call the super-constructor
+		View.apply(this, arguments); // call the super-constructor
 
 		this.dayGrid = new DayGrid(this);
 		this.coordMap = this.dayGrid.coordMap; // the view's date-to-cell mapping is identical to the subcomponent's

+ 117 - 131
src/common/View.js

@@ -1,7 +1,6 @@
 
 /* An abstract class from which other views inherit from
 ----------------------------------------------------------------------------------------------------------------------*/
-// Newer methods should be written as prototype methods, not in the monster `View` function at the bottom.
 
 var View = fc.View = Class.extend({
 
@@ -9,6 +8,7 @@ var View = fc.View = Class.extend({
 	name: null, // deprecated. use `type` instead
 
 	calendar: null, // owner Calendar object
+	options: null, // view-specific options
 	coordMap: null, // a CoordMap object for converting pixel regions to dates
 	el: null, // the view's containing element. set by Calendar
 
@@ -35,23 +35,56 @@ var View = fc.View = Class.extend({
 	widgetContentClass: null,
 	highlightStateClass: null,
 
+	// for date utils, computed from options
+	nextDayThreshold: null,
+	isHiddenDayHash: null,
+
 	// document handlers, bound to `this` object
 	documentMousedownProxy: null,
 
 
-	constructor: View_constructor, // will call init
+	constructor: function(calendar, viewOptions, viewType) {
+		this.calendar = calendar;
+		this.options = viewOptions;
+		this.type = this.name = viewType; // .name is deprecated
 
+		this.nextDayThreshold = moment.duration(this.opt('nextDayThreshold'));
+		this.initTheming();
+		this.initHiddenDays();
 
-	// Serves as a "constructor" to suppliment the monster `View` constructor below
-	init: function() {
-		var tm = this.opt('theme') ? 'ui' : 'fc';
+		this.documentMousedownProxy = $.proxy(this, 'documentMousedown');
+	},
 
-		this.widgetHeaderClass = tm + '-widget-header';
-		this.widgetContentClass = tm + '-widget-content';
-		this.highlightStateClass = tm + '-state-highlight';
 
-		// save references to `this`-bound handlers
-		this.documentMousedownProxy = $.proxy(this, 'documentMousedown');
+	// Retrieves an option with the given name
+	opt: function(name) {
+		var val;
+
+		val = this.options[name]; // look at view-specific options first
+		if (val !== undefined) {
+			return val;
+		}
+
+		val = this.calendar.options[name];
+		if ($.isPlainObject(val) && !isForcedAtomicOption(name)) { // view-option-hashes are deprecated
+			return smartProperty(val, this.type);
+		}
+
+		return val;
+	},
+
+
+	// Triggers handlers that are view-related. Modifies args before passing to calendar.
+	trigger: function(name, thisObj) { // arguments beyond thisObj are passed along
+		var calendar = this.calendar;
+
+		return calendar.trigger.apply(
+			calendar,
+			[name, thisObj || this].concat(
+				Array.prototype.slice.call(arguments, 2), // arguments beyond thisObj
+				[ this ] // always make the last argument a reference to the view. TODO: deprecate
+			)
+		);
 	},
 
 
@@ -201,6 +234,16 @@ var View = fc.View = Class.extend({
 	},
 
 
+	// Initializes internal variables related to theming
+	initTheming: function() {
+		var tm = this.opt('theme') ? 'ui' : 'fc';
+
+		this.widgetHeaderClass = tm + '-widget-header';
+		this.widgetContentClass = tm + '-widget-content';
+		this.highlightStateClass = tm + '-state-highlight';
+	},
+
+
 	/* Dimensions
 	------------------------------------------------------------------------------------------------------------------*/
 
@@ -361,6 +404,21 @@ var View = fc.View = Class.extend({
 	------------------------------------------------------------------------------------------------------------------*/
 
 
+	// Computes if the given event is allowed to be dragged by the user
+	isEventDraggable: function(event) {
+		var source = event.source || {};
+
+		return firstDefined(
+			event.startEditable,
+			source.startEditable,
+			this.opt('eventStartEditable'),
+			event.editable,
+			source.editable,
+			this.opt('editable')
+		);
+	},
+
+
 	// Must be called when an event in the view is dropped onto new location.
 	// `dropLocation` is an object that contains the new start/end/allDay values for the event.
 	reportEventDrop: function(event, dropLocation, el, ev) {
@@ -437,6 +495,21 @@ var View = fc.View = Class.extend({
 	------------------------------------------------------------------------------------------------------------------*/
 
 
+	// Computes if the given event is allowed to be resize by the user
+	isEventResizable: function(event) {
+		var source = event.source || {};
+
+		return firstDefined(
+			event.durationEditable,
+			source.durationEditable,
+			this.opt('eventDurationEditable'),
+			event.editable,
+			source.editable,
+			this.opt('editable')
+		);
+	},
+
+
 	// Must be called when an event in the view has been resized to a new length
 	reportEventResize: function(event, newEnd, el, ev) {
 		var calendar = this.calendar;
@@ -514,156 +587,69 @@ var View = fc.View = Class.extend({
 				this.unselect(ev);
 			}
 		}
-	}
-
-});
-
-
-// We are mixing JavaScript OOP design patterns here by putting methods and member variables in the closed scope of the
-// constructor. Going forward, methods should be part of the prototype.
-function View_constructor(calendar, viewOptions, viewType) {
-	var t = this;
-	
-	// exports
-	t.calendar = calendar;
-	t.opt = opt;
-	t.trigger = trigger;
-	t.isEventDraggable = isEventDraggable;
-	t.isEventResizable = isEventResizable;
-	
-	// locals
-	var options = calendar.options;
-	var nextDayThreshold = moment.duration(options.nextDayThreshold);
-
-
-	// important for view-specific opts
-	viewOptions = viewOptions || {};
-	t.type = t.name = viewType; // .name is deprecated
-
-
-	t.init(); // the "constructor" that concerns the prototype methods
-	
-	
-	function opt(name) {
-		var val;
-
-		val = viewOptions[name];
-		if (val !== undefined) {
-			return val;
-		}
-
-		val = options[name];
-		if ($.isPlainObject(val) && !isForcedAtomicOption(name)) {
-			return smartProperty(val, t.type);
-		}
-
-		return val;
-	}
-
-	
-	function trigger(name, thisObj) {
-		return calendar.trigger.apply(
-			calendar,
-			[name, thisObj || t].concat(Array.prototype.slice.call(arguments, 2), [t])
-		);
-	}
-	
-
-
-	/* Event Editable Boolean Calculations
-	------------------------------------------------------------------------------*/
-
-	
-	function isEventDraggable(event) {
-		var source = event.source || {};
-
-		return firstDefined(
-			event.startEditable,
-			source.startEditable,
-			opt('eventStartEditable'),
-			event.editable,
-			source.editable,
-			opt('editable')
-		);
-	}
-	
-	
-	function isEventResizable(event) {
-		var source = event.source || {};
-
-		return firstDefined(
-			event.durationEditable,
-			source.durationEditable,
-			opt('eventDurationEditable'),
-			event.editable,
-			source.editable,
-			opt('editable')
-		);
-	}
-
+	},
 
 
 	/* Date Utils
-	------------------------------------------------------------------------------*/
+	------------------------------------------------------------------------------------------------------------------*/
 
-	// exports
-	t.isHiddenDay = isHiddenDay;
-	t.skipHiddenDays = skipHiddenDays;
-	t.computeDayRange = computeDayRange;
-	t.isMultiDayEvent = isMultiDayEvent;
 
+	// 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;
 
-	// internals
-	var hiddenDays = 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;
+		if (this.opt('weekends') === false) {
+			hiddenDays.push(0, 6); // 0=sunday, 6=saturday
+		}
 
-	if (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++;
+			}
+		}
 
-	for (var i = 0; i < 7; i++) {
-		if (
-			!(isHiddenDayHash[i] = $.inArray(i, hiddenDays) !== -1)
-		) {
-			dayCnt++;
+		if (!dayCnt) {
+			throw 'invalid hiddenDays'; // all days were hidden? bad.
 		}
-	}
 
-	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
-	function isHiddenDay(day) {
+	isHiddenDay: function(day) {
 		if (moment.isMoment(day)) {
 			day = day.day();
 		}
-		return isHiddenDayHash[day];
-	}
+		return this.isHiddenDayHash[day];
+	},
 
 
 	// Incrementing the current day until it is no longer a hidden day, returning a copy.
 	// 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)
-	function skipHiddenDays(date, inc, isExclusive) {
+	skipHiddenDays: function(date, inc, isExclusive) {
 		var out = date.clone();
 		inc = inc || 1;
 		while (
-			isHiddenDayHash[(out.day() + (isExclusive ? inc : 0) + 7) % 7]
+			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 a new range object.
-	function computeDayRange(range) {
+	computeDayRange: function(range) {
 		var startDay = range.start.clone().stripTime(); // the beginning of the day the range starts
 		var end = range.end;
 		var endDay = null;
@@ -676,7 +662,7 @@ function View_constructor(calendar, viewOptions, viewType) {
 			// 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 >= nextDayThreshold) {
+			if (endTimeMS && endTimeMS >= this.nextDayThreshold) {
 				endDay.add(1, 'days');
 			}
 		}
@@ -688,17 +674,17 @@ function View_constructor(calendar, viewOptions, viewType) {
 		}
 
 		return { start: startDay, end: endDay };
-	}
+	},
 
 
 	// Does the given event visually appear to occupy more than one day?
-	function isMultiDayEvent(event) {
-		var range = computeDayRange(event); // event is range-ish
+	isMultiDayEvent: function(event) {
+		var range = this.computeDayRange(event); // event is range-ish
 
 		return range.end.diff(range.start, 'days') > 1;
 	}
 
-}
+});
 
 
 /* Utils