/* A utility class for rendering
rows.
----------------------------------------------------------------------------------------------------------------------*/
// It leverages methods of the subclass and the View to determine custom rendering behavior for each row "type"
// (such as highlight rows, day rows, helper rows, etc).
function RowRenderer(view) {
this.view = view;
}
RowRenderer.prototype = {
view: null, // a View object
cellHtml: ' | ', // plain default HTML used for a cell when no other is available
// Renders the HTML for a row, leveraging custom cell-HTML-renderers based on the `rowType`.
// Also applies the "intro" and "outro" cells, which are specified by the subclass and views.
// `row` is an optional row number.
rowHtml: function(rowType, row) {
var view = this.view;
var renderCell = this.getHtmlRenderer('cell', rowType);
var cellHtml = '';
var col;
var date;
row = row || 0;
for (col = 0; col < view.colCnt; col++) {
date = view.cellToDate(row, col);
cellHtml += renderCell(row, col, date);
}
cellHtml = this.bookendCells(cellHtml, rowType, row); // apply intro and outro
return '
' + cellHtml + '
';
},
// Applies the "intro" and "outro" HTML to the given cells.
// Intro means the leftmost cell when the calendar is LTR and the rightmost cell when RTL. Vice-versa for outro.
// `cells` can be an HTML string of 's or a jQuery | element
// `row` is an optional row number.
bookendCells: function(cells, rowType, row) {
var view = this.view;
var intro = this.getHtmlRenderer('intro', rowType)(row || 0);
var outro = this.getHtmlRenderer('outro', rowType)(row || 0);
var isRTL = view.opt('isRTL');
var prependHtml = isRTL ? outro : intro;
var appendHtml = isRTL ? intro : outro;
if (typeof cells === 'string') {
return prependHtml + cells + appendHtml;
}
else { // a jQuery
element
return cells.prepend(prependHtml).append(appendHtml);
}
},
// Returns an HTML-rendering function given a specific `rendererName` (like cell, intro, or outro) and a specific
// `rowType` (like day, eventSkeleton, helperSkeleton), which is optional.
// If a renderer for the specific rowType doesn't exist, it will fall back to a generic renderer.
// We will query the View object first for any custom rendering functions, then the methods of the subclass.
getHtmlRenderer: function(rendererName, rowType) {
var view = this.view;
var generalName; // like "cellHtml"
var specificName; // like "dayCellHtml". based on rowType
var provider; // either the View or the RowRenderer subclass, whichever provided the method
var renderer;
generalName = rendererName + 'Html';
if (rowType) {
specificName = rowType + capitaliseFirstLetter(rendererName) + 'Html';
}
if (specificName && (renderer = view[specificName])) {
provider = view;
}
else if (specificName && (renderer = this[specificName])) {
provider = this;
}
else if ((renderer = view[generalName])) {
provider = view;
}
else if ((renderer = this[generalName])) {
provider = this;
}
if (typeof renderer === 'function') {
return function(row) {
return renderer.apply(provider, arguments) || ''; // use correct `this` and always return a string
};
}
// the rendered can be a plain string as well. if not specified, always an empty string.
return function() {
return renderer || '';
};
}
};