event rendering optimizations for agenda view w/ refactoring
This commit is contained in:
parent
f19e54488c
commit
a00104b10b
4 changed files with 411 additions and 685 deletions
582
src/agenda.js
582
src/agenda.js
|
@ -88,15 +88,16 @@ function Agenda(element, options, methods) {
|
|||
nwe, // no weekends (int)
|
||||
rtl, dis, dit, // day index sign / translate
|
||||
minMinute, maxMinute,
|
||||
dayContentElements=[],
|
||||
dayContentLefts=[],
|
||||
dayContentRights=[],
|
||||
colContentPositions = new HorizontalPositionCache(function(col) {
|
||||
return bg.find('td:eq(' + col + ') div div');
|
||||
}),
|
||||
// ...
|
||||
|
||||
view = $.extend(this, viewMethods, methods, {
|
||||
renderAgenda: renderAgenda,
|
||||
renderEvents: renderEvents,
|
||||
rerenderEvents: rerenderEvents,
|
||||
clearEvents: clearEvents,
|
||||
updateSize: updateSize,
|
||||
shown: resetScroll,
|
||||
defaultEventEnd: function(event) {
|
||||
|
@ -287,19 +288,16 @@ function Agenda(element, options, methods) {
|
|||
function updateSize(width, height) {
|
||||
viewWidth = width;
|
||||
viewHeight = height;
|
||||
dayContentLefts = [];
|
||||
dayContentRights = [];
|
||||
colContentPositions.clear();
|
||||
|
||||
bodyTable.width('');
|
||||
body.width(width);
|
||||
body.height(height - head.height());
|
||||
|
||||
// need this for IE6/7. triggers clientWidth to be calculated for
|
||||
// later user in this function. this is ridiculous
|
||||
body[0].clientWidth;
|
||||
bodyTable.width('');
|
||||
|
||||
var topTDs = head.find('tr:first th'),
|
||||
stripeTDs = bg.find('td'),
|
||||
contentWidth = body[0].clientWidth;
|
||||
contentWidth = slotSegmentContainer.width(); // body[0].clientWidth isn't reliable here in IE6
|
||||
|
||||
bodyTable.width(contentWidth);
|
||||
|
||||
// time-axis width
|
||||
|
@ -327,10 +325,6 @@ function Agenda(element, options, methods) {
|
|||
});
|
||||
|
||||
slotHeight = body.find('tr:first div').height() + 1;
|
||||
|
||||
// TODO:
|
||||
//reportTBody(bodyTable.find('tbody'));
|
||||
// Opera 9.25 doesn't detect the bug when called from agenda
|
||||
}
|
||||
|
||||
function slotClick(ev) {
|
||||
|
@ -402,397 +396,153 @@ function Agenda(element, options, methods) {
|
|||
|
||||
|
||||
|
||||
|
||||
/* cell/cell-content positioning calculating/caching
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
// DERIVED FROM grid.js
|
||||
|
||||
function dayContentElement(dayOfWeek) {
|
||||
if (dayContentElements[dayOfWeek] == undefined) {
|
||||
dayContentElements[dayOfWeek] = bg.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div');
|
||||
}
|
||||
return dayContentElements[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
function dayContentLeft(dayOfWeek) {
|
||||
if (dayContentLefts[dayOfWeek] == undefined) {
|
||||
dayContentLefts[dayOfWeek] = dayContentElement(dayOfWeek).position().left + axisWidth;
|
||||
}
|
||||
return dayContentLefts[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
function dayContentRight(dayOfWeek) {
|
||||
if (dayContentRights[dayOfWeek] == undefined) {
|
||||
dayContentRights[dayOfWeek] = dayContentLeft(dayOfWeek) + dayContentElement(dayOfWeek).width();
|
||||
}
|
||||
return dayContentRights[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// renders 'all-day' events at the top
|
||||
|
||||
function renderDaySegs(segRow) {
|
||||
if (options.allDaySlot) {
|
||||
var html='',
|
||||
td = head.find('td'),
|
||||
tdInner = td.find('div div'),
|
||||
tr = td.parent(),
|
||||
top = safePosition(tdInner, td, tr, tr.parent()).top,
|
||||
rowContentHeight = 0,
|
||||
i, len=segRow.length, level,
|
||||
levelHeight,
|
||||
j, seg,
|
||||
event,
|
||||
className,
|
||||
left, right,
|
||||
triggerRes,
|
||||
l=0,
|
||||
_eventElements,
|
||||
eventLefts=[], eventRights=[],
|
||||
eventHSides=[],
|
||||
eventOuterHeights=[];
|
||||
for (i=0; i<len; i++) {
|
||||
level = segRow[i];
|
||||
for (j=0; j<level.length; j++) {
|
||||
seg = level[j];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
if (rtl) {
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
left = seg.isEnd ? 0 : dayContentLeft(seg.end.getDay()-1);
|
||||
right = seg.isStart ? viewWidth : dayContentRight(seg.start.getDay());
|
||||
}else{
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : 0;
|
||||
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : viewWidth;
|
||||
}
|
||||
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) + "'" : '') + ">" +
|
||||
(!event.allDay && seg.isStart ?
|
||||
"<span class='fc-event-time'>" +
|
||||
htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'), options)) +
|
||||
"</span>"
|
||||
:'') +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</a>" +
|
||||
"</div>";
|
||||
l++;
|
||||
}
|
||||
}
|
||||
daySegmentContainer.html(html);
|
||||
_eventElements = daySegmentContainer[0].childNodes;
|
||||
l = 0;
|
||||
for (i=0; i<len; i++) {
|
||||
level = segRow[i];
|
||||
for (j=0; j<level.length; j++) {
|
||||
seg = level[j];
|
||||
event = seg.event;
|
||||
eventElement = $(_eventElements[l]);
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes !== false) {
|
||||
if (triggerRes && typeof triggerRes != 'boolean') {
|
||||
eventElement = $(triggerRes).appendTo(segmentContainer);
|
||||
}
|
||||
eventOuterHeights[l] = eventElement.outerHeight(true);
|
||||
eventHSides[l] = hsides(eventElement, true);
|
||||
seg.element = eventElement;
|
||||
//bootstrapEventHandlers(event, seg, eventElement);
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
l++;
|
||||
}
|
||||
}
|
||||
l = 0;
|
||||
for (i=0; i<len; i++) {
|
||||
level = segRow[i];
|
||||
levelHeight = 0;
|
||||
for (j=0; j<level.length; j++) {
|
||||
seg = level[j];
|
||||
if (eventElement = seg.element) {
|
||||
eventElement.css('top', top);
|
||||
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]);
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
levelHeight = Math.max(levelHeight, eventOuterHeights[l]);
|
||||
}
|
||||
l++;
|
||||
}
|
||||
rowContentHeight += levelHeight;
|
||||
top += levelHeight;
|
||||
}
|
||||
tdInner.height(rowContentHeight);
|
||||
updateSize(viewWidth, viewHeight); // tdInner might have pushed the body down, so resize
|
||||
_renderDaySegs(
|
||||
[segRow],
|
||||
view,
|
||||
axisWidth,
|
||||
viewWidth,
|
||||
function() {
|
||||
return head.find('tr.fc-all-day')
|
||||
},
|
||||
function(dayOfWeek) {
|
||||
return axisWidth + colContentPositions.left(day2col(dayOfWeek));
|
||||
},
|
||||
function(dayOfWeek) {
|
||||
return axisWidth + colContentPositions.right(day2col(dayOfWeek));
|
||||
},
|
||||
daySegmentContainer,
|
||||
bootstrapDayEventHandlers
|
||||
);
|
||||
updateSize(viewWidth, viewHeight); // might have pushed the body down, so resize
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// the original function
|
||||
function renderDaySegs2(segRow) {
|
||||
if (options.allDaySlot) {
|
||||
var td = head.find('td'),
|
||||
tdInner = td.find('div div'),
|
||||
tr = td.parent(),
|
||||
top = safePosition(tdInner, td, tr, tr.parent()).top,
|
||||
rowContentHeight = 0,
|
||||
i, len=segRow.length, level,
|
||||
levelHeight,
|
||||
j, seg,
|
||||
event,
|
||||
className,
|
||||
leftDay, leftRounded,
|
||||
rightDay, rightRounded,
|
||||
left, right,
|
||||
eventElement, anchorElement,
|
||||
triggerRes;
|
||||
for (i=0; i<len; i++) {
|
||||
level = segRow[i];
|
||||
levelHeight = 0;
|
||||
for (j=0; j<level.length; j++) {
|
||||
seg = level[j];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
if (rtl) {
|
||||
leftDay = seg.end.getDay() - 1;
|
||||
leftRounded = seg.isEnd;
|
||||
rightDay = seg.start.getDay();
|
||||
rightRounded = seg.isStart;
|
||||
}else{
|
||||
leftDay = seg.start.getDay();
|
||||
leftRounded = seg.isStart;
|
||||
rightDay = seg.end.getDay() - 1;
|
||||
rightRounded = seg.isEnd;
|
||||
}
|
||||
if (leftRounded) {
|
||||
className += 'fc-corner-left ';
|
||||
left = bg.find('td:eq('+(((leftDay-Math.max(firstDay,nwe)+colCnt)%colCnt)*dis+dit)+') div div').position().left + axisWidth;
|
||||
}else{
|
||||
left = axisWidth;
|
||||
}
|
||||
if (rightRounded) {
|
||||
className += 'fc-corner-right ';
|
||||
right = bg.find('td:eq('+(((rightDay-Math.max(firstDay,nwe)+colCnt)%colCnt)*dis+dit)+') div div');
|
||||
right = right.position().left + right.width() + axisWidth;
|
||||
}else{
|
||||
right = axisWidth + bg.width();
|
||||
}
|
||||
eventElement = $("<div class='" + className + event.className.join(' ') + "'/>")
|
||||
.append(anchorElement = $("<a/>")
|
||||
.append($("<span class='fc-event-title' />")
|
||||
.text(event.title)));
|
||||
if (event.url) {
|
||||
anchorElement.attr('href', event.url);
|
||||
}
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes !== false) {
|
||||
if (triggerRes && typeof triggerRes != 'boolean') {
|
||||
eventElement = $(triggerRes);
|
||||
}
|
||||
eventElement
|
||||
.css({
|
||||
position: 'absolute',
|
||||
top: top,
|
||||
left: left,
|
||||
zIndex: 8
|
||||
})
|
||||
.appendTo(head);
|
||||
setOuterWidth(eventElement, right-left, true);
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableDayEvent(event, eventElement, seg.isStart);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
view.reportEventElement(event, eventElement);
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
levelHeight = Math.max(levelHeight, eventElement.outerHeight(true));
|
||||
}
|
||||
}
|
||||
top += levelHeight;
|
||||
rowContentHeight += levelHeight;
|
||||
}
|
||||
tdInner.height(rowContentHeight);
|
||||
updateSize(viewWidth, viewHeight); // tdInner might have pushed the body down, so resize
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
// renders events in the 'time slots' at the bottom
|
||||
|
||||
function renderSlotSegs(segCols) {
|
||||
renderSlotSegs2(segCols);
|
||||
/*
|
||||
var html='',
|
||||
colI, colLen=segCols.length, col,
|
||||
levelI, level,
|
||||
segI, seg,
|
||||
forward,
|
||||
event,
|
||||
top, bottom,
|
||||
tdInner,
|
||||
width, left,
|
||||
eventElement,
|
||||
|
||||
var event,
|
||||
className,
|
||||
l=0,
|
||||
top,
|
||||
bottom,
|
||||
leftmost,
|
||||
availWidth,
|
||||
forward,
|
||||
width,
|
||||
left,
|
||||
eventTops=[],
|
||||
eventLefts=[],
|
||||
eventOuterWidths=[],
|
||||
triggerRes;
|
||||
for (colI=0; colI<colLen; colI++) {
|
||||
col = segCols[colI];
|
||||
for (levelI=0; levelI<col.length; levelI++) {
|
||||
level = col[levelI];
|
||||
for (segI=0; segI<level.length; segI++) {
|
||||
seg = level[segI];
|
||||
forward = seg.forward || 0;
|
||||
event = seg.event;
|
||||
top = timePosition(seg.start, seg.start);
|
||||
bottom = timePosition(seg.start, seg.end);
|
||||
tdInner = bg.find('td:eq(' + (colI*dis + dit) + ') div div');
|
||||
availWidth = tdInner.width();
|
||||
availWidth = Math.min(availWidth-6, availWidth*.95); // TODO: move this to CSS
|
||||
if (levelI) {
|
||||
// indented and thin
|
||||
width = 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 =
|
||||
}else{
|
||||
// can be entire width, aligned left
|
||||
width = availWidth;
|
||||
}
|
||||
}
|
||||
left = axisWidth + tdInner.position().left + // leftmost possible
|
||||
(availWidth / (levelI + forward + 1) * levelI) // indentation
|
||||
* dis + (rtl ? availWidth - width : 0); // rtl
|
||||
eventLefts[l] = left;
|
||||
eventOuterWidths[l] = width;
|
||||
eventOuterHeights=[],
|
||||
html='',
|
||||
eventElements,
|
||||
eventElement,
|
||||
triggerRes,
|
||||
eventVSides=[],
|
||||
eventHSides=[],
|
||||
eventTitleTops=[],
|
||||
height;
|
||||
|
||||
// calculate desired position/dimensions, create html
|
||||
eachLeaf(segCols, function(l, seg, segI, levelI, colI) {
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-vert ';
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-top ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-bottom ';
|
||||
}
|
||||
top = timePosition(seg.start, seg.start);
|
||||
bottom = timePosition(seg.start, seg.end);
|
||||
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);
|
||||
}else{
|
||||
if (forward) {
|
||||
// moderately wide, aligned left still
|
||||
width = ((availWidth / (forward + 1)) - (12/2)) * 2; // 12 is the predicted width of resizer =
|
||||
}else{
|
||||
// can be entire width, aligned left
|
||||
width = availWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
|
||||
// the original function
|
||||
function renderSlotSegs2(segCols) {
|
||||
var colI, colLen=segCols.length, col,
|
||||
levelI, level,
|
||||
segI, seg,
|
||||
forward,
|
||||
event,
|
||||
top, bottom,
|
||||
tdInner,
|
||||
width, left,
|
||||
className,
|
||||
eventElement, anchorElement, timeElement, titleElement,
|
||||
triggerRes;
|
||||
for (colI=0; colI<colLen; colI++) {
|
||||
col = segCols[colI];
|
||||
for (levelI=0; levelI<col.length; levelI++) {
|
||||
level = col[levelI];
|
||||
for (segI=0; segI<level.length; segI++) {
|
||||
seg = level[segI];
|
||||
forward = seg.forward || 0;
|
||||
event = seg.event;
|
||||
top = timePosition(seg.start, seg.start);
|
||||
bottom = timePosition(seg.start, seg.end);
|
||||
tdInner = bg.find('td:eq(' + (colI*dis + dit) + ') div div');
|
||||
availWidth = tdInner.width();
|
||||
availWidth = Math.min(availWidth-6, availWidth*.95); // TODO: move this to CSS
|
||||
if (levelI) {
|
||||
// indented and thin
|
||||
width = 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 =
|
||||
}else{
|
||||
// can be entire width, aligned left
|
||||
width = availWidth;
|
||||
}
|
||||
}
|
||||
left = axisWidth + tdInner.position().left + // leftmost possible
|
||||
(availWidth / (levelI + forward + 1) * levelI) // indentation
|
||||
* dis + (rtl ? availWidth - width : 0); // rtl
|
||||
className = 'fc-event fc-event-vert ';
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-top ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-bottom ';
|
||||
}
|
||||
eventElement = $("<div class='" + className + event.className.join(' ') + "' />")
|
||||
.append(anchorElement = $("<a><span class='fc-event-bg'/></a>")
|
||||
.append(timeElement = $("<span class='fc-event-time'/>")
|
||||
.text(formatDates(event.start, event.end, view.option('timeFormat'))))
|
||||
.append(titleElement = $("<span class='fc-event-title'/>")
|
||||
.text(event.title)))
|
||||
if (event.url) {
|
||||
anchorElement.attr('href', event.url);
|
||||
}
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes !== false) {
|
||||
if (triggerRes && typeof triggerRes != 'boolean') {
|
||||
eventElement = $(triggerRes);
|
||||
}
|
||||
eventElement
|
||||
.css({
|
||||
position: 'absolute',
|
||||
zIndex: 8,
|
||||
top: top,
|
||||
left: left
|
||||
})
|
||||
.appendTo(bodyContent);
|
||||
setOuterWidth(eventElement, width, true);
|
||||
setOuterHeight(eventElement, bottom-top, true);
|
||||
if (eventElement.height() - titleElement.position().top < 10) {
|
||||
// event title doesn't have enough room, put next to the time
|
||||
timeElement.text(formatDate(event.start, view.option('timeFormat')) + ' - ' + event.title);
|
||||
titleElement.remove();
|
||||
}
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableSlotEvent(event, eventElement, timeElement);
|
||||
if (seg.isEnd) {
|
||||
resizableSlotEvent(event, eventElement, timeElement);
|
||||
}
|
||||
}
|
||||
}
|
||||
view.reportEventElement(event, eventElement);
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
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;
|
||||
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-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();
|
||||
|
||||
// retrieve elements, run through eventRender callback, record outer-edge dimensions
|
||||
eachLeaf(segCols, function(l, seg) {
|
||||
event = seg.event;
|
||||
eventElement = eventElements.eq(l);
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes === false) {
|
||||
eventElement.remove();
|
||||
}else{
|
||||
if (triggerRes && triggerRes !== true) {
|
||||
eventElement.remove();
|
||||
eventElement = $(triggerRes)
|
||||
.css({
|
||||
top: eventTops[l],
|
||||
left: eventLefts[l]
|
||||
})
|
||||
.appendTo(slotSegmentContainer);
|
||||
}
|
||||
seg.element = eventElement;
|
||||
eventVSides[l] = vsides(eventElement, true);
|
||||
eventHSides[l] = hsides(eventElement, true);
|
||||
eventTitleTops[l] = eventElement.find('span.fc-event-title').position().top;
|
||||
bootstrapSlotEventHandlers(event, seg, eventElement);
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// set all positions/dimensions at once
|
||||
eachLeaf(segCols, function(l, seg) {
|
||||
if (eventElement = seg.element) {
|
||||
eventElement
|
||||
.width(eventOuterWidths[l] - eventHSides[l])
|
||||
.height(height = eventOuterHeights[l] - eventVSides[l]);
|
||||
event = seg.event;
|
||||
if (height - eventTitleTops[l] < 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);
|
||||
eventElement.find('span.fc-event-title')
|
||||
.remove();
|
||||
}
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -814,6 +564,45 @@ function Agenda(element, options, methods) {
|
|||
return addMinutes(cloneDate(event.start), options.defaultEventMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function bootstrapDayEventHandlers(event, seg, eventElement) {
|
||||
var attached = false;
|
||||
eventElement.mouseover(function(ev) {
|
||||
if (!attached) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableDayEvent(event, eventElement, seg.isStart);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
attached = true;
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
function bootstrapSlotEventHandlers(event, seg, eventElement) {
|
||||
var attached = false;
|
||||
eventElement.mouseover(function(ev) {
|
||||
if (!attached) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
var timeElement = eventElement.find('span.fc-event-time');
|
||||
draggableSlotEvent(event, eventElement, timeElement);
|
||||
if (seg.isEnd) {
|
||||
resizableSlotEvent(event, eventElement, timeElement);
|
||||
}
|
||||
}
|
||||
attached = true;
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
@ -1038,7 +827,9 @@ function Agenda(element, options, methods) {
|
|||
var slotDelta, prevSlotDelta;
|
||||
eventElement
|
||||
.resizable({
|
||||
handles: 's',
|
||||
handles: {
|
||||
s: 'div.ui-resizable-s'
|
||||
},
|
||||
grid: slotHeight,
|
||||
start: function(ev, ui) {
|
||||
slotDelta = prevSlotDelta = 0;
|
||||
|
@ -1074,15 +865,11 @@ function Agenda(element, options, methods) {
|
|||
// BUG: if event was really short, need to put title back in span
|
||||
}
|
||||
}
|
||||
})
|
||||
.find('div.ui-resizable-s').text('=');
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ALL-DAY event resizing w/ 'view' methods...
|
||||
|
||||
|
||||
|
||||
|
||||
/* Misc
|
||||
|
@ -1105,9 +892,16 @@ function Agenda(element, options, methods) {
|
|||
td = tr.find('td'),
|
||||
innerDiv = td.find('div');
|
||||
return Math.max(0, Math.round(
|
||||
safePosition(innerDiv, td, tr, tr.parent()).top - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)
|
||||
innerDiv.position().top + topCorrect(tr, td) - 1 + slotHeight * ((minutes % slotMinutes) / slotMinutes)
|
||||
));
|
||||
}
|
||||
|
||||
|
||||
|
||||
function day2col(dayOfWeek) {
|
||||
return ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt)*dis+dit;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
|
414
src/grid.js
414
src/grid.js
|
@ -110,7 +110,7 @@ views.basicDay = function(element, options) {
|
|||
|
||||
// rendering bugs
|
||||
|
||||
var tdHeightBug, rtlLeftDiff;
|
||||
var tdHeightBug;
|
||||
|
||||
|
||||
function Grid(element, options, methods) {
|
||||
|
@ -125,9 +125,9 @@ function Grid(element, options, methods) {
|
|||
cachedEvents=[],
|
||||
segments=[],
|
||||
segmentContainer,
|
||||
dayContentElements=[],
|
||||
dayContentLefts=[],
|
||||
dayContentRights=[],
|
||||
dayContentPositions = new HorizontalPositionCache(function(dayOfWeek) {
|
||||
return tbody.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div')
|
||||
}),
|
||||
// ...
|
||||
|
||||
// initialize superclass
|
||||
|
@ -135,6 +135,7 @@ function Grid(element, options, methods) {
|
|||
renderGrid: renderGrid,
|
||||
renderEvents: renderEvents,
|
||||
rerenderEvents: rerenderEvents,
|
||||
clearEvents: clearEvents,
|
||||
updateSize: updateSize,
|
||||
defaultEventEnd: function(event) { // calculates an end if event doesnt have one, mostly for resizing
|
||||
return cloneDate(event.start);
|
||||
|
@ -322,8 +323,7 @@ function Grid(element, options, methods) {
|
|||
function updateSize(width, height) { // does not render/position the events
|
||||
viewWidth = width;
|
||||
viewHeight = height;
|
||||
dayContentLefts = [];
|
||||
dayContentRights = [];
|
||||
dayContentPositions.clear();
|
||||
|
||||
var leftTDs = tbody.find('tr td:first-child'),
|
||||
tbodyHeight = viewHeight - thead.height(),
|
||||
|
@ -336,8 +336,6 @@ function Grid(element, options, methods) {
|
|||
rowHeight2 = tbodyHeight - rowHeight1*(rowCnt-1);
|
||||
}
|
||||
|
||||
reportTBody(tbody);
|
||||
|
||||
if (tdHeightBug == undefined) {
|
||||
// bug in firefox where cell height includes padding
|
||||
var tr = tbody.find('tr:first'),
|
||||
|
@ -361,36 +359,6 @@ function Grid(element, options, methods) {
|
|||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* cell/cell-content positioning calculating/caching
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
function dayContentElement(dayOfWeek) {
|
||||
if (dayContentElements[dayOfWeek] == undefined) {
|
||||
dayContentElements[dayOfWeek] = tbody.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div');
|
||||
}
|
||||
return dayContentElements[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
function dayContentLeft(dayOfWeek) {
|
||||
if (dayContentLefts[dayOfWeek] == undefined) {
|
||||
dayContentLefts[dayOfWeek] = dayContentElement(dayOfWeek).position().left;
|
||||
}
|
||||
return dayContentLefts[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
function dayContentRight(dayOfWeek) {
|
||||
if (dayContentRights[dayOfWeek] == undefined) {
|
||||
dayContentRights[dayOfWeek] = dayContentLeft(dayOfWeek) + dayContentElement(dayOfWeek).width();
|
||||
}
|
||||
return dayContentRights[dayOfWeek];
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Event Rendering
|
||||
|
@ -430,235 +398,23 @@ function Grid(element, options, methods) {
|
|||
|
||||
|
||||
|
||||
function renderSegs(segRows) {
|
||||
//renderSegs2(segRows);
|
||||
//return;
|
||||
var html='',
|
||||
i, len = segRows.length, levels,
|
||||
tr, td,
|
||||
innerDiv,
|
||||
top,
|
||||
rowContentHeight,
|
||||
j, segs,
|
||||
levelHeight,
|
||||
k, seg,
|
||||
event,
|
||||
className,
|
||||
left, right,
|
||||
eventElement,
|
||||
triggerRes,
|
||||
l=0,
|
||||
_eventElements,
|
||||
eventLefts=[], eventRights=[],
|
||||
eventHSides=[],
|
||||
eventOuterHeights=[];
|
||||
for (i=0; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
for (j=0; j<levels.length; j++) {
|
||||
segs = levels[j];
|
||||
for (k=0; k<segs.length; k++) {
|
||||
seg = segs[k];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
if (rtl) {
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
left = seg.isEnd ? 0 : dayContentLeft(seg.end.getDay()-1);
|
||||
right = seg.isStart ? viewWidth : dayContentRight(seg.start.getDay());
|
||||
}else{
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : 0;
|
||||
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : viewWidth;
|
||||
}
|
||||
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) + "'" : '') + ">" +
|
||||
(!event.allDay && seg.isStart ?
|
||||
"<span class='fc-event-time'>" +
|
||||
htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'), options)) +
|
||||
"</span>"
|
||||
:'') +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</a>" +
|
||||
"</div>";
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
segmentContainer.html(html);
|
||||
_eventElements = segmentContainer[0].childNodes;
|
||||
l = 0;
|
||||
for (i=0; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
for (j=0; j<levels.length; j++) {
|
||||
segs = levels[j];
|
||||
for (k=0; k<segs.length; k++) {
|
||||
seg = segs[k];
|
||||
event = seg.event;
|
||||
eventElement = $(_eventElements[l]);
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes !== false) {
|
||||
if (triggerRes && typeof triggerRes != 'boolean') {
|
||||
eventElement = $(triggerRes).appendTo(segmentContainer);
|
||||
}
|
||||
eventOuterHeights[l] = eventElement.outerHeight(true);
|
||||
eventHSides[l] = hsides(eventElement, true);
|
||||
seg.element = eventElement;
|
||||
bootstrapEventHandlers(event, seg, eventElement);
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
l++;
|
||||
}
|
||||
}
|
||||
}
|
||||
l = 0;
|
||||
for (i=0; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
tr = tbody.find('tr:eq('+i+')');
|
||||
td = tr.find('td:first');
|
||||
innerDiv = td.find('div.fc-day-content div').css('position', 'relative');
|
||||
top = safePosition(innerDiv, td, tr, tbody).top;
|
||||
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);
|
||||
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]);
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
levelHeight = Math.max(levelHeight, eventOuterHeights[l]);
|
||||
}
|
||||
l++;
|
||||
}
|
||||
rowContentHeight += levelHeight;
|
||||
top += levelHeight;
|
||||
}
|
||||
innerDiv.height(rowContentHeight);
|
||||
}
|
||||
function renderSegs(segCols) {
|
||||
_renderDaySegs(
|
||||
segCols,
|
||||
view,
|
||||
0,
|
||||
viewWidth,
|
||||
function(i) {
|
||||
return tbody.find('tr:eq('+i+')');
|
||||
},
|
||||
dayContentPositions.left,
|
||||
dayContentPositions.right,
|
||||
segmentContainer,
|
||||
bootstrapEventHandlers
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// the original function
|
||||
function renderSegs2(segRows) {
|
||||
var i, len = segRows.length, levels,
|
||||
tr, td,
|
||||
innerDiv,
|
||||
top,
|
||||
rowContentHeight,
|
||||
j, segs,
|
||||
levelHeight,
|
||||
k, seg,
|
||||
event,
|
||||
className,
|
||||
left, right,
|
||||
eventElement, eventAnchor,
|
||||
triggerRes;
|
||||
for (i=0; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
tr = tbody.find('tr:eq('+i+')');
|
||||
td = tr.find('td:first');
|
||||
innerDiv = td.find('div.fc-day-content div').css('position', 'relative');
|
||||
top = safePosition(innerDiv, td, tr, tbody).top;
|
||||
rowContentHeight = 0;
|
||||
for (j=0; j<levels.length; j++) {
|
||||
segs = levels[j];
|
||||
levelHeight = 0;
|
||||
for (k=0; k<segs.length; k++) {
|
||||
seg = segs[k];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
if (rtl) {
|
||||
left = seg.isEnd ? 0 : dayContentLeft(seg.end.getDay()-1);
|
||||
right = seg.isStart ? viewWidth : dayContentRight(seg.start.getDay());
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
}else{
|
||||
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : 0;
|
||||
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : viewWidth;
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
}
|
||||
eventElement = $("<div class='" + className + event.className.join(' ') + "'/>")
|
||||
.append(eventAnchor = $("<a/>")
|
||||
.append(event.allDay || !seg.isStart ? null :
|
||||
$("<span class='fc-event-time'/>")
|
||||
.html(formatDates(event.start, event.end, view.option('timeFormat'), options)))
|
||||
.append($("<span class='fc-event-title'/>")
|
||||
.text(event.title)));
|
||||
if (event.url) {
|
||||
eventAnchor.attr('href', event.url);
|
||||
}
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes !== false) {
|
||||
if (triggerRes && typeof triggerRes != 'boolean') {
|
||||
eventElement = $(triggerRes);
|
||||
}
|
||||
eventElement
|
||||
.css({
|
||||
position: 'absolute',
|
||||
top: top,
|
||||
left: left + (rtlLeftDiff||0),
|
||||
zIndex: 8
|
||||
})
|
||||
.appendTo(element);
|
||||
setOuterWidth(eventElement, right-left, true);
|
||||
if (rtl && rtlLeftDiff == undefined) {
|
||||
// bug in IE6 where offsets are miscalculated with direction:rtl
|
||||
rtlLeftDiff = left - eventElement.position().left;
|
||||
if (rtlLeftDiff) {
|
||||
eventElement.css('left', left + rtlLeftDiff);
|
||||
}
|
||||
}
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableEvent(event, eventElement);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
view.reportEventElement(event, eventElement);
|
||||
view.trigger('eventAfterRender', event, event, eventElement);
|
||||
levelHeight = Math.max(levelHeight, eventElement.outerHeight(true));
|
||||
}
|
||||
}
|
||||
rowContentHeight += levelHeight;
|
||||
top += levelHeight;
|
||||
}
|
||||
innerDiv.height(rowContentHeight);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function visEventEnd(event) { // returns exclusive 'visible' end, for rendering
|
||||
if (event.end) {
|
||||
|
@ -683,7 +439,7 @@ function Grid(element, options, methods) {
|
|||
}
|
||||
}
|
||||
attached = true;
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
view.trigger('eventMouseover', this, event, ev); // TODO: make sure this isn't being fired twice
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -751,3 +507,131 @@ function Grid(element, options, methods) {
|
|||
|
||||
};
|
||||
|
||||
|
||||
function _renderDaySegs(segRows, view, minLeft, maxLeft, getTr, dayContentLeft, dayContentRight, segmentContainer, bootstrapEventHandlers) {
|
||||
|
||||
var options=view.options,
|
||||
rtl=options.isRTL,
|
||||
event,
|
||||
className,
|
||||
left,
|
||||
right,
|
||||
eventLefts=[],
|
||||
eventRights=[],
|
||||
html='',
|
||||
eventElements,
|
||||
eventElement,
|
||||
triggerRes,
|
||||
eventOuterHeights=[],
|
||||
eventHSides=[],
|
||||
l=0,
|
||||
i=0, len=segRows.length, levels,
|
||||
tr,
|
||||
td,
|
||||
innerDiv,
|
||||
top,
|
||||
rowContentHeight,
|
||||
j, segs,
|
||||
k, seg;
|
||||
|
||||
// calculate desired position/dimensions, create html
|
||||
eachLeaf(segRows, function(l, seg) {
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
if (rtl) {
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
left = seg.isEnd ? dayContentLeft(seg.end.getDay()-1) : minLeft;
|
||||
right = seg.isStart ? dayContentRight(seg.start.getDay()) : maxLeft;
|
||||
}else{
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
if (seg.isEnd) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
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) + "'" : '') + ">" +
|
||||
(!event.allDay && seg.isStart ?
|
||||
"<span class='fc-event-time'>" +
|
||||
htmlEscape(formatDates(event.start, event.end, view.option('timeFormat'), options)) +
|
||||
"</span>"
|
||||
:'') +
|
||||
"<span class='fc-event-title'>" + htmlEscape(event.title) + "</span>" +
|
||||
"</a>" +
|
||||
"</div>";
|
||||
});
|
||||
segmentContainer.html(html);
|
||||
eventElements = segmentContainer.children();
|
||||
|
||||
// retrieve elements, run through eventRender callback, record outer-edge dimensions
|
||||
eachLeaf(segRows, function(l, seg) {
|
||||
event = seg.event;
|
||||
eventElement = eventElements.eq(l);
|
||||
triggerRes = view.trigger('eventRender', event, event, eventElement);
|
||||
if (triggerRes === false) {
|
||||
eventElement.remove();
|
||||
}else{
|
||||
if (triggerRes && triggerRes !== true) {
|
||||
eventElement.remove();
|
||||
eventElement = $(triggerRes)
|
||||
.css('left', eventLefts[l])
|
||||
.appendTo(segmentContainer);
|
||||
}
|
||||
seg.element = eventElement;
|
||||
eventOuterHeights[l] = eventElement.outerHeight(true);
|
||||
eventHSides[l] = hsides(eventElement, true);
|
||||
bootstrapEventHandlers(event, seg, eventElement);
|
||||
view.reportEventElement(event, eventElement);
|
||||
}
|
||||
});
|
||||
|
||||
// set all positions/dimensions at once
|
||||
for (; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
tr = getTr(i);
|
||||
td = tr.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(tr, 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);
|
||||
//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;
|
||||
}
|
||||
innerDiv.height(rowContentHeight);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
|
98
src/util.js
98
src/util.js
|
@ -4,7 +4,8 @@
|
|||
|
||||
var DAY_MS = 86400000,
|
||||
HOUR_MS = 3600000,
|
||||
MINUTE_MS = 60000;
|
||||
MINUTE_MS = 60000,
|
||||
arrayPop = Array.prototype.pop; // for eachLeaf
|
||||
|
||||
function addYears(d, n, keepTime) {
|
||||
d.setFullYear(d.getFullYear() + n);
|
||||
|
@ -296,7 +297,7 @@ var dateFormatters = {
|
|||
/* Element Dimensions
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
function setOuterWidth(element, width, includeMargins) { // TODO: probably eventually remove this
|
||||
function setOuterWidth(element, width, includeMargins) {
|
||||
element.each(function() {
|
||||
var e = $(this);
|
||||
e.width(width - hsides(e, includeMargins));
|
||||
|
@ -313,7 +314,7 @@ function hsides(e, includeMargins) {
|
|||
: 0);
|
||||
}
|
||||
|
||||
function setOuterHeight(element, height, includeMargins) { // TODO: probably eventually remove this
|
||||
function setOuterHeight(element, height, includeMargins) {
|
||||
element.each(function() {
|
||||
var e = $(this);
|
||||
e.height(height - vsides(e, includeMargins));
|
||||
|
@ -335,22 +336,22 @@ function vsides(e, includeMargins) {
|
|||
/* Position Calculation
|
||||
-----------------------------------------------------------------------------*/
|
||||
// nasty bugs in opera 9.25
|
||||
// position() returning relative to direct parent
|
||||
// position()'s top returning incorrectly with TR/TD or elements within TD
|
||||
|
||||
var operaPositionBug;
|
||||
var topBug;
|
||||
|
||||
function reportTBody(tbody) {
|
||||
if (operaPositionBug == undefined) {
|
||||
operaPositionBug = tbody.position().top != tbody.find('tr').position().top;
|
||||
function topCorrect(tr, td) {
|
||||
if (topBug !== false && tr.is('tr')) {
|
||||
var tbody = tr.parent(),
|
||||
trTop = tr.position().top;
|
||||
if (topBug == undefined) {
|
||||
topBug = trTop != tr.children().position().top;
|
||||
}
|
||||
if (topBug) {
|
||||
return tbody.position().top + trTop - (td ? td.position().top : 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function safePosition(element, td, tr, tbody) {
|
||||
var position = element.position();
|
||||
if (operaPositionBug) {
|
||||
position.top += tbody.position().top + tr.position().top - td.position().top;
|
||||
}
|
||||
return position;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -360,24 +361,23 @@ function safePosition(element, td, tr, tbody) {
|
|||
|
||||
function HoverMatrix(changeCallback) {
|
||||
|
||||
var tops=[], lefts=[],
|
||||
var t=this,
|
||||
tops=[], lefts=[],
|
||||
prevRowE, prevColE,
|
||||
origRow, origCol,
|
||||
currRow, currCol;
|
||||
|
||||
this.row = function(e, topBug) {
|
||||
t.row = function(e) {
|
||||
prevRowE = $(e);
|
||||
tops.push(prevRowE.offset().top + (
|
||||
(operaPositionBug && prevRowE.is('tr')) ? prevRowE.parent().position().top : 0
|
||||
));
|
||||
tops.push(prevRowE.offset().top + topCorrect(prevRowE));
|
||||
};
|
||||
|
||||
this.col = function(e) {
|
||||
t.col = function(e) {
|
||||
prevColE = $(e);
|
||||
lefts.push(prevColE.offset().left);
|
||||
};
|
||||
|
||||
this.mouse = function(x, y) {
|
||||
t.mouse = function(x, y) {
|
||||
if (origRow == undefined) {
|
||||
tops.push(tops[tops.length-1] + prevRowE.outerHeight());
|
||||
lefts.push(lefts[lefts.length-1] + prevColE.outerWidth());
|
||||
|
@ -392,13 +392,13 @@ function HoverMatrix(changeCallback) {
|
|||
currRow = r;
|
||||
currCol = c;
|
||||
if (r == -1 || c == -1) {
|
||||
this.cell = null;
|
||||
t.cell = null;
|
||||
}else{
|
||||
if (origRow == undefined) {
|
||||
origRow = r;
|
||||
origCol = c;
|
||||
}
|
||||
this.cell = {
|
||||
t.cell = {
|
||||
row: r,
|
||||
col: c,
|
||||
top: tops[r],
|
||||
|
@ -410,7 +410,7 @@ function HoverMatrix(changeCallback) {
|
|||
colDelta: c-origCol
|
||||
};
|
||||
}
|
||||
changeCallback(this.cell);
|
||||
changeCallback(t.cell);
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -452,4 +452,50 @@ function htmlEscape(s) {
|
|||
.replace(/"/g, '"')
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
var t = this,
|
||||
elements = {},
|
||||
lefts = {},
|
||||
rights = {};
|
||||
|
||||
function e(i) {
|
||||
return elements[i] =
|
||||
elements[i] || getElement(i);
|
||||
}
|
||||
|
||||
t.left = function(i) {
|
||||
return lefts[i] =
|
||||
lefts[i] == undefined ? e(i).position().left : lefts[i];
|
||||
};
|
||||
|
||||
t.right = function(i) {
|
||||
return rights[i] =
|
||||
rights[i] == undefined ? t.left(i) + e(i).width() : rights[i];
|
||||
};
|
||||
|
||||
t.clear = function() {
|
||||
elements = {};
|
||||
lefts = {};
|
||||
rights = {};
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -352,3 +352,5 @@ function segsCollide(seg1, seg2) {
|
|||
return seg1.end > seg2.start && seg1.start < seg2.end;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue