Skip to content

Commit 3c50c6f

Browse files
Switch to JSDoc comments in checker.js
This switches many comments to JSDoc comment format. This will make it easier to auto-generate documentation if desired. Signed-off-by: David A. Wheeler <[email protected]>
1 parent 345f7ed commit 3c50c6f

File tree

1 file changed

+84
-65
lines changed

1 file changed

+84
-65
lines changed

docs/labs/checker.js

Lines changed: 84 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -20,18 +20,23 @@ let startTime = Date.now(); // Time this lab started.
2020
let lastHintTime = null; // Last time we showed a hint.
2121
let lastHintTarget = null; // Last hint button user used.
2222

23-
// Has the input changed since we showed a hint?
24-
// We track this so people can re-see a hint they've already seen.
25-
// This initial value of "true" forces users to wait a delay time before
26-
// they are allowed to see their first hint on an unchanged page.
23+
/**
24+
* True iff the input has changed since we showed a hint.
25+
* We track this so people can re-see a hint they've already seen.
26+
* This initial value of "true" forces users to wait a delay time before
27+
* they are allowed to see their first hint on an unchanged page. */
2728
let changedInputSinceHint = true;
2829

2930
let BACKQUOTE = "`"; // Make it easy to use `${BACKQUOTE}`
3031
let DOLLAR = "$"; // Make it easy to use `${DOLLAR}`
3132

32-
// Current language. Guess English until we learn otherwise.
33+
/** Current language. Guess English until we learn otherwise. */
3334
let lang = "en";
3435

