diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in
index 119540b367ca2127ed6f9612a4a6bf6a79eefd7f..9d326ff02868cfdbbd9a926be8b2d8dbab708835 100644
--- a/dlls/mshtml/Makefile.in
+++ b/dlls/mshtml/Makefile.in
@@ -45,6 +45,7 @@ C_SRCS = \
 	install.c \
 	loadopts.c \
 	main.c \
+	mutation.c \
 	navigate.c \
 	nsembed.c \
 	nsevents.c \
diff --git a/dlls/mshtml/htmlelem2.c b/dlls/mshtml/htmlelem2.c
index 5e625e6d6937a2362df7fb738a3c9a9a0f00af49..3e2215557956f370814fc7366b0a154416e00807 100644
--- a/dlls/mshtml/htmlelem2.c
+++ b/dlls/mshtml/htmlelem2.c
@@ -548,18 +548,18 @@ static HRESULT WINAPI HTMLElement2_removeFilter(IHTMLElement2 *iface, IUnknown *
 static HRESULT WINAPI HTMLElement2_get_clientHeight(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 height=0;
     nsresult nsres;
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsIDOMNSHTMLElement_GetClientHeight(nselem, &height);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsIDOMNSElement_GetClientHeight(nselem, &height);
+        nsIDOMNSElement_Release(nselem);
     }else {
-        ERR("Could not get nsIDOMHTMLNSElement: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement: %08x\n", nsres);
     }
 
     *p = height;
@@ -569,18 +569,18 @@ static HRESULT WINAPI HTMLElement2_get_clientHeight(IHTMLElement2 *iface, long *
 static HRESULT WINAPI HTMLElement2_get_clientWidth(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 width=0;
     nsresult nsres;
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsIDOMNSHTMLElement_GetClientWidth(nselem, &width);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsIDOMNSElement_GetClientWidth(nselem, &width);
+        nsIDOMNSElement_Release(nselem);
     }else {
-        ERR("Could not get nsIDOMHTMLNSElement: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement: %08x\n", nsres);
     }
 
     *p = width;
@@ -727,7 +727,7 @@ static HRESULT WINAPI HTMLElement2_createControlRange(IHTMLElement2 *iface, IDis
 static HRESULT WINAPI HTMLElement2_get_scrollHeight(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 height = 0;
     nsresult nsres;
 
@@ -735,15 +735,15 @@ static HRESULT WINAPI HTMLElement2_get_scrollHeight(IHTMLElement2 *iface, long *
 
     nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsres = nsIDOMNSHTMLElement_GetScrollHeight(nselem, &height);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsres = nsIDOMNSElement_GetScrollHeight(nselem, &height);
+        nsIDOMNSElement_Release(nselem);
         if(NS_FAILED(nsres))
             ERR("GetScrollHeight failed: %08x\n", nsres);
     }else {
-        ERR("Could not get nsIDOMNSHTMLElement interface: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement interface: %08x\n", nsres);
     }
 
-    *p = height;
+    *p = height == -1 ? 0 : height;
     TRACE("*p = %ld\n", *p);
 
     return S_OK;
@@ -752,20 +752,20 @@ static HRESULT WINAPI HTMLElement2_get_scrollHeight(IHTMLElement2 *iface, long *
 static HRESULT WINAPI HTMLElement2_get_scrollWidth(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 width = 0;
     nsresult nsres;
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsres = nsIDOMNSHTMLElement_GetScrollWidth(nselem, &width);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsres = nsIDOMNSElement_GetScrollWidth(nselem, &width);
+        nsIDOMNSElement_Release(nselem);
         if(NS_FAILED(nsres))
             ERR("GetScrollWidth failed: %08x\n", nsres);
     }else {
-        ERR("Could not get nsIDOMNSHTMLElement interface: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement interface: %08x\n", nsres);
     }
 
     *p = width;
@@ -777,7 +777,7 @@ static HRESULT WINAPI HTMLElement2_get_scrollWidth(IHTMLElement2 *iface, long *p
 static HRESULT WINAPI HTMLElement2_put_scrollTop(IHTMLElement2 *iface, long v)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     nsresult nsres;
 
     TRACE("(%p)->(%ld)\n", This, v);
@@ -787,12 +787,12 @@ static HRESULT WINAPI HTMLElement2_put_scrollTop(IHTMLElement2 *iface, long v)
         return E_NOTIMPL;
     }
 
-    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsIDOMNSHTMLElement_SetScrollTop(nselem, v);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsIDOMNSElement_SetScrollTop(nselem, v);
+        nsIDOMNSElement_Release(nselem);
     }else {
-        ERR("Could not get nsIDOMNSHTMLElement interface: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement interface: %08x\n", nsres);
     }
 
     return S_OK;
@@ -801,20 +801,20 @@ static HRESULT WINAPI HTMLElement2_put_scrollTop(IHTMLElement2 *iface, long v)
 static HRESULT WINAPI HTMLElement2_get_scrollTop(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 top = 0;
     nsresult nsres;
 
     TRACE("(%p)->(%p)\n", This, p);
 
-    nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsres = nsIDOMNSHTMLElement_GetScrollTop(nselem, &top);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsres = nsIDOMNSElement_GetScrollTop(nselem, &top);
+        nsIDOMNSElement_Release(nselem);
         if(NS_FAILED(nsres))
             ERR("GetScrollTop failed: %08x\n", nsres);
     }else {
-        ERR("Could not get nsIDOMNSHTMLElement interface: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement interface: %08x\n", nsres);
     }
 
     *p = top;
@@ -826,7 +826,7 @@ static HRESULT WINAPI HTMLElement2_get_scrollTop(IHTMLElement2 *iface, long *p)
 static HRESULT WINAPI HTMLElement2_put_scrollLeft(IHTMLElement2 *iface, long v)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     nsresult nsres;
 
     TRACE("(%p)->(%ld)\n", This, v);
@@ -836,12 +836,12 @@ static HRESULT WINAPI HTMLElement2_put_scrollLeft(IHTMLElement2 *iface, long v)
         return E_NOTIMPL;
     }
 
-    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres)) {
-        nsIDOMNSHTMLElement_SetScrollLeft(nselem, v);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsIDOMNSElement_SetScrollLeft(nselem, v);
+        nsIDOMNSElement_Release(nselem);
     }else {
-        ERR("Could not get nsIDOMNSHTMLElement interface: %08x\n", nsres);
+        ERR("Could not get nsIDOMNSElement interface: %08x\n", nsres);
     }
 
     return S_OK;
@@ -850,7 +850,7 @@ static HRESULT WINAPI HTMLElement2_put_scrollLeft(IHTMLElement2 *iface, long v)
 static HRESULT WINAPI HTMLElement2_get_scrollLeft(IHTMLElement2 *iface, long *p)
 {
     HTMLElement *This = HTMLELEM2_THIS(iface);
-    nsIDOMNSHTMLElement *nselem;
+    nsIDOMNSElement *nselem;
     PRInt32 left = 0;
     nsresult nsres;
 
@@ -865,11 +865,11 @@ static HRESULT WINAPI HTMLElement2_get_scrollLeft(IHTMLElement2 *iface, long *p)
         return E_NOTIMPL;
     }
 
-    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSHTMLElement, (void**)&nselem);
+    nsres = nsIDOMHTMLElement_QueryInterface(This->nselem, &IID_nsIDOMNSElement, (void**)&nselem);
     if(NS_SUCCEEDED(nsres))
     {
-        nsres = nsIDOMNSHTMLElement_GetScrollLeft(nselem, &left);
-        nsIDOMNSHTMLElement_Release(nselem);
+        nsres = nsIDOMNSElement_GetScrollLeft(nselem, &left);
+        nsIDOMNSElement_Release(nselem);
         if(NS_FAILED(nsres))
             left = 0;
     }
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 6cb41bdde3d221266228e45c842127a8181af43b..9ebaaaa8e9fe3b76af49f3672606abaaeb8ae711 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -296,6 +296,13 @@ typedef struct {
     NSContainer *This;
 } nsEventListener;
 
