mirror of
https://github.com/LaCasemate/fab-manager.git
synced 2024-12-03 14:24:23 +01:00
523 lines
18 KiB
JavaScript
523 lines
18 KiB
JavaScript
/*!
|
|
* angular-translate - v2.8.1 - 2015-10-01
|
|
*
|
|
* Copyright (c) 2015 The angular-translate team, Pascal Precht; Licensed MIT
|
|
*/
|
|
(function (root, factory) {
|
|
if (typeof define === 'function' && define.amd) {
|
|
// AMD. Register as an anonymous module unless amdModuleId is set
|
|
define([], function () {
|
|
return (factory());
|
|
});
|
|
} else if (typeof exports === 'object') {
|
|
// Node. Does not work with strict CommonJS, but
|
|
// only CommonJS-like environments that support module.exports,
|
|
// like Node.
|
|
module.exports = factory();
|
|
} else {
|
|
factory();
|
|
}
|
|
}(this, function () {
|
|
|
|
angular.module('pascalprecht.translate')
|
|
/**
|
|
* @ngdoc object
|
|
* @name pascalprecht.translate.$translatePartialLoaderProvider
|
|
*
|
|
* @description
|
|
* By using a $translatePartialLoaderProvider you can configure a list of a needed
|
|
* translation parts directly during the configuration phase of your application's
|
|
* lifetime. All parts you add by using this provider would be loaded by
|
|
* angular-translate at the startup as soon as possible.
|
|
*/
|
|
.provider('$translatePartialLoader', $translatePartialLoader);
|
|
|
|
function $translatePartialLoader() {
|
|
|
|
'use strict';
|
|
|
|
/**
|
|
* @constructor
|
|
* @name Part
|
|
*
|
|
* @description
|
|
* Represents Part object to add and set parts at runtime.
|
|
*/
|
|
function Part(name, priority) {
|
|
this.name = name;
|
|
this.isActive = true;
|
|
this.tables = {};
|
|
this.priority = priority || 0;
|
|
}
|
|
|
|
/**
|
|
* @name parseUrl
|
|
* @method
|
|
*
|
|
* @description
|
|
* Returns a parsed url template string and replaces given target lang
|
|
* and part name it.
|
|
*
|
|
* @param {string|function} urlTemplate - Either a string containing an url pattern (with
|
|
* '{part}' and '{lang}') or a function(part, lang)
|
|
* returning a string.
|
|
* @param {string} targetLang - Language key for language to be used.
|
|
* @return {string} Parsed url template string
|
|
*/
|
|
Part.prototype.parseUrl = function(urlTemplate, targetLang) {
|
|
if (angular.isFunction(urlTemplate)) {
|
|
return urlTemplate(this.name, targetLang);
|
|
}
|
|
return urlTemplate.replace(/\{part\}/g, this.name).replace(/\{lang\}/g, targetLang);
|
|
};
|
|
|
|
Part.prototype.getTable = function(lang, $q, $http, $httpOptions, urlTemplate, errorHandler) {
|
|
|
|
if (!this.tables[lang]) {
|
|
var self = this;
|
|
|
|
return $http(angular.extend({
|
|
method : 'GET',
|
|
url: this.parseUrl(urlTemplate, lang)
|
|
}, $httpOptions))
|
|
.then(function(result){
|
|
self.tables[lang] = result.data;
|
|
return result.data;
|
|
}, function() {
|
|
if (errorHandler) {
|
|
return errorHandler(self.name, lang)
|
|
.then(function(data) {
|
|
self.tables[lang] = data;
|
|
return data;
|
|
}, function() {
|
|
return $q.reject(self.name);
|
|
});
|
|
} else {
|
|
return $q.reject(self.name);
|
|
}
|
|
});
|
|
|
|
} else {
|
|
return $q.when(this.tables[lang]);
|
|
}
|
|
};
|
|
|
|
var parts = {};
|
|
|
|
function hasPart(name) {
|
|
return Object.prototype.hasOwnProperty.call(parts, name);
|
|
}
|
|
|
|
function isStringValid(str) {
|
|
return angular.isString(str) && str !== '';
|
|
}
|
|
|
|
function isPartAvailable(name) {
|
|
if (!isStringValid(name)) {
|
|
throw new TypeError('Invalid type of a first argument, a non-empty string expected.');
|
|
}
|
|
|
|
return (hasPart(name) && parts[name].isActive);
|
|
}
|
|
|
|
function deepExtend(dst, src) {
|
|
for (var property in src) {
|
|
if (src[property] && src[property].constructor &&
|
|
src[property].constructor === Object) {
|
|
dst[property] = dst[property] || {};
|
|
deepExtend(dst[property], src[property]);
|
|
} else {
|
|
dst[property] = src[property];
|
|
}
|
|
}
|
|
return dst;
|
|
}
|
|
|
|
function getPrioritizedParts() {
|
|
var prioritizedParts = [];
|
|
for(var part in parts) {
|
|
if (parts[part].isActive) {
|
|
prioritizedParts.push(parts[part]);
|
|
}
|
|
}
|
|
prioritizedParts.sort(function (a, b) {
|
|
return a.priority - b.priority;
|
|
});
|
|
return prioritizedParts;
|
|
}
|
|
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoaderProvider#addPart
|
|
* @methodOf pascalprecht.translate.$translatePartialLoaderProvider
|
|
*
|
|
* @description
|
|
* Registers a new part of the translation table to be loaded once the
|
|
* `angular-translate` gets into runtime phase. It does not actually load any
|
|
* translation data, but only registers a part to be loaded in the future.
|
|
*
|
|
* @param {string} name A name of the part to add
|
|
* @param {int} [priority=0] Sets the load priority of this part.
|
|
*
|
|
* @returns {object} $translatePartialLoaderProvider, so this method is chainable
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param
|
|
* of the wrong type. Please, note that the `name` param has to be a
|
|
* non-empty **string**.
|
|
*/
|
|
this.addPart = function(name, priority) {
|
|
if (!isStringValid(name)) {
|
|
throw new TypeError('Couldn\'t add part, part name has to be a string!');
|
|
}
|
|
|
|
if (!hasPart(name)) {
|
|
parts[name] = new Part(name, priority);
|
|
}
|
|
parts[name].isActive = true;
|
|
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* @ngdocs function
|
|
* @name pascalprecht.translate.$translatePartialLoaderProvider#setPart
|
|
* @methodOf pascalprecht.translate.$translatePartialLoaderProvider
|
|
*
|
|
* @description
|
|
* Sets a translation table to the specified part. This method does not make the
|
|
* specified part available, but only avoids loading this part from the server.
|
|
*
|
|
* @param {string} lang A language of the given translation table
|
|
* @param {string} part A name of the target part
|
|
* @param {object} table A translation table to set to the specified part
|
|
*
|
|
* @return {object} $translatePartialLoaderProvider, so this method is chainable
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass params
|
|
* of the wrong type. Please, note that the `lang` and `part` params have to be a
|
|
* non-empty **string**s and the `table` param has to be an object.
|
|
*/
|
|
this.setPart = function (lang, part, table) {
|
|
if (!isStringValid(lang)) {
|
|
throw new TypeError('Couldn\'t set part.`lang` parameter has to be a string!');
|
|
}
|
|
if (!isStringValid(part)) {
|
|
throw new TypeError('Couldn\'t set part.`part` parameter has to be a string!');
|
|
}
|
|
if (typeof table !== 'object' || table === null) {
|
|
throw new TypeError('Couldn\'t set part. `table` parameter has to be an object!');
|
|
}
|
|
|
|
if (!hasPart(part)) {
|
|
parts[part] = new Part(part);
|
|
parts[part].isActive = false;
|
|
}
|
|
|
|
parts[part].tables[lang] = table;
|
|
return this;
|
|
};
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoaderProvider#deletePart
|
|
* @methodOf pascalprecht.translate.$translatePartialLoaderProvider
|
|
*
|
|
* @description
|
|
* Removes the previously added part of the translation data. So, `angular-translate` will not
|
|
* load it at the startup.
|
|
*
|
|
* @param {string} name A name of the part to delete
|
|
*
|
|
* @returns {object} $translatePartialLoaderProvider, so this method is chainable
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param of the wrong
|
|
* type. Please, note that the `name` param has to be a non-empty **string**.
|
|
*/
|
|
this.deletePart = function (name) {
|
|
if (!isStringValid(name)) {
|
|
throw new TypeError('Couldn\'t delete part, first arg has to be string.');
|
|
}
|
|
|
|
if (hasPart(name)) {
|
|
parts[name].isActive = false;
|
|
}
|
|
|
|
return this;
|
|
};
|
|
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoaderProvider#isPartAvailable
|
|
* @methodOf pascalprecht.translate.$translatePartialLoaderProvider
|
|
*
|
|
* @description
|
|
* Checks if the specific part is available. A part becomes available after it was added by the
|
|
* `addPart` method. Available parts would be loaded from the server once the `angular-translate`
|
|
* asks the loader to that.
|
|
*
|
|
* @param {string} name A name of the part to check
|
|
*
|
|
* @returns {boolean} Returns **true** if the part is available now and **false** if not.
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param of the wrong
|
|
* type. Please, note that the `name` param has to be a non-empty **string**.
|
|
*/
|
|
this.isPartAvailable = isPartAvailable;
|
|
|
|
/**
|
|
* @ngdoc object
|
|
* @name pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @requires $q
|
|
* @requires $http
|
|
* @requires $injector
|
|
* @requires $rootScope
|
|
* @requires $translate
|
|
*
|
|
* @description
|
|
*
|
|
* @param {object} options Options object
|
|
*
|
|
* @throws {TypeError}
|
|
*/
|
|
this.$get = ['$rootScope', '$injector', '$q', '$http',
|
|
function($rootScope, $injector, $q, $http) {
|
|
|
|
/**
|
|
* @ngdoc event
|
|
* @name pascalprecht.translate.$translatePartialLoader#$translatePartialLoaderStructureChanged
|
|
* @eventOf pascalprecht.translate.$translatePartialLoader
|
|
* @eventType broadcast on root scope
|
|
*
|
|
* @description
|
|
* A $translatePartialLoaderStructureChanged event is called when a state of the loader was
|
|
* changed somehow. It could mean either some part is added or some part is deleted. Anyway when
|
|
* you get this event the translation table is not longer current and has to be updated.
|
|
*
|
|
* @param {string} name A name of the part which is a reason why the event was fired
|
|
*/
|
|
|
|
var service = function(options) {
|
|
if (!isStringValid(options.key)) {
|
|
throw new TypeError('Unable to load data, a key is not a non-empty string.');
|
|
}
|
|
|
|
if (!isStringValid(options.urlTemplate) && !angular.isFunction(options.urlTemplate)) {
|
|
throw new TypeError('Unable to load data, a urlTemplate is not a non-empty string or not a function.');
|
|
}
|
|
|
|
var errorHandler = options.loadFailureHandler;
|
|
if (errorHandler !== undefined) {
|
|
if (!angular.isString(errorHandler)) {
|
|
throw new Error('Unable to load data, a loadFailureHandler is not a string.');
|
|
} else {
|
|
errorHandler = $injector.get(errorHandler);
|
|
}
|
|
}
|
|
|
|
var loaders = [],
|
|
deferred = $q.defer(),
|
|
prioritizedParts = getPrioritizedParts();
|
|
|
|
angular.forEach(prioritizedParts, function(part) {
|
|
loaders.push(
|
|
part.getTable(options.key, $q, $http, options.$http, options.urlTemplate, errorHandler)
|
|
);
|
|
part.urlTemplate = options.urlTemplate;
|
|
});
|
|
|
|
$q.all(loaders)
|
|
.then(function() {
|
|
var table = {};
|
|
angular.forEach(prioritizedParts, function(part) {
|
|
deepExtend(table, part.tables[options.key]);
|
|
});
|
|
deferred.resolve(table);
|
|
}, function() {
|
|
deferred.reject(options.key);
|
|
}
|
|
);
|
|
|
|
return deferred.promise;
|
|
};
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoader#addPart
|
|
* @methodOf pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @description
|
|
* Registers a new part of the translation table. This method does not actually perform any xhr
|
|
* requests to get translation data. The new parts will be loaded in order of priority from the server next time
|
|
* `angular-translate` asks the loader to load translations.
|
|
*
|
|
* @param {string} name A name of the part to add
|
|
* @param {int} [priority=0] Sets the load priority of this part.
|
|
*
|
|
* @returns {object} $translatePartialLoader, so this method is chainable
|
|
*
|
|
* @fires {$translatePartialLoaderStructureChanged} The $translatePartialLoaderStructureChanged
|
|
* event would be fired by this method in case the new part affected somehow on the loaders
|
|
* state. This way it means that there are a new translation data available to be loaded from
|
|
* the server.
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param of the wrong
|
|
* type. Please, note that the `name` param has to be a non-empty **string**.
|
|
*/
|
|
service.addPart = function(name, priority) {
|
|
if (!isStringValid(name)) {
|
|
throw new TypeError('Couldn\'t add part, first arg has to be a string');
|
|
}
|
|
|
|
if (!hasPart(name)) {
|
|
parts[name] = new Part(name, priority);
|
|
$rootScope.$emit('$translatePartialLoaderStructureChanged', name);
|
|
} else if (!parts[name].isActive) {
|
|
parts[name].isActive = true;
|
|
$rootScope.$emit('$translatePartialLoaderStructureChanged', name);
|
|
}
|
|
|
|
return service;
|
|
};
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoader#deletePart
|
|
* @methodOf pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @description
|
|
* Deletes the previously added part of the translation data. The target part could be deleted
|
|
* either logically or physically. When the data is deleted logically it is not actually deleted
|
|
* from the browser, but the loader marks it as not active and prevents it from affecting on the
|
|
* translations. If the deleted in such way part is added again, the loader will use the
|
|
* previously loaded data rather than loading it from the server once more time. But if the data
|
|
* is deleted physically, the loader will completely remove all information about it. So in case
|
|
* of recycling this part will be loaded from the server again.
|
|
*
|
|
* @param {string} name A name of the part to delete
|
|
* @param {boolean=} [removeData=false] An indicator if the loader has to remove a loaded
|
|
* translation data physically. If the `removeData` if set to **false** the loaded data will not be
|
|
* deleted physically and might be reused in the future to prevent an additional xhr requests.
|
|
*
|
|
* @returns {object} $translatePartialLoader, so this method is chainable
|
|
*
|
|
* @fires {$translatePartialLoaderStructureChanged} The $translatePartialLoaderStructureChanged
|
|
* event would be fired by this method in case a part deletion process affects somehow on the
|
|
* loaders state. This way it means that some part of the translation data is now deprecated and
|
|
* the translation table has to be recompiled with the remaining translation parts.
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass some param of the
|
|
* wrong type. Please, note that the `name` param has to be a non-empty **string** and
|
|
* the `removeData` param has to be either **undefined** or **boolean**.
|
|
*/
|
|
service.deletePart = function(name, removeData) {
|
|
if (!isStringValid(name)) {
|
|
throw new TypeError('Couldn\'t delete part, first arg has to be string');
|
|
}
|
|
|
|
if (removeData === undefined) {
|
|
removeData = false;
|
|
} else if (typeof removeData !== 'boolean') {
|
|
throw new TypeError('Invalid type of a second argument, a boolean expected.');
|
|
}
|
|
|
|
if (hasPart(name)) {
|
|
var wasActive = parts[name].isActive;
|
|
if (removeData) {
|
|
var $translate = $injector.get('$translate');
|
|
var cache = $translate.loaderCache();
|
|
if (typeof(cache) === 'string') {
|
|
// getting on-demand instance of loader
|
|
cache = $injector.get(cache);
|
|
}
|
|
// Purging items from cache...
|
|
if (typeof(cache) === 'object') {
|
|
angular.forEach(parts[name].tables, function(value, key) {
|
|
cache.remove(parts[name].parseUrl(parts[name].urlTemplate, key));
|
|
});
|
|
}
|
|
delete parts[name];
|
|
} else {
|
|
parts[name].isActive = false;
|
|
}
|
|
if (wasActive) {
|
|
$rootScope.$emit('$translatePartialLoaderStructureChanged', name);
|
|
}
|
|
}
|
|
|
|
return service;
|
|
};
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoader#isPartLoaded
|
|
* @methodOf pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @description
|
|
* Checks if the registered translation part is loaded into the translation table.
|
|
*
|
|
* @param {string} name A name of the part
|
|
* @param {string} lang A key of the language
|
|
*
|
|
* @returns {boolean} Returns **true** if the translation of the part is loaded to the translation table and **false** if not.
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param of the wrong
|
|
* type. Please, note that the `name` and `lang` params have to be non-empty **string**.
|
|
*/
|
|
service.isPartLoaded = function(name, lang) {
|
|
return angular.isDefined(parts[name]) && angular.isDefined(parts[name].tables[lang]);
|
|
};
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoader#getRegisteredParts
|
|
* @methodOf pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @description
|
|
* Gets names of the parts that were added with the `addPart`.
|
|
*
|
|
* @returns {array} Returns array of registered parts, if none were registered then an empty array is returned.
|
|
*/
|
|
service.getRegisteredParts = function() {
|
|
var registeredParts = [];
|
|
angular.forEach(parts, function(p){
|
|
if(p.isActive) {
|
|
registeredParts.push(p.name);
|
|
}
|
|
});
|
|
return registeredParts;
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
* @ngdoc function
|
|
* @name pascalprecht.translate.$translatePartialLoader#isPartAvailable
|
|
* @methodOf pascalprecht.translate.$translatePartialLoader
|
|
*
|
|
* @description
|
|
* Checks if a target translation part is available. The part becomes available just after it was
|
|
* added by the `addPart` method. Part's availability does not mean that it was loaded from the
|
|
* server, but only that it was added to the loader. The available part might be loaded next
|
|
* time the loader is called.
|
|
*
|
|
* @param {string} name A name of the part to delete
|
|
*
|
|
* @returns {boolean} Returns **true** if the part is available now and **false** if not.
|
|
*
|
|
* @throws {TypeError} The method could throw a **TypeError** if you pass the param of the wrong
|
|
* type. Please, note that the `name` param has to be a non-empty **string**.
|
|
*/
|
|
service.isPartAvailable = isPartAvailable;
|
|
|
|
return service;
|
|
|
|
}];
|
|
|
|
}
|
|
|
|
$translatePartialLoader.displayName = '$translatePartialLoader';
|
|
return 'pascalprecht.translate';
|
|
|
|
}));
|