mirror of
https://github.com/overleaf/overleaf.git
synced 2024-12-26 17:23:51 +00:00
159 lines
4.5 KiB
CoffeeScript
159 lines
4.5 KiB
CoffeeScript
define [
|
|
"spelling/HighlightedWordManager"
|
|
"spelling/SpellingMenuView"
|
|
], (HighlightedWordManager, SpellingMenuView) ->
|
|
class SpellingManager
|
|
constructor: (@ide) ->
|
|
setup = _.once =>
|
|
@updatedLines = []
|
|
@highlightedWordManager = new HighlightedWordManager(@ide)
|
|
@menu = new SpellingMenuView(ide: @ide)
|
|
@menu.on "click:suggestion", (suggestion, highlight) =>
|
|
@menu.hide()
|
|
@replaceWord(highlight, suggestion)
|
|
@menu.on "click:learn", (highlight) =>
|
|
@menu.hide()
|
|
@learnWord highlight
|
|
@ide.editor.on "change:doc", () => @changeOpenDoc()
|
|
@ide.editor.on "update:doc", (e) => @onDocUpdated(e)
|
|
@ide.editor.on "mousemove", (e) => @onMouseMove(e)
|
|
|
|
@ide.on "afterJoinProject", (project) =>
|
|
@project = project
|
|
@language = @ide.project.get("spellCheckLanguage") || window.userSettings.spellCheckLanguage
|
|
if @language? and @language != ""
|
|
setup()
|
|
|
|
@project.on "change:spellCheckLanguage", =>
|
|
@changeOpenDoc()
|
|
|
|
changeOpenDoc: () ->
|
|
@highlightedWordManager.clearRows()
|
|
@runSpellCheck()
|
|
|
|
onDocUpdated: (e) ->
|
|
@highlightedWordManager.applyChange(e.data)
|
|
@markLinesAsUpdated(e.data)
|
|
@runSpellCheckSoon()
|
|
|
|
onMouseMove: (e) ->
|
|
@showMenuIfOverMisspelling(e.position)
|
|
|
|
showMenuIfOverMisspelling: (position) ->
|
|
highlight = @highlightedWordManager.findHighlightWithinRange
|
|
start: position
|
|
end: position
|
|
if highlight
|
|
@menu.showForHighlight(highlight)
|
|
else
|
|
@menu.hideIfAppropriate(position)
|
|
|
|
replaceWord: (highlight, suggestion) ->
|
|
@ide.editor.replaceText {
|
|
start:
|
|
row: highlight.row
|
|
column: highlight.column
|
|
end:
|
|
row: highlight.row
|
|
column: highlight.column + highlight.word.length
|
|
}, suggestion
|
|
|
|
learnWord: (highlight) ->
|
|
@apiRequest "/learn", word: highlight.word
|
|
@highlightedWordManager.removeWord highlight.word
|
|
|
|
getHighlightedWordAtCursor: () ->
|
|
cursor = @ide.editor.getCursorPosition()
|
|
highlight = @highlightedWordManager.findHighlightWithinRange
|
|
start: cursor
|
|
end: cursor
|
|
return highlight
|
|
|
|
runSpellCheckSoon: () ->
|
|
run = () =>
|
|
delete @timeoutId
|
|
@runSpellCheck(@updatedLines)
|
|
@updatedLines = []
|
|
if @timeoutId?
|
|
clearTimeout @timeoutId
|
|
@timeoutId = setTimeout run, 1000
|
|
|
|
markLinesAsUpdated: (change) ->
|
|
start = change.range.start
|
|
end = change.range.end
|
|
|
|
insertLines = () =>
|
|
lines = end.row - start.row
|
|
while lines--
|
|
@updatedLines.splice(start.row, 0, true)
|
|
|
|
removeLines = () =>
|
|
lines = end.row - start.row
|
|
while lines--
|
|
@updatedLines.splice(start.row + 1, 1)
|
|
|
|
if change.action == "insertText"
|
|
@updatedLines[start.row] = true
|
|
insertLines()
|
|
else if change.action == "removeText"
|
|
@updatedLines[start.row] = true
|
|
removeLines()
|
|
else if change.action == "insertLines"
|
|
insertLines()
|
|
else if change.action == "removeLines"
|
|
removeLines()
|
|
|
|
runSpellCheck: (linesToProcess) ->
|
|
{words, positions} = @getWords(linesToProcess)
|
|
language = @ide.project.get("spellCheckLanguage")
|
|
@apiRequest "/check", {language: language, words: words}, (error, result) =>
|
|
if error? or !result? or !result.misspellings?
|
|
return null
|
|
|
|
if linesToProcess?
|
|
for shouldProcess, row in linesToProcess
|
|
@highlightedWordManager.clearRows(row, row) if shouldProcess
|
|
else
|
|
@highlightedWordManager.clearRows()
|
|
|
|
for misspelling in result.misspellings
|
|
word = words[misspelling.index]
|
|
position = positions[misspelling.index]
|
|
@highlightedWordManager.addHighlight
|
|
column: position.column
|
|
row: position.row
|
|
word: word
|
|
suggestions: misspelling.suggestions
|
|
|
|
getWords: (linesToProcess) ->
|
|
lines = @ide.editor.getLines()
|
|
words = []
|
|
positions = []
|
|
for line, row in lines
|
|
if !linesToProcess? or linesToProcess[row]
|
|
wordRegex = /\\?['a-zA-Z\u00C0-\u00FF]+/g
|
|
while (result = wordRegex.exec(line))
|
|
word = result[0]
|
|
if word[0] == "'"
|
|
word = word.slice(1)
|
|
if word[word.length - 1] == "'"
|
|
word = word.slice(0,-1)
|
|
positions.push row: row, column: result.index
|
|
words.push(word)
|
|
return words: words, positions: positions
|
|
|
|
apiRequest: (endpoint, data, callback = (error, result) ->)->
|
|
data.token = @ide.user.get("id")
|
|
data._csrf = csrfToken
|
|
options =
|
|
url: "/spelling" + endpoint
|
|
type: "POST"
|
|
dataType: "json"
|
|
headers:
|
|
"Content-Type": "application/json"
|
|
data: JSON.stringify data
|
|
success: (data, status, xhr) ->
|
|
callback null, data
|
|
error: (xhr, status, error) ->
|
|
callback error
|
|
$.ajax options
|