[MSHTML_WINETEST]
authorChristoph von Wittich <christoph_vw@reactos.org>
Mon, 18 Jan 2010 16:59:11 +0000 (16:59 +0000)
committerChristoph von Wittich <christoph_vw@reactos.org>
Mon, 18 Jan 2010 16:59:11 +0000 (16:59 +0000)
update mshtml winetest to wine 1.1.36

svn path=/trunk/; revision=45136

rostests/winetests/mshtml/dom.c
rostests/winetests/mshtml/events.c
rostests/winetests/mshtml/htmldoc.c
rostests/winetests/mshtml/htmllocation.c [new file with mode: 0644]
rostests/winetests/mshtml/jstest.html [new file with mode: 0644]
rostests/winetests/mshtml/mshtml.rbuild
rostests/winetests/mshtml/rsrc.rc [new file with mode: 0644]
rostests/winetests/mshtml/script.c
rostests/winetests/mshtml/testlist.c

index c13c0a8..5c7380e 100644 (file)
@@ -49,15 +49,26 @@ static const char elem_test_str[] =
     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
     "<test />"
     "<table id=\"tbl\"><tbody><tr></tr><tr id=\"row2\"><td>td1 text</td><td>td2 text</td></tr></tbody></table>"
     "<script id=\"sc\" type=\"text/javascript\"><!--\nfunction Testing() {}\n// -->\n</script>"
     "<test />"
-    "<img id=\"imgid\"/>"
+    "<img id=\"imgid\" name=\"WineImg\"/>"
     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
     "<iframe src=\"about:blank\" id=\"ifr\"></iframe>"
+    "<form id=\"frm\"></form>"
     "</body></html>";
     "</body></html>";
+static const char elem_test2_str[] =
+    "<html><head><title>test</title><style>.body { margin-right: 0px; }</style>"
+    "<body><div id=\"divid\"></div></body>"
+    "</html>";
+
 static const char indent_test_str[] =
     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
 static const char cond_comment_str[] =
     "<html><head><title>test</title></head><body>"
     "<!--[if gte IE 4]> <br> <![endif]-->"
     "</body></html>";
 static const char indent_test_str[] =
     "<html><head><title>test</title></head><body>abc<br /><a href=\"about:blank\">123</a></body></html>";
 static const char cond_comment_str[] =
     "<html><head><title>test</title></head><body>"
     "<!--[if gte IE 4]> <br> <![endif]-->"
     "</body></html>";
+static const char frameset_str[] =
+    "<html><head><title>frameset test</title></head><frameset rows=\"25, 25, *\">"
+    "<frame src=\"about:blank\" name=\"nm1\" id=\"fr1\"><frame src=\"about:blank\" name=\"nm2\" id=\"fr2\">"
+    "<frame src=\"about:blank\" id=\"fr3\">"
+    "</frameset></html>";
 
 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
 
 static WCHAR characterW[] = {'c','h','a','r','a','c','t','e','r',0};
 static WCHAR texteditW[] = {'t','e','x','t','e','d','i','t',0};
@@ -87,7 +98,8 @@ typedef enum {
     ET_IMG,
     ET_TR,
     ET_TD,
     ET_IMG,
     ET_TR,
     ET_TD,
-    ET_IFRAME
+    ET_IFRAME,
+    ET_FORM
 } elem_type_t;
 
 static const IID * const none_iids[] = {
 } elem_type_t;
 
 static const IID * const none_iids[] = {
@@ -304,12 +316,25 @@ static const IID * const iframe_iids[] = {
     &IID_IHTMLElement,
     &IID_IHTMLElement2,
     &IID_IHTMLElement3,
     &IID_IHTMLElement,
     &IID_IHTMLElement2,
     &IID_IHTMLElement3,
+    &IID_IHTMLFrameBase,
     &IID_IHTMLFrameBase2,
     &IID_IDispatchEx,
     &IID_IConnectionPointContainer,
     NULL
 };
 
     &IID_IHTMLFrameBase2,
     &IID_IDispatchEx,
     &IID_IConnectionPointContainer,
     NULL
 };
 
+static const IID * const form_iids[] = {
+    &IID_IHTMLDOMNode,
+    &IID_IHTMLDOMNode2,
+    &IID_IHTMLElement,
+    &IID_IHTMLElement2,
+    &IID_IHTMLElement3,
+    &IID_IHTMLFormElement,
+    &IID_IDispatchEx,
+    &IID_IConnectionPointContainer,
+    NULL
+};
+
 static const IID * const generic_iids[] = {
     &IID_IHTMLDOMNode,
     &IID_IHTMLDOMNode2,
 static const IID * const generic_iids[] = {
     &IID_IHTMLDOMNode,
     &IID_IHTMLDOMNode2,
@@ -341,6 +366,14 @@ static const IID * const cstyle_iids[] = {
     NULL
 };
 
     NULL
 };
 
+static const IID * const img_factory_iids[] = {
+    &IID_IUnknown,
+    &IID_IDispatch,
+    &IID_IDispatchEx,
+    &IID_IHTMLImageElementFactory,
+    NULL
+};
+
 typedef struct {
     const char *tag;
     REFIID *iids;
 typedef struct {
     const char *tag;
     REFIID *iids;
@@ -371,7 +404,8 @@ static const elem_type_info_t elem_type_infos[] = {
     {"IMG",       img_iids,         &DIID_DispHTMLImg},
     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
     {"TD",        td_iids,          NULL},
     {"IMG",       img_iids,         &DIID_DispHTMLImg},
     {"TR",        tr_iids,          &DIID_DispHTMLTableRow},
     {"TD",        td_iids,          NULL},
-    {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame}
+    {"IFRAME",    iframe_iids,      &DIID_DispHTMLIFrame},
+    {"FORM",      form_iids,        &DIID_DispHTMLFormElement}
 };
 
 static const char *dbgstr_guid(REFIID riid)
 };
 
 static const char *dbgstr_guid(REFIID riid)
@@ -429,6 +463,8 @@ static IHTMLDocument2 *create_document(void)
     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IHTMLDocument2, (void**)&doc);
     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IHTMLDocument2, (void**)&doc);
     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+    if(FAILED(hres))
+        return NULL;
 
     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
     if(FAILED(hres)) {
 
     hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
     if(FAILED(hres)) {
@@ -466,7 +502,7 @@ static BOOL _test_get_dispid(unsigned line, IUnknown *unk, IID *iid)
     HRESULT hres;
 
     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
     HRESULT hres;
 
     hres = IUnknown_QueryInterface(unk, &IID_IDispatchEx, (void**)&dispex);
-    ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatch: %08x\n", hres);
+    ok_(__FILE__,line) (hres == S_OK, "Could not get IDispatchEx: %08x\n", hres);
     if(FAILED(hres))
         return FALSE;
 
     if(FAILED(hres))
         return FALSE;
 
@@ -621,6 +657,17 @@ static IHTMLAnchorElement *_get_anchor_iface(unsigned line, IUnknown *unk)
     return anchor;
 }
 
     return anchor;
 }
 
