XoopsModules25x/smallworld

View on GitHub
assets/js/jquery.bookmark.js

Summary

Maintainability
F
5 days
Test Coverage
/* http://keith-wood.name/bookmark.html
    Sharing bookmarks for jQuery v1.4.0.
    Written by Keith Wood (kbwood{at}iinet.com.au) March 2008.
    Dual licensed under the GPL (http://dev.jquery.com/browser/trunk/jquery/GPL-LICENSE.txt) and 
    MIT (http://dev.jquery.com/browser/trunk/jquery/MIT-LICENSE.txt) licenses. 
    Please attribute the author if you use it. */
/*jshint devel:true, forin:false */
/* Allow your page to be shared with various bookmarking sites.
    Attach the functionality with options like:
    $('div selector').bookmark({sites: ['delicious', 'digg']});
*/

(function($) { // Hide scope, no $ conflict
var userAgent = navigator.userAgent.toLowerCase(); // Need the name of userAgen
var PROP_NAME = 'bookmark';

/* Bookmark sharing manager. */
function Bookmark() {
    this._defaults = {
        url: '',    // The URL to bookmark, leave blank for the current page
        sourceTag: '', // Extra tag to add to URL to indicate source when it returns
        title: '',    // The title to bookmark, leave blank for the current one
        description: '',    // A longer description of the site
        sites: [],    // List of site IDs or language selectors (lang:xx) or
            // category selectors (category:xx) to use, empty for all
        iconsStyle: 'bookmark_icons', // CSS class for site icons
        icons: 'bookmarks.png', // Horizontal amalgamation of all site icons
        iconSize: 16,    // The size of the individual icons
        iconCols: 16,    // The number of icons across the combined image
        target: '_blank',    // The name of the target window for the bookmarking links
        compact: true,    // True if a compact presentation should be used, false for full
        hint: 'Send to {s}',    // Popup hint for links, {s} is replaced by display name
        popup: false, // True to have it popup on demand, false to show always
        popupText: 'Bookmark this site...', // Text for the popup trigger
        addFavorite: false,    // True to add a 'add to favourites' link, false for none
        favoriteText: 'Favorite',    // Display name for the favourites link
        favoriteIcon: 0,    // Icon for the favourites link
        addEmail: false,    // True to add a 'e-mail a friend' link, false for none
        emailText: 'E-mail',    // Display name for the e-mail link
        emailIcon: 1,    // Icon for the e-mail link
        emailSubject: 'Interesting page',    // The subject for the e-mail
        emailBody: 'I thought you might find this page interesting:\n{t} ({u})', // The body of the e-mail,
            // use '{t}' for the position of the page title, '{u}' for the page URL,
            // '{d}' for the description, and '\n' for new lines
        manualBookmark: 'Please close this dialog and\npress Ctrl-D to bookmark this page.',
            // Instructions for manually bookmarking the page
        addShowAll: false, // True to show listed sites first, then all on demand
        showAllText: 'Show all ({n})', // Display name for show all link, use '{n}' for the number of sites
        showAllIcon: 2, // Icon for show all link
        showAllTitle: 'All bookmarking sites', // Title for show all popup
        onSelect: null, // Callback on selection
        addAnalytics: false, // True to include Google Analytics for links
        analyticsName: '/share/{r}/{s}' // The "URL" that is passed to the Google Analytics,
            // use '{s}' for the site code, '{n}' for the site name,
            // '{u}' for the current full URL, '{r}' for the current relative URL,
            // or '{t}' for the current title
    };
    this._sites = {    // The definitions of the available bookmarking sites, in URL use
        // '{u}' for the page URL, '{t}' for the page title, and '{d}' for the description
        'aol': {display: 'myAOL', icon: 3, lang: 'en', category: 'bookmark',
            url: 'http://favorites.my.aol.com/ffclient/AddBookmark?url={u}&title={t}'},
        'bitly': {display: 'bit.ly', icon: 4, lang: 'en', category: 'tools',
            url: 'http://bit.ly/?url={u}'},
        'blogger': {display: 'Blogger', icon: 5, lang: 'en', category: 'blog',
            url: 'http://www.blogger.com/blog_this.pyra?t=&u={u}&n={t}'},
        'delicious': {display: 'del.icio.us', icon: 6, lang: 'en', category: 'bookmark',
            url: 'http://del.icio.us/post?url={u}&title={t}'},
        'digg': {display: 'Digg', icon: 7, lang: 'en', category: 'news',
            url: 'http://digg.com/submit?phase=2&url={u}&title={t}'},
        'diigo': {display: 'Diigo', icon: 8, lang: 'en', category: 'social',
            url: 'http://www.diigo.com/post?url={u}&title={t}'},
        'dzone': {display: 'DZone', icon: 9, lang: 'en', category: 'bookmark',
            url: 'http://www.dzone.com/links/add.html?url={u}&title={t}'},
        'facebook': {display: 'Facebook', icon: 10, lang: 'en', category: 'social',
            url: 'http://www.facebook.com/sharer.php?u={u}&t={t}'},
        'fark': {display: 'Fark', icon: 11, lang: 'en', category: 'news',
            url: 'http://cgi.fark.com/cgi/fark/submit.pl?new_url={u}&new_comment={t}'},
        'google': {display: 'Google', icon: 12, lang: 'en', category: 'bookmark',
            url: 'http://www.google.com/bookmarks/mark?op=edit&bkmk={u}&title={t}'},
        'googlereader': {display: 'Google Reader', icon: 13, lang: 'en', category: 'tools',
            url: 'http://www.google.com/reader/link?url={u}&title={t}&srcTitle={u}'},
        'hotmail': {display: 'Hotmail', icon: 14, lang: 'en', category: 'mail',
            url: 'http://www.hotmail.msn.com/secure/start?action=compose&to=&body={u}&subject={t}'},
        'linkedin': {display: 'LinkedIn', icon: 15, lang: 'en', category: 'social',
            url: 'http://www.linkedin.com/shareArticle?mini=true&url={u}&title={t}&ro=false&summary={d}&source='},
        'mixx': {display: 'Mixx', icon: 16, lang: 'en', category: 'news',
            url: 'http://www.mixx.com/submit/story?page_url={u}&title={t}'},
        'multiply': {display: 'Multiply', icon: 17, lang: 'en', category: 'social',
            url: 'http://multiply.com/gus/journal/compose/addthis?body=&url={u}&subject={t}'},
        'myspace': {display: 'MySpace', icon: 18, lang: 'en', category: 'social',
            url: 'http://www.myspace.com/Modules/PostTo/Pages/?u={u}&t={t}'},
        'netvibes': {display: 'Netvibes', icon: 19, lang: 'en', category: 'news',
            url: 'http://www.netvibes.com/share?url={u}&title={t}'},
        'newsvine': {display: 'Newsvine', icon: 20, lang: 'en', category: 'news',
            url: 'http://www.newsvine.com/_wine/save?u={u}&h={t}'},
        'reddit': {display: 'reddit', icon: 21, lang: 'en', category: 'news',
            url: 'http://reddit.com/submit?url={u}&title={t}'},
        'stumbleupon': {display: 'StumbleUpon', icon: 22, lang: 'en', category: 'bookmark',
            url: 'http://www.stumbleupon.com/submit?url={u}&title={t}'},
        'technorati': {display: 'Technorati', icon: 23, lang: 'en', category: 'news',
            url: 'http://www.technorati.com/faves?add={u}'},
        'tipd': {display: 'Tip\'d', icon: 24, lang: 'en', category: 'news',
            url: 'http://tipd.com/submit.php?url={u}'},
        'tumblr': {display: 'tumblr', icon: 25, lang: 'en', category: 'blog',
            url: 'http://www.tumblr.com/share?v=3&u={u}&t={t}'},
        'twitter':{display: 'twitter', icon: 26, lang: 'en', category: 'blog',
            url: 'http://twitter.com/home?status={t}%20{u}'},
        'windows': {display: 'Windows Live', icon: 27, lang: 'en', category: 'bookmark',
            url: 'https://favorites.live.com/quickadd.aspx?marklet=1&mkt=en-us&url={u}&title={t}'},
        'wishlist': {display: 'Amazon WishList', icon: 28, lang: 'en', category: 'shopping',
            url: 'http://www.amazon.com/wishlist/add?u={u}&t={t}'},
        'yahoo': {display: 'Yahoo Bookmarks', icon: 29, lang: 'en', category: 'bookmark',
            url: 'http://bookmarks.yahoo.com/toolbar/savebm?opener=tb&u={u}&t={t}'},
        'yahoobuzz': {display: 'Yahoo Buzz', icon: 30, lang: 'en', category: 'bookmark',
            url: 'http://buzz.yahoo.com/submit?submitUrl={u}&submitHeadline={t}'}
    };
    this.commonSites = [];
    for (var id in this._sites) {
        this.commonSites.push(id);
    }
}

$.extend(Bookmark.prototype, {
    /* Class name added to elements to indicate already configured with bookmarking. */
    markerClassName: 'hasBookmark',

    /* Override the default settings for all bookmarking instances.
        @param    settings    (object) the new settings to use as defaults
        @return void */
    setDefaults: function(settings) {
        extendRemove(this._defaults, settings || {});
        return this;
    },

    /* Add a new bookmarking site to the list.
        @param    id            (string) the ID of the new site
        @param    display        (string) the display name for this site
        @param    icon        (string) the location (URL) of an icon for this site (16x16), or
                            (number) the index of the icon within the combined image
        @param    lang        (string) the language code for this site
        @param    category    (string) the category for this site
        @param    url            (string) the submission URL for this site,
                            with {u} marking where the current page's URL should be inserted,
                            and {t} indicating the title insertion point
        @return this singleton */
    addSite: function(id, display, icon, lang, category, url) {
        this._sites[id] = {display: display, icon: icon, lang: lang, category: category, url: url};
        return this;
    },

    /* Return the list of defined sites.
        @return    (object[]) indexed by site id (string), each object contains
                display    (string) the display name,
                icon    (string) the location of the icon, or
                        (number) the icon's index in the combined image
                lang    (string) the language code for this site
                url        (string) the submission URL for the site */
    getSites: function() {
        return this._sites;
    },

    /* Attach the bookmarking widget to a div.
        @param    target        (element) the bookmark container
        @param    settings    (object) the settings for this container */
    _attachBookmark: function(target, settings) {
        target = $(target);
        if (target.hasClass(this.markerClassName)) {
            return;
        }
        target.addClass(this.markerClassName);
        this._updateBookmark(target, settings);
    },

    /* Reconfigure the settings for a bookmarking div.
        @param    target        (element) the bookmark container
        @param    settings    (object) the new settings for this container or
                            (string) a single setting name
        @param    value        (any) the single setting's value */
    _changeBookmark: function(target, settings, value) {
        target = $(target);
        if (!target.hasClass(this.markerClassName)) {
            return;
        }
        if (typeof settings === 'string') {
            var name = settings;
            settings = {};
            settings[name] = value;
        }
        this._updateBookmark(target, settings);
    },

    /* Construct the requested bookmarking links.
        @param    target    (element) the bookmark container
        @param    settings    (object) the settings for this container */
    _updateBookmark: function(target, settings) {
        var oldSettings = $.data(target[0], PROP_NAME) || $.extend({}, this._defaults);
        settings = extendRemove(oldSettings, settings || {});
        $.data(target[0], PROP_NAME, settings);
        var sites = settings.sites;
        if (sites.length === 0) { // All sites
            $.each($.bookmark._sites, function(id) {
                sites.push(id);
            });
            sites.sort();
        }
        else {
            $.each(sites, function(index, value) {
                var lang = value.match(/lang:(.*)/); // Select by language
                if (lang) {
                    $.each($.bookmark._sites, function(id, site) {
                        if (site.lang === lang[1] && $.inArray(id, sites) === -1) {
                            sites.push(id);
                        }
                    });
                }
                var category = value.match(/category:(.*)/); // Select by category
                if (category) {
                    $.each($.bookmark._sites, function(id, site) {
                        if (site.category === category[1] && $.inArray(id, sites) === -1) {
                            sites.push(id);
                        }
                    });
                }
            });
        }
        target.empty();
        var container = target;
        if (settings.popup) {
            target.append('<a href="#" class="bookmark_popup_text">' + settings.popupText + '</a>');
            container = $('<div class="bookmark_popup"></div>').appendTo(target);
        }
        var details = $.bookmark._getSiteDetails(settings);
        var list = $('<ul class="bookmark_list' +
            (settings.compact ? ' bookmark_compact' : '') + '"></ul>').appendTo(container);
        if (settings.addFavorite) {
            $.bookmark._addOneSite(settings, list, settings.favoriteText, settings.favoriteIcon, '#', function() {
                    $.bookmark._addFavourite(details.url.replace(/'/g, '\\\''), details.title.replace(/'/g, '\\\''));
                    return false;
                });
        }
        if (settings.addEmail) {
            $.bookmark._addOneSite(settings, list, settings.emailText, settings.emailIcon,
                'mailto:?subject=' + encodeURIComponent(settings.emailSubject) +
                '&amp;body=' + encodeURIComponent(settings.emailBody.
                replace(/\{u\}/, details.url).replace(/\{t\}/, details.title).replace(/\{d\}/, details.desc)));
        }
        $.bookmark._addSelectedSites(sites, details, settings, list);
        if (settings.addShowAll) {
            var count = 0;
            for (var n in $.bookmark._sites) {
                count++;
            }
            var showAll = settings.showAllText.replace(/\{n\}/, count);
            $.bookmark._addOneSite(settings, list, showAll, settings.showAllIcon, '#', function() {
                    $.bookmark._showAll(this, settings);
                    return false;
                }, showAll);
        }
        if (settings.popup) {
            target.find('.bookmark_popup_text').click(function() {
                var target = $(this).parent();
                var offset = target.offset();
                target.find('.bookmark_popup').css('left', offset.left).
                    css('top', offset.top + target.outerHeight()).toggle();
                return false;
            });
            $(document).click(function(event) { // Close on external click
                target.find('.bookmark_popup').hide();
            });
        }
    },

    /* Add all the selected sites to the list.
        @param    sites        (string[]) the IDs of the selected sites
        @param    details        (object) details about this page
        @param    settings    (object) the bookmark settings
        @param    list        (jQuery) the list to add to */
    _addSelectedSites: function(sites, details, settings, list) {
        $.each(sites, function(index, id) {
            var site = $.bookmark._sites[id];
            if (site) {
                $.bookmark._addOneSite(settings, list, site.display, site.icon, (settings.onSelect ? '#' :
                    site.url.replace(/\{u\}/, details.url2 + (details.sourceTag ? details.sourceTag + id : '')).
                    replace(/\{t\}/, details.title2).replace(/\{d\}/, details.desc2)),
                    function() {
                        if (settings.addAnalytics && window.pageTracker) {
                            window.pageTracker._trackPageview(settings.analyticsName.
                                replace(/\{s\}/, id).replace(/\{n\}/, site.display).
                                replace(/\{u\}/, details.url).replace(/\{r\}/, details.relUrl).
                                replace(/\{t\}/, details.title));
                        }
                        $('#bookmark_all').remove();
                        $(document).unbind('click.bookmark');
                        if (settings.onSelect) {
                            $.bookmark._selected($(this).closest('.' + $.bookmark.markerClassName)[0], id);
                            return false;
                        }
                        return true;
                    });
            }
        });
    },

    /* Add a single site to the list.
        @param    settings    (object) the bookmark settings
        @param    list        (jQuery) the list to add to
        @param    display        (string) the display name for this site
        @param    icon        (string) the location (URL) of an icon for this site (16x16), or
                            (number) the index of the icon within the combined image
        @param    url            (string) the URl for this site
        @param    onclick        (function, optional) additional processing for this link
        @param    hint        (string, optional) the hint text to use for this link */
    _addOneSite: function(settings, list, display, icon, url, onclick, hint) {
        var hintFormat = settings.hint || '{s}';
        var html = '<li><a href="' + url + '"' +
            (settings.target ? ' target="' + settings.target + '"' : '') + '>';
        if (icon !== null) {
            var title = hint || hintFormat.replace(/\{s\}/, display);
            if (typeof icon === 'number') {
                html += '<span title="' + title + '" ' +
                    (settings.iconsStyle ? 'class="' + settings.iconsStyle + '" ' : '') +
                    'style="' + (settings.iconsStyle ? 'background-position: ' :
                    'background: transparent url(' + settings.icons + ') no-repeat ') + '-' +
                    ((icon % settings.iconCols) * settings.iconSize) + 'px -' +
                    (Math.floor(icon / settings.iconCols) * settings.iconSize) + 'px;' +
                    ($.browser.mozilla && $.browser.version < '1.9' ?
                    ' padding-left: ' + settings.iconSize + 'px; padding-bottom: ' +
                    (Math.max(0, settings.iconSize - 16)) + 'px;' : '') + '"></span>';
            }
            else {
                html += '<img src="' + icon + '" alt="' + title + '" title="' +
                    title + '"' + (($.browser.mozilla && $.browser.version < '1.9') ||
                    ($.browser.msie && $.browser.version < '7.0') ?
                    ' style="vertical-align: bottom;"' :
                    ($.browser.msie ? ' style="vertical-align: middle;"' :
                    ($.browser.opera || $.browser.safari ?
                    ' style="vertical-align: baseline;"' : ''))) + '/>';
            }
            html +=    (settings.compact ? '' : '&#xa0;');
        }
        html +=    (settings.compact ? '' : display) + '</a></li>';
        html = $(html).appendTo(list);
        if (onclick) {
            html.find('a').click(onclick);
        }
    },

    /* Remove the bookmarking widget from a div.
        @param    target    (element) the bookmark container */
    _destroyBookmark: function(target) {
        target = $(target);
        if (!target.hasClass(this.markerClassName)) {
            return;
        }
        target.removeClass(this.markerClassName).empty();
        $.removeData(target[0], PROP_NAME);
    },

    /* Callback when selected.
        @param    target    (element) the target div
        @param    siteID    (string) the selected site ID */
    _selected: function(target, siteID) {
        var settings = $.data(target, PROP_NAME);
        var site = $.bookmark._sites[siteID];
        var details = $.bookmark._getSiteDetails(settings);
        settings.onSelect.apply(target, [siteID, site.display, site.url.replace(/&amp;/g,'&').
            replace(/\{u\}/, details.url2 + (details.sourceTag ? details.sourceTag + siteID : '')).
            replace(/\{t\}/, details.title2).replace(/\{d\}/, details.desc2)]);
    },

    /* Add the current page as a favourite in the browser.
        @param    url    (string) the URL to bookmark
        @param    title    (string) the title to bookmark */
    _addFavourite: function(url, title) {
        if ($.browser.msie) {
            window.external.addFavorite(url, title);
        }
        else {
            alert(this._defaults.manualBookmark);
        }
    },

    /* Show all sites in a popup list.
        @param    elem        (element) the clicked 'Show all' link
        @param    settings    (object) the bookmark settings */
    _showAll: function(elem, settings) {
        var sites = [];
        $.each($.bookmark._sites, function(id) {
            sites.push(id);
        });
        sites.sort();
        var details = $.bookmark._getSiteDetails(settings);
        var list = $('<ul class="bookmark_list"></ul>');
        var saveCompact = settings.compact;
        settings.compact = false;
        $.bookmark._addSelectedSites(sites, details, settings, list);
        settings.compact = saveCompact;
        var all = $('<div id="bookmark_all"><p>' + settings.showAllTitle + '</p></div>').
            append(list).appendTo('body');
        all.css({left: ($(window).width() - all.width()) / 2, top: ($(window).height() - all.height()) / 2}).show();
        $(document).bind('click.bookmark', function(event) {
            if ($(event.target).closest(elem).length === 0 && $(event.target).closest('#bookmark_all').length === 0) {
                $('#bookmark_all').remove();
                $(document).unbind('click.bookmark');
            }
        });
    },

    /* Retrieve details about the current site.
        @param    settings    (object) the bookmark settings
        @return    (object) the site details */
    _getSiteDetails: function(settings) {
        var url = settings.url || window.location.href;
        var title = settings.title || document.title || $('h1:first').text();
        var desc = settings.description || $('meta[name="description"]').attr('content') || '';
        var sourceTag = (!settings.sourceTag ? '' :
            encodeURIComponent((url.indexOf('?') > -1 ? '&' : '?') + settings.sourceTag + '='));
        return {url: url, title: title, desc: desc, relUrl: url.replace(/^.*\/\/[^\/]*\//, ''),
            sourceTag: sourceTag, url2: encodeURIComponent(url),
            title2: encodeURIComponent(title), desc2: encodeURIComponent(desc)};
    }
});

/* jQuery extend now ignores nulls! */
function extendRemove(target, props) {
    $.extend(target, props);
    for (var name in props) {
        if (props[name] === null) {
            target[name] = null;
        }
    }
    return target;
}

/* Attach the bookmarking functionality to a jQuery selection.
    @param    command    (string) the command to run (optional, default 'attach')
    @param    options    (object) the new settings to use for these bookmarking instances
    @return    (jQuery object) for chaining further calls */
$.fn.bookmark = function(options) {
    var otherArgs = Array.prototype.slice.call(arguments, 1);
    return this.each(function() {
        if (typeof options === 'string') {
            if (!$.bookmark['_' + options + 'Bookmark']) {
                throw 'Unknown operation: ' + options;
            }
            $.bookmark['_' + options + 'Bookmark'].
                apply($.bookmark, [this].concat(otherArgs));
        }
        else {
            $.bookmark._attachBookmark(this, options || {});
        }
    });
};

/* Initialise the bookmarking functionality. */
$.bookmark = new Bookmark(); // singleton instance

})(jQuery);


/*!
 * jQuery Browser Plugin 0.1.0
 * https://github.com/gabceb/jquery-browser-plugin
 *
 * Original jquery-browser code Copyright 2005, 2015 jQuery Foundation, Inc. and other contributors
 * http://jquery.org/license
 *
 * Modifications Copyright 2015 Gabriel Cebrian
 * https://github.com/gabceb
 *
 * Released under the MIT license
 *
 * Date: 05-07-2015
 */
/*global window: false */

(function (factory) {
  if (typeof define === 'function' && define.amd) {
    // AMD. Register as an anonymous module.
    define(['jquery'], function ($) {
      return factory($);
    });
  } else if (typeof module === 'object' && typeof module.exports === 'object') {
    // Node-like environment
    module.exports = factory(require('jquery'));
  } else {
    // Browser globals
    factory(window.jQuery);
  }
}(function(jQuery) {
  "use strict";

  function uaMatch( ua ) {
    // If an UA is not provided, default to the current browser UA.
    if ( ua === undefined ) {
      ua = window.navigator.userAgent;
    }
    ua = ua.toLowerCase();

    var match = /(edge)\/([\w.]+)/.exec( ua ) ||
        /(opr)[\/]([\w.]+)/.exec( ua ) ||
        /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
        /(iemobile)[\/]([\w.]+)/.exec( ua ) ||
        /(version)(applewebkit)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+).*(version)[ \/]([\w.]+).*(safari)[ \/]([\w.]+)/.exec( ua ) ||
        /(webkit)[ \/]([\w.]+)/.exec( ua ) ||
        /(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
        /(msie) ([\w.]+)/.exec( ua ) ||
        ua.indexOf("trident") >= 0 && /(rv)(?::| )([\w.]+)/.exec( ua ) ||
        ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
        [];

    var platform_match = /(ipad)/.exec( ua ) ||
        /(ipod)/.exec( ua ) ||
        /(windows phone)/.exec( ua ) ||
        /(iphone)/.exec( ua ) ||
        /(kindle)/.exec( ua ) ||
        /(silk)/.exec( ua ) ||
        /(android)/.exec( ua ) ||
        /(win)/.exec( ua ) ||
        /(mac)/.exec( ua ) ||
        /(linux)/.exec( ua ) ||
        /(cros)/.exec( ua ) ||
        /(playbook)/.exec( ua ) ||
        /(bb)/.exec( ua ) ||
        /(blackberry)/.exec( ua ) ||
        [];

    var browser = {},
        matched = {
          browser: match[ 5 ] || match[ 3 ] || match[ 1 ] || "",
          version: match[ 2 ] || match[ 4 ] || "0",
          versionNumber: match[ 4 ] || match[ 2 ] || "0",
          platform: platform_match[ 0 ] || ""
        };

    if ( matched.browser ) {
      browser[ matched.browser ] = true;
      browser.version = matched.version;
      browser.versionNumber = parseInt(matched.versionNumber, 10);
    }

    if ( matched.platform ) {
      browser[ matched.platform ] = true;
    }

    // These are all considered mobile platforms, meaning they run a mobile browser
    if ( browser.android || browser.bb || browser.blackberry || browser.ipad || browser.iphone ||
      browser.ipod || browser.kindle || browser.playbook || browser.silk || browser[ "windows phone" ]) {
      browser.mobile = true;
    }

    // These are all considered desktop platforms, meaning they run a desktop browser
    if ( browser.cros || browser.mac || browser.linux || browser.win ) {
      browser.desktop = true;
    }

    // Chrome, Opera 15+ and Safari are webkit based browsers
    if ( browser.chrome || browser.opr || browser.safari ) {
      browser.webkit = true;
    }

    // IE11 has a new token so we will assign it msie to avoid breaking changes
    if ( browser.rv || browser.iemobile) {
      var ie = "msie";

      matched.browser = ie;
      browser[ie] = true;
    }

    // Edge is officially known as Microsoft Edge, so rewrite the key to match
    if ( browser.edge ) {
      delete browser.edge;
      var msedge = "msedge";

      matched.browser = msedge;
      browser[msedge] = true;
    }

    // Blackberry browsers are marked as Safari on BlackBerry
    if ( browser.safari && browser.blackberry ) {
      var blackberry = "blackberry";

      matched.browser = blackberry;
      browser[blackberry] = true;
    }

    // Playbook browsers are marked as Safari on Playbook
    if ( browser.safari && browser.playbook ) {
      var playbook = "playbook";

      matched.browser = playbook;
      browser[playbook] = true;
    }

    // BB10 is a newer OS version of BlackBerry
    if ( browser.bb ) {
      var bb = "blackberry";

      matched.browser = bb;
      browser[bb] = true;
    }

    // Opera 15+ are identified as opr
    if ( browser.opr ) {
      var opera = "opera";

      matched.browser = opera;
      browser[opera] = true;
    }

    // Stock Android browsers are marked as Safari on Android.
    if ( browser.safari && browser.android ) {
      var android = "android";

      matched.browser = android;
      browser[android] = true;
    }

    // Kindle browsers are marked as Safari on Kindle
    if ( browser.safari && browser.kindle ) {
      var kindle = "kindle";

      matched.browser = kindle;
      browser[kindle] = true;
    }

     // Kindle Silk browsers are marked as Safari on Kindle
    if ( browser.safari && browser.silk ) {
      var silk = "silk";

      matched.browser = silk;
      browser[silk] = true;
    }

    // Assign the name and platform variable
    browser.name = matched.browser;
    browser.platform = matched.platform;
    return browser;
  }

  // Run the matching process, also assign the function to the returned object
  // for manual, jQuery-free use if desired
  window.jQBrowser = uaMatch( window.navigator.userAgent );
  window.jQBrowser.uaMatch = uaMatch;

  // Only assign to jQuery.browser if jQuery is loaded
  if ( jQuery ) {
    jQuery.browser = window.jQBrowser;
  }

  return window.jQBrowser;
}));