'use strict'; (function (angular) { function tokenToRegExp(token) { return new RegExp(':(' + token + ')(?:\\(([^\\(]+)\\))?'); } angular.module('fdNamedRoutes', []) .provider('namedRouteProvider', ['$locationProvider', function namedRouteProvider($locationProvider) { this.$get = ['$route', function ($route) { var prefix = !$locationProvider.html5Mode() ? '#' + $locationProvider.hashPrefix() : ''; var namedRoutes = Object.keys($route.routes).reduce(function (obj, key) { var route = $route.routes[key]; if (route.name) { if (obj[route.name]) throw new Error('A route named "' + route.name + '" exists'); obj[route.name] = route; } return obj; }, {}); function generate(routeName, routeParams) { var route = namedRoutes[routeName], tokens = routeParams ? Object.keys(routeParams) : null; if (!route) throw new Error('Route "' + name + '" not found'); var url = !tokens ? route.originalPath : tokens.reduce(function (route, token) { return route.replace(tokenToRegExp(token), routeParams[token]); }, route.originalPath); return prefix + url; } return generate; }]; return this; }]) .filter('url', ['namedRouteProvider', function urlFilter(namedRouteProvider) { function filter(routeParams, routeName) { return namedRouteProvider(routeName, routeParams); } return filter; }]) .directive('link', ['namedRouteProvider', function linkDirective(namedRouteProvider) { return { link: function ($scope, ele, attr) { var routeName = attr.link, routeParams = {}; for (var key in attr) { if (attr.hasOwnProperty(key) && /link\w+$/.test(key)) { routeParams[key.slice(4).toLowerCase()] = attr[key]; } } ele.attr('href', namedRouteProvider(routeName, routeParams)); } }; }]); })(window.angular);