Merge pull request #935 from atom/bo-improve-gutter-api

Add a simple gutter api for adding/removing classes
This commit is contained in:
Ben Ogle 2013-10-07 15:35:18 -07:00
commit 53da1db3d8
4 changed files with 152 additions and 4 deletions

View File

@ -123,6 +123,41 @@ describe "editor.", ->
div = document.createElement('div')
div.innerHTML = html
describe "gutter-api.", ->
describe "getLineNumberElementsForClass.", ->
beforeEach ->
editor.gutter.addClassToLine(20, 'omgwow')
editor.gutter.addClassToLine(40, 'omgwow')
benchmark "DOM", 20000, ->
editor.gutter.getLineNumberElementsForClass('omgwow')
benchmark "getLineNumberElement.DOM", 20000, ->
editor.gutter.getLineNumberElement(12)
benchmark "toggle-class", 2000, ->
editor.gutter.addClassToLine(40, 'omgwow')
editor.gutter.removeClassFromLine(40, 'omgwow')
describe "find-then-unset.", ->
classes = ['one', 'two', 'three', 'four']
benchmark "single-class", 200, ->
editor.gutter.addClassToLine(30, 'omgwow')
editor.gutter.addClassToLine(40, 'omgwow')
editor.gutter.removeClassFromAllLines('omgwow')
benchmark "multiple-class", 200, ->
editor.gutter.addClassToLine(30, 'one')
editor.gutter.addClassToLine(30, 'two')
editor.gutter.addClassToLine(40, 'two')
editor.gutter.addClassToLine(40, 'three')
editor.gutter.addClassToLine(40, 'four')
for klass in classes
editor.gutter.removeClassFromAllLines(klass)
describe "line-htmlification.", ->
div = null
html = null

View File

@ -46,7 +46,7 @@
"archive-view": "0.8.0",
"autocomplete": "0.6.0",
"autoflow": "0.3.0",
"bookmarks": "0.4.0",
"bookmarks": "0.5.0",
"bracket-matcher": "0.6.0",
"collaboration": "0.20.0",
"command-logger": "0.4.0",
@ -56,7 +56,7 @@
"find-and-replace": "0.24.0",
"fuzzy-finder": "0.7.0",
"gfm": "0.5.0",
"git-diff": "0.4.0",
"git-diff": "0.5.0",
"gists": "0.3.0",
"github-sign-in": "0.7.0",
"go-to-line": "0.4.0",

View File

@ -1886,6 +1886,49 @@ describe "Editor", ->
config.set("editor.showLineNumbers", false)
expect(editor.gutter.lineNumbers).not.toBeVisible()
describe "using gutter's api", ->
it "can get all the line number elements", ->
elements = editor.gutter.getLineNumberElements()
len = editor.gutter.lastScreenRow - editor.gutter.firstScreenRow + 1
expect(elements).toHaveLength(len)
it "can get a single line number element", ->
element = editor.gutter.getLineNumberElement(3)
expect(element).toBeTruthy()
it "returns falsy when there is no line element", ->
expect(editor.gutter.getLineNumberElement(42)).toHaveLength 0
it "can add and remove classes to all the line numbers", ->
wasAdded = editor.gutter.addClassToAllLines('heyok')
expect(wasAdded).toBe true
elements = editor.gutter.getLineNumberElementsForClass('heyok')
expect($(elements)).toHaveClass('heyok')
editor.gutter.removeClassFromAllLines('heyok')
expect($(editor.gutter.getLineNumberElements())).not.toHaveClass('heyok')
it "can add and remove classes from a single line number", ->
wasAdded = editor.gutter.addClassToLine(3, 'heyok')
expect(wasAdded).toBe true
element = editor.gutter.getLineNumberElement(2)
expect($(element)).not.toHaveClass('heyok')
it "can fetch line numbers by their class", ->
editor.gutter.addClassToLine(1, 'heyok')
editor.gutter.addClassToLine(3, 'heyok')
elements = editor.gutter.getLineNumberElementsForClass('heyok')
expect(elements.length).toBe 2
expect($(elements[0])).toHaveClass 'line-number-1'
expect($(elements[0])).toHaveClass 'heyok'
expect($(elements[1])).toHaveClass 'line-number-3'
expect($(elements[1])).toHaveClass 'heyok'
describe "gutter line highlighting", ->
beforeEach ->
editor.attachToDom(heightInLines: 5.5)

View File

@ -62,6 +62,76 @@ class Gutter extends View
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].childNodes
# 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
### Internal ###
updateLineNumbers: (changes, renderFrom, renderTo) ->
@ -96,12 +166,12 @@ class Gutter extends View
else
rowValue = (row + 1).toString()
classes = 'line-number'
classes = "line-number line-number-#{row}"
classes += ' fold' if editor.isFoldedAtBufferRow(row)
rowValuePadding = _.multiplyString(' ', maxDigits - rowValue.length)
html += """<div class="#{classes}" lineNumber="#{row}">#{rowValuePadding}#{rowValue}</div>"""
html += """<div class="#{classes}">#{rowValuePadding}#{rowValue}</div>"""
lastScreenRow = row