diff --git a/HACKING b/HACKING
index 758ab2c1..6ac51844 100644
--- a/HACKING
+++ b/HACKING
@@ -80,6 +80,7 @@ We try to be quite consistent, but of course, that's not always possible.
Right: if (HACK) // TODO: remove hack
Wrong: if (HACK) /* TODO: remove hack */
Documentation comment blocks use /** ... */
+ Wrap comment documentation comment lines at 80 characters.
* Only wrap lines if it makes the code obviously clearer. Lines longer than 132
characters should probably be broken up rather than wrapped anyway.
diff --git a/common/content/buffer.js b/common/content/buffer.js
index f2a62807..316c2279 100644
--- a/common/content/buffer.js
+++ b/common/content/buffer.js
@@ -1159,7 +1159,7 @@ function Buffer() //{{{
* Saves a page link to disk.
*
* @param {HTMLAnchorElement} elem The page link to save.
- * @param {boolean} skipPrompt Whether to open the "Save Link As..." dialog
+ * @param {boolean} skipPrompt Whether to open the "Save Link As..." dialog.
*/
saveLink: function (elem, skipPrompt)
{
diff --git a/common/content/commands.js b/common/content/commands.js
index e8a0a50f..13833b41 100644
--- a/common/content/commands.js
+++ b/common/content/commands.js
@@ -150,7 +150,7 @@ Command.prototype = {
* @param {number} count @deprecated Whether this command was
* executed with a leading count.
* @param modifiers Any modifiers to be passed to
- * {@link action}
+ * {@link #action}.
*/
execute: function (args, bang, count, modifiers)
{
diff --git a/common/content/events.js b/common/content/events.js
index 0cd60e18..fdea9340 100644
--- a/common/content/events.js
+++ b/common/content/events.js
@@ -189,8 +189,8 @@ function AutoCommands() //{{{
*
* @param {Array} events The array of event names for which this
* autocommand should be executed.
- * @param {string} regex The URL pattern to match against the buffer URL
- * @param {string} cmd The Ex command to run
+ * @param {string} regex The URL pattern to match against the buffer URL.
+ * @param {string} cmd The Ex command to run.
*/
add: function (events, regex, cmd)
{
diff --git a/common/content/io.js b/common/content/io.js
index 9da85767..bcec870a 100644
--- a/common/content/io.js
+++ b/common/content/io.js
@@ -55,6 +55,7 @@ Script.prototype = plugins;
// TODO: why are we passing around strings rather than file objects?
/**
+ * Provides a basic interface to common system I/O operations.
* @instance io
*/
function IO() //{{{
@@ -394,23 +395,99 @@ function IO() //{{{
const self = {
+ /**
+ * @property {number} Open for reading only.
+ * @final
+ */
MODE_RDONLY: 0x01,
+
+ /**
+ * @property {number} Open for writing only.
+ * @final
+ */
MODE_WRONLY: 0x02,
+
+ /**
+ * @property {number} Open for reading and writing.
+ * @final
+ */
MODE_RDWR: 0x04,
+
+ /**
+ * @property {number} If the file does not exist, the file is created.
+ * If the file exists, this flag has no effect.
+ * @final
+ */
MODE_CREATE: 0x08,
+
+ /**
+ * @property {number} The file pointer is set to the end of the file
+ * prior to each write.
+ * @final
+ */
MODE_APPEND: 0x10,
+
+ /**
+ * @property {number} If the file exists, its length is truncated to 0.
+ * @final
+ */
MODE_TRUNCATE: 0x20,
+
+ /**
+ * @property {number} If set, each write will wait for both the file
+ * data and file status to be physically updated.
+ * @final
+ */
MODE_SYNC: 0x40,
+
+ /**
+ * @property {number} With MODE_CREATE, if the file does not exist, the
+ * file is created. If the file already exists, no action and NULL
+ * is returned.
+ * @final
+ */
MODE_EXCL: 0x80,
+ /**
+ * @property {Object} The current file sourcing context. As a file is
+ * being sourced the 'file' and 'line' properties of this context
+ * object are updated appropriately.
+ */
sourcing: null,
+ /**
+ * @property {string} The OS's path separator.
+ */
pathSeparator: WINDOWS ? "\\" : "/",
+ /**
+ * Expands "~" and environment variables in path.
+ *
+ * "~" is expanded to to the value of $HOME. On Windows if this is not
+ * set then the following are tried in order:
+ * $USERPROFILE
+ * ${HOMDRIVE}$HOMEPATH
+ *
+ * The variable notation is $VAR (terminated by a non-word character)
+ * or ${VAR}. %VAR% is also supported on Windows.
+ *
+ * @param {string} path The unexpanded path string.
+ * @param {boolean} relative Whether the path is relative or absolute.
+ * @returns {string}
+ */
expandPath: IO.expandPath,
// TODO: there seems to be no way, short of a new component, to change
// Firefox's CWD - see // https://bugzilla.mozilla.org/show_bug.cgi?id=280953
+ /**
+ * Returns the current working directory.
+ *
+ * It's not possible to change the real CWD of Firefox so this state is
+ * maintained internally. External commands run via {@link #system} are
+ * executed in this directory.
+ *
+ * @returns {nsIFile}
+ */
getCurrentDirectory: function ()
{
let dir = self.getFile(cwd.path);
@@ -423,17 +500,23 @@ function IO() //{{{
return processDir;
},
- setCurrentDirectory: function (newdir)
+ /**
+ * Sets the current working directory.
+ *
+ * @param {string} newDir The new CWD. This may be a relative or
+ * absolute path and is expanded by (@link #expandPath).
+ */
+ setCurrentDirectory: function (newDir)
{
- newdir = newdir || "~";
+ newDir = newDir || "~";
- if (newdir == "-")
+ if (newDir == "-")
{
[cwd, oldcwd] = [oldcwd, this.getCurrentDirectory()];
}
else
{
- let dir = self.getFile(newdir);
+ let dir = self.getFile(newDir);
if (!dir.exists() || !dir.isDirectory())
{
@@ -447,16 +530,28 @@ function IO() //{{{
return self.getCurrentDirectory();
},
- getRuntimeDirectories: function (specialDirectory)
+ /**
+ * Returns all directories named name in 'runtimepath'.
+ *
+ * @param {string} name
+ * @returns {nsIFile[])
+ */
+ getRuntimeDirectories: function (name)
{
let dirs = getPathsFromPathList(options["runtimepath"]);
- dirs = dirs.map(function (dir) joinPaths(dir, specialDirectory))
+ dirs = dirs.map(function (dir) joinPaths(dir, name))
.filter(function (dir) dir.exists() && dir.isDirectory() && dir.isReadable());
return dirs;
},
+ /**
+ * Returns the first user RC file found in dir.
+ *
+ * @param {string} dir The directory to search.
+ * @default $HOME.
+ */
getRCFile: function (dir)
{
dir = dir || "~";
@@ -478,6 +573,14 @@ function IO() //{{{
// return a nsILocalFile for path where you can call isDirectory(), etc. on
// caller must check with .exists() if the returned file really exists
// also expands relative paths
+ /**
+ * Returns an nsIFile object for path, which is expanded
+ * according to {@link #expandPath}.
+ *
+ * @param {string} path The path used to create the file object.
+ * @param {boolean} noCheckPWD Whether to allow a relative path.
+ * @returns {nsIFile}
+ */
getFile: function (path, noCheckPWD)
{
let file = services.create("file");
@@ -501,7 +604,11 @@ function IO() //{{{
},
// TODO: make secure
- // returns a nsILocalFile or null if it could not be created
+ /**
+ * Creates a temporary file.
+ *
+ * @returns {nsIFile}
+ */
createTempFile: function ()
{
let tmpName = EXTENSION_NAME + ".tmp";
@@ -532,17 +639,25 @@ function IO() //{{{
},
- // file is either a full pathname or an instance of file instanceof nsILocalFile
- readDirectory: function (file, sort)
+ /**
+ * Returns the list of files in dir.
+ *
+ * @param {nsIFile|string} dir The directory to read, either a full
+ * pathname or an instance of nsIFile.
+ * @param {boolean} sort Whether to sort the returned directory
+ * entries.
+ * @returns {nsIFile[]}
+ */
+ readDirectory: function (dir, sort)
{
- if (typeof file == "string")
- file = self.getFile(file);
- else if (!(file instanceof Ci.nsILocalFile))
+ if (typeof dir == "string")
+ dir = self.getFile(dir);
+ else if (!(dir instanceof Ci.nsILocalFile))
throw Cr.NS_ERROR_INVALID_ARG; // FIXME: does not work as expected, just shows undefined: undefined
- if (file.isDirectory())
+ if (dir.isDirectory())
{
- let entries = file.directoryEntries;
+ let entries = dir.directoryEntries;
let array = [];
while (entries.hasMoreElements())
{
@@ -558,8 +673,13 @@ function IO() //{{{
// Yes --djk
},
- // file is either a full pathname or an instance of file instanceof nsILocalFile
- // reads a file in "text" mode and returns the string
+ /**
+ * Reads a file in "text" mode and returns the content as a string.
+ *
+ * @param {nsIFile|string} file The file to read, either a full
+ * pathname or an instance of nsIFile.
+ * @returns {string}
+ */
readFile: function (file)
{
let ifstream = Cc["@mozilla.org/network/file-input-stream;1"].createInstance(Ci.nsIFileInputStream);
@@ -585,9 +705,30 @@ function IO() //{{{
return buffer;
},
- // file is either a full pathname or an instance of file instanceof nsILocalFile
- // default permission = 0644, only used when creating a new file, does not change permissions if the file exists
- // mode can be ">" or ">>" in addition to the normal MODE_* flags
+ /**
+ * Writes the string buf to a file.
+ *
+ * @param {nsIFile|string} file The file to write, either a full
+ * pathname or an instance of nsIFile.
+ * @param {string} buf The file content.
+ * @param {string|number} mode The file access mode, a bitwise OR of
+ * the following flags:
+ * (@link #MODE_RDONLY): 0x01
+ * (@link #MODE_WRONLY): 0x02
+ * (@link #MODE_RDWR): 0x04
+ * (@link #MODE_CREATE): 0x08
+ * (@link #MODE_APPEND): 0x10
+ * (@link #MODE_TRUNCATE): 0x20
+ * (@link #MODE_SYNC): 0x40
+ * Alternatively, the following abbreviations may be used:
+ * ">" is equivalent to (@link #MODE_WRONLY) | (@link #MODE_CREATE) | (@link #MODE_TRUNCATE)
+ * ">>" is equivalent to (@link #MODE_WRONLY) | (@link #MODE_CREATE) | (@link #MODE_APPEND)
+ * @default ">"
+ * @param {number} perms The file mode bits of the created file. This
+ * is only used when creating a new file and does not change
+ * permissions if the file exists.
+ * @default 0644
+ */
writeFile: function (file, buf, mode, perms)
{
let ofstream = Cc["@mozilla.org/network/file-output-stream;1"].createInstance(Ci.nsIFileOutputStream);
@@ -615,6 +756,13 @@ function IO() //{{{
ofstream.close();
},
+ /**
+ * Runs an external program.
+ *
+ * @param {string} program The program to run.
+ * @param {string[]} args An array of arguments to pass to program.
+ * @param {boolean} blocking Whether to wait until the process terminates.
+ */
run: function (program, args, blocking)
{
args = args || [];
@@ -673,47 +821,17 @@ lookup:
return process.exitValue;
},
- // when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is fixed
- // is fixed, should use that instead of a tmpfile
- system: function (command, input)
- {
- liberator.echomsg("Calling shell to execute: " + command, 4);
-
- function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"';
-
- return this.withTempFiles(function (stdin, stdout, stderr, cmd) {
-
- if (input)
- this.writeFile(stdin, input);
-
- if (WINDOWS)
- {
- command = "cd /D " + cwd.path + " && " + command + " > " + stdout.path + " 2> " + stderr.path + " < " + stdin.path;
- var res = this.run(options["shell"], options["shellcmdflag"].split(/\s+/).concat(command), true);
- }
- else
- {
-
- this.writeFile(cmd, "cd " + escape(cwd.path) + "\n" +
- ["exec", ">" + escape(stdout.path), "2>" + escape(stderr.path), "<" + escape(stdin.path),
- escape(options["shell"]), options["shellcmdflag"], escape(command)].join(" "));
- res = this.run("/bin/sh", ["-e", cmd.path], true);
- }
-
- if (res > 0) // FIXME: Is this really right? Shouldn't we always show both?
- var output = self.readFile(stderr) + "\nshell returned " + res;
- else
- output = self.readFile(stdout);
-
- // if there is only one \n at the end, chop it off
- if (output && output.indexOf("\n") == output.length - 1)
- output = output.substr(0, output.length - 1);
-
- return output;
- }) || "";
- },
-
// FIXME: multiple paths?
+ /**
+ * Sources files found in 'runtimepath'. For each relative path in
+ * paths each directory in 'runtimepath' is searched and if a
+ * matching file is found it is sourced. Only the first file found (per
+ * specified path) is sourced unless all is specified, then
+ * all found files are sourced.
+ *
+ * @param {string[]} paths An array of relative paths to source.
+ * @param {boolean} all Whether all found files should be sourced.
+ */
sourceFromRuntimePath: function (paths, all)
{
let dirs = getPathsFromPathList(options["runtimepath"]);
@@ -748,8 +866,12 @@ lookup:
return found;
},
- // files which end in .js are sourced as pure JavaScript files,
- // no need (actually forbidden) to add: js <filename.
+ *
+ * @param {string} filename The name of the file to source.
+ * @param {boolean} silent Whether errors should be reported.
+ */
source: function (filename, silent)
{
let wasSourcing = self.sourcing;
@@ -903,11 +1025,68 @@ lookup:
}
},
+ // TODO: when https://bugzilla.mozilla.org/show_bug.cgi?id=68702 is
+ // fixed is fixed, should use that instead of a tmpfile
+ /**
+ * Runs command in a subshell and returns the output in a
+ * string. The shell used is that specified by the 'shell' option.
+ *
+ * @param {string} command The command to run.
+ * @param {string} input Any input to be provided to the command on stdin.
+ * @returns {string}
+ */
+ system: function (command, input)
+ {
+ liberator.echomsg("Calling shell to execute: " + command, 4);
+
+ function escape(str) '"' + str.replace(/[\\"$]/g, "\\$&") + '"';
+
+ return this.withTempFiles(function (stdin, stdout, stderr, cmd) {
+ if (input)
+ this.writeFile(stdin, input);
+
+ if (WINDOWS)
+ {
+ command = "cd /D " + cwd.path + " && " + command + " > " + stdout.path + " 2> " + stderr.path + " < " + stdin.path;
+ var res = this.run(options["shell"], options["shellcmdflag"].split(/\s+/).concat(command), true);
+ }
+ else
+ {
+
+ this.writeFile(cmd, "cd " + escape(cwd.path) + "\n" +
+ ["exec", ">" + escape(stdout.path), "2>" + escape(stderr.path), "<" + escape(stdin.path),
+ escape(options["shell"]), options["shellcmdflag"], escape(command)].join(" "));
+ res = this.run("/bin/sh", ["-e", cmd.path], true);
+ }
+
+ // FIXME: Is this really right? Shouldn't we always show both?
+ if (res > 0)
+ var output = self.readFile(stderr) + "\nshell returned " + res;
+ else
+ output = self.readFile(stdout);
+
+ // if there is only one \n at the end, chop it off
+ if (output && output.indexOf("\n") == output.length - 1)
+ output = output.substr(0, output.length - 1);
+
+ return output;
+ }) || "";
+ },
+
+ /**
+ * Creates a temporary file context for executing external commands.
+ * fn is called with a temp file, created with
+ * {@link #createTempFile}, as each argument.
+ *
+ * @param {function} fn The fn to execute.
+ * @param {Object} self The calling object used when executing fn.
+ */
withTempFiles: function (fn, self)
{
let args = util.map(util.range(0, fn.length), this.createTempFile);
if (!args.every(util.identity))
return false;
+
try
{
return fn.apply(self || this, args);
@@ -923,6 +1102,10 @@ lookup:
}; //}}}
+/**
+ * @property {string} The value of the $VIMPERATOR_RUNTIME environment
+ * variable.
+ */
IO.__defineGetter__("runtimePath", function () {
const rtpvar = config.name.toUpperCase() + "_RUNTIME";
let rtp = services.get("environment").get(rtpvar);
diff --git a/common/content/ui.js b/common/content/ui.js
index 82dea5bc..0fd3a6b9 100644
--- a/common/content/ui.js
+++ b/common/content/ui.js
@@ -29,10 +29,10 @@ the terms of any one of the MPL, the GPL or the LGPL.
/** @scope modules */
/**
- * This class is used for prompting of user input and echoing of messages
+ * This class is used for prompting of user input and echoing of messages.
*
- * it consists of a prompt and command field
- * be sure to only create objects of this class when the chrome is ready
+ * It consists of a prompt and command field be sure to only create objects of
+ * this class when the chrome is ready.
*/
function CommandLine() //{{{
{
@@ -76,7 +76,7 @@ function CommandLine() //{{{
var lastEcho = null;
/**
- * A class for managing the history of an inputField
+ * A class for managing the history of an inputField.
*
* @param {Object} inputField
* @param {string} mode
@@ -99,7 +99,7 @@ function CommandLine() //{{{
this.index = null;
},
/**
- * Permanently save the history
+ * Permanently save the history.
*/
save: function ()
{
@@ -111,7 +111,7 @@ function CommandLine() //{{{
this.store.truncate(options["history"], true);
},
/**
- * Set the current match to val
+ * Set the current match to val.
*
* @param {string} val
*/
@@ -177,7 +177,7 @@ function CommandLine() //{{{
};
/**
- * A class for tab completions on an input field
+ * A class for tab completions on an input field.
*
* @param {Object} input
*/
@@ -597,7 +597,7 @@ function CommandLine() //{{{
var multilineCallback = null;
/**
- * Highlight the messageBox according to group.
+ * Highlight the messageBox according to group.
*/
function setHighlightGroup(group)
{
@@ -605,7 +605,7 @@ function CommandLine() //{{{
}
/**
- * Determines whether the command line should be visible.
+ * Determines whether the command-line should be visible.
*
* @return {boolean}
*/
@@ -714,8 +714,7 @@ function CommandLine() //{{{
}
/**
- * Ensure that the Multiline input widget is the
- * correct size.
+ * Ensure that the multiline input widget is the correct size.
*/
function autosizeMultilineInputWidget()
{
@@ -1027,7 +1026,7 @@ function CommandLine() //{{{
get message() messageBox.value,
/**
- * Open the command line. The main mode is set to
+ * Open the command-line. The main mode is set to
* COMMAND_LINE, the extended mode to extendedMode.
* Further, callbacks defined for extendedMode are
* triggered as appropriate (see {@link Liberator#registerCallback}).
@@ -1061,10 +1060,9 @@ function CommandLine() //{{{
},
/**
- * Closes the command line. This is ordinarilly triggered
- * automatically by a mode change. Will not hide the command
- * line immediately if called directly after a successful
- * command, otherwise it will.
+ * Closes the command-line. This is ordinarily triggered automatically
+ * by a mode change. Will not hide the command-line immediately if
+ * called directly after a successful command, otherwise it will.
*/
close: function close()
{
@@ -1101,7 +1099,7 @@ function CommandLine() //{{{
/**
- * Hides the command line, and shows any status messages that
+ * Hides the command-line, and shows any status messages that
* are under it.
*/
hide: function hide()
@@ -1110,24 +1108,24 @@ function CommandLine() //{{{
},
/**
- * Output the given string onto the command line. With no
- * flags, the message will be shown in the status line if it's
- * short enough to fit, and contains no new lines, and isn't
- * XML. Otherwise, it will be shown in the MOW.
+ * Output the given string onto the command-line. With no flags, the
+ * message will be shown in the status line if it's short enough to
+ * fit, and contains no new lines, and isn't XML. Otherwise, it will be
+ * shown in the MOW.
*
* @param {string} str
* @param {string} highlightGroup The Highlight group for the
* message. @default "Normal"
- * @param {number} flags Changes the bahavior as follows:
- * commandline.APPEND_TO_MESSAGES - Causes message to be added to the messages
- * history, and shown by :messages.
- * commandline.FORCE_SINGLELINE - Forbids the command from
- * being pushed to the MOW if it's too long or of
- * there are already status messages being shown.
- * commandline.DISALLOW_MULTILINE - Cancels the operation if
- * the MOW is already visible.
- * commandline.FORCE_MULTILINE - Forces the message to
- * appear in the MOW.
+ * @param {number} flags Changes the behavior as follows:
+ * commandline.APPEND_TO_MESSAGES - Causes message to be added to the
+ * messages history, and shown by :messages.
+ * commandline.FORCE_SINGLELINE - Forbids the command from being
+ * pushed to the MOW if it's too long or of there are already
+ * status messages being shown.
+ * commandline.DISALLOW_MULTILINE - Cancels the operation if the MOW
+ * is already visible.
+ * commandline.FORCE_MULTILINE - Forces the message to appear in
+ * the MOW.
*/
echo: function echo(str, highlightGroup, flags)
{
@@ -1177,15 +1175,18 @@ function CommandLine() //{{{
},
/**
- * Prompt the user. Sets modes.main to COMMAND_LINE, which the
- * user may pop at any time to close the prompt.
+ * Prompt the user. Sets modes.main to COMMAND_LINE, which the user may
+ * pop at any time to close the prompt.
*
* @param {string} prompt The input prompt to use.
* @param {function(string)} callback
* @param {object} extra
- * @... {function} onChange - A function to be called with the current input every time it changes
- * @... {function(CompletionContext)} completer - A completion function for the user's input.
- * @... {string} promptHighlight - The HighlightGroup used for the prompt. @default "Question"
+ * @... {function} onChange - A function to be called with the current
+ * input every time it changes.
+ * @... {function(CompletionContext)} completer - A completion function
+ * for the user's input.
+ * @... {string} promptHighlight - The HighlightGroup used for the
+ * prompt. @default "Question"
*/
input: function input(prompt, callback, extra)
{
@@ -1207,9 +1208,9 @@ function CommandLine() //{{{
},
/**
- * Get a multiline input from a user, up to but not including
- * the line which matches the given regular expression. Then
- * execute the callback with that string as a parameter.
+ * Get a multiline input from a user, up to but not including the line
+ * which matches the given regular expression. Then execute the
+ * callback with that string as a parameter.
*
* @param {RegExp} untilRegexp
* @param {function(string)} callbackFunc
@@ -1235,10 +1236,9 @@ function CommandLine() //{{{
},
/**
- * Handles all command line events. All key events are passed
- * here when COMMAND_LINE mode is active, as well as all
- * input, keyup, focus, and blur events sent to the
- * command-line XUL element.
+ * Handles all command-line events. All key events are passed here when
+ * COMMAND_LINE mode is active, as well as all input, keyup, focus, and
+ * blur events sent to the command-line XUL element.
*
* @param {Event} event
* @private
@@ -1377,9 +1377,9 @@ function CommandLine() //{{{
},
/**
- * Handle events when we are in multiline output mode,
- * these come from liberator when modes.extended & modes.MULTILINE_OUTPUT
- * and also from #liberator-multiline-output in the XUL
+ * Handle events when we are in multiline output mode, these come from
+ * liberator when modes.extended & modes.MULTILINE_OUTPUT and also from
+ * #liberator-multiline-output in the XUL.
*
* @param {Event} event
*/
@@ -1595,13 +1595,12 @@ function CommandLine() //{{{
},
/**
- * Update or remove the multiline output widget's "MORE"
- * prompt.
+ * Update or remove the multiline output widget's "MORE" prompt.
*
- * @param {boolean} force If true, "-- More --" is shown
- * even if we're at the end of the output.
- * @param {boolean} showHelp When true, show the valid key
- * sequences and what they do.
+ * @param {boolean} force If true, "-- More --" is shown even if we're
+ * at the end of the output.
+ * @param {boolean} showHelp When true, show the valid key sequences
+ * and what they do.
*/
updateMorePrompt: function updateMorePrompt(force, showHelp)
{
@@ -1621,11 +1620,11 @@ function CommandLine() //{{{
},
/**
- * Changes the height of the multilineOutputWidget to fit in
- * the available space.
+ * Changes the height of the multilineOutputWidget to fit in the
+ * available space.
*
- * @param {boolean} open If true, the widget will be opened if
- * it's not already so.
+ * @param {boolean} open If true, the widget will be opened if it's not
+ * already so.
*/
updateOutputHeight: function updateOutputHeight(open)
{
@@ -1665,12 +1664,12 @@ function CommandLine() //{{{
}; //}}}
/**
- * The list which is used for the completion box (and QuickFix window
- * in future).
+ * The list which is used for the completion box (and QuickFix window in
+ * future).
*
- * @param {string} id The id of the