diff options
-rw-r--r-- | src/core/CSS.cpp | 66 | ||||
-rw-r--r-- | src/core/CSS.hpp | 68 | ||||
-rw-r--r-- | test/core/CSSTest.cpp | 54 |
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); } } |