LCOV - code coverage report
Current view: top level - src/root - parse_route.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 69 99 69.7 %
Date: 2020-07-01 03:00:01 Functions: 0 0 -

          Line data    Source code
       1             : import 'dart:collection';
       2             : 
       3             : import 'package:flutter/widgets.dart';
       4             : import 'package:get/src/routes/get_route.dart';
       5             : 
       6             : class GetPageMatch {
       7           1 :   GetPageMatch(this.route);
       8             : 
       9             :   GetPage route;
      10             :   Map<String, String> parameters = <String, String>{};
      11             : }
      12             : 
      13             : class ParseRouteTree {
      14             :   final List<ParseRouteTreeNode> _nodes = <ParseRouteTreeNode>[];
      15             :   // bool _hasDefaultRoute = false;
      16             : 
      17           1 :   void addRoute(GetPage route) {
      18           1 :     String path = route.name;
      19             : 
      20           1 :     if (path == Navigator.defaultRouteName) {
      21             :       // if (_hasDefaultRoute) {
      22             :       //   throw ("Default route was already defined");
      23             :       // }
      24           1 :       var node = ParseRouteTreeNode(path, ParseRouteTreeNodeType.component);
      25           3 :       node.routes = HashSet<GetPage>()..add(route);
      26           2 :       _nodes.add(node);
      27             :       // _hasDefaultRoute = true;
      28             :       return;
      29             :     }
      30           1 :     if (path.startsWith("/")) {
      31           1 :       path = path.substring(1);
      32             :     }
      33           1 :     List<String> pathComponents = path.split('/');
      34             :     ParseRouteTreeNode parent;
      35           3 :     for (int i = 0; i < pathComponents.length; i++) {
      36           1 :       String component = pathComponents[i];
      37           1 :       ParseRouteTreeNode node = _nodeForComponent(component, parent);
      38             :       if (node == null) {
      39           1 :         ParseRouteTreeNodeType type = _typeForComponent(component);
      40           1 :         node = ParseRouteTreeNode(component, type);
      41           1 :         node.parent = parent;
      42             :         if (parent == null) {
      43           2 :           _nodes.add(node);
      44             :         } else {
      45           0 :           parent.nodes.add(node);
      46             :         }
      47             :       }
      48           3 :       if (i == pathComponents.length - 1) {
      49           1 :         if (node.routes == null) {
      50           0 :           node.routes = HashSet<GetPage>()..add(route);
      51             :         } else {
      52           2 :           node.routes.add(route);
      53             :         }
      54             :       }
      55             :       parent = node;
      56             :     }
      57             :   }
      58             : 
      59           1 :   GetPageMatch matchRoute(String path) {
      60             :     String usePath = path;
      61           1 :     if (usePath.startsWith("/")) {
      62           1 :       usePath = path.substring(1);
      63             :     }
      64           1 :     List<String> components = usePath.split("/");
      65           1 :     if (path == Navigator.defaultRouteName) {
      66           1 :       components = ["/"];
      67             :     }
      68             : 
      69             :     Map<ParseRouteTreeNode, ParseRouteTreeNodeMatch> nodeMatches =
      70           1 :         <ParseRouteTreeNode, ParseRouteTreeNodeMatch>{};
      71           1 :     List<ParseRouteTreeNode> nodesToCheck = _nodes;
      72           2 :     for (String checkComponent in components) {
      73             :       Map<ParseRouteTreeNode, ParseRouteTreeNodeMatch> currentMatches =
      74           1 :           <ParseRouteTreeNode, ParseRouteTreeNodeMatch>{};
      75           1 :       List<ParseRouteTreeNode> nextNodes = <ParseRouteTreeNode>[];
      76           2 :       for (ParseRouteTreeNode node in nodesToCheck) {
      77             :         String pathPart = checkComponent;
      78           1 :         Map<String, String> queryMap = {};
      79             : 
      80           1 :         if (checkComponent.contains("?") && !checkComponent.contains("=")) {
      81           0 :           var splitParam = checkComponent.split("?");
      82           0 :           pathPart = splitParam[0];
      83           0 :           queryMap = {pathPart: splitParam[1]};
      84           1 :         } else if (checkComponent.contains("?")) {
      85           0 :           var splitParam = checkComponent.split("?");
      86           0 :           var splitParam2 = splitParam[1].split("=");
      87           0 :           if (!splitParam2[1].contains("&")) {
      88           0 :             pathPart = splitParam[0];
      89           0 :             queryMap = {splitParam2[0]: splitParam2[1]};
      90             :           } else {
      91           0 :             pathPart = splitParam[0];
      92           0 :             final segunda = splitParam[1];
      93           0 :             var other = segunda.split(RegExp(r"[&,=]"));
      94           0 :             for (var i = 0; i < (other.length - 1); i++) {
      95           0 :               bool impar = (i % 2 == 0);
      96             :               if (impar) {
      97           0 :                 queryMap.addAll({other[0 + i]: other[1 + i]});
      98             :               }
      99             :             }
     100             :           }
     101             :         }
     102             : 
     103           3 :         bool isMatch = (node.part == pathPart || node.isParameter());
     104             :         if (isMatch) {
     105           2 :           ParseRouteTreeNodeMatch parentMatch = nodeMatches[node.parent];
     106             :           ParseRouteTreeNodeMatch match =
     107           1 :               ParseRouteTreeNodeMatch.fromMatch(parentMatch, node);
     108           1 :           if (node.isParameter()) {
     109           0 :             String paramKey = node.part.substring(1);
     110           0 :             match.parameters[paramKey] = pathPart;
     111             :           }
     112             :           if (queryMap != null) {
     113           2 :             match.parameters.addAll(queryMap);
     114             :           }
     115             : 
     116           1 :           currentMatches[node] = match;
     117           1 :           if (node.nodes != null) {
     118           2 :             nextNodes.addAll(node.nodes);
     119             :           }
     120             :         }
     121             :       }
     122             :       nodeMatches = currentMatches;
     123             :       nodesToCheck = nextNodes;
     124           3 :       if (currentMatches.values.length == 0) {
     125             :         return null;
     126             :       }
     127             :     }
     128           2 :     List<ParseRouteTreeNodeMatch> matches = nodeMatches.values.toList();
     129           2 :     if (matches.length > 0) {
     130           1 :       ParseRouteTreeNodeMatch match = matches.first;
     131           1 :       ParseRouteTreeNode nodeToUse = match.node;
     132             : 
     133             :       if (nodeToUse != null &&
     134           1 :           nodeToUse.routes != null &&
     135           3 :           nodeToUse.routes.length > 0) {
     136           1 :         HashSet<GetPage> routes = nodeToUse.routes;
     137           2 :         GetPageMatch routeMatch = GetPageMatch(routes.first);
     138             : 
     139           2 :         routeMatch.parameters = match.parameters;
     140             : 
     141             :         return routeMatch;
     142             :       }
     143             :     }
     144             :     return null;
     145             :   }
     146             : 
     147           1 :   ParseRouteTreeNode _nodeForComponent(
     148             :       String component, ParseRouteTreeNode parent) {
     149           1 :     List<ParseRouteTreeNode> nodes = _nodes;
     150             :     if (parent != null) {
     151           0 :       nodes = parent.nodes;
     152             :     }
     153           2 :     for (ParseRouteTreeNode node in nodes) {
     154           2 :       if (node.part == component) {
     155             :         return node;
     156             :       }
     157             :     }
     158             :     return null;
     159             :   }
     160             : 
     161           1 :   ParseRouteTreeNodeType _typeForComponent(String component) {
     162             :     ParseRouteTreeNodeType type = ParseRouteTreeNodeType.component;
     163           1 :     if (_isParameterComponent(component)) {
     164             :       type = ParseRouteTreeNodeType.parameter;
     165             :     }
     166             :     return type;
     167             :   }
     168             : 
     169           1 :   bool _isParameterComponent(String component) {
     170           1 :     return component.startsWith(":");
     171             :   }
     172             : 
     173           0 :   Map<String, String> parseQueryString(String query) {
     174           0 :     var search = RegExp('([^&=]+)=?([^&]*)');
     175           0 :     var params = Map<String, String>();
     176           0 :     if (query.startsWith('?')) query = query.substring(1);
     177           0 :     decode(String s) => Uri.decodeComponent(s.replaceAll('+', ' '));
     178           0 :     for (Match match in search.allMatches(query)) {
     179           0 :       String key = decode(match.group(1));
     180           0 :       String value = decode(match.group(2));
     181           0 :       params[key] = value;
     182             :     }
     183             :     return params;
     184             :   }
     185             : }
     186             : 
     187             : class ParseRouteTreeNodeMatch {
     188           0 :   ParseRouteTreeNodeMatch(this.node);
     189             : 
     190           1 :   ParseRouteTreeNodeMatch.fromMatch(ParseRouteTreeNodeMatch match, this.node) {
     191           2 :     parameters = <String, String>{};
     192             :     if (match != null) {
     193           0 :       parameters.addAll(match.parameters);
     194             :     }
     195             :   }
     196             : 
     197             :   ParseRouteTreeNode node;
     198             :   Map<String, String> parameters = <String, String>{};
     199             : }
     200             : 
     201             : class ParseRouteTreeNode {
     202           1 :   ParseRouteTreeNode(this.part, this.type);
     203             : 
     204             :   String part;
     205             :   ParseRouteTreeNodeType type;
     206             :   HashSet<GetPage> routes = HashSet<GetPage>();
     207             :   List<ParseRouteTreeNode> nodes = <ParseRouteTreeNode>[];
     208             :   ParseRouteTreeNode parent;
     209             : 
     210           1 :   bool isParameter() {
     211           2 :     return type == ParseRouteTreeNodeType.parameter;
     212             :   }
     213             : }
     214             : 
     215          12 : enum ParseRouteTreeNodeType {
     216          12 :   component,
     217          12 :   parameter,
     218             : }

Generated by: LCOV version 1.14