Reviewed by Anders.
[WebKit-https.git] / WebCore / html / HTMLParser.cpp
index bf4322ec60dd1fe406d219944586664207326f78..6e8f8b45ce70b3f6effb3c7984f55cb98be9ee1e 100644 (file)
@@ -71,15 +71,37 @@ public:
         tagName(_tagName),
         level(_level),
         strayTableContent(false),
-        node(_node),
-        next(_next)
-        { }
+        nodeIsRefd(!_node->isDocumentNode()),
+        next(_next),
+        m_node(_node)
+    { 
+        if (nodeIsRefd)
+            m_node->ref();
+    }
+
+    ~HTMLStackElem()
+    {
+        if (nodeIsRefd)
+            m_node->deref();
+    }
+
+    Node* node() { return m_node; }
+    void setNode(Node* _node)
+    {
+        if (nodeIsRefd)
+            m_node->deref();
+        nodeIsRefd = !_node->isDocumentNode();
+        m_node = _node;
+    }
 
     AtomicString tagName;
     int level;
     bool strayTableContent;
-    RefPtr<Node> node;
+    bool nodeIsRefd;
     HTMLStackElem* next;
+
+private:
+    Node* m_node;
 };
 
 /**
@@ -863,7 +885,7 @@ void HTMLParser::popNestedHeaderTag()
         }
         if (currNode && !isInline(currNode))
             return;
-        currNode = curr->node.get();
+        currNode = curr->node();
     }
 }
 
@@ -974,9 +996,9 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
 
     if (!curr || !maxElem || !isAffectedByResidualStyle(maxElem->tagName)) return;
 
-    Node* residualElem = prev->node.get();
-    Node* blockElem = prevMaxElem ? prevMaxElem->node.get() : current;
-    Node* parentElem = elem->node.get();
+    Node* residualElem = prev->node();
+    Node* blockElem = prevMaxElem ? prevMaxElem->node() : current;
+    Node* parentElem = elem->node();
 
     // Check to see if the reparenting that is going to occur is allowed according to the DOM.
     // FIXME: We should either always allow it or perform an additional fixup instead of
@@ -985,7 +1007,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
     if (!parentElem->childAllowed(blockElem))
         return;
     
-    if (maxElem->node->parentNode() != elem->node) {
+    if (maxElem->node()->parentNode() != elem->node()) {
         // Walk the stack and remove any elements that aren't residual style tags.  These
         // are basically just being closed up.  Example:
         // <font><span>Moo<p>Goo</font></p>.
@@ -996,7 +1018,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
             HTMLStackElem* nextElem = currElem->next;
             if (!isResidualStyleTag(currElem->tagName)) {
                 prevElem->next = nextElem;
-                prevElem->node = currElem->node;
+                prevElem->setNode(currElem->node());
                 delete currElem;
             }
             else
@@ -1014,13 +1036,13 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
         // under the reopened residual tags (e.g., the <i> in the above example.)
         Node* prevNode = 0;
         currElem = maxElem;
-        while (currElem->node != residualElem) {
-            if (isResidualStyleTag(currElem->node->localName())) {
+        while (currElem->node() != residualElem) {
+            if (isResidualStyleTag(currElem->node()->localName())) {
                 // Create a clone of this element.
-                RefPtr<Node> currNode = currElem->node->cloneNode(false);
+                RefPtr<Node> currNode = currElem->node()->cloneNode(false);
 
                 // Change the stack element's node to point to the clone.
-                currElem->node = currNode;
+                currElem->setNode(currNode.get());
                 
                 // Attach the previous node as a child of this new node.
                 if (prevNode)
@@ -1036,7 +1058,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
 
         // Now append the chain of new residual style elements if one exists.
         if (prevNode)
-            elem->node->appendChild(prevNode, ec);
+            elem->node()->appendChild(prevNode, ec);
     }
          
     // Check if the block is still in the tree. If it isn't, then we don't
@@ -1088,7 +1110,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
         currElem = currElem->next;
     }
     prevElem->next = elem->next;
-    prevElem->node = elem->node;
+    prevElem->setNode(elem->node());
     delete elem;
     
     // Step 7: Reopen intermediate inlines, e.g., <b><p><i>Foo</b>Goo</p>.
@@ -1109,7 +1131,7 @@ void HTMLParser::handleResidualStyleCloseTagAcrossBlocks(HTMLStackElem* elem)
             // curr->id rather than the node that you should pop to when the element gets pulled off
             // the stack.
             popOneBlock(false);
-            curr->node = currNode;
+            curr->setNode(currNode);
             curr->next = residualStyleStack;
             residualStyleStack = curr;
         }
@@ -1131,7 +1153,7 @@ void HTMLParser::reopenResidualStyleTags(HTMLStackElem* elem, Node* malformedTab
     // Loop for each tag that needs to be reopened.
     while (elem) {
         // Create a shallow clone of the DOM node for this element.
-        RefPtr<Node> newNode = elem->node->cloneNode(false); 
+        RefPtr<Node> newNode = elem->node()->cloneNode(false); 
 
         // Append the new node. In the malformed table case, we need to insert before the table,
         // which will be the last child.
@@ -1236,7 +1258,7 @@ void HTMLParser::popBlock(const AtomicString& _tagName)
                 // the stack.
                 popOneBlock(false);
                 Elem->next = residualStyleStack;
-                Elem->node = currNode;
+                Elem->setNode(currNode);
                 residualStyleStack = Elem;
             }
             else
@@ -1254,11 +1276,11 @@ void HTMLParser::popOneBlock(bool delBlock)
 
     // Form elements restore their state during the parsing process.
     // Also, a few elements (<applet>, <object>) need to know when all child elements (<param>s) are available.
-    if (current && elem->node != current)
+    if (current && elem->node() != current)
         current->closeRenderer();
 
     blockStack = elem->next;
-    setCurrent(elem->node.get());
+    setCurrent(elem->node());
 
     if (elem->strayTableContent)
         inStrayTableContent--;