From: Phiality <bakreski03@gmail.com> --- dlls/mshtml/mshtml_private.h | 5 +- dlls/mshtml/omnavigator.c | 150 +++++++++++++++++++++++++++++++++++ include/mshtmdid.h | 4 + include/mshtml.idl | 40 ++++++++++ 4 files changed, 198 insertions(+), 1 deletion(-) diff --git a/dlls/mshtml/mshtml_private.h b/dlls/mshtml/mshtml_private.h index ce872249e62..536d9ccbff7 100644 --- a/dlls/mshtml/mshtml_private.h +++ b/dlls/mshtml/mshtml_private.h @@ -160,6 +160,7 @@ struct constructor; XDIID(DispHTMLWindow2) \ XDIID(DispHTMLXMLHttpRequest) \ XDIID(DispXDomainRequest) \ + XDIID(DispXMLSerializer) \ XDIID(DispSVGCircleElement) \ XDIID(DispSVGSVGElement) \ XDIID(DispSVGTSpanElement) \ @@ -298,6 +299,7 @@ struct constructor; XIID(IHTMLXMLHttpRequestFactory) \ XIID(IHTMLXDomainRequest) \ XIID(IHTMLXDomainRequestFactory) \ + XIID(IXMLSerializer) \ XIID(IOmHistory) \ XIID(IOmNavigator) \ XIID(ISVGCircleElement) \ @@ -530,7 +532,8 @@ typedef struct { X(Window) \ X(XDomainRequest) \ X(XMLDocument) \ - X(XMLHttpRequest) + X(XMLHttpRequest) \ + X(XMLSerializer) typedef enum { OBJID_NONE, diff --git a/dlls/mshtml/omnavigator.c b/dlls/mshtml/omnavigator.c index fc4d2f5b408..6d26d13636d 100644 --- a/dlls/mshtml/omnavigator.c +++ b/dlls/mshtml/omnavigator.c @@ -451,6 +451,156 @@ static HRESULT init_dom_parser_ctor(struct constructor *constr) return S_OK; } +struct xml_serializer { + DispatchEx dispex; + IXMLSerializer IXMLSerializer_iface; +}; + +static inline struct xml_serializer *impl_from_IXMLSerializer(IXMLSerializer *iface) +{ + return CONTAINING_RECORD(iface, struct xml_serializer, IXMLSerializer_iface); +} + +DISPEX_IDISPATCH_IMPL(xml_serializer, IXMLSerializer, impl_from_IXMLSerializer(iface)->dispex) + +static HRESULT WINAPI xml_serializer_serializeToString(IXMLSerializer *iface, IHTMLDOMNode *node, BSTR *pString) +{ + struct xml_serializer *This = impl_from_IXMLSerializer(iface); + HTMLDOMNode *dom_node; + nsAString nsstr; + HRESULT hres; + + TRACE("(%p)->(%p %p)\n", This, node, pString); + + if(!node || !pString) + return E_INVALIDARG; + + *pString = NULL; + + dom_node = unsafe_impl_from_IHTMLDOMNode(node); + if(!dom_node) { + WARN("not an HTMLDOMNode\n"); + return E_INVALIDARG; + } + + nsAString_Init(&nsstr, NULL); + hres = nsnode_to_nsstring(dom_node->nsnode, &nsstr); + if(SUCCEEDED(hres)) { + const WCHAR *str; + nsAString_GetData(&nsstr, &str); + *pString = SysAllocString(str); + if(!*pString) + hres = E_OUTOFMEMORY; + } + nsAString_Finish(&nsstr); + + return hres; +} + +static const IXMLSerializerVtbl xml_serializer_vtbl = { + xml_serializer_QueryInterface, + xml_serializer_AddRef, + xml_serializer_Release, + xml_serializer_GetTypeInfoCount, + xml_serializer_GetTypeInfo, + xml_serializer_GetIDsOfNames, + xml_serializer_Invoke, + xml_serializer_serializeToString +}; + +static inline struct xml_serializer *xml_serializer_from_DispatchEx(DispatchEx *iface) +{ + return CONTAINING_RECORD(iface, struct xml_serializer, dispex); +} + +static void *xml_serializer_query_interface(DispatchEx *dispex, REFIID riid) +{ + struct xml_serializer *This = xml_serializer_from_DispatchEx(dispex); + + if(IsEqualGUID(&IID_IXMLSerializer, riid)) + return &This->IXMLSerializer_iface; + + return NULL; +} + +static void xml_serializer_destructor(DispatchEx *dispex) +{ + struct xml_serializer *This = xml_serializer_from_DispatchEx(dispex); + free(This); +} + +static HRESULT init_xml_serializer_ctor(struct constructor*); + +static const dispex_static_data_vtbl_t xml_serializer_dispex_vtbl = { + .query_interface = xml_serializer_query_interface, + .destructor = xml_serializer_destructor, +}; + +static const tid_t xml_serializer_iface_tids[] = { + IXMLSerializer_tid, + 0 +}; + +dispex_static_data_t XMLSerializer_dispex = { + .id = OBJID_XMLSerializer, + .init_constructor = &init_xml_serializer_ctor, + .vtbl = &xml_serializer_dispex_vtbl, + .disp_tid = DispXMLSerializer_tid, + .iface_tids = xml_serializer_iface_tids, +}; + +static HRESULT xml_serializer_ctor_value(DispatchEx *dispex, LCID lcid, WORD flags, DISPPARAMS *params, + VARIANT *res, EXCEPINFO *ei, IServiceProvider *caller) +{ + struct constructor *This = constructor_from_DispatchEx(dispex); + struct xml_serializer *ret; + + TRACE("\n"); + + switch(flags) { + case DISPATCH_METHOD|DISPATCH_PROPERTYGET: + if(!res) + return E_INVALIDARG; + /* fall through */ + case DISPATCH_METHOD: + case DISPATCH_CONSTRUCT: + break; + default: + FIXME("flags %x not supported\n", flags); + return E_NOTIMPL; + } + + if(!(ret = calloc(1, sizeof(*ret)))) + return E_OUTOFMEMORY; + + ret->IXMLSerializer_iface.lpVtbl = &xml_serializer_vtbl; + init_dispatch(&ret->dispex, &XMLSerializer_dispex, This->window, dispex_compat_mode(&This->dispex)); + + V_VT(res) = VT_DISPATCH; + V_DISPATCH(res) = (IDispatch*)&ret->IXMLSerializer_iface; + return S_OK; +} + +static const dispex_static_data_vtbl_t xml_serializer_ctor_dispex_vtbl = { + .destructor = constructor_destructor, + .traverse = constructor_traverse, + .unlink = constructor_unlink, + .value = xml_serializer_ctor_value, +}; + +static dispex_static_data_t xml_serializer_ctor_dispex = { + .name = "XMLSerializer", + .constructor_id = OBJID_XMLSerializer, + .vtbl = &xml_serializer_ctor_dispex_vtbl, +}; + +static HRESULT init_xml_serializer_ctor(struct constructor *constr) +{ + init_dispatch(&constr->dispex, &xml_serializer_ctor_dispex, constr->window, + dispex_compat_mode(&constr->window->event_target.dispex)); + return S_OK; +} + typedef struct { DispatchEx dispex; IHTMLScreen IHTMLScreen_iface; diff --git a/include/mshtmdid.h b/include/mshtmdid.h index 45b22f6349f..204e5e403f6 100644 --- a/include/mshtmdid.h +++ b/include/mshtmdid.h @@ -107,6 +107,7 @@ #define DISPID_XMLHTTPREQUEST DISPID_NORMAL_FIRST #define DISPID_XDOMAINREQUEST DISPID_NORMAL_FIRST #define DISPID_DOMPARSER DISPID_NORMAL_FIRST +#define DISPID_XMLSERIALIZER DISPID_NORMAL_FIRST #define DISPID_DOCUMENTCOMPATIBLEINFO_COLLECTION DISPID_NORMAL_FIRST #define DISPID_DOCUMENTCOMPATIBLEINFO DISPID_NORMAL_FIRST #define DISPID_XDOMAINREQUEST DISPID_NORMAL_FIRST @@ -4676,6 +4677,9 @@ /* IDOMParser */ #define DISPID_IDOMPARSER_PARSEFROMSTRING DISPID_DOMPARSER +/* IXMLSerializer */ +#define DISPID_IXMLSERIALIZER_SERIALIZETOSTRING DISPID_XMLSERIALIZER + /* IEventTarget */ #define DISPID_IEVENTTARGET_ADDEVENTLISTENER DISPID_HTMLOBJECT+10 #define DISPID_IEVENTTARGET_REMOVEEVENTLISTENER DISPID_HTMLOBJECT+11 diff --git a/include/mshtml.idl b/include/mshtml.idl index 1d2896f88b8..11f3fa5c59d 100644 --- a/include/mshtml.idl +++ b/include/mshtml.idl @@ -30286,6 +30286,46 @@ coclass DOMParser interface IDOMParser; } +/***************************************************************************** + * IXMLSerializer interface + */ +[ + object, + oleautomation, + dual, + uuid(30510783-98b5-11cf-bb82-00aa00bdce0b) +] +interface IXMLSerializer : IDispatch +{ + [id(DISPID_IXMLSERIALIZER_SERIALIZETOSTRING)] + HRESULT serializeToString([in] IHTMLDOMNode *node, [retval, out] BSTR *pString); +} + +/***************************************************************************** + * DispXMLSerializer dispinterface + */ +[ + hidden, + uuid(305900af-98b5-11cf-bb82-00aa00bdce0b) +] +dispinterface DispXMLSerializer +{ +properties: +methods: + [id(DISPID_IXMLSERIALIZER_SERIALIZETOSTRING)] + BSTR serializeToString([in] IHTMLDOMNode *node); +} + +[ + noncreatable, + uuid(30510784-98b5-11cf-bb82-00aa00bdce0b) +] +coclass XMLSerializer +{ + [default] dispinterface DispXMLSerializer; + interface IXMLSerializer; +} + /***************************************************************************** * IXMLGenericParse interface */ -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10025