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