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