Separate internal and LanguageTool data formats
This allows a bit simpler code and less clutter in the LanguageTool communication.
This commit is contained in:
		| @@ -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 }] | ||||||
|   } |   } | ||||||
| } | } | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user