xref: /reactos/dll/win32/mshtml/htmltextnode.c (revision 8a978a17)
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 
21 struct HTMLDOMTextNode {
22     HTMLDOMNode node;
23     IHTMLDOMTextNode IHTMLDOMTextNode_iface;
24     IHTMLDOMTextNode2 IHTMLDOMTextNode2_iface;
25 
26     nsIDOMText *nstext;
27 };
28 
29 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode *iface)
30 {
31     return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode_iface);
32 }
33 
34 static 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 
42 static 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 
49 static 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 
56 static 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 
62 static 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 
69 static 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 
78 static 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 
87 static 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 
101 static 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 
114 static 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 
121 static 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 
137 static 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 
167 static 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 
182 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 *iface)
183 {
184     return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode2_iface);
185 }
186 
187 static 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 
194 static 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 
201 static 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 
208 static 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 
214 static 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 
221 static 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 
229 static 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 
238 static 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 
245 static 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 
264 static 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 
271 static 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 
278 static 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 
285 static 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 
300 static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
301 {
302     return CONTAINING_RECORD(iface, HTMLDOMTextNode, node);
303 }
304 
305 static 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 
322 static 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 
329 static const cpc_entry_t HTMLDOMTextNode_cpc[] = {{NULL}};
330 
331 static const NodeImplVtbl HTMLDOMTextNodeImplVtbl = {
332     HTMLDOMTextNode_QI,
333     HTMLDOMNode_destructor,
334     HTMLDOMTextNode_cpc,
335     HTMLDOMTextNode_clone
336 };
337 
338 static const tid_t HTMLDOMTextNode_iface_tids[] = {
339     IHTMLDOMNode_tid,
340     IHTMLDOMNode2_tid,
341     IHTMLDOMTextNode_tid,
342     IHTMLDOMTextNode2_tid,
343     0
344 };
345 static dispex_static_data_t HTMLDOMTextNode_dispex = {
346     NULL,
347     DispHTMLDOMTextNode_tid,
348     0,
349     HTMLDOMTextNode_iface_tids
350 };
351 
352 HRESULT 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 }
379