mirror of
https://github.com/LadybirdBrowser/ladybird.git
synced 2025-12-07 21:59:54 +00:00
LibWeb: Implement stubs for XPathEvaluator
This commit is contained in:
parent
1ae7ecc3e9
commit
f04b866cb0
Notes:
github-actions[bot]
2025-10-03 11:17:46 +00:00
Author: https://github.com/johannesg 🔰
Commit: f04b866cb0
Pull-request: https://github.com/LadybirdBrowser/ladybird/pull/6342
Reviewed-by: https://github.com/AtkinsSJ
Reviewed-by: https://github.com/gmta ✅
17 changed files with 441 additions and 1 deletions
56
Libraries/LibWeb/XPath/XPathEvaluator.cpp
Normal file
56
Libraries/LibWeb/XPath/XPathEvaluator.cpp
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Bindings/XPathEvaluatorPrototype.h>
|
||||
#include <LibWeb/WebIDL/ExceptionOr.h>
|
||||
|
||||
#include "XPathEvaluator.h"
|
||||
#include "XPathExpression.h"
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(XPathEvaluator);
|
||||
|
||||
XPathEvaluator::XPathEvaluator(JS::Realm& realm)
|
||||
: Web::Bindings::PlatformObject(realm)
|
||||
{
|
||||
}
|
||||
|
||||
XPathEvaluator::~XPathEvaluator() = default;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathEvaluator>> XPathEvaluator::construct_impl(JS::Realm& realm)
|
||||
{
|
||||
return realm.create<XPathEvaluator>(realm);
|
||||
}
|
||||
|
||||
void XPathEvaluator::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(XPathEvaluator);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathExpression>> XPathEvaluator::create_expression(String const& expression, GC::Ptr<XPathNSResolver> resolver)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
return realm.create<XPathExpression>(realm, expression, resolver);
|
||||
}
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathResult>> XPathEvaluator::evaluate(String const&, DOM::Node const&, GC::Ptr<XPathNSResolver>, WebIDL::UnsignedShort, GC::Ptr<XPathResult>)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
return realm.create<XPathResult>(realm);
|
||||
}
|
||||
|
||||
GC::Ref<DOM::Node> XPathEvaluator::create_ns_resolver(GC::Ref<DOM::Node> node_resolver)
|
||||
{
|
||||
return node_resolver;
|
||||
}
|
||||
|
||||
}
|
||||
35
Libraries/LibWeb/XPath/XPathEvaluator.h
Normal file
35
Libraries/LibWeb/XPath/XPathEvaluator.h
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
#include "XPathExpression.h"
|
||||
#include "XPathNSResolver.h"
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
class XPathEvaluator : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(XPathEvaluator, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(XPathEvaluator);
|
||||
|
||||
explicit XPathEvaluator(JS::Realm&);
|
||||
virtual ~XPathEvaluator() override;
|
||||
|
||||
public:
|
||||
static WebIDL::ExceptionOr<GC::Ref<XPathEvaluator>> construct_impl(JS::Realm&);
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathExpression>> create_expression(String const& expression, GC::Ptr<XPathNSResolver> resolver = nullptr);
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathResult>> evaluate(String const& expression, DOM::Node const& context_node, GC::Ptr<XPathNSResolver> resolver = nullptr, WebIDL::UnsignedShort type = 0, GC::Ptr<XPathResult> result = nullptr);
|
||||
static GC::Ref<DOM::Node> create_ns_resolver(GC::Ref<DOM::Node> node_resolver); // legacy
|
||||
};
|
||||
|
||||
}
|
||||
24
Libraries/LibWeb/XPath/XPathEvaluator.idl
Normal file
24
Libraries/LibWeb/XPath/XPathEvaluator.idl
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
#import <DOM/Node.idl>
|
||||
|
||||
// FIXME: callback interfaces are not currently supported
|
||||
// callback interface XPathNSResolver {
|
||||
// DOMString? lookupNamespaceURI(DOMString? prefix);
|
||||
// };
|
||||
|
||||
// https://dom.spec.whatwg.org/#mixin-xpathevaluatorbase
|
||||
interface mixin XPathEvaluatorBase {
|
||||
[NewObject] XPathExpression createExpression(DOMString expression, optional XPathNSResolver? resolver = null);
|
||||
Node createNSResolver(Node nodeResolver); // legacy
|
||||
// XPathResult.ANY_TYPE = 0
|
||||
XPathResult evaluate(DOMString expression, Node contextNode, optional XPathNSResolver? resolver = null, optional unsigned short type = 0, optional XPathResult? result = null);
|
||||
};
|
||||
Document includes XPathEvaluatorBase;
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-xpathevaluator
|
||||
[Exposed=Window]
|
||||
interface XPathEvaluator {
|
||||
constructor();
|
||||
};
|
||||
|
||||
XPathEvaluator includes XPathEvaluatorBase;
|
||||
|
||||
49
Libraries/LibWeb/XPath/XPathExpression.cpp
Normal file
49
Libraries/LibWeb/XPath/XPathExpression.cpp
Normal file
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Bindings/XPathExpressionPrototype.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
#include "XPathEvaluator.h"
|
||||
#include "XPathExpression.h"
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(XPathExpression);
|
||||
|
||||
XPathExpression::XPathExpression(JS::Realm& realm, String const& expression, GC::Ptr<XPathNSResolver> resolver)
|
||||
: Web::Bindings::PlatformObject(realm)
|
||||
, m_expression(expression)
|
||||
, m_resolver(resolver)
|
||||
{
|
||||
}
|
||||
|
||||
void XPathExpression::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(XPathExpression);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void XPathExpression::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_resolver);
|
||||
}
|
||||
|
||||
XPathExpression::~XPathExpression() = default;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathResult>> XPathExpression::evaluate(DOM::Node const&, WebIDL::UnsignedShort, GC::Ptr<XPathResult>)
|
||||
{
|
||||
auto& realm = this->realm();
|
||||
return realm.create<XPathResult>(realm);
|
||||
}
|
||||
|
||||
}
|
||||
34
Libraries/LibWeb/XPath/XPathExpression.h
Normal file
34
Libraries/LibWeb/XPath/XPathExpression.h
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
class XPathExpression final : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(XPathExpression, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(XPathExpression);
|
||||
|
||||
public:
|
||||
explicit XPathExpression(JS::Realm&, String const& expression, GC::Ptr<XPathNSResolver> resolver);
|
||||
virtual ~XPathExpression() override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
|
||||
WebIDL::ExceptionOr<GC::Ref<XPathResult>> evaluate(DOM::Node const& context_node, WebIDL::UnsignedShort type = 0, GC::Ptr<XPathResult> result = nullptr);
|
||||
|
||||
private:
|
||||
String m_expression;
|
||||
GC::Ptr<XPathNSResolver> m_resolver;
|
||||
};
|
||||
|
||||
}
|
||||
9
Libraries/LibWeb/XPath/XPathExpression.idl
Normal file
9
Libraries/LibWeb/XPath/XPathExpression.idl
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#import <XPath/XPathResult.idl>
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-xpathexpression
|
||||
[Exposed=Window]
|
||||
interface XPathExpression {
|
||||
// XPathResult.ANY_TYPE = 0
|
||||
XPathResult evaluate(Node contextNode, optional unsigned short type = 0, optional XPathResult? result = null);
|
||||
};
|
||||
|
||||
35
Libraries/LibWeb/XPath/XPathNSResolver.cpp
Normal file
35
Libraries/LibWeb/XPath/XPathNSResolver.cpp
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Object.h>
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/WebIDL/CallbackType.h>
|
||||
|
||||
#include "XPathNSResolver.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(XPathNSResolver);
|
||||
|
||||
GC::Ref<XPathNSResolver> XPathNSResolver::create(JS::Realm& realm, GC::Ref<WebIDL::CallbackType> callback)
|
||||
{
|
||||
return realm.create<XPathNSResolver>(realm, callback);
|
||||
}
|
||||
|
||||
XPathNSResolver::XPathNSResolver(JS::Realm& realm, GC::Ref<WebIDL::CallbackType> callback)
|
||||
: JS::Object(ConstructWithPrototypeTag::Tag, realm.intrinsics().object_prototype())
|
||||
, m_callback(callback)
|
||||
{
|
||||
}
|
||||
|
||||
void XPathNSResolver::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_callback);
|
||||
}
|
||||
|
||||
}
|
||||
31
Libraries/LibWeb/XPath/XPathNSResolver.h
Normal file
31
Libraries/LibWeb/XPath/XPathNSResolver.h
Normal file
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
class XPathNSResolver final : public JS::Object {
|
||||
JS_OBJECT(XPathNSResolver, JS::Object);
|
||||
GC_DECLARE_ALLOCATOR(XPathNSResolver);
|
||||
|
||||
public:
|
||||
[[nodiscard]] static GC::Ref<XPathNSResolver> create(JS::Realm&, GC::Ref<WebIDL::CallbackType>);
|
||||
XPathNSResolver(JS::Realm&, GC::Ref<WebIDL::CallbackType>);
|
||||
|
||||
virtual ~XPathNSResolver() = default;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
private:
|
||||
GC::Ref<WebIDL::CallbackType> m_callback;
|
||||
};
|
||||
|
||||
}
|
||||
55
Libraries/LibWeb/XPath/XPathResult.cpp
Normal file
55
Libraries/LibWeb/XPath/XPathResult.cpp
Normal file
|
|
@ -0,0 +1,55 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#include <LibJS/Runtime/Realm.h>
|
||||
#include <LibWeb/Bindings/Intrinsics.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Bindings/XPathResultPrototype.h>
|
||||
#include <LibWeb/DOM/Node.h>
|
||||
|
||||
#include "XPathResult.h"
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
GC_DEFINE_ALLOCATOR(XPathResult);
|
||||
|
||||
XPathResult::XPathResult(JS::Realm& realm)
|
||||
: Web::Bindings::PlatformObject(realm)
|
||||
{
|
||||
m_node_set_iter = m_node_set.end();
|
||||
}
|
||||
|
||||
void XPathResult::initialize(JS::Realm& realm)
|
||||
{
|
||||
WEB_SET_PROTOTYPE_FOR_INTERFACE(XPathResult);
|
||||
Base::initialize(realm);
|
||||
}
|
||||
|
||||
void XPathResult::visit_edges(Cell::Visitor& visitor)
|
||||
{
|
||||
Base::visit_edges(visitor);
|
||||
visitor.visit(m_node_set);
|
||||
}
|
||||
|
||||
XPathResult::~XPathResult() = default;
|
||||
|
||||
GC::Ptr<DOM::Node> XPathResult::iterate_next()
|
||||
{
|
||||
if (m_node_set_iter == m_node_set.end())
|
||||
return nullptr;
|
||||
|
||||
return *m_node_set_iter++;
|
||||
}
|
||||
|
||||
GC::Ptr<DOM::Node> XPathResult::snapshot_item(int index)
|
||||
{
|
||||
if (index < 0 || static_cast<size_t>(index) >= m_node_set.size())
|
||||
return nullptr;
|
||||
|
||||
return m_node_set.at(index);
|
||||
}
|
||||
|
||||
}
|
||||
61
Libraries/LibWeb/XPath/XPathResult.h
Normal file
61
Libraries/LibWeb/XPath/XPathResult.h
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
/*
|
||||
* Copyright (c) 2025, Johannes Gustafsson <johannesgu@outlook.com>
|
||||
*
|
||||
* SPDX-License-Identifier: BSD-2-Clause
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <AK/String.h>
|
||||
#include <AK/Vector.h>
|
||||
#include <LibWeb/Bindings/PlatformObject.h>
|
||||
#include <LibWeb/Forward.h>
|
||||
#include <LibWeb/WebIDL/Types.h>
|
||||
|
||||
namespace Web::XPath {
|
||||
|
||||
class XPathResult : public Bindings::PlatformObject {
|
||||
WEB_PLATFORM_OBJECT(XPathResult, Bindings::PlatformObject);
|
||||
GC_DECLARE_ALLOCATOR(XPathResult);
|
||||
|
||||
public:
|
||||
static WebIDL::UnsignedShort const ANY_TYPE = 0;
|
||||
static WebIDL::UnsignedShort const NUMBER_TYPE = 1;
|
||||
static WebIDL::UnsignedShort const STRING_TYPE = 2;
|
||||
static WebIDL::UnsignedShort const BOOLEAN_TYPE = 3;
|
||||
static WebIDL::UnsignedShort const UNORDERED_NODE_ITERATOR_TYPE = 4;
|
||||
static WebIDL::UnsignedShort const ORDERED_NODE_ITERATOR_TYPE = 5;
|
||||
static WebIDL::UnsignedShort const UNORDERED_NODE_SNAPSHOT_TYPE = 6;
|
||||
static WebIDL::UnsignedShort const ORDERED_NODE_SNAPSHOT_TYPE = 7;
|
||||
static WebIDL::UnsignedShort const ANY_UNORDERED_NODE_TYPE = 8;
|
||||
static WebIDL::UnsignedShort const FIRST_ORDERED_NODE_TYPE = 9;
|
||||
|
||||
XPathResult(JS::Realm&);
|
||||
virtual ~XPathResult() override;
|
||||
virtual void initialize(JS::Realm&) override;
|
||||
virtual void visit_edges(Cell::Visitor&) override;
|
||||
|
||||
WebIDL::UnsignedShort result_type() const { return m_result_type; }
|
||||
WebIDL::Double number_value() const { return m_number_value; }
|
||||
String string_value() { return m_string_value; }
|
||||
WebIDL::Boolean boolean_value() const { return m_boolean_value; }
|
||||
GC::Ptr<DOM::Node> single_node_value() { return m_node_set.is_empty() ? nullptr : m_node_set.first(); }
|
||||
WebIDL::Boolean invalid_iterator_state() const { return m_invalid_iterator_state; }
|
||||
WebIDL::UnsignedLong snapshot_length() const { return m_node_set.size(); }
|
||||
|
||||
GC::Ptr<DOM::Node> iterate_next();
|
||||
GC::Ptr<DOM::Node> snapshot_item(int index);
|
||||
|
||||
private:
|
||||
WebIDL::UnsignedShort m_result_type;
|
||||
WebIDL::Double m_number_value;
|
||||
String m_string_value;
|
||||
WebIDL::Boolean m_boolean_value;
|
||||
WebIDL::Boolean m_invalid_iterator_state;
|
||||
WebIDL::UnsignedLong m_snapshot_length;
|
||||
|
||||
Vector<GC::Ptr<DOM::Node>> m_node_set;
|
||||
Vector<GC::Ptr<DOM::Node>>::Iterator m_node_set_iter;
|
||||
};
|
||||
|
||||
}
|
||||
29
Libraries/LibWeb/XPath/XPathResult.idl
Normal file
29
Libraries/LibWeb/XPath/XPathResult.idl
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
#import <DOM/Node.idl>
|
||||
|
||||
// https://dom.spec.whatwg.org/#interface-xpathresult
|
||||
[Exposed=Window]
|
||||
interface XPathResult {
|
||||
const unsigned short ANY_TYPE = 0;
|
||||
const unsigned short NUMBER_TYPE = 1;
|
||||
const unsigned short STRING_TYPE = 2;
|
||||
const unsigned short BOOLEAN_TYPE = 3;
|
||||
const unsigned short UNORDERED_NODE_ITERATOR_TYPE = 4;
|
||||
const unsigned short ORDERED_NODE_ITERATOR_TYPE = 5;
|
||||
const unsigned short UNORDERED_NODE_SNAPSHOT_TYPE = 6;
|
||||
const unsigned short ORDERED_NODE_SNAPSHOT_TYPE = 7;
|
||||
const unsigned short ANY_UNORDERED_NODE_TYPE = 8;
|
||||
const unsigned short FIRST_ORDERED_NODE_TYPE = 9;
|
||||
|
||||
readonly attribute unsigned short resultType;
|
||||
readonly attribute unrestricted double numberValue;
|
||||
readonly attribute DOMString stringValue;
|
||||
readonly attribute boolean booleanValue;
|
||||
readonly attribute Node? singleNodeValue;
|
||||
readonly attribute boolean invalidIteratorState;
|
||||
readonly attribute unsigned long snapshotLength;
|
||||
|
||||
Node? iterateNext();
|
||||
Node? snapshotItem(unsigned long index);
|
||||
};
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue