如何在`pa11y`中获取目标行号和列范围?

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

How to get the target line number and columns range in `pa11y`?

问题

根据TypeScript的类型定义,`pa11y`返回:

```typescript
interface ResultIssue {
    code: string;
    context: string;
    message: string;
    selector: string;
    type: string;
    typeCode: number;
}

示例数值(看起来TypeScript的类型定义可能有点不完整,但runnerrunnerExtras目前似乎不重要):

{
  code: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId',
  type: 'error',
  typeCode: 1,
  message: '找到没有链接内容和没有名称和/或ID属性的锚点元素。',
  context: '<a><span></span></a>',
  selector: 'html > body > main > a:nth-child(3)',
  runner: 'htmlcs',
  runnerExtras: {}
}

我想创建类似于下面的输出(下面的输出是用于HTML验证,现在需要类似的用于辅助检查):

如何在`pa11y`中获取目标行号和列范围?

然而,pa11y没有提供检索行号和列范围的API。
那么,我们可以做些什么呢?
我对获取源HTML代码没有任何问题,现在剩下的就是检测HTML代码中的问题片段。

第一个线索是context。也许我们可以使用正则表达式或只是String.prototype.indexOf(),但如果出现多个怎么办?如果它总是第一个,我就不满意。

下一个线索是选择器,比如 html > body > main > a:nth-child(3)。看起来它是唯一的。使用node-html-parser,我们可以通过选择器访问元素,但我们如何获取行号和列范围呢?


<details>
<summary>英文:</summary>

According to TypeScript typings the `pa11y` returns:

```typescript
interface ResultIssue {
    code: string;
    context: string;
    message: string;
    selector: string;
    type: string;
    typeCode: number;
}

Example value (looks line the TypeScript typings are a little bit incomplete, but the runner and runnerExtras does not seem to be important for now):

{
  code: &#39;WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId&#39;,
  type: &#39;error&#39;,
  typeCode: 1,
  message: &#39;Anchor element found with no link content and no name and/or ID attribute.&#39;,
  context: &#39;&lt;a&gt;&lt;span&gt;&lt;/span&gt;&lt;/a&gt;&#39;,
  selector: &#39;html &gt; body &gt; main &gt; a:nth-child(3)&#39;,
  runner: &#39;htmlcs&#39;,
  runnerExtras: {}
}

I want to create the output similar to below one (the below one if for HTML validation, now the similar one for the accessibility checking):

如何在`pa11y`中获取目标行号和列范围?

However, the pa11y does not give the API for the line number and the columns range retrieving.
Well, what we can do instead?
I have no problems with the bringing of the source HTML code, all that left is detect the issued fragment at the HTML code.

The first clue is the context. Maybe we can use the regular expression or just String.prototype.indexOf() but what if the occurrences are multiple? I am not fine if it will always the first one.

Next clue is the selector like html &gt; body &gt; main &gt; a:nth-child(3). Looks like it is unique. Using node-html-parser, we can access to the element by selector, but how we can get the line number and the columns range?

答案1

得分: 1

你可以通过解析源HTML,然后使用querySelector来访问元素。

这假设源HTML包含适当的换行符和换行字符(在这种情况下\n)。此外,当使用pre选项进行解析时,确保保留源上的空格和格式。

然后,您可以使用indexOfsubstring的组合来查找源HTML中元素的行号。

例如(这里可能有错误!)

const { parse } = require('node-html-parser');

// 其中htmlContent是源HTML
const root = parse(htmlContent, {
   pre: true
});

// 其中resultIssue.selector是一个字符串,如'html > body > main > a:nth-child(3)'
const element = root.querySelector(resultIssue.selector);

if (element) {
  // 获取元素的HTML字符串
  const sourceHtml = element.toString();

  // 查找源HTML中的元素
  const startIndex = htmlContent.indexOf(sourceHtml);

  // 计算行数(注意:可能是`\r\n`)
  const lineNumber = htmlContent.substring(0, startIndex).split('\n').length;
  console.log('行号:', lineNumber);
} else {
  console.log('未找到元素。');
}

您可以通过在HTML行字符串中查找元素字符串的索引位置来以类似的方式访问近似的列位置。

英文:

You can do this by parsing the source HTML, then use the querySelector to access the element.

This is assuming that the source HTML contains proper line breaks with newline characters (in this case \n). Also you do need to ensure that you preserve whitespaces and formatting on the source when you parss using the pre option.

You can then use a combination of indexOf and substring to find the line number of the element in the source HTML.

For example (apologies typed here so could be errors!)

const { parse } = require(&#39;node-html-parser&#39;);

// where htmlContent is the source HTML
const root = parse(htmlContent, {
   pre: true
});

// where resultIssue.selector is a string such as &#39;html &gt; body &gt; main &gt; a:nth-child(3)&#39;
const element = root.querySelector(resultIssue.selector);

if (element) {
  // get the element as HTML string
  const sourceHtml = element.toString();

  // find the element in the source html
  const startIndex = htmlContent.indexOf(sourceHtml);

  // count the lines (NB: could be `\r\n`)
  const lineNumber = htmlContent.substring(0, startIndex).split(&#39;\n&#39;).length;
  console.log(&#39;Line number:&#39;, lineNumber);
} else {
  console.log(&#39;Element not found.&#39;);
}

You can access the approximate column position in a similar manner by finding the index position of the element string within the HTML line string.

huangapple
  • 本文由 发表于 2023年7月14日 08:26:46
  • 转载请务必保留本文链接:https://go.coder-hub.com/76684017.html
匿名

发表评论

匿名网友

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

确定