router.coffee 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. class app.Router
  2. $.extend @prototype, Events
  3. @routes: [
  4. ['*', 'before' ]
  5. ['/', 'root' ]
  6. ['/about', 'about' ]
  7. ['/news', 'news' ]
  8. ['/help', 'help' ]
  9. ['/:doc-:type/', 'type' ]
  10. ['/:doc/', 'doc' ]
  11. ['/:doc/:path(*)', 'entry' ]
  12. ['*', 'notFound']
  13. ]
  14. constructor: ->
  15. for [path, method] in @constructor.routes
  16. page path, @[method].bind(@)
  17. @setInitialPath()
  18. start: ->
  19. page.start()
  20. return
  21. show: (path) ->
  22. page.show(path)
  23. return
  24. triggerRoute: (name) ->
  25. @trigger name, @context
  26. @trigger 'after', name, @context
  27. return
  28. before: (context, next) ->
  29. @context = context
  30. @trigger 'before', context
  31. next()
  32. return
  33. doc: (context, next) ->
  34. if doc = app.docs.findBy('slug', context.params.doc) or app.disabledDocs.findBy('slug', context.params.doc)
  35. context.doc = doc
  36. context.entry = doc.toEntry()
  37. @triggerRoute 'entry'
  38. else
  39. next()
  40. return
  41. type: (context, next) ->
  42. doc = app.docs.findBy 'slug', context.params.doc
  43. if type = doc?.types.findBy 'slug', context.params.type
  44. context.doc = doc
  45. context.type = type
  46. @triggerRoute 'type'
  47. else
  48. next()
  49. return
  50. entry: (context, next) ->
  51. doc = app.docs.findBy 'slug', context.params.doc
  52. if entry = doc?.findEntryByPathAndHash(context.params.path, context.hash)
  53. context.doc = doc
  54. context.entry = entry
  55. @triggerRoute 'entry'
  56. else
  57. next()
  58. return
  59. root: ->
  60. if app.isSingleDoc()
  61. setTimeout (-> window.location = '/'), 0
  62. else
  63. @triggerRoute 'root'
  64. return
  65. about: (context) ->
  66. context.page = 'about'
  67. @triggerRoute 'page'
  68. return
  69. news: (context) ->
  70. context.page = 'news'
  71. @triggerRoute 'page'
  72. return
  73. help: (context) ->
  74. context.page = 'help'
  75. @triggerRoute 'page'
  76. return
  77. notFound: (context) ->
  78. @triggerRoute 'notFound'
  79. return
  80. isRoot: ->
  81. location.pathname is '/'
  82. setInitialPath: ->
  83. # Remove superfluous forward slashes at the beginning of the path
  84. if (path = location.pathname.replace /^\/{2,}/g, '/') isnt location.pathname
  85. page.replace path + location.search + location.hash, null, true
  86. # When the path is "/#/path", replace it with "/path"
  87. if @isRoot() and path = @getInitialPath()
  88. page.replace path + location.search, null, true
  89. return
  90. getInitialPath: ->
  91. try
  92. (new RegExp "#/(.+)").exec(decodeURIComponent location.hash)?[1]
  93. catch
  94. replaceHash: (hash) ->
  95. page.replace location.pathname + location.search + (hash or ''), null, true
  96. return