LCOV - code coverage report
Current view: top level - src/vroute_elements - vroute_element_base.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 36 38 94.7 %
Date: 2021-03-18 15:42:40 Functions: 0 0 -

          Line data    Source code
       1             : part of '../main.dart';
       2             : 
       3             : @immutable
       4             : abstract class VRouteElement {
       5             :   /// A list of stackedRoutes composed of any type of [VRouteElement]
       6             :   List<VRouteElement> get stackedRoutes;
       7             : 
       8             :   VRoute? buildRoute(
       9             :     VPathRequestData vPathRequestData, {
      10             :     required String? parentRemainingPath,
      11             :     required Map<String, String> parentPathParameters,
      12             :   });
      13             : 
      14             :   /// This function takes a name and tries to find the path corresponding to
      15             :   /// the route matching this name
      16             :   ///
      17             :   /// The deeper nested the route the better
      18             :   /// The given path parameters have to include at least every path parameters of the final path
      19           5 :   String? getPathFromName(
      20             :     String nameToMatch, {
      21             :     required Map<String, String> pathParameters,
      22             :     required String? parentPath,
      23             :     required Map<String, String> remainingPathParameters,
      24             :   }) {
      25             :     // Check if any subroute matches the name
      26          10 :     for (var vRouteElement in stackedRoutes) {
      27           5 :       String? childPathFromName = vRouteElement.getPathFromName(
      28             :         nameToMatch,
      29             :         pathParameters: pathParameters,
      30             :         parentPath: parentPath,
      31             :         remainingPathParameters: remainingPathParameters,
      32             :       );
      33             :       if (childPathFromName != null) {
      34             :         return childPathFromName;
      35             :       }
      36             :     }
      37             : 
      38             :     // Else we return null
      39             :     return null;
      40             :   }
      41             : 
      42             :   /// [GetPathFromPopResult.didPop] is true if this [VRouteElement] popped
      43             :   /// [GetPathFromPopResult.path] is null if this path can't be the right one according to
      44             :   ///                                                                     the path parameters
      45             :   /// [GetPathFromPopResult] is null when this [VRouteElement] does not pop AND none of
      46             :   ///                                                                     its stackedRoutes popped
      47          11 :   GetPathFromPopResult? getPathFromPop(
      48             :     VRouteElement elementToPop, {
      49             :     required Map<String, String> pathParameters,
      50             :     required String? parentPath,
      51             :   }) {
      52             :     // Try to pop from the stackedRoutes
      53          22 :     for (var vRouteElement in stackedRoutes) {
      54          11 :       final childPopResult = vRouteElement.getPathFromPop(
      55             :         elementToPop,
      56             :         pathParameters: pathParameters,
      57             :         parentPath: parentPath,
      58             :       );
      59             :       if (childPopResult != null) {
      60             :         return childPopResult;
      61             :       }
      62             :     }
      63             : 
      64             :     // If none of the stackedRoutes popped and this did not pop, return a null result
      65             :     return null;
      66             :   }
      67             : 
      68             :   /// This is called before the url is updated if this [VRouteElement] was NOT in the
      69             :   /// previous route but is in the new route
      70             :   ///
      71             :   /// Use [vRedirector] if you want to redirect or stop the navigation.
      72             :   /// DO NOT use VRouter methods to redirect.
      73             :   /// [vRedirector] also has information about the route you leave and the route you go to
      74             :   ///
      75             :   /// Note that you should consider the navigation cycle to
      76             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Navigation%20Control/The%20Navigation%20Cycle]
      77             :   ///
      78             :   /// Also see:
      79             :   ///   * [VRouter.beforeEnter] for router level beforeEnter
      80             :   ///   * [VRedirector] to known how to redirect and have access to route information
      81          11 :   Future<void> Function(VRedirector vRedirector) get beforeEnter =>
      82             :       _voidBeforeEnter;
      83             : 
      84             :   /// This is called before the url is updated if this [VRouteElement] was in the previous
      85             :   /// route and is in the new route
      86             :   ///
      87             :   /// Use [vRedirector] if you want to redirect or stop the navigation.
      88             :   /// DO NOT use VRouter methods to redirect.
      89             :   /// [vRedirector] also has information about the route you leave and the route you go to
      90             :   ///
      91             :   /// Note that you should consider the navigation cycle to
      92             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Navigation%20Control/The%20Navigation%20Cycle]
      93             :   ///
      94             :   /// Also see:
      95             :   ///   * [VNavigationGuard.beforeUpdate] for widget level beforeUpdate
      96             :   ///   * [VRedirector] to known how to redirect and have access to route information
      97          19 :   Future<void> Function(VRedirector vRedirector) get beforeUpdate =>
      98             :       _voidBeforeUpdate;
      99             : 
     100             :   /// Called when a url changes, before the url is updated
     101             :   /// Use [vRedirector] if you want to redirect or stop the navigation.
     102             :   /// DO NOT use VRouter methods to redirect.
     103             :   /// [vRedirector] also has information about the route you leave and the route you go to
     104             :   ///
     105             :   /// [saveHistoryState] can be used to save a history state before leaving
     106             :   /// This history state will be restored if the user uses the back button
     107             :   /// You will find the saved history state in the [VRouteElementData] using
     108             :   /// [VRouterData.of(context).historyState]
     109             :   ///
     110             :   /// Note that you should consider the navigation cycle to
     111             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Navigation%20Control/The%20Navigation%20Cycle]
     112             :   ///
     113             :   /// Also see:
     114             :   ///   * [VRouteElement.beforeLeave] for route level beforeLeave
     115             :   ///   * [VNavigationGuard.beforeLeave] for widget level beforeLeave
     116             :   ///   * [VRedirector] to known how to redirect and have access to route information
     117           8 :   Future<void> Function(
     118             :     VRedirector vRedirector,
     119             :     void Function(Map<String, String> state) saveHistoryState,
     120             :   ) get beforeLeave => _voidBeforeLeave;
     121             : 
     122             :   /// This is called after the url and the historyState are updated and this [VRouteElement]
     123             :   /// was NOT in the previous route and is in the new route
     124             :   /// You can't prevent the navigation anymore
     125             :   /// You can get the new route parameters, and queryParameters
     126             :   ///
     127             :   /// Note that you should consider the navigation cycle to
     128             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Navigation%20Control/The%20Navigation%20Cycle]
     129             :   ///
     130             :   /// Also see:
     131             :   ///   * [VRouter.afterEnter] for router level afterEnter
     132             :   ///   * [VNavigationGuard.afterEnter] for widget level afterEnter
     133          11 :   void Function(BuildContext context, String? from, String to) get afterEnter =>
     134             :       _voidAfterEnter;
     135             : 
     136             :   /// This is called after the url and the historyState are updated and this [VRouteElement]
     137             :   /// was in the previous route and is in the new route
     138             :   /// You can't prevent the navigation anymore
     139             :   /// You can get the new route parameters, and queryParameters
     140             :   ///
     141             :   /// Note that you should consider the navigation cycle to
     142             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Navigation%20Control/The%20Navigation%20Cycle]
     143             :   ///
     144             :   /// Also see:
     145             :   ///   * [VNavigationGuard.afterUpdate] for widget level afterUpdate
     146          19 :   void Function(BuildContext context, String? from, String to)
     147             :       get afterUpdate => _voidAfterUpdate;
     148             : 
     149             :   /// Called when a pop event occurs
     150             :   /// A pop event can be called programmatically (with [VRouterData.of(context).pop()])
     151             :   /// or by other widgets such as the appBar back button
     152             :   ///
     153             :   /// Use [vRedirector] if you want to redirect or stop the navigation.
     154             :   /// DO NOT use VRouter methods to redirect.
     155             :   /// [vRedirector] also has information about the route you leave and the route you go to
     156             :   ///
     157             :   /// The route you go to is calculated based on [VRouterState._defaultPop]
     158             :   ///
     159             :   /// Note that you should consider the pop cycle to
     160             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Pop%20Events/onPop]
     161             :   ///
     162             :   /// Also see:
     163             :   ///   * [VRouter.onPop] for router level onPop
     164             :   ///   * [VNavigationGuard.onPop] for widget level onPop
     165             :   ///   * [VRedirector] to known how to redirect and have access to route information
     166           7 :   Future<void> Function(VRedirector vRedirector) get onPop => _voidOnPop;
     167             : 
     168             :   /// Called when a system pop event occurs.
     169             :   /// This happens on android when the system back button is pressed.
     170             :   ///
     171             :   /// Use [vRedirector] if you want to redirect or stop the navigation.
     172             :   /// DO NOT use VRouter methods to redirect.
     173             :   /// [vRedirector] also has information about the route you leave and the route you go to
     174             :   ///
     175             :   /// The route you go to is calculated based on [VRouterState._defaultPop]
     176             :   ///
     177             :   /// Note that you should consider the systemPop cycle to
     178             :   /// handle this precisely, see [https://vrouter.dev/guide/Advanced/Pop%20Events/onSystemPop]
     179             :   ///
     180             :   /// Also see:
     181             :   ///   * [VRouter.onSystemPop] for route level onSystemPop
     182             :   ///   * [VNavigationGuard.onSystemPop] for widget level onSystemPop
     183             :   ///   * [VRedirector] to known how to redirect and have access to route information
     184           4 :   Future<void> Function(VRedirector vRedirector) get onSystemPop =>
     185             :       _voidOnSystemPop;
     186             : 
     187             :   /// Default function for [VRouteElement.beforeEnter]
     188             :   /// Basically does nothing
     189          10 :   static Future<void> _voidBeforeEnter(VRedirector vRedirector) async {}
     190             : 
     191             :   /// Default function for [VRouteElement.beforeUpdate]
     192             :   /// Basically does nothing
     193          10 :   static Future<void> _voidBeforeUpdate(VRedirector vRedirector) async {}
     194             : 
     195             :   /// Default function for [VRouteElement.beforeLeave]
     196             :   /// Basically does nothing
     197           9 :   static Future<void> _voidBeforeLeave(
     198             :     VRedirector? vRedirector,
     199             :     void Function(Map<String, String> state) saveHistoryState,
     200             :   ) async {}
     201             : 
     202             :   /// Default function for [VRouteElement.afterEnter]
     203             :   /// Basically does nothing
     204          10 :   static void _voidAfterEnter(BuildContext context, String? from, String to) {}
     205             : 
     206             :   /// Default function for [VRouteElement.afterUpdate]
     207             :   /// Basically does nothing
     208          10 :   static void _voidAfterUpdate(BuildContext context, String? from, String to) {}
     209             : 
     210             :   /// Default function for [VRouteElement.onPop]
     211             :   /// Basically does nothing
     212           7 :   static Future<void> _voidOnPop(VRedirector vRedirector) async {}
     213             : 
     214             :   /// Default function for [VRouteElement.pnSystemPop]
     215             :   /// Basically does nothing
     216           4 :   static Future<void> _voidOnSystemPop(VRedirector vRedirector) async {}
     217             : }
     218             : 
     219             : /// Return type of [VRouteElement.getPathFromPop]
     220             : ///
     221             : /// [didPop] should be true if this [VRouteElement] is to be popped
     222             : /// [path] should be deducted from the parent path, [VRouteElement.path] and the path parameters,
     223             : ///   Note the it should be null if the path can not be deduced from the said parameters
     224             : class GetPathFromPopResult {
     225             :   final String? path;
     226             :   final bool didPop;
     227             : 
     228           8 :   GetPathFromPopResult({
     229             :     required this.path,
     230             :     required this.didPop,
     231             :   });
     232             : }
     233             : 
     234             : /// Hold every information of the current route we are building
     235             : /// This is used is [VRouteElement.buildRoute] and should be passed down to the next
     236             : /// [VRouteElement.buildRoute] without modification.
     237             : ///
     238             : /// The is used for two purposes:
     239             : ///   1. Giving the needed information for [VRouteElement.buildRoute] to decide how/if it should
     240             : ///       build its route
     241             : ///   2. Holds information that are used to populate the [LocalVRouterData] attached to every
     242             : ///   _  [VRouteElement]
     243             : class VPathRequestData {
     244             :   final String? previousUrl;
     245             :   final Uri uri;
     246             :   final Map<String, String> historyState;
     247             :   final BuildContext rootVRouterContext;
     248             : 
     249          10 :   VPathRequestData({
     250             :     required this.previousUrl,
     251             :     required this.uri,
     252             :     required this.historyState,
     253             :     required this.rootVRouterContext,
     254             :   });
     255             : 
     256          30 :   String get path => uri.path;
     257             : 
     258          30 :   Map<String, String> get queryParameters => uri.queryParameters;
     259             : 
     260          30 :   String get url => uri.toString();
     261             : }
     262             : 
     263             : /// [VRouteElementNode] is used to represent the current route configuration as a tree
     264             : class VRouteElementNode {
     265             :   /// The [VRouteElementNode] containing the [VRouteElement] which is the current nested route
     266             :   /// to be valid, if any
     267             :   ///
     268             :   /// The is used be all types of [VNestedPage]
     269             :   final VRouteElementNode? nestedVRouteElementNode;
     270             : 
     271             :   /// The [VRouteElementNode] containing the [VRouteElement] which is the current stacked routes
     272             :   /// to be valid, if any
     273             :   final VRouteElementNode? stackedVRouteElementNode;
     274             : 
     275             :   /// The [VRouteElement] attached to this node
     276             :   final VRouteElement vRouteElement;
     277             : 
     278          10 :   VRouteElementNode(
     279             :     this.vRouteElement, {
     280             :     this.nestedVRouteElementNode,
     281             :     this.stackedVRouteElementNode,
     282             :   });
     283             : 
     284             :   /// Finding the element to pop for a [VRouteElementNode] means finding which one is at the
     285             :   /// end of the chain of stackedVRouteElementNode (if none then this should be popped)
     286           7 :   VRouteElement getVRouteElementToPop() {
     287           7 :     if (stackedVRouteElementNode != null) {
     288           8 :       return stackedVRouteElementNode!.getVRouteElementToPop();
     289             :     }
     290           7 :     return vRouteElement;
     291             :   }
     292             : 
     293             :   /// This function will search this node and the nested and sub nodes to try to find the node
     294             :   /// that hosts [vRouteElement]
     295           1 :   VRouteElementNode? getChildVRouteElementNode({
     296             :     required VRouteElement vRouteElement,
     297             :   }) {
     298             :     // If this VRouteElementNode contains the given VRouteElement, return this
     299           2 :     if (vRouteElement == this.vRouteElement) {
     300             :       return this;
     301             :     }
     302             : 
     303             :     // Search if the VRouteElementNode containing the VRouteElement is in the nestedVRouteElementNode
     304           1 :     if (nestedVRouteElementNode != null) {
     305           0 :       VRouteElementNode? vRouteElementNode = nestedVRouteElementNode!
     306           0 :           .getChildVRouteElementNode(vRouteElement: vRouteElement);
     307             :       if (vRouteElementNode != null) {
     308             :         return vRouteElementNode;
     309             :       }
     310             :     }
     311             : 
     312             :     // Search if the VRouteElementNode containing the VRouteElement is in the stackedVRouteElementNode
     313           1 :     if (stackedVRouteElementNode != null) {
     314           1 :       VRouteElementNode? vRouteElementNode = stackedVRouteElementNode!
     315           1 :           .getChildVRouteElementNode(vRouteElement: vRouteElement);
     316             :       if (vRouteElementNode != null) {
     317             :         return vRouteElementNode;
     318             :       }
     319             :     }
     320             : 
     321             :     // If the VRouteElement was not find anywhere, return null
     322             :     return null;
     323             :   }
     324             : }

Generated by: LCOV version 1.14