Merge pull request #15834 from atom/jr-decaf-gutter-container

Decaffeinate `GutterContainer`
This commit is contained in:
Jason Rudolph
2017-10-07 15:12:38 -04:00
committed by GitHub
4 changed files with 185 additions and 151 deletions

View File

@@ -1,87 +0,0 @@
{Emitter} = require 'event-kit'
Gutter = require './gutter'
module.exports =
class GutterContainer
constructor: (textEditor) ->
@gutters = []
@textEditor = textEditor
@emitter = new Emitter
scheduleComponentUpdate: ->
@textEditor.scheduleComponentUpdate()
destroy: ->
# Create a copy, because `Gutter::destroy` removes the gutter from
# GutterContainer's @gutters.
guttersToDestroy = @gutters.slice(0)
for gutter in guttersToDestroy
gutter.destroy() if gutter.name isnt 'line-number'
@gutters = []
@emitter.dispose()
addGutter: (options) ->
options = options ? {}
gutterName = options.name
if gutterName is null
throw new Error('A name is required to create a gutter.')
if @gutterWithName(gutterName)
throw new Error('Tried to create a gutter with a name that is already in use.')
newGutter = new Gutter(this, options)
inserted = false
# Insert the gutter into the gutters array, sorted in ascending order by 'priority'.
# This could be optimized, but there are unlikely to be many gutters.
for i in [0...@gutters.length]
if @gutters[i].priority >= newGutter.priority
@gutters.splice(i, 0, newGutter)
inserted = true
break
if not inserted
@gutters.push newGutter
@scheduleComponentUpdate()
@emitter.emit 'did-add-gutter', newGutter
return newGutter
getGutters: ->
@gutters.slice()
gutterWithName: (name) ->
for gutter in @gutters
if gutter.name is name then return gutter
null
observeGutters: (callback) ->
callback(gutter) for gutter in @getGutters()
@onDidAddGutter callback
onDidAddGutter: (callback) ->
@emitter.on 'did-add-gutter', callback
onDidRemoveGutter: (callback) ->
@emitter.on 'did-remove-gutter', callback
###
Section: Private Methods
###
# Processes the destruction of the gutter. Throws an error if this gutter is
# not within this gutterContainer.
removeGutter: (gutter) ->
index = @gutters.indexOf(gutter)
if index > -1
@gutters.splice(index, 1)
@scheduleComponentUpdate()
@emitter.emit 'did-remove-gutter', gutter.name
else
throw new Error 'The given gutter cannot be removed because it is not ' +
'within this GutterContainer.'
# The public interface is Gutter::decorateMarker or TextEditor::decorateMarker.
addGutterDecoration: (gutter, marker, options) ->
if gutter.name is 'line-number'
options.type = 'line-number'
else
options.type = 'gutter'
options.gutterName = gutter.name
@textEditor.decorateMarker(marker, options)

108
src/gutter-container.js Normal file
View File

@@ -0,0 +1,108 @@
const {Emitter} = require('event-kit')
const Gutter = require('./gutter')
module.exports = class GutterContainer {
constructor (textEditor) {
this.gutters = []
this.textEditor = textEditor
this.emitter = new Emitter()
}
scheduleComponentUpdate () {
this.textEditor.scheduleComponentUpdate()
}
destroy () {
// Create a copy, because `Gutter::destroy` removes the gutter from
// GutterContainer's @gutters.
const guttersToDestroy = this.gutters.slice(0)
for (let gutter of guttersToDestroy) {
if (gutter.name !== 'line-number') { gutter.destroy() }
}
this.gutters = []
this.emitter.dispose()
}
addGutter (options) {
options = options || {}
const gutterName = options.name
if (gutterName === null) {
throw new Error('A name is required to create a gutter.')
}
if (this.gutterWithName(gutterName)) {
throw new Error('Tried to create a gutter with a name that is already in use.')
}
const newGutter = new Gutter(this, options)
let inserted = false
// Insert the gutter into the gutters array, sorted in ascending order by 'priority'.
// This could be optimized, but there are unlikely to be many gutters.
for (let i = 0; i < this.gutters.length; i++) {
if (this.gutters[i].priority >= newGutter.priority) {
this.gutters.splice(i, 0, newGutter)
inserted = true
break
}
}
if (!inserted) {
this.gutters.push(newGutter)
}
this.scheduleComponentUpdate()
this.emitter.emit('did-add-gutter', newGutter)
return newGutter
}
getGutters () {
return this.gutters.slice()
}
gutterWithName (name) {
for (let gutter of this.gutters) {
if (gutter.name === name) { return gutter }
}
return null
}
observeGutters (callback) {
for (let gutter of this.getGutters()) { callback(gutter) }
return this.onDidAddGutter(callback)
}
onDidAddGutter (callback) {
return this.emitter.on('did-add-gutter', callback)
}
onDidRemoveGutter (callback) {
return this.emitter.on('did-remove-gutter', callback)
}
/*
Section: Private Methods
*/
// Processes the destruction of the gutter. Throws an error if this gutter is
// not within this gutterContainer.
removeGutter (gutter) {
const index = this.gutters.indexOf(gutter)
if (index > -1) {
this.gutters.splice(index, 1)
this.scheduleComponentUpdate()
this.emitter.emit('did-remove-gutter', gutter.name)
} else {
throw new Error('The given gutter cannot be removed because it is not ' +
'within this GutterContainer.'
)
}
}
// The public interface is Gutter::decorateMarker or TextEditor::decorateMarker.
addGutterDecoration (gutter, marker, options) {
if (gutter.name === 'line-number') {
options.type = 'line-number'
} else {
options.type = 'gutter'
}
options.gutterName = gutter.name
return this.textEditor.decorateMarker(marker, options)
}
}