From: Jacek Caban Subject: mshtml: Added IHTMLBodyElement::scroll attribute implementation. Message-Id: <5280DD6B.4040600@codeweavers.com> Date: Mon, 11 Nov 2013 14:36:43 +0100 --- dlls/mshtml/htmlbody.c | 57 +++++++++++++++++++++++++++++++++++++++++++++---- dlls/mshtml/htmlstyle.c | 47 ++++++++++++++++++++++++++++++++++++---- dlls/mshtml/htmlstyle.h | 3 +++ dlls/mshtml/tests/dom.c | 30 ++++++++++++++++++++++++++ 4 files changed, 129 insertions(+), 8 deletions(-) diff --git a/dlls/mshtml/htmlbody.c b/dlls/mshtml/htmlbody.c index bb5ee34..2b98cf4 100644 --- a/dlls/mshtml/htmlbody.c +++ b/dlls/mshtml/htmlbody.c @@ -30,6 +30,7 @@ #include "mshtml_private.h" #include "htmlevent.h" +#include "htmlstyle.h" WINE_DEFAULT_DEBUG_CHANNEL(mshtml); @@ -602,18 +603,66 @@ static HRESULT WINAPI HTMLBodyElement_get_onunload(IHTMLBodyElement *iface, VARI return E_NOTIMPL; } +static const WCHAR autoW[] = {'a','u','t','o',0}; +static const WCHAR hiddenW[] = {'h','i','d','d','e','n',0}; +static const WCHAR scrollW[] = {'s','c','r','o','l','l',0}; +static const WCHAR visibleW[] = {'v','i','s','i','b','l','e',0}; +static const WCHAR yesW[] = {'y','e','s',0}; +static const WCHAR noW[] = {'n','o',0}; + static HRESULT WINAPI HTMLBodyElement_put_scroll(IHTMLBodyElement *iface, BSTR v) { HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface); - FIXME("(%p)->(%s)\n", This, debugstr_w(v)); - return E_NOTIMPL; + static const WCHAR *val; + + TRACE("(%p)->(%s)\n", This, debugstr_w(v)); + + /* Emulate with CSS visibility attribute */ + if(!strcmpW(v, yesW)) { + val = scrollW; + }else if(!strcmpW(v, autoW)) { + val = visibleW; + }else if(!strcmpW(v, noW)) { + val = hiddenW; + }else { + WARN("Invalid argument %s\n", debugstr_w(v)); + return E_INVALIDARG; + } + + return set_elem_style(&This->textcont.element, STYLEID_OVERFLOW, val); } static HRESULT WINAPI HTMLBodyElement_get_scroll(IHTMLBodyElement *iface, BSTR *p) { HTMLBodyElement *This = impl_from_IHTMLBodyElement(iface); - FIXME("(%p)->(%p)\n", This, p); - return E_NOTIMPL; + const WCHAR *ret; + BSTR overflow; + HRESULT hres; + + TRACE("(%p)->(%p)\n", This, p); + + /* Emulate with CSS visibility attribute */ + hres = get_elem_style(&This->textcont.element, STYLEID_OVERFLOW, &overflow); + if(FAILED(hres)) + return hres; + + if(!overflow || !*overflow) { + *p = NULL; + return S_OK; + }else if(!strcmpW(overflow, visibleW) || !strcmpW(overflow, autoW)) { + ret = autoW; + }else if(!strcmpW(overflow, scrollW)) { + ret = yesW; + }else if(!strcmpW(overflow, hiddenW)) { + ret = noW; + }else { + TRACE("Defaulting %s to NULL", debugstr_w(overflow)); + *p = NULL; + return S_OK; + } + + *p = SysAllocString(ret); + return *p ? S_OK : E_OUTOFMEMORY; } static HRESULT WINAPI HTMLBodyElement_put_onselect(IHTMLBodyElement *iface, VARIANT v) diff --git a/dlls/mshtml/htmlstyle.c b/dlls/mshtml/htmlstyle.c index 5f4fc67..c85e4db 100644 --- a/dlls/mshtml/htmlstyle.c +++ b/dlls/mshtml/htmlstyle.c @@ -3115,11 +3115,9 @@ static dispex_static_data_t HTMLStyle_dispex = { HTMLStyle_iface_tids }; -HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) +static HRESULT get_style_from_elem(HTMLElement *elem, nsIDOMCSSStyleDeclaration **ret) { nsIDOMElementCSSInlineStyle *nselemstyle; - nsIDOMCSSStyleDeclaration *nsstyle; - HTMLStyle *style; nsresult nsres; if(!elem->nselem) { @@ -3131,13 +3129,26 @@ HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) (void**)&nselemstyle); assert(nsres == NS_OK); - nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, &nsstyle); + nsres = nsIDOMElementCSSInlineStyle_GetStyle(nselemstyle, ret); nsIDOMElementCSSInlineStyle_Release(nselemstyle); if(NS_FAILED(nsres)) { ERR("GetStyle failed: %08x\n", nsres); return E_FAIL; } + return S_OK; +} + +HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) +{ + nsIDOMCSSStyleDeclaration *nsstyle; + HTMLStyle *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &nsstyle); + if(FAILED(hres)) + return hres; + style = heap_alloc_zero(sizeof(HTMLStyle)); if(!style) { nsIDOMCSSStyleDeclaration_Release(nsstyle); @@ -3158,3 +3169,31 @@ HRESULT HTMLStyle_Create(HTMLElement *elem, HTMLStyle **ret) *ret = style; return S_OK; } + +HRESULT get_elem_style(HTMLElement *elem, styleid_t styleid, BSTR *ret) +{ + nsIDOMCSSStyleDeclaration *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &style); + if(FAILED(hres)) + return hres; + + hres = get_nsstyle_attr(style, styleid, ret, 0); + nsIDOMCSSStyleDeclaration_Release(style); + return hres; +} + +HRESULT set_elem_style(HTMLElement *elem, styleid_t styleid, const WCHAR *val) +{ + nsIDOMCSSStyleDeclaration *style; + HRESULT hres; + + hres = get_style_from_elem(elem, &style); + if(FAILED(hres)) + return hres; + + hres = set_nsstyle_attr(style, styleid, val, 0); + nsIDOMCSSStyleDeclaration_Release(style); + return hres; +} diff --git a/dlls/mshtml/htmlstyle.h b/dlls/mshtml/htmlstyle.h index 382a226..9294015 100644 --- a/dlls/mshtml/htmlstyle.h +++ b/dlls/mshtml/htmlstyle.h @@ -120,6 +120,9 @@ HRESULT set_nsstyle_attr(nsIDOMCSSStyleDeclaration*,styleid_t,LPCWSTR,DWORD) DEC HRESULT set_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *value, DWORD flags) DECLSPEC_HIDDEN; HRESULT get_nsstyle_attr_var(nsIDOMCSSStyleDeclaration *nsstyle, styleid_t sid, VARIANT *p, DWORD flags) DECLSPEC_HIDDEN; +HRESULT get_elem_style(HTMLElement*,styleid_t,BSTR*) DECLSPEC_HIDDEN; +HRESULT set_elem_style(HTMLElement*,styleid_t,const WCHAR*) DECLSPEC_HIDDEN; + #define ATTR_FIX_PX 0x0001 #define ATTR_FIX_URL 0x0002 #define ATTR_STR_TO_INT 0x0004 diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index f1155d8..e43c754 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -5171,6 +5171,31 @@ static void test_default_body(IHTMLBodyElement *body) VariantClear(&v); } +#define test_body_scroll(a,b) _test_body_scroll(__LINE__,a,b) +static void _test_body_scroll(unsigned line, IHTMLBodyElement *body, const char *ex) +{ + BSTR str; + HRESULT hres; + + hres = IHTMLBodyElement_get_scroll(body, &str); + ok_(__FILE__,line)(hres == S_OK, "get_scroll failed: %08x\n", hres); + ok_(__FILE__,line)(ex ? !strcmp_wa(str, ex) : !str, "scroll = %s\n", wine_dbgstr_w(str)); + SysFreeString(str); +} + +#define set_body_scroll(a,b) _set_body_scroll(__LINE__,a,b) +static void _set_body_scroll(unsigned line, IHTMLBodyElement *body, const char *val) +{ + BSTR str = a2bstr(val); + HRESULT hres; + + hres = IHTMLBodyElement_put_scroll(body, str); + ok_(__FILE__,line)(hres == S_OK, "put_scroll failed: %08x\n", hres); + SysFreeString(str); + + _test_body_scroll(line, body, val); +} + static void test_body_funs(IHTMLBodyElement *body) { VARIANT vbg, vDefaultbg; @@ -5197,6 +5222,11 @@ static void test_body_funs(IHTMLBodyElement *body) hres = IHTMLBodyElement_put_bgColor(body, vDefaultbg); ok(hres == S_OK, "put_bgColor failed: %08x\n", hres); VariantClear(&vDefaultbg); + + test_body_scroll(body, NULL); + set_body_scroll(body, "yes"); + set_body_scroll(body, "no"); + set_body_scroll(body, "auto"); } static void test_history(IHTMLWindow2 *window)