mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-10 23:21:21 +00:00
GUAC-919: Copy Angular changes from old GUAC-546 branch.
This commit is contained in:
committed by
Michael Jumper
parent
ac2617b92a
commit
5c43ae4ff9
8
guacamole/src/main/webapp/lib/plugins/angular-cookies.min.js
vendored
Normal file
8
guacamole/src/main/webapp/lib/plugins/angular-cookies.min.js
vendored
Normal file
@@ -0,0 +1,8 @@
|
||||
/*
|
||||
AngularJS v1.2.7
|
||||
(c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
License: MIT
|
||||
*/
|
||||
(function(p,f,n){'use strict';f.module("ngCookies",["ng"]).factory("$cookies",["$rootScope","$browser",function(d,b){var c={},g={},h,k=!1,l=f.copy,m=f.isUndefined;b.addPollFn(function(){var a=b.cookies();h!=a&&(h=a,l(a,g),l(a,c),k&&d.$apply())})();k=!0;d.$watch(function(){var a,e,d;for(a in g)m(c[a])&&b.cookies(a,n);for(a in c)(e=c[a],f.isString(e))?e!==g[a]&&(b.cookies(a,e),d=!0):f.isDefined(g[a])?c[a]=g[a]:delete c[a];if(d)for(a in e=b.cookies(),c)c[a]!==e[a]&&(m(e[a])?delete c[a]:c[a]=e[a])});
|
||||
return c}]).factory("$cookieStore",["$cookies",function(d){return{get:function(b){return(b=d[b])?f.fromJson(b):b},put:function(b,c){d[b]=f.toJson(c)},remove:function(b){delete d[b]}}}])})(window,window.angular);
|
||||
//# sourceMappingURL=angular-cookies.min.js.map
|
911
guacamole/src/main/webapp/lib/plugins/angular-route.js
vendored
Normal file
911
guacamole/src/main/webapp/lib/plugins/angular-route.js
vendored
Normal file
@@ -0,0 +1,911 @@
|
||||
/**
|
||||
* @license AngularJS v1.2.5
|
||||
* (c) 2010-2014 Google, Inc. http://angularjs.org
|
||||
* License: MIT
|
||||
*/
|
||||
(function(window, angular, undefined) {'use strict';
|
||||
|
||||
/**
|
||||
* @ngdoc overview
|
||||
* @name ngRoute
|
||||
* @description
|
||||
*
|
||||
* # ngRoute
|
||||
*
|
||||
* The `ngRoute` module provides routing and deeplinking services and directives for angular apps.
|
||||
*
|
||||
* ## Example
|
||||
* See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
|
||||
*
|
||||
* {@installModule route}
|
||||
*
|
||||
* <div doc-module-components="ngRoute"></div>
|
||||
*/
|
||||
/* global -ngRouteModule */
|
||||
var ngRouteModule = angular.module('ngRoute', ['ng']).
|
||||
provider('$route', $RouteProvider);
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name ngRoute.$routeProvider
|
||||
* @function
|
||||
*
|
||||
* @description
|
||||
*
|
||||
* Used for configuring routes.
|
||||
*
|
||||
* ## Example
|
||||
* See {@link ngRoute.$route#example $route} for an example of configuring and using `ngRoute`.
|
||||
*
|
||||
* ## Dependencies
|
||||
* Requires the {@link ngRoute `ngRoute`} module to be installed.
|
||||
*/
|
||||
function $RouteProvider(){
|
||||
function inherit(parent, extra) {
|
||||
return angular.extend(new (angular.extend(function() {}, {prototype:parent}))(), extra);
|
||||
}
|
||||
|
||||
var routes = {};
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngRoute.$routeProvider#when
|
||||
* @methodOf ngRoute.$routeProvider
|
||||
*
|
||||
* @param {string} path Route path (matched against `$location.path`). If `$location.path`
|
||||
* contains redundant trailing slash or is missing one, the route will still match and the
|
||||
* `$location.path` will be updated to add or drop the trailing slash to exactly match the
|
||||
* route definition.
|
||||
*
|
||||
* * `path` can contain named groups starting with a colon: e.g. `:name`. All characters up
|
||||
* to the next slash are matched and stored in `$routeParams` under the given `name`
|
||||
* when the route matches.
|
||||
* * `path` can contain named groups starting with a colon and ending with a star:
|
||||
* e.g.`:name*`. All characters are eagerly stored in `$routeParams` under the given `name`
|
||||
* when the route matches.
|
||||
* * `path` can contain optional named groups with a question mark: e.g.`:name?`.
|
||||
*
|
||||
* For example, routes like `/color/:color/largecode/:largecode*\/edit` will match
|
||||
* `/color/brown/largecode/code/with/slashs/edit` and extract:
|
||||
*
|
||||
* * `color: brown`
|
||||
* * `largecode: code/with/slashs`.
|
||||
*
|
||||
*
|
||||
* @param {Object} route Mapping information to be assigned to `$route.current` on route
|
||||
* match.
|
||||
*
|
||||
* Object properties:
|
||||
*
|
||||
* - `controller` âEUR" `{(string|function()=}` âEUR" Controller fn that should be associated with
|
||||
* newly created scope or the name of a {@link angular.Module#controller registered
|
||||
* controller} if passed as a string.
|
||||
* - `controllerAs` âEUR" `{string=}` âEUR" A controller alias name. If present the controller will be
|
||||
* published to scope under the `controllerAs` name.
|
||||
* - `template` âEUR" `{string=|function()=}` âEUR" html template as a string or a function that
|
||||
* returns an html template as a string which should be used by {@link
|
||||
* ngRoute.directive:ngView ngView} or {@link ng.directive:ngInclude ngInclude} directives.
|
||||
* This property takes precedence over `templateUrl`.
|
||||
*
|
||||
* If `template` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* - `templateUrl` âEUR" `{string=|function()=}` âEUR" path or function that returns a path to an html
|
||||
* template that should be used by {@link ngRoute.directive:ngView ngView}.
|
||||
*
|
||||
* If `templateUrl` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Array.<Object>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route
|
||||
*
|
||||
* - `resolve` - `{Object.<string, function>=}` - An optional map of dependencies which should
|
||||
* be injected into the controller. If any of these dependencies are promises, the router
|
||||
* will wait for them all to be resolved or one to be rejected before the controller is
|
||||
* instantiated.
|
||||
* If all the promises are resolved successfully, the values of the resolved promises are
|
||||
* injected and {@link ngRoute.$route#$routeChangeSuccess $routeChangeSuccess} event is
|
||||
* fired. If any of the promises are rejected the
|
||||
* {@link ngRoute.$route#$routeChangeError $routeChangeError} event is fired. The map object
|
||||
* is:
|
||||
*
|
||||
* - `key` âEUR" `{string}`: a name of a dependency to be injected into the controller.
|
||||
* - `factory` - `{string|function}`: If `string` then it is an alias for a service.
|
||||
* Otherwise if function, then it is {@link api/AUTO.$injector#invoke injected}
|
||||
* and the return value is treated as the dependency. If the result is a promise, it is
|
||||
* resolved before its value is injected into the controller. Be aware that
|
||||
* `ngRoute.$routeParams` will still refer to the previous route within these resolve
|
||||
* functions. Use `$route.current.params` to access the new route parameters, instead.
|
||||
*
|
||||
* - `redirectTo` âEUR" {(string|function())=} âEUR" value to update
|
||||
* {@link ng.$location $location} path with and trigger route redirection.
|
||||
*
|
||||
* If `redirectTo` is a function, it will be called with the following parameters:
|
||||
*
|
||||
* - `{Object.<string>}` - route parameters extracted from the current
|
||||
* `$location.path()` by applying the current route templateUrl.
|
||||
* - `{string}` - current `$location.path()`
|
||||
* - `{Object}` - current `$location.search()`
|
||||
*
|
||||
* The custom `redirectTo` function is expected to return a string which will be used
|
||||
* to update `$location.path()` and `$location.search()`.
|
||||
*
|
||||
* - `[reloadOnSearch=true]` - {boolean=} - reload route when only `$location.search()`
|
||||
* or `$location.hash()` changes.
|
||||
*
|
||||
* If the option is set to `false` and url in the browser changes, then
|
||||
* `$routeUpdate` event is broadcasted on the root scope.
|
||||
*
|
||||
* - `[caseInsensitiveMatch=false]` - {boolean=} - match routes without being case sensitive
|
||||
*
|
||||
* If the option is set to `true`, then the particular route can be matched without being
|
||||
* case sensitive
|
||||
*
|
||||
* @returns {Object} self
|
||||
*
|
||||
* @description
|
||||
* Adds a new route definition to the `$route` service.
|
||||
*/
|
||||
this.when = function(path, route) {
|
||||
routes[path] = angular.extend(
|
||||
{reloadOnSearch: true},
|
||||
route,
|
||||
path && pathRegExp(path, route)
|
||||
);
|
||||
|
||||
// create redirection for trailing slashes
|
||||
if (path) {
|
||||
var redirectPath = (path[path.length-1] == '/')
|
||||
? path.substr(0, path.length-1)
|
||||
: path +'/';
|
||||
|
||||
routes[redirectPath] = angular.extend(
|
||||
{redirectTo: path},
|
||||
pathRegExp(redirectPath, route)
|
||||
);
|
||||
}
|
||||
|
||||
return this;
|
||||
};
|
||||
|
||||
/**
|
||||
* @param path {string} path
|
||||
* @param opts {Object} options
|
||||
* @return {?Object}
|
||||
*
|
||||
* @description
|
||||
* Normalizes the given path, returning a regular expression
|
||||
* and the original path.
|
||||
*
|
||||
* Inspired by pathRexp in visionmedia/express/lib/utils.js.
|
||||
*/
|
||||
function pathRegExp(path, opts) {
|
||||
var insensitive = opts.caseInsensitiveMatch,
|
||||
ret = {
|
||||
originalPath: path,
|
||||
regexp: path
|
||||
},
|
||||
keys = ret.keys = [];
|
||||
|
||||
path = path
|
||||
.replace(/([().])/g, '\\$1')
|
||||
.replace(/(\/)?:(\w+)([\?|\*])?/g, function(_, slash, key, option){
|
||||
var optional = option === '?' ? option : null;
|
||||
var star = option === '*' ? option : null;
|
||||
keys.push({ name: key, optional: !!optional });
|
||||
slash = slash || '';
|
||||
return ''
|
||||
+ (optional ? '' : slash)
|
||||
+ '(?:'
|
||||
+ (optional ? slash : '')
|
||||
+ (star && '(.+?)' || '([^/]+)')
|
||||
+ (optional || '')
|
||||
+ ')'
|
||||
+ (optional || '');
|
||||
})
|
||||
.replace(/([\/$\*])/g, '\\$1');
|
||||
|
||||
ret.regexp = new RegExp('^' + path + '$', insensitive ? 'i' : '');
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngRoute.$routeProvider#otherwise
|
||||
* @methodOf ngRoute.$routeProvider
|
||||
*
|
||||
* @description
|
||||
* Sets route definition that will be used on route change when no other route definition
|
||||
* is matched.
|
||||
*
|
||||
* @param {Object} params Mapping information to be assigned to `$route.current`.
|
||||
* @returns {Object} self
|
||||
*/
|
||||
this.otherwise = function(params) {
|
||||
this.when(null, params);
|
||||
return this;
|
||||
};
|
||||
|
||||
|
||||
this.$get = ['$rootScope',
|
||||
'$location',
|
||||
'$routeParams',
|
||||
'$q',
|
||||
'$injector',
|
||||
'$http',
|
||||
'$templateCache',
|
||||
'$sce',
|
||||
function($rootScope, $location, $routeParams, $q, $injector, $http, $templateCache, $sce) {
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name ngRoute.$route
|
||||
* @requires $location
|
||||
* @requires $routeParams
|
||||
*
|
||||
* @property {Object} current Reference to the current route definition.
|
||||
* The route definition contains:
|
||||
*
|
||||
* - `controller`: The controller constructor as define in route definition.
|
||||
* - `locals`: A map of locals which is used by {@link ng.$controller $controller} service for
|
||||
* controller instantiation. The `locals` contain
|
||||
* the resolved values of the `resolve` map. Additionally the `locals` also contain:
|
||||
*
|
||||
* - `$scope` - The current route scope.
|
||||
* - `$template` - The current route template HTML.
|
||||
*
|
||||
* @property {Array.<Object>} routes Array of all configured routes.
|
||||
*
|
||||
* @description
|
||||
* `$route` is used for deep-linking URLs to controllers and views (HTML partials).
|
||||
* It watches `$location.url()` and tries to map the path to an existing route definition.
|
||||
*
|
||||
* Requires the {@link ngRoute `ngRoute`} module to be installed.
|
||||
*
|
||||
* You can define routes through {@link ngRoute.$routeProvider $routeProvider}'s API.
|
||||
*
|
||||
* The `$route` service is typically used in conjunction with the
|
||||
* {@link ngRoute.directive:ngView `ngView`} directive and the
|
||||
* {@link ngRoute.$routeParams `$routeParams`} service.
|
||||
*
|
||||
* @example
|
||||
This example shows how changing the URL hash causes the `$route` to match a route against the
|
||||
URL, and the `ngView` pulls in the partial.
|
||||
|
||||
Note that this example is using {@link ng.directive:script inlined templates}
|
||||
to get it working on jsfiddle as well.
|
||||
|
||||
<example module="ngViewExample" deps="angular-route.js">
|
||||
<file name="index.html">
|
||||
<div ng-controller="MainCntl">
|
||||
Choose:
|
||||
<a href="Book/Moby">Moby</a> |
|
||||
<a href="Book/Moby/ch/1">Moby: Ch1</a> |
|
||||
<a href="Book/Gatsby">Gatsby</a> |
|
||||
<a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
|
||||
<a href="Book/Scarlet">Scarlet Letter</a><br/>
|
||||
|
||||
<div ng-view></div>
|
||||
<hr />
|
||||
|
||||
<pre>$location.path() = {{$location.path()}}</pre>
|
||||
<pre>$route.current.templateUrl = {{$route.current.templateUrl}}</pre>
|
||||
<pre>$route.current.params = {{$route.current.params}}</pre>
|
||||
<pre>$route.current.scope.name = {{$route.current.scope.name}}</pre>
|
||||
<pre>$routeParams = {{$routeParams}}</pre>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<file name="book.html">
|
||||
controller: {{name}}<br />
|
||||
Book Id: {{params.bookId}}<br />
|
||||
</file>
|
||||
|
||||
<file name="chapter.html">
|
||||
controller: {{name}}<br />
|
||||
Book Id: {{params.bookId}}<br />
|
||||
Chapter Id: {{params.chapterId}}
|
||||
</file>
|
||||
|
||||
<file name="script.js">
|
||||
angular.module('ngViewExample', ['ngRoute'])
|
||||
|
||||
.config(function($routeProvider, $locationProvider) {
|
||||
$routeProvider.when('/Book/:bookId', {
|
||||
templateUrl: 'book.html',
|
||||
controller: BookCntl,
|
||||
resolve: {
|
||||
// I will cause a 1 second delay
|
||||
delay: function($q, $timeout) {
|
||||
var delay = $q.defer();
|
||||
$timeout(delay.resolve, 1000);
|
||||
return delay.promise;
|
||||
}
|
||||
}
|
||||
});
|
||||
$routeProvider.when('/Book/:bookId/ch/:chapterId', {
|
||||
templateUrl: 'chapter.html',
|
||||
controller: ChapterCntl
|
||||
});
|
||||
|
||||
// configure html5 to get links working on jsfiddle
|
||||
$locationProvider.html5Mode(true);
|
||||
});
|
||||
|
||||
function MainCntl($scope, $route, $routeParams, $location) {
|
||||
$scope.$route = $route;
|
||||
$scope.$location = $location;
|
||||
$scope.$routeParams = $routeParams;
|
||||
}
|
||||
|
||||
function BookCntl($scope, $routeParams) {
|
||||
$scope.name = "BookCntl";
|
||||
$scope.params = $routeParams;
|
||||
}
|
||||
|
||||
function ChapterCntl($scope, $routeParams) {
|
||||
$scope.name = "ChapterCntl";
|
||||
$scope.params = $routeParams;
|
||||
}
|
||||
</file>
|
||||
|
||||
<file name="scenario.js">
|
||||
it('should load and compile correct template', function() {
|
||||
element('a:contains("Moby: Ch1")').click();
|
||||
var content = element('.doc-example-live [ng-view]').text();
|
||||
expect(content).toMatch(/controller\: ChapterCntl/);
|
||||
expect(content).toMatch(/Book Id\: Moby/);
|
||||
expect(content).toMatch(/Chapter Id\: 1/);
|
||||
|
||||
element('a:contains("Scarlet")').click();
|
||||
sleep(2); // promises are not part of scenario waiting
|
||||
content = element('.doc-example-live [ng-view]').text();
|
||||
expect(content).toMatch(/controller\: BookCntl/);
|
||||
expect(content).toMatch(/Book Id\: Scarlet/);
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name ngRoute.$route#$routeChangeStart
|
||||
* @eventOf ngRoute.$route
|
||||
* @eventType broadcast on root scope
|
||||
* @description
|
||||
* Broadcasted before a route change. At this point the route services starts
|
||||
* resolving all of the dependencies needed for the route change to occurs.
|
||||
* Typically this involves fetching the view template as well as any dependencies
|
||||
* defined in `resolve` route property. Once all of the dependencies are resolved
|
||||
* `$routeChangeSuccess` is fired.
|
||||
*
|
||||
* @param {Object} angularEvent Synthetic event object.
|
||||
* @param {Route} next Future route information.
|
||||
* @param {Route} current Current route information.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name ngRoute.$route#$routeChangeSuccess
|
||||
* @eventOf ngRoute.$route
|
||||
* @eventType broadcast on root scope
|
||||
* @description
|
||||
* Broadcasted after a route dependencies are resolved.
|
||||
* {@link ngRoute.directive:ngView ngView} listens for the directive
|
||||
* to instantiate the controller and render the view.
|
||||
*
|
||||
* @param {Object} angularEvent Synthetic event object.
|
||||
* @param {Route} current Current route information.
|
||||
* @param {Route|Undefined} previous Previous route information, or undefined if current is
|
||||
* first route entered.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name ngRoute.$route#$routeChangeError
|
||||
* @eventOf ngRoute.$route
|
||||
* @eventType broadcast on root scope
|
||||
* @description
|
||||
* Broadcasted if any of the resolve promises are rejected.
|
||||
*
|
||||
* @param {Object} angularEvent Synthetic event object
|
||||
* @param {Route} current Current route information.
|
||||
* @param {Route} previous Previous route information.
|
||||
* @param {Route} rejection Rejection of the promise. Usually the error of the failed promise.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name ngRoute.$route#$routeUpdate
|
||||
* @eventOf ngRoute.$route
|
||||
* @eventType broadcast on root scope
|
||||
* @description
|
||||
*
|
||||
* The `reloadOnSearch` property has been set to false, and we are reusing the same
|
||||
* instance of the Controller.
|
||||
*/
|
||||
|
||||
var forceReload = false,
|
||||
$route = {
|
||||
routes: routes,
|
||||
|
||||
/**
|
||||
* @ngdoc method
|
||||
* @name ngRoute.$route#reload
|
||||
* @methodOf ngRoute.$route
|
||||
*
|
||||
* @description
|
||||
* Causes `$route` service to reload the current route even if
|
||||
* {@link ng.$location $location} hasn't changed.
|
||||
*
|
||||
* As a result of that, {@link ngRoute.directive:ngView ngView}
|
||||
* creates new scope, reinstantiates the controller.
|
||||
*/
|
||||
reload: function() {
|
||||
forceReload = true;
|
||||
$rootScope.$evalAsync(updateRoute);
|
||||
}
|
||||
};
|
||||
|
||||
$rootScope.$on('$locationChangeSuccess', updateRoute);
|
||||
|
||||
return $route;
|
||||
|
||||
/////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
* @param on {string} current url
|
||||
* @param route {Object} route regexp to match the url against
|
||||
* @return {?Object}
|
||||
*
|
||||
* @description
|
||||
* Check if the route matches the current url.
|
||||
*
|
||||
* Inspired by match in
|
||||
* visionmedia/express/lib/router/router.js.
|
||||
*/
|
||||
function switchRouteMatcher(on, route) {
|
||||
var keys = route.keys,
|
||||
params = {};
|
||||
|
||||
if (!route.regexp) return null;
|
||||
|
||||
var m = route.regexp.exec(on);
|
||||
if (!m) return null;
|
||||
|
||||
for (var i = 1, len = m.length; i < len; ++i) {
|
||||
var key = keys[i - 1];
|
||||
|
||||
var val = 'string' == typeof m[i]
|
||||
? decodeURIComponent(m[i])
|
||||
: m[i];
|
||||
|
||||
if (key && val) {
|
||||
params[key.name] = val;
|
||||
}
|
||||
}
|
||||
return params;
|
||||
}
|
||||
|
||||
function updateRoute() {
|
||||
var next = parseRoute(),
|
||||
last = $route.current;
|
||||
|
||||
if (next && last && next.$$route === last.$$route
|
||||
&& angular.equals(next.pathParams, last.pathParams)
|
||||
&& !next.reloadOnSearch && !forceReload) {
|
||||
last.params = next.params;
|
||||
angular.copy(last.params, $routeParams);
|
||||
$rootScope.$broadcast('$routeUpdate', last);
|
||||
} else if (next || last) {
|
||||
forceReload = false;
|
||||
$rootScope.$broadcast('$routeChangeStart', next, last);
|
||||
$route.current = next;
|
||||
if (next) {
|
||||
if (next.redirectTo) {
|
||||
if (angular.isString(next.redirectTo)) {
|
||||
$location.path(interpolate(next.redirectTo, next.params)).search(next.params)
|
||||
.replace();
|
||||
} else {
|
||||
$location.url(next.redirectTo(next.pathParams, $location.path(), $location.search()))
|
||||
.replace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$q.when(next).
|
||||
then(function() {
|
||||
if (next) {
|
||||
var locals = angular.extend({}, next.resolve),
|
||||
template, templateUrl;
|
||||
|
||||
angular.forEach(locals, function(value, key) {
|
||||
locals[key] = angular.isString(value) ?
|
||||
$injector.get(value) : $injector.invoke(value);
|
||||
});
|
||||
|
||||
if (angular.isDefined(template = next.template)) {
|
||||
if (angular.isFunction(template)) {
|
||||
template = template(next.params);
|
||||
}
|
||||
} else if (angular.isDefined(templateUrl = next.templateUrl)) {
|
||||
if (angular.isFunction(templateUrl)) {
|
||||
templateUrl = templateUrl(next.params);
|
||||
}
|
||||
templateUrl = $sce.getTrustedResourceUrl(templateUrl);
|
||||
if (angular.isDefined(templateUrl)) {
|
||||
next.loadedTemplateUrl = templateUrl;
|
||||
template = $http.get(templateUrl, {cache: $templateCache}).
|
||||
then(function(response) { return response.data; });
|
||||
}
|
||||
}
|
||||
if (angular.isDefined(template)) {
|
||||
locals['$template'] = template;
|
||||
}
|
||||
return $q.all(locals);
|
||||
}
|
||||
}).
|
||||
// after route change
|
||||
then(function(locals) {
|
||||
if (next == $route.current) {
|
||||
if (next) {
|
||||
next.locals = locals;
|
||||
angular.copy(next.params, $routeParams);
|
||||
}
|
||||
$rootScope.$broadcast('$routeChangeSuccess', next, last);
|
||||
}
|
||||
}, function(error) {
|
||||
if (next == $route.current) {
|
||||
$rootScope.$broadcast('$routeChangeError', next, last, error);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @returns the current active route, by matching it against the URL
|
||||
*/
|
||||
function parseRoute() {
|
||||
// Match a route
|
||||
var params, match;
|
||||
angular.forEach(routes, function(route, path) {
|
||||
if (!match && (params = switchRouteMatcher($location.path(), route))) {
|
||||
match = inherit(route, {
|
||||
params: angular.extend({}, $location.search(), params),
|
||||
pathParams: params});
|
||||
match.$$route = route;
|
||||
}
|
||||
});
|
||||
// No route matched; fallback to "otherwise" route
|
||||
return match || routes[null] && inherit(routes[null], {params: {}, pathParams:{}});
|
||||
}
|
||||
|
||||
/**
|
||||
* @returns interpolation of the redirect path with the parameters
|
||||
*/
|
||||
function interpolate(string, params) {
|
||||
var result = [];
|
||||
angular.forEach((string||'').split(':'), function(segment, i) {
|
||||
if (i === 0) {
|
||||
result.push(segment);
|
||||
} else {
|
||||
var segmentMatch = segment.match(/(\w+)(.*)/);
|
||||
var key = segmentMatch[1];
|
||||
result.push(params[key]);
|
||||
result.push(segmentMatch[2] || '');
|
||||
delete params[key];
|
||||
}
|
||||
});
|
||||
return result.join('');
|
||||
}
|
||||
}];
|
||||
}
|
||||
|
||||
ngRouteModule.provider('$routeParams', $RouteParamsProvider);
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc object
|
||||
* @name ngRoute.$routeParams
|
||||
* @requires $route
|
||||
*
|
||||
* @description
|
||||
* The `$routeParams` service allows you to retrieve the current set of route parameters.
|
||||
*
|
||||
* Requires the {@link ngRoute `ngRoute`} module to be installed.
|
||||
*
|
||||
* The route parameters are a combination of {@link ng.$location `$location`}'s
|
||||
* {@link ng.$location#methods_search `search()`} and {@link ng.$location#methods_path `path()`}.
|
||||
* The `path` parameters are extracted when the {@link ngRoute.$route `$route`} path is matched.
|
||||
*
|
||||
* In case of parameter name collision, `path` params take precedence over `search` params.
|
||||
*
|
||||
* The service guarantees that the identity of the `$routeParams` object will remain unchanged
|
||||
* (but its properties will likely change) even when a route change occurs.
|
||||
*
|
||||
* Note that the `$routeParams` are only updated *after* a route change completes successfully.
|
||||
* This means that you cannot rely on `$routeParams` being correct in route resolve functions.
|
||||
* Instead you can use `$route.current.params` to access the new route's parameters.
|
||||
*
|
||||
* @example
|
||||
* <pre>
|
||||
* // Given:
|
||||
* // URL: http://server.com/index.html#/Chapter/1/Section/2?search=moby
|
||||
* // Route: /Chapter/:chapterId/Section/:sectionId
|
||||
* //
|
||||
* // Then
|
||||
* $routeParams ==> {chapterId:1, sectionId:2, search:'moby'}
|
||||
* </pre>
|
||||
*/
|
||||
function $RouteParamsProvider() {
|
||||
this.$get = function() { return {}; };
|
||||
}
|
||||
|
||||
ngRouteModule.directive('ngView', ngViewFactory);
|
||||
ngRouteModule.directive('ngView', ngViewFillContentFactory);
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc directive
|
||||
* @name ngRoute.directive:ngView
|
||||
* @restrict ECA
|
||||
*
|
||||
* @description
|
||||
* # Overview
|
||||
* `ngView` is a directive that complements the {@link ngRoute.$route $route} service by
|
||||
* including the rendered template of the current route into the main layout (`index.html`) file.
|
||||
* Every time the current route changes, the included view changes with it according to the
|
||||
* configuration of the `$route` service.
|
||||
*
|
||||
* Requires the {@link ngRoute `ngRoute`} module to be installed.
|
||||
*
|
||||
* @animations
|
||||
* enter - animation is used to bring new content into the browser.
|
||||
* leave - animation is used to animate existing content away.
|
||||
*
|
||||
* The enter and leave animation occur concurrently.
|
||||
*
|
||||
* @scope
|
||||
* @priority 400
|
||||
* @example
|
||||
<example module="ngViewExample" deps="angular-route.js" animations="true">
|
||||
<file name="index.html">
|
||||
<div ng-controller="MainCntl as main">
|
||||
Choose:
|
||||
<a href="Book/Moby">Moby</a> |
|
||||
<a href="Book/Moby/ch/1">Moby: Ch1</a> |
|
||||
<a href="Book/Gatsby">Gatsby</a> |
|
||||
<a href="Book/Gatsby/ch/4?key=value">Gatsby: Ch4</a> |
|
||||
<a href="Book/Scarlet">Scarlet Letter</a><br/>
|
||||
|
||||
<div class="view-animate-container">
|
||||
<div ng-view class="view-animate"></div>
|
||||
</div>
|
||||
<hr />
|
||||
|
||||
<pre>$location.path() = {{main.$location.path()}}</pre>
|
||||
<pre>$route.current.templateUrl = {{main.$route.current.templateUrl}}</pre>
|
||||
<pre>$route.current.params = {{main.$route.current.params}}</pre>
|
||||
<pre>$route.current.scope.name = {{main.$route.current.scope.name}}</pre>
|
||||
<pre>$routeParams = {{main.$routeParams}}</pre>
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<file name="book.html">
|
||||
<div>
|
||||
controller: {{book.name}}<br />
|
||||
Book Id: {{book.params.bookId}}<br />
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<file name="chapter.html">
|
||||
<div>
|
||||
controller: {{chapter.name}}<br />
|
||||
Book Id: {{chapter.params.bookId}}<br />
|
||||
Chapter Id: {{chapter.params.chapterId}}
|
||||
</div>
|
||||
</file>
|
||||
|
||||
<file name="animations.css">
|
||||
.view-animate-container {
|
||||
position:relative;
|
||||
height:100px!important;
|
||||
position:relative;
|
||||
background:white;
|
||||
border:1px solid black;
|
||||
height:40px;
|
||||
overflow:hidden;
|
||||
}
|
||||
|
||||
.view-animate {
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
.view-animate.ng-enter, .view-animate.ng-leave {
|
||||
-webkit-transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
transition:all cubic-bezier(0.250, 0.460, 0.450, 0.940) 1.5s;
|
||||
|
||||
display:block;
|
||||
width:100%;
|
||||
border-left:1px solid black;
|
||||
|
||||
position:absolute;
|
||||
top:0;
|
||||
left:0;
|
||||
right:0;
|
||||
bottom:0;
|
||||
padding:10px;
|
||||
}
|
||||
|
||||
.view-animate.ng-enter {
|
||||
left:100%;
|
||||
}
|
||||
.view-animate.ng-enter.ng-enter-active {
|
||||
left:0;
|
||||
}
|
||||
.view-animate.ng-leave.ng-leave-active {
|
||||
left:-100%;
|
||||
}
|
||||
</file>
|
||||
|
||||
<file name="script.js">
|
||||
angular.module('ngViewExample', ['ngRoute', 'ngAnimate'],
|
||||
function($routeProvider, $locationProvider) {
|
||||
$routeProvider.when('/Book/:bookId', {
|
||||
templateUrl: 'book.html',
|
||||
controller: BookCntl,
|
||||
controllerAs: 'book'
|
||||
});
|
||||
$routeProvider.when('/Book/:bookId/ch/:chapterId', {
|
||||
templateUrl: 'chapter.html',
|
||||
controller: ChapterCntl,
|
||||
controllerAs: 'chapter'
|
||||
});
|
||||
|
||||
// configure html5 to get links working on jsfiddle
|
||||
$locationProvider.html5Mode(true);
|
||||
});
|
||||
|
||||
function MainCntl($route, $routeParams, $location) {
|
||||
this.$route = $route;
|
||||
this.$location = $location;
|
||||
this.$routeParams = $routeParams;
|
||||
}
|
||||
|
||||
function BookCntl($routeParams) {
|
||||
this.name = "BookCntl";
|
||||
this.params = $routeParams;
|
||||
}
|
||||
|
||||
function ChapterCntl($routeParams) {
|
||||
this.name = "ChapterCntl";
|
||||
this.params = $routeParams;
|
||||
}
|
||||
</file>
|
||||
|
||||
<file name="scenario.js">
|
||||
it('should load and compile correct template', function() {
|
||||
element('a:contains("Moby: Ch1")').click();
|
||||
var content = element('.doc-example-live [ng-view]').text();
|
||||
expect(content).toMatch(/controller\: ChapterCntl/);
|
||||
expect(content).toMatch(/Book Id\: Moby/);
|
||||
expect(content).toMatch(/Chapter Id\: 1/);
|
||||
|
||||
element('a:contains("Scarlet")').click();
|
||||
content = element('.doc-example-live [ng-view]').text();
|
||||
expect(content).toMatch(/controller\: BookCntl/);
|
||||
expect(content).toMatch(/Book Id\: Scarlet/);
|
||||
});
|
||||
</file>
|
||||
</example>
|
||||
*/
|
||||
|
||||
|
||||
/**
|
||||
* @ngdoc event
|
||||
* @name ngRoute.directive:ngView#$viewContentLoaded
|
||||
* @eventOf ngRoute.directive:ngView
|
||||
* @eventType emit on the current ngView scope
|
||||
* @description
|
||||
* Emitted every time the ngView content is reloaded.
|
||||
*/
|
||||
ngViewFactory.$inject = ['$route', '$anchorScroll', '$animate'];
|
||||
function ngViewFactory( $route, $anchorScroll, $animate) {
|
||||
return {
|
||||
restrict: 'ECA',
|
||||
terminal: true,
|
||||
priority: 400,
|
||||
transclude: 'element',
|
||||
link: function(scope, $element, attr, ctrl, $transclude) {
|
||||
var currentScope,
|
||||
currentElement,
|
||||
autoScrollExp = attr.autoscroll,
|
||||
onloadExp = attr.onload || '';
|
||||
|
||||
scope.$on('$routeChangeSuccess', update);
|
||||
update();
|
||||
|
||||
function cleanupLastView() {
|
||||
if (currentScope) {
|
||||
currentScope.$destroy();
|
||||
currentScope = null;
|
||||
}
|
||||
if(currentElement) {
|
||||
$animate.leave(currentElement);
|
||||
currentElement = null;
|
||||
}
|
||||
}
|
||||
|
||||
function update() {
|
||||
var locals = $route.current && $route.current.locals,
|
||||
template = locals && locals.$template;
|
||||
|
||||
if (template) {
|
||||
var newScope = scope.$new();
|
||||
var current = $route.current;
|
||||
|
||||
// Note: This will also link all children of ng-view that were contained in the original
|
||||
// html. If that content contains controllers, ... they could pollute/change the scope.
|
||||
// However, using ng-view on an element with additional content does not make sense...
|
||||
// Note: We can't remove them in the cloneAttchFn of $transclude as that
|
||||
// function is called before linking the content, which would apply child
|
||||
// directives to non existing elements.
|
||||
var clone = $transclude(newScope, function(clone) {
|
||||
$animate.enter(clone, null, currentElement || $element, function onNgViewEnter () {
|
||||
if (angular.isDefined(autoScrollExp)
|
||||
&& (!autoScrollExp || scope.$eval(autoScrollExp))) {
|
||||
$anchorScroll();
|
||||
}
|
||||
});
|
||||
cleanupLastView();
|
||||
});
|
||||
|
||||
currentElement = clone;
|
||||
currentScope = current.scope = newScope;
|
||||
currentScope.$emit('$viewContentLoaded');
|
||||
currentScope.$eval(onloadExp);
|
||||
} else {
|
||||
cleanupLastView();
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
// This directive is called during the $transclude call of the first `ngView` directive.
|
||||
// It will replace and compile the content of the element with the loaded template.
|
||||
// We need this directive so that the element content is already filled when
|
||||
// the link function of another directive on the same element as ngView
|
||||
// is called.
|
||||
ngViewFillContentFactory.$inject = ['$compile', '$controller', '$route'];
|
||||
function ngViewFillContentFactory($compile, $controller, $route) {
|
||||
return {
|
||||
restrict: 'ECA',
|
||||
priority: -400,
|
||||
link: function(scope, $element) {
|
||||
var current = $route.current,
|
||||
locals = current.locals;
|
||||
|
||||
$element.html(locals.$template);
|
||||
|
||||
var link = $compile($element.contents());
|
||||
|
||||
if (current.controller) {
|
||||
locals.$scope = scope;
|
||||
var controller = $controller(current.controller, locals);
|
||||
if (current.controllerAs) {
|
||||
scope[current.controllerAs] = controller;
|
||||
}
|
||||
$element.data('$ngControllerController', controller);
|
||||
$element.children().data('$ngControllerController', controller);
|
||||
}
|
||||
|
||||
link(scope);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
})(window, window.angular);
|
31
guacamole/src/main/webapp/lib/plugins/angular-translate-loader-static-files.js
vendored
Normal file
31
guacamole/src/main/webapp/lib/plugins/angular-translate-loader-static-files.js
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*!
|
||||
* angular-translate - v2.2.0 - 2014-06-03
|
||||
* http://github.com/PascalPrecht/angular-translate
|
||||
* Copyright (c) 2014 ; Licensed MIT
|
||||
*/
|
||||
angular.module('pascalprecht.translate').factory('$translateStaticFilesLoader', [
|
||||
'$q',
|
||||
'$http',
|
||||
function ($q, $http) {
|
||||
return function (options) {
|
||||
if (!options || (!angular.isString(options.prefix) || !angular.isString(options.suffix))) {
|
||||
throw new Error('Couldn\'t load static files, no prefix or suffix specified!');
|
||||
}
|
||||
var deferred = $q.defer();
|
||||
$http({
|
||||
url: [
|
||||
options.prefix,
|
||||
options.key,
|
||||
options.suffix
|
||||
].join(''),
|
||||
method: 'GET',
|
||||
params: ''
|
||||
}).success(function (data) {
|
||||
deferred.resolve(data);
|
||||
}).error(function (data) {
|
||||
deferred.reject(options.key);
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
}
|
||||
]);
|
883
guacamole/src/main/webapp/lib/plugins/angular-translate.js
vendored
Normal file
883
guacamole/src/main/webapp/lib/plugins/angular-translate.js
vendored
Normal file
@@ -0,0 +1,883 @@
|
||||
/*!
|
||||
* angular-translate - v2.2.0 - 2014-06-03
|
||||
* http://github.com/PascalPrecht/angular-translate
|
||||
* Copyright (c) 2014 ; Licensed MIT
|
||||
*/
|
||||
angular.module('pascalprecht.translate', ['ng']).run([
|
||||
'$translate',
|
||||
function ($translate) {
|
||||
var key = $translate.storageKey(), storage = $translate.storage();
|
||||
if (storage) {
|
||||
if (!storage.get(key)) {
|
||||
if (angular.isString($translate.preferredLanguage())) {
|
||||
$translate.use($translate.preferredLanguage());
|
||||
} else {
|
||||
storage.set(key, $translate.use());
|
||||
}
|
||||
} else {
|
||||
$translate.use(storage.get(key));
|
||||
}
|
||||
} else if (angular.isString($translate.preferredLanguage())) {
|
||||
$translate.use($translate.preferredLanguage());
|
||||
}
|
||||
}
|
||||
]);
|
||||
angular.module('pascalprecht.translate').provider('$translate', [
|
||||
'$STORAGE_KEY',
|
||||
function ($STORAGE_KEY) {
|
||||
var $translationTable = {}, $preferredLanguage, $availableLanguageKeys = [], $languageKeyAliases, $fallbackLanguage, $fallbackWasString, $uses, $nextLang, $storageFactory, $storageKey = $STORAGE_KEY, $storagePrefix, $missingTranslationHandlerFactory, $interpolationFactory, $interpolatorFactories = [], $interpolationSanitizationStrategy = false, $loaderFactory, $cloakClassName = 'translate-cloak', $loaderOptions, $notFoundIndicatorLeft, $notFoundIndicatorRight, $postCompilingEnabled = false, NESTED_OBJECT_DELIMITER = '.';
|
||||
var getLocale = function () {
|
||||
var nav = window.navigator;
|
||||
return (nav.language || nav.browserLanguage || nav.systemLanguage || nav.userLanguage || '').split('-').join('_');
|
||||
};
|
||||
var negotiateLocale = function (preferred) {
|
||||
var avail = [], locale = angular.lowercase(preferred), i = 0, n = $availableLanguageKeys.length;
|
||||
for (; i < n; i++) {
|
||||
avail.push(angular.lowercase($availableLanguageKeys[i]));
|
||||
}
|
||||
if (avail.indexOf(locale) > -1) {
|
||||
return preferred;
|
||||
}
|
||||
if ($languageKeyAliases) {
|
||||
var alias;
|
||||
for (var langKeyAlias in $languageKeyAliases) {
|
||||
var hasWildcardKey = false;
|
||||
var hasExactKey = $languageKeyAliases.hasOwnProperty(langKeyAlias) && angular.lowercase(langKeyAlias) === angular.lowercase(preferred);
|
||||
if (langKeyAlias.slice(-1) === '*') {
|
||||
hasWildcardKey = langKeyAlias.slice(0, -1) === preferred.slice(0, langKeyAlias.length - 1);
|
||||
}
|
||||
if (hasExactKey || hasWildcardKey) {
|
||||
alias = $languageKeyAliases[langKeyAlias];
|
||||
if (avail.indexOf(angular.lowercase(alias)) > -1) {
|
||||
return alias;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var parts = preferred.split('_');
|
||||
if (parts.length > 1 && avail.indexOf(angular.lowercase(parts[0])) > -1) {
|
||||
return parts[0];
|
||||
}
|
||||
return preferred;
|
||||
};
|
||||
var translations = function (langKey, translationTable) {
|
||||
if (!langKey && !translationTable) {
|
||||
return $translationTable;
|
||||
}
|
||||
if (langKey && !translationTable) {
|
||||
if (angular.isString(langKey)) {
|
||||
return $translationTable[langKey];
|
||||
}
|
||||
} else {
|
||||
if (!angular.isObject($translationTable[langKey])) {
|
||||
$translationTable[langKey] = {};
|
||||
}
|
||||
angular.extend($translationTable[langKey], flatObject(translationTable));
|
||||
}
|
||||
return this;
|
||||
};
|
||||
this.translations = translations;
|
||||
this.cloakClassName = function (name) {
|
||||
if (!name) {
|
||||
return $cloakClassName;
|
||||
}
|
||||
$cloakClassName = name;
|
||||
return this;
|
||||
};
|
||||
var flatObject = function (data, path, result, prevKey) {
|
||||
var key, keyWithPath, keyWithShortPath, val;
|
||||
if (!path) {
|
||||
path = [];
|
||||
}
|
||||
if (!result) {
|
||||
result = {};
|
||||
}
|
||||
for (key in data) {
|
||||
if (!data.hasOwnProperty(key)) {
|
||||
continue;
|
||||
}
|
||||
val = data[key];
|
||||
if (angular.isObject(val)) {
|
||||
flatObject(val, path.concat(key), result, key);
|
||||
} else {
|
||||
keyWithPath = path.length ? '' + path.join(NESTED_OBJECT_DELIMITER) + NESTED_OBJECT_DELIMITER + key : key;
|
||||
if (path.length && key === prevKey) {
|
||||
keyWithShortPath = '' + path.join(NESTED_OBJECT_DELIMITER);
|
||||
result[keyWithShortPath] = '@:' + keyWithPath;
|
||||
}
|
||||
result[keyWithPath] = val;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
this.addInterpolation = function (factory) {
|
||||
$interpolatorFactories.push(factory);
|
||||
return this;
|
||||
};
|
||||
this.useMessageFormatInterpolation = function () {
|
||||
return this.useInterpolation('$translateMessageFormatInterpolation');
|
||||
};
|
||||
this.useInterpolation = function (factory) {
|
||||
$interpolationFactory = factory;
|
||||
return this;
|
||||
};
|
||||
this.useSanitizeValueStrategy = function (value) {
|
||||
$interpolationSanitizationStrategy = value;
|
||||
return this;
|
||||
};
|
||||
this.preferredLanguage = function (langKey) {
|
||||
if (langKey) {
|
||||
$preferredLanguage = langKey;
|
||||
return this;
|
||||
}
|
||||
return $preferredLanguage;
|
||||
};
|
||||
this.translationNotFoundIndicator = function (indicator) {
|
||||
this.translationNotFoundIndicatorLeft(indicator);
|
||||
this.translationNotFoundIndicatorRight(indicator);
|
||||
return this;
|
||||
};
|
||||
this.translationNotFoundIndicatorLeft = function (indicator) {
|
||||
if (!indicator) {
|
||||
return $notFoundIndicatorLeft;
|
||||
}
|
||||
$notFoundIndicatorLeft = indicator;
|
||||
return this;
|
||||
};
|
||||
this.translationNotFoundIndicatorRight = function (indicator) {
|
||||
if (!indicator) {
|
||||
return $notFoundIndicatorRight;
|
||||
}
|
||||
$notFoundIndicatorRight = indicator;
|
||||
return this;
|
||||
};
|
||||
this.fallbackLanguage = function (langKey) {
|
||||
fallbackStack(langKey);
|
||||
return this;
|
||||
};
|
||||
var fallbackStack = function (langKey) {
|
||||
if (langKey) {
|
||||
if (angular.isString(langKey)) {
|
||||
$fallbackWasString = true;
|
||||
$fallbackLanguage = [langKey];
|
||||
} else if (angular.isArray(langKey)) {
|
||||
$fallbackWasString = false;
|
||||
$fallbackLanguage = langKey;
|
||||
}
|
||||
if (angular.isString($preferredLanguage)) {
|
||||
$fallbackLanguage.push($preferredLanguage);
|
||||
}
|
||||
return this;
|
||||
} else {
|
||||
if ($fallbackWasString) {
|
||||
return $fallbackLanguage[0];
|
||||
} else {
|
||||
return $fallbackLanguage;
|
||||
}
|
||||
}
|
||||
};
|
||||
this.use = function (langKey) {
|
||||
if (langKey) {
|
||||
if (!$translationTable[langKey] && !$loaderFactory) {
|
||||
throw new Error('$translateProvider couldn\'t find translationTable for langKey: \'' + langKey + '\'');
|
||||
}
|
||||
$uses = langKey;
|
||||
return this;
|
||||
}
|
||||
return $uses;
|
||||
};
|
||||
var storageKey = function (key) {
|
||||
if (!key) {
|
||||
if ($storagePrefix) {
|
||||
return $storagePrefix + $storageKey;
|
||||
}
|
||||
return $storageKey;
|
||||
}
|
||||
$storageKey = key;
|
||||
};
|
||||
this.storageKey = storageKey;
|
||||
this.useUrlLoader = function (url) {
|
||||
return this.useLoader('$translateUrlLoader', { url: url });
|
||||
};
|
||||
this.useStaticFilesLoader = function (options) {
|
||||
return this.useLoader('$translateStaticFilesLoader', options);
|
||||
};
|
||||
this.useLoader = function (loaderFactory, options) {
|
||||
$loaderFactory = loaderFactory;
|
||||
$loaderOptions = options || {};
|
||||
return this;
|
||||
};
|
||||
this.useLocalStorage = function () {
|
||||
return this.useStorage('$translateLocalStorage');
|
||||
};
|
||||
this.useCookieStorage = function () {
|
||||
return this.useStorage('$translateCookieStorage');
|
||||
};
|
||||
this.useStorage = function (storageFactory) {
|
||||
$storageFactory = storageFactory;
|
||||
return this;
|
||||
};
|
||||
this.storagePrefix = function (prefix) {
|
||||
if (!prefix) {
|
||||
return prefix;
|
||||
}
|
||||
$storagePrefix = prefix;
|
||||
return this;
|
||||
};
|
||||
this.useMissingTranslationHandlerLog = function () {
|
||||
return this.useMissingTranslationHandler('$translateMissingTranslationHandlerLog');
|
||||
};
|
||||
this.useMissingTranslationHandler = function (factory) {
|
||||
$missingTranslationHandlerFactory = factory;
|
||||
return this;
|
||||
};
|
||||
this.usePostCompiling = function (value) {
|
||||
$postCompilingEnabled = !!value;
|
||||
return this;
|
||||
};
|
||||
this.determinePreferredLanguage = function (fn) {
|
||||
var locale = fn && angular.isFunction(fn) ? fn() : getLocale();
|
||||
if (!$availableLanguageKeys.length) {
|
||||
$preferredLanguage = locale;
|
||||
} else {
|
||||
$preferredLanguage = negotiateLocale(locale);
|
||||
}
|
||||
return this;
|
||||
};
|
||||
this.registerAvailableLanguageKeys = function (languageKeys, aliases) {
|
||||
if (languageKeys) {
|
||||
$availableLanguageKeys = languageKeys;
|
||||
if (aliases) {
|
||||
$languageKeyAliases = aliases;
|
||||
}
|
||||
return this;
|
||||
}
|
||||
return $availableLanguageKeys;
|
||||
};
|
||||
this.$get = [
|
||||
'$log',
|
||||
'$injector',
|
||||
'$rootScope',
|
||||
'$q',
|
||||
function ($log, $injector, $rootScope, $q) {
|
||||
var Storage, defaultInterpolator = $injector.get($interpolationFactory || '$translateDefaultInterpolation'), pendingLoader = false, interpolatorHashMap = {}, langPromises = {}, fallbackIndex, startFallbackIteration;
|
||||
var $translate = function (translationId, interpolateParams, interpolationId) {
|
||||
if (angular.isArray(translationId)) {
|
||||
var translateAll = function (translationIds) {
|
||||
var results = {};
|
||||
var promises = [];
|
||||
var translate = function (translationId) {
|
||||
var deferred = $q.defer();
|
||||
var regardless = function (value) {
|
||||
results[translationId] = value;
|
||||
deferred.resolve([
|
||||
translationId,
|
||||
value
|
||||
]);
|
||||
};
|
||||
$translate(translationId, interpolateParams, interpolationId).then(regardless, regardless);
|
||||
return deferred.promise;
|
||||
};
|
||||
for (var i = 0, c = translationIds.length; i < c; i++) {
|
||||
promises.push(translate(translationIds[i]));
|
||||
}
|
||||
return $q.all(promises).then(function () {
|
||||
return results;
|
||||
});
|
||||
};
|
||||
return translateAll(translationId);
|
||||
}
|
||||
var deferred = $q.defer();
|
||||
if (translationId) {
|
||||
translationId = translationId.trim();
|
||||
}
|
||||
var promiseToWaitFor = function () {
|
||||
var promise = $preferredLanguage ? langPromises[$preferredLanguage] : langPromises[$uses];
|
||||
fallbackIndex = 0;
|
||||
if ($storageFactory && !promise) {
|
||||
var langKey = Storage.get($storageKey);
|
||||
promise = langPromises[langKey];
|
||||
if ($fallbackLanguage && $fallbackLanguage.length) {
|
||||
var index = indexOf($fallbackLanguage, langKey);
|
||||
fallbackIndex = index > -1 ? index += 1 : 0;
|
||||
$fallbackLanguage.push($preferredLanguage);
|
||||
}
|
||||
}
|
||||
return promise;
|
||||
}();
|
||||
if (!promiseToWaitFor) {
|
||||
determineTranslation(translationId, interpolateParams, interpolationId).then(deferred.resolve, deferred.reject);
|
||||
} else {
|
||||
promiseToWaitFor.then(function () {
|
||||
determineTranslation(translationId, interpolateParams, interpolationId).then(deferred.resolve, deferred.reject);
|
||||
}, deferred.reject);
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
var indexOf = function (array, searchElement) {
|
||||
for (var i = 0, len = array.length; i < len; i++) {
|
||||
if (array[i] === searchElement) {
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
};
|
||||
var applyNotFoundIndicators = function (translationId) {
|
||||
if ($notFoundIndicatorLeft) {
|
||||
translationId = [
|
||||
$notFoundIndicatorLeft,
|
||||
translationId
|
||||
].join(' ');
|
||||
}
|
||||
if ($notFoundIndicatorRight) {
|
||||
translationId = [
|
||||
translationId,
|
||||
$notFoundIndicatorRight
|
||||
].join(' ');
|
||||
}
|
||||
return translationId;
|
||||
};
|
||||
var useLanguage = function (key) {
|
||||
$uses = key;
|
||||
$rootScope.$emit('$translateChangeSuccess');
|
||||
if ($storageFactory) {
|
||||
Storage.set($translate.storageKey(), $uses);
|
||||
}
|
||||
defaultInterpolator.setLocale($uses);
|
||||
angular.forEach(interpolatorHashMap, function (interpolator, id) {
|
||||
interpolatorHashMap[id].setLocale($uses);
|
||||
});
|
||||
$rootScope.$emit('$translateChangeEnd');
|
||||
};
|
||||
var loadAsync = function (key) {
|
||||
if (!key) {
|
||||
throw 'No language key specified for loading.';
|
||||
}
|
||||
var deferred = $q.defer();
|
||||
$rootScope.$emit('$translateLoadingStart');
|
||||
pendingLoader = true;
|
||||
$injector.get($loaderFactory)(angular.extend($loaderOptions, { key: key })).then(function (data) {
|
||||
var translationTable = {};
|
||||
$rootScope.$emit('$translateLoadingSuccess');
|
||||
if (angular.isArray(data)) {
|
||||
angular.forEach(data, function (table) {
|
||||
angular.extend(translationTable, flatObject(table));
|
||||
});
|
||||
} else {
|
||||
angular.extend(translationTable, flatObject(data));
|
||||
}
|
||||
pendingLoader = false;
|
||||
deferred.resolve({
|
||||
key: key,
|
||||
table: translationTable
|
||||
});
|
||||
$rootScope.$emit('$translateLoadingEnd');
|
||||
}, function (key) {
|
||||
$rootScope.$emit('$translateLoadingError');
|
||||
deferred.reject(key);
|
||||
$rootScope.$emit('$translateLoadingEnd');
|
||||
});
|
||||
return deferred.promise;
|
||||
};
|
||||
if ($storageFactory) {
|
||||
Storage = $injector.get($storageFactory);
|
||||
if (!Storage.get || !Storage.set) {
|
||||
throw new Error('Couldn\'t use storage \'' + $storageFactory + '\', missing get() or set() method!');
|
||||
}
|
||||
}
|
||||
if (angular.isFunction(defaultInterpolator.useSanitizeValueStrategy)) {
|
||||
defaultInterpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy);
|
||||
}
|
||||
if ($interpolatorFactories.length) {
|
||||
angular.forEach($interpolatorFactories, function (interpolatorFactory) {
|
||||
var interpolator = $injector.get(interpolatorFactory);
|
||||
interpolator.setLocale($preferredLanguage || $uses);
|
||||
if (angular.isFunction(interpolator.useSanitizeValueStrategy)) {
|
||||
interpolator.useSanitizeValueStrategy($interpolationSanitizationStrategy);
|
||||
}
|
||||
interpolatorHashMap[interpolator.getInterpolationIdentifier()] = interpolator;
|
||||
});
|
||||
}
|
||||
var getTranslationTable = function (langKey) {
|
||||
var deferred = $q.defer();
|
||||
if ($translationTable.hasOwnProperty(langKey)) {
|
||||
deferred.resolve($translationTable[langKey]);
|
||||
return deferred.promise;
|
||||
} else {
|
||||
langPromises[langKey].then(function (data) {
|
||||
translations(data.key, data.table);
|
||||
deferred.resolve(data.table);
|
||||
}, deferred.reject);
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
var getFallbackTranslation = function (langKey, translationId, interpolateParams, Interpolator) {
|
||||
var deferred = $q.defer();
|
||||
getTranslationTable(langKey).then(function (translationTable) {
|
||||
if (translationTable.hasOwnProperty(translationId)) {
|
||||
Interpolator.setLocale(langKey);
|
||||
deferred.resolve(Interpolator.interpolate(translationTable[translationId], interpolateParams));
|
||||
Interpolator.setLocale($uses);
|
||||
} else {
|
||||
deferred.reject();
|
||||
}
|
||||
}, deferred.reject);
|
||||
return deferred.promise;
|
||||
};
|
||||
var getFallbackTranslationInstant = function (langKey, translationId, interpolateParams, Interpolator) {
|
||||
var result, translationTable = $translationTable[langKey];
|
||||
if (translationTable.hasOwnProperty(translationId)) {
|
||||
Interpolator.setLocale(langKey);
|
||||
result = Interpolator.interpolate(translationTable[translationId], interpolateParams);
|
||||
Interpolator.setLocale($uses);
|
||||
}
|
||||
return result;
|
||||
};
|
||||
var resolveForFallbackLanguage = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator) {
|
||||
var deferred = $q.defer();
|
||||
if (fallbackLanguageIndex < $fallbackLanguage.length) {
|
||||
var langKey = $fallbackLanguage[fallbackLanguageIndex];
|
||||
getFallbackTranslation(langKey, translationId, interpolateParams, Interpolator).then(function (translation) {
|
||||
deferred.resolve(translation);
|
||||
}, function () {
|
||||
var nextFallbackLanguagePromise = resolveForFallbackLanguage(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator);
|
||||
deferred.resolve(nextFallbackLanguagePromise);
|
||||
});
|
||||
} else {
|
||||
if ($missingTranslationHandlerFactory) {
|
||||
var resultString = $injector.get($missingTranslationHandlerFactory)(translationId, $uses);
|
||||
if (resultString !== undefined) {
|
||||
deferred.resolve(resultString);
|
||||
} else {
|
||||
deferred.resolve(translationId);
|
||||
}
|
||||
} else {
|
||||
deferred.resolve(translationId);
|
||||
}
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
var resolveForFallbackLanguageInstant = function (fallbackLanguageIndex, translationId, interpolateParams, Interpolator) {
|
||||
var result;
|
||||
if (fallbackLanguageIndex < $fallbackLanguage.length) {
|
||||
var langKey = $fallbackLanguage[fallbackLanguageIndex];
|
||||
result = getFallbackTranslationInstant(langKey, translationId, interpolateParams, Interpolator);
|
||||
if (!result) {
|
||||
result = resolveForFallbackLanguageInstant(fallbackLanguageIndex + 1, translationId, interpolateParams, Interpolator);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
var fallbackTranslation = function (translationId, interpolateParams, Interpolator) {
|
||||
return resolveForFallbackLanguage(startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex, translationId, interpolateParams, Interpolator);
|
||||
};
|
||||
var fallbackTranslationInstant = function (translationId, interpolateParams, Interpolator) {
|
||||
return resolveForFallbackLanguageInstant(startFallbackIteration > 0 ? startFallbackIteration : fallbackIndex, translationId, interpolateParams, Interpolator);
|
||||
};
|
||||
var determineTranslation = function (translationId, interpolateParams, interpolationId) {
|
||||
var deferred = $q.defer();
|
||||
var table = $uses ? $translationTable[$uses] : $translationTable, Interpolator = interpolationId ? interpolatorHashMap[interpolationId] : defaultInterpolator;
|
||||
if (table && table.hasOwnProperty(translationId)) {
|
||||
var translation = table[translationId];
|
||||
if (translation.substr(0, 2) === '@:') {
|
||||
$translate(translation.substr(2), interpolateParams, interpolationId).then(deferred.resolve, deferred.reject);
|
||||
} else {
|
||||
deferred.resolve(Interpolator.interpolate(translation, interpolateParams));
|
||||
}
|
||||
} else {
|
||||
if ($missingTranslationHandlerFactory && !pendingLoader) {
|
||||
$injector.get($missingTranslationHandlerFactory)(translationId, $uses);
|
||||
}
|
||||
if ($uses && $fallbackLanguage && $fallbackLanguage.length) {
|
||||
fallbackTranslation(translationId, interpolateParams, Interpolator).then(function (translation) {
|
||||
deferred.resolve(translation);
|
||||
}, function (_translationId) {
|
||||
deferred.reject(applyNotFoundIndicators(_translationId));
|
||||
});
|
||||
} else {
|
||||
deferred.reject(applyNotFoundIndicators(translationId));
|
||||
}
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
var determineTranslationInstant = function (translationId, interpolateParams, interpolationId) {
|
||||
var result, table = $uses ? $translationTable[$uses] : $translationTable, Interpolator = interpolationId ? interpolatorHashMap[interpolationId] : defaultInterpolator;
|
||||
if (table && table.hasOwnProperty(translationId)) {
|
||||
var translation = table[translationId];
|
||||
if (translation.substr(0, 2) === '@:') {
|
||||
result = determineTranslationInstant(translation.substr(2), interpolateParams, interpolationId);
|
||||
} else {
|
||||
result = Interpolator.interpolate(translation, interpolateParams);
|
||||
}
|
||||
} else {
|
||||
if ($missingTranslationHandlerFactory && !pendingLoader) {
|
||||
$injector.get($missingTranslationHandlerFactory)(translationId, $uses);
|
||||
}
|
||||
if ($uses && $fallbackLanguage && $fallbackLanguage.length) {
|
||||
fallbackIndex = 0;
|
||||
result = fallbackTranslationInstant(translationId, interpolateParams, Interpolator);
|
||||
} else {
|
||||
result = applyNotFoundIndicators(translationId);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
$translate.preferredLanguage = function () {
|
||||
return $preferredLanguage;
|
||||
};
|
||||
$translate.cloakClassName = function () {
|
||||
return $cloakClassName;
|
||||
};
|
||||
$translate.fallbackLanguage = function (langKey) {
|
||||
if (langKey !== undefined && langKey !== null) {
|
||||
fallbackStack(langKey);
|
||||
if ($loaderFactory) {
|
||||
if ($fallbackLanguage && $fallbackLanguage.length) {
|
||||
for (var i = 0, len = $fallbackLanguage.length; i < len; i++) {
|
||||
if (!langPromises[$fallbackLanguage[i]]) {
|
||||
langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$translate.use($translate.use());
|
||||
}
|
||||
if ($fallbackWasString) {
|
||||
return $fallbackLanguage[0];
|
||||
} else {
|
||||
return $fallbackLanguage;
|
||||
}
|
||||
};
|
||||
$translate.useFallbackLanguage = function (langKey) {
|
||||
if (langKey !== undefined && langKey !== null) {
|
||||
if (!langKey) {
|
||||
startFallbackIteration = 0;
|
||||
} else {
|
||||
var langKeyPosition = indexOf($fallbackLanguage, langKey);
|
||||
if (langKeyPosition > -1) {
|
||||
startFallbackIteration = langKeyPosition;
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
$translate.proposedLanguage = function () {
|
||||
return $nextLang;
|
||||
};
|
||||
$translate.storage = function () {
|
||||
return Storage;
|
||||
};
|
||||
$translate.use = function (key) {
|
||||
if (!key) {
|
||||
return $uses;
|
||||
}
|
||||
var deferred = $q.defer();
|
||||
$rootScope.$emit('$translateChangeStart');
|
||||
var aliasedKey = negotiateLocale(key);
|
||||
if (aliasedKey) {
|
||||
key = aliasedKey;
|
||||
}
|
||||
if (!$translationTable[key] && $loaderFactory) {
|
||||
$nextLang = key;
|
||||
langPromises[key] = loadAsync(key).then(function (translation) {
|
||||
translations(translation.key, translation.table);
|
||||
deferred.resolve(translation.key);
|
||||
if ($nextLang === key) {
|
||||
useLanguage(translation.key);
|
||||
$nextLang = undefined;
|
||||
}
|
||||
}, function (key) {
|
||||
$nextLang = undefined;
|
||||
$rootScope.$emit('$translateChangeError');
|
||||
deferred.reject(key);
|
||||
$rootScope.$emit('$translateChangeEnd');
|
||||
});
|
||||
} else {
|
||||
deferred.resolve(key);
|
||||
useLanguage(key);
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
$translate.storageKey = function () {
|
||||
return storageKey();
|
||||
};
|
||||
$translate.isPostCompilingEnabled = function () {
|
||||
return $postCompilingEnabled;
|
||||
};
|
||||
$translate.refresh = function (langKey) {
|
||||
if (!$loaderFactory) {
|
||||
throw new Error('Couldn\'t refresh translation table, no loader registered!');
|
||||
}
|
||||
var deferred = $q.defer();
|
||||
function resolve() {
|
||||
deferred.resolve();
|
||||
$rootScope.$emit('$translateRefreshEnd');
|
||||
}
|
||||
function reject() {
|
||||
deferred.reject();
|
||||
$rootScope.$emit('$translateRefreshEnd');
|
||||
}
|
||||
$rootScope.$emit('$translateRefreshStart');
|
||||
if (!langKey) {
|
||||
var tables = [];
|
||||
if ($fallbackLanguage && $fallbackLanguage.length) {
|
||||
for (var i = 0, len = $fallbackLanguage.length; i < len; i++) {
|
||||
tables.push(loadAsync($fallbackLanguage[i]));
|
||||
}
|
||||
}
|
||||
if ($uses) {
|
||||
tables.push(loadAsync($uses));
|
||||
}
|
||||
$q.all(tables).then(function (tableData) {
|
||||
angular.forEach(tableData, function (data) {
|
||||
if ($translationTable[data.key]) {
|
||||
delete $translationTable[data.key];
|
||||
}
|
||||
translations(data.key, data.table);
|
||||
});
|
||||
if ($uses) {
|
||||
useLanguage($uses);
|
||||
}
|
||||
resolve();
|
||||
});
|
||||
} else if ($translationTable[langKey]) {
|
||||
loadAsync(langKey).then(function (data) {
|
||||
translations(data.key, data.table);
|
||||
if (langKey === $uses) {
|
||||
useLanguage($uses);
|
||||
}
|
||||
resolve();
|
||||
}, reject);
|
||||
} else {
|
||||
reject();
|
||||
}
|
||||
return deferred.promise;
|
||||
};
|
||||
$translate.instant = function (translationId, interpolateParams, interpolationId) {
|
||||
if (translationId === null || angular.isUndefined(translationId)) {
|
||||
return translationId;
|
||||
}
|
||||
if (angular.isArray(translationId)) {
|
||||
var results = {};
|
||||
for (var i = 0, c = translationId.length; i < c; i++) {
|
||||
results[translationId[i]] = $translate.instant(translationId[i], interpolateParams, interpolationId);
|
||||
}
|
||||
return results;
|
||||
}
|
||||
if (angular.isString(translationId) && translationId.length < 1) {
|
||||
return translationId;
|
||||
}
|
||||
if (translationId) {
|
||||
translationId = translationId.trim();
|
||||
}
|
||||
var result, possibleLangKeys = [];
|
||||
if ($preferredLanguage) {
|
||||
possibleLangKeys.push($preferredLanguage);
|
||||
}
|
||||
if ($uses) {
|
||||
possibleLangKeys.push($uses);
|
||||
}
|
||||
if ($fallbackLanguage && $fallbackLanguage.length) {
|
||||
possibleLangKeys = possibleLangKeys.concat($fallbackLanguage);
|
||||
}
|
||||
for (var j = 0, d = possibleLangKeys.length; j < d; j++) {
|
||||
var possibleLangKey = possibleLangKeys[j];
|
||||
if ($translationTable[possibleLangKey]) {
|
||||
if (typeof $translationTable[possibleLangKey][translationId] !== 'undefined') {
|
||||
result = determineTranslationInstant(translationId, interpolateParams, interpolationId);
|
||||
}
|
||||
}
|
||||
if (typeof result !== 'undefined') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!result && result !== '') {
|
||||
result = translationId;
|
||||
if ($missingTranslationHandlerFactory && !pendingLoader) {
|
||||
$injector.get($missingTranslationHandlerFactory)(translationId, $uses);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
};
|
||||
if ($loaderFactory) {
|
||||
if (angular.equals($translationTable, {})) {
|
||||
$translate.use($translate.use());
|
||||
}
|
||||
if ($fallbackLanguage && $fallbackLanguage.length) {
|
||||
for (var i = 0, len = $fallbackLanguage.length; i < len; i++) {
|
||||
langPromises[$fallbackLanguage[i]] = loadAsync($fallbackLanguage[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return $translate;
|
||||
}
|
||||
];
|
||||
}
|
||||
]);
|
||||
angular.module('pascalprecht.translate').factory('$translateDefaultInterpolation', [
|
||||
'$interpolate',
|
||||
function ($interpolate) {
|
||||
var $translateInterpolator = {}, $locale, $identifier = 'default', $sanitizeValueStrategy = null, sanitizeValueStrategies = {
|
||||
escaped: function (params) {
|
||||
var result = {};
|
||||
for (var key in params) {
|
||||
if (params.hasOwnProperty(key)) {
|
||||
result[key] = angular.element('<div></div>').text(params[key]).html();
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
};
|
||||
var sanitizeParams = function (params) {
|
||||
var result;
|
||||
if (angular.isFunction(sanitizeValueStrategies[$sanitizeValueStrategy])) {
|
||||
result = sanitizeValueStrategies[$sanitizeValueStrategy](params);
|
||||
} else {
|
||||
result = params;
|
||||
}
|
||||
return result;
|
||||
};
|
||||
$translateInterpolator.setLocale = function (locale) {
|
||||
$locale = locale;
|
||||
};
|
||||
$translateInterpolator.getInterpolationIdentifier = function () {
|
||||
return $identifier;
|
||||
};
|
||||
$translateInterpolator.useSanitizeValueStrategy = function (value) {
|
||||
$sanitizeValueStrategy = value;
|
||||
return this;
|
||||
};
|
||||
$translateInterpolator.interpolate = function (string, interpolateParams) {
|
||||
if ($sanitizeValueStrategy) {
|
||||
interpolateParams = sanitizeParams(interpolateParams);
|
||||
}
|
||||
return $interpolate(string)(interpolateParams || {});
|
||||
};
|
||||
return $translateInterpolator;
|
||||
}
|
||||
]);
|
||||
angular.module('pascalprecht.translate').constant('$STORAGE_KEY', 'NG_TRANSLATE_LANG_KEY');
|
||||
angular.module('pascalprecht.translate').directive('translate', [
|
||||
'$translate',
|
||||
'$q',
|
||||
'$interpolate',
|
||||
'$compile',
|
||||
'$parse',
|
||||
'$rootScope',
|
||||
function ($translate, $q, $interpolate, $compile, $parse, $rootScope) {
|
||||
return {
|
||||
restrict: 'AE',
|
||||
scope: true,
|
||||
compile: function (tElement, tAttr) {
|
||||
var translateValuesExist = tAttr.translateValues ? tAttr.translateValues : undefined;
|
||||
var translateInterpolation = tAttr.translateInterpolation ? tAttr.translateInterpolation : undefined;
|
||||
var translateValueExist = tElement[0].outerHTML.match(/translate-value-+/i);
|
||||
return function linkFn(scope, iElement, iAttr) {
|
||||
scope.interpolateParams = {};
|
||||
iAttr.$observe('translate', function (translationId) {
|
||||
if (angular.equals(translationId, '') || !angular.isDefined(translationId)) {
|
||||
scope.translationId = $interpolate(iElement.text().replace(/^\s+|\s+$/g, ''))(scope.$parent);
|
||||
} else {
|
||||
scope.translationId = translationId;
|
||||
}
|
||||
});
|
||||
iAttr.$observe('translateDefault', function (value) {
|
||||
scope.defaultText = value;
|
||||
});
|
||||
if (translateValuesExist) {
|
||||
iAttr.$observe('translateValues', function (interpolateParams) {
|
||||
if (interpolateParams) {
|
||||
scope.$parent.$watch(function () {
|
||||
angular.extend(scope.interpolateParams, $parse(interpolateParams)(scope.$parent));
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
if (translateValueExist) {
|
||||
var fn = function (attrName) {
|
||||
iAttr.$observe(attrName, function (value) {
|
||||
scope.interpolateParams[angular.lowercase(attrName.substr(14, 1)) + attrName.substr(15)] = value;
|
||||
});
|
||||
};
|
||||
for (var attr in iAttr) {
|
||||
if (iAttr.hasOwnProperty(attr) && attr.substr(0, 14) === 'translateValue' && attr !== 'translateValues') {
|
||||
fn(attr);
|
||||
}
|
||||
}
|
||||
}
|
||||
var applyElementContent = function (value, scope, successful) {
|
||||
if (!successful && typeof scope.defaultText !== 'undefined') {
|
||||
value = scope.defaultText;
|
||||
}
|
||||
iElement.html(value);
|
||||
var globallyEnabled = $translate.isPostCompilingEnabled();
|
||||
var locallyDefined = typeof tAttr.translateCompile !== 'undefined';
|
||||
var locallyEnabled = locallyDefined && tAttr.translateCompile !== 'false';
|
||||
if (globallyEnabled && !locallyDefined || locallyEnabled) {
|
||||
$compile(iElement.contents())(scope);
|
||||
}
|
||||
};
|
||||
var updateTranslationFn = function () {
|
||||
if (!translateValuesExist && !translateValueExist) {
|
||||
return function () {
|
||||
var unwatch = scope.$watch('translationId', function (value) {
|
||||
if (scope.translationId && value) {
|
||||
$translate(value, {}, translateInterpolation).then(function (translation) {
|
||||
applyElementContent(translation, scope, true);
|
||||
unwatch();
|
||||
}, function (translationId) {
|
||||
applyElementContent(translationId, scope, false);
|
||||
unwatch();
|
||||
});
|
||||
}
|
||||
}, true);
|
||||
};
|
||||
} else {
|
||||
return function () {
|
||||
var updateTranslations = function () {
|
||||
if (scope.translationId && scope.interpolateParams) {
|
||||
$translate(scope.translationId, scope.interpolateParams, translateInterpolation).then(function (translation) {
|
||||
applyElementContent(translation, scope, true);
|
||||
}, function (translationId) {
|
||||
applyElementContent(translationId, scope, false);
|
||||
});
|
||||
}
|
||||
};
|
||||
scope.$watch('interpolateParams', updateTranslations, true);
|
||||
scope.$watch('translationId', updateTranslations);
|
||||
};
|
||||
}
|
||||
}();
|
||||
var unbind = $rootScope.$on('$translateChangeSuccess', updateTranslationFn);
|
||||
updateTranslationFn();
|
||||
scope.$on('$destroy', unbind);
|
||||
};
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
angular.module('pascalprecht.translate').directive('translateCloak', [
|
||||
'$rootScope',
|
||||
'$translate',
|
||||
function ($rootScope, $translate) {
|
||||
return {
|
||||
compile: function (tElement) {
|
||||
$rootScope.$on('$translateLoadingSuccess', function () {
|
||||
tElement.removeClass($translate.cloakClassName());
|
||||
});
|
||||
tElement.addClass($translate.cloakClassName());
|
||||
}
|
||||
};
|
||||
}
|
||||
]);
|
||||
angular.module('pascalprecht.translate').filter('translate', [
|
||||
'$parse',
|
||||
'$translate',
|
||||
function ($parse, $translate) {
|
||||
return function (translationId, interpolateParams, interpolation) {
|
||||
if (!angular.isObject(interpolateParams)) {
|
||||
interpolateParams = $parse(interpolateParams)(this);
|
||||
}
|
||||
return $translate.instant(translationId, interpolateParams, interpolation);
|
||||
};
|
||||
}
|
||||
]);
|
78
guacamole/src/main/webapp/lib/plugins/modal.js
Normal file
78
guacamole/src/main/webapp/lib/plugins/modal.js
Normal file
@@ -0,0 +1,78 @@
|
||||
/*!
|
||||
* angular-modal v0.0.3
|
||||
* (c) 2013 Brian Ford http://briantford.com
|
||||
* License: MIT
|
||||
*/
|
||||
|
||||
'use strict';
|
||||
|
||||
angular.module('btford.modal', []).
|
||||
factory('btfModal', function ($compile, $rootScope, $controller, $q, $http, $templateCache) {
|
||||
return function modalFactory (config) {
|
||||
|
||||
if ((+!!config.template) + (+!!config.templateUrl) !== 1) {
|
||||
throw new Error('Expected modal to have exacly one of either `template` or `templateUrl`');
|
||||
}
|
||||
|
||||
var template = config.template,
|
||||
controller = config.controller || angular.noop,
|
||||
controllerAs = config.controllerAs,
|
||||
container = angular.element(config.container || document.body),
|
||||
element = null,
|
||||
html;
|
||||
|
||||
if (config.template) {
|
||||
var deferred = $q.defer();
|
||||
deferred.resolve(config.template);
|
||||
html = deferred.promise;
|
||||
} else {
|
||||
html = $http.get(config.templateUrl, {
|
||||
cache: $templateCache
|
||||
}).
|
||||
then(function (response) {
|
||||
return response.data;
|
||||
});
|
||||
}
|
||||
|
||||
function activate (locals) {
|
||||
html.then(function (html) {
|
||||
if (!element) {
|
||||
attach(html, locals);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function attach (html, locals) {
|
||||
element = angular.element(html);
|
||||
|
||||
/*
|
||||
* Changed by James Muehlner to append to the end of the document instead
|
||||
* of the beginning.
|
||||
*/
|
||||
container.append(element);
|
||||
var scope = $rootScope.$new();
|
||||
if (locals) {
|
||||
for (var prop in locals) {
|
||||
scope[prop] = locals[prop];
|
||||
}
|
||||
}
|
||||
var ctrl = $controller(controller, { $scope: scope });
|
||||
if (controllerAs) {
|
||||
scope[controllerAs] = ctrl;
|
||||
}
|
||||
$compile(element)(scope);
|
||||
}
|
||||
|
||||
function deactivate () {
|
||||
if (element) {
|
||||
element.remove();
|
||||
element = null;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
activate: activate,
|
||||
deactivate: deactivate
|
||||
};
|
||||
};
|
||||
});
|
Reference in New Issue
Block a user