(function(BrowserMapUtil)()

in src/main/js/bmaputil.js [25:417]


 (function(BrowserMapUtil) {
    'use strict';

        /**
     * Merge two objects as hashes. Entries with duplicate keys are overwritten with values from the second object.
     *
     * @param {Object} hsh1 - the first hash object
     * @param {Object} hsh2 - the second hash object
     * @return {Object} a hash object obtained by merging the two parameter hash objects
     */
    BrowserMapUtil.merge = function(hsh1, hsh2) {
        var hsh = { },
            prop;
        for (prop in hsh1) {
            if (hsh1.hasOwnProperty(prop)) {
                hsh[prop] = hsh1[prop];
            }
        }
        for (prop in hsh2) {
            if (hsh2.hasOwnProperty(prop)) {
                hsh[prop] = hsh2[prop];
            }
        }
        return hsh;
    };

    /**
     * Returns the set difference between Array a and Array b (a \ b).
     *
     * @param {Array} a - the first Array
     * @param {Array} b - the second Array
     * @return {Array} an Array containing the set difference
     * @throws TypeError if either a or b are not of type Array
     */
    BrowserMapUtil.getArrayDifference = function (a, b) {
        if (!a instanceof Array) {
            throw new TypeError('Expected Array for a');
        }
        if (!b instanceof Array) {
            throw new TypeError('Expected Array for b');
        }
        var i,
            seen = [],
            diff = [];
        for (i = 0; i < b.length; i++) {
            seen[b[i]] = true;
        }
        for (i = 0; i < a.length; i++) {
            if (!seen[a[i]]) {
                diff.push(a[i]);
            }
        }
        return diff;
    };

    /**
     * The <code>cookieManager</code> is used to manage cookies client-side (see
     * <a href="https://developer.mozilla.org/en/DOM/document.cookie">https://developer.mozilla.org/en/DOM/document.cookie</a>).
     *
     * @class BrowserMapUtil.CookieManager
     */
    BrowserMapUtil.CookieManager = {
        /**
         * Returns a <code>Cookie</code> set on the client.
         *
         * @param {String} name - the cookie's name
         * @return {Cookie} the cookie; <code>null</code> if the specified cookie cannot be found
         */
        getCookie : function (name) {
            if (!name || !this.cookieExists(name)) { return null; }
            var cookieValue = decodeURIComponent(document.cookie.replace(new RegExp('(?:^|.*;\\s*)' +
                encodeURIComponent(name).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=\\s*((?:[^;](?!;))*[^;]?).*'), '$1'));
            var cookie = new Cookie(name, cookieValue);
            return cookie;
        },

        /**
         * Sets a <code>Cookie</code> on the client.
         *
         * @param {Cookie} cookie - the cookie
         */
        setCookie : function (cookie) {
            if (!cookie.name || /^(?:expires|max\-age|path|domain|secure)$/.test(cookie.name)) { return; }
            var sExpires = '';
            if (cookie.expires) {
                switch (typeof cookie.expires) {
                    case 'number':
                        sExpires = '; max-age=' + cookie.expires; break;
                    case 'String':
                        sExpires = '; expires=' + cookie.expires; break;
                    case 'object':
                        if (cookie.expires.hasOwnProperty('toGMTString')) {
                            sExpires = '; expires=' + cookie.expires.toGMTString();
                        }
                    break;
                }
            }
            document.cookie = encodeURIComponent(cookie.name) + '=' + encodeURIComponent(cookie.value) + sExpires +
                (cookie.domain ? '; domain=' + cookie.domain : '') + (cookie.path ? '; path=' + cookie.path : '') +
                    (cookie.secure ? '; secure' : '');
        },

        /**
         * Removes a cookie from the client, if one exists.
         *
         * @param {String} name - the <code>Cookie</code>'s name
         */
        removeCookie : function (name) {
            if (!name || !this.cookieExists(name)) { return; }
            var oExpDate = new Date();
            oExpDate.setDate(oExpDate.getDate() - 1);
            document.cookie = encodeURIComponent(name) + '=; expires=' + oExpDate.toGMTString() + ';';
        },

        /**
         * Tests if a cookie exists on the client.
         *
         * @param {String} name - the cookie's name
         * @return {Boolean} <code>true</code> if the cookie exists, <code>false</code> otherwise
         */
        cookieExists : function (name) {
            return (new RegExp('(?:^|;\\s*)' + encodeURIComponent(name).replace(/[\-\.\+\*]/g, '\\$&') + '\\s*\\=')).test(document.cookie);
        },

        cookiesEnabled : function () {
            var cookie = new Cookie('browsermap_test_cookie', 'browsermap_test_cookie', 10, '/');
            this.setCookie(cookie);
            var testCookie = this.getCookie('browsermap_test_cookie');
            if (testCookie !== null) {
                this.removeCookie('browsermap_test_cookie');
                return true;
            }
            return false;
        }
    };

    /**
     * The <code>file</code> object provides various file-related static utility methods.
     *
     * @class BrowserMapUtil.File
     */
    BrowserMapUtil.File = {
        /**
         * Returns the extension of a file based on the file name.
         *
         * @param {String} file - the file's name
         * @return {String} a String containing the file's extension, empty String if the file does not have an extension
         */
        getFileExtension : function (file) {
            var extension = '';
            if (file && file !== '' && file.indexOf('.') != -1) {
                extension = file.substring(file.lastIndexOf('.') + 1, file.length);
            }
            return extension;
        },

        /**
         * Analyses if a file has selectors in its file name and returns the file name (file part + extension) without the selectors.
         *
         * @param {String} file - the file from which to remove the selectors
         * @return {String} a String containing the file with the removed selectors
         */
        removeSelectorsFromFile : function(file) {
            if (file && file !== '') {
                var tokens = file.split('.');
                if (tokens.length > 2) {
                    return tokens[0] + '.' + tokens[tokens.length - 1];
                }
            }
            return file;
        }
    };

    /**
     * The <code>url</code> object provides various URL-related static utility methods.
     *
     * @class BrowserMapUtil.Url
     */
    BrowserMapUtil.Url = {
        /**
         * Analyses a URL an returns the domain part from it.
         *
         * @param {String} url - the URL from which to extract the domain part
         * @return {String} the detected domain
         */
        getDomainFromURL : function (url) {
            var domain = '';
            url = url.replace(/http:\/\/|https:\/\//, '');
            var slashIndex = url.indexOf('/');
            if (slashIndex == -1) {
                domain = url;
            } else {
                domain = url.substring(0, slashIndex);
            }
            return domain;
        },

        /**
         * Decodes the value of a <code>GET</code> request URL parameter.
         *
         * @param {String} value - the encoded value of the parameter
         * @return {String} the decoded value of the parameter
         */
        decodeURLParameterValue : function (value) {
            return decodeURIComponent(value.replace(/\+/g, ' '));
        },

        /**
         * Returns a map with the <code>GET</code> paramters of a URL.
         *
         * @param {String} url - the URL from which the parameters need to be extracted
         * @return {Object} the map with the parameters and their values
         */
        getURLParameters : function (url) {
            var map = {}, self = this;
            var f = function(m,key,value) { map[key] = self.decodeURLParameterValue(value); };
            url.replace(/[?&]+([^=&]+)=([^&]*)/gi, f);
            return map;
        },

        /**
         * Returns the value of a specified <code>GET</code> parameter from a URL if the parameter exists. Otherwise it will return
         * <code>null</code>.
         *
         * @param {String} url - the URL from which the parameter value needs to be extracted
         * @param {String} parameter - the name of the <code>GET</code> parameter whose value needs to be returned
         * @return {String} the value of the parameter, <code>null</code> if the parameter does not exist
         */
        getValueForParameter : function (url, parameter) {
            return this.getURLParameters(url)[parameter];
        },

        /**
         * Returns the <code>GET</code> parameters String from a URL.
         *
         * @param {String} url - the URL form which the parameters String should be extracted
         * @return {String} the parameters String; empty String if the URL is <code>null</code> / empty
         */
        getURLParametersString : function (url) {
            var urlParametersString = '';
            if (url && url !== '' && url.lastIndexOf('?') != -1) {
                urlParametersString = url.substring(url.lastIndexOf('?'), url.length);
            }
            return urlParametersString;
        },

        /**
         * Returns the file part of a URL If the URL sent as a parameter
         * is empty or null, the returned value will be an empty String.
         *
         * @param {String} url - the URL from which the file part should be extracted
         * @return {String} a String containing the file part; empty String if the URL is null or empty or points to a folder instead of
         *      a file
         */
        getFileFromURL : function (url) {
            var file = '';
            if (url && url !== '') {
                url = url.replace('https://', '');
                url = url.replace('http://', '');
                url = url.replace(BrowserMapUtil.Url.getURLParametersString(url), '');
                if (url.lastIndexOf('/') != -1 && url[url.lastIndexOf('/') + 1] != '?') {
                    file = url.substring(url.lastIndexOf('/') + 1, url.length);
                }
            }
            return file;
        },

        /**
         * Retrieves the folder path from a URL.
         *
         * @param {String} url - the URL from which the path is extracted
         * @return {String} a String containing the folder path; empty String if the URL is <code>null</code> or empty or it does not end
         *  with "/"
         */
        getFolderPathFromURL : function (url) {
            var folderPath = '';
            var tmpURL = url;
            tmpURL = tmpURL.replace('https://', '');
            tmpURL = tmpURL.replace('http://', '');
            if (tmpURL && tmpURL !== '' && tmpURL.lastIndexOf('/') != -1) {
                folderPath = tmpURL.substring(0, tmpURL.lastIndexOf('/') + 1);
                folderPath = url.substring(0, url.indexOf(folderPath)) + folderPath;
            }
            return folderPath;
        },

        /**
         * Analyses a resource (the file part from a URL) and retrieves its selectors. The selectors will be returned in an Array. An empty
         * Array will be returned if no selectors have been found.
         *
         * @param {String} url - the URL from which the selectors have to be extracted
         * @return {Array} an Array with the selectors; the Array will be empty if no selectors have been found
         */
        getSelectorsFromURL : function(url) {
            var selectors = [];
            if (url && url !== '') {
                url = url.replace('https://', '');
                url = url.replace('http://', '');
                // ditch the parameters when retrieving selectors
                if (url.lastIndexOf('?') != -1) {
                    url = url.substring(0, url.lastIndexOf('?'));
                }
                if (url.lastIndexOf('/') != -1 ) {
                    url = url.substring(url.lastIndexOf('/') + 1, url.length);
                    var selectorCandidates = url.split('.');
                    if (selectorCandidates.length > 2) {
                        for (var i = 1; i < selectorCandidates.length - 1; i++) {
                            selectors.push(selectorCandidates[i]);
                        }
                    }
                }
            }
            return selectors;
        },

        /**
         * Adds selectors to the supplied URL and returns the modified URL. For example:
         * <pre>
         *      BrowserMapUtil.Url.addSelectorsToUrl('http://www.example.com/index.html', ['mobile'])
         *      ->
         *      'http://www.example.com/index.mobile.html'
         * </pre>
         * @param {String} url - the URL to which selectors need to be added
         * @param {Array} selectors - an Array with the selectors that have to be applied to the current URL
         * @return {String} a String containing the new URL
         */
        addSelectorsToURL : function(url, selectors) {
            var file = this.getFileFromURL(url),
                parameters = BrowserMapUtil.Url.getURLParametersString(url);
            file = BrowserMapUtil.File.removeSelectorsFromFile(file);
            if (file && file !== '') {
                var path = this.getFolderPathFromURL(url);
                var extension = BrowserMapUtil.File.getFileExtension(file);
                file = file.replace('.' + extension, '');
                var newURL = path + file;
                if (selectors.length > 0) {
                    newURL += '.';
                }
                newURL += selectors.join('.');
                if (extension && extension !== '') {
                    newURL += '.' + extension;
                }
                newURL += parameters;
                return newURL;
            }
            return url;
        },

        /**
         * Transforms a relative URL to an absolute one for IE7 which is not able to resolve relative URLs by itself.
         *
         * @param {String} url - the relative URL
         * @return {String} a String with the absolute URL
         */
        qualifyURL : function(url) {
            var absoluteURL = null,
                el;
            if (url) {
                el = document.createElement('div');
                el.innerHTML= '<a href="' + encodeURI(url) + '">x</a>';
                absoluteURL = el.firstChild.href;
            }
            return absoluteURL;
        },

        /**
         * Searches for a canonical link in the current document. If ones is found, its href attribute's value is returned.
         *
         * @return {String} a String with the canonical URL; null if one is not found
         */
        getCanonicalURL : function() {
            var headElement = document.getElementsByTagName('head')[0],
                links,
                i,
                link,
                url;
            if (headElement) {
                links = headElement.getElementsByTagName('link');
                if (links) {
                    for (i = 0; i < links.length; i++) {
                        link = links[i];
                        if (link.rel && link.rel === 'canonical') {
                            url = link.href;
                            break;
                        }
                    }
                }
            }
            return url;
        }
    };

 })(window.BrowserMapUtil = window.BrowserMapUtil || {});