Explorar o código

LibWeb: Add DOMParser

This allows you to invoke the HTML document parser and retrieve a
document as though it was loaded as a web page, minus any scripting
ability.

This does not currently support XML parsing.

This is used by YouTube (or more accurately, Web Components Polyfills)
to polyfill templates.
Luke %!s(int64=4) %!d(string=hai) anos
pai
achega
f7ad8c0f94

+ 3 - 0
Userland/Libraries/LibWeb/Bindings/WindowObjectHelper.h

@@ -22,6 +22,8 @@
 #include <LibWeb/Bindings/DOMExceptionPrototype.h>
 #include <LibWeb/Bindings/DOMExceptionPrototype.h>
 #include <LibWeb/Bindings/DOMImplementationConstructor.h>
 #include <LibWeb/Bindings/DOMImplementationConstructor.h>
 #include <LibWeb/Bindings/DOMImplementationPrototype.h>
 #include <LibWeb/Bindings/DOMImplementationPrototype.h>
+#include <LibWeb/Bindings/DOMParserConstructor.h>
+#include <LibWeb/Bindings/DOMParserPrototype.h>
 #include <LibWeb/Bindings/DocumentConstructor.h>
 #include <LibWeb/Bindings/DocumentConstructor.h>
 #include <LibWeb/Bindings/DocumentFragmentConstructor.h>
 #include <LibWeb/Bindings/DocumentFragmentConstructor.h>
 #include <LibWeb/Bindings/DocumentFragmentPrototype.h>
 #include <LibWeb/Bindings/DocumentFragmentPrototype.h>
@@ -247,6 +249,7 @@
     ADD_WINDOW_OBJECT_INTERFACE(DocumentType)              \
     ADD_WINDOW_OBJECT_INTERFACE(DocumentType)              \
     ADD_WINDOW_OBJECT_INTERFACE(DOMException)              \
     ADD_WINDOW_OBJECT_INTERFACE(DOMException)              \
     ADD_WINDOW_OBJECT_INTERFACE(DOMImplementation)         \
     ADD_WINDOW_OBJECT_INTERFACE(DOMImplementation)         \
+    ADD_WINDOW_OBJECT_INTERFACE(DOMParser)                 \
     ADD_WINDOW_OBJECT_INTERFACE(Element)                   \
     ADD_WINDOW_OBJECT_INTERFACE(Element)                   \
     ADD_WINDOW_OBJECT_INTERFACE(Event)                     \
     ADD_WINDOW_OBJECT_INTERFACE(Event)                     \
     ADD_WINDOW_OBJECT_INTERFACE(EventTarget)               \
     ADD_WINDOW_OBJECT_INTERFACE(EventTarget)               \

+ 2 - 0
Userland/Libraries/LibWeb/CMakeLists.txt

