Reactos
1/*
2 * Copyright 2008 Jacek Caban for CodeWeavers
3 *
4 * This library is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU Lesser General Public
6 * License as published by the Free Software Foundation; either
7 * version 2.1 of the License, or (at your option) any later version.
8 *
9 * This library is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * Lesser General Public License for more details.
13 *
14 * You should have received a copy of the GNU Lesser General Public
15 * License along with this library; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
17 */
18
19#include "mshtml_private.h"
20
21struct HTMLDOMTextNode {
22 HTMLDOMNode node;
23 IHTMLDOMTextNode IHTMLDOMTextNode_iface;
24 IHTMLDOMTextNode2 IHTMLDOMTextNode2_iface;
25
26 nsIDOMText *nstext;
27};
28
29static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode *iface)
30{
31 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode_iface);
32}
33
34static HRESULT WINAPI HTMLDOMTextNode_QueryInterface(IHTMLDOMTextNode *iface,
35 REFIID riid, void **ppv)
36{
37 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
38
39 return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
40}
41
42static ULONG WINAPI HTMLDOMTextNode_AddRef(IHTMLDOMTextNode *iface)
43{
44 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
45
46 return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
47}
48
49static ULONG WINAPI HTMLDOMTextNode_Release(IHTMLDOMTextNode *iface)
50{
51 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
52
53 return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
54}
55
56static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfoCount(IHTMLDOMTextNode *iface, UINT *pctinfo)
57{
58 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
59 return IDispatchEx_GetTypeInfoCount(&This->node.event_target.dispex.IDispatchEx_iface, pctinfo);
60}
61
62static HRESULT WINAPI HTMLDOMTextNode_GetTypeInfo(IHTMLDOMTextNode *iface, UINT iTInfo,
63 LCID lcid, ITypeInfo **ppTInfo)
64{
65 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
66 return IDispatchEx_GetTypeInfo(&This->node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
67}
68
69static HRESULT WINAPI HTMLDOMTextNode_GetIDsOfNames(IHTMLDOMTextNode *iface, REFIID riid,
70 LPOLESTR *rgszNames, UINT cNames,
71 LCID lcid, DISPID *rgDispId)
72{
73 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
74 return IDispatchEx_GetIDsOfNames(&This->node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
75 lcid, rgDispId);
76}
77
78static HRESULT WINAPI HTMLDOMTextNode_Invoke(IHTMLDOMTextNode *iface, DISPID dispIdMember,
79 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams,
80 VARIANT *pVarResult, EXCEPINFO *pExcepInfo, UINT *puArgErr)
81{
82 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
83 return IDispatchEx_Invoke(&This->node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
84 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
85}
86
87static HRESULT WINAPI HTMLDOMTextNode_put_data(IHTMLDOMTextNode *iface, BSTR v)
88{
89 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
90 nsAString nsstr;
91 nsresult nsres;
92
93 TRACE("(%p)->(%s)\n", This, debugstr_w(v));
94
95 nsAString_InitDepend(&nsstr, v);
96 nsres = nsIDOMText_SetData(This->nstext, &nsstr);
97 nsAString_Finish(&nsstr);
98 return NS_SUCCEEDED(nsres) ? S_OK : E_FAIL;
99}
100
101static HRESULT WINAPI HTMLDOMTextNode_get_data(IHTMLDOMTextNode *iface, BSTR *p)
102{
103 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
104 nsAString nsstr;
105 nsresult nsres;
106
107 TRACE("(%p)->(%p)\n", This, p);
108
109 nsAString_Init(&nsstr, NULL);
110 nsres = nsIDOMText_GetData(This->nstext, &nsstr);
111 return return_nsstr(nsres, &nsstr, p);
112}
113
114static HRESULT WINAPI HTMLDOMTextNode_toString(IHTMLDOMTextNode *iface, BSTR *String)
115{
116 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
117 FIXME("(%p)->(%p)\n", This, String);
118 return E_NOTIMPL;
119}
120
121static HRESULT WINAPI HTMLDOMTextNode_get_length(IHTMLDOMTextNode *iface, LONG *p)
122{
123 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
124 UINT32 length = 0;
125 nsresult nsres;
126
127 TRACE("(%p)->(%p)\n", This, p);
128
129 nsres = nsIDOMText_GetLength(This->nstext, &length);
130 if(NS_FAILED(nsres))
131 ERR("GetLength failed: %08x\n", nsres);
132
133 *p = length;
134 return S_OK;
135}
136
137static HRESULT WINAPI HTMLDOMTextNode_splitText(IHTMLDOMTextNode *iface, LONG offset, IHTMLDOMNode **pRetNode)
138{
139 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode(iface);
140 HTMLDOMNode *node;
141 nsIDOMText *text;
142 nsresult nsres;
143 HRESULT hres;
144
145 TRACE("(%p)->(%d %p)\n", This, offset, pRetNode);
146
147 nsres = nsIDOMText_SplitText(This->nstext, offset, &text);
148 if(NS_FAILED(nsres)) {
149 ERR("SplitText failed: %x08x\n", nsres);
150 return E_FAIL;
151 }
152
153 if(!text) {
154 *pRetNode = NULL;
155 return S_OK;
156 }
157
158 hres = get_node(This->node.doc, (nsIDOMNode*)text, TRUE, &node);
159 nsIDOMText_Release(text);
160 if(FAILED(hres))
161 return hres;
162
163 *pRetNode = &node->IHTMLDOMNode_iface;
164 return S_OK;
165}
166
167static const IHTMLDOMTextNodeVtbl HTMLDOMTextNodeVtbl = {
168 HTMLDOMTextNode_QueryInterface,
169 HTMLDOMTextNode_AddRef,
170 HTMLDOMTextNode_Release,
171 HTMLDOMTextNode_GetTypeInfoCount,
172 HTMLDOMTextNode_GetTypeInfo,
173 HTMLDOMTextNode_GetIDsOfNames,
174 HTMLDOMTextNode_Invoke,
175 HTMLDOMTextNode_put_data,
176 HTMLDOMTextNode_get_data,
177 HTMLDOMTextNode_toString,
178 HTMLDOMTextNode_get_length,
179 HTMLDOMTextNode_splitText
180};
181
182static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 *iface)
183{
184 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode2_iface);
185}
186
187static HRESULT WINAPI HTMLDOMTextNode2_QueryInterface(IHTMLDOMTextNode2 *iface, REFIID riid, void **ppv)
188{
189 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
190
191 return IHTMLDOMNode_QueryInterface(&This->node.IHTMLDOMNode_iface, riid, ppv);
192}
193
194static ULONG WINAPI HTMLDOMTextNode2_AddRef(IHTMLDOMTextNode2 *iface)
195{
196 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
197
198 return IHTMLDOMNode_AddRef(&This->node.IHTMLDOMNode_iface);
199}
200
201static ULONG WINAPI HTMLDOMTextNode2_Release(IHTMLDOMTextNode2 *iface)
202{
203 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
204
205 return IHTMLDOMNode_Release(&This->node.IHTMLDOMNode_iface);
206}
207
208static HRESULT WINAPI HTMLDOMTextNode2_GetTypeInfoCount(IHTMLDOMTextNode2 *iface, UINT *pctinfo)
209{
210 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
211 return IDispatchEx_GetTypeInfoCount(&This->node.event_target.dispex.IDispatchEx_iface, pctinfo);
212}
213
214static HRESULT WINAPI HTMLDOMTextNode2_GetTypeInfo(IHTMLDOMTextNode2 *iface, UINT iTInfo,
215 LCID lcid, ITypeInfo **ppTInfo)
216{
217 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
218 return IDispatchEx_GetTypeInfo(&This->node.event_target.dispex.IDispatchEx_iface, iTInfo, lcid, ppTInfo);
219}
220
221static HRESULT WINAPI HTMLDOMTextNode2_GetIDsOfNames(IHTMLDOMTextNode2 *iface, REFIID riid,
222 LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId)
223{
224 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
225 return IDispatchEx_GetIDsOfNames(&This->node.event_target.dispex.IDispatchEx_iface, riid, rgszNames, cNames,
226 lcid, rgDispId);
227}
228
229static HRESULT WINAPI HTMLDOMTextNode2_Invoke(IHTMLDOMTextNode2 *iface, DISPID dispIdMember,
230 REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult,
231 EXCEPINFO *pExcepInfo, UINT *puArgErr)
232{
233 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
234 return IDispatchEx_Invoke(&This->node.event_target.dispex.IDispatchEx_iface, dispIdMember, riid, lcid,
235 wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr);
236}
237
238static HRESULT WINAPI HTMLDOMTextNode2_substringData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR *string)
239{
240 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
241 FIXME("(%p)->(%d %d %p)\n", This, offset, count, string);
242 return E_NOTIMPL;
243}
244
245static HRESULT WINAPI HTMLDOMTextNode2_appendData(IHTMLDOMTextNode2 *iface, BSTR string)
246{
247 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
248 nsAString nsstr;
249 nsresult nsres;
250
251 TRACE("(%p)->(%s)\n", This, debugstr_w(string));
252
253 nsAString_InitDepend(&nsstr, string);
254 nsres = nsIDOMText_AppendData(This->nstext, &nsstr);
255 nsAString_Finish(&nsstr);
256 if(NS_FAILED(nsres)) {
257 ERR("AppendData failed: %08x\n", nsres);
258 return E_FAIL;
259 }
260
261 return S_OK;
262}
263
264static HRESULT WINAPI HTMLDOMTextNode2_insertData(IHTMLDOMTextNode2 *iface, LONG offset, BSTR string)
265{
266 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
267 FIXME("(%p)->(%d %s)\n", This, offset, debugstr_w(string));
268 return E_NOTIMPL;
269}
270
271static HRESULT WINAPI HTMLDOMTextNode2_deleteData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count)
272{
273 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
274 FIXME("(%p)->(%d %d)\n", This, offset, count);
275 return E_NOTIMPL;
276}
277
278static HRESULT WINAPI HTMLDOMTextNode2_replaceData(IHTMLDOMTextNode2 *iface, LONG offset, LONG count, BSTR string)
279{
280 HTMLDOMTextNode *This = impl_from_IHTMLDOMTextNode2(iface);
281 FIXME("(%p)->(%d %d %s)\n", This, offset, count, debugstr_w(string));
282 return E_NOTIMPL;
283}
284
285static const IHTMLDOMTextNode2Vtbl HTMLDOMTextNode2Vtbl = {
286 HTMLDOMTextNode2_QueryInterface,
287 HTMLDOMTextNode2_AddRef,
288 HTMLDOMTextNode2_Release,
289 HTMLDOMTextNode2_GetTypeInfoCount,
290 HTMLDOMTextNode2_GetTypeInfo,
291 HTMLDOMTextNode2_GetIDsOfNames,
292 HTMLDOMTextNode2_Invoke,
293 HTMLDOMTextNode2_substringData,
294 HTMLDOMTextNode2_appendData,
295 HTMLDOMTextNode2_insertData,
296 HTMLDOMTextNode2_deleteData,
297 HTMLDOMTextNode2_replaceData
298};
299
300static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
301{
302 return CONTAINING_RECORD(iface, HTMLDOMTextNode, node);
303}
304
305static HRESULT HTMLDOMTextNode_QI(HTMLDOMNode *iface, REFIID riid, void **ppv)
306{
307 HTMLDOMTextNode *This = impl_from_HTMLDOMNode(iface);
308
309 TRACE("(%p)->(%s %p)\n", This, debugstr_mshtml_guid(riid), ppv);
310
311 if(IsEqualGUID(&IID_IHTMLDOMTextNode, riid))
312 *ppv = &This->IHTMLDOMTextNode_iface;
313 else if(IsEqualGUID(&IID_IHTMLDOMTextNode2, riid))
314 *ppv = &This->IHTMLDOMTextNode2_iface;
315 else
316 return HTMLDOMNode_QI(&This->node, riid, ppv);
317
318 IUnknown_AddRef((IUnknown*)*ppv);
319 return S_OK;
320}
321
322static HRESULT HTMLDOMTextNode_clone(HTMLDOMNode *iface, nsIDOMNode *nsnode, HTMLDOMNode **ret)
323{
324 HTMLDOMTextNode *This = impl_from_HTMLDOMNode(iface);
325
326 return HTMLDOMTextNode_Create(This->node.doc, nsnode, ret);
327}
328
329static const cpc_entry_t HTMLDOMTextNode_cpc[] = {{NULL}};
330
331static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
332 HTMLDOMTextNode_QI,
333 HTMLDOMNode_destructor,
334 HTMLDOMTextNode_cpc,
335 HTMLDOMTextNode_clone
336};
337
338static const tid_t HTMLDOMTextNode_iface_tids[] = {
339 IHTMLDOMNode_tid,
340 IHTMLDOMNode2_tid,
341 IHTMLDOMTextNode_tid,
342 IHTMLDOMTextNode2_tid,
343 0
344};
345static dispex_static_data_t HTMLDOMTextNode_dispex = {
346 NULL,
347 DispHTMLDOMTextNode_tid,
348 0,
349 HTMLDOMTextNode_iface_tids
350};
351
352HRESULT HTMLDOMTextNode_Create(HTMLDocumentNode *doc, nsIDOMNode *nsnode, HTMLDOMNode **node)
353{
354 HTMLDOMTextNode *ret;
355 nsresult nsres;
356
357 ret = heap_alloc_zero(sizeof(*ret));
358 if(!ret)
359 return E_OUTOFMEMORY;
360
361 ret->node.vtbl = &HTMLDOMTextNodeImplVtbl;
362 ret->IHTMLDOMTextNode_iface.lpVtbl = &HTMLDOMTextNodeVtbl;
363 ret->IHTMLDOMTextNode2_iface.lpVtbl = &HTMLDOMTextNode2Vtbl;
364
365 init_dispex(&ret->node.event_target.dispex, (IUnknown*)&ret->IHTMLDOMTextNode_iface,
366 &HTMLDOMTextNode_dispex);
367
368 HTMLDOMNode_Init(doc, &ret->node, nsnode);
369
370 nsres = nsIDOMNode_QueryInterface(nsnode, &IID_nsIDOMText, (void**)&ret->nstext);
371 assert(nsres == NS_OK && (nsIDOMNode*)ret->nstext == ret->node.nsnode);
372
373 /* Share reference with nsnode */
374 nsIDOMNode_Release(ret->node.nsnode);
375
376 *node = &ret->node;
377 return S_OK;
378}