Parsing splits one text run into several Text nodes at each character reference (`<p>a & b</p>` gives 3 child nodes)
Maintainer thường phản hồi trong vòng 5 ngày
Đánh giá
- Độ khó
- 2/5
- Thời gian dự kiến
- 1-3 giờ
- Mức phù hợp với người mới
- 68/100
- Loại issue
- Lỗi
- Độ rõ ràng
- Khá rõ ràng
- Mức độ hoạt động
- Sôi nổi
- Công nghệ
- html, javascript
Hướng nghiên cứu
Bắt đầu với trình xử lý ontext trong esm/shared/parse-from-string.js, nơi issue xác định là thêm một nút Text cho mỗi callback của parser. So sánh hành vi của nó với DomHandler của htmlparser2, sau đó thêm một kiểm thử hồi quy cho markup có chứa tham chiếu ký tự. Hoàn tất khi phân tích ví dụ tạo ra một nút Text có dữ liệu "a & b" và độ bao phủ hiện có vẫn ở mức 100%.
Do mô hình lập chỉ mục viết ra từ nội dung của issue.
Mô tả
Parsing <p>a & b</p> gives the <p> three Text nodes ("a ", "&", " b"). The HTML parsing algorithm appends each character to the previous Text node, and jsdom gives one Text node, "a & b". Code that walks childNodes and treats each Text node as one run sees extra runs wherever the source has an entity. normalize() merges them afterwards, but every consumer of parsed output has to know to call it on every subtree, and a spec parser never produces the split in the first place ("insert a character": https://html.spec.whatwg.org/multipage/parsing.html#insert-a-character).
Asks:
- Should the parser merge text into the previous Text node when the previous sibling under the same parent is a Text node, as the HTML parsing algorithm does?
- If yes, I can open a PR that changes
esm/only, with a test, keeping coverage at 100%.
Environment: linkedom 0.18.14 (npm, latest) and main at e2ee208, htmlparser2 10.1.0, Node 24.14.1, macOS.
Test case:
import { DOMParser } from 'linkedom'
const doc = new DOMParser().parseFromString('<!doctype html><html><body><p>a & b</p></body></html>', 'text/html')
const p = doc.querySelector('p')
console.log('textContent:', JSON.stringify(p.textContent))
console.log('childNodes.length:', p.childNodes.length)
console.log('childNodes data:', JSON.stringify([...p.childNodes].map((n) => n.data)))
Output:
textContent: "a & b"
childNodes.length: 3
childNodes data: ["a ","&"," b"]
Expected: childNodes.length: 1, data ["a & b"] (what jsdom 29.1.1 returns for the same markup).
| Input | linkedom Text nodes | jsdom Text nodes |
|---|---|---|
<p>a and b</p> |
1 | 1 |
<p>a & b</p> |
3 | 1 |
<p>x < y > z ©</p> |
6 | 1 |
parseHTML gives the same result as DOMParser (3 nodes for <p>a & b</p>).
Raw output (npm 0.18.14, main e2ee208, variants, htmlparser2)
$ node repro.mjs # linkedom 0.18.14 from npm
textContent: "a & b"
childNodes.length: 3
childNodes data: ["a ","&"," b"]
$ node repro-main.mjs # main e2ee208 esm/
textContent: "a & b"
childNodes.length: 3
childNodes data: ["a ","&"," b"]
$ node variants.mjs
no entity: 1 ["a and b"]
&: 3 ["a ","&"," b"]
< > ©: 6 ["x ","<"," y ",">"," z ","©"]
parseHTML: 3
$ node htmlparser2-ontext.mjs # htmlparser2 10.1.0, decodeEntities: true
htmlparser2 ontext calls: ["a ","&"," b"]
$ node jsdom-control.mjs
jsdom childNodes.length: 1 ["a & b"]
Where it comes from: htmlparser2 with decodeEntities: true calls ontext once per piece around each character reference. The ontext handler in parseFromString appends a new Text node for every call:
htmlparser2's own DomHandler merges each ontext piece into the previous Text node (domhandler 5.0.3, lib/index.js, ontext), so with the same callbacks it yields one node for <p>a & b</p>.
No existing issue found for this; the closest are #62 and #71, which are about serializing entities, not the node split.
- Ngôn ngữ chính
- HTML
- Star
- 2.1k
- Fork
- 117
- Merge trung bình
- 4 ngày 13 giờ
- Pull request đã merge (30 ngày)
- 2
Chuẩn bị môi trường
Dự án này không cung cấp dev container, Dockerfile hay hướng dẫn đóng góp, nên bạn cần tự thiết lập môi trường: hãy bắt đầu từ README và xem hướng dẫn đóng góp lần đầu của chúng tôi để biết các bước chung.
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của WebReflection/linkedom
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
WebReflection/linkedom#365 ·
Maintainer thường phản hồi trong vòng 5 ngày
-
SVG elements in an HTML document report an upper-cased tagName ("PATH" instead of "path")Có thể đã có người làm @jonasporto đã nhận 9 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 85/100
WebReflection/linkedom#344 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 5 ngày
-
`TextElement.toString()` puts the element text back at the first `><` of the start tag, so an attribute value containing `><` swallows the text of `<style>`, `<script>`, `<title>` and `<textarea>`Có thể đã có người làm @vsolano9 đã nhận 22 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
WebReflection/linkedom#341 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
WebReflection/linkedom#340 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 5 ngày
-
Element#matches() compiles the selector on every callCó thể đã có người làm @jonasporto đã nhận 22 ngày trước. Đang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 35/100
WebReflection/linkedom#348 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 5 ngày
Tất cả issue của WebReflection/linkedom
Issue tương tự
-
`Time.at(t, in: nil)` returns UTC instead of the local time (or the time zone of `t`), unlike CRubyĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
PageParameters.hashCode is inconsistent with equals for named parameters in a different orderĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
bug implicit-state
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
PecanProject/sipnet#435 · 1 bình luận ·
Maintainer thường phản hồi trong vòng 2 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100