summaryrefslogtreecommitdiff
path: root/Libraries/LibWeb/DOM
diff options
context:
space:
mode:
authorAndreas Kling <kling@serenityos.org>2020-08-03 20:30:02 +0200
committerAndreas Kling <kling@serenityos.org>2020-08-03 20:30:02 +0200
commitd367044e67e17316521aa82a72698a3ea3914014 (patch)
tree703735f7e585070d61b1c3ac7a19bee19535aed1 /Libraries/LibWeb/DOM
parent6e221adade45fa4dfc6408c2636b0ddc1a350911 (diff)
downloadserenity-d367044e67e17316521aa82a72698a3ea3914014.zip
LibWeb: Move "element sibling" getters to NonDocumentTypeChildNode
Here's another CRTP mixin since that's the best we can do with C++. This prepares exposing these via IDL on Element and CharacterData.
Diffstat (limited to 'Libraries/LibWeb/DOM')
-rw-r--r--Libraries/LibWeb/DOM/CharacterData.h5
-rw-r--r--Libraries/LibWeb/DOM/Element.h6
-rw-r--r--Libraries/LibWeb/DOM/Node.cpp18
-rw-r--r--Libraries/LibWeb/DOM/Node.h3
-rw-r--r--Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h63
5 files changed, 72 insertions, 23 deletions
diff --git a/Libraries/LibWeb/DOM/CharacterData.h b/Libraries/LibWeb/DOM/CharacterData.h
index 4d2a9fd194..55688f2e6e 100644
--- a/Libraries/LibWeb/DOM/CharacterData.h
+++ b/Libraries/LibWeb/DOM/CharacterData.h
@@ -28,10 +28,13 @@
#include <AK/String.h>
#include <LibWeb/DOM/Node.h>
+#include <LibWeb/DOM/NonDocumentTypeChildNode.h>
namespace Web::DOM {
-class CharacterData : public Node {
+class CharacterData
+ : public Node
+ , public NonDocumentTypeChildNode<CharacterData> {
public:
virtual ~CharacterData() override;
diff --git a/Libraries/LibWeb/DOM/Element.h b/Libraries/LibWeb/DOM/Element.h
index 9b2b18adc4..77d54c4940 100644
--- a/Libraries/LibWeb/DOM/Element.h
+++ b/Libraries/LibWeb/DOM/Element.h
@@ -30,13 +30,17 @@
#include <AK/String.h>
#include <LibWeb/DOM/Attribute.h>
#include <LibWeb/DOM/AttributeNames.h>
+#include <LibWeb/DOM/NonDocumentTypeChildNode.h>
#include <LibWeb/DOM/ParentNode.h>
#include <LibWeb/DOM/TagNames.h>
#include <LibWeb/Layout/LayoutNode.h>
namespace Web::DOM {
-class Element : public ParentNode {
+class Element
+ : public ParentNode
+ , public NonDocumentTypeChildNode<Element> {
+
public:
using WrapperType = Bindings::ElementWrapper;
diff --git a/Libraries/LibWeb/DOM/Node.cpp b/Libraries/LibWeb/DOM/Node.cpp
index 4370a540c6..b6a51ddfe2 100644
--- a/Libraries/LibWeb/DOM/Node.cpp
+++ b/Libraries/LibWeb/DOM/Node.cpp
@@ -92,24 +92,6 @@ String Node::text_content() const
return builder.to_string();
}
-const Element* Node::next_element_sibling() const
-{
- for (auto* node = next_sibling(); node; node = node->next_sibling()) {
- if (node->is_element())
- return static_cast<const Element*>(node);
- }
- return nullptr;
-}
-
-const Element* Node::previous_element_sibling() const
-{
- for (auto* node = previous_sibling(); node; node = node->previous_sibling()) {
- if (node->is_element())
- return static_cast<const Element*>(node);
- }
- return nullptr;
-}
-
RefPtr<LayoutNode> Node::create_layout_node(const CSS::StyleProperties*)
{
return nullptr;
diff --git a/Libraries/LibWeb/DOM/Node.h b/Libraries/LibWeb/DOM/Node.h
index 1bf2ab9d9b..1e23180806 100644
--- a/Libraries/LibWeb/DOM/Node.h
+++ b/Libraries/LibWeb/DOM/Node.h
@@ -120,9 +120,6 @@ public:
void set_layout_node(Badge<LayoutNode>, LayoutNode* layout_node) const { m_layout_node = layout_node; }
- const Element* previous_element_sibling() const;
- const Element* next_element_sibling() const;
-
virtual bool is_child_allowed(const Node&) const { return true; }
bool needs_style_update() const { return m_needs_style_update; }
diff --git a/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h b/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h
new file mode 100644
index 0000000000..720edd2429
--- /dev/null
+++ b/Libraries/LibWeb/DOM/NonDocumentTypeChildNode.h
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2020, Andreas Kling <kling@serenityos.org>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include <AK/Forward.h>
+#include <LibWeb/Forward.h>
+#include <LibWeb/TreeNode.h>
+
+namespace Web::DOM {
+
+template<typename NodeType>
+class NonDocumentTypeChildNode {
+public:
+ Element* previous_element_sibling()
+ {
+ for (auto* sibling = static_cast<NodeType*>(this)->previous_sibling(); sibling; sibling = sibling->previous_sibling()) {
+ if (is<Element>(*sibling))
+ return downcast<Element>(sibling);
+ }
+ return nullptr;
+ }
+
+ Element* next_element_sibling()
+ {
+ for (auto* sibling = static_cast<NodeType*>(this)->next_sibling(); sibling; sibling = sibling->next_sibling()) {
+ if (is<Element>(*sibling))
+ return downcast<Element>(sibling);
+ }
+ return nullptr;
+ }
+
+ const Element* previous_element_sibling() const { return const_cast<NonDocumentTypeChildNode*>(this)->previous_element_sibling(); }
+ const Element* next_element_sibling() const { return const_cast<NonDocumentTypeChildNode*>(this)->next_element_sibling(); }
+
+protected:
+ NonDocumentTypeChildNode() { }
+};
+
+}