Deprecate OC.L10N functions in favor of translation functions from `@nextcloud/l10n`

Signed-off-by: Ferdinand Thiessen <rpm@fthiessen.de>
pull/36287/head
Ferdinand Thiessen 1 year ago
parent 7e3372cd92
commit cdc3848345

@ -81,12 +81,11 @@ import {
unregisterMenu,
} from './menu'
import { isUserAdmin } from './admin'
import L10N, {
getLanguage,
getLocale,
} from './l10n'
import L10N from './l10n'
import {
getCanonicalLocale,
getLanguage,
getLocale,
} from '@nextcloud/l10n'
import {
@ -231,7 +230,13 @@ export default {
* @deprecated 20.0.0 use `getCanonicalLocale` from https://www.npmjs.com/package/@nextcloud/l10n
*/
getCanonicalLocale,
/**
* @deprecated 26.0.0 use `getLocale` from https://www.npmjs.com/package/@nextcloud/l10n
*/
getLocale,
/**
* @deprecated 26.0.0 use `getLanguage` from https://www.npmjs.com/package/@nextcloud/l10n
*/
getLanguage,
/**

@ -1,90 +0,0 @@
/**
* @copyright 2019 Christoph Wurst <christoph@winzerhof-wurst.at>
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author John Molakvoæ <skjnldsv@protonmail.com>
*
* @license AGPL-3.0-or-later
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
// This var is global because it's shared across webpack bundles
window._oc_l10n_registry_translations = window._oc_l10n_registry_translations || {}
window._oc_l10n_registry_plural_functions = window._oc_l10n_registry_plural_functions || {}
/**
* @param {string} appId the app id
* @param {object} translations the translations list
* @param {Function} pluralFunction the translations list
*/
const register = (appId, translations, pluralFunction) => {
window._oc_l10n_registry_translations[appId] = translations
window._oc_l10n_registry_plural_functions[appId] = pluralFunction
}
/**
* @param {string} appId the app id
* @param {object} translations the translations list
* @param {Function} pluralFunction the translations list
*/
const extend = (appId, translations, pluralFunction) => {
window._oc_l10n_registry_translations[appId] = Object.assign(
window._oc_l10n_registry_translations[appId],
translations
)
window._oc_l10n_registry_plural_functions[appId] = pluralFunction
}
/**
* @param {string} appId the app id
* @param {object} translations the translations list
* @param {Function} pluralFunction the translations list
*/
export const registerAppTranslations = (appId, translations, pluralFunction) => {
if (!hasAppTranslations(appId)) {
register(appId, translations, pluralFunction)
} else {
extend(appId, translations, pluralFunction)
}
}
/**
* @param {string} appId the app id
*/
export const unregisterAppTranslations = appId => {
delete window._oc_l10n_registry_translations[appId]
delete window._oc_l10n_registry_plural_functions[appId]
}
/**
* @param {string} appId the app id
* @return {boolean}
*/
export const hasAppTranslations = appId => {
return window._oc_l10n_registry_translations[appId] !== undefined
&& window._oc_l10n_registry_plural_functions[appId] !== undefined
}
/**
* @param {string} appId the app id
* @return {object}
*/
export const getAppTranslations = appId => {
return {
translations: window._oc_l10n_registry_translations[appId] || {},
pluralFunction: window._oc_l10n_registry_plural_functions[appId],
}
}

@ -1,7 +1,6 @@
/**
* Copyright (c) 2014 Vincent Petry <pvince81@owncloud.com>
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
*
* @author Christoph Wurst <christoph@winzerhof-wurst.at>
* @author Daniel Kesselberg <mail@danielkesselberg.de>
@ -28,79 +27,56 @@
*
*/
import _ from 'underscore'
import $ from 'jquery'
import DOMPurify from 'dompurify'
import Handlebars from 'handlebars'
import identity from 'lodash/fp/identity'
import escapeHTML from 'escape-html'
import { generateFilePath } from '@nextcloud/router'
import OC from './index'
import {
getAppTranslations,
hasAppTranslations,
registerAppTranslations,
unregisterAppTranslations,
} from './l10n-registry'
loadTranslations,
translate,
translatePlural,
register,
unregister,
} from '@nextcloud/l10n'
/**
* L10N namespace with localization functions.
*
* @namespace OC.L10n
* @deprecated 26.0.0 use https://www.npmjs.com/package/@nextcloud/l10n
*/
const L10n = {
/**
* Load an app's translation bundle if not loaded already.
*
* @deprecated 26.0.0 use `loadTranslations` from https://www.npmjs.com/package/@nextcloud/l10n
*
* @param {string} appName name of the app
* @param {Function} callback callback to be called when
* the translations are loaded
* @return {Promise} promise
*/
load(appName, callback) {
// already available ?
if (hasAppTranslations(appName) || OC.getLocale() === 'en') {
const deferred = $.Deferred()
const promise = deferred.promise()
promise.then(callback)
deferred.resolve()
return promise
}
const self = this
const url = generateFilePath(appName, 'l10n', OC.getLocale() + '.json')
// load JSON translation bundle per AJAX
return $.get(url)
.then(
function(result) {
if (result.translations) {
self.register(appName, result.translations, result.pluralForm)
}
})
.then(callback)
},
load: loadTranslations,
/**
* Register an app's translation bundle.
*
* @deprecated 26.0.0 use `register` from https://www.npmjs.com/package/@nextcloud/l10
*
* @param {string} appName name of the app
* @param {Object<string, string>} bundle bundle
*/
register(appName, bundle) {
registerAppTranslations(appName, bundle, this._getPlural)
},
register,
/**
* @private
* @deprecated 26.0.0 use `unregister` from https://www.npmjs.com/package/@nextcloud/l10n
*/
_unregister: unregisterAppTranslations,
_unregister: unregister,
/**
* Translate a string
*
* @deprecated 26.0.0 use `translate` from https://www.npmjs.com/package/@nextcloud/l10n
*
* @param {string} app the id of the app for which to translate the string
* @param {string} text the string to translate
* @param {object} [vars] map of placeholder key to value
@ -110,49 +86,13 @@ const L10n = {
* @param {boolean} [options.sanitize=true] enable/disable sanitization (by default enabled)
* @return {string}
*/
translate(app, text, vars, count, options) {
const defaultOptions = {
escape: true,
sanitize: true,
}
const allOptions = options || {}
_.defaults(allOptions, defaultOptions)
const optSanitize = allOptions.sanitize ? DOMPurify.sanitize : identity
const optEscape = allOptions.escape ? escapeHTML : identity
// TODO: cache this function to avoid inline recreation
// of the same function over and over again in case
// translate() is used in a loop
const _build = function(text, vars, count) {
return text.replace(/%n/g, count).replace(/{([^{}]*)}/g,
function(a, b) {
const r = vars[b]
if (typeof r === 'string' || typeof r === 'number') {
return optSanitize(optEscape(r))
} else {
return optSanitize(a)
}
}
)
}
let translation = text
const bundle = getAppTranslations(app)
const value = bundle.translations[text]
if (typeof (value) !== 'undefined') {
translation = value
}
if (typeof vars === 'object' || count !== undefined) {
return optSanitize(_build(translation, vars, count))
} else {
return optSanitize(translation)
}
},
translate,
/**
* Translate a plural string
*
* @deprecated 26.0.0 use `translatePlural` from https://www.npmjs.com/package/@nextcloud/l10n
*
* @param {string} app the id of the app for which to translate the string
* @param {string} textSingular the string to translate for exactly one object
* @param {string} textPlural the string to translate for n objects
@ -162,203 +102,11 @@ const L10n = {
* @param {boolean} [options.escape=true] enable/disable auto escape of placeholders (by default enabled)
* @return {string} Translated string
*/
translatePlural(app, textSingular, textPlural, count, vars, options) {
const identifier = '_' + textSingular + '_::_' + textPlural + '_'
const bundle = getAppTranslations(app)
const value = bundle.translations[identifier]
if (typeof (value) !== 'undefined') {
const translation = value
if ($.isArray(translation)) {
const plural = bundle.pluralFunction(count)
return this.translate(app, translation[plural], vars, count, options)
}
}
if (count === 1) {
return this.translate(app, textSingular, vars, count, options)
} else {
return this.translate(app, textPlural, vars, count, options)
}
},
/**
* The plural function taken from symfony
*
* @param {number} number the number of elements
* @return {number}
* @private
*/
_getPlural(number) {
let language = OC.getLanguage()
if (language === 'pt-BR') {
// temporary set a locale for brazilian
language = 'xbr'
}
if (typeof language === 'undefined' || language === '') {
return (number === 1) ? 0 : 1
}
if (language.length > 3) {
language = language.substring(0, language.lastIndexOf('-'))
}
/*
* The plural rules are derived from code of the Zend Framework (2010-09-25),
* which is subject to the new BSD license (http://framework.zend.com/license/new-bsd).
* Copyright (c) 2005-2010 Zend Technologies USA Inc. (http://www.zend.com)
*/
switch (language) {
case 'az':
case 'bo':
case 'dz':
case 'id':
case 'ja':
case 'jv':
case 'ka':
case 'km':
case 'kn':
case 'ko':
case 'ms':
case 'th':
case 'tr':
case 'vi':
case 'zh':
return 0
case 'af':
case 'bn':
case 'bg':
case 'ca':
case 'da':
case 'de':
case 'el':
case 'en':
case 'eo':
case 'es':
case 'et':
case 'eu':
case 'fa':
case 'fi':
case 'fo':
case 'fur':
case 'fy':
case 'gl':
case 'gu':
case 'ha':
case 'he':
case 'hu':
case 'is':
case 'it':
case 'ku':
case 'lb':
case 'ml':
case 'mn':
case 'mr':
case 'nah':
case 'nb':
case 'ne':
case 'nl':
case 'nn':
case 'no':
case 'oc':
case 'om':
case 'or':
case 'pa':
case 'pap':
case 'ps':
case 'pt':
case 'so':
case 'sq':
case 'sv':
case 'sw':
case 'ta':
case 'te':
case 'tk':
case 'ur':
case 'zu':
return (number === 1) ? 0 : 1
case 'am':
case 'bh':
case 'fil':
case 'fr':
case 'gun':
case 'hi':
case 'hy':
case 'ln':
case 'mg':
case 'nso':
case 'xbr':
case 'ti':
case 'wa':
return ((number === 0) || (number === 1)) ? 0 : 1
case 'be':
case 'bs':
case 'hr':
case 'ru':
case 'sh':
case 'sr':
case 'uk':
return ((number % 10 === 1) && (number % 100 !== 11)) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2)
case 'cs':
case 'sk':
return (number === 1) ? 0 : (((number >= 2) && (number <= 4)) ? 1 : 2)
case 'ga':
return (number === 1) ? 0 : ((number === 2) ? 1 : 2)
case 'lt':
return ((number % 10 === 1) && (number % 100 !== 11)) ? 0 : (((number % 10 >= 2) && ((number % 100 < 10) || (number % 100 >= 20))) ? 1 : 2)
case 'sl':
return (number % 100 === 1) ? 0 : ((number % 100 === 2) ? 1 : (((number % 100 === 3) || (number % 100 === 4)) ? 2 : 3))
case 'mk':
return (number % 10 === 1) ? 0 : 1
case 'mt':
return (number === 1) ? 0 : (((number === 0) || ((number % 100 > 1) && (number % 100 < 11))) ? 1 : (((number % 100 > 10) && (number % 100 < 20)) ? 2 : 3))
case 'lv':
return (number === 0) ? 0 : (((number % 10 === 1) && (number % 100 !== 11)) ? 1 : 2)
case 'pl':
return (number === 1) ? 0 : (((number % 10 >= 2) && (number % 10 <= 4) && ((number % 100 < 12) || (number % 100 > 14))) ? 1 : 2)
case 'cy':
return (number === 1) ? 0 : ((number === 2) ? 1 : (((number === 8) || (number === 11)) ? 2 : 3))
case 'ro':
return (number === 1) ? 0 : (((number === 0) || ((number % 100 > 0) && (number % 100 < 20))) ? 1 : 2)
case 'ar':
return (number === 0) ? 0 : ((number === 1) ? 1 : ((number === 2) ? 2 : (((number % 100 >= 3) && (number % 100 <= 10)) ? 3 : (((number % 100 >= 11) && (number % 100 <= 99)) ? 4 : 5))))
default:
return 0
}
},
translatePlural,
}
export default L10n
/**
* Returns the user's locale
*
* @return {string} locale string
*/
export const getLocale = () => $('html').data('locale') ?? 'en'
/**
* Returns the user's language
*
* @return {string} language string
*/
export const getLanguage = () => $('html').prop('lang')
Handlebars.registerHelper('t', function(app, text) {
return L10n.translate(app, text)
return translate(app, text)
})

