optimizations for month/basic views, groundwork for optimizations in agenda views
This commit is contained in:
parent
2d97e4f15d
commit
1667943d1c
8 changed files with 4729 additions and 166 deletions
|
@ -21,7 +21,7 @@ setDefaults({
|
|||
|
||||
views.agendaWeek = function(element, options) {
|
||||
return new Agenda(element, options, {
|
||||
render: function(date, delta, height, fetchEvents) {
|
||||
render: function(date, delta, width, height, fetchEvents) {
|
||||
if (delta) {
|
||||
addDays(date, delta * 7);
|
||||
}
|
||||
|
@ -41,14 +41,19 @@ views.agendaWeek = function(element, options) {
|
|||
this.option('titleFormat'),
|
||||
options
|
||||
);
|
||||
this.renderAgenda(options.weekends ? 7 : 5, this.option('columnFormat'), height, fetchEvents);
|
||||
this.renderAgenda(
|
||||
options.weekends ? 7 : 5,
|
||||
this.option('columnFormat'),
|
||||
width, height,
|
||||
fetchEvents
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
views.agendaDay = function(element, options) {
|
||||
return new Agenda(element, options, {
|
||||
render: function(date, delta, height, fetchEvents) {
|
||||
render: function(date, delta, width, height, fetchEvents) {
|
||||
if (delta) {
|
||||
addDays(date, delta);
|
||||
if (!options.weekends) {
|
||||
|
@ -58,7 +63,12 @@ views.agendaDay = function(element, options) {
|
|||
this.title = formatDate(date, this.option('titleFormat'), options);
|
||||
this.start = this.visStart = cloneDate(date, true);
|
||||
this.end = this.visEnd = addDays(cloneDate(this.start), 1);
|
||||
this.renderAgenda(1, this.option('columnFormat'), height, fetchEvents);
|
||||
this.renderAgenda(
|
||||
1,
|
||||
this.option('columnFormat'),
|
||||
width, height,
|
||||
fetchEvents
|
||||
);
|
||||
}
|
||||
});
|
||||
};
|
||||
|
@ -68,8 +78,8 @@ function Agenda(element, options, methods) {
|
|||
var head, body, bodyContent, bodyTable, bg,
|
||||
colCnt,
|
||||
axisWidth, colWidth, slotHeight,
|
||||
viewWidth, viewHeight,
|
||||
cachedDaySegs=[], cachedSlotSegs=[],
|
||||
cachedHeight,
|
||||
tm, firstDay,
|
||||
nwe, // no weekends (int)
|
||||
rtl, dis, dit, // day index sign / translate
|
||||
|
@ -88,21 +98,6 @@ function Agenda(element, options, methods) {
|
|||
return start;
|
||||
}
|
||||
return addMinutes(start, options.defaultEventMinutes);
|
||||
},
|
||||
visEventEnd: function(event) {
|
||||
if (event.allDay) {
|
||||
if (event.end) {
|
||||
var end = cloneDate(event.end);
|
||||
return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
|
||||
}else{
|
||||
return addDays(cloneDate(event.start), 1);
|
||||
}
|
||||
}
|
||||
if (event.end) {
|
||||
return cloneDate(event.end);
|
||||
}else{
|
||||
return addMinutes(cloneDate(event.start), options.defaultEventMinutes);
|
||||
}
|
||||
}
|
||||
});
|
||||
view.init(element, options);
|
||||
|
@ -118,7 +113,7 @@ function Agenda(element, options, methods) {
|
|||
element.disableSelection();
|
||||
}
|
||||
|
||||
function renderAgenda(c, colFormat, height, fetchEvents) {
|
||||
function renderAgenda(c, colFormat, width, height, fetchEvents) {
|
||||
colCnt = c;
|
||||
|
||||
// update option-derived variables
|
||||
|
@ -218,7 +213,7 @@ function Agenda(element, options, methods) {
|
|||
|
||||
}else{ // skeleton already built, just modify it
|
||||
|
||||
view.clearEvents();
|
||||
clearEvents();
|
||||
|
||||
// redo column header text and class
|
||||
head.find('tr:first th').slice(1, -1).each(function() {
|
||||
|
@ -253,7 +248,7 @@ function Agenda(element, options, methods) {
|
|||
|
||||
}
|
||||
|
||||
updateSize(height);
|
||||
updateSize(width, height);
|
||||
resetScroll();
|
||||
fetchEvents(renderEvents);
|
||||
|
||||
|
@ -276,8 +271,9 @@ function Agenda(element, options, methods) {
|
|||
}
|
||||
|
||||
|
||||
function updateSize(height) {
|
||||
cachedHeight = height;
|
||||
function updateSize(width, height) {
|
||||
viewWidth = width;
|
||||
viewHeight = height;
|
||||
|
||||
bodyTable.width('');
|
||||
body.height(height - head.height());
|
||||
|
@ -342,10 +338,10 @@ function Agenda(element, options, methods) {
|
|||
/* Event Rendering
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
var cachedEvents;
|
||||
|
||||
function renderEvents(events) {
|
||||
view.reportEvents(events);
|
||||
|
||||
view.reportEvents(cachedEvents = events);
|
||||
var i, len=events.length,
|
||||
dayEvents=[],
|
||||
slotEvents=[];
|
||||
|
@ -356,30 +352,33 @@ function Agenda(element, options, methods) {
|
|||
slotEvents.push(events[i]);
|
||||
}
|
||||
}
|
||||
|
||||
renderDaySegs(cachedDaySegs = stackSegs(view.sliceSegs(dayEvents, view.visStart, view.visEnd)));
|
||||
renderDaySegs(cachedDaySegs = stackSegs(view.sliceSegs(dayEvents, $.map(dayEvents, visEventEnd), view.visStart, view.visEnd)));
|
||||
renderSlotSegs(cachedSlotSegs = compileSlotSegs(slotEvents));
|
||||
}
|
||||
|
||||
|
||||
function rerenderEvents(skipCompile) {
|
||||
view.clearEvents();
|
||||
if (skipCompile) {
|
||||
renderDaySegs(cachedDaySegs);
|
||||
renderSlotSegs(cachedSlotSegs);
|
||||
}else{
|
||||
renderEvents(view.cachedEvents);
|
||||
}
|
||||
function rerenderEvents() {
|
||||
clearEvents();
|
||||
renderEvents(cachedEvents);
|
||||
}
|
||||
|
||||
|
||||
function clearEvents() {
|
||||
$.each(view.eventElements, function() { // TODO: move away from this, empty a container instead
|
||||
this.remove();
|
||||
});
|
||||
view._clearEvents(); // only clears the hashes
|
||||
}
|
||||
|
||||
|
||||
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, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
|
||||
levels = stackSegs(view.sliceSegs(events, ends, d, addMinutes(cloneDate(d), maxMinute-minMinute)));
|
||||
countForwardSegs(levels);
|
||||
segCols.push(levels);
|
||||
addDays(d, 1, true);
|
||||
|
@ -476,7 +475,7 @@ function Agenda(element, options, methods) {
|
|||
rowContentHeight += levelHeight;
|
||||
}
|
||||
tdInner.height(rowContentHeight);
|
||||
updateSize(cachedHeight); // tdInner might have pushed the body down, so resize
|
||||
updateSize(viewWidth, viewHeight); // tdInner might have pushed the body down, so resize
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -574,6 +573,23 @@ function Agenda(element, options, methods) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function visEventEnd(event) { // returns exclusive 'visible' end, for rendering
|
||||
if (event.allDay) {
|
||||
if (event.end) {
|
||||
var end = cloneDate(event.end);
|
||||
return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
|
||||
}else{
|
||||
return addDays(cloneDate(event.start), 1);
|
||||
}
|
||||
}
|
||||
if (event.end) {
|
||||
return cloneDate(event.end);
|
||||
}else{
|
||||
return addMinutes(cloneDate(event.start), options.defaultEventMinutes);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
324
src/grid.js
324
src/grid.js
|
@ -8,7 +8,7 @@ setDefaults({
|
|||
|
||||
views.month = function(element, options) {
|
||||
return new Grid(element, options, {
|
||||
render: function(date, delta, height, fetchEvents) {
|
||||
render: function(date, delta, width, height, fetchEvents) {
|
||||
if (delta) {
|
||||
addMonths(date, delta);
|
||||
date.setDate(1);
|
||||
|
@ -44,7 +44,7 @@ views.month = function(element, options) {
|
|||
rowCnt, options.weekends ? 7 : 5,
|
||||
this.option('columnFormat'),
|
||||
true,
|
||||
height,
|
||||
width, height,
|
||||
fetchEvents
|
||||
);
|
||||
}
|
||||
|
@ -53,7 +53,7 @@ views.month = function(element, options) {
|
|||
|
||||
views.basicWeek = function(element, options) {
|
||||
return new Grid(element, options, {
|
||||
render: function(date, delta, height, fetchEvents) {
|
||||
render: function(date, delta, width, height, fetchEvents) {
|
||||
if (delta) {
|
||||
addDays(date, delta * 7);
|
||||
}
|
||||
|
@ -77,7 +77,7 @@ views.basicWeek = function(element, options) {
|
|||
1, options.weekends ? 7 : 5,
|
||||
this.option('columnFormat'),
|
||||
false,
|
||||
height,
|
||||
width, height,
|
||||
fetchEvents
|
||||
);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ views.basicWeek = function(element, options) {
|
|||
|
||||
views.basicDay = function(element, options) {
|
||||
return new Grid(element, options, {
|
||||
render: function(date, delta, height, fetchEvents) {
|
||||
render: function(date, delta, width, height, fetchEvents) {
|
||||
if (delta) {
|
||||
addDays(date, delta);
|
||||
if (!options.weekends) {
|
||||
|
@ -96,7 +96,13 @@ views.basicDay = function(element, options) {
|
|||
this.title = formatDate(date, this.option('titleFormat'), options);
|
||||
this.start = this.visStart = cloneDate(date, true);
|
||||
this.end = this.visEnd = addDays(cloneDate(this.start), 1);
|
||||
this.renderGrid(1, 1, this.option('columnFormat'), false, height, fetchEvents);
|
||||
this.renderGrid(
|
||||
1, 1,
|
||||
this.option('columnFormat'),
|
||||
false,
|
||||
width, height,
|
||||
fetchEvents
|
||||
);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -112,10 +118,16 @@ function Grid(element, options, methods) {
|
|||
var tm, firstDay,
|
||||
nwe, // no weekends (int)
|
||||
rtl, dis, dit, // day index sign / translate
|
||||
viewWidth, viewHeight,
|
||||
rowCnt, colCnt,
|
||||
colWidth,
|
||||
thead, tbody,
|
||||
cachedSegs=[], //...
|
||||
cachedEvents=[],
|
||||
segments=[],
|
||||
segmentContainer,
|
||||
dayContentElements=[],
|
||||
dayContentLefts=[],
|
||||
dayContentRights=[], // ...
|
||||
|
||||
// initialize superclass
|
||||
view = $.extend(this, viewMethods, methods, {
|
||||
|
@ -125,14 +137,6 @@ function Grid(element, options, methods) {
|
|||
updateSize: updateSize,
|
||||
defaultEventEnd: function(event) { // calculates an end if event doesnt have one, mostly for resizing
|
||||
return cloneDate(event.start);
|
||||
},
|
||||
visEventEnd: function(event) { // returns exclusive 'visible' end, for rendering
|
||||
if (event.end) {
|
||||
var end = cloneDate(event.end);
|
||||
return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
|
||||
}else{
|
||||
return addDays(cloneDate(event.start), 1);
|
||||
}
|
||||
}
|
||||
});
|
||||
view.init(element, options);
|
||||
|
@ -148,7 +152,7 @@ function Grid(element, options, methods) {
|
|||
element.disableSelection();
|
||||
}
|
||||
|
||||
function renderGrid(r, c, colFormat, showNumbers, height, fetchEvents) {
|
||||
function renderGrid(r, c, colFormat, showNumbers, width, height, fetchEvents) {
|
||||
rowCnt = r;
|
||||
colCnt = c;
|
||||
|
||||
|
@ -210,10 +214,12 @@ function Grid(element, options, methods) {
|
|||
}
|
||||
tbody = $(s + "</tbody>").appendTo(table);
|
||||
tbody.find('td').click(dayClick);
|
||||
|
||||
segmentContainer = $("<div/>").appendTo(element);
|
||||
|
||||
}else{ // NOT first time, reuse as many cells as possible
|
||||
|
||||
view.clearEvents();
|
||||
clearEvents();
|
||||
|
||||
var prevRowCnt = tbody.find('tr').length;
|
||||
if (rowCnt < prevRowCnt) {
|
||||
|
@ -296,7 +302,7 @@ function Grid(element, options, methods) {
|
|||
|
||||
}
|
||||
|
||||
updateSize(height);
|
||||
updateSize(width, height);
|
||||
fetchEvents(renderEvents);
|
||||
|
||||
};
|
||||
|
@ -312,10 +318,14 @@ function Grid(element, options, methods) {
|
|||
}
|
||||
|
||||
|
||||
function updateSize(height) {
|
||||
function updateSize(width, height) { // does not render/position the events
|
||||
viewWidth = width;
|
||||
viewHeight = height;
|
||||
dayContentLefts = [];
|
||||
dayContentRights = [];
|
||||
|
||||
var leftTDs = tbody.find('tr td:first-child'),
|
||||
tbodyHeight = height - thead.height(),
|
||||
tbodyHeight = viewHeight - thead.height(),
|
||||
rowHeight1, rowHeight2;
|
||||
|
||||
if (options.weekMode == 'variable') {
|
||||
|
@ -345,30 +355,62 @@ function Grid(element, options, methods) {
|
|||
|
||||
setOuterWidth(
|
||||
thead.find('th').slice(0, -1),
|
||||
colWidth = Math.floor(element.width() / colCnt)
|
||||
colWidth = Math.floor(viewWidth / colCnt)
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* 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
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
function renderEvents(events) {
|
||||
view.reportEvents(events);
|
||||
renderSegs(cachedSegs = compileSegs(events));
|
||||
view.reportEvents(cachedEvents = events);
|
||||
renderSegs(segments = compileSegs(events));
|
||||
}
|
||||
|
||||
|
||||
function rerenderEvents(skipCompile) {
|
||||
view.clearEvents();
|
||||
if (skipCompile) {
|
||||
renderSegs(cachedSegs);
|
||||
}else{
|
||||
renderEvents(view.cachedEvents);
|
||||
}
|
||||
function rerenderEvents() {
|
||||
clearEvents();
|
||||
renderSegs(segments = compileSegs(cachedEvents));
|
||||
}
|
||||
|
||||
|
||||
function clearEvents() {
|
||||
view._clearEvents(); // only clears the hashes
|
||||
segmentContainer.empty();
|
||||
}
|
||||
|
||||
|
||||
|
@ -378,7 +420,7 @@ function Grid(element, options, methods) {
|
|||
rows = [],
|
||||
i=0;
|
||||
for (; i<rowCnt; i++) {
|
||||
rows.push(stackSegs(view.sliceSegs(events, d1, d2)));
|
||||
rows.push(stackSegs(view.sliceSegs(events, $.map(events, visEventEnd), d1, d2)));
|
||||
addDays(d1, 7);
|
||||
addDays(d2, 7);
|
||||
}
|
||||
|
@ -386,7 +428,138 @@ 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
// the original function
|
||||
function renderSegs2(segRows) {
|
||||
var i, len = segRows.length, levels,
|
||||
tr, td,
|
||||
innerDiv,
|
||||
|
@ -397,47 +570,9 @@ function Grid(element, options, methods) {
|
|||
k, seg,
|
||||
event,
|
||||
className,
|
||||
//startElm, endElm,
|
||||
left, right,
|
||||
eventElement, eventAnchor,
|
||||
triggerRes;
|
||||
|
||||
function tbodyLeft() {
|
||||
return 0;
|
||||
}
|
||||
|
||||
var tbodyw;
|
||||
function tbodyRight() {
|
||||
if (tbodyw == undefined) {
|
||||
tbodyw = tbody.width();
|
||||
}
|
||||
return tbodyw;
|
||||
}
|
||||
|
||||
var dayContentElements = [];
|
||||
function dayContentElement(dayOfWeek) {
|
||||
if (dayContentElements[dayOfWeek] == undefined) {
|
||||
dayContentElements[dayOfWeek] = tr.find('td:eq(' + ((dayOfWeek - Math.max(firstDay,nwe)+colCnt) % colCnt) + ') div div');
|
||||
}
|
||||
return dayContentElements[dayOfWeek];
|
||||
}
|
||||
|
||||
var dayContentLefts = [];
|
||||
function dayContentLeft(dayOfWeek) {
|
||||
if (dayContentLefts[dayOfWeek] == undefined) {
|
||||
dayContentLefts[dayOfWeek] = dayContentElement(dayOfWeek).position().left;
|
||||
}
|
||||
return dayContentLefts[dayOfWeek];
|
||||
}
|
||||
|
||||
var dayContentRights = [];
|
||||
function dayContentRight(dayOfWeek) {
|
||||
if (dayContentRights[dayOfWeek] == undefined) {
|
||||
dayContentRights[dayOfWeek] = dayContentLeft(dayOfWeek) + dayContentElement(dayOfWeek).width();
|
||||
}
|
||||
return dayContentRights[dayOfWeek];
|
||||
}
|
||||
|
||||
for (i=0; i<len; i++) {
|
||||
levels = segRows[i];
|
||||
tr = tbody.find('tr:eq('+i+')');
|
||||
|
@ -452,19 +587,9 @@ function Grid(element, options, methods) {
|
|||
seg = segs[k];
|
||||
event = seg.event;
|
||||
className = 'fc-event fc-event-hori ';
|
||||
/*
|
||||
startElm = seg.isStart ?
|
||||
tr.find('td:eq('+((seg.start.getDay()-Math.max(firstDay,nwe)+colCnt)%colCnt)+') div div') :
|
||||
tbody;
|
||||
endElm = seg.isEnd ?
|
||||
tr.find('td:eq('+((seg.end.getDay()-Math.max(firstDay,nwe)+colCnt-1)%colCnt)+') div div') :
|
||||
tbody;
|
||||
*/
|
||||
if (rtl) {
|
||||
left = seg.isEnd ? tbodyLeft() : dayContentLeft(seg.end.getDay()-1);
|
||||
right = seg.isStart ? tbodyRight() : dayContentRight(seg.start.getDay());
|
||||
//left = endElm.position().left;
|
||||
//right = startElm.position().left + startElm.width();
|
||||
left = seg.isEnd ? 0 : dayContentLeft(seg.end.getDay()-1);
|
||||
right = seg.isStart ? viewWidth : dayContentRight(seg.start.getDay());
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-right ';
|
||||
}
|
||||
|
@ -472,10 +597,8 @@ function Grid(element, options, methods) {
|
|||
className += 'fc-corner-left ';
|
||||
}
|
||||
}else{
|
||||
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : tbodyLeft();
|
||||
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : tbodyRight();
|
||||
//left = startElm.position().left;
|
||||
//right = endElm.position().left + endElm.width();
|
||||
left = seg.isStart ? dayContentLeft(seg.start.getDay()) : 0;
|
||||
right = seg.isEnd ? dayContentRight(seg.end.getDay()-1) : viewWidth;
|
||||
if (seg.isStart) {
|
||||
className += 'fc-corner-left ';
|
||||
}
|
||||
|
@ -532,6 +655,37 @@ function Grid(element, options, methods) {
|
|||
innerDiv.height(rowContentHeight);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
|
||||
|
||||
function visEventEnd(event) { // returns exclusive 'visible' end, for rendering
|
||||
if (event.end) {
|
||||
var end = cloneDate(event.end);
|
||||
return (event.allDay || end.getHours() || end.getMinutes()) ? addDays(end, 1) : end;
|
||||
}else{
|
||||
return addDays(cloneDate(event.start), 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
function bootstrapEventHandlers(event, seg, eventElement) {
|
||||
var attached = false;
|
||||
eventElement.mouseover(function(ev) {
|
||||
if (!attached) {
|
||||
view.eventElementHandlers(event, eventElement);
|
||||
if (event.editable || event.editable == undefined && options.editable) {
|
||||
draggableEvent(event, eventElement);
|
||||
if (seg.isEnd) {
|
||||
view.resizableDayEvent(event, eventElement, colWidth);
|
||||
}
|
||||
}
|
||||
attached = true;
|
||||
view.trigger('eventMouseover', this, event, ev);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
|
4389
src/jquery/jquery-uncompressed.js
vendored
Normal file
4389
src/jquery/jquery-uncompressed.js
vendored
Normal file
File diff suppressed because it is too large
Load diff
26
src/main.js
26
src/main.js
|
@ -149,7 +149,9 @@ $.fn.fullCalendar = function(options) {
|
|||
element = $(_element).addClass('fc'),
|
||||
elementWidth,
|
||||
content = $("<div class='fc-content " + tm + "-widget-content' style='position:relative'/>").prependTo(_element), // relative for ie6
|
||||
contentWidth,
|
||||
contentHeight;
|
||||
|
||||
if (options.isRTL) {
|
||||
element.addClass('fc-rtl');
|
||||
}
|
||||
|
@ -214,11 +216,12 @@ $.fn.fullCalendar = function(options) {
|
|||
function render(inc, forceUpdateSize) {
|
||||
if ((elementWidth = _element.offsetWidth) !== 0) { // visible on the screen
|
||||
if (!contentHeight) {
|
||||
contentWidth = content.width();
|
||||
contentHeight = calculateContentHeight();
|
||||
}
|
||||
if (inc || !view.date || +view.date != +date) { // !view.date means it hasn't been rendered yet
|
||||
fixContentSize();
|
||||
view.render(date, inc || 0, contentHeight, function(callback) {
|
||||
view.render(date, inc || 0, contentWidth, contentHeight, function(callback) {
|
||||
// dont refetch if new view contains the same events (or a subset)
|
||||
if (!eventStart || view.visStart < eventStart || view.visEnd > eventEnd) {
|
||||
fetchEvents(callback);
|
||||
|
@ -230,12 +233,14 @@ $.fn.fullCalendar = function(options) {
|
|||
view.date = cloneDate(date);
|
||||
}
|
||||
else if (view.sizeDirty || forceUpdateSize) {
|
||||
view.updateSize(contentHeight);
|
||||
view.rerenderEvents();
|
||||
view.updateSize(contentWidth, contentHeight);
|
||||
view.rerenderEvents(); // TODO: could probably skip recompile??
|
||||
}
|
||||
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
|
||||
// TODO: should this be inclusive with sizeDirty and forceUpdateSize??
|
||||
view.clearEvents();
|
||||
view.renderEvents(events);
|
||||
}
|
||||
|
@ -257,7 +262,7 @@ $.fn.fullCalendar = function(options) {
|
|||
}
|
||||
|
||||
// marks other views' events as dirty
|
||||
function eventsDirtyExcept(exceptView) {
|
||||
function eventsDirtyExcept(exceptView) { // TODO: otherViewsEventsDirty
|
||||
$.each(viewInstances, function() {
|
||||
if (this != exceptView) {
|
||||
this.eventsDirty = true;
|
||||
|
@ -283,16 +288,17 @@ $.fn.fullCalendar = function(options) {
|
|||
|
||||
// called when we know the element size has changed
|
||||
function sizeChanged(fix) {
|
||||
contentWidth = content.width();
|
||||
contentHeight = calculateContentHeight();
|
||||
if (fix) {
|
||||
fixContentSize();
|
||||
}
|
||||
view.updateSize(contentHeight);
|
||||
view.updateSize(contentWidth, contentHeight);
|
||||
if (fix) {
|
||||
unfixContentSize();
|
||||
}
|
||||
sizesDirtyExcept(view);
|
||||
view.rerenderEvents(true);
|
||||
view.rerenderEvents();
|
||||
}
|
||||
|
||||
// calculate what the height of the content should be
|
||||
|
@ -301,9 +307,9 @@ $.fn.fullCalendar = function(options) {
|
|||
return options.contentHeight;
|
||||
}
|
||||
else if (options.height) {
|
||||
return options.height - (header ? header.height() : 0) - horizontalSides(content);
|
||||
return options.height - (header ? header.height() : 0) - horizontalSides(content); // TODO: shouldn't this be vertical sides??
|
||||
}
|
||||
return elementWidth / Math.max(options.aspectRatio, .5);
|
||||
return Math.round(contentWidth / Math.max(options.aspectRatio, .5));
|
||||
}
|
||||
|
||||
|
||||
|
@ -776,7 +782,7 @@ $.fn.fullCalendar = function(options) {
|
|||
}
|
||||
}
|
||||
};
|
||||
$(window).resize(windowResize);
|
||||
//$(window).resize(windowResize);
|
||||
|
||||
|
||||
// let's begin...
|
||||
|
@ -787,7 +793,7 @@ $.fn.fullCalendar = function(options) {
|
|||
setTimeout(function() {
|
||||
render();
|
||||
content.hide().show(); // needed for IE 6
|
||||
view.rerenderEvents(); // needed for IE 7
|
||||
view.rerenderEvents(); // needed for IE 7 // TODO: could probably skip recompile
|
||||
}, 0);
|
||||
}
|
||||
|
||||
|
|
43
src/util.js
43
src/util.js
|
@ -296,42 +296,38 @@ var dateFormatters = {
|
|||
/* Element Dimensions
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
function setOuterWidth(element, width, includeMargins) {
|
||||
function setOuterWidth(element, width, includeMargins) { // TODO: probably eventually remove this
|
||||
element.each(function() {
|
||||
var e = $(this);
|
||||
var w = width - horizontalSides(e);
|
||||
if (includeMargins) {
|
||||
w -= (parseInt(e.css('margin-left')) || 0) +
|
||||
(parseInt(e.css('margin-right')) || 0);
|
||||
}
|
||||
e.width(w);
|
||||
e.width(width - hsides(e, includeMargins));
|
||||
});
|
||||
}
|
||||
|
||||
function horizontalSides(e) {
|
||||
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);
|
||||
(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) {
|
||||
function setOuterHeight(element, height, includeMargins) { // TODO: probably eventually remove this
|
||||
element.each(function() {
|
||||
var e = $(this);
|
||||
var h = height - verticalSides(e);
|
||||
if (includeMargins) {
|
||||
h -= (parseInt(e.css('margin-top')) || 0) +
|
||||
(parseInt(e.css('margin-bottom')) || 0);
|
||||
}
|
||||
e.height(h);
|
||||
e.height(height - vsides(e, includeMargins));
|
||||
});
|
||||
}
|
||||
|
||||
function verticalSides(e) {
|
||||
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);
|
||||
(parseInt(e.css('border-bottom-width')) || 0) +
|
||||
(includeMargins ?
|
||||
(parseInt(e.css('margin-top')) || 0) + (parseInt(e.css('margin-bottom')) || 0)
|
||||
: 0);
|
||||
}
|
||||
|
||||
|
||||
|
@ -432,7 +428,7 @@ function zeroPad(n) {
|
|||
return (n < 10 ? '0' : '') + n;
|
||||
}
|
||||
|
||||
function smartProperty(obj, name) { // get a camel-cased/namespaced property
|
||||
function smartProperty(obj, name) { // get a camel-cased/namespaced property of an object
|
||||
if (obj[name] != undefined) {
|
||||
return obj[name];
|
||||
}
|
||||
|
@ -447,4 +443,13 @@ function smartProperty(obj, name) { // get a camel-cased/namespaced property
|
|||
return obj[''];
|
||||
}
|
||||
|
||||
function htmlEscape(s) {
|
||||
return s
|
||||
.replace(/&/g, '&')
|
||||
.replace(/</g, '<')
|
||||
.replace(/>/g, '>')
|
||||
.replace(/'/g, ''')
|
||||
.replace(/"/g, '"')
|
||||
}
|
||||
|
||||
|
||||
|
|
15
src/view.js
15
src/view.js
|
@ -14,7 +14,6 @@ var viewMethods = {
|
|||
* - visStart
|
||||
* - visEnd
|
||||
* - defaultEventEnd(event)
|
||||
* - visEventEnd(event)
|
||||
* - render(events)
|
||||
* - rerenderEvents()
|
||||
*
|
||||
|
@ -31,7 +30,6 @@ var viewMethods = {
|
|||
init: function(element, options) {
|
||||
this.element = element;
|
||||
this.options = options;
|
||||
this.cachedEvents = [];
|
||||
this.eventsByID = {};
|
||||
this.eventElements = [];
|
||||
this.eventElementsByID = {};
|
||||
|
@ -61,8 +59,7 @@ var viewMethods = {
|
|||
|
||||
reportEvents: function(events) { // events are already normalized at this point
|
||||
var i, len=events.length, event,
|
||||
eventsByID = this.eventsByID = {},
|
||||
cachedEvents = this.cachedEvents = [];
|
||||
eventsByID = this.eventsByID = {};
|
||||
for (i=0; i<len; i++) {
|
||||
event = events[i];
|
||||
if (eventsByID[event._id]) {
|
||||
|
@ -70,7 +67,6 @@ var viewMethods = {
|
|||
}else{
|
||||
eventsByID[event._id] = [event];
|
||||
}
|
||||
cachedEvents.push(event);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -92,10 +88,7 @@ var viewMethods = {
|
|||
|
||||
// event element manipulation
|
||||
|
||||
clearEvents: function() { // only remove ELEMENTS
|
||||
$.each(this.eventElements, function() {
|
||||
this.remove();
|
||||
});
|
||||
_clearEvents: function() { // only resets hashes
|
||||
this.eventElements = [];
|
||||
this.eventElementsByID = {};
|
||||
},
|
||||
|
@ -273,7 +266,7 @@ var viewMethods = {
|
|||
|
||||
// event rendering utilities
|
||||
|
||||
sliceSegs: function(events, start, end) {
|
||||
sliceSegs: function(events, visEventEnds, start, end) {
|
||||
var segs = [],
|
||||
i, len=events.length, event,
|
||||
eventStart, eventEnd,
|
||||
|
@ -282,7 +275,7 @@ var viewMethods = {
|
|||
for (i=0; i<len; i++) {
|
||||
event = events[i];
|
||||
eventStart = event.start;
|
||||
eventEnd = this.visEventEnd(event);
|
||||
eventEnd = visEventEnds[i];
|
||||
if (eventEnd > start && eventStart < end) {
|
||||
if (eventStart < start) {
|
||||
segStart = cloneDate(start);
|
||||
|
|
|
@ -63,7 +63,7 @@ else if (_build) {
|
|||
includeJS('../build/fullcalendar/jquery/ui.resizable.js');
|
||||
}
|
||||
else {
|
||||
includeJS('../src/jquery/jquery.js');
|
||||
includeJS('../src/jquery/jquery-uncompressed.js');
|
||||
includeJS('../src/jquery/ui.core.js');
|
||||
includeJS('../src/jquery/ui.draggable.js');
|
||||
includeJS('../src/jquery/ui.resizable.js');
|
||||
|
|
|
@ -19,7 +19,7 @@
|
|||
center: 'title',
|
||||
right: 'month,agendaWeek,basicWeek,agendaDay,basicDay'
|
||||
},
|
||||
//editable: true,
|
||||
editable: true,
|
||||
events: 'many_events_json.txt'
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue