Associate gutters with their elements and support showing/hiding gutters

This commit is contained in:
Nathan Sobo 2017-03-22 18:21:19 -06:00 committed by Antonio Scandurra
parent 16694a2166
commit d8b22fb3bd
5 changed files with 77 additions and 14 deletions

View File

@ -989,6 +989,41 @@ describe('TextEditorComponent', () => {
'a', 'b', 'c', 'line-number', 'd', 'e'
])
})
it('allows the element of custom gutters to be retrieved', async () => {
const {component, element, editor} = buildComponent()
const gutterA = editor.addGutter({name: 'a', priority: -1})
const gutterB = editor.addGutter({name: 'b', priority: 1})
await component.getNextUpdatePromise()
expect(element.contains(gutterA.element)).toBe(true)
expect(element.contains(gutterB.element)).toBe(true)
})
it('can show and hide custom gutters', async () => {
const {component, element, editor} = buildComponent()
const gutterA = editor.addGutter({name: 'a', priority: -1})
const gutterB = editor.addGutter({name: 'b', priority: 1})
await component.getNextUpdatePromise()
expect(gutterA.element.style.display).toBe('')
expect(gutterB.element.style.display).toBe('')
gutterA.hide()
await component.getNextUpdatePromise()
expect(gutterA.element.style.display).toBe('none')
expect(gutterB.element.style.display).toBe('')
gutterB.hide()
await component.getNextUpdatePromise()
expect(gutterA.element.style.display).toBe('none')
expect(gutterB.element.style.display).toBe('none')
gutterA.show()
await component.getNextUpdatePromise()
expect(gutterA.element.style.display).toBe('')
expect(gutterB.element.style.display).toBe('none')
})
})
describe('mouse input', () => {

View File

@ -8,6 +8,9 @@ class GutterContainer
@textEditor = textEditor
@emitter = new Emitter
scheduleComponentUpdate: ->
@textEditor.scheduleComponentUpdate()
destroy: ->
# Create a copy, because `Gutter::destroy` removes the gutter from
# GutterContainer's @gutters.

View File

@ -70,12 +70,14 @@ class Gutter
hide: ->
if @visible
@visible = false
@gutterContainer.scheduleComponentUpdate()
@emitter.emit 'did-change-visible', this
# Essential: Show the gutter.
show: ->
if not @visible
@visible = true
@gutterContainer.scheduleComponentUpdate()
@emitter.emit 'did-change-visible', this
# Essential: Determine whether the gutter is visible.

View File

@ -242,7 +242,11 @@ class TextEditorComponent {
if (gutter.name === 'line-number') {
return this.renderLineNumberGutter()
} else {
return this.renderCustomGutter(gutter.name)
return $(CustomGutterComponent, {
key: gutter,
gutter: gutter,
height: this.getScrollHeight()
})
}
})
} else {
@ -323,19 +327,6 @@ class TextEditorComponent {
}
}
renderCustomGutter (gutterName) {
return $.div(
{
className: 'gutter',
attributes: {'gutter-name': gutterName}
},
$.div({
className: 'custom-decorations',
style: {height: this.getScrollHeight() + 'px'}
})
)
}
renderScrollContainer () {
const style = {
position: 'absolute',
@ -2106,6 +2097,35 @@ class LineNumberGutterComponent {
}
}
class CustomGutterComponent {
constructor (props) {
this.props = props
etch.initialize(this)
this.props.gutter.element = this.element
}
update (props) {
this.props = props
etch.updateSync(this)
}
render () {
return $.div(
{
className: 'gutter',
attributes: {'gutter-name': this.props.gutter.name},
style: {
display: this.props.gutter.isVisible() ? '' : 'none'
}
},
$.div({
className: 'custom-decorations',
style: {height: this.props.height + 'px'}
})
)
}
}
class LinesTileComponent {
constructor (props) {
this.props = props

View File

@ -392,6 +392,9 @@ class TextEditor extends Model
else
Promise.resolve()
scheduleComponentUpdate: ->
@component?.scheduleUpdate()
serialize: ->
tokenizedBufferState = @tokenizedBuffer.serialize()