mirror of
https://github.com/pulsar-edit/pulsar.git
synced 2024-11-13 08:44:12 +03:00
Merge pull request #3388 from atom/bo-remove-all-old-editor
Remove ancillary old editor views
This commit is contained in:
commit
48f161b63a
@ -1,113 +0,0 @@
|
||||
{View} = require './space-pen-extensions'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
module.exports =
|
||||
class CursorView extends View
|
||||
@content: ->
|
||||
@div class: 'cursor idle', => @raw ' '
|
||||
|
||||
@blinkPeriod: 800
|
||||
|
||||
@blinkCursors: ->
|
||||
element.classList.toggle('blink-off') for [element] in @cursorViews
|
||||
|
||||
@startBlinking: (cursorView) ->
|
||||
@cursorViews ?= []
|
||||
@cursorViews.push(cursorView)
|
||||
if @cursorViews.length is 1
|
||||
@blinkInterval = setInterval(@blinkCursors.bind(this), @blinkPeriod / 2)
|
||||
|
||||
@stopBlinking: (cursorView) ->
|
||||
cursorView[0].classList.remove('blink-off')
|
||||
_.remove(@cursorViews, cursorView)
|
||||
clearInterval(@blinkInterval) if @cursorViews.length is 0
|
||||
|
||||
blinking: false
|
||||
visible: true
|
||||
needsUpdate: true
|
||||
needsRemoval: false
|
||||
shouldPauseBlinking: false
|
||||
|
||||
initialize: (@cursor, @editorView) ->
|
||||
@subscribe @cursor, 'moved', =>
|
||||
@needsUpdate = true
|
||||
@shouldPauseBlinking = true
|
||||
|
||||
@subscribe @cursor, 'visibility-changed', =>
|
||||
@needsUpdate = true
|
||||
|
||||
@subscribe @cursor, 'autoscrolled', =>
|
||||
@editorView.requestDisplayUpdate()
|
||||
|
||||
@subscribe @cursor, 'destroyed', =>
|
||||
@needsRemoval = true
|
||||
|
||||
beforeRemove: ->
|
||||
@editorView.removeCursorView(this)
|
||||
@stopBlinking()
|
||||
|
||||
updateDisplay: ->
|
||||
screenPosition = @getScreenPosition()
|
||||
pixelPosition = @getPixelPosition()
|
||||
|
||||
unless _.isEqual(@lastPixelPosition, pixelPosition)
|
||||
@lastPixelPosition = pixelPosition
|
||||
@css(pixelPosition)
|
||||
@trigger 'cursor:moved'
|
||||
|
||||
if @shouldPauseBlinking
|
||||
@resetBlinking()
|
||||
else if !@startBlinkingTimeout
|
||||
@startBlinking()
|
||||
|
||||
@setVisible(@cursor.isVisible() and not @editorView.getEditor().isFoldedAtScreenRow(screenPosition.row))
|
||||
|
||||
# Override for speed. The base function checks the computedStyle
|
||||
isHidden: ->
|
||||
this[0].style.display is 'none' or not @isOnDom()
|
||||
|
||||
needsAutoscroll: ->
|
||||
@cursor.needsAutoscroll
|
||||
|
||||
clearAutoscroll: ->
|
||||
@cursor.clearAutoscroll()
|
||||
|
||||
getPixelPosition: ->
|
||||
@editorView.pixelPositionForScreenPosition(@getScreenPosition())
|
||||
|
||||
setVisible: (visible) ->
|
||||
unless @visible is visible
|
||||
@visible = visible
|
||||
hiddenCursor = 'hidden-cursor'
|
||||
if visible
|
||||
@removeClass hiddenCursor
|
||||
else
|
||||
@addClass hiddenCursor
|
||||
|
||||
stopBlinking: ->
|
||||
@constructor.stopBlinking(this) if @blinking
|
||||
@blinking = false
|
||||
|
||||
startBlinking: ->
|
||||
@constructor.startBlinking(this) unless @blinking
|
||||
@blinking = true
|
||||
|
||||
resetBlinking: ->
|
||||
@stopBlinking()
|
||||
@startBlinking()
|
||||
|
||||
getBufferPosition: ->
|
||||
@cursor.getBufferPosition()
|
||||
|
||||
getScreenPosition: ->
|
||||
@cursor.getScreenPosition()
|
||||
|
||||
removeIdleClassTemporarily: ->
|
||||
@removeClass 'idle'
|
||||
window.clearTimeout(@idleTimeout) if @idleTimeout
|
||||
@idleTimeout = window.setTimeout (=> @addClass 'idle'), 200
|
||||
|
||||
resetCursorAnimation: ->
|
||||
window.clearTimeout(@idleTimeout) if @idleTimeout
|
||||
@removeClass 'idle'
|
||||
_.defer => @addClass 'idle'
|
@ -1,275 +0,0 @@
|
||||
{View, $, $$, $$$} = require './space-pen-extensions'
|
||||
{Range} = require 'text-buffer'
|
||||
_ = require 'underscore-plus'
|
||||
|
||||
# Represents the portion of the {EditorView} containing row numbers.
|
||||
#
|
||||
# The gutter also indicates if rows are folded.
|
||||
module.exports =
|
||||
class GutterView extends View
|
||||
@content: ->
|
||||
@div class: 'gutter', =>
|
||||
@div outlet: 'lineNumbers', class: 'line-numbers'
|
||||
|
||||
firstScreenRow: null
|
||||
lastScreenRow: null
|
||||
|
||||
initialize: ->
|
||||
@elementBuilder = document.createElement('div')
|
||||
|
||||
afterAttach: (onDom) ->
|
||||
return if @attached or not onDom
|
||||
@attached = true
|
||||
|
||||
highlightLines = => @highlightLines()
|
||||
@getEditorView().on 'cursor:moved', highlightLines
|
||||
@getEditorView().on 'selection:changed', highlightLines
|
||||
@on 'mousedown', (e) => @handleMouseEvents(e)
|
||||
|
||||
beforeRemove: ->
|
||||
$(document).off(".gutter-#{@getEditorView().id}")
|
||||
|
||||
handleMouseEvents: (e) ->
|
||||
editorView = @getEditorView()
|
||||
editor = @getEditor()
|
||||
startRow = editorView.screenPositionFromMouseEvent(e).row
|
||||
if e.shiftKey
|
||||
editor.selectToScreenPosition([startRow + 1, 0])
|
||||
return
|
||||
else
|
||||
editor.getSelection().setScreenRange([[startRow, 0], [startRow, 0]])
|
||||
|
||||
moveHandler = (e) ->
|
||||
start = startRow
|
||||
end = editorView.screenPositionFromMouseEvent(e).row
|
||||
if end > start then end++ else start++
|
||||
editor.getSelection().setScreenRange([[start, 0], [end, 0]])
|
||||
|
||||
$(document).on "mousemove.gutter-#{editorView.id}", moveHandler
|
||||
$(document).one "mouseup.gutter-#{editorView.id}", -> $(document).off 'mousemove', moveHandler
|
||||
|
||||
# Retrieves the containing {EditorView}.
|
||||
#
|
||||
# Returns an {EditorView}.
|
||||
getEditorView: ->
|
||||
@parentView
|
||||
|
||||
getEditor: ->
|
||||
@getEditorView().getEditor()
|
||||
|
||||
# Defines whether to show the gutter or not.
|
||||
#
|
||||
# showLineNumbers - A {Boolean} which, if `false`, hides the gutter
|
||||
setShowLineNumbers: (showLineNumbers) ->
|
||||
if showLineNumbers then @lineNumbers.show() else @lineNumbers.hide()
|
||||
|
||||
# Get all the line-number divs.
|
||||
#
|
||||
# Returns a list of {HTMLElement}s.
|
||||
getLineNumberElements: ->
|
||||
@lineNumbers[0].children
|
||||
|
||||
# Get all the line-number divs.
|
||||
#
|
||||
# Returns a list of {HTMLElement}s.
|
||||
getLineNumberElementsForClass: (klass) ->
|
||||
@lineNumbers[0].getElementsByClassName(klass)
|
||||
|
||||
# Get a single line-number div.
|
||||
#
|
||||
# * bufferRow: 0 based line number
|
||||
#
|
||||
# Returns a list of {HTMLElement}s that correspond to the bufferRow. More than
|
||||
# one in the list indicates a wrapped line.
|
||||
getLineNumberElement: (bufferRow) ->
|
||||
@getLineNumberElementsForClass("line-number-#{bufferRow}")
|
||||
|
||||
# Add a class to all line-number divs.
|
||||
#
|
||||
# * klass: string class name
|
||||
#
|
||||
# Returns true if the class was added to any lines
|
||||
addClassToAllLines: (klass) ->
|
||||
elements = @getLineNumberElements()
|
||||
el.classList.add(klass) for el in elements
|
||||
!!elements.length
|
||||
|
||||
# Remove a class from all line-number divs.
|
||||
#
|
||||
# * klass: string class name. Can only be one class name. i.e. 'my-class'
|
||||
#
|
||||
# Returns true if the class was removed from any lines
|
||||
removeClassFromAllLines: (klass) ->
|
||||
# This is faster than calling $.removeClass on all lines, and faster than
|
||||
# making a new array and iterating through it.
|
||||
elements = @getLineNumberElementsForClass(klass)
|
||||
willRemoveClasses = !!elements.length
|
||||
elements[0].classList.remove(klass) while elements.length > 0
|
||||
willRemoveClasses
|
||||
|
||||
# Add a class to a single line-number div
|
||||
#
|
||||
# * bufferRow: 0 based line number
|
||||
# * klass: string class name
|
||||
#
|
||||
# Returns true if there were lines the class was added to
|
||||
addClassToLine: (bufferRow, klass) ->
|
||||
elements = @getLineNumberElement(bufferRow)
|
||||
el.classList.add(klass) for el in elements
|
||||
!!elements.length
|
||||
|
||||
# Remove a class from a single line-number div
|
||||
#
|
||||
# * bufferRow: 0 based line number
|
||||
# * klass: string class name
|
||||
#
|
||||
# Returns true if there were lines the class was removed from
|
||||
removeClassFromLine: (bufferRow, klass) ->
|
||||
classesRemoved = false
|
||||
elements = @getLineNumberElement(bufferRow)
|
||||
for el in elements
|
||||
hasClass = el.classList.contains(klass)
|
||||
classesRemoved |= hasClass
|
||||
el.classList.remove(klass) if hasClass
|
||||
classesRemoved
|
||||
|
||||
updateLineNumbers: (changes, startScreenRow, endScreenRow) ->
|
||||
# Check if we have something already rendered that overlaps the requested range
|
||||
updateAllLines = not (startScreenRow? and endScreenRow?)
|
||||
updateAllLines |= endScreenRow <= @firstScreenRow or startScreenRow >= @lastScreenRow
|
||||
|
||||
unless updateAllLines
|
||||
for change in changes
|
||||
if change.screenDelta or change.bufferDelta
|
||||
updateAllLines = true
|
||||
break
|
||||
|
||||
# Rebuild the entire gutter if a change added or removed lines
|
||||
if updateAllLines
|
||||
@lineNumbers[0].innerHTML = @buildLineElementsHtml(startScreenRow, endScreenRow)
|
||||
|
||||
# Handle changes that didn't add/remove lines more optimally
|
||||
else
|
||||
if startScreenRow < @firstScreenRow
|
||||
@prependLineElements(@buildLineElements(startScreenRow, @firstScreenRow-1))
|
||||
else if startScreenRow != @firstScreenRow
|
||||
@removeLineElements(startScreenRow - @firstScreenRow)
|
||||
|
||||
if endScreenRow > @lastScreenRow
|
||||
@appendLineElements(@buildLineElements(@lastScreenRow+1, endScreenRow))
|
||||
else if endScreenRow != @lastScreenRow
|
||||
@removeLineElements(endScreenRow - @lastScreenRow)
|
||||
|
||||
@updateFoldableClasses(changes)
|
||||
|
||||
@firstScreenRow = startScreenRow
|
||||
@lastScreenRow = endScreenRow
|
||||
@highlightedRows = null
|
||||
@highlightLines()
|
||||
|
||||
prependLineElements: (lineElements) ->
|
||||
anchor = @lineNumbers[0].children[0]
|
||||
return appendLineElements(lineElements) unless anchor?
|
||||
@lineNumbers[0].insertBefore(lineElements[0], anchor) while lineElements.length > 0
|
||||
null # defeat coffeescript array return
|
||||
|
||||
appendLineElements: (lineElements) ->
|
||||
@lineNumbers[0].appendChild(lineElements[0]) while lineElements.length > 0
|
||||
null # defeat coffeescript array return
|
||||
|
||||
removeLineElements: (numberOfElements) ->
|
||||
children = @getLineNumberElements()
|
||||
|
||||
# children is a live NodeList, so remove from the desired end {numberOfElements} times
|
||||
if numberOfElements < 0
|
||||
@lineNumbers[0].removeChild(children[children.length-1]) while numberOfElements++
|
||||
else if numberOfElements > 0
|
||||
@lineNumbers[0].removeChild(children[0]) while numberOfElements--
|
||||
|
||||
null # defeat coffeescript array return
|
||||
|
||||
buildLineElements: (startScreenRow, endScreenRow) ->
|
||||
@elementBuilder.innerHTML = @buildLineElementsHtml(startScreenRow, endScreenRow)
|
||||
@elementBuilder.children
|
||||
|
||||
buildLineElementsHtml: (startScreenRow, endScreenRow) =>
|
||||
editor = @getEditor()
|
||||
maxDigits = editor.getLineCount().toString().length
|
||||
rows = editor.bufferRowsForScreenRows(startScreenRow, endScreenRow)
|
||||
|
||||
html = ''
|
||||
for row in rows
|
||||
if row is lastRow
|
||||
rowValue = '•'
|
||||
else
|
||||
rowValue = (row + 1).toString()
|
||||
|
||||
classes = "line-number line-number-#{row}"
|
||||
classes += ' foldable' if row isnt lastRow and editor.isFoldableAtBufferRow(row)
|
||||
classes += ' folded' if editor.isFoldedAtBufferRow(row)
|
||||
|
||||
rowValuePadding = _.multiplyString(' ', maxDigits - rowValue.length)
|
||||
|
||||
html += """<div class="#{classes}" data-buffer-row=#{row}>#{rowValuePadding}#{rowValue}<div class="icon-right"></div></div>"""
|
||||
|
||||
lastRow = row
|
||||
|
||||
html
|
||||
|
||||
# Called to update the 'foldable' class of line numbers when there's
|
||||
# a change to the display buffer that doesn't regenerate all the line numbers
|
||||
# anyway.
|
||||
updateFoldableClasses: (changes) ->
|
||||
editor = @getEditor()
|
||||
for {start, end} in changes when start <= @lastScreenRow and end >= @firstScreenRow
|
||||
startScreenRow = Math.max(start - 1, @firstScreenRow)
|
||||
endScreenRow = Math.min(end + 1, @lastScreenRow)
|
||||
lastBufferRow = null
|
||||
for bufferRow in editor.bufferRowsForScreenRows(startScreenRow, endScreenRow) when bufferRow isnt lastBufferRow
|
||||
lastBufferRow = bufferRow
|
||||
if lineNumberElement = @getLineNumberElement(bufferRow)[0]
|
||||
if editor.isFoldableAtBufferRow(bufferRow)
|
||||
lineNumberElement.classList.add('foldable')
|
||||
else
|
||||
lineNumberElement.classList.remove('foldable')
|
||||
|
||||
removeLineHighlights: ->
|
||||
return unless @highlightedLineNumbers
|
||||
for line in @highlightedLineNumbers
|
||||
line.classList.remove('cursor-line')
|
||||
line.classList.remove('cursor-line-no-selection')
|
||||
@highlightedLineNumbers = null
|
||||
|
||||
addLineHighlight: (row, emptySelection) ->
|
||||
return if row < @firstScreenRow or row > @lastScreenRow
|
||||
@highlightedLineNumbers ?= []
|
||||
if highlightedLineNumber = @lineNumbers[0].children[row - @firstScreenRow]
|
||||
highlightedLineNumber.classList.add('cursor-line')
|
||||
highlightedLineNumber.classList.add('cursor-line-no-selection') if emptySelection
|
||||
@highlightedLineNumbers.push(highlightedLineNumber)
|
||||
|
||||
highlightLines: ->
|
||||
editor = @getEditor()
|
||||
return unless editor?.isAlive()
|
||||
|
||||
if editor.getSelection().isEmpty()
|
||||
row = editor.getCursorScreenPosition().row
|
||||
rowRange = new Range([row, 0], [row, 0])
|
||||
return if @selectionEmpty and @highlightedRows?.isEqual(rowRange)
|
||||
|
||||
@removeLineHighlights()
|
||||
@addLineHighlight(row, true)
|
||||
@highlightedRows = rowRange
|
||||
@selectionEmpty = true
|
||||
else
|
||||
selectedRows = editor.getSelection().getScreenRange()
|
||||
endRow = selectedRows.end.row
|
||||
endRow-- if selectedRows.end.column is 0
|
||||
selectedRows = new Range([selectedRows.start.row, 0], [endRow, 0])
|
||||
return if not @selectionEmpty and @highlightedRows?.isEqual(selectedRows)
|
||||
|
||||
@removeLineHighlights()
|
||||
for row in [selectedRows.start.row..selectedRows.end.row]
|
||||
@addLineHighlight(row, false)
|
||||
@highlightedRows = selectedRows
|
||||
@selectionEmpty = false
|
@ -1,85 +0,0 @@
|
||||
{Point, Range} = require 'text-buffer'
|
||||
{View, $$} = require './space-pen-extensions'
|
||||
|
||||
module.exports =
|
||||
class SelectionView extends View
|
||||
|
||||
@content: ->
|
||||
@div class: 'selection'
|
||||
|
||||
regions: null
|
||||
needsRemoval: false
|
||||
|
||||
initialize: ({@editorView, @selection} = {}) ->
|
||||
@regions = []
|
||||
@selection.on 'screen-range-changed', => @editorView.requestDisplayUpdate()
|
||||
@selection.on 'destroyed', =>
|
||||
@needsRemoval = true
|
||||
@editorView.requestDisplayUpdate()
|
||||
|
||||
updateDisplay: ->
|
||||
@clearRegions()
|
||||
range = @getScreenRange()
|
||||
|
||||
@trigger 'selection:changed'
|
||||
@editorView.highlightFoldsContainingBufferRange(@getBufferRange())
|
||||
return if range.isEmpty()
|
||||
|
||||
rowSpan = range.end.row - range.start.row
|
||||
|
||||
if rowSpan == 0
|
||||
@appendRegion(1, range.start, range.end)
|
||||
else
|
||||
@appendRegion(1, range.start, null)
|
||||
if rowSpan > 1
|
||||
@appendRegion(rowSpan - 1, { row: range.start.row + 1, column: 0}, null)
|
||||
@appendRegion(1, { row: range.end.row, column: 0 }, range.end)
|
||||
|
||||
appendRegion: (rows, start, end) ->
|
||||
{ lineHeight, charWidth } = @editorView
|
||||
css = @editorView.pixelPositionForScreenPosition(start)
|
||||
css.height = lineHeight * rows
|
||||
if end
|
||||
css.width = @editorView.pixelPositionForScreenPosition(end).left - css.left
|
||||
else
|
||||
css.right = 0
|
||||
|
||||
region = ($$ -> @div class: 'region').css(css)
|
||||
@append(region)
|
||||
@regions.push(region)
|
||||
|
||||
getCenterPixelPosition: ->
|
||||
{ start, end } = @getScreenRange()
|
||||
startRow = start.row
|
||||
endRow = end.row
|
||||
endRow-- if end.column == 0
|
||||
@editorView.pixelPositionForScreenPosition([((startRow + endRow + 1) / 2), start.column])
|
||||
|
||||
clearRegions: ->
|
||||
region.remove() for region in @regions
|
||||
@regions = []
|
||||
|
||||
getScreenRange: ->
|
||||
@selection.getScreenRange()
|
||||
|
||||
getBufferRange: ->
|
||||
@selection.getBufferRange()
|
||||
|
||||
needsAutoscroll: ->
|
||||
@selection.needsAutoscroll
|
||||
|
||||
clearAutoscroll: ->
|
||||
@selection.clearAutoscroll()
|
||||
|
||||
highlight: ->
|
||||
@unhighlight()
|
||||
@addClass('highlighted')
|
||||
clearTimeout(@unhighlightTimeout)
|
||||
@unhighlightTimeout = setTimeout((=> @unhighlight()), 1000)
|
||||
|
||||
unhighlight: ->
|
||||
@removeClass('highlighted')
|
||||
|
||||
remove: ->
|
||||
@editorView.removeSelectionView(this)
|
||||
super
|
Loading…
Reference in New Issue
Block a user