php / php/php-src

Dom\HTMLDocument: Impossible to add text node on document level

Đang mở
#23,562 4 bình luận 0 reaction 0 người được giao Xem trên GitHub

Chưa có ai nhận issue này.

Feature Status: Needs Triage
Ngôn ngữ chính
C
Star
40.4k
Fork
8.2k
Merge trung bình
2 ngày 13 giờ
Pull request đã merge (30 ngày)
96

Mô tả

Description

The following code...

$doc = \Dom\HTMLDocument::createFromString('Hello <b>world</b>!',LIBXML_HTML_NOIMPLIED);
$greeting = $doc->firstChild;
echo get_class($greeting)."<br />";
$new_greeting = $doc->createTextNode('Welcome');
$greeting->replaceWith($new_greeting);
echo htmlentities($doc->saveHtml());

results in this error:

DOMException: Cannot insert text as a child of a document in Dom\CharacterData->replaceWith()

This is different behavior from the old DOM classes which allowed this. I understand, this spec-compliance is supposed to be a feature. If I understand correctly, the new Lexbor-based parser offers validity checks for some methods and not for others:

https://lexbor.com/modules/dom/

E.g. lxb_dom_node_insert_before_spec vs lxb_dom_node_insert_before etc.

I'm unaware of the current PHP implementation but I assume it is using the _spec versions throughout without any option to turn it off.

I think this is problematic. The NOIMPLIED option is very useful indeed if you want to handle document fragments etc. without unnecessary wrapper tags.

The above code leads to the peculiar situation that you can indeed create a Document with textNodes on the document level, but if you just want to replace that textNode with a different textNode it won't work. This complicates things a lot unnecessarily. Other methods like insertAdjacentHTML, appendChild etc are equally stubborn.

There are different solutions for this: IMHO the easiest one would be to use the non-spec versions of these functions if NOIMPLIED was specified. NOIMPLIED explicitly allows a non-spec document to be imported. Any manipulation should also be allowed then.

Another alternative would be to create a new general flag LIBXML_HTML_RELAX_SPEC.

A third alternative would be to specifically add option flags to the individual methods to allow this for a single call.

I'm unsure what's really the best solution but at the moment, porting over existing code is unnecessarily difficult due to this restriction and I really think this feature would make a lot of sense anyway. Thanks for considering.

Hướng dẫn đóng góp

Mở hướng dẫn đóng góp

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. 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.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Hướng nghiên cứu

Bắt đầu bằng cách tái hiện đoạn mã PHP với Dom\HTMLDocument::createFromString, LIBXML_HTML_NOIMPLIED và CharacterData::replaceWith(). Theo dõi cách replaceWith(), insertAdjacentHTML() và appendChild() xử lý các nút văn bản ở cấp tài liệu, sau đó so sánh các entry point Lexbor tuân thủ và không tuân thủ đặc tả được đề cập trong issue. Công việc được xem là hoàn tất khi đã đưa ra quyết định rõ ràng và triển khai hoặc ghi lại hành vi nhất quán cho các tài liệu NOIMPLIED, kèm theo các bài kiểm thử cho trường hợp được nêu.

Do mô hình lập chỉ mục viết ra từ nội dung của issue.

Đánh giá

Công nghệ
c, php
Lĩnh vực
api, backend
Loại issue
Tính năng
Độ khó
4/5
Thời gian dự kiến
3-5 ngày
Mức độ hoạt động
Sôi nổi
Độ rõ ràng
Khá rõ ràng
Mức phù hợp với người mới
48/100

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.