• This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn more.

Help Me Understand This IIFE With XF Context

TheBigK

Well-known member
#1
I'm referring to the scratchpad.js which is a part of Kier's Scratchpad addon. The file starts with this -

!function($, window, document, _undefined)

I've following questions:-

1. Why does it have "!" before function()? Is it not negating the private scope of stuff inside the function?

2. Why is undefined variable written as _undefined? Is it just a way of writing or there's something more to it?

3. Why do we have a namespace when we already are inside a function? [Does this question make sense?]

This is the JS file:-

Code:
/** @param {jQuery} $ jQuery Object */
!function($, window, document, _undefined)
{
    // new namespace for this add-on: XenForo.Scratchpad
    XenForo.Scratchpad =
    {
        /**
         * A bit like quick reply, but for scratchpad notes
         *
         * @param jQuery form.ScratchpadQuickNote
         */
        QuickNote: function($form)
        {
            // bind a function onto the AutoValidationComplete event of the form AutoValidator
            $form.bind('AutoValidationComplete', function(e)
            {
                // check that templateHtml was received from the AJAX request
                if (e.ajaxData.templateHtml)
                {
                    // prevent the normal AutoValidator success message and redirect stuff
                    e.preventDefault();

                    // hide the 'no notes' message if it's there, and when it is hidden...
                    $('#ScratchpadNoNotes').slideUp(XenForo.speed.fast, function()
                    {
                        // ... load any externals specified by the template, and when that's done...
                        new XenForo.ExtLoader(e.ajaxData, function()
                        {
                            // ... prepend the templateHtml into the notes area
                            $(e.ajaxData.templateHtml).xfInsert('prependTo', '#ScratchpadNewNotes');
                        });

                        // clear the textarea contents and refocus it
                        $form.find('textarea[name=message]').val('').focus();

                        // set the 'date' input field to contain the date of the most recent post (from ajaxData)
                        $form.find('input[name=date]').val(e.ajaxData.date);

                        // re-enable the submit button if it's been disabled
                        $form.find('input:submit').removeAttr('disabled').removeClass('disabled');
                    });
                }
            });
        }
    };

    // register the QuickNote functionality
    XenForo.register('form.ScratchpadQuickNote', 'XenForo.Scratchpad.QuickNote');

}
(jQuery, this, document);
 

HWS

Well-known member
#2
1) Using the ! operator before the function causes it to be treated as an expression, so we can call it "!function(){}()". This will also return the boolean opposite of the return value of the function, in this case true, because !undefined is true. In addition this also helps if a prior script has not been closed correctly, as it inserts a semicolon automatically.

2) A variable can be written like the author wants to write it. In that script Kier seems to like to start it with an underscore.

See:
http://toddmotto.com/what-function-window-document-undefined-iife-really-means/

Or also:
https://xenforo.com/community/threads/question-about-js-file-in-xenforo.51395/
 
Last edited:

TheBigK

Well-known member
#3
Thanks @HWS . I stumbled upon that article after posting my question. Still want to understand why namespace is being used? I gather that it's meant to keep the scope of variables private.
 

Daniel Hood

Well-known member
#4
Thanks @HWS . I stumbled upon that article after posting my question. Still want to understand why namespace is being used? I gather that it's meant to keep the scope of variables private.
It keeps it organized. XenForo.ScratchPad is the add-on. The functions belonging to it should... belong to it.. instead of the XenForo namespace directly (for example everything in xenforo.js belongs to the XenForo namespace).