aboutsummaryrefslogtreecommitdiff
path: root/src/doctree.hh
diff options
context:
space:
mode:
authorJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-08-24 23:13:40 +0200
committerJohannes Hofmann <Johannes.Hofmann@gmx.de>2011-08-24 23:13:40 +0200
commit7ef21cbd8de03848230ca6d75f349bd586926aaa (patch)
tree2cd07d0ac7a0c0b3517cdc6672c8828bea93e133 /src/doctree.hh
parentb245b5abf8e48ab81bbaaec9edb56a4a4b51af6e (diff)
add support for CSS adjacent sibling selectors
Diffstat (limited to 'src/doctree.hh')
-rw-r--r--src/doctree.hh54
1 files changed, 36 insertions, 18 deletions
diff --git a/src/doctree.hh b/src/doctree.hh
index ef7faa7c..c46a5a10 100644
--- a/src/doctree.hh
+++ b/src/doctree.hh
@@ -6,6 +6,8 @@
class DoctreeNode {
public:
DoctreeNode *parent;
+ DoctreeNode *sibling;
+ DoctreeNode *lastChild;
int num; // unique ascending id
int element;
lout::misc::SimpleVector<char*> *klass;
@@ -14,11 +16,27 @@ class DoctreeNode {
DoctreeNode () {
parent = NULL;
+ sibling = NULL;
+ lastChild = NULL;
klass = NULL;
pseudo = NULL;
id = NULL;
element = 0;
};
+
+ ~DoctreeNode () {
+ dFree ((void*) id);
+ while (lastChild) {
+ DoctreeNode *n = lastChild;
+ lastChild = lastChild->sibling;
+ delete n;
+ }
+ if (klass) {
+ for (int i = 0; i < klass->size (); i++)
+ dFree (klass->get(i));
+ delete klass;
+ }
+ }
};
/**
@@ -26,47 +44,47 @@ class DoctreeNode {
*
* The Doctree class defines the interface to the parsed HTML document tree
* as it is used for CSS selector matching.
- * Currently the Doctree can be represented as stack, however to support
- * CSS adjacent siblings or for future JavaScript support it may have to
- * be extended to a real tree.
*/
class Doctree {
private:
DoctreeNode *topNode;
+ DoctreeNode *rootNode;
int num;
public:
Doctree () {
topNode = NULL;
+ rootNode = NULL;
num = 0;
};
- ~Doctree () { while (top ()) pop (); };
+
+ ~Doctree () {
+ if (rootNode)
+ delete rootNode;
+ };
+
DoctreeNode *push () {
DoctreeNode *dn = new DoctreeNode ();
dn->parent = topNode;
+ if (dn->parent) {
+ dn->sibling = dn->parent->lastChild;
+ dn->parent->lastChild = dn;
+ }
dn->num = num++;
+ if (!rootNode)
+ rootNode = dn;
topNode = dn;
return dn;
};
+
void pop () {
- DoctreeNode *dn = topNode;
- if (dn) {
- dFree ((void*) dn->id);
- if (dn->klass) {
- for (int i = 0; i < dn->klass->size (); i++)
- dFree (dn->klass->get(i));
- delete dn->klass;
- }
- topNode = dn->parent;
- delete dn;
- }
+ if (topNode)
+ topNode = topNode->parent;
};
+
inline DoctreeNode *top () {
return topNode;
};
- inline DoctreeNode *parent (const DoctreeNode *node) {
- return node->parent;
- };
};
#endif