From 8bdd273aadf263ef6af4c3b0bfa0f0e5647d6bab Mon Sep 17 00:00:00 2001 From: krzysztofmadejski Date: Mon, 14 Nov 2016 14:15:31 +0000 Subject: [PATCH] #459 passing tests --- demos/multiview/app.js | 9 ++----- src/i18n/pl.js | 3 +++ src/i18n/view.i18n.js | 21 +++++++++++++---- src/view.flot.js | 15 +++++------- src/view.grid.js | 28 +++++++++++----------- src/view.map.js | 16 ++++++------- src/view.multiview.js | 33 +++++++++++--------------- src/view.slickgrid.js | 23 ++++++++---------- src/widget.fields.js | 6 ++--- src/widget.filtereditor.js | 10 ++++---- src/widget.queryeditor.js | 10 +++----- src/widget.valuefilter.js | 13 ++++------- test/view.i18n.test.js | 48 ++++---------------------------------- 13 files changed, 91 insertions(+), 144 deletions(-) diff --git a/demos/multiview/app.js b/demos/multiview/app.js index 6b5831fb..c50980ea 100755 --- a/demos/multiview/app.js +++ b/demos/multiview/app.js @@ -64,14 +64,12 @@ var createMultiView = function(dataset, state) { $el.appendTo(window.explorerDiv); // customize the subviews for the MultiView - var locale = 'en'; var views = [ { id: 'grid', label: 'Grid', view: new recline.View.SlickGrid({ model: dataset, - locale: locale, state: { gridOptions: { editable: true, @@ -95,16 +93,14 @@ var createMultiView = function(dataset, state) { id: 'graph', label: 'Graph', view: new recline.View.Graph({ - model: dataset, - locale: locale + model: dataset }) }, { id: 'map', label: 'Map', view: new recline.View.Map({ - model: dataset, - locale: locale + model: dataset }) } ]; @@ -113,7 +109,6 @@ var createMultiView = function(dataset, state) { model: dataset, el: $el, state: state, - locale: locale, views: views }); return multiView; diff --git a/src/i18n/pl.js b/src/i18n/pl.js index a00e8d2d..74c9fa1c 100644 --- a/src/i18n/pl.js +++ b/src/i18n/pl.js @@ -15,6 +15,9 @@ this.recline.View.translations['pl'] = { Reorder_row: 'Przesuń wiersz', Update: 'Zaktualizuj', Cancel: 'Anuluj', + Updating_row: 'Aktualizuję wiersz', + Row_updated_successfully: 'Wiersz został zaktualizowany', + Error_saving_row: 'Wystąpił błąd aktualizacji wiersza', Filters: 'Filtry', Add_filter: 'Dodaj filtr', Remove_this_filter: 'Usuń filtr', diff --git a/src/i18n/view.i18n.js b/src/i18n/view.i18n.js index 2775e96b..15b4665b 100644 --- a/src/i18n/view.i18n.js +++ b/src/i18n/view.i18n.js @@ -1,8 +1,14 @@ /*jshint multistr:true */ "use strict"; -var I18nMessages = function(uniqueID, translations, languageResolverOrLocale, appHardcodedLocale) { +var I18nMessages = function(libraryID, translations, languageResolverOrLocale, appHardcodedLocale) { + if (typeof this === 'undefined') { + return new I18nMessages(libraryID, translations, languageResolverOrLocale, appHardcodedLocale); + } + var defaultResolver = function() { + var h = $('html'); + return h.attr('lang') || h.attr('xml:lang'); }; // which locale should we use? @@ -16,15 +22,20 @@ var I18nMessages = function(uniqueID, translations, languageResolverOrLocale, ap languageResolverOrLocale = appHardcodedLocale; } - if (I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale]) { - return I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale]; + if (((I18nMessages.prototype._formatters || {})[libraryID] || {})[languageResolverOrLocale]) { + return I18nMessages.prototype._formatters[libraryID][languageResolverOrLocale]; } - I18nMessages.prototype._formatters[uniqueID, languageResolverOrLocale] = this; + I18nMessages.prototype._formatters = I18nMessages.prototype._formatters || {}; + I18nMessages.prototype._formatters[libraryID] = I18nMessages.prototype._formatters[libraryID] || {}; + I18nMessages.prototype._formatters[libraryID][languageResolverOrLocale] = this; // ========== VARIABLES & FUNCTIONS ========== var self = this; + this.uniqueID = this.uniqueID; this.locale = languageResolverOrLocale; + this.translations = translations; + this.appHardcodedLocale = appHardcodedLocale; this.cache= {}; this.getLocale = function() { @@ -37,7 +48,7 @@ var I18nMessages = function(uniqueID, translations, languageResolverOrLocale, ap values = (typeof values !== 'undefined') ? values : {}; // get the message from current locale - var msg = this.translations[this.locale][key]; + var msg = (this.translations[this.locale] || {})[key]; // fallback to key or default message if no translation is defined if (msg == null) { diff --git a/src/view.flot.js b/src/view.flot.js index 38616f51..5906fa93 100644 --- a/src/view.flot.js +++ b/src/view.flot.js @@ -22,7 +22,7 @@ this.recline.View = this.recline.View || {}; // // NB: should *not* provide an el argument to the view but must let the view // generate the element itself (you can then append view.el to the DOM. -my.Flot = Backbone.I18nView.extend({ +my.Flot = Backbone.View.extend({ template: ' \
\
\ @@ -38,7 +38,6 @@ my.Flot = Backbone.I18nView.extend({ initialize: function(options) { var self = this; this.graphColors = ["#edc240", "#afd8f8", "#cb4b4b", "#4da74d", "#9440ed"]; - this.initializeI18n(options.locale); _.bindAll(this, 'render', 'redraw', '_toolTip', '_xaxisLabel'); this.needToRedraw = false; @@ -57,8 +56,7 @@ my.Flot = Backbone.I18nView.extend({ this.previousTooltipPoint = {x: null, y: null}; this.editor = new my.FlotControls({ model: this.model, - state: this.state.toJSON(), - locale: this.locale + state: this.state.toJSON() }); this.listenTo(this.editor.state, 'change', function() { self.state.set(self.editor.state.toJSON()); @@ -69,7 +67,7 @@ my.Flot = Backbone.I18nView.extend({ render: function() { var self = this; - var tmplData = _.extend(this.model.toTemplateJSON(), this.MustacheFormatter()); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache(this.model.toTemplateJSON()); var htmls = Mustache.render(this.template, tmplData); this.$el.html(htmls); this.$graph = this.$el.find('.panel.graph'); @@ -364,7 +362,7 @@ my.Flot = Backbone.I18nView.extend({ } }); -my.FlotControls = Backbone.I18nView.extend({ +my.FlotControls = Backbone.View.extend({ className: "editor", template: ' \
\ @@ -433,14 +431,13 @@ my.FlotControls = Backbone.I18nView.extend({ _.bindAll(this, 'render'); this.listenTo(this.model.fields, 'reset add', this.render); this.state = new recline.Model.ObjectState(options.state); - this.initializeI18n(options.locale); this.render(); }, render: function() { var self = this; var tmplData = this.model.toTemplateJSON(); - tmplData = _.extend(tmplData, this.MustacheFormatter()); + tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); var htmls = Mustache.render(this.template, tmplData); this.$el.html(htmls); @@ -503,7 +500,7 @@ my.FlotControls = Backbone.I18nView.extend({ seriesName: String.fromCharCode(idx + 64 + 1) }, this.model.toTemplateJSON()); - data = _.extend(data, this.MustacheFormatter()); + data = I18nMessages('recline', recline.View.translations).injectMustache(data); var htmls = Mustache.render(this.templateSeriesEditor, data); this.$el.find('.editor-series-group').append(htmls); return this; diff --git a/src/view.grid.js b/src/view.grid.js index 3ef12f77..d2b0792c 100644 --- a/src/view.grid.js +++ b/src/view.grid.js @@ -10,7 +10,7 @@ this.recline.View = this.recline.View || {}; // Provides a tabular view on a Dataset. // // Initialize it with a `recline.Model.Dataset`. -my.Grid = Backbone.I18nView.extend({ +my.Grid = Backbone.View.extend({ tagName: "div", className: "recline-grid-container", @@ -23,7 +23,6 @@ my.Grid = Backbone.I18nView.extend({ hiddenFields: [] }, modelEtc.state ); - this.initializeI18n(modelEtc.locale); this.state = new recline.Model.ObjectState(state); }, @@ -115,7 +114,8 @@ my.Grid = Backbone.I18nView.extend({ } }); var tmplData = this.toTemplateJSON(); - tmplData = _.extend(tmplData, this.MustacheFormatter()); + tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); + var htmls = Mustache.render(this.template, tmplData); this.$el.html(htmls); this.model.records.forEach(function(doc) { @@ -124,8 +124,7 @@ my.Grid = Backbone.I18nView.extend({ var newView = new my.GridRow({ model: doc, el: tr, - fields: self.fields, - locale: self.locale + fields: self.fields }); newView.render(); }); @@ -167,12 +166,11 @@ my.Grid = Backbone.I18nView.extend({ // fields: mydatasets.fields // a FieldList object // }); // -my.GridRow = Backbone.I18nView.extend({ +my.GridRow = Backbone.View.extend({ initialize: function(initData) { _.bindAll(this, 'render'); this._fields = initData.fields; this.listenTo(this.model, 'change', this.render); - this.initializeI18n(initData.locale); }, template: ' \ @@ -207,7 +205,7 @@ my.GridRow = Backbone.I18nView.extend({ render: function() { this.$el.attr('data-id', this.model.id); var tmplData = this.toTemplateJSON(); - tmplData = _.extend(tmplData, this.MustacheFormatter()); + tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); var html = Mustache.render(this.template, tmplData); this.$el.html(html); return this; @@ -237,8 +235,9 @@ my.GridRow = Backbone.I18nView.extend({ var cell = $(e.target).siblings('.data-table-cell-value'); cell.data("previousContents", cell.text()); - var templated = Mustache.render(this.cellEditorTemplate, _.extend({value: cell.text()}, this.MustacheFormatter())); - cell.html(templated); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache({value: cell.text()}); + var output = Mustache.render(this.cellEditorTemplate, tmplData); + cell.html(output); }, onEditorOK: function(e) { @@ -250,14 +249,15 @@ my.GridRow = Backbone.I18nView.extend({ var newData = {}; newData[field] = newValue; this.model.set(newData); - throw "Czym tu jest this? " + this; - this.trigger('recline:flash', {message: "Updating row...", loader: true}); + + var fmt = I18nMessages('recline', recline.View.translations); + this.trigger('recline:flash', {message: fmt.t("Updating_row") + "...", loader: true}); this.model.save().then(function(response) { - this.trigger('recline:flash', {message: "Row updated successfully", category: 'success'}); + this.trigger('recline:flash', {message: fmt.t("Row_updated_successfully"), category: 'success'}); }) .fail(function() { this.trigger('recline:flash', { - message: 'Error saving row', + message: fmt.t('Error_saving_row'), category: 'error', persist: true }); diff --git a/src/view.map.js b/src/view.map.js index 1c1ac875..8763d476 100644 --- a/src/view.map.js +++ b/src/view.map.js @@ -38,7 +38,7 @@ this.recline.View = this.recline.View || {}; // // * map: the Leaflet map (L.Map) // * features: Leaflet GeoJSON layer containing all the features (L.GeoJSON) -my.Map = Backbone.I18nView.extend({ +my.Map = Backbone.View.extend({ template: ' \
\
\ @@ -58,8 +58,6 @@ my.Map = Backbone.I18nView.extend({ // this will be the Leaflet L.Map object (setup below) this.map = null; - this.initializeI18n(options.locale); - var stateData = _.extend({ geomField: null, lonField: null, @@ -97,8 +95,7 @@ my.Map = Backbone.I18nView.extend({ this.menu = new my.MapMenu({ model: this.model, - state: this.state.toJSON(), - locale: this.locale + state: this.state.toJSON() }); this.listenTo(this.menu.state, 'change', function() { self.state.set(self.menu.state.toJSON()); @@ -176,7 +173,8 @@ my.Map = Backbone.I18nView.extend({ // Also sets up the editor fields and the map if necessary. render: function() { var self = this; - var htmls = Mustache.render(this.template, _.extend(this.model.toTemplateJSON(), this.MustacheFormatter())); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache(this.model.toTemplateJSON()); + var htmls = Mustache.render(this.template, tmplData); this.$el.html(htmls); this.$map = this.$el.find('.panel.map'); this.redraw(); @@ -508,7 +506,7 @@ my.Map = Backbone.I18nView.extend({ } }); -my.MapMenu = Backbone.I18nView.extend({ +my.MapMenu = Backbone.View.extend({ className: 'editor', template: ' \ @@ -584,7 +582,6 @@ my.MapMenu = Backbone.I18nView.extend({ this.listenTo(this.model.fields, 'change', this.render); this.state = new recline.Model.ObjectState(options.state); this.listenTo(this.state, 'change', this.render); - this.initializeI18n(options.locale); this.render(); }, @@ -593,7 +590,8 @@ my.MapMenu = Backbone.I18nView.extend({ // Also sets up the editor fields and the map if necessary. render: function() { var self = this; - var htmls = Mustache.render(this.template, _.extend(this.model.toTemplateJSON(), this.MustacheFormatter())); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache(this.model.toTemplateJSON()); + var htmls = Mustache.render(this.template, tmplData); this.$el.html(htmls); if (this._geomReady() && this.model.fields.length){ diff --git a/src/view.multiview.js b/src/view.multiview.js index 9f0029b2..9187a750 100644 --- a/src/view.multiview.js +++ b/src/view.multiview.js @@ -94,7 +94,7 @@ this.recline.View = this.recline.View || {}; // of views in use -- e.g. those specified by the views argument -- but instead // expect either that the default views are fine or that the client to have // initialized the MultiView with the relevant views themselves. -my.MultiView = Backbone.I18nView.extend({ +my.MultiView = Backbone.View.extend({ template: ' \
\
\ @@ -131,8 +131,7 @@ my.MultiView = Backbone.I18nView.extend({ initialize: function(options) { var self = this; this._setupState(options.state); - // todo any better idea to pass locale than by initialization? singleton? or does Intl API handle that? - this.initializeI18n(options.locale); + var fmt = I18nMessages('recline', recline.View.translations); // Hash of 'page' views (i.e. those for whole page) keyed by page name if (options.views) { @@ -140,28 +139,28 @@ my.MultiView = Backbone.I18nView.extend({ } else { this.pageViews = [{ id: 'grid', - label: this.t('Grid'), + label: fmt.t('Grid'), view: new my.SlickGrid({ model: this.model, state: this.state.get('view-grid') }) }, { id: 'graph', - label: this.t('Graph'), + label: fmt.t('Graph'), view: new my.Graph({ model: this.model, state: this.state.get('view-graph') }) }, { id: 'map', - label: this.t('Map'), + label: fmt.t('Map'), view: new my.Map({ model: this.model, state: this.state.get('view-map') }) }, { id: 'timeline', - label: this.t('Timeline'), + label: fmt.t('Timeline'), view: new my.Timeline({ model: this.model, state: this.state.get('view-timeline') @@ -174,17 +173,15 @@ my.MultiView = Backbone.I18nView.extend({ } else { this.sidebarViews = [{ id: 'filterEditor', - label: this.t('Filters'), + label: fmt.t('Filters'), view: new my.FilterEditor({ - model: this.model, - locale: this.locale + model: this.model }) }, { id: 'fieldsView', - label: this.t('Fields'), + label: fmt.t('Fields'), view: new my.Fields({ - model: this.model, - locale: this.locale + model: this.model }) }]; } @@ -208,7 +205,7 @@ my.MultiView = Backbone.I18nView.extend({ }); this.listenTo(this.model, 'query:done', function() { self.clearNotifications(); - self.$el.find('.doc-count').text(self.model.recordCount || this.t('Unknown')); + self.$el.find('.doc-count').text(self.model.recordCount || fmt.t('Unknown')); }); this.listenTo(this.model, 'query:fail', function(error) { self.clearNotifications(); @@ -223,7 +220,7 @@ my.MultiView = Backbone.I18nView.extend({ msg += error.message; } } else { - msg = this.t('backend_error', {}, 'There was an error querying the backend'); + msg = fmt.t('backend_error', {}, 'There was an error querying the backend'); } self.notify({message: msg, category: 'error', persist: true}); }); @@ -242,7 +239,7 @@ my.MultiView = Backbone.I18nView.extend({ var tmplData = this.model.toTemplateJSON(); tmplData.views = this.pageViews; tmplData.sidebarViews = this.sidebarViews; - tmplData = _.extend(tmplData, this.MustacheFormatter()); + tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); var template = Mustache.render(this.template, tmplData); this.$el.html(template); @@ -273,8 +270,7 @@ my.MultiView = Backbone.I18nView.extend({ this.$el.find('.recline-results-info').after(this.pager.el); this.queryEditor = new recline.View.QueryEditor({ - model: this.model.queryState, - locale: this.locale + model: this.model.queryState }); this.$el.find('.query-editor-here').append(this.queryEditor.el); @@ -373,7 +369,6 @@ my.MultiView = Backbone.I18nView.extend({ // now get default data + hash url plus initial state and initial our state object with it var stateData = _.extend({ - locale: 'en', query: query, 'view-graph': graphState, backend: this.model.backend.__type__, diff --git a/src/view.slickgrid.js b/src/view.slickgrid.js index e10a8d78..ad6b6bf0 100644 --- a/src/view.slickgrid.js +++ b/src/view.slickgrid.js @@ -40,11 +40,10 @@ this.recline.View = this.recline.View || {}; // } // }); //// NB: you need an explicit height on the element for slickgrid to work -my.SlickGrid = Backbone.I18nView.extend({ +my.SlickGrid = Backbone.View.extend({ initialize: function(modelEtc) { var self = this; this.$el.addClass('recline-slickgrid'); - this.initializeI18n(modelEtc.locale); // Template for row delete menu , change it if you don't love this.templates = { @@ -73,7 +72,7 @@ my.SlickGrid = Backbone.I18nView.extend({ if(this.state.get("gridOptions") && this.state.get("gridOptions").enabledAddRow != undefined && this.state.get("gridOptions").enabledAddRow == true ){ - this.editor = new my.GridControl({locale: this.locale}) + this.editor = new my.GridControl() this.elSidebar = this.editor.$el this.listenTo(this.editor.state, 'change', function(){ this.model.records.add(new recline.Model.Record()) @@ -104,18 +103,19 @@ my.SlickGrid = Backbone.I18nView.extend({ }, self.state.get('gridOptions')); // We need all columns, even the hidden ones, to show on the column picker - var columns = []; + var columns = []; + var fmt = I18nMessages('recline', recline.View.translations); // custom formatter as default one escapes html // plus this way we distinguish between rendering/formatting and computed value (so e.g. sort still works ...) // row = row index, cell = cell index, value = value, columnDef = column definition, dataContext = full row values var formatter = function(row, cell, value, columnDef, dataContext) { if(columnDef.id == "del"){ - var formatted = Mustache.render(self.templates.deleterow, _.extend({}, self.MustacheFormatter())); + var formatted = Mustache.render(self.templates.deleterow, fmt.injectMustache({})); return formatted; } if(columnDef.id == "#"){ - var formatted = Mustache.render(self.templates.reorderrows, _.extend({}, self.MustacheFormatter())); + var formatted = Mustache.render(self.templates.reorderrows, fmt.injectMustache({})); return formatted; } @@ -133,10 +133,9 @@ my.SlickGrid = Backbone.I18nView.extend({ var validator = function(field) { return function(value){ if (field.type == "date" && isNaN(Date.parse(value))){ - // todo test translation return { valid: false, - msg: self.t('date_required', {}, "A date is required, check field field-date-format") + msg: fmt.t('date_required', {}, "A date is required, check field field-date-format") }; } else { return {valid: true, msg :null } @@ -443,7 +442,7 @@ my.SlickGrid = Backbone.I18nView.extend({ // Add new grid Control to display a new row add menu bouton // It display a simple side-bar menu ,for user to add new // row to grid -my.GridControl= Backbone.I18nView.extend({ +my.GridControl= Backbone.View.extend({ className: "recline-row-add", // Template for row edit menu , change it if you don't love template: '

', @@ -452,16 +451,14 @@ my.GridControl= Backbone.I18nView.extend({ var self = this; _.bindAll(this, 'render'); this.state = new recline.Model.ObjectState(); - options = options || {}; - this.initializeI18n(options.locale); - this.render(); }, render: function() { var self = this; - var formatted = Mustache.render(this.template, _.extend({}, this.MustacheFormatter())); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache({}); + var formatted = Mustache.render(this.template, tmplData); this.$el.html(formatted); }, diff --git a/src/widget.fields.js b/src/widget.fields.js index 4758c927..d3583ad4 100644 --- a/src/widget.fields.js +++ b/src/widget.fields.js @@ -22,7 +22,7 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; -my.Fields = Backbone.I18nView.extend({ +my.Fields = Backbone.View.extend({ className: 'recline-fields-view', template: ' \
\ @@ -75,8 +75,6 @@ my.Fields = Backbone.I18nView.extend({ self.render(); }); this.$el.find('.collapse').collapse(); - this.initializeI18n(model.locale); - this.render(); }, render: function() { @@ -89,7 +87,7 @@ my.Fields = Backbone.I18nView.extend({ out.facets = field.facets.toJSON(); tmplData.fields.push(out); }); - tmplData = _.extend(tmplData, this.MustacheFormatter()); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); var templated = Mustache.render(this.template, tmplData); this.$el.html(templated); } diff --git a/src/widget.filtereditor.js b/src/widget.filtereditor.js index 4f4a4ebe..8637aac2 100644 --- a/src/widget.filtereditor.js +++ b/src/widget.filtereditor.js @@ -6,7 +6,7 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; -my.FilterEditor = Backbone.I18nView.extend({ +my.FilterEditor = Backbone.View.extend({ className: 'recline-filter-editor well', template: ' \
\ @@ -100,12 +100,10 @@ my.FilterEditor = Backbone.I18nView.extend({ 'submit form.js-edit': 'onTermFiltersUpdate', 'submit form.js-add': 'onAddFilter' }, - initialize: function(options) { + initialize: function() { _.bindAll(this, 'render'); this.listenTo(this.model.fields, 'all', this.render); this.listenTo(this.model.queryState, 'change change:filters:new-blank', this.render); - this.initializeI18n(options.locale); - this.render(); }, render: function() { @@ -118,10 +116,10 @@ my.FilterEditor = Backbone.I18nView.extend({ }); tmplData.fields = this.model.fields.toJSON(); tmplData.filterRender = function() { - var filterData = _.extend(this, self.MustacheFormatter()); + var filterData = I18nMessages('recline', recline.View.translations).injectMustache(this); return Mustache.render(self.filterTemplates[this.type], filterData); }; - tmplData = _.extend(tmplData, self.MustacheFormatter()); + tmplData = I18nMessages('recline', recline.View.translations).injectMustache(tmplData); var out = Mustache.render(this.template, tmplData); this.$el.html(out); }, diff --git a/src/widget.queryeditor.js b/src/widget.queryeditor.js index be2620d6..9360c914 100644 --- a/src/widget.queryeditor.js +++ b/src/widget.queryeditor.js @@ -6,7 +6,7 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; -my.QueryEditor = Backbone.I18nView.extend({ +my.QueryEditor = Backbone.View.extend({ className: 'recline-query-editor', template: ' \
\ @@ -27,12 +27,9 @@ my.QueryEditor = Backbone.I18nView.extend({ 'submit form': 'onFormSubmit' }, - initialize: function(options) { + initialize: function() { _.bindAll(this, 'render'); this.listenTo(this.model, 'change', this.render); - options = options || {}; - this.initializeI18n(options.locale); - this.render(); }, onFormSubmit: function(e) { @@ -41,8 +38,7 @@ my.QueryEditor = Backbone.I18nView.extend({ this.model.set({q: query}); }, render: function() { - var tmplData = this.model.toJSON(); - tmplData = _.extend(tmplData, this.MustacheFormatter()); + var tmplData = I18nMessages('recline', recline.View.translations).injectMustache(this.model.toJSON()); var templated = Mustache.render(this.template, tmplData); this.$el.html(templated); } diff --git a/src/widget.valuefilter.js b/src/widget.valuefilter.js index 97babc6f..286c0ee0 100644 --- a/src/widget.valuefilter.js +++ b/src/widget.valuefilter.js @@ -6,7 +6,7 @@ this.recline.View = this.recline.View || {}; (function($, my) { "use strict"; -my.ValueFilter = Backbone.I18nView.extend({ +my.ValueFilter = Backbone.View.extend({ className: 'recline-filter-editor well', template: ' \
\ @@ -50,14 +50,10 @@ my.ValueFilter = Backbone.I18nView.extend({ 'submit form.js-edit': 'onTermFiltersUpdate', 'submit form.js-add': 'onAddFilter' }, - initialize: function(options) { + initialize: function() { _.bindAll(this, 'render'); this.listenTo(this.model.fields, 'all', this.render); this.listenTo(this.model.queryState, 'change change:filters:new-blank', this.render); - - options = options || {}; - this.initializeI18n(options.locale); - this.render(); }, render: function() { @@ -69,10 +65,11 @@ my.ValueFilter = Backbone.I18nView.extend({ return filter; }); tmplData.fields = this.model.fields.toJSON(); + var fmt = I18nMessages('recline', recline.View.translations); tmplData.filterRender = function() { - return Mustache.render(self.filterTemplates.term, this); + return Mustache.render(self.filterTemplates.term, fmt.injectMustache(this)); }; - var out = Mustache.render(this.template, tmplData); + var out = Mustache.render(this.template, fmt.injectMustache(tmplData)); this.$el.html(out); }, updateFilter: function(input) { diff --git a/test/view.i18n.test.js b/test/view.i18n.test.js index 40919b95..9150466f 100644 --- a/test/view.i18n.test.js +++ b/test/view.i18n.test.js @@ -14,30 +14,6 @@ test('translate simple key default locale', function () { equal(fmt.t('Add_row'), 'Add row'); }); -test('override custom locale', function () { - var fmt = I18nMessages('recline', recline.View.translations, 'pl'); - var oldTranslation = recline.View.translations['pl']['Grid']; - - // set custom strings in external app after including recline script - recline.View.translations['pl']['Grid'] = 'Dane'; - - equal(fmt.t('Grid'), 'Dane'); - - recline.View.translations['pl']['Grid'] = oldTranslation; -}); - -test('override default locale', function () { - var fmt = I18nMessages('recline', recline.View.translations, 'en'); - var oldTranslation = recline.View.translations['en']['Grid']; - - // set custom strings in external app after including recline script - recline.View.translations['en']['Grid'] = 'Data'; - - equal(fmt.t('Grid'), 'Data'); - - recline.View.translations['en']['Grid'] = oldTranslation; -}); - test('fallback to key if translation not present', function () { var fmt = I18nMessages('somelib', Fixture.getTranslations()); @@ -53,11 +29,6 @@ test('fallback to default message', function () { test('mustache formatter - simple key', function () { var fmt = I18nMessages('somelib', Fixture.getTranslations(), 'pl'); - // test without template rendering - var mustacheIntegration = fmt.injectMustache({}); - equal(mustacheIntegration.t.Grid, 'Tabela') - - // test within template rendering var template = '{{t.Grid}}'; var tmplData = {}; @@ -84,7 +55,7 @@ test('mustache formatter - complex key', function () { test('translate complex key default locale', function () { var fmt = I18nMessages('somelib', Fixture.getTranslations(), 'pl'); - equal(view.t('codeforall', {records: 3}, '{records} records'), '3 records'); + equal(fmt.t('codeforall', {records: 3}, '{records} records'), '3 records'); }); test('mustache formatter - translate complex key custom locale', function () { @@ -93,7 +64,7 @@ test('mustache formatter - translate complex key custom locale', function () { codeforall: '{records} rekordy' } }; - var fmt = I18nMessages('somelib', translations, 'pl'); + var fmt = I18nMessages('somelib2', translations, 'pl'); equal(fmt.t('codeforall', {records: 3}, '{records} records'), '3 rekordy'); }); @@ -101,14 +72,14 @@ test('mustache formatter - translate complex key custom locale', function () { test('mustache formatter - translate complex key custom locale custom count', function () { var translations = { pl: { - codeforall: {records, plural, ' + + codeforall: '{records, plural, ' + '=0 {brak zdjęć}' + '=1 {{records} zdjęcie}' + 'few {{records} zdjęcia}' + 'other {{records} zdjęć}}' } }; - var fmt = I18nMessages('somelib', translations, 'pl'); + var fmt = I18nMessages('somelib3', translations, 'pl'); equal(fmt.t('codeforall', {records: 0}), 'brak zdjęć'); equal(fmt.t('codeforall', {records: 1}), '1 zdjęcie'); @@ -131,15 +102,6 @@ test('I18nMessages default locale', function () { equal(fmt.getLocale(), 'en'); }); -test('I18nMessages default html:lang default locale resolver', function () { - var fmt = I18nMessages('somelib', {}); - - - $('html').attr('lang', 'de'); - equal(fmt.getLocale(), 'de'); - $('html').attr('lang', null); -}); - test('I18nMessages default locale custom resolver', function () { var localeResolver = function() { return 'fr'; }; var fmt = I18nMessages('somelib', {}, localeResolver); @@ -147,7 +109,7 @@ test('I18nMessages default locale custom resolver', function () { equal(fmt.getLocale(), 'fr'); }); -test('I18nMessages singletons, function () { +test('I18nMessages singletons', function () { var lib1_pl = I18nMessages('lib1', {}, 'pl'); var lib2_pl = I18nMessages('lib2', {}, 'pl'); var lib1_en = I18nMessages('lib1', {}, 'en');