static IEnumerable GetItems(object node) { IEnumerable results = null; switch (node) { case IShellController shell: results = shell.GetItems(); break; case IShellItemController item: results = item.GetItems(); break; case IShellSectionController section: results = section.GetItems(); break; case ShellContent content: results = Array.Empty <object>(); break; case GlobalRouteItem routeItem: results = routeItem.Items; break; } if (results == null) { throw new ArgumentException($"{node}", nameof(node)); } foreach (var result in results) { yield return(result); } if (node is GlobalRouteItem) { yield break; } var keys = Routing.GetRouteKeys(); string route = GetRoute(node); foreach (var key in keys) { if (key.StartsWith(_pathSeparator, StringComparison.Ordinal) && !(node is Shell)) { continue; } var segments = RetrievePaths(key); if (segments[0] == route) { yield return(new GlobalRouteItem(key, key)); } } }
internal static List <RouteRequestBuilder> GenerateRoutePaths(Shell shell, Uri request, Uri originalRequest, bool enableRelativeShellRoutes) { var routeKeys = Routing.GetRouteKeys(); for (int i = 0; i < routeKeys.Length; i++) { routeKeys[i] = FormatUri(routeKeys[i]); } request = FormatUri(request, shell); originalRequest = FormatUri(originalRequest, shell); List <RouteRequestBuilder> possibleRoutePaths = new List <RouteRequestBuilder>(); if (!request.IsAbsoluteUri) { request = ConvertToStandardFormat(shell, request); } string localPath = request.LocalPath; bool relativeMatch = false; if (!originalRequest.IsAbsoluteUri && !originalRequest.OriginalString.StartsWith("//", StringComparison.Ordinal)) { relativeMatch = true; } var segments = RetrievePaths(localPath); var depthStart = 0; if (segments[0] == shell?.Route) { segments = segments.Skip(1).ToArray(); depthStart = 1; } else { depthStart = 0; } if (relativeMatch && shell?.CurrentItem != null) { var result = ProcessRelativeRoute(shell, routeKeys, segments, enableRelativeShellRoutes, originalRequest); if (result.Count > 0) { return(result); } } possibleRoutePaths.Clear(); SearchPath(shell, null, segments, possibleRoutePaths, depthStart); var bestMatches = GetBestMatches(possibleRoutePaths); if (bestMatches.Count > 0) { return(bestMatches); } bestMatches.Clear(); ExpandOutGlobalRoutes(possibleRoutePaths, routeKeys); foreach (var possibleRoutePath in possibleRoutePaths) { if (possibleRoutePath.IsFullMatch) { continue; } var url = possibleRoutePath.PathFull; var globalRouteMatches = SearchForGlobalRoutes( possibleRoutePath.RemainingSegments, new ShellNavigationState(url, false).FullLocation, possibleRoutePath.GetNodeLocation(), routeKeys); if (globalRouteMatches.Count != 1) { continue; } var globalRouteMatch = globalRouteMatches[0]; while (possibleRoutePath.NextSegment != null) { var matchIndex = globalRouteMatch.SegmentsMatched.IndexOf(possibleRoutePath.NextSegment); if (matchIndex < 0) { break; } possibleRoutePath.AddGlobalRoute( globalRouteMatch.GlobalRouteMatches[matchIndex], globalRouteMatch.SegmentsMatched[matchIndex]); } } possibleRoutePaths = GetBestMatches(possibleRoutePaths); if (possibleRoutePaths.Count == 0) { foreach (var routeKey in routeKeys) { if (routeKey == originalRequest.OriginalString) { var builder = new RouteRequestBuilder(routeKey, routeKey, null, new string[] { routeKey }); return(new List <RouteRequestBuilder> { builder }); } } if (!relativeMatch) { for (int i = 0; i < routeKeys.Length; i++) { var route = routeKeys[i]; var uri = ConvertToStandardFormat(shell, CreateUri(route)); if (uri.Equals(request)) { throw new Exception($"Global routes currently cannot be the only page on the stack, so absolute routing to global routes is not supported. For now, just navigate to: {originalRequest.OriginalString.Replace("//", "")}"); } } } } return(possibleRoutePaths); }