entry_page.coffee 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139
  1. class app.views.EntryPage extends app.View
  2. @className: '_page'
  3. @errorClass: '_page-error'
  4. @events:
  5. click: 'onClick'
  6. @routes:
  7. before: 'beforeRoute'
  8. init: ->
  9. @cacheMap = {}
  10. @cacheStack = []
  11. return
  12. deactivate: ->
  13. if super
  14. @empty()
  15. @entry = null
  16. return
  17. loading: ->
  18. @empty()
  19. @trigger 'loading'
  20. return
  21. render: (content = '', fromCache = false) ->
  22. return unless @activated
  23. @empty()
  24. @subview = new (@subViewClass()) @el, @entry
  25. $.batchUpdate @el, =>
  26. @subview.render(content, fromCache)
  27. @addClipboardLinks() unless fromCache
  28. return
  29. if app.disabledDocs.findBy 'slug', @entry.doc.slug
  30. @hiddenView = new app.views.HiddenPage @el, @entry
  31. @trigger 'loaded'
  32. return
  33. CLIPBOARD_LINK = '<a class="_pre-clip" title="Copy to clipboard"></a>'
  34. addClipboardLinks: ->
  35. for el in @findAllByTag('pre')
  36. el.insertAdjacentHTML('afterbegin', CLIPBOARD_LINK)
  37. return
  38. LINKS =
  39. home: 'Homepage'
  40. code: 'Source code'
  41. prepareContent: (content) ->
  42. return content unless @entry.isIndex() and @entry.doc.links
  43. links = for link, url of @entry.doc.links
  44. """<a href="#{url}" class="_links-link">#{LINKS[link]}</a>"""
  45. """<p class="_links">#{links.join('')}</p>#{content}"""
  46. empty: ->
  47. @subview?.deactivate()
  48. @subview = null
  49. @hiddenView?.deactivate()
  50. @hiddenView = null
  51. @resetClass()
  52. super
  53. return
  54. subViewClass: ->
  55. docType = @entry.doc.type
  56. app.views["#{docType[0].toUpperCase()}#{docType[1..]}Page"] or app.views.BasePage
  57. getTitle: ->
  58. @entry.doc.fullName + if @entry.isIndex() then ' documentation' else " / #{@entry.name}"
  59. beforeRoute: =>
  60. @abort()
  61. @cache()
  62. return
  63. onRoute: (context) ->
  64. isSameFile = context.entry.filePath() is @entry?.filePath()
  65. @entry = context.entry
  66. @restore() or @load() unless isSameFile
  67. return
  68. load: ->
  69. @loading()
  70. @xhr = @entry.loadFile @onSuccess, @onError
  71. return
  72. abort: ->
  73. if @xhr
  74. @xhr.abort()
  75. @xhr = null
  76. return
  77. onSuccess: (response) =>
  78. return unless @activated
  79. @xhr = null
  80. @render @prepareContent(response)
  81. return
  82. onError: =>
  83. @xhr = null
  84. @render @tmpl('pageLoadError')
  85. @addClass @constructor.errorClass
  86. app.appCache?.update()
  87. return
  88. cache: ->
  89. return if not @entry or @cacheMap[path = @entry.filePath()]
  90. @cacheMap[path] = @el.innerHTML
  91. @cacheStack.push(path)
  92. while @cacheStack.length > app.config.history_cache_size
  93. delete @cacheMap[@cacheStack.shift()]
  94. return
  95. restore: ->
  96. if @cacheMap[path = @entry.filePath()]
  97. @render @cacheMap[path], true
  98. true
  99. onClick: (event) =>
  100. target = event.target
  101. if target.hasAttribute 'data-retry'
  102. $.stopEvent(event)
  103. @load()
  104. else if target.classList.contains '_pre-clip'
  105. $.stopEvent(event)
  106. target.classList.add if $.copyToClipboard(target.parentNode.textContent) then '_pre-clip-success' else '_pre-clip-error'
  107. setTimeout (-> target.className = '_pre-clip'), 2000
  108. return