mshtml: Added noscript tag handling tests.
[wine] / dlls / mshtml / htmlwindow.c
1 /*
2  * Copyright 2006-2012 Jacek Caban for CodeWeavers
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2.1 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17  */
18
19 #include <stdarg.h>
20 #include <assert.h>
21
22 #define COBJMACROS
23
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winuser.h"
27 #include "ole2.h"
28 #include "mshtmdid.h"
29 #include "shlguid.h"
30 #include "shobjidl.h"
31
32 #define NO_SHLWAPI_REG
33 #include "shlwapi.h"
34
35 #include "wine/debug.h"
36
37 #include "mshtml_private.h"
38 #include "htmlevent.h"
39 #include "binding.h"
40 #include "resource.h"
41
42 WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
43
44 static struct list window_list = LIST_INIT(window_list);
45
46 static inline BOOL is_outer_window(HTMLWindow *window)
47 {
48     return &window->outer_window->base == window;
49 }
50
51 static void release_children(HTMLOuterWindow *This)
52 {
53     HTMLOuterWindow *child;
54
55     while(!list_empty(&This->children)) {
56         child = LIST_ENTRY(list_tail(&This->children), HTMLOuterWindow, sibling_entry);
57
58         list_remove(&child->sibling_entry);
59         child->parent = NULL;
60         IHTMLWindow2_Release(&child->base.IHTMLWindow2_iface);
61     }
62 }
63
64 static HRESULT get_location(HTMLInnerWindow *This, HTMLLocation **ret)
65 {
66     if(This->location) {
67         IHTMLLocation_AddRef(&This->location->IHTMLLocation_iface);
68     }else {
69         HRESULT hres;
70
71         hres = HTMLLocation_Create(This, &This->location);
72         if(FAILED(hres))
73             return hres;
74     }
75
76     *ret = This->location;
77     return S_OK;
78 }
79
80 void get_top_window(HTMLOuterWindow *window, HTMLOuterWindow **ret)
81 {
82     HTMLOuterWindow *iter;
83
84     for(iter = window; iter->parent; iter = iter->parent);
85     *ret = iter;
86 }
87
88 static inline HRESULT set_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
89 {
90     if(!window->inner_window->doc) {
91         FIXME("No document\n");
92         return E_FAIL;
93     }
94
95     return set_event_handler(&window->inner_window->doc->body_event_target, NULL, window->inner_window->doc, eid, var);
96 }
97
98 static inline HRESULT get_window_event(HTMLWindow *window, eventid_t eid, VARIANT *var)
99 {
100     if(!window->inner_window->doc) {
101         FIXME("No document\n");
102         return E_FAIL;
103     }
104
105     return get_event_handler(&window->inner_window->doc->body_event_target, eid, var);
106 }
107
108 static void detach_inner_window(HTMLOuterWindow *outer_window)
109 {
110     HTMLInnerWindow *window = outer_window->base.inner_window;
111
112     if(!window)
113         return;
114
115     if(outer_window->doc_obj && outer_window == outer_window->doc_obj->basedoc.window)
116         window->doc->basedoc.cp_container.forward_container = NULL;
117
118     detach_events(window->doc);
119     abort_window_bindings(window);
120     release_script_hosts(window);
121     window->doc->basedoc.window = NULL;
122     window->base.outer_window = NULL;
123
124     IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
125 }
126
127 static inline HTMLWindow *impl_from_IHTMLWindow2(IHTMLWindow2 *iface)
128 {
129     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow2_iface);
130 }
131
132 static HRESULT WINAPI HTMLWindow2_QueryInterface(IHTMLWindow2 *iface, REFIID riid, void **ppv)
133 {
134     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
135
136     *ppv = NULL;
137
138     if(IsEqualGUID(&IID_IUnknown, riid)) {
139         TRACE("(%p)->(IID_IUnknown %p)\n", This, ppv);
140         *ppv = &This->IHTMLWindow2_iface;
141     }else if(IsEqualGUID(&IID_IDispatch, riid)) {
142         TRACE("(%p)->(IID_IDispatch %p)\n", This, ppv);
143         *ppv = &This->IHTMLWindow2_iface;
144     }else if(IsEqualGUID(&IID_IDispatchEx, riid)) {
145         TRACE("(%p)->(IID_IDispatchEx %p)\n", This, ppv);
146         *ppv = &This->IDispatchEx_iface;
147     }else if(IsEqualGUID(&IID_IHTMLFramesCollection2, riid)) {
148         TRACE("(%p)->(IID_IHTMLFramesCollection2 %p)\n", This, ppv);
149         *ppv = &This->IHTMLWindow2_iface;
150     }else if(IsEqualGUID(&IID_IHTMLWindow2, riid)) {
151         TRACE("(%p)->(IID_IHTMLWindow2 %p)\n", This, ppv);
152         *ppv = &This->IHTMLWindow2_iface;
153     }else if(IsEqualGUID(&IID_IHTMLWindow3, riid)) {
154         TRACE("(%p)->(IID_IHTMLWindow3 %p)\n", This, ppv);
155         *ppv = &This->IHTMLWindow3_iface;
156     }else if(IsEqualGUID(&IID_IHTMLWindow4, riid)) {
157         TRACE("(%p)->(IID_IHTMLWindow4 %p)\n", This, ppv);
158         *ppv = &This->IHTMLWindow4_iface;
159     }else if(IsEqualGUID(&IID_IHTMLWindow5, riid)) {
160         TRACE("(%p)->(IID_IHTMLWindow5 %p)\n", This, ppv);
161         *ppv = &This->IHTMLWindow5_iface;
162     }else if(IsEqualGUID(&IID_IHTMLWindow6, riid)) {
163         TRACE("(%p)->(IID_IHTMLWindow6 %p)\n", This, ppv);
164         *ppv = &This->IHTMLWindow6_iface;
165     }else if(IsEqualGUID(&IID_IHTMLPrivateWindow, riid)) {
166         TRACE("(%p)->(IID_IHTMLPrivateWindow %p)\n", This, ppv);
167         *ppv = &This->IHTMLPrivateWindow_iface;
168     }else if(IsEqualGUID(&IID_IServiceProvider, riid)) {
169         TRACE("(%p)->(IID_IServiceProvider %p)\n", This, ppv);
170         *ppv = &This->IServiceProvider_iface;
171     }else if(IsEqualGUID(&IID_ITravelLogClient, riid)) {
172         TRACE("(%p)->(IID_ITravelLogClient %p)\n", This, ppv);
173         *ppv = &This->ITravelLogClient_iface;
174     }else if(dispex_query_interface(&This->inner_window->dispex, riid, ppv)) {
175         assert(!*ppv);
176         return E_NOINTERFACE;
177     }
178
179     if(*ppv) {
180         IUnknown_AddRef((IUnknown*)*ppv);
181         return S_OK;
182     }
183
184     WARN("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppv);
185     return E_NOINTERFACE;
186 }
187
188 static ULONG WINAPI HTMLWindow2_AddRef(IHTMLWindow2 *iface)
189 {
190     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
191     LONG ref = InterlockedIncrement(&This->ref);
192
193     TRACE("(%p) ref=%d\n", This, ref);
194
195     return ref;
196 }
197
198 static void release_outer_window(HTMLOuterWindow *This)
199 {
200     if(This->pending_window) {
201         abort_window_bindings(This->pending_window);
202         This->pending_window->base.outer_window = NULL;
203         IHTMLWindow2_Release(&This->pending_window->base.IHTMLWindow2_iface);
204     }
205
206     remove_target_tasks(This->task_magic);
207     set_current_mon(This, NULL);
208     detach_inner_window(This);
209     release_children(This);
210
211     if(This->secmgr)
212         IInternetSecurityManager_Release(This->secmgr);
213
214     if(This->frame_element)
215         This->frame_element->content_window = NULL;
216
217     This->window_ref->window = NULL;
218     windowref_release(This->window_ref);
219
220     if(This->nswindow)
221         nsIDOMWindow_Release(This->nswindow);
222
223     list_remove(&This->entry);
224     heap_free(This);
225 }
226
227 static void release_inner_window(HTMLInnerWindow *This)
228 {
229     unsigned i;
230
231     TRACE("%p\n", This);
232
233     remove_target_tasks(This->task_magic);
234     abort_window_bindings(This);
235     release_script_hosts(This);
236
237     if(This->doc) {
238         This->doc->window = NULL;
239         htmldoc_release(&This->doc->basedoc);
240     }
241
242     release_dispex(&This->dispex);
243
244     for(i=0; i < This->global_prop_cnt; i++)
245         heap_free(This->global_props[i].name);
246     heap_free(This->global_props);
247
248     if(This->location) {
249         This->location->window = NULL;
250         IHTMLLocation_Release(&This->location->IHTMLLocation_iface);
251     }
252
253     if(This->image_factory) {
254         This->image_factory->window = NULL;
255         IHTMLImageElementFactory_Release(&This->image_factory->IHTMLImageElementFactory_iface);
256     }
257
258     if(This->option_factory) {
259         This->option_factory->window = NULL;
260         IHTMLOptionElementFactory_Release(&This->option_factory->IHTMLOptionElementFactory_iface);
261     }
262
263     if(This->screen)
264         IHTMLScreen_Release(This->screen);
265     if(This->history)
266         IOmHistory_Release(This->history);
267     if(This->mon)
268         IMoniker_Release(This->mon);
269
270     heap_free(This);
271 }
272
273 static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
274 {
275     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
276     LONG ref = InterlockedDecrement(&This->ref);
277
278     TRACE("(%p) ref=%d\n", This, ref);
279
280     if(!ref) {
281         if(is_outer_window(This))
282             release_outer_window(This->outer_window);
283         else
284             release_inner_window(This->inner_window);
285     }
286
287     return ref;
288 }
289
290 static HRESULT WINAPI HTMLWindow2_GetTypeInfoCount(IHTMLWindow2 *iface, UINT *pctinfo)
291 {
292     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
293
294     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
295 }
296
297 static HRESULT WINAPI HTMLWindow2_GetTypeInfo(IHTMLWindow2 *iface, UINT iTInfo,
298                                               LCID lcid, ITypeInfo **ppTInfo)
299 {
300     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
301
302     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
303 }
304
305 static HRESULT WINAPI HTMLWindow2_GetIDsOfNames(IHTMLWindow2 *iface, REFIID riid,
306                                                 LPOLESTR *rgszNames, UINT cNames,
307                                                 LCID lcid, DISPID *rgDispId)
308 {
309     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
310
311     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
312             rgDispId);
313 }
314
315 static HRESULT WINAPI HTMLWindow2_Invoke(IHTMLWindow2 *iface, DISPID dispIdMember,
316                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
317                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
318 {
319     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
320
321     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
322             pDispParams, pVarResult, pExcepInfo, puArgErr);
323 }
324
325 static HRESULT get_frame_by_index(HTMLOuterWindow *This, PRUint32 index, HTMLOuterWindow **ret)
326 {
327     nsIDOMWindowCollection *nsframes;
328     nsIDOMWindow *nswindow;
329     PRUint32 length;
330     nsresult nsres;
331
332     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsframes);
333     if(NS_FAILED(nsres)) {
334         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
335         return E_FAIL;
336     }
337
338     nsres = nsIDOMWindowCollection_GetLength(nsframes, &length);
339     assert(nsres == NS_OK);
340
341     if(index >= length) {
342         nsIDOMWindowCollection_Release(nsframes);
343         return DISP_E_MEMBERNOTFOUND;
344     }
345
346     nsres = nsIDOMWindowCollection_Item(nsframes, index, &nswindow);
347     nsIDOMWindowCollection_Release(nsframes);
348     if(NS_FAILED(nsres)) {
349         FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
350         return E_FAIL;
351     }
352
353     *ret = nswindow_to_window(nswindow);
354
355     nsIDOMWindow_Release(nswindow);
356     return S_OK;
357 }
358
359 HRESULT get_frame_by_name(HTMLOuterWindow *This, const WCHAR *name, BOOL deep, HTMLOuterWindow **ret)
360 {
361     nsIDOMWindowCollection *nsframes;
362     HTMLOuterWindow *window = NULL;
363     nsIDOMWindow *nswindow;
364     nsAString name_str;
365     PRUint32 length, i;
366     nsresult nsres;
367     HRESULT hres = S_OK;
368
369     nsres = nsIDOMWindow_GetFrames(This->nswindow, &nsframes);
370     if(NS_FAILED(nsres)) {
371         FIXME("nsIDOMWindow_GetFrames failed: 0x%08x\n", nsres);
372         return E_FAIL;
373     }
374
375     nsAString_InitDepend(&name_str, name);
376     nsres = nsIDOMWindowCollection_NamedItem(nsframes, &name_str, &nswindow);
377     nsAString_Finish(&name_str);
378     if(NS_FAILED(nsres)) {
379         nsIDOMWindowCollection_Release(nsframes);
380         return E_FAIL;
381     }
382
383     if(nswindow) {
384         *ret = nswindow_to_window(nswindow);
385         return S_OK;
386     }
387
388     nsres = nsIDOMWindowCollection_GetLength(nsframes, &length);
389     assert(nsres == NS_OK);
390
391     for(i = 0; i < length && !window; ++i) {
392         HTMLOuterWindow *window_iter;
393         BSTR id;
394
395         nsres = nsIDOMWindowCollection_Item(nsframes, i, &nswindow);
396         if(NS_FAILED(nsres)) {
397             FIXME("nsIDOMWindowCollection_Item failed: 0x%08x\n", nsres);
398             hres = E_FAIL;
399             break;
400         }
401
402         window_iter = nswindow_to_window(nswindow);
403
404         nsIDOMWindow_Release(nswindow);
405
406         hres = IHTMLElement_get_id(&window_iter->frame_element->element.IHTMLElement_iface, &id);
407         if(FAILED(hres)) {
408             FIXME("IHTMLElement_get_id failed: 0x%08x\n", hres);
409             break;
410         }
411
412         if(id && !strcmpiW(id, name))
413             window = window_iter;
414
415         SysFreeString(id);
416
417         if(!window && deep)
418             get_frame_by_name(window_iter, name, TRUE, &window);
419     }
420
421     nsIDOMWindowCollection_Release(nsframes);
422     if(FAILED(hres))
423         return hres;
424
425     *ret = window;
426     return NS_OK;
427 }
428
429 static HRESULT WINAPI HTMLWindow2_item(IHTMLWindow2 *iface, VARIANT *pvarIndex, VARIANT *pvarResult)
430 {
431     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
432     HTMLOuterWindow *window = NULL;
433     HRESULT hres;
434
435     TRACE("(%p)->(%p %p)\n", This, pvarIndex, pvarResult);
436
437     switch(V_VT(pvarIndex)) {
438     case VT_I4: {
439         int index = V_I4(pvarIndex);
440         TRACE("Getting index %d\n", index);
441         if(index < 0)
442             return DISP_E_MEMBERNOTFOUND;
443         hres = get_frame_by_index(This->outer_window, index, &window);
444         break;
445     }
446     case VT_UINT: {
447         unsigned int index = V_UINT(pvarIndex);
448         TRACE("Getting index %u\n", index);
449         hres = get_frame_by_index(This->outer_window, index, &window);
450         break;
451     }
452     case VT_BSTR: {
453         BSTR str = V_BSTR(pvarIndex);
454         TRACE("Getting name %s\n", wine_dbgstr_w(str));
455         hres = get_frame_by_name(This->outer_window, str, FALSE, &window);
456         break;
457     }
458     default:
459         WARN("Invalid index %s\n", debugstr_variant(pvarIndex));
460         return E_INVALIDARG;
461     }
462
463     if(FAILED(hres))
464         return hres;
465     if(!window)
466         return DISP_E_MEMBERNOTFOUND;
467
468     IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
469     V_VT(pvarResult) = VT_DISPATCH;
470     V_DISPATCH(pvarResult) = (IDispatch*)window;
471     return S_OK;
472 }
473
474 static HRESULT WINAPI HTMLWindow2_get_length(IHTMLWindow2 *iface, LONG *p)
475 {
476     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
477     nsIDOMWindowCollection *nscollection;
478     PRUint32 length;
479     nsresult nsres;
480
481     TRACE("(%p)->(%p)\n", This, p);
482
483     nsres = nsIDOMWindow_GetFrames(This->outer_window->nswindow, &nscollection);
484     if(NS_FAILED(nsres)) {
485         ERR("GetFrames failed: %08x\n", nsres);
486         return E_FAIL;
487     }
488
489     nsres = nsIDOMWindowCollection_GetLength(nscollection, &length);
490     nsIDOMWindowCollection_Release(nscollection);
491     if(NS_FAILED(nsres)) {
492         ERR("GetLength failed: %08x\n", nsres);
493         return E_FAIL;
494     }
495
496     *p = length;
497     return S_OK;
498 }
499
500 static HRESULT WINAPI HTMLWindow2_get_frames(IHTMLWindow2 *iface, IHTMLFramesCollection2 **p)
501 {
502     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
503     FIXME("(%p)->(%p): semi-stub\n", This, p);
504
505     /* FIXME: Should return a separate Window object */
506     *p = (IHTMLFramesCollection2*)&This->IHTMLWindow2_iface;
507     HTMLWindow2_AddRef(iface);
508     return S_OK;
509 }
510
511 static HRESULT WINAPI HTMLWindow2_put_defaultStatus(IHTMLWindow2 *iface, BSTR v)
512 {
513     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
514     FIXME("(%p)->(%s)\n", This, debugstr_w(v));
515     return E_NOTIMPL;
516 }
517
518 static HRESULT WINAPI HTMLWindow2_get_defaultStatus(IHTMLWindow2 *iface, BSTR *p)
519 {
520     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
521     FIXME("(%p)->(%p)\n", This, p);
522     return E_NOTIMPL;
523 }
524
525 static HRESULT WINAPI HTMLWindow2_put_status(IHTMLWindow2 *iface, BSTR v)
526 {
527     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
528
529     WARN("(%p)->(%s)\n", This, debugstr_w(v));
530
531     /*
532      * FIXME: Since IE7, setting status is blocked, but still possible in certain circumstances.
533      * Ignoring the call should be enough for us.
534      */
535     return S_OK;
536 }
537
538 static HRESULT WINAPI HTMLWindow2_get_status(IHTMLWindow2 *iface, BSTR *p)
539 {
540     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
541
542     TRACE("(%p)->(%p)\n", This, p);
543
544     /* See put_status */
545     *p = NULL;
546     return S_OK;
547 }
548
549 static HRESULT WINAPI HTMLWindow2_setTimeout(IHTMLWindow2 *iface, BSTR expression,
550         LONG msec, VARIANT *language, LONG *timerID)
551 {
552     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
553     VARIANT expr_var;
554
555     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
556
557     V_VT(&expr_var) = VT_BSTR;
558     V_BSTR(&expr_var) = expression;
559
560     return IHTMLWindow3_setTimeout(&This->IHTMLWindow3_iface, &expr_var, msec, language, timerID);
561 }
562
563 static HRESULT WINAPI HTMLWindow2_clearTimeout(IHTMLWindow2 *iface, LONG timerID)
564 {
565     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
566
567     TRACE("(%p)->(%d)\n", This, timerID);
568
569     return clear_task_timer(&This->inner_window->doc->basedoc, FALSE, timerID);
570 }
571
572 #define MAX_MESSAGE_LEN 2000
573
574 static HRESULT WINAPI HTMLWindow2_alert(IHTMLWindow2 *iface, BSTR message)
575 {
576     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
577     WCHAR title[100], *msg = message;
578     DWORD len;
579
580     TRACE("(%p)->(%s)\n", This, debugstr_w(message));
581
582     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, title,
583                     sizeof(title)/sizeof(WCHAR))) {
584         WARN("Could not load message box title: %d\n", GetLastError());
585         return S_OK;
586     }
587
588     len = SysStringLen(message);
589     if(len > MAX_MESSAGE_LEN) {
590         msg = heap_alloc((MAX_MESSAGE_LEN+1)*sizeof(WCHAR));
591         if(!msg)
592             return E_OUTOFMEMORY;
593         memcpy(msg, message, MAX_MESSAGE_LEN*sizeof(WCHAR));
594         msg[MAX_MESSAGE_LEN] = 0;
595     }
596
597     MessageBoxW(This->outer_window->doc_obj->hwnd, msg, title, MB_ICONWARNING);
598     if(msg != message)
599         heap_free(msg);
600     return S_OK;
601 }
602
603 static HRESULT WINAPI HTMLWindow2_confirm(IHTMLWindow2 *iface, BSTR message,
604         VARIANT_BOOL *confirmed)
605 {
606     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
607     WCHAR wszTitle[100];
608
609     TRACE("(%p)->(%s %p)\n", This, debugstr_w(message), confirmed);
610
611     if(!confirmed) return E_INVALIDARG;
612
613     if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
614                 sizeof(wszTitle)/sizeof(WCHAR))) {
615         WARN("Could not load message box title: %d\n", GetLastError());
616         *confirmed = VARIANT_TRUE;
617         return S_OK;
618     }
619
620     if(MessageBoxW(This->outer_window->doc_obj->hwnd, message, wszTitle,
621                 MB_OKCANCEL|MB_ICONQUESTION)==IDOK)
622         *confirmed = VARIANT_TRUE;
623     else *confirmed = VARIANT_FALSE;
624
625     return S_OK;
626 }
627
628 typedef struct
629 {
630     BSTR message;
631     BSTR dststr;
632     VARIANT *textdata;
633 }prompt_arg;
634
635 static INT_PTR CALLBACK prompt_dlgproc(HWND hwnd, UINT msg,
636         WPARAM wparam, LPARAM lparam)
637 {
638     switch(msg)
639     {
640         case WM_INITDIALOG:
641         {
642             prompt_arg *arg = (prompt_arg*)lparam;
643             WCHAR wszTitle[100];
644
645             if(!LoadStringW(get_shdoclc(), IDS_MESSAGE_BOX_TITLE, wszTitle,
646                         sizeof(wszTitle)/sizeof(WCHAR))) {
647                 WARN("Could not load message box title: %d\n", GetLastError());
648                 EndDialog(hwnd, wparam);
649                 return FALSE;
650             }
651
652             SetWindowLongPtrW(hwnd, DWLP_USER, lparam);
653             SetWindowTextW(hwnd, wszTitle);
654             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_PROMPT), arg->message);
655             SetWindowTextW(GetDlgItem(hwnd, ID_PROMPT_EDIT), arg->dststr);
656             return FALSE;
657         }
658         case WM_COMMAND:
659             switch(wparam)
660             {
661                 case MAKEWPARAM(IDCANCEL, BN_CLICKED):
662                     EndDialog(hwnd, wparam);
663                     return TRUE;
664                 case MAKEWPARAM(IDOK, BN_CLICKED):
665                 {
666                     prompt_arg *arg =
667                         (prompt_arg*)GetWindowLongPtrW(hwnd, DWLP_USER);
668                     HWND hwndPrompt = GetDlgItem(hwnd, ID_PROMPT_EDIT);
669                     INT len = GetWindowTextLengthW(hwndPrompt);
670
671                     if(!arg->textdata)
672                     {
673                         EndDialog(hwnd, wparam);
674                         return TRUE;
675                     }
676
677                     V_VT(arg->textdata) = VT_BSTR;
678                     if(!len && !arg->dststr)
679                         V_BSTR(arg->textdata) = NULL;
680                     else
681                     {
682                         V_BSTR(arg->textdata) = SysAllocStringLen(NULL, len);
683                         GetWindowTextW(hwndPrompt, V_BSTR(arg->textdata), len+1);
684                     }
685                     EndDialog(hwnd, wparam);
686                     return TRUE;
687                 }
688             }
689             return FALSE;
690         case WM_CLOSE:
691             EndDialog(hwnd, IDCANCEL);
692             return TRUE;
693         default:
694             return FALSE;
695     }
696 }
697
698 static HRESULT WINAPI HTMLWindow2_prompt(IHTMLWindow2 *iface, BSTR message,
699         BSTR dststr, VARIANT *textdata)
700 {
701     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
702     prompt_arg arg;
703
704     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(message), debugstr_w(dststr), textdata);
705
706     if(textdata) V_VT(textdata) = VT_NULL;
707
708     arg.message = message;
709     arg.dststr = dststr;
710     arg.textdata = textdata;
711
712     DialogBoxParamW(hInst, MAKEINTRESOURCEW(ID_PROMPT_DIALOG),
713             This->outer_window->doc_obj->hwnd, prompt_dlgproc, (LPARAM)&arg);
714     return S_OK;
715 }
716
717 static HRESULT WINAPI HTMLWindow2_get_Image(IHTMLWindow2 *iface, IHTMLImageElementFactory **p)
718 {
719     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
720     HTMLInnerWindow *window = This->inner_window;
721
722     TRACE("(%p)->(%p)\n", This, p);
723
724     if(!window->image_factory) {
725         HRESULT hres;
726
727         hres = HTMLImageElementFactory_Create(window, &window->image_factory);
728         if(FAILED(hres))
729             return hres;
730     }
731
732     *p = &window->image_factory->IHTMLImageElementFactory_iface;
733     IHTMLImageElementFactory_AddRef(*p);
734
735     return S_OK;
736 }
737
738 static HRESULT WINAPI HTMLWindow2_get_location(IHTMLWindow2 *iface, IHTMLLocation **p)
739 {
740     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
741     HTMLLocation *location;
742     HRESULT hres;
743
744     TRACE("(%p)->(%p)\n", This, p);
745
746     hres = get_location(This->inner_window, &location);
747     if(FAILED(hres))
748         return hres;
749
750     *p = &location->IHTMLLocation_iface;
751     return S_OK;
752 }
753
754 static HRESULT WINAPI HTMLWindow2_get_history(IHTMLWindow2 *iface, IOmHistory **p)
755 {
756     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
757     HTMLInnerWindow *window = This->inner_window;
758
759     TRACE("(%p)->(%p)\n", This, p);
760
761     if(!window->history) {
762         HRESULT hres;
763
764         hres = create_history(&window->history);
765         if(FAILED(hres))
766             return hres;
767     }
768
769     IOmHistory_AddRef(window->history);
770     *p = window->history;
771     return S_OK;
772 }
773
774 static HRESULT WINAPI HTMLWindow2_close(IHTMLWindow2 *iface)
775 {
776     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
777     FIXME("(%p)->()\n", This);
778     return E_NOTIMPL;
779 }
780
781 static HRESULT WINAPI HTMLWindow2_put_opener(IHTMLWindow2 *iface, VARIANT v)
782 {
783     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
784     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
785     return E_NOTIMPL;
786 }
787
788 static HRESULT WINAPI HTMLWindow2_get_opener(IHTMLWindow2 *iface, VARIANT *p)
789 {
790     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
791
792     FIXME("(%p)->(%p) returning empty\n", This, p);
793
794     V_VT(p) = VT_EMPTY;
795     return S_OK;
796 }
797
798 static HRESULT WINAPI HTMLWindow2_get_navigator(IHTMLWindow2 *iface, IOmNavigator **p)
799 {
800     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
801
802     TRACE("(%p)->(%p)\n", This, p);
803
804     *p = OmNavigator_Create();
805     return S_OK;
806 }
807
808 static HRESULT WINAPI HTMLWindow2_put_name(IHTMLWindow2 *iface, BSTR v)
809 {
810     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
811     nsAString name_str;
812     nsresult nsres;
813
814     TRACE("(%p)->(%s)\n", This, debugstr_w(v));
815
816     nsAString_InitDepend(&name_str, v);
817     nsres = nsIDOMWindow_SetName(This->outer_window->nswindow, &name_str);
818     nsAString_Finish(&name_str);
819     if(NS_FAILED(nsres))
820         ERR("SetName failed: %08x\n", nsres);
821
822     return S_OK;
823 }
824
825 static HRESULT WINAPI HTMLWindow2_get_name(IHTMLWindow2 *iface, BSTR *p)
826 {
827     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
828     nsAString name_str;
829     nsresult nsres;
830
831     TRACE("(%p)->(%p)\n", This, p);
832
833     nsAString_Init(&name_str, NULL);
834     nsres = nsIDOMWindow_GetName(This->outer_window->nswindow, &name_str);
835     return return_nsstr(nsres, &name_str, p);
836 }
837
838 static HRESULT WINAPI HTMLWindow2_get_parent(IHTMLWindow2 *iface, IHTMLWindow2 **p)
839 {
840     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
841     HTMLOuterWindow *window = This->outer_window;
842
843     TRACE("(%p)->(%p)\n", This, p);
844
845     if(!window->parent)
846         return IHTMLWindow2_get_self(&This->IHTMLWindow2_iface, p);
847
848     *p = &window->parent->base.IHTMLWindow2_iface;
849     IHTMLWindow2_AddRef(*p);
850     return S_OK;
851 }
852
853 static HRESULT WINAPI HTMLWindow2_open(IHTMLWindow2 *iface, BSTR url, BSTR name,
854          BSTR features, VARIANT_BOOL replace, IHTMLWindow2 **pomWindowResult)
855 {
856     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
857     HTMLOuterWindow *window = This->outer_window;
858     INewWindowManager *new_window_mgr;
859     IUri *uri;
860     HRESULT hres;
861
862     TRACE("(%p)->(%s %s %s %x %p)\n", This, debugstr_w(url), debugstr_w(name),
863           debugstr_w(features), replace, pomWindowResult);
864
865     if(!window->doc_obj)
866         return E_UNEXPECTED;
867
868     if(name && *name == '_') {
869         FIXME("Unsupported name %s\n", debugstr_w(name));
870         return E_NOTIMPL;
871     }
872
873     hres = do_query_service((IUnknown*)window->doc_obj->client, &SID_SNewWindowManager, &IID_INewWindowManager,
874             (void**)&new_window_mgr);
875     if(FAILED(hres)) {
876         FIXME("No INewWindowManager\n");
877         return E_NOTIMPL;
878     }
879
880     hres = INewWindowManager_EvaluateNewWindow(new_window_mgr, url, name, window->url,
881             features, !!replace, window->doc_obj->has_popup ? 0 : NWMF_FIRST, 0);
882     INewWindowManager_Release(new_window_mgr);
883     window->doc_obj->has_popup = TRUE;
884     if(FAILED(hres)) {
885         *pomWindowResult = NULL;
886         return S_OK;
887     }
888
889     hres = create_relative_uri(window, url, &uri);
890     if(FAILED(hres))
891         return hres;
892
893     hres = navigate_new_window(window, uri, name, pomWindowResult);
894     IUri_Release(uri);
895     return hres;
896 }
897
898 static HRESULT WINAPI HTMLWindow2_get_self(IHTMLWindow2 *iface, IHTMLWindow2 **p)
899 {
900     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
901
902     TRACE("(%p)->(%p)\n", This, p);
903
904     /* FIXME: We should return kind of proxy window here. */
905     IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
906     *p = &This->IHTMLWindow2_iface;
907     return S_OK;
908 }
909
910 static HRESULT WINAPI HTMLWindow2_get_top(IHTMLWindow2 *iface, IHTMLWindow2 **p)
911 {
912     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
913     HTMLOuterWindow *top;
914
915     TRACE("(%p)->(%p)\n", This, p);
916
917     get_top_window(This->outer_window, &top);
918     *p = &top->base.IHTMLWindow2_iface;
919     IHTMLWindow2_AddRef(*p);
920
921     return S_OK;
922 }
923
924 static HRESULT WINAPI HTMLWindow2_get_window(IHTMLWindow2 *iface, IHTMLWindow2 **p)
925 {
926     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
927
928     TRACE("(%p)->(%p)\n", This, p);
929
930     /* FIXME: We should return kind of proxy window here. */
931     IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
932     *p = &This->IHTMLWindow2_iface;
933     return S_OK;
934 }
935
936 static HRESULT WINAPI HTMLWindow2_navigate(IHTMLWindow2 *iface, BSTR url)
937 {
938     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
939     FIXME("(%p)->(%s)\n", This, debugstr_w(url));
940     return E_NOTIMPL;
941 }
942
943 static HRESULT WINAPI HTMLWindow2_put_onfocus(IHTMLWindow2 *iface, VARIANT v)
944 {
945     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
946     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
947     return E_NOTIMPL;
948 }
949
950 static HRESULT WINAPI HTMLWindow2_get_onfocus(IHTMLWindow2 *iface, VARIANT *p)
951 {
952     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
953     FIXME("(%p)->(%p)\n", This, p);
954     return E_NOTIMPL;
955 }
956
957 static HRESULT WINAPI HTMLWindow2_put_onblur(IHTMLWindow2 *iface, VARIANT v)
958 {
959     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
960     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
961     return E_NOTIMPL;
962 }
963
964 static HRESULT WINAPI HTMLWindow2_get_onblur(IHTMLWindow2 *iface, VARIANT *p)
965 {
966     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
967     FIXME("(%p)->(%p)\n", This, p);
968     return E_NOTIMPL;
969 }
970
971 static HRESULT WINAPI HTMLWindow2_put_onload(IHTMLWindow2 *iface, VARIANT v)
972 {
973     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
974
975     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
976
977     return set_window_event(This, EVENTID_LOAD, &v);
978 }
979
980 static HRESULT WINAPI HTMLWindow2_get_onload(IHTMLWindow2 *iface, VARIANT *p)
981 {
982     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
983
984     TRACE("(%p)->(%p)\n", This, p);
985
986     return get_window_event(This, EVENTID_LOAD, p);
987 }
988
989 static HRESULT WINAPI HTMLWindow2_put_onbeforeunload(IHTMLWindow2 *iface, VARIANT v)
990 {
991     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
992
993     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
994
995     return set_window_event(This, EVENTID_BEFOREUNLOAD, &v);
996 }
997
998 static HRESULT WINAPI HTMLWindow2_get_onbeforeunload(IHTMLWindow2 *iface, VARIANT *p)
999 {
1000     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1001
1002     TRACE("(%p)->(%p)\n", This, p);
1003
1004     return get_window_event(This, EVENTID_BEFOREUNLOAD, p);
1005 }
1006
1007 static HRESULT WINAPI HTMLWindow2_put_onunload(IHTMLWindow2 *iface, VARIANT v)
1008 {
1009     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1010     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1011     return E_NOTIMPL;
1012 }
1013
1014 static HRESULT WINAPI HTMLWindow2_get_onunload(IHTMLWindow2 *iface, VARIANT *p)
1015 {
1016     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1017     FIXME("(%p)->(%p)\n", This, p);
1018     return E_NOTIMPL;
1019 }
1020
1021 static HRESULT WINAPI HTMLWindow2_put_onhelp(IHTMLWindow2 *iface, VARIANT v)
1022 {
1023     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1024
1025     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1026
1027     return set_window_event(This, EVENTID_HELP, &v);
1028 }
1029
1030 static HRESULT WINAPI HTMLWindow2_get_onhelp(IHTMLWindow2 *iface, VARIANT *p)
1031 {
1032     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1033
1034     TRACE("(%p)->(%p)\n", This, p);
1035
1036     return get_window_event(This, EVENTID_HELP, p);
1037 }
1038
1039 static HRESULT WINAPI HTMLWindow2_put_onerror(IHTMLWindow2 *iface, VARIANT v)
1040 {
1041     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1042
1043     FIXME("(%p)->(%s) semi-stub\n", This, debugstr_variant(&v));
1044
1045     return set_window_event(This, EVENTID_ERROR, &v);
1046 }
1047
1048 static HRESULT WINAPI HTMLWindow2_get_onerror(IHTMLWindow2 *iface, VARIANT *p)
1049 {
1050     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1051
1052     TRACE("(%p)->(%p)\n", This, p);
1053
1054     return get_window_event(This, EVENTID_ERROR, p);
1055 }
1056
1057 static HRESULT WINAPI HTMLWindow2_put_onresize(IHTMLWindow2 *iface, VARIANT v)
1058 {
1059     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1060
1061     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1062
1063     return set_window_event(This, EVENTID_RESIZE, &v);
1064 }
1065
1066 static HRESULT WINAPI HTMLWindow2_get_onresize(IHTMLWindow2 *iface, VARIANT *p)
1067 {
1068     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1069
1070     TRACE("(%p)->(%p)\n", This, p);
1071
1072     return get_window_event(This, EVENTID_RESIZE, p);
1073 }
1074
1075 static HRESULT WINAPI HTMLWindow2_put_onscroll(IHTMLWindow2 *iface, VARIANT v)
1076 {
1077     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1078
1079     TRACE("(%p)->(%s)\n", This, debugstr_variant(&v));
1080
1081     return set_window_event(This, EVENTID_SCROLL, &v);
1082 }
1083
1084 static HRESULT WINAPI HTMLWindow2_get_onscroll(IHTMLWindow2 *iface, VARIANT *p)
1085 {
1086     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1087
1088     TRACE("(%p)->(%p)\n", This, p);
1089
1090     return get_window_event(This, EVENTID_SCROLL, p);
1091 }
1092
1093 static HRESULT WINAPI HTMLWindow2_get_document(IHTMLWindow2 *iface, IHTMLDocument2 **p)
1094 {
1095     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1096
1097     TRACE("(%p)->(%p)\n", This, p);
1098
1099     if(This->inner_window->doc) {
1100         /* FIXME: We should return a wrapper object here */
1101         *p = &This->inner_window->doc->basedoc.IHTMLDocument2_iface;
1102         IHTMLDocument2_AddRef(*p);
1103     }else {
1104         *p = NULL;
1105     }
1106
1107     return S_OK;
1108 }
1109
1110 static HRESULT WINAPI HTMLWindow2_get_event(IHTMLWindow2 *iface, IHTMLEventObj **p)
1111 {
1112     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1113     HTMLInnerWindow *window = This->inner_window;
1114
1115     TRACE("(%p)->(%p)\n", This, p);
1116
1117     if(window->event)
1118         IHTMLEventObj_AddRef(window->event);
1119     *p = window->event;
1120     return S_OK;
1121 }
1122
1123 static HRESULT WINAPI HTMLWindow2_get__newEnum(IHTMLWindow2 *iface, IUnknown **p)
1124 {
1125     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1126     FIXME("(%p)->(%p)\n", This, p);
1127     return E_NOTIMPL;
1128 }
1129
1130 static HRESULT WINAPI HTMLWindow2_showModalDialog(IHTMLWindow2 *iface, BSTR dialog,
1131         VARIANT *varArgIn, VARIANT *varOptions, VARIANT *varArgOut)
1132 {
1133     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1134     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(dialog), varArgIn, varOptions, varArgOut);
1135     return E_NOTIMPL;
1136 }
1137
1138 static HRESULT WINAPI HTMLWindow2_showHelp(IHTMLWindow2 *iface, BSTR helpURL, VARIANT helpArg,
1139         BSTR features)
1140 {
1141     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1142     FIXME("(%p)->(%s %s %s)\n", This, debugstr_w(helpURL), debugstr_variant(&helpArg), debugstr_w(features));
1143     return E_NOTIMPL;
1144 }
1145
1146 static HRESULT WINAPI HTMLWindow2_get_screen(IHTMLWindow2 *iface, IHTMLScreen **p)
1147 {
1148     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1149     HTMLInnerWindow *window = This->inner_window;
1150
1151     TRACE("(%p)->(%p)\n", This, p);
1152
1153     if(!window->screen) {
1154         HRESULT hres;
1155
1156         hres = HTMLScreen_Create(&window->screen);
1157         if(FAILED(hres))
1158             return hres;
1159     }
1160
1161     *p = window->screen;
1162     IHTMLScreen_AddRef(window->screen);
1163     return S_OK;
1164 }
1165
1166 static HRESULT WINAPI HTMLWindow2_get_Option(IHTMLWindow2 *iface, IHTMLOptionElementFactory **p)
1167 {
1168     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1169     HTMLInnerWindow *window = This->inner_window;
1170
1171     TRACE("(%p)->(%p)\n", This, p);
1172
1173     if(!window->option_factory) {
1174         HRESULT hres;
1175
1176         hres = HTMLOptionElementFactory_Create(window, &window->option_factory);
1177         if(FAILED(hres))
1178             return hres;
1179     }
1180
1181     *p = &window->option_factory->IHTMLOptionElementFactory_iface;
1182     IHTMLOptionElementFactory_AddRef(*p);
1183
1184     return S_OK;
1185 }
1186
1187 static HRESULT WINAPI HTMLWindow2_focus(IHTMLWindow2 *iface)
1188 {
1189     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1190
1191     TRACE("(%p)->()\n", This);
1192
1193     if(This->outer_window->doc_obj)
1194         SetFocus(This->outer_window->doc_obj->hwnd);
1195     return S_OK;
1196 }
1197
1198 static HRESULT WINAPI HTMLWindow2_get_closed(IHTMLWindow2 *iface, VARIANT_BOOL *p)
1199 {
1200     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1201     FIXME("(%p)->(%p)\n", This, p);
1202     return E_NOTIMPL;
1203 }
1204
1205 static HRESULT WINAPI HTMLWindow2_blur(IHTMLWindow2 *iface)
1206 {
1207     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1208     FIXME("(%p)->()\n", This);
1209     return E_NOTIMPL;
1210 }
1211
1212 static HRESULT WINAPI HTMLWindow2_scroll(IHTMLWindow2 *iface, LONG x, LONG y)
1213 {
1214     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1215     FIXME("(%p)->(%d %d)\n", This, x, y);
1216     return E_NOTIMPL;
1217 }
1218
1219 static HRESULT WINAPI HTMLWindow2_get_clientInformation(IHTMLWindow2 *iface, IOmNavigator **p)
1220 {
1221     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1222     FIXME("(%p)->(%p)\n", This, p);
1223     return E_NOTIMPL;
1224 }
1225
1226 static HRESULT WINAPI HTMLWindow2_setInterval(IHTMLWindow2 *iface, BSTR expression,
1227         LONG msec, VARIANT *language, LONG *timerID)
1228 {
1229     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1230     VARIANT expr;
1231
1232     TRACE("(%p)->(%s %d %p %p)\n", This, debugstr_w(expression), msec, language, timerID);
1233
1234     V_VT(&expr) = VT_BSTR;
1235     V_BSTR(&expr) = expression;
1236     return IHTMLWindow3_setInterval(&This->IHTMLWindow3_iface, &expr, msec, language, timerID);
1237 }
1238
1239 static HRESULT WINAPI HTMLWindow2_clearInterval(IHTMLWindow2 *iface, LONG timerID)
1240 {
1241     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1242
1243     TRACE("(%p)->(%d)\n", This, timerID);
1244
1245     return clear_task_timer(&This->inner_window->doc->basedoc, TRUE, timerID);
1246 }
1247
1248 static HRESULT WINAPI HTMLWindow2_put_offscreenBuffering(IHTMLWindow2 *iface, VARIANT v)
1249 {
1250     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1251     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1252     return E_NOTIMPL;
1253 }
1254
1255 static HRESULT WINAPI HTMLWindow2_get_offscreenBuffering(IHTMLWindow2 *iface, VARIANT *p)
1256 {
1257     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1258     FIXME("(%p)->(%p)\n", This, p);
1259     return E_NOTIMPL;
1260 }
1261
1262 static HRESULT WINAPI HTMLWindow2_execScript(IHTMLWindow2 *iface, BSTR scode, BSTR language,
1263         VARIANT *pvarRet)
1264 {
1265     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1266
1267     TRACE("(%p)->(%s %s %p)\n", This, debugstr_w(scode), debugstr_w(language), pvarRet);
1268
1269     return exec_script(This->inner_window, scode, language, pvarRet);
1270 }
1271
1272 static HRESULT WINAPI HTMLWindow2_toString(IHTMLWindow2 *iface, BSTR *String)
1273 {
1274     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1275
1276     static const WCHAR objectW[] = {'[','o','b','j','e','c','t',']',0};
1277
1278     TRACE("(%p)->(%p)\n", This, String);
1279
1280     if(!String)
1281         return E_INVALIDARG;
1282
1283     *String = SysAllocString(objectW);
1284     return *String ? S_OK : E_OUTOFMEMORY;
1285 }
1286
1287 static HRESULT WINAPI HTMLWindow2_scrollBy(IHTMLWindow2 *iface, LONG x, LONG y)
1288 {
1289     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1290     nsresult nsres;
1291
1292     TRACE("(%p)->(%d %d)\n", This, x, y);
1293
1294     nsres = nsIDOMWindow_ScrollBy(This->outer_window->nswindow, x, y);
1295     if(NS_FAILED(nsres))
1296         ERR("ScrollBy failed: %08x\n", nsres);
1297
1298     return S_OK;
1299 }
1300
1301 static HRESULT WINAPI HTMLWindow2_scrollTo(IHTMLWindow2 *iface, LONG x, LONG y)
1302 {
1303     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1304     nsresult nsres;
1305
1306     TRACE("(%p)->(%d %d)\n", This, x, y);
1307
1308     nsres = nsIDOMWindow_ScrollTo(This->outer_window->nswindow, x, y);
1309     if(NS_FAILED(nsres))
1310         ERR("ScrollTo failed: %08x\n", nsres);
1311
1312     return S_OK;
1313 }
1314
1315 static HRESULT WINAPI HTMLWindow2_moveTo(IHTMLWindow2 *iface, LONG x, LONG y)
1316 {
1317     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1318     FIXME("(%p)->(%d %d)\n", This, x, y);
1319     return E_NOTIMPL;
1320 }
1321
1322 static HRESULT WINAPI HTMLWindow2_moveBy(IHTMLWindow2 *iface, LONG x, LONG y)
1323 {
1324     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1325     FIXME("(%p)->(%d %d)\n", This, x, y);
1326     return E_NOTIMPL;
1327 }
1328
1329 static HRESULT WINAPI HTMLWindow2_resizeTo(IHTMLWindow2 *iface, LONG x, LONG y)
1330 {
1331     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1332     FIXME("(%p)->(%d %d)\n", This, x, y);
1333     return E_NOTIMPL;
1334 }
1335
1336 static HRESULT WINAPI HTMLWindow2_resizeBy(IHTMLWindow2 *iface, LONG x, LONG y)
1337 {
1338     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1339     FIXME("(%p)->(%d %d)\n", This, x, y);
1340     return E_NOTIMPL;
1341 }
1342
1343 static HRESULT WINAPI HTMLWindow2_get_external(IHTMLWindow2 *iface, IDispatch **p)
1344 {
1345     HTMLWindow *This = impl_from_IHTMLWindow2(iface);
1346
1347     TRACE("(%p)->(%p)\n", This, p);
1348
1349     *p = NULL;
1350
1351     if(!This->outer_window->doc_obj->hostui)
1352         return S_OK;
1353
1354     return IDocHostUIHandler_GetExternal(This->outer_window->doc_obj->hostui, p);
1355 }
1356
1357 static const IHTMLWindow2Vtbl HTMLWindow2Vtbl = {
1358     HTMLWindow2_QueryInterface,
1359     HTMLWindow2_AddRef,
1360     HTMLWindow2_Release,
1361     HTMLWindow2_GetTypeInfoCount,
1362     HTMLWindow2_GetTypeInfo,
1363     HTMLWindow2_GetIDsOfNames,
1364     HTMLWindow2_Invoke,
1365     HTMLWindow2_item,
1366     HTMLWindow2_get_length,
1367     HTMLWindow2_get_frames,
1368     HTMLWindow2_put_defaultStatus,
1369     HTMLWindow2_get_defaultStatus,
1370     HTMLWindow2_put_status,
1371     HTMLWindow2_get_status,
1372     HTMLWindow2_setTimeout,
1373     HTMLWindow2_clearTimeout,
1374     HTMLWindow2_alert,
1375     HTMLWindow2_confirm,
1376     HTMLWindow2_prompt,
1377     HTMLWindow2_get_Image,
1378     HTMLWindow2_get_location,
1379     HTMLWindow2_get_history,
1380     HTMLWindow2_close,
1381     HTMLWindow2_put_opener,
1382     HTMLWindow2_get_opener,
1383     HTMLWindow2_get_navigator,
1384     HTMLWindow2_put_name,
1385     HTMLWindow2_get_name,
1386     HTMLWindow2_get_parent,
1387     HTMLWindow2_open,
1388     HTMLWindow2_get_self,
1389     HTMLWindow2_get_top,
1390     HTMLWindow2_get_window,
1391     HTMLWindow2_navigate,
1392     HTMLWindow2_put_onfocus,
1393     HTMLWindow2_get_onfocus,
1394     HTMLWindow2_put_onblur,
1395     HTMLWindow2_get_onblur,
1396     HTMLWindow2_put_onload,
1397     HTMLWindow2_get_onload,
1398     HTMLWindow2_put_onbeforeunload,
1399     HTMLWindow2_get_onbeforeunload,
1400     HTMLWindow2_put_onunload,
1401     HTMLWindow2_get_onunload,
1402     HTMLWindow2_put_onhelp,
1403     HTMLWindow2_get_onhelp,
1404     HTMLWindow2_put_onerror,
1405     HTMLWindow2_get_onerror,
1406     HTMLWindow2_put_onresize,
1407     HTMLWindow2_get_onresize,
1408     HTMLWindow2_put_onscroll,
1409     HTMLWindow2_get_onscroll,
1410     HTMLWindow2_get_document,
1411     HTMLWindow2_get_event,
1412     HTMLWindow2_get__newEnum,
1413     HTMLWindow2_showModalDialog,
1414     HTMLWindow2_showHelp,
1415     HTMLWindow2_get_screen,
1416     HTMLWindow2_get_Option,
1417     HTMLWindow2_focus,
1418     HTMLWindow2_get_closed,
1419     HTMLWindow2_blur,
1420     HTMLWindow2_scroll,
1421     HTMLWindow2_get_clientInformation,
1422     HTMLWindow2_setInterval,
1423     HTMLWindow2_clearInterval,
1424     HTMLWindow2_put_offscreenBuffering,
1425     HTMLWindow2_get_offscreenBuffering,
1426     HTMLWindow2_execScript,
1427     HTMLWindow2_toString,
1428     HTMLWindow2_scrollBy,
1429     HTMLWindow2_scrollTo,
1430     HTMLWindow2_moveTo,
1431     HTMLWindow2_moveBy,
1432     HTMLWindow2_resizeTo,
1433     HTMLWindow2_resizeBy,
1434     HTMLWindow2_get_external
1435 };
1436
1437 static inline HTMLWindow *impl_from_IHTMLWindow3(IHTMLWindow3 *iface)
1438 {
1439     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow3_iface);
1440 }
1441
1442 static HRESULT WINAPI HTMLWindow3_QueryInterface(IHTMLWindow3 *iface, REFIID riid, void **ppv)
1443 {
1444     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1445
1446     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1447 }
1448
1449 static ULONG WINAPI HTMLWindow3_AddRef(IHTMLWindow3 *iface)
1450 {
1451     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1452
1453     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1454 }
1455
1456 static ULONG WINAPI HTMLWindow3_Release(IHTMLWindow3 *iface)
1457 {
1458     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1459
1460     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1461 }
1462
1463 static HRESULT WINAPI HTMLWindow3_GetTypeInfoCount(IHTMLWindow3 *iface, UINT *pctinfo)
1464 {
1465     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1466
1467     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1468 }
1469
1470 static HRESULT WINAPI HTMLWindow3_GetTypeInfo(IHTMLWindow3 *iface, UINT iTInfo,
1471                                               LCID lcid, ITypeInfo **ppTInfo)
1472 {
1473     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1474
1475     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1476 }
1477
1478 static HRESULT WINAPI HTMLWindow3_GetIDsOfNames(IHTMLWindow3 *iface, REFIID riid,
1479                                                 LPOLESTR *rgszNames, UINT cNames,
1480                                                 LCID lcid, DISPID *rgDispId)
1481 {
1482     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1483
1484     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1485             rgDispId);
1486 }
1487
1488 static HRESULT WINAPI HTMLWindow3_Invoke(IHTMLWindow3 *iface, DISPID dispIdMember,
1489                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1490                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1491 {
1492     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1493
1494     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1495             pDispParams, pVarResult, pExcepInfo, puArgErr);
1496 }
1497
1498 static HRESULT WINAPI HTMLWindow3_get_screenLeft(IHTMLWindow3 *iface, LONG *p)
1499 {
1500     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1501     FIXME("(%p)->(%p)\n", This, p);
1502     return E_NOTIMPL;
1503 }
1504
1505 static HRESULT WINAPI HTMLWindow3_get_screenTop(IHTMLWindow3 *iface, LONG *p)
1506 {
1507     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1508     FIXME("(%p)->(%p)\n", This, p);
1509     return E_NOTIMPL;
1510 }
1511
1512 static HRESULT WINAPI HTMLWindow3_attachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp, VARIANT_BOOL *pfResult)
1513 {
1514     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1515     HTMLInnerWindow *window = This->inner_window;
1516
1517     TRACE("(%p)->(%s %p %p)\n", This, debugstr_w(event), pDisp, pfResult);
1518
1519     if(!window->doc) {
1520         FIXME("No document\n");
1521         return E_FAIL;
1522     }
1523
1524     return attach_event(&window->doc->body_event_target, NULL, &window->doc->basedoc, event, pDisp, pfResult);
1525 }
1526
1527 static HRESULT WINAPI HTMLWindow3_detachEvent(IHTMLWindow3 *iface, BSTR event, IDispatch *pDisp)
1528 {
1529     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1530     HTMLInnerWindow *window = This->inner_window;
1531
1532     TRACE("(%p)->()\n", This);
1533
1534     if(!window->doc) {
1535         FIXME("No document\n");
1536         return E_FAIL;
1537     }
1538
1539     return detach_event(window->doc->body_event_target, &window->doc->basedoc, event, pDisp);
1540 }
1541
1542 static HRESULT window_set_timer(HTMLInnerWindow *This, VARIANT *expr, LONG msec, VARIANT *language,
1543         BOOL interval, LONG *timer_id)
1544 {
1545     IDispatch *disp = NULL;
1546
1547     switch(V_VT(expr)) {
1548     case VT_DISPATCH:
1549         disp = V_DISPATCH(expr);
1550         IDispatch_AddRef(disp);
1551         break;
1552
1553     case VT_BSTR:
1554         disp = script_parse_event(This->base.inner_window, V_BSTR(expr));
1555         break;
1556
1557     default:
1558         FIXME("unimplemented expr %s\n", debugstr_variant(expr));
1559         return E_NOTIMPL;
1560     }
1561
1562     if(!disp)
1563         return E_FAIL;
1564
1565     *timer_id = set_task_timer(&This->doc->basedoc, msec, interval, disp);
1566     IDispatch_Release(disp);
1567
1568     return S_OK;
1569 }
1570
1571 static HRESULT WINAPI HTMLWindow3_setTimeout(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1572         VARIANT *language, LONG *timerID)
1573 {
1574     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1575
1576     TRACE("(%p)->(%s %d %s %p)\n", This, debugstr_variant(expression), msec, debugstr_variant(language), timerID);
1577
1578     return window_set_timer(This->inner_window, expression, msec, language, FALSE, timerID);
1579 }
1580
1581 static HRESULT WINAPI HTMLWindow3_setInterval(IHTMLWindow3 *iface, VARIANT *expression, LONG msec,
1582         VARIANT *language, LONG *timerID)
1583 {
1584     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1585
1586     TRACE("(%p)->(%p %d %p %p)\n", This, expression, msec, language, timerID);
1587
1588     return window_set_timer(This->inner_window, expression, msec, language, TRUE, timerID);
1589 }
1590
1591 static HRESULT WINAPI HTMLWindow3_print(IHTMLWindow3 *iface)
1592 {
1593     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1594     FIXME("(%p)\n", This);
1595     return E_NOTIMPL;
1596 }
1597
1598 static HRESULT WINAPI HTMLWindow3_put_onbeforeprint(IHTMLWindow3 *iface, VARIANT v)
1599 {
1600     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1601     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1602     return E_NOTIMPL;
1603 }
1604
1605 static HRESULT WINAPI HTMLWindow3_get_onbeforeprint(IHTMLWindow3 *iface, VARIANT *p)
1606 {
1607     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1608     FIXME("(%p)->(%p)\n", This, p);
1609     return E_NOTIMPL;
1610 }
1611
1612 static HRESULT WINAPI HTMLWindow3_put_onafterprint(IHTMLWindow3 *iface, VARIANT v)
1613 {
1614     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1615     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1616     return E_NOTIMPL;
1617 }
1618
1619 static HRESULT WINAPI HTMLWindow3_get_onafterprint(IHTMLWindow3 *iface, VARIANT *p)
1620 {
1621     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1622     FIXME("(%p)->(%p)\n", This, p);
1623     return E_NOTIMPL;
1624 }
1625
1626 static HRESULT WINAPI HTMLWindow3_get_clipboardData(IHTMLWindow3 *iface, IHTMLDataTransfer **p)
1627 {
1628     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1629     FIXME("(%p)->(%p)\n", This, p);
1630     return E_NOTIMPL;
1631 }
1632
1633 static HRESULT WINAPI HTMLWindow3_showModelessDialog(IHTMLWindow3 *iface, BSTR url,
1634         VARIANT *varArgIn, VARIANT *options, IHTMLWindow2 **pDialog)
1635 {
1636     HTMLWindow *This = impl_from_IHTMLWindow3(iface);
1637     FIXME("(%p)->(%s %p %p %p)\n", This, debugstr_w(url), varArgIn, options, pDialog);
1638     return E_NOTIMPL;
1639 }
1640
1641 static const IHTMLWindow3Vtbl HTMLWindow3Vtbl = {
1642     HTMLWindow3_QueryInterface,
1643     HTMLWindow3_AddRef,
1644     HTMLWindow3_Release,
1645     HTMLWindow3_GetTypeInfoCount,
1646     HTMLWindow3_GetTypeInfo,
1647     HTMLWindow3_GetIDsOfNames,
1648     HTMLWindow3_Invoke,
1649     HTMLWindow3_get_screenLeft,
1650     HTMLWindow3_get_screenTop,
1651     HTMLWindow3_attachEvent,
1652     HTMLWindow3_detachEvent,
1653     HTMLWindow3_setTimeout,
1654     HTMLWindow3_setInterval,
1655     HTMLWindow3_print,
1656     HTMLWindow3_put_onbeforeprint,
1657     HTMLWindow3_get_onbeforeprint,
1658     HTMLWindow3_put_onafterprint,
1659     HTMLWindow3_get_onafterprint,
1660     HTMLWindow3_get_clipboardData,
1661     HTMLWindow3_showModelessDialog
1662 };
1663
1664 static inline HTMLWindow *impl_from_IHTMLWindow4(IHTMLWindow4 *iface)
1665 {
1666     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow4_iface);
1667 }
1668
1669 static HRESULT WINAPI HTMLWindow4_QueryInterface(IHTMLWindow4 *iface, REFIID riid, void **ppv)
1670 {
1671     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1672
1673     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1674 }
1675
1676 static ULONG WINAPI HTMLWindow4_AddRef(IHTMLWindow4 *iface)
1677 {
1678     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1679
1680     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1681 }
1682
1683 static ULONG WINAPI HTMLWindow4_Release(IHTMLWindow4 *iface)
1684 {
1685     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1686
1687     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1688 }
1689
1690 static HRESULT WINAPI HTMLWindow4_GetTypeInfoCount(IHTMLWindow4 *iface, UINT *pctinfo)
1691 {
1692     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1693
1694     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1695 }
1696
1697 static HRESULT WINAPI HTMLWindow4_GetTypeInfo(IHTMLWindow4 *iface, UINT iTInfo,
1698                                               LCID lcid, ITypeInfo **ppTInfo)
1699 {
1700     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1701
1702     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1703 }
1704
1705 static HRESULT WINAPI HTMLWindow4_GetIDsOfNames(IHTMLWindow4 *iface, REFIID riid,
1706                                                 LPOLESTR *rgszNames, UINT cNames,
1707                                                 LCID lcid, DISPID *rgDispId)
1708 {
1709     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1710
1711     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1712             rgDispId);
1713 }
1714
1715 static HRESULT WINAPI HTMLWindow4_Invoke(IHTMLWindow4 *iface, DISPID dispIdMember,
1716                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1717                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1718 {
1719     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1720
1721     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1722             pDispParams, pVarResult, pExcepInfo, puArgErr);
1723 }
1724
1725 static HRESULT WINAPI HTMLWindow4_createPopup(IHTMLWindow4 *iface, VARIANT *varArgIn,
1726                             IDispatch **ppPopup)
1727 {
1728     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1729     FIXME("(%p)->(%p %p)\n", This, varArgIn, ppPopup);
1730     return E_NOTIMPL;
1731 }
1732
1733 static HRESULT WINAPI HTMLWindow4_get_frameElement(IHTMLWindow4 *iface, IHTMLFrameBase **p)
1734 {
1735     HTMLWindow *This = impl_from_IHTMLWindow4(iface);
1736     TRACE("(%p)->(%p)\n", This, p);
1737
1738     if(This->outer_window->frame_element) {
1739         *p = &This->outer_window->frame_element->IHTMLFrameBase_iface;
1740         IHTMLFrameBase_AddRef(*p);
1741     }else
1742         *p = NULL;
1743
1744     return S_OK;
1745 }
1746
1747 static const IHTMLWindow4Vtbl HTMLWindow4Vtbl = {
1748     HTMLWindow4_QueryInterface,
1749     HTMLWindow4_AddRef,
1750     HTMLWindow4_Release,
1751     HTMLWindow4_GetTypeInfoCount,
1752     HTMLWindow4_GetTypeInfo,
1753     HTMLWindow4_GetIDsOfNames,
1754     HTMLWindow4_Invoke,
1755     HTMLWindow4_createPopup,
1756     HTMLWindow4_get_frameElement
1757 };
1758
1759 static inline HTMLWindow *impl_from_IHTMLWindow5(IHTMLWindow5 *iface)
1760 {
1761     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow5_iface);
1762 }
1763
1764 static HRESULT WINAPI HTMLWindow5_QueryInterface(IHTMLWindow5 *iface, REFIID riid, void **ppv)
1765 {
1766     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1767
1768     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1769 }
1770
1771 static ULONG WINAPI HTMLWindow5_AddRef(IHTMLWindow5 *iface)
1772 {
1773     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1774
1775     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1776 }
1777
1778 static ULONG WINAPI HTMLWindow5_Release(IHTMLWindow5 *iface)
1779 {
1780     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1781
1782     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1783 }
1784
1785 static HRESULT WINAPI HTMLWindow5_GetTypeInfoCount(IHTMLWindow5 *iface, UINT *pctinfo)
1786 {
1787     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1788
1789     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1790 }
1791
1792 static HRESULT WINAPI HTMLWindow5_GetTypeInfo(IHTMLWindow5 *iface, UINT iTInfo,
1793         LCID lcid, ITypeInfo **ppTInfo)
1794 {
1795     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1796
1797     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1798 }
1799
1800 static HRESULT WINAPI HTMLWindow5_GetIDsOfNames(IHTMLWindow5 *iface, REFIID riid,
1801         LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
1802 {
1803     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1804
1805     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1806             rgDispId);
1807 }
1808
1809 static HRESULT WINAPI HTMLWindow5_Invoke(IHTMLWindow5 *iface, DISPID dispIdMember,
1810         REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1811         VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1812 {
1813     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1814
1815     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1816             pDispParams, pVarResult, pExcepInfo, puArgErr);
1817 }
1818
1819 static HRESULT WINAPI HTMLWindow5_put_XMLHttpRequest(IHTMLWindow5 *iface, VARIANT v)
1820 {
1821     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1822     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1823     return E_NOTIMPL;
1824 }
1825
1826 static HRESULT WINAPI HTMLWindow5_get_XMLHttpRequest(IHTMLWindow5 *iface, VARIANT *p)
1827 {
1828     HTMLWindow *This = impl_from_IHTMLWindow5(iface);
1829     FIXME("(%p)->(%p)\n", This, p);
1830     return E_NOTIMPL;
1831 }
1832
1833 static const IHTMLWindow5Vtbl HTMLWindow5Vtbl = {
1834     HTMLWindow5_QueryInterface,
1835     HTMLWindow5_AddRef,
1836     HTMLWindow5_Release,
1837     HTMLWindow5_GetTypeInfoCount,
1838     HTMLWindow5_GetTypeInfo,
1839     HTMLWindow5_GetIDsOfNames,
1840     HTMLWindow5_Invoke,
1841     HTMLWindow5_put_XMLHttpRequest,
1842     HTMLWindow5_get_XMLHttpRequest
1843 };
1844
1845 static inline HTMLWindow *impl_from_IHTMLWindow6(IHTMLWindow6 *iface)
1846 {
1847     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLWindow6_iface);
1848 }
1849
1850 static HRESULT WINAPI HTMLWindow6_QueryInterface(IHTMLWindow6 *iface, REFIID riid, void **ppv)
1851 {
1852     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1853
1854     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
1855 }
1856
1857 static ULONG WINAPI HTMLWindow6_AddRef(IHTMLWindow6 *iface)
1858 {
1859     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1860
1861     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
1862 }
1863
1864 static ULONG WINAPI HTMLWindow6_Release(IHTMLWindow6 *iface)
1865 {
1866     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1867
1868     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
1869 }
1870
1871 static HRESULT WINAPI HTMLWindow6_GetTypeInfoCount(IHTMLWindow6 *iface, UINT *pctinfo)
1872 {
1873     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1874
1875     return IDispatchEx_GetTypeInfoCount(&This->IDispatchEx_iface, pctinfo);
1876 }
1877
1878 static HRESULT WINAPI HTMLWindow6_GetTypeInfo(IHTMLWindow6 *iface, UINT iTInfo,
1879                                               LCID lcid, ITypeInfo **ppTInfo)
1880 {
1881     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1882
1883     return IDispatchEx_GetTypeInfo(&This->IDispatchEx_iface, iTInfo, lcid, ppTInfo);
1884 }
1885
1886 static HRESULT WINAPI HTMLWindow6_GetIDsOfNames(IHTMLWindow6 *iface, REFIID riid,
1887                                                 LPOLESTR *rgszNames, UINT cNames,
1888                                                 LCID lcid, DISPID *rgDispId)
1889 {
1890     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1891
1892     return IDispatchEx_GetIDsOfNames(&This->IDispatchEx_iface, riid, rgszNames, cNames, lcid,
1893             rgDispId);
1894 }
1895
1896 static HRESULT WINAPI HTMLWindow6_Invoke(IHTMLWindow6 *iface, DISPID dispIdMember,
1897                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
1898                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
1899 {
1900     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1901
1902     return IDispatchEx_Invoke(&This->IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
1903             pDispParams, pVarResult, pExcepInfo, puArgErr);
1904 }
1905
1906 static HRESULT WINAPI HTMLWindow6_put_XDomainRequest(IHTMLWindow6 *iface, VARIANT v)
1907 {
1908     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1909     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1910     return E_NOTIMPL;
1911 }
1912
1913 static HRESULT WINAPI HTMLWindow6_get_XDomainRequest(IHTMLWindow6 *iface, VARIANT *p)
1914 {
1915     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1916     FIXME("(%p)->(%p)\n", This, p);
1917     return E_NOTIMPL;
1918 }
1919
1920 static HRESULT WINAPI HTMLWindow6_get_sessionStorage(IHTMLWindow6 *iface, IHTMLStorage **p)
1921 {
1922     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1923
1924     FIXME("(%p)->(%p)\n", This, p);
1925
1926     if(!This->inner_window->session_storage) {
1927         HRESULT hres;
1928
1929         hres = create_storage(&This->inner_window->session_storage);
1930         if(FAILED(hres))
1931             return hres;
1932     }
1933
1934     IHTMLStorage_AddRef(This->inner_window->session_storage);
1935     *p = This->inner_window->session_storage;
1936     return S_OK;
1937 }
1938
1939 static HRESULT WINAPI HTMLWindow6_get_localStorage(IHTMLWindow6 *iface, IHTMLStorage **p)
1940 {
1941     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1942     FIXME("(%p)->(%p)\n", This, p);
1943     return E_NOTIMPL;
1944 }
1945
1946 static HRESULT WINAPI HTMLWindow6_put_onhashchange(IHTMLWindow6 *iface, VARIANT v)
1947 {
1948     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1949     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1950     return E_NOTIMPL;
1951 }
1952
1953 static HRESULT WINAPI HTMLWindow6_get_onhashchange(IHTMLWindow6 *iface, VARIANT *p)
1954 {
1955     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1956     FIXME("(%p)->(%p)\n", This, p);
1957     return E_NOTIMPL;
1958 }
1959
1960 static HRESULT WINAPI HTMLWindow6_get_maxConnectionsPerServer(IHTMLWindow6 *iface, LONG *p)
1961 {
1962     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1963     FIXME("(%p)->(%p)\n", This, p);
1964     return E_NOTIMPL;
1965 }
1966
1967 static HRESULT WINAPI HTMLWindow6_postMessage(IHTMLWindow6 *iface, BSTR msg, VARIANT targetOrigin)
1968 {
1969     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1970     FIXME("(%p)->(%s %s)\n", This, debugstr_w(msg), debugstr_variant(&targetOrigin));
1971     return E_NOTIMPL;
1972 }
1973
1974 static HRESULT WINAPI HTMLWindow6_toStaticHTML(IHTMLWindow6 *iface, BSTR bstrHTML, BSTR *pbstrStaticHTML)
1975 {
1976     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1977     FIXME("(%p)->(%s %p)\n", This, debugstr_w(bstrHTML), pbstrStaticHTML);
1978     return E_NOTIMPL;
1979 }
1980
1981 static HRESULT WINAPI HTMLWindow6_put_onmessage(IHTMLWindow6 *iface, VARIANT v)
1982 {
1983     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1984     FIXME("(%p)->(%s)\n", This, debugstr_variant(&v));
1985     return E_NOTIMPL;
1986 }
1987
1988 static HRESULT WINAPI HTMLWindow6_get_onmessage(IHTMLWindow6 *iface, VARIANT *p)
1989 {
1990     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1991     FIXME("(%p)->(%p)\n", This, p);
1992     return E_NOTIMPL;
1993 }
1994
1995 static HRESULT WINAPI HTMLWindow6_msWriteProfilerMark(IHTMLWindow6 *iface, BSTR bstrProfilerMark)
1996 {
1997     HTMLWindow *This = impl_from_IHTMLWindow6(iface);
1998     FIXME("(%p)->(%s)\n", This, debugstr_w(bstrProfilerMark));
1999     return E_NOTIMPL;
2000 }
2001
2002 static const IHTMLWindow6Vtbl HTMLWindow6Vtbl = {
2003     HTMLWindow6_QueryInterface,
2004     HTMLWindow6_AddRef,
2005     HTMLWindow6_Release,
2006     HTMLWindow6_GetTypeInfoCount,
2007     HTMLWindow6_GetTypeInfo,
2008     HTMLWindow6_GetIDsOfNames,
2009     HTMLWindow6_Invoke,
2010     HTMLWindow6_put_XDomainRequest,
2011     HTMLWindow6_get_XDomainRequest,
2012     HTMLWindow6_get_sessionStorage,
2013     HTMLWindow6_get_localStorage,
2014     HTMLWindow6_put_onhashchange,
2015     HTMLWindow6_get_onhashchange,
2016     HTMLWindow6_get_maxConnectionsPerServer,
2017     HTMLWindow6_postMessage,
2018     HTMLWindow6_toStaticHTML,
2019     HTMLWindow6_put_onmessage,
2020     HTMLWindow6_get_onmessage,
2021     HTMLWindow6_msWriteProfilerMark
2022 };
2023
2024 static inline HTMLWindow *impl_from_IHTMLPrivateWindow(IHTMLPrivateWindow *iface)
2025 {
2026     return CONTAINING_RECORD(iface, HTMLWindow, IHTMLPrivateWindow_iface);
2027 }
2028
2029 static HRESULT WINAPI HTMLPrivateWindow_QueryInterface(IHTMLPrivateWindow *iface, REFIID riid, void **ppv)
2030 {
2031     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2032
2033     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2034 }
2035
2036 static ULONG WINAPI HTMLPrivateWindow_AddRef(IHTMLPrivateWindow *iface)
2037 {
2038     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2039
2040     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2041 }
2042
2043 static ULONG WINAPI HTMLPrivateWindow_Release(IHTMLPrivateWindow *iface)
2044 {
2045     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2046
2047     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2048 }
2049
2050 static HRESULT WINAPI HTMLPrivateWindow_SuperNavigate(IHTMLPrivateWindow *iface, BSTR url, BSTR arg2, BSTR arg3,
2051         BSTR arg4, VARIANT *post_data_var, VARIANT *headers_var, ULONG flags)
2052 {
2053     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2054     HTMLOuterWindow *window = This->outer_window;
2055     OLECHAR *translated_url = NULL;
2056     DWORD post_data_size = 0;
2057     BYTE *post_data = NULL;
2058     WCHAR *headers = NULL;
2059     IUri *uri;
2060     HRESULT hres;
2061
2062     TRACE("(%p)->(%s %s %s %s %s %s %x)\n", This, debugstr_w(url), debugstr_w(arg2), debugstr_w(arg3), debugstr_w(arg4),
2063           debugstr_variant(post_data_var), debugstr_variant(headers_var), flags);
2064
2065     if(window->doc_obj->hostui) {
2066         hres = IDocHostUIHandler_TranslateUrl(window->doc_obj->hostui, 0, url, &translated_url);
2067         if(hres != S_OK)
2068             translated_url = NULL;
2069     }
2070
2071     hres = CreateUri(translated_url ? translated_url : url, 0, 0, &uri);
2072     CoTaskMemFree(translated_url);
2073     if(FAILED(hres))
2074         return hres;
2075
2076     if(post_data_var) {
2077         if(V_VT(post_data_var) == (VT_ARRAY|VT_UI1)) {
2078             SafeArrayAccessData(V_ARRAY(post_data_var), (void**)&post_data);
2079             post_data_size = V_ARRAY(post_data_var)->rgsabound[0].cElements;
2080         }
2081     }
2082
2083     if(headers_var && V_VT(headers_var) != VT_EMPTY && V_VT(headers_var) != VT_ERROR) {
2084         if(V_VT(headers_var) != VT_BSTR)
2085             return E_INVALIDARG;
2086
2087         headers = V_BSTR(headers_var);
2088     }
2089
2090     hres = super_navigate(window, uri, headers, post_data, post_data_size);
2091     IUri_Release(uri);
2092     if(post_data)
2093         SafeArrayUnaccessData(V_ARRAY(post_data_var));
2094
2095     return hres;
2096 }
2097
2098 static HRESULT WINAPI HTMLPrivateWindow_GetPendingUrl(IHTMLPrivateWindow *iface, BSTR *url)
2099 {
2100     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2101     FIXME("(%p)->(%p)\n", This, url);
2102     return E_NOTIMPL;
2103 }
2104
2105 static HRESULT WINAPI HTMLPrivateWindow_SetPICSTarget(IHTMLPrivateWindow *iface, IOleCommandTarget *cmdtrg)
2106 {
2107     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2108     FIXME("(%p)->(%p)\n", This, cmdtrg);
2109     return E_NOTIMPL;
2110 }
2111
2112 static HRESULT WINAPI HTMLPrivateWindow_PICSComplete(IHTMLPrivateWindow *iface, int arg)
2113 {
2114     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2115     FIXME("(%p)->(%x)\n", This, arg);
2116     return E_NOTIMPL;
2117 }
2118
2119 static HRESULT WINAPI HTMLPrivateWindow_FindWindowByName(IHTMLPrivateWindow *iface, LPCWSTR name, IHTMLWindow2 **ret)
2120 {
2121     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2122     FIXME("(%p)->(%s %p)\n", This, debugstr_w(name), ret);
2123     return E_NOTIMPL;
2124 }
2125
2126 static HRESULT WINAPI HTMLPrivateWindow_GetAddressBarUrl(IHTMLPrivateWindow *iface, BSTR *url)
2127 {
2128     HTMLWindow *This = impl_from_IHTMLPrivateWindow(iface);
2129     TRACE("(%p)->(%p)\n", This, url);
2130
2131     if(!url)
2132         return E_INVALIDARG;
2133
2134     *url = SysAllocString(This->outer_window->url);
2135     return S_OK;
2136 }
2137
2138 static const IHTMLPrivateWindowVtbl HTMLPrivateWindowVtbl = {
2139     HTMLPrivateWindow_QueryInterface,
2140     HTMLPrivateWindow_AddRef,
2141     HTMLPrivateWindow_Release,
2142     HTMLPrivateWindow_SuperNavigate,
2143     HTMLPrivateWindow_GetPendingUrl,
2144     HTMLPrivateWindow_SetPICSTarget,
2145     HTMLPrivateWindow_PICSComplete,
2146     HTMLPrivateWindow_FindWindowByName,
2147     HTMLPrivateWindow_GetAddressBarUrl
2148 };
2149
2150 static inline HTMLWindow *impl_from_ITravelLogClient(ITravelLogClient *iface)
2151 {
2152     return CONTAINING_RECORD(iface, HTMLWindow, ITravelLogClient_iface);
2153 }
2154
2155 static HRESULT WINAPI TravelLogClient_QueryInterface(ITravelLogClient *iface, REFIID riid, void **ppv)
2156 {
2157     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2158
2159     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2160 }
2161
2162 static ULONG WINAPI TravelLogClient_AddRef(ITravelLogClient *iface)
2163 {
2164     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2165
2166     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2167 }
2168
2169 static ULONG WINAPI TravelLogClient_Release(ITravelLogClient *iface)
2170 {
2171     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2172
2173     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2174 }
2175
2176 static HRESULT WINAPI TravelLogClient_FindWindowByIndex(ITravelLogClient *iface, DWORD dwID, IUnknown **ppunk)
2177 {
2178     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2179
2180     FIXME("(%p)->(%d %p) semi-stub\n", This, dwID, ppunk);
2181
2182     *ppunk = NULL;
2183     return E_FAIL;
2184 }
2185
2186 static HRESULT WINAPI TravelLogClient_GetWindowData(ITravelLogClient *iface, IStream *pStream, LPWINDOWDATA pWinData)
2187 {
2188     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2189     FIXME("(%p)->(%p %p)\n", This, pStream, pWinData);
2190     return E_NOTIMPL;
2191 }
2192
2193 static HRESULT WINAPI TravelLogClient_LoadHistoryPosition(ITravelLogClient *iface, LPWSTR pszUrlLocation, DWORD dwPosition)
2194 {
2195     HTMLWindow *This = impl_from_ITravelLogClient(iface);
2196     FIXME("(%p)->(%s %d)\n", This, debugstr_w(pszUrlLocation), dwPosition);
2197     return E_NOTIMPL;
2198 }
2199
2200 static const ITravelLogClientVtbl TravelLogClientVtbl = {
2201     TravelLogClient_QueryInterface,
2202     TravelLogClient_AddRef,
2203     TravelLogClient_Release,
2204     TravelLogClient_FindWindowByIndex,
2205     TravelLogClient_GetWindowData,
2206     TravelLogClient_LoadHistoryPosition
2207 };
2208
2209 static inline HTMLWindow *impl_from_IDispatchEx(IDispatchEx *iface)
2210 {
2211     return CONTAINING_RECORD(iface, HTMLWindow, IDispatchEx_iface);
2212 }
2213
2214 static HRESULT WINAPI WindowDispEx_QueryInterface(IDispatchEx *iface, REFIID riid, void **ppv)
2215 {
2216     HTMLWindow *This = impl_from_IDispatchEx(iface);
2217
2218     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2219 }
2220
2221 static ULONG WINAPI WindowDispEx_AddRef(IDispatchEx *iface)
2222 {
2223     HTMLWindow *This = impl_from_IDispatchEx(iface);
2224
2225     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2226 }
2227
2228 static ULONG WINAPI WindowDispEx_Release(IDispatchEx *iface)
2229 {
2230     HTMLWindow *This = impl_from_IDispatchEx(iface);
2231
2232     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2233 }
2234
2235 static HRESULT WINAPI WindowDispEx_GetTypeInfoCount(IDispatchEx *iface, UINT *pctinfo)
2236 {
2237     HTMLWindow *This = impl_from_IDispatchEx(iface);
2238
2239     TRACE("(%p)->(%p)\n", This, pctinfo);
2240
2241     return IDispatchEx_GetTypeInfoCount(&This->inner_window->dispex.IDispatchEx_iface, pctinfo);
2242 }
2243
2244 static HRESULT WINAPI WindowDispEx_GetTypeInfo(IDispatchEx *iface, UINT iTInfo,
2245                                                LCID lcid, ITypeInfo **ppTInfo)
2246 {
2247     HTMLWindow *This = impl_from_IDispatchEx(iface);
2248
2249     TRACE("(%p)->(%u %u %p)\n", This, iTInfo, lcid, ppTInfo);
2250
2251     return IDispatchEx_GetTypeInfo(&This->inner_window->dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
2252 }
2253
2254 static HRESULT WINAPI WindowDispEx_GetIDsOfNames(IDispatchEx *iface, REFIID riid,
2255                                                  LPOLESTR *rgszNames, UINT cNames,
2256                                                  LCID lcid, DISPID *rgDispId)
2257 {
2258     HTMLWindow *This = impl_from_IDispatchEx(iface);
2259     UINT i;
2260     HRESULT hres;
2261
2262     WARN("(%p)->(%s %p %u %u %p)\n", This, debugstr_guid(riid), rgszNames, cNames,
2263           lcid, rgDispId);
2264
2265     for(i=0; i < cNames; i++) {
2266         /* We shouldn't use script's IDispatchEx here, so we shouldn't use GetDispID */
2267         hres = IDispatchEx_GetDispID(&This->IDispatchEx_iface, rgszNames[i], 0, rgDispId+i);
2268         if(FAILED(hres))
2269             return hres;
2270     }
2271
2272     return S_OK;
2273 }
2274
2275 static HRESULT WINAPI WindowDispEx_Invoke(IDispatchEx *iface, DISPID dispIdMember,
2276                             REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
2277                             VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
2278 {
2279     HTMLWindow *This = impl_from_IDispatchEx(iface);
2280
2281     TRACE("(%p)->(%d %s %d %d %p %p %p %p)\n", This, dispIdMember, debugstr_guid(riid),
2282           lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
2283
2284     /* FIXME: Use script dispatch */
2285
2286     return IDispatchEx_Invoke(&This->inner_window->dispex.IDispatchEx_iface, dispIdMember, riid, lcid, wFlags,
2287             pDispParams, pVarResult, pExcepInfo, puArgErr);
2288 }
2289
2290 static global_prop_t *alloc_global_prop(HTMLInnerWindow *This, global_prop_type_t type, BSTR name)
2291 {
2292     if(This->global_prop_cnt == This->global_prop_size) {
2293         global_prop_t *new_props;
2294         DWORD new_size;
2295
2296         if(This->global_props) {
2297             new_size = This->global_prop_size*2;
2298             new_props = heap_realloc(This->global_props, new_size*sizeof(global_prop_t));
2299         }else {
2300             new_size = 16;
2301             new_props = heap_alloc(new_size*sizeof(global_prop_t));
2302         }
2303         if(!new_props)
2304             return NULL;
2305         This->global_props = new_props;
2306         This->global_prop_size = new_size;
2307     }
2308
2309     This->global_props[This->global_prop_cnt].name = heap_strdupW(name);
2310     if(!This->global_props[This->global_prop_cnt].name)
2311         return NULL;
2312
2313     This->global_props[This->global_prop_cnt].type = type;
2314     return This->global_props + This->global_prop_cnt++;
2315 }
2316
2317 static inline DWORD prop_to_dispid(HTMLInnerWindow *This, global_prop_t *prop)
2318 {
2319     return MSHTML_DISPID_CUSTOM_MIN + (prop-This->global_props);
2320 }
2321
2322 HRESULT search_window_props(HTMLInnerWindow *This, BSTR bstrName, DWORD grfdex, DISPID *pid)
2323 {
2324     DWORD i;
2325     ScriptHost *script_host;
2326     DISPID id;
2327
2328     for(i=0; i < This->global_prop_cnt; i++) {
2329         /* FIXME: case sensitivity */
2330         if(!strcmpW(This->global_props[i].name, bstrName)) {
2331             *pid = MSHTML_DISPID_CUSTOM_MIN+i;
2332             return S_OK;
2333         }
2334     }
2335
2336     if(find_global_prop(This->base.inner_window, bstrName, grfdex, &script_host, &id)) {
2337         global_prop_t *prop;
2338
2339         prop = alloc_global_prop(This, GLOBAL_SCRIPTVAR, bstrName);
2340         if(!prop)
2341             return E_OUTOFMEMORY;
2342
2343         prop->script_host = script_host;
2344         prop->id = id;
2345
2346         *pid = prop_to_dispid(This, prop);
2347         return S_OK;
2348     }
2349
2350     return DISP_E_UNKNOWNNAME;
2351 }
2352
2353 static HRESULT WINAPI WindowDispEx_GetDispID(IDispatchEx *iface, BSTR bstrName, DWORD grfdex, DISPID *pid)
2354 {
2355     HTMLWindow *This = impl_from_IDispatchEx(iface);
2356     HTMLInnerWindow *window = This->inner_window;
2357     HRESULT hres;
2358
2359     TRACE("(%p)->(%s %x %p)\n", This, debugstr_w(bstrName), grfdex, pid);
2360
2361     hres = search_window_props(window, bstrName, grfdex, pid);
2362     if(hres != DISP_E_UNKNOWNNAME)
2363         return hres;
2364
2365     hres = IDispatchEx_GetDispID(&window->base.inner_window->dispex.IDispatchEx_iface, bstrName, grfdex, pid);
2366     if(hres != DISP_E_UNKNOWNNAME)
2367         return hres;
2368
2369     if(This->outer_window) {
2370         HTMLOuterWindow *frame;
2371
2372         hres = get_frame_by_name(This->outer_window, bstrName, FALSE, &frame);
2373         if(SUCCEEDED(hres) && frame) {
2374             global_prop_t *prop;
2375
2376             IHTMLWindow2_Release(&frame->base.IHTMLWindow2_iface);
2377
2378             prop = alloc_global_prop(window, GLOBAL_FRAMEVAR, bstrName);
2379             if(!prop)
2380                 return E_OUTOFMEMORY;
2381
2382             *pid = prop_to_dispid(window, prop);
2383             return S_OK;
2384         }
2385     }
2386
2387     if(window->doc) {
2388         global_prop_t *prop;
2389         IHTMLElement *elem;
2390
2391         hres = IHTMLDocument3_getElementById(&window->base.inner_window->doc->basedoc.IHTMLDocument3_iface,
2392                                              bstrName, &elem);
2393         if(SUCCEEDED(hres) && elem) {
2394             IHTMLElement_Release(elem);
2395
2396             prop = alloc_global_prop(window, GLOBAL_ELEMENTVAR, bstrName);
2397             if(!prop)
2398                 return E_OUTOFMEMORY;
2399
2400             *pid = prop_to_dispid(window, prop);
2401             return S_OK;
2402         }
2403     }
2404
2405     return DISP_E_UNKNOWNNAME;
2406 }
2407
2408 static HRESULT WINAPI WindowDispEx_InvokeEx(IDispatchEx *iface, DISPID id, LCID lcid, WORD wFlags, DISPPARAMS *pdp,
2409         VARIANT *pvarRes, EXCEPINFO *pei, IServiceProvider *pspCaller)
2410 {
2411     HTMLWindow *This = impl_from_IDispatchEx(iface);
2412     HTMLInnerWindow *window = This->inner_window;
2413
2414     TRACE("(%p)->(%x %x %x %p %p %p %p)\n", This, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
2415
2416     if(id == DISPID_IHTMLWINDOW2_LOCATION && (wFlags & DISPATCH_PROPERTYPUT)) {
2417         HTMLLocation *location;
2418         HRESULT hres;
2419
2420         TRACE("forwarding to location.href\n");
2421
2422         hres = get_location(window, &location);
2423         if(FAILED(hres))
2424             return hres;
2425
2426         hres = IDispatchEx_InvokeEx(&location->dispex.IDispatchEx_iface, DISPID_VALUE, lcid,
2427                 wFlags, pdp, pvarRes, pei, pspCaller);
2428         IHTMLLocation_Release(&location->IHTMLLocation_iface);
2429         return hres;
2430     }
2431
2432     return IDispatchEx_InvokeEx(&window->dispex.IDispatchEx_iface, id, lcid, wFlags, pdp, pvarRes, pei, pspCaller);
2433 }
2434
2435 static HRESULT WINAPI WindowDispEx_DeleteMemberByName(IDispatchEx *iface, BSTR bstrName, DWORD grfdex)
2436 {
2437     HTMLWindow *This = impl_from_IDispatchEx(iface);
2438
2439     TRACE("(%p)->(%s %x)\n", This, debugstr_w(bstrName), grfdex);
2440
2441     return IDispatchEx_DeleteMemberByName(&This->inner_window->dispex.IDispatchEx_iface, bstrName, grfdex);
2442 }
2443
2444 static HRESULT WINAPI WindowDispEx_DeleteMemberByDispID(IDispatchEx *iface, DISPID id)
2445 {
2446     HTMLWindow *This = impl_from_IDispatchEx(iface);
2447
2448     TRACE("(%p)->(%x)\n", This, id);
2449
2450     return IDispatchEx_DeleteMemberByDispID(&This->inner_window->dispex.IDispatchEx_iface, id);
2451 }
2452
2453 static HRESULT WINAPI WindowDispEx_GetMemberProperties(IDispatchEx *iface, DISPID id, DWORD grfdexFetch, DWORD *pgrfdex)
2454 {
2455     HTMLWindow *This = impl_from_IDispatchEx(iface);
2456
2457     TRACE("(%p)->(%x %x %p)\n", This, id, grfdexFetch, pgrfdex);
2458
2459     return IDispatchEx_GetMemberProperties(&This->inner_window->dispex.IDispatchEx_iface, id, grfdexFetch,
2460             pgrfdex);
2461 }
2462
2463 static HRESULT WINAPI WindowDispEx_GetMemberName(IDispatchEx *iface, DISPID id, BSTR *pbstrName)
2464 {
2465     HTMLWindow *This = impl_from_IDispatchEx(iface);
2466
2467     TRACE("(%p)->(%x %p)\n", This, id, pbstrName);
2468
2469     return IDispatchEx_GetMemberName(&This->inner_window->dispex.IDispatchEx_iface, id, pbstrName);
2470 }
2471
2472 static HRESULT WINAPI WindowDispEx_GetNextDispID(IDispatchEx *iface, DWORD grfdex, DISPID id, DISPID *pid)
2473 {
2474     HTMLWindow *This = impl_from_IDispatchEx(iface);
2475
2476     TRACE("(%p)->(%x %x %p)\n", This, grfdex, id, pid);
2477
2478     return IDispatchEx_GetNextDispID(&This->inner_window->dispex.IDispatchEx_iface, grfdex, id, pid);
2479 }
2480
2481 static HRESULT WINAPI WindowDispEx_GetNameSpaceParent(IDispatchEx *iface, IUnknown **ppunk)
2482 {
2483     HTMLWindow *This = impl_from_IDispatchEx(iface);
2484
2485     TRACE("(%p)->(%p)\n", This, ppunk);
2486
2487     *ppunk = NULL;
2488     return S_OK;
2489 }
2490
2491 static const IDispatchExVtbl WindowDispExVtbl = {
2492     WindowDispEx_QueryInterface,
2493     WindowDispEx_AddRef,
2494     WindowDispEx_Release,
2495     WindowDispEx_GetTypeInfoCount,
2496     WindowDispEx_GetTypeInfo,
2497     WindowDispEx_GetIDsOfNames,
2498     WindowDispEx_Invoke,
2499     WindowDispEx_GetDispID,
2500     WindowDispEx_InvokeEx,
2501     WindowDispEx_DeleteMemberByName,
2502     WindowDispEx_DeleteMemberByDispID,
2503     WindowDispEx_GetMemberProperties,
2504     WindowDispEx_GetMemberName,
2505     WindowDispEx_GetNextDispID,
2506     WindowDispEx_GetNameSpaceParent
2507 };
2508
2509 static inline HTMLWindow *impl_from_IServiceProvider(IServiceProvider *iface)
2510 {
2511     return CONTAINING_RECORD(iface, HTMLWindow, IServiceProvider_iface);
2512 }
2513
2514 static HRESULT WINAPI HTMLWindowSP_QueryInterface(IServiceProvider *iface, REFIID riid, void **ppv)
2515 {
2516     HTMLWindow *This = impl_from_IServiceProvider(iface);
2517     return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2518 }
2519
2520 static ULONG WINAPI HTMLWindowSP_AddRef(IServiceProvider *iface)
2521 {
2522     HTMLWindow *This = impl_from_IServiceProvider(iface);
2523     return IHTMLWindow2_AddRef(&This->IHTMLWindow2_iface);
2524 }
2525
2526 static ULONG WINAPI HTMLWindowSP_Release(IServiceProvider *iface)
2527 {
2528     HTMLWindow *This = impl_from_IServiceProvider(iface);
2529     return IHTMLWindow2_Release(&This->IHTMLWindow2_iface);
2530 }
2531
2532 static HRESULT WINAPI HTMLWindowSP_QueryService(IServiceProvider *iface, REFGUID guidService, REFIID riid, void **ppv)
2533 {
2534     HTMLWindow *This = impl_from_IServiceProvider(iface);
2535
2536     if(IsEqualGUID(guidService, &IID_IHTMLWindow2)) {
2537         TRACE("IID_IHTMLWindow2\n");
2538         return IHTMLWindow2_QueryInterface(&This->IHTMLWindow2_iface, riid, ppv);
2539     }
2540
2541     TRACE("(%p)->(%s %s %p)\n", This, debugstr_guid(guidService), debugstr_guid(riid), ppv);
2542
2543     if(!This->outer_window->doc_obj)
2544         return E_NOINTERFACE;
2545
2546     return IServiceProvider_QueryService(&This->outer_window->doc_obj->basedoc.IServiceProvider_iface,
2547             guidService, riid, ppv);
2548 }
2549
2550 static const IServiceProviderVtbl ServiceProviderVtbl = {
2551     HTMLWindowSP_QueryInterface,
2552     HTMLWindowSP_AddRef,
2553     HTMLWindowSP_Release,
2554     HTMLWindowSP_QueryService
2555 };
2556
2557 static inline HTMLInnerWindow *impl_from_DispatchEx(DispatchEx *iface)
2558 {
2559     return CONTAINING_RECORD(iface, HTMLInnerWindow, dispex);
2560 }
2561
2562 static HRESULT HTMLWindow_invoke(DispatchEx *dispex, DISPID id, LCID lcid, WORD flags, DISPPARAMS *params,
2563         VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller)
2564 {
2565     HTMLInnerWindow *This = impl_from_DispatchEx(dispex);
2566     global_prop_t *prop;
2567     DWORD idx;
2568     HRESULT hres;
2569
2570     idx = id - MSHTML_DISPID_CUSTOM_MIN;
2571     if(idx >= This->global_prop_cnt)
2572         return DISP_E_MEMBERNOTFOUND;
2573
2574     prop = This->global_props+idx;
2575
2576     switch(prop->type) {
2577     case GLOBAL_SCRIPTVAR: {
2578         IDispatchEx *iface;
2579         IDispatch *disp;
2580
2581         disp = get_script_disp(prop->script_host);
2582         if(!disp)
2583             return E_UNEXPECTED;
2584
2585         hres = IDispatch_QueryInterface(disp, &IID_IDispatchEx, (void**)&iface);
2586         if(SUCCEEDED(hres)) {
2587             TRACE("%s >>>\n", debugstr_w(prop->name));
2588             hres = IDispatchEx_InvokeEx(iface, prop->id, lcid, flags, params, res, ei, caller);
2589             if(hres == S_OK)
2590                 TRACE("%s <<<\n", debugstr_w(prop->name));
2591             else
2592                 WARN("%s <<< %08x\n", debugstr_w(prop->name), hres);
2593             IDispatchEx_Release(iface);
2594         }else {
2595             FIXME("No IDispatchEx\n");
2596         }
2597         IDispatch_Release(disp);
2598         break;
2599     }
2600     case GLOBAL_ELEMENTVAR:
2601         switch(flags) {
2602         case DISPATCH_PROPERTYGET|DISPATCH_METHOD:
2603         case DISPATCH_PROPERTYGET: {
2604             IHTMLElement *elem;
2605
2606             hres = IHTMLDocument3_getElementById(&This->base.inner_window->doc->basedoc.IHTMLDocument3_iface,
2607                     prop->name, &elem);
2608             if(FAILED(hres))
2609                 return hres;
2610
2611             if(!elem)
2612                 return DISP_E_MEMBERNOTFOUND;
2613
2614             V_VT(res) = VT_DISPATCH;
2615             V_DISPATCH(res) = (IDispatch*)elem;
2616             return S_OK;
2617         }
2618         case DISPATCH_PROPERTYPUT: {
2619             DISPID dispex_id;
2620
2621             hres = dispex_get_dynid(&This->dispex, prop->name, &dispex_id);
2622             if(FAILED(hres))
2623                 return hres;
2624
2625             prop->type = GLOBAL_DISPEXVAR;
2626             prop->id = dispex_id;
2627             return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, dispex_id, 0, flags, params, res, ei, caller);
2628         }
2629         default:
2630             FIXME("Not supported flags: %x\n", flags);
2631             return E_NOTIMPL;
2632         }
2633     case GLOBAL_FRAMEVAR:
2634         if(!This->base.outer_window)
2635             return E_UNEXPECTED;
2636
2637         switch(flags) {
2638         case DISPATCH_PROPERTYGET: {
2639             HTMLOuterWindow *frame;
2640
2641             hres = get_frame_by_name(This->base.outer_window, prop->name, FALSE, &frame);
2642             if(FAILED(hres))
2643                 return hres;
2644
2645             if(!frame)
2646                 return DISP_E_MEMBERNOTFOUND;
2647
2648             V_VT(res) = VT_DISPATCH;
2649             V_DISPATCH(res) = (IDispatch*)&frame->base.inner_window->base.IHTMLWindow2_iface;
2650             IDispatch_AddRef(V_DISPATCH(res));
2651             return S_OK;
2652         }
2653         default:
2654             FIXME("Not supported flags: %x\n", flags);
2655             return E_NOTIMPL;
2656         }
2657     case GLOBAL_DISPEXVAR:
2658         return IDispatchEx_InvokeEx(&This->dispex.IDispatchEx_iface, prop->id, 0, flags, params, res, ei, caller);
2659     default:
2660         ERR("invalid type %d\n", prop->type);
2661         hres = DISP_E_MEMBERNOTFOUND;
2662     }
2663
2664     return hres;
2665 }
2666
2667
2668 static const dispex_static_data_vtbl_t HTMLWindow_dispex_vtbl = {
2669     NULL,
2670     NULL,
2671     HTMLWindow_invoke,
2672     NULL
2673 };
2674
2675 static const tid_t HTMLWindow_iface_tids[] = {
2676     IHTMLWindow2_tid,
2677     IHTMLWindow3_tid,
2678     IHTMLWindow4_tid,
2679     IHTMLWindow6_tid,
2680     0
2681 };
2682
2683 static dispex_static_data_t HTMLWindow_dispex = {
2684     &HTMLWindow_dispex_vtbl,
2685     DispHTMLWindow2_tid,
2686     NULL,
2687     HTMLWindow_iface_tids
2688 };
2689
2690 static void *alloc_window(size_t size)
2691 {
2692     HTMLWindow *window;
2693
2694     window = heap_alloc_zero(size);
2695     if(!window)
2696         return NULL;
2697
2698     window->IHTMLWindow2_iface.lpVtbl = &HTMLWindow2Vtbl;
2699     window->IHTMLWindow3_iface.lpVtbl = &HTMLWindow3Vtbl;
2700     window->IHTMLWindow4_iface.lpVtbl = &HTMLWindow4Vtbl;
2701     window->IHTMLWindow5_iface.lpVtbl = &HTMLWindow5Vtbl;
2702     window->IHTMLWindow6_iface.lpVtbl = &HTMLWindow6Vtbl;
2703     window->IHTMLPrivateWindow_iface.lpVtbl = &HTMLPrivateWindowVtbl;
2704     window->IDispatchEx_iface.lpVtbl = &WindowDispExVtbl;
2705     window->IServiceProvider_iface.lpVtbl = &ServiceProviderVtbl;
2706     window->ITravelLogClient_iface.lpVtbl = &TravelLogClientVtbl;
2707     window->ref = 1;
2708
2709     return window;
2710 }
2711
2712 static HRESULT create_inner_window(HTMLOuterWindow *outer_window, IMoniker *mon, HTMLInnerWindow **ret)
2713 {
2714     HTMLInnerWindow *window;
2715
2716     window = alloc_window(sizeof(HTMLInnerWindow));
2717     if(!window)
2718         return E_OUTOFMEMORY;
2719
2720     list_init(&window->script_hosts);
2721     list_init(&window->bindings);
2722
2723     window->base.outer_window = outer_window;
2724     window->base.inner_window = window;
2725
2726     init_dispex(&window->dispex, (IUnknown*)&window->base.IHTMLWindow2_iface, &HTMLWindow_dispex);
2727
2728     window->task_magic = get_task_target_magic();
2729
2730     if(mon) {
2731         IMoniker_AddRef(mon);
2732         window->mon = mon;
2733     }
2734
2735     *ret = window;
2736     return S_OK;
2737 }
2738
2739 HRESULT HTMLOuterWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow,
2740         HTMLOuterWindow *parent, HTMLOuterWindow **ret)
2741 {
2742     HTMLOuterWindow *window;
2743     HRESULT hres;
2744
2745     window = alloc_window(sizeof(HTMLOuterWindow));
2746     if(!window)
2747         return E_OUTOFMEMORY;
2748
2749     window->base.outer_window = window;
2750     window->base.inner_window = NULL;
2751
2752     window->window_ref = heap_alloc(sizeof(windowref_t));
2753     if(!window->window_ref) {
2754         heap_free(window);
2755         return E_OUTOFMEMORY;
2756     }
2757
2758     window->doc_obj = doc_obj;
2759
2760     window->window_ref->window = window;
2761     window->window_ref->ref = 1;
2762
2763     if(nswindow) {
2764         nsIDOMWindow_AddRef(nswindow);
2765         window->nswindow = nswindow;
2766     }
2767
2768     window->scriptmode = parent ? parent->scriptmode : SCRIPTMODE_GECKO;
2769     window->readystate = READYSTATE_UNINITIALIZED;
2770
2771     hres = create_pending_window(window, NULL);
2772     if(SUCCEEDED(hres))
2773         hres = update_window_doc(window->pending_window);
2774     if(FAILED(hres)) {
2775         IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
2776         return hres;
2777     }
2778
2779     hres = CoInternetCreateSecurityManager(NULL, &window->secmgr, 0);
2780     if(FAILED(hres)) {
2781         IHTMLWindow2_Release(&window->base.IHTMLWindow2_iface);
2782         return hres;
2783     }
2784
2785     window->task_magic = get_task_target_magic();
2786
2787     list_init(&window->children);
2788     list_add_head(&window_list, &window->entry);
2789
2790     if(parent) {
2791         IHTMLWindow2_AddRef(&window->base.IHTMLWindow2_iface);
2792
2793         window->parent = parent;
2794         list_add_tail(&parent->children, &window->sibling_entry);
2795     }
2796
2797     TRACE("%p inner_window %p\n", window, window->base.inner_window);
2798
2799     *ret = window;
2800     return S_OK;
2801 }
2802
2803 HRESULT create_pending_window(HTMLOuterWindow *outer_window, nsChannelBSC *channelbsc)
2804 {
2805     HTMLInnerWindow *pending_window;
2806     HRESULT hres;
2807
2808     hres = create_inner_window(outer_window, outer_window->mon /* FIXME */, &pending_window);
2809     if(FAILED(hres))
2810         return hres;
2811
2812     if(channelbsc) {
2813         IBindStatusCallback_AddRef(&channelbsc->bsc.IBindStatusCallback_iface);
2814         pending_window->bscallback = channelbsc;
2815     }
2816
2817     if(outer_window->pending_window) {
2818         abort_window_bindings(outer_window->pending_window);
2819         outer_window->pending_window->base.outer_window = NULL;
2820         IHTMLWindow2_Release(&outer_window->pending_window->base.IHTMLWindow2_iface);
2821     }
2822
2823     outer_window->pending_window = pending_window;
2824     return S_OK;
2825 }
2826
2827 HRESULT update_window_doc(HTMLInnerWindow *window)
2828 {
2829     HTMLOuterWindow *outer_window = window->base.outer_window;
2830     nsIDOMHTMLDocument *nshtmldoc;
2831     nsIDOMDocument *nsdoc;
2832     nsresult nsres;
2833     HRESULT hres;
2834
2835     assert(!window->doc);
2836
2837     if(!outer_window) {
2838         ERR("NULL outer window\n");
2839         return E_UNEXPECTED;
2840     }
2841
2842     nsres = nsIDOMWindow_GetDocument(outer_window->nswindow, &nsdoc);
2843     if(NS_FAILED(nsres) || !nsdoc) {
2844         ERR("GetDocument failed: %08x\n", nsres);
2845         return E_FAIL;
2846     }
2847
2848     nsres = nsIDOMDocument_QueryInterface(nsdoc, &IID_nsIDOMHTMLDocument, (void**)&nshtmldoc);
2849     nsIDOMDocument_Release(nsdoc);
2850     if(NS_FAILED(nsres)) {
2851         ERR("Could not get nsIDOMHTMLDocument iface: %08x\n", nsres);
2852         return E_FAIL;
2853     }
2854
2855     hres = create_doc_from_nsdoc(nshtmldoc, outer_window->doc_obj, window, &window->doc);
2856     nsIDOMHTMLDocument_Release(nshtmldoc);
2857     if(FAILED(hres))
2858         return hres;
2859
2860     if(outer_window->doc_obj->usermode == EDITMODE) {
2861         nsAString mode_str;
2862         nsresult nsres;
2863
2864         static const PRUnichar onW[] = {'o','n',0};
2865
2866         nsAString_Init(&mode_str, onW);
2867         nsres = nsIDOMHTMLDocument_SetDesignMode(window->doc->nsdoc, &mode_str);
2868         nsAString_Finish(&mode_str);
2869         if(NS_FAILED(nsres))
2870             ERR("SetDesignMode failed: %08x\n", nsres);
2871     }
2872
2873     if(window != outer_window->pending_window) {
2874         ERR("not current pending window\n");
2875         return S_OK;
2876     }
2877
2878     detach_inner_window(outer_window);
2879     outer_window->base.inner_window = window;
2880     outer_window->pending_window = NULL;
2881
2882     if(outer_window->doc_obj->basedoc.window == outer_window || !outer_window->doc_obj->basedoc.window) {
2883         if(outer_window->doc_obj->basedoc.doc_node)
2884             htmldoc_release(&outer_window->doc_obj->basedoc.doc_node->basedoc);
2885         outer_window->doc_obj->basedoc.doc_node = window->doc;
2886         htmldoc_addref(&window->doc->basedoc);
2887     }
2888
2889     return hres;
2890 }
2891
2892 HTMLOuterWindow *nswindow_to_window(const nsIDOMWindow *nswindow)
2893 {
2894     HTMLOuterWindow *iter;
2895
2896     LIST_FOR_EACH_ENTRY(iter, &window_list, HTMLOuterWindow, entry) {
2897         if(iter->nswindow == nswindow)
2898             return iter;
2899     }
2900
2901     return NULL;
2902 }