Преглед изворни кода

HighlightedWordManager is more naive about tracking position

We are relying entirely on Ace's tracking of markers with the anchor trick.
This means that we don't have to apply changes to ensure that the word manager
data structure tracks which row the highlights are on. This is traded off
against slightly less efficient searching/removing
Alasdair Smith пре 8 година
родитељ
комит
9fa85400b3

+ 27 - 32
services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/HighlightedWordManager.coffee

@@ -4,9 +4,7 @@ define [
 	Range = ace.require("ace/range").Range
 
 	class Highlight
-		constructor: (options) ->
-			@row = options.row
-			@column = options.column
+		constructor: (@markerId, @range, options) ->
 			@word = options.word
 			@suggestions = options.suggestions
 
@@ -15,56 +13,53 @@ define [
 			@reset()
 
 		reset: () ->
-			@highlights?.rows.forEach (highlight) =>
+			@highlights?.forEach (highlight) =>
 				@editor.getSession().removeMarker(highlight.markerId)
-			@highlights = rows: []
-
-		addHighlight: (highlight) ->
-			unless highlight instanceof Highlight
-				highlight = new Highlight(highlight)
+			@highlights = []
 
+		addHighlight: (options) ->
 			session = @editor.getSession()
 			doc = session.getDocument()
 			# Set up Range that will automatically update it's positions when the
 			# document changes
 			range = new Range()
 			range.start = doc.createAnchor({
-				row: highlight.row,
-				column: highlight.column
+				row: options.row,
+				column: options.column
 			})
 			range.end = doc.createAnchor({
-				row: highlight.row,
-				column: highlight.column + highlight.word.length
+				row: options.row,
+				column: options.column + options.word.length
 			})
 
-			highlight.markerId = session.addMarker range, "spelling-highlight", 'text', false
-			@highlights.rows[highlight.row] ||= []
-			@highlights.rows[highlight.row].push highlight
+			markerId = session.addMarker range, "spelling-highlight", 'text', false
+
+			@highlights.push new Highlight(markerId, range, options)
 
 		removeHighlight: (highlight) ->
 			@editor.getSession().removeMarker(highlight.markerId)
-			for h, i in @highlights.rows[highlight.row]
-				if h == highlight
-					@highlights.rows[highlight.row].splice(i, 1)
+			@highlights = @highlights.filter (hl) ->
+				hl != highlight
 
 		clearRow: (row) ->
-			row = @highlights.rows[row]
-			for highlight in (row || []).slice()
-				@removeHighlight highlight
+			@highlights.filter (highlight) ->
+				highlight.range.start.row == row
+			.forEach (highlight) =>
+				@removeHighlight(highlight)
 
 		findHighlightWithinRange: (range) ->
-			rows = @highlights.rows.slice(range.start.row, range.end.row + 1)
-			for row in rows
-				for highlight in (row || [])
-					if @_doesHighlightOverlapRange(highlight, range.start, range.end)
-						return highlight
-			return null
+			@highlights.find (highlight) =>
+				@_doesHighlightOverlapRange highlight, range.start, range.end
 
 		_doesHighlightOverlapRange: (highlight, start, end) ->
+			highlightRow = highlight.range.start.row
+			highlightStartColumn = highlight.range.start.column
+			highlightEndColumn = highlight.range.end.column
+
 			highlightIsAllBeforeRange =
-				highlight.row < start.row or
-				(highlight.row == start.row and highlight.column + highlight.word.length <= start.column)
+				highlightRow < start.row or
+				(highlightRow == start.row and highlightEndColumn <= start.column)
 			highlightIsAllAfterRange =
-				highlight.row > end.row or
-				(highlight.row == end.row and highlight.column >= end.column)
+				highlightRow > end.row or
+				(highlightRow == end.row and highlightStartColumn >= end.column)
 			!(highlightIsAllBeforeRange or highlightIsAllAfterRange)

+ 12 - 4
services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckAdapter.coffee

@@ -31,15 +31,23 @@ define [
 			})
 
 		selectHighlightedWord: (highlight) ->
+			row = highlight.range.start.row
+			startColumn = highlight.range.start.column
+			endColumn = highlight.range.end.column
+
 			@editor.getSession().getSelection().setSelectionRange(
 				new Range(
-					highlight.row, highlight.column,
-					highlight.row, highlight.column + highlight.word.length
+					row, startColumn,
+					row, endColumn
 				)
 			)
 
 		replaceWord: (highlight, newWord) =>
+			row = highlight.range.start.row
+			startColumn = highlight.range.start.column
+			endColumn = highlight.range.end.column
+
 			@editor.getSession().replace(new Range(
-				highlight.row, highlight.column,
-				highlight.row, highlight.column + highlight.word.length
+				row, startColumn,
+				row, endColumn
 			), newWord)