Просмотр исходного кода

Re-implement spell check manager with adapter to abstract away editor

Alasdair Smith 8 лет назад
Родитель
Сommit
37ca7b54a6

+ 51 - 133
services/web/public/coffee/ide/editor/directives/aceEditor/spell-check/SpellCheckManager.coffee

@@ -1,129 +1,38 @@
-define [
-	"ide/editor/directives/aceEditor/spell-check/HighlightedWordManager"
-	"ace/ace"
-], (HighlightedWordManager) ->
-	Range = ace.require("ace/range").Range
-
+define [], () ->
 	class SpellCheckManager
-		constructor: (@$scope, @editor, @element, @cache, @$http, @$q) ->
-			$(document.body).append @element.find(".spell-check-menu")
+		constructor: (@$scope, @cache, @$http, @$q, @adapter) ->
 			@inProgressRequest = null
 			@updatedLines = []
-			@highlightedWordManager = new HighlightedWordManager(@editor)
 
-			@$scope.$watch "spellCheckLanguage", (language, oldLanguage) =>
+			@$scope.$watch 'spellCheckLanguage', (language, oldLanguage) =>
 				if language != oldLanguage and oldLanguage?
 					@runFullCheck()
 
-			onChange = (e) =>
-				@runCheckOnChange(e)
-				
-			onScroll = () =>
-				@closeContextMenu()
-
-			@editor.on "changeSession", (e) =>
-				@highlightedWordManager.reset()
-				if @inProgressRequest?
-					@inProgressRequest.abort()
-
-				if @$scope.spellCheckEnabled and @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
-					@runSpellCheckSoon(200)
-
-				e.oldSession?.getDocument().off "change", onChange
-				e.session.getDocument().on "change", onChange
-				
-				e.oldSession?.off "changeScrollTop", onScroll
-				e.session.on "changeScrollTop", onScroll
-
-			@$scope.spellingMenu = {left: '0px', top: '0px'}
+		init: () ->
+			@updatedLines = Array(@adapter.getLines().length).fill(true)
+			@runSpellCheckSoon(200) if @isSpellCheckEnabled()
 
-			@editor.on "nativecontextmenu", (e) =>
-				e.domEvent.stopPropagation();
-				@closeContextMenu(e.domEvent)
-				@openContextMenu(e.domEvent)
+		isSpellCheckEnabled: () ->
+			return !!(
+				@$scope.spellCheck and
+				@$scope.spellCheckLanguage and
+				@$scope.spellCheckLanguage != ''
+			)
 
-			$(document).on "click", (e) =>
-				if e.which != 3 # Ignore if this was a right click
-					@closeContextMenu(e)
-				return true
-
-			@$scope.replaceWord = (highlight, suggestion) =>
-				@replaceWord(highlight, suggestion)
-
-			@$scope.learnWord = (highlight) =>
-				@learnWord(highlight)
-
-		runFullCheck: () ->
-			@highlightedWordManager.clearRows()
-			if @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
-				@runSpellCheck()
-
-		runCheckOnChange: (e) ->
-			if @$scope.spellCheckLanguage and @$scope.spellCheckLanguage != ""
-				@highlightedWordManager.applyChange(e)
-				@markLinesAsUpdated(e)
+		onChange: (e) =>
+			if @isSpellCheckEnabled()
+				@markLinesAsUpdated(@adapter.normalizeChangeEvent(e))
 				@runSpellCheckSoon()
 
-		openContextMenu: (e) ->
-			position = @editor.renderer.screenToTextCoordinates(e.clientX, e.clientY)
-			highlight = @highlightedWordManager.findHighlightWithinRange
-				start: position
-				end:   position
-
-			@$scope.$apply () =>
-				@$scope.spellingMenu.highlight = highlight
-
-			if highlight
-				e.stopPropagation()
-				e.preventDefault()
-
-				@editor.getSession().getSelection().setSelectionRange(
-					new Range(
-						highlight.row, highlight.column
-						highlight.row, highlight.column + highlight.word.length
-					)
-				)
-
-				@$scope.$apply () =>
-					@$scope.spellingMenu.open = true
-					@$scope.spellingMenu.left = e.clientX + 'px'
-					@$scope.spellingMenu.top = e.clientY + 'px'
-				return false
-
-		closeContextMenu: (e) ->
-			# this is triggered on scroll, so for performance only apply
-			# setting when it changes
-			if @$scope?.spellingMenu?.open != false
-				@$scope.$apply () =>
-					@$scope.spellingMenu.open = false
-
-		replaceWord: (highlight, text) ->
-			@editor.getSession().replace(new Range(
-				highlight.row, highlight.column,
-				highlight.row, highlight.column + highlight.word.length
-			), text)
-
-		learnWord: (highlight) ->
-			@apiRequest "/learn", word: highlight.word
-			@highlightedWordManager.removeWord highlight.word
-			language = @$scope.spellCheckLanguage
-			@cache?.put("#{language}:#{highlight.word}", true)
+		onSessionChange: () =>
+			@adapter.wordManager.reset()
+			@inProgressRequest.abort() if @inProgressRequest?
 
