In the browser kernel (typesetting engine) CSS rules tree and the HTML DOM tree to synthesize the rendering tree, it involves the problem of the location property of the render tree, because its location property is determined by the precedence of the CSS selector chain, and a node of the render tree may satisfy multiple selector chains at the same time. This is done by selecting the priority of the selector to complete the assignment of the property.
In this place, I only handled a few simple selector cases: {(. Class) (#id) (Element) (#id,. class,elememt) (#id >.class) (#id elem ENT) (#id. Class)}.
At this point, several selector chains satisfying the render nodes are overlaid with the render nodes from small to large by their priority weighted values, and how do you determine if this render node satisfies a selector chain?
My implementation process is broadly as follows:
First the structure of the given selector is as follows:
struct Cssparserselector { enum TYPE {id,class,element}; Enum RELATION {None,descendant,child,and}; TYPE M_type; std::string m_name; RELATION m_relation; struct Cssparserselector *ptr; Cssparserselector (): M_relation (NONE), PTR (NULL) {}};
Starting with this render node, determine whether this node matches the current selector of the selector list. If matching, determine the relationship of this selector to the next selector: If none, this selector is the last of the selector chain, returns success, if the relationship is and (for example: #id. Class), select the next selector to continue the comparison with this render node, and if the relationship is child, Indicates that this selector is a sub-node of the next selector, returning the matching result of the next selector to the next render node; otherwise, the relationship is descendant, the selector and render nodes each point to the next node, and then the render node continues to backtrack until the first node of the selector that satisfies the backtracking is This will continue to determine if the backtracking selector and the post-backtracking render node match. The process is generally as follows:
Whether the/*** selector matches the render node */bool rendertree::isselectorsmatchrendertree (cssparserselector *selector,rendernode *renderNode) {if (Isselectormatchrendernode (Selector,rendernode)) {if (selector->m_relation = = Cssparserselector::none) {return true; } else if (selector->m_relation = = Cssparserselector::and) {return Isselectorsmatchrendertree (SELECTOR-&G T;ptr,rendernode); } else if (selector->m_relation = = Cssparserselector::child) {return Isselectorsmatchrendertree (selector- >ptr,rendernode->parentnode); } else {return ismatchdescendantrelation (Selector->ptr,rendernode->parentnode); }} else {return false; }}/*** determine whether the relationship with the grandfather matches */bool rendertree::ismatchdescendantrelation (cssparserselector *selector,rendernode *renderNode) {while (Rendernode->gettypeofrendernode ()! = "html" && (! Isselectormatchrendernode (Selector,rendernode))) { Rendernode = rendernode->parentnode; } if (Rendernode->gettypeofrendernode ()! = "html") {return Isselectorsmatchrendertree (Selector,rendernode) ; } else {return false; }}Finally, the results are matched. You can then calculate the priority of the selector list by using a formula.
CSS rule tree and HTML DOM tree when compositing render tree match between render node and selector chain