mshtml: Use vtbl for node destructors.
diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c
index 1494efb..72cd106 100644
--- a/dlls/mshtml/htmlanchor.c
+++ b/dlls/mshtml/htmlanchor.c
@@ -468,19 +468,23 @@
 static void HTMLAnchorElement_destructor(HTMLDOMNode *iface)
 {
     HTMLAnchorElement *This = HTMLANCHOR_NODE_THIS(iface);
-    mshtml_free(This);
+    HTMLElement_destructor(&This->element.node);
 }
 
 #undef HTMLANCHOR_NODE_THIS
 
+static const NodeImplVtbl HTMLAnchorElementImplVtbl = {
+    HTMLAnchorElement_destructor
+};
+
 HTMLElement *HTMLAnchorElement_Create(nsIDOMHTMLElement *nselem)
 {
     HTMLAnchorElement *ret = mshtml_alloc(sizeof(HTMLAnchorElement));
 
     ret->lpHTMLAnchorElementVtbl = &HTMLAnchorElementVtbl;
+    ret->element.node.vtbl = &HTMLAnchorElementImplVtbl;
 
     ret->element.impl = (IUnknown*)HTMLANCHOR(ret);
-    ret->element.destructor = HTMLAnchorElement_destructor;
 
     return &ret->element;
 }
diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c
index 8742032..b3712b7 100644
--- a/dlls/mshtml/htmlbody.c
+++ b/dlls/mshtml/htmlbody.c
@@ -481,11 +481,16 @@
 
     ConnectionPointContainer_Destroy(&This->cp_container);
     nsIDOMHTMLBodyElement_Release(This->nsbody);
-    mshtml_free(This);
+
+    HTMLElement_destructor(&This->textcont.element.node);
 }
 
 #undef HTMLBODY_NODE_THIS
 
+static const NodeImplVtbl HTMLBodyElementImplVtbl = {
+    HTMLBodyElement_destructor
+};
+
 HTMLElement *HTMLBodyElement_Create(nsIDOMHTMLElement *nselem)
 {
     HTMLBodyElement *ret = mshtml_alloc(sizeof(HTMLBodyElement));
@@ -494,6 +499,7 @@
     TRACE("(%p)->(%p)\n", ret, nselem);
 
     ret->lpHTMLBodyElementVtbl = &HTMLBodyElementVtbl;
+    ret->textcont.element.node.vtbl = &HTMLBodyElementImplVtbl;
 
     HTMLTextContainer_Init(&ret->textcont);
 
@@ -509,7 +515,6 @@
         ERR("Could not get nsDOMHTMLBodyElement: %08x\n", nsres);
 
     ret->textcont.element.impl = (IUnknown*)HTMLBODY(ret);
-    ret->textcont.element.destructor = HTMLBodyElement_destructor;
 
     return &ret->textcont.element;
 }
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c
index 76098ce..8bf2e54 100644
--- a/dlls/mshtml/htmlelem.c
+++ b/dlls/mshtml/htmlelem.c
@@ -1265,19 +1265,20 @@
     return HTMLDOMNode_QI(&This->node, riid, ppv);
 }
 
-static void HTMLElement_destructor(HTMLDOMNode *iface)
+void HTMLElement_destructor(HTMLDOMNode *iface)
 {
     HTMLElement *This = HTMLELEM_NODE_THIS(iface);
 
-    if(This->destructor)
-        This->destructor(&This->node);
-
     if(This->nselem)
         nsIDOMHTMLElement_Release(This->nselem);
 
-    mshtml_free(This);
+    HTMLDOMNode_destructor(&This->node);
 }
 
+static const NodeImplVtbl HTMLElementImplVtbl = {
+    HTMLElement_destructor
+};
+
 HTMLElement *HTMLElement_Create(nsIDOMNode *nsnode)
 {
     nsIDOMHTMLElement *nselem;
@@ -1314,9 +1315,9 @@
 
     if(!ret) {
         ret = mshtml_alloc(sizeof(HTMLElement));
+        ret->node.vtbl = &HTMLElementImplVtbl;
 
         ret->impl = NULL;
-        ret->destructor = NULL;
     }
 
     nsAString_Finish(&class_name_str);
@@ -1327,7 +1328,6 @@
     HTMLElement2_Init(ret);
 
     ret->node.impl.elem = HTMLELEM(ret);
-    ret->node.destructor = HTMLElement_destructor;
 
     return ret;
 }
