Add Buffer.findMarker[s], which returns marker[s] matching attributes

This commit is contained in:
Nathan Sobo
2013-04-24 17:10:20 -06:00
parent df6feab346
commit 0f0480b79f
3 changed files with 45 additions and 3 deletions

View File

@@ -954,6 +954,18 @@ describe 'Buffer', ->
buffer.setMarkerHeadPosition(marker, [6, 2])
expect(observeHandler).not.toHaveBeenCalled()
describe ".findMarkers(attributes)", ->
[marker1, marker2, marker3, marker4] = []
beforeEach ->
marker1 = buffer.markRange([[0, 0], [3, 0]], class: 'a')
marker2 = buffer.markRange([[0, 0], [5, 0]], class: 'a')
marker3 = buffer.markRange([[6, 0], [7, 0]], class: 'a')
marker4 = buffer.markRange([[9, 0], [10, 0]], class: 'b')
it "returns the markers matching the given attributes, sorted by the buffer location and size of their ranges", ->
expect(buffer.findMarkers(class: 'a')).toEqual [marker2, marker1, marker3]
describe "marker destruction", ->
marker = null

View File

@@ -13,7 +13,7 @@ class BufferMarker
###
# Internal #
###
constructor: ({@id, @buffer, range, @invalidationStrategy, noTail, reverse}) ->
constructor: ({@id, @buffer, range, @invalidationStrategy, @attributes, noTail, reverse}) ->
@invalidationStrategy ?= 'contains'
@setRange(range, {noTail, reverse})
@@ -45,6 +45,14 @@ class BufferMarker
isReversed: ->
@tailPosition? and @headPosition.isLessThan(@tailPosition)
# Checks that the marker's attributes match the given attributes
#
# Returns a {Boolean}.
matchesAttributes: (queryAttributes) ->
for key, value of queryAttributes
return false unless _.isEqual(@attributes[key], value)
true
# Public: Identifies if the marker's head position is equal to its tail.
#
# Returns a {Boolean}.

View File

@@ -427,6 +427,19 @@ class Buffer
getMarkers: ->
_.values(@validMarkers)
# Public: Finds the first marker satisfying the given attributes
#
# Returns a {String} marker-identifier
findMarker: (attributes) ->
# Public: Finds all markers satisfying the given attributes
#
# Returns an {Array} of {String} marker-identifiers
findMarkers: (attributes) ->
markers = @getMarkers().filter (marker) -> marker.matchesAttributes(attributes)
markers.sort (a, b) -> a.getRange().compare(b.getRange())
_.pluck(markers, 'id')
# Public: Retrieves the quantity of markers in a buffer.
#
# Returns a {Number}.
@@ -436,14 +449,23 @@ class Buffer
# Public: Constructs a new marker at a given range.
#
# range - The marker {Range} (representing the distance between the head and tail)
# options - Options to pass to the {BufferMarker} constructor
# attributes - An optional hash of serializable attributes
# Any attributes you pass will be associated with the marker and can be retrieved
# or used in marker queries.
# The following attribute keys reserved, and control the marker's initial range
# reverse - if `true`, the marker is reversed; that is, its head precedes the tail
# noTail - if `true`, the marker is created without a tail
#
# Returns a {Number} representing the new marker's ID.
markRange: (range, options={}) ->
markRange: (range, attributes={}) ->
optionKeys = ['invalidationStrategy', 'noTail', 'reverse']
options = _.pick(attributes, optionKeys)
attributes = _.omit(attributes, optionKeys)
marker = new BufferMarker(_.defaults({
id: (@nextMarkerId++).toString()
buffer: this
range
attributes
}, options))
@validMarkers[marker.id] = marker
marker.id