Ohm-Management - Projektarbeit B-ME
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

create-route-map.js 4.7KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171
  1. /* @flow */
  2. import Regexp from 'path-to-regexp'
  3. import { cleanPath } from './util/path'
  4. import { assert, warn } from './util/warn'
  5. export function createRouteMap (
  6. routes: Array<RouteConfig>,
  7. oldPathList?: Array<string>,
  8. oldPathMap?: Dictionary<RouteRecord>,
  9. oldNameMap?: Dictionary<RouteRecord>
  10. ): {
  11. pathList: Array<string>;
  12. pathMap: Dictionary<RouteRecord>;
  13. nameMap: Dictionary<RouteRecord>;
  14. } {
  15. // the path list is used to control path matching priority
  16. const pathList: Array<string> = oldPathList || []
  17. // $flow-disable-line
  18. const pathMap: Dictionary<RouteRecord> = oldPathMap || Object.create(null)
  19. // $flow-disable-line
  20. const nameMap: Dictionary<RouteRecord> = oldNameMap || Object.create(null)
  21. routes.forEach(route => {
  22. addRouteRecord(pathList, pathMap, nameMap, route)
  23. })
  24. // ensure wildcard routes are always at the end
  25. for (let i = 0, l = pathList.length; i < l; i++) {
  26. if (pathList[i] === '*') {
  27. pathList.push(pathList.splice(i, 1)[0])
  28. l--
  29. i--
  30. }
  31. }
  32. return {
  33. pathList,
  34. pathMap,
  35. nameMap
  36. }
  37. }
  38. function addRouteRecord (
  39. pathList: Array<string>,
  40. pathMap: Dictionary<RouteRecord>,
  41. nameMap: Dictionary<RouteRecord>,
  42. route: RouteConfig,
  43. parent?: RouteRecord,
  44. matchAs?: string
  45. ) {
  46. const { path, name } = route
  47. if (process.env.NODE_ENV !== 'production') {
  48. assert(path != null, `"path" is required in a route configuration.`)
  49. assert(
  50. typeof route.component !== 'string',
  51. `route config "component" for path: ${String(path || name)} cannot be a ` +
  52. `string id. Use an actual component instead.`
  53. )
  54. }
  55. const pathToRegexpOptions: PathToRegexpOptions = route.pathToRegexpOptions || {}
  56. const normalizedPath = normalizePath(
  57. path,
  58. parent,
  59. pathToRegexpOptions.strict
  60. )
  61. if (typeof route.caseSensitive === 'boolean') {
  62. pathToRegexpOptions.sensitive = route.caseSensitive
  63. }
  64. const record: RouteRecord = {
  65. path: normalizedPath,
  66. regex: compileRouteRegex(normalizedPath, pathToRegexpOptions),
  67. components: route.components || { default: route.component },
  68. instances: {},
  69. name,
  70. parent,
  71. matchAs,
  72. redirect: route.redirect,
  73. beforeEnter: route.beforeEnter,
  74. meta: route.meta || {},
  75. props: route.props == null
  76. ? {}
  77. : route.components
  78. ? route.props
  79. : { default: route.props }
  80. }
  81. if (route.children) {
  82. // Warn if route is named, does not redirect and has a default child route.
  83. // If users navigate to this route by name, the default child will
  84. // not be rendered (GH Issue #629)
  85. if (process.env.NODE_ENV !== 'production') {
  86. if (route.name && !route.redirect && route.children.some(child => /^\/?$/.test(child.path))) {
  87. warn(
  88. false,
  89. `Named Route '${route.name}' has a default child route. ` +
  90. `When navigating to this named route (:to="{name: '${route.name}'"), ` +
  91. `the default child route will not be rendered. Remove the name from ` +
  92. `this route and use the name of the default child route for named ` +
  93. `links instead.`
  94. )
  95. }
  96. }
  97. route.children.forEach(child => {
  98. const childMatchAs = matchAs
  99. ? cleanPath(`${matchAs}/${child.path}`)
  100. : undefined
  101. addRouteRecord(pathList, pathMap, nameMap, child, record, childMatchAs)
  102. })
  103. }
  104. if (route.alias !== undefined) {
  105. const aliases = Array.isArray(route.alias)
  106. ? route.alias
  107. : [route.alias]
  108. aliases.forEach(alias => {
  109. const aliasRoute = {
  110. path: alias,
  111. children: route.children
  112. }
  113. addRouteRecord(
  114. pathList,
  115. pathMap,
  116. nameMap,
  117. aliasRoute,
  118. parent,
  119. record.path || '/' // matchAs
  120. )
  121. })
  122. }
  123. if (!pathMap[record.path]) {
  124. pathList.push(record.path)
  125. pathMap[record.path] = record
  126. }
  127. if (name) {
  128. if (!nameMap[name]) {
  129. nameMap[name] = record
  130. } else if (process.env.NODE_ENV !== 'production' && !matchAs) {
  131. warn(
  132. false,
  133. `Duplicate named routes definition: ` +
  134. `{ name: "${name}", path: "${record.path}" }`
  135. )
  136. }
  137. }
  138. }
  139. function compileRouteRegex (path: string, pathToRegexpOptions: PathToRegexpOptions): RouteRegExp {
  140. const regex = Regexp(path, [], pathToRegexpOptions)
  141. if (process.env.NODE_ENV !== 'production') {
  142. const keys: any = Object.create(null)
  143. regex.keys.forEach(key => {
  144. warn(!keys[key.name], `Duplicate param keys in route with path: "${path}"`)
  145. keys[key.name] = true
  146. })
  147. }
  148. return regex
  149. }
  150. function normalizePath (path: string, parent?: RouteRecord, strict?: boolean): string {
  151. if (!strict) path = path.replace(/\/$/, '')
  152. if (path[0] === '/') return path
  153. if (parent == null) return path
  154. return cleanPath(`${parent.path}/${path}`)
  155. }