Skip to content

Commit

Permalink
Implement minimap scroll indicator
Browse files Browse the repository at this point in the history
  • Loading branch information
abe33 committed Dec 16, 2014
1 parent cb3c9b0 commit 1128bb4
Show file tree
Hide file tree
Showing 3 changed files with 96 additions and 1 deletion.
28 changes: 28 additions & 0 deletions lib/minimap-element.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ class MinimapElement extends HTMLElement

@swapMinimapPosition() if swapPosition

@subscriptions.add atom.config.observe 'minimap.minimapScrollIndicator', (@minimapScrollIndicator) =>
if @minimapScrollIndicator and not @scrollIndicator?
@initializeScrollIndicator()
else if @scrollIndicator?
@disposeScrollIndicator()

attachedCallback: ->
@domPollingIntervalId = setInterval((=> @pollDOM()), @domPollingInterval)
@measureHeightAndWidth()
Expand Down Expand Up @@ -78,6 +84,15 @@ class MinimapElement extends HTMLElement
@visibleArea.classList.add('minimap-visible-area')
@shadowRoot.appendChild(@visibleArea)

initializeScrollIndicator: ->
@scrollIndicator = document.createElement('div')
@scrollIndicator.classList.add 'minimap-scroll-indicator'
@shadowRoot.appendChild(@scrollIndicator)

disposeScrollIndicator: ->
@shadowRoot.removeChild(@scrollIndicator)
@scrollIndicator = undefined

pauseDOMPolling: ->
@domPollingPaused = true
@resumeDOMPollingAfterDelay ?= debounce(@resumeDOMPolling, 100)
Expand Down Expand Up @@ -135,6 +150,19 @@ class MinimapElement extends HTMLElement

@canvas.style.top = (@minimap.getFirstVisibleScreenRow() * @minimap.getLineHeight() - @minimap.getMinimapScrollTop()) + 'px'

if @minimapScrollIndicator and @minimap.canScroll() and not @scrollIndicator
@initializeScrollIndicator()

if @scrollIndicator?
editorHeight = @getTextEditor().getHeight()
indicatorHeight = editorHeight * (editorHeight / @minimap.getHeight())
indicatorScroll = (editorHeight - indicatorHeight) * @minimap.getTextEditorScrollRatio()

@scrollIndicator.style.height = indicatorHeight + 'px'
@scrollIndicator.style.top = indicatorScroll + 'px'

@disposeScrollIndicator() if not @minimap.canScroll()

@updateCanvas()

# ######## ## ######## ## ## ######## ## ## ########
Expand Down
59 changes: 58 additions & 1 deletion spec/minimap-element-spec.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ stylesheetPath = path.resolve __dirname, '..', 'stylesheets', 'minimap.less'
stylesheet = atom.themes.loadStylesheet(stylesheetPath)

describe 'MinimapElement', ->
[editor, minimap, largeSample, smallSample, jasmineContent, editorElement, minimapElement] = []
[editor, minimap, largeSample, mediumSample, smallSample, jasmineContent, editorElement, minimapElement] = []

beforeEach ->
atom.config.set 'minimap.charHeight', 4
Expand All @@ -23,6 +23,7 @@ describe 'MinimapElement', ->

minimap = new Minimap({textEditor: editor})
largeSample = fs.readFileSync(atom.project.resolve('large-file.coffee')).toString()
mediumSample = fs.readFileSync(atom.project.resolve('two-hundred.txt')).toString()
smallSample = fs.readFileSync(atom.project.resolve('sample.coffee')).toString()

editor.setText largeSample
Expand Down Expand Up @@ -76,6 +77,10 @@ describe 'MinimapElement', ->
background: rgba(255,0,0,0.3);
}
atom-text-editor atom-text-editor-minimap::shadow .minimap-scroll-indicator, atom-text-editor::shadow atom-text-editor-minimap::shadow .minimap-scroll-indicator {
background: rgba(0,0,255,0.3);
}
atom-text-editor atom-text-editor-minimap::shadow .minimap-visible-area, atom-text-editor::shadow atom-text-editor-minimap::shadow .minimap-visible-area {
background: rgba(0,255,0,0.3);
}
Expand Down Expand Up @@ -223,3 +228,55 @@ describe 'MinimapElement', ->
it 'moves the attached minimap to the left', ->
expect(Array::indexOf.call(editorElement.shadowRoot.children, minimapElement)).toEqual(0)
nextAnimationFrame()

describe 'when minimap.minimapScrollIndicator setting is true', ->
beforeEach ->
editor.setText(mediumSample)
editor.setScrollTop(50)
nextAnimationFrame()

atom.config.set 'minimap.minimapScrollIndicator', true

it 'adds a scroll indicator in the element', ->
expect(minimapElement.shadowRoot.querySelector('.minimap-scroll-indicator')).toExist()

describe 'and then deactivated', ->
it 'removes the scroll indicator from the element', ->
atom.config.set 'minimap.minimapScrollIndicator', false
expect(minimapElement.shadowRoot.querySelector('.minimap-scroll-indicator')).not.toExist()

describe 'on update', ->
beforeEach ->
height = editor.getHeight()
editorElement.style.height = '500px'

waitsFor -> editor.getHeight() isnt height

runs ->
advanceClock(150)
nextAnimationFrame()

it 'adjusts the size and position of the indicator', ->
indicator = minimapElement.shadowRoot.querySelector('.minimap-scroll-indicator')

height = editor.getHeight() * (editor.getHeight() / minimap.getHeight())
scroll = (editor.getHeight() - height) * minimap.getTextEditorScrollRatio()

expect(indicator.offsetHeight).toBeCloseTo(height, 0)
expect(indicator.offsetTop).toBeCloseTo(scroll, 0)

describe 'when the minimap cannot scroll', ->
beforeEach ->
editor.setText(smallSample)
nextAnimationFrame()

it 'removes the scroll indicator', ->
expect(minimapElement.shadowRoot.querySelector('.minimap-scroll-indicator')).not.toExist()

describe 'and then can scroll again', ->
beforeEach ->
editor.setText(largeSample)
nextAnimationFrame()

it 'attaches the scroll indicator', ->
expect(minimapElement.shadowRoot.querySelector('.minimap-scroll-indicator')).toExist()
10 changes: 10 additions & 0 deletions stylesheets/minimap.less
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,16 @@ atom-text-editor::shadow, atom-text-editor {
position: absolute;
display: 'block';
}

.minimap-scroll-indicator {
position: absolute;
display: block;
right: 0;
width: 2px;
min-height: 2px;
z-index: 10;
background: @background-color-selected;
}
}
}
}
Expand Down

0 comments on commit 1128bb4

Please sign in to comment.