final round of optimizations for event rendering. fixed some new bugs

v1.4.x
Adam Shaw 2010-01-31 22:32:51 -08:00
parent 1fbb7f64cd
commit 0e3e04bbdf
9 changed files with 274 additions and 200 deletions

View File

@ -89,6 +89,7 @@ function Agenda(element, options, methods) {
colContentPositions = new HorizontalPositionCache(function(col) {
return bg.find('td:eq(' + col + ') div div');
}),
slotTopCache = {},
// ...
view = $.extend(this, viewMethods, methods, {
@ -167,7 +168,7 @@ function Agenda(element, options, methods) {
s += "<tr class='fc-all-day'>" +
"<th class='fc-axis fc-leftmost " + tm + "-state-default'>" + options.allDayText + "</th>" +
"<td colspan='" + colCnt + "' class='" + tm + "-state-default'>" +
"<div class='fc-day-content'><div>&nbsp;</div></div></td>" +
"<div class='fc-day-content'><div style='position:relative'>&nbsp;</div></div></td>" +
"<th class='" + tm + "-state-default'>&nbsp;</th>" +
"</tr><tr class='fc-divider fc-last'><th colspan='" + (colCnt+2) + "' class='" +
tm + "-state-default fc-leftmost'><div/></th></tr>";
@ -177,7 +178,7 @@ function Agenda(element, options, methods) {
head.find('td').click(slotClick);
// all-day event container
daySegmentContainer = $("<div/>").appendTo(head);
daySegmentContainer = $("<div style='position:absolute;top:0;left:0'/>").appendTo(head);
// body
d = zeroDate();
@ -191,7 +192,7 @@ function Agenda(element, options, methods) {
"'><th class='fc-axis fc-leftmost " + tm + "-state-default'>" +
((!slotNormal || minutes==0) ? formatDate(d, options.axisFormat) : '&nbsp;') +
"</th><td class='fc-slot" + i + ' ' +
tm + "-state-default'><div>&nbsp;</div></td></tr>";
tm + "-state-default'><div style='position:relative'>&nbsp;</div></td></tr>";
addMinutes(d, options.slotMinutes);
}
s += "</table>";
@ -287,6 +288,7 @@ function Agenda(element, options, methods) {
viewWidth = width;
viewHeight = height;
colContentPositions.clear();
slotTopCache = {};
body.width(width);
body.height(height - head.height());
@ -357,7 +359,7 @@ function Agenda(element, options, methods) {
slotEvents.push(events[i]);
}
}
renderDaySegs(stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd)));
renderDaySegs(compileDaySegs(dayEvents));
renderSlotSegs(compileSlotSegs(slotEvents));
}
@ -375,19 +377,49 @@ function Agenda(element, options, methods) {
}
function compileDaySegs(events) {
var levels = stackSegs(view.sliceSegs(events, $.map(events, visEventEnd), view.visStart, view.visEnd)),
i, levelCnt=levels.length, level,
j, seg,
segs=[];
for (i=0; i<levelCnt; i++) {
level = levels[i];
for (j=0; j<level.length; j++) {
seg = level[j];
seg.row = 0;
seg.level = i;
segs.push(seg);
}
}
return segs;
}
function compileSlotSegs(events) {
var d = addMinutes(cloneDate(view.visStart), minMinute),
ends = $.map(events, visEventEnd),
levels,
segCols = [],
i=0;
for (; i<colCnt; i++) {
levels = stackSegs(view.sliceSegs(events, ends, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
countForwardSegs(levels);
segCols.push(levels);
visEventEnds = $.map(events, visEventEnd),
i, col,
j, level,
k, seg,
segs=[];
for (i=0; i<colCnt; i++) {
col = stackSegs(view.sliceSegs(events, visEventEnds, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
countForwardSegs(col);
for (j=0; j<col.length; j++) {
level = col[j];
for (k=0; k<level.length; k++) {
seg = level[k];
seg.col = i;
seg.level = j;
segs.push(seg);
}
}
addDays(d, 1, true);
}
return segCols;
return segs;
}
@ -395,10 +427,11 @@ function Agenda(element, options, methods) {
// renders 'all-day' events at the top
function renderDaySegs(segRow) {
function renderDaySegs(segs) {
if (options.allDaySlot) {
_renderDaySegs(
[segRow],
segs,
1,
view,
axisWidth,
viewWidth,
@ -422,32 +455,30 @@ function Agenda(element, options, methods) {
// renders events in the 'time slots' at the bottom
function renderSlotSegs(segCols) {
var event,
function renderSlotSegs(segs) {
var i, segCnt=segs.length, seg,
event,
className,
top,
bottom,
top, bottom,
colI, levelI, forward,
leftmost,
availWidth,
forward,
width,
outerWidth,
left,
eventTops=[],
eventLefts=[],
eventOuterWidths=[],
eventOuterHeights=[],
html='',
eventElements,
_eventElements,
eventElement,
triggerRes,
eventVSides=[],
eventHSides=[],
eventTitlePositions=[],
vsideCache={},
hsideCache={},
key, val,
titleSpan,
height;
// calculate desired position/dimensions, create html
eachLeaf(segCols, function(l, seg, segI, levelI, colI) {
// calculate position/dimensions, create html
for (i=0; i<segCnt; i++) {
seg = segs[i];
event = seg.event;
className = 'fc-event fc-event-vert ';
if (seg.isStart) {
@ -458,48 +489,51 @@ function Agenda(element, options, methods) {
}
top = timePosition(seg.start, seg.start);
bottom = timePosition(seg.start, seg.end);
colI = seg.col;
levelI = seg.level;
forward = seg.forward || 0;
leftmost = axisWidth + colContentPositions.left(colI*dis + dit);
availWidth = axisWidth + colContentPositions.right(colI*dis + dit) - leftmost;
availWidth = Math.min(availWidth-6, availWidth*.95); // TODO: move this to CSS
forward = seg.forward || 0;
if (levelI) {
// indented and thin
width = availWidth / (levelI + forward + 1);
outerWidth = availWidth / (levelI + forward + 1);
}else{
if (forward) {
// moderately wide, aligned left still
width = ((availWidth / (forward + 1)) - (12/2)) * 2; // 12 is the predicted width of resizer =
outerWidth = ((availWidth / (forward + 1)) - (12/2)) * 2; // 12 is the predicted width of resizer =
}else{
// can be entire width, aligned left
width = availWidth;
outerWidth = availWidth;
}
}
left = leftmost + // leftmost possible
(availWidth / (levelI + forward + 1) * levelI) // indentation
* dis + (rtl ? availWidth - width : 0); // rtl
eventTops[l] = top;
eventLefts[l] = left;
eventOuterWidths[l] = width;
eventOuterHeights[l] = bottom - top;
* dis + (rtl ? availWidth - outerWidth : 0); // rtl
seg.top = top;
seg.left = left;
seg.outerWidth = outerWidth;
seg.outerHeight = bottom - top;
html +=
"<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;top:" + top + "px;left:" + left + "px'>" +
"<a" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" +
"<span class='fc-event-bg'></span>" +
"<span class='fc-event-time'>" + htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'))) + "</span>" +
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
"<span class='fc-event-bg'/>" +
"</a>" +
((event.editable || event.editable == undefined && options.editable) && !options.disableResizing && $.fn.resizable ?
"<div class='ui-resizable-handle ui-resizable-s'>=</div>"
: '') +
"</div>";
});
slotSegmentContainer.html(html);
eventElements = slotSegmentContainer.children();
}
slotSegmentContainer[0].innerHTML = html;
_eventElements = $.makeArray(slotSegmentContainer[0].childNodes); // TODO: look at .children() again
// retrieve elements, run through eventRender callback, record outer-edge dimensions
eachLeaf(segCols, function(l, seg) {
// retrieve elements, run through eventRender callback, bind event handlers
for (i=0; i<segCnt; i++) {
seg = segs[i];
event = seg.event;
eventElement = eventElements.eq(l);
eventElement = $(_eventElements[i]);
triggerRes = view.trigger('eventRender', event, event, eventElement);
if (triggerRes === false) {
eventElement.remove();
@ -509,28 +543,40 @@ function Agenda(element, options, methods) {
eventElement = $(triggerRes)
.css({
position: 'absolute',
top: eventTops[l],
left: eventLefts[l]
top: seg.top,
left: seg.left
})
.appendTo(slotSegmentContainer);
}
seg.element = eventElement;
eventVSides[l] = vsides(eventElement, true);
eventHSides[l] = hsides(eventElement, true);
eventTitlePositions[l] = eventElement.find('span.fc-event-title').position();
bootstrapSlotEventHandlers(event, seg, eventElement);
view.reportEventElement(event, eventElement);
}
});
}
// record event sides and title positions
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
val = vsideCache[key = seg.key = cssKey(eventElement[0])];
seg.vsides = val == undefined ? (vsideCache[key] = vsides(eventElement[0], true)) : val;
val = hsideCache[key];
seg.hsides = val == undefined ? (hsideCache[key] = hsides(eventElement[0], true)) : val;
titleSpan = eventElement.find('span.fc-event-title');
if (titleSpan.length) {
seg.titleTop = titleSpan[0].offsetTop;
}
}
}
// set all positions/dimensions at once
eachLeaf(segCols, function(l, seg) {
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
eventElement
.width(eventOuterWidths[l] - eventHSides[l])
.height(height = eventOuterHeights[l] - eventVSides[l]);
eventElement[0].style.width = seg.outerWidth - seg.hsides + 'px';
eventElement[0].style.height = (height = seg.outerHeight - seg.vsides) + 'px';
event = seg.event;
if (eventTitlePositions[l] && height - eventTitlePositions[l].top < 10) {
if (seg.titleTop != undefined && height - seg.titleTop < 10) {
// not enough room for title, put it in the time header
eventElement.find('span.fc-event-time')
.text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title);
@ -539,7 +585,7 @@ function Agenda(element, options, methods) {
}
view.trigger('eventAfterRender', event, event, eventElement);
}
});
}
}
@ -874,7 +920,7 @@ function Agenda(element, options, methods) {
// get the Y coordinate of the given time on the given day (both Date objects)
function timePosition(day, time) { // both date object. day holds 00:00 of current day
function timePosition(day, time) { // both date objects. day holds 00:00 of current day
day = cloneDate(day, true);
if (time < addMinutes(cloneDate(day), minMinute)) {
return 0;
@ -885,15 +931,18 @@ function Agenda(element, options, methods) {
var slotMinutes = options.slotMinutes,
minutes = time.getHours()*60 + time.getMinutes() - minMinute,
slotI = Math.floor(minutes / slotMinutes),
td = body.find('tr:eq(' + slotI + ') td'),
innerDiv = td.find('div');
slotTop = slotTopCache[slotI];
if (slotTop == undefined) {
slotTop = slotTopCache[slotI] = body.find('tr:eq(' + slotI + ') td div')[0].offsetTop;
}
return Math.max(0, Math.round(
innerDiv.position().top + topCorrect(td) - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)
slotTop - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)
));
}
function day2col(dayOfWeek) {
return ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt)*dis+dit;
}

View File

@ -205,7 +205,7 @@ function Grid(element, options, methods) {
' fc-today '+tm+'-state-highlight' :
' fc-not-today') + "'>" +
(showNumbers ? "<div class='fc-day-number'>" + d.getDate() + "</div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div></td>";
"<div class='fc-day-content'><div style='position:relative'>&nbsp;</div></div></td>";
addDays(d, 1);
if (nwe) {
skipWeekend(d);
@ -216,7 +216,7 @@ function Grid(element, options, methods) {
tbody = $(s + "</tbody>").appendTo(table);
tbody.find('td').click(dayClick);
segmentContainer = $("<div/>").appendTo(element);
segmentContainer = $("<div/>").appendTo(element); // style='position:absolute;top:0;left:0' // made it a little slower for some reason
}else{ // NOT first time, reuse as many cells as possible
@ -236,7 +236,7 @@ function Grid(element, options, methods) {
tm + '-state-default fc-new fc-day' + (i*colCnt+j) +
(j==dit ? ' fc-leftmost' : '') + "'>" +
(showNumbers ? "<div class='fc-day-number'></div>" : '') +
"<div class='fc-day-content'><div>&nbsp;</div></div>" +
"<div class='fc-day-content'><div style='position:relative'>&nbsp;</div></div>" +
"</td>";
addDays(d, 1);
if (nwe) {
@ -385,31 +385,42 @@ function Grid(element, options, methods) {
function compileSegs(events) {
var d1 = cloneDate(view.visStart),
d2 = addDays(cloneDate(d1), colCnt),
rows = [],
i=0;
for (; i<rowCnt; i++) {
rows.push(stackSegs(view.sliceSegs(events, $.map(events, visEventEnd), d1, d2)));
visEventsEnds = $.map(events, visEventEnd),
i, row,
j, level,
k, seg,
segs=[];
for (i=0; i<rowCnt; i++) {
row = stackSegs(view.sliceSegs(events, visEventsEnds, d1, d2));
for (j=0; j<row.length; j++) {
level = row[j];
for (k=0; k<level.length; k++) {
seg = level[k];
seg.row = i;
seg.level = j;
segs.push(seg);
}
}
addDays(d1, 7);
addDays(d2, 7);
}
return rows;
return segs;
}
function renderSegs(segCols) {
function renderSegs(segs) {
_renderDaySegs(
segCols,
segs,
rowCnt,
view,
0,
viewWidth,
function(i) {
return tbody.find('tr:eq('+i+')');
},
function(i) { return tbody.find('tr:eq('+i+')') },
dayContentPositions.left,
dayContentPositions.right,
segmentContainer,
bootstrapEventHandlers
mouseoverBind
);
}
@ -426,11 +437,12 @@ function Grid(element, options, methods) {
function bootstrapEventHandlers(event, seg, eventElement) {
function mouseoverBind(event, seg, eventElement) {
function mouseover(ev) {
view.trigger('eventMouseover', this, event, ev);
eventElement.unbind('mouseover', mouseover);
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
view.trigger('eventMouseover', this, event, ev);
setTimeout(function() { // because IE will immediately trigger the new mouseover handlers
view.eventElementHandlers(event, eventElement);
if (event.editable || event.editable == undefined && options.editable) {
draggableEvent(event, eventElement);
@ -507,34 +519,28 @@ function Grid(element, options, methods) {
};
function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft, dayContentRight, segmentContainer, bootstrapEventHandlers) {
function _renderDaySegs(segs, rowCnt, view, minLeft, maxLeft, getRow, dayContentLeft, dayContentRight, segmentContainer, mouseoverBind) {
var options=view.options,
rtl=options.isRTL,
i, segCnt=segs.length, seg,
event,
className,
left,
right,
eventLefts=[],
eventRights=[],
left, right,
html='',
eventElements,
_eventElements,
eventElement,
triggerRes,
eventOuterHeights=[],
eventHSides=[],
l=0,
i=0, len=segRows.length, levels,
td,
innerDiv,
top,
rowContentHeight,
j, segs,
levelHeight,
k, seg;
hsideCache={},
vmarginCache={},
key, val,
rowI, top, levelI, levelHeight,
rowDivs=[],
rowDivTops=[];
// calculate desired position/dimensions, create html
eachLeaf(segRows, function(l, seg) {
for (i=0; i<segCnt; i++) {
seg = segs[i];
event = seg.event;
className = 'fc-event fc-event-hori ';
if (rtl) {
@ -556,8 +562,6 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : minLeft;
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : maxLeft;
}
eventLefts[l] = left;
eventRights[l] = right;
html +=
"<div class='" + className + event.className.join(' ') + "' style='position:absolute;z-index:8;left:"+left+"px'>" +
"<a" + (event.url ? " href='" + htmlEscape(event.url) + "'" : '') + ">" +
@ -569,14 +573,17 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
"</a>" +
"</div>";
});
segmentContainer.html(html);
eventElements = segmentContainer.children();
seg.left = left;
seg.outerWidth = right - left;
}
segmentContainer[0].innerHTML = html;
_eventElements = $.makeArray(segmentContainer[0].childNodes); // TODO: look at .children() again
// retrieve elements, run through eventRender callback, record outer-edge dimensions
eachLeaf(segRows, function(l, seg) {
// retrieve elements, run through eventRender callback, bind handlers
for (i=0; i<segCnt; i++) {
seg = segs[i];
eventElement = $(_eventElements[i]);
event = seg.event;
eventElement = eventElements.eq(l);
triggerRes = view.trigger('eventRender', event, event, eventElement);
if (triggerRes === false) {
eventElement.remove();
@ -586,54 +593,81 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
eventElement = $(triggerRes)
.css({
position: 'absolute',
left: eventLefts[l]
left: seg.left
})
.appendTo(segmentContainer);
}
seg.element = eventElement; // will be useful for future rerender optimizations
eventOuterHeights[l] = eventElement.outerHeight(true);
eventHSides[l] = hsides(eventElement, true);
bootstrapEventHandlers(event, seg, eventElement);
seg.element = eventElement;
mouseoverBind(event, seg, eventElement);
view.reportEventElement(event, eventElement);
}
});
}
// set all positions/dimensions at once
for (; i<len; i++) {
levels = segRows[i];
td = getTr(i).find('td:first');
innerDiv = td.find('div.fc-day-content div')
.css('position', 'relative')
.height(''); // this is needed for IE7 to get an accurate position
top = innerDiv.position().top + topCorrect(td);
rowContentHeight = 0;
for (j=0; j<levels.length; j++) {
segs = levels[j];
levelHeight = 0;
for (k=0; k<segs.length; k++) {
seg = segs[k];
if (eventElement = seg.element) {
eventElement.css('top', top);
//IE6 right-to-left sort-of-off-by-one bug
//if (rtl && rtlLeftDiff == undefined) {
// // bug in IE6 where offsets are miscalculated with direction:rtl
// rtlLeftDiff = eventLefts[l] - eventElement.position().left;
// if (rtlLeftDiff) {
// eventElement.css('left', eventLefts[l] + rtlLeftDiff);
// }
//}
eventElement.width(eventRights[l] - eventLefts[l] - eventHSides[l]);
event = seg.event;
view.trigger('eventAfterRender', event, event, eventElement);
levelHeight = Math.max(levelHeight, eventOuterHeights[l]);
}
l++;
}
rowContentHeight += levelHeight;
top += levelHeight;
// record event horizontal sides
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
val = hsideCache[key = seg.key = cssKey(eventElement[0])];
seg.hsides = val == undefined ? (hsideCache[key] = hsides(eventElement[0], true)) : val;
}
}
// set event widths
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
eventElement[0].style.width = seg.outerWidth - seg.hsides + 'px';
}
}
// record event heights
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
val = vmarginCache[key = seg.key];
seg.outerHeight = eventElement[0].offsetHeight + (
val == undefined ? (vmarginCache[key] = vmargins(eventElement[0])) : val
);
}
}
// set row heights, calculate event tops (in relation to row top)
for (i=0, rowI=0; rowI<rowCnt; rowI++) {
top = levelI = levelHeight = 0;
while (i<segCnt && (seg = segs[i]).row == rowI) {
if (seg.level != levelI) {
top += levelHeight;
levelHeight = 0;
levelI++;
}
levelHeight = Math.max(levelHeight, seg.outerHeight||0);
seg.top = top;
i++;
}
rowDivs[rowI] = getRow(rowI).find('td:first div.fc-day-content > div') // > is optimal???
.height(top + levelHeight);
}
// calculate row tops
for (rowI=0; rowI<rowCnt; rowI++) {
rowDivTops[rowI] = rowDivs[rowI][0].offsetTop;
}
// set event tops
for (i=0; i<segCnt; i++) {
seg = segs[i];
if (eventElement = seg.element) {
eventElement[0].style.top = rowDivTops[seg.row] + seg.top + 'px';
event = seg.event;
view.trigger('eventAfterRender', event, event, eventElement);
}
innerDiv.height(rowContentHeight);
}
}
function cssKey(_element) {
return _element.id + '/' + _element.className + '/' + _element.style.cssText.replace(/(^|;)\s*(top|left|width|height)\s*:[^;]*/ig, '');
}

View File

@ -219,7 +219,7 @@ $.fn.fullCalendar = function(options) {
contentWidth = content.width();
contentHeight = calculateContentHeight();
}
if (inc || !view.date || date < view.visStart || date >= view.visEnd) { // !view.date means it hasn't been rendered yet
if (inc || !view.date || date < view.start || date >= view.end) { // !view.date means it hasn't been rendered yet
fixContentSize();
view.render(date, inc || 0, contentWidth, contentHeight, function(callback) {
// dont refetch if new view contains the same events (or a subset)
@ -307,7 +307,7 @@ $.fn.fullCalendar = function(options) {
return options.contentHeight;
}
else if (options.height) {
return options.height - (header ? header.height() : 0) - vsides(content);
return options.height - (header ? header.height() : 0) - vsides(content[0]);
}
return Math.round(contentWidth / Math.max(options.aspectRatio, .5));
}

View File

@ -298,37 +298,42 @@ var dateFormatters = {
-----------------------------------------------------------------------------*/
function setOuterWidth(element, width, includeMargins) {
element.each(function() {
var e = $(this);
e.width(width - hsides(e, includeMargins));
element.each(function(i, _element) {
_element.style.width = width - hsides(_element, includeMargins) + 'px';
});
}
function hsides(e, includeMargins) {
return (parseInt(e.css('border-left-width')) || 0) +
(parseInt(e.css('padding-left')) || 0) +
(parseInt(e.css('padding-right')) || 0) +
(parseInt(e.css('border-right-width')) || 0) +
(includeMargins ?
(parseInt(e.css('margin-left')) || 0) + (parseInt(e.css('margin-right')) || 0)
: 0);
}
function setOuterHeight(element, height, includeMargins) {
element.each(function() {
var e = $(this);
e.height(height - vsides(e, includeMargins));
element.each(function(i, _element) {
_element.style.height = height - vsides(_element, includeMargins) + 'px';
});
}
function vsides(e, includeMargins) {
return (parseInt(e.css('border-top-width')) || 0) +
(parseInt(e.css('padding-top')) || 0) +
(parseInt(e.css('padding-bottom')) || 0) +
(parseInt(e.css('border-bottom-width')) || 0) +
(includeMargins ?
(parseInt(e.css('margin-top')) || 0) + (parseInt(e.css('margin-bottom')) || 0)
: 0);
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);
}
@ -455,18 +460,6 @@ function htmlEscape(s) {
.replace(/"/g, '&quot;')
}
function eachLeaf(node, callback, leafIndex, indexTrail) {
if (node.pop == arrayPop) { // is an array?
for (var i=0, len=node.length; i<len; i++) {
leafIndex = eachLeaf(node[i], callback, leafIndex||0, [i].concat(indexTrail||[]));
}
return leafIndex;
}
callback.apply(node, [leafIndex, node].concat(indexTrail));
return leafIndex + 1;
}
function HorizontalPositionCache(getElement) {
@ -501,4 +494,3 @@ function HorizontalPositionCache(getElement) {

View File

@ -105,7 +105,7 @@ var viewMethods = {
var elements = this.eventElementsByID[event._id],
i, len = elements.length;
for (i=0; i<len; i++) {
if (elements[i] != exceptElement) {
if (elements[i][0] != exceptElement[0]) { // AHAHAHAHAHAHAHAH
elements[i][funcName]();
}
}

View File

@ -9,15 +9,15 @@
$(document).ready(function() {
$('#calendar').fullCalendar({
year: 2009,
month: 11,
year: 2010,
month: 0,
header: {
left: 'prev,next today',
center: 'title',
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
},
editable: true,
events: 'many_events_json.txt'
events: "many_events_json.txt"
});
});

File diff suppressed because one or more lines are too long

View File

@ -50,14 +50,13 @@
return false;
}
else if (event.id == 777) {
return $("<div style='background:green'/>").text(event.title);
return $("<div style='background:green'>").text(event.title);
}
else if (event.id == 999) {
element.css('border-color', 'red');
//console.log('renderEvent (' + event.title + ') - ' + view.title);
}
},
eventAfterRender: function(event, element, view) {
//console.log('after render for "' + event.title + '":');
//console.log(element);
@ -99,9 +98,9 @@
console.log(dayDelta + ' days');
console.log(minuteDelta + ' minutes');
console.log('allday: ' + allDay);
/*setTimeout(function() {
revertFunc();
}, 2000);*/
//setTimeout(function() {
// revertFunc();
//}, 2000);
//console.log(jsEvent);
//console.log(ui);
//console.log(view.title);
@ -120,9 +119,9 @@
console.log('RESIZE!! ' + event.title);
console.log(dayDelta + ' days');
console.log(minuteDelta + ' minutes');
/*setTimeout(function() {
revertFunc();
}, 2000);*/
//setTimeout(function() {
// revertFunc();
//}, 2000);
//console.log(jsEvent);
//console.log(ui);
//console.log(view.title);

View File

@ -1 +1 @@
1.4.3
1.4.4