+typedef struct _mutation_queue_t {
+    DWORD type;
+    nsISupports *nsiface;
+
+    struct _mutation_queue_t *next;
+} mutation_queue_t;
+
 struct NSContainer {
     const nsIWebBrowserChromeVtbl       *lpWebBrowserChromeVtbl;
     const nsIContextMenuListenerVtbl    *lpContextMenuListenerVtbl;
@@ -306,6 +313,10 @@ struct NSContainer {
     const nsIWeakReferenceVtbl          *lpWeakReferenceVtbl;
     const nsISupportsWeakReferenceVtbl  *lpSupportsWeakReferenceVtbl;
 
+    const nsIDocumentObserverVtbl       *lpDocumentObserverVtbl;
+
+    const nsIRunnableVtbl  *lpRunnableVtbl;
+
     nsEventListener blur_listener;
     nsEventListener focus_listener;
     nsEventListener keypress_listener;
@@ -330,6 +341,9 @@ struct NSContainer {
 
     HWND hwnd;
 
+    mutation_queue_t *mutation_queue;
+    mutation_queue_t *mutation_queue_tail;
+
     nsChannelBSC *bscallback; /* hack */
     HWND reset_focus; /* hack */
 
@@ -434,6 +448,10 @@ typedef struct {
 #define NSWEAKREF(x)     ((nsIWeakReference*)             &(x)->lpWeakReferenceVtbl)
 #define NSSUPWEAKREF(x)  ((nsISupportsWeakReference*)     &(x)->lpSupportsWeakReferenceVtbl)
 
+#define NSDOCOBS(x)      ((nsIDocumentObserver*)          &(x)->lpDocumentObserverVtbl)
+
+#define NSRUNNABLE(x)    ((nsIRunnable*)  &(x)->lpRunnableVtbl)
+
 #define NSCHANNEL(x)     ((nsIChannel*)        &(x)->lpHttpChannelVtbl)
 #define NSHTTPCHANNEL(x) ((nsIHttpChannel*)    &(x)->lpHttpChannelVtbl)
 #define NSUPCHANNEL(x)   ((nsIUploadChannel*)  &(x)->lpUploadChannelVtbl)
@@ -487,6 +505,10 @@ void ConnectionPointContainer_Destroy(ConnectionPointContainer*);
 NSContainer *NSContainer_Create(HTMLDocument*,NSContainer*);
 void NSContainer_Release(NSContainer*);
 
+void init_mutation(NSContainer*);
+void set_mutation_observer(NSContainer*,nsIDOMHTMLDocument*);
+BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment);
+
 void HTMLDocument_LockContainer(HTMLDocument*,BOOL);
 void show_context_menu(HTMLDocument*,DWORD,POINT*,IDispatch*);
 void notif_focus(HTMLDocument*);
diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c
new file mode 100644
index 0000000000000000000000000000000000000000..171190829d3812f0d7c2429550a5865427425b99
--- /dev/null
+++ b/dlls/mshtml/mutation.c
@@ -0,0 +1,437 @@
+/*
+ * Copyright 2008 Jacek Caban for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+
+#define COBJMACROS
+
+#include "windef.h"
+#include "winbase.h"
+#include "winuser.h"
+#include "winreg.h"
+#include "ole2.h"
+
+#include "mshtml_private.h"
+#include "htmlevent.h"
+
+#include "wine/debug.h"
+
+WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
+
+enum {
+    MUTATION_COMMENT,
+    MUTATION_SCRIPT
+};
+
+void set_mutation_observer(NSContainer *nscontainer, nsIDOMHTMLDocument *nshtmldoc)
+{
+    nsIDOMNSDocument *nsdoc;
+    nsresult nsres;
+
+    nsres = nsIDOMHTMLDocument_QueryInterface(nshtmldoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
+    if(NS_FAILED(nsres)) {
+        ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
+        return;
+    }
+
+    nsIDOMNSDocument_WineAddObserver(nsdoc, NSDOCOBS(nscontainer));
+    nsIDOMNSDocument_Release(nsdoc);
+}
+
+static void add_script_runner(NSContainer *This)
+{
+    nsIDOMNSDocument *nsdoc;
+    nsresult nsres;
+
+    nsres = nsIDOMHTMLDocument_QueryInterface(This->doc->nsdoc, &IID_nsIDOMNSDocument, (void**)&nsdoc);
+    if(NS_FAILED(nsres)) {
+        ERR("Could not get nsIDOMNSDocument: %08x\n", nsres);
+        return;
+    }
+
+    nsIDOMNSDocument_WineAddScriptRunner(nsdoc, NSRUNNABLE(This));
+    nsIDOMNSDocument_Release(nsdoc);
+}
+
+#define NSRUNNABLE_THIS(iface) DEFINE_THIS(NSContainer, Runnable, iface)
+
+static nsresult NSAPI nsRunnable_QueryInterface(nsIRunnable *iface,
+        nsIIDRef riid, nsQIResult result)
+{
+    NSContainer *This = NSRUNNABLE_THIS(iface);
+
+    if(IsEqualGUID(riid, &IID_nsISupports)) {
+        TRACE("(%p)->(IID_nsISupports %p)\n", This, result);
+        *result = NSRUNNABLE(This);
+    }else if(IsEqualGUID(riid, &IID_nsIRunnable)) {
+        TRACE("(%p)->(IID_nsIRunnable %p)\n", This, result);
+        *result = NSRUNNABLE(This);
+    }else {
+        *result = NULL;
+        WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
+        return NS_NOINTERFACE;
+    }
+
+    nsISupports_AddRef((nsISupports*)*result);
+    return NS_OK;
+}
+
+static nsrefcnt NSAPI nsRunnable_AddRef(nsIRunnable *iface)
+{
+    NSContainer *This = NSRUNNABLE_THIS(iface);
+    return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsrefcnt NSAPI nsRunnable_Release(nsIRunnable *iface)
+{
+    NSContainer *This = NSRUNNABLE_THIS(iface);
+    return nsIWebBrowserChrome_Release(NSWBCHROME(This));
+}
+
+static void pop_mutation_queue(NSContainer *nscontainer)
+{
+    mutation_queue_t *tmp = nscontainer->mutation_queue;
+
+    if(!tmp)
+        return;
+
+    nscontainer->mutation_queue = tmp->next;
+    if(!tmp->next)
+        nscontainer->mutation_queue_tail = NULL;
+
+    nsISupports_Release(tmp->nsiface);
+    heap_free(tmp);
+}
+
+static nsresult NSAPI nsRunnable_Run(nsIRunnable *iface)
+{
+    NSContainer *This = NSRUNNABLE_THIS(iface);
+    nsresult nsres;
+
+    TRACE("(%p)\n", This);
+
+    while(This->mutation_queue) {
+        switch(This->mutation_queue->type) {
+        case MUTATION_COMMENT: {
+            nsIDOMComment *nscomment;
+            nsAString comment_str;
+            BOOL remove_comment = FALSE;
+
+            nsres = nsISupports_QueryInterface(This->mutation_queue->nsiface, &IID_nsIDOMComment, (void**)&nscomment);
+            if(NS_FAILED(nsres)) {
+                ERR("Could not get nsIDOMComment iface:%08x\n", nsres);
+                return NS_OK;
+            }
+
+            nsAString_Init(&comment_str, NULL);
+            nsres = nsIDOMComment_GetData(nscomment, &comment_str);
+            if(NS_SUCCEEDED(nsres)) {
+                const PRUnichar *comment;
+
+                nsAString_GetData(&comment_str, &comment);
+                remove_comment = handle_insert_comment(This->doc, comment);
+            }
+
+            nsAString_Finish(&comment_str);
+
+            if(remove_comment) {
+                nsIDOMNode *nsparent, *tmp;
+                nsAString magic_str;
+
+                static const PRUnichar remove_comment_magicW[] =
+                    {'#','!','w','i','n','e', 'r','e','m','o','v','e','!','#',0};
+
+                nsAString_Init(&magic_str, remove_comment_magicW);
+                nsres = nsIDOMComment_SetData(nscomment, &magic_str);
+                nsAString_Finish(&magic_str);
+                if(NS_FAILED(nsres))
+                    ERR("SetData failed: %08x\n", nsres);
+
+                nsIDOMComment_GetParentNode(nscomment, &nsparent);
+                if(nsparent) {
+                    nsIDOMNode_RemoveChild(nsparent, (nsIDOMNode*)nscomment, &tmp);
+                    nsIDOMNode_Release(nsparent);
+                    nsIDOMNode_Release(tmp);
+                }
+            }
+
+            nsIDOMComment_Release(nscomment);
+            break;
+        }
+
+        case MUTATION_SCRIPT: {
+            nsIDOMHTMLScriptElement *nsscript;
+
+            nsres = nsISupports_QueryInterface(This->mutation_queue->nsiface, &IID_nsIDOMHTMLScriptElement,
+                                               (void**)&nsscript);
+            if(NS_FAILED(nsres)) {
+                ERR("Could not get nsIDOMHTMLScriptElement: %08x\n", nsres);
+                break;
+            }
+
+            doc_insert_script(This->doc, nsscript);
+            nsIDOMHTMLScriptElement_Release(nsscript);
+            break;
+        }
+
+        default:
+            ERR("invalid type %d\n", This->mutation_queue->type);
+        }
+
+        pop_mutation_queue(This);
+    }
+
+    return S_OK;
+}
+
+#undef NSRUNNABLE_THIS
+
+static const nsIRunnableVtbl nsRunnableVtbl = {
+    nsRunnable_QueryInterface,
+    nsRunnable_AddRef,
+    nsRunnable_Release,
+    nsRunnable_Run
+};
+
+#define NSDOCOBS_THIS(iface) DEFINE_THIS(NSContainer, DocumentObserver, iface)
+
+static nsresult NSAPI nsDocumentObserver_QueryInterface(nsIDocumentObserver *iface,
+        nsIIDRef riid, nsQIResult result)
+{
+    NSContainer *This = NSDOCOBS_THIS(iface);
+
+    if(IsEqualGUID(&IID_nsISupports, riid)) {
+        TRACE("(%p)->(IID_nsISupports, %p)\n", This, result);
+        *result = NSWBCHROME(This);
+    }else if(IsEqualGUID(&IID_nsIMutationObserver, riid)) {
+        TRACE("(%p)->(IID_nsIMutationObserver %p)\n", This, result);
+        *result = NSDOCOBS(This);
+    }else if(IsEqualGUID(&IID_nsIDocumentObserver, riid)) {
+        TRACE("(%p)->(IID_nsIDocumentObserver %p)\n", This, result);
+        *result = NSDOCOBS(This);
+    }else {
+        *result = NULL;
+        TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), result);
+        return NS_NOINTERFACE;
+    }
+
+    nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+    return NS_OK;
+}
+
+static nsrefcnt NSAPI nsDocumentObserver_AddRef(nsIDocumentObserver *iface)
+{
+    NSContainer *This = NSDOCOBS_THIS(iface);
+    return nsIWebBrowserChrome_AddRef(NSWBCHROME(This));
+}
+
+static nsrefcnt NSAPI nsDocumentObserver_Release(nsIDocumentObserver *iface)
+{
+    NSContainer *This = NSDOCOBS_THIS(iface);
+    return nsIWebBrowserChrome_Release(NSWBCHROME(This));
+}
+
+static void NSAPI nsDocumentObserver_CharacterDataWillChange(nsIDocumentObserver *iface,
+        nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo)
+{
+}
+
+static void NSAPI nsDocumentObserver_CharacterDataChanged(nsIDocumentObserver *iface,
+        nsIDocument *aDocument, nsIContent *aContent, void /*CharacterDataChangeInfo*/ *aInfo)
+{
+}
+
+static void NSAPI nsDocumentObserver_AttributeChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContent, PRInt32 aNameSpaceID, nsIAtom *aAttribute, PRInt32 aModType, PRUint32 aStateMask)
+{
+}
+
+static void NSAPI nsDocumentObserver_ContentAppended(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContainer, PRInt32 aNewIndexInContainer)
+{
+}
+
+static void NSAPI nsDocumentObserver_ContentInserted(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
+{
+}
+
+static void NSAPI nsDocumentObserver_ContentRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContainer, nsIContent *aChild, PRInt32 aIndexInContainer)
+{
+}
+
+static void NSAPI nsDocumentObserver_NodeWillBeDestroyed(nsIDocumentObserver *iface, const nsINode *aNode)
+{
+}
+
+static void NSAPI nsDocumentObserver_ParentChainChanged(nsIDocumentObserver *iface, nsIContent *aContent)
+{
+}
+
+static void NSAPI nsDocumentObserver_BeginUpdate(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsUpdateType aUpdateType)
+{
+}
+
+static void NSAPI nsDocumentObserver_EndUpdate(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsUpdateType aUpdateType)
+{
+}
+
+static void NSAPI nsDocumentObserver_BeginLoad(nsIDocumentObserver *iface, nsIDocument *aDocument)
+{
+}
+
+static void NSAPI nsDocumentObserver_EndLoad(nsIDocumentObserver *iface, nsIDocument *aDocument)
+{
+}
+
+static void NSAPI nsDocumentObserver_ContentStatesChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContent1, nsIContent *aContent2, PRInt32 aStateMask)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleSheetAdded(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleSheetRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleSheetApplicableStateChanged(nsIDocumentObserver *iface,
+        nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aApplicable)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleRuleChanged(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIStyleSheet *aStyleSheet, nsIStyleRule *aOldStyleRule, nsIStyleSheet *aNewStyleRule)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleRuleAdded(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)
+{
+}
+
+static void NSAPI nsDocumentObserver_StyleRuleRemoved(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule)
+{
+}
+
+static void push_mutation_queue(NSContainer *nscontainer, DWORD type, nsISupports *nsiface)
+{
+    mutation_queue_t *elem;
+
+    elem = heap_alloc(sizeof(mutation_queue_t));
+    if(!elem)
+        return;
+
+    elem->next = NULL;
+    elem->type = type;
+    elem->nsiface = nsiface;
+    nsISupports_AddRef(nsiface);
+
+    if(nscontainer->mutation_queue_tail)
+        nscontainer->mutation_queue_tail = nscontainer->mutation_queue_tail->next = elem;
+    else
+        nscontainer->mutation_queue = nscontainer->mutation_queue_tail = elem;
+}
+
+static void NSAPI nsDocumentObserver_BindToDocument(nsIDocumentObserver *iface, nsIDocument *aDocument,
+        nsIContent *aContent)
+{
+    NSContainer *This = NSDOCOBS_THIS(iface);
+    nsIDOMComment *nscomment;
+    nsIDOMElement *nselem;
+    nsresult nsres;
+
+    TRACE("(%p)\n", This);
+
+    nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMElement, (void**)&nselem);
+    if(NS_SUCCEEDED(nsres)) {
+        check_event_attr(This->doc, nselem);
+        nsIDOMElement_Release(nselem);
+    }
+
+    nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMComment, (void**)&nscomment);
+    if(NS_SUCCEEDED(nsres)) {
+        TRACE("comment node\n");
+
+        push_mutation_queue(This, MUTATION_COMMENT, (nsISupports*)nscomment);
+        nsIDOMComment_Release(nscomment);
+        add_script_runner(This);
+    }
+}
+
+static void NSAPI nsDocumentObserver_DoneAddingChildren(nsIDocumentObserver *iface, nsIContent *aContent,
+        PRBool aHaveNotified)
+{
+    NSContainer *This = NSDOCOBS_THIS(iface);
+    nsIDOMHTMLScriptElement *nsscript;
+    nsresult nsres;
+
+    TRACE("(%p)->(%p %x)\n", This, aContent, aHaveNotified);
+
+    nsres = nsISupports_QueryInterface(aContent, &IID_nsIDOMHTMLScriptElement, (void**)&nsscript);
+    if(NS_SUCCEEDED(nsres)) {
+        push_mutation_queue(This, MUTATION_SCRIPT, (nsISupports*)nsscript);
+        nsIDOMHTMLScriptElement_Release(nsscript);
+        add_script_runner(This);
+    }
+}
+
+#undef NSMUTATIONOBS_THIS
+
+static const nsIDocumentObserverVtbl nsDocumentObserverVtbl = {
+    nsDocumentObserver_QueryInterface,
+    nsDocumentObserver_AddRef,
+    nsDocumentObserver_Release,
+    nsDocumentObserver_CharacterDataWillChange,
+    nsDocumentObserver_CharacterDataChanged,
+    nsDocumentObserver_AttributeChanged,
+    nsDocumentObserver_ContentAppended,
+    nsDocumentObserver_ContentInserted,
+    nsDocumentObserver_ContentRemoved,
+    nsDocumentObserver_NodeWillBeDestroyed,
+    nsDocumentObserver_ParentChainChanged,
+    nsDocumentObserver_BeginUpdate,
+    nsDocumentObserver_EndUpdate,
+    nsDocumentObserver_BeginLoad,
+    nsDocumentObserver_EndLoad,
+    nsDocumentObserver_ContentStatesChanged,
+    nsDocumentObserver_StyleSheetAdded,
+    nsDocumentObserver_StyleSheetRemoved,
+    nsDocumentObserver_StyleSheetApplicableStateChanged,
+    nsDocumentObserver_StyleRuleChanged,
+    nsDocumentObserver_StyleRuleAdded,
+    nsDocumentObserver_StyleRuleRemoved,
+    nsDocumentObserver_BindToDocument,
+    nsDocumentObserver_DoneAddingChildren
+};
+
+void init_mutation(NSContainer *nscontainer)
+{
+    nscontainer->lpDocumentObserverVtbl  = &nsDocumentObserverVtbl;
+    nscontainer->lpRunnableVtbl          = &nsRunnableVtbl;
+}
diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c
index c7756ae2618c3ab845b792bb7971cb7fe1da2100..0797977c326ceed9063139a31c25673095ca9422 100644
--- a/dlls/mshtml/nsembed.c
+++ b/dlls/mshtml/nsembed.c
@@ -661,7 +661,7 @@ static void nsnode_to_nsstring_rec(nsIContentSerializer *serializer, nsIDOMNode
     case ELEMENT_NODE: {
         nsIDOMElement *nselem;
         nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMElement, (void**)&nselem);
-        nsIContentSerializer_AppendElementStart(serializer, nselem, has_children, str);
+        nsIContentSerializer_AppendElementStart(serializer, nselem, nselem, str);
         nsIDOMElement_Release(nselem);
         break;
     }
