jQuery Interlink Plugin

January 17, 2016 ยท View on GitHub

/**

  • jQuery Interlink Plugin
  • Developed by Matthias "nihylum" Kaschubowski ( Jan 17, 2016 )
  • Available and archived at invisible.directory
  • (c) 2016 Matthias Kaschubowski
  • License: MIT */

interlinkDebug = $(document.currentScript).data('debug') ? true : false;

var interlink = function(target) {

this.target = target;
this.debug = interlinkDebug;

if ( this.debug )
{
    console.log('Interlink processing task started.');
}

this.match = function(props)
{
    if ( typeof props === 'object' )
    {
        var state = true;

        for ( dataKey in props )
        {
            if ( typeof props[dataKey].source === 'undefined' )
            {
                if ( this.debug )
                {
                    console.log('Trying to match entire string:' + props[dataKey]);
                }

                if ( this.target.data(dataKey) !== props[dataKey] && state === true )
                {
                    state = false;
                }
            }

            if ( typeof props[dataKey].source === 'string' )
            {
                if ( this.debug )
                {
                    console.log('Trying to match regular expression:' + props[dataKey]);
                }

                if ( typeof this.target.data(dataKey) !== 'undefined' && ! props[dataKey].test(this.target.data(dataKey)) )
                {
                    state = false;
                }
            }
        }

        if ( this.debug )
        {
            console.log('Matching task completed, result is: ' + state);
        }

        return state;
    }
    else if ( typeof props !== 'undefined' )
    {
        throw "IllegalFormatException: match property must be an object or undefined";
    }

    return true;
};

this.applyStyles = function(styles)
{
    this.target.css(styles);
};

this.engage = function(event, handler, fetchParams, components)
{
    this.target.on(event, handler);

    if ( typeof fetchParams === 'object' )
    {
        var ajaxParams = $.extend({
            interlinkHandler: handler,
            interlinkTarget: this.target,
            interlinkEvent: event,
            interlinkComponents: components,
        }, fetchParams);

        $.ajax(ajaxParams).done(function(data, status, xhr) {
            var reponse = {
                data: data,
                status: status,
                xhr: xhr,
            };

            this.interlinkTarget.trigger(
                this.interlinkEvent,
                [
                    this.interlinkTarget,
                    components,
                    reponse
                ]
            );
        });

        return;
    }
};

};

(function( $ ) {

$.fn.interlink = function(settings, event)
{
    if ( typeof settings !== 'object' )
    {
        throw "IllegalFormatException: settings argument must hold an object";
    }

    if ( typeof settings.components === 'object' && typeof settings.links === 'object' )
    {
        if ( typeof React === 'undefined' )
        {
            throw "DependencyMissingException: React.js library is not loaded.";
        }

        if ( interlinkDebug )
        {
            console.log('Interlink is in react mode');
        }

        var components = {};

        for ( currentComponent in settings.components )
        {
            if ( typeof settings.components[currentComponent] !== 'object' )
            {
                throw "IllegalFormatException: components property must hold and array of objects";
            }

            if ( interlinkDebug )
            {
                console.log('Interlink React-Component created: ' + currentComponent);
            }

            components[currentComponent] = React.createClass(settings.components[currentComponent]);
        }

        if ( interlinkDebug )
        {
            console.log('Interlink has created ' + components.length + ' components');
        }

        settings = settings.links;
    }

    this.each(function() {

        var linker = new interlink($(this));

        for ( key in settings )
        {
            var info = settings[key];
            var currentEvent = info.event || event;
            var currentMatch = info.match || {};

            if ( typeof currentEvent === 'undefined' )
            {
                throw "UnexpectedEventCascade: No event defined for link " + key;
            }

            if ( linker.match(currentMatch) )
            {
                if ( linker.debug )
                {
                    console.log('Interlink matched on key "' + key + '"')
                }

                if ( typeof info.style === 'object' )
                {
                    linker.applyStyles(info.style);
                }

                if ( info.handler )
                {
                    linker.engage(currentEvent, info.handler, this.fetch, components);
                }
            }
        }

        if ( typeof event === 'string' )
        {
            $(this).trigger(event, [this, components]);
        }
    });

    return this;
};

})( jQuery );