summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/core/CSS.cpp46
-rw-r--r--src/core/CSS.hpp44
2 files changed, 79 insertions, 11 deletions
diff --git a/src/core/CSS.cpp b/src/core/CSS.cpp
index 06d062e..c2397d1 100644
--- a/src/core/CSS.cpp
+++ b/src/core/CSS.cpp
@@ -20,24 +20,19 @@
namespace ousia {
-/**
- * This returns all children of this SelectorNode that are connected by
- * the given operator, have the given className and the given
- * PseudoSelector.
- */
std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
const SelectionOperator &op, const std::string &className,
const PseudoSelector &select)
{
std::vector<Rooted<SelectorNode>> out;
- for(auto& e : edges){
- if(e->getSelectionOperator() != op){
+ for (auto &e : edges) {
+ if (e->getSelectionOperator() != op) {
continue;
}
- if(e->getTarget()->getName() != className){
+ if (e->getTarget()->getName() != className) {
continue;
}
- if(e->getTarget()->getPseudoSelector() != select){
+ if (e->getTarget()->getPseudoSelector() != select) {
continue;
}
out.push_back(e->getTarget());
@@ -45,5 +40,36 @@ std::vector<Rooted<SelectorNode>> SelectorNode::getChildren(
return out;
}
-
+std::vector<Rooted<SelectorNode>> SelectorNode::append(
+ Rooted<SelectorEdge> edge)
+{
+ std::vector<Rooted<SelectorNode>> out;
+ // look if we already have a child in an equivalent edge.
+ std::vector<Rooted<SelectorNode>> children =
+ getChildren(edge->getSelectionOperator(), edge->getTarget()->getName(),
+ edge->getTarget()->getPseudoSelector());
+ // note that this can only be one child or no child.
+ if (children.size() == 0) {
+ // if there is no child the appending process is trivial: We can just
+ // add the whole subtree represented by the other node as child here.
+ edges.push_back(edge);
+ } else {
+ // otherwise we start the appending process recursively on the child
+ // level.
+ // TODO: RuleSet merging
+ if (edge->getTarget()->getEdges().size() == 0) {
+ // if there are no more subsequent edges this is a leafe we could
+ // not merge, because it is already present in the Tree.
+ out.push_back(edge->getTarget());
+ } else {
+ // otherwise we go into recursion.
+ for (auto &e : edge->getTarget()->getEdges()) {
+ std::vector<Rooted<SelectorNode>> childLeafs =
+ children[0]->append(e);
+ out.insert(out.end(), childLeafs.begin(), childLeafs.end());
+ }
+ }
+ }
+ return out;
+}
}
diff --git a/src/core/CSS.hpp b/src/core/CSS.hpp
index f5d8c1d..c313f25 100644
--- a/src/core/CSS.hpp
+++ b/src/core/CSS.hpp
@@ -45,7 +45,8 @@ struct Specificity {
Specificity(int b, int c, int d) : b(b), c(c), d(d) {}
};
-//TODO: Is this correct? I used this to prevent "multiple definition" errors
+// 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);
@@ -254,6 +255,7 @@ public:
: Node(mgr, std::move(name)),
pseudoSelector(std::move(pseudoSelector)),
edges(this) //,
+ // TODO: This is temporarily commented out until the TypeSystem works.
// ruleSets(acquire(ruleSets))
{
}
@@ -262,6 +264,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; }
@@ -274,6 +277,45 @@ public:
const std::string &className,
const PseudoSelector &select);
+ /**
+ * 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.
+ *
+ * Consider the example of the following SelectorTree T:
+ *
+ * root
+ * | \
+ * A B
+ * |
+ * C
+ *
+ * and the following SelectorEdge e with its subsequent Tree T_e
+ *
+ * |
+ * A
+ * |\
+ * C D
+ *
+ * If we call root.append(e) the resulting SelectorTree looks like
+ * this:
+ *
+ * root
+ * | \
+ * A B
+ * |\
+ * C D
+ *
+ * The method returns all leafs of T that are equivalent to leafs of T_e
+ * and thus could not be appended to T, because they were already contained
+ * there. In our example this would be a vector containing just C.
+ *
+ * @param edge a Rooted reference to an edge that shall be appended to this
+ * SelectorNode.
+ * @return A list of leafs of this SelectorTree that could not be appended,
+ * because they were already contained.
+ */
+ std::vector<Rooted<SelectorNode>> append(Rooted<SelectorEdge> edge);
};
}
#endif