2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
/* Date Math
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
var DAY_MS = 86400000,
|
2009-10-10 10:12:40 +02:00
|
|
|
HOUR_MS = 3600000,
|
2010-01-27 08:58:43 +01:00
|
|
|
MINUTE_MS = 60000;
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
function addYears(d, n, keepTime) {
|
|
|
|
d.setFullYear(d.getFullYear() + n);
|
2009-10-01 07:39:02 +02:00
|
|
|
if (!keepTime) {
|
|
|
|
clearTime(d);
|
|
|
|
}
|
|
|
|
return d;
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
function addMonths(d, n, keepTime) { // prevents day overflow/underflow
|
2009-10-14 09:01:55 +02:00
|
|
|
if (+d) { // prevent infinite looping on invalid dates
|
|
|
|
var m = d.getMonth() + n,
|
|
|
|
check = cloneDate(d);
|
|
|
|
check.setDate(1);
|
|
|
|
check.setMonth(m);
|
|
|
|
d.setMonth(m);
|
|
|
|
if (!keepTime) {
|
|
|
|
clearTime(d);
|
|
|
|
}
|
|
|
|
while (d.getMonth() != check.getMonth()) {
|
|
|
|
d.setDate(d.getDate() + (d < check ? 1 : -1));
|
|
|
|
}
|
2009-10-01 07:39:02 +02:00
|
|
|
}
|
|
|
|
return d;
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
|
|
|
|
2009-10-01 07:39:02 +02:00
|
|
|
function addDays(d, n, keepTime) { // deals with daylight savings
|
2009-12-21 10:32:03 +01:00
|
|
|
if (+d) {
|
2009-10-14 09:01:55 +02:00
|
|
|
var dd = d.getDate() + n,
|
|
|
|
check = cloneDate(d);
|
2009-12-21 10:32:03 +01:00
|
|
|
check.setHours(9); // set to middle of day
|
2009-10-14 09:01:55 +02:00
|
|
|
check.setDate(dd);
|
|
|
|
d.setDate(dd);
|
|
|
|
if (!keepTime) {
|
|
|
|
clearTime(d);
|
|
|
|
}
|
2009-12-21 10:32:03 +01:00
|
|
|
fixDate(d, check);
|
|
|
|
}
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
fc.addDays = addDays;
|
|
|
|
|
|
|
|
function fixDate(d, check) { // force d to be on check's YMD, for daylight savings purposes
|
|
|
|
if (+d) { // prevent infinite looping on invalid dates
|
2009-10-14 09:01:55 +02:00
|
|
|
while (d.getDate() != check.getDate()) {
|
|
|
|
d.setTime(+d + (d < check ? 1 : -1) * HOUR_MS);
|
|
|
|
}
|
2009-10-01 07:39:02 +02:00
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
function addMinutes(d, n) {
|
|
|
|
d.setMinutes(d.getMinutes() + n);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
function clearTime(d) {
|
|
|
|
d.setHours(0);
|
|
|
|
d.setMinutes(0);
|
|
|
|
d.setSeconds(0);
|
|
|
|
d.setMilliseconds(0);
|
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
function cloneDate(d, dontKeepTime) {
|
|
|
|
if (dontKeepTime) {
|
|
|
|
return clearTime(new Date(+d));
|
|
|
|
}
|
|
|
|
return new Date(+d);
|
|
|
|
}
|
2010-05-03 06:47:23 +02:00
|
|
|
fc.cloneDate = cloneDate;
|
2009-09-21 06:57:20 +02:00
|
|
|
|
2009-11-01 00:51:30 +01:00
|
|
|
function zeroDate() { // returns a Date with time 00:00:00 and dateOfMonth=1
|
|
|
|
var i=0, d;
|
|
|
|
do {
|
|
|
|
d = new Date(1970, i++, 1);
|
2010-03-14 02:06:13 +01:00
|
|
|
} while (d.getHours()); // != 0
|
2009-11-01 00:51:30 +01:00
|
|
|
return d;
|
|
|
|
}
|
|
|
|
|
|
|
|
function skipWeekend(date, inc, excl) {
|
|
|
|
inc = inc || 1;
|
2010-03-14 02:06:13 +01:00
|
|
|
while (!date.getDay() || (excl && date.getDay()==1 || !excl && date.getDay()==6)) {
|
2009-11-01 00:51:30 +01:00
|
|
|
addDays(date, inc);
|
|
|
|
}
|
|
|
|
return date;
|
|
|
|
}
|
|
|
|
|
2010-05-29 07:11:26 +02:00
|
|
|
function dayDiff(d1, d2) { // d1 - d2
|
|
|
|
return Math.round((cloneDate(d1, true) - cloneDate(d2, true)) / DAY_MS);
|
|
|
|
}
|
|
|
|
|
2010-07-04 01:15:34 +02:00
|
|
|
function setYMD(date, y, m, d) {
|
|
|
|
if (y !== undefined && y != date.getFullYear()) {
|
|
|
|
date.setDate(1);
|
|
|
|
date.setMonth(0);
|
|
|
|
date.setFullYear(y);
|
|
|
|
}
|
|
|
|
if (m !== undefined && m != date.getMonth()) {
|
|
|
|
date.setDate(1);
|
|
|
|
date.setMonth(m);
|
|
|
|
}
|
|
|
|
if (d !== undefined) {
|
|
|
|
date.setDate(d);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Date Parsing
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var parseDate = fc.parseDate = function(s) {
|
|
|
|
if (typeof s == 'object') { // already a Date object
|
|
|
|
return s;
|
|
|
|
}
|
|
|
|
if (typeof s == 'number') { // a UNIX timestamp
|
|
|
|
return new Date(s * 1000);
|
|
|
|
}
|
|
|
|
if (typeof s == 'string') {
|
|
|
|
if (s.match(/^\d+$/)) { // a UNIX timestamp
|
|
|
|
return new Date(parseInt(s) * 1000);
|
|
|
|
}
|
2009-12-21 10:32:03 +01:00
|
|
|
return parseISO8601(s, true) || (s ? new Date(s) : null);
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
2009-12-22 04:19:41 +01:00
|
|
|
// TODO: never return invalid dates (like from new Date(<string>)), return null instead
|
2009-09-21 06:57:20 +02:00
|
|
|
return null;
|
2010-03-14 02:06:13 +01:00
|
|
|
};
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
var parseISO8601 = fc.parseISO8601 = function(s, ignoreTimezone) {
|
|
|
|
// derived from http://delete.me.uk/2005/03/iso8601.html
|
2009-12-22 09:41:38 +01:00
|
|
|
// TODO: for a know glitch/feature, read tests/issue_206_parseDate_dst.html
|
2009-12-21 10:32:03 +01:00
|
|
|
var m = s.match(/^([0-9]{4})(-([0-9]{2})(-([0-9]{2})([T ]([0-9]{2}):([0-9]{2})(:([0-9]{2})(\.([0-9]+))?)?(Z|(([-+])([0-9]{2}):([0-9]{2})))?)?)?)?$/);
|
|
|
|
if (!m) {
|
|
|
|
return null;
|
|
|
|
}
|
|
|
|
var date = new Date(m[1], 0, 1),
|
|
|
|
check = new Date(m[1], 0, 1, 9, 0),
|
|
|
|
offset = 0;
|
|
|
|
if (m[3]) {
|
|
|
|
date.setMonth(m[3] - 1);
|
|
|
|
check.setMonth(m[3] - 1);
|
|
|
|
}
|
|
|
|
if (m[5]) {
|
|
|
|
date.setDate(m[5]);
|
|
|
|
check.setDate(m[5]);
|
|
|
|
}
|
|
|
|
fixDate(date, check);
|
|
|
|
if (m[7]) {
|
|
|
|
date.setHours(m[7]);
|
|
|
|
}
|
|
|
|
if (m[8]) {
|
|
|
|
date.setMinutes(m[8]);
|
|
|
|
}
|
|
|
|
if (m[10]) {
|
|
|
|
date.setSeconds(m[10]);
|
|
|
|
}
|
|
|
|
if (m[12]) {
|
|
|
|
date.setMilliseconds(Number("0." + m[12]) * 1000);
|
|
|
|
}
|
|
|
|
fixDate(date, check);
|
2009-09-21 06:57:20 +02:00
|
|
|
if (!ignoreTimezone) {
|
2009-12-21 10:32:03 +01:00
|
|
|
if (m[14]) {
|
|
|
|
offset = Number(m[16]) * 60 + Number(m[17]);
|
|
|
|
offset *= m[15] == '-' ? 1 : -1;
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
|
|
|
offset -= date.getTimezoneOffset();
|
|
|
|
}
|
2009-12-21 10:32:03 +01:00
|
|
|
return new Date(+date + (offset * 60 * 1000));
|
2010-03-14 02:06:13 +01:00
|
|
|
};
|
2009-09-21 06:57:20 +02:00
|
|
|
|
2009-11-30 05:16:47 +01:00
|
|
|
var parseTime = fc.parseTime = function(s) { // returns minutes since start of day
|
|
|
|
if (typeof s == 'number') { // an hour
|
|
|
|
return s * 60;
|
|
|
|
}
|
|
|
|
if (typeof s == 'object') { // a Date object
|
|
|
|
return s.getHours() * 60 + s.getMinutes();
|
|
|
|
}
|
|
|
|
var m = s.match(/(\d+)(?::(\d+))?\s*(\w+)?/);
|
|
|
|
if (m) {
|
|
|
|
var h = parseInt(m[1]);
|
|
|
|
if (m[3]) {
|
|
|
|
h %= 12;
|
|
|
|
if (m[3].toLowerCase().charAt(0) == 'p') {
|
|
|
|
h += 12;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return h * 60 + (m[2] ? parseInt(m[2]) : 0);
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
|
|
|
|
/* Date Formatting
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
var formatDate = fc.formatDate = function(date, format, options) {
|
|
|
|
return formatDates(date, null, format, options);
|
2010-03-14 02:06:13 +01:00
|
|
|
};
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
var formatDates = fc.formatDates = function(date1, date2, format, options) {
|
|
|
|
options = options || defaults;
|
|
|
|
var date = date1,
|
|
|
|
otherDate = date2,
|
|
|
|
i, len = format.length, c,
|
|
|
|
i2, formatter,
|
|
|
|
res = '';
|
|
|
|
for (i=0; i<len; i++) {
|
|
|
|
c = format.charAt(i);
|
|
|
|
if (c == "'") {
|
|
|
|
for (i2=i+1; i2<len; i2++) {
|
|
|
|
if (format.charAt(i2) == "'") {
|
|
|
|
if (date) {
|
|
|
|
if (i2 == i+1) {
|
|
|
|
res += "'";
|
|
|
|
}else{
|
|
|
|
res += format.substring(i+1, i2);
|
|
|
|
}
|
|
|
|
i = i2;
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (c == '(') {
|
|
|
|
for (i2=i+1; i2<len; i2++) {
|
|
|
|
if (format.charAt(i2) == ')') {
|
|
|
|
var subres = formatDate(date, format.substring(i+1, i2), options);
|
|
|
|
if (parseInt(subres.replace(/\D/, ''))) {
|
|
|
|
res += subres;
|
|
|
|
}
|
|
|
|
i = i2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (c == '[') {
|
|
|
|
for (i2=i+1; i2<len; i2++) {
|
|
|
|
if (format.charAt(i2) == ']') {
|
|
|
|
var subformat = format.substring(i+1, i2);
|
|
|
|
var subres = formatDate(date, subformat, options);
|
|
|
|
if (subres != formatDate(otherDate, subformat, options)) {
|
|
|
|
res += subres;
|
|
|
|
}
|
|
|
|
i = i2;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else if (c == '{') {
|
|
|
|
date = date2;
|
|
|
|
otherDate = date1;
|
|
|
|
}
|
|
|
|
else if (c == '}') {
|
|
|
|
date = date1;
|
|
|
|
otherDate = date2;
|
|
|
|
}
|
|
|
|
else {
|
|
|
|
for (i2=len; i2>i; i2--) {
|
|
|
|
if (formatter = dateFormatters[format.substring(i, i2)]) {
|
|
|
|
if (date) {
|
|
|
|
res += formatter(date, options);
|
|
|
|
}
|
|
|
|
i = i2 - 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (i2 == i) {
|
|
|
|
if (date) {
|
|
|
|
res += c;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return res;
|
2010-03-14 02:06:13 +01:00
|
|
|
};
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
var dateFormatters = {
|
|
|
|
s : function(d) { return d.getSeconds() },
|
|
|
|
ss : function(d) { return zeroPad(d.getSeconds()) },
|
|
|
|
m : function(d) { return d.getMinutes() },
|
|
|
|
mm : function(d) { return zeroPad(d.getMinutes()) },
|
|
|
|
h : function(d) { return d.getHours() % 12 || 12 },
|
|
|
|
hh : function(d) { return zeroPad(d.getHours() % 12 || 12) },
|
|
|
|
H : function(d) { return d.getHours() },
|
|
|
|
HH : function(d) { return zeroPad(d.getHours()) },
|
|
|
|
d : function(d) { return d.getDate() },
|
|
|
|
dd : function(d) { return zeroPad(d.getDate()) },
|
|
|
|
ddd : function(d,o) { return o.dayNamesShort[d.getDay()] },
|
|
|
|
dddd: function(d,o) { return o.dayNames[d.getDay()] },
|
|
|
|
M : function(d) { return d.getMonth() + 1 },
|
|
|
|
MM : function(d) { return zeroPad(d.getMonth() + 1) },
|
|
|
|
MMM : function(d,o) { return o.monthNamesShort[d.getMonth()] },
|
|
|
|
MMMM: function(d,o) { return o.monthNames[d.getMonth()] },
|
|
|
|
yy : function(d) { return (d.getFullYear()+'').substring(2) },
|
|
|
|
yyyy: function(d) { return d.getFullYear() },
|
|
|
|
t : function(d) { return d.getHours() < 12 ? 'a' : 'p' },
|
|
|
|
tt : function(d) { return d.getHours() < 12 ? 'am' : 'pm' },
|
|
|
|
T : function(d) { return d.getHours() < 12 ? 'A' : 'P' },
|
|
|
|
TT : function(d) { return d.getHours() < 12 ? 'AM' : 'PM' },
|
|
|
|
u : function(d) { return formatDate(d, "yyyy-MM-dd'T'HH:mm:ss'Z'") },
|
|
|
|
S : function(d) {
|
|
|
|
var date = d.getDate();
|
2010-03-14 02:06:13 +01:00
|
|
|
if (date > 10 && date < 20) {
|
|
|
|
return 'th';
|
|
|
|
}
|
2009-09-21 06:57:20 +02:00
|
|
|
return ['st', 'nd', 'rd'][date%10-1] || 'th';
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Element Dimensions
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
function setOuterWidth(element, width, includeMargins) {
|
2010-02-01 07:32:51 +01:00
|
|
|
element.each(function(i, _element) {
|
|
|
|
_element.style.width = width - hsides(_element, includeMargins) + 'px';
|
2009-09-21 06:57:20 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
|
|
|
function setOuterHeight(element, height, includeMargins) {
|
2010-02-01 07:32:51 +01:00
|
|
|
element.each(function(i, _element) {
|
|
|
|
_element.style.height = height - vsides(_element, includeMargins) + 'px';
|
2009-09-21 06:57:20 +02:00
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2010-02-01 07:32:51 +01:00
|
|
|
|
|
|
|
function hsides(_element, includeMargins) {
|
|
|
|
return (parseFloat(jQuery.curCSS(_element, 'paddingLeft', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'paddingRight', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'borderLeftWidth', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'borderRightWidth', true)) || 0) +
|
|
|
|
(includeMargins ? hmargins(_element) : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function hmargins(_element) {
|
|
|
|
return (parseFloat(jQuery.curCSS(_element, 'marginLeft', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'marginRight', true)) || 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function vsides(_element, includeMargins) {
|
|
|
|
return (parseFloat(jQuery.curCSS(_element, 'paddingTop', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'paddingBottom', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'borderTopWidth', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'borderBottomWidth', true)) || 0) +
|
|
|
|
(includeMargins ? vmargins(_element) : 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
function vmargins(_element) {
|
|
|
|
return (parseFloat(jQuery.curCSS(_element, 'marginTop', true)) || 0) +
|
|
|
|
(parseFloat(jQuery.curCSS(_element, 'marginBottom', true)) || 0);
|
2009-11-29 09:12:36 +01:00
|
|
|
}
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
|
2010-02-16 07:32:43 +01:00
|
|
|
|
|
|
|
function setMinHeight(element, h) {
|
2010-02-21 02:44:24 +01:00
|
|
|
h = typeof h == 'number' ? h + 'px' : h;
|
|
|
|
element[0].style.cssText += ';min-height:' + h + ';_height:' + h;
|
2010-02-16 07:32:43 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-10-13 06:22:40 +02:00
|
|
|
/* Position Calculation
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
// nasty bugs in opera 9.25
|
2010-01-25 07:56:57 +01:00
|
|
|
// position()'s top returning incorrectly with TR/TD or elements within TD
|
2009-10-13 06:22:40 +02:00
|
|
|
|
2010-01-25 07:56:57 +01:00
|
|
|
var topBug;
|
2009-10-13 06:22:40 +02:00
|
|
|
|
2010-01-26 08:05:57 +01:00
|
|
|
function topCorrect(tr) { // tr/th/td or anything else
|
|
|
|
if (topBug !== false) {
|
|
|
|
var cell;
|
|
|
|
if (tr.is('th,td')) {
|
|
|
|
tr = (cell = tr).parent();
|
|
|
|
}
|
2010-03-14 02:06:13 +01:00
|
|
|
if (topBug === undefined && tr.is('tr')) {
|
2010-01-26 08:05:57 +01:00
|
|
|
topBug = tr.position().top != tr.children().position().top;
|
2010-01-25 07:56:57 +01:00
|
|
|
}
|
|
|
|
if (topBug) {
|
2010-01-26 08:05:57 +01:00
|
|
|
return tr.parent().position().top + (cell ? tr.position().top - cell.position().top : 0);
|
2010-01-25 07:56:57 +01:00
|
|
|
}
|
2009-10-13 06:22:40 +02:00
|
|
|
}
|
2010-01-25 07:56:57 +01:00
|
|
|
return 0;
|
2009-10-13 06:22:40 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
/* Coordinate Grid
|
2009-09-21 06:57:20 +02:00
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
function CoordinateGrid(buildFunc) {
|
2009-09-21 06:57:20 +02:00
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
var t = this;
|
|
|
|
var rows;
|
|
|
|
var cols;
|
2009-09-21 06:57:20 +02:00
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
t.build = function() {
|
|
|
|
rows = [];
|
|
|
|
cols = [];
|
|
|
|
buildFunc(rows, cols);
|
|
|
|
};
|
|
|
|
|
|
|
|
t.cell = function(x, y) {
|
|
|
|
var rowCnt = rows.length;
|
|
|
|
var colCnt = cols.length;
|
|
|
|
var i, r=-1, c=-1;
|
|
|
|
for (i=0; i<rowCnt; i++) {
|
|
|
|
if (y >= rows[i][0] && y < rows[i][1]) {
|
|
|
|
r = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for (i=0; i<colCnt; i++) {
|
|
|
|
if (x >= cols[i][0] && x < cols[i][1]) {
|
|
|
|
c = i;
|
|
|
|
break;
|
2009-09-21 06:57:20 +02:00
|
|
|
}
|
|
|
|
}
|
2010-06-29 06:51:13 +02:00
|
|
|
return (r>=0 && c>=0) ? { row:r, col:c } : null;
|
2009-09-21 06:57:20 +02:00
|
|
|
};
|
2010-04-23 05:27:14 +02:00
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
t.rect = function(row0, col0, row1, col1, originElement) { // row1,col1 is inclusive
|
2010-04-23 05:27:14 +02:00
|
|
|
var origin = originElement.offset();
|
|
|
|
return {
|
2010-06-29 06:51:13 +02:00
|
|
|
top: rows[row0][0] - origin.top,
|
|
|
|
left: cols[col0][0] - origin.left,
|
|
|
|
width: cols[col1][1] - cols[col0][0],
|
|
|
|
height: rows[row1][1] - rows[row0][0]
|
2010-04-23 05:27:14 +02:00
|
|
|
};
|
|
|
|
};
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
/* Hover Listener
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
|
|
|
function HoverListener(coordinateGrid) {
|
|
|
|
|
|
|
|
var t = this;
|
|
|
|
var bindType;
|
|
|
|
var change;
|
|
|
|
var firstCell;
|
|
|
|
var cell;
|
|
|
|
|
|
|
|
t.start = function(_change, ev, _bindType) {
|
|
|
|
change = _change;
|
|
|
|
firstCell = cell = null;
|
|
|
|
coordinateGrid.build();
|
|
|
|
mouse(ev);
|
|
|
|
bindType = _bindType || 'mousemove';
|
|
|
|
$(document).bind(bindType, mouse);
|
|
|
|
};
|
|
|
|
|
|
|
|
function mouse(ev) {
|
|
|
|
var newCell = coordinateGrid.cell(ev.pageX, ev.pageY);
|
|
|
|
if (!newCell != !cell || newCell && (newCell.row != cell.row || newCell.col != cell.col)) {
|
|
|
|
if (newCell) {
|
|
|
|
if (!firstCell) {
|
|
|
|
firstCell = newCell;
|
|
|
|
}
|
|
|
|
change(newCell, firstCell, newCell.row-firstCell.row, newCell.col-firstCell.col);
|
|
|
|
}else{
|
|
|
|
change(newCell, firstCell);
|
|
|
|
}
|
|
|
|
cell = newCell;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
t.stop = function() {
|
|
|
|
$(document).unbind(bindType, mouse);
|
|
|
|
return cell;
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2009-09-21 06:57:20 +02:00
|
|
|
/* Misc Utils
|
|
|
|
-----------------------------------------------------------------------------*/
|
|
|
|
|
2010-06-29 06:51:13 +02:00
|
|
|
var dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
|
2009-09-21 06:57:20 +02:00
|
|
|
|
|
|
|
function zeroPad(n) {
|
|
|
|
return (n < 10 ? '0' : '') + n;
|
|
|
|
}
|
|
|
|
|
2009-12-31 03:45:39 +01:00
|
|
|
function smartProperty(obj, name) { // get a camel-cased/namespaced property of an object
|
2010-03-14 02:06:13 +01:00
|
|
|
if (obj[name] !== undefined) {
|
2009-10-13 06:22:40 +02:00
|
|
|
return obj[name];
|
|
|
|
}
|
|
|
|
var parts = name.split(/(?=[A-Z])/),
|
|
|
|
i=parts.length-1, res;
|
|
|
|
for (; i>=0; i--) {
|
|
|
|
res = obj[parts[i].toLowerCase()];
|
2010-03-14 02:06:13 +01:00
|
|
|
if (res !== undefined) {
|
2009-10-13 06:22:40 +02:00
|
|
|
return res;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return obj[''];
|
|
|
|
}
|
|
|
|
|
2009-12-31 03:45:39 +01:00
|
|
|
function htmlEscape(s) {
|
2010-07-04 01:24:45 +02:00
|
|
|
return s.replace(/&/g, '&')
|
2009-12-31 03:45:39 +01:00
|
|
|
.replace(/</g, '<')
|
|
|
|
.replace(/>/g, '>')
|
|
|
|
.replace(/'/g, ''')
|
2010-07-04 01:24:45 +02:00
|
|
|
.replace(/"/g, '"')
|
|
|
|
.replace(/\n/g, '<br />');
|
2009-12-31 03:45:39 +01:00
|
|
|
}
|
|
|
|
|
2010-01-25 07:56:57 +01:00
|
|
|
|
|
|
|
|
|
|
|
function HorizontalPositionCache(getElement) {
|
|
|
|
|
|
|
|
var t = this,
|
|
|
|
elements = {},
|
|
|
|
lefts = {},
|
|
|
|
rights = {};
|
|
|
|
|
|
|
|
function e(i) {
|
2010-03-14 02:06:13 +01:00
|
|
|
return elements[i] = elements[i] || getElement(i);
|
2010-01-25 07:56:57 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
t.left = function(i) {
|
2010-03-14 02:06:13 +01:00
|
|
|
return lefts[i] = lefts[i] === undefined ? e(i).position().left : lefts[i];
|
2010-01-25 07:56:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
t.right = function(i) {
|
2010-03-14 02:06:13 +01:00
|
|
|
return rights[i] = rights[i] === undefined ? t.left(i) + e(i).width() : rights[i];
|
2010-01-25 07:56:57 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
t.clear = function() {
|
|
|
|
elements = {};
|
|
|
|
lefts = {};
|
|
|
|
rights = {};
|
|
|
|
};
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
2010-02-04 07:56:20 +01:00
|
|
|
function cssKey(_element) {
|
|
|
|
return _element.id + '/' + _element.className + '/' + _element.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig, '');
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-29 07:11:26 +02:00
|
|
|
|
2010-05-03 06:47:23 +02:00
|
|
|
function cmp(a, b) {
|
2010-04-23 05:27:14 +02:00
|
|
|
return a - b;
|
|
|
|
}
|
2010-05-29 07:11:26 +02:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
function exclEndDay(event) {
|
|
|
|
if (event.end) {
|
|
|
|
return _exclEndDay(event.end, event.allDay);
|
|
|
|
}else{
|
|
|
|
return addDays(cloneDate(event.start), 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
function _exclEndDay(end, allDay) {
|
|
|
|
end = cloneDate(end);
|
2010-07-03 23:09:14 +02:00
|
|
|
return allDay || end.getHours() || end.getMinutes() ? addDays(end, 1) : clearTime(end);
|
2010-05-29 07:11:26 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2010-05-03 06:47:23 +02:00
|
|
|
|
2010-05-31 19:18:29 +02:00
|
|
|
function disableTextSelection(element) {
|
|
|
|
element
|
|
|
|
.attr('unselectable', 'on')
|
|
|
|
.css('MozUserSelect', 'none')
|
|
|
|
.bind('selectstart.ui', function() { return false; });
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
function enableTextSelection(element) {
|
|
|
|
element
|
|
|
|
.attr('unselectable', 'off')
|
|
|
|
.css('MozUserSelect', '')
|
|
|
|
.unbind('selectstart.ui');
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
2010-05-03 06:47:23 +02:00
|
|
|
|