diff options
-rw-r--r-- | src/core/CSS.hpp | 89 | ||||
-rw-r--r-- | src/plugins/css/CSSParser.cpp | 9 | ||||
-rw-r--r-- | test/plugins/css/CSSParserTest.cpp | 8 |
3 files changed, 62 insertions, 44 deletions
diff --git a/src/core/CSS.hpp b/src/core/CSS.hpp index 1c0ed17..3b4289a 100644 --- a/src/core/CSS.hpp +++ b/src/core/CSS.hpp @@ -23,6 +23,8 @@ #include <vector> #include <tuple> +#include <core/variant/Variant.hpp> + #include "Managed.hpp" #include "Node.hpp" @@ -44,51 +46,43 @@ struct Specificity { int d; Specificity(int b, int c, int d) : b(b), c(c), d(d) {} -}; -// TODO: Is this inline usage correct? I used this to prevent "multiple -// definition" errors -inline bool operator<(const Specificity &x, const Specificity &y) -{ - return std::tie(x.b, x.c, x.d) < std::tie(y.b, y.c, y.d); -} + friend bool operator<(const Specificity &x, const Specificity &y) + { + return std::tie(x.b, x.c, x.d) < std::tie(y.b, y.c, y.d); + } -inline bool operator>(const Specificity &x, const Specificity &y) -{ - return std::tie(x.b, x.c, x.d) > std::tie(y.b, y.c, y.d); -} + friend bool operator>(const Specificity &x, const Specificity &y) + { + return std::tie(x.b, x.c, x.d) > std::tie(y.b, y.c, y.d); + } -inline bool operator==(const Specificity &x, const Specificity &y) -{ - return std::tie(x.b, x.c, x.d) == std::tie(y.b, y.c, y.d); -} + friend bool operator==(const Specificity &x, const Specificity &y) + { + return std::tie(x.b, x.c, x.d) == std::tie(y.b, y.c, y.d); + } +}; /** * The RuleSet class serves as a container class for key-value * pairs. The values are TypeInstances. The proper type is * implicitly defined by the keyword. - * - * TODO: This code is currently commented out until the TypeSystem works. */ -/*class RuleSet : public Managed { +class RuleSet : public Managed { private: - const std::map<std::string, std::string> values; - const Specificity specificity; + const std::map<std::string, variant::Variant> values; public: - RuleSet(Manager &mgr, std::map<std::string, std::string> values, - Specificity specificity) - : Managed(mgr), values(std::move(values)), specificity(specificity) - { - } - - const std::map<std::string, std::string> &getValues() const - { - return values; - } + /** + * Initializes an empty RuleSet. + */ + RuleSet(Manager &mgr) : Managed(mgr), values() {} - const Specificity &getSpecificity() const { return specificity; } -};*/ + const std::map<std::string, variant::Variant> &getValues() const + { + return values; + } +}; /** * PseudoSelectors are functions that change the behaviour of Selectors. @@ -249,8 +243,8 @@ public: private: const PseudoSelector pseudoSelector; ManagedVector<SelectorEdge> edges; - // TODO: This is temporarily commented out until the TypeSystem works. - // Owned<RuleSet> ruleSets; + Owned<RuleSet> ruleSet; + bool accepting; /** * This is an internal method all getChildren variants refer to. @@ -260,21 +254,28 @@ private: const PseudoSelector *select); public: + + /** + * This initializes an empty SelectorNode with the given name and the + * given PseudoSelector. + */ SelectorNode(Manager &mgr, std::string name, PseudoSelector pseudoSelector) : Node(mgr, std::move(name)), pseudoSelector(std::move(pseudoSelector)), - edges(this) //, - // TODO: This is temporarily commented out until the TypeSystem works. - // ruleSets(acquire(ruleSets)) + edges(this), + ruleSet(new RuleSet(mgr), this) { } + /** + * This initializes an empty SelectorNode with the given name and the + * trivial PseudoSelector "true". + */ 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)) + edges(this), + ruleSet(new RuleSet(mgr), this) { } @@ -282,9 +283,7 @@ public: ManagedVector<SelectorEdge> &getEdges() { return edges; } - // TODO: This is temporarily commented out until the TypeSystem works. - // const std::vector<Owned<RuleSet>> &getRuleSets() const { return - // ruleSets; } + Rooted<RuleSet> getRuleSet() const { return ruleSet; } /** * This returns the child of this SelectorNode that is connected by @@ -386,6 +385,10 @@ public: * automatically using the DESCENDANT SelectionOperator. */ std::vector<Rooted<SelectorNode>> append(Rooted<SelectorNode> node); + + bool isAccepting() { return accepting; } + + void setAccepting(bool accepting) { this->accepting = accepting; } }; } #endif diff --git a/src/plugins/css/CSSParser.cpp b/src/plugins/css/CSSParser.cpp index 6653d9e..85d8858 100644 --- a/src/plugins/css/CSSParser.cpp +++ b/src/plugins/css/CSSParser.cpp @@ -99,6 +99,15 @@ void CSSParser::parseDocument(Rooted<SelectorNode> root, std::vector<Rooted<SelectorNode>> leafList; parseSelectors(root, tokenizer, leafList, ctx); // TODO: Parse Ruleset + for (auto &leaf : leafList) { + /* every leaf is an accepting node, if one considers the SelectorTree + * to be a finite state machine. This is relevant, if users do not use + * the CSS Parser to parse actual Ruleset content but to construct a + * SelectorTree just to identify a part of the DocumentTree. + */ + leaf->setAccepting(true); + //TODO: append RuleSets + } parseDocument(root, tokenizer, ctx); } diff --git a/test/plugins/css/CSSParserTest.cpp b/test/plugins/css/CSSParserTest.cpp index 84d4893..20d0836 100644 --- a/test/plugins/css/CSSParserTest.cpp +++ b/test/plugins/css/CSSParserTest.cpp @@ -24,7 +24,7 @@ namespace ousia { namespace parser { -namespace css { +namespace css { TEST(CSSParser, testParseSelectors) { // create a string describing a SelectorTree as input. @@ -58,6 +58,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, A->getPseudoSelector()); } ASSERT_EQ(2, A->getEdges().size()); + ASSERT_FALSE(A->isAccepting()); { // assert A > B std::vector<Rooted<SelectorNode>> Achildren = @@ -70,6 +71,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, B->getPseudoSelector()); } ASSERT_EQ(0, B->getEdges().size()); + ASSERT_TRUE(B->isAccepting()); // assert A B:r Achildren = A->getChildren(SelectionOperator::DESCENDANT, "B"); ASSERT_EQ(1, Achildren.size()); @@ -80,6 +82,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, Br->getPseudoSelector()); } ASSERT_EQ(0, Br->getEdges().size()); + ASSERT_TRUE(Br->isAccepting()); } // assert C#a children = root->getChildren("C"); @@ -91,6 +94,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, C->getPseudoSelector()); } ASSERT_EQ(1, C->getEdges().size()); + ASSERT_FALSE(C->isAccepting()); { // assert C#a A[bla=\"blub\"] std::vector<Rooted<SelectorNode>> Cchildren = @@ -103,6 +107,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, A->getPseudoSelector()); } ASSERT_EQ(0, A->getEdges().size()); + ASSERT_TRUE(A->isAccepting()); } // assert A::g(4,2,3) children = root->getChildren("A"); @@ -114,6 +119,7 @@ TEST(CSSParser, testParseSelectors) ASSERT_EQ(select, Ag->getPseudoSelector()); } ASSERT_EQ(0, Ag->getEdges().size()); + ASSERT_TRUE(Ag->isAccepting()); } } } |