+#define get_text_iface(u) _get_text_iface(__LINE__,u)
+static IHTMLDOMTextNode *_get_text_iface(unsigned line, IUnknown *unk)
+{
+    IHTMLDOMTextNode *text;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IHTMLDOMTextNode, (void**)&text);
+    ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLDOMTextNode: %08x\n", hres);
+    return text;
+}
+
 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
 {
 #define test_node_name(u,n) _test_node_name(__LINE__,u,n)
 static void _test_node_name(unsigned line, IUnknown *unk, const char *exname)
 {
@@ -641,21 +688,36 @@ static IHTMLDocument2 *_get_owner_doc(unsigned line, IUnknown *unk)
 {
     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
     IDispatch *disp = (void*)0xdeadbeef;
 {
     IHTMLDOMNode2 *node = _get_node2_iface(line, unk);
     IDispatch *disp = (void*)0xdeadbeef;
-    IHTMLDocument2 *doc;
+    IHTMLDocument2 *doc = NULL;
     HRESULT hres;
 
     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
     IHTMLDOMNode2_Release(node);
     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
     HRESULT hres;
 
     hres = IHTMLDOMNode2_get_ownerDocument(node, &disp);
     IHTMLDOMNode2_Release(node);
     ok_(__FILE__,line)(hres == S_OK, "get_ownerDocument failed: %08x\n", hres);
-    ok_(__FILE__,line)(disp != NULL, "disp = NULL\n");
 
 
-    hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
-    IDispatch_Release(disp);
-    ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
+    if(disp) {
+        hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
+        IDispatch_Release(disp);
+        ok_(__FILE__,line)(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
+    }
 
     return doc;
 }
 
 
     return doc;
 }
 
+#define get_doc_window(d) _get_doc_window(__LINE__,d)
+static IHTMLWindow2 *_get_doc_window(unsigned line, IHTMLDocument2 *doc)
+{
+    IHTMLWindow2 *window;
+    HRESULT hres;
+
+    window = NULL;
+    hres = IHTMLDocument2_get_parentWindow(doc, &window);
+    ok_(__FILE__,line)(hres == S_OK, "get_parentWindow failed: %08x\n", hres);
+    ok_(__FILE__,line)(window != NULL, "window == NULL\n");
+
+    return window;
+}
+
 #define clone_node(n,d) _clone_node(__LINE__,n,d)
 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
 {
 #define clone_node(n,d) _clone_node(__LINE__,n,d)
 static IHTMLDOMNode *_clone_node(unsigned line, IUnknown *unk, VARIANT_BOOL deep)
 {
@@ -809,6 +871,64 @@ static IHTMLDocument2 *_get_doc_node(unsigned line, IHTMLDocument2 *doc)
     return ret;
 }
 
     return ret;
 }
 
+#define test_window_name(d,e) _test_window_name(__LINE__,d,e)
+static void _test_window_name(unsigned line, IHTMLWindow2 *window, const char *exname)
+{
+    BSTR name;
+    HRESULT hres;
+
+    hres = IHTMLWindow2_get_name(window, &name);
+    ok_(__FILE__,line)(hres == S_OK, "get_name failed: %08x\n", hres);
+    if(exname)
+        ok_(__FILE__,line)(!strcmp_wa(name, exname), "name = %s\n", wine_dbgstr_w(name));
+    else
+        ok_(__FILE__,line)(!name, "name = %s\n", wine_dbgstr_w(name));
+}
+
+#define set_window_name(w,n) _set_window_name(__LINE__,w,n)
+static void _set_window_name(unsigned line, IHTMLWindow2 *window, const char *name)
+{
+    BSTR str;
+    HRESULT hres;
+
+    str = a2bstr(name);
+    hres = IHTMLWindow2_put_name(window, str);
+    SysFreeString(str);
+    ok_(__FILE__,line)(hres == S_OK, "put_name failed: %08x\n", hres);
+
+    _test_window_name(line, window, name);
+}
+
+#define test_window_length(w,l) _test_window_length(__LINE__,w,l)
+static void _test_window_length(unsigned line, IHTMLWindow2 *window, LONG exlen)
+{
+    LONG length = -1;
+    HRESULT hres;
+
+    hres = IHTMLWindow2_get_length(window, &length);
+    ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
+    ok_(__FILE__,line)(length == exlen, "length = %d, expected %d\n", length, exlen);
+}
+
+#define get_frame_content_window(e) _get_frame_content_window(__LINE__,e)
+static IHTMLWindow2 *_get_frame_content_window(unsigned line, IUnknown *elem)
+{
+    IHTMLFrameBase2 *base2;
+    IHTMLWindow2 *window;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
+    ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
+
+    window = NULL;
+    hres = IHTMLFrameBase2_get_contentWindow(base2, &window);
+    IHTMLFrameBase2_Release(base2);
+    ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
+    ok(window != NULL, "contentWindow = NULL\n");
+
+    return window;
+}
+
 static void test_get_set_attr(IHTMLDocument2 *doc)
 {
     IHTMLElement *elem;
 static void test_get_set_attr(IHTMLDocument2 *doc)
 {
     IHTMLElement *elem;
@@ -875,8 +995,8 @@ static void test_get_set_attr(IHTMLDocument2 *doc)
     bstr = a2bstr("newattribute");
     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
     bstr = a2bstr("newattribute");
     hres = IHTMLElement_getAttribute(elem, bstr, 0, &val);
     ok(hres == S_OK, "getAttribute failed: %08x\n", hres);
-    todo_wine ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
-    todo_wine ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
+    ok(V_VT(&val) == VT_BOOL, "variant type should have been VT_BOOL (0x%x), was: 0x%x\n", VT_BOOL, V_VT(&val));
+    ok(V_BOOL(&val) == VARIANT_TRUE, "variant value should have been VARIANT_TRUE (0x%x), was %d\n", VARIANT_TRUE, V_BOOL(&val));
     VariantClear(&val);
     SysFreeString(bstr);
 
     VariantClear(&val);
     SysFreeString(bstr);
 
@@ -1002,6 +1122,105 @@ static IHTMLOptionElement *_create_option_elem(unsigned line, IHTMLDocument2 *do
     return option;
 }
 
     return option;
 }
 
+#define test_img_width(o,w) _test_img_width(__LINE__,o,w)
+static void _test_img_width(unsigned line, IHTMLImgElement *img, const long exp)
+{
+    LONG found = -1;
+    HRESULT hres;
+
+    hres = IHTMLImgElement_get_width(img, &found);
+    todo_wine ok_(__FILE__,line) (hres == S_OK, "get_width failed: %08x\n", hres);
+    todo_wine ok_(__FILE__,line) (found == exp, "width=%d\n", found);
+}
+
+#define test_img_put_width(o,w) _test_img_put_width(__LINE__,o,w)
+static void _test_img_put_width(unsigned line, IHTMLImgElement *img, const long width)
+{
+    HRESULT hres;
+
+    hres = IHTMLImgElement_put_width(img, width);
+    todo_wine ok(hres == S_OK, "put_width failed: %08x\n", hres);
+
+    _test_img_width(line, img, width);
+}
+
+#define test_img_height(o,h) _test_img_height(__LINE__,o,h)
+static void _test_img_height(unsigned line, IHTMLImgElement *img, const long exp)
+{
+    LONG found = -1;
+    HRESULT hres;
+
+    hres = IHTMLImgElement_get_height(img, &found);
+    todo_wine ok_(__FILE__,line) (hres == S_OK, "get_height failed: %08x\n", hres);
+    todo_wine ok_(__FILE__,line) (found == exp, "height=%d\n", found);
+}
+
+#define test_img_put_height(o,w) _test_img_put_height(__LINE__,o,w)
+static void _test_img_put_height(unsigned line, IHTMLImgElement *img, const long height)
+{
+    HRESULT hres;
+
+    hres = IHTMLImgElement_put_height(img, height);
+    todo_wine ok(hres == S_OK, "put_height failed: %08x\n", hres);
+
+    _test_img_height(line, img, height);
+}
+
+#define create_img_elem(d,t,v) _create_img_elem(__LINE__,d,t,v)
+static IHTMLImgElement *_create_img_elem(unsigned line, IHTMLDocument2 *doc,
+        LONG wdth, LONG hght)
+{
+    IHTMLImageElementFactory *factory;
+    IHTMLImgElement *img;
+    IHTMLWindow2 *window;
+    VARIANT width, height;
+    char buf[16];
+    HRESULT hres;
+
+    hres = IHTMLDocument2_get_parentWindow(doc, &window);
+    ok_(__FILE__,line) (hres == S_OK, "get_parentElement failed: %08x\n", hres);
+
+    hres = IHTMLWindow2_get_Image(window, &factory);
+    IHTMLWindow2_Release(window);
+    ok_(__FILE__,line) (hres == S_OK, "get_Image failed: %08x\n", hres);
+
+    test_ifaces((IUnknown*)factory, img_factory_iids);
+    test_disp((IUnknown*)factory, &IID_IHTMLImageElementFactory, "[object]");
+
+    if(wdth >= 0){
+        snprintf(buf, 16, "%d", wdth);
+        V_VT(&width) = VT_BSTR;
+        V_BSTR(&width) = a2bstr(buf);
+    }else{
+        V_VT(&width) = VT_EMPTY;
+        wdth = 0;
+    }
+
+    if(hght >= 0){
+        snprintf(buf, 16, "%d", hght);
+        V_VT(&height) = VT_BSTR;
+        V_BSTR(&height) = a2bstr(buf);
+    }else{
+        V_VT(&height) = VT_EMPTY;
+        hght = 0;
+    }
+
+    hres = IHTMLImageElementFactory_create(factory, width, height, &img);
+    ok_(__FILE__,line) (hres == S_OK, "create failed: %08x\n", hres);
+
+    IHTMLImageElementFactory_Release(factory);
+    VariantClear(&width);
+    VariantClear(&height);
+
+    if(SUCCEEDED(hres)) {
+        _test_img_width(line, img, wdth);
+        _test_img_height(line, img, hght);
+        return img;
+    }
+
+    return NULL;
+}
+
 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
 {
 #define test_select_length(s,l) _test_select_length(__LINE__,s,l)
 static void _test_select_length(unsigned line, IHTMLSelectElement *select, LONG length)
 {
@@ -1404,6 +1623,21 @@ static void _test_elem_set_innerhtml(unsigned line, IUnknown *unk, const char *i
     SysFreeString(html);
 }
 
     SysFreeString(html);
 }
 
+#define test_elem_set_outerhtml(e,t) _test_elem_set_outerhtml(__LINE__,e,t)
+static void _test_elem_set_outerhtml(unsigned line, IUnknown *unk, const char *outer_html)
+{
+    IHTMLElement *elem = _get_elem_iface(line, unk);
+    BSTR html;
+    HRESULT hres;
+
+    html = a2bstr(outer_html);
+    hres = IHTMLElement_put_outerHTML(elem, html);
+    ok_(__FILE__,line)(hres == S_OK, "put_outerHTML failed: %08x\n", hres);
+
+    IHTMLElement_Release(elem);
+    SysFreeString(html);
+}
+
 #define get_first_child(n) _get_first_child(__LINE__,n)
 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
 {
 #define get_first_child(n) _get_first_child(__LINE__,n)
 static IHTMLDOMNode *_get_first_child(unsigned line, IUnknown *unk)
 {
@@ -1446,6 +1680,20 @@ static IHTMLDOMNode *_test_node_get_parent(unsigned line, IUnknown *unk)
     return parent;
 }
 
     return parent;
 }
 
+#define node_get_next(u) _node_get_next(__LINE__,u)
+static IHTMLDOMNode *_node_get_next(unsigned line, IUnknown *unk)
+{
+    IHTMLDOMNode *node = _get_node_iface(line, unk);
+    IHTMLDOMNode *next;
+    HRESULT hres;
+
+    hres = IHTMLDOMNode_get_nextSibling(node, &next);
+    IHTMLDOMNode_Release(node);
+    ok_(__FILE__,line) (hres == S_OK, "get_nextSiblibg failed: %08x\n", hres);
+
+    return next;
+}
+
 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
 {
 #define test_elem_get_parent(u) _test_elem_get_parent(__LINE__,u)
 static IHTMLElement *_test_elem_get_parent(unsigned line, IUnknown *unk)
 {
@@ -1501,6 +1749,19 @@ static void _test_select_get_disabled(unsigned line, IHTMLSelectElement *select,
     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
 }
 
     _test_elem3_get_disabled(line, (IUnknown*)select, exb);
 }
 
+#define test_text_length(u,l) _test_text_length(__LINE__,u,l)
+static void _test_text_length(unsigned line, IUnknown *unk, LONG l)
+{
+    IHTMLDOMTextNode *text = _get_text_iface(line, unk);
+    LONG length;
+    HRESULT hres;
+
+    hres = IHTMLDOMTextNode_get_length(text, &length);
+    ok_(__FILE__,line)(hres == S_OK, "get_length failed: %08x\n", hres);
+    ok_(__FILE__,line)(length == l, "length = %d, expected %d\n", length, l);
+    IHTMLDOMTextNode_Release(text);
+}
+
 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
 {
 #define test_select_set_disabled(i,b) _test_select_set_disabled(__LINE__,i,b)
 static void _test_select_set_disabled(unsigned line, IHTMLSelectElement *select, VARIANT_BOOL b)
 {
@@ -1666,6 +1927,20 @@ static void _test_img_set_alt(unsigned line, IUnknown *unk, const char *alt)
     _test_img_alt(line, unk, alt);
 }
 
     _test_img_alt(line, unk, alt);
 }
 
+#define test_img_name(u, c) _test_img_name(__LINE__,u, c)
+static void _test_img_name(unsigned line, IUnknown *unk, const char *pValue)
+{
+    IHTMLImgElement *img = _get_img_iface(line, unk);
+    BSTR sName;
+    HRESULT hres;
+
+    hres = IHTMLImgElement_get_name(img, &sName);
+    ok_(__FILE__,line) (hres == S_OK, "get_Name failed: %08x\n", hres);
+    ok_(__FILE__,line) (!strcmp_wa (sName, pValue), "expected '%s' got '%s'\n", pValue, wine_dbgstr_w(sName));
+    SysFreeString(sName);
+}
+
+
 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
 {
 #define test_input_get_disabled(i,b) _test_input_get_disabled(__LINE__,i,b)
 static void _test_input_get_disabled(unsigned line, IHTMLInputElement *input, VARIANT_BOOL exb)
 {
@@ -1847,6 +2122,39 @@ static void _test_elem_set_tabindex(unsigned line, IUnknown *unk, short index)
     _test_elem_tabindex(line, unk, index);
 }
 
     _test_elem_tabindex(line, unk, index);
 }
 
+#define test_elem_filters(u) _test_elem_filters(__LINE__,u)
+static void _test_elem_filters(unsigned line, IUnknown *unk)
+{
+    IHTMLElement *elem = _get_elem_iface(line, unk);
+    HRESULT hres;
+    IHTMLFiltersCollection *filters;
+
+    hres = IHTMLElement_get_filters(elem, &filters);
+    ok_(__FILE__,line) (hres == S_OK || broken(hres == REGDB_E_CLASSNOTREG) /* NT4 */,
+                        "get_filters failed: %08x\n", hres);
+    if(hres == S_OK)
+    {
+        LONG len;
+        IDispatchEx *dispex;
+
+        hres = IHTMLFiltersCollection_get_length(filters, &len);
+        ok_(__FILE__,line) (hres == S_OK, "get_length failed: %08x\n", hres);
+        ok_(__FILE__,line) (len == 0, "expect 0 got %d\n", len);
+
+        hres = IHTMLFiltersCollection_QueryInterface(filters, &IID_IDispatchEx, (void**)&dispex);
+        ok_(__FILE__,line) (hres == S_OK || broken(hres == E_NOINTERFACE),
+                            "Could not get IDispatchEx interface: %08x\n", hres);
+        if(SUCCEEDED(hres)) {
+            test_disp((IUnknown*)filters, &IID_IHTMLFiltersCollection, "[object]");
+            IDispatchEx_Release(dispex);
+        }
+
+        IHTMLFiltersCollection_Release(filters);
+    }
+
+    IHTMLElement_Release(elem);
+}
+
 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
 {
 #define test_elem_set_class(u,c) _test_elem_set_class(__LINE__,u,c)
 static void _test_elem_set_class(unsigned line, IUnknown *unk, const char *class)
 {
@@ -2000,6 +2308,40 @@ static void _test_elem_client_rect(unsigned line, IUnknown *unk)
     IHTMLElement2_Release(elem);
 }
 
     IHTMLElement2_Release(elem);
 }
 
+#define get_elem_doc(e) _get_elem_doc(__LINE__,e)
+static IHTMLDocument2 *_get_elem_doc(unsigned line, IUnknown *unk)
+{
+    IHTMLElement *elem = _get_elem_iface(line, unk);
+    IHTMLDocument2 *doc;
+    IDispatch *disp;
+    HRESULT hres;
+
+    disp = NULL;
+    hres = IHTMLElement_get_document(elem, &disp);
+    ok(hres == S_OK, "get_document failed: %08x\n", hres);
+    ok(disp != NULL, "disp == NULL\n");
+
+    hres = IDispatch_QueryInterface(disp, &IID_IHTMLDocument2, (void**)&doc);
+    IDispatch_Release(disp);
+    ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
+
+    return doc;
+}
+
+#define get_window_doc(e) _get_window_doc(__LINE__,e)
+static IHTMLDocument2 *_get_window_doc(unsigned line, IHTMLWindow2 *window)
+{
+    IHTMLDocument2 *doc;
+    HRESULT hres;
+
+    doc = NULL;
+    hres = IHTMLWindow2_get_document(window, &doc);
+    ok(hres == S_OK, "get_document failed: %08x\n", hres);
+    ok(doc != NULL, "disp == NULL\n");
+
+    return doc;
+}
+
 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
 {
 #define test_create_elem(d,t) _test_create_elem(__LINE__,d,t)
 static IHTMLElement *_test_create_elem(unsigned line, IHTMLDocument2 *doc, const char *tag)
 {
@@ -2378,6 +2720,30 @@ static void test_create_option_elem(IHTMLDocument2 *doc)
     IHTMLOptionElement_Release(option);
 }
 
     IHTMLOptionElement_Release(option);
 }
 
+static void test_create_img_elem(IHTMLDocument2 *doc)
+{
+    IHTMLImgElement *img;
+
+    img = create_img_elem(doc, 10, 15);
+
+    if(img){
+        test_img_put_width(img, 5);
+        test_img_put_height(img, 20);
+
+        IHTMLImgElement_Release(img);
+        img = NULL;
+    }
+
+    img = create_img_elem(doc, -1, -1);
+
+    if(img){
+        test_img_put_width(img, 5);
+        test_img_put_height(img, 20);
+
+        IHTMLImgElement_Release(img);
+    }
+}
+
 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
 {
     IHTMLBodyElement *body;
 static IHTMLTxtRange *test_create_body_range(IHTMLDocument2 *doc)
 {
     IHTMLBodyElement *body;
@@ -2753,6 +3119,60 @@ static void test_navigator(IHTMLDocument2 *doc)
     ok(!ref, "navigator should be destroyed here\n");
 }
 
     ok(!ref, "navigator should be destroyed here\n");
 }
 
+static void test_screen(IHTMLWindow2 *window)
+{
+    IHTMLScreen *screen, *screen2;
+    IDispatchEx *dispex;
+    LONG l, exl;
+    HDC hdc;
+    HRESULT hres;
+
+    static const WCHAR displayW[] = {'D','I','S','P','L','A','Y',0};
+
+    screen = NULL;
+    hres = IHTMLWindow2_get_screen(window, &screen);
+    ok(hres == S_OK, "get_screen failed: %08x\n", hres);
+    ok(screen != NULL, "screen == NULL\n");
+
+    screen2 = NULL;
+    hres = IHTMLWindow2_get_screen(window, &screen2);
+    ok(hres == S_OK, "get_screen failed: %08x\n", hres);
+    ok(screen2 != NULL, "screen == NULL\n");
+    ok(iface_cmp((IUnknown*)screen2, (IUnknown*)screen), "screen2 != screen\n");
+    IHTMLScreen_Release(screen2);
+
+    hres = IHTMLScreen_QueryInterface(screen, &IID_IDispatchEx, (void**)&dispex);
+    ok(hres == S_OK || broken(hres == E_NOINTERFACE), "Could not get IDispatchEx interface: %08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        test_disp((IUnknown*)screen, &DIID_DispHTMLScreen, "[object]");
+        IDispatchEx_Release(dispex);
+    }
+
+    hdc = CreateICW(displayW, NULL, NULL, NULL);
+
+    exl = GetDeviceCaps(hdc, HORZRES);
+    l = 0xdeadbeef;
+    hres = IHTMLScreen_get_width(screen, &l);
+    ok(hres == S_OK, "get_width failed: %08x\n", hres);
+    ok(l == exl, "width = %d, expected %d\n", l, exl);
+
+    exl = GetDeviceCaps(hdc, VERTRES);
+    l = 0xdeadbeef;
+    hres = IHTMLScreen_get_height(screen, &l);
+    ok(hres == S_OK, "get_height failed: %08x\n", hres);
+    ok(l == exl, "height = %d, expected %d\n", l, exl);
+
+    exl = GetDeviceCaps(hdc, BITSPIXEL);
+    l = 0xdeadbeef;
+    hres = IHTMLScreen_get_colorDepth(screen, &l);
+    ok(hres == S_OK, "get_height failed: %08x\n", hres);
+    ok(l == exl, "height = %d, expected %d\n", l, exl);
+
+    DeleteObject(hdc);
+
+    IHTMLScreen_Release(screen);
+}
+
 static void test_current_style(IHTMLCurrentStyle *current_style)
 {
     BSTR str;
 static void test_current_style(IHTMLCurrentStyle *current_style)
 {
     BSTR str;
@@ -3017,6 +3437,7 @@ static void test_current_style(IHTMLCurrentStyle *current_style)
 
 static void test_style2(IHTMLStyle2 *style2)
 {
 
 static void test_style2(IHTMLStyle2 *style2)
 {
+    VARIANT v;
     BSTR str;
     HRESULT hres;
 
     BSTR str;
     HRESULT hres;
 
@@ -3035,6 +3456,27 @@ static void test_style2(IHTMLStyle2 *style2)
     ok(hres == S_OK, "get_position failed: %08x\n", hres);
     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
     SysFreeString(str);
     ok(hres == S_OK, "get_position failed: %08x\n", hres);
     ok(!strcmp_wa(str, "absolute"), "get_position returned %s\n", wine_dbgstr_w(str));
     SysFreeString(str);
+
+    /* Test right */
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLStyle2_get_right(style2, &v);
+    ok(hres == S_OK, "get_top failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(right)=%d\n", V_VT(&v));
+    ok(!V_BSTR(&v), "V_BSTR(right) != NULL\n");
+    VariantClear(&v);
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = a2bstr("3px");
+    hres = IHTMLStyle2_put_right(style2, v);
+    ok(hres == S_OK, "put_right failed: %08x\n", hres);
+    VariantClear(&v);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLStyle2_get_right(style2, &v);
+    ok(hres == S_OK, "get_right failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(v)=%d\n", V_VT(&v));
+    ok(!strcmp_wa(V_BSTR(&v), "3px"), "V_BSTR(v) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
 }
 
 static void test_style3(IHTMLStyle3 *style3)
 }
 
 static void test_style3(IHTMLStyle3 *style3)
@@ -3429,6 +3871,24 @@ static void test_default_style(IHTMLStyle *style)
     hres = IHTMLStyle_put_margin(style, NULL);
     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
 
     hres = IHTMLStyle_put_margin(style, NULL);
     ok(hres == S_OK, "put_margin failed: %08x\n", hres);
 
+    str = (void*)0xdeadbeef;
+    hres = IHTMLStyle_get_marginTop(style, &v);
+    ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(marginTop) = %d\n", V_VT(&v));
+    ok(!V_BSTR(&v), "V_BSTR(marginTop) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = a2bstr("6px");
+    hres = IHTMLStyle_put_marginTop(style, v);
+    SysFreeString(V_BSTR(&v));
+    ok(hres == S_OK, "put_marginTop failed: %08x\n", hres);
+
+    str = (void*)0xdeadbeef;
+    hres = IHTMLStyle_get_marginTop(style, &v);
+    ok(hres == S_OK, "get_marginTop failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(marginTop) = %d\n", V_VT(&v));
+    ok(!strcmp_wa(V_BSTR(&v), "6px"), "V_BSTR(marginTop) = %s\n", wine_dbgstr_w(V_BSTR(&v)));
+
     str = NULL;
     hres = IHTMLStyle_get_border(style, &str);
     ok(hres == S_OK, "get_border failed: %08x\n", hres);
     str = NULL;
     hres = IHTMLStyle_get_border(style, &str);
     ok(hres == S_OK, "get_border failed: %08x\n", hres);
@@ -3943,6 +4403,108 @@ static void test_default_style(IHTMLStyle *style)
     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
     SysFreeString(sDefault);
 
     ok(hres == S_OK, "put_borderColor failed: %08x\n", hres);
     SysFreeString(sDefault);
 
+    /* BorderRight */
+    hres = IHTMLStyle_get_borderRight(style, &sDefault);
+    ok(hres == S_OK, "get_borderRight failed: %08x\n", hres);
+
+    str = a2bstr("thick dotted red");
+    hres = IHTMLStyle_put_borderRight(style, str);
+    ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
+    SysFreeString(str);
+
+    /* IHTMLStyle_get_borderRight appears to have a bug where
+        it returns the first letter of the color.  So we check
+        each style individually.
+     */
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderRightColor(style, &v);
+    todo_wine ok(hres == S_OK, "get_borderRightColor failed: %08x\n", hres);
+    todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderRightWidth(style, &v);
+    ok(hres == S_OK, "get_borderRightWidth failed: %08x\n", hres);
+    ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    hres = IHTMLStyle_get_borderRightStyle(style, &str);
+    ok(hres == S_OK, "get_borderRightStyle failed: %08x\n", hres);
+    ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    hres = IHTMLStyle_put_borderRight(style, sDefault);
+    ok(hres == S_OK, "put_borderRight failed: %08x\n", hres);
+    SysFreeString(sDefault);
+
+    /* BorderTop */
+    hres = IHTMLStyle_get_borderTop(style, &sDefault);
+    ok(hres == S_OK, "get_borderTop failed: %08x\n", hres);
+
+    str = a2bstr("thick dotted red");
+    hres = IHTMLStyle_put_borderTop(style, str);
+    ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
+    SysFreeString(str);
+
+    /* IHTMLStyle_get_borderTop appears to have a bug where
+        it returns the first letter of the color.  So we check
+        each style individually.
+     */
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderTopColor(style, &v);
+    todo_wine ok(hres == S_OK, "get_borderTopColor failed: %08x\n", hres);
+    todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderTopWidth(style, &v);
+    ok(hres == S_OK, "get_borderTopWidth failed: %08x\n", hres);
+    ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    hres = IHTMLStyle_get_borderTopStyle(style, &str);
+    ok(hres == S_OK, "get_borderTopStyle failed: %08x\n", hres);
+    ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    hres = IHTMLStyle_put_borderTop(style, sDefault);
+    ok(hres == S_OK, "put_borderTop failed: %08x\n", hres);
+    SysFreeString(sDefault);
+
+    /* BorderBottom */
+    hres = IHTMLStyle_get_borderBottom(style, &sDefault);
+    ok(hres == S_OK, "get_borderBottom failed: %08x\n", hres);
+
+    str = a2bstr("thick dotted red");
+    hres = IHTMLStyle_put_borderBottom(style, str);
+    ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
+    SysFreeString(str);
+
+    /* IHTMLStyle_get_borderBottom appears to have a bug where
+        it returns the first letter of the color.  So we check
+        each style individually.
+     */
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderBottomColor(style, &v);
+    todo_wine ok(hres == S_OK, "get_borderBottomColor failed: %08x\n", hres);
+    todo_wine ok(!strcmp_wa(V_BSTR(&v), "red"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    V_BSTR(&v) = NULL;
+    hres = IHTMLStyle_get_borderBottomWidth(style, &v);
+    ok(hres == S_OK, "get_borderBottomWidth failed: %08x\n", hres);
+    ok(!strcmp_wa(V_BSTR(&v), "thick"), "str=%s\n", wine_dbgstr_w(V_BSTR(&v)));
+    VariantClear(&v);
+
+    hres = IHTMLStyle_get_borderBottomStyle(style, &str);
+    ok(hres == S_OK, "get_borderBottomStyle failed: %08x\n", hres);
+    ok(!strcmp_wa(str, "dotted"), "str=%s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    hres = IHTMLStyle_put_borderBottom(style, sDefault);
+    ok(hres == S_OK, "put_borderBottom failed: %08x\n", hres);
+    SysFreeString(sDefault);
+
     /* BorderLeft */
     hres = IHTMLStyle_get_borderLeft(style, &sDefault);
     ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres);
     /* BorderLeft */
     hres = IHTMLStyle_get_borderLeft(style, &sDefault);
     ok(hres == S_OK, "get_borderLeft failed: %08x\n", hres);
@@ -4215,9 +4777,12 @@ static void test_doc_elem(IHTMLDocument2 *doc)
     doc_node = get_doc_node(doc);
     owner_doc = get_owner_doc((IUnknown*)elem);
     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
     doc_node = get_doc_node(doc);
     owner_doc = get_owner_doc((IUnknown*)elem);
     ok(iface_cmp((IUnknown *)doc_node, (IUnknown *)owner_doc), "doc_node != owner_doc\n");
-    IHTMLDocument2_Release(doc_node);
     IHTMLDocument2_Release(owner_doc);
 
     IHTMLDocument2_Release(owner_doc);
 
+    owner_doc = get_owner_doc((IUnknown*)doc_node);
+    ok(!owner_doc, "owner_doc = %p\n", owner_doc);
+    IHTMLDocument2_Release(doc_node);
+
     test_elem_client_rect((IUnknown*)elem);
 
     IHTMLElement_Release(elem);
     test_elem_client_rect((IUnknown*)elem);
 
     IHTMLElement_Release(elem);
@@ -4229,8 +4794,6 @@ static void test_default_body(IHTMLBodyElement *body)
     BSTR bstr;
     HRESULT hres;
     VARIANT v;
     BSTR bstr;
     HRESULT hres;
     VARIANT v;
-    WCHAR sBodyText[] = {'#','F','F','0','0','0','0',0};
-    WCHAR sTextInvalid[] = {'I','n','v','a','l','i','d',0};
 
     bstr = (void*)0xdeadbeef;
     hres = IHTMLBodyElement_get_background(body, &bstr);
 
     bstr = (void*)0xdeadbeef;
     hres = IHTMLBodyElement_get_background(body, &bstr);
@@ -4251,10 +4814,9 @@ static void test_default_body(IHTMLBodyElement *body)
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
     ok(bstr == NULL, "bstr != NULL\n");
 
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
     ok(bstr == NULL, "bstr != NULL\n");
 
-
     /* get_text - Invalid Text */
     V_VT(&v) = VT_BSTR;
     /* get_text - Invalid Text */
     V_VT(&v) = VT_BSTR;
-    V_BSTR(&v) = SysAllocString(sTextInvalid);
+    V_BSTR(&v) = a2bstr("Invalid");
     hres = IHTMLBodyElement_put_text(body, v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     VariantClear(&v);
     hres = IHTMLBodyElement_put_text(body, v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     VariantClear(&v);
@@ -4263,12 +4825,12 @@ static void test_default_body(IHTMLBodyElement *body)
     hres = IHTMLBodyElement_get_text(body, &v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
     hres = IHTMLBodyElement_get_text(body, &v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
-    ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v != '#00a0d0'\n");
+    ok(!strcmp_wa(V_BSTR(&v), "#00a0d0"), "v = %s, expected '#00a0d0'\n", wine_dbgstr_w(V_BSTR(&v)));
     VariantClear(&v);
 
     /* get_text - Valid Text */
     V_VT(&v) = VT_BSTR;
     VariantClear(&v);
 
     /* get_text - Valid Text */
     V_VT(&v) = VT_BSTR;
-    V_BSTR(&v) = SysAllocString(sBodyText);
+    V_BSTR(&v) = a2bstr("#FF0000");
     hres = IHTMLBodyElement_put_text(body, v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     VariantClear(&v);
     hres = IHTMLBodyElement_put_text(body, v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     VariantClear(&v);
@@ -4277,23 +4839,22 @@ static void test_default_body(IHTMLBodyElement *body)
     hres = IHTMLBodyElement_get_text(body, &v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
     hres = IHTMLBodyElement_get_text(body, &v);
     ok(hres == S_OK, "expect S_OK got 0x%08d\n", hres);
     ok(V_VT(&v) == VT_BSTR, "Expected VT_BSTR got %d\n", V_VT(&v));
-    ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v != '#ff0000'\n");
+    ok(!strcmp_wa(V_BSTR(&v), "#ff0000"), "v = %s, expected '#ff0000'\n", wine_dbgstr_w(V_BSTR(&v)));
     VariantClear(&v);
 }
 
 static void test_body_funs(IHTMLBodyElement *body)
 {
     VariantClear(&v);
 }
 
 static void test_body_funs(IHTMLBodyElement *body)
 {
-    static WCHAR sRed[] = {'r','e','d',0};
-    VARIANT vbg;
-    VARIANT vDefaultbg;
+    VARIANT vbg, vDefaultbg;
     HRESULT hres;
 
     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
     HRESULT hres;
 
     hres = IHTMLBodyElement_get_bgColor(body, &vDefaultbg);
     ok(hres == S_OK, "get_bgColor failed: %08x\n", hres);
     ok(V_VT(&vDefaultbg) == VT_BSTR, "bstr != NULL\n");
+    ok(!V_BSTR(&vDefaultbg), "V_BSTR(bgColor) = %s\n", wine_dbgstr_w(V_BSTR(&vDefaultbg)));
 
     V_VT(&vbg) = VT_BSTR;
 
     V_VT(&vbg) = VT_BSTR;
-    V_BSTR(&vbg) = SysAllocString(sRed);
+    V_BSTR(&vbg) = a2bstr("red");
     hres = IHTMLBodyElement_put_bgColor(body, vbg);
     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
     VariantClear(&vbg);
     hres = IHTMLBodyElement_put_bgColor(body, vbg);
     ok(hres == S_OK, "put_bgColor failed: %08x\n", hres);
     VariantClear(&vbg);
@@ -4369,6 +4930,11 @@ static void test_window(IHTMLDocument2 *doc)
     ok(!strcmp_wa(str, "[object]"), "toString returned %s\n", wine_dbgstr_w(str));
     SysFreeString(str);
 
     ok(!strcmp_wa(str, "[object]"), "toString returned %s\n", wine_dbgstr_w(str));
     SysFreeString(str);
 
+    test_window_name(window, NULL);
+    set_window_name(window, "test");
+    test_window_length(window, 0);
+    test_screen(window);
+
     IHTMLWindow2_Release(window);
 }
 
     IHTMLWindow2_Release(window);
 }
 
@@ -4481,6 +5047,9 @@ static void test_defaults(IHTMLDocument2 *doc)
 
     IHTMLStyleSheetsCollection_Release(stylesheetcol);
 
 
     IHTMLStyleSheetsCollection_Release(stylesheetcol);
 
+    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFiltersCollection, (void**)&body);
+    ok(hres == E_NOINTERFACE, "got interface IHTMLFiltersCollection\n");
+
     test_default_selection(doc);
     test_doc_title(doc, "");
 }
     test_default_selection(doc);
     test_doc_title(doc, "");
 }
@@ -4573,12 +5142,27 @@ static void doc_write(IHTMLDocument2 *doc, BOOL ln, const char *text)
     SafeArrayDestroy(sa);
 }
 
     SafeArrayDestroy(sa);
 }
 
+static void test_frame_doc(IUnknown *frame_elem)
+{
+    IHTMLDocument2 *window_doc, *elem_doc;
+    IHTMLWindow2 *content_window;
+
+    content_window = get_frame_content_window(frame_elem);
+    window_doc = get_window_doc(content_window);
+    IHTMLWindow2_Release(content_window);
+
+    elem_doc = get_elem_doc(frame_elem);
+    ok(iface_cmp((IUnknown*)window_doc, (IUnknown*)elem_doc), "content_doc != elem_doc\n");
+
+    IHTMLDocument2_Release(elem_doc);
+    IHTMLDocument2_Release(window_doc);
+}
+
 static void test_iframe_elem(IHTMLElement *elem)
 {
 static void test_iframe_elem(IHTMLElement *elem)
 {
+    IHTMLDocument2 *content_doc, *owner_doc;
     IHTMLElementCollection *col;
     IHTMLElementCollection *col;
-    IHTMLDocument2 *content_doc;
     IHTMLWindow2 *content_window;
     IHTMLWindow2 *content_window;
-    IHTMLFrameBase2 *base2;
     IDispatch *disp;
     VARIANT errv;
     BSTR str;
     IDispatch *disp;
     VARIANT errv;
     BSTR str;
@@ -4592,21 +5176,13 @@ static void test_iframe_elem(IHTMLElement *elem)
         ET_BR
     };
 
         ET_BR
     };
 
-    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase2, (void**)&base2);
-    ok(hres == S_OK, "Could not get IHTMFrameBase2 iface: %08x\n", hres);
-    if (!base2) return;
+    test_frame_doc((IUnknown*)elem);
 
 
-    content_window = NULL;
-    hres = IHTMLFrameBase2_get_contentWindow(base2, &content_window);
-    IHTMLFrameBase2_Release(base2);
-    ok(hres == S_OK, "get_contentWindow failed: %08x\n", hres);
-    ok(content_window != NULL, "contentWindow = NULL\n");
+    content_window = get_frame_content_window((IUnknown*)elem);
+    test_window_length(content_window, 0);
 
 
-    content_doc = NULL;
-    hres = IHTMLWindow2_get_document(content_window, &content_doc);
+    content_doc = get_window_doc(content_window);
     IHTMLWindow2_Release(content_window);
     IHTMLWindow2_Release(content_window);
-    ok(hres == S_OK, "get_document failed: %08x\n", hres);
-    ok(content_doc != NULL, "content_doc = NULL\n");
 
     str = a2bstr("text/html");
     V_VT(&errv) = VT_ERROR;
 
     str = a2bstr("text/html");
     V_VT(&errv) = VT_ERROR;
@@ -4629,6 +5205,9 @@ static void test_iframe_elem(IHTMLElement *elem)
     hres = IHTMLDocument2_close(content_doc);
     ok(hres == S_OK, "close failed: %08x\n", hres);
 
     hres = IHTMLDocument2_close(content_doc);
     ok(hres == S_OK, "close failed: %08x\n", hres);
 
+    owner_doc = get_owner_doc((IUnknown*)content_doc);
+    ok(!owner_doc, "owner_doc = %p\n", owner_doc);
+
     IHTMLDocument2_Release(content_doc);
 }
 
     IHTMLDocument2_Release(content_doc);
 }
 
@@ -4738,6 +5317,7 @@ static void test_elems(IHTMLDocument2 *doc)
     IHTMLDOMChildrenCollection *child_col;
     IHTMLElement *elem, *elem2, *elem3;
     IHTMLDOMNode *node, *node2;
     IHTMLDOMChildrenCollection *child_col;
     IHTMLElement *elem, *elem2, *elem3;
     IHTMLDOMNode *node, *node2;
+    IHTMLWindow2 *window;
     IDispatch *disp;
     LONG type;
     HRESULT hres;
     IDispatch *disp;
     LONG type;
     HRESULT hres;
@@ -4767,7 +5347,8 @@ static void test_elems(IHTMLDocument2 *doc)
         ET_SCRIPT,
         ET_TEST,
         ET_IMG,
         ET_SCRIPT,
         ET_TEST,
         ET_IMG,
-        ET_IFRAME
+        ET_IFRAME,
+        ET_FORM
     };
 
     static const elem_type_t item_types[] = {
     };
 
     static const elem_type_t item_types[] = {
@@ -4831,6 +5412,7 @@ static void test_elems(IHTMLDocument2 *doc)
         test_elem_set_class((IUnknown*)elem, NULL);
         test_elem_tabindex((IUnknown*)elem, 0);
         test_elem_set_tabindex((IUnknown*)elem, 1);
         test_elem_set_class((IUnknown*)elem, NULL);
         test_elem_tabindex((IUnknown*)elem, 0);
         test_elem_set_tabindex((IUnknown*)elem, 1);
+        test_elem_filters((IUnknown*)elem);
 
         node = test_node_get_parent((IUnknown*)elem);
         ok(node != NULL, "node == NULL\n");
 
         node = test_node_get_parent((IUnknown*)elem);
         ok(node != NULL, "node == NULL\n");
@@ -4875,7 +5457,7 @@ static void test_elems(IHTMLDocument2 *doc)
     elem = get_elem_by_id(doc, "s", TRUE);
     if(elem) {
         IHTMLSelectElement *select;
     elem = get_elem_by_id(doc, "s", TRUE);
     if(elem) {
         IHTMLSelectElement *select;
-        IHTMLDocument2 *doc_node;
+        IHTMLDocument2 *doc_node, *elem_doc;
 
         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select);
         ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres);
 
         hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLSelectElement, (void**)&select);
         ok(hres == S_OK, "Could not get IHTMLSelectElement interface: %08x\n", hres);
@@ -4899,12 +5481,12 @@ static void test_elems(IHTMLDocument2 *doc)
 
         IHTMLSelectElement_Release(select);
 
 
         IHTMLSelectElement_Release(select);
 
-        hres = IHTMLElement_get_document(elem, &disp);
-        ok(hres == S_OK, "get_document failed: %08x\n", hres);
+        elem_doc = get_elem_doc((IUnknown*)elem);
 
         doc_node = get_doc_node(doc);
 
         doc_node = get_doc_node(doc);
-        ok(iface_cmp((IUnknown*)disp, (IUnknown*)doc_node), "disp != doc\n");
+        ok(iface_cmp((IUnknown*)elem_doc, (IUnknown*)doc_node), "disp != doc\n");
         IHTMLDocument2_Release(doc_node);
         IHTMLDocument2_Release(doc_node);
+        IHTMLDocument2_Release(elem_doc);
 
         IHTMLElement_Release(elem);
     }
 
         IHTMLElement_Release(elem);
     }
@@ -4991,6 +5573,7 @@ static void test_elems(IHTMLDocument2 *doc)
         test_img_set_src((IUnknown*)elem, "about:blank");
         test_img_alt((IUnknown*)elem, NULL);
         test_img_set_alt((IUnknown*)elem, "alt test");
         test_img_set_src((IUnknown*)elem, "about:blank");
         test_img_alt((IUnknown*)elem, NULL);
         test_img_set_alt((IUnknown*)elem, "alt test");
+        test_img_name((IUnknown*)elem, "WineImg");
         IHTMLElement_Release(elem);
     }
 
         IHTMLElement_Release(elem);
     }
 
@@ -5054,11 +5637,13 @@ static void test_elems(IHTMLDocument2 *doc)
         ok(hres == S_OK, "get_length failed: %08x\n", hres);
         ok(length, "length=0\n");
 
         ok(hres == S_OK, "get_length failed: %08x\n", hres);
         ok(length, "length=0\n");
 
+        node2 = NULL;
         node = get_child_item(child_col, 0);
         ok(node != NULL, "node == NULL\n");
         if(node) {
             type = get_node_type((IUnknown*)node);
             ok(type == 3, "type=%d\n", type);
         node = get_child_item(child_col, 0);
         ok(node != NULL, "node == NULL\n");
         if(node) {
             type = get_node_type((IUnknown*)node);
             ok(type == 3, "type=%d\n", type);
+            node2 = node_get_next((IUnknown*)node);
             IHTMLDOMNode_Release(node);
         }
 
             IHTMLDOMNode_Release(node);
         }
 
@@ -5069,6 +5654,8 @@ static void test_elems(IHTMLDocument2 *doc)
             ok(type == 8, "type=%d\n", type);
 
             test_elem_id((IUnknown*)node, NULL);
             ok(type == 8, "type=%d\n", type);
 
             test_elem_id((IUnknown*)node, NULL);
+            ok(iface_cmp((IUnknown*)node2, (IUnknown*)node), "node2 != node\n");
+            IHTMLDOMNode_Release(node2);
             IHTMLDOMNode_Release(node);
         }
 
             IHTMLDOMNode_Release(node);
         }
 
@@ -5097,6 +5684,7 @@ static void test_elems(IHTMLDocument2 *doc)
 
     test_stylesheets(doc);
     test_create_option_elem(doc);
 
     test_stylesheets(doc);
     test_create_option_elem(doc);
+    test_create_img_elem(doc);
 
     elem = get_doc_elem_by_id(doc, "tbl");
     ok(elem != NULL, "elem = NULL\n");
 
     elem = get_doc_elem_by_id(doc, "tbl");
     ok(elem != NULL, "elem = NULL\n");
@@ -5148,9 +5736,50 @@ static void test_elems(IHTMLDocument2 *doc)
     test_elem_innerhtml((IUnknown*)elem, "inner html");
     test_elem_set_innerhtml((IUnknown*)elem, "");
     test_elem_innerhtml((IUnknown*)elem, NULL);
     test_elem_innerhtml((IUnknown*)elem, "inner html");
     test_elem_set_innerhtml((IUnknown*)elem, "");
     test_elem_innerhtml((IUnknown*)elem, NULL);
+    node = node_get_next((IUnknown*)elem);
+    ok(!node, "node = %p\n", node);
+
+    elem2 = get_doc_elem_by_id(doc, "x");
+    test_elem_tag((IUnknown*)elem2, "A");
+    node = node_get_next((IUnknown*)elem2);
+    IHTMLDOMNode_Release(node);
+    IHTMLElement_Release(elem2);
     IHTMLElement_Release(elem);
 
     IHTMLDocument3_Release(doc3);
     IHTMLElement_Release(elem);
 
     IHTMLDocument3_Release(doc3);
+
+    window = get_doc_window(doc);
+    test_window_name(window, NULL);
+    set_window_name(window, "test name");
+    test_window_length(window, 1);
+    IHTMLWindow2_Release(window);
+}
+
+static void test_elems2(IHTMLDocument2 *doc)
+{
+    IHTMLElement *elem, *elem2;
+
+    static const elem_type_t outer_types[] = {
+        ET_BR,
+        ET_A
+    };
+
+    elem = get_doc_elem_by_id(doc, "divid");
+
+    test_elem_set_innerhtml((IUnknown*)elem, "<div id=\"innerid\"></div>");
+    elem2 = get_doc_elem_by_id(doc, "innerid");
+    ok(elem2 != NULL, "elem2 == NULL\n");
+    test_elem_set_outerhtml((IUnknown*)elem2, "<br><a href=\"about:blank\" id=\"aid\">a</a>");
+    test_elem_all((IUnknown*)elem, outer_types, sizeof(outer_types)/sizeof(*outer_types));
+    IHTMLElement_Release(elem2);
+
+    elem2 = get_doc_elem_by_id(doc, "aid");
+    ok(elem2 != NULL, "elem2 == NULL\n");
+    test_elem_set_outerhtml((IUnknown*)elem2, "");
+    test_elem_all((IUnknown*)elem, outer_types, 1);
+    IHTMLElement_Release(elem2);
+
+    IHTMLElement_Release(elem);
 }
 
 static void test_create_elems(IHTMLDocument2 *doc)
 }
 
 static void test_create_elems(IHTMLDocument2 *doc)
@@ -5201,6 +5830,7 @@ static void test_create_elems(IHTMLDocument2 *doc)
     node = test_create_text(doc, "test");
     test_ifaces((IUnknown*)node, text_iids);
     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
     node = test_create_text(doc, "test");
     test_ifaces((IUnknown*)node, text_iids);
     test_disp((IUnknown*)node, &DIID_DispHTMLDOMTextNode, "[object]");
+    test_text_length((IUnknown*)node, 4);
 
     V_VT(&var) = VT_NULL;
     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
 
     V_VT(&var) = VT_NULL;
     node2 = test_node_insertbefore((IUnknown*)body, node, &var);
@@ -5315,6 +5945,257 @@ static void test_cond_comment(IHTMLDocument2 *doc)
     IHTMLElementCollection_Release(col);
 }
 
     IHTMLElementCollection_Release(col);
 }
 