-		getHighlightedWordAtCursor: () ->
-			cursor = @editor.getCursorPosition()
-			highlight = @highlightedWordManager.findHighlightWithinRange
-				start: cursor
-				end: cursor
-			return highlight
+			@runSpellCheckSoon(200) if @isSpellCheckEnabled()
 
-		runSpellCheckSoon: (delay = 1000) ->
-			run = () =>
-				delete @timeoutId
-				@runSpellCheck(@updatedLines)
-				@updatedLines = []
-			if @timeoutId?
-				clearTimeout @timeoutId
-			@timeoutId = setTimeout run, delay
+		runFullCheck: () ->
+			@adapter.wordManager.reset()
+			@runSpellCheck() if @isSpellCheckEnabled()
 
 		markLinesAsUpdated: (change) ->
 			start = change.start
@@ -146,6 +55,15 @@ define [
 				@updatedLines[start.row] = true
 				removeLines()
 
+		runSpellCheckSoon: (delay = 1000) ->
+			run = () =>
+				delete @timeoutId
+				@runSpellCheck(@updatedLines)
+				@updatedLines = []
+			if @timeoutId?
+				clearTimeout @timeoutId
+			@timeoutId = setTimeout run, delay
+
 		runSpellCheck: (linesToProcess) ->
 			{words, positions} = @getWords(linesToProcess)
 			language = @$scope.spellCheckLanguage
@@ -178,11 +96,11 @@ define [
 			displayResult = (highlights) =>
 				if linesToProcess?
 					for shouldProcess, row in linesToProcess
-						@highlightedWordManager.clearRows(row, row) if shouldProcess
+						@adapter.wordManager.clearRow(row) if shouldProcess
 				else
-					@highlightedWordManager.clearRows()
+					@adapter.wordManager.reset()
 				for highlight in highlights
-					@highlightedWordManager.addHighlight highlight
+					@adapter.wordManager.addHighlight highlight
 
 			if not words.length
 				displayResult highlights
@@ -212,8 +130,24 @@ define [
 							seen[key] = true
 					displayResult highlights
 
+		apiRequest: (endpoint, data, callback = (error, result) ->)->
+			data.token = window.user.id
+			data._csrf = window.csrfToken
+			# use angular timeout option to cancel request if doc is changed
+			requestHandler = @$q.defer()
+			options = {timeout: requestHandler.promise}
+			httpRequest = @$http.post("/spelling" + endpoint, data, options)
+			.then (response) =>
+				callback(null, response.data)
+			.catch (response) =>
+				callback(new Error('api failure'))
+			# provide a method to cancel the request
+			abortRequest = () ->
+				requestHandler.resolve()
+			return { abort: abortRequest }
+
 		getWords: (linesToProcess) ->
-			lines = @editor.getValue().split("\n")
+			lines = @adapter.getLines()
 			words = []
 			positions = []
 			for line, row in lines
@@ -232,22 +166,6 @@ define [
 						words.push(word)
 			return words: words, positions: positions
 
-		apiRequest: (endpoint, data, callback = (error, result) ->)->
-			data.token = window.user.id
-			data._csrf = window.csrfToken
-			# use angular timeout option to cancel request if doc is changed
-			requestHandler = @$q.defer()
-			options = {timeout: requestHandler.promise}
-			httpRequest = @$http.post("/spelling" + endpoint, data, options)
-			.then (response) =>
-				callback(null, response.data)
-			.catch (response) =>
-				callback(new Error('api failure'))
-			# provide a method to cancel the request
-			abortRequest = () ->
-				requestHandler.resolve()
-			return { abort: abortRequest }
-
 		blacklistedCommandRegex: ///
 			\\                    # initial backslash
 			(label                # any of these commands