/** * @license * Copyright Google Inc. All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ import { Observable } from 'rxjs/Observable'; import { of } from 'rxjs/observable/of'; import { ActivatedRouteSnapshot, RouterStateSnapshot, inheritedParamsDataResolve } from './router_state'; import { PRIMARY_OUTLET, defaultUrlMatcher } from './shared'; import { UrlSegmentGroup, mapChildrenIntoArray } from './url_tree'; import { forEach, last, merge } from './utils/collection'; import { TreeNode } from './utils/tree'; var NoMatch = (function () { function NoMatch() { } return NoMatch; }()); /** * @param {?} rootComponentType * @param {?} config * @param {?} urlTree * @param {?} url * @return {?} */ export function recognize(rootComponentType, config, urlTree, url) { return new Recognizer(rootComponentType, config, urlTree, url).recognize(); } var Recognizer = (function () { /** * @param {?} rootComponentType * @param {?} config * @param {?} urlTree * @param {?} url */ function Recognizer(rootComponentType, config, urlTree, url) { this.rootComponentType = rootComponentType; this.config = config; this.urlTree = urlTree; this.url = url; } /** * @return {?} */ Recognizer.prototype.recognize = function () { try { var /** @type {?} */ rootSegmentGroup = split(this.urlTree.root, [], [], this.config).segmentGroup; var /** @type {?} */ children = this.processSegmentGroup(this.config, rootSegmentGroup, PRIMARY_OUTLET); var /** @type {?} */ root = new ActivatedRouteSnapshot([], Object.freeze({}), Object.freeze(this.urlTree.queryParams), this.urlTree.fragment, {}, PRIMARY_OUTLET, this.rootComponentType, null, this.urlTree.root, -1, {}); var /** @type {?} */ rootNode = new TreeNode(root, children); var /** @type {?} */ routeState = new RouterStateSnapshot(this.url, rootNode); this.inheriteParamsAndData(routeState._root); return of(routeState); } catch (e) { return new Observable(function (obs) { return obs.error(e); }); } }; /** * @param {?} routeNode * @return {?} */ Recognizer.prototype.inheriteParamsAndData = function (routeNode) { var _this = this; var /** @type {?} */ route = routeNode.value; var /** @type {?} */ i = inheritedParamsDataResolve(route); route.params = Object.freeze(i.params); route.data = Object.freeze(i.data); routeNode.children.forEach(function (n) { return _this.inheriteParamsAndData(n); }); }; /** * @param {?} config * @param {?} segmentGroup * @param {?} outlet * @return {?} */ Recognizer.prototype.processSegmentGroup = function (config, segmentGroup, outlet) { if (segmentGroup.segments.length === 0 && segmentGroup.hasChildren()) { return this.processChildren(config, segmentGroup); } else { return this.processSegment(config, segmentGroup, segmentGroup.segments, outlet); } }; /** * @param {?} config * @param {?} segmentGroup * @return {?} */ Recognizer.prototype.processChildren = function (config, segmentGroup) { var _this = this; var /** @type {?} */ children = mapChildrenIntoArray(segmentGroup, function (child, childOutlet) { return _this.processSegmentGroup(config, child, childOutlet); }); checkOutletNameUniqueness(children); sortActivatedRouteSnapshots(children); return children; }; /** * @param {?} config * @param {?} segmentGroup * @param {?} segments * @param {?} outlet * @return {?} */ Recognizer.prototype.processSegment = function (config, segmentGroup, segments, outlet) { for (var _i = 0, config_1 = config; _i < config_1.length; _i++) { var r = config_1[_i]; try { return this.processSegmentAgainstRoute(r, segmentGroup, segments, outlet); } catch (e) { if (!(e instanceof NoMatch)) throw e; } } if (this.noLeftoversInUrl(segmentGroup, segments, outlet)) { return []; } else { throw new NoMatch(); } }; /** * @param {?} segmentGroup * @param {?} segments * @param {?} outlet * @return {?} */ Recognizer.prototype.noLeftoversInUrl = function (segmentGroup, segments, outlet) { return segments.length === 0 && !segmentGroup.children[outlet]; }; /** * @param {?} route * @param {?} rawSegment * @param {?} segments * @param {?} outlet * @return {?} */ Recognizer.prototype.processSegmentAgainstRoute = function (route, rawSegment, segments, outlet) { if (route.redirectTo) throw new NoMatch(); if ((route.outlet ? route.outlet : PRIMARY_OUTLET) !== outlet) throw new NoMatch(); if (route.path === '**') { var /** @type {?} */ params = segments.length > 0 ? last(segments).parameters : {}; var /** @type {?} */ snapshot_1 = new ActivatedRouteSnapshot(segments, params, Object.freeze(this.urlTree.queryParams), this.urlTree.fragment, getData(route), outlet, route.component, route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + segments.length, getResolve(route)); return [new TreeNode(snapshot_1, [])]; } var _a = match(rawSegment, route, segments), consumedSegments = _a.consumedSegments, parameters = _a.parameters, lastChild = _a.lastChild; var /** @type {?} */ rawSlicedSegments = segments.slice(lastChild); var /** @type {?} */ childConfig = getChildConfig(route); var _b = split(rawSegment, consumedSegments, rawSlicedSegments, childConfig), segmentGroup = _b.segmentGroup, slicedSegments = _b.slicedSegments; var /** @type {?} */ snapshot = new ActivatedRouteSnapshot(consumedSegments, parameters, Object.freeze(this.urlTree.queryParams), this.urlTree.fragment, getData(route), outlet, route.component, route, getSourceSegmentGroup(rawSegment), getPathIndexShift(rawSegment) + consumedSegments.length, getResolve(route)); if (slicedSegments.length === 0 && segmentGroup.hasChildren()) { var /** @type {?} */ children = this.processChildren(childConfig, segmentGroup); return [new TreeNode(snapshot, children)]; } else if (childConfig.length === 0 && slicedSegments.length === 0) { return [new TreeNode(snapshot, [])]; } else { var /** @type {?} */ children = this.processSegment(childConfig, segmentGroup, slicedSegments, PRIMARY_OUTLET); return [new TreeNode(snapshot, children)]; } }; return Recognizer; }()); function Recognizer_tsickle_Closure_declarations() { /** @type {?} */ Recognizer.prototype.rootComponentType; /** @type {?} */ Recognizer.prototype.config; /** @type {?} */ Recognizer.prototype.urlTree; /** @type {?} */ Recognizer.prototype.url; } /** * @param {?} nodes * @return {?} */ function sortActivatedRouteSnapshots(nodes) { nodes.sort(function (a, b) { if (a.value.outlet === PRIMARY_OUTLET) return -1; if (b.value.outlet === PRIMARY_OUTLET) return 1; return a.value.outlet.localeCompare(b.value.outlet); }); } /** * @param {?} route * @return {?} */ function getChildConfig(route) { if (route.children) { return route.children; } else if (route.loadChildren) { return ((route))._loadedConfig.routes; } else { return []; } } /** * @param {?} segmentGroup * @param {?} route * @param {?} segments * @return {?} */ function match(segmentGroup, route, segments) { if (route.path === '') { if (route.pathMatch === 'full' && (segmentGroup.hasChildren() || segments.length > 0)) { throw new NoMatch(); } else { return { consumedSegments: [], lastChild: 0, parameters: {} }; } } var /** @type {?} */ matcher = route.matcher || defaultUrlMatcher; var /** @type {?} */ res = matcher(segments, segmentGroup, route); if (!res) throw new NoMatch(); var /** @type {?} */ posParams = {}; forEach(res.posParams, function (v, k) { posParams[k] = v.path; }); var /** @type {?} */ parameters = merge(posParams, res.consumed[res.consumed.length - 1].parameters); return { consumedSegments: res.consumed, lastChild: res.consumed.length, parameters: parameters }; } /** * @param {?} nodes * @return {?} */ function checkOutletNameUniqueness(nodes) { var /** @type {?} */ names = {}; nodes.forEach(function (n) { var /** @type {?} */ routeWithSameOutletName = names[n.value.outlet]; if (routeWithSameOutletName) { var /** @type {?} */ p = routeWithSameOutletName.url.map(function (s) { return s.toString(); }).join('/'); var /** @type {?} */ c = n.value.url.map(function (s) { return s.toString(); }).join('/'); throw new Error("Two segments cannot have the same outlet name: '" + p + "' and '" + c + "'."); } names[n.value.outlet] = n.value; }); } /** * @param {?} segmentGroup * @return {?} */ function getSourceSegmentGroup(segmentGroup) { var /** @type {?} */ s = segmentGroup; while (s._sourceSegment) { s = s._sourceSegment; } return s; } /** * @param {?} segmentGroup * @return {?} */ function getPathIndexShift(segmentGroup) { var /** @type {?} */ s = segmentGroup; var /** @type {?} */ res = (s._segmentIndexShift ? s._segmentIndexShift : 0); while (s._sourceSegment) { s = s._sourceSegment; res += (s._segmentIndexShift ? s._segmentIndexShift : 0); } return res - 1; } /** * @param {?} segmentGroup * @param {?} consumedSegments * @param {?} slicedSegments * @param {?} config * @return {?} */ function split(segmentGroup, consumedSegments, slicedSegments, config) { if (slicedSegments.length > 0 && containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, config)) { var /** @type {?} */ s = new UrlSegmentGroup(consumedSegments, createChildrenForEmptyPaths(segmentGroup, consumedSegments, config, new UrlSegmentGroup(slicedSegments, segmentGroup.children))); s._sourceSegment = segmentGroup; s._segmentIndexShift = consumedSegments.length; return { segmentGroup: s, slicedSegments: [] }; } else if (slicedSegments.length === 0 && containsEmptyPathMatches(segmentGroup, slicedSegments, config)) { var /** @type {?} */ s = new UrlSegmentGroup(segmentGroup.segments, addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, config, segmentGroup.children)); s._sourceSegment = segmentGroup; s._segmentIndexShift = consumedSegments.length; return { segmentGroup: s, slicedSegments: slicedSegments }; } else { var /** @type {?} */ s = new UrlSegmentGroup(segmentGroup.segments, segmentGroup.children); s._sourceSegment = segmentGroup; s._segmentIndexShift = consumedSegments.length; return { segmentGroup: s, slicedSegments: slicedSegments }; } } /** * @param {?} segmentGroup * @param {?} slicedSegments * @param {?} routes * @param {?} children * @return {?} */ function addEmptyPathsToChildrenIfNeeded(segmentGroup, slicedSegments, routes, children) { var /** @type {?} */ res = {}; for (var _i = 0, routes_1 = routes; _i < routes_1.length; _i++) { var r = routes_1[_i]; if (emptyPathMatch(segmentGroup, slicedSegments, r) && !children[getOutlet(r)]) { var /** @type {?} */ s = new UrlSegmentGroup([], {}); s._sourceSegment = segmentGroup; s._segmentIndexShift = segmentGroup.segments.length; res[getOutlet(r)] = s; } } return merge(children, res); } /** * @param {?} segmentGroup * @param {?} consumedSegments * @param {?} routes * @param {?} primarySegment * @return {?} */ function createChildrenForEmptyPaths(segmentGroup, consumedSegments, routes, primarySegment) { var /** @type {?} */ res = {}; res[PRIMARY_OUTLET] = primarySegment; primarySegment._sourceSegment = segmentGroup; primarySegment._segmentIndexShift = consumedSegments.length; for (var _i = 0, routes_2 = routes; _i < routes_2.length; _i++) { var r = routes_2[_i]; if (r.path === '' && getOutlet(r) !== PRIMARY_OUTLET) { var /** @type {?} */ s = new UrlSegmentGroup([], {}); s._sourceSegment = segmentGroup; s._segmentIndexShift = consumedSegments.length; res[getOutlet(r)] = s; } } return res; } /** * @param {?} segmentGroup * @param {?} slicedSegments * @param {?} routes * @return {?} */ function containsEmptyPathMatchesWithNamedOutlets(segmentGroup, slicedSegments, routes) { return routes .filter(function (r) { return emptyPathMatch(segmentGroup, slicedSegments, r) && getOutlet(r) !== PRIMARY_OUTLET; }) .length > 0; } /** * @param {?} segmentGroup * @param {?} slicedSegments * @param {?} routes * @return {?} */ function containsEmptyPathMatches(segmentGroup, slicedSegments, routes) { return routes.filter(function (r) { return emptyPathMatch(segmentGroup, slicedSegments, r); }).length > 0; } /** * @param {?} segmentGroup * @param {?} slicedSegments * @param {?} r * @return {?} */ function emptyPathMatch(segmentGroup, slicedSegments, r) { if ((segmentGroup.hasChildren() || slicedSegments.length > 0) && r.pathMatch === 'full') return false; return r.path === '' && r.redirectTo === undefined; } /** * @param {?} route * @return {?} */ function getOutlet(route) { return route.outlet ? route.outlet : PRIMARY_OUTLET; } /** * @param {?} route * @return {?} */ function getData(route) { return route.data ? route.data : {}; } /** * @param {?} route * @return {?} */ function getResolve(route) { return route.resolve ? route.resolve : {}; } //# sourceMappingURL=recognize.js.map