merged speedups, fixed resulting eventRender and eventMouseover bugs

This commit is contained in:
Adam Shaw 2010-01-26 23:58:43 -08:00
parent 7158fc3470
commit 87f4ace780
5 changed files with 92 additions and 93 deletions

View file

@ -81,9 +81,7 @@ function Agenda(element, options, methods) {
viewWidth, viewHeight, viewWidth, viewHeight,
cachedEvents=[], cachedEvents=[],
daySegmentContainer, daySegmentContainer,
daySegments=[],
slotSegmentContainer, slotSegmentContainer,
slotSegments=[],
tm, firstDay, tm, firstDay,
nwe, // no weekends (int) nwe, // no weekends (int)
rtl, dis, dit, // day index sign / translate rtl, dis, dit, // day index sign / translate
@ -359,8 +357,8 @@ function Agenda(element, options, methods) {
slotEvents.push(events[i]); slotEvents.push(events[i]);
} }
} }
renderDaySegs(daySegments = stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd))); renderDaySegs(stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd)));
renderSlotSegs(slotSegments = compileSlotSegs(slotEvents)); renderSlotSegs(compileSlotSegs(slotEvents));
} }
@ -371,9 +369,9 @@ function Agenda(element, options, methods) {
function clearEvents() { function clearEvents() {
view._clearEvents(); // only clears the hashes
daySegmentContainer.empty(); daySegmentContainer.empty();
slotSegmentContainer.empty(); slotSegmentContainer.empty();
view._clearEvents(); // only clears the hashes
} }
@ -445,7 +443,7 @@ function Agenda(element, options, methods) {
triggerRes, triggerRes,
eventVSides=[], eventVSides=[],
eventHSides=[], eventHSides=[],
eventTitleTops=[], eventTitlePositions=[],
height; height;
// calculate desired position/dimensions, create html // calculate desired position/dimensions, create html
@ -510,6 +508,7 @@ function Agenda(element, options, methods) {
eventElement.remove(); eventElement.remove();
eventElement = $(triggerRes) eventElement = $(triggerRes)
.css({ .css({
position: 'absolute',
top: eventTops[l], top: eventTops[l],
left: eventLefts[l] left: eventLefts[l]
}) })
@ -518,7 +517,7 @@ function Agenda(element, options, methods) {
seg.element = eventElement; seg.element = eventElement;
eventVSides[l] = vsides(eventElement, true); eventVSides[l] = vsides(eventElement, true);
eventHSides[l] = hsides(eventElement, true); eventHSides[l] = hsides(eventElement, true);
eventTitleTops[l] = eventElement.find('span.fc-event-title').position().top; eventTitlePositions[l] = eventElement.find('span.fc-event-title').position();
bootstrapSlotEventHandlers(event, seg, eventElement); bootstrapSlotEventHandlers(event, seg, eventElement);
view.reportEventElement(event, eventElement); view.reportEventElement(event, eventElement);
} }
@ -531,7 +530,7 @@ function Agenda(element, options, methods) {
.width(eventOuterWidths[l] - eventHSides[l]) .width(eventOuterWidths[l] - eventHSides[l])
.height(height = eventOuterHeights[l] - eventVSides[l]); .height(height = eventOuterHeights[l] - eventVSides[l]);
event = seg.event; event = seg.event;
if (height - eventTitleTops[l] < 10) { if (eventTitlePositions[l] && height - eventTitlePositions[l].top < 10) {
// not enough room for title, put it in the time header // not enough room for title, put it in the time header
eventElement.find('span.fc-event-time') eventElement.find('span.fc-event-time')
.text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title); .text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title);
@ -567,9 +566,10 @@ function Agenda(element, options, methods) {
function bootstrapDayEventHandlers(event, seg, eventElement) { function bootstrapDayEventHandlers(event, seg, eventElement) {
var attached = false; function mouseover(ev) {
eventElement.mouseover(function(ev) { view.trigger('eventMouseover', this, event, ev);
if (!attached) { eventElement.unbind('mouseover', mouseover);
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
view.eventElementHandlers(event, eventElement); view.eventElementHandlers(event, eventElement);
if (event.editable || event.editable == undefined && options.editable) { if (event.editable || event.editable == undefined && options.editable) {
draggableDayEvent(event, eventElement, seg.isStart); draggableDayEvent(event, eventElement, seg.isStart);
@ -577,18 +577,18 @@ function Agenda(element, options, methods) {
view.resizableDayEvent(event, eventElement, colWidth); view.resizableDayEvent(event, eventElement, colWidth);
} }
} }
attached = true; },0);
view.trigger('eventMouseover', this, event, ev); }
} eventElement.mouseover(mouseover);
});
} }
function bootstrapSlotEventHandlers(event, seg, eventElement) { function bootstrapSlotEventHandlers(event, seg, eventElement) {
var attached = false; function mouseover(ev) {
eventElement.mouseover(function(ev) { view.trigger('eventMouseover', this, event, ev);
if (!attached) { eventElement.unbind('mouseover', mouseover);
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
view.eventElementHandlers(event, eventElement); view.eventElementHandlers(event, eventElement);
if (event.editable || event.editable == undefined && options.editable) { if (event.editable || event.editable == undefined && options.editable) {
var timeElement = eventElement.find('span.fc-event-time'); var timeElement = eventElement.find('span.fc-event-time');
@ -597,10 +597,9 @@ function Agenda(element, options, methods) {
resizableSlotEvent(event, eventElement, timeElement); resizableSlotEvent(event, eventElement, timeElement);
} }
} }
attached = true; },0);
view.trigger('eventMouseover', this, event, ev); }
} eventElement.mouseover(mouseover);
});
} }
@ -824,47 +823,46 @@ function Agenda(element, options, methods) {
function resizableSlotEvent(event, eventElement, timeElement) { function resizableSlotEvent(event, eventElement, timeElement) {
if (!options.disableResizing && eventElement.resizable) { if (!options.disableResizing && eventElement.resizable) {
var slotDelta, prevSlotDelta; var slotDelta, prevSlotDelta;
eventElement eventElement.resizable({
.resizable({ handles: {
handles: { s: 'div.ui-resizable-s'
s: 'div.ui-resizable-s' },
}, grid: slotHeight,
grid: slotHeight, start: function(ev, ui) {
start: function(ev, ui) { slotDelta = prevSlotDelta = 0;
slotDelta = prevSlotDelta = 0; view.hideEvents(event, eventElement);
view.hideEvents(event, eventElement); if ($.browser.msie && $.browser.version == '6.0') {
if ($.browser.msie && $.browser.version == '6.0') { eventElement.css('overflow', 'hidden');
eventElement.css('overflow', 'hidden');
}
eventElement.css('z-index', 9);
view.trigger('eventResizeStart', this, event, ev, ui);
},
resize: function(ev, ui) {
// don't rely on ui.size.height, doesn't take grid into account
slotDelta = Math.round((Math.max(slotHeight, eventElement.height()) - ui.originalSize.height) / slotHeight);
if (slotDelta != prevSlotDelta) {
timeElement.text(
formatDates(
event.start,
(!slotDelta && !event.end) ? null : // no change, so don't display time range
addMinutes(view.eventEnd(event), options.slotMinutes*slotDelta),
view.option('timeFormat')
)
);
prevSlotDelta = slotDelta;
}
},
stop: function(ev, ui) {
view.trigger('eventResizeStop', this, event, ev, ui);
if (slotDelta) {
view.eventResize(this, event, 0, options.slotMinutes*slotDelta, ev, ui);
}else{
eventElement.css('z-index', 8);
view.showEvents(event, eventElement);
// BUG: if event was really short, need to put title back in span
}
} }
}); eventElement.css('z-index', 9);
view.trigger('eventResizeStart', this, event, ev, ui);
},
resize: function(ev, ui) {
// don't rely on ui.size.height, doesn't take grid into account
slotDelta = Math.round((Math.max(slotHeight, eventElement.height()) - ui.originalSize.height) / slotHeight);
if (slotDelta != prevSlotDelta) {
timeElement.text(
formatDates(
event.start,
(!slotDelta && !event.end) ? null : // no change, so don't display time range
addMinutes(view.eventEnd(event), options.slotMinutes*slotDelta),
view.option('timeFormat')
)
);
prevSlotDelta = slotDelta;
}
},
stop: function(ev, ui) {
view.trigger('eventResizeStop', this, event, ev, ui);
if (slotDelta) {
view.eventResize(this, event, 0, options.slotMinutes*slotDelta, ev, ui);
}else{
eventElement.css('z-index', 8);
view.showEvents(event, eventElement);
// BUG: if event was really short, need to put title back in span
}
}
});
} }
} }
@ -887,8 +885,7 @@ function Agenda(element, options, methods) {
var slotMinutes = options.slotMinutes, var slotMinutes = options.slotMinutes,
minutes = time.getHours()*60 + time.getMinutes() - minMinute, minutes = time.getHours()*60 + time.getMinutes() - minMinute,
slotI = Math.floor(minutes / slotMinutes), slotI = Math.floor(minutes / slotMinutes),
tr = body.find('tr:eq(' + slotI + ')'), td = body.find('tr:eq(' + slotI + ') td'),
td = tr.find('td'),
innerDiv = td.find('div'); innerDiv = td.find('div');
return Math.max(0, Math.round( return Math.max(0, Math.round(
innerDiv.position().top + topCorrect(td) - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes) innerDiv.position().top + topCorrect(td) - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)

View file

@ -123,7 +123,6 @@ function Grid(element, options, methods) {
colWidth, colWidth,
thead, tbody, thead, tbody,
cachedEvents=[], cachedEvents=[],
segments=[],
segmentContainer, segmentContainer,
dayContentPositions = new HorizontalPositionCache(function(dayOfWeek) { dayContentPositions = new HorizontalPositionCache(function(dayOfWeek) {
return tbody.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div') return tbody.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div')
@ -367,13 +366,13 @@ function Grid(element, options, methods) {
function renderEvents(events) { function renderEvents(events) {
view.reportEvents(cachedEvents = events); view.reportEvents(cachedEvents = events);
renderSegs(segments = compileSegs(events)); renderSegs(compileSegs(events));
} }
function rerenderEvents() { function rerenderEvents() {
clearEvents(); clearEvents();
renderSegs(segments = compileSegs(cachedEvents)); renderSegs(compileSegs(cachedEvents));
} }
@ -428,9 +427,10 @@ function Grid(element, options, methods) {
function bootstrapEventHandlers(event, seg, eventElement) { function bootstrapEventHandlers(event, seg, eventElement) {
var attached = false; function mouseover(ev) {
eventElement.mouseover(function(ev) { view.trigger('eventMouseover', this, event, ev);
if (!attached) { eventElement.unbind('mouseover', mouseover);
setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover
view.eventElementHandlers(event, eventElement); view.eventElementHandlers(event, eventElement);
if (event.editable || event.editable == undefined && options.editable) { if (event.editable || event.editable == undefined && options.editable) {
draggableEvent(event, eventElement); draggableEvent(event, eventElement);
@ -438,10 +438,9 @@ function Grid(element, options, methods) {
view.resizableDayEvent(event, eventElement, colWidth); view.resizableDayEvent(event, eventElement, colWidth);
} }
} }
attached = true; },0);
view.trigger('eventMouseover', this, event, ev); // TODO: make sure this isn't being fired twice }
} eventElement.mouseover(mouseover);
});
} }
@ -526,12 +525,12 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
eventHSides=[], eventHSides=[],
l=0, l=0,
i=0, len=segRows.length, levels, i=0, len=segRows.length, levels,
tr,
td, td,
innerDiv, innerDiv,
top, top,
rowContentHeight, rowContentHeight,
j, segs, j, segs,
levelHeight,
k, seg; k, seg;
// calculate desired position/dimensions, create html // calculate desired position/dimensions, create html
@ -585,10 +584,13 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
if (triggerRes && triggerRes !== true) { if (triggerRes && triggerRes !== true) {
eventElement.remove(); eventElement.remove();
eventElement = $(triggerRes) eventElement = $(triggerRes)
.css('left', eventLefts[l]) .css({
position: 'absolute',
left: eventLefts[l]
})
.appendTo(segmentContainer); .appendTo(segmentContainer);
} }
seg.element = eventElement; seg.element = eventElement; // will be useful for future rerender optimizations
eventOuterHeights[l] = eventElement.outerHeight(true); eventOuterHeights[l] = eventElement.outerHeight(true);
eventHSides[l] = hsides(eventElement, true); eventHSides[l] = hsides(eventElement, true);
bootstrapEventHandlers(event, seg, eventElement); bootstrapEventHandlers(event, seg, eventElement);
@ -599,8 +601,7 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
// set all positions/dimensions at once // set all positions/dimensions at once
for (; i<len; i++) { for (; i<len; i++) {
levels = segRows[i]; levels = segRows[i];
tr = getTr(i); td = getTr(i).find('td:first');
td = tr.find('td:first');
innerDiv = td.find('div.fc-day-content div') innerDiv = td.find('div.fc-day-content div')
.css('position', 'relative') .css('position', 'relative')
.height(''); // this is needed for IE7 to get an accurate position .height(''); // this is needed for IE7 to get an accurate position
@ -613,6 +614,7 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft,
seg = segs[k]; seg = segs[k];
if (eventElement = seg.element) { if (eventElement = seg.element) {
eventElement.css('top', top); eventElement.css('top', top);
//IE6 right-to-left sort-of-off-by-one bug
//if (rtl && rtlLeftDiff == undefined) { //if (rtl && rtlLeftDiff == undefined) {
// // bug in IE6 where offsets are miscalculated with direction:rtl // // bug in IE6 where offsets are miscalculated with direction:rtl
// rtlLeftDiff = eventLefts[l] - eventElement.position().left; // rtlLeftDiff = eventLefts[l] - eventElement.position().left;

View file

@ -219,7 +219,7 @@ $.fn.fullCalendar = function(options) {
contentWidth = content.width(); contentWidth = content.width();
contentHeight = calculateContentHeight(); 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.visStart || date >= view.visEnd) { // !view.date means it hasn't been rendered yet
fixContentSize(); fixContentSize();
view.render(date, inc || 0, contentWidth, contentHeight, function(callback) { view.render(date, inc || 0, contentWidth, contentHeight, function(callback) {
// dont refetch if new view contains the same events (or a subset) // dont refetch if new view contains the same events (or a subset)
@ -239,7 +239,7 @@ $.fn.fullCalendar = function(options) {
else if (view.eventsDirty) { else if (view.eventsDirty) {
// ensure events are rerendered if another view messed with them // ensure events are rerendered if another view messed with them
// pass in 'events' b/c event might have been added/removed // pass in 'events' b/c event might have been added/removed
// executed on a switchView // executed on a changeView
// TODO: should this be inclusive with sizeDirty and forceUpdateSize?? // TODO: should this be inclusive with sizeDirty and forceUpdateSize??
view.clearEvents(); view.clearEvents();
view.renderEvents(events); view.renderEvents(events);
@ -307,7 +307,7 @@ $.fn.fullCalendar = function(options) {
return options.contentHeight; return options.contentHeight;
} }
else if (options.height) { else if (options.height) {
return options.height - (header ? header.height() : 0) - horizontalSides(content); // TODO: shouldn't this be vertical sides?? return options.height - (header ? header.height() : 0) - vsides(content);
} }
return Math.round(contentWidth / Math.max(options.aspectRatio, .5)); return Math.round(contentWidth / Math.max(options.aspectRatio, .5));
} }
@ -371,7 +371,7 @@ $.fn.fullCalendar = function(options) {
url: src, url: src,
dataType: 'json', dataType: 'json',
data: params, data: params,
cache: options.cacheEvents || options.cacheParam || false, // don't let jquery prevent caching if cacheParam is being used cache: options.cacheParam || false, // don't let jquery prevent caching if cacheParam is being used
success: reportEventsAndPop success: reportEventsAndPop
}); });
} }
@ -782,7 +782,7 @@ $.fn.fullCalendar = function(options) {
} }
} }
}; };
//$(window).resize(windowResize); $(window).resize(windowResize);
// let's begin... // let's begin...

View file

@ -4,8 +4,7 @@
var DAY_MS = 86400000, var DAY_MS = 86400000,
HOUR_MS = 3600000, HOUR_MS = 3600000,
MINUTE_MS = 60000, MINUTE_MS = 60000;
arrayPop = Array.prototype.pop; // for eachLeaf
function addYears(d, n, keepTime) { function addYears(d, n, keepTime) {
d.setFullYear(d.getFullYear() + n); d.setFullYear(d.getFullYear() + n);
@ -425,7 +424,8 @@ function HoverMatrix(changeCallback) {
-----------------------------------------------------------------------------*/ -----------------------------------------------------------------------------*/
var undefined, var undefined,
dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat']; dayIDs = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'],
arrayPop = Array.prototype.pop;
function zeroPad(n) { function zeroPad(n) {
return (n < 10 ? '0' : '') + n; return (n < 10 ? '0' : '') + n;

View file

@ -74,15 +74,15 @@
/* /*
eventMouseover: function(event, jsEvent, view) { eventMouseover: function(event, jsEvent, view) {
console.log('MOUSEOVER ' + event.title); console.log('MOUSEOVER ' + event.title);
console.log(jsEvent); //console.log(jsEvent);
console.log(view); //console.log(view);
console.log(this); //console.log(this);
}, },
eventMouseout: function(event, jsEvent, view) { eventMouseout: function(event, jsEvent, view) {
console.log('MOUSEOUT ' + event.title); console.log('MOUSEOUT ' + event.title);
console.log(jsEvent); //console.log(jsEvent);
console.log(view); //console.log(view);
console.log(this); //console.log(this);
}, },
*/ */