diff options
author | Morris Jobke <hey@morrisjobke.de> | 2015-01-07 12:57:33 +0100 |
---|---|---|
committer | Morris Jobke <hey@morrisjobke.de> | 2015-01-07 12:57:33 +0100 |
commit | 5ce295907fd9469905d561de71d83149a6c0f6c5 (patch) | |
tree | 2cadbfbac7f3a10531e55830911fc5d5ee168b13 /core/js | |
parent | a014b9ad9c0947b09e249e770d7149b02819bbc0 (diff) | |
parent | bfdf0db7c069f3a456c48b185f6222c1dcef2bbe (diff) | |
download | nextcloud-server-5ce295907fd9469905d561de71d83149a6c0f6c5.tar.gz nextcloud-server-5ce295907fd9469905d561de71d83149a6c0f6c5.zip |
Merge pull request #12687 from owncloud/auto-escape-t-placeholders
Auto escape t placeholders
Diffstat (limited to 'core/js')
-rw-r--r-- | core/js/l10n.js | 38 | ||||
-rw-r--r-- | core/js/share.js | 10 | ||||
-rw-r--r-- | core/js/tests/specs/l10nSpec.js | 10 |
3 files changed, 43 insertions, 15 deletions
diff --git a/core/js/l10n.js b/core/js/l10n.js index 0c660584322..60ffa949191 100644 --- a/core/js/l10n.js +++ b/core/js/l10n.js @@ -62,8 +62,8 @@ OC.L10N = { * Register an app's translation bundle. * * @param {String} appName name of the app - * @param {Object<String,String>} strings bundle - * @param {{Function|String}} [pluralForm] optional plural function or plural string + * @param {Object<String,String>} bundle + * @param {Function|String} [pluralForm] optional plural function or plural string */ register: function(appName, bundle, pluralForm) { this._bundles[appName] = bundle || {}; @@ -129,9 +129,17 @@ OC.L10N = { * @param {string} text the string to translate * @param [vars] map of placeholder key to value * @param {number} [count] number to replace %n with + * @param {array} [options] options array + * @param {bool} [options.escape=true] enable/disable auto escape of placeholders (by default enabled) * @return {string} */ - translate: function(app, text, vars, count) { + translate: function(app, text, vars, count, options) { + var defaultOptions = { + escape: true + }, + allOptions = options || {}; + _.defaults(allOptions, defaultOptions); + // TODO: cache this function to avoid inline recreation // of the same function over and over again in case // translate() is used in a loop @@ -139,7 +147,15 @@ OC.L10N = { return text.replace(/%n/g, count).replace(/{([^{}]*)}/g, function (a, b) { var r = vars[b]; - return typeof r === 'string' || typeof r === 'number' ? r : a; + if(typeof r === 'string' || typeof r === 'number') { + if(allOptions.escape) { + return escapeHTML(r); + } else { + return r; + } + } else { + return a; + } } ); }; @@ -160,13 +176,15 @@ OC.L10N = { /** * Translate a plural string * @param {string} app the id of the app for which to translate the string - * @param {string} text_singular the string to translate for exactly one object - * @param {string} text_plural the string to translate for n objects + * @param {string} textSingular the string to translate for exactly one object + * @param {string} textPlural the string to translate for n objects * @param {number} count number to determine whether to use singular or plural * @param [vars] map of placeholder key to value + * @param {array} [options] options array + * @param {bool} [options.escape=true] enable/disable auto escape of placeholders (by default enabled) * @return {string} Translated string */ - translatePlural: function(app, textSingular, textPlural, count, vars) { + translatePlural: function(app, textSingular, textPlural, count, vars, options) { var identifier = '_' + textSingular + '_::_' + textPlural + '_'; var bundle = this._bundles[app] || {}; var value = bundle[identifier]; @@ -174,15 +192,15 @@ OC.L10N = { var translation = value; if ($.isArray(translation)) { var plural = this._pluralFunctions[app](count); - return this.translate(app, translation[plural.plural], vars, count); + return this.translate(app, translation[plural.plural], vars, count, options); } } if(count === 1) { - return this.translate(app, textSingular, vars, count); + return this.translate(app, textSingular, vars, count, options); } else{ - return this.translate(app, textPlural, vars, count); + return this.translate(app, textPlural, vars, count, options); } } }; diff --git a/core/js/share.js b/core/js/share.js index 00d1dab519c..2692ff60b5c 100644 --- a/core/js/share.js +++ b/core/js/share.js @@ -255,7 +255,7 @@ OC.Share={ message = this._formatSharedByOwner(owner); } else if (recipients) { - message = t('core', 'Shared with {recipients}', {recipients: escapeHTML(recipients)}); + message = t('core', 'Shared with {recipients}', {recipients: recipients}); } action.html(' <span>' + message + '</span>').prepend(img); if (owner) { @@ -355,9 +355,9 @@ OC.Share={ var html = '<div id="dropdown" class="drop shareDropDown" data-item-type="'+itemType+'" data-item-source="'+itemSource+'">'; if (data !== false && data.reshare !== false && data.reshare.uid_owner !== undefined) { if (data.reshare.share_type == OC.Share.SHARE_TYPE_GROUP) { - html += '<span class="reshare">'+t('core', 'Shared with you and the group {group} by {owner}', {group: escapeHTML(data.reshare.share_with), owner: escapeHTML(data.reshare.displayname_owner)})+'</span>'; + html += '<span class="reshare">'+t('core', 'Shared with you and the group {group} by {owner}', {group: data.reshare.share_with, owner: data.reshare.displayname_owner})+'</span>'; } else { - html += '<span class="reshare">'+t('core', 'Shared with you by {owner}', {owner: escapeHTML(data.reshare.displayname_owner)})+'</span>'; + html += '<span class="reshare">'+t('core', 'Shared with you by {owner}', {owner: data.reshare.displayname_owner})+'</span>'; } html += '<br />'; } @@ -395,7 +395,7 @@ OC.Share={ var defaultExpireMessage = ''; if ((itemType === 'folder' || itemType === 'file') && oc_appconfig.core.defaultExpireDateEnforced) { - defaultExpireMessage = t('core', 'The public link will expire no later than {days} days after it is created', {'days': escapeHTML(oc_appconfig.core.defaultExpireDate)}) + '<br/>'; + defaultExpireMessage = t('core', 'The public link will expire no later than {days} days after it is created', {'days': oc_appconfig.core.defaultExpireDate}) + '<br/>'; } html += '<label for="linkText" class="hidden-visually">'+t('core', 'Link')+'</label>'; @@ -622,7 +622,7 @@ OC.Share={ if (collectionList.length > 0) { $(collectionList).append(', '+shareWithDisplayName); } else { - var html = '<li style="clear: both;" data-collection="'+item+'">'+t('core', 'Shared in {item} with {user}', {'item': escapeHTML(item), user: escapeHTML(shareWithDisplayName)})+'</li>'; + var html = '<li style="clear: both;" data-collection="'+item+'">'+t('core', 'Shared in {item} with {user}', {'item': item, user: shareWithDisplayName})+'</li>'; $('#shareWithList').prepend(html); } } else { diff --git a/core/js/tests/specs/l10nSpec.js b/core/js/tests/specs/l10nSpec.js index cf7c8b11b1c..bafc7746d6c 100644 --- a/core/js/tests/specs/l10nSpec.js +++ b/core/js/tests/specs/l10nSpec.js @@ -42,6 +42,16 @@ describe('OC.L10N tests', function() { t(TEST_APP, 'Hello {name}, the weather is {weather}', {name: 'Steve', weather: t(TEST_APP, 'sunny')}) ).toEqual('Hallo Steve, das Wetter ist sonnig'); }); + it('returns text with escaped placeholder', function() { + expect( + t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'}) + ).toEqual('Hello <strong>Steve</strong>'); + }); + it('returns text with not escaped placeholder', function() { + expect( + t(TEST_APP, 'Hello {name}', {name: '<strong>Steve</strong>'}, null, {escape: false}) + ).toEqual('Hello <strong>Steve</strong>'); + }); }); describe('plurals', function() { function checkPlurals() { |