@@ -70,6 +70,7 @@ set(SOURCES
     HTML/AttributeNames.cpp
     HTML/AttributeNames.cpp
     HTML/BrowsingContextContainer.cpp
     HTML/BrowsingContextContainer.cpp
     HTML/CanvasRenderingContext2D.cpp
     HTML/CanvasRenderingContext2D.cpp
+    HTML/DOMParser.cpp
     HTML/EventNames.cpp
     HTML/EventNames.cpp
     HTML/FormAssociatedElement.cpp
     HTML/FormAssociatedElement.cpp
     HTML/GlobalEventHandlers.cpp
     HTML/GlobalEventHandlers.cpp
@@ -331,6 +332,7 @@ libweb_js_wrapper(DOM/Range)
 libweb_js_wrapper(DOM/Text)
 libweb_js_wrapper(DOM/Text)
 libweb_js_wrapper(HTML/CanvasRenderingContext2D)
 libweb_js_wrapper(HTML/CanvasRenderingContext2D)
 libweb_js_wrapper(HTML/CloseEvent)
 libweb_js_wrapper(HTML/CloseEvent)
+libweb_js_wrapper(HTML/DOMParser)
 libweb_js_wrapper(HTML/HTMLAnchorElement)
 libweb_js_wrapper(HTML/HTMLAnchorElement)
 libweb_js_wrapper(HTML/HTMLAreaElement)
 libweb_js_wrapper(HTML/HTMLAreaElement)
 libweb_js_wrapper(HTML/HTMLAudioElement)
 libweb_js_wrapper(HTML/HTMLAudioElement)

+ 2 - 0
Userland/Libraries/LibWeb/Forward.h

@@ -59,6 +59,7 @@ enum class QuirksMode;
 namespace Web::HTML {
 namespace Web::HTML {
 class CanvasRenderingContext2D;
 class CanvasRenderingContext2D;
 class CloseEvent;
 class CloseEvent;
+class DOMParser;
 class EventHandler;
 class EventHandler;
 class HTMLAnchorElement;
 class HTMLAnchorElement;
 class HTMLAreaElement;
 class HTMLAreaElement;
@@ -211,6 +212,7 @@ class DocumentTypeWrapper;
 class DocumentWrapper;
 class DocumentWrapper;
 class DOMExceptionWrapper;
 class DOMExceptionWrapper;
 class DOMImplementationWrapper;
 class DOMImplementationWrapper;
+class DOMParserWrapper;
 class ElementWrapper;
 class ElementWrapper;
 class EventListenerWrapper;
 class EventListenerWrapper;
 class EventTargetWrapper;
 class EventTargetWrapper;

+ 41 - 0
Userland/Libraries/LibWeb/HTML/DOMParser.cpp

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#include <LibWeb/HTML/DOMParser.h>
+#include <LibWeb/HTML/Parser/HTMLDocumentParser.h>
+
+namespace Web::HTML {
+
+DOMParser::DOMParser()
+{
+}
+
+DOMParser::~DOMParser()
+{
+}
+
+// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#dom-domparser-parsefromstring
+NonnullRefPtr<DOM::Document> DOMParser::parse_from_string(String const& string, String const& type)
+{
+    // FIXME: Pass in this's relevant global object's associated Document's URL.
+    auto document = DOM::Document::create();
+    document->set_content_type(type);
+
+    // NOTE: This isn't a case insensitive match since the DOMParserSupportedType enum enforces an all lowercase type.
+    if (type == "text/html") {
+        // FIXME: Set document's type to "html".
+        HTMLDocumentParser parser(document, string, "UTF-8");
+        // FIXME: This is to match the default URL. Instead, pass in this's relevant global object's associated Document's URL.
+        parser.run("about:blank");
+    } else {
+        dbgln("DOMParser::parse_from_string: Unimplemented parser for type: {}", type);
+        TODO();
+    }
+
+    return document;
+}
+
+}

+ 39 - 0
Userland/Libraries/LibWeb/HTML/DOMParser.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2021, Luke Wilde <lukew@serenityos.org>
+ *
+ * SPDX-License-Identifier: BSD-2-Clause
+ */
+
+#pragma once
+
+#include <AK/RefCounted.h>
+#include <AK/Weakable.h>
+#include <LibWeb/Bindings/Wrappable.h>
+#include <LibWeb/DOM/Document.h>
+#include <LibWeb/DOM/ExceptionOr.h>
+#include <LibWeb/Forward.h>
+
+namespace Web::HTML {
+
+// https://html.spec.whatwg.org/multipage/dynamic-markup-insertion.html#domparser
+class DOMParser final
+    : public RefCounted<DOMParser>
+    , public Weakable<DOMParser>
+    , public Bindings::Wrappable {
+public:
+    using WrapperType = Bindings::DOMParserWrapper;
+
+    static DOM::ExceptionOr<NonnullRefPtr<DOMParser>> create_with_global_object(Bindings::WindowObject&)
+    {
+        return adopt_ref(*new DOMParser());
+    }
+
+    virtual ~DOMParser() override;
+
+    NonnullRefPtr<DOM::Document> parse_from_string(String const&, String const&);
+
+private:
+    DOMParser();
+};
+
+}

+ 6 - 0
Userland/Libraries/LibWeb/HTML/DOMParser.idl

@@ -0,0 +1,6 @@
+interface DOMParser {
+    constructor();
+
+    // FIXME: "type" should use the DOMParserSupportedType enum.
+    Document parseFromString(DOMString string, DOMString type);
+};