summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/CSS.cpp66
-rw-r--r--src/core/CSS.hpp68
-rw-r--r--test/core/CSSTest.cpp54
3 files changed, 174 insertions, 14 deletions
diff --git a/src/core/CSS.cpp b/src/core/CSS.cpp
index c2397d1..8beb075 100644
--- a/src/core/CSS.cpp
+++ b/src/core/CSS.cpp
@@ -20,19 +20,23 @@
namespace ousia {
+/*
+ * different versions of "getChildren".
+ */
+
std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
- const SelectionOperator &op, const std::string &className,
- const PseudoSelector &select)
+ const SelectionOperator *op, const std::string *className,
+ const PseudoSelector *select)
{
std::vector<Rooted<SelectorNode>> out;
for (auto &e : edges) {
- if (e->getSelectionOperator() != op) {
+ if (op && e->getSelectionOperator() != *op) {
continue;
}
- if (e->getTarget()->getName() != className) {
+ if (className && e->getTarget()->getName() != *className) {
continue;
}
- if (e->getTarget()->getPseudoSelector() != select) {
+ if (select && e->getTarget()->getPseudoSelector() != *select) {
continue;
}
out.push_back(e->getTarget());
@@ -40,6 +44,58 @@ std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
return out;
}
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const SelectionOperator &op, const std::string &className,
+ const PseudoSelector &select)
+{
+ return getChildren(&op, &className, &select);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const std::string &className, const PseudoSelector &select)
+{
+ return getChildren(NULL, &className, &select);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const SelectionOperator &op, const PseudoSelector &select)
+{
+ return getChildren(&op, NULL, &select);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const SelectionOperator &op, const std::string &className)
+{
+ return getChildren(&op, &className, NULL);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const SelectionOperator &op)
+{
+ return getChildren(&op, NULL, NULL);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const std::string &className)
+{
+ return getChildren(NULL, &className, NULL);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
+ const PseudoSelector &select)
+{
+ return getChildren(NULL, NULL, &select);
+}
+
+std::vector<Rooted<SelectorNode>> SelectorNode::getChildren()
+{
+ return getChildren(NULL, NULL, NULL);
+}
+
+/*
+ * append
+ */
+
std::vector<Rooted<SelectorNode>> SelectorNode::append(
Rooted<SelectorEdge> edge)
{
diff --git a/src/core/CSS.hpp b/src/core/CSS.hpp
index c313f25..8c87ee7 100644
--- a/src/core/CSS.hpp
+++ b/src/core/CSS.hpp
@@ -250,6 +250,13 @@ private:
// TODO: This is temporarily commented out until the TypeSystem works.
// Owned<RuleSet> ruleSets;
+ /**
+ * This is an internal method all getChildren variants refer to.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const SelectionOperator *op,
+ const std::string *className,
+ const PseudoSelector *select);
+
public:
SelectorNode(Manager &mgr, std::string name, PseudoSelector pseudoSelector)
: Node(mgr, std::move(name)),
@@ -260,6 +267,15 @@ public:
{
}
+ SelectorNode(Manager &mgr, std::string name)
+ : Node(mgr, std::move(name)),
+ pseudoSelector("true", false),
+ edges(this) //,
+ // TODO: This is temporarily commented out until the TypeSystem works.
+ // ruleSets(acquire(ruleSets))
+ {
+ }
+
const PseudoSelector &getPseudoSelector() const { return pseudoSelector; }
ManagedVector<SelectorEdge> &getEdges() { return edges; }
@@ -269,15 +285,61 @@ public:
// ruleSets; }
/**
- * This returns all children of this SelectorNode that are connected by
- * the given operator, have the given className and the given
- * PseudoSelector.
+ * This returns the child of this SelectorNode that is connected by
+ * the given operator, has the given className and the given
+ * PseudoSelector. For convention reasons with the other methods, this
+ * also returns a vector, which might either be empty or has exactly one
+ * element.
*/
std::vector<Rooted<SelectorNode>> getChildren(const SelectionOperator &op,
const std::string &className,
const PseudoSelector &select);
/**
+ * This returns all children of this SelectorNode that have the given
+ * className and the given PseudoSelector.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const std::string &className,
+ const PseudoSelector &select);
+
+ /**
+ * This returns all children of this SelectorNode that are connected by the
+ * given SelectionOperator and have the given PseudoSelector.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const SelectionOperator &op,
+ const PseudoSelector &select);
+
+ /**
+ * This returns all children of this SelectorNode that are connected by the
+ * given SelectionOperator and have the given className.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const SelectionOperator &op,
+ const std::string &className);
+
+ /**
+ * This returns all children of this SelectorNode that are connected by the
+ * given SelectionOperator.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const SelectionOperator &op);
+
+ /**
+ * This returns all children of this SelectorNode that have the given
+ * className.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const std::string &className);
+
+ /**
+ * This returns all children of this SelectorNode that have the given
+ * PseudoSelector.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren(const PseudoSelector &select);
+
+ /**
+ * This returns all children of this SelectorNode.
+ */
+ std::vector<Rooted<SelectorNode>> getChildren();
+
+ /**
* This appends the given edge and the subsequent SelectorTree to
* this SelectorNode. Note that only those nodes get appended to the
* SelectorTree that are not already contained in this SelectorTree.
diff --git a/test/core/CSSTest.cpp b/test/core/CSSTest.cpp
index 2c695d9..fdb8238 100644
--- a/test/core/CSSTest.cpp
+++ b/test/core/CSSTest.cpp
@@ -115,13 +115,55 @@ TEST(Specificity, testOperators)
TEST(SelectorNode, testGetChildren)
{
Manager mgr(1);
- Rooted<SelectorNode> root{new SelectorNode{mgr, "root", {"true", false}}};
- Rooted<SelectorNode> child{new SelectorNode{mgr, "A", {"true", false}}};
- root->getEdges().push_back(
- new SelectorNode::SelectorEdge{mgr, child, SelectionOperator::DESCENDANT});
+ // build some children.
+ Rooted<SelectorNode> root{new SelectorNode{mgr, "root"}};
+ Rooted<SelectorNode> A{new SelectorNode{mgr, "A"}};
+ Rooted<SelectorNode> AMy_Select{
+ new SelectorNode{mgr, "A", {"my_select", {"a", "b"}, false}}};
+ Rooted<SelectorNode> B{new SelectorNode{mgr, "B"}};
+
+ std::vector<Rooted<SelectorNode>> children = {A, AMy_Select, B};
+
+ for (auto &c : children) {
+ root->getEdges().push_back(new SelectorNode::SelectorEdge{
+ mgr, c, SelectionOperator::DESCENDANT});
+ }
+ root->getEdges().push_back(new SelectorNode::SelectorEdge{
+ mgr, B, SelectionOperator::DIRECT_DESCENDANT});
+
+ // make some checks.
+ std::vector<Rooted<SelectorNode>> expected = {A};
std::vector<Rooted<SelectorNode>> actual =
root->getChildren(SelectionOperator::DESCENDANT, "A", {"true", false});
- ASSERT_EQ(1,actual.size());
- ASSERT_EQ(child, actual[0]);
+ ASSERT_EQ(expected, actual);
+
+ expected = {A, AMy_Select};
+ actual = root->getChildren(SelectionOperator::DESCENDANT, "A");
+ ASSERT_EQ(expected, actual);
+ actual = root->getChildren("A");
+ ASSERT_EQ(expected, actual);
+
+ expected = {A, AMy_Select, B};
+ actual = root->getChildren(SelectionOperator::DESCENDANT);
+ ASSERT_EQ(expected, actual);
+
+ expected = {B};
+ actual = root->getChildren(SelectionOperator::DIRECT_DESCENDANT);
+ ASSERT_EQ(expected, actual);
+
+ expected = {B, B};
+ actual = root->getChildren("B");
+ ASSERT_EQ(expected, actual);
+
+ {
+ expected = {A, B, B};
+ PseudoSelector select = {"true", false};
+ actual = root->getChildren(select);
+ ASSERT_EQ(expected, actual);
+ }
+
+ expected = {A, AMy_Select, B, B};
+ actual = root->getChildren();
+ ASSERT_EQ(expected, actual);
}
}