diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/core/CSS.cpp | 46 | ||||
| -rw-r--r-- | src/core/CSS.hpp | 44 | 
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  | 
