Separate internal and LanguageTool data formats
This allows a bit simpler code and less clutter in the LanguageTool communication.
This commit is contained in:
parent
279c815b15
commit
0d8d6e165a
@ -24,7 +24,7 @@ async function besCheckText(el)
|
|||||||
{
|
{
|
||||||
switch (el.nodeType) {
|
switch (el.nodeType) {
|
||||||
case Node.TEXT_NODE:
|
case Node.TEXT_NODE:
|
||||||
return [{ text: el.textContent, el: el }]
|
return [{ text: el.textContent, el: el, markup: false }]
|
||||||
|
|
||||||
case Node.ELEMENT_NODE:
|
case Node.ELEMENT_NODE:
|
||||||
let data = []
|
let data = []
|
||||||
@ -36,15 +36,15 @@ async function besCheckText(el)
|
|||||||
{
|
{
|
||||||
case 'inline':
|
case 'inline':
|
||||||
case 'inline-block':
|
case 'inline-block':
|
||||||
data.splice(0, 0, { markup: '<'+el.tagName+'>', el: el })
|
data.splice(0, 0, { text: '<'+el.tagName+'>', el: el, markup: true })
|
||||||
data.splice(data.length, 0, { markup: '</'+el.tagName+'>' })
|
data.splice(data.length, 0, { text: '</'+el.tagName+'>', markup: true })
|
||||||
return data;
|
return data;
|
||||||
default:
|
default:
|
||||||
let regAllWhitespace = /^\s*$/
|
let regAllWhitespace = /^\s*$/
|
||||||
if (data.some(x => 'text' in x && !regAllWhitespace.test(x.text))) {
|
if (data.some(x => !x.markup && !regAllWhitespace.test(x.text))) {
|
||||||
const requestData = {
|
const requestData = {
|
||||||
format: 'plain',
|
format: 'plain',
|
||||||
data: JSON.stringify({annotation: data}),
|
data: JSON.stringify({annotation: data.map(x => x.markup ? { markup: x.text } : { text: x.text })}),
|
||||||
language: 'sl',
|
language: 'sl',
|
||||||
level: 'picky'
|
level: 'picky'
|
||||||
}
|
}
|
||||||
@ -62,34 +62,27 @@ async function besCheckText(el)
|
|||||||
return response.json()
|
return response.json()
|
||||||
})
|
})
|
||||||
.then(responseData => {
|
.then(responseData => {
|
||||||
// responseData.matches.sort((a, b) => a.offset < b.offset ? -1 : a.offset > b.offset ? +1 : 0)
|
// Reverse sort grammar mistakes for easier markup insertion later.
|
||||||
|
// When we start inserting grammar mistakes at the back, indexes before that remain valid.
|
||||||
responseData.matches.sort((a, b) => a.offset < b.offset ? +1 : a.offset > b.offset ? -1 : 0);
|
responseData.matches.sort((a, b) => a.offset < b.offset ? +1 : a.offset > b.offset ? -1 : 0);
|
||||||
responseData.matches.forEach(match => {
|
responseData.matches.forEach(match => {
|
||||||
let range = document.createRange()
|
let range = document.createRange()
|
||||||
|
|
||||||
// Locate start of the grammar mistake.
|
// Locate start of the grammar mistake.
|
||||||
for (let idx = 0, startingOffset = 0; ; ) {
|
for (let idx = 0, startingOffset = 0; ; startingOffset += data[idx++].text.length) {
|
||||||
if ('text' in data[idx]) {
|
if (!data[idx].markup && /*startingOffset <= match.offset &&*/ match.offset < startingOffset + data[idx].text.length) {
|
||||||
if (startingOffset <= match.offset && match.offset < startingOffset + data[idx].text.length) {
|
range.setStart(data[idx].el, match.offset - startingOffset)
|
||||||
range.setStart(data[idx].el, match.offset - startingOffset)
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
startingOffset += data[idx++].text.length
|
|
||||||
}
|
}
|
||||||
else startingOffset += data[idx++].markup.length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Locate end of the grammar mistake.
|
// Locate end of the grammar mistake.
|
||||||
let endOffset = match.offset + match.length
|
let endOffset = match.offset + match.length
|
||||||
for (let idx = 0, startingOffset = 0; ; ) {
|
for (let idx = 0, startingOffset = 0; ; startingOffset += data[idx++].text.length) {
|
||||||
if ('text' in data[idx]) {
|
if (!data[idx].markup && /*startingOffset <= endOffset &&*/ endOffset <= startingOffset + data[idx].text.length) {
|
||||||
if (startingOffset <= endOffset && endOffset <= startingOffset + data[idx].text.length) {
|
range.setEnd(data[idx].el, endOffset - startingOffset)
|
||||||
range.setEnd(data[idx].el, endOffset - startingOffset)
|
break
|
||||||
break
|
|
||||||
}
|
|
||||||
startingOffset += data[idx++].text.length
|
|
||||||
}
|
}
|
||||||
else startingOffset += data[idx++].markup.length
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const span = document.createElement('span')
|
const span = document.createElement('span')
|
||||||
@ -98,7 +91,7 @@ async function besCheckText(el)
|
|||||||
// Dirty hack, copied from: https://stackoverflow.com/questions/67634286/invalidstateerror-failed-to-execute-surroundcontents-on-range-the-range-ha
|
// Dirty hack, copied from: https://stackoverflow.com/questions/67634286/invalidstateerror-failed-to-execute-surroundcontents-on-range-the-range-ha
|
||||||
span.appendChild(range.extractContents());
|
span.appendChild(range.extractContents());
|
||||||
range.insertNode(span);
|
range.insertNode(span);
|
||||||
|
|
||||||
// This is a better way to apply span elements,
|
// This is a better way to apply span elements,
|
||||||
// but it doesnt work when the range has partially selected a non-Text node.
|
// but it doesnt work when the range has partially selected a non-Text node.
|
||||||
// range.surroundContents(span)
|
// range.surroundContents(span)
|
||||||
@ -106,14 +99,14 @@ async function besCheckText(el)
|
|||||||
})
|
})
|
||||||
.catch(error => {
|
.catch(error => {
|
||||||
// TODO: Make parsing issues non-fatal.
|
// TODO: Make parsing issues non-fatal.
|
||||||
throw new Error('Request to backend server failed: ' + error)
|
throw new Error('Parsing backend server response failed: ' + error)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
return [{ markup: '<'+el.tagName+'/>', el: el }]
|
return [{ text: '<'+el.tagName+'/>', el: el, markup: true }]
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return [{ markup: '<?'+el.nodeType+'>', el: el }]
|
return [{ text: '<?'+el.nodeType+'>', el: el, markup: true }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user