+static void test_frame(IDispatch *disp, const char *exp_id)
+{
+    IHTMLWindow2 *frame2, *parent, *top;
+    IHTMLDocument2 *parent_doc, *top_doc;
+    IHTMLWindow4 *frame;
+    IHTMLFrameBase *frame_elem;
+    HRESULT hres;
+
+    hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow4, (void**)&frame);
+    ok(hres == S_OK, "Could not get IHTMLWindow4 interface: 0x%08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IHTMLWindow4_get_frameElement(frame, &frame_elem);
+    ok(hres == S_OK, "IHTMLWindow4_get_frameElement failed: 0x%08x\n", hres);
+    IHTMLWindow4_Release(frame);
+    if(FAILED(hres))
+        return;
+
+    test_frame_doc((IUnknown*)frame_elem);
+    test_elem_id((IUnknown*)frame_elem, exp_id);
+    IHTMLElement_Release(frame_elem);
+
+    hres = IDispatch_QueryInterface(disp, &IID_IHTMLWindow2, (void**)&frame2);
+    ok(hres == S_OK, "Could not get IHTMLWindow2 interface: 0x%08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IHTMLWindow2_get_parent(frame2, &parent);
+    ok(hres == S_OK, "IHTMLWindow2_get_parent failed: 0x%08x\n", hres);
+    if(FAILED(hres)){
+        IHTMLWindow2_Release(frame2);
+        return;
+    }
+
+    hres = IHTMLWindow2_get_document(parent, &parent_doc);
+    ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
+    IHTMLWindow2_Release(parent);
+    if(FAILED(hres)){
+        IHTMLWindow2_Release(frame2);
+        return;
+    }
+
+    test_doc_title(parent_doc, "frameset test");
+    IHTMLDocument2_Release(parent_doc);
+
+    /* test get_top */
+    hres = IHTMLWindow2_get_top(frame2, &top);
+    ok(hres == S_OK, "IHTMLWindow2_get_top failed: 0x%08x\n", hres);
+    IHTMLWindow2_Release(frame2);
+    if(FAILED(hres))
+        return;
+
+    hres = IHTMLWindow2_get_document(top, &top_doc);
+    ok(hres == S_OK, "IHTMLWindow2_get_document failed: 0x%08x\n", hres);
+    IHTMLWindow2_Release(top);
+    if(FAILED(hres))
+        return;
+
+    test_doc_title(top_doc, "frameset test");
+    IHTMLDocument2_Release(top_doc);
+}
+
+static void test_frameset(IHTMLDocument2 *doc)
+{
+    IHTMLWindow2 *window;
+    IHTMLFramesCollection2 *frames;
+    IHTMLElement *elem;
+    IHTMLFrameBase *fbase;
+    LONG length;
+    VARIANT index_var, result_var;
+    BSTR str;
+    HRESULT hres;
+
+    window = get_doc_window(doc);
+
+    /* test using IHTMLFramesCollection object */
+
+    hres = IHTMLWindow2_get_frames(window, &frames);
+    ok(hres == S_OK, "IHTMLWindow2_get_frames failed: 0x%08x\n", hres);
+    IHTMLWindow2_Release(window);
+    if(FAILED(hres))
+        return;
+
+    /* test result length */
+    hres = IHTMLFramesCollection2_get_length(frames, &length);
+    ok(hres == S_OK, "IHTMLFramesCollection2_get_length failed: 0x%08x\n", hres);
+    ok(length == 3, "IHTMLFramesCollection2_get_length should have been 3, was: %d\n", length);
+
+    /* test first frame */
+    V_VT(&index_var) = VT_I4;
+    V_I4(&index_var) = 0;
+    hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
+    }
+    VariantClear(&result_var);
+
+    /* test second frame */
+    V_I4(&index_var) = 1;
+    hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
+    }
+    VariantClear(&result_var);
+
+    /* fail on next frame */
+    V_I4(&index_var) = 3;
+    hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLFramesCollection2_item should have"
+           "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
+    VariantClear(&result_var);
+
+    /* string argument (element id lookup) */
+    V_VT(&index_var) = VT_BSTR;
+    V_BSTR(&index_var) = a2bstr("fr1");
+    hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLFramesCollection2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame(V_DISPATCH(&result_var), "fr1");
+    }
+    VariantClear(&result_var);
+    VariantClear(&index_var);
+
+    /* invalid argument */
+    V_VT(&index_var) = VT_BOOL;
+    V_BOOL(&index_var) = VARIANT_TRUE;
+    hres = IHTMLFramesCollection2_item(frames, &index_var, &result_var);
+    ok(hres == E_INVALIDARG, "IHTMLFramesCollection2_item should have"
+           "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
+    VariantClear(&result_var);
+
+    IHTMLFramesCollection2_Release(frames);
+
+    /* test using IHTMLWindow2 inheritance */
+
+    /* test result length */
+    hres = IHTMLWindow2_get_length(window, &length);
+    ok(hres == S_OK, "IHTMLWindow2_get_length failed: 0x%08x\n", hres);
+    ok(length == 3, "IHTMLWindow2_get_length should have been 3, was: %d\n", length);
+
+    /* test first frame */
+    V_VT(&index_var) = VT_I4;
+    V_I4(&index_var) = 0;
+    hres = IHTMLWindow2_item(window, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame((IDispatch*)V_DISPATCH(&result_var), "fr1");
+    }
+    VariantClear(&result_var);
+
+    /* test second frame */
+    V_I4(&index_var) = 1;
+    hres = IHTMLWindow2_item(window, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
+    }
+    VariantClear(&result_var);
+
+    /* fail on next frame */
+    V_I4(&index_var) = 3;
+    hres = IHTMLWindow2_item(window, &index_var, &result_var);
+    ok(hres == DISP_E_MEMBERNOTFOUND, "IHTMLWindow2_item should have"
+           "failed with DISP_E_MEMBERNOTFOUND, instead: 0x%08x\n", hres);
+    VariantClear(&result_var);
+
+    /* string argument (element id lookup) */
+    V_VT(&index_var) = VT_BSTR;
+    V_BSTR(&index_var) = a2bstr("fr2");
+    hres = IHTMLWindow2_item(window, &index_var, &result_var);
+    ok(hres == S_OK, "IHTMLWindow2_item failed: 0x%08x\n", hres);
+    if(SUCCEEDED(hres)) {
+        ok(V_VT(&result_var) == VT_DISPATCH, "result type should have been VT_DISPATCH, was: 0x%x\n", V_VT(&result_var));
+        test_frame((IDispatch*)V_DISPATCH(&result_var), "fr2");
+    }
+    VariantClear(&result_var);
+    VariantClear(&index_var);
+
+    /* invalid argument */
+    V_VT(&index_var) = VT_BOOL;
+    V_BOOL(&index_var) = VARIANT_TRUE;
+    hres = IHTMLWindow2_item(window, &index_var, &result_var);
+    ok(hres == E_INVALIDARG, "IHTMLWindow2_item should have"
+           "failed with E_INVALIDARG, instead: 0x%08x\n", hres);
+    VariantClear(&result_var);
+
+    /* getElementById with node name attributes */
+    elem = get_doc_elem_by_id(doc, "nm1");
+    test_elem_id((IUnknown*)elem, "fr1");
+
+    /* get/put scrolling */
+    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
+    ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
+
+    hres = IHTMLFrameBase_get_scrolling(fbase, &str);
+    ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
+    ok(!strcmp_wa(str, "auto"), "get_scrolling should have given 'auto', gave: %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    str = a2bstr("no");
+    hres = IHTMLFrameBase_put_scrolling(fbase, str);
+    ok(hres == S_OK, "IHTMLFrameBase_put_scrolling failed: 0x%08x\n", hres);
+    SysFreeString(str);
+
+    hres = IHTMLFrameBase_get_scrolling(fbase, &str);
+    ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
+    ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    str = a2bstr("junk");
+    hres = IHTMLFrameBase_put_scrolling(fbase, str);
+    ok(hres == E_INVALIDARG, "IHTMLFrameBase_put_scrolling should have failed "
+            "with E_INVALIDARG, instead: 0x%08x\n", hres);
+    SysFreeString(str);
+
+    hres = IHTMLFrameBase_get_scrolling(fbase, &str);
+    ok(hres == S_OK, "IHTMLFrameBase_get_scrolling failed: 0x%08x\n", hres);
+    ok(!strcmp_wa(str, "no"), "get_scrolling should have given 'no', gave: %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    /* get_name */
+    hres = IHTMLFrameBase_get_name(fbase, &str);
+    ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
+    ok(!strcmp_wa(str, "nm1"), "get_name should have given 'nm1', gave: %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    IHTMLFrameBase_Release(fbase);
+    IHTMLElement_Release(elem);
+
+    /* get_name with no name attr */
+    elem = get_doc_elem_by_id(doc, "fr3");
+    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLFrameBase, (void**)&fbase);
+    ok(hres == S_OK, "Could not get IHTMLFrameBase interface: 0x%08x\n", hres);
+
+    hres = IHTMLFrameBase_get_name(fbase, &str);
+    ok(hres == S_OK, "IHTMLFrameBase_get_name failed: 0x%08x\n", hres);
+    ok(str == NULL, "get_name should have given 'null', gave: %s\n", wine_dbgstr_w(str));
+    SysFreeString(str);
+
+    IHTMLFrameBase_Release(fbase);
+    IHTMLElement_Release(elem);
+}
+
 static IHTMLDocument2 *notif_doc;
 static BOOL doc_complete;
 
 static IHTMLDocument2 *notif_doc;
 static BOOL doc_complete;
 
@@ -5425,10 +6306,8 @@ typedef void (*domtest_t)(IHTMLDocument2*);
 static void run_domtest(const char *str, domtest_t test)
 {
     IHTMLDocument2 *doc;
 static void run_domtest(const char *str, domtest_t test)
 {
     IHTMLDocument2 *doc;
-    IHTMLElement *body = NULL;
     ULONG ref;
     MSG msg;
     ULONG ref;
     MSG msg;
-    HRESULT hres;
 
     doc = create_doc_with_string(str);
     if(!doc)
 
     doc = create_doc_with_string(str);
     if(!doc)
@@ -5441,15 +6320,7 @@ static void run_domtest(const char *str, domtest_t test)
         DispatchMessage(&msg);
     }
 
         DispatchMessage(&msg);
     }
 
-    hres = IHTMLDocument2_get_body(doc, &body);
-    ok(hres == S_OK, "get_body failed: %08x\n", hres);
-
-    if(body) {
-        IHTMLElement_Release(body);
-        test(doc);
-    }else {
-        skip("Could not get document body. Assuming no Gecko installed.\n");
-    }
+    test(doc);
 
     ref = IHTMLDocument2_Release(doc);
     ok(!ref ||
 
     ref = IHTMLDocument2_Release(doc);
     ok(!ref ||
@@ -5457,39 +6328,8 @@ static void run_domtest(const char *str, domtest_t test)
        "ref = %d\n", ref);
 }
 
        "ref = %d\n", ref);
 }
 
-static void gecko_installer_workaround(BOOL disable)
-{
-    HKEY hkey;
-    DWORD res;
-
-    static BOOL has_url = FALSE;
-    static char url[2048];
-
-    if(!disable && !has_url)
-        return;
-
-    res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
-    if(res != ERROR_SUCCESS)
-        return;
-
-    if(disable) {
-        DWORD type, size = sizeof(url);
-
-        res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
-        if(res == ERROR_SUCCESS && type == REG_SZ)
-            has_url = TRUE;
-
-        RegDeleteValue(hkey, "GeckoUrl");
-    }else {
-        RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
-    }
-
-    RegCloseKey(hkey);
-}
-
 START_TEST(dom)
 {
 START_TEST(dom)
 {
-    gecko_installer_workaround(TRUE);
     CoInitialize(NULL);
 
     run_domtest(doc_str1, test_doc_elem);
     CoInitialize(NULL);
 
     run_domtest(doc_str1, test_doc_elem);
@@ -5501,11 +6341,12 @@ START_TEST(dom)
     }else {
         skip("IE running in Enhanced Security Configuration\n");
     }
     }else {
         skip("IE running in Enhanced Security Configuration\n");
     }
+    run_domtest(elem_test2_str, test_elems2);
     run_domtest(doc_blank, test_create_elems);
     run_domtest(doc_blank, test_defaults);
     run_domtest(indent_test_str, test_indent);
     run_domtest(cond_comment_str, test_cond_comment);
     run_domtest(doc_blank, test_create_elems);
     run_domtest(doc_blank, test_defaults);
     run_domtest(indent_test_str, test_indent);
     run_domtest(cond_comment_str, test_cond_comment);
+    run_domtest(frameset_str, test_frameset);
 
     CoUninitialize();
 
     CoUninitialize();
-    gecko_installer_workaround(FALSE);
 }
 }
index d0ddadb..84bfae2 100644 (file)
@@ -27,6 +27,7 @@
 #include "winbase.h"
 #include "ole2.h"
 #include "mshtml.h"
 #include "winbase.h"
 #include "ole2.h"
 #include "mshtml.h"
+#include "mshtmdid.h"
 #include "docobj.h"
 #include "hlink.h"
 #include "dispex.h"
 #include "docobj.h"
 #include "hlink.h"
 #include "dispex.h"
@@ -61,10 +62,15 @@ DEFINE_EXPECT(body_onclick);
 DEFINE_EXPECT(div_onclick);
 DEFINE_EXPECT(div_onclick_attached);
 DEFINE_EXPECT(timeout);
 DEFINE_EXPECT(div_onclick);
 DEFINE_EXPECT(div_onclick_attached);
 DEFINE_EXPECT(timeout);
+DEFINE_EXPECT(doccp_onclick);
+DEFINE_EXPECT(iframe_onreadystatechange_loading);
+DEFINE_EXPECT(iframe_onreadystatechange_interactive);
+DEFINE_EXPECT(iframe_onreadystatechange_complete);
 
 static HWND container_hwnd = NULL;
 static IHTMLWindow2 *window;
 static IOleDocumentView *view;
 
 static HWND container_hwnd = NULL;
 static IHTMLWindow2 *window;
 static IOleDocumentView *view;
+static BOOL xy_todo;
 
 typedef struct {
     LONG x;
 
 typedef struct {
     LONG x;
@@ -84,12 +90,8 @@ static const char click_doc_str[] =
     "<div id=\"clickdiv\" style=\"text-align: center; background: red; font-size: 32\">click here</div>"
     "</body></html>";
 
     "<div id=\"clickdiv\" style=\"text-align: center; background: red; font-size: 32\">click here</div>"
     "</body></html>";
 
-static const char *debugstr_w(LPCWSTR str)
-{
-    static char buf[1024];
-    WideCharToMultiByte(CP_ACP, 0, str, -1, buf, sizeof(buf), NULL, NULL);
-    return buf;
-}
+static const char readystate_doc_str[] =
+    "<<html><body><iframe id=\"iframe\"></iframe></body></html>";
 
 static const char *debugstr_guid(REFIID riid)
 {
 
 static const char *debugstr_guid(REFIID riid)
 {
@@ -209,6 +211,18 @@ static IHTMLElement2 *_get_elem2_iface(unsigned line, IUnknown *unk)
     return elem2;
 }
 
     return elem2;
 }
 
+#define get_elem3_iface(u) _get_elem3_iface(__LINE__,u)
+static IHTMLElement3 *_get_elem3_iface(unsigned line, IUnknown *unk)
+{
+    IHTMLElement3 *elem3;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IHTMLElement3, (void**)&elem3);
+    ok_(__FILE__,line) (hres == S_OK, "Could not get IHTMLElement3 iface: %08x\n", hres);
+
+    return elem3;
+}
+
 #define doc_get_body(d) _doc_get_body(__LINE__,d)
 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
 {
 #define doc_get_body(d) _doc_get_body(__LINE__,d)
 static IHTMLElement *_doc_get_body(unsigned line, IHTMLDocument2 *doc)
 {
@@ -249,7 +263,7 @@ static void _test_elem_tag(unsigned line, IUnknown *unk, const char *extag)
     hres = IHTMLElement_get_tagName(elem, &tag);
     IHTMLElement_Release(elem);
     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
     hres = IHTMLElement_get_tagName(elem, &tag);
     IHTMLElement_Release(elem);
     ok_(__FILE__, line) (hres == S_OK, "get_tagName failed: %08x\n", hres);
-    ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", debugstr_w(tag), extag);
+    ok_(__FILE__, line) (!strcmp_wa(tag, extag), "got tag: %s, expected %s\n", wine_dbgstr_w(tag), extag);
 
     SysFreeString(tag);
 }
 
     SysFreeString(tag);
 }
@@ -268,6 +282,22 @@ static IHTMLEventObj *_get_event_obj(unsigned line)
     return event;
 }
 
     return event;
 }
 
+#define elem_fire_event(a,b,c) _elem_fire_event(__LINE__,a,b,c)
+static void _elem_fire_event(unsigned line, IUnknown *unk, const char *event, VARIANT *evobj)
+{
+    IHTMLElement3 *elem3 = _get_elem3_iface(line, unk);
+    VARIANT_BOOL b;
+    BSTR str;
+    HRESULT hres;
+
+    b = 100;
+    str = a2bstr(event);
+    hres = IHTMLElement3_fireEvent(elem3, str, evobj, &b);
+    SysFreeString(str);
+    ok_(__FILE__,line)(hres == S_OK, "fireEvent failed: %08x\n", hres);
+    ok_(__FILE__,line)(b == VARIANT_TRUE, "fireEvent returned %x\n", b);
+}
+
 #define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g)
 static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 #define test_event_args(a,b,c,d,e,f,g) _test_event_args(__LINE__,a,b,c,d,e,f,g)
 static void _test_event_args(unsigned line, const IID *dispiid, DISPID id, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
@@ -312,8 +342,8 @@ static void _test_attached_event_args(unsigned line, DISPID id, WORD wFlags, DIS
     IHTMLEventObj_Release(event);
 }
 
     IHTMLEventObj_Release(event);
 }
 
-#define test_event_src(t) _test_event_src(__LINE__,t)
-static void _test_event_src(unsigned line, const char *src_tag)
+#define get_event_src() _get_event_src(__LINE__)
+static IHTMLElement *_get_event_src(unsigned line)
 {
     IHTMLEventObj *event = _get_event_obj(line);
     IHTMLElement *src_elem = NULL;
 {
     IHTMLEventObj *event = _get_event_obj(line);
     IHTMLElement *src_elem = NULL;
@@ -323,6 +353,14 @@ static void _test_event_src(unsigned line, const char *src_tag)
     IHTMLEventObj_Release(event);
     ok_(__FILE__,line) (hres == S_OK, "get_srcElement failed: %08x\n", hres);
 
     IHTMLEventObj_Release(event);
     ok_(__FILE__,line) (hres == S_OK, "get_srcElement failed: %08x\n", hres);
 
+    return src_elem;
+}
+
+#define test_event_src(t) _test_event_src(__LINE__,t)
+static void _test_event_src(unsigned line, const char *src_tag)
+{
+    IHTMLElement *src_elem = _get_event_src(line);
+
     if(src_tag) {
         ok_(__FILE__,line) (src_elem != NULL, "src_elem = NULL\n");
         _test_elem_tag(line, (IUnknown*)src_elem, src_tag);
     if(src_tag) {
         ok_(__FILE__,line) (src_elem != NULL, "src_elem = NULL\n");
         _test_elem_tag(line, (IUnknown*)src_elem, src_tag);
@@ -465,10 +503,14 @@ static void _test_event_clientx(unsigned line, IHTMLEventObj *event, LONG exl)
 
     hres = IHTMLEventObj_get_clientX(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_clientX failed: %08x\n", hres);
 
     hres = IHTMLEventObj_get_clientX(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_clientX failed: %08x\n", hres);
-    if(exl == -10) /* don't test the exact value */
-        ok_(__FILE__,line)(l > 0, "clientX = %d\n", l);
-    else
+    if(exl == -10)  {/* don't test the exact value */
+        if(xy_todo)
+            todo_wine ok_(__FILE__,line)(l > 0, "clientX = %d\n", l);
+        else
+            ok_(__FILE__,line)(l > 0, "clientX = %d\n", l);
+    }else {
         ok_(__FILE__,line)(l == exl, "clientX = %d, expected %d\n", l, exl);
         ok_(__FILE__,line)(l == exl, "clientX = %d, expected %d\n", l, exl);
+    }
 }
 
 static void _test_event_clienty(unsigned line, IHTMLEventObj *event, LONG exl)
 }
 
 static void _test_event_clienty(unsigned line, IHTMLEventObj *event, LONG exl)
@@ -478,10 +520,14 @@ static void _test_event_clienty(unsigned line, IHTMLEventObj *event, LONG exl)
 
     hres = IHTMLEventObj_get_clientY(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_clientY failed: %08x\n", hres);
 
     hres = IHTMLEventObj_get_clientY(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_clientY failed: %08x\n", hres);
-    if(exl == -10) /* don't test the exact value */
-        ok_(__FILE__,line)(l > 0, "clientY = %d\n", l);
-    else
+    if(exl == -10)  {/* don't test the exact value */
+        if(xy_todo)
+            todo_wine ok_(__FILE__,line)(l > 0, "clientY = %d\n", l);
+        else
+            ok_(__FILE__,line)(l > 0, "clientY = %d\n", l);
+    }else {
         ok_(__FILE__,line)(l == exl, "clientY = %d, expected %d\n", l, exl);
         ok_(__FILE__,line)(l == exl, "clientY = %d, expected %d\n", l, exl);
+    }
 }
 
 static void _test_event_offsetx(unsigned line, IHTMLEventObj *event, LONG exl)
 }
 
 static void _test_event_offsetx(unsigned line, IHTMLEventObj *event, LONG exl)
@@ -517,10 +563,14 @@ static void _test_event_screenx(unsigned line, IHTMLEventObj *event, LONG exl)
 
     hres = IHTMLEventObj_get_screenX(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_screenX failed: %08x\n", hres);
 
     hres = IHTMLEventObj_get_screenX(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_screenX failed: %08x\n", hres);
-    if(exl == -10) /* don't test the exact value */
-        ok_(__FILE__,line)(l > 0, "screenX = %d\n", l);
-    else
+    if(exl == -10) { /* don't test the exact value */
+        if(xy_todo)
+            todo_wine ok_(__FILE__,line)(l > 0, "screenX = %d\n", l);
+        else
+            ok_(__FILE__,line)(l > 0, "screenX = %d\n", l);
+    }else {
         ok_(__FILE__,line)(l == exl, "screenX = %d, expected %d\n", l, exl);
         ok_(__FILE__,line)(l == exl, "screenX = %d, expected %d\n", l, exl);
+    }
 }
 
 static void _test_event_screeny(unsigned line, IHTMLEventObj *event, LONG exl)
 }
 
 static void _test_event_screeny(unsigned line, IHTMLEventObj *event, LONG exl)
@@ -530,10 +580,14 @@ static void _test_event_screeny(unsigned line, IHTMLEventObj *event, LONG exl)
 
     hres = IHTMLEventObj_get_screenY(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_screenY failed: %08x\n", hres);
 
     hres = IHTMLEventObj_get_screenY(event, &l);
     ok_(__FILE__,line)(hres == S_OK, "get_screenY failed: %08x\n", hres);
-    if(exl == -10) /* don't test the exact value */
-        ok_(__FILE__,line)(l > 0, "screenY = %d\n", l);
-    else
+    if(exl == -10) { /* don't test the exact value */
+        if(xy_todo)
+            todo_wine ok_(__FILE__,line)(l > 0, "screenY = %d\n", l);
+        else
+            ok_(__FILE__,line)(l > 0, "screenY = %d\n", l);
+    }else {
         ok_(__FILE__,line)(l == exl, "screenY = %d, expected %d\n", l, exl);
         ok_(__FILE__,line)(l == exl, "screenY = %d, expected %d\n", l, exl);
+    }
 }
 
 static void _test_event_type(unsigned line, IHTMLEventObj *event, const char *exstr)
 }
 
 static void _test_event_type(unsigned line, IHTMLEventObj *event, const char *exstr)
@@ -690,7 +744,7 @@ static HRESULT WINAPI DispatchEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lc
 
 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
 {
 
 static HRESULT WINAPI DispatchEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
 {
-    ok(0, "unexpected call %s %x\n", debugstr_w(bstrName), grfdex);
+    ok(0, "unexpected call %s %x\n", wine_dbgstr_w(bstrName), grfdex);
     return E_NOTIMPL;
 }
 
     return E_NOTIMPL;
 }
 
@@ -793,6 +847,54 @@ static HRESULT WINAPI body_onclick(IDispatchEx *iface, DISPID id, LCID lcid, WOR
 
 EVENT_HANDLER_FUNC_OBJ(body_onclick);
 
 
 EVENT_HANDLER_FUNC_OBJ(body_onclick);
 
+static HRESULT WINAPI iframe_onreadystatechange(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    IHTMLFrameBase2 *iframe;
+    IHTMLElement2 *elem2;
+    IHTMLElement *elem;
+    VARIANT v;
+    BSTR str;
+    HRESULT hres;
+
+    test_event_args(&DIID_DispHTMLIFrame, id, wFlags, pdp, pvarRes, pei, pspCaller);
+    test_event_src("IFRAME");
+
+    elem = get_event_src();
+    elem2 = get_elem2_iface((IUnknown*)elem);
+    IHTMLElement_Release(elem);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLElement2_get_readyState(elem2, &v);
+    ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_BSTR, "V_VT(readyState) = %d\n", V_VT(&v));
+
+    hres = IHTMLElement2_QueryInterface(elem2, &IID_IHTMLFrameBase2, (void**)&iframe);
+    IHTMLElement2_Release(elem2);
+    ok(hres == S_OK, "Could not get IHTMLFrameBase2 iface: %08x\n", hres);
+
+    str = NULL;
+    hres = IHTMLFrameBase2_get_readyState(iframe, &str);
+    IHTMLFrameBase2_Release(iframe);
+    ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
+    ok(str != NULL, "readyState == NULL\n");
+    ok(!lstrcmpW(str, V_BSTR(&v)), "ready states differ\n");
+    VariantClear(&v);
+
+    if(!strcmp_wa(str, "loading"))
+        CHECK_EXPECT(iframe_onreadystatechange_loading);
+    else if(!strcmp_wa(str, "interactive"))
+        CHECK_EXPECT(iframe_onreadystatechange_interactive);
+    else if(!strcmp_wa(str, "complete"))
+        CHECK_EXPECT(iframe_onreadystatechange_complete);
+    else
+        ok(0, "unexpected state %s\n", wine_dbgstr_w(str));
+
+    return S_OK;
+}
+
+EVENT_HANDLER_FUNC_OBJ(iframe_onreadystatechange);
+
 static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
 static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
 {
@@ -802,6 +904,74 @@ static HRESULT WINAPI nocall(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFla
 
 EVENT_HANDLER_FUNC_OBJ(nocall);
 
 
 EVENT_HANDLER_FUNC_OBJ(nocall);
 
+#define CONNECTION_POINT_OBJ(cpname, diid) \
+    static HRESULT WINAPI cpname ## _QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv) \
+    { \
+        *ppv = NULL; \
+        if(IsEqualGUID(riid, &IID_IUnknown) \
+           || IsEqualGUID(riid, &IID_IDispatch) \
+           || IsEqualGUID(riid, &diid)) \
+            *ppv = iface; \
+        else { \
+            ok(0, "unexpected riid %s\n", debugstr_guid(riid)); \
+            return E_NOINTERFACE; \
+        } \
+        return S_OK; \
+    } \
+    static IDispatchExVtbl cpname ## Vtbl = { \
+        cpname ## _QueryInterface, \
+        DispatchEx_AddRef,  \
+        DispatchEx_Release, \
+        DispatchEx_GetTypeInfoCount, \
+        DispatchEx_GetTypeInfo, \
+        DispatchEx_GetIDsOfNames, \
+        cpname, \
+        DispatchEx_GetDispID, \
+        DispatchEx_InvokeEx, \
+        DispatchEx_DeleteMemberByName, \
+        DispatchEx_DeleteMemberByDispID, \
+        DispatchEx_GetMemberProperties, \
+        DispatchEx_GetMemberName, \
+        DispatchEx_GetNextDispID, \
+        DispatchEx_GetNameSpaceParent \
+    }; \
+    static IDispatchEx cpname ## _obj = { &cpname ## Vtbl }
+
+#define test_cp_args(a,b,c,d,e,f) _test_cp_args(__LINE__,a,b,c,d,e,f)
+static void _test_cp_args(unsigned line, REFIID riid, WORD flags, DISPPARAMS *dp, VARIANT *vres, EXCEPINFO *ei, UINT *argerr)
+{
+    ok_(__FILE__,line)(IsEqualGUID(&IID_NULL, riid), "riid = %s\n", debugstr_guid(riid));
+    ok_(__FILE__,line)(flags == DISPATCH_METHOD, "flags = %x\n", flags);
+    ok_(__FILE__,line)(dp != NULL, "dp == NULL\n");
+    ok_(__FILE__,line)(!dp->cArgs, "dp->cArgs = %d\n", dp->cArgs);
+    ok_(__FILE__,line)(!dp->rgvarg, "dp->rgvarg = %p\n", dp->rgvarg);
+    ok_(__FILE__,line)(!dp->cNamedArgs, "dp->cNamedArgs = %d\n", dp->cNamedArgs);
+    ok_(__FILE__,line)(!dp->rgdispidNamedArgs, "dp->rgdispidNamedArgs = %p\n", dp->rgdispidNamedArgs);
+    ok_(__FILE__,line)(vres != NULL, "vres == NULL\n");
+    ok_(__FILE__,line)(V_VT(vres) == VT_EMPTY, "V_VT(vres) = %d\n", V_VT(vres));
+    ok_(__FILE__,line)(ei != NULL, "ei == NULL\n");
+    ok_(__FILE__,line)(argerr != NULL, "argerr == NULL\n");
+}
+
+static HRESULT WINAPI doccp(IDispatchEx *iface, DISPID dispIdMember,
+                            REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+                            VARIANT *pVarResult, EXCEPINFO *pei, UINT *puArgErr)
+{
+    switch(dispIdMember) {
+    case DISPID_HTMLDOCUMENTEVENTS_ONCLICK:
+        CHECK_EXPECT(doccp_onclick);
+        test_cp_args(riid, wFlags, pdp, pVarResult, pei, puArgErr);
+        break;
+    default:
+        ok(0, "unexpected call %d\n", dispIdMember);
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+CONNECTION_POINT_OBJ(doccp, DIID_HTMLDocumentEvents);
+
 static HRESULT WINAPI timeoutFunc_Invoke(IDispatchEx *iface, DISPID dispIdMember,
                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
 static HRESULT WINAPI timeoutFunc_Invoke(IDispatchEx *iface, DISPID dispIdMember,
                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
@@ -854,9 +1024,51 @@ static void pump_msgs(BOOL *b)
     }
 }
 
     }
 }
 
+static IConnectionPoint *get_cp(IUnknown *unk, REFIID riid)
+{
+    IConnectionPointContainer *cp_container;
+    IConnectionPoint *cp;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&cp_container);
+    ok(hres == S_OK, "Could not get IConnectionPointContainer: %08x\n", hres);
+
+    hres = IConnectionPointContainer_FindConnectionPoint(cp_container, riid, &cp);
+    IConnectionPointContainer_Release(cp_container);
+    ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
+
+    return cp;
+}
+
+static DWORD register_cp(IUnknown *unk, REFIID riid, IUnknown *sink)
+{
+    IConnectionPoint *cp;
+    DWORD cookie;
+    HRESULT hres;
+
+    cp = get_cp(unk, riid);
+    hres = IConnectionPoint_Advise(cp, sink, &cookie);
+    IConnectionPoint_Release(cp);
+    ok(hres == S_OK, "Advise failed: %08x\n", hres);
+
+    return cookie;
+}
+
+static void unregister_cp(IUnknown *unk, REFIID riid, DWORD cookie)
+{
+    IConnectionPoint *cp;
+    HRESULT hres;
+
+    cp = get_cp(unk, riid);
+    hres = IConnectionPoint_Unadvise(cp, cookie);
+    IConnectionPoint_Release(cp);
+    ok(hres == S_OK, "Unadvise failed: %08x\n", hres);
+}
+
 static void test_onclick(IHTMLDocument2 *doc)
 {
     IHTMLElement *div, *body;
 static void test_onclick(IHTMLDocument2 *doc)
 {
     IHTMLElement *div, *body;
+    DWORD cp_cookie;
     VARIANT v;
     HRESULT hres;
 
     VARIANT v;
     HRESULT hres;
 
@@ -870,6 +1082,10 @@ static void test_onclick(IHTMLDocument2 *doc)
     ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
     ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v));
 
     ok(hres == S_OK, "get_onclick failed: %08x\n", hres);
     ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v));
 
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLElement_put_onclick(div, v);
+    ok(hres == E_NOTIMPL, "put_onclick failed: %08x\n", hres);
+
     V_VT(&v) = VT_DISPATCH;
     V_DISPATCH(&v) = (IDispatch*)&div_onclick_obj;
     hres = IHTMLElement_put_onclick(div, v);
     V_VT(&v) = VT_DISPATCH;
     V_DISPATCH(&v) = (IDispatch*)&div_onclick_obj;
     hres = IHTMLElement_put_onclick(div, v);
@@ -918,10 +1134,106 @@ static void test_onclick(IHTMLDocument2 *doc)
         CHECK_CALLED(document_onclick);
     }
 
         CHECK_CALLED(document_onclick);
     }
 
