router.coffee 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137
  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. @context = context
  32. @trigger 'before', context
  33. next()
  34. return
  35. doc: (context, next) ->
  36. if doc = app.docs.findBySlug(context.params.doc) or app.disabledDocs.findBySlug(context.params.doc)
  37. context.doc = doc
  38. context.entry = doc.toEntry()
  39. @triggerRoute 'entry'
  40. else
  41. next()
  42. return
  43. type: (context, next) ->
  44. doc = app.docs.findBySlug(context.params.doc)
  45. if type = doc?.types.findBy 'slug', context.params.type
  46. context.doc = doc
  47. context.type = type
  48. @triggerRoute 'type'
  49. else
  50. next()
  51. return
  52. entry: (context, next) ->
  53. doc = app.docs.findBySlug(context.params.doc)
  54. if entry = doc?.findEntryByPathAndHash(context.params.path, context.hash)
  55. context.doc = doc
  56. context.entry = entry
  57. @triggerRoute 'entry'
  58. else
  59. next()
  60. return
  61. root: ->
  62. if app.isSingleDoc()
  63. setTimeout (-> window.location = '/'), 0
  64. else
  65. @triggerRoute 'root'
  66. return
  67. settings: ->
  68. @triggerRoute 'settings'
  69. return
  70. offline: ->
  71. @triggerRoute 'offline'
  72. return
  73. about: (context) ->
  74. context.page = 'about'
  75. @triggerRoute 'page'
  76. return
  77. news: (context) ->
  78. context.page = 'news'
  79. @triggerRoute 'page'
  80. return
  81. help: (context) ->
  82. context.page = 'help'
  83. @triggerRoute 'page'
  84. return
  85. notFound: (context) ->
  86. @triggerRoute 'notFound'
  87. return
  88. isRoot: ->
  89. location.pathname is '/'
  90. isDocIndex: ->
  91. @context and @context.doc and @context.entry is @context.doc.toEntry()
  92. setInitialPath: ->
  93. # Remove superfluous forward slashes at the beginning of the path
  94. if (path = location.pathname.replace /^\/{2,}/g, '/') isnt location.pathname
  95. page.replace path + location.search + location.hash, null, true
  96. if @isRoot()
  97. if path = @getInitialPathFromHash()
  98. page.replace path + location.search, null, true
  99. else if path = @getInitialPathFromCookie()
  100. page.replace path + location.search + location.hash, null, true
  101. return
  102. getInitialPathFromHash: ->
  103. try
  104. (new RegExp "#/(.+)").exec(decodeURIComponent location.hash)?[1]
  105. catch
  106. getInitialPathFromCookie: ->
  107. if path = Cookies.get('initial_path')
  108. Cookies.expire('initial_path')
  109. path
  110. replaceHash: (hash) ->
  111. page.replace location.pathname + location.search + (hash or ''), null, true
  112. return