From 87f4ace7806555c4cb7183445f792f9654ec8f5d Mon Sep 17 00:00:00 2001 From: Adam Shaw Date: Tue, 26 Jan 2010 23:58:43 -0800 Subject: [PATCH] merged speedups, fixed resulting eventRender and eventMouseover bugs --- src/agenda.js | 125 +++++++++++++++++++++----------------------- src/grid.js | 32 ++++++------ src/main.js | 10 ++-- src/util.js | 6 +-- tests/triggers.html | 12 ++--- 5 files changed, 92 insertions(+), 93 deletions(-) diff --git a/src/agenda.js b/src/agenda.js index 6a4986c..85eb95a 100644 --- a/src/agenda.js +++ b/src/agenda.js @@ -81,9 +81,7 @@ function Agenda(element, options, methods) { viewWidth, viewHeight, cachedEvents=[], daySegmentContainer, - daySegments=[], slotSegmentContainer, - slotSegments=[], tm, firstDay, nwe, // no weekends (int) rtl, dis, dit, // day index sign / translate @@ -359,8 +357,8 @@ function Agenda(element, options, methods) { slotEvents.push(events[i]); } } - renderDaySegs(daySegments = stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd))); - renderSlotSegs(slotSegments = compileSlotSegs(slotEvents)); + renderDaySegs(stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd))); + renderSlotSegs(compileSlotSegs(slotEvents)); } @@ -371,9 +369,9 @@ function Agenda(element, options, methods) { function clearEvents() { + view._clearEvents(); // only clears the hashes daySegmentContainer.empty(); slotSegmentContainer.empty(); - view._clearEvents(); // only clears the hashes } @@ -445,7 +443,7 @@ function Agenda(element, options, methods) { triggerRes, eventVSides=[], eventHSides=[], - eventTitleTops=[], + eventTitlePositions=[], height; // calculate desired position/dimensions, create html @@ -510,6 +508,7 @@ function Agenda(element, options, methods) { eventElement.remove(); eventElement = $(triggerRes) .css({ + position: 'absolute', top: eventTops[l], left: eventLefts[l] }) @@ -518,7 +517,7 @@ function Agenda(element, options, methods) { seg.element = eventElement; eventVSides[l] = vsides(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); view.reportEventElement(event, eventElement); } @@ -531,7 +530,7 @@ function Agenda(element, options, methods) { .width(eventOuterWidths[l] - eventHSides[l]) .height(height = eventOuterHeights[l] - eventVSides[l]); 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 eventElement.find('span.fc-event-time') .text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title); @@ -567,9 +566,10 @@ function Agenda(element, options, methods) { function bootstrapDayEventHandlers(event, seg, eventElement) { - var attached = false; - eventElement.mouseover(function(ev) { - if (!attached) { + function mouseover(ev) { + view.trigger('eventMouseover', this, event, ev); + eventElement.unbind('mouseover', mouseover); + setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover view.eventElementHandlers(event, eventElement); if (event.editable || event.editable == undefined && options.editable) { draggableDayEvent(event, eventElement, seg.isStart); @@ -577,18 +577,18 @@ function Agenda(element, options, methods) { view.resizableDayEvent(event, eventElement, colWidth); } } - attached = true; - view.trigger('eventMouseover', this, event, ev); - } - }); + },0); + } + eventElement.mouseover(mouseover); } function bootstrapSlotEventHandlers(event, seg, eventElement) { - var attached = false; - eventElement.mouseover(function(ev) { - if (!attached) { + function mouseover(ev) { + view.trigger('eventMouseover', this, event, ev); + eventElement.unbind('mouseover', mouseover); + setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover view.eventElementHandlers(event, eventElement); if (event.editable || event.editable == undefined && options.editable) { var timeElement = eventElement.find('span.fc-event-time'); @@ -597,10 +597,9 @@ function Agenda(element, options, methods) { resizableSlotEvent(event, eventElement, timeElement); } } - attached = true; - view.trigger('eventMouseover', this, event, ev); - } - }); + },0); + } + eventElement.mouseover(mouseover); } @@ -824,47 +823,46 @@ function Agenda(element, options, methods) { function resizableSlotEvent(event, eventElement, timeElement) { if (!options.disableResizing && eventElement.resizable) { var slotDelta, prevSlotDelta; - eventElement - .resizable({ - handles: { - s: 'div.ui-resizable-s' - }, - grid: slotHeight, - start: function(ev, ui) { - slotDelta = prevSlotDelta = 0; - view.hideEvents(event, eventElement); - if ($.browser.msie && $.browser.version == '6.0') { - 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.resizable({ + handles: { + s: 'div.ui-resizable-s' + }, + grid: slotHeight, + start: function(ev, ui) { + slotDelta = prevSlotDelta = 0; + view.hideEvents(event, eventElement); + if ($.browser.msie && $.browser.version == '6.0') { + 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 + } + } + }); } } @@ -887,8 +885,7 @@ function Agenda(element, options, methods) { var slotMinutes = options.slotMinutes, minutes = time.getHours()*60 + time.getMinutes() - minMinute, slotI = Math.floor(minutes / slotMinutes), - tr = body.find('tr:eq(' + slotI + ')'), - td = tr.find('td'), + td = body.find('tr:eq(' + slotI + ') td'), innerDiv = td.find('div'); return Math.max(0, Math.round( innerDiv.position().top + topCorrect(td) - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes) diff --git a/src/grid.js b/src/grid.js index f5edf15..20a8f9e 100644 --- a/src/grid.js +++ b/src/grid.js @@ -123,7 +123,6 @@ function Grid(element, options, methods) { colWidth, thead, tbody, cachedEvents=[], - segments=[], segmentContainer, dayContentPositions = new HorizontalPositionCache(function(dayOfWeek) { 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) { view.reportEvents(cachedEvents = events); - renderSegs(segments = compileSegs(events)); + renderSegs(compileSegs(events)); } function rerenderEvents() { clearEvents(); - renderSegs(segments = compileSegs(cachedEvents)); + renderSegs(compileSegs(cachedEvents)); } @@ -428,9 +427,10 @@ function Grid(element, options, methods) { function bootstrapEventHandlers(event, seg, eventElement) { - var attached = false; - eventElement.mouseover(function(ev) { - if (!attached) { + function mouseover(ev) { + view.trigger('eventMouseover', this, event, ev); + eventElement.unbind('mouseover', mouseover); + setTimeout(function() { // because IE will immediately trigger eventElementHandlers's mouseover view.eventElementHandlers(event, eventElement); if (event.editable || event.editable == undefined && options.editable) { draggableEvent(event, eventElement); @@ -438,10 +438,9 @@ function Grid(element, options, methods) { view.resizableDayEvent(event, eventElement, colWidth); } } - attached = true; - view.trigger('eventMouseover', this, event, ev); // TODO: make sure this isn't being fired twice - } - }); + },0); + } + eventElement.mouseover(mouseover); } @@ -526,12 +525,12 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft, eventHSides=[], l=0, i=0, len=segRows.length, levels, - tr, td, innerDiv, top, rowContentHeight, j, segs, + levelHeight, k, seg; // calculate desired position/dimensions, create html @@ -585,10 +584,13 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft, if (triggerRes && triggerRes !== true) { eventElement.remove(); eventElement = $(triggerRes) - .css('left', eventLefts[l]) + .css({ + position: 'absolute', + left: eventLefts[l] + }) .appendTo(segmentContainer); } - seg.element = eventElement; + seg.element = eventElement; // will be useful for future rerender optimizations eventOuterHeights[l] = eventElement.outerHeight(true); eventHSides[l] = hsides(eventElement, true); bootstrapEventHandlers(event, seg, eventElement); @@ -599,8 +601,7 @@ function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft, // set all positions/dimensions at once for (; i 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(); view.render(date, inc || 0, contentWidth, contentHeight, function(callback) { // dont refetch if new view contains the same events (or a subset) @@ -239,7 +239,7 @@ $.fn.fullCalendar = function(options) { else if (view.eventsDirty) { // ensure events are rerendered if another view messed with them // 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?? view.clearEvents(); view.renderEvents(events); @@ -307,7 +307,7 @@ $.fn.fullCalendar = function(options) { return options.contentHeight; } 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)); } @@ -371,7 +371,7 @@ $.fn.fullCalendar = function(options) { url: src, dataType: 'json', 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 }); } @@ -782,7 +782,7 @@ $.fn.fullCalendar = function(options) { } } }; - //$(window).resize(windowResize); + $(window).resize(windowResize); // let's begin... diff --git a/src/util.js b/src/util.js index 55f3765..f075e59 100644 --- a/src/util.js +++ b/src/util.js @@ -4,8 +4,7 @@ var DAY_MS = 86400000, HOUR_MS = 3600000, - MINUTE_MS = 60000, - arrayPop = Array.prototype.pop; // for eachLeaf + MINUTE_MS = 60000; function addYears(d, n, keepTime) { d.setFullYear(d.getFullYear() + n); @@ -425,7 +424,8 @@ function HoverMatrix(changeCallback) { -----------------------------------------------------------------------------*/ 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) { return (n < 10 ? '0' : '') + n; diff --git a/tests/triggers.html b/tests/triggers.html index 6756911..ebec504 100644 --- a/tests/triggers.html +++ b/tests/triggers.html @@ -74,15 +74,15 @@ /* eventMouseover: function(event, jsEvent, view) { console.log('MOUSEOVER ' + event.title); - console.log(jsEvent); - console.log(view); - console.log(this); + //console.log(jsEvent); + //console.log(view); + //console.log(this); }, eventMouseout: function(event, jsEvent, view) { console.log('MOUSEOUT ' + event.title); - console.log(jsEvent); - console.log(view); - console.log(this); + //console.log(jsEvent); + //console.log(view); + //console.log(this); }, */