quality_gates.projects.noResults=No Projects
quality_gates.projects.select_hint=Click to associate this project with the quality gate
quality_gates.projects.deselect_hint=Click to remove association between this project and the quality gate
+quality_gates.operator.LT=is less than
+quality_gates.operator.GT=is greater than
+quality_gates.operator.EQ=equals
+quality_gates.operator.NE=is not
#------------------------------------------------------------------------------
#
'third-party/jquery.js',
'third-party/underscore.js',
'third-party/require.js',
+ 'translate.js',
'common/inputs.js',
// libs
preprocessors: {
'navigator/**/*.js': 'coverage',
- 'common/inputs.js': 'coverage'
+ 'common/inputs.js': 'coverage',
+ 'translate.js': 'coverage'
},
"alerts.notes.error",
"alerts.notes.ok",
"alerts.notes.warn",
- "alerts.operator.!=",
- "alerts.operator.<",
- "alerts.operator.=",
- "alerts.operator.>",
"alerts.select_metric",
"alerts.warn_tooltip",
"are_you_sure",
"name",
"quality_gates.add",
"quality_gates.add_condition",
+ "quality_gates.conditions",
"quality_gates.copy",
"quality_gates.health_icons",
"quality_gates.introduction",
"quality_gates.no_conditions",
"quality_gates.noQualityGates",
+ "quality_gates.operator.LT",
+ "quality_gates.operator.GT",
+ "quality_gates.operator.EQ",
+ "quality_gates.operator.NE",
"quality_gates.page",
"quality_gates.projects",
"quality_gates.projects.all",
<%= javascript_include_tag 'third-party/select2' %>
<%= javascript_include_tag 'select2-jquery-ui-fix' %>
+ <%= javascript_include_tag 'translate' %>
+
<%= javascript_include_tag 'widgets/widget' %>
<%= javascript_include_tag 'widgets/bubble-chart' %>
<%= javascript_include_tag 'widgets/timeline' %>
'warning': '<%= escape_javascript message('measure_filter.criteria.alert.warn') -%>',
'ok': '<%= escape_javascript message('measure_filter.criteria.alert.ok') -%>',
'days': '<%= escape_javascript message('measure_filter.criteria.age.days') -%>',
- 'filtersList': '<%= escape_javascript message('measure_filter.filter_list') -%>'
+ 'filtersList': '<%= escape_javascript message('measure_filter.filter_list') -%>',
+
+ 'work_duration': {
+ 'x_days': '<%= escape_javascript message('work_duration.x_days') -%>',
+ 'x_hours': '<%= escape_javascript message('work_duration.x_hours') -%>',
+ 'x_minutes': '<%= escape_javascript message('work_duration.x_minutes') -%>'
+ }
}
});
<script>
window.SS = {
- metricPeriods: [
- { key: '1', text: '<%= Api::Utils.period_label(1) -%>' },
- { key: '2', text: '<%= Api::Utils.period_label(2) -%>' },
- { key: '3', text: '<%= Api::Utils.period_label(3) -%>' }
- ],
-
workDuration: {
days: '<%= message('work_duration.x_days') -%>',
hours: '<%= message('work_duration.x_hours') -%>',
minutes: '<%= message('work_duration.x_minutes') -%>'
- },
-
- phrases: {
- areYouSure: '<%= message('are_you_sure') -%>',
- alerts: {
- operator: {
- 'LT': '<%= message('alerts.operator.<') -%>',
- 'GT': '<%= message('alerts.operator.>') -%>',
- 'EQ': '<%= message('alerts.operator.=') -%>',
- 'NE': '<%= message('alerts.operator.!=') -%>'
- },
- select_metric: '<%= message('alerts.select_metric') -%>'
- },
- projects: {
- 'with': '<%= message('quality_gates.projects.with') -%>',
- without: '<%= message('quality_gates.projects.without') -%>',
- all: '<%= message('quality_gates.projects.all') -%>',
- select_hint: '<%= message('quality_gates.projects.select_hint') -%>',
- deselect_hint: '<%= message('quality_gates.projects.deselect_hint') -%>',
- noResults: '<%= message('quality_gates.projects.noResults') -%>'
- }
}
};
</script>
<script id="quality-gate-actions-template" type="text/x-handlebars-template">
- <h1 class="navigator-header-title"><%= message('quality_gates.page') -%></h1>
+ <h1 class="navigator-header-title">{{t 'quality_gates.page'}}</h1>
{{#if canEdit}}
<div class="navigator-header-actions button-group">
- <button id="quality-gate-add"><%= message('add_verb') -%></button>
+ <button id="quality-gate-add">{{t 'add_verb'}}</button>
</div>
{{/if}}
</script>
<td width="10%" nowrap>
{{#if canEdit}}
<select name="period">
- <option value="0"><%= message('value') -%></option>
+ <option value="0">{{t 'value'}}</option>
{{#each periods}}<option value="{{key}}">{{text}}</option>{{/each}}
</select>
{{else}}
{{#if canEdit}}
<select name="operator">
{{#operators metric.type}}
- <option value="{{this}}">{{translate 'alerts.operator' this}}</option>
+ <option value="{{this}}">{{t 'quality_gates.operator' this}}</option>
{{/operators}}
</select>
{{else}}
- {{translate 'alerts.operator' op}}
+ {{t 'quality_gates.operator' op}}
{{/if}}
</td>
<td width="15%">
- <i class="icon-alert-warn" title="<%= message('alerts.warn_tooltip') -%>"></i>
+ <i class="icon-alert-warn" title="{{t 'alerts.warn_tooltip'}}"></i>
{{#if canEdit}}
<input name="warning" class="measure-input" data-type="{{metric.type}}" type="text">
{{else}}
{{/if}}
</td>
<td width="15%">
- <i class="icon-alert-error" title="<%= message('alerts.error_tooltip') -%>"></i>
+ <i class="icon-alert-error" title="{{t 'alerts.error_tooltip'}}"></i>
{{#if canEdit}}
<input name="error" class="measure-input" data-type="{{metric.type}}" type="text">
{{else}}
{{#if canEdit}}
{{#if id}}
<div class="button-group">
- <button class="update-condition" disabled><%= message('update_verb') -%></button>
- <button class="button-red delete-condition"><%= message('delete') -%></button>
+ <button class="update-condition" disabled>{{t 'update_verb'}}</button>
+ <button class="button-red delete-condition">{{t 'delete'}}</button>
</div>
{{else}}
<div class="button-group">
- <button class="add-condition"><%= message('add_verb') -%></button>
- <a class="action cancel-add-condition"><%= message('cancel') -%></a>
+ <button class="add-condition">{{t 'add_verb'}}</button>
+ <a class="action cancel-add-condition">{{t 'cancel'}}</a>
</div>
{{/if}}
{{/if}}
<script id="quality-gate-detail-conditions-empty-template" type="text/x-handlebars-template">
<td colspan="6">
- <%= message('quality_gates.no_conditions') -%>
+ {{t 'quality_gates.no_conditions'}}
</td>
</script>
<script id="quality-gate-detail-conditions-template" type="text/x-handlebars-template">
- <div class="quality-gate-section-name"><%= message('quality_gates.conditions') -%></div>
+ <div class="quality-gate-section-name">{{t 'quality_gates.conditions'}}</div>
<div class="quality-gate-introduction">
- <p><%= message('quality_gates.introduction') -%>
- <a class="link-action quality-gate-introduction-show-more"><%= message('more') -%></a>
+ <p>{{t 'quality_gates.introduction'}}
+ <a class="link-action quality-gate-introduction-show-more">{{t 'more'}}</a>
</p>
<div class="quality-gate-introduction-more">
- <%= message('quality_gates.health_icons') -%>
+ {{t 'quality_gates.health_icons'}}
<table class="data">
<thead>
<tr>
<tbody>
<tr class="even">
<td><i class="icon-alert-ok"></i></td>
- <td><%= message('alerts.notes.ok') -%></td>
+ <td>{{t 'alerts.notes.ok'}}</td>
</tr>
<tr class="odd">
<td><i class="icon-alert-warn"></i></td>
- <td><%= message('alerts.notes.warn') -%></td>
+ <td>{{t 'alerts.notes.warn'}}</td>
</tr>
<tr class="even">
<td><i class="icon-alert-error"></i></td>
- <td><%= message('alerts.notes.error') -%></td>
+ <td>{{t 'alerts.notes.error'}}</td>
</tr>
</tbody>
</table>
{{#if canEdit}}
<div class="quality-gate-new-condition">
- <label for="quality-gate-new-condition-metric"><%= message('quality_gates.add_condition') -%>:</label>
+ <label for="quality-gate-new-condition-metric">{{t 'quality_gates.add_condition'}}:</label>
<select id="quality-gate-new-condition-metric">
<option></option>
{{#each metricGroups}}
{{#if canEdit}}
<div class="navigator-header-actions button-group">
- <button id="quality-gate-rename"><%= message('rename') -%></button>
- <button id="quality-gate-copy"><%= message('copy') -%></button>
+ <button id="quality-gate-rename">{{t 'rename'}}</button>
+ <button id="quality-gate-copy">{{t 'copy'}}</button>
{{#if default}}
- <button id="quality-gate-unset-as-default"><%= message('unset_as_default') -%></button>
+ <button id="quality-gate-unset-as-default">{{t 'unset_as_default'}}</button>
{{else}}
- <button id="quality-gate-set-as-default"><%= message('set_as_default') -%></button>
+ <button id="quality-gate-set-as-default">{{t 'set_as_default'}}</button>
{{/if}}
- <button id="quality-gate-delete" class="button-red"><%= message('delete') -%></button>
+ <button id="quality-gate-delete" class="button-red">{{t 'delete'}}</button>
</div>
{{/if}}
</script>
<script id="quality-gate-detail-projects-template" type="text/x-handlebars-template">
- <div class="quality-gate-section-name"><%= message('quality_gates.projects') -%></div>
+ <div class="quality-gate-section-name">{{t 'quality_gates.projects'}}</div>
{{#if default}}
- <p><%= message('quality_gates.projects_for_default') -%></p>
+ <p>{{t 'quality_gates.projects_for_default'}}</p>
{{else}}
<div id="select-list-projects"></div>
{{/if}}
<script id="quality-gate-edit-template" type="text/x-handlebars-template">
<form>
<div class="modal-head">
- {{#eq method "rename"}}<h2><%= message('quality_gates.rename') -%> {{name}}</h2>{{/eq}}
- {{#eq method "copy"}}<h2><%= message('quality_gates.copy') -%> {{name}}</h2>{{/eq}}
- {{#eq method "create"}}<h2><%= message('quality_gates.add') -%></h2>{{/eq}}
+ {{#eq method "rename"}}<h2>{{t 'quality_gates.rename'}} {{name}}</h2>{{/eq}}
+ {{#eq method "copy"}}<h2>{{t 'quality_gates.copy'}} {{name}}</h2>{{/eq}}
+ {{#eq method "create"}}<h2>{{t 'quality_gates.add'}}</h2>{{/eq}}
</div>
<div class="modal-body">
<div class="modal-error"></div>
<div class="modal-field">
- <label for="quality-gate-edit-name"><%= message('name') -%> <em class="mandatory">*</em></label>
+ <label for="quality-gate-edit-name">{{t 'name'}} <em class="mandatory">*</em></label>
<input id="quality-gate-edit-name" type="text" size="50" maxlength="100">
</div>
</div>
<div class="modal-foot">
- {{#eq method "rename"}}<button><%= message('save') -%></button>{{/eq}}
- {{#eq method "copy"}}<button><%= message('copy') -%></button>{{/eq}}
- {{#eq method "create"}}<button><%= message('create') -%></button>{{/eq}}
- <a id="quality-gate-cancel-create" class="action"><%= message('cancel') -%></a>
+ {{#eq method "rename"}}<button>{{t 'save'}}</button>{{/eq}}
+ {{#eq method "copy"}}<button>{{t 'copy'}}</button>{{/eq}}
+ {{#eq method "create"}}<button>{{t 'create'}}</button>{{/eq}}
+ <a id="quality-gate-cancel-create" class="action">{{t 'cancel'}}</a>
</div>
</form>
</script>
<script id="quality-gate-sidebar-list-empty-template" type="text/x-handlebars-template">
- <div class="line line-nowrap"><%= message('quality_gates.noQualityGates') -%></div>
+ <div class="line line-nowrap">{{t 'quality_gates.noQualityGates'}}</div>
</script>
<script id="quality-gate-sidebar-list-item-template" type="text/x-handlebars-template">
- <div class="line line-nowrap">{{name}} {{#if default}}<span class="subtitle">(<%= message('default') -%>)</span>{{/if}}</div>
+ <div class="line line-nowrap">{{name}} {{#if default}}<span class="subtitle">({{t 'default'}})</span>{{/if}}</div>
</script>
return url;
});
- Handlebars.registerHelper('translate', function(key, prefix) {
- var args = Array.prototype.slice.call(arguments, 0, -1),
- tokens = args.reduce(function(prev, current) {
- return prev.concat(current.split('.'));
- }, []),
- start = window.SS.phrases;
-
- return tokens.reduce(function(prev, current) {
- return current ? prev[current] : prev;
- }, start);
+ Handlebars.registerHelper('translate', function() {
+ var args = Array.prototype.slice.call(arguments, 0, -1);
+ return window.translate.apply(this, args);
+ });
+
+ Handlebars.registerHelper('t', function() {
+ var args = Array.prototype.slice.call(arguments, 0, -1);
+ return window.t.apply(this, args);
});
Handlebars.registerHelper('pluginActions', function(actions, options) {
convertWorkDuration = (value) ->
- daysPattern = transformPattern window.SS.workDuration.days
- hoursPattern = transformPattern window.SS.workDuration.hours
- minutesPattern = transformPattern window.SS.workDuration.minutes
+ daysPattern = transformPattern t('work_duration.x_days')
+ hoursPattern = transformPattern t('work_duration.x_hours')
+ minutesPattern = transformPattern t('work_duration.x_minutes')
days = value.match daysPattern
hours = value.match hoursPattern
hours = Math.floor((value - days * 8 * 60) / 60)
minutes = value % 60
result = []
- result.push window.SS.workDuration.days.replace('{0}', days) if days > 0
- result.push window.SS.workDuration.hours.replace('{0}', hours) if hours > 0
- result.push window.SS.workDuration.minutes.replace('{0}', minutes) if minutes > 0
+ result.push t('work_duration.x_days').replace('{0}', days) if days > 0
+ result.push t('work_duration.x_hours').replace('{0}', hours) if hours > 0
+ result.push t('work_duration.x_minutes').replace('{0}', minutes) if minutes > 0
result.join ' '
convertWorkDuration = function(value) {
var days, daysPattern, hours, hoursPattern, minutes, minutesPattern;
- daysPattern = transformPattern(window.SS.workDuration.days);
- hoursPattern = transformPattern(window.SS.workDuration.hours);
- minutesPattern = transformPattern(window.SS.workDuration.minutes);
+ daysPattern = transformPattern(t('work_duration.x_days'));
+ hoursPattern = transformPattern(t('work_duration.x_hours'));
+ minutesPattern = transformPattern(t('work_duration.x_minutes'));
days = value.match(daysPattern);
hours = value.match(hoursPattern);
minutes = value.match(minutesPattern);
minutes = value % 60;
result = [];
if (days > 0) {
- result.push(window.SS.workDuration.days.replace('{0}', days));
+ result.push(t('work_duration.x_days').replace('{0}', days));
}
if (hours > 0) {
- result.push(window.SS.workDuration.hours.replace('{0}', hours));
+ result.push(t('work_duration.x_hours').replace('{0}', hours));
}
if (minutes > 0) {
- result.push(window.SS.workDuration.minutes.replace('{0}', minutes));
+ result.push(t('work_duration.x_minutes').replace('{0}', minutes));
}
return result.join(' ');
};
App.openFirstQualityGate() if initial
- # Load metrics and the list of quality gates before start the application
+ # Call app, Load metrics and the list of quality gates before start the application
+ appXHR = jQuery.ajax
+ url: "#{baseUrl}/api/qualitygates/app"
+ .done (r) =>
+ App.canEdit = r.edit
+ App.periods = r.periods
+ window.messages = r.messages
+
qualityGatesXHR = App.qualityGates.fetch()
- jQuery.when(App.metrics.fetch(), qualityGatesXHR)
- .done ->
- # Set permissions
- App.canEdit = qualityGatesXHR.responseJSON.edit
+ jQuery.when(App.metrics.fetch(), qualityGatesXHR, appXHR)
+ .done ->
# Remove the initial spinner
jQuery('.quality-gate-page-loader').remove()
});
requirejs(['backbone', 'backbone.marionette', 'handlebars', 'quality-gate/collections/quality-gates', 'quality-gate/collections/metrics', 'quality-gate/views/quality-gate-sidebar-list-view', 'quality-gate/views/quality-gate-actions-view', 'quality-gate/views/quality-gate-edit-view', 'quality-gate/router', 'quality-gate/layout', 'common/handlebars-extensions'], function(Backbone, Marionette, Handlebars, QualityGates, Metrics, QualityGateSidebarListItemView, QualityGateActionsView, QualityGateEditView, QualityGateRouter, QualityGateLayout) {
- var App, qualityGatesXHR;
+ var App, appXHR, qualityGatesXHR,
+ _this = this;
jQuery.ajaxSetup({
error: function(jqXHR) {
var errorBox, text, _ref;
return App.openFirstQualityGate();
}
});
+ appXHR = jQuery.ajax({
+ url: "" + baseUrl + "/api/qualitygates/app"
+ }).done(function(r) {
+ App.canEdit = r.edit;
+ App.periods = r.periods;
+ return window.messages = r.messages;
+ });
qualityGatesXHR = App.qualityGates.fetch();
- return jQuery.when(App.metrics.fetch(), qualityGatesXHR).done(function() {
- App.canEdit = qualityGatesXHR.responseJSON.edit;
+ return jQuery.when(App.metrics.fetch(), qualityGatesXHR, appXHR).done(function() {
jQuery('.quality-gate-page-loader').remove();
return App.start();
});
deleteCondition: ->
- if confirm window.SS.phrases.areYouSure
+ if confirm t('are_you_sure')
@showSpinner()
@model.delete().done =>
@options.collectionView.updateConditions()
serializeData: ->
- period = _.findWhere(window.SS.metricPeriods, key: '' + this.model.get('period'))
+ period = _.findWhere(@options.app.periods, key: '' + this.model.get('period'))
_.extend super,
canEdit: @options.app.canEdit
- periods: window.SS.metricPeriods
+ periods: @options.app.periods
periodText: period?.text
QualityGateDetailConditionView.prototype.deleteCondition = function() {
var _this = this;
- if (confirm(window.SS.phrases.areYouSure)) {
+ if (confirm(t('are_you_sure'))) {
this.showSpinner();
return this.model["delete"]().done(function() {
_this.options.collectionView.updateConditions();
QualityGateDetailConditionView.prototype.serializeData = function() {
var period;
- period = _.findWhere(window.SS.metricPeriods, {
+ period = _.findWhere(this.options.app.periods, {
key: '' + this.model.get('period')
});
return _.extend(QualityGateDetailConditionView.__super__.serializeData.apply(this, arguments), {
canEdit: this.options.app.canEdit,
- periods: window.SS.metricPeriods,
+ periods: this.options.app.periods,
periodText: period != null ? period.text : void 0
});
};
@ui.metricSelect.select2
allowClear: false,
width: '250px',
- placeholder: window.SS.phrases.alerts.select_metric
+ placeholder: t('alerts.select_metric')
groupedMetrics: ->
return this.ui.metricSelect.select2({
allowClear: false,
width: '250px',
- placeholder: window.SS.phrases.alerts.select_metric
+ placeholder: t('alerts.select_metric')
});
};
deleteQualityGate: ->
- if confirm window.SS.phrases.areYouSure
+ if confirm t('are_you_sure')
@showSpinner()
jQuery.ajax
type: 'POST'
QualityGateDetailHeaderView.prototype.deleteQualityGate = function() {
var _this = this;
- if (confirm(window.SS.phrases.areYouSure)) {
+ if (confirm(t('are_you_sure'))) {
this.showSpinner();
return jQuery.ajax({
type: 'POST',
selectParameter: 'projectId'
selectParameterValue: 'id'
labels:
- selected: window.SS.phrases.projects.with
- deselected: window.SS.phrases.projects.without
- all: window.SS.phrases.projects.all
- noResults: window.SS.phrases.projects.noResults
+ selected: t('quality_gates.projects.with')
+ deselected: t('quality_gates.projects.without')
+ all: t('quality_gates.projects.all')
+ noResults: t('quality_gates.projects.noResults')
tooltips:
- select: window.SS.phrases.projects.select_hint
- deselect: window.SS.phrases.projects.deselect_hint
+ select: t('quality_gates.projects.select_hint')
+ deselect: t('quality_gates.projects.deselect_hint')
selectParameter: 'projectId',
selectParameterValue: 'id',
labels: {
- selected: window.SS.phrases.projects["with"],
- deselected: window.SS.phrases.projects.without,
- all: window.SS.phrases.projects.all,
- noResults: window.SS.phrases.projects.noResults
+ selected: t('quality_gates.projects.with'),
+ deselected: t('quality_gates.projects.without'),
+ all: t('quality_gates.projects.all'),
+ noResults: t('quality_gates.projects.noResults')
},
tooltips: {
- select: window.SS.phrases.projects.select_hint,
- deselect: window.SS.phrases.projects.deselect_hint
+ select: t('quality_gates.projects.select_hint'),
+ deselect: t('quality_gates.projects.deselect_hint')
}
});
}
describe 'WORK_DUR suite', ->
beforeEach ->
- window.SS =
- workDuration:
- days: '{0}d', hours: '{0}h', minutes: '{0}min'
+ window.SS = {}
+ window.SS.phrases =
+ 'work_duration':
+ 'x_days': '{0}d', 'x_hours': '{0}h', 'x_minutes': '{0}min'
@input = $('<input type="text">')
@input.appendTo $('body')
describe('WORK_DUR suite', function() {
beforeEach(function() {
- window.SS = {
- workDuration: {
- days: '{0}d',
- hours: '{0}h',
- minutes: '{0}min'
+ window.SS = {};
+ window.SS.phrases = {
+ 'work_duration': {
+ 'x_days': '{0}d',
+ 'x_hours': '{0}h',
+ 'x_minutes': '{0}min'
}
};
this.input = $('<input type="text">');
--- /dev/null
+$ = jQuery
+
+describe 'translation "t" suite', ->
+
+ beforeEach ->
+ window.messages =
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING ANOTHER'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(t('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(t('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(t('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'fallbacks to "translate"', ->
+ window.messages = undefined
+ expect(t('something')).toBe 'SOMETHING ANOTHER'
+
+
+ it 'returns the key when no translation', ->
+ expect(t('something_another')).toBe 'something_another'
+
+
+
+describe 'translation "translate" suite', ->
+
+ beforeEach ->
+ window.SS =
+ phrases:
+ 'something': 'SOMETHING'
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE'
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+
+
+ afterEach ->
+ window.messages = window.SS = undefined
+
+
+ it 'translates', ->
+ expect(translate('something')).toBe 'SOMETHING'
+
+
+ it 'translates with underscore', ->
+ expect(translate('something_with_underscore')).toBe 'SOMETHING_WITH_UNDERSCORE'
+
+
+ it 'translates with braces', ->
+ expect(translate('something_with{braces}')).toBe 'SOMETHING_WITH{braces}'
+
+
+ it 'returns the key when no translation', ->
+ expect(translate('something_another')).toBe 'something_another'
+
--- /dev/null
+// Generated by CoffeeScript 1.6.3
+(function() {
+ var $;
+
+ $ = jQuery;
+
+ describe('translation "t" suite', function() {
+ beforeEach(function() {
+ window.messages = {
+ 'something': 'SOMETHING',
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE',
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+ };
+ return window.SS = {
+ phrases: {
+ 'something': 'SOMETHING ANOTHER'
+ }
+ };
+ });
+ afterEach(function() {
+ return window.messages = window.SS = void 0;
+ });
+ it('translates', function() {
+ return expect(t('something')).toBe('SOMETHING');
+ });
+ it('translates with underscore', function() {
+ return expect(t('something_with_underscore')).toBe('SOMETHING_WITH_UNDERSCORE');
+ });
+ it('translates with braces', function() {
+ return expect(t('something_with{braces}')).toBe('SOMETHING_WITH{braces}');
+ });
+ it('fallbacks to "translate"', function() {
+ window.messages = void 0;
+ return expect(t('something')).toBe('SOMETHING ANOTHER');
+ });
+ return it('returns the key when no translation', function() {
+ return expect(t('something_another')).toBe('something_another');
+ });
+ });
+
+ describe('translation "translate" suite', function() {
+ beforeEach(function() {
+ return window.SS = {
+ phrases: {
+ 'something': 'SOMETHING',
+ 'something_with_underscore': 'SOMETHING_WITH_UNDERSCORE',
+ 'something_with{braces}': 'SOMETHING_WITH{braces}'
+ }
+ };
+ });
+ afterEach(function() {
+ return window.messages = window.SS = void 0;
+ });
+ it('translates', function() {
+ return expect(translate('something')).toBe('SOMETHING');
+ });
+ it('translates with underscore', function() {
+ return expect(translate('something_with_underscore')).toBe('SOMETHING_WITH_UNDERSCORE');
+ });
+ it('translates with braces', function() {
+ return expect(translate('something_with{braces}')).toBe('SOMETHING_WITH{braces}');
+ });
+ return it('returns the key when no translation', function() {
+ return expect(translate('something_another')).toBe('something_another');
+ });
+ });
+
+}).call(this);
--- /dev/null
+(function() {
+ var warn = function(message) {
+ if (console != null && typeof console.warn === 'function') {
+ console.warn(message);
+ }
+ };
+
+ window.t = function() {
+ if (!window.messages) {
+ return window.translate.apply(this, arguments);
+ }
+
+ var args = Array.prototype.slice.call(arguments, 0),
+ key = args.join('.');
+ if (!window.messages[key]) {
+ warn('No translation for "' + key + '"');
+ }
+ return (window.messages && window.messages[key]) || key;
+ };
+
+
+ window.translate = function() {
+ var args = Array.prototype.slice.call(arguments, 0),
+ tokens = args.reduce(function(prev, current) {
+ return prev.concat(current.split('.'));
+ }, []),
+ key = tokens.join('.'),
+ start = window.SS.phrases,
+ found = true;
+
+ var result = tokens.reduce(function(prev, current) {
+ if (!current || !prev[current]) {
+ warn('No translation for "' + key + '"');
+ found = false;
+ }
+ return current ? prev[current] : prev;
+ }, start);
+
+ return found ? result : key;
+ };
+
+})();
<js>/javascripts/third-party/select2.js</js>
<js>/javascripts/select2-jquery-ui-fix.js</js>
+ <js>/javascripts/translate.js</js>
+
<js>/javascripts/widgets/widget.js</js>
<js>/javascripts/widgets/bubble-chart.js</js>
<js>/javascripts/widgets/timeline.js</js>