From 745f601d2359f7a72d6c839991e9b7d287e54d29 Mon Sep 17 00:00:00 2001 From: Jacek Caban Date: Mon, 26 Oct 2009 23:05:37 +0100 Subject: [PATCH] mshtml: Moved binding list to HTMLDocumentNode. --- dlls/mshtml/htmldoc.c | 2 +- dlls/mshtml/htmlwindow.c | 3 +++ dlls/mshtml/mshtml_private.h | 11 ++++---- dlls/mshtml/navigate.c | 49 +++++++++++++++++++++--------------- dlls/mshtml/nsio.c | 37 +++++++++++++++++++++------ dlls/mshtml/persist.c | 2 +- dlls/mshtml/script.c | 2 +- 7 files changed, 70 insertions(+), 36 deletions(-) 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;