diff forum/Themes/Vamp/scripts/stats.js @ 76:e3e11437ecea website

Add forum code
author Chris Cannam
date Sun, 07 Jul 2013 11:25:48 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/forum/Themes/Vamp/scripts/stats.js	Sun Jul 07 11:25:48 2013 +0200
@@ -0,0 +1,239 @@
+function smf_StatsCenter(oOptions)
+{
+	this.opt = oOptions;
+
+	this.oTable = null;
+	this.oYears = {};
+
+	this.bIsLoading = false;
+
+	this.init();
+}
+
+smf_StatsCenter.prototype.init = function ()
+{
+	this.oTable = document.getElementById(this.opt.sTableId);
+
+	// Is the table actually present?
+	if (typeof(this.oTable) != 'object')
+		return;
+
+	// Find all months and years defined in the table.
+	var aRows = this.oTable.getElementsByTagName('tr');
+	var aResults = [];
+
+	var sYearId = null;
+	var oCurYear = null;
+
+	var sMonthId = null;
+	var oCurMonth = null;
+	for (var i = 0, n = aRows.length; i < n; i++)
+	{
+		// Check if the current row represents a year.
+		if ((aResults = this.opt.reYearPattern.exec(aRows[i].id)) != null)
+		{
+			// The id is part of the pattern match.
+			sYearId = aResults[1];
+
+			// Setup the object that'll have the state information of the year.
+			this.oYears[sYearId] = {
+				oCollapseImage: document.getElementById(this.opt.sYearImageIdPrefix + sYearId),
+				oMonths: {}
+			};
+
+			// Create a shortcut, makes things more readable.
+			oCurYear = this.oYears[sYearId];
+
+			// Use the collapse image to determine the current state.
+			oCurYear.bIsCollapsed = oCurYear.oCollapseImage.src.indexOf(this.opt.sYearImageCollapsed) >= 0;
+
+			// Setup the toggle element for the year.
+			oCurYear.oToggle = new smc_Toggle({
+				bToggleEnabled: true,
+				bCurrentlyCollapsed: oCurYear.bIsCollapsed,
+				instanceRef: this,
+				sYearId: sYearId,
+				funcOnBeforeCollapse: function () {
+					this.opt.instanceRef.onBeforeCollapseYear(this);
+				},
+				aSwappableContainers: [
+				],
+				aSwapImages: [
+					{
+						sId: this.opt.sYearImageIdPrefix + sYearId,
+						srcExpanded: smf_images_url + '/' + this.opt.sYearImageExpanded,
+						altExpanded: '-',
+						srcCollapsed: smf_images_url + '/' + this.opt.sYearImageCollapsed,
+						altCollapsed: '+'
+					}
+				],
+				aSwapLinks: [
+					{
+						sId: this.opt.sYearLinkIdPrefix + sYearId,
+						msgExpanded: sYearId,
+						msgCollapsed: sYearId
+					}
+				]
+			});
+		}
+
+		// Or maybe the current row represents a month.
+		else if ((aResults = this.opt.reMonthPattern.exec(aRows[i].id)) != null)
+		{
+			// Set the id to the matched pattern.
+			sMonthId = aResults[1];
+
+			// Initialize the month as a child object of the year.
+			oCurYear.oMonths[sMonthId] = {
+				oCollapseImage: document.getElementById(this.opt.sMonthImageIdPrefix + sMonthId)
+			};
+
+			// Create a shortcut to the current month.
+			oCurMonth = oCurYear.oMonths[sMonthId];
+
+			// Determine whether the month is currently collapsed or expanded..
+			oCurMonth.bIsCollapsed = oCurMonth.oCollapseImage.src.indexOf(this.opt.sMonthImageCollapsed) >= 0;
+
+			var sLinkText = getInnerHTML(document.getElementById(this.opt.sMonthLinkIdPrefix + sMonthId));
+
+			// Setup the toggle element for the month.
+			oCurMonth.oToggle = new smc_Toggle({
+				bToggleEnabled: true,
+				bCurrentlyCollapsed: oCurMonth.bIsCollapsed,
+				instanceRef: this,
+				sMonthId: sMonthId,
+				funcOnBeforeCollapse: function () {
+					this.opt.instanceRef.onBeforeCollapseMonth(this);
+				},
+				funcOnBeforeExpand: function () {
+					this.opt.instanceRef.onBeforeExpandMonth(this);
+				},
+				aSwappableContainers: [
+				],
+				aSwapImages: [
+					{
+						sId: this.opt.sMonthImageIdPrefix + sMonthId,
+						srcExpanded: smf_images_url + '/' + this.opt.sMonthImageExpanded,
+						altExpanded: '-',
+						srcCollapsed: smf_images_url + '/' + this.opt.sMonthImageCollapsed,
+						altCollapsed: '+'
+					}
+				],
+				aSwapLinks: [
+					{
+						sId: this.opt.sMonthLinkIdPrefix +  sMonthId,
+						msgExpanded: sLinkText,
+						msgCollapsed: sLinkText
+					}
+				]
+			});
+
+			oCurYear.oToggle.opt.aSwappableContainers[oCurYear.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
+		}
+
+		else if((aResults = this.opt.reDayPattern.exec(aRows[i].id)) != null)
+		{
+			oCurMonth.oToggle.opt.aSwappableContainers[oCurMonth.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
+			oCurYear.oToggle.opt.aSwappableContainers[oCurYear.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
+		}
+	}
+
+	// Collapse all collapsed years!
+	for (i = 0; i < this.opt.aCollapsedYears.length; i++)
+		this.oYears[this.opt.aCollapsedYears[i]].oToggle.toggle();
+}
+
+smf_StatsCenter.prototype.onBeforeCollapseYear = function (oToggle)
+{
+	// Tell SMF that all underlying months have disappeared.
+	for (var sMonth in this.oYears[oToggle.opt.sYearId].oMonths)
+		if (this.oYears[oToggle.opt.sYearId].oMonths[sMonth].oToggle.opt.aSwappableContainers.length > 0)
+			this.oYears[oToggle.opt.sYearId].oMonths[sMonth].oToggle.changeState(true);
+}
+
+
+smf_StatsCenter.prototype.onBeforeCollapseMonth = function (oToggle)
+{
+	if (!oToggle.bCollapsed)
+	{
+		// Tell SMF that it the state has changed.
+		getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + 'action=stats;collapse=' + oToggle.opt.sMonthId + ';xml');
+
+		// Remove the month rows from the year toggle.
+		var aNewContainers = [];
+		var oYearToggle = this.oYears[oToggle.opt.sMonthId.substr(0, 4)].oToggle;
+
+		for (var i = 0, n = oYearToggle.opt.aSwappableContainers.length; i < n; i++)
+			if (!in_array(oYearToggle.opt.aSwappableContainers[i], oToggle.opt.aSwappableContainers))
+				aNewContainers[aNewContainers.length] = oYearToggle.opt.aSwappableContainers[i];
+
+		oYearToggle.opt.aSwappableContainers = aNewContainers;
+	}
+}
+
+
+smf_StatsCenter.prototype.onBeforeExpandMonth = function (oToggle)
+{
+	// Ignore if we're still loading the previous batch.
+	if (this.bIsLoading)
+		return;
+
+	if (oToggle.opt.aSwappableContainers.length == 0)
+	{
+		// A complicated way to call getXMLDocument, but stay in scope.
+		this.tmpMethod = getXMLDocument;
+		this.oXmlRequestHandle = this.tmpMethod(smf_prepareScriptUrl(smf_scripturl) + 'action=stats;expand=' + oToggle.opt.sMonthId + ';xml', this.onDocReceived);
+		delete this.tmpMethod;
+
+		if ('ajax_indicator' in window)
+			ajax_indicator(true);
+
+		this.bIsLoading = true;
+	}
+
+	// Silently let SMF know this one is expanded.
+	else
+		getXMLDocument(smf_prepareScriptUrl(smf_scripturl) + 'action=stats;expand=' + oToggle.opt.sMonthId + ';xml');
+}
+
+smf_StatsCenter.prototype.onDocReceived = function (oXMLDoc)
+{
+	// Loop through all the months we got from the XML.
+	var aMonthNodes = oXMLDoc.getElementsByTagName('month');
+	for (var iMonthIndex = 0, iNumMonths = aMonthNodes.length; iMonthIndex < iNumMonths; iMonthIndex++)
+	{
+		var sMonthId = aMonthNodes[iMonthIndex].getAttribute('id');
+		var iStart = document.getElementById('tr_month_' + sMonthId).rowIndex + 1;
+		var sYearId = sMonthId.substr(0, 4);
+
+		// Within the current months, check out all the days.
+		var aDayNodes = aMonthNodes[iMonthIndex].getElementsByTagName('day');
+		for (var iDayIndex = 0, iNumDays = aDayNodes.length; iDayIndex < iNumDays; iDayIndex++)
+		{
+			var oCurRow = this.oTable.insertRow(iStart + iDayIndex);
+			oCurRow.className = this.opt.sDayRowClassname;
+			oCurRow.id = this.opt.sDayRowIdPrefix + aDayNodes[iDayIndex].getAttribute('date');
+
+			for (var iCellIndex = 0, iNumCells = this.opt.aDataCells.length; iCellIndex < iNumCells; iCellIndex++)
+			{
+				var oCurCell = oCurRow.insertCell(-1);
+
+				if (this.opt.aDataCells[iCellIndex] == 'date')
+					oCurCell.style.paddingLeft = '6ex';
+				else
+					oCurCell.style.textAlign = 'center';
+
+				var sCurData = aDayNodes[iDayIndex].getAttribute(this.opt.aDataCells[iCellIndex]);
+				oCurCell.appendChild(document.createTextNode(sCurData));
+			}
+
+			// Add these day rows to the toggle objects in case of collapse.
+			this.oYears[sYearId].oMonths[sMonthId].oToggle.opt.aSwappableContainers[this.oYears[sYearId].oMonths[sMonthId].oToggle.opt.aSwappableContainers.length] = oCurRow.id;
+			this.oYears[sYearId].oToggle.opt.aSwappableContainers[this.oYears[sYearId].oToggle.opt.aSwappableContainers.length] = oCurRow.id;
+		}
+	}
+
+	this.bIsLoading = false;
+	if (typeof(window.ajax_indicator) == 'function')
+		ajax_indicator(false);
+}
\ No newline at end of file