diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c
index 2c650f27349..c1eca663a86 100644
--- a/dlls/mshtml/htmldoc.c
+++ b/dlls/mshtml/htmldoc.c
@@ -1825,6 +1825,7 @@ HRESULT create_doc_from_nsdoc(nsIDOMHTMLDocument *nsdoc, HTMLDocumentObj *doc_ob
doc->basedoc.window = window;
+ list_init(&doc->bindings);
list_init(&doc->selection_list);
list_init(&doc->range_list);
@@ -1972,7 +1973,6 @@ HRESULT HTMLDocument_Create(IUnknown *pUnkOuter, REFIID riid, void** ppvObject)
doc->ref = 1;
doc->basedoc.doc_obj = doc;
- list_init(&doc->bindings);
doc->usermode = UNKNOWN_USERMODE;
doc->readystate = READYSTATE_UNINITIALIZED;
diff --git a/dlls/mshtml/htmlwindow.c b/dlls/mshtml/htmlwindow.c
index 5a53e5ad2f0..bda8719d900 100644
--- a/dlls/mshtml/htmlwindow.c
+++ b/dlls/mshtml/htmlwindow.c
@@ -39,6 +39,7 @@ static struct list window_list = LIST_INIT(window_list);
static void window_set_docnode(HTMLWindow *window, HTMLDocumentNode *doc_node)
{
if(window->doc) {
+ abort_document_bindings(window->doc);
window->doc->basedoc.window = NULL;
htmldoc_release(&window->doc->basedoc);
}
@@ -158,6 +159,7 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
if(!ref) {
DWORD i;
+ remove_target_tasks(This->task_magic);
set_window_bscallback(This, NULL);
set_current_mon(This, NULL);
window_set_docnode(This, NULL);
@@ -1584,6 +1586,7 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTML
window->scriptmode = SCRIPTMODE_GECKO;
list_init(&window->script_hosts);
+ window->task_magic = get_task_target_magic();
update_window_doc(window);
list_init(&window->children);
diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h
index 66822d7b26f..eb4b34f123c 100644
--- a/dlls/mshtml/mshtml_private.h
+++ b/dlls/mshtml/mshtml_private.h
@@ -213,6 +213,7 @@ struct HTMLWindow {
LONG ref;
windowref_t *window_ref;
+ LONG task_magic;
HTMLDocumentNode *doc;
HTMLDocumentObj *doc_obj;
@@ -362,9 +363,6 @@ struct HTMLDocumentObj {
LPWSTR mime;
DWORD update;
-
- /* FIXME: probably should be in document node object */
- struct list bindings;
};
typedef struct {
@@ -501,6 +499,7 @@ struct HTMLDocumentNode {
mutation_queue_t *mutation_queue;
mutation_queue_t *mutation_queue_tail;
+ struct list bindings;
struct list selection_list;
struct list range_list;
};
@@ -663,10 +662,10 @@ nsresult get_nsinterface(nsISupports*,REFIID,void**);
void set_window_bscallback(HTMLWindow*,nsChannelBSC*);
void set_current_mon(HTMLWindow*,IMoniker*);
-HRESULT start_binding(HTMLDocument*,BSCallback*,IBindCtx*);
-void detach_document_bindings(HTMLDocumentObj*);
+HRESULT start_binding(HTMLWindow*,HTMLDocumentNode*,BSCallback*,IBindCtx*);
+void abort_document_bindings(HTMLDocumentNode*);
-HRESULT bind_mon_to_buffer(HTMLDocument*,IMoniker*,void**,DWORD*);
+HRESULT bind_mon_to_buffer(HTMLDocumentNode*,IMoniker*,void**,DWORD*);
nsChannelBSC *create_channelbsc(IMoniker*);
HRESULT channelbsc_load_stream(nsChannelBSC*,IStream*);
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c
index 4f0e60e1f3a..d5fea3af886 100644
--- a/dlls/mshtml/navigate.c
+++ b/dlls/mshtml/navigate.c
@@ -84,7 +84,7 @@ struct BSCallback {
IMoniker *mon;
IBinding *binding;
- HTMLDocument *doc;
+ HTMLDocumentNode *doc;
struct list entry;
};
@@ -315,7 +315,7 @@ static HRESULT WINAPI BindStatusCallback_OnStartBinding(IBindStatusCallback *ifa
This->binding = pbind;
if(This->doc)
- list_add_head(&This->doc->doc_obj->bindings, &This->entry);
+ list_add_head(&This->doc->bindings, &This->entry);
return This->vtbl->start_binding(This);
}
@@ -707,7 +707,7 @@ static void parse_post_data(nsIInputStream *post_data_stream, LPWSTR *headers_re
*post_data_len_ret = post_data_len;
}
-HRESULT start_binding(HTMLDocument *doc, BSCallback *bscallback, IBindCtx *bctx)
+HRESULT start_binding(HTMLWindow *window, HTMLDocumentNode *doc, BSCallback *bscallback, IBindCtx *bctx)
{
IStream *str = NULL;
HRESULT hres;
@@ -716,7 +716,8 @@ HRESULT start_binding(HTMLDocument *doc, BSCallback *bscallback, IBindCtx *bctx)
/* NOTE: IE7 calls IsSystemMoniker here*/
- call_docview_84(doc->doc_obj);
+ if(window)
+ call_docview_84(window->doc_obj);
if(bctx) {
RegisterBindStatusCallback(bctx, STATUSCLB(bscallback), NULL, 0);
@@ -848,14 +849,14 @@ static BufferBSC *create_bufferbsc(IMoniker *mon)
return ret;
}
-HRESULT bind_mon_to_buffer(HTMLDocument *doc, IMoniker *mon, void **buf, DWORD *size)
+HRESULT bind_mon_to_buffer(HTMLDocumentNode *doc, IMoniker *mon, void **buf, DWORD *size)
{
BufferBSC *bsc = create_bufferbsc(mon);
HRESULT hres;
*buf = NULL;
- hres = start_binding(doc, &bsc->bsc, NULL);
+ hres = start_binding(NULL, doc, &bsc->bsc, NULL);
if(SUCCEEDED(hres)) {
hres = bsc->hres;
if(SUCCEEDED(hres)) {
@@ -874,6 +875,8 @@ HRESULT bind_mon_to_buffer(HTMLDocument *doc, IMoniker *mon, void **buf, DWORD *
struct nsChannelBSC {
BSCallback bsc;
+ HTMLWindow *window;
+
nsChannel *nschannel;
nsIStreamListener *nslistener;
nsISupports *nscontext;
@@ -950,11 +953,12 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream)
on_start_nsrequest(This);
+ if(This->window)
+ update_window_doc(This->window);
+
/* events are reset when a new document URI is loaded, so re-initialise them here */
- if(This->bsc.doc && This->bsc.doc->window->bscallback == This && This->bsc.doc->doc_obj->nscontainer) {
- update_window_doc(This->bsc.doc->window);
- init_nsevents(This->bsc.doc->doc_obj->nscontainer);
- }
+ if(This->window && This->window->doc_obj->basedoc.window == This->window)
+ init_nsevents(This->window->doc_obj->nscontainer);
}
This->bsc.readed += This->nsstream->buf_size;
@@ -1109,27 +1113,32 @@ IMoniker *get_channelbsc_mon(nsChannelBSC *This)
void set_window_bscallback(HTMLWindow *window, nsChannelBSC *callback)
{
- BSCallback *iter;
-
if(window->bscallback) {
if(window->bscallback->bsc.binding)
IBinding_Abort(window->bscallback->bsc.binding);
window->bscallback->bsc.doc = NULL;
+ window->bscallback->window = NULL;
IBindStatusCallback_Release(STATUSCLB(&window->bscallback->bsc));
}
- if(window->doc_obj) {
- LIST_FOR_EACH_ENTRY(iter, &window->doc_obj->bindings, BSCallback, entry) {
- iter->doc = NULL;
- list_remove(&iter->entry);
- }
- }
-
window->bscallback = callback;
if(callback) {
+ callback->window = window;
IBindStatusCallback_AddRef(STATUSCLB(&callback->bsc));
- callback->bsc.doc = &window->doc_obj->basedoc;
+ callback->bsc.doc = window->doc;
+ }
+}
+
+void abort_document_bindings(HTMLDocumentNode *doc)
+{
+ BSCallback *iter;
+
+ LIST_FOR_EACH_ENTRY(iter, &doc->bindings, BSCallback, entry) {
+ if(iter->binding)
+ IBinding_Abort(iter->binding);
+ iter->doc = NULL;
+ list_remove(&iter->entry);
}
}
diff --git a/dlls/mshtml/nsio.c b/dlls/mshtml/nsio.c
index 9b2b33b3487..94004ab9b9f 100644
--- a/dlls/mshtml/nsio.c
+++ b/dlls/mshtml/nsio.c
@@ -726,7 +726,7 @@ static HTMLWindow *get_channel_window(nsChannel *This)
typedef struct {
task_t header;
- HTMLDocument *doc;
+ HTMLDocumentNode *doc;
nsChannelBSC *bscallback;
} start_binding_task_t;
@@ -734,7 +734,21 @@ static void start_binding_proc(task_t *_task)
{
start_binding_task_t *task = (start_binding_task_t*)_task;
- start_binding(task->doc, (BSCallback*)task->bscallback, NULL);
+ start_binding(NULL, task->doc, (BSCallback*)task->bscallback, NULL);
+}
+
+typedef struct {
+ task_t header;
+ HTMLWindow *window;
+ nsChannelBSC *bscallback;
+} start_doc_binding_task_t;
+
+static void start_doc_binding_proc(task_t *_task)
+{
+ start_doc_binding_task_t *task = (start_doc_binding_task_t*)_task;
+
+ start_binding(task->window, NULL, (BSCallback*)task->bscallback, NULL);
+ IUnknown_Release((IUnknown*)task->bscallback);
}
static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_channel, nsIStreamListener *listener,
@@ -742,7 +756,6 @@ static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_chan
{
nsChannelBSC *bscallback;
IMoniker *mon = NULL;
- start_binding_task_t *task;
HRESULT hres;
hres = create_mon_for_nschannel(This, &mon);
@@ -757,12 +770,22 @@ static nsresult async_open(nsChannel *This, HTMLWindow *window, BOOL is_doc_chan
channelbsc_set_channel(bscallback, This, listener, context);
- task = heap_alloc(sizeof(start_binding_task_t));
+ if(is_doc_channel) {
+ start_doc_binding_task_t *task;
- task->doc = &window->doc_obj->basedoc;
- task->bscallback = bscallback;
+ set_window_bscallback(window, bscallback);
- push_task(&task->header, start_binding_proc, window->doc_obj->basedoc.task_magic);
+ task = heap_alloc(sizeof(start_doc_binding_task_t));
+ task->window = window;
+ task->bscallback = bscallback;
+ push_task(&task->header, start_doc_binding_proc, window->task_magic);
+ }else {
+ start_binding_task_t *task = heap_alloc(sizeof(start_binding_task_t));
+
+ task->doc = window->doc;
+ task->bscallback = bscallback;
+ push_task(&task->header, start_binding_proc, window->doc->basedoc.task_magic);
+ }
return NS_OK;
}
diff --git a/dlls/mshtml/persist.c b/dlls/mshtml/persist.c
index 6490c3da8a4..97814815962 100644
--- a/dlls/mshtml/persist.c
+++ b/dlls/mshtml/persist.c
@@ -361,7 +361,7 @@ static HRESULT WINAPI PersistMoniker_Load(IPersistMoniker *iface, BOOL fFullyAva
return hres;
if(!bind_complete)
- return start_binding(This, (BSCallback*)This->window->bscallback, pibc);
+ return start_binding(This->window, NULL, (BSCallback*)This->window->bscallback, pibc);
return S_OK;
}
diff --git a/dlls/mshtml/script.c b/dlls/mshtml/script.c
index 5c83e1ed294..4ee0da08b31 100644
--- a/dlls/mshtml/script.c
+++ b/dlls/mshtml/script.c
@@ -645,7 +645,7 @@ static void parse_extern_script(ScriptHost *script_host, LPCWSTR src)
if(FAILED(hres))
return;
- hres = bind_mon_to_buffer(&script_host->window->doc_obj->basedoc, mon, (void**)&buf, &size);
+ hres = bind_mon_to_buffer(script_host->window->doc, mon, (void**)&buf, &size);
IMoniker_Release(mon);
if(FAILED(hres))
return;