Issues (1686)

themes/default/scripts/stats.js (13 issues)

1
/*!
2
 * @package   ElkArte Forum
3
 * @copyright ElkArte Forum contributors
4
 * @license   BSD http://opensource.org/licenses/BSD-3-Clause (see accompanying LICENSE.txt file)
5
 *
6
 * This file contains code covered by:
7
 * copyright: 2011 Simple Machines (http://www.simplemachines.org)
8
 *
9
 * @version 2.0 dev
10
 */
11
12
/**
13
 * This file contains javascript associated with the displaying statistics and the like
14
 */
15
16
/**
17
 * Stats object for expanding / collapsing the forum year/month stats section
18
 *
19
 * @param {object} oOptions
20
 */
21
function elk_StatsCenter (oOptions)
22
{
23
	this.opt = oOptions;
24
	this.oTable = null;
25
	this.oYears = {};
26
	this.bIsLoading = false;
27
28
	this.init();
29
}
30
31
// Start up the stats area, current year/month expanded, all others collapsed and ready for action
32
elk_StatsCenter.prototype.init = function() {
33
	this.oTable = document.getElementById(this.opt.sTableId);
34
35
	// Is the table actually present?
36
	if (typeof (this.oTable) !== 'object')
37
	{
38
		return;
39
	}
40
41
	// Find all months and years defined in the table.
42
	let aRows = this.oTable.getElementsByTagName('tr'),
43
		aResults = [],
0 ignored issues
show
The assignment to variable aResults seems to be never used. Consider removing it.
Loading history...
44
		sYearId = null,
0 ignored issues
show
The assignment to sYearId seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
45
		oCurYear = null,
46
		sMonthId = null,
0 ignored issues
show
The assignment to sMonthId seems to be never used. If you intend to free memory here, this is not necessary since the variable leaves the scope anyway.
Loading history...
47
		oCurMonth = null;
48
49
	for (let i = 0, n = aRows.length; i < n; i++)
50
	{
51
		// Check if the current row represents a year.
52
		if ((aResults = this.opt.reYearPattern.exec(aRows[i].id)) !== null)
53
		{
54
			// The id is part of the pattern match.
55
			sYearId = aResults[1];
56
57
			// Setup the object that'll have the state information of the year.
58
			this.oYears[sYearId] = {
59
				oCollapseImage: document.getElementById(this.opt.sYearImageIdPrefix + sYearId),
60
				oMonths: {}
61
			};
62
63
			// Create a shortcut, makes things more readable.
64
			oCurYear = this.oYears[sYearId];
65
66
			// Use the collapse image to determine the current state.
67
			oCurYear.bIsCollapsed = oCurYear.oCollapseImage.src.indexOf(this.opt.sYearImageCollapsed) >= 0;
68
69
			// Setup the toggle element for the year.
70
			oCurYear.oToggle = new elk_Toggle({
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like elk_Toggle should be capitalized.
Loading history...
The variable elk_Toggle seems to be never declared. If this is a global, consider adding a /** global: elk_Toggle */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
71
				bToggleEnabled: true,
72
				bCurrentlyCollapsed: oCurYear.bIsCollapsed,
73
				instanceRef: this,
74
				sYearId: sYearId,
75
				funcOnBeforeCollapse: function() {
76
					this.opt.instanceRef.onBeforeCollapseYear(this);
77
				},
78
				aSwappableContainers: [],
79
				aSwapImages: [
80
					{
81
						sId: this.opt.sYearImageIdPrefix + sYearId,
82
						srcExpanded: elk_images_url + '/' + this.opt.sYearImageExpanded,
0 ignored issues
show
The variable elk_images_url seems to be never declared. If this is a global, consider adding a /** global: elk_images_url */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
83
						altExpanded: '&#9650;',
84
						srcCollapsed: elk_images_url + '/' + this.opt.sYearImageCollapsed,
85
						altCollapsed: '&#9660;'
86
					}
87
				],
88
				aSwapLinks: [
89
					{
90
						sId: this.opt.sYearLinkIdPrefix + sYearId,
91
						msgExpanded: sYearId,
92
						msgCollapsed: sYearId
93
					}
94
				]
95
			});
96
		}
97
		// Or maybe the current row represents a month.
98
		else if ((aResults = this.opt.reMonthPattern.exec(aRows[i].id)) !== null)
99
		{
100
			// Set the id to the matched pattern.
101
			sMonthId = aResults[1];
102
103
			// Initialize the month as a child object of the year.
104
			oCurYear.oMonths[sMonthId] = {
105
				oCollapseImage: document.getElementById(this.opt.sMonthImageIdPrefix + sMonthId)
106
			};
107
108
			// Create a shortcut to the current month.
109
			oCurMonth = oCurYear.oMonths[sMonthId];
110
111
			// Determine whether the month is currently collapsed or expanded..
112
			oCurMonth.bIsCollapsed = oCurMonth.oCollapseImage.src.indexOf(this.opt.sMonthImageCollapsed) >= 0;
113
114
			let sLinkText = document.getElementById(this.opt.sMonthLinkIdPrefix + sMonthId).innerHTML;
115
116
			// Setup the toggle element for the month.
117
			oCurMonth.oToggle = new elk_Toggle({
0 ignored issues
show
Coding Style Best Practice introduced by
By convention, constructors like elk_Toggle should be capitalized.
Loading history...
118
				bToggleEnabled: true,
119
				bCurrentlyCollapsed: oCurMonth.bIsCollapsed,
120
				instanceRef: this,
121
				sMonthId: sMonthId,
122
				funcOnBeforeCollapse: function() {
123
					this.opt.instanceRef.onBeforeCollapseMonth(this);
124
				},
125
				funcOnBeforeExpand: function() {
126
					this.opt.instanceRef.onBeforeExpandMonth(this);
127
				},
128
				aSwappableContainers: [],
129
				aSwapImages: [
130
					{
131
						sId: this.opt.sMonthImageIdPrefix + sMonthId,
132
						srcExpanded: elk_images_url + '/' + this.opt.sMonthImageExpanded,
133
						altExpanded: '&#9650;',
134
						srcCollapsed: elk_images_url + '/' + this.opt.sMonthImageCollapsed,
135
						altCollapsed: '&#9660;'
136
					}
137
				],
138
				aSwapLinks: [
139
					{
140
						sId: this.opt.sMonthLinkIdPrefix + sMonthId,
141
						msgExpanded: sLinkText,
142
						msgCollapsed: sLinkText
143
					}
144
				]
145
			});
146
147
			oCurYear.oToggle.opt.aSwappableContainers[oCurYear.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
148
		}
149
		// Must be a day then
150
		else if ((aResults = this.opt.reDayPattern.exec(aRows[i].id)) !== null)
151
		{
152
			oCurMonth.oToggle.opt.aSwappableContainers[oCurMonth.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
153
			oCurYear.oToggle.opt.aSwappableContainers[oCurYear.oToggle.opt.aSwappableContainers.length] = aRows[i].id;
154
		}
155
	}
156
157
	// Collapse all collapsed years!
158
	for (i = 0; i < this.opt.aCollapsedYears.length; i++)
0 ignored issues
show
The variable i seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.i.
Loading history...
159
	{
160
		this.oYears[this.opt.aCollapsedYears[i]].oToggle.toggle();
161
	}
162
};
163
164
// Helper function for year collapsing, close the months first
165
elk_StatsCenter.prototype.onBeforeCollapseYear = function(oToggle) {
166
	// Tell ElkArte that all underlying months have disappeared.
167
	for (let sMonth in this.oYears[oToggle.opt.sYearId].oMonths)
168
	{
169
		if (this.oYears[oToggle.opt.sYearId].oMonths[sMonth].oToggle.opt.aSwappableContainers.length > 0)
170
		{
171
			this.oYears[oToggle.opt.sYearId].oMonths[sMonth].oToggle.changeState(true);
172
		}
173
	}
174
};
175
176
// Helper function, called before the month is collapsed
177
elk_StatsCenter.prototype.onBeforeCollapseMonth = function(oToggle) {
178
	if (!oToggle.bCollapsed)
179
	{
180
		// Tell ElkArte that the state has changed.
181
		getXMLDocument(elk_prepareScriptUrl(elk_scripturl) + 'action=stats;collapse=' + oToggle.opt.sMonthId + ';api=xml');
0 ignored issues
show
The variable elk_scripturl seems to be never declared. If this is a global, consider adding a /** global: elk_scripturl */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
182
183
		// Remove the month rows from the year toggle.
184
		let aNewContainers = [],
185
			oYearToggle = this.oYears[oToggle.opt.sMonthId.substr(0, 4)].oToggle;
186
187
		for (let i = 0, n = oYearToggle.opt.aSwappableContainers.length; i < n; i++)
188
		{
189
			if (!in_array(oYearToggle.opt.aSwappableContainers[i], oToggle.opt.aSwappableContainers))
190
			{
191
				aNewContainers[aNewContainers.length] = oYearToggle.opt.aSwappableContainers[i];
192
			}
193
		}
194
195
		oYearToggle.opt.aSwappableContainers = aNewContainers;
196
	}
197
};
198
199
// Helper function, called before the month is expanded out, makes the ajax call to get the data
200
elk_StatsCenter.prototype.onBeforeExpandMonth = function(oToggle) {
201
	// Ignore if we're still loading the previous batch.
202
	if (this.bIsLoading)
203
	{
204
		return;
205
	}
206
207
	if (oToggle.opt.aSwappableContainers.length === 0)
208
	{
209
		// Make the ajax call
210
		sendXMLDocument.call(this, elk_prepareScriptUrl(elk_scripturl) + 'action=stats;expand=' + oToggle.opt.sMonthId + ';api=xml', '', this.onDocReceived);
0 ignored issues
show
The variable elk_scripturl seems to be never declared. If this is a global, consider adding a /** global: elk_scripturl */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
The variable sendXMLDocument seems to be never declared. If this is a global, consider adding a /** global: sendXMLDocument */ comment.

This checks looks for references to variables that have not been declared. This is most likey a typographical error or a variable has been renamed.

To learn more about declaring variables in Javascript, see the MDN.

Loading history...
211
212
		if ('ajax_indicator' in window)
213
		{
214
			ajax_indicator(true);
215
		}
216
217
		this.bIsLoading = true;
218
	}
219
	// Silently let ElkArte know this one is expanded.
220
	else
221
	{
222
		getXMLDocument(elk_prepareScriptUrl(elk_scripturl) + 'action=stats;expand=' + oToggle.opt.sMonthId + ';api=xml');
223
	}
224
};
225
226
// Callback for the ajax call to get the statistical information for the expanded section
227
elk_StatsCenter.prototype.onDocReceived = function(oXMLDoc) {
228
	// Loop through all the months we got from the XML.
229
	let aMonthNodes = oXMLDoc.getElementsByTagName('month');
230
231
	// All the data to expand
232
	let sMonthId,
233
		iStart,
234
		sYearId,
235
		aDayNodes,
236
		iDayIndex,
237
		oCurRow,
238
		oCurCell,
239
		sCurData,
240
		iCellIndex;
241
242
	for (let iMonthIndex = 0, iNumMonths = aMonthNodes.length; iMonthIndex < iNumMonths; iMonthIndex++)
243
	{
244
		sMonthId = aMonthNodes[iMonthIndex].getAttribute('id');
245
		iStart = document.getElementById('tr_month_' + sMonthId).rowIndex + 1;
246
		sYearId = sMonthId.substr(0, 4);
247
248
		// Within the current months, check out all the days.
249
		aDayNodes = aMonthNodes[iMonthIndex].getElementsByTagName('day');
250
		for (iDayIndex = 0, iNumDays = aDayNodes.length; iDayIndex < iNumDays; iDayIndex++)
0 ignored issues
show
The variable iNumDays seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.iNumDays.
Loading history...
251
		{
252
			oCurRow = this.oTable.insertRow(iStart + iDayIndex);
253
			oCurRow.className = this.opt.sDayRowClassname;
254
			oCurRow.id = this.opt.sDayRowIdPrefix + aDayNodes[iDayIndex].getAttribute('date');
255
256
			for (iCellIndex = 0, iNumCells = this.opt.aDataCells.length; iCellIndex < iNumCells; iCellIndex++)
0 ignored issues
show
The variable iNumCells seems to be never declared. Assigning variables without defining them first makes them global. If this was intended, consider making it explicit like using window.iNumCells.
Loading history...
257
			{
258
				oCurCell = oCurRow.insertCell(-1);
259
260
				if (this.opt.aDataCells[iCellIndex] === 'date')
261
				{
262
					oCurCell.style.paddingLeft = '6ex';
263
				}
264
				else
265
				{
266
					oCurCell.style.textAlign = 'center';
267
				}
268
269
				sCurData = aDayNodes[iDayIndex].getAttribute(this.opt.aDataCells[iCellIndex]);
270
				oCurCell.appendChild(document.createTextNode(sCurData));
271
			}
272
273
			// Add these day rows to the toggle objects in case of collapse.
274
			this.oYears[sYearId].oMonths[sMonthId].oToggle.opt.aSwappableContainers[this.oYears[sYearId].oMonths[sMonthId].oToggle.opt.aSwappableContainers.length] = oCurRow.id;
275
			this.oYears[sYearId].oToggle.opt.aSwappableContainers[this.oYears[sYearId].oToggle.opt.aSwappableContainers.length] = oCurRow.id;
276
		}
277
	}
278
279
	this.bIsLoading = false;
280
	if (typeof (window.ajax_indicator) === 'function')
281
	{
282
		ajax_indicator(false);
283
	}
284
};
285