소스 검색

LibWeb: Implement `document.createCDATASection()`

Tim Ledbetter 1 년 전
부모
커밋
02c2b1e67e

+ 3 - 0
Tests/LibWeb/Text/expected/DOM/Document-createCDATASection.txt

@@ -0,0 +1,3 @@
+<xml><![CDATA[Some <CDATA> data & then some]]></xml>
+Exception: NotSupportedError
+Exception: InvalidCharacterError

+ 21 - 0
Tests/LibWeb/Text/input/DOM/Document-createCDATASection.html

@@ -0,0 +1,21 @@
+<script src="../include.js"></script>
+<script>
+    test(() => {
+        const xmlDocument = new DOMParser().parseFromString("<xml></xml>", "application/xml");
+        const validCdata = xmlDocument.createCDATASection("Some <CDATA> data & then some");
+        xmlDocument.querySelector("xml").appendChild(validCdata);
+        println(new XMLSerializer().serializeToString(xmlDocument));
+
+        try {
+            document.createCDATASection("This isn't valid for HTML documents")
+        } catch (e) {
+            println(`Exception: ${e.name}`);
+        }
+
+        try {
+            const cdataWithAnEndDelimiter = xmlDocument.createCDATASection("This: ']]>' is a CDATA end delimiter");
+        } catch (e) {
+            println(`Exception: ${e.name}`);
+        }
+    });
+</script>

+ 16 - 0
Userland/Libraries/LibWeb/DOM/Document.cpp

@@ -25,6 +25,7 @@
 #include <LibWeb/CSS/VisualViewport.h>
 #include <LibWeb/Cookie/ParsedCookie.h>
 #include <LibWeb/DOM/Attr.h>
+#include <LibWeb/DOM/CDATASection.h>
 #include <LibWeb/DOM/Comment.h>
 #include <LibWeb/DOM/CustomEvent.h>
 #include <LibWeb/DOM/DOMImplementation.h>
@@ -1473,6 +1474,21 @@ JS::NonnullGCPtr<Text> Document::create_text_node(String const& data)
     return heap().allocate<Text>(realm(), *this, data);
 }
 
+// https://dom.spec.whatwg.org/#dom-document-createcdatasection
+WebIDL::ExceptionOr<JS::NonnullGCPtr<CDATASection>> Document::create_cdata_section(String const& data)
+{
+    // 1. If this is an HTML document, then throw a "NotSupportedError" DOMException.
+    if (is_html_document())
+        return WebIDL::NotSupportedError::create(realm(), "This operation is not supported for HTML documents"_fly_string);
+
+    // 2. If data contains the string "]]>", then throw an "InvalidCharacterError" DOMException.
+    if (data.contains("]]>"sv))
+        return WebIDL::InvalidCharacterError::create(realm(), "String may not contain ']]>'"_fly_string);
+
+    // 3. Return a new CDATASection node with its data set to data and node document set to this.
+    return heap().allocate<CDATASection>(realm(), *this, data);
+}
+
 JS::NonnullGCPtr<Comment> Document::create_comment(String const& data)
 {
     return heap().allocate<Comment>(realm(), *this, data);

+ 1 - 0
Userland/Libraries/LibWeb/DOM/Document.h

@@ -242,6 +242,7 @@ public:
     WebIDL::ExceptionOr<JS::NonnullGCPtr<Element>> create_element_ns(Optional<FlyString> const& namespace_, String const& qualified_name, Variant<String, ElementCreationOptions> const& options);
     JS::NonnullGCPtr<DocumentFragment> create_document_fragment();
     JS::NonnullGCPtr<Text> create_text_node(String const& data);
+    WebIDL::ExceptionOr<JS::NonnullGCPtr<CDATASection>> create_cdata_section(String const& data);
     JS::NonnullGCPtr<Comment> create_comment(String const& data);
     WebIDL::ExceptionOr<JS::NonnullGCPtr<ProcessingInstruction>> create_processing_instruction(String const& target, String const& data);
 

+ 2 - 0
Userland/Libraries/LibWeb/DOM/Document.idl

@@ -1,5 +1,6 @@
 #import <Animations/DocumentTimeline.idl>
 #import <CSS/StyleSheetList.idl>
+#import <DOM/CDATASection.idl>
 #import <DOM/Comment.idl>
 #import <DOM/DOMImplementation.idl>
 #import <DOM/DocumentFragment.idl>
@@ -80,6 +81,7 @@ interface Document : Node {
     [CEReactions, NewObject] Element createElementNS([FlyString] DOMString? namespace, DOMString qualifiedName, optional (DOMString or ElementCreationOptions) options = {});
     DocumentFragment createDocumentFragment();
     Text createTextNode(DOMString data);
+    [NewObject] CDATASection createCDATASection(DOMString data);
     Comment createComment(DOMString data);
     [NewObject] ProcessingInstruction createProcessingInstruction(DOMString target, DOMString data);
 

+ 2 - 1
Userland/Libraries/LibWeb/DOM/Node.cpp

@@ -15,6 +15,7 @@
 #include <LibWeb/Bindings/MainThreadVM.h>
 #include <LibWeb/Bindings/NodePrototype.h>
 #include <LibWeb/DOM/Attr.h>
+#include <LibWeb/DOM/CDATASection.h>
 #include <LibWeb/DOM/Comment.h>
 #include <LibWeb/DOM/DocumentType.h>
 #include <LibWeb/DOM/Element.h>
@@ -360,7 +361,7 @@ WebIDL::ExceptionOr<void> Node::ensure_pre_insertion_validity(JS::NonnullGCPtr<N
 
     // FIXME: All the following "Invalid node type for insertion" messages could be more descriptive.
     // 4. If node is not a DocumentFragment, DocumentType, Element, or CharacterData node, then throw a "HierarchyRequestError" DOMException.
-    if (!is<DocumentFragment>(*node) && !is<DocumentType>(*node) && !is<Element>(*node) && !is<Text>(*node) && !is<Comment>(*node) && !is<ProcessingInstruction>(*node))
+    if (!is<DocumentFragment>(*node) && !is<DocumentType>(*node) && !is<Element>(*node) && !is<Text>(*node) && !is<Comment>(*node) && !is<ProcessingInstruction>(*node) && !is<CDATASection>(*node))
         return WebIDL::HierarchyRequestError::create(realm(), "Invalid node type for insertion"_fly_string);
 
     // 5. If either node is a Text node and parent is a document, or node is a doctype and parent is not a document, then throw a "HierarchyRequestError" DOMException.