diff --git a/dlls/mshtml/htmlanchor.c b/dlls/mshtml/htmlanchor.c
index 1ef7f72b30a..00301ade0a5 100644
--- a/dlls/mshtml/htmlanchor.c
+++ b/dlls/mshtml/htmlanchor.c
@@ -73,6 +73,7 @@ static HRESULT navigate_anchor_window(HTMLAnchorElement *This, const WCHAR *targ
static HRESULT navigate_anchor(HTMLAnchorElement *This)
{
nsAString href_str, target_str;
+ HTMLWindow *window = NULL;
nsresult nsres;
HRESULT hres = E_FAIL;
@@ -87,14 +88,18 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This)
nsAString_GetData(&target_str, &target);
if(*target && strcmpiW(target, _selfW)) {
- if(strcmpiW(target, _parentW) && strcmpiW(target, _topW)) {
- hres = navigate_anchor_window(This, target);
+ if(!strcmpiW(target, _topW)) {
+ TRACE("target _top\n");
+ get_top_window(This->element.node.doc->basedoc.window, &window);
+ }else if(!strcmpiW(target, _parentW)) {
+ FIXME("Navigating to target _parent is not implemented\n");
+ nsAString_Finish(&target_str);
+ return S_OK;
}else {
- FIXME("Navigating to target %s is not implemented\n", debugstr_w(target));
- hres = S_OK;
+ hres = navigate_anchor_window(This, target);
+ nsAString_Finish(&target_str);
+ return hres;
}
- nsAString_Finish(&target_str);
- return hres;
}
}
nsAString_Finish(&target_str);
@@ -106,7 +111,8 @@ static HRESULT navigate_anchor(HTMLAnchorElement *This)
nsAString_GetData(&href_str, &href);
if(*href) {
- HTMLWindow *window = This->element.node.doc->basedoc.window;
+ if(!window)
+ window = This->element.node.doc->basedoc.window;
hres = navigate_url(window, href, window->url);
}else {
TRACE("empty href\n");
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 2623520f632..2bd5d7edf0f 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -107,6 +107,14 @@ static HRESULT get_location(HTMLWindow *This, HTMLLocation **ret)
return S_OK;
}
+void get_top_window(HTMLWindow *window, HTMLWindow **ret)
+{
+ HTMLWindow *iter;
+
+ for(iter = window; iter->parent; iter = iter->parent);
+ *ret = iter;
+}
+
static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
{
if(!window->doc) {
@@ -838,13 +846,12 @@ static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p
static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
{
HTMLWindow *This = impl_from_IHTMLWindow2(iface);
- HTMLWindow *curr;
+ HTMLWindow *top;
+
TRACE("(%p)->(%p)\n", This, p);
- curr = This;
- while(curr->parent)
- curr = curr->parent;
- *p = &curr->IHTMLWindow2_iface;
+ get_top_window(This, &top);
+ *p = &top->IHTMLWindow2_iface;
IHTMLWindow2_AddRef(*p);
return S_OK;
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 2e4df12663f..789ffb58aa3 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -631,6 +631,7 @@ HRESULT create_document_fragment(nsIDOMNode*,HTMLDocumentNode*,HTMLDocumentNode*
HRESULT HTMLWindow_Create(HTMLDocumentObj*,nsIDOMWindow*,HTMLWindow*,HTMLWindow**) DECLSPEC_HIDDEN;
void update_window_doc(HTMLWindow*) DECLSPEC_HIDDEN;
HTMLWindow *nswindow_to_window(const nsIDOMWindow*) DECLSPEC_HIDDEN;
+void get_top_window(HTMLWindow*,HTMLWindow**) DECLSPEC_HIDDEN;
HTMLOptionElementFactory *HTMLOptionElementFactory_Create(HTMLWindow*) DECLSPEC_HIDDEN;
HTMLImageElementFactory *HTMLImageElementFactory_Create(HTMLWindow*) DECLSPEC_HIDDEN;
HRESULT HTMLLocation_Create(HTMLWindow*,HTMLLocation**) DECLSPEC_HIDDEN;