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.
devdocs/assets/javascripts/views/content/content.coffee

185 lines
3.9 KiB

class app.views.Content extends app.View
@el: '._content'
@loadingClass: '_content-loading'
@events:
click: 'onClick'
@shortcuts:
altUp: 'scrollStepUp'
altDown: 'scrollStepDown'
pageUp: 'scrollPageUp'
pageDown: 'scrollPageDown'
pageTop: 'scrollToTop'
pageBottom: 'scrollToBottom'
altF: 'onAltF'
@routes:
before: 'beforeRoute'
after: 'afterRoute'
init: ->
@scrollEl = if app.isMobile() then document.body else @el
@scrollMap = {}
@scrollStack = []
@rootPage = new app.views.RootPage
@staticPage = new app.views.StaticPage
@settingsPage = new app.views.SettingsPage
@offlinePage = new app.views.OfflinePage
@typePage = new app.views.TypePage
@entryPage = new app.views.EntryPage
@entryPage
.on 'loading', @onEntryLoading
.on 'loaded', @onEntryLoaded
app
.on 'ready', @onReady
.on 'bootError', @onBootError
return
show: (view) ->
@hideLoading()
unless view is @view
@view?.deactivate()
@html @view = view
@view.activate()
return
showLoading: ->
@addClass @constructor.loadingClass
return
isLoading: ->
@el.classList.contains @constructor.loadingClass
hideLoading: ->
@removeClass @constructor.loadingClass
return
scrollTo: (value) ->
@scrollEl.scrollTop = value or 0
return
smoothScrollTo: (value) ->
if app.settings.get('fastScroll')
@scrollTo value
else
$.smoothScroll @scrollEl, value or 0
return
scrollBy: (n) ->
@smoothScrollTo @scrollEl.scrollTop + n
return
scrollToTop: =>
@smoothScrollTo 0
return
scrollToBottom: =>
@smoothScrollTo @scrollEl.scrollHeight
return
scrollStepUp: =>
@scrollBy -80
return
scrollStepDown: =>
@scrollBy 80
return
scrollPageUp: =>
@scrollBy 40 - @scrollEl.clientHeight
return
scrollPageDown: =>
@scrollBy @scrollEl.clientHeight - 40
return
scrollToTarget: ->
return if @isLoading()
if @routeCtx.hash and el = @findTargetByHash @routeCtx.hash
$.scrollToWithImageLock el, @scrollEl, 'top',
margin: if @scrollEl is @el then 0 else $.offset(@el).top
$.highlight el, className: '_highlight'
else
@scrollTo @scrollMap[@routeCtx.state.id]
clearTimeout @scrollTimeout
return
onReady: =>
@hideLoading()
return
onBootError: =>
@hideLoading()
@html @tmpl('bootError')
return
onEntryLoading: =>
@showLoading()
return
onEntryLoaded: =>
@hideLoading()
@scrollToTarget()
return
beforeRoute: (context) =>
@cacheScrollPosition()
@routeCtx = context
@scrollTimeout = @delay @scrollToTarget
return
cacheScrollPosition: ->
return if not @routeCtx or @routeCtx.hash
unless @scrollMap[@routeCtx.state.id]?
@scrollStack.push @routeCtx.state.id
while @scrollStack.length > app.config.history_cache_size
delete @scrollMap[@scrollStack.shift()]
@scrollMap[@routeCtx.state.id] = @scrollEl.scrollTop
return
afterRoute: (route, context) =>
switch route
when 'root'
@show @rootPage
when 'entry'
@show @entryPage
when 'type'
@show @typePage
when 'settings'
@show @settingsPage
when 'offline'
@show @offlinePage
else
@show @staticPage
@view.onRoute(context)
app.document.setTitle @view.getTitle?()
return
onClick: (event) =>
link = $.closestLink event.target, @el
if link and @isExternalUrl link.getAttribute('href')
$.stopEvent(event)
$.popup(link)
return
onAltF: (event) =>
unless document.activeElement and $.hasChild @el, document.activeElement
@find('a:not(:empty)')?.focus()
$.stopEvent(event)
findTargetByHash: (hash) ->
el = try $.id decodeURIComponent(hash) catch
el or= try $.id(hash) catch
el
isExternalUrl: (url) ->
url?[0..5] in ['http:/', 'https:']