mirror of
https://gitlab.winehq.org/wine/wine.git
synced 2025-08-28 18:23:54 +02:00
696 lines
23 KiB
C
696 lines
23 KiB
C
/*
|
|
* Copyright 2008 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 <stdarg.h>
|
|
|
|
#define COBJMACROS
|
|
|
|
#include "windef.h"
|
|
#include "winbase.h"
|
|
#include "winuser.h"
|
|
#include "ole2.h"
|
|
#include "mshtmdid.h"
|
|
|
|
#include "mshtml_private.h"
|
|
#include "htmlevent.h"
|
|
|
|
#include "wine/debug.h"
|
|
|
|
WINE_DEFAULT_DEBUG_CHANNEL(mshtml);
|
|
|
|
struct CharacterData {
|
|
IWineHTMLCharacterData IWineHTMLCharacterData_iface;
|
|
HTMLDOMNode *node;
|
|
nsIDOMCharacterData *nschardata;
|
|
};
|
|
|
|
struct HTMLDOMTextNode {
|
|
HTMLDOMNode node;
|
|
IHTMLDOMTextNode IHTMLDOMTextNode_iface;
|
|
IHTMLDOMTextNode2 IHTMLDOMTextNode2_iface;
|
|
struct CharacterData character_data;
|
|
|
|
nsIDOMText *nstext;
|
|
};
|
|
|
|
struct HTMLCommentElement {
|
|
HTMLElement element;
|
|
IHTMLCommentElement IHTMLCommentElement_iface;
|
|
IHTMLCommentElement2 IHTMLCommentElement2_iface;
|
|
struct CharacterData character_data;
|
|
};
|
|
|
|
static inline struct CharacterData *impl_from_IWineHTMLCharacterData(IWineHTMLCharacterData *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, struct CharacterData, IWineHTMLCharacterData_iface);
|
|
}
|
|
|
|
DISPEX_IDISPATCH_IMPL(CharacterData, IWineHTMLCharacterData,
|
|
impl_from_IWineHTMLCharacterData(iface)->node->event_target.dispex)
|
|
|
|
static HRESULT WINAPI CharacterData_put_data(IWineHTMLCharacterData *iface, BSTR v)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
nsAString nsstr;
|
|
nsresult nsres;
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_w(v));
|
|
|
|
if(!This->nschardata) {
|
|
FIXME("legacy doctype comment\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
nsAString_InitDepend(&nsstr, v);
|
|
nsres = nsIDOMCharacterData_SetData(This->nschardata, &nsstr);
|
|
nsAString_Finish(&nsstr);
|
|
return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_get_data(IWineHTMLCharacterData *iface, BSTR *p)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
const PRUnichar *str, *end;
|
|
nsAString nsstr;
|
|
nsresult nsres;
|
|
HRESULT hres;
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
if(!This->nschardata) {
|
|
nsAString_Init(&nsstr, NULL);
|
|
hres = nsnode_to_nsstring(This->node->nsnode, &nsstr);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
nsAString_GetData(&nsstr, &str);
|
|
end = str + wcslen(str);
|
|
if(*str == '<') {
|
|
end -= (end[-1] == '>');
|
|
str++;
|
|
str += (*str == '!');
|
|
}
|
|
|
|
if(!(*p = SysAllocStringLen(str, end - str)))
|
|
hres = E_OUTOFMEMORY;
|
|
nsAString_Finish(&nsstr);
|
|
return hres;
|
|
}
|
|
|
|
nsAString_Init(&nsstr, NULL);
|
|
nsres = nsIDOMCharacterData_GetData(This->nschardata, &nsstr);
|
|
return return_nsstr(nsres, &nsstr, p);
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_get_length(IWineHTMLCharacterData *iface, LONG *p)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
UINT32 length = 0;
|
|
nsresult nsres;
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
if(!This->nschardata) {
|
|
FIXME("legacy doctype comment\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
nsres = nsIDOMCharacterData_GetLength(This->nschardata, &length);
|
|
if(NS_FAILED(nsres))
|
|
return map_nsresult(nsres);
|
|
|
|
*p = length;
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_substringData(IWineHTMLCharacterData *iface, LONG offset, LONG count, BSTR *string)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
|
|
FIXME("(%p)->(%ld %ld %p)\n", This, offset, count, string);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_appendData(IWineHTMLCharacterData *iface, BSTR string)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
nsAString nsstr;
|
|
nsresult nsres;
|
|
|
|
TRACE("(%p)->(%s)\n", This, debugstr_w(string));
|
|
|
|
if(!This->nschardata) {
|
|
FIXME("legacy doctype comment\n");
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
nsAString_InitDepend(&nsstr, string);
|
|
nsres = nsIDOMCharacterData_AppendData(This->nschardata, &nsstr);
|
|
nsAString_Finish(&nsstr);
|
|
if(NS_FAILED(nsres))
|
|
return map_nsresult(nsres);
|
|
|
|
return S_OK;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_insertData(IWineHTMLCharacterData *iface, LONG offset, BSTR string)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
|
|
FIXME("(%p)->(%ld %s)\n", This, offset, debugstr_w(string));
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_deleteData(IWineHTMLCharacterData *iface, LONG offset, LONG count)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
|
|
FIXME("(%p)->(%ld %ld)\n", This, offset, count);
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI CharacterData_replaceData(IWineHTMLCharacterData *iface, LONG offset, LONG count, BSTR string)
|
|
{
|
|
struct CharacterData *This = impl_from_IWineHTMLCharacterData(iface);
|
|
|
|
FIXME("(%p)->(%ld %ld %s)\n", This, offset, count, debugstr_w(string));
|
|
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const IWineHTMLCharacterDataVtbl CharacterDataVtbl = {
|
|
CharacterData_QueryInterface,
|
|
CharacterData_AddRef,
|
|
CharacterData_Release,
|
|
CharacterData_GetTypeInfoCount,
|
|
CharacterData_GetTypeInfo,
|
|
CharacterData_GetIDsOfNames,
|
|
CharacterData_Invoke,
|
|
CharacterData_put_data,
|
|
CharacterData_get_data,
|
|
CharacterData_get_length,
|
|
CharacterData_substringData,
|
|
CharacterData_appendData,
|
|
CharacterData_insertData,
|
|
CharacterData_deleteData,
|
|
CharacterData_replaceData
|
|
};
|
|
|
|
static void CharacterData_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
|
|
{
|
|
dispex_info_add_interface(info, IWineHTMLCharacterData_tid, NULL);
|
|
}
|
|
|
|
dispex_static_data_t CharacterData_dispex = {
|
|
.id = OBJID_CharacterData,
|
|
.prototype_id = OBJID_Node,
|
|
.init_info = CharacterData_init_dispex_info,
|
|
};
|
|
|
|
static void init_char_data(HTMLDOMNode *node, nsIDOMCharacterData *nschardata, struct CharacterData *ret)
|
|
{
|
|
/* nschardata shares reference with nsnode */
|
|
ret->IWineHTMLCharacterData_iface.lpVtbl = &CharacterDataVtbl;
|
|
ret->nschardata = nschardata;
|
|
ret->node = node;
|
|
}
|
|
|
|
static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode_iface);
|
|
}
|
|
|
|
DISPEX_IDISPATCH_IMPL(HTMLDOMTextNode, IHTMLDOMTextNode,
|
|
impl_from_IHTMLDOMTextNode(iface)->node.event_target.dispex)
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode_put_data(IHTMLDOMTextNode *iface, BSTR v)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
|
|
return CharacterData_put_data(&This->character_data.IWineHTMLCharacterData_iface, v);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode_get_data(IHTMLDOMTextNode *iface, BSTR *p)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
|
|
return CharacterData_get_data(&This->character_data.IWineHTMLCharacterData_iface, p);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode_toString(IHTMLDOMTextNode *iface, BSTR *String)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
|
|
|
|
TRACE("(%p)->(%p)\n", This, String);
|
|
|
|
if(!String)
|
|
return E_INVALIDARG;
|
|
|
|
return IHTMLDOMTextNode_get_data(&This->IHTMLDOMTextNode_iface, String);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode_get_length(IHTMLDOMTextNode *iface, LONG *p)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
|
|
return CharacterData_get_length(&This->character_data.IWineHTMLCharacterData_iface, p);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode_splitText(IHTMLDOMTextNode *iface, LONG offset, IHTMLDOMNode **pRetNode)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
|
|
HTMLDOMNode *node;
|
|
nsIDOMText *text;
|
|
nsresult nsres;
|
|
HRESULT hres;
|
|
|
|
TRACE("(%p)->(%ld %p)\n", This, offset, pRetNode);
|
|
|
|
nsres = nsIDOMText_SplitText(This->nstext, offset, &text);
|
|
if(NS_FAILED(nsres)) {
|
|
ERR("SplitText failed: %lx08x\n", nsres);
|
|
return E_FAIL;
|
|
}
|
|
|
|
if(!text) {
|
|
*pRetNode = NULL;
|
|
return S_OK;
|
|
}
|
|
|
|
hres = get_node((nsIDOMNode*)text, TRUE, &node);
|
|
nsIDOMText_Release(text);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
*pRetNode = &node->IHTMLDOMNode_iface;
|
|
return S_OK;
|
|
}
|
|
|
|
static const IHTMLDOMTextNodeVtbl HTMLDOMTextNodeVtbl = {
|
|
HTMLDOMTextNode_QueryInterface,
|
|
HTMLDOMTextNode_AddRef,
|
|
HTMLDOMTextNode_Release,
|
|
HTMLDOMTextNode_GetTypeInfoCount,
|
|
HTMLDOMTextNode_GetTypeInfo,
|
|
HTMLDOMTextNode_GetIDsOfNames,
|
|
HTMLDOMTextNode_Invoke,
|
|
HTMLDOMTextNode_put_data,
|
|
HTMLDOMTextNode_get_data,
|
|
HTMLDOMTextNode_toString,
|
|
HTMLDOMTextNode_get_length,
|
|
HTMLDOMTextNode_splitText
|
|
};
|
|
|
|
static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode2_iface);
|
|
}
|
|
|
|
DISPEX_IDISPATCH_IMPL(HTMLDOMTextNode2, IHTMLDOMTextNode2,
|
|
impl_from_IHTMLDOMTextNode2(iface)->node.event_target.dispex)
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode2_substringData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR *string)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
|
|
return CharacterData_substringData(&This->character_data.IWineHTMLCharacterData_iface, offset, count, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode2_appendData(IHTMLDOMTextNode2 *iface, BSTR string)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
|
|
return CharacterData_appendData(&This->character_data.IWineHTMLCharacterData_iface, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode2_insertData(IHTMLDOMTextNode2 *iface, LONG offset, BSTR string)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
|
|
return CharacterData_insertData(&This->character_data.IWineHTMLCharacterData_iface, offset, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode2_deleteData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
|
|
return CharacterData_deleteData(&This->character_data.IWineHTMLCharacterData_iface, offset, count);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLDOMTextNode2_replaceData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR string)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
|
|
return CharacterData_replaceData(&This->character_data.IWineHTMLCharacterData_iface, offset, count, string);
|
|
}
|
|
|
|
static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = {
|
|
HTMLDOMTextNode2_QueryInterface,
|
|
HTMLDOMTextNode2_AddRef,
|
|
HTMLDOMTextNode2_Release,
|
|
HTMLDOMTextNode2_GetTypeInfoCount,
|
|
HTMLDOMTextNode2_GetTypeInfo,
|
|
HTMLDOMTextNode2_GetIDsOfNames,
|
|
HTMLDOMTextNode2_Invoke,
|
|
HTMLDOMTextNode2_substringData,
|
|
HTMLDOMTextNode2_appendData,
|
|
HTMLDOMTextNode2_insertData,
|
|
HTMLDOMTextNode2_deleteData,
|
|
HTMLDOMTextNode2_replaceData
|
|
};
|
|
|
|
static inline HTMLDOMTextNode *impl_from_DispatchEx(DispatchEx *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLDOMTextNode, node.event_target.dispex);
|
|
}
|
|
|
|
static void *HTMLDOMTextNode_query_interface(DispatchEx *dispex, REFIID riid)
|
|
{
|
|
HTMLDOMTextNode *This = impl_from_DispatchEx(dispex);
|
|
|
|
if(IsEqualGUID(&IID_IHTMLDOMTextNode, riid))
|
|
return &This->IHTMLDOMTextNode_iface;
|
|
if(IsEqualGUID(&IID_IHTMLDOMTextNode2, riid))
|
|
return &This->IHTMLDOMTextNode2_iface;
|
|
if(IsEqualGUID(&IID_IWineHTMLCharacterData, riid))
|
|
return &This->character_data.IWineHTMLCharacterData_iface;
|
|
|
|
return HTMLDOMNode_query_interface(&This->node.event_target.dispex, riid);
|
|
}
|
|
|
|
static const cpc_entry_t HTMLDOMTextNode_cpc[] = {{NULL}};
|
|
|
|
static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
|
|
.cpc_entries = HTMLDOMTextNode_cpc,
|
|
};
|
|
|
|
static const dispex_static_data_vtbl_t Text_dispex_vtbl = {
|
|
.query_interface = HTMLDOMTextNode_query_interface,
|
|
.destructor = HTMLDOMNode_destructor,
|
|
.traverse = HTMLDOMNode_traverse,
|
|
.unlink = HTMLDOMNode_unlink
|
|
};
|
|
|
|
static void Text_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
|
|
{
|
|
static const dispex_hook_t textnode_ie9_hooks[] = {
|
|
{DISPID_IHTMLDOMTEXTNODE_TOSTRING},
|
|
{DISPID_UNKNOWN}
|
|
};
|
|
HTMLDOMNode_init_dispex_info(info, mode);
|
|
if(mode >= COMPAT_MODE_IE9)
|
|
CharacterData_init_dispex_info(info, mode);
|
|
else
|
|
dispex_info_add_interface(info, IHTMLDOMTextNode2_tid, NULL);
|
|
dispex_info_add_interface(info, IHTMLDOMTextNode_tid, mode >= COMPAT_MODE_IE9 ? textnode_ie9_hooks : NULL);
|
|
}
|
|
|
|
static const tid_t Text_iface_tids[] = {
|
|
IHTMLDOMNode_tid,
|
|
0
|
|
};
|
|
dispex_static_data_t Text_dispex = {
|
|
.id = OBJID_Text,
|
|
.prototype_id = OBJID_CharacterData,
|
|
.vtbl = &Text_dispex_vtbl,
|
|
.disp_tid = DispHTMLDOMTextNode_tid,
|
|
.iface_tids = Text_iface_tids,
|
|
.init_info = Text_init_dispex_info,
|
|
};
|
|
|
|
HRESULT HTMLDOMTextNode_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNode **node)
|
|
{
|
|
HTMLDOMTextNode *ret;
|
|
nsresult nsres;
|
|
|
|
ret = calloc(1, sizeof(*ret));
|
|
if(!ret)
|
|
return E_OUTOFMEMORY;
|
|
|
|
ret->node.vtbl = &HTMLDOMTextNodeImplVtbl;
|
|
ret->IHTMLDOMTextNode_iface.lpVtbl = &HTMLDOMTextNodeVtbl;
|
|
ret->IHTMLDOMTextNode2_iface.lpVtbl = &HTMLDOMTextNode2Vtbl;
|
|
|
|
HTMLDOMNode_Init(doc, &ret->node, nsnode, &Text_dispex);
|
|
|
|
nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMText, (void**)&ret->nstext);
|
|
assert(nsres == NS_OK && (nsIDOMNode*)ret->nstext == ret->node.nsnode);
|
|
|
|
/* Share reference with nsnode */
|
|
nsIDOMNode_Release(ret->node.nsnode);
|
|
|
|
init_char_data(&ret->node, (nsIDOMCharacterData*)ret->nstext, &ret->character_data);
|
|
|
|
*node = &ret->node;
|
|
return S_OK;
|
|
}
|
|
|
|
static inline HTMLCommentElement *comment_from_IHTMLCommentElement(IHTMLCommentElement *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLCommentElement, IHTMLCommentElement_iface);
|
|
}
|
|
|
|
DISPEX_IDISPATCH_IMPL(HTMLCommentElement, IHTMLCommentElement,
|
|
comment_from_IHTMLCommentElement(iface)->element.node.event_target.dispex)
|
|
|
|
static HRESULT WINAPI HTMLCommentElement_put_text(IHTMLCommentElement *iface, BSTR v)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement(iface);
|
|
FIXME("(%p)->(%s)\n", This, debugstr_w(v));
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement_get_text(IHTMLCommentElement *iface, BSTR *p)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement(iface);
|
|
|
|
TRACE("(%p)->(%p)\n", This, p);
|
|
|
|
return IHTMLElement_get_outerHTML(&This->element.IHTMLElement_iface, p);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement_put_atomic(IHTMLCommentElement *iface, LONG v)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement(iface);
|
|
FIXME("(%p)->(%ld)\n", This, v);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement_get_atomic(IHTMLCommentElement *iface, LONG *p)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement(iface);
|
|
FIXME("(%p)->(%p)\n", This, p);
|
|
return E_NOTIMPL;
|
|
}
|
|
|
|
static const IHTMLCommentElementVtbl HTMLCommentElementVtbl = {
|
|
HTMLCommentElement_QueryInterface,
|
|
HTMLCommentElement_AddRef,
|
|
HTMLCommentElement_Release,
|
|
HTMLCommentElement_GetTypeInfoCount,
|
|
HTMLCommentElement_GetTypeInfo,
|
|
HTMLCommentElement_GetIDsOfNames,
|
|
HTMLCommentElement_Invoke,
|
|
HTMLCommentElement_put_text,
|
|
HTMLCommentElement_get_text,
|
|
HTMLCommentElement_put_atomic,
|
|
HTMLCommentElement_get_atomic
|
|
};
|
|
|
|
static inline HTMLCommentElement *comment_from_IHTMLCommentElement2(IHTMLCommentElement2 *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLCommentElement, IHTMLCommentElement2_iface);
|
|
}
|
|
|
|
DISPEX_IDISPATCH_IMPL(HTMLCommentElement2, IHTMLCommentElement2,
|
|
comment_from_IHTMLCommentElement2(iface)->element.node.event_target.dispex)
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_put_data(IHTMLCommentElement2 *iface, BSTR v)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_put_data(&This->character_data.IWineHTMLCharacterData_iface, v);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_get_data(IHTMLCommentElement2 *iface, BSTR *p)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_get_data(&This->character_data.IWineHTMLCharacterData_iface, p);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_get_length(IHTMLCommentElement2 *iface, LONG *p)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_get_length(&This->character_data.IWineHTMLCharacterData_iface, p);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_substringData(IHTMLCommentElement2 *iface, LONG offset, LONG count, BSTR *string)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_substringData(&This->character_data.IWineHTMLCharacterData_iface, offset, count, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_appendData(IHTMLCommentElement2 *iface, BSTR string)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_appendData(&This->character_data.IWineHTMLCharacterData_iface, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_insertData(IHTMLCommentElement2 *iface, LONG offset, BSTR string)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_insertData(&This->character_data.IWineHTMLCharacterData_iface, offset, string);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_deleteData(IHTMLCommentElement2 *iface, LONG offset, LONG count)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_deleteData(&This->character_data.IWineHTMLCharacterData_iface, offset, count);
|
|
}
|
|
|
|
static HRESULT WINAPI HTMLCommentElement2_replaceData(IHTMLCommentElement2 *iface, LONG offset, LONG count, BSTR string)
|
|
{
|
|
HTMLCommentElement *This = comment_from_IHTMLCommentElement2(iface);
|
|
return CharacterData_replaceData(&This->character_data.IWineHTMLCharacterData_iface, offset, count, string);
|
|
}
|
|
|
|
static const IHTMLCommentElement2Vtbl HTMLCommentElement2Vtbl = {
|
|
HTMLCommentElement2_QueryInterface,
|
|
HTMLCommentElement2_AddRef,
|
|
HTMLCommentElement2_Release,
|
|
HTMLCommentElement2_GetTypeInfoCount,
|
|
HTMLCommentElement2_GetTypeInfo,
|
|
HTMLCommentElement2_GetIDsOfNames,
|
|
HTMLCommentElement2_Invoke,
|
|
HTMLCommentElement2_put_data,
|
|
HTMLCommentElement2_get_data,
|
|
HTMLCommentElement2_get_length,
|
|
HTMLCommentElement2_substringData,
|
|
HTMLCommentElement2_appendData,
|
|
HTMLCommentElement2_insertData,
|
|
HTMLCommentElement2_deleteData,
|
|
HTMLCommentElement2_replaceData
|
|
};
|
|
|
|
static inline HTMLCommentElement *comment_from_HTMLDOMNode(HTMLDOMNode *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLCommentElement, element.node);
|
|
}
|
|
|
|
static HRESULT HTMLCommentElement_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
|
|
{
|
|
HTMLCommentElement *This = comment_from_HTMLDOMNode(iface);
|
|
HTMLElement *new_elem;
|
|
HRESULT hres;
|
|
|
|
hres = HTMLCommentElement_Create(This->element.node.doc, nsnode, &new_elem);
|
|
if(FAILED(hres))
|
|
return hres;
|
|
|
|
*ret = &new_elem->node;
|
|
return S_OK;
|
|
}
|
|
|
|
static inline HTMLCommentElement *comment_from_DispatchEx(DispatchEx *iface)
|
|
{
|
|
return CONTAINING_RECORD(iface, HTMLCommentElement, element.node.event_target.dispex);
|
|
}
|
|
|
|
static void *HTMLCommentElement_query_interface(DispatchEx *dispex, REFIID riid)
|
|
{
|
|
HTMLCommentElement *This = comment_from_DispatchEx(dispex);
|
|
|
|
if(IsEqualGUID(&IID_IHTMLCommentElement, riid))
|
|
return &This->IHTMLCommentElement_iface;
|
|
if(IsEqualGUID(&IID_IHTMLCommentElement2, riid))
|
|
return &This->IHTMLCommentElement2_iface;
|
|
if(IsEqualGUID(&IID_IWineHTMLCharacterData, riid))
|
|
return &This->character_data.IWineHTMLCharacterData_iface;
|
|
|
|
return HTMLElement_query_interface(&This->element.node.event_target.dispex, riid);
|
|
}
|
|
|
|
static const NodeImplVtbl HTMLCommentElementImplVtbl = {
|
|
.clsid = &CLSID_HTMLCommentElement,
|
|
.cpc_entries = HTMLElement_cpc,
|
|
.clone = HTMLCommentElement_clone,
|
|
.get_attr_col = HTMLElement_get_attr_col
|
|
};
|
|
|
|
static const event_target_vtbl_t HTMLCommentElement_event_target_vtbl = {
|
|
{
|
|
HTMLELEMENT_DISPEX_VTBL_ENTRIES,
|
|
.query_interface= HTMLCommentElement_query_interface,
|
|
.destructor = HTMLElement_destructor,
|
|
.traverse = HTMLElement_traverse,
|
|
.unlink = HTMLElement_unlink
|
|
},
|
|
HTMLELEMENT_EVENT_TARGET_VTBL_ENTRIES,
|
|
.handle_event = HTMLElement_handle_event
|
|
};
|
|
|
|
static void Comment_init_dispex_info(dispex_data_t *info, compat_mode_t mode)
|
|
{
|
|
static const dispex_hook_t ie9_hooks[] = {
|
|
{DISPID_IHTMLCOMMENTELEMENT_ATOMIC},
|
|
{DISPID_UNKNOWN}
|
|
};
|
|
|
|
if(mode >= COMPAT_MODE_IE9)
|
|
HTMLDOMNode_init_dispex_info(info, mode);
|
|
else
|
|
HTMLElement_init_dispex_info(info, mode);
|
|
CharacterData_init_dispex_info(info, mode);
|
|
|
|
dispex_info_add_interface(info, IHTMLCommentElement_tid, mode >= COMPAT_MODE_IE9 ? ie9_hooks : NULL);
|
|
}
|
|
|
|
dispex_static_data_t Comment_dispex = {
|
|
.id = OBJID_Comment,
|
|
.prototype_id = OBJID_CharacterData,
|
|
.vtbl = &HTMLCommentElement_event_target_vtbl.dispex_vtbl,
|
|
.disp_tid = DispHTMLCommentElement_tid,
|
|
.init_info = Comment_init_dispex_info,
|
|
};
|
|
|
|
HRESULT HTMLCommentElement_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLElement **elem)
|
|
{
|
|
nsIDOMCharacterData *nschardata;
|
|
HTMLCommentElement *ret;
|
|
nsresult nsres;
|
|
|
|
ret = calloc(1, sizeof(*ret));
|
|
if(!ret)
|
|
return E_OUTOFMEMORY;
|
|
|
|
ret->element.node.vtbl = &HTMLCommentElementImplVtbl;
|
|
ret->IHTMLCommentElement_iface.lpVtbl = &HTMLCommentElementVtbl;
|
|
ret->IHTMLCommentElement2_iface.lpVtbl = &HTMLCommentElement2Vtbl;
|
|
|
|
HTMLElement_Init(&ret->element, doc, NULL, &Comment_dispex);
|
|
HTMLDOMNode_Init(doc, &ret->element.node, nsnode, &Comment_dispex);
|
|
|
|
nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMCharacterData, (void**)&nschardata);
|
|
if(nsres != NS_OK)
|
|
nschardata = NULL;
|
|
else {
|
|
assert((nsIDOMNode*)nschardata == nsnode);
|
|
|
|
/* Share reference with nsnode */
|
|
nsIDOMCharacterData_Release(nschardata);
|
|
}
|
|
init_char_data(&ret->element.node, nschardata, &ret->character_data);
|
|
|
|
*elem = &ret->element;
|
|
return S_OK;
|
|
}
|