+    xy_todo = TRUE;
+
+    SET_EXPECT(div_onclick);
+    SET_EXPECT(div_onclick_attached);
+    SET_EXPECT(body_onclick);
+    SET_EXPECT(document_onclick);
+
+    hres = IHTMLElement_click(div);
+    ok(hres == S_OK, "click failed: %08x\n", hres);
+
+    CHECK_CALLED(div_onclick);
+    CHECK_CALLED(div_onclick_attached);
+    CHECK_CALLED(body_onclick);
+    CHECK_CALLED(document_onclick);
+
+    SET_EXPECT(div_onclick);
+    SET_EXPECT(div_onclick_attached);
+    SET_EXPECT(body_onclick);
+    SET_EXPECT(document_onclick);
+
+    V_VT(&v) = VT_EMPTY;
+    elem_fire_event((IUnknown*)div, "onclick", &v);
+
+    CHECK_CALLED(div_onclick);
+    CHECK_CALLED(div_onclick_attached);
+    CHECK_CALLED(body_onclick);
+    CHECK_CALLED(document_onclick);
+
+    cp_cookie = register_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, (IUnknown*)&doccp_obj);
+
+    SET_EXPECT(div_onclick);
+    SET_EXPECT(div_onclick_attached);
+    SET_EXPECT(body_onclick);
+    SET_EXPECT(document_onclick);
+    SET_EXPECT(doccp_onclick);
+
+    hres = IHTMLElement_click(div);
+    ok(hres == S_OK, "click failed: %08x\n", hres);
+
+    CHECK_CALLED(div_onclick);
+    CHECK_CALLED(div_onclick_attached);
+    CHECK_CALLED(body_onclick);
+    CHECK_CALLED(document_onclick);
+    CHECK_CALLED(doccp_onclick);
+
+    unregister_cp((IUnknown*)doc, &DIID_HTMLDocumentEvents, cp_cookie);
+
     IHTMLElement_Release(div);
     IHTMLElement_Release(body);
 }
 
     IHTMLElement_Release(div);
     IHTMLElement_Release(body);
 }
 
+static void test_onreadystatechange(IHTMLDocument2 *doc)
+{
+    IHTMLFrameBase *iframe;
+    IHTMLElement2 *elem2;
+    IHTMLElement *elem;
+    VARIANT v;
+    BSTR str;
+    HRESULT hres;
+
+    elem = get_elem_id(doc, "iframe");
+    elem2 = get_elem2_iface((IUnknown*)elem);
+    IHTMLElement_Release(elem);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLElement2_get_onreadystatechange(elem2, &v);
+    ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_NULL, "V_VT(onreadystatechange) = %d\n", V_VT(&v));
+
+    V_VT(&v) = VT_DISPATCH;
+    V_DISPATCH(&v) = (IDispatch*)&iframe_onreadystatechange_obj;
+    hres = IHTMLElement2_put_onreadystatechange(elem2, v);
+    ok(hres == S_OK, "put_onreadystatechange failed: %08x\n", hres);
+
+    V_VT(&v) = VT_EMPTY;
+    hres = IHTMLElement2_get_onreadystatechange(elem2, &v);
+    ok(hres == S_OK, "get_onreadystatechange failed: %08x\n", hres);
+    ok(V_VT(&v) == VT_DISPATCH, "V_VT(onreadystatechange) = %d\n", V_VT(&v));
+    ok(V_DISPATCH(&v) == (IDispatch*)&iframe_onreadystatechange_obj, "unexpected onreadystatechange value\n");
+
+    hres = IHTMLElement2_QueryInterface(elem2, &IID_IHTMLFrameBase, (void**)&iframe);
+    IHTMLElement2_Release(elem2);
+    ok(hres == S_OK, "Could not get IHTMLFrameBase iface: %08x\n", hres);
+
+    hres = IHTMLFrameBase_put_src(iframe, (str = a2bstr("about:blank")));
+    SysFreeString(str);
+    ok(hres == S_OK, "put_src failed: %08x\n", hres);
+
+    SET_EXPECT(iframe_onreadystatechange_loading);
+    SET_EXPECT(iframe_onreadystatechange_interactive);
+    SET_EXPECT(iframe_onreadystatechange_complete);
+    pump_msgs(&called_iframe_onreadystatechange_complete);
+    todo_wine
+    CHECK_CALLED(iframe_onreadystatechange_loading);
+    CHECK_CALLED(iframe_onreadystatechange_interactive);
+    CHECK_CALLED(iframe_onreadystatechange_complete);
+
+    IHTMLFrameBase_Release(iframe);
+}
+
 static void test_timeout(IHTMLDocument2 *doc)
 {
     IHTMLWindow3 *win3;
 static void test_timeout(IHTMLDocument2 *doc)
 {
     IHTMLWindow3 *win3;
@@ -1462,12 +1774,23 @@ static void set_client_site(IHTMLDocument2 *doc, BOOL set)
 static IHTMLDocument2 *create_document(void)
 {
     IHTMLDocument2 *doc;
 static IHTMLDocument2 *create_document(void)
 {
     IHTMLDocument2 *doc;
+    IHTMLDocument5 *doc5;
     HRESULT hres;
 
     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IHTMLDocument2, (void**)&doc);
     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
     HRESULT hres;
 
     hres = CoCreateInstance(&CLSID_HTMLDocument, NULL, CLSCTX_INPROC_SERVER|CLSCTX_INPROC_HANDLER,
             &IID_IHTMLDocument2, (void**)&doc);
     ok(hres == S_OK, "CoCreateInstance failed: %08x\n", hres);
+    if (FAILED(hres))
+        return NULL;
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument5, (void**)&doc5);
+    if(FAILED(hres)) {
+        win_skip("Could not get IHTMLDocument5 interface, probably too old IE\n");
+        IHTMLDocument2_Release(doc);
+        return NULL;
+    }
 
 
+    IHTMLDocument5_Release(doc5);
     return doc;
 }
 
     return doc;
 }
 
@@ -1478,11 +1801,13 @@ static void run_test(const char *str, testfunc_t test)
 {
     IHTMLDocument2 *doc;
     IHTMLElement *body = NULL;
 {
     IHTMLDocument2 *doc;
     IHTMLElement *body = NULL;
-    ULONG ref;
     MSG msg;
     HRESULT hres;
 
     MSG msg;
     HRESULT hres;
 
+    xy_todo = FALSE;
     doc = create_document();
     doc = create_document();
+    if (!doc)
+        return;
     set_client_site(doc, TRUE);
     doc_load_string(doc, str);
     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
     set_client_site(doc, TRUE);
     doc_load_string(doc, str);
     do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
@@ -1511,8 +1836,7 @@ static void run_test(const char *str, testfunc_t test)
     }
 
     set_client_site(doc, FALSE);
     }
 
     set_client_site(doc, FALSE);
-    ref = IHTMLDocument2_Release(doc);
-    ok(!ref, "ref = %d\n", ref);
+    IHTMLDocument2_Release(doc);
 }
 
 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 }
 
 static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
@@ -1548,6 +1872,7 @@ START_TEST(events)
 
     run_test(empty_doc_str, test_timeout);
     run_test(click_doc_str, test_onclick);
 
     run_test(empty_doc_str, test_timeout);
     run_test(click_doc_str, test_onclick);
+    run_test(readystate_doc_str, test_onreadystatechange);
 
     DestroyWindow(container_hwnd);
     CoUninitialize();
 
     DestroyWindow(container_hwnd);
     CoUninitialize();
index 7a4d5ee..1666020 100644 (file)
@@ -29,6 +29,7 @@
 #include "ole2.h"
 #include "mshtml.h"
 #include "docobj.h"
 #include "ole2.h"
 #include "mshtml.h"
 #include "docobj.h"
+#include "wininet.h"
 #include "mshtmhst.h"
 #include "mshtmdid.h"
 #include "mshtmcid.h"
 #include "mshtmhst.h"
 #include "mshtmdid.h"
 #include "mshtmcid.h"
@@ -148,15 +149,18 @@ DEFINE_EXPECT(EnableModeless_FALSE);
 DEFINE_EXPECT(Frame_EnableModeless_TRUE);
 DEFINE_EXPECT(Frame_EnableModeless_FALSE);
 DEFINE_EXPECT(Frame_GetWindow);
 DEFINE_EXPECT(Frame_EnableModeless_TRUE);
 DEFINE_EXPECT(Frame_EnableModeless_FALSE);
 DEFINE_EXPECT(Frame_GetWindow);
+DEFINE_EXPECT(TranslateUrl);
+DEFINE_EXPECT(Advise_Close);
 
 static IUnknown *doc_unk;
 static IMoniker *doc_mon;
 static BOOL expect_LockContainer_fLock;
 static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE;
 
 static IUnknown *doc_unk;
 static IMoniker *doc_mon;
 static BOOL expect_LockContainer_fLock;
 static BOOL expect_InPlaceUIWindow_SetActiveObject_active = TRUE;
-static BOOL ipsex;
+static BOOL ipsex, ipsw;
 static BOOL set_clientsite = FALSE, container_locked = FALSE;
 static BOOL readystate_set_loading = FALSE, readystate_set_interactive = FALSE, load_from_stream;
 static BOOL editmode = FALSE, show_failed;
 static BOOL set_clientsite = FALSE, container_locked = FALSE;
 static BOOL readystate_set_loading = FALSE, readystate_set_interactive = FALSE, load_from_stream;
 static BOOL editmode = FALSE, show_failed;
