src/utils/UpdateNotification.js
function _getUpdateInformation(force, dontCache, _versionInfoUrl) {
        // Last time the versionInfoURL was fetched
        var lastInfoURLFetchTime = PreferencesManager.getViewState("lastInfoURLFetchTime");

        var result = new $.Deferred();
        var fetchData = false;
        var data;

        // If force is true, always fetch
        if (force) {
            fetchData = true;
        }

        // If we don't have data saved in prefs, fetch
        data = PreferencesManager.getViewState("updateInfo");
        if (!data) {
            fetchData = true;
        }

        // If more than 24 hours have passed since our last fetch, fetch again
        if ((new Date()).getTime() > lastInfoURLFetchTime + ONE_DAY) {
            fetchData = true;
        }

        if (fetchData) {
            var lookupPromise = new $.Deferred(),
                localVersionInfoUrl;

            // If the current locale isn't "en" or "en-US", check whether we actually have a
            //   locale-specific update notification, and fall back to "en" if not.
            // Note: we check for both "en" and "en-US" to watch for the general case or
            //    country-specific English locale.  The former appears default on Mac, while
            //    the latter appears default on Windows.
            var locale = brackets.getLocale().toLowerCase();
            if (locale !== "en" && locale !== "en-us") {
                localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl();
                $.ajax({
                    url: localVersionInfoUrl,
                    cache: false,
                    type: "HEAD"
                }).fail(function (jqXHR, status, error) {
                    // get rid of any country information from locale and try again
                    var tmpUrl = _getVersionInfoUrl(brackets.getLocale(), true);
                    if (tmpUrl !== localVersionInfoUrl) {
                        $.ajax({
                            url: tmpUrl,
                            cache: false,
                            type: "HEAD"
                        }).fail(function (jqXHR, status, error) {
                            localVersionInfoUrl = _getVersionInfoUrl("en");
                        }).done(function (jqXHR, status, error) {
                            localVersionInfoUrl = tmpUrl;
                        }).always(function (jqXHR, status, error) {
                            lookupPromise.resolve();
                        });
                    } else {
                        localVersionInfoUrl = _getVersionInfoUrl("en");
                        lookupPromise.resolve();
                    }
                }).done(function (jqXHR, status, error) {
                    lookupPromise.resolve();
                });
            } else {
                localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl("en");
                lookupPromise.resolve();
            }

            lookupPromise.done(function () {
                $.ajax({
                    url: localVersionInfoUrl,
                    dataType: "json",
                    cache: false
                }).done(function (updateInfo, textStatus, jqXHR) {
                    if (!dontCache) {
                        lastInfoURLFetchTime = (new Date()).getTime();
                        PreferencesManager.setViewState("lastInfoURLFetchTime", lastInfoURLFetchTime);
                        PreferencesManager.setViewState("updateInfo", updateInfo);
                    }
                    result.resolve(updateInfo);
                }).fail(function (jqXHR, status, error) {
                    // When loading data for unit tests, the error handler is
                    // called but the responseText is valid. Try to use it here,
                    // but *don't* save the results in prefs.

                    if (!jqXHR.responseText) {
                        // Text is NULL or empty string, reject().
                        result.reject();
                        return;
                    }

                    try {
                        data = JSON.parse(jqXHR.responseText);
                        result.resolve(data);
                    } catch (e) {
                        result.reject();
                    }
                });
            });
        } else {
            result.resolve(data);
        }

        return result.promise();
    }
function _getUpdateInformation(force, dontCache, _versionInfoUrl) {
        // Last time the versionInfoURL was fetched
        var lastInfoURLFetchTime = PreferencesManager.getViewState("lastInfoURLFetchTime");

        var result = new $.Deferred();
        var fetchData = false;
        var data;

        // If force is true, always fetch
        if (force) {
            fetchData = true;
        }

        // If we don't have data saved in prefs, fetch
        data = PreferencesManager.getViewState("updateInfo");
        if (!data) {
            fetchData = true;
        }

        // If more than 24 hours have passed since our last fetch, fetch again
        if ((new Date()).getTime() > lastInfoURLFetchTime + ONE_DAY) {
            fetchData = true;
        }

        if (fetchData) {
            var lookupPromise = new $.Deferred(),
                localVersionInfoUrl;

            // If the current locale isn't "en" or "en-US", check whether we actually have a
            //   locale-specific update notification, and fall back to "en" if not.
            // Note: we check for both "en" and "en-US" to watch for the general case or
            //    country-specific English locale.  The former appears default on Mac, while
            //    the latter appears default on Windows.
            var locale = brackets.getLocale().toLowerCase();
            if (locale !== "en" && locale !== "en-us") {
                localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl();
                $.ajax({
                    url: localVersionInfoUrl,
                    cache: false,
                    type: "HEAD"
                }).fail(function (jqXHR, status, error) {
                    // get rid of any country information from locale and try again
                    var tmpUrl = _getVersionInfoUrl(brackets.getLocale(), true);
                    if (tmpUrl !== localVersionInfoUrl) {
                        $.ajax({
                            url: tmpUrl,
                            cache: false,
                            type: "HEAD"
                        }).fail(function (jqXHR, status, error) {
                            localVersionInfoUrl = _getVersionInfoUrl("en");
                        }).done(function (jqXHR, status, error) {
                            localVersionInfoUrl = tmpUrl;
                        }).always(function (jqXHR, status, error) {
                            lookupPromise.resolve();
                        });
                    } else {
                        localVersionInfoUrl = _getVersionInfoUrl("en");
                        lookupPromise.resolve();
                    }
                }).done(function (jqXHR, status, error) {
                    lookupPromise.resolve();
                });
            } else {
                localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl("en");
                lookupPromise.resolve();
            }

            lookupPromise.done(function () {
                $.ajax({
                    url: localVersionInfoUrl,
                    dataType: "json",
                    cache: false
                }).done(function (updateInfo, textStatus, jqXHR) {
                    if (!dontCache) {
                        lastInfoURLFetchTime = (new Date()).getTime();
                        PreferencesManager.setViewState("lastInfoURLFetchTime", lastInfoURLFetchTime);
                        PreferencesManager.setViewState("updateInfo", updateInfo);
                    }
                    result.resolve(updateInfo);
                }).fail(function (jqXHR, status, error) {
                    // When loading data for unit tests, the error handler is
                    // called but the responseText is valid. Try to use it here,
                    // but *don't* save the results in prefs.

                    if (!jqXHR.responseText) {
                        // Text is NULL or empty string, reject().
                        result.reject();
                        return;
                    }

                    try {
                        data = JSON.parse(jqXHR.responseText);
                        result.resolve(data);
                    } catch (e) {
                        result.reject();
                    }
                });
            });
        } else {
            result.resolve(data);
        }

        return result.promise();
    }
