Use presenter for rendering overlay decorations

We’re still doing some sync DOM reads and computation in the view that
should eventually be made async and moved into the presenter, but I’m
going to leave it alone for now.
This commit is contained in:
Nathan Sobo 2015-01-27 09:34:14 -07:00
parent e4c95d8ac3
commit 9d7285d04a

View File

@ -1,47 +1,42 @@
module.exports =
class OverlayManager
constructor: (@container) ->
@overlays = {}
@overlayNodesById = {}
render: (props) ->
{presenter, editor, overlayDecorations} = props
lineHeight = presenter.getLineHeight()
{presenter} = props
existingDecorations = null
for markerId, {headPixelPosition, tailPixelPosition, decorations} of overlayDecorations
for decoration in decorations
pixelPosition =
if decoration.position is 'tail' then tailPixelPosition else headPixelPosition
for decorationId, {pixelPosition, item} of presenter.state.content.overlays
@renderOverlay(presenter, decorationId, item, pixelPosition)
@renderOverlay(editor, decoration, pixelPosition, lineHeight)
existingDecorations ?= {}
existingDecorations[decoration.id] = true
for id, overlay of @overlays
unless existingDecorations? and id of existingDecorations
@container.removeChild(overlay)
delete @overlays[id]
for id, overlayNode of @overlayNodesById
unless presenter.state.content.overlays.hasOwnProperty(id)
overlayNode.remove()
delete @overlayNodesById[id]
return
renderOverlay: (editor, decoration, pixelPosition, lineHeight) ->
item = atom.views.getView(decoration.item)
unless overlay = @overlays[decoration.id]
overlay = @overlays[decoration.id] = document.createElement('atom-overlay')
overlay.appendChild(item)
@container.appendChild(overlay)
renderOverlay: (presenter, decorationId, item, pixelPosition) ->
item = atom.views.getView(item)
unless overlayNode = @overlayNodesById[decorationId]
overlayNode = @overlayNodesById[decorationId] = document.createElement('atom-overlay')
overlayNode.appendChild(item)
@container.appendChild(overlayNode)
itemWidth = item.offsetWidth
itemHeight = item.offsetHeight
{scrollTop} = presenter.state
{scrollLeft} = presenter.state.content
left = pixelPosition.left
if left + itemWidth - editor.getScrollLeft() > editor.getWidth() and left - itemWidth >= editor.getScrollLeft()
if left + itemWidth - scrollLeft > presenter.getClientWidth() and left - itemWidth >= scrollLeft
left -= itemWidth
top = pixelPosition.top + lineHeight
if top + itemHeight - editor.getScrollTop() > editor.getHeight() and top - itemHeight - lineHeight >= editor.getScrollTop()
top -= itemHeight + lineHeight
top = pixelPosition.top + presenter.getLineHeight()
if top + itemHeight - scrollTop > presenter.getClientHeight() and top - itemHeight - presenter.getLineHeight() >= scrollTop
top -= itemHeight + presenter.getLineHeight()
overlay.style.top = top + 'px'
overlay.style.left = left + 'px'
overlayNode.style.top = top + 'px'
overlayNode.style.left = left + 'px'