You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@wicket.apache.org by jd...@apache.org on 2010/12/30 12:53:40 UTC
svn commit: r1053863 [3/9] - in /wicket/trunk/wicket-datetime/src:
main/java/org/apache/wicket/extensions/yui/
main/java/org/apache/wicket/extensions/yui/calendar/
main/java/org/apache/wicket/extensions/yui/calendar/assets/skins/sam/
main/java/org/apac...
Modified: wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/calendar.js
URL: http://svn.apache.org/viewvc/wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/calendar.js?rev=1053863&r1=1053862&r2=1053863&view=diff
==============================================================================
--- wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/calendar.js (original)
+++ wicket/trunk/wicket-datetime/src/main/java/org/apache/wicket/extensions/yui/calendar/calendar.js Thu Dec 30 11:53:40 2010
@@ -1,8 +1,8 @@
/*
-Copyright (c) 2009, Yahoo! Inc. All rights reserved.
+Copyright (c) 2010, Yahoo! Inc. All rights reserved.
Code licensed under the BSD License:
-http://developer.yahoo.net/yui/license.txt
-version: 2.7.0
+http://developer.yahoo.com/yui/license.html
+version: 2.8.2r1
*/
(function () {
@@ -537,18 +537,19 @@ version: 2.7.0
* the property's event
* @param {Object} obj The Object to use for scoping the event handler
* (see CustomEvent documentation)
- * @param {Boolean} override Optional. If true, will override "this"
- * within the handler to map to the scope Object passed into the method.
+ * @param {Boolean} overrideContext Optional. If true, will override
+ * "this" within the handler to map to the scope Object passed into the
+ * method.
* @return {Boolean} True, if the subscription was successful,
* otherwise false.
*/
- subscribeToConfigEvent: function (key, handler, obj, override) {
+ subscribeToConfigEvent: function (key, handler, obj, overrideContext) {
var property = this.config[key.toLowerCase()];
if (property && property.event) {
if (!Config.alreadySubscribed(property.event, handler, obj)) {
- property.event.subscribe(handler, obj, override);
+ property.event.subscribe(handler, obj, overrideContext);
}
return true;
} else {
@@ -690,401 +691,406 @@ version: 2.7.0
}());
/**
+* The datemath module provides utility methods for basic JavaScript Date object manipulation and
+* comparison.
+*
+* @module datemath
+*/
+
+/**
* YAHOO.widget.DateMath is used for simple date manipulation. The class is a static utility
* used for adding, subtracting, and comparing dates.
* @namespace YAHOO.widget
* @class DateMath
*/
YAHOO.widget.DateMath = {
- /**
- * Constant field representing Day
- * @property DAY
- * @static
- * @final
- * @type String
- */
- DAY : "D",
-
- /**
- * Constant field representing Week
- * @property WEEK
- * @static
- * @final
- * @type String
- */
- WEEK : "W",
-
- /**
- * Constant field representing Year
- * @property YEAR
- * @static
- * @final
- * @type String
- */
- YEAR : "Y",
-
- /**
- * Constant field representing Month
- * @property MONTH
- * @static
- * @final
- * @type String
- */
- MONTH : "M",
-
- /**
- * Constant field representing one day, in milliseconds
- * @property ONE_DAY_MS
- * @static
- * @final
- * @type Number
- */
- ONE_DAY_MS : 1000*60*60*24,
-
- /**
- * Constant field representing the date in first week of January
- * which identifies the first week of the year.
- * <p>
- * In the U.S, Jan 1st is normally used based on a Sunday start of week.
- * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
- * </p>
- * @property WEEK_ONE_JAN_DATE
- * @static
- * @type Number
- */
- WEEK_ONE_JAN_DATE : 1,
-
- /**
- * Adds the specified amount of time to the this instance.
- * @method add
- * @param {Date} date The JavaScript Date object to perform addition on
- * @param {String} field The field constant to be used for performing addition.
- * @param {Number} amount The number of units (measured in the field constant) to add to the date.
- * @return {Date} The resulting Date object
- */
- add : function(date, field, amount) {
- var d = new Date(date.getTime());
- switch (field) {
- case this.MONTH:
- var newMonth = date.getMonth() + amount;
- var years = 0;
-
- if (newMonth < 0) {
- while (newMonth < 0) {
- newMonth += 12;
- years -= 1;
- }
- } else if (newMonth > 11) {
- while (newMonth > 11) {
- newMonth -= 12;
- years += 1;
- }
- }
-
- d.setMonth(newMonth);
- d.setFullYear(date.getFullYear() + years);
- break;
- case this.DAY:
- this._addDays(d, amount);
- // d.setDate(date.getDate() + amount);
- break;
- case this.YEAR:
- d.setFullYear(date.getFullYear() + amount);
- break;
- case this.WEEK:
- this._addDays(d, (amount * 7));
- // d.setDate(date.getDate() + (amount * 7));
- break;
- }
- return d;
- },
-
- /**
- * Private helper method to account for bug in Safari 2 (webkit < 420)
- * when Date.setDate(n) is called with n less than -128 or greater than 127.
- * <p>
- * Fix approach and original findings are available here:
- * http://brianary.blogspot.com/2006/03/safari-date-bug.html
- * </p>
- * @method _addDays
- * @param {Date} d JavaScript date object
- * @param {Number} nDays The number of days to add to the date object (can be negative)
- * @private
- */
- _addDays : function(d, nDays) {
- if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
- if (nDays < 0) {
- // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
- for(var min = -128; nDays < min; nDays -= min) {
- d.setDate(d.getDate() + min);
- }
- } else {
- // Ensure we don't go above 96 + 31 = 127
- for(var max = 96; nDays > max; nDays -= max) {
- d.setDate(d.getDate() + max);
- }
- }
- // nDays should be remainder between -128 and 96
- }
- d.setDate(d.getDate() + nDays);
- },
-
- /**
- * Subtracts the specified amount of time from the this instance.
- * @method subtract
- * @param {Date} date The JavaScript Date object to perform subtraction on
- * @param {Number} field The this field constant to be used for performing subtraction.
- * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
- * @return {Date} The resulting Date object
- */
- subtract : function(date, field, amount) {
- return this.add(date, field, (amount*-1));
- },
-
- /**
- * Determines whether a given date is before another date on the calendar.
- * @method before
- * @param {Date} date The Date object to compare with the compare argument
- * @param {Date} compareTo The Date object to use for the comparison
- * @return {Boolean} true if the date occurs before the compared date; false if not.
- */
- before : function(date, compareTo) {
- var ms = compareTo.getTime();
- if (date.getTime() < ms) {
- return true;
- } else {
- return false;
- }
- },
-
- /**
- * Determines whether a given date is after another date on the calendar.
- * @method after
- * @param {Date} date The Date object to compare with the compare argument
- * @param {Date} compareTo The Date object to use for the comparison
- * @return {Boolean} true if the date occurs after the compared date; false if not.
- */
- after : function(date, compareTo) {
- var ms = compareTo.getTime();
- if (date.getTime() > ms) {
- return true;
- } else {
- return false;
- }
- },
-
- /**
- * Determines whether a given date is between two other dates on the calendar.
- * @method between
- * @param {Date} date The date to check for
- * @param {Date} dateBegin The start of the range
- * @param {Date} dateEnd The end of the range
- * @return {Boolean} true if the date occurs between the compared dates; false if not.
- */
- between : function(date, dateBegin, dateEnd) {
- if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
- return true;
- } else {
- return false;
- }
- },
-
- /**
- * Retrieves a JavaScript Date object representing January 1 of any given year.
- * @method getJan1
- * @param {Number} calendarYear The calendar year for which to retrieve January 1
- * @return {Date} January 1 of the calendar year specified.
- */
- getJan1 : function(calendarYear) {
- return this.getDate(calendarYear,0,1);
- },
-
- /**
- * Calculates the number of days the specified date is from January 1 of the specified calendar year.
- * Passing January 1 to this function would return an offset value of zero.
- * @method getDayOffset
- * @param {Date} date The JavaScript date for which to find the offset
- * @param {Number} calendarYear The calendar year to use for determining the offset
- * @return {Number} The number of days since January 1 of the given year
- */
- getDayOffset : function(date, calendarYear) {
- var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
-
- // Find the number of days the passed in date is away from the calendar year start
- var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
- return dayOffset;
- },
-
- /**
- * Calculates the week number for the given date. Can currently support standard
- * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
- * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
- *
- * @method getWeekNumber
- * @param {Date} date The JavaScript date for which to find the week number
- * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
- * Defaults to 0
- * @param {Number} janDate The date in the first week of January which defines week one for the year
- * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
- * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
- *
- * @return {Number} The number of the week containing the given date.
- */
- getWeekNumber : function(date, firstDayOfWeek, janDate) {
-
- // Setup Defaults
- firstDayOfWeek = firstDayOfWeek || 0;
- janDate = janDate || this.WEEK_ONE_JAN_DATE;
-
- var targetDate = this.clearTime(date),
- startOfWeek,
- endOfWeek;
-
- if (targetDate.getDay() === firstDayOfWeek) {
- startOfWeek = targetDate;
- } else {
- startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
- }
-
- var startYear = startOfWeek.getFullYear(),
- startTime = startOfWeek.getTime();
-
- // DST shouldn't be a problem here, math is quicker than setDate();
- endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
-
- var weekNum;
- if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
- // If years don't match, endOfWeek is in Jan. and if the
- // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
- weekNum = 1;
- } else {
- // Get the 1st day of the 1st week, and
- // find how many days away we are from it.
- var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
- weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
-
- // Round days to smoothen out 1 hr DST diff
- var daysDiff = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
-
- // Calc. Full Weeks
- var rem = daysDiff % 7;
- var weeksDiff = (daysDiff - rem)/7;
- weekNum = weeksDiff + 1;
- }
- return weekNum;
- },
-
- /**
- * Get the first day of the week, for the give date.
- * @param {Date} dt The date in the week for which the first day is required.
- * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
- * @return {Date} The first day of the week
- */
- getFirstDayOfWeek : function (dt, startOfWeek) {
- startOfWeek = startOfWeek || 0;
- var dayOfWeekIndex = dt.getDay(),
- dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
-
- return this.subtract(dt, this.DAY, dayOfWeek);
- },
-
- /**
- * Determines if a given week overlaps two different years.
- * @method isYearOverlapWeek
- * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
- * @return {Boolean} true if the date overlaps two different years.
- */
- isYearOverlapWeek : function(weekBeginDate) {
- var overlaps = false;
- var nextWeek = this.add(weekBeginDate, this.DAY, 6);
- if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
- overlaps = true;
- }
- return overlaps;
- },
-
- /**
- * Determines if a given week overlaps two different months.
- * @method isMonthOverlapWeek
- * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
- * @return {Boolean} true if the date overlaps two different months.
- */
- isMonthOverlapWeek : function(weekBeginDate) {
- var overlaps = false;
- var nextWeek = this.add(weekBeginDate, this.DAY, 6);
- if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
- overlaps = true;
- }
- return overlaps;
- },
-
- /**
- * Gets the first day of a month containing a given date.
- * @method findMonthStart
- * @param {Date} date The JavaScript Date used to calculate the month start
- * @return {Date} The JavaScript Date representing the first day of the month
- */
- findMonthStart : function(date) {
- var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
- return start;
- },
-
- /**
- * Gets the last day of a month containing a given date.
- * @method findMonthEnd
- * @param {Date} date The JavaScript Date used to calculate the month end
- * @return {Date} The JavaScript Date representing the last day of the month
- */
- findMonthEnd : function(date) {
- var start = this.findMonthStart(date);
- var nextMonth = this.add(start, this.MONTH, 1);
- var end = this.subtract(nextMonth, this.DAY, 1);
- return end;
- },
-
- /**
- * Clears the time fields from a given date, effectively setting the time to 12 noon.
- * @method clearTime
- * @param {Date} date The JavaScript Date for which the time fields will be cleared
- * @return {Date} The JavaScript Date cleared of all time fields
- */
- clearTime : function(date) {
- date.setHours(12,0,0,0);
- return date;
- },
-
- /**
- * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
- * are set to 0. The method allows Date instances to be created with the a year less than 100. "new Date(year, month, date)" implementations
- * set the year to 19xx if a year (xx) which is less than 100 is provided.
- * <p>
- * <em>NOTE:</em>Validation on argument values is not performed. It is the caller's responsibility to ensure
- * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
- * </p>
- * @method getDate
- * @param {Number} y Year.
- * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
- * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
- * @return {Date} The JavaScript date object with year, month, date set as provided.
- */
- getDate : function(y, m, d) {
- var dt = null;
- if (YAHOO.lang.isUndefined(d)) {
- d = 1;
- }
- if (y >= 100) {
- dt = new Date(y, m, d);
- } else {
- dt = new Date();
- dt.setFullYear(y);
- dt.setMonth(m);
- dt.setDate(d);
- dt.setHours(0,0,0,0);
- }
- return dt;
- }
-};
+ /**
+ * Constant field representing Day
+ * @property DAY
+ * @static
+ * @final
+ * @type String
+ */
+ DAY : "D",
+
+ /**
+ * Constant field representing Week
+ * @property WEEK
+ * @static
+ * @final
+ * @type String
+ */
+ WEEK : "W",
+
+ /**
+ * Constant field representing Year
+ * @property YEAR
+ * @static
+ * @final
+ * @type String
+ */
+ YEAR : "Y",
+
+ /**
+ * Constant field representing Month
+ * @property MONTH
+ * @static
+ * @final
+ * @type String
+ */
+ MONTH : "M",
+
+ /**
+ * Constant field representing one day, in milliseconds
+ * @property ONE_DAY_MS
+ * @static
+ * @final
+ * @type Number
+ */
+ ONE_DAY_MS : 1000*60*60*24,
+
+ /**
+ * Constant field representing the date in first week of January
+ * which identifies the first week of the year.
+ * <p>
+ * In the U.S, Jan 1st is normally used based on a Sunday start of week.
+ * ISO 8601, used widely throughout Europe, uses Jan 4th, based on a Monday start of week.
+ * </p>
+ * @property WEEK_ONE_JAN_DATE
+ * @static
+ * @type Number
+ */
+ WEEK_ONE_JAN_DATE : 1,
+
+ /**
+ * Adds the specified amount of time to the this instance.
+ * @method add
+ * @param {Date} date The JavaScript Date object to perform addition on
+ * @param {String} field The field constant to be used for performing addition.
+ * @param {Number} amount The number of units (measured in the field constant) to add to the date.
+ * @return {Date} The resulting Date object
+ */
+ add : function(date, field, amount) {
+ var d = new Date(date.getTime());
+ switch (field) {
+ case this.MONTH:
+ var newMonth = date.getMonth() + amount;
+ var years = 0;
+
+ if (newMonth < 0) {
+ while (newMonth < 0) {
+ newMonth += 12;
+ years -= 1;
+ }
+ } else if (newMonth > 11) {
+ while (newMonth > 11) {
+ newMonth -= 12;
+ years += 1;
+ }
+ }
+
+ d.setMonth(newMonth);
+ d.setFullYear(date.getFullYear() + years);
+ break;
+ case this.DAY:
+ this._addDays(d, amount);
+ // d.setDate(date.getDate() + amount);
+ break;
+ case this.YEAR:
+ d.setFullYear(date.getFullYear() + amount);
+ break;
+ case this.WEEK:
+ this._addDays(d, (amount * 7));
+ // d.setDate(date.getDate() + (amount * 7));
+ break;
+ }
+ return d;
+ },
+
+ /**
+ * Private helper method to account for bug in Safari 2 (webkit < 420)
+ * when Date.setDate(n) is called with n less than -128 or greater than 127.
+ * <p>
+ * Fix approach and original findings are available here:
+ * http://brianary.blogspot.com/2006/03/safari-date-bug.html
+ * </p>
+ * @method _addDays
+ * @param {Date} d JavaScript date object
+ * @param {Number} nDays The number of days to add to the date object (can be negative)
+ * @private
+ */
+ _addDays : function(d, nDays) {
+ if (YAHOO.env.ua.webkit && YAHOO.env.ua.webkit < 420) {
+ if (nDays < 0) {
+ // Ensure we don't go below -128 (getDate() is always 1 to 31, so we won't go above 127)
+ for(var min = -128; nDays < min; nDays -= min) {
+ d.setDate(d.getDate() + min);
+ }
+ } else {
+ // Ensure we don't go above 96 + 31 = 127
+ for(var max = 96; nDays > max; nDays -= max) {
+ d.setDate(d.getDate() + max);
+ }
+ }
+ // nDays should be remainder between -128 and 96
+ }
+ d.setDate(d.getDate() + nDays);
+ },
+
+ /**
+ * Subtracts the specified amount of time from the this instance.
+ * @method subtract
+ * @param {Date} date The JavaScript Date object to perform subtraction on
+ * @param {Number} field The this field constant to be used for performing subtraction.
+ * @param {Number} amount The number of units (measured in the field constant) to subtract from the date.
+ * @return {Date} The resulting Date object
+ */
+ subtract : function(date, field, amount) {
+ return this.add(date, field, (amount*-1));
+ },
+
+ /**
+ * Determines whether a given date is before another date on the calendar.
+ * @method before
+ * @param {Date} date The Date object to compare with the compare argument
+ * @param {Date} compareTo The Date object to use for the comparison
+ * @return {Boolean} true if the date occurs before the compared date; false if not.
+ */
+ before : function(date, compareTo) {
+ var ms = compareTo.getTime();
+ if (date.getTime() < ms) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Determines whether a given date is after another date on the calendar.
+ * @method after
+ * @param {Date} date The Date object to compare with the compare argument
+ * @param {Date} compareTo The Date object to use for the comparison
+ * @return {Boolean} true if the date occurs after the compared date; false if not.
+ */
+ after : function(date, compareTo) {
+ var ms = compareTo.getTime();
+ if (date.getTime() > ms) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Determines whether a given date is between two other dates on the calendar.
+ * @method between
+ * @param {Date} date The date to check for
+ * @param {Date} dateBegin The start of the range
+ * @param {Date} dateEnd The end of the range
+ * @return {Boolean} true if the date occurs between the compared dates; false if not.
+ */
+ between : function(date, dateBegin, dateEnd) {
+ if (this.after(date, dateBegin) && this.before(date, dateEnd)) {
+ return true;
+ } else {
+ return false;
+ }
+ },
+
+ /**
+ * Retrieves a JavaScript Date object representing January 1 of any given year.
+ * @method getJan1
+ * @param {Number} calendarYear The calendar year for which to retrieve January 1
+ * @return {Date} January 1 of the calendar year specified.
+ */
+ getJan1 : function(calendarYear) {
+ return this.getDate(calendarYear,0,1);
+ },
+
+ /**
+ * Calculates the number of days the specified date is from January 1 of the specified calendar year.
+ * Passing January 1 to this function would return an offset value of zero.
+ * @method getDayOffset
+ * @param {Date} date The JavaScript date for which to find the offset
+ * @param {Number} calendarYear The calendar year to use for determining the offset
+ * @return {Number} The number of days since January 1 of the given year
+ */
+ getDayOffset : function(date, calendarYear) {
+ var beginYear = this.getJan1(calendarYear); // Find the start of the year. This will be in week 1.
+
+ // Find the number of days the passed in date is away from the calendar year start
+ var dayOffset = Math.ceil((date.getTime()-beginYear.getTime()) / this.ONE_DAY_MS);
+ return dayOffset;
+ },
+
+ /**
+ * Calculates the week number for the given date. Can currently support standard
+ * U.S. week numbers, based on Jan 1st defining the 1st week of the year, and
+ * ISO8601 week numbers, based on Jan 4th defining the 1st week of the year.
+ *
+ * @method getWeekNumber
+ * @param {Date} date The JavaScript date for which to find the week number
+ * @param {Number} firstDayOfWeek The index of the first day of the week (0 = Sun, 1 = Mon ... 6 = Sat).
+ * Defaults to 0
+ * @param {Number} janDate The date in the first week of January which defines week one for the year
+ * Defaults to the value of YAHOO.widget.DateMath.WEEK_ONE_JAN_DATE, which is 1 (Jan 1st).
+ * For the U.S, this is normally Jan 1st. ISO8601 uses Jan 4th to define the first week of the year.
+ *
+ * @return {Number} The number of the week containing the given date.
+ */
+ getWeekNumber : function(date, firstDayOfWeek, janDate) {
+
+ // Setup Defaults
+ firstDayOfWeek = firstDayOfWeek || 0;
+ janDate = janDate || this.WEEK_ONE_JAN_DATE;
+
+ var targetDate = this.clearTime(date),
+ startOfWeek,
+ endOfWeek;
+
+ if (targetDate.getDay() === firstDayOfWeek) {
+ startOfWeek = targetDate;
+ } else {
+ startOfWeek = this.getFirstDayOfWeek(targetDate, firstDayOfWeek);
+ }
+
+ var startYear = startOfWeek.getFullYear();
+
+ // DST shouldn't be a problem here, math is quicker than setDate();
+ endOfWeek = new Date(startOfWeek.getTime() + 6*this.ONE_DAY_MS);
+
+ var weekNum;
+ if (startYear !== endOfWeek.getFullYear() && endOfWeek.getDate() >= janDate) {
+ // If years don't match, endOfWeek is in Jan. and if the
+ // week has WEEK_ONE_JAN_DATE in it, it's week one by definition.
+ weekNum = 1;
+ } else {
+ // Get the 1st day of the 1st week, and
+ // find how many days away we are from it.
+ var weekOne = this.clearTime(this.getDate(startYear, 0, janDate)),
+ weekOneDayOne = this.getFirstDayOfWeek(weekOne, firstDayOfWeek);
+
+ // Round days to smoothen out 1 hr DST diff
+ var daysDiff = Math.round((targetDate.getTime() - weekOneDayOne.getTime())/this.ONE_DAY_MS);
+
+ // Calc. Full Weeks
+ var rem = daysDiff % 7;
+ var weeksDiff = (daysDiff - rem)/7;
+ weekNum = weeksDiff + 1;
+ }
+ return weekNum;
+ },
+
+ /**
+ * Get the first day of the week, for the give date.
+ * @param {Date} dt The date in the week for which the first day is required.
+ * @param {Number} startOfWeek The index for the first day of the week, 0 = Sun, 1 = Mon ... 6 = Sat (defaults to 0)
+ * @return {Date} The first day of the week
+ */
+ getFirstDayOfWeek : function (dt, startOfWeek) {
+ startOfWeek = startOfWeek || 0;
+ var dayOfWeekIndex = dt.getDay(),
+ dayOfWeek = (dayOfWeekIndex - startOfWeek + 7) % 7;
+
+ return this.subtract(dt, this.DAY, dayOfWeek);
+ },
+
+ /**
+ * Determines if a given week overlaps two different years.
+ * @method isYearOverlapWeek
+ * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
+ * @return {Boolean} true if the date overlaps two different years.
+ */
+ isYearOverlapWeek : function(weekBeginDate) {
+ var overlaps = false;
+ var nextWeek = this.add(weekBeginDate, this.DAY, 6);
+ if (nextWeek.getFullYear() != weekBeginDate.getFullYear()) {
+ overlaps = true;
+ }
+ return overlaps;
+ },
+
+ /**
+ * Determines if a given week overlaps two different months.
+ * @method isMonthOverlapWeek
+ * @param {Date} weekBeginDate The JavaScript Date representing the first day of the week.
+ * @return {Boolean} true if the date overlaps two different months.
+ */
+ isMonthOverlapWeek : function(weekBeginDate) {
+ var overlaps = false;
+ var nextWeek = this.add(weekBeginDate, this.DAY, 6);
+ if (nextWeek.getMonth() != weekBeginDate.getMonth()) {
+ overlaps = true;
+ }
+ return overlaps;
+ },
+
+ /**
+ * Gets the first day of a month containing a given date.
+ * @method findMonthStart
+ * @param {Date} date The JavaScript Date used to calculate the month start
+ * @return {Date} The JavaScript Date representing the first day of the month
+ */
+ findMonthStart : function(date) {
+ var start = this.getDate(date.getFullYear(), date.getMonth(), 1);
+ return start;
+ },
+
+ /**
+ * Gets the last day of a month containing a given date.
+ * @method findMonthEnd
+ * @param {Date} date The JavaScript Date used to calculate the month end
+ * @return {Date} The JavaScript Date representing the last day of the month
+ */
+ findMonthEnd : function(date) {
+ var start = this.findMonthStart(date);
+ var nextMonth = this.add(start, this.MONTH, 1);
+ var end = this.subtract(nextMonth, this.DAY, 1);
+ return end;
+ },
+
+ /**
+ * Clears the time fields from a given date, effectively setting the time to 12 noon.
+ * @method clearTime
+ * @param {Date} date The JavaScript Date for which the time fields will be cleared
+ * @return {Date} The JavaScript Date cleared of all time fields
+ */
+ clearTime : function(date) {
+ date.setHours(12,0,0,0);
+ return date;
+ },
+ /**
+ * Returns a new JavaScript Date object, representing the given year, month and date. Time fields (hr, min, sec, ms) on the new Date object
+ * are set to 0. The method allows Date instances to be created with the a year less than 100. "new Date(year, month, date)" implementations
+ * set the year to 19xx if a year (xx) which is less than 100 is provided.
+ * <p>
+ * <em>NOTE:</em>Validation on argument values is not performed. It is the caller's responsibility to ensure
+ * arguments are valid as per the ECMAScript-262 Date object specification for the new Date(year, month[, date]) constructor.
+ * </p>
+ * @method getDate
+ * @param {Number} y Year.
+ * @param {Number} m Month index from 0 (Jan) to 11 (Dec).
+ * @param {Number} d (optional) Date from 1 to 31. If not provided, defaults to 1.
+ * @return {Date} The JavaScript date object with year, month, date set as provided.
+ */
+ getDate : function(y, m, d) {
+ var dt = null;
+ if (YAHOO.lang.isUndefined(d)) {
+ d = 1;
+ }
+ if (y >= 100) {
+ dt = new Date(y, m, d);
+ } else {
+ dt = new Date();
+ dt.setFullYear(y);
+ dt.setMonth(m);
+ dt.setDate(d);
+ dt.setHours(0,0,0,0);
+ }
+ return dt;
+ }
+};
/**
* The Calendar component is a UI control that enables users to choose one or more dates from a graphical calendar presented in a one-month or
* multi-month interface. Calendars are generated entirely via script and can be navigated without any page refreshes.
@@ -1095,10 +1101,10 @@ YAHOO.widget.DateMath = {
*/
(function(){
- var Dom = YAHOO.util.Dom,
- Event = YAHOO.util.Event,
- Lang = YAHOO.lang,
- DateMath = YAHOO.widget.DateMath;
+ var Dom = YAHOO.util.Dom,
+ Event = YAHOO.util.Event,
+ Lang = YAHOO.lang,
+ DateMath = YAHOO.widget.DateMath;
/**
* Calendar is the base class for the Calendar widget. In its most basic
@@ -1107,9 +1113,9 @@ YAHOO.widget.DateMath = {
* months and years.
* <p>To construct the placeholder for the calendar widget, the code is as
* follows:
-* <xmp>
-* <div id="calContainer"></div>
-* </xmp>
+* <xmp>
+* <div id="calContainer"></div>
+* </xmp>
* </p>
* <p>
* <strong>NOTE: As of 2.4.0, the constructor's ID argument is optional.</strong>
@@ -1118,14 +1124,14 @@ YAHOO.widget.DateMath = {
* in the document).
*
* E.g.:
-* <xmp>
-* var c = new YAHOO.widget.Calendar("calContainer", configOptions);
-* </xmp>
+* <xmp>
+* var c = new YAHOO.widget.Calendar("calContainer", configOptions);
+* </xmp>
* or:
* <xmp>
* var containerDiv = YAHOO.util.Dom.get("calContainer");
-* var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
-* </xmp>
+* var c = new YAHOO.widget.Calendar(containerDiv, configOptions);
+* </xmp>
* </p>
* <p>
* If not provided, the ID will be generated from the container DIV ID by adding an "_t" suffix.
@@ -1140,14 +1146,14 @@ YAHOO.widget.DateMath = {
* @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
*/
function Calendar(id, containerId, config) {
- this.init.apply(this, arguments);
+ this.init.apply(this, arguments);
}
/**
* The path to be used for images loaded for the Calendar
* @property YAHOO.widget.Calendar.IMG_ROOT
* @static
-* @deprecated You can now customize images by overriding the calclose, calnavleft and calnavright default CSS classes for the close icon, left arrow and right arrow respectively
+* @deprecated You can now customize images by overriding the calclose, calnavleft and calnavright default CSS classes for the close icon, left arrow and right arrow respectively
* @type String
*/
Calendar.IMG_ROOT = null;
@@ -1252,65 +1258,90 @@ Calendar.MEDIUM = "medium";
Calendar.ONE_CHAR = "1char";
/**
+* The set of default Config property keys and values for the Calendar.
+*
+* <p>
+* NOTE: This property is made public in order to allow users to change
+* the default values of configuration properties. Users should not
+* modify the key string, unless they are overriding the Calendar implementation
+* </p>
+*
+* <p>
+* The property is an object with key/value pairs, the key being the
+* uppercase configuration property name and the value being an object
+* literal with a key string property, and a value property, specifying the
+* default value of the property. To override a default value, you can set
+* the value property, for example, <code>YAHOO.widget.Calendar.DEFAULT_CONFIG.MULTI_SELECT.value = true;</code>
+*
+* @property YAHOO.widget.Calendar.DEFAULT_CONFIG
+* @static
+* @type Object
+*/
+
+Calendar.DEFAULT_CONFIG = {
+ YEAR_OFFSET : {key:"year_offset", value:0, supercedes:["pagedate", "selected", "mindate","maxdate"]},
+ TODAY : {key:"today", value:new Date(), supercedes:["pagedate"]},
+ PAGEDATE : {key:"pagedate", value:null},
+ SELECTED : {key:"selected", value:[]},
+ TITLE : {key:"title", value:""},
+ CLOSE : {key:"close", value:false},
+ IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
+ MINDATE : {key:"mindate", value:null},
+ MAXDATE : {key:"maxdate", value:null},
+ MULTI_SELECT : {key:"multi_select", value:false},
+ START_WEEKDAY : {key:"start_weekday", value:0},
+ SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
+ SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
+ SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
+ HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
+ NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
+ NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
+ MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
+ MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
+ WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
+ WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
+ WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
+ WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
+ LOCALE_MONTHS:{key:"locale_months", value:"long"},
+ LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
+ DATE_DELIMITER:{key:"date_delimiter", value:","},
+ DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
+ DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
+ MY_MONTH_POSITION:{key:"my_month_position", value:1},
+ MY_YEAR_POSITION:{key:"my_year_position", value:2},
+ MD_MONTH_POSITION:{key:"md_month_position", value:1},
+ MD_DAY_POSITION:{key:"md_day_position", value:2},
+ MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
+ MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
+ MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
+ MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
+ MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
+ MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
+ MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""},
+ NAV: {key:"navigator", value: null},
+ STRINGS : {
+ key:"strings",
+ value: {
+ previousMonth : "Previous Month",
+ nextMonth : "Next Month",
+ close: "Close"
+ },
+ supercedes : ["close", "title"]
+ }
+};
+
+/**
* The set of default Config property keys and values for the Calendar
* @property YAHOO.widget.Calendar._DEFAULT_CONFIG
+* @deprecated Made public. See the public DEFAULT_CONFIG property for details
* @final
* @static
* @private
* @type Object
*/
-Calendar._DEFAULT_CONFIG = {
- // Default values for pagedate and selected are not class level constants - they are set during instance creation
- PAGEDATE : {key:"pagedate", value:null},
- SELECTED : {key:"selected", value:null},
- TITLE : {key:"title", value:""},
- CLOSE : {key:"close", value:false},
- IFRAME : {key:"iframe", value:(YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) ? true : false},
- MINDATE : {key:"mindate", value:null},
- MAXDATE : {key:"maxdate", value:null},
- MULTI_SELECT : {key:"multi_select", value:false},
- START_WEEKDAY : {key:"start_weekday", value:0},
- SHOW_WEEKDAYS : {key:"show_weekdays", value:true},
- SHOW_WEEK_HEADER : {key:"show_week_header", value:false},
- SHOW_WEEK_FOOTER : {key:"show_week_footer", value:false},
- HIDE_BLANK_WEEKS : {key:"hide_blank_weeks", value:false},
- NAV_ARROW_LEFT: {key:"nav_arrow_left", value:null} ,
- NAV_ARROW_RIGHT : {key:"nav_arrow_right", value:null} ,
- MONTHS_SHORT : {key:"months_short", value:["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]},
- MONTHS_LONG: {key:"months_long", value:["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"]},
- WEEKDAYS_1CHAR: {key:"weekdays_1char", value:["S", "M", "T", "W", "T", "F", "S"]},
- WEEKDAYS_SHORT: {key:"weekdays_short", value:["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]},
- WEEKDAYS_MEDIUM: {key:"weekdays_medium", value:["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]},
- WEEKDAYS_LONG: {key:"weekdays_long", value:["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]},
- LOCALE_MONTHS:{key:"locale_months", value:"long"},
- LOCALE_WEEKDAYS:{key:"locale_weekdays", value:"short"},
- DATE_DELIMITER:{key:"date_delimiter", value:","},
- DATE_FIELD_DELIMITER:{key:"date_field_delimiter", value:"/"},
- DATE_RANGE_DELIMITER:{key:"date_range_delimiter", value:"-"},
- MY_MONTH_POSITION:{key:"my_month_position", value:1},
- MY_YEAR_POSITION:{key:"my_year_position", value:2},
- MD_MONTH_POSITION:{key:"md_month_position", value:1},
- MD_DAY_POSITION:{key:"md_day_position", value:2},
- MDY_MONTH_POSITION:{key:"mdy_month_position", value:1},
- MDY_DAY_POSITION:{key:"mdy_day_position", value:2},
- MDY_YEAR_POSITION:{key:"mdy_year_position", value:3},
- MY_LABEL_MONTH_POSITION:{key:"my_label_month_position", value:1},
- MY_LABEL_YEAR_POSITION:{key:"my_label_year_position", value:2},
- MY_LABEL_MONTH_SUFFIX:{key:"my_label_month_suffix", value:" "},
- MY_LABEL_YEAR_SUFFIX:{key:"my_label_year_suffix", value:""},
- NAV: {key:"navigator", value: null},
- STRINGS : {
- key:"strings",
- value: {
- previousMonth : "Previous Month",
- nextMonth : "Next Month",
- close: "Close"
- },
- supercedes : ["close", "title"]
- }
-};
+Calendar._DEFAULT_CONFIG = Calendar.DEFAULT_CONFIG;
-var DEF_CFG = Calendar._DEFAULT_CONFIG;
+var DEF_CFG = Calendar.DEFAULT_CONFIG;
/**
* The set of Custom Event types supported by the Calendar
@@ -1321,5828 +1352,5943 @@ var DEF_CFG = Calendar._DEFAULT_CONFIG;
* @type Object
*/
Calendar._EVENT_TYPES = {
- BEFORE_SELECT : "beforeSelect",
- SELECT : "select",
- BEFORE_DESELECT : "beforeDeselect",
- DESELECT : "deselect",
- CHANGE_PAGE : "changePage",
- BEFORE_RENDER : "beforeRender",
- RENDER : "render",
- BEFORE_DESTROY : "beforeDestroy",
- DESTROY : "destroy",
- RESET : "reset",
- CLEAR : "clear",
- BEFORE_HIDE : "beforeHide",
- HIDE : "hide",
- BEFORE_SHOW : "beforeShow",
- SHOW : "show",
- BEFORE_HIDE_NAV : "beforeHideNav",
- HIDE_NAV : "hideNav",
- BEFORE_SHOW_NAV : "beforeShowNav",
- SHOW_NAV : "showNav",
- BEFORE_RENDER_NAV : "beforeRenderNav",
- RENDER_NAV : "renderNav"
+ BEFORE_SELECT : "beforeSelect",
+ SELECT : "select",
+ BEFORE_DESELECT : "beforeDeselect",
+ DESELECT : "deselect",
+ CHANGE_PAGE : "changePage",
+ BEFORE_RENDER : "beforeRender",
+ RENDER : "render",
+ BEFORE_DESTROY : "beforeDestroy",
+ DESTROY : "destroy",
+ RESET : "reset",
+ CLEAR : "clear",
+ BEFORE_HIDE : "beforeHide",
+ HIDE : "hide",
+ BEFORE_SHOW : "beforeShow",
+ SHOW : "show",
+ BEFORE_HIDE_NAV : "beforeHideNav",
+ HIDE_NAV : "hideNav",
+ BEFORE_SHOW_NAV : "beforeShowNav",
+ SHOW_NAV : "showNav",
+ BEFORE_RENDER_NAV : "beforeRenderNav",
+ RENDER_NAV : "renderNav"
+};
+
+/**
+* The set of default style constants for the Calendar
+* @property YAHOO.widget.Calendar.STYLES
+* @static
+* @type Object An object with name/value pairs for the class name identifier/value.
+*/
+Calendar.STYLES = {
+ CSS_ROW_HEADER: "calrowhead",
+ CSS_ROW_FOOTER: "calrowfoot",
+ CSS_CELL : "calcell",
+ CSS_CELL_SELECTOR : "selector",
+ CSS_CELL_SELECTED : "selected",
+ CSS_CELL_SELECTABLE : "selectable",
+ CSS_CELL_RESTRICTED : "restricted",
+ CSS_CELL_TODAY : "today",
+ CSS_CELL_OOM : "oom",
+ CSS_CELL_OOB : "previous",
+ CSS_HEADER : "calheader",
+ CSS_HEADER_TEXT : "calhead",
+ CSS_BODY : "calbody",
+ CSS_WEEKDAY_CELL : "calweekdaycell",
+ CSS_WEEKDAY_ROW : "calweekdayrow",
+ CSS_FOOTER : "calfoot",
+ CSS_CALENDAR : "yui-calendar",
+ CSS_SINGLE : "single",
+ CSS_CONTAINER : "yui-calcontainer",
+ CSS_NAV_LEFT : "calnavleft",
+ CSS_NAV_RIGHT : "calnavright",
+ CSS_NAV : "calnav",
+ CSS_CLOSE : "calclose",
+ CSS_CELL_TOP : "calcelltop",
+ CSS_CELL_LEFT : "calcellleft",
+ CSS_CELL_RIGHT : "calcellright",
+ CSS_CELL_BOTTOM : "calcellbottom",
+ CSS_CELL_HOVER : "calcellhover",
+ CSS_CELL_HIGHLIGHT1 : "highlight1",
+ CSS_CELL_HIGHLIGHT2 : "highlight2",
+ CSS_CELL_HIGHLIGHT3 : "highlight3",
+ CSS_CELL_HIGHLIGHT4 : "highlight4",
+ CSS_WITH_TITLE: "withtitle",
+ CSS_FIXED_SIZE: "fixedsize",
+ CSS_LINK_CLOSE: "link-close"
};
/**
* The set of default style constants for the Calendar
* @property YAHOO.widget.Calendar._STYLES
+* @deprecated Made public. See the public STYLES property for details
* @final
* @static
* @private
* @type Object
*/
-Calendar._STYLES = {
- CSS_ROW_HEADER: "calrowhead",
- CSS_ROW_FOOTER: "calrowfoot",
- CSS_CELL : "calcell",
- CSS_CELL_SELECTOR : "selector",
- CSS_CELL_SELECTED : "selected",
- CSS_CELL_SELECTABLE : "selectable",
- CSS_CELL_RESTRICTED : "restricted",
- CSS_CELL_TODAY : "today",
- CSS_CELL_OOM : "oom",
- CSS_CELL_OOB : "previous",
- CSS_HEADER : "calheader",
- CSS_HEADER_TEXT : "calhead",
- CSS_BODY : "calbody",
- CSS_WEEKDAY_CELL : "calweekdaycell",
- CSS_WEEKDAY_ROW : "calweekdayrow",
- CSS_FOOTER : "calfoot",
- CSS_CALENDAR : "yui-calendar",
- CSS_SINGLE : "single",
- CSS_CONTAINER : "yui-calcontainer",
- CSS_NAV_LEFT : "calnavleft",
- CSS_NAV_RIGHT : "calnavright",
- CSS_NAV : "calnav",
- CSS_CLOSE : "calclose",
- CSS_CELL_TOP : "calcelltop",
- CSS_CELL_LEFT : "calcellleft",
- CSS_CELL_RIGHT : "calcellright",
- CSS_CELL_BOTTOM : "calcellbottom",
- CSS_CELL_HOVER : "calcellhover",
- CSS_CELL_HIGHLIGHT1 : "highlight1",
- CSS_CELL_HIGHLIGHT2 : "highlight2",
- CSS_CELL_HIGHLIGHT3 : "highlight3",
- CSS_CELL_HIGHLIGHT4 : "highlight4"
-};
+Calendar._STYLES = Calendar.STYLES;
Calendar.prototype = {
- /**
- * The configuration object used to set up the calendars various locale and style options.
- * @property Config
- * @private
- * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
- * @type Object
- */
- Config : null,
-
- /**
- * The parent CalendarGroup, only to be set explicitly by the parent group
- * @property parent
- * @type CalendarGroup
- */
- parent : null,
-
- /**
- * The index of this item in the parent group
- * @property index
- * @type Number
- */
- index : -1,
-
- /**
- * The collection of calendar table cells
- * @property cells
- * @type HTMLTableCellElement[]
- */
- cells : null,
-
- /**
- * The collection of calendar cell dates that is parallel to the cells collection. The array contains dates field arrays in the format of [YYYY, M, D].
- * @property cellDates
- * @type Array[](Number[])
- */
- cellDates : null,
-
- /**
- * The id that uniquely identifies this Calendar.
- * @property id
- * @type String
- */
- id : null,
-
- /**
- * The unique id associated with the Calendar's container
- * @property containerId
- * @type String
- */
- containerId: null,
-
- /**
- * The DOM element reference that points to this calendar's container element. The calendar will be inserted into this element when the shell is rendered.
- * @property oDomContainer
- * @type HTMLElement
- */
- oDomContainer : null,
-
- /**
- * A Date object representing today's date.
- * @property today
- * @type Date
- */
- today : null,
-
- /**
- * The list of render functions, along with required parameters, used to render cells.
- * @property renderStack
- * @type Array[]
- */
- renderStack : null,
-
- /**
- * A copy of the initial render functions created before rendering.
- * @property _renderStack
- * @private
- * @type Array
- */
- _renderStack : null,
-
- /**
- * A reference to the CalendarNavigator instance created for this Calendar.
- * Will be null if the "navigator" configuration property has not been set
- * @property oNavigator
- * @type CalendarNavigator
- */
- oNavigator : null,
-
- /**
- * The private list of initially selected dates.
- * @property _selectedDates
- * @private
- * @type Array
- */
- _selectedDates : null,
-
- /**
- * A map of DOM event handlers to attach to cells associated with specific CSS class names
- * @property domEventMap
- * @type Object
- */
- domEventMap : null,
-
- /**
- * Protected helper used to parse Calendar constructor/init arguments.
- *
- * As of 2.4.0, Calendar supports a simpler constructor
- * signature. This method reconciles arguments
- * received in the pre 2.4.0 and 2.4.0 formats.
- *
- * @protected
- * @method _parseArgs
- * @param {Array} Function "arguments" array
- * @return {Object} Object with id, container, config properties containing
- * the reconciled argument values.
- **/
- _parseArgs : function(args) {
- /*
- 2.4.0 Constructors signatures
-
- new Calendar(String)
- new Calendar(HTMLElement)
- new Calendar(String, ConfigObject)
- new Calendar(HTMLElement, ConfigObject)
-
- Pre 2.4.0 Constructor signatures
-
- new Calendar(String, String)
- new Calendar(String, HTMLElement)
- new Calendar(String, String, ConfigObject)
- new Calendar(String, HTMLElement, ConfigObject)
- */
- var nArgs = {id:null, container:null, config:null};
-
- if (args && args.length && args.length > 0) {
- switch (args.length) {
- case 1:
- nArgs.id = null;
- nArgs.container = args[0];
- nArgs.config = null;
- break;
- case 2:
- if (Lang.isObject(args[1]) && !args[1].tagName && !(args[1] instanceof String)) {
- nArgs.id = null;
- nArgs.container = args[0];
- nArgs.config = args[1];
- } else {
- nArgs.id = args[0];
- nArgs.container = args[1];
- nArgs.config = null;
- }
- break;
- default: // 3+
- nArgs.id = args[0];
- nArgs.container = args[1];
- nArgs.config = args[2];
- break;
- }
- } else {
- }
- return nArgs;
- },
-
- /**
- * Initializes the Calendar widget.
- * @method init
- *
- * @param {String} id optional The id of the table element that will represent the Calendar widget. As of 2.4.0, this argument is optional.
- * @param {String | HTMLElement} container The id of the container div element that will wrap the Calendar table, or a reference to a DIV element which exists in the document.
- * @param {Object} config optional The configuration object containing the initial configuration values for the Calendar.
- */
- init : function(id, container, config) {
- // Normalize 2.4.0, pre 2.4.0 args
- var nArgs = this._parseArgs(arguments);
-
- id = nArgs.id;
- container = nArgs.container;
- config = nArgs.config;
-
- this.oDomContainer = Dom.get(container);
-
- if (!this.oDomContainer.id) {
- this.oDomContainer.id = Dom.generateId();
- }
- if (!id) {
- id = this.oDomContainer.id + "_t";
- }
-
- this.id = id;
- this.containerId = this.oDomContainer.id;
-
- this.initEvents();
-
- this.today = new Date();
- DateMath.clearTime(this.today);
-
- /**
- * The Config object used to hold the configuration variables for the Calendar
- * @property cfg
- * @type YAHOO.util.Config
- */
- this.cfg = new YAHOO.util.Config(this);
-
- /**
- * The local object which contains the Calendar's options
- * @property Options
- * @type Object
- */
- this.Options = {};
-
- /**
- * The local object which contains the Calendar's locale settings
- * @property Locale
- * @type Object
- */
- this.Locale = {};
-
- this.initStyles();
-
- Dom.addClass(this.oDomContainer, this.Style.CSS_CONTAINER);
- Dom.addClass(this.oDomContainer, this.Style.CSS_SINGLE);
-
- this.cellDates = [];
- this.cells = [];
- this.renderStack = [];
- this._renderStack = [];
-
- this.setupConfig();
-
- if (config) {
- this.cfg.applyConfig(config, true);
- }
-
- this.cfg.fireQueue();
- },
-
- /**
- * Default Config listener for the iframe property. If the iframe config property is set to true,
- * renders the built-in IFRAME shim if the container is relatively or absolutely positioned.
- *
- * @method configIframe
- */
- configIframe : function(type, args, obj) {
- var useIframe = args[0];
-
- if (!this.parent) {
- if (Dom.inDocument(this.oDomContainer)) {
- if (useIframe) {
- var pos = Dom.getStyle(this.oDomContainer, "position");
-
- if (pos == "absolute" || pos == "relative") {
-
- if (!Dom.inDocument(this.iframe)) {
- this.iframe = document.createElement("iframe");
- this.iframe.src = "javascript:false;";
-
- Dom.setStyle(this.iframe, "opacity", "0");
-
- if (YAHOO.env.ua.ie && YAHOO.env.ua.ie <= 6) {
- Dom.addClass(this.iframe, "fixedsize");
- }
-
- this.oDomContainer.insertBefore(this.iframe, this.oDomContainer.firstChild);
- }
- }
- } else {
- if (this.iframe) {
- if (this.iframe.parentNode) {
- this.iframe.parentNode.removeChild(this.iframe);
- }
- this.iframe = null;
- }
- }
- }
- }
- },
-
- /**
- * Default handler for the "title" property
- * @method configTitle
- */
- configTitle : function(type, args, obj) {
- var title = args[0];
-
- // "" disables title bar
- if (title) {
- this.createTitleBar(title);
- } else {
- var close = this.cfg.getProperty(DEF_CFG.CLOSE.key);
- if (!close) {
- this.removeTitleBar();
- } else {
- this.createTitleBar(" ");
- }
- }
- },
-
- /**
- * Default handler for the "close" property
- * @method configClose
- */
- configClose : function(type, args, obj) {
- var close = args[0],
- title = this.cfg.getProperty(DEF_CFG.TITLE.key);
-
- if (close) {
- if (!title) {
- this.createTitleBar(" ");
- }
- this.createCloseButton();
- } else {
- this.removeCloseButton();
- if (!title) {
- this.removeTitleBar();
- }
- }
- },
-
- /**
- * Initializes Calendar's built-in CustomEvents
- * @method initEvents
- */
- initEvents : function() {
-
- var defEvents = Calendar._EVENT_TYPES,
- CE = YAHOO.util.CustomEvent,
- cal = this; // To help with minification
-
- /**
- * Fired before a date selection is made
- * @event beforeSelectEvent
- */
- cal.beforeSelectEvent = new CE(defEvents.BEFORE_SELECT);
-
- /**
- * Fired when a date selection is made
- * @event selectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- cal.selectEvent = new CE(defEvents.SELECT);
-
- /**
- * Fired before a date or set of dates is deselected
- * @event beforeDeselectEvent
- */
- cal.beforeDeselectEvent = new CE(defEvents.BEFORE_DESELECT);
-
- /**
- * Fired when a date or set of dates is deselected
- * @event deselectEvent
- * @param {Array} Array of Date field arrays in the format [YYYY, MM, DD].
- */
- cal.deselectEvent = new CE(defEvents.DESELECT);
-
- /**
- * Fired when the Calendar page is changed
- * @event changePageEvent
- */
- cal.changePageEvent = new CE(defEvents.CHANGE_PAGE);
-
- /**
- * Fired before the Calendar is rendered
- * @event beforeRenderEvent
- */
- cal.beforeRenderEvent = new CE(defEvents.BEFORE_RENDER);
-
- /**
- * Fired when the Calendar is rendered
- * @event renderEvent
- */
- cal.renderEvent = new CE(defEvents.RENDER);
-
- /**
- * Fired just before the Calendar is to be destroyed
- * @event beforeDestroyEvent
- */
- cal.beforeDestroyEvent = new CE(defEvents.BEFORE_DESTROY);
-
- /**
- * Fired after the Calendar is destroyed. This event should be used
- * for notification only. When this event is fired, important Calendar instance
- * properties, dom references and event listeners have already been
- * removed/dereferenced, and hence the Calendar instance is not in a usable
- * state.
- *
- * @event destroyEvent
- */
- cal.destroyEvent = new CE(defEvents.DESTROY);
-
- /**
- * Fired when the Calendar is reset
- * @event resetEvent
- */
- cal.resetEvent = new CE(defEvents.RESET);
-
- /**
- * Fired when the Calendar is cleared
- * @event clearEvent
- */
- cal.clearEvent = new CE(defEvents.CLEAR);
-
- /**
- * Fired just before the Calendar is to be shown
- * @event beforeShowEvent
- */
- cal.beforeShowEvent = new CE(defEvents.BEFORE_SHOW);
-
- /**
- * Fired after the Calendar is shown
- * @event showEvent
- */
- cal.showEvent = new CE(defEvents.SHOW);
-
- /**
- * Fired just before the Calendar is to be hidden
- * @event beforeHideEvent
- */
- cal.beforeHideEvent = new CE(defEvents.BEFORE_HIDE);
-
- /**
- * Fired after the Calendar is hidden
- * @event hideEvent
- */
- cal.hideEvent = new CE(defEvents.HIDE);
-
- /**
- * Fired just before the CalendarNavigator is to be shown
- * @event beforeShowNavEvent
- */
- cal.beforeShowNavEvent = new CE(defEvents.BEFORE_SHOW_NAV);
-
- /**
- * Fired after the CalendarNavigator is shown
- * @event showNavEvent
- */
- cal.showNavEvent = new CE(defEvents.SHOW_NAV);
-
- /**
- * Fired just before the CalendarNavigator is to be hidden
- * @event beforeHideNavEvent
- */
- cal.beforeHideNavEvent = new CE(defEvents.BEFORE_HIDE_NAV);
-
- /**
- * Fired after the CalendarNavigator is hidden
- * @event hideNavEvent
- */
- cal.hideNavEvent = new CE(defEvents.HIDE_NAV);
-
- /**
- * Fired just before the CalendarNavigator is to be rendered
- * @event beforeRenderNavEvent
- */
- cal.beforeRenderNavEvent = new CE(defEvents.BEFORE_RENDER_NAV);
-
- /**
- * Fired after the CalendarNavigator is rendered
- * @event renderNavEvent
- */
- cal.renderNavEvent = new CE(defEvents.RENDER_NAV);
-
- cal.beforeSelectEvent.subscribe(cal.onBeforeSelect, this, true);
- cal.selectEvent.subscribe(cal.onSelect, this, true);
- cal.beforeDeselectEvent.subscribe(cal.onBeforeDeselect, this, true);
- cal.deselectEvent.subscribe(cal.onDeselect, this, true);
- cal.changePageEvent.subscribe(cal.onChangePage, this, true);
- cal.renderEvent.subscribe(cal.onRender, this, true);
- cal.resetEvent.subscribe(cal.onReset, this, true);
- cal.clearEvent.subscribe(cal.onClear, this, true);
- },
-
- /**
- * The default event handler for clicks on the "Previous Month" navigation UI
- *
- * @method doPreviousMonthNav
- * @param {DOMEvent} e The DOM event
- * @param {Calendar} cal A reference to the calendar
- */
- doPreviousMonthNav : function(e, cal) {
- Event.preventDefault(e);
- // previousMonth invoked in a timeout, to allow
- // event to bubble up, with correct target. Calling
- // previousMonth, will call render which will remove
- // HTML which generated the event, resulting in an
- // invalid event target in certain browsers.
- setTimeout(function() {
- cal.previousMonth();
- var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_LEFT, "a", cal.oDomContainer);
- if (navs && navs[0]) {
- try {
- navs[0].focus();
- } catch (e) {
- // ignore
- }
- }
- }, 0);
- },
-
- /**
- * The default event handler for clicks on the "Next Month" navigation UI
- *
- * @method doNextMonthNav
- * @param {DOMEvent} e The DOM event
- * @param {Calendar} cal A reference to the calendar
- */
- doNextMonthNav : function(e, cal) {
- Event.preventDefault(e);
- setTimeout(function() {
- cal.nextMonth();
- var navs = Dom.getElementsByClassName(cal.Style.CSS_NAV_RIGHT, "a", cal.oDomContainer);
- if (navs && navs[0]) {
- try {
- navs[0].focus();
- } catch (e) {
- // ignore
- }
- }
- }, 0);
- },
-
- /**
- * The default event handler for date cell selection. Currently attached to
- * the Calendar's bounding box, referenced by it's <a href="#property_oDomContainer">oDomContainer</a> property.
- *
- * @method doSelectCell
- * @param {DOMEvent} e The DOM event
- * @param {Calendar} cal A reference to the calendar
- */
- doSelectCell : function(e, cal) {
- var cell, d, date, index;
-
- var target = Event.getTarget(e),
- tagName = target.tagName.toLowerCase(),
- defSelector = false;
-
- while (tagName != "td" && !Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
-
- if (!defSelector && tagName == "a" && Dom.hasClass(target, cal.Style.CSS_CELL_SELECTOR)) {
- defSelector = true;
- }
-
- target = target.parentNode;
- tagName = target.tagName.toLowerCase();
-
- if (target == this.oDomContainer || tagName == "html") {
- return;
- }
- }
-
- if (defSelector) {
- // Stop link href navigation for default renderer
- Event.preventDefault(e);
- }
-
- cell = target;
-
- if (Dom.hasClass(cell, cal.Style.CSS_CELL_SELECTABLE)) {
- index = cal.getIndexFromId(cell.id);
- if (index > -1) {
- d = cal.cellDates[index];
- if (d) {
- date = DateMath.getDate(d[0],d[1]-1,d[2]);
-
- var link;
-
- if (cal.Options.MULTI_SELECT) {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
-
- var cellDate = cal.cellDates[index];
- var cellDateIndex = cal._indexOfSelectedFieldArray(cellDate);
-
- if (cellDateIndex > -1) {
- cal.deselectCell(index);
- } else {
- cal.selectCell(index);
- }
-
- } else {
- link = cell.getElementsByTagName("a")[0];
- if (link) {
- link.blur();
- }
- cal.selectCell(index);
- }
- }
- }
- }
- },
-
- /**
- * The event that is executed when the user hovers over a cell
- * @method doCellMouseOver
- * @param {DOMEvent} e The event
- * @param {Calendar} cal A reference to the calendar passed by the Event utility
- */
- doCellMouseOver : function(e, cal) {
- var target;
- if (e) {
- target = Event.getTarget(e);
- } else {
- target = this;
- }
-
- while (target.tagName && target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (!target.tagName || target.tagName.toLowerCase() == "html") {
- return;
- }
- }
-
- if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- Dom.addClass(target, cal.Style.CSS_CELL_HOVER);
- }
- },
-
- /**
- * The event that is executed when the user moves the mouse out of a cell
- * @method doCellMouseOut
- * @param {DOMEvent} e The event
- * @param {Calendar} cal A reference to the calendar passed by the Event utility
- */
- doCellMouseOut : function(e, cal) {
- var target;
- if (e) {
- target = Event.getTarget(e);
- } else {
- target = this;
- }
-
- while (target.tagName && target.tagName.toLowerCase() != "td") {
- target = target.parentNode;
- if (!target.tagName || target.tagName.toLowerCase() == "html") {
- return;
- }
- }
-
- if (Dom.hasClass(target, cal.Style.CSS_CELL_SELECTABLE)) {
- Dom.removeClass(target, cal.Style.CSS_CELL_HOVER);
- }
- },
-
- setupConfig : function() {
- var cfg = this.cfg;
-
- /**
- * The month/year representing the current visible Calendar date (mm/yyyy)
- * @config pagedate
- * @type String | Date
- * @default today's date
- */
- cfg.addProperty(DEF_CFG.PAGEDATE.key, { value:new Date(), handler:this.configPageDate } );
-
- /**
- * The date or range of dates representing the current Calendar selection
- * @config selected
- * @type String
- * @default []
- */
- cfg.addProperty(DEF_CFG.SELECTED.key, { value:[], handler:this.configSelected } );
-
- /**
- * The title to display above the Calendar's month header
- * @config title
- * @type String
- * @default ""
- */
- cfg.addProperty(DEF_CFG.TITLE.key, { value:DEF_CFG.TITLE.value, handler:this.configTitle } );
-
- /**
- * Whether or not a close button should be displayed for this Calendar
- * @config close
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.CLOSE.key, { value:DEF_CFG.CLOSE.value, handler:this.configClose } );
-
- /**
- * Whether or not an iframe shim should be placed under the Calendar to prevent select boxes from bleeding through in Internet Explorer 6 and below.
- * This property is enabled by default for IE6 and below. It is disabled by default for other browsers for performance reasons, but can be
- * enabled if required.
- *
- * @config iframe
- * @type Boolean
- * @default true for IE6 and below, false for all other browsers
- */
- cfg.addProperty(DEF_CFG.IFRAME.key, { value:DEF_CFG.IFRAME.value, handler:this.configIframe, validator:cfg.checkBoolean } );
-
- /**
- * The minimum selectable date in the current Calendar (mm/dd/yyyy)
- * @config mindate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MINDATE.key, { value:DEF_CFG.MINDATE.value, handler:this.configMinDate } );
-
- /**
- * The maximum selectable date in the current Calendar (mm/dd/yyyy)
- * @config maxdate
- * @type String | Date
- * @default null
- */
- cfg.addProperty(DEF_CFG.MAXDATE.key, { value:DEF_CFG.MAXDATE.value, handler:this.configMaxDate } );
-
-
- // Options properties
-
- /**
- * True if the Calendar should allow multiple selections. False by default.
- * @config MULTI_SELECT
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.MULTI_SELECT.key, { value:DEF_CFG.MULTI_SELECT.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * The weekday the week begins on. Default is 0 (Sunday = 0, Monday = 1 ... Saturday = 6).
- * @config START_WEEKDAY
- * @type number
- * @default 0
- */
- cfg.addProperty(DEF_CFG.START_WEEKDAY.key, { value:DEF_CFG.START_WEEKDAY.value, handler:this.configOptions, validator:cfg.checkNumber } );
-
- /**
- * True if the Calendar should show weekday labels. True by default.
- * @config SHOW_WEEKDAYS
- * @type Boolean
- * @default true
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEKDAYS.key, { value:DEF_CFG.SHOW_WEEKDAYS.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row headers. False by default.
- * @config SHOW_WEEK_HEADER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_HEADER.key, { value:DEF_CFG.SHOW_WEEK_HEADER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should show week row footers. False by default.
- * @config SHOW_WEEK_FOOTER
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.SHOW_WEEK_FOOTER.key,{ value:DEF_CFG.SHOW_WEEK_FOOTER.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * True if the Calendar should suppress weeks that are not a part of the current month. False by default.
- * @config HIDE_BLANK_WEEKS
- * @type Boolean
- * @default false
- */
- cfg.addProperty(DEF_CFG.HIDE_BLANK_WEEKS.key, { value:DEF_CFG.HIDE_BLANK_WEEKS.value, handler:this.configOptions, validator:cfg.checkBoolean } );
-
- /**
- * The image that should be used for the left navigation arrow.
- * @config NAV_ARROW_LEFT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the left arrow - "calnavleft"
- * @default null
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_LEFT.key, { value:DEF_CFG.NAV_ARROW_LEFT.value, handler:this.configOptions } );
-
- /**
- * The image that should be used for the right navigation arrow.
- * @config NAV_ARROW_RIGHT
- * @type String
- * @deprecated You can customize the image by overriding the default CSS class for the right arrow - "calnavright"
- * @default null
- */
- cfg.addProperty(DEF_CFG.NAV_ARROW_RIGHT.key, { value:DEF_CFG.NAV_ARROW_RIGHT.value, handler:this.configOptions } );
-
- // Locale properties
-
- /**
- * The short month labels for the current locale.
- * @config MONTHS_SHORT
- * @type String[]
- * @default ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
- */
- cfg.addProperty(DEF_CFG.MONTHS_SHORT.key, { value:DEF_CFG.MONTHS_SHORT.value, handler:this.configLocale } );
-
- /**
- * The long month labels for the current locale.
- * @config MONTHS_LONG
- * @type String[]
- * @default ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"
- */
- cfg.addProperty(DEF_CFG.MONTHS_LONG.key, { value:DEF_CFG.MONTHS_LONG.value, handler:this.configLocale } );
-
- /**
- * The 1-character weekday labels for the current locale.
- * @config WEEKDAYS_1CHAR
- * @type String[]
- * @default ["S", "M", "T", "W", "T", "F", "S"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_1CHAR.key, { value:DEF_CFG.WEEKDAYS_1CHAR.value, handler:this.configLocale } );
-
- /**
- * The short weekday labels for the current locale.
- * @config WEEKDAYS_SHORT
- * @type String[]
- * @default ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_SHORT.key, { value:DEF_CFG.WEEKDAYS_SHORT.value, handler:this.configLocale } );
-
- /**
- * The medium weekday labels for the current locale.
- * @config WEEKDAYS_MEDIUM
- * @type String[]
- * @default ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_MEDIUM.key, { value:DEF_CFG.WEEKDAYS_MEDIUM.value, handler:this.configLocale } );
-
- /**
- * The long weekday labels for the current locale.
- * @config WEEKDAYS_LONG
- * @type String[]
- * @default ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"]
- */
- cfg.addProperty(DEF_CFG.WEEKDAYS_LONG.key, { value:DEF_CFG.WEEKDAYS_LONG.value, handler:this.configLocale } );
-
- /**
- * Refreshes the locale values used to build the Calendar.
- * @method refreshLocale
- * @private
- */
- var refreshLocale = function() {
- cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
- cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
- };
-
- cfg.subscribeToConfigEvent(DEF_CFG.START_WEEKDAY.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_SHORT.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.MONTHS_LONG.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_1CHAR.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_SHORT.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_MEDIUM.key, refreshLocale, this, true);
- cfg.subscribeToConfigEvent(DEF_CFG.WEEKDAYS_LONG.key, refreshLocale, this, true);
-
- /**
- * The setting that determines which length of month labels should be used. Possible values are "short" and "long".
- * @config LOCALE_MONTHS
- * @type String
- * @default "long"
- */
- cfg.addProperty(DEF_CFG.LOCALE_MONTHS.key, { value:DEF_CFG.LOCALE_MONTHS.value, handler:this.configLocaleValues } );
-
- /**
- * The setting that determines which length of weekday labels should be used. Possible values are "1char", "short", "medium", and "long".
- * @config LOCALE_WEEKDAYS
- * @type String
- * @default "short"
- */
- cfg.addProperty(DEF_CFG.LOCALE_WEEKDAYS.key, { value:DEF_CFG.LOCALE_WEEKDAYS.value, handler:this.configLocaleValues } );
-
- /**
- * The value used to delimit individual dates in a date string passed to various Calendar functions.
- * @config DATE_DELIMITER
- * @type String
- * @default ","
- */
- cfg.addProperty(DEF_CFG.DATE_DELIMITER.key, { value:DEF_CFG.DATE_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The value used to delimit date fields in a date string passed to various Calendar functions.
- * @config DATE_FIELD_DELIMITER
- * @type String
- * @default "/"
- */
- cfg.addProperty(DEF_CFG.DATE_FIELD_DELIMITER.key, { value:DEF_CFG.DATE_FIELD_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The value used to delimit date ranges in a date string passed to various Calendar functions.
- * @config DATE_RANGE_DELIMITER
- * @type String
- * @default "-"
- */
- cfg.addProperty(DEF_CFG.DATE_RANGE_DELIMITER.key, { value:DEF_CFG.DATE_RANGE_DELIMITER.value, handler:this.configLocale } );
-
- /**
- * The position of the month in a month/year date string
- * @config MY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MY_MONTH_POSITION.key, { value:DEF_CFG.MY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/year date string
- * @config MY_YEAR_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MY_YEAR_POSITION.key, { value:DEF_CFG.MY_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day date string
- * @config MD_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MD_MONTH_POSITION.key, { value:DEF_CFG.MD_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/year date string
- * @config MD_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MD_DAY_POSITION.key, { value:DEF_CFG.MD_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in a month/day/year date string
- * @config MDY_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MDY_MONTH_POSITION.key, { value:DEF_CFG.MDY_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the day in a month/day/year date string
- * @config MDY_DAY_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MDY_DAY_POSITION.key, { value:DEF_CFG.MDY_DAY_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in a month/day/year date string
- * @config MDY_YEAR_POSITION
- * @type Number
- * @default 3
- */
- cfg.addProperty(DEF_CFG.MDY_YEAR_POSITION.key, { value:DEF_CFG.MDY_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the month in the month year label string used as the Calendar header
- * @config MY_LABEL_MONTH_POSITION
- * @type Number
- * @default 1
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_POSITION.key, { value:DEF_CFG.MY_LABEL_MONTH_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The position of the year in the month year label string used as the Calendar header
- * @config MY_LABEL_YEAR_POSITION
- * @type Number
- * @default 2
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_POSITION.key, { value:DEF_CFG.MY_LABEL_YEAR_POSITION.value, handler:this.configLocale, validator:cfg.checkNumber } );
-
- /**
- * The suffix used after the month when rendering the Calendar header
- * @config MY_LABEL_MONTH_SUFFIX
- * @type String
- * @default " "
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_MONTH_SUFFIX.key, { value:DEF_CFG.MY_LABEL_MONTH_SUFFIX.value, handler:this.configLocale } );
-
- /**
- * The suffix used after the year when rendering the Calendar header
- * @config MY_LABEL_YEAR_SUFFIX
- * @type String
- * @default ""
- */
- cfg.addProperty(DEF_CFG.MY_LABEL_YEAR_SUFFIX.key, { value:DEF_CFG.MY_LABEL_YEAR_SUFFIX.value, handler:this.configLocale } );
-
- /**
- * Configuration for the Month/Year CalendarNavigator UI which allows the user to jump directly to a
- * specific Month/Year without having to scroll sequentially through months.
- * <p>
- * Setting this property to null (default value) or false, will disable the CalendarNavigator UI.
- * </p>
- * <p>
- * Setting this property to true will enable the CalendarNavigatior UI with the default CalendarNavigator configuration values.
- * </p>
- * <p>
- * This property can also be set to an object literal containing configuration properties for the CalendarNavigator UI.
- * The configuration object expects the the following case-sensitive properties, with the "strings" property being a nested object.
- * Any properties which are not provided will use the default values (defined in the CalendarNavigator class).
- * </p>
- * <dl>
- * <dt>strings</dt>
- * <dd><em>Object</em> : An object with the properties shown below, defining the string labels to use in the Navigator's UI
- * <dl>
- * <dt>month</dt><dd><em>String</em> : The string to use for the month label. Defaults to "Month".</dd>
- * <dt>year</dt><dd><em>String</em> : The string to use for the year label. Defaults to "Year".</dd>
- * <dt>submit</dt><dd><em>String</em> : The string to use for the submit button label. Defaults to "Okay".</dd>
- * <dt>cancel</dt><dd><em>String</em> : The string to use for the cancel button label. Defaults to "Cancel".</dd>
- * <dt>invalidYear</dt><dd><em>String</em> : The string to use for invalid year values. Defaults to "Year needs to be a number".</dd>
- * </dl>
- * </dd>
- * <dt>monthFormat</dt><dd><em>String</em> : The month format to use. Either YAHOO.widget.Calendar.LONG, or YAHOO.widget.Calendar.SHORT. Defaults to YAHOO.widget.Calendar.LONG</dd>
- * <dt>initialFocus</dt><dd><em>String</em> : Either "year" or "month" specifying which input control should get initial focus. Defaults to "year"</dd>
- * </dl>
- * <p>E.g.</p>
- * <pre>
- * var navConfig = {
- * strings: {
- * month:"Calendar Month",
- * year:"Calendar Year",
- * submit: "Submit",
- * cancel: "Cancel",
- * invalidYear: "Please enter a valid year"
- * },
- * monthFormat: YAHOO.widget.Calendar.SHORT,
- * initialFocus: "month"
- * }
- * </pre>
- * @config navigator
- * @type {Object|Boolean}
- * @default null
- */
- cfg.addProperty(DEF_CFG.NAV.key, { value:DEF_CFG.NAV.value, handler:this.configNavigator } );
-
- /**
- * The map of UI strings which the Calendar UI uses.
- *
- * @config strings
- * @type {Object}
- * @default An object with the properties shown below:
- * <dl>
- * <dt>previousMonth</dt><dd><em>String</em> : The string to use for the "Previous Month" navigation UI. Defaults to "Previous Month".</dd>
- * <dt>nextMonth</dt><dd><em>String</em> : The string to use for the "Next Month" navigation UI. Defaults to "Next Month".</dd>
- * <dt>close</dt><dd><em>String</em> : The string to use for the close button label. Defaults to "Close".</dd>
- * </dl>
- */
- cfg.addProperty(DEF_CFG.STRINGS.key, {
- value:DEF_CFG.STRINGS.value,
- handler:this.configStrings,
- validator: function(val) {
- return Lang.isObject(val);
- },
- supercedes:DEF_CFG.STRINGS.supercedes
- });
- },
-
- /**
- * The default handler for the "strings" property
- * @method configStrings
- */
- configStrings : function(type, args, obj) {
- var val = Lang.merge(DEF_CFG.STRINGS.value, args[0]);
- this.cfg.setProperty(DEF_CFG.STRINGS.key, val, true);
- },
-
- /**
- * The default handler for the "pagedate" property
- * @method configPageDate
- */
- configPageDate : function(type, args, obj) {
- this.cfg.setProperty(DEF_CFG.PAGEDATE.key, this._parsePageDate(args[0]), true);
- },
-
- /**
- * The default handler for the "mindate" property
- * @method configMinDate
- */
- configMinDate : function(type, args, obj) {
- var val = args[0];
- if (Lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(DEF_CFG.MINDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
- }
- },
-
- /**
- * The default handler for the "maxdate" property
- * @method configMaxDate
- */
- configMaxDate : function(type, args, obj) {
- var val = args[0];
- if (Lang.isString(val)) {
- val = this._parseDate(val);
- this.cfg.setProperty(DEF_CFG.MAXDATE.key, DateMath.getDate(val[0],(val[1]-1),val[2]));
- }
- },
-
- /**
- * The default handler for the "selected" property
- * @method configSelected
- */
- configSelected : function(type, args, obj) {
- var selected = args[0],
- cfgSelected = DEF_CFG.SELECTED.key;
-
- if (selected) {
- if (Lang.isString(selected)) {
- this.cfg.setProperty(cfgSelected, this._parseDates(selected), true);
- }
- }
- if (! this._selectedDates) {
- this._selectedDates = this.cfg.getProperty(cfgSelected);
- }
- },
-
- /**
- * The default handler for all configuration options properties
- * @method configOptions
- */
- configOptions : function(type, args, obj) {
- this.Options[type.toUpperCase()] = args[0];
- },
-
- /**
- * The default handler for all configuration locale properties
- * @method configLocale
- */
- configLocale : function(type, args, obj) {
- this.Locale[type.toUpperCase()] = args[0];
-
- this.cfg.refireEvent(DEF_CFG.LOCALE_MONTHS.key);
- this.cfg.refireEvent(DEF_CFG.LOCALE_WEEKDAYS.key);
- },
-
- /**
- * The default handler for all configuration locale field length properties
- * @method configLocaleValues
- */
- configLocaleValues : function(type, args, obj) {
-
- type = type.toLowerCase();
-
- var val = args[0],
- cfg = this.cfg,
- Locale = this.Locale;
-
- switch (type) {
- case DEF_CFG.LOCALE_MONTHS.key:
- switch (val) {
- case Calendar.SHORT:
- Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_SHORT.key).concat();
- break;
- case Calendar.LONG:
- Locale.LOCALE_MONTHS = cfg.getProperty(DEF_CFG.MONTHS_LONG.key).concat();
- break;
- }
- break;
- case DEF_CFG.LOCALE_WEEKDAYS.key:
- switch (val) {
- case Calendar.ONE_CHAR:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_1CHAR.key).concat();
- break;
- case Calendar.SHORT:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_SHORT.key).concat();
- break;
- case Calendar.MEDIUM:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_MEDIUM.key).concat();
- break;
- case Calendar.LONG:
- Locale.LOCALE_WEEKDAYS = cfg.getProperty(DEF_CFG.WEEKDAYS_LONG.key).concat();
- break;
- }
-
- var START_WEEKDAY = cfg.getProperty(DEF_CFG.START_WEEKDAY.key);
-
- if (START_WEEKDAY > 0) {
- for (var w=0; w < START_WEEKDAY; ++w) {
- Locale.LOCALE_WEEKDAYS.push(Locale.LOCALE_WEEKDAYS.shift());
- }
- }
- break;
- }
- },
-
- /**
- * The default handler for the "navigator" property
- * @method configNavigator
- */
- configNavigator : function(type, args, obj) {
- var val = args[0];
- if (YAHOO.widget.CalendarNavigator && (val === true || Lang.isObject(val))) {
- if (!this.oNavigator) {
- this.oNavigator = new YAHOO.widget.CalendarNavigator(this);
- // Cleanup DOM Refs/Events before innerHTML is removed.
- this.beforeRenderEvent.subscribe(function () {
- if (!this.pages) {
- this.oNavigator.erase();
- }
- }, this, true);
- }
- } else {
- if (this.oNavigator) {
- this.oNavigator.destroy();
- this.oNavigator = null;
- }
- }
- },
-
- /**
- * Defines the style constants for the Calendar
- * @method initStyles
- */
- initStyles : function() {
-
- var defStyle = Calendar._STYLES;
-
- this.Style = {
- /**
- * @property Style.CSS_ROW_HEADER
- */
- CSS_ROW_HEADER: defStyle.CSS_ROW_HEADER,
- /**
- * @property Style.CSS_ROW_FOOTER
- */
- CSS_ROW_FOOTER: defStyle.CSS_ROW_FOOTER,
- /**
- * @property Style.CSS_CELL
- */
- CSS_CELL : defStyle.CSS_CELL,
- /**
- * @property Style.CSS_CELL_SELECTOR
- */
- CSS_CELL_SELECTOR : defStyle.CSS_CELL_SELECTOR,
- /**
- * @property Style.CSS_CELL_SELECTED
- */
- CSS_CELL_SELECTED : defStyle.CSS_CELL_SELECTED,
- /**
- * @property Style.CSS_CELL_SELECTABLE
- */
- CSS_CELL_SELECTABLE : defStyle.CSS_CELL_SELECTABLE,
- /**
- * @property Style.CSS_CELL_RESTRICTED
- */
- CSS_CELL_RESTRICTED : defStyle.CSS_CELL_RESTRICTED,
- /**
- * @property Style.CSS_CELL_TODAY
- */
- CSS_CELL_TODAY : defStyle.CSS_CELL_TODAY,
- /**
- * @property Style.CSS_CELL_OOM
- */
- CSS_CELL_OOM : defStyle.CSS_CELL_OOM,
- /**
- * @property Style.CSS_CELL_OOB
- */
- CSS_CELL_OOB : defStyle.CSS_CELL_OOB,
- /**
- * @property Style.CSS_HEADER
- */
- CSS_HEADER : defStyle.CSS_HEADER,
- /**
- * @property Style.CSS_HEADER_TEXT
- */
- CSS_HEADER_TEXT : defStyle.CSS_HEADER_TEXT,
- /**
- * @property Style.CSS_BODY
- */
- CSS_BODY : defStyle.CSS_BODY,
- /**
- * @property Style.CSS_WEEKDAY_CELL
- */
- CSS_WEEKDAY_CELL : defStyle.CSS_WEEKDAY_CELL,
- /**
- * @property Style.CSS_WEEKDAY_ROW
- */
- CSS_WEEKDAY_ROW : defStyle.CSS_WEEKDAY_ROW,
- /**
- * @property Style.CSS_FOOTER
- */
- CSS_FOOTER : defStyle.CSS_FOOTER,
- /**
- * @property Style.CSS_CALENDAR
- */
- CSS_CALENDAR : defStyle.CSS_CALENDAR,
- /**
- * @property Style.CSS_SINGLE
- */
- CSS_SINGLE : defStyle.CSS_SINGLE,
- /**
- * @property Style.CSS_CONTAINER
- */
- CSS_CONTAINER : defStyle.CSS_CONTAINER,
- /**
- * @property Style.CSS_NAV_LEFT
- */
- CSS_NAV_LEFT : defStyle.CSS_NAV_LEFT,
- /**
- * @property Style.CSS_NAV_RIGHT
- */
- CSS_NAV_RIGHT : defStyle.CSS_NAV_RIGHT,
- /**
- * @property Style.CSS_NAV
- */
- CSS_NAV : defStyle.CSS_NAV,
- /**
- * @property Style.CSS_CLOSE
- */
- CSS_CLOSE : defStyle.CSS_CLOSE,
- /**
- * @property Style.CSS_CELL_TOP
- */
- CSS_CELL_TOP : defStyle.CSS_CELL_TOP,
- /**
- * @property Style.CSS_CELL_LEFT
- */
- CSS_CELL_LEFT : defStyle.CSS_CELL_LEFT,
- /**
- * @property Style.CSS_CELL_RIGHT
- */
- CSS_CELL_RIGHT : defStyle.CSS_CELL_RIGHT,
- /**
- * @property Style.CSS_CELL_BOTTOM
- */
- CSS_CELL_BOTTOM : defStyle.CSS_CELL_BOTTOM,
- /**
- * @property Style.CSS_CELL_HOVER
- */
- CSS_CELL_HOVER : defStyle.CSS_CELL_HOVER,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT1
- */
- CSS_CELL_HIGHLIGHT1 : defStyle.CSS_CELL_HIGHLIGHT1,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT2
- */
- CSS_CELL_HIGHLIGHT2 : defStyle.CSS_CELL_HIGHLIGHT2,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT3
- */
- CSS_CELL_HIGHLIGHT3 : defStyle.CSS_CELL_HIGHLIGHT3,
- /**
- * @property Style.CSS_CELL_HIGHLIGHT4
- */
- CSS_CELL_HIGHLIGHT4 : defStyle.CSS_CELL_HIGHLIGHT4
- };
- },
-
- /**
- * Builds the date label that will be displayed in the calendar header or
- * footer, depending on configuration.
- * @method buildMonthLabel
- * @return {String} The formatted calendar month label
- */
- buildMonthLabel : function() {
- return this._buildMonthLabel(this.cfg.getProperty(DEF_CFG.PAGEDATE.key));
- },
+ /**
+ * The configuration object used to set up the calendars various locale and style options.
+ * @property Config
+ * @private
+ * @deprecated Configuration properties should be set by calling Calendar.cfg.setProperty.
+ * @type Object
+ */
+ Config : null,
/**
- * Helper method, to format a Month Year string, given a JavaScript Date, based on the
- * Calendar localization settings
- *
- * @method _buildMonthLabel
- * @private
- * @param {Date} date
- * @return {String} Formated month, year string
- */
- _buildMonthLabel : function(date) {
- var monthLabel = this.Locale.LOCALE_MONTHS[date.getMonth()] + this.Locale.MY_LABEL_MONTH_SUFFIX,
- yearLabel = date.getFullYear() + this.Locale.MY_LABEL_YEAR_SUFFIX;
-
- if (this.Locale.MY_LABEL_MONTH_POSITION == 2 || this.Locale.MY_LABEL_YEAR_POSITION == 1) {
- return yearLabel + monthLabel;
- } else {
- return monthLabel + yearLabel;
- }
- },
-
- /**
- * Builds the date digit that will be displayed in calendar cells
- * @method buildDayLabel
- * @param {Date} workingDate The current working date
- * @return {String} The formatted day label
- */
- buildDayLabel : function(workingDate) {
- return workingDate.getDate();
- },
-
- /**
- * Creates the title bar element and adds it to Calendar container DIV
- *
- * @method createTitleBar
- * @param {String} strTitle The title to display in the title bar
- * @return The title bar element
- */
- createTitleBar : function(strTitle) {
- var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || document.createElement("div");
- tDiv.className = YAHOO.widget.CalendarGroup.CSS_2UPTITLE;
- tDiv.innerHTML = strTitle;
- this.oDomContainer.insertBefore(tDiv, this.oDomContainer.firstChild);
-
- Dom.addClass(this.oDomContainer, "withtitle");
-
- return tDiv;
- },
-
- /**
- * Removes the title bar element from the DOM
- *
- * @method removeTitleBar
- */
- removeTitleBar : function() {
- var tDiv = Dom.getElementsByClassName(YAHOO.widget.CalendarGroup.CSS_2UPTITLE, "div", this.oDomContainer)[0] || null;
- if (tDiv) {
- Event.purgeElement(tDiv);
- this.oDomContainer.removeChild(tDiv);
- }
- Dom.removeClass(this.oDomContainer, "withtitle");
- },
-
- /**
- * Creates the close button HTML element and adds it to Calendar container DIV
- *
- * @method createCloseButton
- * @return The close HTML element created
- */
- createCloseButton : function() {
- var cssClose = YAHOO.widget.CalendarGroup.CSS_2UPCLOSE,
- DEPR_CLOSE_PATH = "us/my/bn/x_d.gif",
- lnk = Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0],
- strings = this.cfg.getProperty(DEF_CFG.STRINGS.key),
- closeStr = (strings && strings.close) ? strings.close : "";
-
- if (!lnk) {
- lnk = document.createElement("a");
- Event.addListener(lnk, "click", function(e, cal) {
- cal.hide();
- Event.preventDefault(e);
- }, this);
- }
-
- lnk.href = "#";
- lnk.className = "link-close";
-
- if (Calendar.IMG_ROOT !== null) {
- var img = Dom.getElementsByClassName(cssClose, "img", lnk)[0] || document.createElement("img");
- img.src = Calendar.IMG_ROOT + DEPR_CLOSE_PATH;
- img.className = cssClose;
- lnk.appendChild(img);
- } else {
- lnk.innerHTML = '<span class="' + cssClose + ' ' + this.Style.CSS_CLOSE + '">' + closeStr + '</span>';
- }
- this.oDomContainer.appendChild(lnk);
-
- return lnk;
- },
-
- /**
- * Removes the close button HTML element from the DOM
- *
- * @method removeCloseButton
- */
- removeCloseButton : function() {
- var btn = Dom.getElementsByClassName("link-close", "a", this.oDomContainer)[0] || null;
- if (btn) {
- Event.purgeElement(btn);
- this.oDomContainer.removeChild(btn);
- }
- },
-
- /**
- * Renders the calendar header.
- * @method renderHeader
- * @param {Array} html The current working HTML array
- * @return {Array} The current working HTML array
- */
- renderHeader : function(html) {
-
-
- var colSpan = 7,
- DEPR_NAV_LEFT = "us/tr/callt.gif",
- DEPR_NAV_RIGHT = "us/tr/calrt.gif",
- cfg = this.cfg,
- pageDate = cfg.getProperty(DEF_CFG.PAGEDATE.key),
- strings= cfg.getProperty(DEF_CFG.STRINGS.key),
- prevStr = (strings && strings.previousMonth) ? strings.previousMonth : "",
- nextStr = (strings && strings.nextMonth) ? strings.nextMonth : "",
- monthLabel;
+ * The parent CalendarGroup, only to be set explicitly by the parent group
+ * @property parent
+ * @type CalendarGroup
+ */
+ parent : null,
- if (cfg.getProperty(DEF_CFG.SHOW_WEEK_HEADER.key)) {
- colSpan += 1;
- }
-
- if (cfg.getProperty(DEF_CFG.SHOW_WEEK_FOOTER.key)) {
- colSpan += 1;
- }
-
- html[html.length] = "<thead>";
- html[html.length] = "<tr>";
- html[html.length] = '<th colspan="' + colSpan + '" class="' + this.Style.CSS_HEADER_TEXT + '">';
- html[html.length] = '<div class="' + this.Style.CSS_HEADER + '">';
-
- var renderLeft, renderRight = false;
-
- if (this.parent) {
- if (this.index === 0) {
- renderLeft = true;
- }
- if (this.index == (this.parent.cfg.getProperty("pages") -1)) {
- renderRight = true;
- }
- } else {
- renderLeft = true;
- renderRight = true;
- }
-
- if (renderLeft) {
- monthLabel = this._buildMonthLabel(DateMath.subtract(pageDate, DateMath.MONTH, 1));
-
- var leftArrow = cfg.getProperty(DEF_CFG.NAV_ARROW_LEFT.key);
- // Check for deprecated customization - If someone set IMG_ROOT, but didn't set NAV_ARROW_LEFT, then set NAV_ARROW_LEFT to the old deprecated value
- if (leftArrow === null && Calendar.IMG_ROOT !== null) {
- leftArrow = Calendar.IMG_ROOT + DEPR_NAV_LEFT;
- }
- var leftStyle = (leftArrow === null) ? "" : ' style="background-image:url(' + leftArrow + ')"';
- html[html.length] = '<a class="' + this.Style.CSS_NAV_LEFT + '"' + leftStyle + ' href="#">' + prevStr + ' (' + monthLabel + ')' + '</a>';
- }
-
- var lbl = this.buildMonthLabel();
- var cal = this.parent || this;
[... 10057 lines stripped ...]