@@ -733,7 +733,7 @@ void nsnode_to_nsstring(nsIDOMNode *nsdoc, nsAString *str)
         return;
     }
 
-    nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE);
+    nsres = nsIContentSerializer_Init(serializer, 0, 100, NULL, FALSE, FALSE /* FIXME */);
     if(NS_FAILED(nsres))
         ERR("Init failed: %08x\n", nsres);
 
@@ -816,7 +816,8 @@ void set_ns_editmode(NSContainer *This)
         return;
     }
 
-    nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window, NULL, FALSE);
+    nsres = nsIEditingSession_MakeWindowEditable(editing_session, dom_window,
+            NULL, FALSE, TRUE, TRUE);
     nsIEditingSession_Release(editing_session);
     nsIDOMWindow_Release(dom_window);
     if(NS_FAILED(nsres)) {
@@ -865,6 +866,9 @@ void update_nsdocument(HTMLDocument *doc)
         nsIDOMHTMLDocument_Release(doc->nsdoc);
 
     doc->nsdoc = nsdoc;
+
+    if(nsdoc)
+        set_mutation_observer(doc->nscontainer, nsdoc);
 }
 
 void close_gecko(void)
@@ -1668,6 +1672,7 @@ NSContainer *NSContainer_Create(HTMLDocument *doc, NSContainer *parent)
 
     ret->doc = doc;
     ret->ref = 1;
