Update xstatic-angular-gettext to 2.3.8.0
Change-Id: Ic0c5929299b6f5ad9347b579b0f9d60d1921bfd9
This commit is contained in:
parent
3d1b433477
commit
6ec7c032b3
@ -1,8 +1,6 @@
|
||||
include README.txt
|
||||
recursive-include xstatic/pkg/angular_gettext *
|
||||
|
||||
recursive-include xstatic *
|
||||
global-exclude *.pyc
|
||||
global-exclude *.pyo
|
||||
global-exclude *.orig
|
||||
global-exclude *.rej
|
||||
|
||||
|
20
setup.cfg
Normal file
20
setup.cfg
Normal file
@ -0,0 +1,20 @@
|
||||
[metadata]
|
||||
name = XStatic-Angular-Gettext
|
||||
description = Angular-Gettext 2.3.8 (XStatic packaging standard)
|
||||
description-file = README.rst
|
||||
maintainer = Rob Cresswell
|
||||
maintainer-email = robert.cresswell@outlook.com
|
||||
home-page = https://angular-gettext.rocketeer.be/
|
||||
keywords = angular_gettext xstatic
|
||||
license = MIT
|
||||
zip_safe = False
|
||||
namespace_packages =
|
||||
xstatic
|
||||
xstatic.pkg
|
||||
|
||||
[files]
|
||||
packages =
|
||||
xstatic
|
||||
|
||||
[bdist_wheel]
|
||||
universal = True
|
8
setup.py
8
setup.py
@ -1,11 +1,10 @@
|
||||
from setuptools import setup, find_packages
|
||||
from xstatic.pkg import angular_gettext as xs
|
||||
|
||||
# The README.txt file should be written in reST so that PyPI can use
|
||||
# it to generate your project's PyPI page.
|
||||
long_description = open('README.txt').read()
|
||||
|
||||
from setuptools import setup, find_packages
|
||||
|
||||
setup(
|
||||
name=xs.PACKAGE_NAME,
|
||||
version=xs.PACKAGE_VERSION,
|
||||
@ -19,9 +18,8 @@ setup(
|
||||
url=xs.HOMEPAGE,
|
||||
platforms=xs.PLATFORMS,
|
||||
packages=find_packages(),
|
||||
namespace_packages=['xstatic', 'xstatic.pkg', ],
|
||||
namespace_packages=['xstatic', 'xstatic.pkg'],
|
||||
include_package_data=True,
|
||||
zip_safe=False,
|
||||
install_requires=[], # nothing! :)
|
||||
# if you like, you MAY use the 'XStatic' package.
|
||||
install_requires=[],
|
||||
)
|
||||
|
@ -11,9 +11,9 @@ NAME = __name__.split('.')[-1] # package name (e.g. 'foo' or 'foo_bar')
|
||||
# please use a all-lowercase valid python
|
||||
# package name
|
||||
|
||||
VERSION = '2.1.0' # version of the packaged files, please use the upstream
|
||||
VERSION = '2.3.8' # version of the packaged files, please use the upstream
|
||||
# version number
|
||||
BUILD = '1' # our package build number, so we can release new builds
|
||||
BUILD = '0' # our package build number, so we can release new builds
|
||||
# with fixes for xstatic stuff.
|
||||
PACKAGE_VERSION = VERSION + '.' + BUILD # version used for PyPi
|
||||
|
||||
@ -24,20 +24,22 @@ CLASSIFIERS = []
|
||||
KEYWORDS = '%s xstatic' % NAME
|
||||
|
||||
# XStatic-* package maintainer:
|
||||
MAINTAINER = 'Thai Tran'
|
||||
MAINTAINER_EMAIL = 'tqtran@us.ibm.com'
|
||||
MAINTAINER = 'Rob Cresswell'
|
||||
MAINTAINER_EMAIL = 'robert.cresswell@outlook.com'
|
||||
|
||||
# this refers to the project homepage of the stuff we packaged:
|
||||
HOMEPAGE = 'https://angular-gettext.rocketeer.be/'
|
||||
|
||||
# this refers to all files:
|
||||
LICENSE = '(same as %s)' % DISPLAY_NAME
|
||||
LICENSE = 'MIT'
|
||||
|
||||
from os.path import join, dirname
|
||||
BASE_DIR = join(dirname(__file__), 'data')
|
||||
# linux package maintainers just can point to their file locations like this:
|
||||
#BASE_DIR = '/usr/share/javascript/jquery'
|
||||
|
||||
MAIN='angular-gettext.js'
|
||||
|
||||
LOCATIONS = {
|
||||
# CDN locations (if no public CDN exists, use an empty dict)
|
||||
# if value is a string, it is a base location, just append relative
|
||||
|
550
xstatic/pkg/angular_gettext/data/angular-gettext.js
vendored
550
xstatic/pkg/angular_gettext/data/angular-gettext.js
vendored
@ -1,5 +1,45 @@
|
||||
/**
|
||||
* @ngdoc module
|
||||
* @name gettext
|
||||
* @packageName angular-gettext
|
||||
* @description Super simple Gettext for Angular.JS
|
||||
*
|
||||
* A sample application can be found at https://github.com/rubenv/angular-gettext-example.
|
||||
* This is an adaptation of the [TodoMVC](http://todomvc.com/) example. You can use this as a guideline while adding {@link angular-gettext angular-gettext} to your own application.
|
||||
*/
|
||||
/**
|
||||
* @ngdoc factory
|
||||
* @module gettext
|
||||
* @name gettextPlurals
|
||||
* @param {String} [langCode=en] language code
|
||||
* @param {Number} [n=0] number to calculate form for
|
||||
* @returns {Number} plural form number
|
||||
* @description Provides correct plural form id for the given language
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextPlurals('ru', 10); // 1
|
||||
* gettextPlurals('en', 1); // 0
|
||||
* gettextPlurals(); // 1
|
||||
* ```
|
||||
*/
|
||||
angular.module('gettext', []);
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @module gettext
|
||||
* @name gettext
|
||||
* @kind function
|
||||
* @param {String} str annotation key
|
||||
* @description Gettext constant function for annotating strings
|
||||
*
|
||||
* ```js
|
||||
* angular.module('myApp', ['gettext']).config(function(gettext) {
|
||||
* /// MyApp document title
|
||||
* gettext('my-app.title');
|
||||
* ...
|
||||
* })
|
||||
* ```
|
||||
*/
|
||||
angular.module('gettext').constant('gettext', function (str) {
|
||||
/*
|
||||
* Does nothing, simply returns the input string.
|
||||
@ -10,7 +50,19 @@ angular.module('gettext').constant('gettext', function (str) {
|
||||
return str;
|
||||
});
|
||||
|
||||
angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http", "$cacheFactory", "$interpolate", "$rootScope", function (gettextPlurals, $http, $cacheFactory, $interpolate, $rootScope) {
|
||||
/**
|
||||
* @ngdoc service
|
||||
* @module gettext
|
||||
* @name gettextCatalog
|
||||
* @requires gettextPlurals
|
||||
* @requires gettextFallbackLanguage
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$http $http
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$cacheFactory $cacheFactory
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$interpolate $interpolate
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$rootScope $rootScope
|
||||
* @description Provides set of method to translate stings
|
||||
*/
|
||||
angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "gettextFallbackLanguage", "$http", "$cacheFactory", "$interpolate", "$rootScope", function (gettextPlurals, gettextFallbackLanguage, $http, $cacheFactory, $interpolate, $rootScope) {
|
||||
var catalog;
|
||||
var noContext = '$$noContext';
|
||||
|
||||
@ -38,34 +90,134 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http",
|
||||
};
|
||||
|
||||
function broadcastUpdated() {
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name gettextCatalog#gettextLanguageChanged
|
||||
* @eventType broadcast on $rootScope
|
||||
* @description Fires language change notification without any additional parameters.
|
||||
*/
|
||||
$rootScope.$broadcast('gettextLanguageChanged');
|
||||
}
|
||||
|
||||
catalog = {
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#debug
|
||||
* @public
|
||||
* @type {Boolean} false
|
||||
* @see gettextCatalog#debug
|
||||
* @description Whether or not to prefix untranslated strings with `[MISSING]:` or a custom prefix.
|
||||
*/
|
||||
debug: false,
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#debugPrefix
|
||||
* @public
|
||||
* @type {String} [MISSING]:
|
||||
* @description Custom prefix for untranslated strings when {@link gettextCatalog#debug gettextCatalog#debug} set to `true`.
|
||||
*/
|
||||
debugPrefix: '[MISSING]: ',
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#showTranslatedMarkers
|
||||
* @public
|
||||
* @type {Boolean} false
|
||||
* @description Whether or not to wrap all processed text with markers.
|
||||
*
|
||||
* Example output: `[Welcome]`
|
||||
*/
|
||||
showTranslatedMarkers: false,
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#translatedMarkerPrefix
|
||||
* @public
|
||||
* @type {String} [
|
||||
* @description Custom prefix to mark strings that have been run through {@link angular-gettext angular-gettext}.
|
||||
*/
|
||||
translatedMarkerPrefix: '[',
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#translatedMarkerSuffix
|
||||
* @public
|
||||
* @type {String} ]
|
||||
* @description Custom suffix to mark strings that have been run through {@link angular-gettext angular-gettext}.
|
||||
*/
|
||||
translatedMarkerSuffix: ']',
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#strings
|
||||
* @private
|
||||
* @type {Object}
|
||||
* @description An object of loaded translation strings. Shouldn't be used directly.
|
||||
*/
|
||||
strings: {},
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#baseLanguage
|
||||
* @protected
|
||||
* @deprecated
|
||||
* @since 2.0
|
||||
* @type {String} en
|
||||
* @description The default language, in which you're application is written.
|
||||
*
|
||||
* This defaults to English and it's generally a bad idea to use anything else:
|
||||
* if your language has different pluralization rules you'll end up with incorrect translations.
|
||||
*/
|
||||
baseLanguage: 'en',
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#currentLanguage
|
||||
* @public
|
||||
* @type {String}
|
||||
* @description Active language.
|
||||
*/
|
||||
currentLanguage: 'en',
|
||||
/**
|
||||
* @ngdoc property
|
||||
* @name gettextCatalog#cache
|
||||
* @public
|
||||
* @type {String} en
|
||||
* @description Language cache for lazy load
|
||||
*/
|
||||
cache: $cacheFactory('strings'),
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#setCurrentLanguage
|
||||
* @public
|
||||
* @param {String} lang language name
|
||||
* @description Sets the current language and makes sure that all translations get updated correctly.
|
||||
*/
|
||||
setCurrentLanguage: function (lang) {
|
||||
this.currentLanguage = lang;
|
||||
broadcastUpdated();
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#getCurrentLanguage
|
||||
* @public
|
||||
* @returns {String} current language
|
||||
* @description Returns the current language.
|
||||
*/
|
||||
getCurrentLanguage: function () {
|
||||
return this.currentLanguage;
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#setStrings
|
||||
* @public
|
||||
* @param {String} language language name
|
||||
* @param {Object.<String>} strings set of strings where the key is the translation `key` and `value` is the translated text
|
||||
* @description Processes an object of string definitions. {@link guide:manual-setstrings More details here}.
|
||||
*/
|
||||
setStrings: function (language, strings) {
|
||||
if (!this.strings[language]) {
|
||||
this.strings[language] = {};
|
||||
}
|
||||
|
||||
var defaultPlural = gettextPlurals(language, 1);
|
||||
for (var key in strings) {
|
||||
var val = strings[key];
|
||||
|
||||
@ -84,7 +236,10 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http",
|
||||
// Expand single strings for each context.
|
||||
for (var context in val) {
|
||||
var str = val[context];
|
||||
val[context] = angular.isArray(str) ? str : [str];
|
||||
if (!angular.isArray(str)) {
|
||||
val[context] = [];
|
||||
val[context][defaultPlural] = str;
|
||||
}
|
||||
}
|
||||
this.strings[language][key] = val;
|
||||
}
|
||||
@ -92,22 +247,73 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http",
|
||||
broadcastUpdated();
|
||||
},
|
||||
|
||||
getStringForm: function (string, n, context) {
|
||||
var stringTable = this.strings[this.currentLanguage] || {};
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#getStringFormFor
|
||||
* @protected
|
||||
* @param {String} language language name
|
||||
* @param {String} string translation key
|
||||
* @param {Number=} n number to build sting form for
|
||||
* @param {String=} context translation key context, e.g. {@link doc:context Verb, Noun}
|
||||
* @returns {String|Null} translated or annotated string or null if language is not set
|
||||
* @description Translate a string with the given language, count and context.
|
||||
*/
|
||||
getStringFormFor: function (language, string, n, context) {
|
||||
if (!language) {
|
||||
return null;
|
||||
}
|
||||
var stringTable = this.strings[language] || {};
|
||||
var contexts = stringTable[string] || {};
|
||||
var plurals = contexts[context || noContext] || [];
|
||||
return plurals[n];
|
||||
return plurals[gettextPlurals(language, n)];
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#getString
|
||||
* @public
|
||||
* @param {String} string translation key
|
||||
* @param {$rootScope.Scope=} scope scope to do interpolation against
|
||||
* @param {String=} context translation key context, e.g. {@link doc:context Verb, Noun}
|
||||
* @returns {String} translated or annotated string
|
||||
* @description Translate a string with the given scope and context.
|
||||
*
|
||||
* First it tries {@link gettextCatalog#currentLanguage gettextCatalog#currentLanguage} (e.g. `en-US`) then {@link gettextFallbackLanguage fallback} (e.g. `en`).
|
||||
*
|
||||
* When `scope` is supplied it uses Angular.JS interpolation, so something like this will do what you expect:
|
||||
* ```js
|
||||
* var hello = gettextCatalog.getString("Hello {{name}}!", { name: "Ruben" });
|
||||
* // var hello will be "Hallo Ruben!" in Dutch.
|
||||
* ```
|
||||
* Avoid using scopes - this skips interpolation and is a lot faster.
|
||||
*/
|
||||
getString: function (string, scope, context) {
|
||||
string = this.getStringForm(string, 0, context) || prefixDebug(string);
|
||||
var fallbackLanguage = gettextFallbackLanguage(this.currentLanguage);
|
||||
string = this.getStringFormFor(this.currentLanguage, string, 1, context) ||
|
||||
this.getStringFormFor(fallbackLanguage, string, 1, context) ||
|
||||
prefixDebug(string);
|
||||
string = scope ? $interpolate(string)(scope) : string;
|
||||
return addTranslatedMarkers(string);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#getPlural
|
||||
* @public
|
||||
* @param {Number} n number to build sting form for
|
||||
* @param {String} string translation key
|
||||
* @param {String} stringPlural plural translation key
|
||||
* @param {$rootScope.Scope=} scope scope to do interpolation against
|
||||
* @param {String=} context translation key context, e.g. {@link doc:context Verb, Noun}
|
||||
* @returns {String} translated or annotated string
|
||||
* @see {@link gettextCatalog#getString gettextCatalog#getString} for details
|
||||
* @description Translate a plural string with the given context.
|
||||
*/
|
||||
getPlural: function (n, string, stringPlural, scope, context) {
|
||||
var form = gettextPlurals(this.currentLanguage, n);
|
||||
string = this.getStringForm(string, form, context) || prefixDebug(n === 1 ? string : stringPlural);
|
||||
var fallbackLanguage = gettextFallbackLanguage(this.currentLanguage);
|
||||
string = this.getStringFormFor(this.currentLanguage, string, n, context) ||
|
||||
this.getStringFormFor(fallbackLanguage, string, n, context) ||
|
||||
prefixDebug(n === 1 ? string : stringPlural);
|
||||
if (scope) {
|
||||
scope.$count = n;
|
||||
string = $interpolate(string)(scope);
|
||||
@ -115,15 +321,27 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http",
|
||||
return addTranslatedMarkers(string);
|
||||
},
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextCatalog#loadRemote
|
||||
* @public
|
||||
* @param {String} url location of the translations
|
||||
* @description Load a set of translation strings from a given URL.
|
||||
*
|
||||
* This should be a JSON catalog generated with [angular-gettext-tools](https://github.com/rubenv/angular-gettext-tools).
|
||||
* {@link guide:lazy-loading More details here}.
|
||||
*/
|
||||
loadRemote: function (url) {
|
||||
return $http({
|
||||
method: 'GET',
|
||||
url: url,
|
||||
cache: catalog.cache
|
||||
}).success(function (data) {
|
||||
}).then(function (response) {
|
||||
var data = response.data;
|
||||
for (var lang in data) {
|
||||
catalog.setStrings(lang, data[lang]);
|
||||
}
|
||||
return response;
|
||||
});
|
||||
}
|
||||
};
|
||||
@ -131,37 +349,105 @@ angular.module('gettext').factory('gettextCatalog', ["gettextPlurals", "$http",
|
||||
return catalog;
|
||||
}]);
|
||||
|
||||
angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$animate", "$compile", "$window", function (gettextCatalog, $parse, $animate, $compile, $window) {
|
||||
// Trim polyfill for old browsers (instead of jQuery)
|
||||
// Based on AngularJS-v1.2.2 (angular.js#620)
|
||||
var trim = (function () {
|
||||
if (!String.prototype.trim) {
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
||||
};
|
||||
}
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.trim() : value;
|
||||
};
|
||||
})();
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @module gettext
|
||||
* @name translate
|
||||
* @requires gettextCatalog
|
||||
* @requires gettextUtil
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$parse $parse
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$animate $animate
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$compile $compile
|
||||
* @requires https://docs.angularjs.org/api/ng/service/$window $window
|
||||
* @restrict AE
|
||||
* @param {String} [translatePlural] plural form
|
||||
* @param {Number} translateN value to watch to substitute correct plural form
|
||||
* @param {String} translateContext context value, e.g. {@link doc:context Verb, Noun}
|
||||
* @description Annotates and translates text inside directive
|
||||
*
|
||||
* Full interpolation support is available in translated strings, so the following will work as expected:
|
||||
* ```js
|
||||
* <div translate>Hello {{name}}!</div>
|
||||
* ```
|
||||
*
|
||||
* You can also use custom context parameters while interpolating. This approach allows usage
|
||||
* of angular filters as well as custom logic inside your translated messages without unnecessary impact on translations.
|
||||
*
|
||||
* So for example when you have message like this:
|
||||
* ```js
|
||||
* <div translate>Last modified {{modificationDate | date:'yyyy-MM-dd HH:mm:ss Z'}} by {{author}}.</div>
|
||||
* ```
|
||||
* you will have it extracted in exact same version so it would look like this:
|
||||
* `Last modified {{modificationDate | date:'yyyy-MM-dd HH:mm:ss Z'}} by {{author}}`.
|
||||
* To start with it might be too complicated to read and handle by non technical translator. It's easy to make mistake
|
||||
* when copying format for example. Secondly if you decide to change format by some point of the project translation will broke
|
||||
* as it won't be the same string anymore.
|
||||
*
|
||||
* Instead your translator should only be concerned to place {{modificationDate}} correctly and you should have a free hand
|
||||
* to modify implementation details on how to present the results. This is how you can achieve the goal:
|
||||
* ```js
|
||||
* <div translate translate-params-modification-date="modificationDate | date:'yyyy-MM-dd HH:mm:ss Z'">Last modified {{modificationDate}} by {{author}}.</div>
|
||||
* ```
|
||||
*
|
||||
* There's a few more things worth to point out:
|
||||
* 1. You can use as many parameters as you want. Each parameter begins with `translate-params-` followed by snake-case parameter name.
|
||||
* Each parameter will be available for interpolation in camelCase manner (just like angular directive works by default).
|
||||
* ```js
|
||||
* <div translate translate-params-my-custom-param="param1" translate-params-name="name">Param {{myCustomParam}} has been changed by {{name}}.</div>
|
||||
* ```
|
||||
* 2. You can rename your variables from current scope to simple ones if you like.
|
||||
* ```js
|
||||
* <div translate translate-params-date="veryUnintuitiveNameForDate">Today's date is: {{date}}.</div>
|
||||
* ```
|
||||
* 3. You can use translate-params only for some interpolations. Rest would be treated as usual.
|
||||
* ```js
|
||||
* <div translate translate-params-cost="cost | currency">This product: {{product}} costs {{cost}}.</div>
|
||||
* ```
|
||||
*/
|
||||
angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$animate", "$compile", "$window", "gettextUtil", function (gettextCatalog, $parse, $animate, $compile, $window, gettextUtil) {
|
||||
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase($window.navigator.userAgent)) || [])[1], 10);
|
||||
var PARAMS_PREFIX = 'translateParams';
|
||||
|
||||
function assert(condition, missing, found) {
|
||||
if (!condition) {
|
||||
throw new Error('You should add a ' + missing + ' attribute whenever you add a ' + found + ' attribute.');
|
||||
}
|
||||
function getCtxAttr(key) {
|
||||
return gettextUtil.lcFirst(key.replace(PARAMS_PREFIX, ''));
|
||||
}
|
||||
|
||||
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase($window.navigator.userAgent)) || [])[1], 10);
|
||||
function handleInterpolationContext(scope, attrs, update) {
|
||||
var attributes = Object.keys(attrs).filter(function (key) {
|
||||
return gettextUtil.startsWith(key, PARAMS_PREFIX) && key !== PARAMS_PREFIX;
|
||||
});
|
||||
|
||||
if (!attributes.length) {
|
||||
return null;
|
||||
}
|
||||
|
||||
var interpolationContext = angular.extend({}, scope);
|
||||
var unwatchers = [];
|
||||
attributes.forEach(function (attribute) {
|
||||
var unwatch = scope.$watch(attrs[attribute], function (newVal) {
|
||||
var key = getCtxAttr(attribute);
|
||||
interpolationContext[key] = newVal;
|
||||
update(interpolationContext);
|
||||
});
|
||||
unwatchers.push(unwatch);
|
||||
});
|
||||
scope.$on('$destroy', function () {
|
||||
unwatchers.forEach(function (unwatch) {
|
||||
unwatch();
|
||||
});
|
||||
});
|
||||
return interpolationContext;
|
||||
}
|
||||
|
||||
return {
|
||||
restrict: 'AE',
|
||||
terminal: true,
|
||||
compile: function compile(element, attrs) {
|
||||
// Validate attributes
|
||||
assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
|
||||
assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
|
||||
gettextUtil.assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
|
||||
gettextUtil.assert(!attrs.translateN || attrs.translatePlural, 'translate-plural', 'translate-n');
|
||||
|
||||
var msgid = trim(element.html());
|
||||
var msgid = gettextUtil.trim(element.html());
|
||||
var translatePlural = attrs.translatePlural;
|
||||
var translateContext = attrs.translateContext;
|
||||
|
||||
@ -179,17 +465,18 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$
|
||||
var pluralScope = null;
|
||||
var linking = true;
|
||||
|
||||
function update() {
|
||||
function update(interpolationContext) {
|
||||
interpolationContext = interpolationContext || null;
|
||||
|
||||
// Fetch correct translated string.
|
||||
var translated;
|
||||
if (translatePlural) {
|
||||
scope = pluralScope || (pluralScope = scope.$new());
|
||||
scope.$count = countFn(scope);
|
||||
translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, null, translateContext);
|
||||
translated = gettextCatalog.getPlural(scope.$count, msgid, translatePlural, interpolationContext, translateContext);
|
||||
} else {
|
||||
translated = gettextCatalog.getString(msgid, null, translateContext);
|
||||
translated = gettextCatalog.getString(msgid, interpolationContext, translateContext);
|
||||
}
|
||||
|
||||
var oldContents = element.contents();
|
||||
|
||||
if (oldContents.length === 0){
|
||||
@ -197,7 +484,7 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$
|
||||
}
|
||||
|
||||
// Avoid redundant swaps
|
||||
if (translated === trim(oldContents.html())){
|
||||
if (translated === gettextUtil.trim(oldContents.html())){
|
||||
// Take care of unlinked content
|
||||
if (linking){
|
||||
$compile(oldContents)(scope);
|
||||
@ -214,20 +501,86 @@ angular.module('gettext').directive('translate', ["gettextCatalog", "$parse", "$
|
||||
$animate.leave(oldContents);
|
||||
}
|
||||
|
||||
var interpolationContext = handleInterpolationContext(scope, attrs, update);
|
||||
update(interpolationContext);
|
||||
linking = false;
|
||||
|
||||
if (attrs.translateN) {
|
||||
scope.$watch(attrs.translateN, update);
|
||||
scope.$watch(attrs.translateN, function () {
|
||||
update(interpolationContext);
|
||||
});
|
||||
}
|
||||
|
||||
scope.$on('gettextLanguageChanged', update);
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name translate#gettextLanguageChanged
|
||||
* @eventType listen on scope
|
||||
* @description Listens for language updates and changes translation accordingly
|
||||
*/
|
||||
scope.$on('gettextLanguageChanged', function () {
|
||||
update(interpolationContext);
|
||||
});
|
||||
|
||||
update();
|
||||
linking = false;
|
||||
}
|
||||
};
|
||||
}
|
||||
};
|
||||
}]);
|
||||
|
||||
/**
|
||||
* @ngdoc factory
|
||||
* @module gettext
|
||||
* @name gettextFallbackLanguage
|
||||
* @param {String} langCode language code
|
||||
* @returns {String|Null} fallback language
|
||||
* @description Strips regional code and returns language code only
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextFallbackLanguage('ru'); // "null"
|
||||
* gettextFallbackLanguage('en_GB'); // "en"
|
||||
* gettextFallbackLanguage(); // null
|
||||
* ```
|
||||
*/
|
||||
angular.module("gettext").factory("gettextFallbackLanguage", function () {
|
||||
var cache = {};
|
||||
var pattern = /([^_]+)_[^_]+$/;
|
||||
|
||||
return function (langCode) {
|
||||
if (cache[langCode]) {
|
||||
return cache[langCode];
|
||||
}
|
||||
|
||||
var matches = pattern.exec(langCode);
|
||||
if (matches) {
|
||||
cache[langCode] = matches[1];
|
||||
return matches[1];
|
||||
}
|
||||
|
||||
return null;
|
||||
};
|
||||
});
|
||||
/**
|
||||
* @ngdoc filter
|
||||
* @module gettext
|
||||
* @name translate
|
||||
* @requires gettextCatalog
|
||||
* @param {String} input translation key
|
||||
* @param {String} context context to evaluate key against
|
||||
* @returns {String} translated string or annotated key
|
||||
* @see {@link doc:context Verb, Noun}
|
||||
* @description Takes key and returns string
|
||||
*
|
||||
* Sometimes it's not an option to use an attribute (e.g. when you want to annotate an attribute value).
|
||||
* There's a `translate` filter available for this purpose.
|
||||
*
|
||||
* ```html
|
||||
* <input type="text" placeholder="{{'Username'|translate}}" />
|
||||
* ```
|
||||
* This filter does not support plural strings.
|
||||
*
|
||||
* You may want to use {@link guide:custom-annotations custom annotations} to avoid using the `translate` filter all the time. * Is
|
||||
*/
|
||||
angular.module('gettext').filter('translate', ["gettextCatalog", function (gettextCatalog) {
|
||||
function filter(input, context) {
|
||||
return gettextCatalog.getString(input, null, context);
|
||||
@ -238,8 +591,12 @@ angular.module('gettext').filter('translate', ["gettextCatalog", function (gette
|
||||
|
||||
// Do not edit this file, it is autogenerated using genplurals.py!
|
||||
angular.module("gettext").factory("gettextPlurals", function () {
|
||||
var languageCodes = {
|
||||
"pt_BR": "pt_BR",
|
||||
"pt-BR": "pt_BR"
|
||||
};
|
||||
return function (langCode, n) {
|
||||
switch (langCode) {
|
||||
switch (getLanguageCode(langCode)) {
|
||||
case "ay": // Aymará
|
||||
case "bo": // Tibetan
|
||||
case "cgg": // Chiga
|
||||
@ -348,5 +705,116 @@ angular.module("gettext").factory("gettextPlurals", function () {
|
||||
default: // Everything else
|
||||
return n != 1 ? 1 : 0;
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Method extracts iso639-2 language code from code with locale e.g. pl_PL, en_US, etc.
|
||||
* If it's provided with standalone iso639-2 language code it simply returns it.
|
||||
* @param {String} langCode
|
||||
* @returns {String} iso639-2 language Code
|
||||
*/
|
||||
function getLanguageCode(langCode) {
|
||||
if (!languageCodes[langCode]) {
|
||||
languageCodes[langCode] = langCode.split(/\-|_/).shift();
|
||||
}
|
||||
return languageCodes[langCode];
|
||||
}
|
||||
});
|
||||
|
||||
/**
|
||||
* @ngdoc factory
|
||||
* @module gettext
|
||||
* @name gettextUtil
|
||||
* @description Utility service for common operations and polyfills.
|
||||
*/
|
||||
angular.module('gettext').factory('gettextUtil', function gettextUtil() {
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextUtil#trim
|
||||
* @public
|
||||
* @param {string} value String to be trimmed.
|
||||
* @description Trim polyfill for old browsers (instead of jQuery). Based on AngularJS-v1.2.2 (angular.js#620).
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextUtil.assert(' no blanks '); // "no blanks"
|
||||
* ```
|
||||
*/
|
||||
var trim = (function () {
|
||||
if (!String.prototype.trim) {
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.replace(/^\s*/, '').replace(/\s*$/, '') : value;
|
||||
};
|
||||
}
|
||||
return function (value) {
|
||||
return (typeof value === 'string') ? value.trim() : value;
|
||||
};
|
||||
})();
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextUtil#assert
|
||||
* @public
|
||||
* @param {bool} condition condition to check
|
||||
* @param {String} missing name of the directive missing attribute
|
||||
* @param {String} found name of attribute that has been used with directive
|
||||
* @description Throws error if condition is not met, which means that directive was used with certain parameter
|
||||
* that requires another one (which is missing).
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextUtil.assert(!attrs.translatePlural || attrs.translateN, 'translate-n', 'translate-plural');
|
||||
* //You should add a translate-n attribute whenever you add a translate-plural attribute.
|
||||
* ```
|
||||
*/
|
||||
function assert(condition, missing, found) {
|
||||
if (!condition) {
|
||||
throw new Error('You should add a ' + missing + ' attribute whenever you add a ' + found + ' attribute.');
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextUtil#startsWith
|
||||
* @public
|
||||
* @param {string} target String on which checking will occur.
|
||||
* @param {string} query String expected to be at the beginning of target.
|
||||
* @returns {boolean} Returns true if object has no ownProperties. For arrays returns true if length == 0.
|
||||
* @description Checks if string starts with another string.
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextUtil.startsWith('Home sweet home.', 'Home'); //true
|
||||
* gettextUtil.startsWith('Home sweet home.', 'sweet'); //false
|
||||
* ```
|
||||
*/
|
||||
function startsWith(target, query) {
|
||||
return target.indexOf(query) === 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name gettextUtil#lcFirst
|
||||
* @public
|
||||
* @param {string} target String to transform.
|
||||
* @returns {string} Strings beginning with lowercase letter.
|
||||
* @description Makes first letter of the string lower case
|
||||
*
|
||||
* Example
|
||||
* ```js
|
||||
* gettextUtil.lcFirst('Home Sweet Home.'); //'home Sweet Home'
|
||||
* gettextUtil.lcFirst('ShouldBeCamelCase.'); //'shouldBeCamelCase'
|
||||
* ```
|
||||
*/
|
||||
function lcFirst(target) {
|
||||
var first = target.charAt(0).toLowerCase();
|
||||
return first + target.substr(1);
|
||||
}
|
||||
|
||||
return {
|
||||
trim: trim,
|
||||
assert: assert,
|
||||
startsWith: startsWith,
|
||||
lcFirst: lcFirst
|
||||
};
|
||||
});
|
||||
|
Loading…
x
Reference in New Issue
Block a user