Nofus is a very small JavaScript library providing utility functions designed to be used in UserScripts.
Its functions all reside inside the nf object, though a few have "aliases" as noted below.
Items outside the nf object can be "installed", including one that embeds within Node.prototype (which is not installed by default).
Convenience aliases (shorthand functions outside the nf object) are also loaded by default. Search this page for alias or see the key below.
This is an object whose keys enumerate the Nofus aliases, such as w$, which maps to nf.wait$. This object is not meant to be manipulated.
If this is set before loading nofus.js and its value evaluates to false, the aliases will not be loaded. See nf.installAliases below.
Compare two version strings.
Usage: nf.compareVersions(versionA, versionB, [cmp])
- versionA (string): The first version string to compare, e.g. 
2.10.8 - versionB (string): The first version string to compare, e.g. 
2.8.10 - cmp (string): The (optional) comparison operator
>is default- Also supports 
>=,==,!=,<=, and< 
 - Returns a boolean
 
Convenience wrappers for console.log and friends gated by whether it exceeds nf.logLevel. Includes a time stamp, an optional logo, and of course the log message and objects it may reference.
Usage: nf.log(message, [substitution…])
- log (string): The type of log. One of 
debug,assert,log,info,warn,error - message (string): A message to pass to 
console[log] - substitution (any): Optional item(s) referred to by the message; see Using string substitutions
 
The level at which logs appear in the console.
Usage: nf_config.logLevel = level	// run before loading nofus.js
Usage: nf.setLogLevel(level …)	// details below
- level (string): One of 
trace,debug,log,info,warn, orerror - Levels before the specified level in the above list are suppressed
 - For example, 
nf.log("test")will not show up givennf.logLevel == "info" nf_config.logLevelis used if it is set- This otherwise defaults to 
info 
Sets nf.logLevel to the lowest given valid level.
Usage: nf.setLogLevel(level …)
- level (string): One or more of 
trace,debug,log,info,warn, orerror - Returns a boolean representing whether the level was set (though it may not have changed)
 
Add CSS to all nf.log and related messages that can include your logo.
Usage: nf.logLogo = `background:0/1em url("${logo_url}") no-repeat; padding-left:3ex` 
See nf.log above
Get UserScript metadata for a given key with an optional regex to filter the hits.
Usage: nf.GM.getMetas(key, [matcher])
- key (string): The UserScript meta block key (without the 
@), e.g.include - matcher (RegExp): An optional regular expression values must match
 - Requires 
@grant GM.infoand/or@grant GM_infoin your userscript metadata - Returns either an array of strings or else null
 
Get the first matching UserScript metadata for a given key with an optional regex to filter the hits.
Usage: nf.GM.getMeta(key, [matcher])
- key (string): The UserScript meta block key (without the 
@), e.g.include - matcher (RegExp): An optional regular expression values must match
- Unlike 
nf.GM.getMetas(), match groups are returned 
 - Unlike 
 - Requires 
@grant GM.infoand/or@grant GM_infoin your userscript metadata - Returns either a string or else 
undefined 
Get HTML element(s) matched by a given CSS selector.
Usage: nf.query$(css, [scope], [all])
- css (string): A CSS selector like 
aor evenarticle > a[href^="http://example.com/"] - scope (HTMLElement): An optional HTML element (or document) to limit the search to (defaults to 
document) - all (boolean): An optional boolean to denote this requests a list of all results rather than just the first (defaults to 
false) - Returns either an HTMLElement or an array of HTMLElements depending on 
all 
This wraps document.querySelector, document.querySelectorAll, element.querySelector, and element.querySelectorAll.
nf.queryAll$ and qa$ simply run with all = true.
(aliases for the above)
Wait for HTML elements matching given CSS selector, then run the given function on them.
Usage: nf.wait$(css, action, [scope], [options])
- css (string): A CSS selector like 
aor evenarticle > a[href^="http://example.com/"] - action (function): A function to be run on matching elements as they appear
 - scope (HTMLElement): An optional HTML element (or document) to limit the search to (defaults to 
document) - options (object): MutationObserver observe() function options, plus one just for us.
now: Trigger upon setting this up (on by default)childList: Trigger on changes to the scope's child element list (on by default)subtree: Trigger on changes to the scope's subtree (on by default)attributes: Trigger on changes to attributes within the scope (on by default)
 - Returns the MutationObserver object so you can do 
w = nf.wait$(…)and then optionally disable it later withw.disconnect() 
(alias for nf.wait$)
Add to or else make and insert a new CSS <style> element
Usage: nf.style$(css, [where])
- css (string): The stylesheet content to add
 - where (HTMLDocument|HTMLElement,HTMLStyleElement|XMLDocument): Either an HTML/XML document, an HTMLElement, or else an existing 
