UNPKG

@angular/router-deprecated

Version:
153 lines 7.27 kB
"use strict"; var async_1 = require('../facade/async'); var collection_1 = require('../facade/collection'); var exceptions_1 = require('../facade/exceptions'); var lang_1 = require('../facade/lang'); var route_config_impl_1 = require('../route_config/route_config_impl'); var async_route_handler_1 = require('./route_handlers/async_route_handler'); var sync_route_handler_1 = require('./route_handlers/sync_route_handler'); var param_route_path_1 = require('./route_paths/param_route_path'); var regex_route_path_1 = require('./route_paths/regex_route_path'); var rules_1 = require('./rules'); /** * A `RuleSet` is responsible for recognizing routes for a particular component. * It is consumed by `RouteRegistry`, which knows how to recognize an entire hierarchy of * components. */ var RuleSet = (function () { function RuleSet() { this.rulesByName = new collection_1.Map(); // map from name to rule this.auxRulesByName = new collection_1.Map(); // map from starting path to rule this.auxRulesByPath = new collection_1.Map(); // TODO: optimize this into a trie this.rules = []; // the rule to use automatically when recognizing or generating from this rule set this.defaultRule = null; } /** * Configure additional rules in this rule set from a route definition * @returns {boolean} true if the config is terminal */ RuleSet.prototype.config = function (config) { var handler; if (lang_1.isPresent(config.name) && config.name[0].toUpperCase() != config.name[0]) { var suggestedName = config.name[0].toUpperCase() + config.name.substring(1); throw new exceptions_1.BaseException("Route \"" + config.path + "\" with name \"" + config.name + "\" does not begin with an uppercase letter. Route names should be PascalCase like \"" + suggestedName + "\"."); } if (config instanceof route_config_impl_1.AuxRoute) { handler = new sync_route_handler_1.SyncRouteHandler(config.component, config.data); var routePath_1 = this._getRoutePath(config); var auxRule = new rules_1.RouteRule(routePath_1, handler, config.name); this.auxRulesByPath.set(routePath_1.toString(), auxRule); if (lang_1.isPresent(config.name)) { this.auxRulesByName.set(config.name, auxRule); } return auxRule.terminal; } var useAsDefault = false; if (config instanceof route_config_impl_1.Redirect) { var routePath_2 = this._getRoutePath(config); var redirector = new rules_1.RedirectRule(routePath_2, config.redirectTo); this._assertNoHashCollision(redirector.hash, config.path); this.rules.push(redirector); return true; } if (config instanceof route_config_impl_1.Route) { handler = new sync_route_handler_1.SyncRouteHandler(config.component, config.data); useAsDefault = lang_1.isPresent(config.useAsDefault) && config.useAsDefault; } else if (config instanceof route_config_impl_1.AsyncRoute) { handler = new async_route_handler_1.AsyncRouteHandler(config.loader, config.data); useAsDefault = lang_1.isPresent(config.useAsDefault) && config.useAsDefault; } var routePath = this._getRoutePath(config); var newRule = new rules_1.RouteRule(routePath, handler, config.name); this._assertNoHashCollision(newRule.hash, config.path); if (useAsDefault) { if (lang_1.isPresent(this.defaultRule)) { throw new exceptions_1.BaseException("Only one route can be default"); } this.defaultRule = newRule; } this.rules.push(newRule); if (lang_1.isPresent(config.name)) { this.rulesByName.set(config.name, newRule); } return newRule.terminal; }; /** * Given a URL, returns a list of `RouteMatch`es, which are partial recognitions for some route. */ RuleSet.prototype.recognize = function (urlParse) { var solutions = []; this.rules.forEach(function (routeRecognizer) { var pathMatch = routeRecognizer.recognize(urlParse); if (lang_1.isPresent(pathMatch)) { solutions.push(pathMatch); } }); // handle cases where we are routing just to an aux route if (solutions.length == 0 && lang_1.isPresent(urlParse) && urlParse.auxiliary.length > 0) { return [async_1.PromiseWrapper.resolve(new rules_1.PathMatch(null, null, urlParse.auxiliary))]; } return solutions; }; RuleSet.prototype.recognizeAuxiliary = function (urlParse) { var routeRecognizer = this.auxRulesByPath.get(urlParse.path); if (lang_1.isPresent(routeRecognizer)) { return [routeRecognizer.recognize(urlParse)]; } return [async_1.PromiseWrapper.resolve(null)]; }; RuleSet.prototype.hasRoute = function (name) { return this.rulesByName.has(name); }; RuleSet.prototype.componentLoaded = function (name) { return this.hasRoute(name) && lang_1.isPresent(this.rulesByName.get(name).handler.componentType); }; RuleSet.prototype.loadComponent = function (name) { return this.rulesByName.get(name).handler.resolveComponentType(); }; RuleSet.prototype.generate = function (name, params) { var rule = this.rulesByName.get(name); if (lang_1.isBlank(rule)) { return null; } return rule.generate(params); }; RuleSet.prototype.generateAuxiliary = function (name, params) { var rule = this.auxRulesByName.get(name); if (lang_1.isBlank(rule)) { return null; } return rule.generate(params); }; RuleSet.prototype._assertNoHashCollision = function (hash, path /** TODO #9100 */) { this.rules.forEach(function (rule) { if (hash == rule.hash) { throw new exceptions_1.BaseException("Configuration '" + path + "' conflicts with existing route '" + rule.path + "'"); } }); }; RuleSet.prototype._getRoutePath = function (config) { if (lang_1.isPresent(config.regex)) { if (lang_1.isFunction(config.serializer)) { return new regex_route_path_1.RegexRoutePath(config.regex, config.serializer, config.regex_group_names); } else { throw new exceptions_1.BaseException("Route provides a regex property, '" + config.regex + "', but no serializer property"); } } if (lang_1.isPresent(config.path)) { // Auxiliary routes do not have a slash at the start var path = (config instanceof route_config_impl_1.AuxRoute && config.path.startsWith('/')) ? config.path.substring(1) : config.path; return new param_route_path_1.ParamRoutePath(path); } throw new exceptions_1.BaseException('Route must provide either a path or regex property'); }; return RuleSet; }()); exports.RuleSet = RuleSet; //# sourceMappingURL=rule_set.js.map