36+
/**
37+
* Resources for localizations, in particular, for translations.
38+
* This intentionally mimics the format of library i18next.
39+
*/
3540
const resources = {
3641
en: {
3742
translation: {
@@ -90,7 +95,8 @@ const resources = {
9095
},
9196
};
9297

93-
/** Provide an "assert" (JavaScript doesn't have one built-in).
98+
/**
99+
* Provide an "assert" function (JavaScript doesn't have one built-in).
94100
* This one uses "Error" to provide a stack trace.
95101
*/
96102
function myAssert(condition, message) {
@@ -99,13 +105,17 @@ function myAssert(condition, message) {
99105
}
100106
}
101107

102-
// Format a string, replacing {NUM} with item NUM.
103-
// We use this function to simplify internationalization.
104-
// Use as: myFormat("Demo {0} result", ["Name"])
105-
// https://www.geeksforgeeks.org/what-are-the-equivalent-of-printf-string-format-in-javascript/
106-
// This is *not* set as a property on String; if we did that,
107-
// we'd modify the global namespace, possibly messing up something
108-
// already there.
108+
/**
109+
* Format a string, replacing {NUM} with item NUM.
110+
* We use this function to simplify internationalization.
111+
* Use as: myFormat("Demo {0} result", ["Name"]). See:
112+
* https://www.geeksforgeeks.org/what-are-the-equivalent-of-printf-string-format-in-javascript/
113+
* This is *not* set as a property on String; if we did that,
114+
* we'd modify the global namespace, possibly messing up something
115+
* already there.
116+
* @param s {string} - string to format, where {NUM} is to be replaced
117+
* @param replacements {Array} - Array of strings for replacements
118+
*/
109119
function myFormat(s, replacements) {
110120
return s.replace(/{(\d+)}/g, function (match, number) {
111121
return typeof replacements[number] != 'undefined'
@@ -119,7 +129,10 @@ myAssert(myFormat("Hello", []) === "Hello");
119129
myAssert(myFormat("Hello {0}, are you {1}?", ["friend", "well"]) ===
120130
"Hello friend, are you well?");
121131

122-
// Retrieve translation for given key from resources.
132+
/** Retrieve translation for given key from resources.
133+
* @param key {string} - key to be retrieved
134+
* @returns {string} - translated key for the current local `lang`
135+
*/
123136
function t(key) {
124137
let result = resources[lang]['translation'][key];
125138

@@ -129,7 +142,8 @@ function t(key) {
129142
return result;
130143
}
131144

132-
// Retrieve translation from object for given field
145+
/** Retrieve translation from object for given field
146+
*/
133147
function retrieve_t(obj, field) {
134148
let result = obj[field + "_" + lang];
135149

@@ -139,7 +153,7 @@ function retrieve_t(obj, field) {
139153
return result;
140154
}
141155

142-
// Determine language of document. Set with <html lang="...">.
156+
/** Return language of document. Set with <html lang="...">. */
143157
function determine_locale() {
144158
let lang = document.documentElement.lang;
145159
if (!lang) {
@@ -148,25 +162,27 @@ function determine_locale() {
148162
return lang;
149163
}
150164

151-
// This array contains the default pattern preprocessing commands, in order.
152-
// We process every pattern through these (in order) to create a final regex
153-
// to be used to match a pattern.
154-
//
155-
// We preprocess regexes to (1) simplify the pattern language and
156-
// (2) optimize performance.
157-
// Each item in this array has two elements:
158-
// a regex and its replacement string on match.
159-
// Yes, these preprocess patterns are regexes that process regexes.
160-
//
161-
// People can instead define their *own* sequence of
162-
// preprocessing commands, to make their language easier to handle
163-
// (e.g., Python). Do this by setting `info.preprocessing`.
164-
// Its format is a sequence of arrays, each element is an array of
165-
// 2 or 3 strings of form pattern, replacementString [, flags]
166-
//
167-
// Our default pattern preprocessing commands include some optimizations;
168-
// we want people to get rapid feedback even with complex correct patterns.
169-
//
165+
/**
166+
* Array that containing the pattern preprocessing commands, in order.
167+
* We set it to its default value to start with.
168+
* We process every pattern through these (in order) to create a final regex
169+
* to be used to match a pattern.
170+
*
171+
* We preprocess regexes to (1) simplify the pattern language and
172+
* (2) optimize performance.
173+
* Each item in this array has two elements:
174+
* a regex and its replacement string on match.
175+
* Yes, these preprocess patterns are regexes that process regexes.
176+
*
177+
* People can instead define their *own* sequence of
178+
* preprocessing commands, to make their language easier to handle
179+
* (e.g., Python). Do this by setting `info.preprocessing`.
180+
* Its format is a sequence of arrays, each element is an array of
181+
* 2 or 3 strings of form pattern, replacementString [, flags]
182+
*
183+
* Our default pattern preprocessing commands include some optimizations;
184+
* we want people to get rapid feedback even with complex correct patterns.
185+
*/
170186
let preprocessRegexes = [
171187
// Remove end-of-line characters (\n and \r)
172188
[/[\n\r]+/g, ''],
@@ -218,9 +234,9 @@ function escapeHTML(unsafe) {
218234
.replace(/\'/g, "&#039;"));
219235
}
220236

221-
/* Compute Set difference lhs \ rhs.
222-
* @lhs - Set to start with
223-
* @rhs - Set to remove from the lhs
237+
/** Compute Set difference lhs \ rhs.
238+
* @param lhs - Set to start with
239+
* @param rhs - Set to remove from the lhs
224240
* Set difference is in Firefox nightly, but is not yet released.
225241
* So we compute it ourselves. This is equivalent to lhs.difference(rhs)
226242
*/
@@ -230,16 +246,17 @@ function setDifference(lhs, rhs) {
230246
return new Set(result);
231247
}
232248

233-
/* Return differences between two objects
249+
/** Return differences between two objects
250+
* (this is useful for debugging)
234251
*/
235252
function objectDiff(obj1, obj2) {
236253
let diff = {};
237-
254+
238255
function compare(obj1, obj2, path = '') {
239256
for (const key in obj1) {
240257
if (obj1.hasOwnProperty(key)) {
241258
const newPath = path ? `${path}.${key}` : key;
242-
259+
243260
if (!obj2.hasOwnProperty(key)) {
244261
diff[newPath] = [obj1[key], undefined];
245262
} else if (typeof obj1[key] === 'object' && typeof obj2[key] === 'object') {
@@ -249,23 +266,23 @@ function objectDiff(obj1, obj2) {
249266
}
250267
}
251268
}
252-
269+
253270
for (const key in obj2) {
254271
if (obj2.hasOwnProperty(key) && !obj1.hasOwnProperty(key)) {
255272
const newPath = path ? `${path}.${key}` : key;
256273
diff[newPath] = [undefined, obj2[key]];
257274
}
258275
}
259276
}
260-
277+
261278
compare(obj1, obj2);
262279
return diff;
263280
}
264281

265-
/*
282+
/**
266283
* Show debug output in debug region and maybe via alert box
267-
* @debugOutput - the debug information to show
268-
* @alwaysAlert - if true, ALWAYS show an alert
284+
* @param debugOutput - the debug information to show
285+
* @param alwaysAlert - if true, ALWAYS show an alert
269286
* This does *not* raise or re-raise an exception; it may be just informative.
270287
*/
271288
function showDebugOutput(debugOutput, alwaysAlert = true) {
@@ -290,8 +307,8 @@ function showDebugOutput(debugOutput, alwaysAlert = true) {
290307
* Given take a regex string, preprocess it (using our array of
291308
* definitions and preprocessing regexes),
292309
* and return a processed regex as a String.
293-
* @regexString - String to be converted into a compiled Regex
294-
* @fullMatch - require full match (insert "^" at beginning, "$" at end).
310+
* @param {string} regexString - String to be converted into a compiled Regex
311+
* @param {Boolean} fullMatch - require full match ("^" at start, "$" at end)
295312
*/
296313
function processRegexToString(regexString, fullMatch = true) {
297314
// Replace all definitions. This makes regexes much easier to use,
@@ -314,9 +331,9 @@ function processRegexToString(regexString, fullMatch = true) {
314331
/**
315332
* Given take a regex string, preprocess it (using our array of
316333
* preprocessing regexes), and return a final compiled Regexp.
317-
* @regexString - String to be converted into a compiled Regexp
318-
* @description - Description of @regexString's purpose (for error reports)
319-
* @fullMatch - require full match (insert "^" at beginning, "$" at end).
334+
* @param {String} regexString - String to be converted into a compiled Regexp
335+
* @param description - Description of its purpose (for error reports)
336+
* @param fullMatch - require full match? (insert "^" at start, "$" at end).
320337
*/
321338
function processRegex(regexString, description, fullMatch = true) {
322339
let processedRegexString = processRegexToString(regexString, fullMatch);
@@ -331,9 +348,9 @@ function processRegex(regexString, description, fullMatch = true) {
331348
}
332349
}
333350

334-
/*
351+
/**
335352
* Determine if preprocessing produces the expected final regex answer.
336-
* @example - 2-element array. LHS is to be processed, RHS is expected result
353+
* @param example - 2-element array [to be processed, expected result]
337354
*/
338355
function validProcessing(example) {
339356
let [unProcessed, expectedProcessed] = example;
@@ -345,19 +362,19 @@ function validProcessing(example) {
345362

346363
/**
347364
* Return true iff the indexed attempt matches the indexed correct.
348-
* @attempt - Array of strings that might be correct
349-
* @index - Integer index (0+)
350-
* @correct - Array of compiled regexes describing correct answer
365+
* @param attempt - Array of strings that might be correct
366+
* @param index - Integer index (0+)
367+
* @param correct - Array of compiled regexes describing correct answer
351368
*/
352369
function calcOneMatch(attempt, index = 0, correct = correctRe) {
353370
return correct[index].test(attempt[index]);
354371
}
355372

356373
/**
357374
* Return true iff all of attempt matches all of correct.
358-
* @attempt - Array of strings that might be correct
359-
* @correct - Array of compiled regexes describing correct answer
360-
* @validIndexes - Array of indexes to check (default: all indexes)
375+
* @param attempt - Array of strings that might be correct
376+
* @param correct - Array of compiled regexes describing correct answer
377+
* @param validIndexes - Array of indexes to check (default: all indexes)
361378
*/
362379
function calcMatch(attempt, correct = correctRe, validIndexes = null) {
363380
if (!correct) { // Defensive test, should never happen.
@@ -391,8 +408,8 @@ function retrieveAttempt() {
391408

392409
const attemptIdPattern = /^attempt(\d+)$/;
393410

394-
/*
395-
* Given Node @form in document, return array of indexes of input/textareas
411+
/**
412+
* Given Node form in document, return array of indexes of input/textareas
396413
* that are relevant for that form.
397414
* The values retrieved are *input* field indexes (`inputIndexes`),
398415
* starting at 0 for the first user input.
@@ -544,7 +561,7 @@ function runCheck() {
544561
}
545562

546563
/** Return the best-matching hint string given an attempt.
547-
* @attempt - array of strings of attempt to give hints on
564+
* @param attempt - array of strings of attempt to give hints on
548565
*/
549566
function findHint(attempt, validIndexes = undefined) {
550567
// Find a matching hint (matches present and NOT absent)
@@ -621,7 +638,7 @@ function maybeShowAnswer(e) {
621638
}
622639
}
623640

624-
// Return true iff target is the same hint button as last time, without edits.
641+
/** Return true iff target is same hint button as last time & no edits. */
625642
function sameHint(target) {
626643
return (target == lastHintTarget) && !changedInputSinceHint;
627644
}
@@ -720,9 +737,10 @@ function processHints(requestedHints) {
720737
}
721738

722739
/** Set global values based on other than "correct" and "expected" values.
723-
* The correct and expected values may come from elsewhere, but we have to set up the
740+
* The correct and expected values may come from elsewhere,
741+
* but we have to set up the
724742
* info-based values first, because info can change how those are interpreted.
725-
* @configurationInfo: Data to use
743+
* @param configurationInfo - Data to use
726744
*/
727745
function processInfo(configurationInfo) {
728746
const allowedInfoFields = new Set([
@@ -907,6 +925,7 @@ function setupInfo() {
907925
};
908926
}
909927

928+
/** Initialize the whole HTML page */
910929
function initPage() {
911930
// Set current locale
912931
lang = determine_locale();

0 commit comments

Comments
 (0)