diff --git a/dlls/mshtml/htmlinput.c b/dlls/mshtml/htmlinput.c
index 4b60e21..0991fd8 100644
--- a/dlls/mshtml/htmlinput.c
+++ b/dlls/mshtml/htmlinput.c
@@ -733,17 +733,23 @@
     HTMLInputElement *This = HTMLINPUT_NODE_THIS(iface);
 
     nsIDOMHTMLInputElement_Release(This->nsinput);
-    mshtml_free(This);
+
+    HTMLElement_destructor(&This->element.node);
 }
 
 #undef HTMLINPUT_NODE_THIS
 
+static const NodeImplVtbl HTMLInputElementImplVtbl = {
+    HTMLInputElement_destructor
+};
+
 HTMLElement *HTMLInputElement_Create(nsIDOMHTMLElement *nselem)
 {
     HTMLInputElement *ret = mshtml_alloc(sizeof(HTMLInputElement));
     nsresult nsres;
 
     ret->lpHTMLInputElementVtbl = &HTMLInputElementVtbl;
+    ret->element.node.vtbl = &HTMLInputElementImplVtbl;
 
     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLInputElement,
                                              (void**)&ret->nsinput);
@@ -751,7 +757,6 @@
         ERR("Could not get nsIDOMHTMLInputElement interface: %08x\n", nsres);
 
     ret->element.impl = (IUnknown*)HTMLINPUT(ret);
-    ret->element.destructor = HTMLInputElement_destructor;
 
     return &ret->element;
 }
diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c
index 0e2c127..d93d0ac 100644
--- a/dlls/mshtml/htmlnode.c
+++ b/dlls/mshtml/htmlnode.c
@@ -331,6 +331,16 @@
     return E_NOINTERFACE;
 }
 
+void HTMLDOMNode_destructor(HTMLDOMNode *This)
+{
+    if(This->nsnode)
+        nsIDOMNode_Release(This->nsnode);
+}
+
+static const NodeImplVtbl HTMLDOMNodeImplVtbl = {
+    HTMLDOMNode_destructor
+};
+
 static HTMLDOMNode *create_node(HTMLDocument *doc, nsIDOMNode *nsnode)
 {
     HTMLDOMNode *ret;
@@ -344,8 +354,8 @@
         break;
     default:
         ret = mshtml_alloc(sizeof(HTMLDOMNode));
+        ret->vtbl = &HTMLDOMNodeImplVtbl;
         ret->impl.unk = NULL;
-        ret->destructor = NULL;
     }
 
     ret->lpHTMLDOMNodeVtbl = &HTMLDOMNodeVtbl;
@@ -393,10 +403,7 @@
 
     for(iter = This->nodes; iter; iter = next) {
         next = iter->next;
-        nsIDOMNode_Release(iter->nsnode);
-        if(iter->destructor)
-            iter->destructor(iter);
-        else
-            mshtml_free(iter);
+        iter->vtbl->destructor(iter);
+        mshtml_free(iter);
     }
 }
diff --git a/dlls/mshtml/htmlselect.c b/dlls/mshtml/htmlselect.c
index 65175f9..4fc6d57 100644
--- a/dlls/mshtml/htmlselect.c
+++ b/dlls/mshtml/htmlselect.c
@@ -384,17 +384,23 @@
     HTMLSelectElement *This = HTMLSELECT_NODE_THIS(iface);
 
     nsIDOMHTMLSelectElement_Release(This->nsselect);
-    mshtml_free(This);
+
+    HTMLElement_destructor(&This->element.node);
 }
 
 #undef HTMLSELECT_NODE_THIS
 