<style>element (default =document) - Returns the HTMLStyleElement
 
Make an HTML node with attributes and children.
Usage: nf.$html(nodeName[.className…], [attributes], [child] …)
Usage: nf.$html(object attributes …)
- nodeName (string): The tag name of the HTML element to create
 - className (string): nodeName is split on dots to add classes
 - attributes (object): A quick way to define attributes as an object, e.g. 
{href: "http://example.com", class: "external"}. These are HTML attributes except:nodeNamesets the element name (and alleviates the need for the nodeName argument) and is not an attributetext&textContentset content (with both,textis an attribute)classNamesetsclass(with both, both are attributes)valuesets the Javascript value, not the HTML attribute- accepts 
dataset.fooBarasdata-foo-bar 
 - child (Node): A DOM element (probably HTMLElement or Text) to append to the new HTML node
 - Returns the HTMLElement node
 
(alias for nf.$html)
Make a text fragment
Usage: nf.$text(text)
- text (string): The content of the element to create
 - Returns a Text node
 
This wraps document.createTextNode.
(alias for nf.$txt)
Insert given element after reference element, like ref.insertBefore(…)
Usage: nf.insertAfter(add, ref)
- add (HTMLElement): The element to add
 - ref (HTMLElement): The element to add it after
 - Returns the added element (
add) 
Install nf.insertAfter as Node.prototype.insertAfter.
Usage: nf.installInsertAfter()
- After running, you can use 
elem.insertAfter()just like you useelem.insertBefore() 
Create regular expressions more legibly. Supports Perl's x and xx modifiers, allowing white space and comments for legibility and documentation.
Usage: nf.regex(pattern, [flags])
- pattern (string): A string to convert to a regular expression — remember to escape all backslashes!
 - flags (string): A string of regex flags, including two new flags 
xandxxWhen given thexflag, comments and spaces are removed:- An unescaped 
#and everything after it on the line is removed as a comment - Unescaped white space is removed as well
 - Things are a little different in bracketed character classes:
#is always literal\nis always literal- The 
xflag retains other spaces whilexxremoves them 
 - For now, you can put spaces in meta-patterns like 
(? i:text), though this is hard to read and therefore not recommended, and this functionality may change to be more like Perl in the future 
 - An unescaped 
 - Returns a RegExp object
 
This wraps the RegExp constructor.
(alias for nf.regex)
Split the given string into an array. By default, this defaults to using spacing as a separator. Leading/trailing separators will not create empty string members. Inspired by AWK's split and Perl's qw.
Usage: nf.split(str, [sep], [limit])
- str (string): A string to split into the array
 - sep (RegEx|string): The separator pattern to split with (optional, defaults to matching space characters)
 - limit (number): an optional maximum count of items in the array to create. If hit, remaining content is not split
 - Returns an array
 
