Przeglądaj źródła

important bugfix and enhancements to custom-view buttonText

Adam Shaw 11 lat temu
rodzic
commit
334324bc0f
3 zmienionych plików z 197 dodań i 24 usunięć
  1. 39 18
      src/Calendar.js
  2. 5 5
      src/Header.js
  3. 153 1
      tests/automated/custom-view-duration.js

+ 39 - 18
src/Calendar.js

@@ -59,7 +59,7 @@ function Calendar(element, instanceOptions) {
 	t.option = option;
 	t.option = option;
 	t.trigger = trigger;
 	t.trigger = trigger;
 	t.isValidViewType = isValidViewType;
 	t.isValidViewType = isValidViewType;
-	t.getDefaultViewButtonText = getDefaultViewButtonText;
+	t.getViewButtonText = getViewButtonText;
 
 
 
 
 
 
@@ -69,7 +69,7 @@ function Calendar(element, instanceOptions) {
 
 
 
 
 	var localeData = createObject( // make a cheap copy
 	var localeData = createObject( // make a cheap copy
-		getMomentLocaleData(options.lang)
+		getMomentLocaleData(options.lang) // will fall back to en
 	);
 	);
 
 
 	if (options.monthNames) {
 	if (options.monthNames) {
@@ -203,6 +203,14 @@ function Calendar(element, instanceOptions) {
 	};
 	};
 
 
 
 
+	// Produces a human-readable string for the given duration.
+	// Side-effect: changes the locale of the given duration.
+	function humanizeDuration(duration) {
+		return (duration.locale || duration.lang).call(duration, options.lang) // works moment-pre-2.8
+			.humanize();
+	}
+
+
 	
 	
 	// Imports
 	// Imports
 	// -----------------------------------------------------------------------------------
 	// -----------------------------------------------------------------------------------
@@ -398,12 +406,15 @@ function Calendar(element, instanceOptions) {
 
 
 	// Gets information about how to create a view
 	// Gets information about how to create a view
 	function getViewSpec(requestedViewType) {
 	function getViewSpec(requestedViewType) {
-		var hash = options.views || {};
+		var allDefaultButtonText = options.defaultButtonText || {};
+		var allButtonText = options.buttonText || {};
+		var hash = options.views || {}; // the `views` option object
 		var viewType = requestedViewType;
 		var viewType = requestedViewType;
 		var viewOptionsChain = [];
 		var viewOptionsChain = [];
 		var viewOptions;
 		var viewOptions;
 		var viewClass;
 		var viewClass;
-		var duration;
+		var duration, unit, unitIsSingle = false;
+		var buttonText;
 
 
 		if (viewSpecCache[requestedViewType]) {
 		if (viewSpecCache[requestedViewType]) {
 			return viewSpecCache[requestedViewType];
 			return viewSpecCache[requestedViewType];
@@ -432,20 +443,33 @@ function Calendar(element, instanceOptions) {
 
 
 		if (viewClass) {
 		if (viewClass) {
 
 
-			// options that are specified per the view's duration, like "week" or "day"
 			duration = viewOptions.duration || viewClass.duration;
 			duration = viewOptions.duration || viewClass.duration;
 			if (duration) {
 			if (duration) {
 				duration = moment.duration(duration);
 				duration = moment.duration(duration);
-				$.each(intervalUnits, function(i, unit) {
-					if (hash[unit] && computeIntervalAs(unit, duration) === 1) {
-						viewOptions = $.extend({}, hash[unit], viewOptions); // lowest priority
-					}
-				});
+				unit = computeIntervalUnit(duration);
+				unitIsSingle = computeIntervalAs(unit, duration) === 1;
 			}
 			}
 
 
+			// options that are specified per the view's duration, like "week" or "day"
+			if (unitIsSingle && hash[unit]) {
+				viewOptions = $.extend({}, hash[unit], viewOptions); // lowest priority
+			}
+
+			// compute the final text for the button representing this view
+			buttonText =
+				allButtonText[requestedViewType] || // init options, like "agendaWeek"
+				(unitIsSingle ? allButtonText[unit] : null) || // init options, like "week"
+				allDefaultButtonText[requestedViewType] || // lang data, like "agendaWeek"
+				(unitIsSingle ? allDefaultButtonText[unit] : null) || // lang data, like "week"
+				viewOptions.buttonText ||
+				viewClass.buttonText ||
+				(duration ? humanizeDuration(duration) : null) ||
+				requestedViewType;
+
 			return (viewSpecCache[requestedViewType] = {
 			return (viewSpecCache[requestedViewType] = {
 				'class': viewClass,
 				'class': viewClass,
-				options: viewOptions
+				options: viewOptions,
+				buttonText: buttonText
 			});
 			});
 		}
 		}
 	}
 	}
@@ -457,15 +481,12 @@ function Calendar(element, instanceOptions) {
 	}
 	}
 
 
 
 
-	// Gets the text that should be displayed on a view's button in the header, by default.
-	// Values in the global `buttonText` option will eventually override this value.
-	function getDefaultViewButtonText(viewType) {
+	// Gets the text that should be displayed on a view's button in the header
+	function getViewButtonText(viewType) {
 		var spec = getViewSpec(viewType);
 		var spec = getViewSpec(viewType);
 
 
-		if (spec) { // valid view?
-			return smartProperty(options.defaultButtonText, viewType) || // takes precedence. defined by languages
-				spec.options.buttonText || // defined by custom view options
-				viewType; // last resort
+		if (spec) {
+			return spec.buttonText;
 		}
 		}
 	}
 	}
 	
 	

+ 5 - 5
src/Header.js

@@ -59,7 +59,7 @@ function Header(calendar, options) {
 					var themeIcon;
 					var themeIcon;
 					var normalIcon;
 					var normalIcon;
 					var defaultText;
 					var defaultText;
-					var defaultViewText;
+					var viewText; // highest priority
 					var customText;
 					var customText;
 					var innerHtml;
 					var innerHtml;
 					var classes;
 					var classes;
@@ -80,7 +80,7 @@ function Header(calendar, options) {
 								calendar.changeView(buttonName);
 								calendar.changeView(buttonName);
 							};
 							};
 							viewsWithButtons.push(buttonName);
 							viewsWithButtons.push(buttonName);
-							defaultViewText = calendar.getDefaultViewButtonText(buttonName);
+							viewText = calendar.getViewButtonText(buttonName);
 						}
 						}
 						if (buttonClick) {
 						if (buttonClick) {
 
 
@@ -90,8 +90,8 @@ function Header(calendar, options) {
 							defaultText = smartProperty(options.defaultButtonText, buttonName); // from languages
 							defaultText = smartProperty(options.defaultButtonText, buttonName); // from languages
 							customText = smartProperty(options.buttonText, buttonName);
 							customText = smartProperty(options.buttonText, buttonName);
 
 
-							if (customText) {
-								innerHtml = htmlEscape(customText);
+							if (viewText || customText) {
+								innerHtml = htmlEscape(viewText || customText);
 							}
 							}
 							else if (themeIcon && options.theme) {
 							else if (themeIcon && options.theme) {
 								innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
 								innerHtml = "<span class='ui-icon ui-icon-" + themeIcon + "'></span>";
@@ -100,7 +100,7 @@ function Header(calendar, options) {
 								innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
 								innerHtml = "<span class='fc-icon fc-icon-" + normalIcon + "'></span>";
 							}
 							}
 							else {
 							else {
-								innerHtml = htmlEscape(defaultViewText || defaultText || buttonName);
+								innerHtml = htmlEscape(defaultText || buttonName);
 							}
 							}
 
 
 							classes = [
 							classes = [

+ 153 - 1
tests/automated/custom-view-duration.js

@@ -1,4 +1,4 @@
-describe('custom view duration', function() {
+describe('custom view', function() {
 	var options;
 	var options;
 
 
 	beforeEach(function() {
 	beforeEach(function() {
@@ -186,4 +186,156 @@ describe('custom view duration', function() {
 		expect($('.fc-day-grid .fc-day:first')).toBeMatchedBy('[data-date="2013-12-29"]');
 		expect($('.fc-day-grid .fc-day:first')).toBeMatchedBy('[data-date="2013-12-29"]');
 		expect($('.fc-day-grid .fc-day:last')).toBeMatchedBy('[data-date="2015-01-03"]');
 		expect($('.fc-day-grid .fc-day:last')).toBeMatchedBy('[data-date="2015-01-03"]');
 	});
 	});
+
+	describe('buttonText', function() {
+
+		it('accepts buttonText exact-match override', function() {
+			options.buttonText = {
+				custom: 'over-ridden'
+			};
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 4 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('over-ridden');
+		});
+
+		it('accepts buttonText single-unit-match override', function() {
+			options.buttonText = {
+				day: '1day-over-ridden'
+			};
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 1 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('1day-over-ridden');
+		});
+
+		it('does not accept buttonText unit-match override when unit is more than one', function() {
+			options.buttonText = {
+				day: '1day!!!???'
+			};
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 2 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('awesome');
+		});
+
+		it('accepts lang\'s defaultButtonText single-unit-match override', function() {
+			options.lang = 'fr';
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 1 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('Jour');
+		});
+
+		it('does not accept lang\'s defaultButtonText single-unit-match override when unit>1', function() {
+			options.lang = 'fr';
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 2 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('awesome');
+		});
+
+		it('respects custom view\'s value', function() {
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 4 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('awesome');
+		});
+
+		it('respects custom view\'s value, even when a "smart" property name', function() {
+			options.views.basicFourDay = { // "basicFourDay" is a pitfall for smartProperty
+				type: 'basic',
+				duration: { days: 4 },
+				buttonText: 'awesome'
+			};
+			options.header = {
+				center: 'basicFourDay,month'
+			};
+			options.defaultView = 'basicFourDay';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-basicFourDay-button')).toHaveText('awesome');
+		});
+
+		it('falls back to humanized duration when not given', function() {
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 4 }
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('4 days');
+		});
+
+		it('falls back to humanized duration and respects language', function() {
+			options.lang = 'fr';
+			options.views.custom = {
+				type: 'basic',
+				duration: { days: 4 }
+			};
+			options.header = {
+				center: 'custom,month'
+			};
+			options.defaultView = 'custom';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-custom-button')).toHaveText('4 jours');
+			expect($('.fc-month-button')).toHaveText('Mois'); // test for the heck of it
+		});
+
+		it('falls back to view name when view lacks metadata', function() {
+			options.views = {
+				crazy: $.fullCalendar.View.extend()
+			};
+			options.header = {
+				center: 'crazy,month'
+			};
+			options.defaultView = 'crazy';
+			$('#cal').fullCalendar(options);
+			expect($('.fc-crazy-button')).toHaveText('crazy');
+		});
+	});
 });
 });