diff --git a/resources/l10n/template.pot b/resources/l10n/template.pot index d12a31ef..dbe13d5c 100644 --- a/resources/l10n/template.pot +++ b/resources/l10n/template.pot @@ -6,9 +6,9 @@ #, fuzzy msgid "" msgstr "" -"Project-Id-Version: LOOT 0.10.0\n" +"Project-Id-Version: LOOT 0.10.1\n" "Report-Msgid-Bugs-To: https://github.com/loot/loot/issues\n" -"POT-Creation-Date: 2016-11-22 18:27+0000\n" +"POT-Creation-Date: 2016-11-22 19:11+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -25,10 +25,20 @@ msgstr "" msgid "Updating and parsing masterlist..." msgstr "" +#: src/gui/html/js/events.js:97 +#, javascript-format +msgid "Masterlist updated to revision %s." +msgstr "" + #: src/gui/html/js/events.js:100 msgid "No masterlist update was necessary." msgstr "" +#: src/gui/html/js/events.js:130 +#, javascript-format +msgid "Failed to sort plugins. Details: %s" +msgstr "" + #: src/gui/html/js/events.js:150 msgid "Sorting made no changes to the load order." msgstr "" @@ -75,6 +85,12 @@ msgstr "" msgid "The load order has been copied to the clipboard." msgstr "" +#: src/gui/html/js/events.js:267 +#, javascript-format +msgid "" +"You have not yet applied or cancelled your %s. Are you sure you want to quit?" +msgstr "" + #: src/gui/html/js/events.js:267 src/gui/html/js/translateStaticText.js:214 msgid "Quit" msgstr "" @@ -87,6 +103,22 @@ msgstr "" msgid "metadata edits" msgstr "" +#: src/gui/html/js/events.js:395 +#, javascript-format +msgid "The metadata for \"%s\" has been copied to the clipboard." +msgstr "" + +#: src/gui/html/js/events.js:399 +#, javascript-format +msgid "" +"Are you sure you want to clear all existing user-added metadata from \"%s\"?" +msgstr "" + +#: src/gui/html/js/events.js:414 +#, javascript-format +msgid "The user-added metadata for \"%s\" has been cleared." +msgstr "" + #: src/gui/html/js/filters.js:28 msgid "Do not clean" msgstr "" @@ -100,6 +132,11 @@ msgstr "" msgid "Error" msgstr "" +#: src/gui/html/js/initialise.js:250 +#, javascript-format +msgid "A [new release](%s) of LOOT is available." +msgstr "" + #: src/gui/html/js/translateStaticText.js:36 msgid "Active Plugin" msgstr "" diff --git a/scripts/git/pre-commit b/scripts/git/pre-commit index 771d732a..df6e6d82 100755 --- a/scripts/git/pre-commit +++ b/scripts/git/pre-commit @@ -5,7 +5,7 @@ # commit if more than one line in it has changed, otherwise discard any changes # to it. -xgettext -k"translate:1,1t" -k"translate:1c,2,t" --add-location=full --from-code=utf-8 --package-name=LOOT --package-version=0.10.1 --copyright-holder="WrinklyNinja" --msgid-bugs-address="https://github.com/loot/loot/issues" -o resources/l10n/template.pot src/gui/html/js/*.* src/gui/*.cpp src/backend/*/*.* src/backend/*.* +xgettext -k"translate:1,1t" -k"translateFormatted:1" --add-location=full --from-code=utf-8 --package-name=LOOT --package-version=0.10.1 --copyright-holder="WrinklyNinja" --msgid-bugs-address="https://github.com/loot/loot/issues" -o resources/l10n/template.pot src/gui/html/js/*.* src/gui/*.cpp src/gui/query/*.h src/backend/*/*.* src/backend/*.* sed -i 's|charset=CHARSET|charset=UTF-8|' resources/l10n/template.pot diff --git a/src/gui/html/elements/loot-plugin-card.html b/src/gui/html/elements/loot-plugin-card.html index 3ab1470a..5d7f40e4 100644 --- a/src/gui/html/elements/loot-plugin-card.html +++ b/src/gui/html/elements/loot-plugin-card.html @@ -240,7 +240,7 @@ updateIsCleanIcon() { this.$.isClean.hidden = !this.data.cleanedWith; - this.$.isCleanTooltip.textContent = loot.l10n.translate('Verified clean by %s', this.data.cleanedWith); + this.$.isCleanTooltip.textContent = loot.l10n.translateFormatted('Verified clean by %s', this.data.cleanedWith); }, updateStyling() { diff --git a/src/gui/html/js/events.js b/src/gui/html/js/events.js index 8fad28ba..e8fc9b59 100644 --- a/src/gui/html/js/events.js +++ b/src/gui/html/js/events.js @@ -94,7 +94,7 @@ function updateMasterlist() { } }); - loot.Dialog.showNotification(loot.l10n.translate('Masterlist updated to revision %s.', + loot.Dialog.showNotification(loot.l10n.translateFormatted('Masterlist updated to revision %s.', loot.game.masterlist.revision)); } else { loot.Dialog.showNotification(loot.l10n.translate('No masterlist update was necessary.')); @@ -127,7 +127,7 @@ function onSortPlugins() { const message = result.globalMessages.find(item => ( item.text.startsWith('Cyclic interaction detected' ))).text; - throw new Error(loot.l10n.translate('Failed to sort plugins. Details: %s', message)); + throw new Error(loot.l10n.translateFormatted('Failed to sort plugins. Details: %s', message)); } /* Check if sorted load order differs from current load order. */ @@ -264,7 +264,7 @@ function onOpenLogLocation() { loot.query('openLogLocation').catch(loot.handlePromiseError); } function handleUnappliedChangesClose(change) { - loot.Dialog.askQuestion('', loot.l10n.translate('You have not yet applied or cancelled your %s. Are you sure you want to quit?', change), loot.l10n.translate('Quit'), (result) => { + loot.Dialog.askQuestion('', loot.l10n.translateFormatted('You have not yet applied or cancelled your %s. Are you sure you want to quit?', change), loot.l10n.translate('Quit'), (result) => { if (!result) { return; } @@ -392,11 +392,11 @@ function onEditorClose(evt) { } function onCopyMetadata(evt) { loot.query('copyMetadata', evt.target.getName()).then(() => { - loot.Dialog.showNotification(loot.l10n.translate('The metadata for "%s" has been copied to the clipboard.', evt.target.getName())); + loot.Dialog.showNotification(loot.l10n.translateFormatted('The metadata for "%s" has been copied to the clipboard.', evt.target.getName())); }).catch(loot.handlePromiseError); } function onClearMetadata(evt) { - loot.Dialog.askQuestion('', loot.l10n.translate('Are you sure you want to clear all existing user-added metadata from "%s"?', evt.target.getName()), loot.l10n.translate('Clear'), (result) => { + loot.Dialog.askQuestion('', loot.l10n.translateFormatted('Are you sure you want to clear all existing user-added metadata from "%s"?', evt.target.getName()), loot.l10n.translate('Clear'), (result) => { if (!result) { return; } @@ -411,7 +411,7 @@ function onClearMetadata(evt) { existingPlugin.update(plugin); } - loot.Dialog.showNotification(loot.l10n.translate('The user-added metadata for "%s" has been cleared.', evt.target.getName())); + loot.Dialog.showNotification(loot.l10n.translateFormatted('The user-added metadata for "%s" has been cleared.', evt.target.getName())); /* Now perform search again. If there is no current search, this won't do anything. */ document.getElementById('searchBar').search(); diff --git a/src/gui/html/js/initialise.js b/src/gui/html/js/initialise.js index 3e16fa6a..e25dcf51 100644 --- a/src/gui/html/js/initialise.js +++ b/src/gui/html/js/initialise.js @@ -247,7 +247,7 @@ dom.appendGeneralMessages([{ type: 'warn', - content: loot.l10n.translate('A [new release](%s) of LOOT is available.', 'https://github.com/loot/loot/releases/latest'), + content: loot.l10n.translateFormatted('A [new release](%s) of LOOT is available.', 'https://github.com/loot/loot/releases/latest'), }]); }) .catch(handlePromiseError); diff --git a/src/gui/html/js/translator.js b/src/gui/html/js/translator.js index f48509c2..f412f1df 100644 --- a/src/gui/html/js/translator.js +++ b/src/gui/html/js/translator.js @@ -64,7 +64,11 @@ }); } - translate(text, ...substitutions) { + translate(text) { + return this.translateFormatted(text); + } + + translateFormatted(text, ...substitutions) { if (text === undefined) { return ''; } diff --git a/src/tests/gui/html/js/test_translator.js b/src/tests/gui/html/js/test_translator.js index ca865cdf..ac0362b2 100644 --- a/src/tests/gui/html/js/test_translator.js +++ b/src/tests/gui/html/js/test_translator.js @@ -72,6 +72,50 @@ describe('Translator', () => { l10n.translate('foo').should.equal('bar'); }); + }); + + describe('#translateFormatted()', () => { + let l10n; + + beforeEach(() => { + l10n = new loot.Translator(); + }); + + it('should return original string if the translator has not been loaded', () => { + l10n.translateFormatted('foo').should.equal('foo'); + }); + + it('should return an empty string if nothing is passed', () => + l10n.load().then(() => { + l10n.translateFormatted().should.equal(''); + }) + ); + + it('should return the input string if the current locale is "en"', () => + l10n.load().then(() => { + l10n.translateFormatted('foo').should.equal('foo'); + }) + ); + + it('should return the translated string if locale data has been loaded', () => { + /* Since loading data doesn't work in the browser, hack it by setting some + data manually. */ + l10n.jed = new window.Jed({ + locale_data: { + messages: { + '': { + domain: 'messages', + lang: 'en', + plural_forms: 'nplurals=2; plural=(n != 1);', + }, + foo: ['bar'], + }, + }, + domain: 'messages', + }); + + l10n.translateFormatted('foo').should.equal('bar'); + }); it('should subsitute additional arguments into string', () => { /* Since loading data doesn't work in the browser, hack it by setting some @@ -90,7 +134,7 @@ describe('Translator', () => { domain: 'messages', }); - l10n.translate('foo %1$s %2$s', 'is not', 'bar').should.equal('bar is bar'); + l10n.translateFormatted('foo %1$s %2$s', 'is not', 'bar').should.equal('bar is bar'); }); }); });