router.js 3.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. class app.Router
  2. $.extend @prototype, Events
  3. @routes: [
  4. ['*', 'before' ]
  5. ['/', 'root' ]
  6. ['/settings', 'settings' ]
  7. ['/offline', 'offline' ]
  8. ['/about', 'about' ]
  9. ['/news', 'news' ]
  10. ['/help', 'help' ]
  11. ['/:doc-:type/', 'type' ]
  12. ['/:doc/', 'doc' ]
  13. ['/:doc/:path(*)', 'entry' ]
  14. ['*', 'notFound' ]
  15. ]
  16. constructor: ->
  17. for [path, method] in @constructor.routes
  18. page path, @[method].bind(@)
  19. @setInitialPath()
  20. start: ->
  21. page.start()
  22. return
  23. show: (path) ->
  24. page.show(path)
  25. return
  26. triggerRoute: (name) ->
  27. @trigger name, @context
  28. @trigger 'after', name, @context
  29. return
  30. before: (context, next) ->
  31. previousContext = @context
  32. @context = context
  33. @trigger 'before', context
  34. if res = next()
  35. @context = previousContext
  36. return res
  37. else
  38. return
  39. doc: (context, next) ->
  40. if doc = app.docs.findBySlug(context.params.doc) or app.disabledDocs.findBySlug(context.params.doc)
  41. context.doc = doc
  42. context.entry = doc.toEntry()
  43. @triggerRoute 'entry'
  44. return
  45. else
  46. return next()
  47. type: (context, next) ->
  48. doc = app.docs.findBySlug(context.params.doc)
  49. if type = doc?.types.findBy 'slug', context.params.type
  50. context.doc = doc
  51. context.type = type
  52. @triggerRoute 'type'
  53. return
  54. else
  55. return next()
  56. entry: (context, next) ->
  57. doc = app.docs.findBySlug(context.params.doc)
  58. return next() unless doc
  59. path = context.params.path
  60. hash = context.hash
  61. if entry = doc.findEntryByPathAndHash(path, hash)
  62. context.doc = doc
  63. context.entry = entry
  64. @triggerRoute 'entry'
  65. return
  66. else if path.slice(-6) is '/index'
  67. path = path.substr(0, path.length - 6)
  68. return entry.fullPath() if entry = doc.findEntryByPathAndHash(path, hash)
  69. else
  70. path = "#{path}/index"
  71. return entry.fullPath() if entry = doc.findEntryByPathAndHash(path, hash)
  72. return next()
  73. root: ->
  74. return '/' if app.isSingleDoc()
  75. @triggerRoute 'root'
  76. return
  77. settings: (context) ->
  78. return "/#/#{context.path}" if app.isSingleDoc()
  79. @triggerRoute 'settings'
  80. return
  81. offline: (context)->
  82. return "/#/#{context.path}" if app.isSingleDoc()
  83. @triggerRoute 'offline'
  84. return
  85. about: (context) ->
  86. return "/#/#{context.path}" if app.isSingleDoc()
  87. context.page = 'about'
  88. @triggerRoute 'page'
  89. return
  90. news: (context) ->
  91. return "/#/#{context.path}" if app.isSingleDoc()
  92. context.page = 'news'
  93. @triggerRoute 'page'
  94. return
  95. help: (context) ->
  96. return "/#/#{context.path}" if app.isSingleDoc()
  97. context.page = 'help'
  98. @triggerRoute 'page'
  99. return
  100. notFound: (context) ->
  101. @triggerRoute 'notFound'
  102. return
  103. isIndex: ->
  104. @context?.path is '/' or (app.isSingleDoc() and @context?.entry?.isIndex())
  105. isSettings: ->
  106. @context?.path is '/settings'
  107. setInitialPath: ->
  108. # Remove superfluous forward slashes at the beginning of the path
  109. if (path = location.pathname.replace /^\/{2,}/g, '/') isnt location.pathname
  110. page.replace path + location.search + location.hash, null, true
  111. if location.pathname is '/'
  112. if path = @getInitialPathFromHash()
  113. page.replace path + location.search, null, true
  114. else if path = @getInitialPathFromCookie()
  115. page.replace path + location.search + location.hash, null, true
  116. return
  117. getInitialPathFromHash: ->
  118. try
  119. (new RegExp "#/(.+)").exec(decodeURIComponent location.hash)?[1]
  120. catch
  121. getInitialPathFromCookie: ->
  122. if path = Cookies.get('initial_path')
  123. Cookies.expire('initial_path')
  124. path
  125. replaceHash: (hash) ->
  126. page.replace location.pathname + location.search + (hash or ''), null, true
  127. return