-- v2: mshtml: Get rid of unused HTMLElement_toString_dispids. mshtml: Expose respective props from StyleSheetPrototype. mshtml: Don't expose toString from styles in IE9+ modes. mshtml: Don't expose the *Expression methods from styles in IE9+ modes. mshtml: Don't expose the clip* props from style declaration or properties mshtml: Don't expose 'behavior' prop from styles in IE11 mode. mshtml: Expose respective props from MSCSSPropertiesPrototype. mshtml/tests: Add more tests for the style aliased prop names.
From: Gabriel Ivăncescu gabrielopcode@gmail.com
It's pretty messed up; they're part of the objects themselves (not prototypes) and are props with values, not accessors, even though they change based on the underlying style.
They are also not enumerated by getOwnPropertyNames, while hasOwnProperty returns true, but in one case (getComputedStyle) it also can't retrieve a descriptor for some.
To implement them properly we'd need overrides like with the other volatile objects (localStorage for example), which needs a revamp on jscript, so for now just add the tests.
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/tests/documentmode.js | 89 ++++++++++++++++++++++++------- 1 file changed, 70 insertions(+), 19 deletions(-)
diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 672b8d92bd4..39e0df198bc 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -815,42 +815,93 @@ sync_test("xhr open", function() { });
sync_test("style_props", function() { - var style = document.body.style, currentStyle = document.body.currentStyle, computedStyle = window.getComputedStyle ? window.getComputedStyle(document.body) : undefined; - - 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 r, style = document.body.style, currentStyle = document.body.currentStyle, computedStyle = window.getComputedStyle ? window.getComputedStyle(document.body) : undefined; + + function test_exposed(prop, expect_style, expect_currentStyle, expect_computedStyle, own_prop) { + if(own_prop === undefined) + own_prop = (v < 9); + function test(prop, obj, expect, name) { + if(!expect) + ok(!(prop in obj), prop + " found in " + name + " object."); + else { + ok(prop in obj, prop + " not found in " + name + " object."); + if(own_prop) { + ok(Object.prototype.hasOwnProperty.call(obj, prop), prop + " not prop of " + name + " object."); + if(Object.getOwnPropertyDescriptor) { + var desc = Object.getOwnPropertyDescriptor(obj, prop); + if(name === "computedStyle" && prop.indexOf("-") === -1) { + todo_wine. + ok(desc === undefined, prop + " of " + name + " object is not undefined."); + return; + } + ok(desc.value === obj[prop], prop + " of " + name + " object value = ." + desc.value + ", expected " + obj[prop]); + ok(!("get" in desc), prop + " of " + name + " object has a getter."); + ok(!("set" in desc), prop + " of " + name + " object has a setter."); + ok(desc.writable === true, prop + " of " + name + " object not writable."); + ok(desc.enumerable === true, prop + " of " + name + " object not enumerable."); + ok(desc.configurable === true, prop + " of " + name + " object not configurable."); + } + } + } } + + test(prop, style, expect_style, "style"); + test(prop, currentStyle, expect_currentStyle, "currentStyle"); + if(computedStyle) + test(prop, computedStyle, expect_computedStyle, "computedStyle"); }
var v = document.documentMode;
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("z-index", true, 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("float", true, 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("background-clip", v >= 9, v >= 9, v >= 9, true); 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); + + if(Object.getOwnPropertyNames) { + r = Object.getOwnPropertyNames(style); + todo_wine. + ok(!r.length, "style has own props: " + r); + r = Object.getOwnPropertyNames(currentStyle); + todo_wine. + ok(!r.length, "currentStyle has own props: " + r); + r = Object.getOwnPropertyNames(computedStyle); + todo_wine. + ok(!r.length, "computedStyle has own props: " + r); + + r = Object.getOwnPropertyDescriptor(style, "z-index"); + ok(r.value === "", "style z-index value = " + r.value); + style.zIndex = 1; + r = Object.getOwnPropertyDescriptor(style, "z-index"); + ok(r.value === 1, "style z-index value after set = " + r.value); + + Object.defineProperty(style, "z-index", { get: function() { return "42"; }, configurable: true }); + todo_wine. + ok(style.zIndex === 1, "style zIndex after defineProperty = " + style.zIndex); + todo_wine. + ok(style["z-index"] === "42", "style z-index after defineProperty = " + style["z-index"]); + + r = Object.getOwnPropertyDescriptor(style, "z-index"); + todo_wine. + ok(!("value" in r), "style z-index after defineProperty still has value"); + todo_wine. + ok(typeof(r.get) === "function", "style z-index after defineProperty not a getter"); + + r = delete style["z-index"]; + ok(r === true, "delete style z-index returned " + r); + ok(style["z-index"] === 1, "style z-index after delete = " + style["z-index"]); + } });
sync_test("createElement_inline_attr", function() {
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlcurstyle.c | 34 ++++++ dlls/mshtml/htmlstyle.c | 172 +++++++++++++++++++++++++-- dlls/mshtml/htmlstyle.h | 19 +++ dlls/mshtml/mshtml_private.h | 1 + dlls/mshtml/mshtml_private_iface.idl | 17 +++ dlls/mshtml/tests/documentmode.js | 70 ++++++++++- dlls/mshtml/tests/dom.js | 27 ++++- 7 files changed, 322 insertions(+), 18 deletions(-)
diff --git a/dlls/mshtml/htmlcurstyle.c b/dlls/mshtml/htmlcurstyle.c index f54879fb729..203ebb0aaef 100644 --- a/dlls/mshtml/htmlcurstyle.c +++ b/dlls/mshtml/htmlcurstyle.c @@ -1086,6 +1086,39 @@ static const IHTMLCurrentStyle4Vtbl HTMLCurrentStyle4Vtbl = { HTMLCurrentStyle4_get_maxWidth };
+static inline HTMLCurrentStyle *HTMLCurrentStyle_from_IWineCSSProperties(IWineCSSProperties *iface) +{ + return CONTAINING_RECORD(iface, HTMLCurrentStyle, css_style.IWineCSSProperties_iface); +} + +static HRESULT WINAPI HTMLCurrentStyle_get_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT *p) +{ + HTMLCurrentStyle *This = HTMLCurrentStyle_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %08lx %p)\n", This, debugstr_w(name), flags, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLCurrentStyle_set_attribute(IWineCSSProperties *iface, BSTR name, VARIANT value, LONG flags) +{ + HTMLCurrentStyle *This = HTMLCurrentStyle_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %s %08lx)\n", This, debugstr_w(name), debugstr_variant(&value), flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI HTMLCurrentStyle_remove_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT_BOOL *p) +{ + HTMLCurrentStyle *This = HTMLCurrentStyle_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %08lx %p)\n", This, debugstr_w(name), flags, p); + return E_NOTIMPL; +} + +static const CSSStyleVtbl HTMLCurrentStyle_CSSStyleVtbl = { + .get_attribute = HTMLCurrentStyle_get_attribute, + .set_attribute = HTMLCurrentStyle_set_attribute, + .remove_attribute = HTMLCurrentStyle_remove_attribute, + .attr_compat_ie10_mask = ATTR_COMPAT_IE10 +}; + static inline HTMLCurrentStyle *impl_from_DispatchEx(DispatchEx *dispex) { return CONTAINING_RECORD(dispex, HTMLCurrentStyle, css_style.dispex); @@ -1200,6 +1233,7 @@ HRESULT HTMLCurrentStyle_Create(HTMLElement *elem, IHTMLCurrentStyle **p) ret->IHTMLCurrentStyle4_iface.lpVtbl = &HTMLCurrentStyle4Vtbl;
init_css_style(&ret->css_style, nsstyle, &MSCurrentStyleCSSProperties_dispex, &elem->node.event_target.dispex); + ret->css_style.vtbl = &HTMLCurrentStyle_CSSStyleVtbl; nsIDOMCSSStyleDeclaration_Release(nsstyle);
IHTMLElement_AddRef(&elem->IHTMLElement_iface); diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 92dd9f853be..1e62fa3899a 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -102,14 +102,6 @@ static const WCHAR *overflow_values[] = { NULL };
-#define ATTR_FIX_PX 0x0001 -#define ATTR_FIX_URL 0x0002 -#define ATTR_STR_TO_INT 0x0004 -#define ATTR_HEX_INT 0x0008 -#define ATTR_REMOVE_COMMA 0x0010 -#define ATTR_NO_NULL 0x0020 -#define ATTR_COMPAT_IE10 0x0040 - typedef struct { const WCHAR *name; DISPID dispid; @@ -422,7 +414,8 @@ static const style_tbl_entry_t style_tbl[] = { { L"filter", DISPID_IHTMLCSSSTYLEDECLARATION_FILTER, - DISPID_A_FILTER + DISPID_A_FILTER, + ATTR_COMPAT_IE10_DECL }, { L"float", @@ -734,7 +727,7 @@ static const style_tbl_entry_t *lookup_style_tbl(CSSStyle *style, const WCHAR *n
c = wcscmp(style_tbl[i].name, name); if(!c) { - if((style_tbl[i].flags & ATTR_COMPAT_IE10) && dispex_compat_mode(&style->dispex) < COMPAT_MODE_IE10) + if((style_tbl[i].flags & style->vtbl->attr_compat_ie10_mask) && dispex_compat_mode(&style->dispex) < COMPAT_MODE_IE10) return NULL; return style_tbl+i; } @@ -9547,6 +9540,44 @@ static const IHTMLCSSStyleDeclaration2Vtbl HTMLCSSStyleDeclaration2Vtbl = { HTMLCSSStyleDeclaration2_get_animationFillMode };
+static inline CSSStyle *impl_from_IWineCSSProperties(IWineCSSProperties *iface) +{ + return CONTAINING_RECORD(iface, CSSStyle, IWineCSSProperties_iface); +} + +DISPEX_IDISPATCH_IMPL(CSSProperties, IWineCSSProperties, impl_from_IWineCSSProperties(iface)->dispex) + +static HRESULT WINAPI CSSProperties_setAttribute(IWineCSSProperties *iface, BSTR name, VARIANT value, LONG flags) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + return This->vtbl->set_attribute(iface, name, value, flags); +} + +static HRESULT WINAPI CSSProperties_getAttribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT *p) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + return This->vtbl->get_attribute(iface, name, flags, p); +} + +static HRESULT WINAPI CSSProperties_removeAttribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT_BOOL *p) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + return This->vtbl->remove_attribute(iface, name, flags, p); +} + +static const IWineCSSPropertiesVtbl CSSPropertiesVtbl = { + CSSProperties_QueryInterface, + CSSProperties_AddRef, + CSSProperties_Release, + CSSProperties_GetTypeInfoCount, + CSSProperties_GetTypeInfo, + CSSProperties_GetIDsOfNames, + CSSProperties_Invoke, + CSSProperties_setAttribute, + CSSProperties_getAttribute, + CSSProperties_removeAttribute +}; + static inline CSSStyle *impl_from_DispatchEx(DispatchEx *dispex) { return CONTAINING_RECORD(dispex, CSSStyle, dispex); @@ -9560,6 +9591,8 @@ void *CSSStyle_query_interface(DispatchEx *dispex, REFIID riid) return &This->IHTMLCSSStyleDeclaration_iface; if(IsEqualGUID(&IID_IHTMLCSSStyleDeclaration2, riid)) return &This->IHTMLCSSStyleDeclaration2_iface; + if(IsEqualGUID(&IID_IWineCSSProperties, riid)) + return &This->IWineCSSProperties_iface;
return NULL; } @@ -9602,6 +9635,36 @@ HRESULT CSSStyle_get_dispid(DispatchEx *dispex, const WCHAR *name, DWORD flags, return DISP_E_UNKNOWNNAME; }
+static inline HTMLStyle *HTMLStyle_from_IWineCSSProperties(IWineCSSProperties *iface) +{ + return CONTAINING_RECORD(iface, HTMLStyle, css_style.IWineCSSProperties_iface); +} + +static HRESULT WINAPI HTMLStyle_get_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT *p) +{ + HTMLStyle *This = HTMLStyle_from_IWineCSSProperties(iface); + return HTMLStyle_getAttribute(&This->IHTMLStyle_iface, name, flags, p); +} + +static HRESULT WINAPI HTMLStyle_set_attribute(IWineCSSProperties *iface, BSTR name, VARIANT value, LONG flags) +{ + HTMLStyle *This = HTMLStyle_from_IWineCSSProperties(iface); + return HTMLStyle_setAttribute(&This->IHTMLStyle_iface, name, value, flags); +} + +static HRESULT WINAPI HTMLStyle_remove_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT_BOOL *p) +{ + HTMLStyle *This = HTMLStyle_from_IWineCSSProperties(iface); + return HTMLStyle_removeAttribute(&This->IHTMLStyle_iface, name, flags, p); +} + +static const CSSStyleVtbl HTMLStyle_CSSStyleVtbl = { + .get_attribute = HTMLStyle_get_attribute, + .set_attribute = HTMLStyle_set_attribute, + .remove_attribute = HTMLStyle_remove_attribute, + .attr_compat_ie10_mask = ATTR_COMPAT_IE10 +}; + static inline HTMLStyle *HTMLStyle_from_DispatchEx(DispatchEx *dispex) { return CONTAINING_RECORD(dispex, HTMLStyle, css_style.dispex); @@ -9649,8 +9712,14 @@ static void HTMLStyle_unlink(DispatchEx *dispex)
void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { - if(mode >= COMPAT_MODE_IE9) - dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, NULL); + static const dispex_hook_t styledecl_ie11_hooks[] = { + {DISPID_IHTMLCSSSTYLEDECLARATION_BEHAVIOR}, + {DISPID_UNKNOWN} + }; + if(mode >= COMPAT_MODE_IE9) { + dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, mode >= COMPAT_MODE_IE11 ? styledecl_ie11_hooks : NULL); + dispex_info_add_interface(info, IWineCSSProperties_tid, NULL); + } if(mode >= COMPAT_MODE_IE10) dispex_info_add_interface(info, IHTMLCSSStyleDeclaration2_tid, NULL); } @@ -9658,6 +9727,7 @@ void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode) dispex_static_data_t MSCSSProperties_dispex = { .id = PROT_MSCSSProperties, .prototype_id = PROT_CSSStyleDeclaration, + .init_info = CSSStyle_init_dispex_info, };
static const dispex_static_data_vtbl_t MSStyleCSSProperties_dispex_vtbl = { @@ -9727,6 +9797,7 @@ void init_css_style(CSSStyle *style, nsIDOMCSSStyleDeclaration *nsstyle, dispex_ { style->IHTMLCSSStyleDeclaration_iface.lpVtbl = &HTMLCSSStyleDeclarationVtbl; style->IHTMLCSSStyleDeclaration2_iface.lpVtbl = &HTMLCSSStyleDeclaration2Vtbl; + style->IWineCSSProperties_iface.lpVtbl = &CSSPropertiesVtbl; style->nsstyle = nsstyle; nsIDOMCSSStyleDeclaration_AddRef(nsstyle);
@@ -9760,12 +9831,85 @@ HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) IHTMLDOMNode_AddRef(&elem->node.IHTMLDOMNode_iface);
init_css_style(&style->css_style, nsstyle, &MSStyleCSSProperties_dispex, &elem->node.event_target.dispex); + style->css_style.vtbl = &HTMLStyle_CSSStyleVtbl; nsIDOMCSSStyleDeclaration_Release(nsstyle);
*ret = style; return S_OK; }
+static HRESULT WINAPI CSSStyleDeclaration_get_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT *p) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %08lx %p)\n", This, debugstr_w(name), flags, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI CSSStyleDeclaration_set_attribute(IWineCSSProperties *iface, BSTR name, VARIANT value, LONG flags) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %s %08lx)\n", This, debugstr_w(name), debugstr_variant(&value), flags); + return E_NOTIMPL; +} + +static HRESULT WINAPI CSSStyleDeclaration_remove_attribute(IWineCSSProperties *iface, BSTR name, LONG flags, VARIANT_BOOL *p) +{ + CSSStyle *This = impl_from_IWineCSSProperties(iface); + FIXME("(%p)->(%s %08lx %p)\n", This, debugstr_w(name), flags, p); + return E_NOTIMPL; +} + +static const CSSStyleVtbl CSSStyleDeclaration_CSSStyleVtbl = { + .get_attribute = CSSStyleDeclaration_get_attribute, + .set_attribute = CSSStyleDeclaration_set_attribute, + .remove_attribute = CSSStyleDeclaration_remove_attribute, + .attr_compat_ie10_mask = ATTR_COMPAT_IE10 | ATTR_COMPAT_IE10_DECL +}; + +static void CSSStyleDeclaration_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t styledecl_hooks[] = { + {DISPID_IHTMLCSSSTYLEDECLARATION_FILTER}, + + /* IE10+ */ + {DISPID_IHTMLCSSSTYLEDECLARATION_BACKGROUNDPOSITIONX}, + {DISPID_IHTMLCSSSTYLEDECLARATION_BACKGROUNDPOSITIONY}, + {DISPID_IHTMLCSSSTYLEDECLARATION_STYLEFLOAT}, + {DISPID_IHTMLCSSSTYLEDECLARATION_BEHAVIOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_IMEMODE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTGRIDCHAR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTGRIDLINE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTGRIDMODE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTGRIDTYPE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTGRID}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LINEBREAK}, + {DISPID_IHTMLCSSSTYLEDECLARATION_TEXTJUSTIFYTRIM}, + {DISPID_IHTMLCSSSTYLEDECLARATION_TEXTKASHIDA}, + {DISPID_IHTMLCSSSTYLEDECLARATION_TEXTAUTOSPACE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_ACCELERATOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_LAYOUTFLOW}, + {DISPID_IHTMLCSSSTYLEDECLARATION_ZOOM}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARBASECOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARFACECOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBAR3DLIGHTCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARSHADOWCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARHIGHLIGHTCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARDARKSHADOWCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARARROWCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_SCROLLBARTRACKCOLOR}, + {DISPID_IHTMLCSSSTYLEDECLARATION_WRITINGMODE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_TEXTKASHIDASPACE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_MSINTERPOLATIONMODE}, + {DISPID_IHTMLCSSSTYLEDECLARATION_MSBLOCKPROGRESSION}, + {DISPID_UNKNOWN} + }; + const dispex_hook_t *const styledecl_ie10_hooks = styledecl_hooks + 1; + + dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, mode >= COMPAT_MODE_IE10 ? styledecl_ie10_hooks : styledecl_hooks); + if(mode >= COMPAT_MODE_IE10) + dispex_info_add_interface(info, IHTMLCSSStyleDeclaration2_tid, NULL); +} + static const dispex_static_data_vtbl_t CSSStyleDeclaration_dispex_vtbl = { CSSSTYLE_DISPEX_VTBL_ENTRIES, .query_interface = CSSStyle_query_interface, @@ -9777,7 +9921,7 @@ dispex_static_data_t CSSStyleDeclaration_dispex = { .id = PROT_CSSStyleDeclaration, .vtbl = &CSSStyleDeclaration_dispex_vtbl, .disp_tid = DispHTMLW3CComputedStyle_tid, - .init_info = CSSStyle_init_dispex_info, + .init_info = CSSStyleDeclaration_init_dispex_info, };
HRESULT create_computed_style(nsIDOMCSSStyleDeclaration *nsstyle, DispatchEx *owner, IHTMLCSSStyleDeclaration **p) @@ -9788,6 +9932,8 @@ HRESULT create_computed_style(nsIDOMCSSStyleDeclaration *nsstyle, DispatchEx *ow return E_OUTOFMEMORY;
init_css_style(style, nsstyle, &CSSStyleDeclaration_dispex, owner); + style->vtbl = &CSSStyleDeclaration_CSSStyleVtbl; + *p = &style->IHTMLCSSStyleDeclaration_iface; return S_OK; } diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index b37daf95fa6..37bdc6e7636 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -17,11 +17,30 @@ */
typedef struct CSSStyle CSSStyle; +typedef struct CSSStyleVtbl CSSStyleVtbl; + +#define ATTR_FIX_PX 0x0001 +#define ATTR_FIX_URL 0x0002 +#define ATTR_STR_TO_INT 0x0004 +#define ATTR_HEX_INT 0x0008 +#define ATTR_REMOVE_COMMA 0x0010 +#define ATTR_NO_NULL 0x0020 +#define ATTR_COMPAT_IE10 0x0040 +#define ATTR_COMPAT_IE10_DECL 0x0080 + +struct CSSStyleVtbl { + HRESULT (WINAPI *get_attribute)(IWineCSSProperties*,BSTR,LONG,VARIANT*); + HRESULT (WINAPI *set_attribute)(IWineCSSProperties*,BSTR,VARIANT,LONG); + HRESULT (WINAPI *remove_attribute)(IWineCSSProperties*,BSTR,LONG,VARIANT_BOOL*); + unsigned attr_compat_ie10_mask; +};
struct CSSStyle { DispatchEx dispex; + const CSSStyleVtbl *vtbl; IHTMLCSSStyleDeclaration IHTMLCSSStyleDeclaration_iface; IHTMLCSSStyleDeclaration2 IHTMLCSSStyleDeclaration2_iface; + IWineCSSProperties IWineCSSProperties_iface;
nsIDOMCSSStyleDeclaration *nsstyle; }; diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index f3ba8f75c15..95f7a5f4941 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -304,6 +304,7 @@ typedef struct ScriptHost ScriptHost; XIID(IWineHTMLElementPrivate) \ XIID(IWineHTMLWindowPrivate) \ XIID(IWineHTMLWindowCompatPrivate) \ + XIID(IWineCSSProperties) \ XIID(IWinePageTransitionEvent) \ XIID(IWineXMLHttpRequestPrivate) \ XIID(IWineMSHTMLConsole) \ diff --git a/dlls/mshtml/mshtml_private_iface.idl b/dlls/mshtml/mshtml_private_iface.idl index 6fcf465e5be..bcaeb7f5f5c 100644 --- a/dlls/mshtml/mshtml_private_iface.idl +++ b/dlls/mshtml/mshtml_private_iface.idl @@ -204,6 +204,23 @@ interface IWineHTMLElementPrivate : IDispatch HRESULT classList([retval, out] IDispatch **class_list); }
+[ + odl, + oleautomation, + dual, + hidden, + uuid(465908fd-f394-489f-b7a3-4c00fbbe9eed) +] +interface IWineCSSProperties : IDispatch +{ + [id(DISPID_IHTMLSTYLE_SETATTRIBUTE)] + HRESULT setAttribute([in] BSTR name, [in] VARIANT value, [defaultvalue(1), in] LONG flags); + [id(DISPID_IHTMLSTYLE_GETATTRIBUTE)] + HRESULT getAttribute([in] BSTR name, [defaultvalue(0), in] LONG flags, [out, retval] VARIANT *p); + [id(DISPID_IHTMLSTYLE_REMOVEATTRIBUTE)] + HRESULT removeAttribute([in] BSTR name, [defaultvalue(1), in] LONG flags, [out, retval] VARIANT_BOOL *p); +} + [ odl, oleautomation, diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 39e0df198bc..c6c9f725756 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -853,10 +853,10 @@ sync_test("style_props", function() {
var v = document.documentMode;
- test_exposed("removeAttribute", true, broken(true) ? v >= 9 : false /* todo_wine */, false); + test_exposed("removeAttribute", true, v >= 9, false); test_exposed("zIndex", true, true, true); test_exposed("z-index", true, true, true, true); - test_exposed("filter", true, true, broken(true) ? v >= 10 : v >= 9 /* todo_wine */); + test_exposed("filter", true, true, v >= 10); test_exposed("pixelTop", true, false, false); test_exposed("float", true, true, true, true); test_exposed("css-float", false, false, false); @@ -877,7 +877,7 @@ sync_test("style_props", function() { todo_wine. ok(!r.length, "currentStyle has own props: " + r); r = Object.getOwnPropertyNames(computedStyle); - todo_wine. + todo_wine_if(v >= 10). ok(!r.length, "computedStyle has own props: " + r);
r = Object.getOwnPropertyDescriptor(style, "z-index"); @@ -3766,6 +3766,55 @@ sync_test("prototype props", function() {
check(CharacterData, [ "appendData", "data", "deleteData", "insertData", "length", "replaceData", "substringData" ]); check(Comment, [ "text" ]); + check(CSSStyleDeclaration, [ + ["alignContent",11], ["alignItems",11], ["alignSelf",11], "alignmentBaseline", ["animation",10], ["animationDelay",10], + ["animationDirection",10], ["animationDuration",10], ["animationFillMode",10], ["animationIterationCount",10], ["animationName",10], + ["animationPlayState",10], ["animationTimingFunction",10], ["backfaceVisibility",10], "background", "backgroundAttachment", + "backgroundClip", "backgroundColor", "backgroundImage", "backgroundOrigin", "backgroundPosition", "backgroundRepeat", "backgroundSize", + "baselineShift", "border", "borderBottom", "borderBottomColor", "borderBottomLeftRadius", "borderBottomRightRadius", "borderBottomStyle", + "borderBottomWidth", "borderCollapse", "borderColor", ["borderImage",11], ["borderImageOutset",11], ["borderImageRepeat",11], + ["borderImageSlice",11], ["borderImageSource",11], ["borderImageWidth",11], "borderLeft", "borderLeftColor", "borderLeftStyle", + "borderLeftWidth", "borderRadius", "borderRight", "borderRightColor", "borderRightStyle", "borderRightWidth", "borderSpacing", + "borderStyle", "borderTop", "borderTopColor", "borderTopLeftRadius", "borderTopRightRadius", "borderTopStyle", "borderTopWidth", + "borderWidth", "bottom", "boxShadow", "boxSizing", ["breakAfter",10], ["breakBefore",10], ["breakInside",10], "captionSide", "clear", + "clip", "clipPath", "clipRule", "color", ["colorInterpolationFilters",10], ["columnCount",10], ["columnFill",10], ["columnGap",10], + ["columnRule",10], ["columnRuleColor",10], ["columnRuleStyle",10], ["columnRuleWidth",10], ["columnSpan",10], ["columnWidth",10], + ["columns",10], "content", "counterIncrement", "counterReset", "cssFloat", "cssText", "cursor", "direction", "display", "dominantBaseline", + "emptyCells", ["enableBackground",10], "fill", "fillOpacity", "fillRule", ["filter",10], ["flex",11], ["flexBasis",11], ["flexDirection",11], + ["flexFlow",11], ["flexGrow",11], ["flexShrink",11], ["flexWrap",11], ["floodColor",10], ["floodOpacity",10], "font", "fontFamily", + ["fontFeatureSettings",10], "fontSize", "fontSizeAdjust", "fontStretch", "fontStyle", "fontVariant", "fontWeight", "getPropertyPriority", + "getPropertyValue", "glyphOrientationHorizontal", "glyphOrientationVertical", "height", "item", ["justifyContent",11], "kerning", "left", + "length", "letterSpacing", ["lightingColor",10], "lineHeight", "listStyle", "listStyleImage", "listStylePosition", "listStyleType", "margin", + "marginBottom", "marginLeft", "marginRight", "marginTop", "marker", "markerEnd", "markerMid", "markerStart", "mask", "maxHeight", "maxWidth", + "minHeight", "minWidth", ["msAnimation",10], ["msAnimationDelay",10], ["msAnimationDirection",10], ["msAnimationDuration",10], + ["msAnimationFillMode",10], ["msAnimationIterationCount",10], ["msAnimationName",10], ["msAnimationPlayState",10], ["msAnimationTimingFunction",10], + ["msBackfaceVisibility",10], ["msContentZoomChaining",10], ["msContentZoomLimit",10], ["msContentZoomLimitMax",10], ["msContentZoomLimitMin",10], + ["msContentZoomSnap",10], ["msContentZoomSnapPoints",10], ["msContentZoomSnapType",10], ["msContentZooming",10], ["msFlex",10], ["msFlexAlign",10], + ["msFlexDirection",10], ["msFlexFlow",10], ["msFlexItemAlign",10], ["msFlexLinePack",10], ["msFlexNegative",10], ["msFlexOrder",10], + ["msFlexPack",10], ["msFlexPositive",10], ["msFlexPreferredSize",10], ["msFlexWrap",10], ["msFlowFrom",10], ["msFlowInto",10], + ["msFontFeatureSettings",10], ["msGridColumn",10], ["msGridColumnAlign",10], ["msGridColumnSpan",10], ["msGridColumns",10], ["msGridRow",10], + ["msGridRowAlign",10], ["msGridRowSpan",10], ["msGridRows",10], ["msHighContrastAdjust",10], ["msHyphenateLimitChars",10], + ["msHyphenateLimitLines",10], ["msHyphenateLimitZone",10], ["msHyphens",10], ["msImeAlign",11], ["msOverflowStyle",10], ["msPerspective",10], + ["msPerspectiveOrigin",10], ["msScrollChaining",10], ["msScrollLimit",10], ["msScrollLimitXMax",10], ["msScrollLimitXMin",10], + ["msScrollLimitYMax",10], ["msScrollLimitYMin",10], ["msScrollRails",10], ["msScrollSnapPointsX",10], ["msScrollSnapPointsY",10], + ["msScrollSnapType",10], ["msScrollSnapX",10], ["msScrollSnapY",10], ["msScrollTranslation",10], ["msTextCombineHorizontal",11], + ["msTextSizeAdjust",11], ["msTouchAction",10], ["msTouchSelect",10], "msTransform", "msTransformOrigin", ["msTransformStyle",10], ["msTransition",10], + ["msTransitionDelay",10], ["msTransitionDuration",10], ["msTransitionProperty",10], ["msTransitionTimingFunction",10], ["msUserSelect",10], + ["msWrapFlow",10], ["msWrapMargin",10], ["msWrapThrough",10], "opacity", ["order",11], "orphans", "outline", "outlineColor", "outlineStyle", + "outlineWidth", "overflow", "overflowX", "overflowY", "padding", "paddingBottom", "paddingLeft", "paddingRight", "paddingTop", "pageBreakAfter", + "pageBreakBefore", "pageBreakInside", "parentRule", ["perspective",10], ["perspectiveOrigin",10], "pointerEvents", "position", "quotes", + "removeProperty", "right", "rubyAlign", "rubyOverhang", "rubyPosition", "setProperty", "stopColor", "stopOpacity", "stroke", "strokeDasharray", + "strokeDashoffset", "strokeLinecap", "strokeLinejoin", "strokeMiterlimit", "strokeOpacity", "strokeWidth", "tableLayout", "textAlign", "textAlignLast", + "textAnchor", "textDecoration", "textIndent", "textJustify", "textOverflow", ["textShadow",10], "textTransform", "textUnderlinePosition", "top", + ["touchAction",11], ["transform",10], ["transformOrigin",10], ["transformStyle",10], ["transition",10], ["transitionDelay",10], ["transitionDuration",10], + ["transitionProperty",10], ["transitionTimingFunction",10], "unicodeBidi", "verticalAlign", "visibility", "whiteSpace", "widows", "width", "wordBreak", + "wordSpacing", "wordWrap", "zIndex" + ], [ + ["alignContent",11], ["alignItems",11], ["alignSelf",11], ["borderImage",11], ["borderImageOutset",11], ["borderImageRepeat",11], ["borderImageSlice",11], + ["borderImageSource",11], ["borderImageWidth",11], "clipBottom", "clipLeft", "clipRight", "clipTop", ["flex",11], ["flexBasis",11], ["flexDirection",11], + ["flexFlow",11], ["flexGrow",11], ["flexShrink",11], ["flexWrap",11], ["justifyContent",11], ["msImeAlign",11], ["msTextCombineHorizontal",11], + ["msTextSizeAdjust",11], ["order",11], ["touchAction",11] + ]); check(CSSStyleRule, [ "readOnly", "selectorText", "style" ]); check(CustomEvent, [ "detail", "initCustomEvent" ]); check(Document, [ @@ -3888,6 +3937,21 @@ sync_test("prototype props", function() { "initMouseEvent", "layerX", "layerY", "metaKey", "offsetX", "offsetY", "pageX", "pageY", "relatedTarget", "screenX", "screenY", "shiftKey", "toElement", "which", "x", "y" ]); + check(MSCSSProperties, [ + "accelerator", "backgroundPositionX", "backgroundPositionY", ["behavior",9,10], ["filter",9,9], "getAttribute", + "imeMode", "layoutFlow", "layoutGrid", "layoutGridChar", "layoutGridLine", "layoutGridMode", "layoutGridType", + "lineBreak", "msBlockProgression", "msInterpolationMode", "removeAttribute", "scrollbar3dLightColor", + "scrollbarArrowColor", "scrollbarBaseColor", "scrollbarDarkShadowColor", "scrollbarFaceColor", + "scrollbarHighlightColor", "scrollbarShadowColor", "scrollbarTrackColor", "setAttribute", "styleFloat", + "textAutospace", "textJustifyTrim", "textKashida", "textKashidaSpace", "writingMode", "zoom" + ]); + check(MSCurrentStyleCSSProperties, [ "blockDirection", "clipBottom", "clipLeft", "clipRight", "clipTop", "hasLayout" ], + [ ["behavior",11], "clipBottom", "clipLeft", "clipRight", "clipTop"]); + check(MSStyleCSSProperties, [ + "pixelBottom", "pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "posBottom", + "posHeight", "posLeft", "posRight", "posTop", "posWidth", "textDecorationBlink", "textDecorationLineThrough", + "textDecorationNone", "textDecorationOverline", "textDecorationUnderline" + ], [ ["behavior",11], "getExpression", "removeExpression", "setExpression", "toString" ]); check(Node, [ "ATTRIBUTE_NODE", "CDATA_SECTION_NODE", "COMMENT_NODE", "DOCUMENT_FRAGMENT_NODE", "DOCUMENT_NODE", "DOCUMENT_POSITION_CONTAINED_BY", "DOCUMENT_POSITION_CONTAINS", "DOCUMENT_POSITION_DISCONNECTED", diff --git a/dlls/mshtml/tests/dom.js b/dlls/mshtml/tests/dom.js index 5ee5a788c90..256cab60d7c 100644 --- a/dlls/mshtml/tests/dom.js +++ b/dlls/mshtml/tests/dom.js @@ -470,12 +470,35 @@ sync_test("style_properties", function() { try { current_style.zIndex = 1; ok(false, "expected exception"); - }catch(e) {} + }catch(e) { + todo_wine. + ok(e.name === "NoModificationAllowedError", "setting current_style.zIndex threw " + e.name); + }
try { computed_style.zIndex = 1; ok(false, "expected exception"); - }catch(e) {} + }catch(e) { + todo_wine. + ok(e.name === "NoModificationAllowedError", "setting computed_style.zIndex threw " + e.name); + } + + /* prop not found in any IHTMLCurrentStyle* interfaces, but exposed from common CSSStyleDeclarationPrototype */ + try { + current_style.perspective = 1; + ok(false, "expected exception"); + }catch(e) { + todo_wine. + ok(e.name === "NoModificationAllowedError", "setting current_style.perspective threw " + e.name); + } + + try { + computed_style.perspective = 1; + ok(false, "expected exception"); + }catch(e) { + todo_wine. + ok(e.name === "NoModificationAllowedError", "setting computed_style.perspective threw " + e.name); + }
elem = elem.nextSibling; computed_style = window.getComputedStyle(elem);
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlcurstyle.c | 14 ++++++++++++-- dlls/mshtml/htmlstyle.c | 13 +++++++++++-- dlls/mshtml/tests/documentmode.js | 4 ++-- 3 files changed, 25 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlcurstyle.c b/dlls/mshtml/htmlcurstyle.c index 203ebb0aaef..297a0a58610 100644 --- a/dlls/mshtml/htmlcurstyle.c +++ b/dlls/mshtml/htmlcurstyle.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "mshtml_private.h" #include "htmlstyle.h" @@ -1160,6 +1161,16 @@ static void HTMLCurrentStyle_unlink(DispatchEx *dispex) } }
+static void MSCurrentStyleCSSProperties_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t currentstyle_ie11_hooks[] = { + {DISPID_IHTMLCURRENTSTYLE_BEHAVIOR}, + {DISPID_UNKNOWN} + }; + CSSStyle_init_dispex_info(info, mode); + dispex_info_add_interface(info, IHTMLCurrentStyle_tid, mode >= COMPAT_MODE_IE11 ? currentstyle_ie11_hooks : NULL); +} + static const dispex_static_data_vtbl_t MSCurrentStyleCSSProperties_dispex_vtbl = { CSSSTYLE_DISPEX_VTBL_ENTRIES, .query_interface = HTMLCurrentStyle_query_interface, @@ -1168,7 +1179,6 @@ static const dispex_static_data_vtbl_t MSCurrentStyleCSSProperties_dispex_vtbl = };
static const tid_t MSCurrentStyleCSSProperties_iface_tids[] = { - IHTMLCurrentStyle_tid, IHTMLCurrentStyle2_tid, IHTMLCurrentStyle3_tid, IHTMLCurrentStyle4_tid, @@ -1180,7 +1190,7 @@ dispex_static_data_t MSCurrentStyleCSSProperties_dispex = { .vtbl = &MSCurrentStyleCSSProperties_dispex_vtbl, .disp_tid = DispHTMLCurrentStyle_tid, .iface_tids = MSCurrentStyleCSSProperties_iface_tids, - .init_info = CSSStyle_init_dispex_info, + .init_info = MSCurrentStyleCSSProperties_init_dispex_info, };
HRESULT HTMLCurrentStyle_Create(HTMLElement *elem, IHTMLCurrentStyle **p) diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 1e62fa3899a..8f43cb90a70 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9730,6 +9730,16 @@ dispex_static_data_t MSCSSProperties_dispex = { .init_info = CSSStyle_init_dispex_info, };
+static void MSStyleCSSProperties_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const dispex_hook_t style2_ie11_hooks[] = { + {DISPID_IHTMLSTYLE2_BEHAVIOR}, + {DISPID_UNKNOWN} + }; + CSSStyle_init_dispex_info(info, mode); + dispex_info_add_interface(info, IHTMLStyle2_tid, mode >= COMPAT_MODE_IE11 ? style2_ie11_hooks : NULL); +} + static const dispex_static_data_vtbl_t MSStyleCSSProperties_dispex_vtbl = { CSSSTYLE_DISPEX_VTBL_ENTRIES, .query_interface = HTMLStyle_query_interface, @@ -9742,7 +9752,6 @@ static const tid_t MSStyleCSSProperties_iface_tids[] = { IHTMLStyle5_tid, IHTMLStyle4_tid, IHTMLStyle3_tid, - IHTMLStyle2_tid, IHTMLStyle_tid, 0 }; @@ -9752,7 +9761,7 @@ dispex_static_data_t MSStyleCSSProperties_dispex = { .vtbl = &MSStyleCSSProperties_dispex_vtbl, .disp_tid = DispHTMLStyle_tid, .iface_tids = MSStyleCSSProperties_iface_tids, - .init_info = CSSStyle_init_dispex_info, + .init_info = MSStyleCSSProperties_init_dispex_info, };
static HRESULT get_style_from_elem(HTMLElement *elem, nsIDOMCSSStyleDeclaration **ret) diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index c6c9f725756..f19f76679eb 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3946,12 +3946,12 @@ sync_test("prototype props", function() { "textAutospace", "textJustifyTrim", "textKashida", "textKashidaSpace", "writingMode", "zoom" ]); check(MSCurrentStyleCSSProperties, [ "blockDirection", "clipBottom", "clipLeft", "clipRight", "clipTop", "hasLayout" ], - [ ["behavior",11], "clipBottom", "clipLeft", "clipRight", "clipTop"]); + [ "clipBottom", "clipLeft", "clipRight", "clipTop"]); check(MSStyleCSSProperties, [ "pixelBottom", "pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "posBottom", "posHeight", "posLeft", "posRight", "posTop", "posWidth", "textDecorationBlink", "textDecorationLineThrough", "textDecorationNone", "textDecorationOverline", "textDecorationUnderline" - ], [ ["behavior",11], "getExpression", "removeExpression", "setExpression", "toString" ]); + ], [ "getExpression", "removeExpression", "setExpression", "toString" ]); check(Node, [ "ATTRIBUTE_NODE", "CDATA_SECTION_NODE", "COMMENT_NODE", "DOCUMENT_FRAGMENT_NODE", "DOCUMENT_NODE", "DOCUMENT_POSITION_CONTAINED_BY", "DOCUMENT_POSITION_CONTAINS", "DOCUMENT_POSITION_DISCONNECTED",
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 13 ++++++++++++- dlls/mshtml/tests/documentmode.js | 8 +++----- 2 files changed, 15 insertions(+), 6 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 8f43cb90a70..8a4a58a87fd 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9714,10 +9714,17 @@ void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { static const dispex_hook_t styledecl_ie11_hooks[] = { {DISPID_IHTMLCSSSTYLEDECLARATION_BEHAVIOR}, + + /* IE10 and below */ + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPTOP}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPRIGHT}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPBOTTOM}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPLEFT}, {DISPID_UNKNOWN} }; + const dispex_hook_t *const styledecl_hooks = styledecl_ie11_hooks + 1; if(mode >= COMPAT_MODE_IE9) { - dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, mode >= COMPAT_MODE_IE11 ? styledecl_ie11_hooks : NULL); + dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, mode >= COMPAT_MODE_IE11 ? styledecl_ie11_hooks : styledecl_hooks); dispex_info_add_interface(info, IWineCSSProperties_tid, NULL); } if(mode >= COMPAT_MODE_IE10) @@ -9910,6 +9917,10 @@ static void CSSStyleDeclaration_init_dispex_info(dispex_data_t *info, compat_mod {DISPID_IHTMLCSSSTYLEDECLARATION_TEXTKASHIDASPACE}, {DISPID_IHTMLCSSSTYLEDECLARATION_MSINTERPOLATIONMODE}, {DISPID_IHTMLCSSSTYLEDECLARATION_MSBLOCKPROGRESSION}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPTOP}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPRIGHT}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPBOTTOM}, + {DISPID_IHTMLCSSSTYLEDECLARATION_CLIPLEFT}, {DISPID_UNKNOWN} }; const dispex_hook_t *const styledecl_ie10_hooks = styledecl_hooks + 1; diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f19f76679eb..45e88d3499e 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3811,9 +3811,8 @@ sync_test("prototype props", function() { "wordSpacing", "wordWrap", "zIndex" ], [ ["alignContent",11], ["alignItems",11], ["alignSelf",11], ["borderImage",11], ["borderImageOutset",11], ["borderImageRepeat",11], ["borderImageSlice",11], - ["borderImageSource",11], ["borderImageWidth",11], "clipBottom", "clipLeft", "clipRight", "clipTop", ["flex",11], ["flexBasis",11], ["flexDirection",11], - ["flexFlow",11], ["flexGrow",11], ["flexShrink",11], ["flexWrap",11], ["justifyContent",11], ["msImeAlign",11], ["msTextCombineHorizontal",11], - ["msTextSizeAdjust",11], ["order",11], ["touchAction",11] + ["borderImageSource",11], ["borderImageWidth",11], ["flex",11], ["flexBasis",11], ["flexDirection",11], ["flexFlow",11], ["flexGrow",11], ["flexShrink",11], + ["flexWrap",11], ["justifyContent",11], ["msImeAlign",11], ["msTextCombineHorizontal",11], ["msTextSizeAdjust",11], ["order",11], ["touchAction",11] ]); check(CSSStyleRule, [ "readOnly", "selectorText", "style" ]); check(CustomEvent, [ "detail", "initCustomEvent" ]); @@ -3945,8 +3944,7 @@ sync_test("prototype props", function() { "scrollbarHighlightColor", "scrollbarShadowColor", "scrollbarTrackColor", "setAttribute", "styleFloat", "textAutospace", "textJustifyTrim", "textKashida", "textKashidaSpace", "writingMode", "zoom" ]); - check(MSCurrentStyleCSSProperties, [ "blockDirection", "clipBottom", "clipLeft", "clipRight", "clipTop", "hasLayout" ], - [ "clipBottom", "clipLeft", "clipRight", "clipTop"]); + check(MSCurrentStyleCSSProperties, [ "blockDirection", "clipBottom", "clipLeft", "clipRight", "clipTop", "hasLayout" ]); check(MSStyleCSSProperties, [ "pixelBottom", "pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "posBottom", "posHeight", "posLeft", "posRight", "posTop", "posWidth", "textDecorationBlink", "textDecorationLineThrough",
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 9 ++++++++- dlls/mshtml/tests/documentmode.js | 3 ++- 2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 8a4a58a87fd..790a9767437 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9741,10 +9741,17 @@ static void MSStyleCSSProperties_init_dispex_info(dispex_data_t *info, compat_mo { static const dispex_hook_t style2_ie11_hooks[] = { {DISPID_IHTMLSTYLE2_BEHAVIOR}, + + /* IE9+ */ + {DISPID_IHTMLSTYLE2_SETEXPRESSION}, + {DISPID_IHTMLSTYLE2_GETEXPRESSION}, + {DISPID_IHTMLSTYLE2_REMOVEEXPRESSION}, {DISPID_UNKNOWN} }; + const dispex_hook_t *const style2_ie9_hooks = style2_ie11_hooks + 1; CSSStyle_init_dispex_info(info, mode); - dispex_info_add_interface(info, IHTMLStyle2_tid, mode >= COMPAT_MODE_IE11 ? style2_ie11_hooks : NULL); + dispex_info_add_interface(info, IHTMLStyle2_tid, mode >= COMPAT_MODE_IE11 ? style2_ie11_hooks : + mode >= COMPAT_MODE_IE9 ? style2_ie9_hooks : NULL); }
static const dispex_static_data_vtbl_t MSStyleCSSProperties_dispex_vtbl = { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 45e88d3499e..1ce2a4bee99 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -854,6 +854,7 @@ sync_test("style_props", function() { var v = document.documentMode;
test_exposed("removeAttribute", true, v >= 9, false); + test_exposed("setExpression", v < 9, false, false); test_exposed("zIndex", true, true, true); test_exposed("z-index", true, true, true, true); test_exposed("filter", true, true, v >= 10); @@ -3949,7 +3950,7 @@ sync_test("prototype props", function() { "pixelBottom", "pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "posBottom", "posHeight", "posLeft", "posRight", "posTop", "posWidth", "textDecorationBlink", "textDecorationLineThrough", "textDecorationNone", "textDecorationOverline", "textDecorationUnderline" - ], [ "getExpression", "removeExpression", "setExpression", "toString" ]); + ], [ "toString" ]); check(Node, [ "ATTRIBUTE_NODE", "CDATA_SECTION_NODE", "COMMENT_NODE", "DOCUMENT_FRAGMENT_NODE", "DOCUMENT_NODE", "DOCUMENT_POSITION_CONTAINED_BY", "DOCUMENT_POSITION_CONTAINS", "DOCUMENT_POSITION_DISCONNECTED",
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstyle.c | 6 +++++- dlls/mshtml/tests/documentmode.js | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-)
diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 790a9767437..cd1efda80ba 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -9739,6 +9739,10 @@ dispex_static_data_t MSCSSProperties_dispex = {
static void MSStyleCSSProperties_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { + static const dispex_hook_t style_ie9_hooks[] = { + {DISPID_IHTMLSTYLE_TOSTRING}, + {DISPID_UNKNOWN} + }; static const dispex_hook_t style2_ie11_hooks[] = { {DISPID_IHTMLSTYLE2_BEHAVIOR},
@@ -9752,6 +9756,7 @@ static void MSStyleCSSProperties_init_dispex_info(dispex_data_t *info, compat_mo CSSStyle_init_dispex_info(info, mode); dispex_info_add_interface(info, IHTMLStyle2_tid, mode >= COMPAT_MODE_IE11 ? style2_ie11_hooks : mode >= COMPAT_MODE_IE9 ? style2_ie9_hooks : NULL); + dispex_info_add_interface(info, IHTMLStyle_tid, mode >= COMPAT_MODE_IE9 ? style_ie9_hooks : NULL); }
static const dispex_static_data_vtbl_t MSStyleCSSProperties_dispex_vtbl = { @@ -9766,7 +9771,6 @@ static const tid_t MSStyleCSSProperties_iface_tids[] = { IHTMLStyle5_tid, IHTMLStyle4_tid, IHTMLStyle3_tid, - IHTMLStyle_tid, 0 }; dispex_static_data_t MSStyleCSSProperties_dispex = { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index 1ce2a4bee99..f6c6a9fbde9 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3950,7 +3950,7 @@ sync_test("prototype props", function() { "pixelBottom", "pixelHeight", "pixelLeft", "pixelRight", "pixelTop", "pixelWidth", "posBottom", "posHeight", "posLeft", "posRight", "posTop", "posWidth", "textDecorationBlink", "textDecorationLineThrough", "textDecorationNone", "textDecorationOverline", "textDecorationUnderline" - ], [ "toString" ]); + ]); check(Node, [ "ATTRIBUTE_NODE", "CDATA_SECTION_NODE", "COMMENT_NODE", "DOCUMENT_FRAGMENT_NODE", "DOCUMENT_NODE", "DOCUMENT_POSITION_CONTAINED_BY", "DOCUMENT_POSITION_CONTAINS", "DOCUMENT_POSITION_DISCONNECTED",
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlstylesheet.c | 23 ++++++++++++++++++++++- dlls/mshtml/tests/documentmode.js | 5 +++++ 2 files changed, 27 insertions(+), 1 deletion(-)
diff --git a/dlls/mshtml/htmlstylesheet.c b/dlls/mshtml/htmlstylesheet.c index 277b2ea04d1..4b9cc3f56a6 100644 --- a/dlls/mshtml/htmlstylesheet.c +++ b/dlls/mshtml/htmlstylesheet.c @@ -24,6 +24,7 @@ #include "winbase.h" #include "winuser.h" #include "ole2.h" +#include "mshtmdid.h"
#include "wine/debug.h"
@@ -1199,6 +1200,25 @@ static void HTMLStyleSheet_destructor(DispatchEx *dispex) free(This); }
+static void StyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t mode) +{ + static const DISPID stylesheet_dispids[] = { + DISPID_IHTMLSTYLESHEET_PARENTSTYLESHEET, + DISPID_IHTMLSTYLESHEET_DISABLED, + DISPID_UNKNOWN + }; + static const DISPID stylesheet4_dispids[] = { + DISPID_IHTMLSTYLESHEET4_IE9_TYPE, + DISPID_IHTMLSTYLESHEET4_IE9_HREF, + DISPID_IHTMLSTYLESHEET4_IE9_TITLE, + DISPID_IHTMLSTYLESHEET4_OWNERNODE, + DISPID_IHTMLSTYLESHEET4_IE9_MEDIA, + DISPID_UNKNOWN + }; + dispex_info_add_dispids(info, IHTMLStyleSheet4_tid, stylesheet4_dispids); + dispex_info_add_dispids(info, IHTMLStyleSheet_tid, stylesheet_dispids); +} + static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t mode) { if(mode >= COMPAT_MODE_IE9) @@ -1206,7 +1226,8 @@ static void HTMLStyleSheet_init_dispex_info(dispex_data_t *info, compat_mode_t m }
dispex_static_data_t StyleSheet_dispex = { - .id = PROT_StyleSheet, + .id = PROT_StyleSheet, + .init_info = StyleSheet_init_dispex_info, };
static const dispex_static_data_vtbl_t CSSStyleSheet_dispex_vtbl = { diff --git a/dlls/mshtml/tests/documentmode.js b/dlls/mshtml/tests/documentmode.js index f6c6a9fbde9..a3401e52e13 100644 --- a/dlls/mshtml/tests/documentmode.js +++ b/dlls/mshtml/tests/documentmode.js @@ -3815,6 +3815,10 @@ sync_test("prototype props", function() { ["borderImageSource",11], ["borderImageWidth",11], ["flex",11], ["flexBasis",11], ["flexDirection",11], ["flexFlow",11], ["flexGrow",11], ["flexShrink",11], ["flexWrap",11], ["justifyContent",11], ["msImeAlign",11], ["msTextCombineHorizontal",11], ["msTextSizeAdjust",11], ["order",11], ["touchAction",11] ]); + check(CSSStyleSheet, [ + "addImport", "addPageRule", "addRule", "cssRules", "cssText", "deleteRule", "href", "id", "imports", "insertRule", + "isAlternate", "isPrefAlternate", "ownerRule", "owningElement", "pages", "readOnly", "removeImport", "removeRule", "rules" + ], [ "addPageRule", "href", "isAlternate", "isPrefAlternate", "pages" ]); check(CSSStyleRule, [ "readOnly", "selectorText", "style" ]); check(CustomEvent, [ "detail", "initCustomEvent" ]); check(Document, [ @@ -3973,6 +3977,7 @@ sync_test("prototype props", function() { if(v >= 10) check(ProgressEvent, [ "initProgressEvent", "lengthComputable", "loaded", "total" ]); check(StorageEvent, [ "initStorageEvent", "key", "newValue", "oldValue", "storageArea", "url" ]); + check(StyleSheet, [ "disabled", "href", "media", "ownerNode", "parentStyleSheet", "title", "type" ]); check(Text, [ "removeNode", "replaceNode", "replaceWholeText", "splitText", "swapNode", "wholeText" ], [ "replaceWholeText", "wholeText" ]); check(UIEvent, [ "detail", "initUIEvent", "view" ], null, [ "deviceSessionId" ]); });
From: Gabriel Ivăncescu gabrielopcode@gmail.com
Signed-off-by: Gabriel Ivăncescu gabrielopcode@gmail.com --- dlls/mshtml/htmlelem.c | 5 ----- 1 file changed, 5 deletions(-)
diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index 3d586db02d2..fcd8c969a01 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -6793,11 +6793,6 @@ void HTMLElement_init_dispex_info(dispex_data_t *info, compat_mode_t mode) dispex_info_add_interface(info, IHTMLUniqueName_tid, NULL); }
-const DISPID HTMLElement_toString_dispids[] = { - DISPID_IHTMLELEMENT_TOSTRING, - DISPID_UNKNOWN -}; - static const event_target_vtbl_t HTMLElement_event_target_vtbl = { { HTMLELEMENT_DISPEX_VTBL_ENTRIES,
Jacek Caban (@jacek) commented about dlls/mshtml/htmlstyle.c:
HTMLCSSStyleDeclaration2_get_animationFillMode
};
+static inline CSSStyle *impl_from_IWineCSSProperties(IWineCSSProperties *iface) +{
- return CONTAINING_RECORD(iface, CSSStyle, IWineCSSProperties_iface);
+}
+DISPEX_IDISPATCH_IMPL(CSSProperties, IWineCSSProperties, impl_from_IWineCSSProperties(iface)->dispex)
+static HRESULT WINAPI CSSProperties_setAttribute(IWineCSSProperties *iface, BSTR name, VARIANT value, LONG flags) +{
- CSSStyle *This = impl_from_IWineCSSProperties(iface);
- return This->vtbl->set_attribute(iface, name, value, flags);
+}
If we're forwarding everything anyway, I don't see a point of the extra indirection. We could implement the interface separately in `HTMLStyle` and `HTMLCurrentStyle`. Since computed style should not expose it, having it outside `CSSStyle` seems cleaner anyway.
Jacek Caban (@jacek) commented about dlls/mshtml/htmlstyle.c:
c = wcscmp(style_tbl[i].name, name); if(!c) {
if((style_tbl[i].flags & ATTR_COMPAT_IE10) && dispex_compat_mode(&style->dispex) < COMPAT_MODE_IE10)
if((style_tbl[i].flags & style->vtbl->attr_compat_ie10_mask) && dispex_compat_mode(&style->dispex) < COMPAT_MODE_IE10)
Can we split it out of this commit? This use of vtbl will likely need to be changed (see my other comment), but having it in a separated commit or even outside this MR would be cleaner.
Jacek Caban (@jacek) commented about dlls/mshtml/htmlstyle.c:
void CSSStyle_init_dispex_info(dispex_data_t *info, compat_mode_t mode) {
- if(mode >= COMPAT_MODE_IE9)
dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, NULL);
- static const dispex_hook_t styledecl_ie11_hooks[] = {
{DISPID_IHTMLCSSSTYLEDECLARATION_BEHAVIOR},
{DISPID_UNKNOWN}
- };
- if(mode >= COMPAT_MODE_IE9) {
dispex_info_add_interface(info, IHTMLCSSStyleDeclaration_tid, mode >= COMPAT_MODE_IE11 ? styledecl_ie11_hooks : NULL);
dispex_info_add_interface(info, IWineCSSProperties_tid, NULL);
- } if(mode >= COMPAT_MODE_IE10) dispex_info_add_interface(info, IHTMLCSSStyleDeclaration2_tid, NULL);
}
While at it, please rename it to `MSCSSProperties_init_dispex_info` to match the public, exposed name. `CSSStyle` is becoming confusing in this context.
Please remove mentions of jscript revamp from the commit message. As discussed, there is no evidence that it's needed for style objects so far.
On Wed Dec 4 12:29:39 2024 +0000, Jacek Caban wrote:
Can we split it out of this commit? This use of vtbl will likely need to be changed (see my other comment), but having it in a separated commit or even outside this MR would be cleaner.
I can try to split it before this patch, but it is required for the tests, otherwise stuff like `filter` would simply fail because they would have an invalid DISPID. Let me see.
On Wed Dec 4 15:44:40 2024 +0000, Gabriel Ivăncescu wrote:
I can try to split it before this patch, but it is required for the tests, otherwise stuff like `filter` would simply fail because they would have an invalid DISPID. Let me see.
I meant after, not before. Is it needed for the initial prototype split?
On Wed Dec 4 15:48:04 2024 +0000, Jacek Caban wrote:
I meant after, not before. Is it needed for the initial prototype split?
Yeah, it has to match what's available, else the DISPIDs would simply point to a builtin func that doesn't exist (i.e. `get_builtin_func` will fail).
On Wed Dec 4 15:51:23 2024 +0000, Gabriel Ivăncescu wrote:
Yeah, it has to match what's available, else the DISPIDs would simply point to a builtin func that doesn't exist (i.e. `get_builtin_func` will fail).
Could we just skip the search in `CSSStyle_get_dispid` if the name does not contain '-' or something similar? The thing we probably want to check is if the same is the same as the regular accessor property name. Prior to prototypes support, it would never be the case as the builtin property would be found first. Unless I'm missing something, those differ only when there is '-' involved.
On Wed Dec 4 16:09:10 2024 +0000, Jacek Caban wrote:
Could we just skip the search in `CSSStyle_get_dispid` if the name does not contain '-' or something similar? The thing we probably want to check is if the same is the same as the regular accessor property name. Prior to prototypes support, it would never be the case as the builtin property would be found first. Unless I'm missing something, those differ only when there is '-' involved.
Yeah that can probably work, I'll try that if you're fine with it.
On Wed Dec 4 16:15:33 2024 +0000, Gabriel Ivăncescu wrote:
Yeah that can probably work, I'll try that if you're fine with it.
Or what about if I add a flag so it's less "hacky"?
On Wed Dec 4 16:21:53 2024 +0000, Gabriel Ivăncescu wrote:
Or what about if I add a flag so it's less "hacky"?
I'm not sure what you mean. My main hope is that the solution will not require manually tagging individual CSS properties for things that are expressed in disp info anyway.
On Wed Dec 4 16:28:15 2024 +0000, Jacek Caban wrote:
I'm not sure what you mean. My main hope is that the solution will not require manually tagging individual CSS properties for things that are expressed in disp info anyway.
I mean tagging the ones that have the same names as builtin so we prefer builtins for them. Not about their compat versions or anything like that.
On Wed Dec 4 16:32:34 2024 +0000, Gabriel Ivăncescu wrote:
I mean tagging the ones that have the same names as builtin so we prefer builtins for them. Not about their compat versions or anything like that.
Note that it seems looking for '-' won't work because "float" refers to "cssFloat" builtin and it doesn't have '-' so I guess we have to do it anyway.
On Wed Dec 4 16:34:53 2024 +0000, Gabriel Ivăncescu wrote:
Note that it seems looking for '-' won't work because "float" refers to "cssFloat" builtin and it doesn't have '-' so I guess we have to do it anyway.
I guess if we need to, we may make the check precise with something like `dispex_prop_name` (maybe avoiding string allocation) on found dispid. I was hoping to avoid too much complication given that it will have to be revisited for using own properties instead of aliasing them, but that seems more robust.
On Wed Dec 4 16:59:47 2024 +0000, Jacek Caban wrote:
I guess if we need to, we may make the check precise with something like `dispex_prop_name` (maybe avoiding string allocation) on found dispid. I was hoping to avoid too much complication given that it will have to be revisited for using own properties instead of aliasing them, but that seems more robust.
Well I went with the flag, since it's only for get_dispid, I don't think it's too bad to tag them like this and can just pass the flag directly.