+    init_mutation(ret);
 
     nsres = nsIComponentManager_CreateInstanceByContractID(pCompMgr, NS_WEBBROWSER_CONTRACTID,
             NULL, &IID_nsIWebBrowser, (void**)&ret->webbrowser);
diff --git a/dlls/mshtml/nsevents.c b/dlls/mshtml/nsevents.c
index 806e9eb6d4ba3ec3be08107cd7fd2a7c4d98a44c..20227f7b7ea1a75b2ed5eb712df982e1b550687d 100644
--- a/dlls/mshtml/nsevents.c
+++ b/dlls/mshtml/nsevents.c
@@ -178,7 +178,7 @@ static nsresult NSAPI handle_load(nsIDOMEventListener *iface, nsIDOMEvent *event
 #define IE_MAJOR_VERSION 7
 #define IE_MINOR_VERSION 0
 
-static BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment)
+BOOL handle_insert_comment(HTMLDocument *doc, const PRUnichar *comment)
 {
     DWORD len;
     int majorv = 0, minorv = 0;
@@ -484,8 +484,6 @@ void init_nsevents(NSContainer *This)
     static const PRUnichar wsz_focus[]     = {'f','o','c','u','s',0};
     static const PRUnichar wsz_keypress[]  = {'k','e','y','p','r','e','s','s',0};
     static const PRUnichar wsz_load[]      = {'l','o','a','d',0};
-    static const PRUnichar DOMNodeInsertedW[] =
-        {'D','O','M','N','o','d','e','I','n','s','e','r','t','e','d',0};
 
     init_listener(&This->blur_listener,        This, &blur_vtbl);
     init_listener(&This->focus_listener,       This, &focus_vtbl);
@@ -511,7 +509,6 @@ void init_nsevents(NSContainer *This)
     init_event(target, wsz_focus,      NSEVENTLIST(&This->focus_listener),       TRUE);
     init_event(target, wsz_keypress,   NSEVENTLIST(&This->keypress_listener),    FALSE);
     init_event(target, wsz_load,       NSEVENTLIST(&This->load_listener),        TRUE);
-    init_event(target, DOMNodeInsertedW,NSEVENTLIST(&This->node_insert_listener),TRUE);
 
     nsIDOMEventTarget_Release(target);
 }
diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl
index 5953143fa908d6a46875865438fda14b2a7f0ede..219ac0c1800ad77df78b72d2712c7ceaf6ef0c06 100644
--- a/dlls/mshtml/nsiface.idl
+++ b/dlls/mshtml/nsiface.idl
@@ -23,7 +23,7 @@
  * compatible with XPCOM, usable in C code.
  */
 
-cpp_quote("#define GECKO_VERSION \"0.1.0\"")
+cpp_quote("#define GECKO_VERSION \"0.9.0\"")
 cpp_quote("#define GECKO_VERSION_STRING \"Wine Gecko \" GECKO_VERSION")
 
 import "wtypes.idl";
@@ -83,6 +83,7 @@ interface nsIEditActionListener;
 interface nsIDocumentStateListener;
 interface nsIDOMCSSStyleSheet;
 interface nsIDOMDocumentView;
+interface nsIDocumentObserver;
 
 interface IMoniker;
 
@@ -126,6 +127,15 @@ typedef nsISupports nsIContentFilter;
 typedef nsISupports nsIDOMMediaList;
 typedef nsISupports nsIDOMHTMLTableCaptionElement;
 typedef nsISupports nsIDOMHTMLTableSectionElement;
+typedef nsISupports nsIDOMClientRectList;
+typedef nsISupports nsIDOMClientRect;
+typedef nsISupports nsIDOMLocation;
+typedef nsISupports nsIBoxObject;
+typedef nsISupports nsIDocument;
+typedef nsISupports nsIContent;
+typedef nsISupports nsINode;
+typedef nsISupports nsIStyleSheet;
+typedef nsISupports nsIStyleRule;
 
 [
     object,
@@ -228,6 +238,17 @@ interface nsIInterfaceRequestor : nsISupports
     nsresult GetInterface(const nsIID *riid, void **result);
 }
 
