1/* 2 * Copyright (C) 2006, 2007, 2009 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY 14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR 17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26#include "config.h" 27#include "WebKitDLL.h" 28#include "DOMCoreClasses.h" 29 30#include "DOMCSSClasses.h" 31#include "DOMEventsClasses.h" 32#include "DOMHTMLClasses.h" 33#include "WebKitGraphics.h" 34 35#include <WebCore/BString.h> 36#include <WebCore/COMPtr.h> 37#include <WebCore/DOMWindow.h> 38#include <WebCore/Document.h> 39#include <WebCore/Element.h> 40#include <WebCore/Frame.h> 41#include <WebCore/SimpleFontData.h> 42#include <WebCore/HTMLFormElement.h> 43#include <WebCore/HTMLInputElement.h> 44#include <WebCore/HTMLNames.h> 45#include <WebCore/HTMLOptionElement.h> 46#include <WebCore/HTMLSelectElement.h> 47#include <WebCore/HTMLTextAreaElement.h> 48#include <WebCore/NodeList.h> 49#include <WebCore/RenderObject.h> 50#include <WebCore/RenderTreeAsText.h> 51 52#include <initguid.h> 53// {3B0C0EFF-478B-4b0b-8290-D2321E08E23E} 54DEFINE_GUID(IID_DOMElement, 0x3b0c0eff, 0x478b, 0x4b0b, 0x82, 0x90, 0xd2, 0x32, 0x1e, 0x8, 0xe2, 0x3e); 55 56// Our normal style is just to say "using namespace WebCore" rather than having 57// individual using directives for each type from that namespace. But 58// "DOMObject" exists both in the WebCore namespace and unnamespaced in this 59// file, which leads to ambiguities if we say "using namespace WebCore". 60using namespace WebCore::HTMLNames; 61using WTF::AtomicString; 62using WebCore::BString; 63using WebCore::Element; 64using WebCore::ExceptionCode; 65using WebCore::FontDescription; 66using WebCore::Frame; 67using WebCore::IntRect; 68using WTF::String; 69 70// DOMObject - IUnknown ------------------------------------------------------- 71 72HRESULT STDMETHODCALLTYPE DOMObject::QueryInterface(REFIID riid, void** ppvObject) 73{ 74 *ppvObject = 0; 75 if (IsEqualGUID(riid, IID_IDOMObject)) 76 *ppvObject = static_cast<IDOMObject*>(this); 77 else 78 return WebScriptObject::QueryInterface(riid, ppvObject); 79 80 AddRef(); 81 return S_OK; 82} 83 84// DOMNode - IUnknown --------------------------------------------------------- 85 86HRESULT STDMETHODCALLTYPE DOMNode::QueryInterface(REFIID riid, void** ppvObject) 87{ 88 *ppvObject = 0; 89 if (IsEqualGUID(riid, IID_IDOMNode)) 90 *ppvObject = static_cast<IDOMNode*>(this); 91 else if (IsEqualGUID(riid, __uuidof(DOMNode))) 92 *ppvObject = static_cast<DOMNode*>(this); 93 else 94 return DOMObject::QueryInterface(riid, ppvObject); 95 96 AddRef(); 97 return S_OK; 98} 99 100// DOMNode -------------------------------------------------------------------- 101 102HRESULT STDMETHODCALLTYPE DOMNode::nodeName( 103 /* [retval][out] */ BSTR* result) 104{ 105 if (!result) 106 return E_POINTER; 107 108 if (!m_node) 109 return E_FAIL; 110 111 *result = BString(m_node->nodeName()).release(); 112 return S_OK; 113} 114 115HRESULT STDMETHODCALLTYPE DOMNode::nodeValue( 116 /* [retval][out] */ BSTR* result) 117{ 118 if (!m_node) 119 return E_FAIL; 120 WTF::String nodeValueStr = m_node->nodeValue(); 121 *result = SysAllocStringLen(nodeValueStr.characters(), nodeValueStr.length()); 122 if (nodeValueStr.length() && !*result) 123 return E_OUTOFMEMORY; 124 return S_OK; 125} 126 127HRESULT STDMETHODCALLTYPE DOMNode::setNodeValue( 128 /* [in] */ BSTR /*value*/) 129{ 130 ASSERT_NOT_REACHED(); 131 return E_NOTIMPL; 132} 133 134HRESULT STDMETHODCALLTYPE DOMNode::nodeType( 135 /* [retval][out] */ unsigned short* /*result*/) 136{ 137 ASSERT_NOT_REACHED(); 138 return E_NOTIMPL; 139} 140 141HRESULT STDMETHODCALLTYPE DOMNode::parentNode( 142 /* [retval][out] */ IDOMNode** result) 143{ 144 *result = 0; 145 if (!m_node || !m_node->parentNode()) 146 return E_FAIL; 147 *result = DOMNode::createInstance(m_node->parentNode()); 148 return *result ? S_OK : E_FAIL; 149} 150 151HRESULT STDMETHODCALLTYPE DOMNode::childNodes( 152 /* [retval][out] */ IDOMNodeList** result) 153{ 154 if (!m_node) 155 return E_FAIL; 156 157 if (!result) 158 return E_POINTER; 159 160 *result = DOMNodeList::createInstance(m_node->childNodes().get()); 161 return *result ? S_OK : E_FAIL; 162} 163 164HRESULT STDMETHODCALLTYPE DOMNode::firstChild( 165 /* [retval][out] */ IDOMNode** /*result*/) 166{ 167 ASSERT_NOT_REACHED(); 168 return E_NOTIMPL; 169} 170 171HRESULT STDMETHODCALLTYPE DOMNode::lastChild( 172 /* [retval][out] */ IDOMNode** /*result*/) 173{ 174 ASSERT_NOT_REACHED(); 175 return E_NOTIMPL; 176} 177 178HRESULT STDMETHODCALLTYPE DOMNode::previousSibling( 179 /* [retval][out] */ IDOMNode** /*result*/) 180{ 181 ASSERT_NOT_REACHED(); 182 return E_NOTIMPL; 183} 184 185HRESULT STDMETHODCALLTYPE DOMNode::nextSibling( 186 /* [retval][out] */ IDOMNode** result) 187{ 188 if (!result) 189 return E_POINTER; 190 *result = 0; 191 if (!m_node) 192 return E_FAIL; 193 *result = DOMNode::createInstance(m_node->nextSibling()); 194 return *result ? S_OK : E_FAIL; 195} 196 197HRESULT STDMETHODCALLTYPE DOMNode::attributes( 198 /* [retval][out] */ IDOMNamedNodeMap** /*result*/) 199{ 200 ASSERT_NOT_REACHED(); 201 return E_NOTIMPL; 202} 203 204HRESULT STDMETHODCALLTYPE DOMNode::ownerDocument( 205 /* [retval][out] */ IDOMDocument** result) 206{ 207 if (!result) 208 return E_POINTER; 209 *result = 0; 210 if (!m_node) 211 return E_FAIL; 212 *result = DOMDocument::createInstance(m_node->ownerDocument()); 213 return *result ? S_OK : E_FAIL; 214} 215 216HRESULT STDMETHODCALLTYPE DOMNode::insertBefore( 217 /* [in] */ IDOMNode* newChild, 218 /* [in] */ IDOMNode* refChild, 219 /* [retval][out] */ IDOMNode** result) 220{ 221 if (!result) 222 return E_POINTER; 223 224 *result = 0; 225 226 if (!m_node) 227 return E_FAIL; 228 229 COMPtr<DOMNode> newChildNode(Query, newChild); 230 if (!newChildNode) 231 return E_FAIL; 232 233 COMPtr<DOMNode> refChildNode(Query, refChild); 234 235 ExceptionCode ec; 236 if (!m_node->insertBefore(newChildNode->node(), refChildNode ? refChildNode->node() : 0, ec)) 237 return E_FAIL; 238 239 *result = newChild; 240 (*result)->AddRef(); 241 return S_OK; 242} 243 244HRESULT STDMETHODCALLTYPE DOMNode::replaceChild( 245 /* [in] */ IDOMNode* /*newChild*/, 246 /* [in] */ IDOMNode* /*oldChild*/, 247 /* [retval][out] */ IDOMNode** /*result*/) 248{ 249 ASSERT_NOT_REACHED(); 250 return E_NOTIMPL; 251} 252 253HRESULT STDMETHODCALLTYPE DOMNode::removeChild( 254 /* [in] */ IDOMNode* oldChild, 255 /* [retval][out] */ IDOMNode** result) 256{ 257 if (!result) 258 return E_POINTER; 259 260 *result = 0; 261 262 if (!m_node) 263 return E_FAIL; 264 265 COMPtr<DOMNode> oldChildNode(Query, oldChild); 266 if (!oldChildNode) 267 return E_FAIL; 268 269 ExceptionCode ec; 270 if (!m_node->removeChild(oldChildNode->node(), ec)) 271 return E_FAIL; 272 273 *result = oldChild; 274 (*result)->AddRef(); 275 return S_OK; 276} 277 278HRESULT STDMETHODCALLTYPE DOMNode::appendChild( 279 /* [in] */ IDOMNode* /*oldChild*/, 280 /* [retval][out] */ IDOMNode** /*result*/) 281{ 282 ASSERT_NOT_REACHED(); 283 return E_NOTIMPL; 284} 285 286HRESULT STDMETHODCALLTYPE DOMNode::hasChildNodes( 287 /* [retval][out] */ BOOL* /*result*/) 288{ 289 ASSERT_NOT_REACHED(); 290 return E_NOTIMPL; 291} 292 293HRESULT STDMETHODCALLTYPE DOMNode::cloneNode( 294 /* [in] */ BOOL /*deep*/, 295 /* [retval][out] */ IDOMNode** /*result*/) 296{ 297 ASSERT_NOT_REACHED(); 298 return E_NOTIMPL; 299} 300 301HRESULT STDMETHODCALLTYPE DOMNode::normalize( void) 302{ 303 ASSERT_NOT_REACHED(); 304 return E_NOTIMPL; 305} 306 307HRESULT STDMETHODCALLTYPE DOMNode::isSupported( 308 /* [in] */ BSTR /*feature*/, 309 /* [in] */ BSTR /*version*/, 310 /* [retval][out] */ BOOL* /*result*/) 311{ 312 ASSERT_NOT_REACHED(); 313 return E_NOTIMPL; 314} 315 316HRESULT STDMETHODCALLTYPE DOMNode::namespaceURI( 317 /* [retval][out] */ BSTR* /*result*/) 318{ 319 ASSERT_NOT_REACHED(); 320 return E_NOTIMPL; 321} 322 323HRESULT STDMETHODCALLTYPE DOMNode::prefix( 324 /* [retval][out] */ BSTR* /*result*/) 325{ 326 ASSERT_NOT_REACHED(); 327 return E_NOTIMPL; 328} 329 330HRESULT STDMETHODCALLTYPE DOMNode::setPrefix( 331 /* [in] */ BSTR /*prefix*/) 332{ 333 ASSERT_NOT_REACHED(); 334 return E_NOTIMPL; 335} 336 337HRESULT STDMETHODCALLTYPE DOMNode::localName( 338 /* [retval][out] */ BSTR* /*result*/) 339{ 340 ASSERT_NOT_REACHED(); 341 return E_NOTIMPL; 342} 343 344HRESULT STDMETHODCALLTYPE DOMNode::hasAttributes( 345 /* [retval][out] */ BOOL* /*result*/) 346{ 347 ASSERT_NOT_REACHED(); 348 return E_NOTIMPL; 349} 350 351HRESULT STDMETHODCALLTYPE DOMNode::isSameNode( 352 /* [in] */ IDOMNode* other, 353 /* [retval][out] */ BOOL* result) 354{ 355 if (!result) { 356 ASSERT_NOT_REACHED(); 357 return E_POINTER; 358 } 359 360 *result = FALSE; 361 362 if (!other) 363 return E_POINTER; 364 365 COMPtr<DOMNode> domOther; 366 HRESULT hr = other->QueryInterface(__uuidof(DOMNode), (void**)&domOther); 367 if (FAILED(hr)) 368 return hr; 369 370 *result = m_node->isSameNode(domOther->node()) ? TRUE : FALSE; 371 return S_OK; 372} 373 374HRESULT STDMETHODCALLTYPE DOMNode::isEqualNode( 375 /* [in] */ IDOMNode* /*other*/, 376 /* [retval][out] */ BOOL* /*result*/) 377{ 378 ASSERT_NOT_REACHED(); 379 return E_NOTIMPL; 380} 381 382HRESULT STDMETHODCALLTYPE DOMNode::textContent( 383 /* [retval][out] */ BSTR* result) 384{ 385 if (!result) 386 return E_POINTER; 387 388 *result = BString(m_node->textContent()).release(); 389 390 return S_OK; 391} 392 393HRESULT STDMETHODCALLTYPE DOMNode::setTextContent( 394 /* [in] */ BSTR /*text*/) 395{ 396 ASSERT_NOT_REACHED(); 397 return E_NOTIMPL; 398} 399 400// DOMNode - IDOMEventTarget -------------------------------------------------- 401 402HRESULT STDMETHODCALLTYPE DOMNode::addEventListener( 403 /* [in] */ BSTR /*type*/, 404 /* [in] */ IDOMEventListener* /*listener*/, 405 /* [in] */ BOOL /*useCapture*/) 406{ 407 return E_NOTIMPL; 408} 409 410HRESULT STDMETHODCALLTYPE DOMNode::removeEventListener( 411 /* [in] */ BSTR /*type*/, 412 /* [in] */ IDOMEventListener* /*listener*/, 413 /* [in] */ BOOL /*useCapture*/) 414{ 415 return E_NOTIMPL; 416} 417 418HRESULT STDMETHODCALLTYPE DOMNode::dispatchEvent( 419 /* [in] */ IDOMEvent* evt, 420 /* [retval][out] */ BOOL* result) 421{ 422 if (!m_node || !evt) 423 return E_FAIL; 424 425#if 0 // FIXME - raise dom exceptions 426 if (![self _node]->isEventTargetNode()) 427 WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR); 428#endif 429 430 COMPtr<DOMEvent> domEvent; 431 HRESULT hr = evt->QueryInterface(IID_DOMEvent, (void**) &domEvent); 432 if (FAILED(hr)) 433 return hr; 434 435 WebCore::ExceptionCode ec = 0; 436 *result = m_node->dispatchEvent(domEvent->coreEvent(), ec) ? TRUE : FALSE; 437#if 0 // FIXME - raise dom exceptions 438 WebCore::raiseOnDOMError(ec); 439#endif 440 return S_OK; 441} 442 443// DOMNode - DOMNode ---------------------------------------------------------- 444 445DOMNode::DOMNode(WebCore::Node* n) 446: m_node(0) 447{ 448 if (n) 449 n->ref(); 450 451 m_node = n; 452} 453 454DOMNode::~DOMNode() 455{ 456 if (m_node) 457 m_node->deref(); 458} 459 460IDOMNode* DOMNode::createInstance(WebCore::Node* n) 461{ 462 if (!n) 463 return 0; 464 465 HRESULT hr = S_OK; 466 IDOMNode* domNode = 0; 467 WebCore::Node::NodeType nodeType = n->nodeType(); 468 469 switch (nodeType) { 470 case WebCore::Node::ELEMENT_NODE: 471 { 472 IDOMElement* newElement = DOMElement::createInstance(static_cast<WebCore::Element*>(n)); 473 if (newElement) { 474 hr = newElement->QueryInterface(IID_IDOMNode, (void**)&domNode); 475 newElement->Release(); 476 } 477 } 478 break; 479 case WebCore::Node::DOCUMENT_NODE: 480 { 481 IDOMDocument* newDocument = DOMDocument::createInstance(n->document()); 482 if (newDocument) { 483 hr = newDocument->QueryInterface(IID_IDOMNode, (void**)&domNode); 484 newDocument->Release(); 485 } 486 } 487 break; 488 default: 489 { 490 DOMNode* newNode = new DOMNode(n); 491 hr = newNode->QueryInterface(IID_IDOMNode, (void**)&domNode); 492 } 493 break; 494 } 495 496 if (FAILED(hr)) 497 return 0; 498 499 return domNode; 500} 501 502// DOMNodeList - IUnknown ----------------------------------------------------- 503 504HRESULT STDMETHODCALLTYPE DOMNodeList::QueryInterface(REFIID riid, void** ppvObject) 505{ 506 *ppvObject = 0; 507 if (IsEqualGUID(riid, IID_IDOMNodeList)) 508 *ppvObject = static_cast<IDOMNodeList*>(this); 509 else 510 return DOMObject::QueryInterface(riid, ppvObject); 511 512 AddRef(); 513 return S_OK; 514} 515 516// IDOMNodeList --------------------------------------------------------------- 517 518HRESULT STDMETHODCALLTYPE DOMNodeList::item( 519 /* [in] */ UINT index, 520 /* [retval][out] */ IDOMNode **result) 521{ 522 *result = 0; 523 if (!m_nodeList) 524 return E_FAIL; 525 526 WebCore::Node* itemNode = m_nodeList->item(index); 527 if (!itemNode) 528 return E_FAIL; 529 530 *result = DOMNode::createInstance(itemNode); 531 return *result ? S_OK : E_FAIL; 532} 533 534HRESULT STDMETHODCALLTYPE DOMNodeList::length( 535 /* [retval][out] */ UINT *result) 536{ 537 *result = 0; 538 if (!m_nodeList) 539 return E_FAIL; 540 *result = m_nodeList->length(); 541 return S_OK; 542} 543 544// DOMNodeList - DOMNodeList -------------------------------------------------- 545 546DOMNodeList::DOMNodeList(WebCore::NodeList* l) 547: m_nodeList(0) 548{ 549 if (l) 550 l->ref(); 551 552 m_nodeList = l; 553} 554 555DOMNodeList::~DOMNodeList() 556{ 557 if (m_nodeList) 558 m_nodeList->deref(); 559} 560 561IDOMNodeList* DOMNodeList::createInstance(WebCore::NodeList* l) 562{ 563 if (!l) 564 return 0; 565 566 IDOMNodeList* domNodeList = 0; 567 DOMNodeList* newNodeList = new DOMNodeList(l); 568 if (FAILED(newNodeList->QueryInterface(IID_IDOMNodeList, (void**)&domNodeList))) 569 return 0; 570 571 return domNodeList; 572} 573 574// DOMDocument - IUnknown ----------------------------------------------------- 575 576HRESULT STDMETHODCALLTYPE DOMDocument::QueryInterface(REFIID riid, void** ppvObject) 577{ 578 *ppvObject = 0; 579 if (IsEqualGUID(riid, IID_IDOMDocument)) 580 *ppvObject = static_cast<IDOMDocument*>(this); 581 else if (IsEqualGUID(riid, IID_IDOMViewCSS)) 582 *ppvObject = static_cast<IDOMViewCSS*>(this); 583 else if (IsEqualGUID(riid, IID_IDOMDocumentEvent)) 584 *ppvObject = static_cast<IDOMDocumentEvent*>(this); 585 else 586 return DOMNode::QueryInterface(riid, ppvObject); 587 588 AddRef(); 589 return S_OK; 590} 591 592// DOMDocument ---------------------------------------------------------------- 593 594HRESULT STDMETHODCALLTYPE DOMDocument::doctype( 595 /* [retval][out] */ IDOMDocumentType** /*result*/) 596{ 597 ASSERT_NOT_REACHED(); 598 return E_NOTIMPL; 599} 600 601HRESULT STDMETHODCALLTYPE DOMDocument::implementation( 602 /* [retval][out] */ IDOMImplementation** /*result*/) 603{ 604 ASSERT_NOT_REACHED(); 605 return E_NOTIMPL; 606} 607 608HRESULT STDMETHODCALLTYPE DOMDocument::documentElement( 609 /* [retval][out] */ IDOMElement** result) 610{ 611 *result = DOMElement::createInstance(m_document->documentElement()); 612 return *result ? S_OK : E_FAIL; 613} 614 615HRESULT STDMETHODCALLTYPE DOMDocument::createElement( 616 /* [in] */ BSTR tagName, 617 /* [retval][out] */ IDOMElement** result) 618{ 619 if (!m_document) 620 return E_FAIL; 621 622 String tagNameString(tagName); 623 ExceptionCode ec; 624 *result = DOMElement::createInstance(m_document->createElement(tagNameString, ec).get()); 625 return *result ? S_OK : E_FAIL; 626} 627 628HRESULT STDMETHODCALLTYPE DOMDocument::createDocumentFragment( 629 /* [retval][out] */ IDOMDocumentFragment** /*result*/) 630{ 631 ASSERT_NOT_REACHED(); 632 return E_NOTIMPL; 633} 634 635HRESULT STDMETHODCALLTYPE DOMDocument::createTextNode( 636 /* [in] */ BSTR /*data*/, 637 /* [retval][out] */ IDOMText** /*result*/) 638{ 639 ASSERT_NOT_REACHED(); 640 return E_NOTIMPL; 641} 642 643HRESULT STDMETHODCALLTYPE DOMDocument::createComment( 644 /* [in] */ BSTR /*data*/, 645 /* [retval][out] */ IDOMComment** /*result*/) 646{ 647 ASSERT_NOT_REACHED(); 648 return E_NOTIMPL; 649} 650 651HRESULT STDMETHODCALLTYPE DOMDocument::createCDATASection( 652 /* [in] */ BSTR /*data*/, 653 /* [retval][out] */ IDOMCDATASection** /*result*/) 654{ 655 ASSERT_NOT_REACHED(); 656 return E_NOTIMPL; 657} 658 659HRESULT STDMETHODCALLTYPE DOMDocument::createProcessingInstruction( 660 /* [in] */ BSTR /*target*/, 661 /* [in] */ BSTR /*data*/, 662 /* [retval][out] */ IDOMProcessingInstruction** /*result*/) 663{ 664 ASSERT_NOT_REACHED(); 665 return E_NOTIMPL; 666} 667 668HRESULT STDMETHODCALLTYPE DOMDocument::createAttribute( 669 /* [in] */ BSTR /*name*/, 670 /* [retval][out] */ IDOMAttr** /*result*/) 671{ 672 ASSERT_NOT_REACHED(); 673 return E_NOTIMPL; 674} 675 676HRESULT STDMETHODCALLTYPE DOMDocument::createEntityReference( 677 /* [in] */ BSTR /*name*/, 678 /* [retval][out] */ IDOMEntityReference** /*result*/) 679{ 680 ASSERT_NOT_REACHED(); 681 return E_NOTIMPL; 682} 683 684HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagName( 685 /* [in] */ BSTR tagName, 686 /* [retval][out] */ IDOMNodeList** result) 687{ 688 if (!m_document) 689 return E_FAIL; 690 691 String tagNameString(tagName); 692 *result = DOMNodeList::createInstance(m_document->getElementsByTagName(tagNameString).get()); 693 return *result ? S_OK : E_FAIL; 694} 695 696HRESULT STDMETHODCALLTYPE DOMDocument::importNode( 697 /* [in] */ IDOMNode* /*importedNode*/, 698 /* [in] */ BOOL /*deep*/, 699 /* [retval][out] */ IDOMNode** /*result*/) 700{ 701 ASSERT_NOT_REACHED(); 702 return E_NOTIMPL; 703} 704 705HRESULT STDMETHODCALLTYPE DOMDocument::createElementNS( 706 /* [in] */ BSTR /*namespaceURI*/, 707 /* [in] */ BSTR /*qualifiedName*/, 708 /* [retval][out] */ IDOMElement** /*result*/) 709{ 710 ASSERT_NOT_REACHED(); 711 return E_NOTIMPL; 712} 713 714HRESULT STDMETHODCALLTYPE DOMDocument::createAttributeNS( 715 /* [in] */ BSTR /*namespaceURI*/, 716 /* [in] */ BSTR /*qualifiedName*/, 717 /* [retval][out] */ IDOMAttr** /*result*/) 718{ 719 ASSERT_NOT_REACHED(); 720 return E_NOTIMPL; 721} 722 723HRESULT STDMETHODCALLTYPE DOMDocument::getElementsByTagNameNS( 724 /* [in] */ BSTR namespaceURI, 725 /* [in] */ BSTR localName, 726 /* [retval][out] */ IDOMNodeList** result) 727{ 728 if (!m_document) 729 return E_FAIL; 730 731 String namespaceURIString(namespaceURI); 732 String localNameString(localName); 733 *result = DOMNodeList::createInstance(m_document->getElementsByTagNameNS(namespaceURIString, localNameString).get()); 734 return *result ? S_OK : E_FAIL; 735} 736 737HRESULT STDMETHODCALLTYPE DOMDocument::getElementById( 738 /* [in] */ BSTR elementId, 739 /* [retval][out] */ IDOMElement** result) 740{ 741 if (!m_document) 742 return E_FAIL; 743 744 String idString(elementId); 745 *result = DOMElement::createInstance(m_document->getElementById(idString)); 746 return *result ? S_OK : E_FAIL; 747} 748 749// DOMDocument - IDOMViewCSS -------------------------------------------------- 750 751HRESULT STDMETHODCALLTYPE DOMDocument::getComputedStyle( 752 /* [in] */ IDOMElement* elt, 753 /* [in] */ BSTR pseudoElt, 754 /* [retval][out] */ IDOMCSSStyleDeclaration** result) 755{ 756 if (!elt || !result) 757 return E_POINTER; 758 759 COMPtr<DOMElement> domEle; 760 HRESULT hr = elt->QueryInterface(IID_DOMElement, (void**)&domEle); 761 if (FAILED(hr)) 762 return hr; 763 Element* element = domEle->element(); 764 765 WebCore::DOMWindow* dv = m_document->defaultView(); 766 String pseudoEltString(pseudoElt); 767 768 if (!dv) 769 return E_FAIL; 770 771 *result = DOMCSSStyleDeclaration::createInstance(dv->getComputedStyle(element, pseudoEltString.impl()).get()); 772 return *result ? S_OK : E_FAIL; 773} 774 775// DOMDocument - IDOMDocumentEvent -------------------------------------------- 776 777HRESULT STDMETHODCALLTYPE DOMDocument::createEvent( 778 /* [in] */ BSTR eventType, 779 /* [retval][out] */ IDOMEvent **result) 780{ 781 String eventTypeString(eventType, SysStringLen(eventType)); 782 WebCore::ExceptionCode ec = 0; 783 *result = DOMEvent::createInstance(m_document->createEvent(eventTypeString, ec)); 784 return *result ? S_OK : E_FAIL; 785} 786 787// DOMDocument - DOMDocument -------------------------------------------------- 788 789DOMDocument::DOMDocument(WebCore::Document* d) 790: DOMNode(d) 791, m_document(d) 792{ 793} 794 795DOMDocument::~DOMDocument() 796{ 797} 798 799IDOMDocument* DOMDocument::createInstance(WebCore::Document* d) 800{ 801 if (!d) 802 return 0; 803 804 HRESULT hr; 805 IDOMDocument* domDocument = 0; 806 807 if (d->isHTMLDocument()) { 808 DOMHTMLDocument* newDocument = new DOMHTMLDocument(d); 809 hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument); 810 } else { 811 DOMDocument* newDocument = new DOMDocument(d); 812 hr = newDocument->QueryInterface(IID_IDOMDocument, (void**)&domDocument); 813 } 814 815 if (FAILED(hr)) 816 return 0; 817 818 return domDocument; 819} 820 821// DOMElement - IUnknown ------------------------------------------------------ 822 823HRESULT STDMETHODCALLTYPE DOMElement::QueryInterface(REFIID riid, void** ppvObject) 824{ 825 *ppvObject = 0; 826 if (IsEqualGUID(riid, IID_IDOMElement)) 827 *ppvObject = static_cast<IDOMElement*>(this); 828 else if (IsEqualGUID(riid, IID_DOMElement)) 829 *ppvObject = static_cast<DOMElement*>(this); 830 else if (IsEqualGUID(riid, IID_IDOMElementPrivate)) 831 *ppvObject = static_cast<IDOMElementPrivate*>(this); 832 else if (IsEqualGUID(riid, IID_IDOMNodeExtensions)) 833 *ppvObject = static_cast<IDOMNodeExtensions*>(this); 834 else if (IsEqualGUID(riid, IID_IDOMElementCSSInlineStyle)) 835 *ppvObject = static_cast<IDOMElementCSSInlineStyle*>(this); 836 else if (IsEqualGUID(riid, IID_IDOMElementExtensions)) 837 *ppvObject = static_cast<IDOMElementExtensions*>(this); 838 else 839 return DOMNode::QueryInterface(riid, ppvObject); 840 841 AddRef(); 842 return S_OK; 843} 844 845// DOMElement - IDOMNodeExtensions--------------------------------------------- 846 847HRESULT STDMETHODCALLTYPE DOMElement::boundingBox( 848 /* [retval][out] */ LPRECT rect) 849{ 850 ::SetRectEmpty(rect); 851 852 if (!m_element) 853 return E_FAIL; 854 855 WebCore::RenderObject *renderer = m_element->renderer(); 856 if (renderer) { 857 IntRect boundsIntRect = renderer->absoluteBoundingBoxRect(); 858 rect->left = boundsIntRect.x(); 859 rect->top = boundsIntRect.y(); 860 rect->right = boundsIntRect.x() + boundsIntRect.width(); 861 rect->bottom = boundsIntRect.y() + boundsIntRect.height(); 862 } 863 864 return S_OK; 865} 866 867HRESULT STDMETHODCALLTYPE DOMElement::lineBoxRects( 868 /* [size_is][in] */ RECT* /*rects*/, 869 /* [in] */ int /*cRects*/) 870{ 871 return E_NOTIMPL; 872} 873 874// IDOMElement ---------------------------------------------------------------- 875 876HRESULT STDMETHODCALLTYPE DOMElement::tagName( 877 /* [retval][out] */ BSTR* result) 878{ 879 if (!m_element) 880 return E_FAIL; 881 882 if (!result) 883 return E_POINTER; 884 885 *result = BString(m_element->tagName()).release(); 886 return S_OK; 887} 888 889HRESULT STDMETHODCALLTYPE DOMElement::getAttribute( 890 /* [in] */ BSTR name, 891 /* [retval][out] */ BSTR* result) 892{ 893 if (!m_element) 894 return E_FAIL; 895 WTF::String nameString(name, SysStringLen(name)); 896 WTF::String& attrValueString = (WTF::String&) m_element->getAttribute(nameString); 897 *result = SysAllocStringLen(attrValueString.characters(), attrValueString.length()); 898 if (attrValueString.length() && !*result) 899 return E_OUTOFMEMORY; 900 return S_OK; 901} 902 903HRESULT STDMETHODCALLTYPE DOMElement::setAttribute( 904 /* [in] */ BSTR name, 905 /* [in] */ BSTR value) 906{ 907 if (!m_element) 908 return E_FAIL; 909 910 WTF::String nameString(name, SysStringLen(name)); 911 WTF::String valueString(value, SysStringLen(value)); 912 WebCore::ExceptionCode ec = 0; 913 m_element->setAttribute(nameString, valueString, ec); 914 return ec ? E_FAIL : S_OK; 915} 916 917HRESULT STDMETHODCALLTYPE DOMElement::removeAttribute( 918 /* [in] */ BSTR /*name*/) 919{ 920 ASSERT_NOT_REACHED(); 921 return E_NOTIMPL; 922} 923 924HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNode( 925 /* [in] */ BSTR /*name*/, 926 /* [retval][out] */ IDOMAttr** /*result*/) 927{ 928 ASSERT_NOT_REACHED(); 929 return E_NOTIMPL; 930} 931 932HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNode( 933 /* [in] */ IDOMAttr* /*newAttr*/, 934 /* [retval][out] */ IDOMAttr** /*result*/) 935{ 936 ASSERT_NOT_REACHED(); 937 return E_NOTIMPL; 938} 939 940HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNode( 941 /* [in] */ IDOMAttr* /*oldAttr*/, 942 /* [retval][out] */ IDOMAttr** /*result*/) 943{ 944 ASSERT_NOT_REACHED(); 945 return E_NOTIMPL; 946} 947 948HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagName( 949 /* [in] */ BSTR /*name*/, 950 /* [retval][out] */ IDOMNodeList** /*result*/) 951{ 952 ASSERT_NOT_REACHED(); 953 return E_NOTIMPL; 954} 955 956HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNS( 957 /* [in] */ BSTR /*namespaceURI*/, 958 /* [in] */ BSTR /*localName*/, 959 /* [retval][out] */ BSTR* /*result*/) 960{ 961 ASSERT_NOT_REACHED(); 962 return E_NOTIMPL; 963} 964 965HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNS( 966 /* [in] */ BSTR /*namespaceURI*/, 967 /* [in] */ BSTR /*qualifiedName*/, 968 /* [in] */ BSTR /*value*/) 969{ 970 ASSERT_NOT_REACHED(); 971 return E_NOTIMPL; 972} 973 974HRESULT STDMETHODCALLTYPE DOMElement::removeAttributeNS( 975 /* [in] */ BSTR /*namespaceURI*/, 976 /* [in] */ BSTR /*localName*/) 977{ 978 ASSERT_NOT_REACHED(); 979 return E_NOTIMPL; 980} 981 982HRESULT STDMETHODCALLTYPE DOMElement::getAttributeNodeNS( 983 /* [in] */ BSTR /*namespaceURI*/, 984 /* [in] */ BSTR /*localName*/, 985 /* [retval][out] */ IDOMAttr** /*result*/) 986{ 987 ASSERT_NOT_REACHED(); 988 return E_NOTIMPL; 989} 990 991HRESULT STDMETHODCALLTYPE DOMElement::setAttributeNodeNS( 992 /* [in] */ IDOMAttr* /*newAttr*/, 993 /* [retval][out] */ IDOMAttr** /*result*/) 994{ 995 ASSERT_NOT_REACHED(); 996 return E_NOTIMPL; 997} 998 999HRESULT STDMETHODCALLTYPE DOMElement::getElementsByTagNameNS( 1000 /* [in] */ BSTR /*namespaceURI*/, 1001 /* [in] */ BSTR /*localName*/, 1002 /* [retval][out] */ IDOMNodeList** /*result*/) 1003{ 1004 ASSERT_NOT_REACHED(); 1005 return E_NOTIMPL; 1006} 1007 1008HRESULT STDMETHODCALLTYPE DOMElement::hasAttribute( 1009 /* [in] */ BSTR /*name*/, 1010 /* [retval][out] */ BOOL* /*result*/) 1011{ 1012 ASSERT_NOT_REACHED(); 1013 return E_NOTIMPL; 1014} 1015 1016HRESULT STDMETHODCALLTYPE DOMElement::hasAttributeNS( 1017 /* [in] */ BSTR /*namespaceURI*/, 1018 /* [in] */ BSTR /*localName*/, 1019 /* [retval][out] */ BOOL* /*result*/) 1020{ 1021 ASSERT_NOT_REACHED(); 1022 return E_NOTIMPL; 1023} 1024 1025HRESULT STDMETHODCALLTYPE DOMElement::focus( void) 1026{ 1027 if (!m_element) 1028 return E_FAIL; 1029 m_element->focus(); 1030 return S_OK; 1031} 1032 1033HRESULT STDMETHODCALLTYPE DOMElement::blur( void) 1034{ 1035 if (!m_element) 1036 return E_FAIL; 1037 m_element->blur(); 1038 return S_OK; 1039} 1040 1041// IDOMElementPrivate --------------------------------------------------------- 1042 1043HRESULT DOMElement::coreElement(void **element) 1044{ 1045 if (!m_element) 1046 return E_FAIL; 1047 *element = (void*) m_element; 1048 return S_OK; 1049} 1050 1051HRESULT STDMETHODCALLTYPE DOMElement::isEqual( 1052 /* [in] */ IDOMElement *other, 1053 /* [retval][out] */ BOOL *result) 1054{ 1055 *result = FALSE; 1056 1057 if (!other || !result) 1058 return E_POINTER; 1059 1060 IDOMElementPrivate* otherPriv; 1061 HRESULT hr = other->QueryInterface(IID_IDOMElementPrivate, (void**) &otherPriv); 1062 if (FAILED(hr)) 1063 return hr; 1064 1065 void* otherCoreEle; 1066 hr = otherPriv->coreElement(&otherCoreEle); 1067 otherPriv->Release(); 1068 if (FAILED(hr)) 1069 return hr; 1070 1071 *result = (otherCoreEle == (void*)m_element) ? TRUE : FALSE; 1072 return S_OK; 1073} 1074 1075HRESULT STDMETHODCALLTYPE DOMElement::isFocused( 1076 /* [retval][out] */ BOOL *result) 1077{ 1078 if (!m_element) 1079 return E_FAIL; 1080 1081 if (m_element->document()->focusedNode() == m_element) 1082 *result = TRUE; 1083 else 1084 *result = FALSE; 1085 1086 return S_OK; 1087} 1088 1089HRESULT STDMETHODCALLTYPE DOMElement::innerText( 1090 /* [retval][out] */ BSTR* result) 1091{ 1092 if (!result) { 1093 ASSERT_NOT_REACHED(); 1094 return E_POINTER; 1095 } 1096 1097 if (!m_element) { 1098 ASSERT_NOT_REACHED(); 1099 return E_FAIL; 1100 } 1101 1102 *result = BString(m_element->innerText()).release(); 1103 return S_OK; 1104} 1105 1106HRESULT STDMETHODCALLTYPE DOMElement::font(WebFontDescription* webFontDescription) 1107{ 1108 if (!webFontDescription) { 1109 ASSERT_NOT_REACHED(); 1110 return E_POINTER; 1111 } 1112 1113 ASSERT(m_element); 1114 1115 WebCore::RenderObject* renderer = m_element->renderer(); 1116 if (!renderer) 1117 return E_FAIL; 1118 1119 FontDescription fontDescription = renderer->style()->font().fontDescription(); 1120 AtomicString family = fontDescription.family().family(); 1121 webFontDescription->family = family.characters(); 1122 webFontDescription->familyLength = family.length(); 1123 webFontDescription->size = fontDescription.computedSize(); 1124 webFontDescription->bold = fontDescription.weight() >= WebCore::FontWeight600; 1125 webFontDescription->italic = fontDescription.italic(); 1126 1127 return S_OK; 1128} 1129 1130HRESULT STDMETHODCALLTYPE DOMElement::renderedImage(HBITMAP* image) 1131{ 1132 if (!image) { 1133 ASSERT_NOT_REACHED(); 1134 return E_POINTER; 1135 } 1136 *image = 0; 1137 1138 ASSERT(m_element); 1139 1140 Frame* frame = m_element->document()->frame(); 1141 if (!frame) 1142 return E_FAIL; 1143 1144 *image = frame->nodeImage(m_element); 1145 if (!*image) 1146 return E_FAIL; 1147 1148 return S_OK; 1149} 1150 1151HRESULT STDMETHODCALLTYPE DOMElement::markerTextForListItem( 1152 /* [retval][out] */ BSTR* markerText) 1153{ 1154 if (!markerText) 1155 return E_POINTER; 1156 1157 ASSERT(m_element); 1158 1159 *markerText = BString(WebCore::markerTextForListItem(m_element)).release(); 1160 return S_OK; 1161} 1162 1163// IDOMElementCSSInlineStyle -------------------------------------------------- 1164 1165HRESULT STDMETHODCALLTYPE DOMElement::style( 1166 /* [retval][out] */ IDOMCSSStyleDeclaration** result) 1167{ 1168 if (!result) 1169 return E_POINTER; 1170 if (!m_element) 1171 return E_FAIL; 1172 1173 WebCore::CSSStyleDeclaration* style = m_element->style(); 1174 if (!style) 1175 return E_FAIL; 1176 1177 *result = DOMCSSStyleDeclaration::createInstance(style); 1178 return *result ? S_OK : E_FAIL; 1179} 1180 1181// IDOMElementExtensions ------------------------------------------------------ 1182 1183HRESULT STDMETHODCALLTYPE DOMElement::offsetLeft( 1184 /* [retval][out] */ int* result) 1185{ 1186 if (!m_element) 1187 return E_FAIL; 1188 1189 *result = m_element->offsetLeft(); 1190 return S_OK; 1191} 1192 1193HRESULT STDMETHODCALLTYPE DOMElement::offsetTop( 1194 /* [retval][out] */ int* result) 1195{ 1196 if (!m_element) 1197 return E_FAIL; 1198 1199 *result = m_element->offsetTop(); 1200 return S_OK; 1201} 1202 1203HRESULT STDMETHODCALLTYPE DOMElement::offsetWidth( 1204 /* [retval][out] */ int* result) 1205{ 1206 if (!m_element) 1207 return E_FAIL; 1208 1209 *result = m_element->offsetWidth(); 1210 return S_OK; 1211} 1212 1213HRESULT STDMETHODCALLTYPE DOMElement::offsetHeight( 1214 /* [retval][out] */ int* result) 1215{ 1216 if (!m_element) 1217 return E_FAIL; 1218 1219 *result = m_element->offsetHeight(); 1220 return S_OK; 1221} 1222 1223HRESULT STDMETHODCALLTYPE DOMElement::offsetParent( 1224 /* [retval][out] */ IDOMElement** /*result*/) 1225{ 1226 // FIXME 1227 ASSERT_NOT_REACHED(); 1228 return E_NOTIMPL; 1229} 1230 1231HRESULT STDMETHODCALLTYPE DOMElement::clientWidth( 1232 /* [retval][out] */ int* result) 1233{ 1234 if (!m_element) 1235 return E_FAIL; 1236 1237 *result = m_element->clientWidth(); 1238 return S_OK; 1239} 1240 1241HRESULT STDMETHODCALLTYPE DOMElement::clientHeight( 1242 /* [retval][out] */ int* result) 1243{ 1244 if (!m_element) 1245 return E_FAIL; 1246 1247 *result = m_element->clientHeight(); 1248 return S_OK; 1249} 1250 1251HRESULT STDMETHODCALLTYPE DOMElement::scrollLeft( 1252 /* [retval][out] */ int* result) 1253{ 1254 if (!m_element) 1255 return E_FAIL; 1256 1257 *result = m_element->scrollLeft(); 1258 return S_OK; 1259} 1260 1261HRESULT STDMETHODCALLTYPE DOMElement::setScrollLeft( 1262 /* [in] */ int /*newScrollLeft*/) 1263{ 1264 // FIXME 1265 ASSERT_NOT_REACHED(); 1266 return E_NOTIMPL; 1267} 1268 1269HRESULT STDMETHODCALLTYPE DOMElement::scrollTop( 1270 /* [retval][out] */ int* result) 1271{ 1272 if (!m_element) 1273 return E_FAIL; 1274 1275 *result = m_element->scrollTop(); 1276 return S_OK; 1277} 1278 1279HRESULT STDMETHODCALLTYPE DOMElement::setScrollTop( 1280 /* [in] */ int /*newScrollTop*/) 1281{ 1282 // FIXME 1283 ASSERT_NOT_REACHED(); 1284 return E_NOTIMPL; 1285} 1286 1287HRESULT STDMETHODCALLTYPE DOMElement::scrollWidth( 1288 /* [retval][out] */ int* result) 1289{ 1290 if (!m_element) 1291 return E_FAIL; 1292 1293 *result = m_element->scrollWidth(); 1294 return S_OK; 1295} 1296 1297HRESULT STDMETHODCALLTYPE DOMElement::scrollHeight( 1298 /* [retval][out] */ int* result) 1299{ 1300 if (!m_element) 1301 return E_FAIL; 1302 1303 *result = m_element->scrollHeight(); 1304 return S_OK; 1305} 1306 1307HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoView( 1308 /* [in] */ BOOL alignWithTop) 1309{ 1310 if (!m_element) 1311 return E_FAIL; 1312 1313 m_element->scrollIntoView(!!alignWithTop); 1314 return S_OK; 1315} 1316 1317HRESULT STDMETHODCALLTYPE DOMElement::scrollIntoViewIfNeeded( 1318 /* [in] */ BOOL centerIfNeeded) 1319{ 1320 if (!m_element) 1321 return E_FAIL; 1322 1323 m_element->scrollIntoViewIfNeeded(!!centerIfNeeded); 1324 return S_OK; 1325} 1326 1327// DOMElement ----------------------------------------------------------------- 1328 1329DOMElement::DOMElement(WebCore::Element* e) 1330: DOMNode(e) 1331, m_element(e) 1332{ 1333} 1334 1335DOMElement::~DOMElement() 1336{ 1337} 1338 1339IDOMElement* DOMElement::createInstance(WebCore::Element* e) 1340{ 1341 if (!e) 1342 return 0; 1343 1344 HRESULT hr; 1345 IDOMElement* domElement = 0; 1346 1347 if (e->hasTagName(formTag)) { 1348 DOMHTMLFormElement* newElement = new DOMHTMLFormElement(e); 1349 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1350 } else if (e->hasTagName(iframeTag)) { 1351 DOMHTMLIFrameElement* newElement = new DOMHTMLIFrameElement(e); 1352 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1353 } else if (e->hasTagName(inputTag)) { 1354 DOMHTMLInputElement* newElement = new DOMHTMLInputElement(e); 1355 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1356 } else if (e->hasTagName(optionTag)) { 1357 DOMHTMLOptionElement* newElement = new DOMHTMLOptionElement(e); 1358 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1359 } else if (e->hasTagName(selectTag)) { 1360 DOMHTMLSelectElement* newElement = new DOMHTMLSelectElement(e); 1361 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1362 } else if (e->hasTagName(textareaTag)) { 1363 DOMHTMLTextAreaElement* newElement = new DOMHTMLTextAreaElement(e); 1364 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1365 } else if (e->isHTMLElement()) { 1366 DOMHTMLElement* newElement = new DOMHTMLElement(e); 1367 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1368 } else { 1369 DOMElement* newElement = new DOMElement(e); 1370 hr = newElement->QueryInterface(IID_IDOMElement, (void**)&domElement); 1371 } 1372 1373 if (FAILED(hr)) 1374 return 0; 1375 1376 return domElement; 1377} 1378