+static BOOL inplace_deactivated;
 static int stream_read, protocol_read;
 static enum load_state_t {
     LD_DOLOAD,
 static int stream_read, protocol_read;
 static enum load_state_t {
     LD_DOLOAD,
@@ -177,12 +181,14 @@ static const char html_page[] =
 
 static const char css_data[] = "body {color: red}";
 
 
 static const char css_data[] = "body {color: red}";
 
+static const WCHAR http_urlW[] =
+    {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
+
 static const WCHAR doc_url[] = {'w','i','n','e','t','e','s','t',':','d','o','c',0};
 static const WCHAR about_blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
 
 static HRESULT QueryInterface(REFIID riid, void **ppv);
 static void test_MSHTML_QueryStatus(IUnknown*,DWORD);
 static const WCHAR doc_url[] = {'w','i','n','e','t','e','s','t',':','d','o','c',0};
 static const WCHAR about_blank_url[] = {'a','b','o','u','t',':','b','l','a','n','k',0};
 
 static HRESULT QueryInterface(REFIID riid, void **ppv);
 static void test_MSHTML_QueryStatus(IUnknown*,DWORD);
-static BOOL nogecko = FALSE;
 
 #define test_readyState(u) _test_readyState(__LINE__,u)
 static void _test_readyState(unsigned,IUnknown*);
 
 #define test_readyState(u) _test_readyState(__LINE__,u)
 static void _test_readyState(unsigned,IUnknown*);
@@ -211,6 +217,30 @@ static int strcmp_wa(LPCWSTR strw, const char *stra)
     return lstrcmpA(stra, buf);
 }
 
     return lstrcmpA(stra, buf);
 }
 
+static const WCHAR *strstrW( const WCHAR *str, const WCHAR *sub )
+{
+    while (*str)
+    {
+        const WCHAR *p1 = str, *p2 = sub;
+        while (*p1 && *p2 && *p1 == *p2) { p1++; p2++; }
+        if (!*p2) return str;
+        str++;
+    }
+    return NULL;
+}
+
+static BSTR a2bstr(const char *str)
+{
+    BSTR ret;
+    int len;
+
+    len = MultiByteToWideChar(CP_ACP, 0, str, -1, NULL, 0);
+    ret = SysAllocStringLen(NULL, len);
+    MultiByteToWideChar(CP_ACP, 0, str, -1, ret, len);
+
+    return ret;
+}
+
 static BOOL is_english(void)
 {
     return PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH
 static BOOL is_english(void)
 {
     return PRIMARYLANGID(GetSystemDefaultLangID()) == LANG_ENGLISH
@@ -652,6 +682,7 @@ static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPB
         DWORD site_data = 0xdeadbeef;
 
         hres = IHlink_GetTargetFrameName(pihlNavigate, &frame_name);
         DWORD site_data = 0xdeadbeef;
 
         hres = IHlink_GetTargetFrameName(pihlNavigate, &frame_name);
+        todo_wine
         ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
         ok(frame_name == NULL, "frame_name = %p\n", frame_name);
 
         ok(hres == S_FALSE, "GetTargetFrameName failed: %08x\n", hres);
         ok(frame_name == NULL, "frame_name = %p\n", frame_name);
 
@@ -663,6 +694,7 @@ static HRESULT WINAPI HlinkFrame_Navigate(IHlinkFrame *iface, DWORD grfHLNF, LPB
         hres = IHlink_GetHlinkSite(pihlNavigate, &site, &site_data);
         ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
         ok(site == NULL, "site = %p\n, expected NULL\n", site);
         hres = IHlink_GetHlinkSite(pihlNavigate, &site, &site_data);
         ok(hres == S_OK, "GetHlinkSite failed: %08x\n", hres);
         ok(site == NULL, "site = %p\n, expected NULL\n", site);
+        todo_wine
         ok(site_data == 0xdeadbeef, "site_data = %x\n", site_data);
     }
 
         ok(site_data == 0xdeadbeef, "site_data = %x\n", site_data);
     }
 
@@ -749,6 +781,7 @@ static HRESULT WINAPI PropertyNotifySink_OnChanged(IPropertyNotifySink *iface, D
     case 1012:
         CHECK_EXPECT(OnChanged_1012);
         return S_OK;
     case 1012:
         CHECK_EXPECT(OnChanged_1012);
         return S_OK;
+    case 1030:
     case 3000029:
     case 3000030:
         /* TODO */
     case 3000029:
     case 3000030:
         /* TODO */
@@ -1455,22 +1488,23 @@ static const IOleInPlaceFrameVtbl InPlaceUIWindowVtbl = {
 
 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
 
 
 static IOleInPlaceFrame InPlaceUIWindow = { &InPlaceUIWindowVtbl };
 
-static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSiteEx *iface, REFIID riid, void **ppv)
+static HRESULT WINAPI InPlaceSiteWindowless_QueryInterface(IOleInPlaceSiteWindowless *iface, REFIID riid, void **ppv)
 {
     return QueryInterface(riid, ppv);
 }
 
 {
     return QueryInterface(riid, ppv);
 }
 
-static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSiteEx *iface)
+static ULONG WINAPI InPlaceSiteWindowless_AddRef(IOleInPlaceSiteWindowless *iface)
 {
     return 2;
 }
 
 {
     return 2;
 }
 
-static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSiteEx *iface)
+static ULONG WINAPI InPlaceSiteWindowless_Release(IOleInPlaceSiteWindowless *iface)
 {
     return 1;
 }
 
 {
     return 1;
 }
 
-static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwnd)
+static HRESULT WINAPI InPlaceSiteWindowless_GetWindow(
+        IOleInPlaceSiteWindowless *iface, HWND *phwnd)
 {
     CHECK_EXPECT2(GetWindow);
     ok(phwnd != NULL, "phwnd = NULL\n");
 {
     CHECK_EXPECT2(GetWindow);
     ok(phwnd != NULL, "phwnd = NULL\n");
@@ -1478,32 +1512,38 @@ static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSiteEx *iface, HWND *phwn
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSiteEx *iface, BOOL fEnterMode)
+static HRESULT WINAPI InPlaceSiteWindowless_ContextSensitiveHelp(
+        IOleInPlaceSiteWindowless *iface, BOOL fEnterMode)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_CanInPlaceActivate(
+        IOleInPlaceSiteWindowless *iface)
 {
     CHECK_EXPECT(CanInPlaceActivate);
     return S_OK;
 }
 
 {
     CHECK_EXPECT(CanInPlaceActivate);
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceActivate(
+        IOleInPlaceSiteWindowless *iface)
 {
     CHECK_EXPECT(OnInPlaceActivate);
 {
     CHECK_EXPECT(OnInPlaceActivate);
+    inplace_deactivated = FALSE;
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_OnUIActivate(
+        IOleInPlaceSiteWindowless *iface)
 {
     CHECK_EXPECT(OnUIActivate);
     return S_OK;
 }
 
 {
     CHECK_EXPECT(OnUIActivate);
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
-        IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
+static HRESULT WINAPI InPlaceSiteWindowless_GetWindowContext(
+        IOleInPlaceSiteWindowless *iface, IOleInPlaceFrame **ppFrame,
+        IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
 {
     static const RECT rect = {0,0,500,500};
         LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
 {
     static const RECT rect = {0,0,500,500};
@@ -1534,44 +1574,52 @@ static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSiteEx *iface,
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSiteEx *iface, SIZE scrollExtant)
+static HRESULT WINAPI InPlaceSiteWindowless_Scroll(
+        IOleInPlaceSiteWindowless *iface, SIZE scrollExtent)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSiteEx *iface, BOOL fUndoable)
+static HRESULT WINAPI InPlaceSiteWindowless_OnUIDeactivate(
+        IOleInPlaceSiteWindowless *iface, BOOL fUndoable)
 {
     CHECK_EXPECT(OnUIDeactivate);
     ok(!fUndoable, "fUndoable = TRUE\n");
     return S_OK;
 }
 
 {
     CHECK_EXPECT(OnUIDeactivate);
     ok(!fUndoable, "fUndoable = TRUE\n");
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceDeactivate(
+        IOleInPlaceSiteWindowless *iface)
 {
     CHECK_EXPECT(OnInPlaceDeactivate);
 {
     CHECK_EXPECT(OnInPlaceDeactivate);
+    inplace_deactivated = TRUE;
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_DiscardUndoState(
+        IOleInPlaceSiteWindowless *iface)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_DeactivateAndUndo(
+        IOleInPlaceSiteWindowless *iface)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSiteEx *iface, LPCRECT lprcPosRect)
+static HRESULT WINAPI InPlaceSiteWindowless_OnPosRectChange(
+        IOleInPlaceSiteWindowless *iface, LPCRECT lprcPosRect)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI InPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface, BOOL *pfNoRedraw, DWORD dwFlags)
+static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceActivateEx(
+        IOleInPlaceSiteWindowless *iface, BOOL *pfNoRedraw, DWORD dwFlags)
 {
     CHECK_EXPECT(OnInPlaceActivateEx);
 
 {
     CHECK_EXPECT(OnInPlaceActivateEx);
 
@@ -1582,7 +1630,8 @@ static HRESULT WINAPI InPlaceSiteEx_OnInPlaceActivateEx(IOleInPlaceSiteEx *iface
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *iface, BOOL fNoRedraw)
+static HRESULT WINAPI InPlaceSiteWindowless_OnInPlaceDeactivateEx(
+        IOleInPlaceSiteWindowless *iface, BOOL fNoRedraw)
 {
     CHECK_EXPECT(OnInPlaceDeactivateEx);
 
 {
     CHECK_EXPECT(OnInPlaceDeactivateEx);
 
@@ -1591,34 +1640,134 @@ static HRESULT WINAPI InPlaceSiteEx_OnInPlaceDeactivateEx(IOleInPlaceSiteEx *ifa
     return S_OK;
 }
 
     return S_OK;
 }
 
-static HRESULT WINAPI InPlaceSiteEx_RequestUIActivate(IOleInPlaceSiteEx *iface)
+static HRESULT WINAPI InPlaceSiteWindowless_RequestUIActivate(
+        IOleInPlaceSiteWindowless *iface)
 {
 {
-    CHECK_EXPECT(RequestUIActivate);
+    CHECK_EXPECT2(RequestUIActivate);
     return S_OK;
 }
 
     return S_OK;
 }
 
-static const IOleInPlaceSiteExVtbl InPlaceSiteVtbl = {
-    InPlaceSite_QueryInterface,
-    InPlaceSite_AddRef,
-    InPlaceSite_Release,
-    InPlaceSite_GetWindow,
-    InPlaceSite_ContextSensitiveHelp,
-    InPlaceSite_CanInPlaceActivate,
-    InPlaceSite_OnInPlaceActivate,
-    InPlaceSite_OnUIActivate,
-    InPlaceSite_GetWindowContext,
-    InPlaceSite_Scroll,
-    InPlaceSite_OnUIDeactivate,
-    InPlaceSite_OnInPlaceDeactivate,
-    InPlaceSite_DiscardUndoState,
-    InPlaceSite_DeactivateAndUndo,
-    InPlaceSite_OnPosRectChange,
-    InPlaceSiteEx_OnInPlaceActivateEx,
-    InPlaceSiteEx_OnInPlaceDeactivateEx,
-    InPlaceSiteEx_RequestUIActivate
+static HRESULT WINAPI InPlaceSiteWindowless_CanWindowlessActivate(
+        IOleInPlaceSiteWindowless *iface)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_GetCapture(
+        IOleInPlaceSiteWindowless *iface)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_SetCapture(
+        IOleInPlaceSiteWindowless *iface, BOOL fCapture)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_GetFocus(
+        IOleInPlaceSiteWindowless *iface)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_SetFocus(
+        IOleInPlaceSiteWindowless *iface, BOOL fFocus)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_GetDC(
+        IOleInPlaceSiteWindowless *iface, LPCRECT pRect,
+        DWORD grfFlags, HDC *phDC)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_ReleaseDC(
+        IOleInPlaceSiteWindowless *iface, HDC hDC)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_InvalidateRect(
+        IOleInPlaceSiteWindowless *iface, LPCRECT pRect, BOOL fErase)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_InvalidateRgn(
+        IOleInPlaceSiteWindowless *iface, HRGN hRGN, BOOL fErase)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_ScrollRect(
+        IOleInPlaceSiteWindowless *iface, INT dx, INT dy,
+        LPCRECT pRectScroll, LPCRECT pRectClip)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_AdjustRect(
+        IOleInPlaceSiteWindowless *iface, LPRECT prc)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSiteWindowless_OnDefWindowMessage(
+        IOleInPlaceSiteWindowless *iface, UINT msg,
+        WPARAM wParam, LPARAM lParam, LRESULT *plResult)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static const IOleInPlaceSiteWindowlessVtbl InPlaceSiteWindowlessVtbl = {
+    InPlaceSiteWindowless_QueryInterface,
+    InPlaceSiteWindowless_AddRef,
+    InPlaceSiteWindowless_Release,
+    InPlaceSiteWindowless_GetWindow,
+    InPlaceSiteWindowless_ContextSensitiveHelp,
+    InPlaceSiteWindowless_CanInPlaceActivate,
+    InPlaceSiteWindowless_OnInPlaceActivate,
+    InPlaceSiteWindowless_OnUIActivate,
+    InPlaceSiteWindowless_GetWindowContext,
+    InPlaceSiteWindowless_Scroll,
+    InPlaceSiteWindowless_OnUIDeactivate,
+    InPlaceSiteWindowless_OnInPlaceDeactivate,
+    InPlaceSiteWindowless_DiscardUndoState,
+    InPlaceSiteWindowless_DeactivateAndUndo,
+    InPlaceSiteWindowless_OnPosRectChange,
+    InPlaceSiteWindowless_OnInPlaceActivateEx,
+    InPlaceSiteWindowless_OnInPlaceDeactivateEx,
+    InPlaceSiteWindowless_RequestUIActivate,
+    InPlaceSiteWindowless_CanWindowlessActivate,
+    InPlaceSiteWindowless_GetCapture,
+    InPlaceSiteWindowless_SetCapture,
+    InPlaceSiteWindowless_GetFocus,
+    InPlaceSiteWindowless_SetFocus,
+    InPlaceSiteWindowless_GetDC,
+    InPlaceSiteWindowless_ReleaseDC,
+    InPlaceSiteWindowless_InvalidateRect,
+    InPlaceSiteWindowless_InvalidateRgn,
+    InPlaceSiteWindowless_ScrollRect,
+    InPlaceSiteWindowless_AdjustRect,
+    InPlaceSiteWindowless_OnDefWindowMessage
 };
 
 };
 
-static IOleInPlaceSiteEx InPlaceSiteEx = { &InPlaceSiteVtbl };
+static IOleInPlaceSiteWindowless InPlaceSiteWindowless = { &InPlaceSiteWindowlessVtbl };
 
 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
 {
 
 static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
 {
@@ -1723,7 +1872,7 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum
     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
 
     if(SUCCEEDED(hres)) {
     ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
 
     if(SUCCEEDED(hres)) {
-        hres = IOleDocument_CreateView(document, (IOleInPlaceSite*)&InPlaceSiteEx, NULL, 0, &view);
+        hres = IOleDocument_CreateView(document, (IOleInPlaceSite*)&InPlaceSiteWindowless, NULL, 0, &view);
         ok(hres == S_OK, "CreateView failed: %08x\n", hres);
 
         if(SUCCEEDED(hres)) {
         ok(hres == S_OK, "CreateView failed: %08x\n", hres);
 
         if(SUCCEEDED(hres)) {
@@ -1734,16 +1883,16 @@ static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocum
 
             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
 
             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
-            ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n",
-                    inplacesite, &InPlaceSiteEx);
+            ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteWindowless, "inplacesite=%p, expected %p\n",
+                    inplacesite, &InPlaceSiteWindowless);
 
 
-            hres = IOleDocumentView_SetInPlaceSite(view, (IOleInPlaceSite*)&InPlaceSiteEx);
+            hres = IOleDocumentView_SetInPlaceSite(view, (IOleInPlaceSite*)&InPlaceSiteWindowless);
             ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
 
             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
             ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
 
             hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
             ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
-            ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteEx, "inplacesite=%p, expected %p\n",
-                    inplacesite, &InPlaceSiteEx);
+            ok(inplacesite == (IOleInPlaceSite*)&InPlaceSiteWindowless, "inplacesite=%p, expected %p\n",
+                    inplacesite, &InPlaceSiteWindowless);
 
             hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobj);
             ok(hres == S_OK, "Could not get IOleInPlaceActiveObject: %08x\n", hres);
 
             hres = IOleDocumentView_QueryInterface(view, &IID_IOleInPlaceActiveObject, (void**)&activeobj);
             ok(hres == S_OK, "Could not get IOleInPlaceActiveObject: %08x\n", hres);
@@ -2092,8 +2241,13 @@ static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, ID
 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
 {
 static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
         OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
 {
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+    CHECK_EXPECT(TranslateUrl);
+    ok(!dwTranslate, "dwTranslate = %x\n", dwTranslate);
+    ok(!strcmp_wa(pchURLIn, "about:blank"), "pchURLIn = %s\n", wine_dbgstr_w(pchURLIn));
+    ok(ppchURLOut != NULL, "ppchURLOut == NULL\n");
+    ok(!*ppchURLOut, "*ppchURLOut = %p\n", *ppchURLOut);
+
+    return S_FALSE;
 }
 
 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
 }
 
 static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
@@ -2216,6 +2370,8 @@ static HRESULT WINAPI OleCommandTarget_Exec(IOleCommandTarget *iface, const GUID
             ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
             ok(nCmdexecopt == 0, "nCmdexecopts=%08x\n", nCmdexecopt);
             ok(pvaOut == NULL, "pvaOut=%p\n", pvaOut);
             ok(pvaIn == NULL, "pvaIn=%p\n", pvaIn);
+            readystate_set_loading = FALSE;
+            readystate_set_interactive = FALSE;
             load_state = LD_COMPLETE;
             return S_OK;
         case OLECMDID_SETDOWNLOADSTATE:
             load_state = LD_COMPLETE;
             return S_OK;
         case OLECMDID_SETDOWNLOADSTATE:
@@ -2508,6 +2664,62 @@ static const IServiceProviderVtbl ServiceProviderVtbl = {
 
 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
 
 
 static IServiceProvider ServiceProvider = { &ServiceProviderVtbl };
 
+static HRESULT WINAPI AdviseSink_QueryInterface(IAdviseSink *iface,
+        REFIID riid, void **ppv)
+{
+    return QueryInterface(riid, ppv);
+}
+
+static ULONG WINAPI AdviseSink_AddRef(IAdviseSink *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI AdviseSink_Release(IAdviseSink *iface)
+{
+    return 1;
+}
+
+static void WINAPI AdviseSink_OnDataChange(IAdviseSink *iface,
+        FORMATETC *pFormatetc, STGMEDIUM *pStgmed)
+{
+    ok(0, "unexpected call\n");
+}
+
+static void WINAPI AdviseSink_OnViewChange(IAdviseSink *iface,
+        DWORD dwAspect, LONG lindex)
+{
+    ok(0, "unexpected call\n");
+}
+
+static void WINAPI AdviseSink_OnRename(IAdviseSink *iface, IMoniker *pmk)
+{
+    ok(0, "unexpected call\n");
+}
+
+static void WINAPI AdviseSink_OnSave(IAdviseSink *iface)
+{
+    ok(0, "unexpected call\n");
+}
+
+static void WINAPI AdviseSink_OnClose(IAdviseSink *iface)
+{
+    CHECK_EXPECT(Advise_Close);
+}
+
+static const IAdviseSinkVtbl AdviseSinkVtbl = {
+    AdviseSink_QueryInterface,
+    AdviseSink_AddRef,
+    AdviseSink_Release,
+    AdviseSink_OnDataChange,
+    AdviseSink_OnViewChange,
+    AdviseSink_OnRename,
+    AdviseSink_OnSave,
+    AdviseSink_OnClose
+};
+
+static IAdviseSink AdviseSink = { &AdviseSinkVtbl };
+
 DEFINE_GUID(IID_unk1, 0xD48A6EC6,0x6A4A,0x11CF,0x94,0xA7,0x44,0x45,0x53,0x54,0x00,0x00); /* HTMLWindow2 ? */
 DEFINE_GUID(IID_IThumbnailView, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD);
 DEFINE_GUID(IID_IRenMailEditor, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
 DEFINE_GUID(IID_unk1, 0xD48A6EC6,0x6A4A,0x11CF,0x94,0xA7,0x44,0x45,0x53,0x54,0x00,0x00); /* HTMLWindow2 ? */
 DEFINE_GUID(IID_IThumbnailView, 0x7BB0B520,0xB1A7,0x11D2,0xBB,0x23,0x00,0xC0,0x4F,0x79,0xAB,0xCD);
 DEFINE_GUID(IID_IRenMailEditor, 0x000670BA,0x0000,0x0000,0xC0,0x00,0x00,0x00,0x00,0x00,0x00,0x46);
@@ -2527,7 +2739,7 @@ static HRESULT QueryInterface(REFIID riid, void **ppv)
     else if(IsEqualGUID(&IID_IOleContainer, riid))
         *ppv = &OleContainer;
     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
     else if(IsEqualGUID(&IID_IOleContainer, riid))
         *ppv = &OleContainer;
     else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
-        *ppv = &InPlaceSiteEx;
+        *ppv = &InPlaceSiteWindowless;
     else if(IsEqualGUID(&IID_IOleCommandTarget , riid))
         *ppv = &OleCommandTarget;
     else if(IsEqualGUID(&IID_IDispatch, riid))
     else if(IsEqualGUID(&IID_IOleCommandTarget , riid))
         *ppv = &OleCommandTarget;
     else if(IsEqualGUID(&IID_IDispatch, riid))
@@ -2535,7 +2747,9 @@ static HRESULT QueryInterface(REFIID riid, void **ppv)
     else if(IsEqualGUID(&IID_IServiceProvider, riid))
         *ppv = &ServiceProvider;
     else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid))
     else if(IsEqualGUID(&IID_IServiceProvider, riid))
         *ppv = &ServiceProvider;
     else if(IsEqualGUID(&IID_IOleInPlaceSiteEx, riid))
-        *ppv = ipsex ? &InPlaceSiteEx : NULL;
+        *ppv = ipsex ? &InPlaceSiteWindowless : NULL;
+    else if(IsEqualGUID(&IID_IOleInPlaceSiteWindowless, riid))
+        *ppv = ipsw ? &InPlaceSiteWindowless : NULL;
     else if(IsEqualGUID(&IID_IOleControlSite, riid))
         *ppv = &OleControlSite;
     else if(IsEqualGUID(&IID_IDocHostShowUI, riid))
     else if(IsEqualGUID(&IID_IOleControlSite, riid))
         *ppv = &OleControlSite;
     else if(IsEqualGUID(&IID_IDocHostShowUI, riid))
@@ -2565,10 +2779,58 @@ static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam
     return DefWindowProc(hwnd, msg, wParam, lParam);
 }
 
     return DefWindowProc(hwnd, msg, wParam, lParam);
 }
 
+static void test_doscroll(IUnknown *unk)
+{
+    IHTMLDocument3 *doc;
+    IHTMLElement2 *elem2;
+    IHTMLElement *elem;
+    VARIANT v;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument3, (void**)&doc);
+    ok(hres == S_OK, "Could not get IHTMLDocument3 iface: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IHTMLDocument3_get_documentElement(doc, &elem);
+    IHTMLDocument3_Release(doc);
+    ok(hres == S_OK, "get_documentElement failed: %08x\n", hres);
+    switch(load_state) {
+    case LD_DOLOAD:
+    case LD_NO:
+        ok(!elem, "elem != NULL\n");
+    default:
+        break;
+    case LD_INTERACTIVE:
+    case LD_COMPLETE:
+        ok(elem != NULL, "elem == NULL\n");
+    }
+    if(!elem)
+        return;
+
+    hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLElement2, (void**)&elem2);
+    IHTMLElement_Release(elem);
+    ok(hres == S_OK, "Could not get IHTMLElement2 iface: %08x\n", hres);
+
+    V_VT(&v) = VT_BSTR;
+    V_BSTR(&v) = a2bstr("left");
+    hres = IHTMLElement2_doScroll(elem2, v);
+    SysFreeString(V_BSTR(&v));
+    IHTMLElement2_Release(elem2);
+
+    if(inplace_deactivated)
+        ok(hres == E_PENDING, "doScroll failed: %08x\n", hres);
+    else if(load_state == LD_COMPLETE)
+        ok(hres == S_OK, "doScroll failed: %08x\n", hres);
+    else
+        ok(hres == E_PENDING || hres == S_OK, "doScroll failed: %08x\n", hres);
+}
+
 static void _test_readyState(unsigned line, IUnknown *unk)
 {
     IHTMLDocument2 *htmldoc;
     DISPPARAMS dispparams;
 static void _test_readyState(unsigned line, IUnknown *unk)
 {
     IHTMLDocument2 *htmldoc;
     DISPPARAMS dispparams;
+    IHTMLElement *elem;
     BSTR state;
     VARIANT out;
     HRESULT hres;
     BSTR state;
     VARIANT out;
     HRESULT hres;
@@ -2604,6 +2866,26 @@ static void _test_readyState(unsigned line, IUnknown *unk)
          wine_dbgstr_w(state), load_state);
     SysFreeString(state);
 
          wine_dbgstr_w(state), load_state);
     SysFreeString(state);
 
+    hres = IHTMLDocument2_get_body(htmldoc, &elem);
+    ok_(__FILE__,line)(hres == S_OK, "get_body failed: %08x\n", hres);
+    if(elem) {
+        IHTMLElement2 *elem2;
+        VARIANT var;
+
+        hres = IHTMLElement_QueryInterface(elem, &IID_IHTMLElement2, (void**)&elem2);
+        IHTMLElement_Release(elem);
+        ok(hres == S_OK, "Could not get IHTMLElement2 iface: %08x\n", hres);
+
+        hres = IHTMLElement2_get_readyState(elem2, &var);
+        IHTMLElement2_Release(elem2);
+        ok(hres == S_OK, "get_readyState failed: %08x\n", hres);
+        ok(V_VT(&var) == VT_BSTR, "V_VT(state) = %d\n", V_VT(&var));
+        ok(!strcmp_wa(V_BSTR(&var), "complete"), "unexpected body state %s\n", wine_dbgstr_w(V_BSTR(&var)));
+        VariantClear(&var);
+    }else {
+        ok_(__FILE__,line)(load_state != LD_COMPLETE, "body is NULL in complete state\n");
+    }
+
     dispparams.cArgs = 0;
     dispparams.cNamedArgs = 0;
     dispparams.rgdispidNamedArgs = NULL;
     dispparams.cArgs = 0;
     dispparams.cNamedArgs = 0;
     dispparams.rgdispidNamedArgs = NULL;
@@ -2618,6 +2900,8 @@ static void _test_readyState(unsigned line, IUnknown *unk)
     ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out));
     ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%d, expected %d\n", V_I4(&out), load_state%5);
 
     ok_(__FILE__,line) (V_VT(&out) == VT_I4, "V_VT(out)=%d\n", V_VT(&out));
     ok_(__FILE__,line) (V_I4(&out) == load_state%5, "VT_I4(out)=%d, expected %d\n", V_I4(&out), load_state%5);
 
+    test_doscroll((IUnknown*)htmldoc);
+
     IHTMLDocument2_Release(htmldoc);
 }
 
     IHTMLDocument2_Release(htmldoc);
 }
 
@@ -2669,6 +2953,7 @@ static void test_ConnectionPointContainer(IUnknown *unk)
     if(FAILED(hres))
         return;
 
     if(FAILED(hres))
         return;
 
+    test_ConnectionPoint(container, &IID_IDispatch);
     test_ConnectionPoint(container, &IID_IPropertyNotifySink);
     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents);
     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents2);
     test_ConnectionPoint(container, &IID_IPropertyNotifySink);
     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents);
     test_ConnectionPoint(container, &DIID_HTMLDocumentEvents2);
@@ -2780,6 +3065,7 @@ static void test_Load(IPersistMoniker *persist, IMoniker *mon)
 #define DWL_CSS       0x0002
 #define DWL_TRYCSS    0x0004
 #define DWL_HTTP      0x0008
 #define DWL_CSS       0x0002
 #define DWL_TRYCSS    0x0004
 #define DWL_HTTP      0x0008
+#define DWL_EMPTY     0x0010
 
 static void test_download(DWORD flags)
 {
 
 static void test_download(DWORD flags)
 {
@@ -2796,7 +3082,8 @@ static void test_download(DWORD flags)
     if((flags & DWL_VERBDONE) && !load_from_stream)
         SET_EXPECT(GetHostInfo);
     SET_EXPECT(SetStatusText);
     if((flags & DWL_VERBDONE) && !load_from_stream)
         SET_EXPECT(GetHostInfo);
     SET_EXPECT(SetStatusText);
-    SET_EXPECT(Exec_SETDOWNLOADSTATE_1);
+    if(!(flags & DWL_EMPTY))
+        SET_EXPECT(Exec_SETDOWNLOADSTATE_1);
     SET_EXPECT(GetDropTarget);
     if(flags & DWL_TRYCSS)
         SET_EXPECT(Exec_ShellDocView_84);
     SET_EXPECT(GetDropTarget);
     if(flags & DWL_TRYCSS)
         SET_EXPECT(Exec_ShellDocView_84);
@@ -2821,7 +3108,8 @@ static void test_download(DWORD flags)
     SET_EXPECT(OnChanged_1005);
     SET_EXPECT(OnChanged_READYSTATE);
     SET_EXPECT(Exec_SETPROGRESSPOS);
     SET_EXPECT(OnChanged_1005);
     SET_EXPECT(OnChanged_READYSTATE);
     SET_EXPECT(Exec_SETPROGRESSPOS);
-    SET_EXPECT(Exec_SETDOWNLOADSTATE_0);
+    if(!(flags & DWL_EMPTY))
+        SET_EXPECT(Exec_SETDOWNLOADSTATE_0);
     SET_EXPECT(Exec_ShellDocView_103);
     SET_EXPECT(Exec_ShellDocView_105);
     SET_EXPECT(Exec_ShellDocView_140);
     SET_EXPECT(Exec_ShellDocView_103);
     SET_EXPECT(Exec_ShellDocView_105);
     SET_EXPECT(Exec_ShellDocView_140);
@@ -2842,31 +3130,18 @@ static void test_download(DWORD flags)
     if((flags & DWL_VERBDONE) && !load_from_stream)
         CHECK_CALLED(GetHostInfo);
     CHECK_CALLED(SetStatusText);
     if((flags & DWL_VERBDONE) && !load_from_stream)
         CHECK_CALLED(GetHostInfo);
     CHECK_CALLED(SetStatusText);
-    CHECK_CALLED(Exec_SETDOWNLOADSTATE_1);
+    if(!(flags & DWL_EMPTY))
+        CHECK_CALLED(Exec_SETDOWNLOADSTATE_1);
     CHECK_CALLED(GetDropTarget);
     if(flags & DWL_TRYCSS)
         SET_CALLED(Exec_ShellDocView_84);
     if(flags & DWL_CSS) {
     CHECK_CALLED(GetDropTarget);
     if(flags & DWL_TRYCSS)
         SET_CALLED(Exec_ShellDocView_84);
     if(flags & DWL_CSS) {
-        if(called_CreateInstance) {
-            CHECK_CALLED(CreateInstance);
-            CHECK_CALLED(Start);
-            CHECK_CALLED(LockRequest);
-            CHECK_CALLED(Terminate);
-            CHECK_CALLED(Protocol_Read);
-            CHECK_CALLED(UnlockRequest);
-        }else {
-            skip("CreateInstance not called. Assuming no Gecko installed.\n");
-
-            SET_CALLED(Exec_ShellDocView_84);
-            SET_CALLED(CreateInstance);
-            SET_CALLED(Start);
-            SET_CALLED(LockRequest);
-            SET_CALLED(Terminate);
-            SET_CALLED(Protocol_Read);
-            SET_CALLED(UnlockRequest);
-
-            nogecko = TRUE;
-        }
+        CHECK_CALLED(CreateInstance);
+        CHECK_CALLED(Start);
+        CHECK_CALLED(LockRequest);
+        CHECK_CALLED(Terminate);
+        CHECK_CALLED(Protocol_Read);
+        CHECK_CALLED(UnlockRequest);
     }
     SET_CALLED(Exec_Explorer_69);
     SET_CALLED(EnableModeless_TRUE); /* IE7 */
     }
     SET_CALLED(Exec_Explorer_69);
     SET_CALLED(EnableModeless_TRUE); /* IE7 */
@@ -2881,7 +3156,8 @@ static void test_download(DWORD flags)
     CHECK_CALLED(OnChanged_1005);
     CHECK_CALLED(OnChanged_READYSTATE);
     CHECK_CALLED(Exec_SETPROGRESSPOS);
     CHECK_CALLED(OnChanged_1005);
     CHECK_CALLED(OnChanged_READYSTATE);
     CHECK_CALLED(Exec_SETPROGRESSPOS);
-    CHECK_CALLED(Exec_SETDOWNLOADSTATE_0);
+    if(!(flags & DWL_EMPTY))
+        CHECK_CALLED(Exec_SETDOWNLOADSTATE_0);
     SET_CALLED(Exec_ShellDocView_103);
     SET_CALLED(Exec_ShellDocView_105);
     SET_CALLED(Exec_ShellDocView_140);
     SET_CALLED(Exec_ShellDocView_103);
     SET_CALLED(Exec_ShellDocView_105);
     SET_CALLED(Exec_ShellDocView_140);
@@ -2933,6 +3209,34 @@ static void test_Persist(IUnknown *unk, IMoniker *mon)
     }
 }
 
     }
 }
 
+static void test_put_href(IUnknown *unk)
+{
+    IHTMLLocation *location;
+    IHTMLDocument2 *doc;
+    BSTR str;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc);
+    ok(hres == S_OK, "Could not get IHTMLDocument2 iface: %08x\n", hres);
+
+    location = NULL;
+    hres = IHTMLDocument2_get_location(doc, &location);
+    IHTMLDocument2_Release(doc);
+    ok(hres == S_OK, "get_location failed: %08x\n", hres);
+    ok(location != NULL, "location == NULL\n");
+
+    SET_EXPECT(TranslateUrl);
+    SET_EXPECT(Navigate);
+    str = a2bstr("about:blank");
+    hres = IHTMLLocation_put_href(location, str);
+    SysFreeString(str);
+    ok(hres == S_OK, "put_href failed: %08x\n", hres);
+    CHECK_CALLED(TranslateUrl);
+    CHECK_CALLED(Navigate);
+
+    IHTMLLocation_Release(location);
+}
+
 static const OLECMDF expect_cmds[OLECMDID_GETPRINTTEMPLATE+1] = {
     0,
     OLECMDF_SUPPORTED,                  /* OLECMDID_OPEN */
 static const OLECMDF expect_cmds[OLECMDID_GETPRINTTEMPLATE+1] = {
     0,
     OLECMDF_SUPPORTED,                  /* OLECMDID_OPEN */
@@ -3227,13 +3531,12 @@ static void test_exec_fontname(IUnknown *unk, LPCWSTR name, LPCWSTR exname)
    }
 
    hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_FONTNAME, 0, in, out);
    }
 
    hres = IOleCommandTarget_Exec(cmdtrg, &CGID_MSHTML, IDM_FONTNAME, 0, in, out);
-   if(!nogecko)
-       ok(hres == S_OK, "Exec(IDM_FONTNAME) failed: %08x\n", hres);
+   ok(hres == S_OK, "Exec(IDM_FONTNAME) failed: %08x\n", hres);
 
    if(in)
        VariantClear(in);
 
 
    if(in)
        VariantClear(in);
 
-   if(out && !nogecko) {
+   if(out) {
        ok(V_VT(out) == VT_BSTR, "V_VT(out) = %x\n", V_VT(out));
        if(V_VT(out) == VT_BSTR) {
            if(exname)
        ok(V_VT(out) == VT_BSTR, "V_VT(out) = %x\n", V_VT(out));
        if(V_VT(out) == VT_BSTR) {
            if(exname)
@@ -3503,6 +3806,54 @@ static void test_Close(IUnknown *unk, BOOL set_client)
     IOleObject_Release(oleobj);
 }
 
     IOleObject_Release(oleobj);
 }
 
+static void test_Advise(IUnknown *unk)
+{
+    IOleObject *oleobj = NULL;
+    IEnumSTATDATA *enum_advise = (void*)0xdeadbeef;
+    DWORD conn;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
+    ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    hres = IOleObject_Unadvise(oleobj, 0);
+    ok(hres == OLE_E_NOCONNECTION, "Unadvise returned: %08x\n", hres);
+
+    hres = IOleObject_EnumAdvise(oleobj, &enum_advise);
+    ok(hres == S_OK, "EnumAdvise returned: %08x\n", hres);
+    ok(enum_advise == NULL, "enum_advise != NULL\n");
+
+    conn = -1;
+    hres = IOleObject_Advise(oleobj, NULL, &conn);
+    /* Old IE returns S_OK and sets conn to 1 */
+    ok(hres == E_INVALIDARG || hres == S_OK, "Advise returned: %08x\n", hres);
+    ok(conn == 0 || conn == 1, "conn = %d\n", conn);
+
+    hres = IOleObject_Advise(oleobj, &AdviseSink, NULL);
+    ok(hres == E_INVALIDARG, "Advise returned: %08x\n", hres);
+
+    hres = IOleObject_Advise(oleobj, &AdviseSink, &conn);
+    ok(hres == S_OK, "Advise returned: %08x\n", hres);
+    ok(conn == 1, "conn = %d\n", conn);
+
+    hres = IOleObject_Advise(oleobj, &AdviseSink, &conn);
+    ok(hres == S_OK, "Advise returned: %08x\n", hres);
+    ok(conn == 2, "conn = %d\n", conn);
+
+    hres = IOleObject_Unadvise(oleobj, 1);
+    ok(hres == S_OK, "Unadvise returned: %08x\n", hres);
+
+    hres = IOleObject_Unadvise(oleobj, 1);
+    ok(hres == OLE_E_NOCONNECTION, "Unadvise returned: %08x\n", hres);
+
+    hres = IOleObject_Unadvise(oleobj, 2);
+    ok(hres == S_OK, "Unadvise returned: %08x\n", hres);
+
+    IOleObject_Release(oleobj);
+}
+
 static void test_OnFrameWindowActivate(IUnknown *unk)
 {
     IOleInPlaceActiveObject *inplaceact;
 static void test_OnFrameWindowActivate(IUnknown *unk)
 {
     IOleInPlaceActiveObject *inplaceact;
@@ -3818,6 +4169,36 @@ static void test_StreamLoad(IUnknown *unk)
     IPersistStreamInit_Release(init);
 }
 
     IPersistStreamInit_Release(init);
 }
 
+static void test_StreamInitNew(IUnknown *unk)
+{
+    IPersistStreamInit *init;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IPersistStreamInit, (void**)&init);
+    ok(hres == S_OK, "QueryInterface(IID_IPersistStreamInit) failed: %08x\n", hres);
+    if(FAILED(hres))
+        return;
+
+    SET_EXPECT(Invoke_AMBIENT_SILENT);
+    SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
+    SET_EXPECT(Exec_ShellDocView_37);
+    SET_EXPECT(OnChanged_READYSTATE);
+    readystate_set_loading = TRUE;
+
+    hres = IPersistStreamInit_InitNew(init);
+    ok(hres == S_OK, "Load failed: %08x\n", hres);
+
+    CHECK_CALLED(Invoke_AMBIENT_SILENT);
+    CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
+    CHECK_CALLED(Exec_ShellDocView_37);
+    CHECK_CALLED(OnChanged_READYSTATE);
+
+    test_timer(EXPECT_SETTITLE);
+    test_GetCurMoniker(unk, NULL, about_blank_url);
+
+    IPersistStreamInit_Release(init);
+}
+
 static void test_QueryInterface(IUnknown *unk)
 {
     IUnknown *qi;
 static void test_QueryInterface(IUnknown *unk)
 {
     IUnknown *qi;
@@ -3868,6 +4249,7 @@ static void init_test(enum load_state_t ls) {
     stream_read = 0;
     protocol_read = 0;
     ipsex = FALSE;
     stream_read = 0;
     protocol_read = 0;
     ipsex = FALSE;
+    inplace_deactivated = FALSE;
 }
 
 static void test_HTMLDocument(BOOL do_load)
 }
 
 static void test_HTMLDocument(BOOL do_load)
@@ -3886,6 +4268,7 @@ static void test_HTMLDocument(BOOL do_load)
     doc_unk = unk;
 
     test_QueryInterface(unk);
     doc_unk = unk;
 
     test_QueryInterface(unk);
+    test_Advise(unk);
     test_IsDirty(unk, S_FALSE);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
     test_external(unk, FALSE);
     test_IsDirty(unk, S_FALSE);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
     test_external(unk, FALSE);
@@ -4013,6 +4396,63 @@ static void test_HTMLDocument_hlink(void)
     ok(ref == 0, "ref=%d, expected 0\n", ref);
 }
 
     ok(ref == 0, "ref=%d, expected 0\n", ref);
 }
 
