1 /* 2 * DOM Document Fragment implementation 3 * 4 * Copyright 2007 Alistair Leslie-Hughes 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, write to the Free Software 18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 19 */ 20 21 #define COBJMACROS 22 23 #include "config.h" 24 25 #include <stdarg.h> 26 #ifdef HAVE_LIBXML2 27 # include <libxml/parser.h> 28 # include <libxml/xmlerror.h> 29 #endif 30 31 #include "windef.h" 32 #include "winbase.h" 33 #include "winuser.h" 34 #include "ole2.h" 35 #include "msxml6.h" 36 37 #include "msxml_private.h" 38 39 #include "wine/debug.h" 40 41 #ifdef HAVE_LIBXML2 42 43 WINE_DEFAULT_DEBUG_CHANNEL(msxml); 44 45 typedef struct _domfrag 46 { 47 xmlnode node; 48 IXMLDOMDocumentFragment IXMLDOMDocumentFragment_iface; 49 LONG ref; 50 } domfrag; 51 52 static const tid_t domfrag_se_tids[] = { 53 IXMLDOMNode_tid, 54 IXMLDOMDocumentFragment_tid, 55 NULL_tid 56 }; 57 58 static inline domfrag *impl_from_IXMLDOMDocumentFragment( IXMLDOMDocumentFragment *iface ) 59 { 60 return CONTAINING_RECORD(iface, domfrag, IXMLDOMDocumentFragment_iface); 61 } 62 63 static HRESULT WINAPI domfrag_QueryInterface( 64 IXMLDOMDocumentFragment *iface, 65 REFIID riid, 66 void** ppvObject ) 67 { 68 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 69 TRACE("(%p)->(%s %p)\n", This, debugstr_guid(riid), ppvObject); 70 71 if ( IsEqualGUID( riid, &IID_IXMLDOMDocumentFragment ) || 72 IsEqualGUID( riid, &IID_IXMLDOMNode ) || 73 IsEqualGUID( riid, &IID_IDispatch ) || 74 IsEqualGUID( riid, &IID_IUnknown ) ) 75 { 76 *ppvObject = iface; 77 } 78 else if(node_query_interface(&This->node, riid, ppvObject)) 79 { 80 return *ppvObject ? S_OK : E_NOINTERFACE; 81 } 82 else if(IsEqualGUID( riid, &IID_ISupportErrorInfo )) 83 { 84 return node_create_supporterrorinfo(domfrag_se_tids, ppvObject); 85 } 86 else 87 { 88 TRACE("Unsupported interface %s\n", debugstr_guid(riid)); 89 *ppvObject = NULL; 90 return E_NOINTERFACE; 91 } 92 93 IXMLDOMDocumentFragment_AddRef(iface); 94 return S_OK; 95 } 96 97 static ULONG WINAPI domfrag_AddRef( 98 IXMLDOMDocumentFragment *iface ) 99 { 100 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 101 ULONG ref = InterlockedIncrement( &This->ref ); 102 TRACE("(%p)->(%d)\n", This, ref); 103 return ref; 104 } 105 106 static ULONG WINAPI domfrag_Release( 107 IXMLDOMDocumentFragment *iface ) 108 { 109 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 110 ULONG ref = InterlockedDecrement( &This->ref ); 111 112 TRACE("(%p)->(%d)\n", This, ref); 113 if ( ref == 0 ) 114 { 115 destroy_xmlnode(&This->node); 116 heap_free( This ); 117 } 118 119 return ref; 120 } 121 122 static HRESULT WINAPI domfrag_GetTypeInfoCount( 123 IXMLDOMDocumentFragment *iface, 124 UINT* pctinfo ) 125 { 126 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 127 return IDispatchEx_GetTypeInfoCount(&This->node.dispex.IDispatchEx_iface, pctinfo); 128 } 129 130 static HRESULT WINAPI domfrag_GetTypeInfo( 131 IXMLDOMDocumentFragment *iface, 132 UINT iTInfo, LCID lcid, 133 ITypeInfo** ppTInfo ) 134 { 135 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 136 return IDispatchEx_GetTypeInfo(&This->node.dispex.IDispatchEx_iface, 137 iTInfo, lcid, ppTInfo); 138 } 139 140 static HRESULT WINAPI domfrag_GetIDsOfNames( 141 IXMLDOMDocumentFragment *iface, 142 REFIID riid, LPOLESTR* rgszNames, 143 UINT cNames, LCID lcid, DISPID* rgDispId ) 144 { 145 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 146 return IDispatchEx_GetIDsOfNames(&This->node.dispex.IDispatchEx_iface, 147 riid, rgszNames, cNames, lcid, rgDispId); 148 } 149 150 static HRESULT WINAPI domfrag_Invoke( 151 IXMLDOMDocumentFragment *iface, 152 DISPID dispIdMember, REFIID riid, LCID lcid, 153 WORD wFlags, DISPPARAMS* pDispParams, VARIANT* pVarResult, 154 EXCEPINFO* pExcepInfo, UINT* puArgErr ) 155 { 156 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 157 return IDispatchEx_Invoke(&This->node.dispex.IDispatchEx_iface, 158 dispIdMember, riid, lcid, wFlags, pDispParams, pVarResult, pExcepInfo, puArgErr); 159 } 160 161 static HRESULT WINAPI domfrag_get_nodeName( 162 IXMLDOMDocumentFragment *iface, 163 BSTR* p ) 164 { 165 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 166 167 static const WCHAR document_fragmentW[] = 168 {'#','d','o','c','u','m','e','n','t','-','f','r','a','g','m','e','n','t',0}; 169 170 TRACE("(%p)->(%p)\n", This, p); 171 172 return return_bstr(document_fragmentW, p); 173 } 174 175 static HRESULT WINAPI domfrag_get_nodeValue( 176 IXMLDOMDocumentFragment *iface, 177 VARIANT* value) 178 { 179 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 180 TRACE("(%p)->(%p)\n", This, value); 181 return return_null_var(value); 182 } 183 184 static HRESULT WINAPI domfrag_put_nodeValue( 185 IXMLDOMDocumentFragment *iface, 186 VARIANT value) 187 { 188 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 189 TRACE("(%p)->(%s)\n", This, debugstr_variant(&value)); 190 return E_FAIL; 191 } 192 193 static HRESULT WINAPI domfrag_get_nodeType( 194 IXMLDOMDocumentFragment *iface, 195 DOMNodeType* domNodeType ) 196 { 197 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 198 199 TRACE("(%p)->(%p)\n", This, domNodeType); 200 201 *domNodeType = NODE_DOCUMENT_FRAGMENT; 202 return S_OK; 203 } 204 205 static HRESULT WINAPI domfrag_get_parentNode( 206 IXMLDOMDocumentFragment *iface, 207 IXMLDOMNode** parent ) 208 { 209 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 210 211 TRACE("(%p)->(%p)\n", This, parent); 212 213 return node_get_parent(&This->node, parent); 214 } 215 216 static HRESULT WINAPI domfrag_get_childNodes( 217 IXMLDOMDocumentFragment *iface, 218 IXMLDOMNodeList** outList) 219 { 220 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 221 222 TRACE("(%p)->(%p)\n", This, outList); 223 224 return node_get_child_nodes(&This->node, outList); 225 } 226 227 static HRESULT WINAPI domfrag_get_firstChild( 228 IXMLDOMDocumentFragment *iface, 229 IXMLDOMNode** domNode) 230 { 231 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 232 233 TRACE("(%p)->(%p)\n", This, domNode); 234 235 return node_get_first_child(&This->node, domNode); 236 } 237 238 static HRESULT WINAPI domfrag_get_lastChild( 239 IXMLDOMDocumentFragment *iface, 240 IXMLDOMNode** domNode) 241 { 242 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 243 244 TRACE("(%p)->(%p)\n", This, domNode); 245 246 return node_get_last_child(&This->node, domNode); 247 } 248 249 static HRESULT WINAPI domfrag_get_previousSibling( 250 IXMLDOMDocumentFragment *iface, 251 IXMLDOMNode** domNode) 252 { 253 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 254 255 TRACE("(%p)->(%p)\n", This, domNode); 256 257 return return_null_node(domNode); 258 } 259 260 static HRESULT WINAPI domfrag_get_nextSibling( 261 IXMLDOMDocumentFragment *iface, 262 IXMLDOMNode** domNode) 263 { 264 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 265 266 TRACE("(%p)->(%p)\n", This, domNode); 267 268 return return_null_node(domNode); 269 } 270 271 static HRESULT WINAPI domfrag_get_attributes( 272 IXMLDOMDocumentFragment *iface, 273 IXMLDOMNamedNodeMap** attributeMap) 274 { 275 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 276 277 TRACE("(%p)->(%p)\n", This, attributeMap); 278 279 return return_null_ptr((void**)attributeMap); 280 } 281 282 static HRESULT WINAPI domfrag_insertBefore( 283 IXMLDOMDocumentFragment *iface, 284 IXMLDOMNode* newNode, VARIANT refChild, 285 IXMLDOMNode** outOldNode) 286 { 287 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 288 289 TRACE("(%p)->(%p %s %p)\n", This, newNode, debugstr_variant(&refChild), outOldNode); 290 291 /* TODO: test */ 292 return node_insert_before(&This->node, newNode, &refChild, outOldNode); 293 } 294 295 static HRESULT WINAPI domfrag_replaceChild( 296 IXMLDOMDocumentFragment *iface, 297 IXMLDOMNode* newNode, 298 IXMLDOMNode* oldNode, 299 IXMLDOMNode** outOldNode) 300 { 301 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 302 303 TRACE("(%p)->(%p %p %p)\n", This, newNode, oldNode, outOldNode); 304 305 /* TODO: test */ 306 return node_replace_child(&This->node, newNode, oldNode, outOldNode); 307 } 308 309 static HRESULT WINAPI domfrag_removeChild( 310 IXMLDOMDocumentFragment *iface, 311 IXMLDOMNode *child, IXMLDOMNode **oldChild) 312 { 313 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 314 TRACE("(%p)->(%p %p)\n", This, child, oldChild); 315 return node_remove_child(&This->node, child, oldChild); 316 } 317 318 static HRESULT WINAPI domfrag_appendChild( 319 IXMLDOMDocumentFragment *iface, 320 IXMLDOMNode *child, IXMLDOMNode **outChild) 321 { 322 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 323 TRACE("(%p)->(%p %p)\n", This, child, outChild); 324 return node_append_child(&This->node, child, outChild); 325 } 326 327 static HRESULT WINAPI domfrag_hasChildNodes( 328 IXMLDOMDocumentFragment *iface, 329 VARIANT_BOOL *ret) 330 { 331 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 332 TRACE("(%p)->(%p)\n", This, ret); 333 return node_has_childnodes(&This->node, ret); 334 } 335 336 static HRESULT WINAPI domfrag_get_ownerDocument( 337 IXMLDOMDocumentFragment *iface, 338 IXMLDOMDocument **doc) 339 { 340 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 341 TRACE("(%p)->(%p)\n", This, doc); 342 return node_get_owner_doc(&This->node, doc); 343 } 344 345 static HRESULT WINAPI domfrag_cloneNode( 346 IXMLDOMDocumentFragment *iface, 347 VARIANT_BOOL deep, IXMLDOMNode** outNode) 348 { 349 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 350 TRACE("(%p)->(%d %p)\n", This, deep, outNode); 351 return node_clone( &This->node, deep, outNode ); 352 } 353 354 static HRESULT WINAPI domfrag_get_nodeTypeString( 355 IXMLDOMDocumentFragment *iface, 356 BSTR* p) 357 { 358 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 359 static const WCHAR documentfragmentW[] = {'d','o','c','u','m','e','n','t','f','r','a','g','m','e','n','t',0}; 360 361 TRACE("(%p)->(%p)\n", This, p); 362 363 return return_bstr(documentfragmentW, p); 364 } 365 366 static HRESULT WINAPI domfrag_get_text( 367 IXMLDOMDocumentFragment *iface, 368 BSTR* p) 369 { 370 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 371 TRACE("(%p)->(%p)\n", This, p); 372 return node_get_text(&This->node, p); 373 } 374 375 static HRESULT WINAPI domfrag_put_text( 376 IXMLDOMDocumentFragment *iface, 377 BSTR p) 378 { 379 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 380 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 381 return node_put_text( &This->node, p ); 382 } 383 384 static HRESULT WINAPI domfrag_get_specified( 385 IXMLDOMDocumentFragment *iface, 386 VARIANT_BOOL* isSpecified) 387 { 388 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 389 FIXME("(%p)->(%p) stub!\n", This, isSpecified); 390 *isSpecified = VARIANT_TRUE; 391 return S_OK; 392 } 393 394 static HRESULT WINAPI domfrag_get_definition( 395 IXMLDOMDocumentFragment *iface, 396 IXMLDOMNode** definitionNode) 397 { 398 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 399 FIXME("(%p)->(%p)\n", This, definitionNode); 400 return E_NOTIMPL; 401 } 402 403 static HRESULT WINAPI domfrag_get_nodeTypedValue( 404 IXMLDOMDocumentFragment *iface, 405 VARIANT *v) 406 { 407 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 408 TRACE("(%p)->(%p)\n", This, v); 409 return return_null_var(v); 410 } 411 412 static HRESULT WINAPI domfrag_put_nodeTypedValue( 413 IXMLDOMDocumentFragment *iface, 414 VARIANT typedValue) 415 { 416 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 417 FIXME("(%p)->(%s)\n", This, debugstr_variant(&typedValue)); 418 return E_NOTIMPL; 419 } 420 421 static HRESULT WINAPI domfrag_get_dataType( 422 IXMLDOMDocumentFragment *iface, 423 VARIANT* typename) 424 { 425 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 426 TRACE("(%p)->(%p)\n", This, typename); 427 return return_null_var( typename ); 428 } 429 430 static HRESULT WINAPI domfrag_put_dataType( 431 IXMLDOMDocumentFragment *iface, 432 BSTR p) 433 { 434 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 435 436 TRACE("(%p)->(%s)\n", This, debugstr_w(p)); 437 438 if(!p) 439 return E_INVALIDARG; 440 441 return E_FAIL; 442 } 443 444 static HRESULT WINAPI domfrag_get_xml( 445 IXMLDOMDocumentFragment *iface, 446 BSTR* p) 447 { 448 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 449 450 TRACE("(%p)->(%p)\n", This, p); 451 452 return node_get_xml(&This->node, FALSE, p); 453 } 454 455 static HRESULT WINAPI domfrag_transformNode( 456 IXMLDOMDocumentFragment *iface, 457 IXMLDOMNode *node, BSTR *p) 458 { 459 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 460 TRACE("(%p)->(%p %p)\n", This, node, p); 461 return node_transform_node(&This->node, node, p); 462 } 463 464 static HRESULT WINAPI domfrag_selectNodes( 465 IXMLDOMDocumentFragment *iface, 466 BSTR p, IXMLDOMNodeList** outList) 467 { 468 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 469 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outList); 470 return node_select_nodes(&This->node, p, outList); 471 } 472 473 static HRESULT WINAPI domfrag_selectSingleNode( 474 IXMLDOMDocumentFragment *iface, 475 BSTR p, IXMLDOMNode** outNode) 476 { 477 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 478 TRACE("(%p)->(%s %p)\n", This, debugstr_w(p), outNode); 479 return node_select_singlenode(&This->node, p, outNode); 480 } 481 482 static HRESULT WINAPI domfrag_get_parsed( 483 IXMLDOMDocumentFragment *iface, 484 VARIANT_BOOL* isParsed) 485 { 486 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 487 FIXME("(%p)->(%p) stub!\n", This, isParsed); 488 *isParsed = VARIANT_TRUE; 489 return S_OK; 490 } 491 492 static HRESULT WINAPI domfrag_get_namespaceURI( 493 IXMLDOMDocumentFragment *iface, 494 BSTR* p) 495 { 496 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 497 TRACE("(%p)->(%p)\n", This, p); 498 return node_get_namespaceURI(&This->node, p); 499 } 500 501 static HRESULT WINAPI domfrag_get_prefix( 502 IXMLDOMDocumentFragment *iface, 503 BSTR* prefix) 504 { 505 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 506 TRACE("(%p)->(%p)\n", This, prefix); 507 return return_null_bstr( prefix ); 508 } 509 510 static HRESULT WINAPI domfrag_get_baseName( 511 IXMLDOMDocumentFragment *iface, 512 BSTR* name) 513 { 514 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 515 FIXME("(%p)->(%p): needs test\n", This, name); 516 return return_null_bstr( name ); 517 } 518 519 static HRESULT WINAPI domfrag_transformNodeToObject( 520 IXMLDOMDocumentFragment *iface, 521 IXMLDOMNode* domNode, VARIANT var1) 522 { 523 domfrag *This = impl_from_IXMLDOMDocumentFragment( iface ); 524 FIXME("(%p)->(%p %s)\n", This, domNode, debugstr_variant(&var1)); 525 return E_NOTIMPL; 526 } 527 528 static const struct IXMLDOMDocumentFragmentVtbl domfrag_vtbl = 529 { 530 domfrag_QueryInterface, 531 domfrag_AddRef, 532 domfrag_Release, 533 domfrag_GetTypeInfoCount, 534 domfrag_GetTypeInfo, 535 domfrag_GetIDsOfNames, 536 domfrag_Invoke, 537 domfrag_get_nodeName, 538 domfrag_get_nodeValue, 539 domfrag_put_nodeValue, 540 domfrag_get_nodeType, 541 domfrag_get_parentNode, 542 domfrag_get_childNodes, 543 domfrag_get_firstChild, 544 domfrag_get_lastChild, 545 domfrag_get_previousSibling, 546 domfrag_get_nextSibling, 547 domfrag_get_attributes, 548 domfrag_insertBefore, 549 domfrag_replaceChild, 550 domfrag_removeChild, 551 domfrag_appendChild, 552 domfrag_hasChildNodes, 553 domfrag_get_ownerDocument, 554 domfrag_cloneNode, 555 domfrag_get_nodeTypeString, 556 domfrag_get_text, 557 domfrag_put_text, 558 domfrag_get_specified, 559 domfrag_get_definition, 560 domfrag_get_nodeTypedValue, 561 domfrag_put_nodeTypedValue, 562 domfrag_get_dataType, 563 domfrag_put_dataType, 564 domfrag_get_xml, 565 domfrag_transformNode, 566 domfrag_selectNodes, 567 domfrag_selectSingleNode, 568 domfrag_get_parsed, 569 domfrag_get_namespaceURI, 570 domfrag_get_prefix, 571 domfrag_get_baseName, 572 domfrag_transformNodeToObject 573 }; 574 575 static const tid_t domfrag_iface_tids[] = { 576 IXMLDOMDocumentFragment_tid, 577 0 578 }; 579 580 static dispex_static_data_t domfrag_dispex = { 581 NULL, 582 IXMLDOMDocumentFragment_tid, 583 NULL, 584 domfrag_iface_tids 585 }; 586 587 IUnknown* create_doc_fragment( xmlNodePtr fragment ) 588 { 589 domfrag *This; 590 591 This = heap_alloc( sizeof *This ); 592 if ( !This ) 593 return NULL; 594 595 This->IXMLDOMDocumentFragment_iface.lpVtbl = &domfrag_vtbl; 596 This->ref = 1; 597 598 init_xmlnode(&This->node, fragment, (IXMLDOMNode*)&This->IXMLDOMDocumentFragment_iface, &domfrag_dispex); 599 600 return (IUnknown*)&This->IXMLDOMDocumentFragment_iface; 601 } 602 603 #endif 604