mirror of
https://github.com/videojs/video.js.git
synced 2024-12-25 02:42:10 +02:00
Normalise lang codes to lowercase for insensitive match
Use primary code ('en') if specific code ('en-us') doesn not match Always re-merge languages closes #2177 Updated language function to lowercase internally Updated component.localize to not require stubbing
This commit is contained in:
parent
4007add5e5
commit
6b2dca32fc
@ -34,6 +34,7 @@ CHANGELOG
|
||||
* @eXon made additional tech 2.0 improvements listed in #2126 ([view](https://github.com/videojs/video.js/pull/2166))
|
||||
* @heff Cleaned up and documented src/js/video.js and DOM functions ([view](https://github.com/videojs/video.js/pull/2182))
|
||||
* @mmcc Changed to pure CSS slider handles ([view](https://github.com/videojs/video.js/pull/2132))
|
||||
* @mister-ben updated language support to handle language codes with regions ([view](https://github.com/videojs/video.js/pull/2177))
|
||||
|
||||
--------------------
|
||||
|
||||
|
@ -37,7 +37,7 @@ Video.js uses key/value object dictionaries in JSON form. A sample dictionary fo
|
||||
```
|
||||
|
||||
Notes:
|
||||
|
||||
|
||||
- The file name should always be in the format `XX.json`, where `XX` is the two letter value of the language reported to the browser (for options see the bottom of this document).
|
||||
- For automatic inclusion at build time, add your language file to the `/lang` directory (see 'Adding Languages to Video.js below').
|
||||
|
||||
@ -45,7 +45,7 @@ Adding Languages to Video.js
|
||||
----------------------------
|
||||
Additional language support can be added to Video.js in multiple ways.
|
||||
|
||||
1. Create language scripts out of your JSON objects by using our custom grunt task `vjslanguages`. This task is automatically run as part of the default grunt task in Video.JS, but can be configured to match your `src`/`dist` directories if different. Once these scripts are created, just add them to your DOM like any other script.
|
||||
1. Create language scripts out of your JSON objects by using our custom grunt task `vjslanguages`. This task is automatically run as part of the default grunt task in Video.JS, but can be configured to match your `src`/`dist` directories if different. Once these scripts are created, just add them to your DOM like any other script.
|
||||
|
||||
NOTE: These need to be added after the core Video.js script.
|
||||
|
||||
@ -122,6 +122,24 @@ During a Video.js player instantiation you can force it to localize to a specifi
|
||||
</video>
|
||||
```
|
||||
|
||||
Determining Player Language
|
||||
---------------------------
|
||||
|
||||
The player language is set to one of the following in descending priority
|
||||
|
||||
* The language set in setup options as above
|
||||
* The document language (`lang` attribute of the `html` element)
|
||||
* Browser language preference
|
||||
* 'en'
|
||||
|
||||
That can be overridden after instantiation with `language('fr')`.
|
||||
|
||||
Language selection
|
||||
------------------
|
||||
|
||||
* Language codes are considered case-insensitively (`en-US` == `en-us`).
|
||||
* If there is no match for a language code with a subcode (`en-us`), a match for the primary code (`en`) is used if available.
|
||||
|
||||
Localization in Plugins
|
||||
-----------------------
|
||||
|
||||
@ -133,7 +151,7 @@ var details = '<div class="vjs-errors-details">' + player.localize('Technical de
|
||||
|
||||
Language Codes
|
||||
--------------
|
||||
The following is a list of official language codes.
|
||||
The following is a list of official language codes.
|
||||
|
||||
**NOTE:** For supported language translations, please see the [Languages Folder (/lang)](../../lang) folder located in the project root.
|
||||
|
||||
@ -180,10 +198,10 @@ The following is a list of official language codes.
|
||||
<tr><th>fj<th><td>Fiji</td></tr>
|
||||
<tr><th>fi<th><td>Finnish</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
<table>
|
||||
<tr><th>fr<th><td>French</td></tr>
|
||||
<tr><th>fy<th><td>Frisian</td></tr>
|
||||
@ -223,10 +241,10 @@ The following is a list of official language codes.
|
||||
<tr><th>lo<th><td>Laothian</td></tr>
|
||||
<tr><th>la<th><td>Latin</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
<table>
|
||||
<tr><th>lv<th><td>Latvian (Lettish)</td></tr>
|
||||
<tr><th>li<th><td>Limburgish ( Limburger)</td></tr>
|
||||
@ -266,10 +284,10 @@ The following is a list of official language codes.
|
||||
<tr><th>ii<th><td>Sichuan Yi</td></tr>
|
||||
<tr><th>sd<th><td>Sindhi</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
<td>
|
||||
|
||||
|
||||
<table>
|
||||
<tr><th>si<th><td>Sinhalese</td></tr>
|
||||
<tr><th>ss<th><td>Siswati</td></tr>
|
||||
@ -307,7 +325,7 @@ The following is a list of official language codes.
|
||||
<tr><th>yo<th><td>Yoruba</td></tr>
|
||||
<tr><th>zu<th><td>Zulu</td></tr>
|
||||
</table>
|
||||
|
||||
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
|
@ -217,11 +217,24 @@ class Component {
|
||||
}
|
||||
|
||||
localize(string) {
|
||||
let lang = this.player_.language();
|
||||
let languages = this.player_.languages();
|
||||
let code = this.player_.language && this.player_.language();
|
||||
let languages = this.player_.languages && this.player_.languages();
|
||||
|
||||
if (languages && languages[lang] && languages[lang][string]) {
|
||||
return languages[lang][string];
|
||||
if (!code || !languages) {
|
||||
return string;
|
||||
}
|
||||
|
||||
let language = languages[code];
|
||||
|
||||
if (language && language[string]) {
|
||||
return language[string];
|
||||
}
|
||||
|
||||
let primaryCode = code.split('-')[0];
|
||||
let primaryLang = languages[primaryCode];
|
||||
|
||||
if (primaryLang && primaryLang[string]) {
|
||||
return primaryLang[string];
|
||||
}
|
||||
|
||||
return string;
|
||||
|
@ -104,11 +104,21 @@ class Player extends Component {
|
||||
// Store the tag attributes used to restore html5 element
|
||||
this.tagAttributes = tag && Dom.getElAttributes(tag);
|
||||
|
||||
// Update Current Language
|
||||
this.language_ = options['language'] || globalOptions['language'];
|
||||
// Update current language
|
||||
this.language(options.language || globalOptions.language);
|
||||
|
||||
// Update Supported Languages
|
||||
this.languages_ = options['languages'] || globalOptions['languages'];
|
||||
if (options['languages']) {
|
||||
// Normalise player option languages to lowercase
|
||||
let languagesToLower = {};
|
||||
|
||||
Object.getOwnPropertyNames(options['languages']).forEach(function(name) {
|
||||
languagesToLower[name.toLowerCase()] = options['languages'][name];
|
||||
});
|
||||
this.languages_ = languagesToLower;
|
||||
} else {
|
||||
this.languages_ = globalOptions['languages'];
|
||||
}
|
||||
|
||||
// Cache for video property values.
|
||||
this.cache_ = {};
|
||||
@ -2075,24 +2085,31 @@ class Player extends Component {
|
||||
|
||||
/**
|
||||
* The player's language code
|
||||
* @param {String} languageCode The locale string
|
||||
* @return {String} The locale string when getting
|
||||
* @return {Player} self, when setting
|
||||
*
|
||||
* NOTE: The language should be set in the player options if you want the
|
||||
* the controls to be built with a specific language. Changing the lanugage
|
||||
* later will not update controls text.
|
||||
*
|
||||
* @param {String} code The locale string
|
||||
* @return {String} The locale string when getting
|
||||
* @return {Player} self, when setting
|
||||
*/
|
||||
language(languageCode) {
|
||||
if (languageCode === undefined) {
|
||||
language(code) {
|
||||
if (code === undefined) {
|
||||
return this.language_;
|
||||
}
|
||||
|
||||
this.language_ = languageCode;
|
||||
this.language_ = (''+code).toLowerCase();
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the player's language dictionary
|
||||
* Merge every time, because a newly added plugin might call videojs.addLanguage() at any time
|
||||
* Languages specified directly in the player options have precedence
|
||||
*/
|
||||
languages() {
|
||||
return this.languages_;
|
||||
return mergeOptions(globalOptions['languages'], this.languages_);
|
||||
}
|
||||
|
||||
toJSON() {
|
||||
|
@ -312,6 +312,7 @@ videojs.plugin = plugin;
|
||||
* @return {Object} The resulting language dictionary object
|
||||
*/
|
||||
videojs.addLanguage = function(code, data){
|
||||
code = ('' + code).toLowerCase();
|
||||
return merge(globalOptions.languages, { [code]: data })[code];
|
||||
};
|
||||
|
||||
|
@ -229,9 +229,7 @@ test('component can be subclassed externally', function(){
|
||||
var ControlBar = videojs.getComponent('ControlBar');
|
||||
|
||||
var player = new (Component.extend({
|
||||
languages: function(){},
|
||||
reportUserActivity: function(){},
|
||||
language: function(){},
|
||||
textTracks: function(){ return {
|
||||
addEventListener: Function.prototype,
|
||||
removeEventListener: Function.prototype
|
||||
|
@ -16,8 +16,6 @@ test('should hide volume control if it\'s not supported', function(){
|
||||
id: noop,
|
||||
on: noop,
|
||||
ready: noop,
|
||||
language: noop,
|
||||
languages: noop,
|
||||
tech: {
|
||||
'featuresVolumeControl': false
|
||||
},
|
||||
@ -39,8 +37,6 @@ test('should test and toggle volume control on `loadstart`', function(){
|
||||
listeners = [];
|
||||
player = {
|
||||
id: noop,
|
||||
language: noop,
|
||||
languages: noop,
|
||||
on: function(event, callback){
|
||||
// don't fire dispose listeners
|
||||
if (event !== 'dispose') {
|
||||
|
@ -791,3 +791,25 @@ test('should have a sensible toJSON that is equivalent to player.options', funct
|
||||
|
||||
deepEqual(player2.toJSON(), popts, 'no circular references');
|
||||
});
|
||||
|
||||
test('should ignore case in language codes and try primary code', function() {
|
||||
expect(3);
|
||||
|
||||
var player = TestHelpers.makePlayer({
|
||||
'languages': {
|
||||
'en-gb': {
|
||||
'Good': 'Brilliant'
|
||||
},
|
||||
'EN': {
|
||||
'Good': 'Awesome',
|
||||
'Error': 'Problem'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
player.language('en-gb');
|
||||
strictEqual(player.localize('Good'), 'Brilliant', 'Used subcode specific localisation');
|
||||
strictEqual(player.localize('Error'), 'Problem', 'Used primary code localisation');
|
||||
player.language('en-GB');
|
||||
strictEqual(player.localize('Good'), 'Brilliant', 'Ignored case');
|
||||
});
|
||||
|
@ -46,6 +46,17 @@ test('should add the value to the languages object', function() {
|
||||
deepEqual(result['Hello'], globalOptions.languages['es']['Hello'], 'should also match');
|
||||
});
|
||||
|
||||
test('should add the value to the languages object with lower case lang code', function() {
|
||||
var code, data, result;
|
||||
|
||||
code = 'DE';
|
||||
data = {'Hello': 'Guten Tag'};
|
||||
result = videojs.addLanguage(code, data);
|
||||
|
||||
ok(globalOptions['languages'][code.toLowerCase()], 'should exist');
|
||||
equal(globalOptions['languages'][code.toLowerCase()]['Hello'], 'Guten Tag', 'should match');
|
||||
deepEqual(result, globalOptions['languages'][code.toLowerCase()], 'should also match');
|
||||
});
|
||||
|
||||
test('should expose plugin registry function', function() {
|
||||
var pluginName, pluginFunction, player;
|
||||
|
Loading…
Reference in New Issue
Block a user