mirror of https://github.com/freeCodeCamp/devdocs
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.
161 lines
3.2 KiB
161 lines
3.2 KiB
class app.views.Sidebar extends app.View
|
|
@el: '._sidebar'
|
|
|
|
@events:
|
|
focus: 'onFocus'
|
|
select: 'onSelect'
|
|
click: 'onClick'
|
|
|
|
@routes:
|
|
after: 'afterRoute'
|
|
|
|
@shortcuts:
|
|
altR: 'onAltR'
|
|
escape: 'onEscape'
|
|
|
|
init: ->
|
|
@addSubview @hover = new app.views.SidebarHover @el unless app.isMobile()
|
|
@addSubview @search = new app.views.Search
|
|
|
|
@search
|
|
.on 'searching', @onSearching
|
|
.on 'clear', @onSearchClear
|
|
.scope
|
|
.on 'change', @onScopeChange
|
|
|
|
@results = new app.views.Results @, @search
|
|
@docList = new app.views.DocList
|
|
|
|
app.on 'ready', @onReady
|
|
|
|
$.on document.documentElement, 'mouseleave', (event) => @display() if event.clientX < 10
|
|
$.on document.documentElement, 'mouseenter', => @resetDisplay(forceNoHover: false)
|
|
return
|
|
|
|
display: ->
|
|
@addClass 'show'
|
|
return
|
|
|
|
resetDisplay: (options = {}) ->
|
|
return unless @hasClass 'show'
|
|
@removeClass 'show'
|
|
|
|
unless options.forceNoHover is false or @hasClass 'no-hover'
|
|
@addClass 'no-hover'
|
|
$.on window, 'mousemove', @resetHoverOnMouseMove
|
|
return
|
|
|
|
resetHoverOnMouseMove: =>
|
|
$.off window, 'mousemove', @resetHoverOnMouseMove
|
|
$.requestAnimationFrame @resetHover
|
|
|
|
resetHover: =>
|
|
@removeClass 'no-hover'
|
|
|
|
showView: (view) ->
|
|
unless @view is view
|
|
@hover?.hide()
|
|
@saveScrollPosition()
|
|
@view?.deactivate()
|
|
@view = view
|
|
@render()
|
|
@view.activate()
|
|
@restoreScrollPosition()
|
|
return
|
|
|
|
render: ->
|
|
@html @view
|
|
return
|
|
|
|
showDocList: ->
|
|
@showView @docList
|
|
return
|
|
|
|
showResults: =>
|
|
@display()
|
|
@showView @results
|
|
return
|
|
|
|
reset: ->
|
|
@display()
|
|
@showDocList()
|
|
@docList.reset()
|
|
@search.reset()
|
|
return
|
|
|
|
onReady: =>
|
|
@view = @docList
|
|
@render()
|
|
@view.activate()
|
|
return
|
|
|
|
onScopeChange: (newDoc, previousDoc) =>
|
|
@docList.closeDoc(previousDoc) if previousDoc
|
|
if newDoc then @docList.reveal(newDoc.toEntry()) else @scrollToTop()
|
|
return
|
|
|
|
saveScrollPosition: ->
|
|
if @view is @docList
|
|
@scrollTop = @el.scrollTop
|
|
return
|
|
|
|
restoreScrollPosition: ->
|
|
if @view is @docList and @scrollTop
|
|
@el.scrollTop = @scrollTop
|
|
@scrollTop = null
|
|
else
|
|
@scrollToTop()
|
|
return
|
|
|
|
scrollToTop: ->
|
|
@el.scrollTop = 0
|
|
return
|
|
|
|
onSearching: =>
|
|
@showResults()
|
|
return
|
|
|
|
onSearchClear: =>
|
|
@resetDisplay()
|
|
@showDocList()
|
|
return
|
|
|
|
onFocus: (event) =>
|
|
@display()
|
|
$.scrollTo event.target, @el, 'continuous', bottomGap: 2 unless event.target is @el
|
|
return
|
|
|
|
onSelect: =>
|
|
@resetDisplay()
|
|
return
|
|
|
|
onClick: (event) =>
|
|
return if event.which isnt 1
|
|
if $.eventTarget(event).hasAttribute? 'data-reset-list'
|
|
$.stopEvent(event)
|
|
@onAltR()
|
|
return
|
|
|
|
onAltR: =>
|
|
@reset()
|
|
@docList.reset(revealCurrent: true)
|
|
@display()
|
|
return
|
|
|
|
onEscape: =>
|
|
@reset()
|
|
@resetDisplay()
|
|
if doc = @search.getScopeDoc() then @docList.reveal(doc.toEntry()) else @scrollToTop()
|
|
return
|
|
|
|
onDocEnabled: ->
|
|
@docList.onEnabled()
|
|
@reset()
|
|
return
|
|
|
|
afterRoute: (name, context) =>
|
|
return if app.shortcuts.eventInProgress?.name is 'escape'
|
|
@reset() if not context.init and app.router.isIndex()
|
|
@resetDisplay()
|
|
return
|