[PATCH 0/2] MR9976: mshtml: Update element event handlers when the corresponding attribute value changes.
Based on patch by Yongjie Yao from !8586. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/9976
From: Jacek Caban <jacek@codeweavers.com> --- dlls/mshtml/htmlevent.c | 5 ++++- dlls/mshtml/tests/documentmode.js | 1 - dlls/mshtml/tests/events.c | 1 - 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index cb5c1127bd2..e3301f2ddfd 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -4748,10 +4748,11 @@ HRESULT set_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var return set_event_handler_disp(event_target, eid, V_DISPATCH(var)); case VT_BSTR: { + compat_mode_t compat_mode = dispex_compat_mode(&event_target->dispex); VARIANT *v; HRESULT hres; - if(!use_event_quirks(event_target)) + if(compat_mode == COMPAT_MODE_IE8) FIXME("Setting to string %s not supported\n", debugstr_w(V_BSTR(var))); /* @@ -4761,6 +4762,8 @@ HRESULT set_event_handler(EventTarget *event_target, eventid_t eid, VARIANT *var * properties. */ remove_event_handler(event_target, eid); + if(compat_mode >= COMPAT_MODE_IE9) + return S_OK; hres = get_event_dispex_ref(event_target, eid, TRUE, &v); if(FAILED(hres)) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 1c5f5dd4d25..b0df4ed2479 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -2892,7 +2892,6 @@ sync_test("elem_attr", function() { ok(r === (v < 9 ? "test" : "string"), "onclick attr = " + r); r = elem.removeAttribute("onclick"); ok(r === (v < 9 ? true : undefined), "removeAttribute returned " + r); - todo_wine_if(v >= 9). ok(elem.onclick === null, "removed onclick = " + elem.onclick); elem.setAttribute("ondblclick", arr); diff --git a/dlls/mshtml/tests/events.c b/dlls/mshtml/tests/events.c index fbb5a9535ee..77c76957144 100644 --- a/dlls/mshtml/tests/events.c +++ b/dlls/mshtml/tests/events.c @@ -2545,7 +2545,6 @@ static void test_onclick(IHTMLDocument2 *doc) ok(V_VT(&v) == VT_BSTR, "V_VT(onclick) = %d\n", V_VT(&v)); ok(!lstrcmpW(V_BSTR(&v), L"function();"), "V_BSTR(onclick) = %s\n", wine_dbgstr_w(V_BSTR(&v))); }else { - todo_wine ok(V_VT(&v) == VT_NULL, "V_VT(onclick) = %d\n", V_VT(&v)); } VariantClear(&v); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9976
From: Jacek Caban <jacek@codeweavers.com> Based on patch by Yongjie Yao. --- dlls/mshtml/htmlevent.c | 39 +++++++++++++++++++++++++++++++ dlls/mshtml/htmlevent.h | 1 + dlls/mshtml/mutation.c | 21 ++++++++++++++++- dlls/mshtml/nsiface.idl | 15 +++++++++++- dlls/mshtml/tests/documentmode.js | 33 ++++++++++++++++++++++++++ 5 files changed, 107 insertions(+), 2 deletions(-) diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index e3301f2ddfd..cfe2acb4fe0 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -4884,6 +4884,45 @@ void update_doc_cp_events(HTMLDocumentNode *doc, cp_static_data_t *cp) } } +void event_attr_changed(HTMLDocumentNode *doc, nsIDOMElement *nselem, const WCHAR *name) +{ + nsAString name_str, value_str; + const PRUnichar *value; + HTMLDOMNode *node; + IDispatch *disp; + eventid_t eid; + nsresult nsres; + HRESULT hres; + + eid = attr_to_eid(name); + if(eid == EVENTID_LAST) + return; + + hres = get_node((nsIDOMNode*)nselem, TRUE, &node); + if(FAILED(hres)) + return; + + nsAString_InitDepend(&name_str, name); + nsAString_InitDepend(&value_str, NULL); + + nsres = nsIDOMElement_GetAttribute(nselem, &name_str, &value_str); + if(NS_SUCCEEDED(nsres)) { + nsAString_GetData(&value_str, &value); + + TRACE("%p.%s = %s\n", nselem, debugstr_w(name), debugstr_w(value)); + + disp = script_parse_event(doc->window, value); + if(disp) { + set_event_handler_disp(get_node_event_prop_target(node, eid), eid, disp); + IDispatch_Release(disp); + } + } + + node_release(node); + nsAString_Finish(&name_str); + nsAString_Finish(&value_str); +} + void check_event_attr(HTMLDocumentNode *doc, nsIDOMElement *nselem) { nsIDOMMozNamedAttrMap *attr_map; diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index 3f4e11690f8..9576d91c9ff 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -98,6 +98,7 @@ typedef struct DOMEvent { const WCHAR *get_event_name(eventid_t); void check_event_attr(HTMLDocumentNode*,nsIDOMElement*); +void event_attr_changed(HTMLDocumentNode*,nsIDOMElement*,const WCHAR*); void traverse_event_target(EventTarget*,nsCycleCollectionTraversalCallback*); void release_event_target(EventTarget*); HRESULT set_event_handler(EventTarget*,eventid_t,VARIANT*); diff --git a/dlls/mshtml/mutation.c b/dlls/mshtml/mutation.c index 92fc97a03d9..b330bf3d883 100644 --- a/dlls/mshtml/mutation.c +++ b/dlls/mshtml/mutation.c @@ -785,8 +785,27 @@ static void NSAPI nsDocumentObserver_AttributeWillChange(nsIDocumentObserver *if } static void NSAPI nsDocumentObserver_AttributeChanged(nsIDocumentObserver *iface, nsIDocument *aDocument, - void *aElement, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType, const nsAttrValue *aOldValue) + /*mozilla::dom::Element*/ void *aElement, LONG aNameSpaceID, nsIAtom *aAttribute, LONG aModType, const nsAttrValue *aOldValue) { + HTMLDocumentNode *This = impl_from_nsIDocumentObserver(iface); + nsIDOMElement *elem; + nsAString name_str; + const WCHAR *name; + nsresult nsres; + + nsAString_Init(&name_str, NULL); + nsres = nsIAtom_ScriptableToString(aAttribute, &name_str); + assert(nsres == NS_OK); + nsAString_GetData(&name_str, &name); + + TRACE("(%p)->(%p, %s)\n", This, aElement, debugstr_w(name)); + + nsres = nsISupports_QueryInterface(aElement, &IID_nsIDOMElement, (void **)&elem); + assert(nsres == NS_OK); + + event_attr_changed(This, elem, name); + nsAString_Finish(&name_str); + nsIDOMElement_Release(elem); } static void NSAPI nsDocumentObserver_NativeAnonymousChildListChange(nsIDocumentObserver *iface, nsIDocument *aDocument, diff --git a/dlls/mshtml/nsiface.idl b/dlls/mshtml/nsiface.idl index 1f2131dfb24..8bba7d9f83b 100644 --- a/dlls/mshtml/nsiface.idl +++ b/dlls/mshtml/nsiface.idl @@ -143,7 +143,6 @@ typedef nsISupports nsIDOMCSSValue; typedef nsISupports nsIPrintSession; typedef nsISupports nsIControllerCommandTable; typedef nsISupports nsIPrincipal; -typedef nsISupports nsIAtom; typedef nsISupports nsISupportsArray; typedef nsISupports nsIContentFilter; typedef nsISupports nsIDOMMediaList; @@ -273,6 +272,20 @@ interface nsIRunnable : nsISupports nsresult Run(); } +[ + object, + uuid(8b8c11d4-3ed5-4079-8974-73c7576cdb34), + local +] +interface nsIAtom : nsISupports +{ + nsresult ScriptableToString(nsAString *_retval); + nsresult ToUTF8String(nsACString *_retval); + nsresult ScriptableEquals(const nsAString *aString, bool *_retval); + bool EqualsUTF8(const nsACString *aString); + bool IsStaticAtom(); +} + [ object, uuid(d1899240-f9d2-11d2-bdd6-000064657374), diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index b0df4ed2479..dadd7ba6b04 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3169,6 +3169,39 @@ sync_test("elem_attrNS", function() { ok(r === "13", "numattr = " + r); }); + +var rec; + +sync_test("event attr", function() { + document.body.innerHTML = '<div></div>'; + var elem = document.body.firstChild, prev; + var v = document.documentMode; + + ok(elem.onclick === null, "elem.onclick = " + elem.onclick); + elem.setAttribute("onclick", "rec += 'attr';"); + if (v < 8) + ok(elem.onclick === "rec += 'attr';", "elem.onclick = " + elem.onclick); + else + todo_wine_if(v == 8). + ok(typeof(elem.onclick) === "function", "elem.onclick = " + elem.onclick); + rec = ""; + elem.click(); + todo_wine_if(v == 8). + ok(rec === (v < 8 ? "" : "attr"), "unexpected rec = " + rec ); + + elem.setAttribute("onclick", "rec += 'attr2';"); + rec = ""; + elem.click(); + todo_wine_if(v == 8). + ok(rec === (v < 8 ? "" : "attr2"), "unexpected rec = " + rec ); + + elem.onclick = "rec += 'prop';"; + ok(elem.onclick === (v < 9 ? "rec += 'prop';" : null), "elem.onclick = " + elem.onclick); + rec = ""; + elem.click(); + ok(rec === "", "unexpected rec = " + rec ); +}); + sync_test("builtins_diffs", function() { var v = document.documentMode; -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/9976
participants (2)
-
Jacek Caban -
Jacek Caban (@jacek)