Jelajahi Sumber

change how EventDefs are parsed/contructed. cloning functionality

Adam Shaw 8 tahun lalu
induk
melakukan
44c398132b

+ 1 - 1
src/EventManager.js

@@ -1451,7 +1451,7 @@ Calendar.prototype._buildBusinessGroup = function(wholeDay, rawDefs, ignoreNoDow
 			fullRawDef.end = null;
 		}
 
-		eventDef = new RecurringEventDefinition(fullRawDef);
+		eventDef = RecurringEventDefinition.parse(fullRawDef);
 
 		eventInstances.push.apply(eventInstances, // append
 			eventDef.buildInstances(rangeStart, rangeEnd)

+ 58 - 23
src/models/EventDefinition.js

@@ -7,38 +7,73 @@ var EventDefinition = Class.extend({
 	rendering: null,
 	miscProps: null,
 
-	// calendar needed for zoned moment instantiation
-	constructor: function(rawProps, source, calendar) {
-		this.source = source;
-		this.id = rawProps.id || ('_fc' + (++EventDefinition.uuid));
-		this.title = rawProps.title || '';
-		this.rendering = rawProps.rendering || null;
-
-		this.assignMiscProps(rawProps);
-	},
-
-	assignMiscProps: function(rawProps) {
-		var miscProps = {};
-		var name;
-
-		for (name in rawProps) {
-			if (!this.isStandardProp(name)) {
-				miscProps[name] = rawProps[name];
-			}
-		}
 
-		this.miscProps = miscProps;
+	constructor: function() {
+		this.miscProps = {};
 	},
 
-	isStandardProp: function(name) {
-		return name === 'id' || name === 'title' || name === 'rendering';
-	},
 
 	buildInstances: function(start, end) {
 		// subclasses must implement
+	},
+
+
+	clone: function() {
+		var copy = new this.constructor();
+
+		copy.source = this.source;
+		copy.id = this.id;
+		copy.title = this.title;
+		copy.rendering = this.rendering;
+		copy.miscProps = $.extend({}, this.miscProps);
+
+		return copy;
 	}
 
 });
 
+
 EventDefinition.uuid = 0;
+EventDefinition.reservedPropMap = {};
+
+
+EventDefinition.addReservedProps = function(props) {
+	var map = {};
+	var propName;
+
+	for (propName in props) {
+		map[propName] = true;
+	}
+
+	// won't modify original object. don't want sideeffects on superclasses
+	this.reservedPropMap = $.extend({}, this.reservedPropMap, map);
+};
+
+
+EventDefinition.isReservedProp = function(propName) {
+	return this.reservedPropMap[propName] || false;
+};
+
+
+EventDefinition.parse = function(rawProps) {
+	var def = new this();
+	var propName;
+	var miscProps = {};
+
+	def.id = rawProps.id || ('_fc' + (++EventDefinition.uuid));
+	def.title = rawProps.title || '';
+	def.rendering = rawProps.rendering || null;
+
+	for (propName in rawProps) {
+		if (!this.isReservedProp(propName)) {
+			miscProps[propName] = rawProps[propName];
+		}
+	}
+
+	def.miscProps = miscProps;
+
+	return def;
+};
+
 
+EventDefinition.addReservedProps([ 'id', 'title', 'rendering' ]);

+ 13 - 4
src/models/EventDefinitionCollection.js

@@ -12,23 +12,32 @@ var EventDefinitionCollection = Class.extend({
 	},
 
 	addRaw: function(eventInput, source) {
-		var eventDefsById = this.eventDefsById;
 		var eventDef;
 
 		if (isEventInputRecurring(eventInput)) {
-			eventDef = new RecurringEventDefinition(eventInput, source, this.calendar);
+			eventDef = RecurringEventDefinition.parse(eventInput);
 		}
 		else {
-			eventDef = new SingleEventDefinition(eventInput, source, this.calendar);
+			eventDef = SingleEventDefinition.parse(eventInput, this.calendar);
+		}
+
+		if (source) {
+			eventDef.source = source;
 		}
 
+		this.add(eventDef);
+	},
+
+	add: function(eventDef) {
+		var eventDefsById = this.eventDefsById;
+
 		this.eventDefs.push(eventDef);
 
 		(eventDefsById[eventDef.id] || (eventDefsById[eventDef.id] = []))
 			.push(eventDef);
 	},
 
-	getById: function(id) {
+	getById: function(id) { // TODO: getArrayById
 		return this.eventDefsById[id];
 	},
 

+ 47 - 27
src/models/RecurringEventDefinition.js

@@ -5,26 +5,6 @@ var RecurringEventDefinition = EventDefinition.extend({
 	endTime: null,
 	dowHash: null,
 
-	constructor: function(rawProps, source, calendar) {
-		EventDefinition.apply(this, arguments);
-
-		if (rawProps.start) {
-			this.startTime = moment.duration(rawProps.start);
-		}
-
-		if (rawProps.end) {
-			this.endTime = moment.duration(rawProps.end);
-		}
-
-		if (rawProps.dow) {
-			this.dowHash = this.buildDowHash(rawProps.dow);
-		}
-	},
-
-	isStandardProp: function(name) {
-		return EventDefinition.prototype.isStandardProp(name) ||
-			name === 'start' || name === 'end' || name === 'dow';
-	},
 
 	buildInstances: function(start, end) {
 		var date = start.clone();
@@ -64,16 +44,56 @@ var RecurringEventDefinition = EventDefinition.extend({
 		return eventInstances;
 	},
 
-	buildDowHash: function(dowArray) {
-		var dowHash = {};
-		var i;
 
-		// make a boolean hash as to whether the event occurs on each day-of-week
-		for (i = 0; i < dowArray.length; i++) {
-			dowHash[dowArray[i]] = true;
+	setDow: function(dowArray) {
+		if (!this.dowHash) {
+			this.dowHash = {};
+		}
+
+		for (var i = 0; i < dowArray.length; i++) {
+			this.dowHash[dowArray[i]] = true;
+		}
+	},
+
+
+	clone: function() {
+		var def = EventDefinition.prototype.clone.call(this);
+
+		if (def.startTime) {
+			def.startTime = moment.duration(this.startTime);
 		}
 
-		return dowHash;
+		if (def.endTime) {
+			def.endTime = moment.duration(this.endTime);
+		}
+
+		if (this.dowHash) {
+			def.dowHash = $.extend({}, this.dowHash);
+		}
+
+		return def;
 	}
 
 });
+
+
+RecurringEventDefinition.addReservedProps([ 'start', 'end', 'dow' ]);
+
+
+RecurringEventDefinition.parse = function(rawProps) {
+	var def = EventDefinition.parse.call(this, rawProps); // RecurringEventDefinition
+
+	if (rawProps.start) {
+		def.startTime = moment.duration(rawProps.start);
+	}
+
+	if (rawProps.end) {
+		def.endTime = moment.duration(rawProps.end);
+	}
+
+	if (rawProps.dow) {
+		def.setDow(rawProps.dow);
+	}
+
+	return def;
+};

+ 26 - 11
src/models/SingleEventDefinition.js

@@ -4,17 +4,6 @@ var SingleEventDefinition = EventDefinition.extend({
 	start: null,
 	end: null,
 
-	constructor: function(rawProps, source, calendar) {
-		EventDefinition.apply(this, arguments);
-
-		this.start = calendar.moment(rawProps.start || rawProps.date); // 'date' is an alias
-		this.end = rawProps.end ? calendar.moment(rawProps.end) : null;
-	},
-
-	isStandardProp: function(name) {
-		return EventDefinition.prototype.isStandardProp(name) ||
-			name === 'start' || name === 'end' || name === 'date'; // 'date' is an alias
-	},
 
 	buildInstances: function() { // disregards start/end
 		return [
@@ -23,6 +12,32 @@ var SingleEventDefinition = EventDefinition.extend({
 				new EventDateProfile(this.start, this.end)
 			)
 		];
+	},
+
+
+	clone: function() {
+		var def = EventDefinition.prototype.clone.call(this);
+
+		def.start = this.start.clone();
+
+		if (this.end) {
+			def.end = this.end.clone();
+		}
+
+		return def;
 	}
 
 });
+
+
+SingleEventDefinition.addReservedProps([ 'start', 'end', 'date' ]);
+
+
+SingleEventDefinition.parse = function(rawProps, calendar) {
+	var def = EventDefinition.parse.call(this, rawProps); // a SingleEventDefinition
+
+	def.start = calendar.moment(rawProps.start || rawProps.date); // 'date' is an alias
+	def.end = rawProps.end ? calendar.moment(rawProps.end) : null;
+
+	return def;
+};