This is a wrapper for Array.prototype.split().
(alias for nf.split named after Perl's qw function)
A nearly-complete C-style sprintf implementation.
Usage: nf.sprintf(template, [substitution…])
- template (string): A string with percent encodings to be substituted with subsequent arguments
 - substitution (any): A value to be interpreted by the corresponding percent encoding in the template
 - Perl's sprintf documentation is particularly good
 - Returns a string
 
Round a number human-readable units (English or metric or binary/bytes)
Usage: nf.round(num, [width], [type])
- num (number): A number
 - width (number): An integer representing how many decimals to round to (excluding the decimal point)
 - type (string): One of:
English: Uses capitalKfor thousands andBfor billionsMetric: Uses lowercasekfor thousands andGfor giga (billions)Fractional: Metric including fractional units (mfor thousandths)Bytes: Metric but in blocks of 1024 rather than 1000
 - Returns a string
 
Convert seconds to colon-delimited time string (Y:D:HH"MM"SS.SSS, e.g. 4:20).
Usage: nf.sec2time(seconds, [units])
- seconds (number): A number of seconds
 - units (boolean): Whether to display time with colons or with words (optional)
 - Returns a string
 
Convert seconds to unit-based time string (Yy Dd Hh Mm S.SSSs, e.g. 3d 14m).
Usage: nf.sec2units(seconds)
- seconds (number): A number of seconds
 - Returns a string
 
Convert colon-delimited time string (Y:D:H:M:S) to seconds.
Usage: nf.time2sec(time)
- time (string): A colon-delimited string of numbers
 - Returns a number
 
Convert unit-based time (Yy Dd Hh Mm S.SSSs, e.g. 3d 14m) to seconds.
Usage: nf.units2sec(time)
- time (string): A string of numbers with units delimited by spaces or commas
 - Units include 
y,mo,w,d,h,m,sand some longer forms, including full words - This does not account for leap years (1y = 365.00d) since it doesn't know the relevant year
 - Returns a number
 
Convert various time formats to either seconds or a colon-delimited time string.
Usage: nf.timecalc(time)
- time (string or number): A string representing units or colon-delimited numbers or else a number of seconds
 - Returns either a number or a string
 
Convert pretty much anything to a string
Usage: nf.stringify(obj)
- obj (any): The item to convert into a string
 - Returns a string
 
Fast non-cryptographic checksum hasher using Fowler-Noll-Vo.
Usage: nf.hash(str, [radix], [seed])
- str (string): A string (or anything 
nf.stringifycan handle) to hash - radix (number): An integer between 2 and 36 for the output format
 - seed (number): The seed to hash with (changing this from the default is not advised)
 - Do not use for secure collision-resistant code!
 - Returns a number or a string representing a radix other than 10
 
Fast non-cryptographic checksum hasher using Fowler-Noll-Vo with hexadecimal output.
Usage: nf.hash_hex(str, [seed])
See nf.hash above. This simply sets the radix to 16.
Convert a CSS color into a string for #RRGGBB[AA] or an array for (r, g, b, [a])
Usage: nf.color2hex(color, [format])
- color (string): A string representing a CSS color value
 - format (string): One of:
hex: Returns a string of the given color's hexadecimal code (default)num: Returns a number representing the given color's hexadecimal codergb: Returns an array of red, green, blue (all 0-255), and alpha (0-1)srgb: Returns an array of red, green, blue, and alpha (all 0-1)
 - Returns either a string or an array of numbers
 
Count the direct ("own") keys of an object.
Usage: nf.objKeys(obj)
- obj (object): The object whose direct keys we will count
 - Returns an integer or else undefined
 
Determine if something is an empty object.
Usage: nf.objEmpty(obj)
- obj (object): The object whose direct keys we will count
 - Returns a boolean
 
Simple sleep function, either async or else wrapping a function.
Usage: nf.sleep(ms, [action, [args…]])
- ms (number): How many milliseconds to wait
 - action (function): A function to run after the wait time (if missing, run asynchronously)
 - args (any): The arguments to pass to the action function
 - Returns either a Promise or else undefined
 
Install all aliases.
Usage: nf.installAliases()
Remove all aliases.
Usage: nf.uninstallAliases()
As a plugin to Nofus, all functions have an .origin that states where they come from. For example, you can evaluate nf.movable.origin to see that it comes from nf.dialog.
The class for Nofus Dialog.
Create, embed, and optionally display a dialog.
Usage: new nf.dialog([title], [attributes])
- title (string): The title of the dialog window (defaults to the current host)
 - attributes (object):
- backdropClose (boolean): Whether clicking outside the dialog closes it (default = true)
 - id (string): The 
idof the root HTMLDialogElement - open (boolean): Open upon creation (default = true)
 - recenter (boolean): Center the dialog on each open (default = true)
 - resetCSS (boolean): Do not inherit CSS from outside the dialog (default = true)
 
 - Returns an nf.dialog
 
(Optionally set and) return the dialog title.
Usage: .title([title])
- title (string|HTMLElement): The title
 - Returns the title
 
Set the dialog's primary background and foreground colors.
Usage: .setColors(string background, [string background2], [string foreground])
- background (string): The background color_value
 - background2 (string): A background accent color_value (defaults to a darker or lighter version of background)
 - foreground (string): The text color_value (defaults to white given a darker background or black given a lighter background)
 - Returns undefined
 
Get one of the dialog's colors.
Usage: .getColor(which)
- which (string): One of 
foreground,background,background2, or shorthand variants of those,fg,bg, orbg2 - Returns a string containing the value (see also 
nf.color2hexabove) 
Close the dialog.
Usage: .close()
Open the dialog, optionally repositioning it in the center of the screen
Usage: .close([recenter])
- recenter (boolean): Whether or not to reposition; defaults to the option set when creating the dialog
 
Add a tab to the dialog with given name and zero or more children.
Usage: .tab([title], [content…])
- title (string): The text to put on the tab itself
 - content (string|HTMLElement|Text): Zero or more items to become children of the tab body
 - Returns the created tab's body, which notably has some extra features:
body.tab: The HTMLLabelElement holding the tab itselfbody.focus(): Switch to the tab
 
Append one or more elements or text (as paragraphs) to the dialog body.
Usage: .append([item…])
- item (string|HTMLElement|Text): Zero or more items to append to the dialog body
 - Returns the last item that was added
 
The numeric portion of the given element's computed value for the given style.
Usage: nf.getStyleNum(elem, style)
- elem (HTMLElement): The element to examine
 - style (string): The style to compute
 - Returns a string representing the computed style value
 
Make the given element movable either by itself or else a child element
Usage: nf.movable(elem, [handle])
- elem (HTMLElement): The element to make movable
 - handle (HTMLElement): An optional child of the element to control movement (like a window's title bar)