diff --git a/nailgun/static/js/libs/i18next.amd.withJQuery-1.6.3.js b/nailgun/static/js/libs/i18next-1.7.1.js similarity index 96% rename from nailgun/static/js/libs/i18next.amd.withJQuery-1.6.3.js rename to nailgun/static/js/libs/i18next-1.7.1.js index 96e9a220d4..2f531ae03c 100644 --- a/nailgun/static/js/libs/i18next.amd.withJQuery-1.6.3.js +++ b/nailgun/static/js/libs/i18next-1.7.1.js @@ -1,20 +1,8 @@ -// i18next, v1.6.3 +// i18next, v1.7.1 // Copyright (c)2013 Jan Mühlemann (jamuhl). // Distributed under MIT license // http://i18next.com -(function (root, factory) { - if (typeof exports === 'object') { - - var jquery = require('jquery'); - - module.exports = factory(jquery); - - } else if (typeof define === 'function' && define.amd) { - - define(['jquery'], factory); - - } -}(this, function ($) { +(function() { // add indexOf to non ECMA-262 standard compliant browsers if (!Array.prototype.indexOf) { @@ -81,12 +69,28 @@ }; } - var i18n = {} - , resStore = {} - , currentLng - , replacementCounter = 0 - , languages = []; + var root = this + , $ = root.jQuery || root.Zepto + , i18n = {} + , resStore = {} + , currentLng + , replacementCounter = 0 + , languages = [] + , initialized = false; + + // Export the i18next object for **CommonJS**. + // If we're not in CommonJS, add `i18n` to the + // global object or to jquery. + if (typeof module !== 'undefined' && module.exports) { + module.exports = i18n; + } else { + if ($) { + $.i18n = $.i18n || i18n; + } + + root.i18n = root.i18n || i18n; + } // defaults var o = { lng: undefined, @@ -135,9 +139,12 @@ cookieExpirationTime: undefined, useCookie: true, cookieName: 'i18next', + cookieDomain: undefined, postProcess: undefined, - parseMissingKey: undefined + parseMissingKey: undefined, + + shortcutFunction: 'sprintf' // or: defaultValue }; function _extend(target, source) { if (!source || typeof source === 'function') { @@ -497,7 +504,7 @@ } var _cookie = { - create: function(name,value,minutes) { + create: function(name,value,minutes,domain) { var expires; if (minutes) { var date = new Date(); @@ -505,7 +512,8 @@ expires = "; expires="+date.toGMTString(); } else expires = ""; - document.cookie = name+"="+value+expires+"; path=/"; + domain = (domain)? "domain="+domain+";" : ""; + document.cookie = name+"="+value+expires+";"+domain+"path=/"; }, read: function(name) { @@ -525,7 +533,7 @@ }; var cookie_noop = { - create: function(name,value,minutes) {}, + create: function(name,value,minutes,domain) {}, read: function(name) { return null; }, remove: function(name) {} }; @@ -577,6 +585,7 @@ // override defaults with passed in options f.extend(o, options); + delete o.fixLng; /* passed in each time */ // create namespace object if namespace is passed in as string if (typeof o.ns == 'string') { @@ -595,7 +604,7 @@ if (!o.lng) o.lng = f.detectLanguage(); if (o.lng) { // set cookie with lng set (as detectLanguage will set cookie on need) - if (o.useCookie) f.cookie.create(o.cookieName, o.lng, o.cookieExpirationTime); + if (o.useCookie) f.cookie.create(o.cookieName, o.lng, o.cookieExpirationTime, o.cookieDomain); } else { o.lng = o.fallbackLng; if (o.useCookie) f.cookie.remove(o.cookieName); @@ -605,6 +614,16 @@ currentLng = languages[0]; f.log('currentLng set to: ' + currentLng); + var lngTranslate = translate; + if (options.fixLng) { + lngTranslate = function(key, options) { + options = options || {}; + options.lng = options.lng || lngTranslate.lng; + return translate(key, options); + }; + lngTranslate.lng = currentLng; + } + pluralExtensions.setCurrentLng(currentLng); // add JQuery extensions @@ -619,8 +638,9 @@ // return immidiatly if res are passed in if (o.resStore) { resStore = o.resStore; - if (cb) cb(translate); - if (deferred) deferred.resolve(); + initialized = true; + if (cb) cb(lngTranslate); + if (deferred) deferred.resolve(lngTranslate); if (deferred) return deferred.promise(); return; } @@ -640,9 +660,10 @@ // else load them i18n.sync.load(lngsToLoad, o, function(err, store) { resStore = store; + initialized = true; - if (cb) cb(translate); - if (deferred) deferred.resolve(); + if (cb) cb(lngTranslate); + if (deferred) deferred.resolve(lngTranslate); }); if (deferred) return deferred.promise(); @@ -745,8 +766,13 @@ } } - function setLng(lng, cb) { - return init({lng: lng}, cb); + function setLng(lng, options, cb) { + if (typeof options === 'function') { + cb = options; + options = {}; + } + options.lng = lng; + return init(options, cb); } function lng() { @@ -787,6 +813,7 @@ function localize(ele, options) { var key = ele.attr(o.selectorAttr); + if (!key && typeof key !== 'undefined' && key !== false) key = ele.text() || ele.val(); if (!key) return; var target = ele @@ -905,17 +932,25 @@ function exists(key, options) { options = options || {}; - var notFound = options.defaultValue || key + var notFound = _getDefaultValue(key, options) , found = _find(key, options); return found !== undefined || found === notFound; } function translate(key, options) { + if (!initialized) { + f.log('i18next not finished initialization. you might have called t function before loading resources finished.') + return options.defaultValue || ''; + }; replacementCounter = 0; return _translate.apply(null, arguments); } + function _getDefaultValue(key, options) { + return (options.defaultValue !== undefined) ? options.defaultValue : key; + } + function _injectSprintfProcessor() { var values = []; @@ -931,16 +966,34 @@ }; } - function _translate(key, options) { - + function _translate(potentialKeys, options) { if (typeof options == 'string') { - // mh: gettext like sprintf syntax found, automatically create sprintf processor - options = _injectSprintfProcessor.apply(null, arguments); + if (o.shortcutFunction === 'sprintf') { + // mh: gettext like sprintf syntax found, automatically create sprintf processor + options = _injectSprintfProcessor.apply(null, arguments); + } else if (o.shortcutFunction === 'defaultValue') { + options = { + defaultValue: options + } + } } else { options = options || {}; - } + } - var notFound = options.defaultValue || key + if (typeof potentialKeys == 'string') { + potentialKeys = [potentialKeys]; + } + + var key = null; + + for (var i = 0; i < potentialKeys.length; i++) { + key = potentialKeys[i]; + if (exists(key)) { + break; + } + } + + var notFound = _getDefaultValue(key, options) , found = _find(key, options) , lngs = options.lng ? f.toLanguages(options.lng) : languages , ns = options.ns || o.ns.defaultNs @@ -983,7 +1036,7 @@ notFound = applyReuse(notFound, options); if (postProcessor && postProcessors[postProcessor]) { - var val = options.defaultValue || key; + var val = _getDefaultValue(key, options); found = postProcessors[postProcessor](val, key, options); } } @@ -995,7 +1048,7 @@ options = options || {}; var optionWithoutCount, translated - , notFound = options.defaultValue || key + , notFound = _getDefaultValue(key, options) , lngs = languages; if (!resStore) { return notFound; } // no resStore to translate from @@ -1085,12 +1138,11 @@ value = 'key \'' + ns + ':' + key + ' (' + l + ')\' ' + 'returned a object instead of string.'; f.log(value); - } else { + } else if (typeof value !== 'number') { var copy = {}; // apply child translation on a copy - for (var m in value) { - // apply translation on childs + f.each(value, function(m) { copy[m] = _translate(ns + o.nsseparator + key + o.keyseparator + m, options); - } + }); value = copy; } } @@ -2607,9 +2659,4 @@ i18n.addPostProcessor = addPostProcessor; i18n.options = o; - $.i18n = i18n; - $.t = i18n.t; - - return i18n; - -})); \ No newline at end of file +})(); \ No newline at end of file diff --git a/nailgun/static/js/main.js b/nailgun/static/js/main.js index b24e739773..beed13527b 100644 --- a/nailgun/static/js/main.js +++ b/nailgun/static/js/main.js @@ -13,6 +13,7 @@ * License for the specific language governing permissions and limitations * under the License. **/ +'use strict'; requirejs.config({ baseUrl: 'static', urlArgs: '_=' + (new Date()).getTime(), @@ -23,7 +24,7 @@ requirejs.config({ 'jquery-timeout': 'js/libs/jquery.timeout', 'jquery-ui': 'js/libs/jquery-ui-1.10.2.custom', 'jquery-autoNumeric': 'js/libs/autoNumeric', - i18next: 'js/libs/i18next.amd.withJQuery-1.6.3', + i18next: 'js/libs/i18next-1.7.1', utils: 'js/utils', underscore: 'js/libs/lodash', backbone: 'js/libs/backbone', @@ -60,7 +61,10 @@ requirejs.config({ deps: ['jquery'] }, i18next: { - deps: ['jquery'] + deps: ['text!i18n/translation.json', 'jquery'], + init: function(translation, $) { + $.i18n.init({resStore: JSON.parse(translation)}); + } }, 'jquery-checkbox': { deps: ['jquery'] @@ -78,13 +82,8 @@ requirejs.config({ }); require([ - 'text!i18n/translation.json', 'jquery', 'underscore', 'backbone', 'stickit', 'deepModel', 'coccyx', 'i18next', 'bootstrap', 'retina', 'jquery-checkbox', 'jquery-timeout', 'jquery-ui', 'jquery-autoNumeric', 'app' -], function(translation) { - 'use strict'; - var app = _.last(arguments); - $.i18n.init({ - resStore: JSON.parse(translation) - }).always(app.initialize); +], function() { + require('app').initialize(); }); diff --git a/nailgun/static/js/views/capacity_page.js b/nailgun/static/js/views/capacity_page.js index 534e76c42c..0b7d03f557 100644 --- a/nailgun/static/js/views/capacity_page.js +++ b/nailgun/static/js/views/capacity_page.js @@ -25,7 +25,9 @@ function(commonViews, models, capacityPageTemplate) { var CapacityPage = commonViews.Page.extend({ navbarActiveElement: 'support', breadcrumbsPath: [['home', '#'], ['support', '#support'], 'capacity'], - title: $.t('capacity_page.title'), + title: function() { + return $.t('capacity_page.title'); + }, updateInterval: 2000, template: _.template(capacityPageTemplate), events: { diff --git a/nailgun/static/js/views/clusters_page.js b/nailgun/static/js/views/clusters_page.js index 59feae2985..7b35b4eae3 100644 --- a/nailgun/static/js/views/clusters_page.js +++ b/nailgun/static/js/views/clusters_page.js @@ -30,7 +30,9 @@ function(models, utils, commonViews, dialogViews, clustersPageTemplate, clusterT ClustersPage = commonViews.Page.extend({ navbarActiveElement: 'clusters', breadcrumbsPath: [['home', '#'], 'environments'], - title: $.t('clusters_page.title'), + title: function() { + return $.t('clusters_page.title'); + }, template: _.template(clustersPageTemplate), render: function() { this.$el.html(this.template({clusters: this.collection})).i18n(); diff --git a/nailgun/static/js/views/common.js b/nailgun/static/js/views/common.js index bfa00964fc..c5c70c5a24 100644 --- a/nailgun/static/js/views/common.js +++ b/nailgun/static/js/views/common.js @@ -255,7 +255,7 @@ function(utils, models, dialogViews, navbarTemplate, nodesStatsTemplate, notific ], setLocale: function(e) { var newLocale = _.find(this.locales, {locale: $(e.currentTarget).data('locale')}); - $.i18n.setLng(newLocale.locale); + $.i18n.setLng(newLocale.locale, {}); window.location.reload(); }, getCurrentLocale: function() { @@ -264,7 +264,7 @@ function(utils, models, dialogViews, navbarTemplate, nodesStatsTemplate, notific setDefaultLocale: function() { var currentLocale = this.getCurrentLocale(); if (!currentLocale) { - $.i18n.setLng(this.locales[0].locale); + $.i18n.setLng(this.locales[0].locale, {}); } }, initialize: function(options) { diff --git a/nailgun/static/js/views/notifications_page.js b/nailgun/static/js/views/notifications_page.js index 90276729e2..9d06e64f56 100644 --- a/nailgun/static/js/views/notifications_page.js +++ b/nailgun/static/js/views/notifications_page.js @@ -27,7 +27,9 @@ function(utils, models, commonViews, dialogViews, notificationsListTemplate) { var NotificationsPage = commonViews.Page.extend({ navbarActiveElement: null, breadcrumbsPath: [['home', '#'], 'notifications'], - title: $.t('notifications_page.title'), + title: function() { + return $.t('notifications_page.title'); + }, template: _.template(notificationsListTemplate), templateHelpers: _.pick(utils, 'urlify'), events: { diff --git a/nailgun/static/js/views/releases_page.js b/nailgun/static/js/views/releases_page.js index cb495eb257..6d1c755849 100644 --- a/nailgun/static/js/views/releases_page.js +++ b/nailgun/static/js/views/releases_page.js @@ -29,7 +29,9 @@ function(utils, commonViews, dialogViews, releasesListTemplate, releaseTemplate) ReleasesPage = commonViews.Page.extend({ navbarActiveElement: 'releases', breadcrumbsPath: [['home', '#'], 'releases'], - title: $.t('release_page.title'), + title: function() { + return $.t('release_page.title'); + }, updateInterval: 5000, template: _.template(releasesListTemplate), scheduleUpdate: function() { diff --git a/nailgun/static/js/views/support_page.js b/nailgun/static/js/views/support_page.js index 46f40fd449..875c8603d7 100644 --- a/nailgun/static/js/views/support_page.js +++ b/nailgun/static/js/views/support_page.js @@ -25,7 +25,9 @@ function(commonViews, models, supportPageTemplate) { var SupportPage = commonViews.Page.extend({ navbarActiveElement: 'support', breadcrumbsPath: [['home', '#'], 'support'], - title: $.t('support_page.title'), + title: function() { + return $.t('support_page.title'); + }, updateInterval: 2000, template: _.template(supportPageTemplate), events: { diff --git a/nailgun/ui_tests/helpers.js b/nailgun/ui_tests/helpers.js index 35a4dcc36d..00175ac888 100644 --- a/nailgun/ui_tests/helpers.js +++ b/nailgun/ui_tests/helpers.js @@ -15,6 +15,10 @@ **/ var baseUrl = 'http://127.0.0.1:5544/'; +casper.on('page.error', function(msg) { + casper.echo(msg, 'ERROR'); +}); + casper.loadPage = function(page) { return this.thenOpen(baseUrl + page).waitWhileSelector('#content > .loading'); }