|
@@ -35,6 +35,37 @@
|
|
|
|
|
|
|
|
namespace Rml {
|
|
namespace Rml {
|
|
|
|
|
|
|
|
|
|
+static int NodeIndexInParent(const Node* node)
|
|
|
|
|
+{
|
|
|
|
|
+ const Node* parent = node->GetParentNode();
|
|
|
|
|
+ if (!parent)
|
|
|
|
|
+ return -1;
|
|
|
|
|
+
|
|
|
|
|
+ int index = 0;
|
|
|
|
|
+ for (const Node* sibling : parent->IterateChildren<Node>())
|
|
|
|
|
+ {
|
|
|
|
|
+ if (sibling == node)
|
|
|
|
|
+ return index;
|
|
|
|
|
+ index++;
|
|
|
|
|
+ }
|
|
|
|
|
+ return -1;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+NodePtrProxy::NodePtrProxy(NodePtr node) : node(std::move(node)) {}
|
|
|
|
|
+NodePtrProxy::NodePtrProxy(ElementPtr element) : node(As<NodePtr>(std::move(element))) {}
|
|
|
|
|
+Node* NodePtrProxy::Get()
|
|
|
|
|
+{
|
|
|
|
|
+ return node.get();
|
|
|
|
|
+}
|
|
|
|
|
+NodePtr NodePtrProxy::Extract()
|
|
|
|
|
+{
|
|
|
|
|
+ return std::move(node);
|
|
|
|
|
+}
|
|
|
|
|
+NodePtrProxy::operator bool() const
|
|
|
|
|
+{
|
|
|
|
|
+ return node != nullptr;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
Node::Node() {}
|
|
Node::Node() {}
|
|
|
|
|
|
|
|
Node::~Node()
|
|
Node::~Node()
|
|
@@ -67,18 +98,18 @@ bool Node::HasChildNodes() const
|
|
|
return (int)children.size() > num_non_dom_children;
|
|
return (int)children.size() > num_non_dom_children;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Node* Node::AppendChild(NodePtr child, bool dom_node)
|
|
|
|
|
|
|
+Node* Node::AppendChild(NodePtrProxy child, bool dom_node)
|
|
|
{
|
|
{
|
|
|
- RMLUI_ASSERT(child && child.get() != this);
|
|
|
|
|
- Node* child_ptr = child.get();
|
|
|
|
|
|
|
+ RMLUI_ASSERT(child && child.Get() != this);
|
|
|
|
|
+ Node* child_ptr = child.Get();
|
|
|
if (dom_node)
|
|
if (dom_node)
|
|
|
{
|
|
{
|
|
|
auto it_end = children.end();
|
|
auto it_end = children.end();
|
|
|
- children.insert(it_end - num_non_dom_children, std::move(child));
|
|
|
|
|
|
|
+ children.insert(it_end - num_non_dom_children, child.Extract());
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- children.push_back(std::move(child));
|
|
|
|
|
|
|
+ children.push_back(child.Extract());
|
|
|
num_non_dom_children++;
|
|
num_non_dom_children++;
|
|
|
}
|
|
}
|
|
|
// Set parent just after inserting into children. This allows us to e.g. get our previous sibling in SetParent.
|
|
// Set parent just after inserting into children. This allows us to e.g. get our previous sibling in SetParent.
|
|
@@ -89,7 +120,7 @@ Node* Node::AppendChild(NodePtr child, bool dom_node)
|
|
|
return child_ptr;
|
|
return child_ptr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Node* Node::InsertBefore(NodePtr child, Node* adjacent_node)
|
|
|
|
|
|
|
+Node* Node::InsertBefore(NodePtrProxy child, Node* adjacent_node)
|
|
|
{
|
|
{
|
|
|
RMLUI_ASSERT(child);
|
|
RMLUI_ASSERT(child);
|
|
|
// Find the position in the list of children of the adjacent element. If it's nullptr, or we can't find it, then we
|
|
// Find the position in the list of children of the adjacent element. If it's nullptr, or we can't find it, then we
|
|
@@ -112,40 +143,40 @@ Node* Node::InsertBefore(NodePtr child, Node* adjacent_node)
|
|
|
|
|
|
|
|
if (found_child)
|
|
if (found_child)
|
|
|
{
|
|
{
|
|
|
- child_ptr = child.get();
|
|
|
|
|
|
|
+ child_ptr = child.Get();
|
|
|
|
|
|
|
|
const bool dom_node = ((int)child_index < GetNumChildNodes());
|
|
const bool dom_node = ((int)child_index < GetNumChildNodes());
|
|
|
if (!dom_node)
|
|
if (!dom_node)
|
|
|
num_non_dom_children++;
|
|
num_non_dom_children++;
|
|
|
|
|
|
|
|
- children.insert(children.begin() + child_index, std::move(child));
|
|
|
|
|
|
|
+ children.insert(children.begin() + child_index, child.Extract());
|
|
|
child_ptr->SetParent(this);
|
|
child_ptr->SetParent(this);
|
|
|
|
|
|
|
|
OnChildNodeAdd(child_ptr, dom_node);
|
|
OnChildNodeAdd(child_ptr, dom_node);
|
|
|
}
|
|
}
|
|
|
else
|
|
else
|
|
|
{
|
|
{
|
|
|
- child_ptr = AppendChild(std::move(child));
|
|
|
|
|
|
|
+ child_ptr = AppendChild(child.Extract());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
return child_ptr;
|
|
return child_ptr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-NodePtr Node::ReplaceChild(NodePtr insert_node, Node* replace_node)
|
|
|
|
|
|
|
+NodePtr Node::ReplaceChild(NodePtrProxy insert_node, Node* replace_node)
|
|
|
{
|
|
{
|
|
|
RMLUI_ASSERT(insert_node);
|
|
RMLUI_ASSERT(insert_node);
|
|
|
auto it_replace = std::find_if(children.begin(), children.end(), [replace_node](const NodePtr& node) { return node.get() == replace_node; });
|
|
auto it_replace = std::find_if(children.begin(), children.end(), [replace_node](const NodePtr& node) { return node.get() == replace_node; });
|
|
|
if (it_replace == children.end())
|
|
if (it_replace == children.end())
|
|
|
{
|
|
{
|
|
|
- AppendChild(std::move(insert_node));
|
|
|
|
|
|
|
+ AppendChild(insert_node.Extract());
|
|
|
return nullptr;
|
|
return nullptr;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
const std::ptrdiff_t replace_index = std::distance(children.begin(), it_replace);
|
|
const std::ptrdiff_t replace_index = std::distance(children.begin(), it_replace);
|
|
|
const bool dom_node = (replace_index < (std::ptrdiff_t)children.size() - num_non_dom_children);
|
|
const bool dom_node = (replace_index < (std::ptrdiff_t)children.size() - num_non_dom_children);
|
|
|
|
|
|
|
|
- Node* inserted_node_ptr = insert_node.get();
|
|
|
|
|
- children.insert(children.begin() + replace_index, std::move(insert_node));
|
|
|
|
|
|
|
+ Node* inserted_node_ptr = insert_node.Get();
|
|
|
|
|
+ children.insert(children.begin() + replace_index, insert_node.Extract());
|
|
|
if (!dom_node)
|
|
if (!dom_node)
|
|
|
num_non_dom_children++;
|
|
num_non_dom_children++;
|
|
|
inserted_node_ptr->SetParent(this);
|
|
inserted_node_ptr->SetParent(this);
|
|
@@ -178,34 +209,34 @@ NodePtr Node::RemoveChild(Node* child)
|
|
|
return detached_child;
|
|
return detached_child;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Element* Node::AppendChild(ElementPtr child, bool dom_element)
|
|
|
|
|
|
|
+Element* Node::GetParentElement() const
|
|
|
{
|
|
{
|
|
|
- return rmlui_static_cast<Element*>(AppendChild(As<NodePtr>(std::move(child)), dom_element));
|
|
|
|
|
|
|
+ return AsIf<Element*>(GetParentNode());
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Element* Node::InsertBefore(ElementPtr child, Element* adjacent_element)
|
|
|
|
|
|
|
+Node* Node::GetParentNode() const
|
|
|
{
|
|
{
|
|
|
- return rmlui_static_cast<Element*>(InsertBefore(As<NodePtr>(std::move(child)), adjacent_element));
|
|
|
|
|
|
|
+ return parent;
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-ElementPtr Node::ReplaceChild(ElementPtr inserted_element, Element* replaced_element)
|
|
|
|
|
|
|
+Node* Node::GetNextSibling() const
|
|
|
{
|
|
{
|
|
|
- return As<ElementPtr>(ReplaceChild(As<NodePtr>(std::move(inserted_element)), replaced_element));
|
|
|
|
|
|
|
+ return GetChildNode(NodeIndexInParent(this) + 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-ElementPtr Node::RemoveChild(Element* child)
|
|
|
|
|
|
|
+Node* Node::GetPreviousSibling() const
|
|
|
{
|
|
{
|
|
|
- return As<ElementPtr>(RemoveChild(As<Node*>(child)));
|
|
|
|
|
|
|
+ return GetChildNode(NodeIndexInParent(this) - 1);
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Element* Node::GetParentNode() const
|
|
|
|
|
|
|
+Node* Node::GetFirstChild() const
|
|
|
{
|
|
{
|
|
|
- return GetParentElement();
|
|
|
|
|
|
|
+ return children.empty() ? nullptr : children.front().get();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-Element* Node::GetParentElement() const
|
|
|
|
|
|
|
+Node* Node::GetLastChild() const
|
|
|
{
|
|
{
|
|
|
- return rmlui_dynamic_cast<Element*>(parent);
|
|
|
|
|
|
|
+ return children.empty() ? nullptr : children.back().get();
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ElementDocument* Node::GetOwnerDocument() const
|
|
ElementDocument* Node::GetOwnerDocument() const
|