英文:
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的类型定义可能有点不完整,但runner
和runnerExtras
目前似乎不重要):
{
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
没有提供检索行号和列范围的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: 'WCAG2AAA.Principle4.Guideline4_1.4_1_2.H91.A.EmptyNoId',
type: 'error',
typeCode: 1,
message: 'Anchor element found with no link content and no name and/or ID attribute.',
context: '<a><span></span></a>',
selector: 'html > body > main > a:nth-child(3)',
runner: 'htmlcs',
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):
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 > body > main > 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
选项进行解析时,确保保留源上的空格和格式。
然后,您可以使用indexOf
和substring
的组合来查找源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('node-html-parser');
// where htmlContent is the source HTML
const root = parse(htmlContent, {
pre: true
});
// where resultIssue.selector is a string such as 'html > body > main > a:nth-child(3)'
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('\n').length;
console.log('Line number:', lineNumber);
} else {
console.log('Element not found.');
}
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.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论