From 9c6353977fa64dcd972dbd4bb080fbbd7ec9ea46 Mon Sep 17 00:00:00 2001 From: Ben Ogle Date: Mon, 7 Oct 2013 14:57:45 -0700 Subject: [PATCH] Rework the api using native methods. This is :racehorse: editor.300-line-file.gutter-api.getLineNumberElementsForClass.DOM: 3 / 20000 = 0.00015ms editor.300-line-file.gutter-api.getLineNumberElement.DOM: 8 / 20000 = 0.0004ms editor.300-line-file.gutter-api.toggle-class: 17 / 2000 = 0.0085ms editor.300-line-file.gutter-api.find-then-unset.single-class: 3 / 200 = 0.015ms editor.300-line-file.gutter-api.find-then-unset.multiple-class: 9 / 200 = 0.045ms --- spec/editor-spec.coffee | 18 +++++++++--------- src/gutter.coffee | 38 ++++++++++++++++++++++++++------------ 2 files changed, 35 insertions(+), 21 deletions(-) diff --git a/spec/editor-spec.coffee b/spec/editor-spec.coffee index 700a88e16..48de79f12 100644 --- a/spec/editor-spec.coffee +++ b/spec/editor-spec.coffee @@ -1894,24 +1894,24 @@ describe "Editor", -> it "can get a single line number element", -> element = editor.gutter.getLineNumberElement(3) - expect(element).toBeTruthy() - expect($(element)).toHaveClass('line-number') - expect($(element)).toHaveClass('line-number-3') it "returns falsy when there is no line element", -> - expect(editor.gutter.getLineNumberElement(42).length).toBeFalsy() + expect(editor.gutter.getLineNumberElement(42)).toHaveLength 0 it "can add and remove classes to all the line numbers", -> - elements = editor.gutter.addClassToAllLines('heyok') + wasAdded = editor.gutter.addClassToAllLines('heyok') + expect(wasAdded).toBe true + + elements = editor.gutter.getLineNumberElementsForClass('heyok') expect($(elements)).toHaveClass('heyok') - elements = editor.gutter.removeClassFromAllLines('heyok') - expect($(elements)).not.toHaveClass('heyok') + editor.gutter.removeClassFromAllLines('heyok') + expect($(editor.gutter.getLineNumberElements())).not.toHaveClass('heyok') it "can add and remove classes from a single line number", -> - element = editor.gutter.addClassToLine(3, 'heyok') - expect($(element)).toHaveClass('heyok') + wasAdded = editor.gutter.addClassToLine(3, 'heyok') + expect(wasAdded).toBe true element = editor.gutter.getLineNumberElement(2) expect($(element)).not.toHaveClass('heyok') diff --git a/src/gutter.coffee b/src/gutter.coffee index bca1db848..1e38daa7a 100644 --- a/src/gutter.coffee +++ b/src/gutter.coffee @@ -78,7 +78,8 @@ class Gutter extends View # # * bufferRow: 0 based line number # - # Returns a list of {HTMLElement}s that correspond to the bufferRow + # 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}") @@ -86,37 +87,50 @@ class Gutter extends View # # * klass: string class name # - # Returns a list of {HTMLElement}s. + # Returns true if the class was added to any lines addClassToAllLines: (klass)-> - $.fn.addClass.call(@getLineNumberElements(), 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 + # * klass: string class name. Can only be one class name. i.e. 'my-class' # - # Returns a list of {HTMLElement}s. + # Returns true if the class was removed from any lines removeClassFromAllLines: (klass)-> - $.fn.removeClass.call(@getLineNumberElements(), 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 the {HTMLElement} on which the class was set. undefined if the line was not found + # Returns true if there were lines the class was added to addClassToLine: (bufferRow, klass)-> - line = @getLineNumberElement(bufferRow) - $.fn.addClass.call(line, klass) if line and line.length + 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 the {HTMLElement} on which the class was set. undefined if the line was not found + # Returns true if there were lines the class was removed from removeClassFromLine: (bufferRow, klass)-> - line = @getLineNumberElement(bufferRow) - $.fn.removeClass.call(line, klass) if line and line.length + classesRemoved = false + elements = @getLineNumberElement(bufferRow) + for el in elements + hasClass = el.classList.contains(klass) + classesRemoved |= hasClass + el.classList.remove(klass) if hasClass + classesRemoved ### Internal ###