UsefulJS

UsefulJS is a JavaScript library whose purpose is twofold:

The UsefulJS philosophy

Every JavaScript programmer has probably written a function to pad strings to a fixed width, a function to determine whether this year is a leap year, functions to manipulate class names of document elements, functions to do something better with Date objects than call toString on them, functions to work around the inadequacies of Number.toFixed and so on.

The major browser vendors have recognized that JavaScript programmers routinely and repeatedly solve the same problems, so we now have support for things like:

However, if we use them, our code is liable to break. Therefore, we're stuck with stuff like this:

var arrayIndexOf = function(arr, item) {
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === item) {
            return i;
        }
    }
    return -1;
};

Or, if we're aware that indexOf is now an Array.prototype method in many browsers, we might write:

var arrayIndexOf = function(arr, item) {
    if ("indexOf" in arr) {
        return arr.indexOf(item);
    }
    for (var i = 0; i < arr.length; i++) {
        if (arr[i] === item) {
            return i;
        }
    }
    return -1;
};

Worse, we may have filled in the perceived inadequacy in Array by blindly patching in the missing functionality with something that doesn't quite work according to spec:

Array.prototype.indexOf = function(item) {
    for (var i = 0; i < this.length; i++) {
        if (this[i] === item) {
            return i;
        }
    }
    return -1;
};

The basic problem in all cases is the same: we can't rely on the JavaScript programming environment that our code is running in.

With UsefulJS that isn't true. We can optimistically write:

// Basic stuff
[1, 2, 3, 4].indexOf(2);
"Three score years".startsWith("Three");
var startTime = Date.now();
document.body.classList.add("myClass");
// Bleeding-edge
var fmtObj = new Intl.DateTimeFormat("zh-TW-u-nu-fullwide-ca-roc"),
    dateStr = fmtObj.format(new Date()),  // "民國102年11月13日"
    uLiterals = Array.from(dateStr, function(c, idx) {
        return '\\u' + c.charCodeAt(idx).toString(16).padLeft(4, '0');
    });

and expect everything to just work.

See the documentation for individual modules for details of the standard JavaScript API functionality that they provide.

Standard library enhancements

Besides providing missing JavaScript functionality, UsefulJS provides a wide range of additional functionality, including:

In a nutshell, this is what UsefulJS does:

Makes the runtime environment sane then makes it better

Building UsefulJS

If you downloaded the dev bundle, you'll need a version of make. Windows users can get one by installing Cygwin. Start off by unpacking the dev bundle to your working directory then edit minjs.mk which defines the function for minifying JavaScript files. I use Google Closure Compiler. Even if you use this, you probably don't have it installed in the same place as me. If you don't have any minification tool, you can change the definition to this:

define minjs
	cp $1 $2
endef

With that done, you just need to type:

$ make all

For a clean build, type:

$ make clean all

Using UsefulJS

Include UsefulJS somwhere in your list of JavaScript includes:

...
<script src="UsefulJS-min-latest.js"></script>
...

If you want the extensions, use this:

...
<script src="UsefulJS-min-full-latest.js"></script>
...

UsefulJS has no dependencies on any other libraries so load order is irrelevant.

If you are using the development libraries, load order is important: you need to load the core module first. All other modules are independent and can be loaded in any order:

...
<script src="src/core.js"></script>
<script src="src/string.js"></script>
<script src="src/locale_en.js"></script>
<script src="etc."></script>
...

Any required extensions should be loaded after the core modules

Fixing the environment

Having loaded the library, you have a number of more-or-less useful functions under a number of different namespaces. To realize the full potential, call the fix method:

window.onload = function() {
    var fixed = UsefulJS.fix();
    ...
};

Or, if you're loading the library in the head:

<script type="text/javascript">
    var g_fixed = UsefulJS.fix();
</script>
The fix method takes an optional opts paramter that controls which fixes are applied. Some fixes have to be explicitly disabled while others have to be explicitly enabled. See the core module documentation and documentation for individual modules for more information.

UsefulJS modules

UsefulJS extensions

Extensions are not part of the core library. They offer specialist functionality that will only be useful in certain applications. Be aware that they are not independent modules; for example, the UsefulJS.DnD extension needs UsefulJS.Event.

Browser Support

UsefulJS has been tested on the following browsers:

BrowserVersions
Mozilla Firefox24+
Google Chrome25, 30+
Internet Explorer7, 8, 9, 10
Safari6.0+
Mobile Safari9.0+
Opera11.0, 17.0+
Konqueror4.6
Maxthon4.1

Licence

UsefulJS is released under the Apache 2.0 License and is copyright 2013-2015 Christopher Williams.

The licence terms basically boil down to: use, modify and redistribute freely, but acknowledge use and respect my copyright. Oh, and let me know if you find it useful - contact details below.

Acknowledgements

This site uses Twitter Bootstrap

Microsoft's excellent style guides were used as the primary sources for localization information.

The JQuery Globalize project was used as a secondary source.

Contacts

Contact me with any questions, suggestions or bugs

For bug reports, please start the subject with "BUG". For localization issues, please start the subject with "L10N"