50
package-lock.json generated

@ -21,7 +21,7 @@
"@nextcloud/event-bus": "^3.0.2",
"@nextcloud/files": "^3.0.0-beta.5",
"@nextcloud/initial-state": "^2.0.0",
"@nextcloud/l10n": "^2.0.0",
"@nextcloud/l10n": "^2.1.0",
"@nextcloud/logger": "^2.5.0",
"@nextcloud/moment": "^1.2.1",
"@nextcloud/password-confirmation": "^4.0.4",
@ -4331,9 +4331,9 @@
"integrity": "sha512-xmNP30v/RnkJ2z1HcuEo7YfcLJJa+FdWTwgNldXHOlMeMbl/ESpsGkWL2sULrhYurz64L0JpfwEdi/cHcmyuZQ=="
},
"node_modules/@nextcloud/l10n": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-2.0.0.tgz",
"integrity": "sha512-ugE1h/lDewtKFUf/mXq7i/jP0p/OW+18edt7PFNIabYHJvbRpLgBQsYH5UIOqTWUPc/LyuK3NVdIXkALdGPwSA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-2.1.0.tgz",
"integrity": "sha512-rToqXwxcsDTcijvSdgyJAKuOuW7XggDYH00/t3GN5HzO1lNNnVtOj7cc5WmiTknciM+En2oVSMFIUPs6HehjVQ==",
"dependencies": {
"@nextcloud/router": "^2.0.0",
"dompurify": "^2.4.1",
@ -4952,9 +4952,9 @@
}
},
"node_modules/@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
"integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
"dev": true
},
"node_modules/@sideway/pinpoint": {
@ -12957,9 +12957,9 @@
}
},
"node_modules/http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
"dev": true,
"optional": true,
"peer": true
@ -23698,9 +23698,9 @@
}
},
"node_modules/ua-parser-js": {
"version": "0.7.33",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
"integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==",
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
"dev": true,
"funding": [
{
@ -28496,9 +28496,9 @@
"integrity": "sha512-xmNP30v/RnkJ2z1HcuEo7YfcLJJa+FdWTwgNldXHOlMeMbl/ESpsGkWL2sULrhYurz64L0JpfwEdi/cHcmyuZQ=="
},
"@nextcloud/l10n": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-2.0.0.tgz",
"integrity": "sha512-ugE1h/lDewtKFUf/mXq7i/jP0p/OW+18edt7PFNIabYHJvbRpLgBQsYH5UIOqTWUPc/LyuK3NVdIXkALdGPwSA==",
"version": "2.1.0",
"resolved": "https://registry.npmjs.org/@nextcloud/l10n/-/l10n-2.1.0.tgz",
"integrity": "sha512-rToqXwxcsDTcijvSdgyJAKuOuW7XggDYH00/t3GN5HzO1lNNnVtOj7cc5WmiTknciM+En2oVSMFIUPs6HehjVQ==",
"requires": {
"@nextcloud/router": "^2.0.0",
"dompurify": "^2.4.1",
@ -28987,9 +28987,9 @@
}
},
"@sideway/formula": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.1.tgz",
"integrity": "sha512-/poHZJJVjx3L+zVD6g9KgHfYnb443oi7wLu/XKojDviHy6HOEOA6z1Trk5aR1dGcmPenJEgb2sK2I80LeS3MIg==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/@sideway/formula/-/formula-3.0.0.tgz",
"integrity": "sha512-vHe7wZ4NOXVfkoRb8T5otiENVlT7a3IAiw7H5M2+GO+9CDgcVUUsX1zalAztCmwyOr2RUTGJdgB+ZvSVqmdHmg==",
"dev": true
},
"@sideway/pinpoint": {
@ -35290,9 +35290,9 @@
}
},
"http-cache-semantics": {
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz",
"integrity": "sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==",
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.0.tgz",
"integrity": "sha512-carPklcUh7ROWRK7Cv27RPtdhYhUsela/ue5/jKzjegVvXDqM2ILE9Q2BGn9JZJh1g87cp56su/FgQSzcWS8cQ==",
"dev": true,
"optional": true,
"peer": true
@ -43579,9 +43579,9 @@
"dev": true
},
"ua-parser-js": {
"version": "0.7.33",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.33.tgz",
"integrity": "sha512-s8ax/CeZdK9R/56Sui0WM6y9OFREJarMRHqLB2EwkovemBxNQ+Bqu8GAsUnVcXKgphb++ghr/B2BZx4mahujPw==",
"version": "0.7.31",
"resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-0.7.31.tgz",
"integrity": "sha512-qLK/Xe9E2uzmYI3qLeOmI0tEOt+TBBQyUIAh4aAgU05FVYzeZrKUdkAZfBNVGRaHVgV0TDkdEngJSw/SyQchkQ==",
"dev": true
},
"uc.micro": {

@ -46,7 +46,7 @@
"@nextcloud/event-bus": "^3.0.2",
"@nextcloud/files": "^3.0.0-beta.5",
"@nextcloud/initial-state": "^2.0.0",
"@nextcloud/l10n": "^2.0.0",
"@nextcloud/l10n": "^2.1.0",
"@nextcloud/logger": "^2.5.0",
"@nextcloud/moment": "^1.2.1",
"@nextcloud/password-confirmation": "^4.0.4",

Loading…
Cancel
Save