@spalger/kibana
Version:
Kibana is an open source (Apache Licensed), browser based analytics and search dashboard for Elasticsearch. Kibana is a snap to setup and start using. Kibana strives to be easy to get started with, while also being flexible and powerful, just like Elastic
191 lines (160 loc) • 6.01 kB
JavaScript
define(function (require) {
var _ = require('lodash');
require('ui/filters/uriescape');
require('ui/filters/rison');
require('ui/modules').get('kibana/url')
.service('kbnUrl', function (Private) { return Private(KbnUrlProvider); });
function KbnUrlProvider($route, $location, $rootScope, globalState, $parse, getAppState) {
var self = this;
/**
* Navigate to a url
*
* @param {String} url - the new url, can be a template. See #eval
* @param {Object} [paramObj] - optional set of parameters for the url template
* @return {undefined}
*/
self.change = function (url, paramObj) {
self._changeLocation('url', url, paramObj);
};
/**
* Same as #change except only changes the url's path,
* leaving the search string and such intact
*
* @param {String} path - the new path, can be a template. See #eval
* @param {Object} [paramObj] - optional set of parameters for the path template
* @return {undefined}
*/
self.changePath = function (path, paramObj) {
self._changeLocation('path', path, paramObj);
};
/**
* Same as #change except that it removes the current url from history
*
* @param {String} url - the new url, can be a template. See #eval
* @param {Object} [paramObj] - optional set of parameters for the url template
* @return {undefined}
*/
self.redirect = function (url, paramObj) {
self._changeLocation('url', url, paramObj, true);
};
/**
* Same as #redirect except only changes the url's path,
* leaving the search string and such intact
*
* @param {String} path - the new path, can be a template. See #eval
* @param {Object} [paramObj] - optional set of parameters for the path template
* @return {undefined}
*/
self.redirectPath = function (path, paramObj) {
self._changeLocation('path', path, paramObj, true);
};
/**
* Evaluate a url template. templates can contain double-curly wrapped
* expressions that are evaluated in the context of the paramObj
*
* @param {String} template - the url template to evaluate
* @param {Object} [paramObj] - the variables to expose to the template
* @return {String} - the evaluated result
* @throws {Error} If any of the expressions can't be parsed.
*/
self.eval = function (template, paramObj) {
paramObj = paramObj || {};
return template.replace(/\{\{([^\}]+)\}\}/g, function (match, expr) {
// remove filters
var key = expr.split('|')[0].trim();
// verify that the expression can be evaluated
var p = $parse(key)(paramObj);
// if evaluation can't be made, throw
if (_.isUndefined(p)) {
throw new Error('Replacement failed, unresolved expression: ' + expr);
}
// append uriescape filter if not included
if (expr.indexOf('uriescape') === -1) {
expr += '|uriescape';
}
return $parse(expr)(paramObj);
});
};
/**
* convert an object's route to an href, compatible with
* window.location.href= and <a href="">
*
* @param {Object} obj - any object that list's it's routes at obj.routes{}
* @param {string} route - the route name
* @return {string} - the computed href
*/
self.getRouteHref = function (obj, route) {
return '#' + self.getRouteUrl(obj, route);
};
/**
* convert an object's route to a url, compatible with url.change() or $location.url()
*
* @param {Object} obj - any object that list's it's routes at obj.routes{}
* @param {string} route - the route name
* @return {string} - the computed url
*/
self.getRouteUrl = function (obj, route) {
var template = obj && obj.routes && obj.routes[route];
if (template) return self.eval(template, obj);
};
/**
* Similar to getRouteUrl, supports objects which list their routes,
* and redirects to the named route. See #redirect
*
* @param {Object} obj - any object that list's it's routes at obj.routes{}
* @param {string} route - the route name
* @return {undefined}
*/
self.redirectToRoute = function (obj, route) {
self.redirect(self.getRouteUrl(obj, route));
};
/**
* Similar to getRouteUrl, supports objects which list their routes,
* and changes the url to the named route. See #change
*
* @param {Object} obj - any object that list's it's routes at obj.routes{}
* @param {string} route - the route name
* @return {undefined}
*/
self.changeToRoute = function (obj, route) {
self.change(self.getRouteUrl(obj, route));
};
/////
// private api
/////
var reloading;
self._changeLocation = function (type, url, paramObj, replace) {
var prev = {
path: $location.path(),
search: $location.search()
};
url = self.eval(url, paramObj);
$location[type](url);
if (replace) $location.replace();
var next = {
path: $location.path(),
search: $location.search()
};
if (self._shouldAutoReload(next, prev)) {
var appState = getAppState();
if (appState) appState.destroy();
reloading = $rootScope.$on('$locationChangeSuccess', function () {
// call the "unlisten" function returned by $on
reloading();
reloading = false;
$route.reload();
});
}
};
self._shouldAutoReload = function (next, prev) {
if (reloading) return false;
var route = $route.current && $route.current.$$route;
if (!route) return false;
if (next.path !== prev.path) return false;
var reloadOnSearch = route.reloadOnSearch;
var searchSame = _.isEqual(next.search, prev.search);
return (reloadOnSearch && searchSame) || !reloadOnSearch;
};
}
return KbnUrlProvider;
});