The storage event url prop fix is tested after the location.hash tests are added, implicitly. I didn't find a need to add extra tests for no reason there.
The super_navigate changes for fragments is also necessary for the location.hash tests (and its behavior, apparently)…
-- v3: mshtml: Implement document.importNode. mshtml: Implement HTMLLocation_put_hash. mshtml: Always use super_navigate when navigating fragments. mshtml: Don't include fragment in storage event's url prop. mshtml: Return E_ABORT if wine-gecko's OnDataAvailable aborts the binding. mshtml: Improve locale stub for KeyboardEvent. mshtml: Implement isContentEditable for HTML elements. mshtml/tests: Handle broken localStorage on native.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/events.c | 20 +++++++++++++++++--- dlls/mshtml/tests/misc.c | 16 +++++++++++++--- 2 files changed, 30 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index b53851d61bf..8175205b830 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -4024,12 +4024,19 @@ static void test_storage_events(const char *doc_str) ok(hres == S_OK, "Could not get IHTMLWindow6: %08lx\n", hres); IHTMLWindow2_Release(window);
- hres = IHTMLWindow6_get_sessionStorage(window6, &session_storage[i]); - ok(hres == S_OK, "get_sessionStorage[%u] failed: %08lx\n", i, hres); - ok(session_storage[i] != NULL, "session_storage[%u] == NULL\n", i); hres = IHTMLWindow6_get_localStorage(window6, &local_storage[i]); + + /* w10pro64 testbot VM sometimes returns this for some reason */ + if(hres == WININET_E_INTERNAL_ERROR) { + win_skip("localStorage is buggy and not available, skipping storage events tests\n"); + goto done; + } + ok(hres == S_OK, "get_localStorage[%u] failed: %08lx\n", i, hres); ok(local_storage[i] != NULL, "local_storage[%u] == NULL\n", i); + hres = IHTMLWindow6_get_sessionStorage(window6, &session_storage[i]); + ok(hres == S_OK, "get_sessionStorage[%u] failed: %08lx\n", i, hres); + ok(session_storage[i] != NULL, "session_storage[%u] == NULL\n", i);
hres = IHTMLDocument2_QueryInterface(doc[i], &IID_IHTMLDocument6, (void**)&doc6); if(SUCCEEDED(hres)) { @@ -4125,6 +4132,9 @@ static void test_storage_events(const char *doc_str) pump_msgs(&called_doc1_onstoragecommit); CHECK_CALLED(doc1_onstoragecommit);
+ for(i = 0; i < ARRAY_SIZE(local_storage); i++) + IHTMLStorage_Release(local_storage[i]); + /* session storage */ key = SysAllocString(L"foobar"); hres = IHTMLStorage_removeItem(session_storage[0], key); @@ -4184,6 +4194,10 @@ static void test_storage_events(const char *doc_str) CHECK_CALLED(doc1_onstorage); if(document_mode >= 9) CHECK_CALLED(window1_onstorage);
+ for(i = 0; i < ARRAY_SIZE(session_storage); i++) + IHTMLStorage_Release(session_storage[i]); + +done: set_client_site(doc[0], FALSE); set_client_site(doc[1], FALSE); IHTMLDocument2_Release(doc[0]); diff --git a/dlls/mshtml/tests/misc.c b/dlls/mshtml/tests/misc.c index 5f38f9d45fb..e4703a3b646 100644 --- a/dlls/mshtml/tests/misc.c +++ b/dlls/mshtml/tests/misc.c @@ -161,8 +161,14 @@ static HRESULT get_localstorage(IHTMLDocument2 *doc, IHTMLStorage **storage) }
hres = IHTMLWindow6_get_localStorage(window6, storage); - ok(hres == S_OK, "get_localStorage failed: %08lx\n", hres); - ok(*storage != NULL, "*storage == NULL\n"); + + /* w10pro64 testbot VM sometimes returns this for some reason */ + if(hres == WININET_E_INTERNAL_ERROR) + win_skip("localStorage is buggy and not available, skipping tests\n"); + else { + ok(hres == S_OK, "get_localStorage failed: %08lx\n", hres); + ok(*storage != NULL, "*storage == NULL\n"); + }
IHTMLWindow6_Release(window6); return hres; @@ -206,7 +212,11 @@ static void test_HTMLStorage(void) doc2 = create_doc_from_url(L"http://www.codeweavers.com/");
hres = get_localstorage(doc, &storage); - ok(hres == S_OK, "got %08lx\n", hres); + if(hres != S_OK) { + IHTMLDocument2_Release(doc2); + IHTMLDocument2_Release(doc); + return; + }
hres = get_localstorage(doc2, &storage2); ok(hres == S_OK, "got %08lx\n", hres);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 15 +++++++++++++-- dlls/mshtml/tests/dom.c | 16 ++++++++++++++++ 2 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 8a45a354a04..4d92929b985 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -4256,8 +4256,19 @@ static HRESULT WINAPI HTMLElement3_get_contentEditable(IHTMLElement3 *iface, BST static HRESULT WINAPI HTMLElement3_get_isContentEditable(IHTMLElement3 *iface, VARIANT_BOOL *p) { HTMLElement *This = impl_from_IHTMLElement3(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + nsresult nsres; + cpp_bool r; + + TRACE("(%p)->(%p)\n", This, p); + + if(!This->html_element) { + FIXME("non-HTML element\n"); + return E_NOTIMPL; + } + + nsres = nsIDOMHTMLElement_GetIsContentEditable(This->html_element, &r); + *p = variant_bool(NS_SUCCEEDED(nsres) && r); + return S_OK; }
static HRESULT WINAPI HTMLElement3_put_hideFocus(IHTMLElement3 *iface, VARIANT_BOOL v) diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index 6f4e8ed007b..70b047ccbe1 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -3945,6 +3945,7 @@ static void test_contenteditable(IUnknown *unk) IHTMLElement3 *elem3 = get_elem3_iface(unk); HRESULT hres; BSTR str, strDefault; + VARIANT_BOOL vbool;
hres = IHTMLElement3_get_contentEditable(elem3, &strDefault); ok(hres == S_OK, "get_contentEditable failed: 0x%08lx\n", hres); @@ -3957,6 +3958,21 @@ static void test_contenteditable(IUnknown *unk) ok(hres == S_OK, "get_contentEditable failed: 0x%08lx\n", hres); ok(!lstrcmpW(str, L"true"), "Got %s, expected %s\n", wine_dbgstr_w(str), "true"); SysFreeString(str); + hres = IHTMLElement3_get_isContentEditable(elem3, &vbool); + ok(hres == S_OK, "get_isContentEditable failed: 0x%08lx\n", hres); + ok(vbool == VARIANT_TRUE, "Got %d, expected VARIANT_TRUE\n", vbool); + + str = SysAllocString(L"inherit"); + hres = IHTMLElement3_put_contentEditable(elem3, str); + ok(hres == S_OK, "put_contentEditable(%s) failed: 0x%08lx\n", wine_dbgstr_w(str), hres); + SysFreeString(str); + hres = IHTMLElement3_get_contentEditable(elem3, &str); + ok(hres == S_OK, "get_contentEditable failed: 0x%08lx\n", hres); + ok(!lstrcmpW(str, L"inherit"), "Got %s, expected %s\n", wine_dbgstr_w(str), "inherit"); + SysFreeString(str); + hres = IHTMLElement3_get_isContentEditable(elem3, &vbool); + ok(hres == S_OK, "get_isContentEditable failed: 0x%08lx\n", hres); + ok(vbool == VARIANT_FALSE, "Got %d, expected VARIANT_FALSE\n", vbool);
/* Restore origin contentEditable */ hres = IHTMLElement3_put_contentEditable(elem3, strDefault);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 7 +++++-- dlls/mshtml/tests/events.js | 1 + 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 59a8d50d40e..835e11c74aa 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2154,8 +2154,11 @@ static HRESULT WINAPI DOMKeyboardEvent_get_char(IDOMKeyboardEvent *iface, VARIAN static HRESULT WINAPI DOMKeyboardEvent_get_locale(IDOMKeyboardEvent *iface, BSTR *p) { DOMKeyboardEvent *This = impl_from_IDOMKeyboardEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + FIXME("(%p)->(%p) semi-stub\n", This, p); + + *p = SysAllocString(L""); + return *p ? S_OK : E_OUTOFMEMORY; }
static const IDOMKeyboardEventVtbl DOMKeyboardEventVtbl = { diff --git a/dlls/mshtml/tests/events.js b/dlls/mshtml/tests/events.js index 156330e984b..3b29798e9a1 100644 --- a/dlls/mshtml/tests/events.js +++ b/dlls/mshtml/tests/events.js @@ -760,6 +760,7 @@ sync_test("keyboard_event", function() { ok(e.location === 0, "location = " + e.location); ok(e.detail === 0, "detail = " + e.detail); ok(e.which === 0, "which = " + e.which); + ok(e.locale === "", "locale = " + e.locale); });
sync_test("custom_event", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/navigate.c | 6 ++++-- dlls/mshtml/nsembed.c | 2 ++ 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 3594cfe0a6c..66542fbd676 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -1184,8 +1184,10 @@ static HRESULT read_stream_data(nsChannelBSC *This, IStream *stream) (nsIRequest*)&This->nschannel->nsIHttpChannel_iface, This->nscontext, &This->nsstream->nsIInputStream_iface, This->bsc.read-This->nsstream->buf_size, This->nsstream->buf_size); - if(NS_FAILED(nsres)) - ERR("OnDataAvailable failed: %08lx\n", nsres); + if(NS_FAILED(nsres)) { + WARN("OnDataAvailable failed: %08lx\n", nsres); + return map_nsresult(nsres); + }
if(This->nsstream->buf_size == sizeof(This->nsstream->buf)) { ERR("buffer is full\n"); diff --git a/dlls/mshtml/nsembed.c b/dlls/mshtml/nsembed.c index 67d40ca0085..0b16cd90306 100644 --- a/dlls/mshtml/nsembed.c +++ b/dlls/mshtml/nsembed.c @@ -911,6 +911,8 @@ HRESULT map_nsresult(nsresult nsres) return E_UNEXPECTED; case NS_ERROR_DOM_NO_MODIFICATION_ALLOWED_ERR: return 0x80700007; /* according to tests */ + case NS_BINDING_ABORTED: + return E_ABORT; } return E_FAIL; }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstorage.c | 14 ++++++++++---- dlls/mshtml/tests/documentmode.js | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-)
diff --git a/dlls/mshtml/htmlstorage.c b/dlls/mshtml/htmlstorage.c index bf93e28fdf6..d8ecf573b2b 100644 --- a/dlls/mshtml/htmlstorage.c +++ b/dlls/mshtml/htmlstorage.c @@ -235,7 +235,7 @@ struct send_storage_event_ctx { BSTR key; BSTR old_value; BSTR new_value; - const WCHAR *url; + BSTR url; };
static HRESULT push_storage_event_task(struct send_storage_event_ctx *ctx, HTMLInnerWindow *window, BOOL commit) @@ -324,11 +324,16 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value BSTR hostname = NULL; HRESULT hres = S_OK;
+ ctx.url = NULL; if(!window) goto done; - get_top_window(window->base.outer_window, &top_window); + if(window->base.outer_window->uri_nofrag) { + hres = IUri_GetDisplayUri(window->base.outer_window->uri_nofrag, &ctx.url); + if(hres != S_OK) + goto done; + }
- ctx.url = window->base.outer_window->url; + get_top_window(window->base.outer_window, &top_window); ctx.key = key; ctx.old_value = old_value; ctx.new_value = new_value; @@ -351,9 +356,10 @@ static HRESULT send_storage_event(HTMLStorage *storage, BSTR key, BSTR old_value hres = push_storage_event_task(&ctx, window, TRUE);
done: + SysFreeString(ctx.url); SysFreeString(hostname); SysFreeString(old_value); - return hres; + return FAILED(hres) ? hres : S_OK; }
static HRESULT WINAPI HTMLStorage_QueryInterface(IHTMLStorage *iface, REFIID riid, void **ppv) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index a0f170c73b4..92f30f8b7e9 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -1468,7 +1468,7 @@ async_test("storage events", function() { ok(e.key === key, "key = " + e.key + ", expected " + key); ok(e.oldValue === oldValue, "oldValue = " + e.oldValue + ", expected " + oldValue); ok(e.newValue === newValue, "newValue = " + e.newValue + ", expected " + newValue); - s = (idx ? iframe.contentWindow : window)["location"]["href"]; + s = (idx ? iframe.contentWindow : window)["location"]["href"].split('#', 1)[0]; ok(e.url === s, "url = " + e.url + ", expected " + s); }
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/binding.h | 1 + dlls/mshtml/navigate.c | 34 +++++++++++++++++++++------------- 2 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/dlls/mshtml/binding.h b/dlls/mshtml/binding.h index 479cb71cf15..2b3693a8c89 100644 --- a/dlls/mshtml/binding.h +++ b/dlls/mshtml/binding.h @@ -136,6 +136,7 @@ typedef struct { #define BINDING_REFRESH 0x0008 #define BINDING_SUBMIT 0x0010 #define BINDING_NOFRAG 0x0020 +#define BINDING_FRAGNAV 0x0040
HRESULT set_http_header(struct list*,const WCHAR*,int,const WCHAR*,int) DECLSPEC_HIDDEN; HRESULT create_redirect_nschannel(const WCHAR*,nsChannel*,nsChannel**) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/navigate.c b/dlls/mshtml/navigate.c index 66542fbd676..2084b13847e 100644 --- a/dlls/mshtml/navigate.c +++ b/dlls/mshtml/navigate.c @@ -2213,15 +2213,10 @@ HRESULT super_navigate(HTMLOuterWindow *window, IUri *uri, DWORD flags, const WC } }
- if(!(flags & BINDING_NOFRAG) && window->uri_nofrag && !post_data_size) { - BOOL eq; - - hres = IUri_IsEqual(uri_nofrag, window->uri_nofrag, &eq); - if(SUCCEEDED(hres) && eq) { - IUri_Release(uri_nofrag); - TRACE("fragment navigate\n"); - return navigate_fragment(window, uri); - } + if(flags & BINDING_FRAGNAV) { + IUri_Release(uri_nofrag); + TRACE("fragment navigate\n"); + return navigate_fragment(window, uri); }
hres = CreateURLMonikerEx2(NULL, uri_nofrag, &mon, URL_MK_UNIFORM); @@ -2449,6 +2444,9 @@ HRESULT hlink_frame_navigate(HTMLDocumentObj *doc, LPCWSTR url, nsChannel *nscha static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *display_uri, const request_data_t *request_data, DWORD flags) { + DWORD post_data_len = request_data ? request_data->post_data_len : 0; + void *post_data = post_data_len ? request_data->post_data : NULL; + const WCHAR *headers = request_data ? request_data->headers : NULL; nsWineURI *nsuri; HRESULT hres;
@@ -2457,11 +2455,18 @@ static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *dis if(!window->browser) return E_UNEXPECTED;
- if(window->browser->doc->webbrowser) { - DWORD post_data_len = request_data ? request_data->post_data_len : 0; - void *post_data = post_data_len ? request_data->post_data : NULL; - const WCHAR *headers = request_data ? request_data->headers : NULL; + if(!(flags & BINDING_NOFRAG) && window->uri_nofrag && !post_data_len) { + IUri *uri_nofrag = get_uri_nofrag(uri); + if(uri_nofrag) { + BOOL frag_nav = FALSE; + IUri_IsEqual(uri_nofrag, window->uri_nofrag, &frag_nav); + IUri_Release(uri_nofrag); + if(frag_nav) + flags |= BINDING_FRAGNAV; + } + }
+ if(window->browser->doc->webbrowser) { if(!(flags & BINDING_REFRESH)) { BSTR frame_name = NULL; BOOL cancel = FALSE; @@ -2485,6 +2490,9 @@ static HRESULT navigate_uri(HTMLOuterWindow *window, IUri *uri, const WCHAR *dis return super_navigate(window, uri, flags, headers, post_data, post_data_len); }
+ if(flags & BINDING_FRAGNAV) + return super_navigate(window, uri, flags, headers, post_data, post_data_len); + if(is_main_content_window(window)) { BOOL cancel;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmllocation.c | 25 +++++++++++++++++++++++-- dlls/mshtml/tests/documentmode.js | 12 ++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmllocation.c b/dlls/mshtml/htmllocation.c index 8f7800ff2a3..26365a7a5d0 100644 --- a/dlls/mshtml/htmllocation.c +++ b/dlls/mshtml/htmllocation.c @@ -524,8 +524,29 @@ static HRESULT WINAPI HTMLLocation_get_search(IHTMLLocation *iface, BSTR *p) static HRESULT WINAPI HTMLLocation_put_hash(IHTMLLocation *iface, BSTR v) { HTMLLocation *This = impl_from_IHTMLLocation(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + WCHAR *hash = v; + HRESULT hres; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + if(!This->window || !This->window->base.outer_window) { + FIXME("No window available\n"); + return E_FAIL; + } + + if(hash[0] != '#') { + unsigned size = (1 /* # */ + wcslen(v) + 1) * sizeof(WCHAR); + if(!(hash = heap_alloc(size))) + return E_OUTOFMEMORY; + hash[0] = '#'; + memcpy(hash + 1, v, size - sizeof(WCHAR)); + } + + hres = navigate_url(This->window->base.outer_window, hash, This->window->base.outer_window->uri, BINDING_NAVIGATED); + + if(hash != v) + heap_free(hash); + return hres; }
static HRESULT WINAPI HTMLLocation_get_hash(IHTMLLocation *iface, BSTR *p) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 92f30f8b7e9..5da89349d6d 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -895,6 +895,18 @@ async_test("script_load", function() { external.writeStream("simple", "ready_states += 'exec,';"); });
+sync_test("location", function() { + document.body.innerHTML = '<a name="testanchor">test</a>'; + + ok(location.hash === "", "initial location.hash = " + location.hash); + location.hash = "TestAnchor"; + ok(location.hash === "#TestAnchor", "location.hash after set to TestAnchor = " + location.hash); + location.hash = "##foo"; + ok(location.hash === "##foo", "location.hash after set to ##foo = " + location.hash); + location.hash = "#testanchor"; + ok(location.hash === "#testanchor", "location.hash after set to #testanchor = " + location.hash); +}); + sync_test("navigator", function() { var v = document.documentMode, re; var app = navigator.appVersion;
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmldoc.c | 37 ++++++++++++++++++++++++++++++++++-- dlls/mshtml/htmlnode.c | 5 +++++ dlls/mshtml/mshtml_private.h | 2 ++ dlls/mshtml/tests/dom.js | 27 ++++++++++++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmldoc.c b/dlls/mshtml/htmldoc.c index dd7d9f44d48..0988d34f85b 100644 --- a/dlls/mshtml/htmldoc.c +++ b/dlls/mshtml/htmldoc.c @@ -4375,8 +4375,41 @@ static HRESULT WINAPI HTMLDocument7_importNode(IHTMLDocument7 *iface, IHTMLDOMNo VARIANT_BOOL fDeep, IHTMLDOMNode3 **ppNodeDest) { HTMLDocumentNode *This = impl_from_IHTMLDocument7(iface); - FIXME("(%p)->(%p %x %p)\n", This, pNodeSource, fDeep, ppNodeDest); - return E_NOTIMPL; + nsIDOMNode *nsnode = NULL; + HTMLDOMNode *node; + nsresult nsres; + HRESULT hres; + + TRACE("(%p)->(%p %x %p)\n", This, pNodeSource, fDeep, ppNodeDest); + + if(!This->nsdoc) { + WARN("NULL nsdoc\n"); + return E_UNEXPECTED; + } + + if(!(node = unsafe_impl_from_IHTMLDOMNode(pNodeSource))) { + ERR("not our node\n"); + return E_FAIL; + } + + nsres = nsIDOMHTMLDocument_ImportNode(This->nsdoc, node->nsnode, !!fDeep, 1, &nsnode); + if(NS_FAILED(nsres)) { + ERR("ImportNode failed: %08lx\n", nsres); + return map_nsresult(nsres); + } + + if(!nsnode) { + *ppNodeDest = NULL; + return S_OK; + } + + hres = get_node(nsnode, TRUE, &node); + nsIDOMNode_Release(nsnode); + if(FAILED(hres)) + return hres; + + *ppNodeDest = &node->IHTMLDOMNode3_iface; + return hres; }
static HRESULT WINAPI HTMLDocument7_get_parentWindow(IHTMLDocument7 *iface, IHTMLWindow2 **p) diff --git a/dlls/mshtml/htmlnode.c b/dlls/mshtml/htmlnode.c index 42ac37a7736..a293b332a9f 100644 --- a/dlls/mshtml/htmlnode.c +++ b/dlls/mshtml/htmlnode.c @@ -1067,6 +1067,11 @@ static const IHTMLDOMNodeVtbl HTMLDOMNodeVtbl = { HTMLDOMNode_get_nextSibling };
+HTMLDOMNode *unsafe_impl_from_IHTMLDOMNode(IHTMLDOMNode *iface) +{ + return iface->lpVtbl == &HTMLDOMNodeVtbl ? impl_from_IHTMLDOMNode(iface) : NULL; +} + static HTMLDOMNode *get_node_obj(IHTMLDOMNode *iface) { HTMLDOMNode *ret; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index c403b4efc54..23eeb0ec11b 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -807,6 +807,8 @@ struct HTMLDOMNode { HTMLDocumentNode *doc; };
+HTMLDOMNode *unsafe_impl_from_IHTMLDOMNode(IHTMLDOMNode*) DECLSPEC_HIDDEN; + static inline void node_addref(HTMLDOMNode *node) { IHTMLDOMNode_AddRef(&node->IHTMLDOMNode_iface); diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 43c52d89757..5a31b869c8f 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -722,3 +722,30 @@ sync_test("classList", function() { ok(("" + classList) === " testclass foobar ", "Expected classList value ' testclass foobar ', got " + classList); ok(classList.toString() === " testclass foobar ", "Expected classList toString ' testclass foobar ', got " + classList.toString()); }); + +sync_test("importNode", function() { + var node, node2, orig_node, doc = document.implementation.createHTMLDocument("TestDoc"); + doc.body.innerHTML = '<div id="test"><span/></div>'; + orig_node = doc.getElementById("test"); + + node = document.importNode(orig_node, false); + ok(node !== orig_node, "node = orig_node"); + ok(orig_node.hasChildNodes() === true, "orig_node does not have child nodes"); + ok(orig_node.parentNode === doc.body, "orig_node.parentNode = " + orig_node.parentNode); + ok(node.hasChildNodes() === false, "node has child nodes with shallow import"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + + node = document.importNode(orig_node, true); + ok(node !== orig_node, "node = orig_node"); + ok(orig_node.hasChildNodes() === true, "orig_node does not have child nodes"); + ok(orig_node.parentNode === doc.body, "orig_node.parentNode = " + orig_node.parentNode); + ok(node.hasChildNodes() === true, "node does not have child nodes with deep import"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + + node2 = document.importNode(node, false); + ok(node !== node2, "node = node2"); + ok(node.hasChildNodes() === true, "node does not have child nodes"); + ok(node.parentNode === null, "node.parentNode = " + node.parentNode); + ok(node2.hasChildNodes() === false, "node2 has child nodes"); + ok(node2.parentNode === null, "node2.parentNode = " + node2.parentNode); +});
On Wed Nov 2 14:34:17 2022 +0000, Gabriel Ivăncescu wrote:
Well I can certainly call it if frag_nav is TRUE, but I wanted to re-use the post_data stuff. I'm thinking of moving those variables outside the if block, I think that should be fine and much simpler.
In its current form, super_navigate() supports properly only the main content window. It's very likely that IHTMLPrivateWindow::SuperNavigate is broken for frames and it's not obvious how it should behave. Your patch uses it for frames, but only when doing fragment-only navigation. That logic seems questionable in general and in practice, it would mean that we'd do CGID_ShellDocView notification for non-top level documents. I'd expect that we should either do it for all frame navigations or (more likely) we shouldn't do it for fragment-only frame navigation.
On Thu Nov 3 13:59:28 2022 +0000, Jacek Caban wrote:
In its current form, super_navigate() supports properly only the main content window. It's very likely that IHTMLPrivateWindow::SuperNavigate is broken for frames and it's not obvious how it should behave. Your patch uses it for frames, but only when doing fragment-only navigation. That logic seems questionable in general and in practice, it would mean that we'd do CGID_ShellDocView notification for non-top level documents. I'd expect that we should either do it for all frame navigations or (more likely) we shouldn't do it for fragment-only frame navigation.
I see, thanks for the explanation, I didn't know how it worked.