+static const NodeImplVtbl HTMLSelectElementImplVtbl = {
+    HTMLSelectElement_destructor
+};
+
 HTMLElement *HTMLSelectElement_Create(nsIDOMHTMLElement *nselem)
 {
     HTMLSelectElement *ret = mshtml_alloc(sizeof(HTMLSelectElement));
     nsresult nsres;
 
     ret->lpHTMLSelectElementVtbl = &HTMLSelectElementVtbl;
+    ret->element.node.vtbl = &HTMLSelectElementImplVtbl;
     
     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLSelectElement,
                                              (void**)&ret->nsselect);
@@ -402,7 +408,6 @@
         ERR("Could not get nsIDOMHTMLSelectElement interfce: %08x\n", nsres);
 
     ret->element.impl = (IUnknown*)HTMLSELECT(ret);
-    ret->element.destructor = HTMLSelectElement_destructor;
 
     return &ret->element;
 }
diff --git a/dlls/mshtml/htmltextarea.c b/dlls/mshtml/htmltextarea.c
index 6994d97..38206c2 100644
--- a/dlls/mshtml/htmltextarea.c
+++ b/dlls/mshtml/htmltextarea.c
@@ -391,17 +391,23 @@
     HTMLTextAreaElement *This = HTMLTXTAREA_NODE_THIS(iface);
 
     nsIDOMHTMLTextAreaElement_Release(This->nstextarea);
-    mshtml_free(This);
+
+    HTMLElement_destructor(&This->element.node);
 }
 
 #undef HTMLTXTAREA_NODE_THIS
 
+static const NodeImplVtbl HTMLTextAreaElementImplVtbl = {
+    HTMLTextAreaElement_destructor
+};
+
 HTMLElement *HTMLTextAreaElement_Create(nsIDOMHTMLElement *nselem)
 {
     HTMLTextAreaElement *ret = mshtml_alloc(sizeof(HTMLTextAreaElement));
     nsresult nsres;
 
     ret->lpHTMLTextAreaElementVtbl = &HTMLTextAreaElementVtbl;
+    ret->element.node.vtbl = &HTMLTextAreaElementImplVtbl;
 
     nsres = nsIDOMHTMLElement_QueryInterface(nselem, &IID_nsIDOMHTMLTextAreaElement,
                                              (void**)&ret->nstextarea);
@@ -409,7 +415,6 @@
         ERR("Could not get nsDOMHTMLInputElement: %08x\n", nsres);
 
     ret->element.impl = (IUnknown*)HTMLTXTAREA(ret);
-    ret->element.destructor = HTMLTextAreaElement_destructor;
 
     return &ret->element;
 }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 4e49923..8cb11e7 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -250,10 +250,13 @@
     nsProtocolStream *nsstream;
 };
 
+typedef struct {
+    void (*destructor)(HTMLDOMNode*);
+} NodeImplVtbl;
+
 struct HTMLDOMNode {
     const IHTMLDOMNodeVtbl *lpHTMLDOMNodeVtbl;
-
-    void (*destructor)(HTMLDOMNode*);
+    const NodeImplVtbl *vtbl;
 
     union {
         IUnknown *unk;
@@ -269,10 +272,8 @@
 typedef struct {
     HTMLDOMNode node;
 
-    const IHTMLElementVtbl *lpHTMLElementVtbl;
-    const IHTMLElement2Vtbl *lpHTMLElement2Vtbl;
-
-    void (*destructor)(HTMLDOMNode*);
+    const IHTMLElementVtbl   *lpHTMLElementVtbl;
+    const IHTMLElement2Vtbl  *lpHTMLElement2Vtbl;
 
     nsIDOMHTMLElement *nselem;
 
@@ -427,7 +428,10 @@
 void HTMLTextContainer_Init(HTMLTextContainer*);
 
 HRESULT HTMLDOMNode_QI(HTMLDOMNode*,REFIID,void**);
+void HTMLDOMNode_destructor(HTMLDOMNode*);
+
 HRESULT HTMLElement_QI(HTMLElement*,REFIID,void**);
+void HTMLElement_destructor(HTMLDOMNode*);
 
 HTMLDOMNode *get_node(HTMLDocument*,nsIDOMNode*);
 void release_nodes(HTMLDocument*);