Code coverage report for src/navigation-plan.js

Statements: 80.52% (62 / 77)      Branches: 76.32% (29 / 38)      Functions: 77.78% (7 / 9)      Lines: 81.58% (62 / 76)      Ignored: none     

All files » src/ » navigation-plan.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 1571 1         1               10   9 9         1 10 10 10   10 1 1 1     1     9 8 8   8 7 7   7   7             7 2 5 1   4 1 3 2   1     7                                   8     1 1             1     1 8 8 8   8 5       5 1       7 7       7 3       4 3     1 1 1 1 1                         1 1 1   1         1 1    
import {Redirect} from './navigation-commands';
import {_resolveUrl} from './util';
 
/**
* The strategy to use when activating modules during navigation.
*/
export const activationStrategy = {
  noChange: 'no-change',
  invokeLifecycle: 'invoke-lifecycle',
  replace: 'replace'
};
 
export class BuildNavigationPlanStep {
  run(navigationInstruction: NavigationInstruction, next: Function) {
    return _buildNavigationPlan(navigationInstruction)
      .then(plan => {
        navigationInstruction.plan = plan;
        return next();
      }).catch(next.cancel);
  }
}
 
export function _buildNavigationPlan(instruction: NavigationInstruction, forceLifecycleMinimum): Promise<Object> {
  let prev = instruction.previousInstruction;
  let config = instruction.config;
  let plan = {};
 
  if ('redirect' in config) {
    let redirectLocation = _resolveUrl(config.redirect, getInstructionBaseUrl(instruction));
    Eif (instruction.queryString) {
      redirectLocation += '?' + instruction.queryString;
    }
 
    return Promise.reject(new Redirect(redirectLocation));
  }
 
  if (prev) {
    let newParams = hasDifferentParameterValues(prev, instruction);
    let pending = [];
 
    for (let viewPortName in prev.viewPortInstructions) {
      let prevViewPortInstruction = prev.viewPortInstructions[viewPortName];
      let nextViewPortConfig = config.viewPorts[viewPortName];
 
      Iif (!nextViewPortConfig) throw new Error(`Invalid Route Config: Configuration for viewPort "${viewPortName}" was not found for route: "${instruction.config.route}."`);
 
      let viewPortPlan = plan[viewPortName] = {
        name: viewPortName,
        config: nextViewPortConfig,
        prevComponent: prevViewPortInstruction.component,
        prevModuleId: prevViewPortInstruction.moduleId
      };
 
      if (prevViewPortInstruction.moduleId !== nextViewPortConfig.moduleId) {
        viewPortPlan.strategy = activationStrategy.replace;
      } else if ('determineActivationStrategy' in prevViewPortInstruction.component.viewModel) {
        viewPortPlan.strategy = prevViewPortInstruction.component.viewModel
          .determineActivationStrategy(...instruction.lifecycleArgs);
      } else if (config.activationStrategy) {
        viewPortPlan.strategy = config.activationStrategy;
      } else if (newParams || forceLifecycleMinimum) {
        viewPortPlan.strategy = activationStrategy.invokeLifecycle;
      } else {
        viewPortPlan.strategy = activationStrategy.noChange;
      }
 
      Iif (viewPortPlan.strategy !== activationStrategy.replace && prevViewPortInstruction.childRouter) {
        let path = instruction.getWildcardPath();
        let task = prevViewPortInstruction.childRouter
          ._createNavigationInstruction(path, instruction).then(childInstruction => { // eslint-disable-line no-loop-func
            viewPortPlan.childNavigationInstruction = childInstruction;
 
            return _buildNavigationPlan(
              childInstruction,
              viewPortPlan.strategy === activationStrategy.invokeLifecycle)
              .then(childPlan => {
                childInstruction.plan = childPlan;
              });
          });
 
        pending.push(task);
      }
    }
 
    return Promise.all(pending).then(() => plan);
  }
 
  for (let viewPortName in config.viewPorts) {
    plan[viewPortName] = {
      name: viewPortName,
      strategy: activationStrategy.replace,
      config: instruction.config.viewPorts[viewPortName]
    };
  }
 
  return Promise.resolve(plan);
}
 
function hasDifferentParameterValues(prev: NavigationInstruction, next: NavigationInstruction): boolean {
  let prevParams = prev.params;
  let nextParams = next.params;
  let nextWildCardName = next.config.hasChildRouter ? next.getWildCardName() : null;
 
  for (let key in nextParams) {
    Iif (key === nextWildCardName) {
      continue;
    }
 
    if (prevParams[key] !== nextParams[key]) {
      return true;
    }
  }
 
  for (let key in prevParams) {
    Iif (key === nextWildCardName) {
      continue;
    }
 
    if (prevParams[key] !== nextParams[key]) {
      return true;
    }
  }
 
  if (!next.options.compareQueryParams) {
    return false;
  }
 
  let prevQueryParams = prev.queryParams;
  let nextQueryParams = next.queryParams;
  for (let key in nextQueryParams) {
    Eif (prevQueryParams[key] !== nextQueryParams[key]) {
      return true;
    }
  }
 
  for (let key in prevQueryParams) {
    if (prevQueryParams[key] !== nextQueryParams[key]) {
      return true;
    }
  }
 
  return false;
}
 
function getInstructionBaseUrl(instruction: NavigationInstruction): string {
  let instructionBaseUrlParts = [];
  instruction = instruction.parentInstruction;
 
  while (instruction) {
    instructionBaseUrlParts.unshift(instruction.getBaseUrl());
    instruction = instruction.parentInstruction;
  }
 
  instructionBaseUrlParts.unshift('/');
  return instructionBaseUrlParts.join('');
}