+[
+    object,
+    uuid(4a2abaf0-6886-11d3-9382-00104ba0fd40),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIRunnable : nsISupports
+{
+    nsresult Run();
+}
+
 [
     object,
     uuid(d1899240-f9d2-11d2-bdd6-000064657374),
@@ -635,6 +656,35 @@ interface nsIDOMElementCSSInlineStyle : nsISupports
     nsresult GetStyle(nsIDOMCSSStyleDeclaration **aStyle);
 }
 
+[
+    object,
+    uuid(f0aef489-18c5-4de6-99d5-58b3758b098c),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIDOMNSElement : nsISupports
+{
+    nsresult GetElementsByClassName(const nsAString *classes, nsIDOMNodeList **_retval);
+    nsresult GetClientRects(nsIDOMClientRectList **_retval);
+    nsresult GetBoundingClientRect(nsIDOMClientRect **_retval);
+    nsresult GetScrollTop(PRInt32 *aScrollTop);
+    nsresult SetScrollTop(PRInt32 aScrollTop);
+    nsresult GetScrollLeft(PRInt32 *aScrollLeft);
+    nsresult SetScrollLeft(PRInt32 aScrollLeft);
+    nsresult GetScrollHeight(PRInt32 *aScrollHeight);
+    nsresult GetScrollWidth(PRInt32 *aScrollWidth);
+    nsresult GetClientTop(PRInt32 *aClientTop);
+    nsresult GetClientLeft(PRInt32 *aClientLeft);
+    nsresult GetClientHeight(PRInt32 *aClientHeight);
+    nsresult GetClientWidth(PRInt32 *aClientWidth);
+    nsresult GetFirstElementChild(nsIDOMElement **aFirstElementChild);
+    nsresult GetLastElementChild(nsIDOMElement **aLastElementChild);
+    nsresult GetPreviousElementSibling(nsIDOMElement **aPreviousElementSibling);
+    nsresult GetNextElementSibling(nsIDOMElement **aNextElementSibling);
+    nsresult GetChildElementCount(PRUint32 *aChildElementCount);
+    nsresult GetChildren(nsIDOMNodeList **aChildren);
+}
+
 cpp_quote("#undef GetClassName")
 
 [
@@ -659,7 +709,7 @@ interface nsIDOMHTMLElement : nsIDOMElement
 
 [
     object,
-    uuid(da83b2ec-8264-4410-8496-ada3acd2ae42),
+    uuid(7f142f9a-fba7-4949-93d6-cf08a974ac51),
     local
     /* NOT_FROZEN */
 ]
@@ -672,19 +722,15 @@ interface nsIDOMNSHTMLElement : nsISupports
     nsresult GetOffsetParent(nsIDOMElement **aOffsetParent);
     nsresult GetInnerHTML(nsAString *aInnerHTML);
     nsresult SetInnerHTML(const nsAString *aInnerHTML);
-    nsresult GetScrollTop(PRInt32 *aScrollTop);
-    nsresult SetScrollTop(PRInt32 aScrollTop);
-    nsresult GetScrollLeft(PRInt32 *aScrollLeft);
-    nsresult SetScrollLeft(PRInt32 aScrollLeft);
-    nsresult GetScrollHeight(PRInt32 *aScrollHeight);
-    nsresult GetScrollWidth(PRInt32 *aScrollWidth);
-    nsresult GetClientHeight(PRInt32 *aClientHeight);
-    nsresult GetClientWidth(PRInt32 *aClientWidth);
     nsresult GetTabIndex(PRInt32 *aTabIndex);
     nsresult SetTabIndex(PRInt32 aTabIndex);
+    nsresult GetContentEditable(nsAString *aContentEditable);
+    nsresult SetContentEditable(const nsAString *aContentEditable);
     nsresult blur();
     nsresult focus();
     nsresult ScrollIntoView(PRBool top);
+    nsresult GetSpellcheck(PRBool *aSpellcheck);
+    nsresult SetSpellcheck(PRBool aSpellcheck);
 }
 
 [
@@ -802,6 +848,34 @@ interface nsIDOMDocument : nsIDOMNode
     nsresult GetElementById(const nsAString *elementId, nsIDOMElement **_retval);
 }
 
+[
+    object,
+    uuid(533a8131-8d0c-4ebf-990b-7fad7cd51466),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIDOMNSDocument : nsISupports
+{
+    nsresult GetCharacterSet(nsAString *aCharacterSet);
+    nsresult GetDir(nsAString *aDir);
+    nsresult SetDir(const nsAString *aDir);
+    nsresult GetLocation(nsIDOMLocation **aLocation);
+    nsresult GetTitle(nsAString *aTitle);
+    nsresult SetTitle(const nsAString *aTitle);
+    nsresult GetContentType(nsAString *aContentType);
+    nsresult GetLastModified(nsAString *aLastModified);
+    nsresult GetReferrer(nsAString *aReferrer);
+    nsresult GetBoxObjectFor(nsIDOMElement *elt, nsIBoxObject **_retval);
+    nsresult HasFocus(PRBool *_retval);
+    nsresult GetActiveElement(nsIDOMElement **aActiveElement);
+    nsresult GetElementsByClassName(const nsAString *classes, nsIDOMNodeList **_retval);
+    nsresult ElementFromPoint(PRInt32 x, PRInt32 y, nsIDOMElement **_retval);
+
+    /* Wine extensions */
+    nsresult WineAddObserver(nsIDocumentObserver *aObserver);
+    nsresult WineAddScriptRunner(nsIRunnable *aRunnable);
+}
+
 [
     object,
     uuid(a6cf9084-15b3-11d2-932e-00805f8add32),
@@ -855,7 +929,7 @@ interface nsIDOMNSHTMLDocument : nsISupports
     nsresult SetDomain(const nsAString *aDomain);
     nsresult GetEmbeds(nsIDOMHTMLCollection **aEmbeds);
     nsresult GetSelection(nsAString *_retval);
-    nsresult Open(nsIDOMDocument **_retval);
+    nsresult Open(nsACString *aContentType, PRBool aReplace, nsIDOMDocument **_retval);
     nsresult Write();
     nsresult Writeln();
     nsresult Clear();
@@ -941,17 +1015,15 @@ interface nsIDOMRange : nsISupports
 
 [
     object,
-    uuid(a6cf90f2-15b3-11d2-932e-00805f8add32),
+    uuid(59188642-23b4-41d6-bde1-302c3906d1f0),
     local
+    /* NOT_FROZEN */
 ]
 interface nsIDOMNSRange : nsISupports
 {
     nsresult CreateContextualFragment([in] const nsAString *fragment, [out] nsIDOMDocumentFragment **_retval);
     nsresult IsPointInRange([in] nsIDOMNode *parent, [in] PRInt32 offset, [out] PRBool *_retval);
     nsresult ComparePoint([in] nsIDOMNode *parent, [in] PRInt32 offset, [out] PRInt16 *_retval);
-    nsresult IntersectsNode([in] nsIDOMNode *n, [out] PRBool *_retval);
-    nsresult CompareNode([in] nsIDOMNode *n, [out] PRUint16 *_retval);
-    nsresult nSDetach();
 }
 
 
@@ -1468,7 +1540,7 @@ interface nsIWebNavigation : nsISupports
 
 [
     object,
-    uuid(f1094df6-ce0e-42c9-9847-2f663172c38d),
+    uuid(5af07661-6477-4235-8814-4a45215855b8),
     local
     /* NOT_FROZEN */
 ]
@@ -1479,7 +1551,7 @@ interface nsIPrintSettings : nsISupports
     nsresult SetPrintOptions(PRInt32 aType, PRBool aTurnOnOff);
     nsresult GetPrintOptions(PRInt32 aType, PRBool *_retval);
     nsresult GetPrintOptionsBits(PRInt32 *_retval);
-    nsresult GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight);
+    nsresult GetEffectivePageSize(double *aWidth, double *aHeight);
     nsresult Clone(nsIPrintSettings **_retval);
     nsresult Assign(nsIPrintSettings *aPS);
     nsresult GetPrintSession(nsIPrintSession **aPrintSession);
@@ -1488,6 +1560,14 @@ interface nsIPrintSettings : nsISupports
     nsresult SetStartPageRange(PRInt32 aStartPageRange);
     nsresult GetEndPageRange(PRInt32 *aEndPageRange);
     nsresult SetEndPageRange(PRInt32 aEndPageRange);
+    nsresult GetEdgeTop(double *aEdgeTop);
+    nsresult SetEdgeTop(double aEdgeTop);
+    nsresult GetEdgeLeft(double *aEdgeLeft);
+    nsresult SetEdgeLeft(double aEdgeLeft);
+    nsresult GetEdgeBottom(double *aEdgeBottom);
+    nsresult SetEdgeBottom(double aEdgeBottom);
+    nsresult GetEdgeRight(double *aEdgeRight);
+    nsresult SetEdgeRight(double aEdgeRight);
     nsresult GetMarginTop(double *aMarginTop);
     nsresult SetMarginTop(double aMarginTop);
     nsresult GetMarginLeft(double *aMarginLeft);
@@ -1496,6 +1576,14 @@ interface nsIPrintSettings : nsISupports
     nsresult SetMarginBottom(double aMarginBottom);
     nsresult GetMarginRight(double *aMarginRight);
     nsresult SetMarginRight(double aMarginRight);
+    nsresult GetUnwriteableMarginTop(double *aUnwriteableMarginTop);
+    nsresult SetUnwriteableMarginTop(double aUnwriteableMarginTop);
+    nsresult GetUnwriteableMarginLeft(double *aUnwriteableMarginLeft);
+    nsresult SetUnwriteableMarginLeft(double aUnwriteableMarginLeft);
+    nsresult GetUnwriteableMarginBottom(double *aUnwriteableMarginBottom);
+    nsresult SetUnwriteableMarginBottom(double aUnwriteableMarginBottom);
+    nsresult GetUnwriteableMarginRight(double *aUnwriteableMarginRight);
+    nsresult SetUnwriteableMarginRight(double aUnwriteableMarginRight);
     nsresult GetScaling(double *aScaling);
     nsresult SetScaling(double aScaling);
     nsresult GetPrintBGColors(PRBool *aPrintBGColors);
@@ -1558,8 +1646,6 @@ interface nsIPrintSettings : nsISupports
     nsresult SetPrintReversed(PRBool aPrintReversed);
     nsresult GetPrintInColor(PRBool *aPrintInColor);
     nsresult SetPrintInColor(PRBool aPrintInColor);
-    nsresult GetPaperSize(PRInt32 *aPaperSize);
-    nsresult SetPaperSize(PRInt32 aPaperSize);
     nsresult GetOrientation(PRInt32 *aOrientation);
     nsresult SetOrientation(PRInt32 aOrientation);
     nsresult GetPrintCommand(PRUnichar **aPrintCommand);
@@ -1572,6 +1658,8 @@ interface nsIPrintSettings : nsISupports
     nsresult SetPrintToFile(PRBool aPrintToFile);
     nsresult GetToFileName(PRUnichar **aToFileName);
     nsresult SetToFileName(const PRUnichar *aToFileName);
+    nsresult GetOutputFormat(PRInt16 *aOutputFormat);
+    nsresult SetOutputFormat(PRInt16 aOutputFormat);
     nsresult GetPrintPageDelay(PRInt32 *aPrintPageDelay);
     nsresult SetPrintPageDelay(PRInt32 aPrintPageDelay);
     nsresult GetIsInitializedFromPrinter(PRBool *aIsInitializedFromPrinter);
@@ -1579,7 +1667,12 @@ interface nsIPrintSettings : nsISupports
     nsresult GetIsInitializedFromPrefs(PRBool *aIsInitializedFromPrefs);
     nsresult SetIsInitializedFromPrefs(PRBool aIsInitializedFromPrefs);
     nsresult SetMarginInTwips(nsMargin *aMargin);
+    nsresult SetEdgeInTwips(nsMargin *aEdge);
     nsresult GetMarginInTwips(nsMargin *aMargin);
+    nsresult GetEdgeInTwips(nsMargin *aEdge);
+    nsresult SetupSilentPrinting();
+    nsresult SetUnwriteableMarginInTwips(nsMargin *aEdge);
+    nsresult GetUnwriteableMarginInTwips(nsMargin *aEdge);
 }
 
 [
@@ -1773,14 +1866,22 @@ interface nsIIOService : nsISupports
 
 [
     object,
-    uuid(f0c5dddb-4713-4603-af2d-bf671838996b),
+    uuid(57322c6f-f4ec-4e46-8253-b74be220de16),
     local,
     /* NOT_FROZEN */
 ]
 interface nsINetUtil : nsISupports
 {
     nsresult ParseContentType(const nsACString *aTypeHeader, nsACString *aCharset,
-                              PRBool *aHadCharset, nsACString *aContentType);
+            PRBool *aHadCharset, nsACString *_retval);
+    nsresult ProtocolHasFlags(nsIURI *aURI, PRUint32 aFlag, PRBool *_retval);
+    nsresult URIChainHasFlags(nsIURI *aURI, PRUint32 aFlags, PRBool *_retval);
+    nsresult ToImmutableURI(nsIURI *aURI, nsIURI **_retval);
+    nsresult EscapeString(const nsACString *aString, PRUint32 aEscapeType, nsACString *_retval);
+    nsresult EscapeURL(const nsACString *aStr, PRUint32 aFlags, nsACString *_retval);
+    nsresult UnescapeString(const nsACString *aStr, PRUint32 aFlags, nsACString *_retval);
+    nsresult ExtractCharsetFromContentType(const nsACString *aTypeHeader, nsACString *aCharset,
+            PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd, PRBool *_retval);
 }
 
 [
@@ -2104,7 +2205,7 @@ interface nsIWindowWatcher : nsISupports
 
 [
     object,
-    uuid(d39fd2b4-3978-45d2-a4be-ba448171b61b),
+    uuid(274cd32e-3675-47e1-9d8a-fc6504ded9ce),
     local
     /* NOT_FROZEN */
 ]
@@ -2112,12 +2213,16 @@ interface nsIEditingSession : nsISupports
 {
     nsresult GetEditorStatus(PRUint32 *aEditorStatus);
     nsresult MakeWindowEditable(nsIDOMWindow *window, const char *aEditorType,
-                                PRBool doAfterUriLoad);
+            PRBool doAfterUriLoad, PRBool aMakeWholeDocumentEditable, PRBool aInteractive);
     nsresult WindowIsEditable(nsIDOMWindow *window, PRBool *_retval);
     nsresult GetEditorForWindow(nsIDOMWindow *window, nsIEditor **_retval);
     nsresult SetupEditorOnWindow(nsIDOMWindow *window);
     nsresult TearDownEditorOnWindow(nsIDOMWindow *window);
     nsresult SetEditorOnControllers(nsIDOMWindow *aWindow, nsIEditor *aEditor);
+    nsresult DisableJSAndPlugins(nsIDOMWindow *aWindow);
+    nsresult RestoreJSAndPlugins(nsIDOMWindow *aWindow);
+    nsresult DetachFromWindow(nsIDOMWindow *aWindow);
+    nsresult ReattachToWindow(nsIDOMWindow *aWindow);
 }
 
 [
@@ -2193,13 +2298,14 @@ interface nsIController : nsISupports
 
 [
     object,
-    uuid(d650439a-ca29-410d-a906-b0557fb62fcd),
+    uuid(34769de0-30d0-4cef-894a-fcd8bb27c4b4),
     local
     /* NOT_FROZEN */
 ]
 interface nsIContentSerializer : nsISupports
 {
-    nsresult Init(PRUint32 flags, PRUint32 aWrapColumn, const char* aCharSet, PRBool aIsCopying);
+    nsresult Init(PRUint32 flags, PRUint32 aWrapColumn, const char* aCharSet, PRBool aIsCopying,
+            PRBool aIsWholeDocument);
     nsresult AppendText(nsIDOMText *aText, PRInt32 aStartOffset, PRInt32 aEndOffset, nsAString *aStr);
     nsresult AppendCDATASection(nsIDOMCDATASection *aCDATASection, PRInt32 aStartOffset,
             PRInt32 aEndOffset, nsAString *aStr);
@@ -2208,7 +2314,8 @@ interface nsIContentSerializer : nsISupports
     nsresult AppendComment(nsIDOMComment *aComment, PRInt32 aStartOffset, PRInt32 aEndOffset,
             nsAString *aStr);
     nsresult AppendDoctype(nsIDOMDocumentType *aDoctype, nsAString *aStr);
-    nsresult AppendElementStart(nsIDOMElement *aElement, PRBool aHasChildren, nsAString *aStr);
+    nsresult AppendElementStart(nsIDOMElement *aElement, nsIDOMElement *aOriginalElement,
+            nsAString *aStr);
     nsresult AppendElementEnd(nsIDOMElement *aElement, nsAString *aStr);
     nsresult Flush(nsAString *aStr);
     nsresult AppendDocumentStart(nsIDOMDocument *aDocument, nsAString *aStr);
@@ -2216,7 +2323,7 @@ interface nsIContentSerializer : nsISupports
 
 [
     object,
-    uuid(D4882FFB-E927-408b-96BE-D4391B456FA9),
+    uuid(96b60ba0-634a-41e4-928e-78ab0b3c4b46),
     local
     /* NOT_FROZEN */
 ]
@@ -2246,8 +2353,9 @@ interface nsIEditor  : nsISupports
     nsresult SetDocumentCharacterSet([in] const nsACString *val);
     nsresult ResetModificationCount();
     nsresult GetModificationCount([out] PRInt32 *_retval);
-    nsresult IncrementModificationCount([in] long aModCount);
+    nsresult IncrementModificationCount([in] PRInt32 aModCount);
     nsresult GetTransactionManager([out] nsITransactionManager **_retval);
+    nsresult SetTransactionManager(nsITransactionManager *aTransactionManager);
     nsresult DoTransaction([in] nsITransaction *txn);
     nsresult EnableUndo([in] PRBool enable);
     nsresult Undo([in] PRUint32 count);
@@ -2261,6 +2369,8 @@ interface nsIEditor  : nsISupports
     nsresult ShouldTxnSetSelection([out] PRBool *_retval);
     nsresult SetShouldTxnSetSelection([in] PRBool should);
     nsresult GetInlineSpellChecker([out] nsIInlineSpellChecker **_retval);
+    nsresult SyncRealTimeSpell();
+    nsresult SetSpellcheckUserOverride(PRBool enable);
     nsresult Cut();
     nsresult CanCut([out] PRBool *_retval);
     nsresult Copy();
@@ -2296,6 +2406,7 @@ interface nsIEditor  : nsISupports
     nsresult DumpContentTree();
     nsresult DebugDumpContent();
     nsresult DebugUnitTests([out] PRInt32 *outNumTests, [out] PRInt32 *outNumTestsFailed);
+    PRBool IsModifiableNode(nsIDOMNode *aNode);
 }
 
 [
@@ -2366,6 +2477,57 @@ interface nsIHTMLEditor : nsISupports
     nsresult SetReturnInParagraphCreatesNewParagraph([in] PRBool prb);
 }
 
+[
+    object,
+    uuid(32e68316-67d4-44a5-8d35-0d390fa9df11),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIMutationObserver : nsISupports
+{
+    void CharacterDataWillChange(nsIDocument *aDocument, nsIContent *aContent,
+                                 void /*CharacterDataChangeInfo*/ *aInfo);
+    void CharacterDataChanged(nsIDocument *aDocument, nsIContent *aContent,
+                              void /*CharacterDataChangeInfo*/ *aInfo);
+    void AttributeChanged(nsIDocument *aDocument, nsIContent *aContent, PRInt32 aNameSpaceID,
+                          nsIAtom *aAttribute, PRInt32 aModType, PRUint32 aStateMask);
+    void ContentAppended(nsIDocument *aDocument, nsIContent *aContainer, PRInt32 aNewIndexInContainer);
+    void ContentInserted(nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aChild,
+                         PRInt32 aIndexInContainer);
+    void ContentRemoved(nsIDocument *aDocument, nsIContent *aContainer, nsIContent *aChild,
+                        PRInt32 aIndexInContainer);
+    void NodeWillBeDestroyed(const nsINode *aNode);
+    void ParentChainChanged(nsIContent *aContent);
+}
+
+[
+    object,
+    uuid(4e14e321-a4bb-49f8-a57a-2363668d14d0),
+    local
+    /* NOT_FROZEN */
+]
+interface nsIDocumentObserver : nsIMutationObserver
+{
+    typedef int nsUpdateType;
+
+    void BeginUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
+    void EndUpdate(nsIDocument *aDocument, nsUpdateType aUpdateType);
+    void BeginLoad(nsIDocument *aDocument);
+    void EndLoad(nsIDocument *aDocument);
+    void ContentStatesChanged(nsIDocument *aDocument, nsIContent *aContent1, nsIContent *aContent2,
+                              PRInt32 aStateMask);
+    void StyleSheetAdded(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet);
+    void StyleSheetRemoved(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, PRBool aDocumentSheet);
+    void StyleSheetApplicableStateChanged(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet,
+                                          PRBool aApplicable);
+    void StyleRuleChanged(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aOldStyleRule,
+                          nsIStyleRule *aNewStyleRule);
+    void StyleRuleAdded(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule);
+    void StyleRuleRemoved(nsIDocument *aDocument, nsIStyleSheet *aStyleSheet, nsIStyleRule *aStyleRule);
+    void BindToDocument(nsIDocument *aDocument, nsIContent *aContent);
+    void DoneAddingContent(nsIContent *aContent, PRBool aHaveNotified);
+}
+
 /*
  * NOTE:
  * This is a private Wine interface that is implemented by our implementation
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c
index c918d12ff72bdc4c564169df982638cc1877c193..7c402b295a9268a305bc1e93ffdf4d0a89af6b97 100644
--- a/dlls/mshtml/nsio.c
+++ b/dlls/mshtml/nsio.c
@@ -2276,11 +2276,76 @@ static nsresult NSAPI nsNetUtil_ParseContentType(nsINetUtil *iface, const nsACSt
     return nsINetUtil_ParseContentType(net_util, aTypeHeader, aCharset, aHadCharset, aContentType);
 }
 
+static nsresult NSAPI nsNetUtil_ProtocolHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
+{
+    TRACE("()\n");
+
+    return nsINetUtil_ProtocolHasFlags(net_util, aURI, aFlags, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_URIChainHasFlags(nsINetUtil *iface, nsIURI *aURI, PRUint32 aFlags, PRBool *_retval)
+{
+    TRACE("(%p %08x %p)\n", aURI, aFlags, _retval);
+
+    if(aFlags == (1<<11)) {
+        *_retval = FALSE;
+        return NS_OK;
+    }
+
+    return nsINetUtil_URIChainHasFlags(net_util, aURI, aFlags, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_ToImmutableURI(nsINetUtil *iface, nsIURI *aURI, nsIURI **_retval)
+{
+    TRACE("(%p %p)\n", aURI, _retval);
+
+    return nsINetUtil_ToImmutableURI(net_util, aURI, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_EscapeString(nsINetUtil *iface, const nsACString *aString,
+                                             PRUint32 aEscapeType, nsACString *_retval)
+{
+    TRACE("(%p %x %p)\n", aString, aEscapeType, _retval);
+
+    return nsINetUtil_EscapeString(net_util, aString, aEscapeType, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_EscapeURL(nsINetUtil *iface, const nsACString *aStr, PRUint32 aFlags,
+                                          nsACString *_retval)
+{
+    TRACE("(%p %08x %p)\n", aStr, aFlags, _retval);
+
+    return nsINetUtil_EscapeURL(net_util, aStr, aFlags, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_UnescapeString(nsINetUtil *iface, const nsACString *aStr,
+                                               PRUint32 aFlags, nsACString *_retval)
+{
+    TRACE("(%p %08x %p)\n", aStr, aFlags, _retval);
+
+    return nsINetUtil_UnescapeString(net_util, aStr, aFlags, _retval);
+}
+
+static nsresult NSAPI nsNetUtil_ExtractCharsetFromContentType(nsINetUtil *iface, const nsACString *aTypeHeader,
+        nsACString *aCharset, PRInt32 *aCharsetStart, PRInt32 *aCharsetEnd, PRBool *_retval)
+{
+    TRACE("(%p %p %p %p %p)\n", aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
+
+    return nsINetUtil_ExtractCharsetFromContentType(net_util, aTypeHeader, aCharset, aCharsetStart, aCharsetEnd, _retval);
+}
+
 static const nsINetUtilVtbl nsNetUtilVtbl = {
     nsNetUtil_QueryInterface,
     nsNetUtil_AddRef,
     nsNetUtil_Release,
-    nsNetUtil_ParseContentType
+    nsNetUtil_ParseContentType,
+    nsNetUtil_ProtocolHasFlags,
+    nsNetUtil_URIChainHasFlags,
+    nsNetUtil_ToImmutableURI,
+    nsNetUtil_EscapeString,
+    nsNetUtil_EscapeURL,
+    nsNetUtil_UnescapeString,
+    nsNetUtil_ExtractCharsetFromContentType
 };
 
 static nsINetUtil nsNetUtil = { &nsNetUtilVtbl };