CoderBear's Blog
Dissecting a JavaScript Library I
Aug 18, 2015

In this series of posts, I shall be taking a simple (hopefully) library that I've used often in the past, and play around with its source code and eventually get a fair idea of how it works.

Please note that this series is open ended and depending how this experiment goes, I shall decide how and when to wrap it up. I hope you learn something out of it.

The library I've chosen to analyse is called Noty. Its a neat little notification library that I've used before. Please go through the library's home page and spend a few minutes trying to understand its usage. Its simple enough, and shouldn't take more than a few minutes.

To avoid a version mis-match, I've just copied the source code of v2.3.6 into my repo, which we shall be using as a playground. You can clone it from here. Look at the index.html and the app.js files. They are simple and contain a bare minimum usage of the library, where I click a button, and a notification pops up.


jquery.noty.packaged.js

It is this file that's of primary concern to us. It lies in the the packaged folder, where there's also the file o.noty.packaged.js. This is nothing but a copy of the original file, so its easy to reference it as and when we keep making changes.

On initial scan of the file, the file can roughly be split it into three sections. The first is the NotyObject, second is the notyRenderer and the third being the noty object itself. It is also note worthy that most of the third object noty seems to consist of similar code with minor changes for different layouts/positions.

As my starting point, all I know is that this command pops up a notification.

var n = noty({ text: 'NOTY - a jquery notification library!' });

Lets start with NotyObject. We reached this object by tracing the function call from line 560 where the noty function is exposed via window.noty, which points to line 352/355 where NotyObject is initalised.


// Helpers
window.noty = function noty(options) {
    return $.notyRenderer.init(options);
};

$.notyRenderer.init = function(options) {

// Renderer creates a new noty
var notification = Object.create(NotyObject).init(options);
.
.
.


NotyObject contains the following methods - init, _build, show, close, closeCleanUp, setText, setType, setTimeout and stopPropagation. It also contains some properties - namely closed, showing and shown. There happens to be an underscore as a prefix for one of the method names. This by convention means that _build is a non public method, and will be called internally by some other method.

Looking at the method names, logic dictates that the path of execution of the methods is likely to be - initialize (init), build and then show, followed by close and closeCleanup.

The scope of this post shall be to focus on the first method, init. As the comment explains, init is going to take any user given options and fill in any missing or unspecified parameters with the default object, which it will then pass on to _build. Technically, if I call on noty with no parameters, and comment out all of init's code that mixes the user specified params with the default ones, this library should still function and will running entirely on its default parameters.

Let us look for the default object . It is declared further down the file on line 520 called $.noty.defaults, and shall be the reference point for all the default properties.


// jquery.noty.packaged.js,

init: function(options) {

    // Mix in the passed in options with the default options
    this.options = $.extend({}, $.noty.defaults, options);

    // if not a custom layout, replace the layout name, 
    // with the layout object matching the name in the $.noty object
    this.options.layout = (this.options.custom) ? $.noty.layouts['inline'] : $.noty.layouts[this.options.layout];

    // if given layout exists, replace the theme with the object
    // matching the theme name in the $.noty object
    if($.noty.themes[this.options.theme])
        this.options.theme = $.noty.themes[this.options.theme];
    else
        options.themeClassName = this.options.theme;

    // delete layout and theme passed in options
    delete options.layout;
    delete options.theme;

    // over ride options with options of the layout object
    this.options = $.extend({}, this.options, this.options.layout.options);

    // add id for the noty object
    this.options.id = 'noty_' + (new Date().getTime() * Math.floor(Math.random() * 1000000));

    // add back any user options that might have been over ridden
    this.options = $.extend({}, this.options, options);

    // Build the noty dom initial structure
    this._build();

    // return this so we can chain/use the bridge with less code.
    return this;
}, // end init


The app.js file containes the line debugger, which can be uncommented incase you want to follow the path of execution and check the status of the variables in the stack at each level in the console.

In the next post, we shall continue to analyse a few more functions and get a clearer understadning of certain high level as well as implementation specifics.

Feel free to get back to me with any doubts or clarifications. I shall try my best to answer each one of them personally.



Receive my blogs in your email. Subscribe.

Only Javascript. No Spam. Promise.