diff options
Diffstat (limited to 'Libraries')
-rw-r--r-- | Libraries/LibWeb/Bindings/DocumentWrapper.cpp | 19 | ||||
-rw-r--r-- | Libraries/LibWeb/Bindings/DocumentWrapper.h | 1 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Document.cpp | 20 | ||||
-rw-r--r-- | Libraries/LibWeb/DOM/Document.h | 1 |
4 files changed, 41 insertions, 0 deletions
diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp index 13381d82a7..a74fa06b01 100644 --- a/Libraries/LibWeb/Bindings/DocumentWrapper.cpp +++ b/Libraries/LibWeb/Bindings/DocumentWrapper.cpp @@ -41,6 +41,7 @@ DocumentWrapper::DocumentWrapper(Document& document) : NodeWrapper(document) { put_native_function("getElementById", get_element_by_id, 1); + put_native_function("querySelector", query_selector, 1); put_native_function("querySelectorAll", query_selector_all, 1); } @@ -86,6 +87,23 @@ JS::Value DocumentWrapper::get_element_by_id(JS::Interpreter& interpreter) return wrap(interpreter.heap(), const_cast<Element&>(*element)); } +JS::Value DocumentWrapper::query_selector(JS::Interpreter& interpreter) +{ + auto* document = document_from(interpreter); + if (!document) + return {}; + if (!interpreter.argument_count()) + return interpreter.throw_exception<JS::TypeError>("querySelector() needs one argument"); + auto selector = interpreter.argument(0).to_string(interpreter); + if (interpreter.exception()) + return {}; + // FIXME: Throw if selector is invalid + auto element = document->query_selector(selector); + if (!element) + return JS::js_null(); + return wrap(interpreter.heap(), *element); +} + JS::Value DocumentWrapper::query_selector_all(JS::Interpreter& interpreter) { auto* document = document_from(interpreter); @@ -96,6 +114,7 @@ JS::Value DocumentWrapper::query_selector_all(JS::Interpreter& interpreter) auto selector = interpreter.argument(0).to_string(interpreter); if (interpreter.exception()) return {}; + // FIXME: Throw if selector is invalid auto elements = document->query_selector_all(selector); // FIXME: This should be a static NodeList, not a plain JS::Array. auto* node_list = JS::Array::create(interpreter.global_object()); diff --git a/Libraries/LibWeb/Bindings/DocumentWrapper.h b/Libraries/LibWeb/Bindings/DocumentWrapper.h index 86f2270ae9..9cf4c765b3 100644 --- a/Libraries/LibWeb/Bindings/DocumentWrapper.h +++ b/Libraries/LibWeb/Bindings/DocumentWrapper.h @@ -43,6 +43,7 @@ private: virtual const char* class_name() const override { return "DocumentWrapper"; } static JS::Value get_element_by_id(JS::Interpreter&); + static JS::Value query_selector(JS::Interpreter&); static JS::Value query_selector_all(JS::Interpreter&); }; diff --git a/Libraries/LibWeb/DOM/Document.cpp b/Libraries/LibWeb/DOM/Document.cpp index dec30f6e80..c01cb1c1ba 100644 --- a/Libraries/LibWeb/DOM/Document.cpp +++ b/Libraries/LibWeb/DOM/Document.cpp @@ -321,6 +321,26 @@ Vector<const Element*> Document::get_elements_by_name(const String& name) const return elements; } +RefPtr<Element> Document::query_selector(const StringView& selector_text) +{ + auto selector = parse_selector(selector_text); + if (!selector.has_value()) + return {}; + + dump_selector(selector.value()); + + RefPtr<Element> result; + for_each_in_subtree_of_type<Element>([&](auto& element) { + if (SelectorEngine::matches(selector.value(), element)) { + result = element; + return IterationDecision::Break; + } + return IterationDecision::Continue; + }); + + return result; +} + NonnullRefPtrVector<Element> Document::query_selector_all(const StringView& selector_text) { auto selector = parse_selector(selector_text); diff --git a/Libraries/LibWeb/DOM/Document.h b/Libraries/LibWeb/DOM/Document.h index dc9c88bb56..8829171c7a 100644 --- a/Libraries/LibWeb/DOM/Document.h +++ b/Libraries/LibWeb/DOM/Document.h @@ -116,6 +116,7 @@ public: void schedule_style_update(); Vector<const Element*> get_elements_by_name(const String&) const; + RefPtr<Element> query_selector(const StringView&); NonnullRefPtrVector<Element> query_selector_all(const StringView&); const String& source() const { return m_source; } |