-- v2: mshtml: Implement style msTransform. mshtml: Implement style msTransition. mshtml: Compactify the style_props expose tests for each style object into mshtml: Don't allow vendor prefixed CSS props for style prop operations. mshtml: Fix box-sizing CSS property. mshtml: Use bitfields for the event BOOL fields. mshtml: Fix special case between stopImmediatePropagation and setting mshtml: Implement HTMLEventObj's cancelBubble on top of the underlying mshtml: Implement event.cancelBubble.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 26 ++++++--- dlls/mshtml/tests/events.js | 102 +++++++++++++++++++++++++++++++++--- 2 files changed, 114 insertions(+), 14 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 6489c557def..789ae8c2f3a 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -2013,7 +2013,6 @@ static HRESULT WINAPI DOMEvent_stopPropagation(IDOMEvent *iface) TRACE("(%p)\n", This);
This->stop_propagation = TRUE; - nsIDOMEvent_StopPropagation(This->nsevent); return S_OK; }
@@ -2024,7 +2023,6 @@ static HRESULT WINAPI DOMEvent_stopImmediatePropagation(IDOMEvent *iface) TRACE("(%p)\n", This);
This->stop_immediate_propagation = This->stop_propagation = TRUE; - nsIDOMEvent_StopImmediatePropagation(This->nsevent); return S_OK; }
@@ -2041,15 +2039,25 @@ 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; + + /* stop_immediate_propagation is not able to be interrupted, but native has a weird behavior. */ + This->stop_propagation = (v != VARIANT_FALSE); + return S_OK; }
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) @@ -4323,6 +4331,9 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp } }
+ if(event->stop_immediate_propagation) + nsIDOMEvent_StopImmediatePropagation(event->nsevent); + for(listener = listeners; listener < listeners + listeners_cnt; listener++) IDispatch_Release(listener->function); if(listeners != listeners_buf) @@ -4469,6 +4480,9 @@ static HRESULT dispatch_event_object(EventTarget *event_target, DOMEvent *event, call_event_handlers(target_chain[i], event, dispatch_mode); }
+ if(event->stop_propagation) + nsIDOMEvent_StopPropagation(event->nsevent); + if(r) *r = variant_bool(!event->prevent_default);
diff --git a/dlls/mshtml/tests/events.js b/dlls/mshtml/tests/events.js index 9282d48bacc..2e8e87b0a72 100644 --- a/dlls/mshtml/tests/events.js +++ b/dlls/mshtml/tests/events.js @@ -255,63 +255,149 @@ 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); }
- div1.addEventListener("click", stop_immediate_propagation, true); + function stop_immediate_propagation_cancel_bubble_false(e) { + calls += "immediateStop and cancelBubble(false),"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before stopImmediatePropagation = " + e.cancelBubble); + e.stopImmediatePropagation(); + e.cancelBubble = false; + e.cancelBubble_winetest = e.eventPhase < 2 ? true : false; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble after stopImmediatePropagation and setting cancelBubble to false = " + 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_impl(i, e) { + calls += "cancelBubble["+i+"],"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before setting cancelBubble = " + e.cancelBubble); + e.cancelBubble = true; + if(e.eventPhase < 2) + 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); + } + + var cancel_bubble = []; + for(var i = 0; i < 4; i++) + eval('cancel_bubble.push(function(e) { return cancel_bubble_impl('+i+', e); });'); + + function cancel_bubble_false(e) { + calls += "cancelBubble(false),"; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before setting cancelBubble to false = " + e.cancelBubble); + e.cancelBubble = false; + if(e.cancelBubble_winetest && e.eventPhase !== 1) + delete e.cancelBubble_winetest; + ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble after setting cancelBubble to false = " + e.cancelBubble); + ok(e.bubbles === true, "bubbles = " + e.bubbles); + ok(e.cancelable === true, "cancelable = " + e.cancelable); + ok(e.defaultPrevented === false, "defaultPrevented = " + e.defaultPrevented); + } + + div1.addEventListener("click", stop_immediate_propagation_cancel_bubble_false, true); div1.addEventListener("click", stop_propagation, true); + div1.addEventListener("click", cancel_bubble[0], true); + div1.addEventListener("click", cancel_bubble_false, true); div1.addEventListener("click", record_call("div1.click(capture)"), true);
div2.addEventListener("click", stop_immediate_propagation, true); + div2.addEventListener("click", cancel_bubble[1], true); div2.addEventListener("click", stop_propagation, true); div2.addEventListener("click", record_call("div2.click(capture)"), true);
+ div1.addEventListener("click", cancel_bubble[2], false); + div1.addEventListener("click", cancel_bubble_false, false); div1.addEventListener("click", stop_propagation, false); div1.addEventListener("click", record_call("div1.click(bubble)"), false);
+ div2.addEventListener("click", stop_immediate_propagation_cancel_bubble_false, false); div2.addEventListener("click", stop_propagation, false); + div2.addEventListener("click", cancel_bubble[3], false); + div2.addEventListener("click", cancel_bubble_false, false); div2.addEventListener("click", record_call("div2.click(bubble)"), false);
calls = ""; div2.click(); - ok(calls === "immediateStop,", "calls = " + calls); + ok(calls === "immediateStop and cancelBubble(false),", "calls = " + calls);
- div1.removeEventListener("click", stop_immediate_propagation, true); + div1.removeEventListener("click", stop_immediate_propagation_cancel_bubble_false, true); calls = ""; div2.click(); - ok(calls === "stop,div1.click(capture),", "calls = " + calls); + ok(calls === "stop,cancelBubble[0],cancelBubble(false),div1.click(capture),", "calls = " + calls);
div1.removeEventListener("click", stop_propagation, true); calls = ""; div2.click(); - ok(calls === "div1.click(capture),immediateStop,", "calls = " + calls); + ok(calls === "cancelBubble[0],cancelBubble(false),div1.click(capture),immediateStop,", "calls = " + calls); + + div1.removeEventListener("click", cancel_bubble[0], true); + calls = ""; + div2.click(); + ok(calls === "cancelBubble(false),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),", + todo_wine. + ok(calls === "cancelBubble(false),div1.click(capture),cancelBubble[1],stop,div2.click(capture),immediateStop and cancelBubble(false),cancelBubble[2],", // weird native behavior + "calls = " + calls); + + div2.removeEventListener("click", stop_immediate_propagation_cancel_bubble_false, false); + calls = ""; + div2.click(); + ok(calls === "cancelBubble(false),div1.click(capture),cancelBubble[1],stop,div2.click(capture),stop,cancelBubble[3],cancelBubble(false),div2.click(bubble),cancelBubble[2],cancelBubble(false),stop,div1.click(bubble),", + "calls = " + calls); + + div2.removeEventListener("click", cancel_bubble_false, false); + calls = ""; + div2.click(); + ok(calls === "cancelBubble(false),div1.click(capture),cancelBubble[1],stop,div2.click(capture),stop,cancelBubble[3],div2.click(bubble),", + "calls = " + calls); + + div2.removeEventListener("click", cancel_bubble[1], true); + calls = ""; + div2.click(); + ok(calls === "cancelBubble(false),div1.click(capture),stop,div2.click(capture),stop,cancelBubble[3],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 === "cancelBubble(false),div1.click(capture),div2.click(capture),stop,cancelBubble[3],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 === "cancelBubble(false),div1.click(capture),div2.click(capture),cancelBubble[3],div2.click(bubble),", + "calls = " + calls); + + div2.removeEventListener("click", cancel_bubble[3], false); + calls = ""; + div2.click(); + ok(calls === "cancelBubble(false),div1.click(capture),div2.click(capture),div2.click(bubble),cancelBubble[2],cancelBubble(false),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 789ae8c2f3a..809d4d5915c 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
This implements same buggy style as native, where cancelBubble = false does not affect the immediate propagation flag, while it does affect normal propagation flag.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.c | 11 ++++++----- dlls/mshtml/tests/events.js | 1 - 2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlevent.c b/dlls/mshtml/htmlevent.c index 809d4d5915c..24eb6ca7832 100644 --- a/dlls/mshtml/htmlevent.c +++ b/dlls/mshtml/htmlevent.c @@ -4264,8 +4264,7 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp } }
- for(listener = listeners; !event->stop_immediate_propagation - && listener < listeners + listeners_cnt; listener++) { + for(listener = listeners; listener < listeners + listeners_cnt; listener++) { if(listener->type != LISTENER_TYPE_ATTACHED) { DISPID named_arg = DISPID_THIS; VARIANTARG args[2]; @@ -4328,10 +4327,12 @@ static void call_event_handlers(EventTarget *event_target, DOMEvent *event, disp WARN("%p %s attached <<< %08lx\n", event_target, debugstr_w(event->type), hres); } } - }
- if(event->stop_immediate_propagation) - nsIDOMEvent_StopImmediatePropagation(event->nsevent); + if(event->stop_immediate_propagation) { + nsIDOMEvent_StopImmediatePropagation(event->nsevent); + break; + } + }
for(listener = listeners; listener < listeners + listeners_cnt; listener++) IDispatch_Release(listener->function); diff --git a/dlls/mshtml/tests/events.js b/dlls/mshtml/tests/events.js index 2e8e87b0a72..96d33f0181c 100644 --- a/dlls/mshtml/tests/events.js +++ b/dlls/mshtml/tests/events.js @@ -360,7 +360,6 @@ sync_test("stop_propagation", function() { div2.removeEventListener("click", stop_immediate_propagation, true); calls = ""; div2.click(); - todo_wine. ok(calls === "cancelBubble(false),div1.click(capture),cancelBubble[1],stop,div2.click(capture),immediateStop and cancelBubble(false),cancelBubble[2],", // weird native behavior "calls = " + calls);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Since there's a lot of them.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlevent.h | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/dlls/mshtml/htmlevent.h b/dlls/mshtml/htmlevent.h index cd099850771..324f39ea746 100644 --- a/dlls/mshtml/htmlevent.h +++ b/dlls/mshtml/htmlevent.h @@ -83,16 +83,16 @@ typedef struct DOMEvent { EventTarget *target; EventTarget *current_target; ULONGLONG time_stamp; - BOOL bubbles; - BOOL cancelable; - BOOL prevent_default; - BOOL stop_propagation; - BOOL stop_immediate_propagation; - BOOL trusted; + unsigned bubbles : 1; + unsigned cancelable : 1; + unsigned prevent_default : 1; + unsigned stop_propagation : 1; + unsigned stop_immediate_propagation : 1; + unsigned trusted : 1; + unsigned no_event_obj : 1; DOM_EVENT_PHASE phase;
IHTMLEventObj *event_obj; - BOOL no_event_obj; } DOMEvent;
const WCHAR *get_event_name(eventid_t);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
First of all it was already pretty much broken because the table must be sorted, and '-' comes first. And secondly, IE uses the unprefixed box-sizing property, not -moz-box-sizing, although we do have to convert it for wine-gecko.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 29 +++++++++++++++++++++-------- 1 file changed, 21 insertions(+), 8 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index cfc50f150ba..0e2c2a2407c 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -116,6 +116,7 @@ typedef struct { DISPID compat_dispid; unsigned flags; const WCHAR **allowed_values; + const WCHAR *nsname; } style_tbl_entry_t;
static const style_tbl_entry_t style_tbl[] = { @@ -318,9 +319,11 @@ static const style_tbl_entry_t style_tbl[] = { ATTR_FIX_PX }, { - L"-moz-box-sizing", + L"box-sizing", DISPID_IHTMLCSSSTYLEDECLARATION_BOXSIZING, - DISPID_A_BOXSIZING + DISPID_A_BOXSIZING, + 0, NULL, + L"-moz-box-sizing" }, { L"clear", @@ -702,6 +705,16 @@ static const style_tbl_entry_t style_tbl[] = {
C_ASSERT(ARRAY_SIZE(style_tbl) == STYLEID_MAX_VALUE);
+static const WCHAR *get_style_nsname(const style_tbl_entry_t *style_entry) +{ + return style_entry->nsname ? style_entry->nsname : style_entry->name; +} + +static const WCHAR *get_style_prop_nsname(const style_tbl_entry_t *style_entry, const WCHAR *orig_name) +{ + return style_entry ? get_style_nsname(style_entry) : orig_name; +} + static const style_tbl_entry_t *lookup_style_tbl(CSSStyle *style, const WCHAR *name) { int c, i, min = 0, max = ARRAY_SIZE(style_tbl)-1; @@ -788,7 +801,7 @@ static HRESULT set_nsstyle_property(nsIDOMCSSStyleDeclaration *nsstyle, styleid_ nsAString str_name, str_empty; nsresult nsres;
- nsAString_InitDepend(&str_name, style_tbl[sid].name); + nsAString_InitDepend(&str_name, get_style_nsname(&style_tbl[sid])); 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, get_style_nsname(&style_tbl[sid])); nsres = nsIDOMCSSStyleDeclaration_GetPropertyValue(nsstyle, &str_name, value); nsAString_Finish(&str_name); if(NS_FAILED(nsres)) @@ -2946,7 +2959,7 @@ static HRESULT WINAPI HTMLStyle_removeAttribute(IHTMLStyle *iface, BSTR strAttri return S_OK; }
- nsAString_InitDepend(&name_str, style_entry->name); + nsAString_InitDepend(&name_str, get_style_nsname(style_entry)); nsAString_Init(&ret_str, NULL); nsres = nsIDOMCSSStyleDeclaration_RemoveProperty(This->css_style.nsstyle, &name_str, &ret_str); if(NS_SUCCEEDED(nsres)) { @@ -4443,7 +4456,7 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration_getPropertyValue(IHTMLCSSStyleDecl TRACE("(%p)->(%s %p)\n", This, debugstr_w(name), value);
style_entry = lookup_style_tbl(This, name); - nsAString_InitDepend(&name_str, style_entry ? style_entry->name : name); + nsAString_InitDepend(&name_str, get_style_prop_nsname(style_entry, name)); nsAString_InitDepend(&value_str, NULL); nsres = nsIDOMCSSStyleDeclaration_GetPropertyValue(This->nsstyle, &name_str, &value_str); nsAString_Finish(&name_str); @@ -4467,7 +4480,7 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration_removeProperty(IHTMLCSSStyleDeclar TRACE("(%p)->(%s %p)\n", This, debugstr_w(bstrPropertyName), pbstrPropertyValue);
style_entry = lookup_style_tbl(This, bstrPropertyName); - nsAString_InitDepend(&name_str, style_entry ? style_entry->name : bstrPropertyName); + nsAString_InitDepend(&name_str, get_style_prop_nsname(style_entry, bstrPropertyName)); nsAString_Init(&ret_str, NULL); nsres = nsIDOMCSSStyleDeclaration_RemoveProperty(This->nsstyle, &name_str, &ret_str); nsAString_Finish(&name_str); @@ -4500,7 +4513,7 @@ static HRESULT WINAPI HTMLCSSStyleDeclaration_setProperty(IHTMLCSSStyleDeclarati nsAString_InitDepend(&priority_str, NULL); }
- nsAString_InitDepend(&name_str, style_entry ? style_entry->name : name); + nsAString_InitDepend(&name_str, get_style_prop_nsname(style_entry, name)); nsres = nsIDOMCSSStyleDeclaration_SetProperty(This->nsstyle, &name_str, &value_str, &priority_str); nsAString_Finish(&name_str); nsAString_Finish(&value_str);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
-ms-* prefix is not accepted by gecko anyway, and it needs to be implemented manually.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 2 +- dlls/mshtml/tests/dom.js | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 0e2c2a2407c..40cee5d1890 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -712,7 +712,7 @@ static const WCHAR *get_style_nsname(const style_tbl_entry_t *style_entry)
static const WCHAR *get_style_prop_nsname(const style_tbl_entry_t *style_entry, const WCHAR *orig_name) { - return style_entry ? get_style_nsname(style_entry) : orig_name; + return style_entry ? get_style_nsname(style_entry) : orig_name[0] == '-' ? L"" : orig_name; }
static const style_tbl_entry_t *lookup_style_tbl(CSSStyle *style, const WCHAR *name) diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 325cacf4823..df47e45cf4b 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -399,6 +399,25 @@ sync_test("style_properties", function() { ok(val === "", "removeProperty() returned " + val); ok(style.testVal === "test", "testVal = " + style.testVal);
+ val = style.getPropertyValue("testVal"); + ok(val === "", 'style.getPropertyValue("testVal") = ' + val); + ok(style.testVal === "test", "testVal = " + style.testVal); + + style.setProperty("testVal", "1px"); + val = style.getPropertyValue("testVal"); + ok(val === "", 'style.getPropertyValue("testVal") = ' + val); + ok(style.testVal === "test", "testVal = " + style.testVal); + + style.setProperty("test", "1px"); + val = style.getPropertyValue("test"); + ok(val === "", 'style.getPropertyValue("test") = ' + val); + ok(!("test" in style), "test in style"); + + style.setProperty("-moz-box-sizing", "border-box"); + val = style.getPropertyValue("-moz-box-sizing"); + ok(val === "", 'style.getPropertyValue("-moz-box-sizing") = ' + val); + ok(!("-moz-box-sizing" in style), "-moz-box-sizing in style"); + style["z-index"] = 1; ok(style.zIndex === 1, "zIndex = " + style.zIndex); ok(style["z-index"] === 1, "z-index = " + style["z-index"]);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/documentmode.js | 72 +++++++++++-------------------- 1 file changed, 26 insertions(+), 46 deletions(-)
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 016b51c9eda..6cc4edf0c63 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -660,60 +660,40 @@ sync_test("xhr open", function() { });
sync_test("style_props", function() { - var style = document.body.style; + var style = document.body.style, currentStyle = document.body.currentStyle, computedStyle = window.getComputedStyle ? window.getComputedStyle(document.body) : undefined;
- function test_exposed(prop, expect) { - if(expect) + function test_exposed(prop, expect_style, expect_currentStyle, expect_computedStyle) { + if(expect_style) ok(prop in style, prop + " not found in style object."); else ok(!(prop in style), prop + " found in style object."); + if(expect_currentStyle) + ok(prop in currentStyle, prop + " not found in currentStyle object."); + else + ok(!(prop in currentStyle), prop + " found in currentStyle object."); + if(computedStyle) { + if(expect_computedStyle) + ok(prop in computedStyle, prop + " not found in computedStyle object."); + else + ok(!(prop in computedStyle), prop + " found in computedStyle object."); + } }
var v = document.documentMode;
- test_exposed("removeAttribute", true); - test_exposed("zIndex", true); - test_exposed("z-index", true); - test_exposed("filter", true); - test_exposed("pixelTop", true); - test_exposed("float", true); - test_exposed("css-float", false); - test_exposed("style-float", false); - test_exposed("setProperty", v >= 9); - test_exposed("removeProperty", v >= 9); - test_exposed("background-clip", v >= 9); - test_exposed("msTransform", v >= 9); - test_exposed("transform", v >= 10); - - style = document.body.currentStyle; - - test_exposed("zIndex", true); - test_exposed("z-index", true); - test_exposed("filter", true); - test_exposed("pixelTop", false); - test_exposed("float", true); - test_exposed("css-float", false); - test_exposed("style-float", false); - test_exposed("setProperty", v >= 9); - test_exposed("removeProperty", v >= 9); - test_exposed("background-clip", v >= 9); - test_exposed("transform", v >= 10); - - if(window.getComputedStyle) { - style = window.getComputedStyle(document.body); - - test_exposed("removeAttribute", false); - test_exposed("zIndex", true); - test_exposed("z-index", true); - test_exposed("pixelTop", false); - test_exposed("float", true); - test_exposed("css-float", false); - test_exposed("style-float", false); - test_exposed("setProperty", v >= 9); - test_exposed("removeProperty", v >= 9); - test_exposed("background-clip", v >= 9); - test_exposed("transform", v >= 10); - } + test_exposed("removeAttribute", true, broken(true) ? v >= 9 : false /* todo_wine */, false); + test_exposed("zIndex", true, true, true); + test_exposed("z-index", true, true, true); + test_exposed("filter", true, true, broken(true) ? v >= 10 : v >= 9 /* todo_wine */); + test_exposed("pixelTop", true, false, false); + test_exposed("float", true, true, true); + test_exposed("css-float", false, false, false); + test_exposed("style-float", false, false, false); + test_exposed("setProperty", v >= 9, v >= 9, v >= 9); + test_exposed("removeProperty", v >= 9, v >= 9, v >= 9); + test_exposed("background-clip", v >= 9, v >= 9, v >= 9); + test_exposed("msTransform", v >= 9, v >= 9, v >= 9); + test_exposed("transform", v >= 10, v >= 10, v >= 10); });
sync_test("createElement_inline_attr", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 19 +++++++++++++++---- dlls/mshtml/htmlstyle.h | 1 + dlls/mshtml/tests/documentmode.js | 2 ++ dlls/mshtml/tests/dom.js | 14 ++++++++++++++ 4 files changed, 32 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 40cee5d1890..2be34b74745 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -120,6 +120,13 @@ 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, NULL, + L"transition" + }, { L"animation", DISPID_IHTMLCSSSTYLEDECLARATION2_ANIMATION, @@ -8773,15 +8780,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 0818e555cb9..47b006a9105 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 6cc4edf0c63..16f2056ba93 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -693,7 +693,9 @@ sync_test("style_props", function() { test_exposed("removeProperty", v >= 9, v >= 9, v >= 9); test_exposed("background-clip", v >= 9, v >= 9, v >= 9); test_exposed("msTransform", v >= 9, v >= 9, v >= 9); + test_exposed("msTransition", v >= 10, v >= 10, v >= 10); test_exposed("transform", v >= 10, v >= 10, v >= 10); + test_exposed("transition", v >= 10, v >= 10, v >= 10); });
sync_test("createElement_inline_attr", function() { diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index df47e45cf4b..da21f2e0156 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -477,6 +477,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 | 19 +++++++++++++++---- dlls/mshtml/htmlstyle.h | 1 + dlls/mshtml/tests/dom.js | 1 + 3 files changed, 17 insertions(+), 4 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 2be34b74745..4da5f89b611 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -120,6 +120,13 @@ typedef struct { } style_tbl_entry_t;
static const style_tbl_entry_t style_tbl[] = { + { + L"-ms-transform", + DISPID_IHTMLCSSSTYLEDECLARATION_MSTRANSFORM, + DISPID_UNKNOWN, + 0, NULL, + L"transform" + }, { L"-ms-transition", DISPID_IHTMLCSSSTYLEDECLARATION2_MSTRANSITION, @@ -7282,15 +7289,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 47b006a9105..66509147836 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 da21f2e0156..bafc42e325b 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -480,6 +480,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++) {
This was more quirky than I expected, also fixed a bunch of stuff in the styles (including an existing issue).
Anyway, setting cancelBubble to false works but only during bubbling phase, and also disables stopPropagation (if it wasn't stopped yet obviously), but not the stopImmediatePropagation, which leads to a bug on Windows that I also emulated since it didn't really make the code more complex.
Jacek Caban (@jacek) commented about dlls/mshtml/htmlevent.c:
TRACE("(%p)\n", This); This->stop_immediate_propagation = This->stop_propagation = TRUE;
- nsIDOMEvent_StopImmediatePropagation(This->nsevent);
Why do you move this call? If `cancelBubble` can't affect it, we may as well keep it.
Jacek Caban (@jacek) commented about dlls/mshtml/tests/events.js:
calls += "cancelBubble["+i+"],";
ok(e.cancelBubble === (e.cancelBubble_winetest ? true : false), "cancelBubble before setting cancelBubble = " + e.cancelBubble);
e.cancelBubble = true;
if(e.eventPhase < 2)
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);
- }
- var cancel_bubble = [];
- for(var i = 0; i < 4; i++)
eval('cancel_bubble.push(function(e) { return cancel_bubble_impl('+i+', e); });');
Please don't use `eval`. You may as well just return a function from `cancel_bybble_impl` and just call it here.
Jacek Caban (@jacek) commented about dlls/mshtml/htmlstyle.c:
static const WCHAR *get_style_prop_nsname(const style_tbl_entry_t *style_entry, const WCHAR *orig_name) {
- return style_entry ? get_style_nsname(style_entry) : orig_name;
- return style_entry ? get_style_nsname(style_entry) : orig_name[0] == '-' ? L"" : orig_name;
Do you have a specific case where something like that actually maters? We still use Gecko for parsing CSS, so those properties will still have an effect, except now we'd be stick with the parsed value even if the script tries to change it.
On Mon Jul 22 15:16:28 2024 +0000, Jacek Caban wrote:
Do you have a specific case where something like that actually maters? We still use Gecko for parsing CSS, so those properties will still have an effect, except now we'd be stick with the parsed value even if the script tries to change it.
Not really, it was just for the test I added (and split it into this patch), should I drop the test too or keep it todo_wine?