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
impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode * iface)29 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode(IHTMLDOMTextNode *iface)
30 {
31 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode_iface);
32 }
33
HTMLDOMTextNode_QueryInterface(IHTMLDOMTextNode * iface,REFIID riid,void ** ppv)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
HTMLDOMTextNode_AddRef(IHTMLDOMTextNode * iface)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
HTMLDOMTextNode_Release(IHTMLDOMTextNode * iface)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
HTMLDOMTextNode_GetTypeInfoCount(IHTMLDOMTextNode * iface,UINT * pctinfo)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
HTMLDOMTextNode_GetTypeInfo(IHTMLDOMTextNode * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)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
HTMLDOMTextNode_GetIDsOfNames(IHTMLDOMTextNode * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)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
HTMLDOMTextNode_Invoke(IHTMLDOMTextNode * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)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
HTMLDOMTextNode_put_data(IHTMLDOMTextNode * iface,BSTR v)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
HTMLDOMTextNode_get_data(IHTMLDOMTextNode * iface,BSTR * p)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
HTMLDOMTextNode_toString(IHTMLDOMTextNode * iface,BSTR * String)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
HTMLDOMTextNode_get_length(IHTMLDOMTextNode * iface,LONG * p)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
HTMLDOMTextNode_splitText(IHTMLDOMTextNode * iface,LONG offset,IHTMLDOMNode ** pRetNode)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
impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 * iface)182 static inline HTMLDOMTextNode *impl_from_IHTMLDOMTextNode2(IHTMLDOMTextNode2 *iface)
183 {
184 return CONTAINING_RECORD(iface, HTMLDOMTextNode, IHTMLDOMTextNode2_iface);
185 }
186
HTMLDOMTextNode2_QueryInterface(IHTMLDOMTextNode2 * iface,REFIID riid,void ** ppv)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
HTMLDOMTextNode2_AddRef(IHTMLDOMTextNode2 * iface)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
HTMLDOMTextNode2_Release(IHTMLDOMTextNode2 * iface)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
HTMLDOMTextNode2_GetTypeInfoCount(IHTMLDOMTextNode2 * iface,UINT * pctinfo)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
HTMLDOMTextNode2_GetTypeInfo(IHTMLDOMTextNode2 * iface,UINT iTInfo,LCID lcid,ITypeInfo ** ppTInfo)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
HTMLDOMTextNode2_GetIDsOfNames(IHTMLDOMTextNode2 * iface,REFIID riid,LPOLESTR * rgszNames,UINT cNames,LCID lcid,DISPID * rgDispId)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
HTMLDOMTextNode2_Invoke(IHTMLDOMTextNode2 * iface,DISPID dispIdMember,REFIID riid,LCID lcid,WORD wFlags,DISPPARAMS * pDispParams,VARIANT * pVarResult,EXCEPINFO * pExcepInfo,UINT * puArgErr)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
HTMLDOMTextNode2_substringData(IHTMLDOMTextNode2 * iface,LONG offset,LONG count,BSTR * string)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
HTMLDOMTextNode2_appendData(IHTMLDOMTextNode2 * iface,BSTR string)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
HTMLDOMTextNode2_insertData(IHTMLDOMTextNode2 * iface,LONG offset,BSTR string)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
HTMLDOMTextNode2_deleteData(IHTMLDOMTextNode2 * iface,LONG offset,LONG count)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
HTMLDOMTextNode2_replaceData(IHTMLDOMTextNode2 * iface,LONG offset,LONG count,BSTR string)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
impl_from_HTMLDOMNode(HTMLDOMNode * iface)300 static inline HTMLDOMTextNode *impl_from_HTMLDOMNode(HTMLDOMNode *iface)
301 {
302 return CONTAINING_RECORD(iface, HTMLDOMTextNode, node);
303 }
304
HTMLDOMTextNode_QI(HTMLDOMNode * iface,REFIID riid,void ** ppv)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
HTMLDOMTextNode_clone(HTMLDOMNode * iface,nsIDOMNode * nsnode,HTMLDOMNode ** ret)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
HTMLDOMTextNode_Create(HTMLDocumentNode * doc,nsIDOMNode * nsnode,HTMLDOMNode ** node)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