content.coffee 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165
  1. class app.views.Content extends app.View
  2. @el: '._content'
  3. @loadingClass: '_content-loading'
  4. @events:
  5. click: 'onClick'
  6. @shortcuts:
  7. altUp: 'scrollStepUp'
  8. altDown: 'scrollStepDown'
  9. pageUp: 'scrollPageUp'
  10. pageDown: 'scrollPageDown'
  11. home: 'scrollToTop'
  12. end: 'scrollToBottom'
  13. altF: 'onAltF'
  14. @routes:
  15. before: 'beforeRoute'
  16. after: 'afterRoute'
  17. init: ->
  18. @scrollEl = if app.isMobile() then document.body else @el
  19. @scrollMap = {}
  20. @scrollStack = []
  21. @rootPage = new app.views.RootPage
  22. @staticPage = new app.views.StaticPage
  23. @typePage = new app.views.TypePage
  24. @entryPage = new app.views.EntryPage
  25. @entryPage
  26. .on 'loading', @onEntryLoading
  27. .on 'loaded', @onEntryLoaded
  28. app
  29. .on 'ready', @onReady
  30. .on 'bootError', @onBootError
  31. return
  32. show: (view) ->
  33. unless view is @view
  34. @view?.deactivate()
  35. @html @view = view
  36. @view.activate()
  37. return
  38. showLoading: ->
  39. @addClass @constructor.loadingClass
  40. return
  41. hideLoading: ->
  42. @removeClass @constructor.loadingClass
  43. return
  44. scrollTo: (value) ->
  45. @scrollEl.scrollTop = value or 0
  46. return
  47. scrollBy: (n) ->
  48. @scrollEl.scrollTop += n
  49. return
  50. scrollToTop: =>
  51. @scrollTo 0
  52. return
  53. scrollToBottom: =>
  54. @scrollTo @scrollEl.scrollHeight
  55. return
  56. scrollStepUp: =>
  57. @scrollBy -50
  58. return
  59. scrollStepDown: =>
  60. @scrollBy 50
  61. return
  62. scrollPageUp: =>
  63. @scrollBy 80 - @scrollEl.clientHeight
  64. return
  65. scrollPageDown: =>
  66. @scrollBy @scrollEl.clientHeight - 80
  67. return
  68. scrollToTarget: ->
  69. if @routeCtx.hash and el = @findTargetByHash @routeCtx.hash
  70. $.scrollToWithImageLock el, @scrollEl, 'top',
  71. margin: 20 + if @scrollEl is @el then 0 else $.offset(@el).top
  72. $.highlight el, className: '_highlight'
  73. else
  74. @scrollTo @scrollMap[@routeCtx.state.id]
  75. return
  76. onReady: =>
  77. @hideLoading()
  78. return
  79. onBootError: =>
  80. @hideLoading()
  81. @html @tmpl('bootError')
  82. return
  83. onEntryLoading: =>
  84. @showLoading()
  85. return
  86. onEntryLoaded: =>
  87. @hideLoading()
  88. @scrollToTarget()
  89. return
  90. beforeRoute: (context) =>
  91. @cacheScrollPosition()
  92. @routeCtx = context
  93. @delay @scrollToTarget
  94. return
  95. cacheScrollPosition: ->
  96. return if not @routeCtx or @routeCtx.hash
  97. unless @scrollMap[@routeCtx.state.id]?
  98. @scrollStack.push @routeCtx.state.id
  99. while @scrollStack.length > app.config.history_cache_size
  100. delete @scrollMap[@scrollStack.shift()]
  101. @scrollMap[@routeCtx.state.id] = @scrollEl.scrollTop
  102. return
  103. afterRoute: (route, context) =>
  104. switch route
  105. when 'root'
  106. @show @rootPage
  107. when 'entry'
  108. @show @entryPage
  109. when 'type'
  110. @show @typePage
  111. else
  112. @show @staticPage
  113. @view.onRoute(context)
  114. app.document.setTitle @view.getTitle?()
  115. return
  116. onClick: (event) =>
  117. link = $.closestLink event.target, @el
  118. if link and @isExternalUrl link.getAttribute('href')
  119. $.stopEvent(event)
  120. $.popup(link)
  121. return
  122. onAltF: (event) =>
  123. unless document.activeElement and $.hasChild @el, document.activeElement
  124. @findByTag('a')?.focus()
  125. $.stopEvent(event)
  126. findTargetByHash: (hash) ->
  127. el = try $.id decodeURIComponent(hash) catch
  128. el or= try $.id(hash) catch
  129. el
  130. isExternalUrl: (url) ->
  131. url?[0..5] in ['http:/', 'https:']