+static void test_cookies(IUnknown *unk)
+{
+    WCHAR buf[1024];
+    IHTMLDocument2 *doc;
+    DWORD size;
+    BSTR str, str2;
+    BOOL b;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IHTMLDocument2, (void**)&doc);
+    ok(hres == S_OK, "QueryInterface(IID_IHTMLDocument2) failed: %08x\n", hres);
+
+    hres = IHTMLDocument2_get_cookie(doc, &str);
+    ok(hres == S_OK, "get_cookie failed: %08x\n", hres);
+    if(str) {
+        size = sizeof(buf)/sizeof(WCHAR);
+        b = InternetGetCookieW(http_urlW, NULL, buf, &size);
+        ok(b, "InternetGetCookieW failed: %08x\n", GetLastError());
+        ok(!lstrcmpW(buf, str), "cookie = %s, expected %s\n", wine_dbgstr_w(str), wine_dbgstr_w(buf));
+        SysFreeString(str);
+    }
+
+    str = a2bstr("test=testval");
+    hres = IHTMLDocument2_put_cookie(doc, str);
+    ok(hres == S_OK, "put_cookie failed: %08x\n", hres);
+
+    str2 = NULL;
+    hres = IHTMLDocument2_get_cookie(doc, &str2);
+    ok(hres == S_OK, "get_cookie failed: %08x\n", hres);
+    ok(str2 != NULL, "cookie = NULL\n");
+    size = sizeof(buf)/sizeof(WCHAR);
+    b = InternetGetCookieW(http_urlW, NULL, buf, &size);
+    ok(b, "InternetGetCookieW failed: %08x\n", GetLastError());
+    ok(!lstrcmpW(buf, str2), "cookie = %s, expected %s\n", wine_dbgstr_w(str2), wine_dbgstr_w(buf));
+    ok(strstrW(str2, str) != NULL, "could not find %s in %s\n", wine_dbgstr_w(str), wine_dbgstr_w(str2));
+    SysFreeString(str);
+    SysFreeString(str2);
+
+    str = a2bstr("test=testval2");
+    hres = IHTMLDocument2_put_cookie(doc, str);
+    ok(hres == S_OK, "put_cookie failed: %08x\n", hres);
+
+    str2 = NULL;
+    hres = IHTMLDocument2_get_cookie(doc, &str2);
+    ok(hres == S_OK, "get_cookie failed: %08x\n", hres);
+    ok(str2 != NULL, "cookie = NULL\n");
+    size = sizeof(buf)/sizeof(WCHAR);
+    b = InternetGetCookieW(http_urlW, NULL, buf, &size);
+    ok(b, "InternetGetCookieW failed: %08x\n", GetLastError());
+    ok(!lstrcmpW(buf, str2), "cookie = %s, expected %s\n", wine_dbgstr_w(str2), wine_dbgstr_w(buf));
+    ok(strstrW(str2, str) != NULL, "could not find %s in %s\n", wine_dbgstr_w(str), wine_dbgstr_w(str2));
+    SysFreeString(str);
+    SysFreeString(str2);
+
+    IHTMLDocument2_Release(doc);
+}
+
 static void test_HTMLDocument_http(void)
 {
     IMoniker *http_mon;
 static void test_HTMLDocument_http(void)
 {
     IMoniker *http_mon;
@@ -4020,9 +4460,6 @@ static void test_HTMLDocument_http(void)
     ULONG ref;
     HRESULT hres;
 
     ULONG ref;
     HRESULT hres;
 
-    static const WCHAR http_urlW[] =
-        {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g',0};
-
     trace("Testing HTMLDocument (http)...\n");
 
     hres = CreateURLMoniker(NULL, http_urlW, &http_mon);
     trace("Testing HTMLDocument (http)...\n");
 
     hres = CreateURLMoniker(NULL, http_urlW, &http_mon);
@@ -4050,9 +4487,12 @@ static void test_HTMLDocument_http(void)
     else
         win_skip("IE running in Enhanced Security Configuration\n");
 
     else
         win_skip("IE running in Enhanced Security Configuration\n");
 
+    test_cookies(unk);
     test_IsDirty(unk, S_FALSE);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
 
     test_IsDirty(unk, S_FALSE);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
 
+    test_put_href(unk);
+
     test_InPlaceDeactivate(unk, TRUE);
     test_Close(unk, FALSE);
     test_IsDirty(unk, S_FALSE);
     test_InPlaceDeactivate(unk, TRUE);
     test_Close(unk, FALSE);
     test_IsDirty(unk, S_FALSE);
@@ -4069,10 +4509,29 @@ static void test_HTMLDocument_http(void)
     ok(!ref, "ref=%d, expected 0\n", ref);
 }
 
     ok(!ref, "ref=%d, expected 0\n", ref);
 }
 
+static void test_QueryService(IUnknown *unk, BOOL success)
+{
+    IServiceProvider *sp;
+    IHlinkFrame *hf;
+    HRESULT hres;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IServiceProvider, (void**)&sp);
+    ok(hres == S_OK, "QueryService returned %08x\n", hres);
+
+    hres = IServiceProvider_QueryService(sp, &IID_IHlinkFrame, &IID_IHlinkFrame, (void**)&hf);
+    if(SUCCEEDED(hres))
+        IHlinkFrame_Release(hf);
+
+    ok(hres == (success?S_OK:E_NOINTERFACE), "QueryService returned %08x, expected %08x\n", hres, success?S_OK:E_NOINTERFACE);
+
+    IServiceProvider_Release(sp);
+}
+
 static void test_HTMLDocument_StreamLoad(void)
 {
     IOleObject *oleobj;
     IUnknown *unk;
 static void test_HTMLDocument_StreamLoad(void)
 {
     IOleObject *oleobj;
     IUnknown *unk;
+    DWORD conn;
     HRESULT hres;
     ULONG ref;
 
     HRESULT hres;
     ULONG ref;
 
@@ -4089,10 +4548,15 @@ static void test_HTMLDocument_StreamLoad(void)
     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
 
     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
 
+    hres = IOleObject_Advise(oleobj, &AdviseSink, &conn);
+    ok(hres == S_OK, "Advise failed: %08x\n", hres);
+
     test_readyState(unk);
     test_IsDirty(unk, S_FALSE);
     test_ConnectionPointContainer(unk);
     test_readyState(unk);
     test_IsDirty(unk, S_FALSE);
     test_ConnectionPointContainer(unk);
+    test_QueryService(unk, FALSE);
     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
+    test_QueryService(unk, TRUE);
     test_DoVerb(oleobj);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
 
     test_DoVerb(oleobj);
     test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
 
@@ -4105,7 +4569,64 @@ static void test_HTMLDocument_StreamLoad(void)
 
     test_UIDeactivate();
     test_InPlaceDeactivate(unk, TRUE);
 
     test_UIDeactivate();
     test_InPlaceDeactivate(unk, TRUE);
+    SET_EXPECT(Advise_Close);
+    test_Close(unk, FALSE);
+    CHECK_CALLED(Advise_Close);
+    test_IsDirty(unk, S_FALSE);
+
+    if(view) {
+        IOleDocumentView_Release(view);
+        view = NULL;
+    }
+
+
+    ref = IUnknown_Release(unk);
+    ok(ref == 0, "ref=%d, expected 0\n", ref);
+}
+
+static void test_HTMLDocument_StreamInitNew(void)
+{
+    IOleObject *oleobj;
+    IUnknown *unk;
+    DWORD conn;
+    HRESULT hres;
+    ULONG ref;
+
+    trace("Testing HTMLDocument (IPersistStreamInit)...\n");
+
+    init_test(LD_DOLOAD);
+    load_from_stream = TRUE;
+
+    hres = create_document(&unk);
+    if(FAILED(hres))
+        return;
+    doc_unk = unk;
+
+    hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
+    ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
+
+    hres = IOleObject_Advise(oleobj, &AdviseSink, &conn);
+    ok(hres == S_OK, "Advise failed: %08x\n", hres);
+
+    test_readyState(unk);
+    test_IsDirty(unk, S_FALSE);
+    test_ConnectionPointContainer(unk);
+    test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
+    test_DoVerb(oleobj);
+    test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
+
+    IOleObject_Release(oleobj);
+
+    test_GetCurMoniker(unk, NULL, NULL);
+    test_StreamInitNew(unk);
+    test_download(DWL_VERBDONE|DWL_TRYCSS|DWL_EMPTY);
+    test_MSHTML_QueryStatus(unk, OLECMDF_SUPPORTED);
+
+    test_UIDeactivate();
+    test_InPlaceDeactivate(unk, TRUE);
+    SET_EXPECT(Advise_Close);
     test_Close(unk, FALSE);
     test_Close(unk, FALSE);
+    CHECK_CALLED(Advise_Close);
     test_IsDirty(unk, S_FALSE);
 
     if(view) {
     test_IsDirty(unk, S_FALSE);
 
     if(view) {
@@ -4149,6 +4670,7 @@ static void test_editing_mode(BOOL do_load)
 {
     IUnknown *unk;
     IOleObject *oleobj;
 {
     IUnknown *unk;
     IOleObject *oleobj;
+    DWORD conn;
     HRESULT hres;
     ULONG ref;
 
     HRESULT hres;
     ULONG ref;
 
@@ -4165,6 +4687,9 @@ static void test_editing_mode(BOOL do_load)
     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
 
     hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
     ok(hres == S_OK, "Could not get IOleObject: %08x\n", hres);
 
+    hres = IOleObject_Advise(oleobj, &AdviseSink, &conn);
+    ok(hres == S_OK, "Advise failed: %08x\n", hres);
+
     test_readyState(unk);
     test_ConnectionPointContainer(unk);
     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
     test_readyState(unk);
     test_ConnectionPointContainer(unk);
     test_ClientSite(oleobj, CLIENTSITE_EXPECTPATH);
@@ -4197,17 +4722,15 @@ static void test_editing_mode(BOOL do_load)
 
         test_exec_noargs(unk, IDM_JUSTIFYRIGHT);
         test_timer(EXPECT_UPDATEUI);
 
         test_exec_noargs(unk, IDM_JUSTIFYRIGHT);
         test_timer(EXPECT_UPDATEUI);
-        if(!nogecko)
-            test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
-                             OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
+        test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
+                         OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
 
         test_exec_noargs(unk, IDM_JUSTIFYCENTER);
         test_timer(EXPECT_UPDATEUI);
         test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
                          OLECMDF_SUPPORTED|OLECMDF_ENABLED);
 
         test_exec_noargs(unk, IDM_JUSTIFYCENTER);
         test_timer(EXPECT_UPDATEUI);
         test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYRIGHT,
                          OLECMDF_SUPPORTED|OLECMDF_ENABLED);
-        if(!nogecko)
-            test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYCENTER,
-                             OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
+        test_QueryStatus(unk, &CGID_MSHTML, IDM_JUSTIFYCENTER,
+                         OLECMDF_SUPPORTED|OLECMDF_ENABLED|OLECMDF_LATCHED);
 
         test_exec_noargs(unk, IDM_HORIZONTALLINE);
         test_timer(EXPECT_UPDATEUI);
 
         test_exec_noargs(unk, IDM_HORIZONTALLINE);
         test_timer(EXPECT_UPDATEUI);
@@ -4217,7 +4740,9 @@ static void test_editing_mode(BOOL do_load)
 
     test_UIDeactivate();
     test_InPlaceDeactivate(unk, TRUE);
 
     test_UIDeactivate();
     test_InPlaceDeactivate(unk, TRUE);
+    SET_EXPECT(Advise_Close);
     test_Close(unk, FALSE);
     test_Close(unk, FALSE);
+    CHECK_CALLED(Advise_Close);
 
     if(view) {
         IOleDocumentView_Release(view);
 
     if(view) {
         IOleDocumentView_Release(view);
@@ -4228,51 +4753,171 @@ static void test_editing_mode(BOOL do_load)
     ok(ref == 0, "ref=%d, expected 0\n", ref);
 }
 
     ok(ref == 0, "ref=%d, expected 0\n", ref);
 }
 
-static void register_protocol(void)
+static void test_UIActivate(BOOL do_load, BOOL use_ipsex, BOOL use_ipsw)
 {
 {
-    IInternetSession *session;
+    IUnknown *unk;
+    IOleObject *oleobj;
+    IOleInPlaceSite *inplacesite;
     HRESULT hres;
     HRESULT hres;
+    ULONG ref;
 
 
-    static const WCHAR wsz_winetest[] = {'w','i','n','e','t','e','s','t',0};
+    trace("Running OleDocumentView_UIActivate tests (%d %d %d)\n", do_load, use_ipsex, use_ipsw);
 
 
-    hres = CoInternetGetSession(0, &session, 0);
-    ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
+    init_test(do_load ? LD_DOLOAD : LD_NO);
 
 
-    hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL,
-            wsz_winetest, 0, NULL, 0);
-    ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
+    hres = create_document(&unk);
+    if(FAILED(hres))
+        return;
+    doc_unk = unk;
 
 
-    IInternetSession_Release(session);
-}
+    ipsex = use_ipsex;
+    ipsw = use_ipsw;
 
 
-static void gecko_installer_workaround(BOOL disable)
-{
-    HKEY hkey;
-    DWORD res;
+    hres = IUnknown_QueryInterface(unk, &IID_IOleObject, (void**)&oleobj);
+    ok(hres == S_OK, "QueryInterface(IID_IOleObject) failed: %08x\n", hres);
 
 
-    static BOOL has_url = FALSE;
-    static char url[2048];
+    hres = IUnknown_QueryInterface(unk, &IID_IOleDocumentView, (void**)&view);
+    ok(hres == S_OK, "QueryInterface(IID_IOleDocumentView) failed: %08x\n", hres);
 
 
-    if(!disable && !has_url)
-        return;
+    SET_EXPECT(Invoke_AMBIENT_USERMODE);
+    SET_EXPECT(GetHostInfo);
+    SET_EXPECT(Invoke_AMBIENT_DLCONTROL);
+    SET_EXPECT(Invoke_AMBIENT_SILENT);
+    SET_EXPECT(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
+    SET_EXPECT(Invoke_AMBIENT_USERAGENT);
+    SET_EXPECT(Invoke_AMBIENT_PALETTE);
+    SET_EXPECT(GetOptionKeyPath);
+    SET_EXPECT(GetOverrideKeyPath);
+    SET_EXPECT(GetWindow);
+    SET_EXPECT(QueryStatus_SETPROGRESSTEXT);
+    SET_EXPECT(Exec_SETPROGRESSMAX);
+    SET_EXPECT(Exec_SETPROGRESSPOS);
 
 
-    res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
-    if(res != ERROR_SUCCESS)
-        return;
+    hres = IOleObject_SetClientSite(oleobj, &ClientSite);
+    ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
 
 
-    if(disable) {
-        DWORD type, size = sizeof(url);
+    CHECK_CALLED(Invoke_AMBIENT_USERMODE);
+    CHECK_CALLED(GetHostInfo);
+    CHECK_CALLED(Invoke_AMBIENT_DLCONTROL);
+    CHECK_CALLED(Invoke_AMBIENT_SILENT);
+    CHECK_CALLED(Invoke_AMBIENT_OFFLINEIFNOTCONNECTED);
+    CHECK_CALLED(Invoke_AMBIENT_USERAGENT);
+    CHECK_CALLED(Invoke_AMBIENT_PALETTE);
+    CHECK_CALLED(GetOptionKeyPath);
+    CHECK_CALLED(GetOverrideKeyPath);
+    CHECK_CALLED(GetWindow);
+    CHECK_CALLED(QueryStatus_SETPROGRESSTEXT);
+    CHECK_CALLED(Exec_SETPROGRESSMAX);
+    CHECK_CALLED(Exec_SETPROGRESSPOS);
 
 
-        res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
-        if(res == ERROR_SUCCESS && type == REG_SZ)
-            has_url = TRUE;
+    hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
+    ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
+    ok(inplacesite == NULL, "inplacesite = %p, expected NULL\n", inplacesite);
 
 
-        RegDeleteValue(hkey, "GeckoUrl");
-    }else {
-        RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
+    SET_EXPECT(GetContainer);
+    SET_EXPECT(LockContainer);
+    SET_EXPECT(CanInPlaceActivate);
+    SET_EXPECT(GetWindowContext);
+    SET_EXPECT(GetWindow);
+    if(use_ipsex) {
+        SET_EXPECT(OnInPlaceActivateEx);
+        SET_EXPECT(RequestUIActivate);
     }
     }
+    else
+        SET_EXPECT(OnInPlaceActivate);
+    SET_EXPECT(OnUIActivate);
+    SET_EXPECT(SetStatusText);
+    SET_EXPECT(Exec_SETPROGRESSMAX);
+    SET_EXPECT(Exec_SETPROGRESSPOS);
+    SET_EXPECT(ShowUI);
+    SET_EXPECT(InPlaceUIWindow_SetActiveObject);
+    SET_EXPECT(InPlaceFrame_SetBorderSpace);
+    SET_EXPECT(OnFocus_TRUE);
+    SET_EXPECT(SetActiveObject);
+    expect_LockContainer_fLock = TRUE;
+
+    hres = IOleDocumentView_UIActivate(view, TRUE);
+    ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
+
+    CHECK_CALLED(GetContainer);
+    CHECK_CALLED(LockContainer);
+    CHECK_CALLED(CanInPlaceActivate);
+    CHECK_CALLED(GetWindowContext);
+    CHECK_CALLED(GetWindow);
+    if(use_ipsex) {
+        CHECK_CALLED(OnInPlaceActivateEx);
+        SET_EXPECT(RequestUIActivate);
+    }
+    else
+        CHECK_CALLED(OnInPlaceActivate);
+    CHECK_CALLED(OnUIActivate);
+    CHECK_CALLED(SetStatusText);
+    CHECK_CALLED(Exec_SETPROGRESSMAX);
+    CHECK_CALLED(Exec_SETPROGRESSPOS);
+    CHECK_CALLED(ShowUI);
+    CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
+    CHECK_CALLED(InPlaceFrame_SetBorderSpace);
+    CHECK_CALLED(OnFocus_TRUE);
+    CHECK_CALLED(SetActiveObject);
+    container_locked = TRUE;
+
+    SET_EXPECT(SetActiveObject_null);
+    SET_EXPECT(InPlaceUIWindow_SetActiveObject);
+    SET_EXPECT(HideUI);
+    SET_EXPECT(OnUIDeactivate);
+
+    hres = IOleDocumentView_UIActivate(view, FALSE);
+    ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
+
+    CHECK_CALLED(SetActiveObject_null);
+    CHECK_CALLED(InPlaceUIWindow_SetActiveObject);
+    CHECK_CALLED(HideUI);
+    CHECK_CALLED(OnUIDeactivate);
+
+    hres = IOleDocumentView_GetInPlaceSite(view, &inplacesite);
+    ok(hres == S_OK, "GetInPlaceSite failed: %08x\n", hres);
+    ok(inplacesite != NULL, "inplacesite = NULL\n");
+    IOleInPlaceSite_Release(inplacesite);
+
+    SET_EXPECT(OnFocus_FALSE);
+    if(use_ipsex)
+        SET_EXPECT(OnInPlaceDeactivateEx);
+    else
+        SET_EXPECT(OnInPlaceDeactivate);
+
+    test_CloseView();
+
+    CHECK_CALLED(OnFocus_FALSE);
+    if(use_ipsex)
+        CHECK_CALLED(OnInPlaceDeactivateEx);
+    else
+        CHECK_CALLED(OnInPlaceDeactivate);
 
 
-    RegCloseKey(hkey);
+    test_Close(unk, TRUE);
+
+    IOleObject_Release(oleobj);
+    IOleDocumentView_Release(view);
+    view = NULL;
+
+    ref = IUnknown_Release(unk);
+    ok(ref == 0, "ref=%d, expected 0\n", ref);
+}
+
+static void register_protocol(void)
+{
+    IInternetSession *session;
+    HRESULT hres;
+
+    static const WCHAR wsz_winetest[] = {'w','i','n','e','t','e','s','t',0};
+
+    hres = CoInternetGetSession(0, &session, 0);
+    ok(hres == S_OK, "CoInternetGetSession failed: %08x\n", hres);
+
+    hres = IInternetSession_RegisterNameSpace(session, &ClassFactory, &IID_NULL,
+            wsz_winetest, 0, NULL, 0);
+    ok(hres == S_OK, "RegisterNameSpace failed: %08x\n", hres);
+
+    IInternetSession_Release(session);
 }
 
 static void test_HTMLDoc_ISupportErrorInfo(void)
 }
 
 static void test_HTMLDoc_ISupportErrorInfo(void)
@@ -4322,8 +4967,6 @@ static void test_IPersistHistory(void)
 
 START_TEST(htmldoc)
 {
 
 START_TEST(htmldoc)
 {
-    gecko_installer_workaround(TRUE);
-
     CoInitialize(NULL);
     container_hwnd = create_container_window();
     register_protocol();
     CoInitialize(NULL);
     container_hwnd = create_container_window();
     register_protocol();
@@ -4333,15 +4976,20 @@ START_TEST(htmldoc)
         test_HTMLDocument(FALSE);
         test_HTMLDocument(TRUE);
         test_HTMLDocument_StreamLoad();
         test_HTMLDocument(FALSE);
         test_HTMLDocument(TRUE);
         test_HTMLDocument_StreamLoad();
+        test_HTMLDocument_StreamInitNew();
         test_editing_mode(FALSE);
         test_editing_mode(TRUE);
         test_HTMLDocument_http();
         test_editing_mode(FALSE);
         test_editing_mode(TRUE);
         test_HTMLDocument_http();
+        test_UIActivate(FALSE, FALSE, FALSE);
+        test_UIActivate(FALSE, TRUE, FALSE);
+        test_UIActivate(FALSE, TRUE, TRUE);
+        test_UIActivate(TRUE, FALSE, FALSE);
+        test_UIActivate(TRUE, TRUE, FALSE);
+        test_UIActivate(TRUE, TRUE, TRUE);
     }
     test_HTMLDoc_ISupportErrorInfo();
     test_IPersistHistory();
 
     DestroyWindow(container_hwnd);
     CoUninitialize();
     }
     test_HTMLDoc_ISupportErrorInfo();
     test_IPersistHistory();
 
     DestroyWindow(container_hwnd);
     CoUninitialize();
-
-    gecko_installer_workaround(FALSE);
 }
 }
diff --git a/rostests/winetests/mshtml/htmllocation.c b/rostests/winetests/mshtml/htmllocation.c
new file mode 100644 (file)
index 0000000..60a1f20
--- /dev/null
@@ -0,0 +1,368 @@
+/*
+ * Copyright 2009 Andrew Eikum 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
+ */
+
+#define COBJMACROS
+#define CONST_VTABLE
+
+#include <wine/test.h>
+
+#include "mshtml.h"
+
+struct location_test {
+    const char *name;
+    const WCHAR *url;
+
+    const char *href;
+    const char *protocol;
+    const char *host;
+    const char *hostname;
+    const char *port;
+    const char *pathname;
+    const char *search;
+    const char *hash;
+};
+
+static const WCHAR http_url[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','?','s','e','a','r','c','h','#','h','a','s','h',0};
+static const struct location_test http_test = {
+            "HTTP",
+            http_url,
+            "http://www.winehq.org/?search#hash",
+            "http:",
+            "www.winehq.org:80",
+            "www.winehq.org",
+            "80",
+            "",
+            "?search",
+            "#hash"
+            };
+
+static const WCHAR http_file_url[] = {'h','t','t','p',':','/','/','w','w','w','.','w','i','n','e','h','q','.','o','r','g','/','f','i','l','e','?','s','e','a','r','c','h','#','h','a','s','h',0};
+static const struct location_test http_file_test = {
+            "HTTP with file",
+            http_file_url,
+            "http://www.winehq.org/file?search#hash",
+            "http:",
+            "www.winehq.org:80",
+            "www.winehq.org",
+            "80",
+            "file",
+            "?search",
+            "#hash"
+            };
+
+static const WCHAR ftp_url[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g','/',0};
+static const struct location_test ftp_test = {
+            "FTP",
+            ftp_url,
+            "ftp://ftp.winehq.org/",
+            "ftp:",
+            "ftp.winehq.org:21",
+            "ftp.winehq.org",
+            "21",
+            "",
+            NULL,
+            NULL
+            };
+
+static const WCHAR ftp_file_url[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g','/','f','i','l','e',0};
+static const struct location_test ftp_file_test = {
+            "FTP with file",
+            ftp_file_url,
+            "ftp://ftp.winehq.org/file",
+            "ftp:",
+            "ftp.winehq.org:21",
+            "ftp.winehq.org",
+            "21",
+            "file",
+            NULL,
+            NULL
+            };
+
+static const WCHAR file_url[] = {'f','i','l','e',':','/','/','C',':','\\','w','i','n','d','o','w','s','\\','w','i','n','.','i','n','i',0};
+static const struct location_test file_test = {
+            "FILE",
+            file_url,
+            "file:///C:/windows/win.ini",
+            "file:",
+            NULL,
+            NULL,
+            "",
+            "C:\\windows\\win.ini",
+            NULL,
+            NULL
+            };
+
+static int str_eq_wa(LPCWSTR strw, const char *stra)
+{
+    CHAR buf[512];
+
+    if(strw == NULL || stra == NULL){
+        if((void*)strw == (void*)stra)
+            return 1;
+        return 0;
+    }
+
+    WideCharToMultiByte(CP_ACP, 0, strw, -1, buf, sizeof(buf), NULL, NULL);
+    return !lstrcmpA(stra, buf);
+}
+
+static void test_href(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_href(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_href should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_href(loc, &str);
+    ok(hres == S_OK, "%s: get_href failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->href),
+                "%s: expected retrieved href to be L\"%s\", was: %s\n",
+                test->name, test->href, wine_dbgstr_w(str));
+}
+
+static void test_protocol(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_protocol(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_protocol should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_protocol(loc, &str);
+    ok(hres == S_OK, "%s: get_protocol failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->protocol),
+                "%s: expected retrieved protocol to be L\"%s\", was: %s\n",
+                test->name, test->protocol, wine_dbgstr_w(str));
+}
+
+static void test_host(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_host(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_host should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_host(loc, &str);
+    ok(hres == S_OK, "%s: get_host failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->host),
+                "%s: expected retrieved host to be L\"%s\", was: %s\n",
+                test->name, test->host, wine_dbgstr_w(str));
+}
+
+static void test_hostname(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_hostname(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_hostname should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_hostname(loc, &str);
+    ok(hres == S_OK, "%s: get_hostname failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->hostname),
+                "%s: expected retrieved hostname to be L\"%s\", was: %s\n",
+                test->name, test->hostname, wine_dbgstr_w(str));
+}
+
+static void test_port(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_port(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_port should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_port(loc, &str);
+    ok(hres == S_OK, "%s: get_port failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->port),
+                "%s: expected retrieved port to be L\"%s\", was: %s\n",
+                test->name, test->port, wine_dbgstr_w(str));
+}
+
+static void test_pathname(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_pathname(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_pathname should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_pathname(loc, &str);
+    ok(hres == S_OK, "%s: get_pathname failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->pathname),
+                "%s: expected retrieved pathname to be L\"%s\", was: %s\n",
+                test->name, test->pathname, wine_dbgstr_w(str));
+}
+
+static void test_search(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_search(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_search should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_search(loc, &str);
+    ok(hres == S_OK, "%s: get_search failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->search),
+                "%s: expected retrieved search to be L\"%s\", was: %s\n",
+                test->name, test->search, wine_dbgstr_w(str));
+}
+
+static void test_hash(IHTMLLocation *loc, const struct location_test *test)
+{
+    HRESULT hres;
+    BSTR str;
+
+    hres = IHTMLLocation_get_hash(loc, NULL);
+    ok(hres == E_POINTER,
+            "%s: get_hash should have failed with E_POINTER (0x%08x), was: 0x%08x\n",
+            test->name, E_POINTER, hres);
+
+    hres = IHTMLLocation_get_hash(loc, &str);
+    ok(hres == S_OK, "%s: get_hash failed: 0x%08x\n", test->name, hres);
+    if(hres == S_OK)
+        ok(str_eq_wa(str, test->hash),
+                "%s: expected retrieved hash to be L\"%s\", was: %s\n",
+                test->name, test->hash, wine_dbgstr_w(str));
+}
+
+static void perform_test(const struct location_test* test)
+{
+    HRESULT hres;
+    IBindCtx *bc;
+    IMoniker *url_mon;
+    IPersistMoniker *persist_mon;
+    IHTMLDocument2 *doc;
+    IHTMLDocument6 *doc6;
+    IHTMLLocation *location;
+
+    hres = CreateBindCtx(0, &bc);
+    ok(hres == S_OK, "%s: CreateBindCtx failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres))
+        return;
+
+    hres = CreateURLMoniker(NULL, test->url, &url_mon);
+    ok(hres == S_OK, "%s: CreateURLMoniker failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres)){
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    hres = CoCreateInstance(&CLSID_HTMLDocument, NULL,
+            CLSCTX_INPROC_SERVER | CLSCTX_INPROC_HANDLER, &IID_IHTMLDocument2,
+            (void**)&doc);
+    ok(hres == S_OK, "%s: CoCreateInstance failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres)){
+        IMoniker_Release(url_mon);
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IHTMLDocument6, (void**)&doc6);
+    if(hres == S_OK){
+        IHTMLDocument6_Release(doc6);
+    }else{
+        win_skip("%s: Could not get IHTMLDocument6, probably too old IE. Requires IE 8+\n", test->name);
+        IMoniker_Release(url_mon);
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker,
+            (void**)&persist_mon);
+    ok(hres == S_OK, "%s: IHTMlDocument2_QueryInterface failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres)){
+        IHTMLDocument2_Release(doc);
+        IMoniker_Release(url_mon);
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    hres = IPersistMoniker_Load(persist_mon, FALSE, url_mon, bc,
+            STGM_SHARE_EXCLUSIVE | STGM_READWRITE);
+    ok(hres == S_OK, "%s: IPersistMoniker_Load failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres)){
+        IPersistMoniker_Release(persist_mon);
+        IHTMLDocument2_Release(doc);
+        IMoniker_Release(url_mon);
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    hres = IHTMLDocument2_get_location(doc, &location);
+    ok(hres == S_OK, "%s: IHTMLDocument2_get_location failed: 0x%08x\n", test->name, hres);
+    if(FAILED(hres)){
+        IPersistMoniker_Release(persist_mon);
+        IHTMLDocument2_Release(doc);
+        IMoniker_Release(url_mon);
+        IBindCtx_Release(bc);
+        return;
+    }
+
+    test_href(location, test);
+    test_protocol(location, test);
+    test_host(location, test);
+    test_hostname(location, test);
+    test_port(location, test);
+    test_pathname(location, test);
+    test_search(location, test);
+    test_hash(location, test);
+
+    IHTMLLocation_Release(location);
+    IPersistMoniker_Release(persist_mon);
+    IHTMLDocument2_Release(doc);
+    IMoniker_Release(url_mon);
+    IBindCtx_Release(bc);
+}
+
+START_TEST(htmllocation)
+{
+    CoInitialize(NULL);
+
+    perform_test(&http_test);
+    perform_test(&http_file_test);
+    perform_test(&ftp_test);
+    perform_test(&ftp_file_test);
+    perform_test(&file_test);
+
+    CoUninitialize();
+}
diff --git a/rostests/winetests/mshtml/jstest.html b/rostests/winetests/mshtml/jstest.html
new file mode 100644 (file)
index 0000000..72ef427
--- /dev/null
@@ -0,0 +1,20 @@
+<html>
+<head>
+<script>
+function ok(b,m) {
+    return external.ok(b, m);
+}
+
+function runTest() {
+    obj = new Object();
+    ok(obj === window.obj, "obj !== window.obj");
+
+    ok(typeof(divid) === "object", "typeof(divid) = " + typeof(divid));
+
+    external.reportSuccess();
+}
+</script>
+<body onload="runTest();">
+<div id="divid"></div>
+</body>
+</html>
index 280dced..90696e4 100644 (file)
@@ -7,16 +7,20 @@
        <file>dom.c</file>
        <file>events.c</file>
        <file>htmldoc.c</file>
        <file>dom.c</file>
        <file>events.c</file>
        <file>htmldoc.c</file>
+       <file>htmllocation.c</file>
        <file>misc.c</file>
        <file>protocol.c</file>
        <file>script.c</file>
        <file>testlist.c</file>
        <file>misc.c</file>
        <file>protocol.c</file>
        <file>script.c</file>
        <file>testlist.c</file>
+       <file>rsrc.rc</file>
        <library>wine</library>
        <library>uuid</library>
        <library>strmiids</library>
        <library>wine</library>
        <library>uuid</library>
        <library>strmiids</library>
+       <library>wininet</library>
        <library>ole32</library>
        <library>oleaut32</library>
        <library>user32</library>
        <library>ole32</library>
        <library>oleaut32</library>
        <library>user32</library>
+       <library>gdi32</library>
        <library>urlmon</library>
        <library>advapi32</library>
        <library>ntdll</library>
        <library>urlmon</library>
        <library>advapi32</library>
        <library>ntdll</library>
diff --git a/rostests/winetests/mshtml/rsrc.rc b/rostests/winetests/mshtml/rsrc.rc
new file mode 100644 (file)
index 0000000..70925ca
--- /dev/null
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2009 Jacek Caban
+ *
+ * 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
+ */
+
+/* @makedep: jstest.html */
+jstest.html HTML "jstest.html"
index 5f59ea4..fae49c8 100644 (file)
 #include "windef.h"
 #include "winbase.h"
 #include "ole2.h"
 #include "windef.h"
 #include "winbase.h"
 #include "ole2.h"
+#include "wininet.h"
+#include "docobj.h"
 #include "dispex.h"
 #include "dispex.h"
+#include "hlink.h"
 #include "mshtml.h"
 #include "mshtml.h"
+#include "mshtmhst.h"
 #include "initguid.h"
 #include "activscp.h"
 #include "activdbg.h"
 #include "initguid.h"
 #include "activscp.h"
 #include "activdbg.h"
@@ -112,16 +116,25 @@ DEFINE_EXPECT(AddNamedItem);
 DEFINE_EXPECT(ParseScriptText);
 DEFINE_EXPECT(GetScriptDispatch);
 DEFINE_EXPECT(funcDisp);
 DEFINE_EXPECT(ParseScriptText);
 DEFINE_EXPECT(GetScriptDispatch);
 DEFINE_EXPECT(funcDisp);
+DEFINE_EXPECT(script_divid_d);
 DEFINE_EXPECT(script_testprop_d);
 DEFINE_EXPECT(script_testprop_i);
 DEFINE_EXPECT(script_testprop_d);
 DEFINE_EXPECT(script_testprop_i);
+DEFINE_EXPECT(script_testprop2_d);
 DEFINE_EXPECT(AXQueryInterface_IActiveScript);
 DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
 DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
 DEFINE_EXPECT(AXSetInterfaceSafetyOptions);
 DEFINE_EXPECT(AXQueryInterface_IActiveScript);
 DEFINE_EXPECT(AXQueryInterface_IObjectSafety);
 DEFINE_EXPECT(AXGetInterfaceSafetyOptions);
 DEFINE_EXPECT(AXSetInterfaceSafetyOptions);
+DEFINE_EXPECT(external_success);
 
 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
 
 #define TESTSCRIPT_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80746}"
+#define TESTACTIVEX_CLSID "{178fc163-f585-4e24-9c13-4bb7faf80646}"
 
 #define DISPID_SCRIPT_TESTPROP   0x100000
 
 #define DISPID_SCRIPT_TESTPROP   0x100000
+#define DISPID_SCRIPT_TESTPROP2  0x100001
+
+#define DISPID_EXTERNAL_OK             0x300000
+#define DISPID_EXTERNAL_TRACE          0x300001
+#define DISPID_EXTERNAL_REPORTSUCCESS  0x300002
 
 static const GUID CLSID_TestScript =
     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
 
 static const GUID CLSID_TestScript =
     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x07,0x46}};
@@ -129,9 +142,12 @@ static const GUID CLSID_TestActiveX =
     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
 
 static IHTMLDocument2 *notif_doc;
     {0x178fc163,0xf585,0x4e24,{0x9c,0x13,0x4b,0xb7,0xfa,0xf8,0x06,0x46}};
 
 static IHTMLDocument2 *notif_doc;
+static IOleDocumentView *view;
 static IDispatchEx *window_dispex;
 static BOOL doc_complete;
 static IDispatch *script_disp;
 static IDispatchEx *window_dispex;
 static BOOL doc_complete;
 static IDispatch *script_disp;
+static BOOL ax_objsafe;
+static HWND container_hwnd;
 
 static const char *debugstr_guid(REFIID riid)
 {
 
 static const char *debugstr_guid(REFIID riid)
 {
@@ -164,6 +180,28 @@ static BSTR a2bstr(const char *str)
     return ret;
 }
 
     return ret;
 }
 
+static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
+{
+    HKEY hkey;
+    DWORD res;
+
+    if(!init) {
+        RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
+        return TRUE;
+    }
+
+    res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
+    if(res != ERROR_SUCCESS)
+        return FALSE;
+
+    if(def_value)
+        res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
+
+    RegCloseKey(hkey);
+
+    return res == ERROR_SUCCESS;
+}
+
 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
         REFIID riid, void**ppv)
 {
 static HRESULT WINAPI PropertyNotifySink_QueryInterface(IPropertyNotifySink *iface,
         REFIID riid, void**ppv)
 {
@@ -298,128 +336,716 @@ static HRESULT WINAPI DispatchEx_GetMemberName(IDispatchEx *iface, DISPID id, BS
     return E_NOTIMPL;
 }
 
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+static HRESULT WINAPI DispatchEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    CHECK_EXPECT(funcDisp);
+
+    ok(id == DISPID_VALUE, "id = %d\n", id);
+    ok(lcid == 0, "lcid = %x\n", lcid);
+    ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
+    ok(pdp != NULL, "pdp == NULL\n");
+    ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
+    ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
+    ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
+    ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
+    ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
+    ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
+    ok(pvarRes != NULL, "pvarRes == NULL\n");
+    ok(pei != NULL, "pei == NULL\n");
+    ok(!pspCaller, "pspCaller != NULL\n");
+
+    V_VT(pvarRes) = VT_I4;
+    V_I4(pvarRes) = 100;
+    return S_OK;
+}
+
+static IDispatchExVtbl testObjVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    DispatchEx_GetDispID,
+    funcDisp_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx funcDisp = { &testObjVtbl };
+
+static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    if(!strcmp_wa(bstrName, "testProp")) {
+        CHECK_EXPECT(script_testprop_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_SCRIPT_TESTPROP;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "testProp2")) {
+        CHECK_EXPECT(script_testprop2_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        *pid = DISPID_SCRIPT_TESTPROP2;
+        return S_OK;
+    }
+
+    if(!strcmp_wa(bstrName, "divid")) {
+        CHECK_EXPECT(script_divid_d);
+        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
+        return E_FAIL;
+    }
+
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    switch(id) {
+    case DISPID_SCRIPT_TESTPROP:
+        CHECK_EXPECT(script_testprop_i);
+
+        ok(lcid == 0, "lcid = %x\n", lcid);
+        ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs);
+        ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n");
+        ok(!pdp->rgvarg, "rgvarg != NULL\n");
+        ok(pvarRes != NULL, "pvarRes == NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+        ok(!pspCaller, "pspCaller != NULL\n");
+
+        V_VT(pvarRes) = VT_NULL;
+        break;
+    default:
+        ok(0, "unexpected call\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static IDispatchExVtbl scriptDispVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    scriptDisp_GetDispID,
+    scriptDisp_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx scriptDisp = { &scriptDispVtbl };
+
+static HRESULT WINAPI externalDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+{
+    if(!strcmp_wa(bstrName, "ok")) {
+        *pid = DISPID_EXTERNAL_OK;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "trace")) {
+        *pid = DISPID_EXTERNAL_TRACE;
+        return S_OK;
+    }
+    if(!strcmp_wa(bstrName, "reportSuccess")) {
+        *pid = DISPID_EXTERNAL_REPORTSUCCESS;
+        return S_OK;
+    }
+
+    ok(0, "unexpected name %s\n", wine_dbgstr_w(bstrName));
+    return DISP_E_UNKNOWNNAME;
+}
+
+static HRESULT WINAPI externalDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
+        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+{
+    switch(id) {
+    case DISPID_EXTERNAL_OK:
+        ok(wFlags == INVOKE_FUNC || wFlags == (INVOKE_FUNC|INVOKE_PROPERTYGET), "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 2, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(psp->rgvargs+1) = %d\n", V_VT(pdp->rgvarg));
+        ok(V_BOOL(pdp->rgvarg+1), "%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
+
+        return S_OK;
+
+     case DISPID_EXTERNAL_TRACE:
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(pdp->rgvarg != NULL, "rgvarg == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 1, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        ok(V_VT(pdp->rgvarg) == VT_BSTR, "V_VT(psp->rgvargs) = %d\n", V_VT(pdp->rgvarg));
+        if(V_VT(pdp->rgvarg) == VT_BSTR)
+            trace("%s\n", wine_dbgstr_w(V_BSTR(pdp->rgvarg)));
+
+        return S_OK;
+
+    case DISPID_EXTERNAL_REPORTSUCCESS:
+        CHECK_EXPECT(external_success);
+
+        ok(wFlags == INVOKE_FUNC, "wFlags = %x\n", wFlags);
+        ok(pdp != NULL, "pdp == NULL\n");
+        ok(!pdp->rgdispidNamedArgs, "rgdispidNamedArgs != NULL\n");
+        ok(pdp->cArgs == 0, "cArgs = %d\n", pdp->cArgs);
+        ok(!pdp->cNamedArgs, "cNamedArgs = %d\n", pdp->cNamedArgs);
+        ok(!pvarRes, "pvarRes != NULL\n");
+        ok(pei != NULL, "pei == NULL\n");
+
+        return S_OK;
+
+    default:
+        ok(0, "unexpected call\n");
+        return E_NOTIMPL;
+    }
+
+    return S_OK;
+}
+
+static IDispatchExVtbl externalDispVtbl = {
+    DispatchEx_QueryInterface,
+    DispatchEx_AddRef,
+    DispatchEx_Release,
+    DispatchEx_GetTypeInfoCount,
+    DispatchEx_GetTypeInfo,
+    DispatchEx_GetIDsOfNames,
+    DispatchEx_Invoke,
+    externalDisp_GetDispID,
+    externalDisp_InvokeEx,
+    DispatchEx_DeleteMemberByName,
+    DispatchEx_DeleteMemberByDispID,
+    DispatchEx_GetMemberProperties,
+    DispatchEx_GetMemberName,
+    DispatchEx_GetNextDispID,
+    DispatchEx_GetNameSpaceParent
+};
+
+static IDispatchEx externalDisp = { &externalDispVtbl };
+
+static HRESULT QueryInterface(REFIID,void**);
+
+static HRESULT WINAPI DocHostUIHandler_QueryInterface(IDocHostUIHandler2 *iface, REFIID riid, void **ppv)
+{
+    return QueryInterface(riid, ppv);
+}
+
+static ULONG WINAPI DocHostUIHandler_AddRef(IDocHostUIHandler2 *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI DocHostUIHandler_Release(IDocHostUIHandler2 *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI DocHostUIHandler_ShowContextMenu(IDocHostUIHandler2 *iface, DWORD dwID, POINT *ppt,
+        IUnknown *pcmdtReserved, IDispatch *pdicpReserved)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_GetHostInfo(IDocHostUIHandler2 *iface, DOCHOSTUIINFO *pInfo)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_ShowUI(IDocHostUIHandler2 *iface, DWORD dwID,
+        IOleInPlaceActiveObject *pActiveObject, IOleCommandTarget *pCommandTarget,
+        IOleInPlaceFrame *pFrame, IOleInPlaceUIWindow *pDoc)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_HideUI(IDocHostUIHandler2 *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_UpdateUI(IDocHostUIHandler2 *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_EnableModeless(IDocHostUIHandler2 *iface, BOOL fEnable)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_OnDocWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_OnFrameWindowActivate(IDocHostUIHandler2 *iface, BOOL fActivate)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_ResizeBorder(IDocHostUIHandler2 *iface, LPCRECT prcBorder,
+        IOleInPlaceUIWindow *pUIWindow, BOOL fRameWindow)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_TranslateAccelerator(IDocHostUIHandler2 *iface, LPMSG lpMsg,
+        const GUID *pguidCmdGroup, DWORD nCmdID)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_GetOptionKeyPath(IDocHostUIHandler2 *iface,
+        LPOLESTR *pchKey, DWORD dw)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_GetDropTarget(IDocHostUIHandler2 *iface,
+        IDropTarget *pDropTarget, IDropTarget **ppDropTarget)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_GetExternal(IDocHostUIHandler2 *iface, IDispatch **ppDispatch)
+{
+    *ppDispatch = (IDispatch*)&externalDisp;
+    return S_OK;
+}
+
+static HRESULT WINAPI DocHostUIHandler_TranslateUrl(IDocHostUIHandler2 *iface, DWORD dwTranslate,
+        OLECHAR *pchURLIn, OLECHAR **ppchURLOut)
+{
+    return S_FALSE;
+}
+
+static HRESULT WINAPI DocHostUIHandler_FilterDataObject(IDocHostUIHandler2 *iface, IDataObject *pDO,
+        IDataObject **ppPORet)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI DocHostUIHandler_GetOverrideKeyPath(IDocHostUIHandler2 *iface,
+        LPOLESTR *pchKey, DWORD dw)
+{
+    return E_NOTIMPL;
+}
+
+static const IDocHostUIHandler2Vtbl DocHostUIHandlerVtbl = {
+    DocHostUIHandler_QueryInterface,
+    DocHostUIHandler_AddRef,
+    DocHostUIHandler_Release,
+    DocHostUIHandler_ShowContextMenu,
+    DocHostUIHandler_GetHostInfo,
+    DocHostUIHandler_ShowUI,
+    DocHostUIHandler_HideUI,
+    DocHostUIHandler_UpdateUI,
+    DocHostUIHandler_EnableModeless,
+    DocHostUIHandler_OnDocWindowActivate,
+    DocHostUIHandler_OnFrameWindowActivate,
+    DocHostUIHandler_ResizeBorder,
+    DocHostUIHandler_TranslateAccelerator,
+    DocHostUIHandler_GetOptionKeyPath,
+    DocHostUIHandler_GetDropTarget,
+    DocHostUIHandler_GetExternal,
+    DocHostUIHandler_TranslateUrl,
+    DocHostUIHandler_FilterDataObject,
+    DocHostUIHandler_GetOverrideKeyPath
+};
+
+static IDocHostUIHandler2 DocHostUIHandler = { &DocHostUIHandlerVtbl };
+
+static HRESULT WINAPI InPlaceFrame_QueryInterface(IOleInPlaceFrame *iface, REFIID riid, void **ppv)
+{
+    return E_NOINTERFACE;
+}
+
+static ULONG WINAPI InPlaceFrame_AddRef(IOleInPlaceFrame *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI InPlaceFrame_Release(IOleInPlaceFrame *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI InPlaceFrame_GetWindow(IOleInPlaceFrame *iface, HWND *phwnd)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_ContextSensitiveHelp(IOleInPlaceFrame *iface, BOOL fEnterMode)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_GetBorder(IOleInPlaceFrame *iface, LPRECT lprectBorder)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_RequestBorderSpace(IOleInPlaceFrame *iface,
+        LPCBORDERWIDTHS pborderwidths)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_SetBorderSpace(IOleInPlaceFrame *iface,
+        LPCBORDERWIDTHS pborderwidths)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceFrame_SetActiveObject(IOleInPlaceFrame *iface,
+        IOleInPlaceActiveObject *pActiveObject, LPCOLESTR pszObjName)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceFrame_InsertMenus(IOleInPlaceFrame *iface, HMENU hmenuShared,
+        LPOLEMENUGROUPWIDTHS lpMenuWidths)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_SetMenu(IOleInPlaceFrame *iface, HMENU hmenuShared,
+        HOLEMENU holemenu, HWND hwndActiveObject)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_RemoveMenus(IOleInPlaceFrame *iface, HMENU hmenuShared)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_SetStatusText(IOleInPlaceFrame *iface, LPCOLESTR pszStatusText)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceFrame_EnableModeless(IOleInPlaceFrame *iface, BOOL fEnable)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceFrame_TranslateAccelerator(IOleInPlaceFrame *iface, LPMSG lpmsg, WORD wID)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static const IOleInPlaceFrameVtbl InPlaceFrameVtbl = {
+    InPlaceFrame_QueryInterface,
+    InPlaceFrame_AddRef,
+    InPlaceFrame_Release,
+    InPlaceFrame_GetWindow,
+    InPlaceFrame_ContextSensitiveHelp,
+    InPlaceFrame_GetBorder,
+    InPlaceFrame_RequestBorderSpace,
+    InPlaceFrame_SetBorderSpace,
+    InPlaceFrame_SetActiveObject,
+    InPlaceFrame_InsertMenus,
+    InPlaceFrame_SetMenu,
+    InPlaceFrame_RemoveMenus,
+    InPlaceFrame_SetStatusText,
+    InPlaceFrame_EnableModeless,
+    InPlaceFrame_TranslateAccelerator
+};
+
+static IOleInPlaceFrame InPlaceFrame = { &InPlaceFrameVtbl };
+
+static HRESULT WINAPI InPlaceSite_QueryInterface(IOleInPlaceSite *iface, REFIID riid, void **ppv)
+{
+    return QueryInterface(riid, ppv);
+}
+
+static ULONG WINAPI InPlaceSite_AddRef(IOleInPlaceSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI InPlaceSite_Release(IOleInPlaceSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI InPlaceSite_GetWindow(IOleInPlaceSite *iface, HWND *phwnd)
+{
+    *phwnd = container_hwnd;
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_ContextSensitiveHelp(IOleInPlaceSite *iface, BOOL fEnterMode)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSite_CanInPlaceActivate(IOleInPlaceSite *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_OnInPlaceActivate(IOleInPlaceSite *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_OnUIActivate(IOleInPlaceSite *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_GetWindowContext(IOleInPlaceSite *iface,
+        IOleInPlaceFrame **ppFrame, IOleInPlaceUIWindow **ppDoc, LPRECT lprcPosRect,
+        LPRECT lprcClipRect, LPOLEINPLACEFRAMEINFO lpFrameInfo)
+{
+    static const RECT rect = {0,0,300,300};
+
+    *ppFrame = &InPlaceFrame;
+    *ppDoc = (IOleInPlaceUIWindow*)&InPlaceFrame;
+    *lprcPosRect = rect;
+    *lprcClipRect = rect;
+
+    lpFrameInfo->cb = sizeof(*lpFrameInfo);
+    lpFrameInfo->fMDIApp = FALSE;
+    lpFrameInfo->hwndFrame = container_hwnd;
+    lpFrameInfo->haccel = NULL;
+    lpFrameInfo->cAccelEntries = 0;
+
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_Scroll(IOleInPlaceSite *iface, SIZE scrollExtant)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSite_OnUIDeactivate(IOleInPlaceSite *iface, BOOL fUndoable)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_OnInPlaceDeactivate(IOleInPlaceSite *iface)
+{
+    return S_OK;
+}
+
+static HRESULT WINAPI InPlaceSite_DiscardUndoState(IOleInPlaceSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSite_DeactivateAndUndo(IOleInPlaceSite *iface)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI InPlaceSite_OnPosRectChange(IOleInPlaceSite *iface, LPCRECT lprcPosRect)
+{
+    return E_NOTIMPL;
+}
+
+static const IOleInPlaceSiteVtbl InPlaceSiteVtbl = {
+    InPlaceSite_QueryInterface,
+    InPlaceSite_AddRef,
+    InPlaceSite_Release,
+    InPlaceSite_GetWindow,
+    InPlaceSite_ContextSensitiveHelp,
+    InPlaceSite_CanInPlaceActivate,
+    InPlaceSite_OnInPlaceActivate,
+    InPlaceSite_OnUIActivate,
+    InPlaceSite_GetWindowContext,
+    InPlaceSite_Scroll,
+    InPlaceSite_OnUIDeactivate,
+    InPlaceSite_OnInPlaceDeactivate,
+    InPlaceSite_DiscardUndoState,
+    InPlaceSite_DeactivateAndUndo,
+    InPlaceSite_OnPosRectChange,
+};
+
+static IOleInPlaceSite InPlaceSite = { &InPlaceSiteVtbl };
+
+static HRESULT WINAPI ClientSite_QueryInterface(IOleClientSite *iface, REFIID riid, void **ppv)
+{
+    return QueryInterface(riid, ppv);
+}
+
+static ULONG WINAPI ClientSite_AddRef(IOleClientSite *iface)
+{
+    return 2;
+}
+
+static ULONG WINAPI ClientSite_Release(IOleClientSite *iface)
+{
+    return 1;
+}
+
+static HRESULT WINAPI ClientSite_SaveObject(IOleClientSite *iface)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ClientSite_GetMoniker(IOleClientSite *iface, DWORD dwAssign, DWORD dwWhichMoniker,
+        IMoniker **ppmon)
+{
+    ok(0, "unexpected call\n");
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ClientSite_GetContainer(IOleClientSite *iface, IOleContainer **ppContainer)
+{
+    return E_NOTIMPL;
+}
+
+static HRESULT WINAPI ClientSite_ShowObject(IOleClientSite *iface)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI DispatchEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
+static HRESULT WINAPI ClientSite_OnShowWindow(IOleClientSite *iface, BOOL fShow)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI DispatchEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+static HRESULT WINAPI ClientSite_RequestNewObjectLayout(IOleClientSite *iface)
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
 {
     ok(0, "unexpected call\n");
     return E_NOTIMPL;
 }
 
-static HRESULT WINAPI funcDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
-        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
-{
-    CHECK_EXPECT(funcDisp);
+static const IOleClientSiteVtbl ClientSiteVtbl = {
+    ClientSite_QueryInterface,
+    ClientSite_AddRef,
+    ClientSite_Release,
+    ClientSite_SaveObject,
+    ClientSite_GetMoniker,
+    ClientSite_GetContainer,
+    ClientSite_ShowObject,
+    ClientSite_OnShowWindow,
+    ClientSite_RequestNewObjectLayout
+};
 
 
-    ok(id == DISPID_VALUE, "id = %d\n", id);
-    ok(lcid == 0, "lcid = %x\n", lcid);
-    ok(wFlags == DISPATCH_METHOD, "wFlags = %x\n", wFlags);
-    ok(pdp != NULL, "pdp == NULL\n");
-    ok(pdp->cArgs == 2, "pdp->cArgs = %d\n", pdp->cArgs);
-    ok(pdp->cNamedArgs == 1, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
-    ok(pdp->rgdispidNamedArgs[0] == DISPID_THIS, "pdp->rgdispidNamedArgs[0] = %d\n", pdp->rgdispidNamedArgs[0]);
-    ok(V_VT(pdp->rgvarg) == VT_DISPATCH, "V_VT(rgvarg) = %d\n", V_VT(pdp->rgvarg));
-    ok(V_VT(pdp->rgvarg+1) == VT_BOOL, "V_VT(rgvarg[1]) = %d\n", V_VT(pdp->rgvarg));
-    ok(V_BOOL(pdp->rgvarg+1) == VARIANT_TRUE, "V_BOOL(rgvarg[1]) = %x\n", V_BOOL(pdp->rgvarg));
-    ok(pvarRes != NULL, "pvarRes == NULL\n");
-    ok(pei != NULL, "pei == NULL\n");
-    ok(!pspCaller, "pspCaller != NULL\n");
+static IOleClientSite ClientSite = { &ClientSiteVtbl };
 
 
-    V_VT(pvarRes) = VT_I4;
-    V_I4(pvarRes) = 100;
-    return S_OK;
+static HRESULT WINAPI DocumentSite_QueryInterface(IOleDocumentSite *iface, REFIID riid, void **ppv)
+{
+    return QueryInterface(riid, ppv);
 }
 
 }
 
-static IDispatchExVtbl testObjVtbl = {
-    DispatchEx_QueryInterface,
-    DispatchEx_AddRef,
-    DispatchEx_Release,
-    DispatchEx_GetTypeInfoCount,
-    DispatchEx_GetTypeInfo,
-    DispatchEx_GetIDsOfNames,
-    DispatchEx_Invoke,
-    DispatchEx_GetDispID,
-    funcDisp_InvokeEx,
-    DispatchEx_DeleteMemberByName,
-    DispatchEx_DeleteMemberByDispID,
-    DispatchEx_GetMemberProperties,
-    DispatchEx_GetMemberName,
-    DispatchEx_GetNextDispID,
-    DispatchEx_GetNameSpaceParent
-};
-
-static IDispatchEx funcDisp = { &testObjVtbl };
-
-static HRESULT WINAPI scriptDisp_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
+static ULONG WINAPI DocumentSite_AddRef(IOleDocumentSite *iface)
 {
 {
-    if(!strcmp_wa(bstrName, "testProp")) {
-        CHECK_EXPECT(script_testprop_d);
-        ok(grfdex == fdexNameCaseSensitive, "grfdex = %x\n", grfdex);
-        *pid = DISPID_SCRIPT_TESTPROP;
-        return S_OK;
-    }
+    return 2;
+}
 
 
-    ok(0, "unexpected call\n");
-    return E_NOTIMPL;
+static ULONG WINAPI DocumentSite_Release(IOleDocumentSite *iface)
+{
+    return 1;
 }
 
 }
 
-static HRESULT WINAPI scriptDisp_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
-        VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
+static HRESULT WINAPI DocumentSite_ActivateMe(IOleDocumentSite *iface, IOleDocumentView *pViewToActivate)
 {
 {
-    switch(id) {
-    case DISPID_SCRIPT_TESTPROP:
-        CHECK_EXPECT(script_testprop_i);
+    RECT rect = {0,0,300,300};
+    IOleDocument *document;
+    HRESULT hres;
 
 
-        ok(lcid == 0, "lcid = %x\n", lcid);
-        ok(wFlags == DISPATCH_PROPERTYGET, "wFlags = %x\n", wFlags);
-        ok(pdp != NULL, "pdp == NULL\n");
-        ok(pdp->cArgs == 0, "pdp->cArgs = %d\n", pdp->cArgs);
-        ok(pdp->cNamedArgs == 0, "pdp->cNamedArgs = %d\n", pdp->cNamedArgs);
-        ok(!pdp->rgdispidNamedArgs, "pdp->rgdispidNamedArgs != NULL\n");
-        ok(!pdp->rgvarg, "rgvarg != NULL\n");
-        ok(pvarRes != NULL, "pvarRes == NULL\n");
-        ok(pei != NULL, "pei == NULL\n");
-        ok(!pspCaller, "pspCaller != NULL\n");
+    hres = IOleDocumentView_QueryInterface(pViewToActivate, &IID_IOleDocument, (void**)&document);
+    ok(hres == S_OK, "could not get IOleDocument: %08x\n", hres);
 
 
-        V_VT(pvarRes) = VT_NULL;
-        break;
-    default:
-        ok(0, "unexpected call\n");
-        return E_NOTIMPL;
-    }
+    hres = IOleDocument_CreateView(document, &InPlaceSite, NULL, 0, &view);
+    IOleDocument_Release(document);
+    ok(hres == S_OK, "CreateView failed: %08x\n", hres);
+
+    hres = IOleDocumentView_SetInPlaceSite(view, &InPlaceSite);
+    ok(hres == S_OK, "SetInPlaceSite failed: %08x\n", hres);
+
+    hres = IOleDocumentView_UIActivate(view, TRUE);
+    ok(hres == S_OK, "UIActivate failed: %08x\n", hres);
+
+    hres = IOleDocumentView_SetRect(view, &rect);
+    ok(hres == S_OK, "SetRect failed: %08x\n", hres);
+
+    hres = IOleDocumentView_Show(view, TRUE);
+    ok(hres == S_OK, "Show failed: %08x\n", hres);
 
     return S_OK;
 }
 
 
     return S_OK;
 }
 
-static IDispatchExVtbl scriptDispVtbl = {
-    DispatchEx_QueryInterface,
-    DispatchEx_AddRef,
-    DispatchEx_Release,
-    DispatchEx_GetTypeInfoCount,
-    DispatchEx_GetTypeInfo,
-    DispatchEx_GetIDsOfNames,
-    DispatchEx_Invoke,
-    scriptDisp_GetDispID,
-    scriptDisp_InvokeEx,
-    DispatchEx_DeleteMemberByName,
-    DispatchEx_DeleteMemberByDispID,
-    DispatchEx_GetMemberProperties,
-    DispatchEx_GetMemberName,
-    DispatchEx_GetNextDispID,
-    DispatchEx_GetNameSpaceParent
+static const IOleDocumentSiteVtbl DocumentSiteVtbl = {
+    DocumentSite_QueryInterface,
+    DocumentSite_AddRef,
+    DocumentSite_Release,
+    DocumentSite_ActivateMe
 };
 
 };
 
-static IDispatchEx scriptDisp = { &scriptDispVtbl };
+static IOleDocumentSite DocumentSite = { &DocumentSiteVtbl };
+
+static HRESULT QueryInterface(REFIID riid, void **ppv)
+{
+    *ppv = NULL;
+
+    if(IsEqualGUID(&IID_IUnknown, riid) || IsEqualGUID(&IID_IOleClientSite, riid))
+        *ppv = &ClientSite;
+    else if(IsEqualGUID(&IID_IOleDocumentSite, riid))
+        *ppv = &DocumentSite;
+    else if(IsEqualGUID(&IID_IOleWindow, riid) || IsEqualGUID(&IID_IOleInPlaceSite, riid))
+        *ppv = &InPlaceSite;
+    else if(IsEqualGUID(&IID_IDocHostUIHandler, riid) || IsEqualGUID(&IID_IDocHostUIHandler2, riid))
+        *ppv = &DocHostUIHandler;
+
+    return *ppv ? S_OK : E_NOINTERFACE;
+}
 
 static IHTMLDocument2 *create_document(void)
 {
 
 static IHTMLDocument2 *create_document(void)
 {
@@ -433,18 +1059,13 @@ static IHTMLDocument2 *create_document(void)
     return doc;
 }
 
     return doc;
 }
 
-static IHTMLDocument2 *create_doc_with_string(const char *str)
+static void load_string(IHTMLDocument2 *doc, const char *str)
 {
     IPersistStreamInit *init;
     IStream *stream;
 {
     IPersistStreamInit *init;
     IStream *stream;
-    IHTMLDocument2 *doc;
     HGLOBAL mem;
     SIZE_T len;
 
     HGLOBAL mem;
     SIZE_T len;
 
-    notif_doc = doc = create_document();
-    if(!doc)
-        return NULL;
-
     doc_complete = FALSE;
     len = strlen(str);
     mem = GlobalAlloc(0, len);
     doc_complete = FALSE;
     len = strlen(str);
     mem = GlobalAlloc(0, len);
@@ -456,45 +1077,76 @@ static IHTMLDocument2 *create_doc_with_string(const char *str)
     IPersistStreamInit_Load(init, stream);
     IPersistStreamInit_Release(init);
     IStream_Release(stream);
     IPersistStreamInit_Load(init, stream);
     IPersistStreamInit_Release(init);
     IStream_Release(stream);
-
-    return doc;
 }
 
 }
 
-static void do_advise(IUnknown *unk, REFIID riid, IUnknown *unk_advise)
+static void do_advise(IHTMLDocument2 *doc, REFIID riid, IUnknown *unk_advise)
 {
     IConnectionPointContainer *container;
     IConnectionPoint *cp;
     DWORD cookie;
     HRESULT hres;
 
 {
     IConnectionPointContainer *container;
     IConnectionPoint *cp;
     DWORD cookie;
     HRESULT hres;
 
-    hres = IUnknown_QueryInterface(unk, &IID_IConnectionPointContainer, (void**)&container);
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IConnectionPointContainer, (void**)&container);
     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
 
     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
     IConnectionPointContainer_Release(container);
     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
 
     ok(hres == S_OK, "QueryInterface(IID_IConnectionPointContainer) failed: %08x\n", hres);
 
     hres = IConnectionPointContainer_FindConnectionPoint(container, riid, &cp);
     IConnectionPointContainer_Release(container);
     ok(hres == S_OK, "FindConnectionPoint failed: %08x\n", hres);
 
+    notif_doc = doc;
+
     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
     IConnectionPoint_Release(cp);
     ok(hres == S_OK, "Advise failed: %08x\n", hres);
 }
 
     hres = IConnectionPoint_Advise(cp, unk_advise, &cookie);
     IConnectionPoint_Release(cp);
     ok(hres == S_OK, "Advise failed: %08x\n", hres);
 }
 
+static void set_client_site(IHTMLDocument2 *doc, BOOL set)
+{
+    IOleObject *oleobj;
+    HRESULT hres;
+
+    if(!set && view) {
+        IOleDocumentView_Show(view, FALSE);
+        IOleDocumentView_CloseView(view, 0);
+        IOleDocumentView_SetInPlaceSite(view, NULL);
+        IOleDocumentView_Release(view);
+        view = NULL;
+    }
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IOleObject, (void**)&oleobj);
+    ok(hres == S_OK, "Could not et IOleObject: %08x\n", hres);
+
+    hres = IOleObject_SetClientSite(oleobj, set ? &ClientSite : NULL);
+    ok(hres == S_OK, "SetClientSite failed: %08x\n", hres);
+
+    if(set) {
+        IHlinkTarget *hlink;
+
+        hres = IOleObject_QueryInterface(oleobj, &IID_IHlinkTarget, (void**)&hlink);
+        ok(hres == S_OK, "Could not get IHlinkTarget iface: %08x\n", hres);
+
+        hres = IHlinkTarget_Navigate(hlink, 0, NULL);
+        ok(hres == S_OK, "Navgate failed: %08x\n", hres);
+
+        IHlinkTarget_Release(hlink);
+    }
+
+    IOleObject_Release(oleobj);
+}
+
 typedef void (*domtest_t)(IHTMLDocument2*);
 
 typedef void (*domtest_t)(IHTMLDocument2*);
 
-static IHTMLDocument2 *create_and_load_doc(const char *str)
+static void load_doc(IHTMLDocument2 *doc, const char *str)
 {
 {
-    IHTMLDocument2 *doc;
     IHTMLElement *body = NULL;
     IHTMLElement *body = NULL;
-    ULONG ref;
     MSG msg;
     HRESULT hres;
     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
     DISPID dispID = -1;
     OLECHAR *name;
 
     MSG msg;
     HRESULT hres;
     static const WCHAR ucPtr[] = {'b','a','c','k','g','r','o','u','n','d',0};
     DISPID dispID = -1;
     OLECHAR *name;
 
-
-    doc = create_doc_with_string(str);
-    do_advise((IUnknown*)doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
+    load_string(doc, str);
+    do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
 
     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
         TranslateMessage(&msg);
 
     while(!doc_complete && GetMessage(&msg, NULL, 0, 0)) {
         TranslateMessage(&msg);
@@ -504,13 +1156,6 @@ static IHTMLDocument2 *create_and_load_doc(const char *str)
     hres = IHTMLDocument2_get_body(doc, &body);
     ok(hres == S_OK, "get_body failed: %08x\n", hres);
 
     hres = IHTMLDocument2_get_body(doc, &body);
     ok(hres == S_OK, "get_body failed: %08x\n", hres);
 
-    if(!body) {
-        skip("Could not get document body. Assuming no Gecko installed.\n");
-        ref = IHTMLDocument2_Release(doc);
-        ok(!ref, "ref = %d\n", ref);
-        return NULL;
-    }
-
     /* Check we can query for function on the IHTMLElementBody interface */
     name = (WCHAR*)ucPtr;
     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
     /* Check we can query for function on the IHTMLElementBody interface */
     name = (WCHAR*)ucPtr;
     hres = IHTMLElement_GetIDsOfNames(body, &IID_NULL, &name, 1, LOCALE_USER_DEFAULT, &dispID);
@@ -518,7 +1163,6 @@ static IHTMLDocument2 *create_and_load_doc(const char *str)
     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
 
     IHTMLElement_Release(body);
     ok(dispID == DISPID_IHTMLBODYELEMENT_BACKGROUND, "Incorrect dispID got (%d)\n", dispID);
 
     IHTMLElement_Release(body);
-    return doc;
 }
 
 static IActiveScriptSite *site;
 }
 
 static IActiveScriptSite *site;
@@ -592,6 +1236,8 @@ static HRESULT WINAPI AXObjectSafety_QueryInterface(IObjectSafety *iface, REFIID
 
     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
         CHECK_EXPECT(AXQueryInterface_IObjectSafety);
 
     if(IsEqualGUID(&IID_IObjectSafety, riid)) {
         CHECK_EXPECT(AXQueryInterface_IObjectSafety);
+        if(!ax_objsafe)
+            return E_NOINTERFACE;
         *ppv = iface;
         return S_OK;
     }
         *ppv = iface;
         return S_OK;
     }
@@ -640,6 +1286,12 @@ static const IObjectSafetyVtbl AXObjectSafetyVtbl = {
 
 static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
 
 
 static IObjectSafety AXObjectSafety = { &AXObjectSafetyVtbl };
 
+static BOOL set_safe_reg(BOOL init)
+{
+    return init_key("CLSID\\"TESTACTIVEX_CLSID"\\Implemented Categories\\{7dd95801-9882-11cf-9fa9-00aa006c42c4}",
+                    NULL, init);
+}
+
 static void test_security(void)
 {
     IInternetHostSecurityManager *sec_mgr;
 static void test_security(void)
 {
     IInternetHostSecurityManager *sec_mgr;
@@ -666,6 +1318,7 @@ static void test_security(void)
     cs.pUnk = (IUnknown*)&AXObjectSafety;
     cs.dwFlags = 0;
 
     cs.pUnk = (IUnknown*)&AXObjectSafety;
     cs.dwFlags = 0;
 
+    ax_objsafe = TRUE;
     SET_EXPECT(AXQueryInterface_IActiveScript);
     SET_EXPECT(AXQueryInterface_IObjectSafety);
     SET_EXPECT(AXGetInterfaceSafetyOptions);
     SET_EXPECT(AXQueryInterface_IActiveScript);
     SET_EXPECT(AXQueryInterface_IObjectSafety);
     SET_EXPECT(AXGetInterfaceSafetyOptions);
@@ -682,6 +1335,55 @@ static void test_security(void)
     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
     CoTaskMemFree(ppolicy);
 
     ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
     CoTaskMemFree(ppolicy);
 
+    ax_objsafe = FALSE;
+    SET_EXPECT(AXQueryInterface_IActiveScript);
+    SET_EXPECT(AXQueryInterface_IObjectSafety);
+    hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+            &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+    CHECK_CALLED(AXQueryInterface_IActiveScript);
+    CHECK_CALLED(AXQueryInterface_IObjectSafety);
+
+    ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
+    ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
+    ok(*(DWORD*)ppolicy == URLPOLICY_DISALLOW, "policy = %x\n", *(DWORD*)ppolicy);
+    CoTaskMemFree(ppolicy);
+
+    if(set_safe_reg(TRUE)) {
+        ax_objsafe = FALSE;
+        SET_EXPECT(AXQueryInterface_IActiveScript);
+        SET_EXPECT(AXQueryInterface_IObjectSafety);
+        hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+                 &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+        CHECK_CALLED(AXQueryInterface_IActiveScript);
+        CHECK_CALLED(AXQueryInterface_IObjectSafety);
+
+        ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
+        ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
+        ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
+        CoTaskMemFree(ppolicy);
+
+        ax_objsafe = TRUE;
+        SET_EXPECT(AXQueryInterface_IActiveScript);
+        SET_EXPECT(AXQueryInterface_IObjectSafety);
+        SET_EXPECT(AXGetInterfaceSafetyOptions);
+        SET_EXPECT(AXSetInterfaceSafetyOptions);
+        hres = IInternetHostSecurityManager_QueryCustomPolicy(sec_mgr, &GUID_CUSTOM_CONFIRMOBJECTSAFETY,
+                &ppolicy, &policy_size, (BYTE*)&cs, sizeof(cs), 0);
+        CHECK_CALLED(AXQueryInterface_IActiveScript);
+        CHECK_CALLED(AXQueryInterface_IObjectSafety);
+        CHECK_CALLED(AXGetInterfaceSafetyOptions);
+        CHECK_CALLED(AXSetInterfaceSafetyOptions);
+
+        ok(hres == S_OK, "QueryCusromPolicy failed: %08x\n", hres);
+        ok(policy_size == sizeof(DWORD), "policy_size = %d\n", policy_size);
+        ok(*(DWORD*)ppolicy == URLPOLICY_ALLOW, "policy = %x\n", *(DWORD*)ppolicy);
+        CoTaskMemFree(ppolicy);
+
+        set_safe_reg(FALSE);
+    }else {
+        skip("Could not set safety registry\n");
+    }
+
     IInternetHostSecurityManager_Release(sec_mgr);
 }
 
     IInternetHostSecurityManager_Release(sec_mgr);
 }
 
@@ -817,13 +1519,13 @@ static HRESULT WINAPI ActiveScriptParse_AddScriptlet(IActiveScriptParse *iface,
     return E_NOTIMPL;
 }
 
     return E_NOTIMPL;
 }
 
-static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, VARIANT *var)
+static HRESULT dispex_propput(IDispatchEx *obj, DISPID id, DWORD flags, VARIANT *var)
 {
     DISPID propput_arg = DISPID_PROPERTYPUT;
     DISPPARAMS dp = {var, &propput_arg, 1, 1};
     EXCEPINFO ei = {0};
 
 {
     DISPID propput_arg = DISPID_PROPERTYPUT;
     DISPPARAMS dp = {var, &propput_arg, 1, 1};
     EXCEPINFO ei = {0};
 
-    return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT, &dp, NULL, &ei, NULL);
+    return IDispatchEx_InvokeEx(obj, id, LOCALE_NEUTRAL, DISPATCH_PROPERTYPUT|flags, &dp, NULL, &ei, NULL);
 }
 
 static void test_func(IDispatchEx *obj)
 }
 
 static void test_func(IDispatchEx *obj)
@@ -871,7 +1573,7 @@ static void test_func(IDispatchEx *obj)
 
     V_VT(&var) = VT_I4;
     V_I4(&var) = 100;
 
     V_VT(&var) = VT_I4;
     V_I4(&var) = 100;
-    hres = dispex_propput(obj, id, &var);
+    hres = dispex_propput(obj, id, 0, &var);
     ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
 
     IDispatchEx_Release(dispex);
     ok(hres == E_NOTIMPL, "InvokeEx failed: %08x\n", hres);
 
     IDispatchEx_Release(dispex);
@@ -890,7 +1592,7 @@ static void test_nextdispid(IDispatchEx *dispex)
     SysFreeString(name);
 
     V_VT(&var) = VT_EMPTY;
     SysFreeString(name);
 
     V_VT(&var) = VT_EMPTY;
-    hres = dispex_propput(dispex, dyn_id, &var);
+    hres = dispex_propput(dispex, dyn_id, 0, &var);
 
     while(last_id != dyn_id) {
         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id);
 
     while(last_id != dyn_id) {
         hres = IDispatchEx_GetNextDispID(dispex, fdexEnumAll, last_id, &id);
@@ -915,6 +1617,33 @@ static void test_nextdispid(IDispatchEx *dispex)
     ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n");
 }
 
     ok(id == DISPID_STARTENUM, "id != DISPID_STARTENUM\n");
 }
 
+static void test_global_id(void)
+{
+    VARIANT var;
+    DISPPARAMS dp;
+    EXCEPINFO ei;
+    BSTR tmp;
+    DISPID id;
+    HRESULT hres;
+
+    SET_EXPECT(GetScriptDispatch);
+    SET_EXPECT(script_divid_d);
+    tmp = a2bstr("divid");
+    hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive, &id);
+    ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
+    SysFreeString(tmp);
+    CHECK_CALLED(GetScriptDispatch);
+    CHECK_CALLED(script_divid_d);
+
+    VariantInit(&var);
+    memset(&ei, 0, sizeof(ei));
+    memset(&dp, 0, sizeof(dp));
+    hres = IDispatchEx_InvokeEx(window_dispex, id, 0, DISPATCH_PROPERTYGET, &dp, &var, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_DISPATCH, "V_VT(var) = %d\n", V_VT(&var));
+    VariantClear(&var);
+}
+
 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
 static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *iface,
         LPCOLESTR pstrCode, LPCOLESTR pstrItemName, IUnknown *punkContext,
         LPCOLESTR pstrDelimiter, CTXARG_T dwSourceContextCookie, ULONG ulStartingLine,
@@ -976,7 +1705,7 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
 
     V_VT(&var) = VT_I4;
     V_I4(&var) = 100;
 
     V_VT(&var) = VT_I4;
     V_I4(&var) = 100;
-    hres = dispex_propput(document, id, &var);
+    hres = dispex_propput(document, id, 0, &var);
     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
 
     tmp = SysAllocString(testW);
     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
 
     tmp = SysAllocString(testW);
@@ -990,7 +1719,37 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
     hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
     ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
     ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
-    ok(V_I4(&var) == 100, "V_I4(&var) == NULL\n");
+    ok(V_I4(&var) == 100, "V_I4(&var) = %d\n", V_I4(&var));
+
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = 200;
+    hres = dispex_propput(document, id, DISPATCH_PROPERTYPUTREF, &var);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+
+    VariantInit(&var);
+    memset(&dp, 0, sizeof(dp));
+    memset(&ei, 0, sizeof(ei));
+    hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
+    ok(V_I4(&var) == 200, "V_I4(&var) = %d\n", V_I4(&var));
+
+    memset(&dp, 0, sizeof(dp));
+    memset(&ei, 0, sizeof(ei));
+    V_VT(&var) = VT_I4;
+    V_I4(&var) = 300;
+    dp.cArgs = 1;
+    dp.rgvarg = &var;
+    hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYPUT, &dp, NULL, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+
+    VariantInit(&var);
+    memset(&dp, 0, sizeof(dp));
+    memset(&ei, 0, sizeof(ei));
+    hres = IDispatchEx_InvokeEx(document, id, LOCALE_NEUTRAL, INVOKE_PROPERTYGET, &dp, &var, &ei, NULL);
+    ok(hres == S_OK, "InvokeEx failed: %08x\n", hres);
+    ok(V_VT(&var) == VT_I4, "V_VT(var)=%d\n", V_VT(&var));
+    ok(V_I4(&var) == 300, "V_I4(&var) = %d\n", V_I4(&var));
 
     unk = (void*)0xdeadbeef;
     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
 
     unk = (void*)0xdeadbeef;
     hres = IDispatchEx_GetNameSpaceParent(window_dispex, &unk);
@@ -1074,6 +1833,18 @@ static HRESULT WINAPI ActiveScriptParse_ParseScriptText(IActiveScriptParse *ifac
     CHECK_CALLED(GetScriptDispatch);
     CHECK_CALLED(script_testprop_i);
 
     CHECK_CALLED(GetScriptDispatch);
     CHECK_CALLED(script_testprop_i);
 
+    SET_EXPECT(GetScriptDispatch);
+    SET_EXPECT(script_testprop2_d);
+    tmp = a2bstr("testProp2");
+    hres = IDispatchEx_GetDispID(window_dispex, tmp, fdexNameCaseSensitive|fdexNameEnsure, &id);
+    ok(hres == S_OK, "GetDispID failed: %08x\n", hres);
+    ok(id != DISPID_SCRIPT_TESTPROP2, "id == DISPID_SCRIPT_TESTPROP2\n");
+    CHECK_CALLED(GetScriptDispatch);
+    CHECK_CALLED(script_testprop2_d);
+    SysFreeString(tmp);
+
+    test_global_id();
+
     test_security();
 
     return S_OK;
     test_security();
 
     return S_OK;
@@ -1391,6 +2162,7 @@ static IClassFactory script_cf = { &ClassFactoryVtbl };
 
 static const char simple_script_str[] =
     "<html><head></head><body>"
 
 static const char simple_script_str[] =
     "<html><head></head><body>"
+    "<div id=\"divid\"></div>"
     "<script language=\"TestScript\">simple script</script>"
     "</body></html>";
 
     "<script language=\"TestScript\">simple script</script>"
     "</body></html>";
 
@@ -1398,6 +2170,10 @@ static void test_simple_script(void)
 {
     IHTMLDocument2 *doc;
 
 {
     IHTMLDocument2 *doc;
 
+    doc = create_document();
+    if(!doc)
+        return;
+
     SET_EXPECT(CreateInstance);
     SET_EXPECT(GetInterfaceSafetyOptions);
     SET_EXPECT(SetInterfaceSafetyOptions);
     SET_EXPECT(CreateInstance);
     SET_EXPECT(GetInterfaceSafetyOptions);
     SET_EXPECT(SetInterfaceSafetyOptions);
@@ -1412,8 +2188,7 @@ static void test_simple_script(void)
     SET_EXPECT(ParseScriptText);
     SET_EXPECT(SetScriptState_CONNECTED);
 
     SET_EXPECT(ParseScriptText);
     SET_EXPECT(SetScriptState_CONNECTED);
 
-    doc = create_and_load_doc(simple_script_str);
-    if(!doc) return;
+    load_doc(doc, simple_script_str);
 
     CHECK_CALLED(CreateInstance);
     CHECK_CALLED(GetInterfaceSafetyOptions);
 
     CHECK_CALLED(CreateInstance);
     CHECK_CALLED(GetInterfaceSafetyOptions);
@@ -1443,26 +2218,61 @@ static void test_simple_script(void)
     CHECK_CALLED(Close);
 }
 
     CHECK_CALLED(Close);
 }
 
-static BOOL init_key(const char *key_name, const char *def_value, BOOL init)
+static void run_js_script(const char *test_name)
 {
 {
-    HKEY hkey;
-    DWORD res;
+    WCHAR url[INTERNET_MAX_URL_LENGTH];
+    char urlA[INTERNET_MAX_URL_LENGTH];
+    IPersistMoniker *persist;
+    IHTMLDocument2 *doc;
+    IMoniker *mon;
+    MSG msg;
+    HRESULT hres;
 
 
-    if(!init) {
-        RegDeleteKey(HKEY_CLASSES_ROOT, key_name);
-        return TRUE;
-    }
+    static const char res[] = "res://";
 
 
-    res = RegCreateKeyA(HKEY_CLASSES_ROOT, key_name, &hkey);
-    if(res != ERROR_SUCCESS)
-        return FALSE;
+    trace("running %s...\n", test_name);
 
 
-    if(def_value)
-        res = RegSetValueA(hkey, NULL, REG_SZ, def_value, strlen(def_value));
+    doc = create_document();
+    if(!doc)
+        return;
 
 
-    RegCloseKey(hkey);
+    set_client_site(doc, TRUE);
+    do_advise(doc, &IID_IPropertyNotifySink, (IUnknown*)&PropertyNotifySink);
 
 
-    return res == ERROR_SUCCESS;
+    lstrcpyA(urlA, res);
+    GetModuleFileNameA(NULL, urlA + lstrlenA(res), sizeof(urlA) - lstrlenA(res));
+    lstrcatA(urlA, "/");
+    lstrcatA(urlA, test_name);
+    MultiByteToWideChar(CP_ACP, 0, urlA, -1, url, sizeof(url)/sizeof(WCHAR));
+
+    hres = CreateURLMoniker(NULL, url, &mon);
+    ok(hres == S_OK, "CreateURLMoniker failed: %08x\n", hres);
+
+    hres = IHTMLDocument2_QueryInterface(doc, &IID_IPersistMoniker, (void**)&persist);
+    ok(hres == S_OK, "Could not get IPersistMoniker iface: %08x\n", hres);
+
+    hres = IPersistMoniker_Load(persist, FALSE, mon, NULL, 0);
+    ok(hres == S_OK, "Load failed: %08x\n", hres);
+
+    IMoniker_Release(mon);
+    IPersistMoniker_Release(persist);
+
+    SET_EXPECT(external_success);
+
+    while(!called_external_success && GetMessage(&msg, NULL, 0, 0)) {
+        TranslateMessage(&msg);
+        DispatchMessage(&msg);
+    }
+
+    CHECK_CALLED(external_success);
+
+    set_client_site(doc, FALSE);
+    IHTMLDocument2_Release(doc);
+}
+
+static void run_js_tests(void)
+{
+    run_js_script("jstest.html");
 }
 
 static BOOL init_registry(BOOL init)
 }
 
 static BOOL init_registry(BOOL init)
@@ -1491,44 +2301,38 @@ static BOOL register_script_engine(void)
     return TRUE;
 }
 
     return TRUE;
 }
 
-static void gecko_installer_workaround(BOOL disable)
+static LRESULT WINAPI wnd_proc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
 {
 {
-    HKEY hkey;
-    DWORD res;
-
-    static BOOL has_url = FALSE;
-    static char url[2048];
-
-    if(!disable && !has_url)
-        return;
-
-    res = RegOpenKey(HKEY_CURRENT_USER, "Software\\Wine\\MSHTML", &hkey);
-    if(res != ERROR_SUCCESS)
-        return;
-
-    if(disable) {
-        DWORD type, size = sizeof(url);
-
-        res = RegQueryValueEx(hkey, "GeckoUrl", NULL, &type, (PVOID)url, &size);
-        if(res == ERROR_SUCCESS && type == REG_SZ)
-            has_url = TRUE;
+    return DefWindowProc(hwnd, msg, wParam, lParam);
+}
 
 
-        RegDeleteValue(hkey, "GeckoUrl");
-    }else {
-        RegSetValueEx(hkey, "GeckoUrl", 0, REG_SZ, (PVOID)url, lstrlenA(url)+1);
-    }
+static HWND create_container_window(void)
+{
+    static const CHAR szHTMLDocumentTest[] = "HTMLDocumentTest";
+    static WNDCLASSEXA wndclass = {
+        sizeof(WNDCLASSEXA),
+        0,
+        wnd_proc,
+        0, 0, NULL, NULL, NULL, NULL, NULL,
+        szHTMLDocumentTest,
+        NULL
+    };
 
 
-    RegCloseKey(hkey);
+    RegisterClassExA(&wndclass);
+    return CreateWindowA(szHTMLDocumentTest, szHTMLDocumentTest,
+            WS_OVERLAPPEDWINDOW, CW_USEDEFAULT, CW_USEDEFAULT,
+            300, 300, NULL, NULL, NULL, NULL);
 }
 
 START_TEST(script)
 {
 }
 
 START_TEST(script)
 {
-    gecko_installer_workaround(TRUE);
     CoInitialize(NULL);
     CoInitialize(NULL);
+    container_hwnd = create_container_window();
 
     if(winetest_interactive || ! is_ie_hardened()) {
         if(register_script_engine()) {
             test_simple_script();
 
     if(winetest_interactive || ! is_ie_hardened()) {
         if(register_script_engine()) {
             test_simple_script();
+            run_js_tests();
             init_registry(FALSE);
         }else {
             skip("Could not register TestScript engine\n");
             init_registry(FALSE);
         }else {
             skip("Could not register TestScript engine\n");
@@ -1537,6 +2341,6 @@ START_TEST(script)
         skip("IE running in Enhanced Security Configuration\n");
     }
 
         skip("IE running in Enhanced Security Configuration\n");
     }
 
+    DestroyWindow(container_hwnd);
     CoUninitialize();
     CoUninitialize();
-    gecko_installer_workaround(FALSE);
 }
 }
index f902699..5582344 100644 (file)
@@ -9,6 +9,7 @@
 extern void func_dom(void);
 extern void func_events(void);
 extern void func_htmldoc(void);
 extern void func_dom(void);
 extern void func_events(void);
 extern void func_htmldoc(void);
+extern void func_htmllocation(void);
 extern void func_misc(void);
 extern void func_protocol(void);
 extern void func_script(void);
 extern void func_misc(void);
 extern void func_protocol(void);
 extern void func_script(void);
@@ -18,6 +19,7 @@ const struct test winetest_testlist[] =
     { "dom", func_dom },
     { "events", func_events },
        { "htmldoc", func_htmldoc },
     { "dom", func_dom },
     { "events", func_events },
        { "htmldoc", func_htmldoc },
+       { "htmllocation", func_htmllocation },
     { "misc", func_misc },
     { "protocol", func_protocol },
     { "script", func_script },
     { "misc", func_misc },
     { "protocol", func_protocol },
     { "script", func_script },