From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 16 +++++++++--- dlls/mshtml/tests/events.js | 49 ++++++++++++++++++++++++++++++++++--- 2 files changed, 57 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 68f20607c7b..a8cff87c8a2 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2041,15 +2041,23 @@ static HRESULT WINAPI DOMEvent_get_isTrusted(IDOMEvent *iface, VARIANT_BOOL *p) static HRESULT WINAPI DOMEvent_put_cancelBubble(IDOMEvent *iface, VARIANT_BOOL v) { DOMEvent *This = impl_from_IDOMEvent(iface); - FIXME("(%p)->(%x)\n", This, v); - return E_NOTIMPL; + + TRACE("(%p)->(%x)\n", This, v); + + if(This->phase < 2) + return S_OK; + + return DOMEvent_stopPropagation(&This->IDOMEvent_iface); }
static HRESULT WINAPI DOMEvent_get_cancelBubble(IDOMEvent *iface, VARIANT_BOOL *p) { DOMEvent *This = impl_from_IDOMEvent(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + *p = variant_bool(This->stop_propagation); + return S_OK; }
static HRESULT WINAPI DOMEvent_get_srcElement(IDOMEvent *iface, IHTMLElement **p) diff --git a/dlls/mshtml/tests/events.js b/dlls/mshtml/tests/events.js index 9282d48bacc..a9d0fad3f9d 100644 --- a/dlls/mshtml/tests/events.js +++ b/dlls/mshtml/tests/events.js @@ -255,14 +255,34 @@ sync_test("stop_propagation", function() {
function stop_propagation(e) { calls += "stop,"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before stopPropagation = " + e.cancelBubble); e.stopPropagation(); + e.cancelBubble_winetest = true; + ok(e.cancelBubble === true, "cancelBubble after stopPropagation = " + e.cancelBubble); ok(e.bubbles === true, "bubbles = " + e.bubbles); ok(e.defaultPrevented === false, "defaultPrevented = " + e.defaultPrevented); }
function stop_immediate_propagation(e) { calls += "immediateStop,"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before stopImmediatePropagation = " + e.cancelBubble); e.stopImmediatePropagation(); + e.cancelBubble_winetest = true; + ok(e.cancelBubble === true, "cancelBubble after stopImmediatePropagation = " + e.cancelBubble); + ok(e.bubbles === true, "bubbles = " + e.bubbles); + ok(e.cancelable === true, "cancelable = " + e.cancelable); + ok(e.defaultPrevented === false, "defaultPrevented = " + e.defaultPrevented); + } + + function cancel_bubble(e) { + calls += "cancelBubble,"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before setting cancelBubble = " + e.cancelBubble); + e.cancelBubble = true; + if(e.eventPhase === 1) + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble after setting cancelBubble during capture phase = " + e.cancelBubble); + else + ok(e.cancelBubble === true, "cancelBubble after setting cancelBubble during bubble phase = " + e.cancelBubble); + e.cancelBubble_winetest = e.cancelBubble; ok(e.bubbles === true, "bubbles = " + e.bubbles); ok(e.cancelable === true, "cancelable = " + e.cancelable); ok(e.defaultPrevented === false, "defaultPrevented = " + e.defaultPrevented); @@ -270,16 +290,20 @@ sync_test("stop_propagation", function() {
div1.addEventListener("click", stop_immediate_propagation, true); div1.addEventListener("click", stop_propagation, true); + div1.addEventListener("click", cancel_bubble, true); div1.addEventListener("click", record_call("div1.click(capture)"), true);
div2.addEventListener("click", stop_immediate_propagation, true); + div2.addEventListener("click", cancel_bubble, true); div2.addEventListener("click", stop_propagation, true); div2.addEventListener("click", record_call("div2.click(capture)"), true);
+ div1.addEventListener("click", cancel_bubble, false); div1.addEventListener("click", stop_propagation, false); div1.addEventListener("click", record_call("div1.click(bubble)"), false);
div2.addEventListener("click", stop_propagation, false); + div2.addEventListener("click", cancel_bubble, false); div2.addEventListener("click", record_call("div2.click(bubble)"), false);
calls = ""; @@ -289,29 +313,46 @@ sync_test("stop_propagation", function() { div1.removeEventListener("click", stop_immediate_propagation, true); calls = ""; div2.click(); - ok(calls === "stop,div1.click(capture),", "calls = " + calls); + ok(calls === "stop,cancelBubble,div1.click(capture),", "calls = " + calls);
div1.removeEventListener("click", stop_propagation, true); calls = ""; div2.click(); + ok(calls === "cancelBubble,div1.click(capture),immediateStop,", "calls = " + calls); + + div1.removeEventListener("click", cancel_bubble, true); + calls = ""; + div2.click(); ok(calls === "div1.click(capture),immediateStop,", "calls = " + calls);
div2.removeEventListener("click", stop_immediate_propagation, true); calls = ""; div2.click(); - ok(calls === "div1.click(capture),stop,div2.click(capture),stop,div2.click(bubble),", + ok(calls === "div1.click(capture),cancelBubble,stop,div2.click(capture),stop,cancelBubble,div2.click(bubble),", + "calls = " + calls); + + div2.removeEventListener("click", cancel_bubble, true); + calls = ""; + div2.click(); + ok(calls === "div1.click(capture),stop,div2.click(capture),stop,cancelBubble,div2.click(bubble),", "calls = " + calls);
div2.removeEventListener("click", stop_propagation, true); calls = ""; div2.click(); - ok(calls === "div1.click(capture),div2.click(capture),stop,div2.click(bubble),", + ok(calls === "div1.click(capture),div2.click(capture),stop,cancelBubble,div2.click(bubble),", "calls = " + calls);
div2.removeEventListener("click", stop_propagation, false); calls = ""; div2.click(); - ok(calls === "div1.click(capture),div2.click(capture),div2.click(bubble),stop,div1.click(bubble),", + ok(calls === "div1.click(capture),div2.click(capture),cancelBubble,div2.click(bubble),", + "calls = " + calls); + + div2.removeEventListener("click", cancel_bubble, false); + calls = ""; + div2.click(); + ok(calls === "div1.click(capture),div2.click(capture),div2.click(bubble),cancelBubble,stop,div1.click(bubble),", "calls = " + calls); });
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index a8cff87c8a2..8162d2ae4bc 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -504,7 +504,7 @@ static HRESULT WINAPI HTMLEventObj_put_cancelBubble(IHTMLEventObj *iface, VARIAN TRACE("(%p)->(%x)\n", This, v);
if(This->event) - IDOMEvent_stopPropagation(&This->event->IDOMEvent_iface); + IDOMEvent_put_cancelBubble(&This->event->IDOMEvent_iface, v); return S_OK; }
@@ -514,8 +514,7 @@ static HRESULT WINAPI HTMLEventObj_get_cancelBubble(IHTMLEventObj *iface, VARIAN
TRACE("(%p)->(%p)\n", This, p);
- *p = variant_bool(This->event && This->event->stop_propagation); - return S_OK; + return IDOMEvent_get_cancelBubble(&This->event->IDOMEvent_iface, p); }
static HRESULT WINAPI HTMLEventObj_get_fromElement(IHTMLEventObj *iface, IHTMLElement **p)
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 29 +++++++++++++++++++++++------ dlls/mshtml/htmlstyle.h | 1 + dlls/mshtml/tests/documentmode.js | 2 ++ dlls/mshtml/tests/dom.js | 14 ++++++++++++++ 4 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index def56f7aedb..cda3af595a5 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -119,6 +119,12 @@ typedef struct { } style_tbl_entry_t;
static const style_tbl_entry_t style_tbl[] = { + { + L"-ms-transition", + DISPID_IHTMLCSSSTYLEDECLARATION2_MSTRANSITION, + DISPID_UNKNOWN, + ATTR_COMPAT_IE10 + }, { L"animation", DISPID_IHTMLCSSSTYLEDECLARATION2_ANIMATION, @@ -783,12 +789,19 @@ static LPWSTR fix_url_value(LPCWSTR val) return ret; }
+static const WCHAR *skip_name_prefix(const WCHAR *name) +{ + if(name[0] == '-') + name += sizeof("-ms-") - 1; + return name; +} + static HRESULT set_nsstyle_property(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, const nsAString *value) { nsAString str_name, str_empty; nsresult nsres;
- nsAString_InitDepend(&str_name, style_tbl[sid].name); + nsAString_InitDepend(&str_name, skip_name_prefix(style_tbl[sid].name)); nsAString_InitDepend(&str_empty, L""); nsres = nsIDOMCSSStyleDeclaration_SetProperty(nsstyle, &str_name, value, &str_empty); nsAString_Finish(&str_name); @@ -867,7 +880,7 @@ static HRESULT get_nsstyle_attr_nsval(nsIDOMCSSStyleDeclaration *nsstyle, stylei nsAString str_name; nsresult nsres;
- nsAString_InitDepend(&str_name, style_tbl[sid].name); + nsAString_InitDepend(&str_name, skip_name_prefix(style_tbl[sid].name)); nsres = nsIDOMCSSStyleDeclaration_GetPropertyValue(nsstyle, &str_name, value); nsAString_Finish(&str_name); if(NS_FAILED(nsres)) @@ -8760,15 +8773,19 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration2_get_msTransitionDelay(IHTMLCSSSty static HRESULT WINAPI HTMLCSSStyleDeclaration2_put_msTransition(IHTMLCSSStyleDeclaration2 *iface, BSTR v) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration2(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_style_property(This, STYLEID_MSTRANSITION, v); }
static HRESULT WINAPI HTMLCSSStyleDeclaration2_get_msTransition(IHTMLCSSStyleDeclaration2 *iface, BSTR *p) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration2(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_style_property(This, STYLEID_MSTRANSITION, p); }
static HRESULT WINAPI HTMLCSSStyleDeclaration2_put_msTouchAction(IHTMLCSSStyleDeclaration2 *iface, BSTR v) diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index f6d5ea7c5bb..d3e9a2401bc 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -40,6 +40,7 @@ struct HTMLStyle {
/* NOTE: Make sure to keep in sync with style_tbl in htmlstyle.c */ typedef enum { + STYLEID_MSTRANSITION, STYLEID_ANIMATION, STYLEID_ANIMATION_NAME, STYLEID_BACKGROUND, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 867130aec3d..422facdca18 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -683,7 +683,9 @@ sync_test("style_props", function() { test_exposed("removeProperty", v >= 9); test_exposed("background-clip", v >= 9); test_exposed("msTransform", v >= 9); + test_exposed("msTransition", v >= 10); test_exposed("transform", v >= 10); + test_exposed("transition", v >= 10);
style = document.body.currentStyle;
diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 325cacf4823..5580e5e9cd4 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -458,6 +458,20 @@ sync_test("style_properties", function() { ok(computed_style.zIndex === 4, "computed_style.zIndex = " + computed_style.zIndex);
window.getComputedStyle(elem, null); + + /* ms* prefixed styles alias */ + var list = [ + [ "transition", "background-color 0.5s linear 0.1s" ] + ]; + for(var i = 0; i < list.length; i++) { + var s = list[i][0], v = list[i][1], ms = "ms" + s[0].toUpperCase() + s.substring(1); + style[s] = v; + ok(style[s] === v, "style." + s + " = " + style[s] + ", expected " + v); + ok(style[ms] === v, "style." + ms + " = " + style[ms] + ", expected " + v); + elem.style[ms] = v; + ok(elem.style[s] === v, "elem.style." + s + " = " + elem.style[s] + ", expected " + v); + ok(elem.style[ms] === v, "elem.style." + ms + " = " + elem.style[ms] + ", expected " + v); + } });
sync_test("stylesheets", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 17 +++++++++++++---- dlls/mshtml/htmlstyle.h | 1 + dlls/mshtml/tests/dom.js | 1 + 3 files changed, 15 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index cda3af595a5..da97e6c6879 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -119,6 +119,11 @@ typedef struct { } style_tbl_entry_t;
static const style_tbl_entry_t style_tbl[] = { + { + L"-ms-transform", + DISPID_IHTMLCSSSTYLEDECLARATION_MSTRANSFORM, + DISPID_UNKNOWN + }, { L"-ms-transition", DISPID_IHTMLCSSSTYLEDECLARATION2_MSTRANSITION, @@ -7275,15 +7280,19 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration_get_boxShadow(IHTMLCSSStyleDeclara static HRESULT WINAPI HTMLCSSStyleDeclaration_put_msTransform(IHTMLCSSStyleDeclaration *iface, BSTR v) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + return set_style_property(This, STYLEID_MSTRANSFORM, v); }
static HRESULT WINAPI HTMLCSSStyleDeclaration_get_msTransform(IHTMLCSSStyleDeclaration *iface, BSTR *p) { CSSStyle *This = impl_from_IHTMLCSSStyleDeclaration(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + + TRACE("(%p)->(%p)\n", This, p); + + return get_style_property(This, STYLEID_MSTRANSFORM, p); }
static HRESULT WINAPI HTMLCSSStyleDeclaration_put_msTransformOrigin(IHTMLCSSStyleDeclaration *iface, BSTR v) diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index d3e9a2401bc..c0703e39fad 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -40,6 +40,7 @@ struct HTMLStyle {
/* NOTE: Make sure to keep in sync with style_tbl in htmlstyle.c */ typedef enum { + STYLEID_MSTRANSFORM, STYLEID_MSTRANSITION, STYLEID_ANIMATION, STYLEID_ANIMATION_NAME, diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 5580e5e9cd4..3b86a25417f 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -461,6 +461,7 @@ sync_test("style_properties", function() {
/* ms* prefixed styles alias */ var list = [ + [ "transform", "translate(5px, 5px)" ], [ "transition", "background-color 0.5s linear 0.1s" ] ]; for(var i = 0; i < list.length; i++) {
Jacek Caban (@jacek) commented about dlls/mshtml/htmlevent.c:
static HRESULT WINAPI DOMEvent_put_cancelBubble(IDOMEvent *iface, VARIANT_BOOL v) { DOMEvent *This = impl_from_IDOMEvent(iface);
- FIXME("(%p)->(%x)\n", This, v);
- return E_NOTIMPL;
- TRACE("(%p)->(%x)\n", This, v);
- if(This->phase < 2)
return S_OK;
- return DOMEvent_stopPropagation(&This->IDOMEvent_iface);
What if `v` is false (and yeah, `IHTMLEventObj` probably got it wrong too)?
Jacek Caban (@jacek) commented about dlls/mshtml/htmlstyle.c:
nsAString str_name; nsresult nsres;
- nsAString_InitDepend(&str_name, style_tbl[sid].name);
There are more places that would need a similar change.
On Wed Jul 17 14:20:46 2024 +0000, Jacek Caban wrote:
What if `v` is false (and yeah, `IHTMLEventObj` probably got it wrong too)?
Oh yeah, oops, will test and check.
On Wed Jul 17 14:20:47 2024 +0000, Jacek Caban wrote:
There are more places that would need a similar change.
While looking for them I found this construct in some places (such as in `getPropertyValue`):
```c style_entry = lookup_style_tbl(This, name); nsAString_InitDepend(&name_str, style_entry ? style_entry->name : name); ``` What's the point of the whole `style_entry` thing? `lookup_style_tbl` uses case sensitive lookup, so it either always matches `name` or returns NULL. Even if it returns NULL due to `ATTR_COMPAT_IE10`, it ends up using name anyway which is the same thing?
Am I missing something?