mshtml: Store window reference in nsURI.
This commit is contained in:
parent
2d1a7173a4
commit
45ce37fe64
|
@ -180,6 +180,10 @@ static ULONG WINAPI HTMLWindow2_Release(IHTMLWindow2 *iface)
|
|||
release_event_target(This->event_target);
|
||||
for(i=0; i < This->global_prop_cnt; i++)
|
||||
heap_free(This->global_props[i].name);
|
||||
|
||||
This->window_ref->window = NULL;
|
||||
windowref_release(This->window_ref);
|
||||
|
||||
heap_free(This->global_props);
|
||||
heap_free(This->event_vector);
|
||||
release_script_hosts(This);
|
||||
|
@ -1553,12 +1557,21 @@ HRESULT HTMLWindow_Create(HTMLDocumentObj *doc_obj, nsIDOMWindow *nswindow, HTML
|
|||
if(!window)
|
||||
return E_OUTOFMEMORY;
|
||||
|
||||
window->window_ref = heap_alloc(sizeof(windowref_t));
|
||||
if(!window->window_ref) {
|
||||
heap_free(window->window_ref);
|
||||
return E_OUTOFMEMORY;
|
||||
}
|
||||
|
||||
window->lpHTMLWindow2Vtbl = &HTMLWindow2Vtbl;
|
||||
window->lpHTMLWindow3Vtbl = &HTMLWindow3Vtbl;
|
||||
window->lpIDispatchExVtbl = &WindowDispExVtbl;
|
||||
window->ref = 1;
|
||||
window->doc_obj = doc_obj;
|
||||
|
||||
window->window_ref->window = window;
|
||||
window->window_ref->ref = 1;
|
||||
|
||||
init_dispex(&window->dispex, (IUnknown*)HTMLWINDOW2(window), &HTMLWindow_dispex);
|
||||
|
||||
if(nswindow) {
|
||||
|
|
|
@ -157,7 +157,6 @@ void release_dispex(DispatchEx*);
|
|||
BOOL dispex_query_interface(DispatchEx*,REFIID,void**);
|
||||
HRESULT dispex_get_dprop_ref(DispatchEx*,const WCHAR*,BOOL,VARIANT**);
|
||||
|
||||
typedef struct HTMLWindow HTMLWindow;
|
||||
typedef struct HTMLDocumentNode HTMLDocumentNode;
|
||||
typedef struct HTMLDocumentObj HTMLDocumentObj;
|
||||
|
||||
|
@ -200,6 +199,11 @@ struct HTMLLocation {
|
|||
HTMLWindow *window;
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
HTMLWindow *window;
|
||||
LONG ref;
|
||||
} windowref_t;
|
||||
|
||||
struct HTMLWindow {
|
||||
DispatchEx dispex;
|
||||
const IHTMLWindow2Vtbl *lpHTMLWindow2Vtbl;
|
||||
|
@ -208,6 +212,8 @@ struct HTMLWindow {
|
|||
|
||||
LONG ref;
|
||||
|
||||
windowref_t *window_ref;
|
||||
|
||||
HTMLDocumentNode *doc;
|
||||
HTMLDocumentObj *doc_obj;
|
||||
nsIDOMWindow *nswindow;
|
||||
|
@ -655,6 +661,7 @@ nsresult get_nsinterface(nsISupports*,REFIID,void**);
|
|||
void set_document_bscallback(HTMLDocument*,nsChannelBSC*);
|
||||
void set_current_mon(HTMLDocument*,IMoniker*);
|
||||
HRESULT start_binding(HTMLDocument*,BSCallback*,IBindCtx*);
|
||||
void detach_document_bindings(HTMLDocumentObj*);
|
||||
|
||||
HRESULT bind_mon_to_buffer(HTMLDocument*,IMoniker*,void**,DWORD*);
|
||||
|
||||
|
@ -877,6 +884,17 @@ static inline char *heap_strdupWtoA(LPCWSTR str)
|
|||
return ret;
|
||||
}
|
||||
|
||||
static inline void windowref_addref(windowref_t *ref)
|
||||
{
|
||||
InterlockedIncrement(&ref->ref);
|
||||
}
|
||||
|
||||
static inline void windowref_release(windowref_t *ref)
|
||||
{
|
||||
if(!InterlockedDecrement(&ref->ref))
|
||||
heap_free(ref);
|
||||
}
|
||||
|
||||
HINSTANCE get_shdoclc(void);
|
||||
|
||||
extern HINSTANCE hInst;
|
||||
|
|
|
@ -135,7 +135,6 @@ typedef nsISupports nsIDOMHTMLTableSectionElement;
|
|||
typedef nsISupports nsIDOMClientRectList;
|
||||
typedef nsISupports nsIDOMClientRect;
|
||||
typedef nsISupports nsIDOMLocation;
|
||||
typedef nsISupports nsIBoxObject;
|
||||
typedef nsISupports nsIDocument;
|
||||
typedef nsISupports nsIContent;
|
||||
typedef nsISupports nsINode;
|
||||
|
@ -1638,6 +1637,20 @@ interface nsIWebNavigation : nsISupports
|
|||
nsresult SetSessionHistory(nsISHistory *aSessionHistory);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(570f39d0-efd0-11d3-b093-00a024ffc08c),
|
||||
local
|
||||
/* FROZEN */
|
||||
]
|
||||
interface nsIWebProgress : nsISupports
|
||||
{
|
||||
nsresult AddProgressListener(nsIWebProgressListener *aListener, PRUint32 aNotifyMask);
|
||||
nsresult RemoveProgressListener(nsIWebProgressListener *aListener);
|
||||
nsresult GetDOMWindow(nsIDOMWindow **aDOMWindow);
|
||||
nsresult GetIsLoadingDocument(PRBool *aIsLoadingDocument);
|
||||
}
|
||||
|
||||
[
|
||||
object,
|
||||
uuid(343700dd-078b-42b6-a809-b9c1d7e951d0),
|
||||
|
@ -2644,9 +2657,12 @@ interface nsIDocumentObserver : nsIMutationObserver
|
|||
interface nsIWineURI : nsIURL
|
||||
{
|
||||
typedef struct NSContainer NSContainer;
|
||||
typedef struct HTMLWindow HTMLWindow;
|
||||
|
||||
nsresult GetNSContainer(NSContainer **aNSContainer);
|
||||
nsresult SetNSContainer(NSContainer *aNSContainer);
|
||||
nsresult GetWindow(HTMLWindow **aHTMLWindow);
|
||||
nsresult SetWindow(HTMLWindow *aHTMLWindow);
|
||||
nsresult GetIsDocumentURI(PRBool *aIsDocumentURI);
|
||||
nsresult SetIsDocumentURI(PRBool aIsDocumentURI);
|
||||
nsresult GetWineURL(LPCWSTR *aURL);
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef struct {
|
|||
nsIURI *uri;
|
||||
nsIURL *nsurl;
|
||||
NSContainer *container;
|
||||
windowref_t *window_ref;
|
||||
LPWSTR wine_url;
|
||||
PRBool is_doc_uri;
|
||||
BOOL use_wine_url;
|
||||
|
@ -67,7 +68,7 @@ typedef struct {
|
|||
#define NSURI(x) ((nsIURI*) &(x)->lpWineURIVtbl)
|
||||
#define NSWINEURI(x) ((nsIWineURI*) &(x)->lpWineURIVtbl)
|
||||
|
||||
static nsresult create_uri(nsIURI*,NSContainer*,nsIWineURI**);
|
||||
static nsresult create_uri(nsIURI*,HTMLWindow*,NSContainer*,nsIWineURI**);
|
||||
|
||||
static const char *debugstr_nsacstr(const nsACString *nsstr)
|
||||
{
|
||||
|
@ -680,6 +681,49 @@ static NSContainer *get_nscontainer_from_load_group(nsChannel *This)
|
|||
return container;
|
||||
}
|
||||
|
||||
static HTMLWindow *get_channel_window(nsChannel *This)
|
||||
{
|
||||
nsIRequestObserver *req_observer;
|
||||
nsIWebProgress *web_progress;
|
||||
nsIDOMWindow *nswindow;
|
||||
HTMLWindow *window;
|
||||
nsresult nsres;
|
||||
|
||||
if(!This->load_group) {
|
||||
ERR("NULL load_group\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsres = nsILoadGroup_GetGroupObserver(This->load_group, &req_observer);
|
||||
if(NS_FAILED(nsres) || !req_observer) {
|
||||
ERR("GetGroupObserver failed: %08x\n", nsres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsres = nsIRequestObserver_QueryInterface(req_observer, &IID_nsIWebProgress, (void**)&web_progress);
|
||||
nsIRequestObserver_Release(req_observer);
|
||||
if(NS_FAILED(nsres)) {
|
||||
ERR("Could not get nsIWebProgress iface: %08x\n", nsres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nsres = nsIWebProgress_GetDOMWindow(web_progress, &nswindow);
|
||||
nsIWebProgress_Release(web_progress);
|
||||
if(NS_FAILED(nsres) || !nswindow) {
|
||||
ERR("GetDOMWindow failed: %08x\n", nsres);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
window = nswindow_to_window(nswindow);
|
||||
nsIDOMWindow_Release(nswindow);
|
||||
|
||||
if(window)
|
||||
IHTMLWindow2_AddRef(HTMLWINDOW2(window));
|
||||
else
|
||||
FIXME("NULL window for %p\n", nswindow);
|
||||
return window;
|
||||
}
|
||||
|
||||
static nsresult async_open_doc_uri(nsChannel *This, NSContainer *container,
|
||||
nsIStreamListener *listener, nsISupports *context, BOOL *open)
|
||||
{
|
||||
|
@ -756,12 +800,29 @@ static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListen
|
|||
{
|
||||
nsChannel *This = NSCHANNEL_THIS(iface);
|
||||
NSContainer *container;
|
||||
HTMLWindow *window;
|
||||
PRBool is_doc_uri;
|
||||
BOOL open = TRUE;
|
||||
nsresult nsres = NS_OK;
|
||||
|
||||
TRACE("(%p)->(%p %p)\n", This, aListener, aContext);
|
||||
|
||||
if(TRACE_ON(mshtml)) {
|
||||
LPCWSTR url;
|
||||
|
||||
nsIWineURI_GetWineURL(This->uri, &url);
|
||||
TRACE("opening %s\n", debugstr_w(url));
|
||||
}
|
||||
|
||||
nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri);
|
||||
if(is_doc_uri) {
|
||||
window = get_channel_window(This);
|
||||
if(window) {
|
||||
nsIWineURI_SetWindow(This->uri, window);
|
||||
IHTMLWindow2_Release(HTMLWINDOW2(window));
|
||||
}
|
||||
}
|
||||
|
||||
nsIWineURI_GetNSContainer(This->uri, &container);
|
||||
|
||||
if(!container && This->load_group) {
|
||||
|
@ -777,8 +838,6 @@ static nsresult NSAPI nsChannel_AsyncOpen(nsIHttpChannel *iface, nsIStreamListen
|
|||
: NS_ERROR_UNEXPECTED;
|
||||
}
|
||||
|
||||
nsIWineURI_GetIsDocumentURI(This->uri, &is_doc_uri);
|
||||
|
||||
if(is_doc_uri && (This->load_flags & LOAD_INITIAL_DOCUMENT_URI))
|
||||
nsres = async_open_doc_uri(This, container, aListener, aContext, &open);
|
||||
|
||||
|
@ -1347,6 +1406,8 @@ static nsrefcnt NSAPI nsURI_Release(nsIWineURI *iface)
|
|||
TRACE("(%p) ref=%d\n", This, ref);
|
||||
|
||||
if(!ref) {
|
||||
if(This->window_ref)
|
||||
windowref_release(This->window_ref);
|
||||
if(This->container)
|
||||
nsIWebBrowserChrome_Release(NSWBCHROME(This->container));
|
||||
if(This->nsurl)
|
||||
|
@ -1708,7 +1769,7 @@ static nsresult NSAPI nsURI_Clone(nsIWineURI *iface, nsIURI **_retval)
|
|||
}
|
||||
}
|
||||
|
||||
nsres = create_uri(nsuri, This->container, &wine_uri);
|
||||
nsres = create_uri(nsuri, This->window_ref ? This->window_ref->window : NULL, This->container, &wine_uri);
|
||||
if(NS_FAILED(nsres)) {
|
||||
WARN("create_uri failed: %08x\n", nsres);
|
||||
return nsres;
|
||||
|
@ -2081,6 +2142,48 @@ static nsresult NSAPI nsURI_SetNSContainer(nsIWineURI *iface, NSContainer *aCont
|
|||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI nsURI_GetWindow(nsIWineURI *iface, HTMLWindow **aHTMLWindow)
|
||||
{
|
||||
nsURI *This = NSURI_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, aHTMLWindow);
|
||||
|
||||
if(This->window_ref && This->window_ref->window) {
|
||||
IHTMLWindow2_AddRef(HTMLWINDOW2(This->window_ref->window));
|
||||
*aHTMLWindow = This->window_ref->window;
|
||||
}else {
|
||||
*aHTMLWindow = NULL;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI nsURI_SetWindow(nsIWineURI *iface, HTMLWindow *aHTMLWindow)
|
||||
{
|
||||
nsURI *This = NSURI_THIS(iface);
|
||||
|
||||
TRACE("(%p)->(%p)\n", This, aHTMLWindow);
|
||||
|
||||
if(This->window_ref) {
|
||||
if(This->window_ref->window == aHTMLWindow)
|
||||
return NS_OK;
|
||||
TRACE("Changing %p -> %p\n", This->window_ref->window, aHTMLWindow);
|
||||
windowref_release(This->window_ref);
|
||||
}
|
||||
|
||||
if(aHTMLWindow) {
|
||||
windowref_addref(aHTMLWindow->window_ref);
|
||||
This->window_ref = aHTMLWindow->window_ref;
|
||||
|
||||
if(aHTMLWindow->doc_obj)
|
||||
nsIWineURI_SetNSContainer(NSWINEURI(This), aHTMLWindow->doc_obj->nscontainer);
|
||||
}else {
|
||||
This->window_ref = NULL;
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
static nsresult NSAPI nsURI_GetIsDocumentURI(nsIWineURI *iface, PRBool *aIsDocumentURI)
|
||||
{
|
||||
nsURI *This = NSURI_THIS(iface);
|
||||
|
@ -2193,26 +2296,24 @@ static const nsIWineURIVtbl nsWineURIVtbl = {
|
|||
nsURL_GetRelativeSpec,
|
||||
nsURI_GetNSContainer,
|
||||
nsURI_SetNSContainer,
|
||||
nsURI_GetWindow,
|
||||
nsURI_SetWindow,
|
||||
nsURI_GetIsDocumentURI,
|
||||
nsURI_SetIsDocumentURI,
|
||||
nsURI_GetWineURL,
|
||||
nsURI_SetWineURL
|
||||
};
|
||||
|
||||
static nsresult create_uri(nsIURI *uri, NSContainer *container, nsIWineURI **_retval)
|
||||
static nsresult create_uri(nsIURI *uri, HTMLWindow *window, NSContainer *container, nsIWineURI **_retval)
|
||||
{
|
||||
nsURI *ret = heap_alloc(sizeof(nsURI));
|
||||
nsURI *ret = heap_alloc_zero(sizeof(nsURI));
|
||||
|
||||
ret->lpWineURIVtbl = &nsWineURIVtbl;
|
||||
ret->ref = 1;
|
||||
ret->uri = uri;
|
||||
ret->container = container;
|
||||
ret->wine_url = NULL;
|
||||
ret->is_doc_uri = FALSE;
|
||||
ret->use_wine_url = FALSE;
|
||||
|
||||
if(container)
|
||||
nsIWebBrowserChrome_AddRef(NSWBCHROME(container));
|
||||
nsIWineURI_SetNSContainer(NSWINEURI(ret), container);
|
||||
nsIWineURI_SetWindow(NSWINEURI(ret), window);
|
||||
|
||||
if(uri)
|
||||
nsIURI_QueryInterface(uri, &IID_nsIURL, (void**)&ret->nsurl);
|
||||
|
@ -2449,7 +2550,7 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *
|
|||
const char *aOriginCharset, nsIURI *aBaseURI, nsIURI **_retval)
|
||||
{
|
||||
const char *spec = NULL;
|
||||
NSContainer *nscontainer = NULL;
|
||||
HTMLWindow *window = NULL;
|
||||
nsIURI *uri = NULL;
|
||||
LPCWSTR base_wine_url = NULL;
|
||||
nsIWineURI *base_wine_uri = NULL, *wine_uri;
|
||||
|
@ -2493,20 +2594,20 @@ static nsresult NSAPI nsIOService_NewURI(nsIIOService *iface, const nsACString *
|
|||
if(aBaseURI) {
|
||||
nsres = nsIURI_QueryInterface(aBaseURI, &IID_nsIWineURI, (void**)&base_wine_uri);
|
||||
if(NS_SUCCEEDED(nsres)) {
|
||||
nsIWineURI_GetNSContainer(base_wine_uri, &nscontainer);
|
||||
nsIWineURI_GetWindow(base_wine_uri, &window);
|
||||
nsIWineURI_GetWineURL(base_wine_uri, &base_wine_url);
|
||||
}else {
|
||||
TRACE("Could not get base nsIWineURI: %08x\n", nsres);
|
||||
}
|
||||
}
|
||||
|
||||
TRACE("nscontainer = %p\n", nscontainer);
|
||||
TRACE("window = %p\n", window);
|
||||
|
||||
nsres = create_uri(uri, nscontainer, &wine_uri);
|
||||
nsres = create_uri(uri, window, NULL, &wine_uri);
|
||||
*_retval = (nsIURI*)wine_uri;
|
||||
|
||||
if(nscontainer)
|
||||
nsIWebBrowserChrome_Release(NSWBCHROME(nscontainer));
|
||||
if(window)
|
||||
IHTMLWindow2_Release(HTMLWINDOW2(window));
|
||||
|
||||
if(base_wine_url) {
|
||||
WCHAR url[INTERNET_MAX_URL_LENGTH], rel_url[INTERNET_MAX_URL_LENGTH];
|
||||
|
|
Loading…
Reference in New Issue