Grammarly是如何知道在哪里放置红色下划线的?

huangapple go评论91阅读模式
英文:

How does Grammarly know where to position the red underline?

问题

我最近对像LanguageTool和Grammarly这样的工具如何在屏幕上显示拼写错误的单词下方的红色波浪线感到着迷。我想做类似的事情,但是在首次显示下划线后,在单词上悬停时显示丰富的弹出窗口,其中包括同义词等内容。

这与浏览器扩展无关。请查看我提供的链接,了解Grammarly的SDK插件和LanguageTool的API示例。

我知道Grammarly使用Shadow DOM和插槽将文本区域包装起来,但我仍然无法确定他们如何能够(高效地)确定文本区域中特定单词的位置。LanguageTool不使用Shadow DOM。

当我检查时,它们都没有显示重复的克隆HTML,我认为它们可能会以某种方式将文本拆分成标记,以获取边界矩形,但似乎不是这样。

使用<grammarly-editor-plugin><textarea></textarea></grammarly-editor-plugin>的结果
Grammarly是如何知道在哪里放置红色下划线的?

LanguageTool示例:
Grammarly是如何知道在哪里放置红色下划线的?

我尝试使用Canvas API来获取特定单词的尺寸,但这不足以确定它在文本区域中的位置,因为该单词可能位于第一行以外的行。

为了使这种方法奏效,他们必须获取文本区域中的所有单词,计算它们的尺寸,并使用文本区域的尺寸来确定目标单词在文本区域中的所在行;结合单词的尺寸,特别是宽度,他们将能够获得在文本区域内的x和y位置。然而,这似乎太昂贵和慢,无法像它们的下划线显示那样快速完成。

我可以使用contenteditable,只需将每个单词包装在自己的span中,但这似乎不是最理想的方法。

还有其他人知道他们如何能够确定文本区域中单词的X和Y位置吗?

英文:

I've recently become fascinated with how tools like LanguageTool and Grammarly show red underlines on mispelled words on the screen. I'd like to do something similar but to show rich popovers with things like synonyms on hover of a word after first showing an underline on said word.

> This is not about browser extensions. See the links I've included to Grammarly's SDK plugins & LanguageTool's API examples.

I know Grammarly is using the Shadow DOM with slots to wrap the textarea, but I still can't tell how they're able to (efficiently) determine the position of a specific word in the textarea. LanguageTool doesn't use the Shadow DOM.

Neither duplicate show cloned HTML when I inspect it, which I thought they might in order to some how break the text into tokens that they could get bounding rects for -- but that doesn't appear to be it.

The result of using &lt;grammarly-editor-plugin&gt;&lt;textarea&gt;&lt;/textarea&gt;&lt;/grammarly-editor-plugin&gt;
Grammarly是如何知道在哪里放置红色下划线的?

LanguageTool example:
Grammarly是如何知道在哪里放置红色下划线的?

I tried using the Canvas API to get the dimensions of a specific word, but that isn't enough to determine its position in the textarea because the word could be on a line greater than the first.

In order to make this approach work, they have to be getting all the words in the textarea, computing their dimensions, and using the dimensions of the textarea to determine which line a target word is in the textarea; together with the dimensions, specifically the width, of the word, they would then have the x & y positions within the textarea. However, this seems too expensive and slow to pull off as fast as their underlines appear to show.

I could go with contenteditable by just wrapping each word in its own span, but that seems less than ideal.

Does anyone else know how else they could be able to determine the X & Y position of a word in a textarea.

答案1

得分: 1

你激发了我的热情,但结果并没有太大的挑战! Grammarly是如何知道在哪里放置红色下划线的?

<!DOCTYPE html>

<head>

<style>

u{color:red;}

.con{width:500px; height:100px; border:1px solid black;}

</style>

</head>

<body>

<script>

const Correct=['Once','upon','a','time','there','were','three','little','pigs'];

function CheckSpelling(){

var S=Con.innerHTML.replace(/<u>/g,'').replace(/</u>/g,'');

var A=S.split(' ');

for(let i=0; i<A.length; i++){

 if(Correct.includes(A[i])===false){A[i]='<u>'+A[i]+'</u>';}

} Con.innerHTML=A.join(' ');}

</script>

Change the words below and click spellcheck...<br><br>

<div id="Con" class="con" spellcheck="false" contenteditable="true">Once upon a time there were three little pigs</div>

<br>

<button onclick="CheckSpelling();">Check Spelling</button>

<br><br>

NB: Optionally you can automate the spellcheck by adding a oninput="CheckSpelling();" to the container.

</body>

</html>
英文:

You got me all fired up but it didn't turn out to be much of a challenge! Grammarly是如何知道在哪里放置红色下划线的?

&lt;!DOCTYPE html&gt;

&lt;head&gt;

&lt;style&gt;

u{color:red;}

.con{width:500px; height:100px; border:1px solid black;}

&lt;/style&gt;

&lt;/head&gt;

&lt;body&gt;

&lt;script&gt;

const Correct=[&#39;Once&#39;,&#39;upon&#39;,&#39;a&#39;,&#39;time&#39;,&#39;there&#39;,&#39;were&#39;,&#39;three&#39;,&#39;little&#39;,&#39;pigs&#39;];


function CheckSpelling(){

var S=Con.innerHTML.replace(/&lt;u\&gt;/g,&#39;&#39;).replace(/&lt;\/u\&gt;/g,&#39;&#39;);

var A=S.split(&#39; &#39;);

for(let i=0; i&lt;A.length; i++){

 if(Correct.includes(A[i])===false){A[i]=&#39;&lt;u&gt;&#39;+A[i]+&#39;&lt;/u&gt;&#39;;}

} Con.innerHTML=A.join(&#39; &#39;);}


&lt;/script&gt;

Change the words below and click spellcheck...&lt;br&gt;&lt;br&gt;

&lt;div id=&quot;Con&quot; class=&quot;con&quot; spellcheck=&quot;false&quot; contenteditable=&quot;true&quot;&gt;Once upon a time there were three little pigs&lt;/div&gt;

&lt;br&gt;

&lt;button onclick=&quot;CheckSpelling();&quot;&gt;Check Spelling&lt;/button&gt;

&lt;br&gt;&lt;br&gt;

NB: Optionally you can automate the spellcheck by adding a oninput=&quot;CheckSpelling();&quot; to the container.

&lt;/body&gt;

&lt;/html&gt;

答案2

得分: 1

On macOS, Grammarly uses the Accessibility API for getting and setting values and properties of controls (selection, text content, character position, caret position, etc.). For changing texts, it emulates keystrokes. For underlining the text, it uses an overlay window.

I suppose that on MS Windows, it uses equivalent techniques (the UIAutomation API and overlay windows).

英文:

On macOS, Grammarly uses the Accessibility API for getting and setting values and properties of controls (selection, text content, character position, caret position, etc.). For changing texts, it emulates keystrokes. For underlining the text, it uses an overlay window.

I suppose that on MS Windows, it uses equivalent techniques (the UIAutomation API and overlay windows).

huangapple
  • 本文由 发表于 2023年3月12日 08:28:54
  • 转载请务必保留本文链接:https://go.coder-hub.com/75710398.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定