/* * Copyright (C) 2004 Apple Computer, Inc. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source exceptionCode must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE COMPUTER, INC. OR * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ #import "DOM.h" #include <objc/objc-class.h> #import <JavaScriptCore/WebScriptObjectPrivate.h> #import "csshelper.h" #import "dom2_range.h" #import "dom2_rangeimpl.h" #import "dom2_traversal.h" #import "dom2_viewsimpl.h" #import "dom_doc.h" #import "dom_docimpl.h" #import "dom_element.h" #import "dom_elementimpl.h" #import "dom_exception.h" #import "dom_node.h" #import "dom_nodeimpl.h" #import "dom_string.h" #import "dom_stringimpl.h" #import "dom_text.h" #import "dom_textimpl.h" #import "dom_xml.h" #import "dom_xmlimpl.h" #import "html_elementimpl.h" #import "htmltags.h" #import "khtml_part.h" #import "render_object.h" #import "DOMEventsInternal.h" #import "DOMHTML.h" #import "DOMInternal.h" #import "DOMPrivate.h" #import "KWQAssertions.h" #import "KWQFoundationExtras.h" #import "KWQKHTMLPart.h" using DOM::Attr; using DOM::AttrImpl; using DOM::CharacterDataImpl; using DOM::DocumentFragmentImpl; using DOM::DocumentType; using DOM::DocumentTypeImpl; using DOM::Document; using DOM::DocumentImpl; using DOM::DOMImplementationImpl; using DOM::DOMString; using DOM::DOMStringImpl; using DOM::Element; using DOM::ElementImpl; using DOM::EntityImpl; using DOM::HTMLElementImpl; using DOM::NamedNodeMap; using DOM::NamedNodeMapImpl; using DOM::Node; using DOM::NodeFilter; using DOM::NodeFilterCondition; using DOM::NodeFilterImpl; using DOM::NodeImpl; using DOM::NodeIteratorImpl; using DOM::NodeListImpl; using DOM::NotationImpl; using DOM::ProcessingInstructionImpl; using DOM::Range; using DOM::RangeException; using DOM::RangeImpl; using DOM::TextImpl; using DOM::TreeWalkerImpl; using khtml::RenderObject; @interface DOMAttr (WebCoreInternal) + (DOMAttr *)_attrWithImpl:(AttrImpl *)impl; - (AttrImpl *)_attrImpl; @end @interface DOMImplementation (WebCoreInternal) + (DOMImplementation *)_DOMImplementationWithImpl:(DOMImplementationImpl *)impl; - (DOMImplementationImpl *)_DOMImplementationImpl; @end @interface DOMNamedNodeMap (WebCoreInternal) + (DOMNamedNodeMap *)_namedNodeMapWithImpl:(NamedNodeMapImpl *)impl; @end //------------------------------------------------------------------------------------------ // Factory methods inline NamedNodeMap NamedNodeMapImpl::createInstance(NamedNodeMapImpl *impl) { return NamedNodeMap(impl); } inline Attr AttrImpl::createInstance(AttrImpl *impl) { return Attr(impl); } inline Element ElementImpl::createInstance(ElementImpl *impl) { return Element(impl); } inline DocumentType DocumentTypeImpl::createInstance(DocumentTypeImpl *impl) { return DocumentType(impl); } inline Document DocumentImpl::createInstance(DocumentImpl *impl) { return Document(impl); } //------------------------------------------------------------------------------------------ // DOMObject @implementation DOMObject // Prevent creation of DOM objects by clients who just "[[xxx alloc] init]". - (id)init { [NSException raise:NSGenericException format:@"+[%s init]: should never be used", [self class]->name]; [self release]; return nil; } - (void)dealloc { if (_internal) { removeDOMWrapper(_internal); } [super dealloc]; } - (void)finalize { if (_internal) { removeDOMWrapper(_internal); } [super finalize]; } - (id)copyWithZone:(NSZone *)zone { return [self retain]; } @end @implementation DOMObject (WebCoreInternal) - (id)_init { return [super _init]; } @end //------------------------------------------------------------------------------------------ // DOMNode @implementation DOMNode - (void)dealloc { if (_internal) { DOM_cast<NodeImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<NodeImpl *>(_internal)->deref(); } [super finalize]; } - (NSString *)description { if (!_internal) { return [NSString stringWithFormat:@"<%@: null>", [[self class] description], self]; } NSString *value = [self nodeValue]; if (value) { return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>", [[self class] description], [self nodeName], _internal, value]; } return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal]; } - (NSString *)nodeName { return [self _nodeImpl]->nodeName(); } - (NSString *)nodeValue { // Documentation says we can raise a DOMSTRING_SIZE_ERR. // However, the lower layer does not report that error up to us. return [self _nodeImpl]->nodeValue(); } - (void)setNodeValue:(NSString *)string { ASSERT(string); int exceptionCode = 0; [self _nodeImpl]->setNodeValue(string, exceptionCode); raiseOnDOMError(exceptionCode); } - (unsigned short)nodeType { return [self _nodeImpl]->nodeType(); } - (DOMNode *)parentNode { return [DOMNode _nodeWithImpl:[self _nodeImpl]->parentNode()]; } - (DOMNodeList *)childNodes { return [DOMNodeList _nodeListWithImpl:[self _nodeImpl]->childNodes()]; } - (DOMNode *)firstChild { return [DOMNode _nodeWithImpl:[self _nodeImpl]->firstChild()]; } - (DOMNode *)lastChild { return [DOMNode _nodeWithImpl:[self _nodeImpl]->lastChild()]; } - (DOMNode *)previousSibling { return [DOMNode _nodeWithImpl:[self _nodeImpl]->previousSibling()]; } - (DOMNode *)nextSibling { return [DOMNode _nodeWithImpl:[self _nodeImpl]->nextSibling()]; } - (DOMNamedNodeMap *)attributes { // DOM level 2 core specification says: // A NamedNodeMap containing the attributes of this node (if it is an Element) or null otherwise. return nil; } - (DOMDocument *)ownerDocument { return [DOMDocument _documentWithImpl:[self _nodeImpl]->getDocument()]; } - (DOMNode *)insertBefore:(DOMNode *)newChild :(DOMNode *)refChild { ASSERT(newChild); ASSERT(refChild); int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeImpl]->insertBefore([newChild _nodeImpl], [refChild _nodeImpl], exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)replaceChild:(DOMNode *)newChild :(DOMNode *)oldChild { ASSERT(newChild); ASSERT(oldChild); int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeImpl]->replaceChild([newChild _nodeImpl], [oldChild _nodeImpl], exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)removeChild:(DOMNode *)oldChild { ASSERT(oldChild); int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeImpl]->removeChild([oldChild _nodeImpl], exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)appendChild:(DOMNode *)newChild { ASSERT(newChild); int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeImpl]->appendChild([newChild _nodeImpl], exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (BOOL)hasChildNodes { return [self _nodeImpl]->hasChildNodes(); } - (DOMNode *)cloneNode:(BOOL)deep { return [DOMNode _nodeWithImpl:[self _nodeImpl]->cloneNode(deep)]; } - (void)normalize { [self _nodeImpl]->normalize(); } - (BOOL)isSupported:(NSString *)feature :(NSString *)version { ASSERT(feature); ASSERT(version); // Method not reflected in DOM::NodeImpl interface return Node([self _nodeImpl]).isSupported(feature, version); } - (NSString *)namespaceURI { // Method not reflected in DOM::NodeImpl interface return Node([self _nodeImpl]).namespaceURI(); } - (NSString *)prefix { return [self _nodeImpl]->prefix(); } - (void)setPrefix:(NSString *)prefix { ASSERT(prefix); int exceptionCode = 0; [self _nodeImpl]->setPrefix(prefix, exceptionCode); raiseOnDOMError(exceptionCode); } - (NSString *)localName { return [self _nodeImpl]->localName(); } - (BOOL)hasAttributes { // Method not reflected in DOM::NodeImpl interface return Node([self _nodeImpl]).hasAttributes(); } - (void)addEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture { ERROR("unimplemented"); } - (void)removeEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture { ERROR("unimplemented"); } - (BOOL)dispatchEvent:(DOMEvent *)event { int exceptionCode = 0; BOOL result = [self _nodeImpl]->dispatchEvent([event _eventImpl], exceptionCode); raiseOnDOMError(exceptionCode); return result; } @end @implementation DOMNode (WebCoreInternal) - (id)_initWithNodeImpl:(NodeImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMNode *)_nodeWithImpl:(NodeImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; Class wrapperClass = nil; switch (impl->nodeType()) { case Node::ELEMENT_NODE: if (impl->isHTMLElement()) { // FIXME: There are no identifiers for HTMLHeadingElement, HTMLModElement, // HTMLTableCaptionElement, HTMLTableColElement, HTMLTableSectionElement. // Find other ways to identify them. switch (impl->identifier()) { case ID_HTML: wrapperClass = [DOMHTMLHtmlElement class]; break; case ID_HEAD: wrapperClass = [DOMHTMLHeadElement class]; break; case ID_LINK: wrapperClass = [DOMHTMLLinkElement class]; break; case ID_TITLE: wrapperClass = [DOMHTMLTitleElement class]; break; case ID_META: wrapperClass = [DOMHTMLMetaElement class]; break; case ID_BASE: wrapperClass = [DOMHTMLBaseElement class]; break; case ID_ISINDEX: wrapperClass = [DOMHTMLIsIndexElement class]; break; case ID_STYLE: wrapperClass = [DOMHTMLStyleElement class]; break; case ID_BODY: wrapperClass = [DOMHTMLBodyElement class]; break; case ID_FORM: wrapperClass = [DOMHTMLFormElement class]; break; case ID_SELECT: wrapperClass = [DOMHTMLSelectElement class]; break; case ID_OPTGROUP: wrapperClass = [DOMHTMLOptGroupElement class]; break; case ID_OPTION: wrapperClass = [DOMHTMLOptionElement class]; break; case ID_INPUT: wrapperClass = [DOMHTMLInputElement class]; break; case ID_TEXTAREA: wrapperClass = [DOMHTMLTextAreaElement class]; break; case ID_BUTTON: wrapperClass = [DOMHTMLButtonElement class]; break; case ID_LABEL: wrapperClass = [DOMHTMLLabelElement class]; break; case ID_FIELDSET: wrapperClass = [DOMHTMLFieldSetElement class]; break; case ID_LEGEND: wrapperClass = [DOMHTMLLegendElement class]; break; case ID_UL: wrapperClass = [DOMHTMLUListElement class]; break; case ID_OL: wrapperClass = [DOMHTMLOListElement class]; break; case ID_DL: wrapperClass = [DOMHTMLDListElement class]; break; case ID_DIR: wrapperClass = [DOMHTMLDirectoryElement class]; break; case ID_MENU: wrapperClass = [DOMHTMLMenuElement class]; break; case ID_LI: wrapperClass = [DOMHTMLLIElement class]; break; case ID_DIV: wrapperClass = [DOMHTMLDivElement class]; break; case ID_P: wrapperClass = [DOMHTMLParagraphElement class]; break; case ID_Q: wrapperClass = [DOMHTMLQuoteElement class]; break; case ID_PRE: wrapperClass = [DOMHTMLPreElement class]; break; case ID_BR: wrapperClass = [DOMHTMLBRElement class]; break; case ID_BASEFONT: wrapperClass = [DOMHTMLFontElement class]; break; case ID_FONT: wrapperClass = [DOMHTMLFontElement class]; break; case ID_HR: wrapperClass = [DOMHTMLHRElement class]; break; case ID_A: wrapperClass = [DOMHTMLAnchorElement class]; break; case ID_IMG: wrapperClass = [DOMHTMLImageElement class]; break; case ID_OBJECT: wrapperClass = [DOMHTMLObjectElement class]; break; case ID_PARAM: wrapperClass = [DOMHTMLParamElement class]; break; case ID_APPLET: wrapperClass = [DOMHTMLAppletElement class]; break; case ID_MAP: wrapperClass = [DOMHTMLMapElement class]; break; case ID_AREA: wrapperClass = [DOMHTMLAreaElement class]; break; case ID_SCRIPT: wrapperClass = [DOMHTMLScriptElement class]; break; case ID_TABLE: wrapperClass = [DOMHTMLTableElement class]; break; case ID_TD: wrapperClass = [DOMHTMLTableCellElement class]; break; case ID_TR: wrapperClass = [DOMHTMLTableRowElement class]; break; case ID_FRAMESET: wrapperClass = [DOMHTMLFrameSetElement class]; break; case ID_FRAME: wrapperClass = [DOMHTMLFrameElement class]; break; case ID_IFRAME: wrapperClass = [DOMHTMLIFrameElement class]; break; default: wrapperClass = [DOMHTMLElement class]; } } else { wrapperClass = [DOMElement class]; } break; case Node::ATTRIBUTE_NODE: wrapperClass = [DOMAttr class]; break; case Node::TEXT_NODE: wrapperClass = [DOMText class]; break; case Node::CDATA_SECTION_NODE: wrapperClass = [DOMCDATASection class]; break; case Node::ENTITY_REFERENCE_NODE: wrapperClass = [DOMEntityReference class]; break; case Node::ENTITY_NODE: wrapperClass = [DOMEntity class]; break; case Node::PROCESSING_INSTRUCTION_NODE: wrapperClass = [DOMProcessingInstruction class]; break; case Node::COMMENT_NODE: wrapperClass = [DOMComment class]; break; case Node::DOCUMENT_NODE: if (static_cast<DocumentImpl *>(impl)->isHTMLDocument()) { wrapperClass = [DOMHTMLDocument class]; } else { wrapperClass = [DOMDocument class]; } break; case Node::DOCUMENT_TYPE_NODE: wrapperClass = [DOMDocumentType class]; break; case Node::DOCUMENT_FRAGMENT_NODE: wrapperClass = [DOMDocumentFragment class]; break; case Node::NOTATION_NODE: wrapperClass = [DOMNotation class]; break; } return [[[wrapperClass alloc] _initWithNodeImpl:impl] autorelease]; } - (NodeImpl *)_nodeImpl { return DOM_cast<NodeImpl *>(_internal); } - (BOOL)isContentEditable { return [self _nodeImpl]->isContentEditable(); } - (const KJS::Bindings::RootObject *)_executionContext { NodeImpl *n = [self _nodeImpl]; if (!n) return 0; DocumentImpl *doc = n->getDocument(); if (!doc) return 0; KWQKHTMLPart *p = KWQ(doc->part()); if (!p) return 0; return p->executionContextForDOM(); } @end //------------------------------------------------------------------------------------------ // DOMNamedNodeMap @implementation DOMNamedNodeMap - (void)dealloc { if (_internal) { DOM_cast<NamedNodeMapImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<NamedNodeMapImpl *>(_internal)->deref(); } [super finalize]; } - (NamedNodeMapImpl *)_namedNodeMapImpl { return DOM_cast<NamedNodeMapImpl *>(_internal); } - (DOMNode *)getNamedItem:(NSString *)name { ASSERT(name); // Method not reflected in DOM::NamedNodeMapImpl interface NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.getNamedItem(name)); return [DOMNode _nodeWithImpl:result.handle()]; } - (DOMNode *)setNamedItem:(DOMNode *)arg { ASSERT(arg); // Method not reflected in DOM::NamedNodeMapImpl interface try { NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.setNamedItem([arg _nodeImpl])); return [DOMNode _nodeWithImpl:result.handle()]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNode *)removeNamedItem:(NSString *)name { ASSERT(name); // Method not reflected in DOM::NamedNodeMapImpl interface try { NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.removeNamedItem(name)); return [DOMNode _nodeWithImpl:result.handle()]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNode *)item:(unsigned long)index { return [DOMNode _nodeWithImpl:[self _namedNodeMapImpl]->item(index)]; } - (unsigned long)length { return [self _namedNodeMapImpl]->length(); } - (DOMNode *)getNamedItemNS:(NSString *)namespaceURI :(NSString *)localName { if (!namespaceURI || !localName) { return nil; } // Method not reflected in DOM::NamedNodeMapImpl interface NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.getNamedItemNS(namespaceURI, localName)); return [DOMNode _nodeWithImpl:result.handle()]; } - (DOMNode *)setNamedItemNS:(DOMNode *)arg { ASSERT(arg); // Method not reflected in DOM::NamedNodeMapImpl interface try { NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.setNamedItemNS([arg _nodeImpl])); return [DOMNode _nodeWithImpl:result.handle()]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNode *)removeNamedItemNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); // Method not reflected in DOM::NamedNodeMapImpl interface try { NamedNodeMap map = NamedNodeMapImpl::createInstance([self _namedNodeMapImpl]); Node result(map.removeNamedItemNS(namespaceURI, localName)); return [DOMNode _nodeWithImpl:result.handle()]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } @end @implementation DOMNamedNodeMap (WebCoreInternal) - (id)_initWithNamedNodeMapImpl:(NamedNodeMapImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMNamedNodeMap *)_namedNodeMapWithImpl:(NamedNodeMapImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithNamedNodeMapImpl:impl] autorelease]; } @end //------------------------------------------------------------------------------------------ // DOMNodeList @implementation DOMNodeList - (void)dealloc { if (_internal) { DOM_cast<NodeListImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<NodeListImpl *>(_internal)->deref(); } [super finalize]; } - (NodeListImpl *)_nodeListImpl { return DOM_cast<NodeListImpl *>(_internal); } - (DOMNode *)item:(unsigned long)index { return [DOMNode _nodeWithImpl:[self _nodeListImpl]->item(index)]; } - (unsigned long)length { return [self _nodeListImpl]->length(); } @end @implementation DOMNodeList (WebCoreInternal) - (id)_initWithNodeListImpl:(NodeListImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMNodeList *)_nodeListWithImpl:(NodeListImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithNodeListImpl:impl] autorelease]; } @end //------------------------------------------------------------------------------------------ // DOMImplementation @implementation DOMImplementation - (void)dealloc { if (_internal) { DOM_cast<DOMImplementationImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<DOMImplementationImpl *>(_internal)->deref(); } [super finalize]; } - (BOOL)hasFeature:(NSString *)feature :(NSString *)version { ASSERT(feature); ASSERT(version); return [self _DOMImplementationImpl]->hasFeature(feature, version); } - (DOMDocumentType *)createDocumentType:(NSString *)qualifiedName :(NSString *)publicId :(NSString *)systemId { ASSERT(qualifiedName); ASSERT(publicId); ASSERT(systemId); int exceptionCode = 0; DocumentTypeImpl *impl = [self _DOMImplementationImpl]->createDocumentType(qualifiedName, publicId, systemId, exceptionCode); raiseOnDOMError(exceptionCode); return static_cast<DOMDocumentType *>([DOMNode _nodeWithImpl:impl]); } - (DOMDocument *)createDocument:(NSString *)namespaceURI :(NSString *)qualifiedName :(DOMDocumentType *)doctype { ASSERT(namespaceURI); ASSERT(qualifiedName); int exceptionCode = 0; DocumentType dt = DocumentTypeImpl::createInstance(static_cast<DocumentTypeImpl *>([doctype _nodeImpl])); DocumentImpl *impl = [self _DOMImplementationImpl]->createDocument(namespaceURI, qualifiedName, dt, exceptionCode); raiseOnDOMError(exceptionCode); return static_cast<DOMDocument *>([DOMNode _nodeWithImpl:impl]); } @end @implementation DOMImplementation (DOMImplementationCSS) - (DOMCSSStyleSheet *)createCSSStyleSheet:(NSString *)title :(NSString *)media { ASSERT(title); ASSERT(media); int exceptionCode = 0; DOMString titleString(title); DOMString mediaString(media); DOMCSSStyleSheet *result = [DOMCSSStyleSheet _CSSStyleSheetWithImpl:[self _DOMImplementationImpl]->createCSSStyleSheet(titleString.implementation(), mediaString.implementation(), exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } @end @implementation DOMImplementation (WebCoreInternal) - (id)_initWithDOMImplementationImpl:(DOMImplementationImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMImplementation *)_DOMImplementationWithImpl:(DOMImplementationImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithDOMImplementationImpl:impl] autorelease]; } - (DOMImplementationImpl *)_DOMImplementationImpl { return DOM_cast<DOMImplementationImpl *>(_internal); } @end //------------------------------------------------------------------------------------------ // DOMDocumentFragment @implementation DOMDocumentFragment @end @implementation DOMDocumentFragment (WebCoreInternal) + (DOMDocumentFragment *)_documentFragmentWithImpl:(DocumentFragmentImpl *)impl { return static_cast<DOMDocumentFragment *>([DOMNode _nodeWithImpl:impl]); } - (DocumentFragmentImpl *)_fragmentImpl { return static_cast<DocumentFragmentImpl *>(DOM_cast<NodeImpl *>(_internal)); } @end //------------------------------------------------------------------------------------------ // DOMDocument @implementation DOMDocument - (DOMDocumentType *)doctype { return static_cast<DOMDocumentType *>([DOMNode _nodeWithImpl:[self _documentImpl]->doctype()]); } - (DOMImplementation *)implementation { return [DOMImplementation _DOMImplementationWithImpl:[self _documentImpl]->implementation()]; } - (DOMElement *)documentElement { return static_cast<DOMElement *>([DOMNode _nodeWithImpl:[self _documentImpl]->documentElement()]); } - (DOMElement *)createElement:(NSString *)tagName { ASSERT(tagName); int exceptionCode = 0; DOMElement *result = static_cast<DOMElement *>([DOMNode _nodeWithImpl:[self _documentImpl]->createElement(tagName, exceptionCode)]); raiseOnDOMError(exceptionCode); return result; } - (DOMDocumentFragment *)createDocumentFragment { return static_cast<DOMDocumentFragment *>([DOMNode _nodeWithImpl:[self _documentImpl]->createDocumentFragment()]); } - (DOMText *)createTextNode:(NSString *)data { ASSERT(data); return static_cast<DOMText *>([DOMNode _nodeWithImpl:[self _documentImpl]->createTextNode(data)]); } - (DOMComment *)createComment:(NSString *)data { ASSERT(data); return static_cast<DOMComment *>([DOMNode _nodeWithImpl:[self _documentImpl]->createComment(data)]); } - (DOMCDATASection *)createCDATASection:(NSString *)data { ASSERT(data); // Documentation says we can raise a NOT_SUPPORTED_ERR. // However, the lower layer does not report that error up to us. return static_cast<DOMCDATASection *>([DOMNode _nodeWithImpl:[self _documentImpl]->createCDATASection(data)]); } - (DOMProcessingInstruction *)createProcessingInstruction:(NSString *)target :(NSString *)data { ASSERT(target); ASSERT(data); // Documentation says we can raise a INVALID_CHARACTER_ERR or a NOT_SUPPORTED_ERR. // However, the lower layer does not report these errors up to us. return static_cast<DOMProcessingInstruction *>([DOMNode _nodeWithImpl:[self _documentImpl]->createProcessingInstruction(target, data)]); } - (DOMAttr *)createAttribute:(NSString *)name { ASSERT(name); // Method not reflected in DOM::DocumentImpl interface try { Document doc(DocumentImpl::createInstance([self _documentImpl])); Attr result(doc.createAttribute(name)); return static_cast<DOMAttr *>([DOMNode _nodeWithImpl:result.handle()]); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMEntityReference *)createEntityReference:(NSString *)name { ASSERT(name); // Documentation says we can raise a INVALID_CHARACTER_ERR or a NOT_SUPPORTED_ERR. // However, the lower layer does not report these errors up to us. return static_cast<DOMEntityReference *>([DOMNode _nodeWithImpl:[self _documentImpl]->createEntityReference(name)]); } - (DOMNodeList *)getElementsByTagName:(NSString *)tagname { ASSERT(tagname); return [DOMNodeList _nodeListWithImpl:[self _documentImpl]->getElementsByTagNameNS(0, DOMString(tagname).implementation())]; } - (DOMNode *)importNode:(DOMNode *)importedNode :(BOOL)deep { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _documentImpl]->importNode([importedNode _nodeImpl], deep, exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMElement *)createElementNS:(NSString *)namespaceURI :(NSString *)qualifiedName { ASSERT(namespaceURI); ASSERT(qualifiedName); int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _documentImpl]->createElementNS(namespaceURI, qualifiedName, exceptionCode)]; raiseOnDOMError(exceptionCode); return static_cast<DOMElement *>(result); } - (DOMAttr *)createAttributeNS:(NSString *)namespaceURI :(NSString *)qualifiedName { ASSERT(namespaceURI); ASSERT(qualifiedName); // Method not reflected in DOM::DocumentImpl interface try { Document doc(DocumentImpl::createInstance([self _documentImpl])); Attr result(doc.createAttributeNS(namespaceURI, qualifiedName)); return static_cast<DOMAttr *>([DOMNode _nodeWithImpl:result.handle()]); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNodeList *)getElementsByTagNameNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); return [DOMNodeList _nodeListWithImpl:[self _documentImpl]->getElementsByTagNameNS(DOMString(namespaceURI).implementation(), DOMString(localName).implementation())]; } - (DOMElement *)getElementById:(NSString *)elementId { ASSERT(elementId); return static_cast<DOMElement *>([DOMNode _nodeWithImpl:[self _documentImpl]->getElementById(elementId)]); } @end @implementation DOMDocument (DOMDocumentRange) - (DOMRange *)createRange { return [DOMRange _rangeWithImpl:[self _documentImpl]->createRange()]; } @end @implementation DOMDocument (DOMDocumentCSS) - (DOMCSSStyleDeclaration *)getComputedStyle:(DOMElement *)elt :(NSString *)pseudoElt { ElementImpl *elementImpl = [elt _elementImpl]; DOMString pseudoEltString(pseudoElt); return [DOMCSSStyleDeclaration _styleDeclarationWithImpl:[self _documentImpl]->defaultView()->getComputedStyle(elementImpl, pseudoEltString.implementation())]; } - (DOMCSSStyleDeclaration *)getOverrideStyle:(DOMElement *)elt :(NSString *)pseudoElt; { // FIXME: This is unimplemented by khtml, // so for now, we just return the computed style return [self getComputedStyle:elt :pseudoElt]; } @end @implementation DOMDocument (DOMDocumentStyle) - (DOMStyleSheetList *)styleSheets { return [DOMStyleSheetList _styleSheetListWithImpl:[self _documentImpl]->styleSheets()]; } @end @implementation DOMDocument (DOMDocumentExtensions) - (DOMCSSStyleDeclaration *)createCSSStyleDeclaration; { return [DOMCSSStyleDeclaration _styleDeclarationWithImpl:[self _documentImpl]->createCSSStyleDeclaration()]; } @end @implementation DOMDocument (WebCoreInternal) + (DOMDocument *)_documentWithImpl:(DocumentImpl *)impl { return static_cast<DOMDocument *>([DOMNode _nodeWithImpl:impl]); } - (DocumentImpl *)_documentImpl { return static_cast<DocumentImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (DOMElement *)_ownerElement { ElementImpl *element = [self _documentImpl]->ownerElement(); return element ? [DOMElement _elementWithImpl:element] : nil; } @end //------------------------------------------------------------------------------------------ // DOMCharacterData @implementation DOMCharacterData - (CharacterDataImpl *)_characterDataImpl { return static_cast<CharacterDataImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (NSString *)data { // Documentation says we can raise a DOMSTRING_SIZE_ERR. // However, the lower layer does not report that error up to us. return [self _characterDataImpl]->data(); } - (void)setData:(NSString *)data { ASSERT(data); int exceptionCode = 0; [self _characterDataImpl]->setData(data, exceptionCode); raiseOnDOMError(exceptionCode); } - (unsigned long)length { return [self _characterDataImpl]->length(); } - (NSString *)substringData:(unsigned long)offset :(unsigned long)count { int exceptionCode = 0; NSString *result = [self _characterDataImpl]->substringData(offset, count, exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (void)appendData:(NSString *)arg { ASSERT(arg); int exceptionCode = 0; [self _characterDataImpl]->appendData(arg, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)insertData:(unsigned long)offset :(NSString *)arg { ASSERT(arg); int exceptionCode = 0; [self _characterDataImpl]->insertData(offset, arg, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)deleteData:(unsigned long)offset :(unsigned long) count; { int exceptionCode = 0; [self _characterDataImpl]->deleteData(offset, count, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)replaceData:(unsigned long)offset :(unsigned long)count :(NSString *)arg { ASSERT(arg); int exceptionCode = 0; [self _characterDataImpl]->replaceData(offset, count, arg, exceptionCode); raiseOnDOMError(exceptionCode); } @end //------------------------------------------------------------------------------------------ // DOMAttr @implementation DOMAttr - (NSString *)name { return [self _attrImpl]->nodeName(); } - (BOOL)specified { return [self _attrImpl]->specified(); } - (NSString *)value { return [self _attrImpl]->nodeValue(); } - (void)setValue:(NSString *)value { ASSERT(value); int exceptionCode = 0; [self _attrImpl]->setValue(value, exceptionCode); raiseOnDOMError(exceptionCode); } - (DOMElement *)ownerElement { return [DOMElement _elementWithImpl:[self _attrImpl]->ownerElement()]; } @end @implementation DOMAttr (WebCoreInternal) + (DOMAttr *)_attrWithImpl:(AttrImpl *)impl { return static_cast<DOMAttr *>([DOMNode _nodeWithImpl:impl]); } - (AttrImpl *)_attrImpl { return static_cast<AttrImpl *>(DOM_cast<NodeImpl *>(_internal)); } @end //------------------------------------------------------------------------------------------ // DOMElement @implementation DOMElement - (NSString *)tagName { return [self _elementImpl]->tagName(); } - (DOMNamedNodeMap *)attributes { return [DOMNamedNodeMap _namedNodeMapWithImpl:[self _elementImpl]->attributes()]; } - (NSString *)getAttribute:(NSString *)name { ASSERT(name); return [self _elementImpl]->getAttribute(name); } - (void)setAttribute:(NSString *)name :(NSString *)value { ASSERT(name); ASSERT(value); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); element.setAttribute(name, value); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); } } - (void)removeAttribute:(NSString *)name { ASSERT(name); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); element.removeAttribute(name); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); } } - (DOMAttr *)getAttributeNode:(NSString *)name { ASSERT(name); // Method not reflected in DOM::ElementImpl interface Element element(ElementImpl::createInstance([self _elementImpl])); Attr result(element.getAttributeNode(name)); return [DOMAttr _attrWithImpl:static_cast<AttrImpl *>(result.handle())]; } - (DOMAttr *)setAttributeNode:(DOMAttr *)newAttr { ASSERT(newAttr); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); Attr attr(AttrImpl::createInstance([newAttr _attrImpl])); Attr result(element.setAttributeNode(attr)); return [DOMAttr _attrWithImpl:static_cast<AttrImpl *>(result.handle())]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMAttr *)removeAttributeNode:(DOMAttr *)oldAttr { ASSERT(oldAttr); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); Attr attr(AttrImpl::createInstance([oldAttr _attrImpl])); Attr result(element.removeAttributeNode(attr)); return [DOMAttr _attrWithImpl:static_cast<AttrImpl *>(result.handle())]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNodeList *)getElementsByTagName:(NSString *)name { ASSERT(name); return [DOMNodeList _nodeListWithImpl:[self _elementImpl]->getElementsByTagNameNS(0, DOMString(name).implementation())]; } - (NSString *)getAttributeNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); Element element(ElementImpl::createInstance([self _elementImpl])); return element.getAttributeNS(namespaceURI, localName); } - (void)setAttributeNS:(NSString *)namespaceURI :(NSString *)qualifiedName :(NSString *)value { ASSERT(namespaceURI); ASSERT(qualifiedName); ASSERT(value); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); element.setAttributeNS(namespaceURI, qualifiedName, value); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); } } - (void)removeAttributeNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); element.removeAttributeNS(namespaceURI, localName); } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); } } - (DOMAttr *)getAttributeNodeNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); // Method not reflected in DOM::ElementImpl interface Element element(ElementImpl::createInstance([self _elementImpl])); Attr result(element.getAttributeNodeNS(namespaceURI, localName)); return [DOMAttr _attrWithImpl:static_cast<AttrImpl *>(result.handle())]; } - (DOMAttr *)setAttributeNodeNS:(DOMAttr *)newAttr { ASSERT(newAttr); // Method not reflected in DOM::ElementImpl interface try { Element element(ElementImpl::createInstance([self _elementImpl])); Attr attr(AttrImpl::createInstance([newAttr _attrImpl])); Attr result(element.setAttributeNodeNS(attr)); return [DOMAttr _attrWithImpl:static_cast<AttrImpl *>(result.handle())]; } catch (const DOM::DOMException &e) { raiseOnDOMError(e.code); return nil; } } - (DOMNodeList *)getElementsByTagNameNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); return [DOMNodeList _nodeListWithImpl:[self _elementImpl]->getElementsByTagNameNS(DOMString(namespaceURI).implementation(), DOMString(localName).implementation())]; } - (BOOL)hasAttribute:(NSString *)name { ASSERT(name); // Method not reflected in DOM::ElementImpl interface Element element(ElementImpl::createInstance([self _elementImpl])); return element.hasAttribute(name); } - (BOOL)hasAttributeNS:(NSString *)namespaceURI :(NSString *)localName { ASSERT(namespaceURI); ASSERT(localName); // Method not reflected in DOM::ElementImpl interface Element element(ElementImpl::createInstance([self _elementImpl])); return element.hasAttributeNS(namespaceURI, localName); } @end @implementation DOMElement (DOMElementCSSInlineStyle) - (DOMCSSStyleDeclaration *)style { ElementImpl *impl = [self _elementImpl]; if (impl->isHTMLElement()) return [DOMCSSStyleDeclaration _styleDeclarationWithImpl:static_cast<HTMLElementImpl *>(impl)->getInlineStyleDecl()]; return nil; } @end @implementation DOMElement (WebCoreInternal) + (DOMElement *)_elementWithImpl:(ElementImpl *)impl { return static_cast<DOMElement *>([DOMNode _nodeWithImpl:impl]); } - (ElementImpl *)_elementImpl { return static_cast<ElementImpl *>(DOM_cast<NodeImpl *>(_internal)); } @end @implementation DOMElement (WebPrivate) - (NSFont *)_font { RenderObject *renderer = [self _elementImpl]->renderer(); if (renderer) { return renderer->style()->font().getNSFont(); } return nil; } - (NSURL *)_getURLAttribute:(NSString *)name { ASSERT(name); ElementImpl *e = [self _elementImpl]; ASSERT(e); return KURL(e->getDocument()->completeURL(khtml::parseURL(e->getAttribute(name)).string())).getNSURL(); } @end //------------------------------------------------------------------------------------------ // DOMText @implementation DOMText - (TextImpl *)_textImpl { return static_cast<TextImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (DOMText *)splitText:(unsigned long)offset { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _textImpl]->splitText(offset, exceptionCode)]; raiseOnDOMError(exceptionCode); return static_cast<DOMText *>(result); } @end //------------------------------------------------------------------------------------------ // DOMComment @implementation DOMComment @end //------------------------------------------------------------------------------------------ // DOMCDATASection @implementation DOMCDATASection @end //------------------------------------------------------------------------------------------ // DOMDocumentType @implementation DOMDocumentType - (DocumentTypeImpl *)_documentTypeImpl { return static_cast<DocumentTypeImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (NSString *)name { return [self _documentTypeImpl]->publicId(); } - (DOMNamedNodeMap *)entities { return [DOMNamedNodeMap _namedNodeMapWithImpl:[self _documentTypeImpl]->entities()]; } - (DOMNamedNodeMap *)notations { return [DOMNamedNodeMap _namedNodeMapWithImpl:[self _documentTypeImpl]->notations()]; } - (NSString *)publicId { return [self _documentTypeImpl]->publicId(); } - (NSString *)systemId { return [self _documentTypeImpl]->systemId(); } - (NSString *)internalSubset { return [self _documentTypeImpl]->internalSubset(); } @end //------------------------------------------------------------------------------------------ // DOMNotation @implementation DOMNotation - (NotationImpl *)_notationImpl { return static_cast<NotationImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (NSString *)publicId { return [self _notationImpl]->publicId(); } - (NSString *)systemId { return [self _notationImpl]->systemId(); } @end //------------------------------------------------------------------------------------------ // DOMEntity @implementation DOMEntity - (EntityImpl *)_entityImpl { return static_cast<EntityImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (NSString *)publicId { return [self _entityImpl]->publicId(); } - (NSString *)systemId { return [self _entityImpl]->systemId(); } - (NSString *)notationName { return [self _entityImpl]->notationName(); } @end //------------------------------------------------------------------------------------------ // DOMEntityReference @implementation DOMEntityReference @end //------------------------------------------------------------------------------------------ // DOMProcessingInstruction @implementation DOMProcessingInstruction - (ProcessingInstructionImpl *)_processingInstructionImpl { return static_cast<ProcessingInstructionImpl *>(DOM_cast<NodeImpl *>(_internal)); } - (NSString *)target { return [self _processingInstructionImpl]->target(); } - (NSString *)data { return [self _processingInstructionImpl]->data(); } - (void)setData:(NSString *)data { ASSERT(data); int exceptionCode = 0; [self _processingInstructionImpl]->setData(data, exceptionCode); raiseOnDOMError(exceptionCode); } @end //------------------------------------------------------------------------------------------ // DOMRange @implementation DOMRange - (void)dealloc { if (_internal) { DOM_cast<RangeImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<RangeImpl *>(_internal)->deref(); } [super finalize]; } - (NSString *)description { if (!_internal) return @"<DOMRange: null>"; return [NSString stringWithFormat:@"<DOMRange: %@ %ld %@ %ld>", [self startContainer], [self startOffset], [self endContainer], [self endOffset]]; } - (DOMNode *)startContainer { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _rangeImpl]->startContainer(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (long)startOffset { int exceptionCode = 0; long result = [self _rangeImpl]->startOffset(exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)endContainer { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _rangeImpl]->endContainer(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (long)endOffset { int exceptionCode = 0; long result = [self _rangeImpl]->endOffset(exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (BOOL)collapsed { int exceptionCode = 0; BOOL result = [self _rangeImpl]->collapsed(exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)commonAncestorContainer { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _rangeImpl]->commonAncestorContainer(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (void)setStart:(DOMNode *)refNode :(long)offset { int exceptionCode = 0; [self _rangeImpl]->setStart([refNode _nodeImpl], offset, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)setEnd:(DOMNode *)refNode :(long)offset { int exceptionCode = 0; [self _rangeImpl]->setEnd([refNode _nodeImpl], offset, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)setStartBefore:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->setStartBefore([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)setStartAfter:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->setStartAfter([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)setEndBefore:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->setEndBefore([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)setEndAfter:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->setEndAfter([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)collapse:(BOOL)toStart { int exceptionCode = 0; [self _rangeImpl]->collapse(toStart, exceptionCode); raiseOnDOMError(exceptionCode); } - (void)selectNode:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->selectNode([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)selectNodeContents:(DOMNode *)refNode { int exceptionCode = 0; [self _rangeImpl]->selectNodeContents([refNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (short)compareBoundaryPoints:(unsigned short)how :(DOMRange *)sourceRange { int exceptionCode = 0; short result = [self _rangeImpl]->compareBoundaryPoints(static_cast<Range::CompareHow>(how), [sourceRange _rangeImpl], exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (void)deleteContents { int exceptionCode = 0; [self _rangeImpl]->deleteContents(exceptionCode); raiseOnDOMError(exceptionCode); } - (DOMDocumentFragment *)extractContents { int exceptionCode = 0; DOMDocumentFragment *result = [DOMDocumentFragment _documentFragmentWithImpl:[self _rangeImpl]->extractContents(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMDocumentFragment *)cloneContents { int exceptionCode = 0; DOMDocumentFragment *result = [DOMDocumentFragment _documentFragmentWithImpl:[self _rangeImpl]->cloneContents(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (void)insertNode:(DOMNode *)newNode { int exceptionCode = 0; [self _rangeImpl]->insertNode([newNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (void)surroundContents:(DOMNode *)newParent { int exceptionCode = 0; [self _rangeImpl]->surroundContents([newParent _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (DOMRange *)cloneRange { int exceptionCode = 0; DOMRange *result = [DOMRange _rangeWithImpl:[self _rangeImpl]->cloneRange(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (NSString *)toString { int exceptionCode = 0; NSString *result = [self _rangeImpl]->toString(exceptionCode); raiseOnDOMError(exceptionCode); return result; } - (void)detach { int exceptionCode = 0; [self _rangeImpl]->detach(exceptionCode); raiseOnDOMError(exceptionCode); } @end @implementation DOMRange (WebCoreInternal) - (id)_initWithRangeImpl:(RangeImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMRange *)_rangeWithImpl:(RangeImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithRangeImpl:impl] autorelease]; } - (RangeImpl *)_rangeImpl { return DOM_cast<RangeImpl *>(_internal); } @end @implementation DOMRange (WebPrivate) - (NSString *)_text { return [self _rangeImpl]->text().string().getNSString(); } @end //------------------------------------------------------------------------------------------ //------------------------------------------------------------------------------------------ @implementation DOMNodeFilter - (id)_initWithNodeFilterImpl:(NodeFilterImpl *)impl { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); return self; } + (DOMNodeFilter *)_nodeFilterWithImpl:(NodeFilterImpl *)impl { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithNodeFilterImpl:impl] autorelease]; } - (NodeFilterImpl *)_nodeFilterImpl { return DOM_cast<NodeFilterImpl *>(_internal); } - (void)dealloc { if (_internal) DOM_cast<NodeFilterImpl *>(_internal)->deref(); [super dealloc]; } - (void)finalize { if (_internal) DOM_cast<NodeFilterImpl *>(_internal)->deref(); [super finalize]; } - (short)acceptNode:(DOMNode *)node { return [self _nodeFilterImpl]->acceptNode([node _nodeImpl]); } @end @implementation DOMNodeIterator - (id)_initWithNodeIteratorImpl:(NodeIteratorImpl *)impl filter:(id <DOMNodeFilter>)filter { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); m_filter = [filter retain]; return self; } - (NodeIteratorImpl *)_nodeIteratorImpl { return DOM_cast<NodeIteratorImpl *>(_internal); } - (void)dealloc { [m_filter release]; if (_internal) { [self detach]; DOM_cast<NodeIteratorImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { [self detach]; DOM_cast<NodeIteratorImpl *>(_internal)->deref(); } [super finalize]; } - (DOMNode *)root { return [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->root()]; } - (unsigned long)whatToShow { return [self _nodeIteratorImpl]->whatToShow(); } - (id <DOMNodeFilter>)filter { if (m_filter) // This node iterator was created from the objc side return [[m_filter retain] autorelease]; // This node iterator was created from the c++ side return [DOMNodeFilter _nodeFilterWithImpl:[self _nodeIteratorImpl]->filter()]; } - (BOOL)expandEntityReferences { return [self _nodeIteratorImpl]->expandEntityReferences(); } - (DOMNode *)nextNode { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->nextNode(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (DOMNode *)previousNode { int exceptionCode = 0; DOMNode *result = [DOMNode _nodeWithImpl:[self _nodeIteratorImpl]->previousNode(exceptionCode)]; raiseOnDOMError(exceptionCode); return result; } - (void)detach { int exceptionCode = 0; [self _nodeIteratorImpl]->detach(exceptionCode); raiseOnDOMError(exceptionCode); } @end @implementation DOMNodeIterator(WebCoreInternal) + (DOMNodeIterator *)_nodeIteratorWithImpl:(NodeIteratorImpl *)impl filter:(id <DOMNodeFilter>)filter { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithNodeIteratorImpl:impl filter:filter] autorelease]; } @end @implementation DOMTreeWalker - (id)_initWithTreeWalkerImpl:(TreeWalkerImpl *)impl filter:(id <DOMNodeFilter>)filter { ASSERT(impl); [super _init]; _internal = DOM_cast<DOMObjectInternal *>(impl); impl->ref(); addDOMWrapper(self, impl); m_filter = [filter retain]; return self; } - (TreeWalkerImpl *)_treeWalkerImpl { return DOM_cast<TreeWalkerImpl *>(_internal); } - (void)dealloc { if (m_filter) [m_filter release]; if (_internal) { DOM_cast<TreeWalkerImpl *>(_internal)->deref(); } [super dealloc]; } - (void)finalize { if (_internal) { DOM_cast<TreeWalkerImpl *>(_internal)->deref(); } [super finalize]; } - (DOMNode *)root { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->root()]; } - (unsigned long)whatToShow { return [self _treeWalkerImpl]->whatToShow(); } - (id <DOMNodeFilter>)filter { if (m_filter) // This tree walker was created from the objc side return [[m_filter retain] autorelease]; // This tree walker was created from the c++ side return [DOMNodeFilter _nodeFilterWithImpl:[self _treeWalkerImpl]->filter()]; } - (BOOL)expandEntityReferences { return [self _treeWalkerImpl]->expandEntityReferences(); } - (DOMNode *)currentNode { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->currentNode()]; } - (void)setCurrentNode:(DOMNode *)currentNode { int exceptionCode = 0; [self _treeWalkerImpl]->setCurrentNode([currentNode _nodeImpl], exceptionCode); raiseOnDOMError(exceptionCode); } - (DOMNode *)parentNode { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->parentNode()]; } - (DOMNode *)firstChild { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->firstChild()]; } - (DOMNode *)lastChild { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->lastChild()]; } - (DOMNode *)previousSibling { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->previousSibling()]; } - (DOMNode *)nextSibling { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->nextSibling()]; } - (DOMNode *)previousNode { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->previousNode()]; } - (DOMNode *)nextNode { return [DOMNode _nodeWithImpl:[self _treeWalkerImpl]->nextNode()]; } @end @implementation DOMTreeWalker (WebCoreInternal) + (DOMTreeWalker *)_treeWalkerWithImpl:(TreeWalkerImpl *)impl filter:(id <DOMNodeFilter>)filter { if (!impl) return nil; id cachedInstance; cachedInstance = getDOMWrapper(impl); if (cachedInstance) return [[cachedInstance retain] autorelease]; return [[[self alloc] _initWithTreeWalkerImpl:impl filter:filter] autorelease]; } @end class ObjCNodeFilterCondition : public NodeFilterCondition { public: ObjCNodeFilterCondition(id <DOMNodeFilter>); virtual ~ObjCNodeFilterCondition(); virtual short acceptNode(const Node &) const; private: ObjCNodeFilterCondition(const ObjCNodeFilterCondition &); ObjCNodeFilterCondition &operator=(const ObjCNodeFilterCondition &); id <DOMNodeFilter> m_filter; }; ObjCNodeFilterCondition::ObjCNodeFilterCondition(id <DOMNodeFilter> filter) : m_filter(filter) { ASSERT(m_filter); CFRetain(m_filter); } ObjCNodeFilterCondition::~ObjCNodeFilterCondition() { CFRelease(m_filter); } short ObjCNodeFilterCondition::acceptNode(const Node &n) const { if (n.isNull()) return NodeFilter::FILTER_REJECT; return [m_filter acceptNode:[DOMNode _nodeWithImpl:n.handle()]]; } @implementation DOMDocument (DOMDocumentTraversal) - (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences { NodeFilter cppFilter; if (filter) cppFilter = NodeFilter(new ObjCNodeFilterCondition(filter)); int exceptionCode = 0; NodeIteratorImpl *impl = [self _documentImpl]->createNodeIterator([root _nodeImpl], whatToShow, cppFilter.handle(), expandEntityReferences, exceptionCode); raiseOnDOMError(exceptionCode); return [DOMNodeIterator _nodeIteratorWithImpl:impl filter:filter]; } - (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned long)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences { NodeFilter cppFilter; if (filter) cppFilter = NodeFilter(new ObjCNodeFilterCondition(filter)); int exceptionCode = 0; TreeWalkerImpl *impl = [self _documentImpl]->createTreeWalker([root _nodeImpl], whatToShow, cppFilter.handle(), expandEntityReferences, exceptionCode); raiseOnDOMError(exceptionCode); return [DOMTreeWalker _treeWalkerWithImpl:impl filter:filter]; } @end