diff --git a/dlls/mshtml/Makefile.in b/dlls/mshtml/Makefile.in index 0844307249e..3abed0a5705 100644 --- a/dlls/mshtml/Makefile.in +++ b/dlls/mshtml/Makefile.in @@ -57,6 +57,7 @@ C_SRCS = \ secmgr.c \ selection.c \ service.c \ + svg.c \ task.c \ txtrange.c \ view.c \ diff --git a/dlls/mshtml/htmlelem.c b/dlls/mshtml/htmlelem.c index a46938016a6..aa1fc5bc202 100644 --- a/dlls/mshtml/htmlelem.c +++ b/dlls/mshtml/htmlelem.c @@ -5891,16 +5891,24 @@ HRESULT HTMLElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, BOOL use_g tag = get_tag_desc(tag_name); if(tag) { hres = tag->constructor(doc, nselem, &elem); - }else if(use_generic) { - hres = HTMLGenericElement_Create(doc, nselem, &elem); }else { - elem = heap_alloc_zero(sizeof(HTMLElement)); - if(elem) { - elem->node.vtbl = &HTMLElementImplVtbl; - HTMLElement_Init(elem, doc, nselem, &HTMLElement_dispex); - hres = S_OK; + nsIDOMSVGElement *svg_element; + + nsres = nsIDOMElement_QueryInterface(nselem, &IID_nsIDOMSVGElement, (void**)&svg_element); + if(NS_SUCCEEDED(nsres)) { + hres = create_svg_element(doc, svg_element, tag_name, &elem); + nsIDOMSVGElement_Release(svg_element); + }else if(use_generic) { + hres = HTMLGenericElement_Create(doc, nselem, &elem); }else { - hres = E_OUTOFMEMORY; + elem = heap_alloc_zero(sizeof(HTMLElement)); + if(elem) { + elem->node.vtbl = &HTMLElementImplVtbl; + HTMLElement_Init(elem, doc, nselem, &HTMLElement_dispex); + hres = S_OK; + }else { + hres = E_OUTOFMEMORY; + } } } diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index 26037f0fe71..f8d08835f2a 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -246,7 +246,8 @@ typedef struct EventTarget EventTarget; XIID(IHTMLXMLHttpRequest) \ XIID(IHTMLXMLHttpRequestFactory) \ XIID(IOmHistory) \ - XIID(IOmNavigator) + XIID(IOmNavigator) \ + XIID(ISVGElement) typedef enum { #define XIID(iface) iface ## _tid, @@ -1071,6 +1072,8 @@ HRESULT HTMLTextAreaElement_Create(HTMLDocumentNode*,nsIDOMElement*,HTMLElement* HRESULT HTMLTitleElement_Create(HTMLDocumentNode*,nsIDOMElement*,HTMLElement**) DECLSPEC_HIDDEN; HRESULT HTMLGenericElement_Create(HTMLDocumentNode*,nsIDOMElement*,HTMLElement**) DECLSPEC_HIDDEN; +HRESULT create_svg_element(HTMLDocumentNode*,nsIDOMSVGElement*,const WCHAR*,HTMLElement**) DECLSPEC_HIDDEN; + void HTMLDOMNode_Init(HTMLDocumentNode*,HTMLDOMNode*,nsIDOMNode*,dispex_static_data_t*) DECLSPEC_HIDDEN; void HTMLElement_Init(HTMLElement*,HTMLDocumentNode*,nsIDOMElement*,dispex_static_data_t*) DECLSPEC_HIDDEN; diff --git a/dlls/mshtml/svg.c b/dlls/mshtml/svg.c new file mode 100644 index 00000000000..bada820f9de --- /dev/null +++ b/dlls/mshtml/svg.c @@ -0,0 +1,225 @@ +/* + * Copyright 2019 Jacek Caban for CodeWeavers + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + */ + +#include +#include +#include + +#define COBJMACROS + +#include "windef.h" +#include "winbase.h" +#include "winuser.h" +#include "winreg.h" +#include "ole2.h" +#include "mshtmdid.h" + +#include "wine/debug.h" + +#include "mshtml_private.h" + +WINE_DEFAULT_DEBUG_CHANNEL(mshtml); + +struct SVGElement { + HTMLElement element; + ISVGElement ISVGElement_iface; +}; + +static inline SVGElement *impl_from_ISVGElement(ISVGElement *iface) +{ + return CONTAINING_RECORD(iface, SVGElement, ISVGElement_iface); +} + +static HRESULT WINAPI SVGElement_QueryInterface(ISVGElement *iface, + REFIID riid, void **ppv) +{ + SVGElement *This = impl_from_ISVGElement(iface); + + return IHTMLDOMNode_QueryInterface(&This->element.node.IHTMLDOMNode_iface, riid, ppv); +} + +static ULONG WINAPI SVGElement_AddRef(ISVGElement *iface) +{ + SVGElement *This = impl_from_ISVGElement(iface); + + return IHTMLDOMNode_AddRef(&This->element.node.IHTMLDOMNode_iface); +} + +static ULONG WINAPI SVGElement_Release(ISVGElement *iface) +{ + SVGElement *This = impl_from_ISVGElement(iface); + + return IHTMLDOMNode_Release(&This->element.node.IHTMLDOMNode_iface); +} + +static HRESULT WINAPI SVGElement_GetTypeInfoCount(ISVGElement *iface, UINT *pctinfo) +{ + SVGElement *This = impl_from_ISVGElement(iface); + return IDispatchEx_GetTypeInfoCount(&This->element.node.event_target.dispex.IDispatchEx_iface, pctinfo); +} + +static HRESULT WINAPI SVGElement_GetTypeInfo(ISVGElement *iface, UINT iTInfo, + LCID lcid, ITypeInfo **ppTInfo) +{ + SVGElement *This = impl_from_ISVGElement(iface); + return IDispatchEx_GetTypeInfo(&This->element.node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, + ppTInfo); +} + +static HRESULT WINAPI SVGElement_GetIDsOfNames(ISVGElement *iface, REFIID riid, + LPOLESTR *rgszNames, UINT cNames, + LCID lcid, DISPID *rgDispId) +{ + SVGElement *This = impl_from_ISVGElement(iface); + return IDispatchEx_GetIDsOfNames(&This->element.node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, + cNames, lcid, rgDispId); +} + +static HRESULT WINAPI SVGElement_Invoke(ISVGElement *iface, DISPID dispIdMember, + REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, + VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr) +{ + SVGElement *This = impl_from_ISVGElement(iface); + return IDispatchEx_Invoke(&This->element.node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, + lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); +} + +static HRESULT WINAPI SVGElement_put_xmlbase(ISVGElement *iface, BSTR v) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%s)\n", This, debugstr_w(v)); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_get_xmlbase(ISVGElement *iface, BSTR *p) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_putref_ownerSVGElement(ISVGElement *iface, ISVGSVGElement *v) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_get_ownerSVGElement(ISVGElement *iface, ISVGSVGElement **p) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_putref_viewportElement(ISVGElement *iface, ISVGElement *v) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_get_viewportElement(ISVGElement *iface, ISVGElement **p) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_putref_focusable(ISVGElement *iface, ISVGAnimatedEnumeration *v) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, v); + return E_NOTIMPL; +} + +static HRESULT WINAPI SVGElement_get_focusable(ISVGElement *iface, ISVGAnimatedEnumeration **p) +{ + SVGElement *This = impl_from_ISVGElement(iface); + FIXME("(%p)->(%p)\n", This, p); + return E_NOTIMPL; +} + +static const ISVGElementVtbl SVGElementVtbl = { + SVGElement_QueryInterface, + SVGElement_AddRef, + SVGElement_Release, + SVGElement_GetTypeInfoCount, + SVGElement_GetTypeInfo, + SVGElement_GetIDsOfNames, + SVGElement_Invoke, + SVGElement_put_xmlbase, + SVGElement_get_xmlbase, + SVGElement_putref_ownerSVGElement, + SVGElement_get_ownerSVGElement, + SVGElement_putref_viewportElement, + SVGElement_get_viewportElement, + SVGElement_putref_focusable, + SVGElement_get_focusable +}; + +static inline SVGElement *SVGElement_from_HTMLDOMNode(HTMLDOMNode *iface) +{ + return CONTAINING_RECORD(iface, SVGElement, element.node); +} + +static HRESULT SVGElement_QI(HTMLDOMNode *iface, REFIID riid, void **ppv) +{ + SVGElement *This = SVGElement_from_HTMLDOMNode(iface); + + TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv); + + if(IsEqualGUID(&IID_ISVGElement, riid)) + *ppv = &This->ISVGElement_iface; + else + return HTMLElement_QI(&This->element.node, riid, ppv); + + IUnknown_AddRef((IUnknown*)*ppv); + return S_OK; +} + +static const NodeImplVtbl SVGElementImplVtbl = { + &CLSID_SVGElement, + SVGElement_QI, + HTMLElement_destructor, + HTMLElement_cpc, + HTMLElement_clone, + NULL, + HTMLElement_get_attr_col, +}; + +static void init_svg_element(SVGElement *svg_element, HTMLDocumentNode *doc, nsIDOMSVGElement *nselem) +{ + if(!svg_element->element.node.vtbl) + svg_element->element.node.vtbl = &SVGElementImplVtbl; + svg_element->ISVGElement_iface.lpVtbl = &SVGElementVtbl; + HTMLElement_Init(&svg_element->element, doc, (nsIDOMElement*)nselem, NULL); +} + +HRESULT create_svg_element(HTMLDocumentNode *doc, nsIDOMSVGElement *dom_element, const WCHAR *tag_name, HTMLElement **elem) +{ + SVGElement *svg_element; + + svg_element = heap_alloc_zero(sizeof(*svg_element)); + if(!svg_element) + return E_OUTOFMEMORY; + + init_svg_element(svg_element, doc, dom_element); + *elem = &svg_element->element; + return S_OK; +} diff --git a/dlls/mshtml/tests/dom.c b/dlls/mshtml/tests/dom.c index c3d11bee460..2a7f11fecaf 100644 --- a/dlls/mshtml/tests/dom.c +++ b/dlls/mshtml/tests/dom.c @@ -442,6 +442,18 @@ static const IID * const generic_iids[] = { NULL }; +static const IID * const svg_iids[] = { + ELEM_IFACES, + &IID_ISVGElement, + NULL +}; + +static const IID * const circle_iids[] = { + ELEM_IFACES, + &IID_ISVGElement, + NULL +}; + static const IID * const style_iids[] = { &IID_IUnknown, &IID_IDispatch, @@ -531,8 +543,8 @@ static const elem_type_info_t elem_type_infos[] = { {"LABEL", label_iids, &DIID_DispHTMLLabelElement, &CLSID_HTMLLabelElement}, {"BUTTON", button_iids, &DIID_DispHTMLButtonElement, &CLSID_HTMLButtonElement}, {"AREA", area_iids, &DIID_DispHTMLAreaElement, &CLSID_HTMLAreaElement}, - {"svg", elem_iids, NULL}, - {"circle", elem_iids, NULL} + {"svg", svg_iids, NULL}, + {"circle", circle_iids, NULL} }; static int strcmp_wa(LPCWSTR strw, const char *stra) diff --git a/include/mshtml.idl b/include/mshtml.idl index 92493a1bdd2..7cc9e93af2f 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -16201,6 +16201,22 @@ methods: WINE_IHTMLELEMENT_DISPINTERFACE_DECL; } +/***************************************************************************** + * SVGElement coclass + */ +[ + noncreatable, + uuid(30510564-98b5-11cf-bb82-00aa00bdce0b) +] +coclass SVGElement +{ + [default] dispinterface DispSVGElement; + [source, default] dispinterface HTMLElementEvents; + [source] dispinterface HTMLElementEvents2; + interface ISVGElement; + interface IHTMLElement; +} + /***************************************************************************** * ISVGLength interface */