function _getUpdateInformation ( force , dontCache , _versionInfoUrl ) { // Last time the versionInfoURL was fetched var lastInfoURLFetchTime = PreferencesManager . getViewState ( "lastInfoURLFetchTime" ) ; var result = new $ . Deferred ( ) ; var fetchData = false ; var data ; // If force is true, always fetch if ( force ) { fetchData = true ; } // If we don't have data saved in prefs, fetch data = PreferencesManager . getViewState ( "updateInfo" ) ; if ( ! data ) { fetchData = true ; } // If more than 24 hours have passed since our last fetch, fetch again if ( ( new Date ( ) ) . getTime ( ) > lastInfoURLFetchTime + ONE_DAY ) { fetchData = true ; } if ( fetchData ) { var lookupPromise = new $ . Deferred ( ) , localVersionInfoUrl ; // If the current locale isn't "en" or "en-US", check whether we actually have a //   locale-specific update notification, and fall back to "en" if not. // Note: we check for both "en" and "en-US" to watch for the general case or //    country-specific English locale.  The former appears default on Mac, while //    the latter appears default on Windows. var locale = brackets . getLocale ( ) . toLowerCase ( ) ; if ( locale !== "en" && locale !== "en-us" ) { localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl ( ) ; $ . ajax ( { url : localVersionInfoUrl , cache : false , type : "HEAD" } ) . fail ( function ( jqXHR , status , error ) { // get rid of any country information from locale and try again var tmpUrl = _getVersionInfoUrl ( brackets . getLocale ( ) , true ) ; if ( tmpUrl !== localVersionInfoUrl ) { $ . ajax ( { url : tmpUrl , cache : false , type : "HEAD" } ) . fail ( function ( jqXHR , status , error ) { localVersionInfoUrl = _getVersionInfoUrl ( "en" ) ; } ) . done ( function ( jqXHR , status , error ) { localVersionInfoUrl = tmpUrl ; } ) . always ( function ( jqXHR , status , error ) { lookupPromise . resolve ( ) ; } ) ; } else { localVersionInfoUrl = _getVersionInfoUrl ( "en" ) ; lookupPromise . resolve ( ) ; } } ) . done ( function ( jqXHR , status , error ) { lookupPromise . resolve ( ) ; } ) ; } else { localVersionInfoUrl = _versionInfoUrl || _getVersionInfoUrl ( "en" ) ; lookupPromise . resolve ( ) ; } lookupPromise . done ( function ( ) { $ . ajax ( { url : localVersionInfoUrl , dataType : "json" , cache : false } ) . done ( function ( updateInfo , textStatus , jqXHR ) { if ( ! dontCache ) { lastInfoURLFetchTime = ( new Date ( ) ) . getTime ( ) ; PreferencesManager . setViewState ( "lastInfoURLFetchTime" , lastInfoURLFetchTime ) ; PreferencesManager . setViewState ( "updateInfo" , updateInfo ) ; } result . resolve ( updateInfo ) ; } ) . fail ( function ( jqXHR , status , error ) { // When loading data for unit tests, the error handler is // called but the responseText is valid. Try to use it here, // but *don't* save the results in prefs. if ( ! jqXHR . responseText ) { // Text is NULL or empty string, reject(). result . reject ( ) ; return ; } try { data = JSON . parse ( jqXHR . responseText ) ; result . resolve ( data ) ; } catch ( e ) { result . reject ( ) ; } } ) ; } ) ; } else { result . resolve ( data ) ; } return result . promise ( ) ; }
Get a data structure that has information for all builds of Brackets.

If force is true, the information is always fetched from _versionInfoURL.
If force is false, we try to use cached information. If more than
24 hours have passed since the last fetch, or if cached data can't be found,
the data is fetched again.

If new data is fetched and dontCache is false, the data is saved in preferences
for quick fetching later.
_versionInfoUrl is used for unit testing.
Get a data structure that has information for all builds of Brackets .