mirror of
https://github.com/atom/atom.git
synced 2026-04-28 03:01:47 -04:00
By default overlays are positioned at the head of the given marker. This option allows them to be positioned at the tail instead by passing `position: ’tail’` when creating the decoration, which is useful for autocomplete.
47 lines
1.6 KiB
CoffeeScript
47 lines
1.6 KiB
CoffeeScript
module.exports =
|
|
class OverlayManager
|
|
constructor: (@container) ->
|
|
@overlays = {}
|
|
|
|
render: (props) ->
|
|
{editor, overlayDecorations, lineHeightInPixels} = props
|
|
|
|
existingDecorations = null
|
|
for markerId, {headPixelPosition, tailPixelPosition, decorations} of overlayDecorations
|
|
for decoration in decorations
|
|
pixelPosition =
|
|
if decoration.position is 'tail' then tailPixelPosition else headPixelPosition
|
|
|
|
@renderOverlay(editor, decoration, pixelPosition, lineHeightInPixels)
|
|
|
|
existingDecorations ?= {}
|
|
existingDecorations[decoration.id] = true
|
|
|
|
for id, overlay of @overlays
|
|
unless existingDecorations? and id of existingDecorations
|
|
@container.removeChild(overlay)
|
|
delete @overlays[id]
|
|
|
|
return
|
|
|
|
renderOverlay: (editor, decoration, pixelPosition, lineHeightInPixels) ->
|
|
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)
|
|
|
|
itemWidth = item.offsetWidth
|
|
itemHeight = item.offsetHeight
|
|
|
|
left = pixelPosition.left
|
|
if left + itemWidth - editor.getScrollLeft() > editor.getWidth() and left - itemWidth >= editor.getScrollLeft()
|
|
left -= itemWidth
|
|
|
|
top = pixelPosition.top + lineHeightInPixels
|
|
if top + itemHeight - editor.getScrollTop() > editor.getHeight() and top - itemHeight - lineHeightInPixels >= editor.getScrollTop()
|
|
top -= itemHeight + lineHeightInPixels
|
|
|
|
overlay.style.top = top + 'px'
|
|
overlay.style.left = left + 'px'
|