a538b1d81a002a1cb2fea6fe0ddf779b1ee115b2
[WebKit-https.git] / WebCore / bindings / objc / DOM.mm
1 /*
2  * Copyright (C) 2004-2006 Apple Computer, Inc.  All rights reserved.
3  * Copyright (C) 2006 James G. Speth (speth@end.com)
4  * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  *
15  * THIS SOFTWARE IS PROVIDED BY APPLE COMPUTER, INC. ``AS IS'' AND ANY
16  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
18  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE COMPUTER, INC. OR
19  * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
23  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
26  */
27
28 #import "config.h"
29 #import "DOM.h"
30
31 #import "CDATASection.h"
32 #import "CSSStyleSheet.h"
33 #import "Comment.h"
34 #import "DOMImplementationFront.h"
35 #import "DOMInternal.h"
36 #import "DOMPrivate.h"
37 #import "DeprecatedValueList.h"
38 #import "Document.h"
39 #import "DocumentFragment.h"
40 #import "DocumentType.h"
41 #import "EntityReference.h"
42 #import "Event.h"
43 #import "EventListener.h"
44 #import "FontData.h"
45 #import "FoundationExtras.h"
46 #import "FrameMac.h"
47 #import "HTMLDocument.h"
48 #import "HTMLNames.h"
49 #import "HTMLPlugInElement.h"
50 #import "IntRect.h"
51 #import "NodeFilter.h"
52 #import "NodeFilterCondition.h"
53 #import "NodeIterator.h"
54 #import "NodeList.h"
55 #import "ProcessingInstruction.h"
56 #import "QualifiedName.h"
57 #import "Range.h"
58 #import "RenderImage.h"
59 #import "Text.h"
60 #import "TreeWalker.h"
61 #import "WebScriptObjectPrivate.h"
62 #import "csshelper.h"
63 #import <objc/objc-class.h>
64 #import <wtf/HashMap.h>
65
66 using namespace WebCore::HTMLNames;
67
68 class ObjCEventListener : public WebCore::EventListener {
69 public:
70     static ObjCEventListener* find(id <DOMEventListener>);
71     static ObjCEventListener* create(id <DOMEventListener>);
72
73 private:
74     ObjCEventListener(id <DOMEventListener>);
75     virtual ~ObjCEventListener();
76
77     virtual void handleEvent(WebCore::Event*, bool isWindowEvent);
78
79     id <DOMEventListener> m_listener;
80 };
81
82 typedef HashMap<id, ObjCEventListener*> ListenerMap;
83 typedef HashMap<WebCore::AtomicStringImpl*, Class> ObjCClassMap;
84
85 static ObjCClassMap* elementClassMap;
86 static ListenerMap* listenerMap;
87
88
89 //------------------------------------------------------------------------------------------
90 // DOMNode
91
92 static void addElementClass(const WebCore::QualifiedName& tag, Class objCClass)
93 {
94     elementClassMap->set(tag.localName().impl(), objCClass);
95 }
96
97 static void createHTMLElementClassMap()
98 {
99     // Create the table.
100     elementClassMap = new ObjCClassMap;
101     
102     // Populate it with HTML element classes.
103     addElementClass(aTag, [DOMHTMLAnchorElement class]);
104     addElementClass(appletTag, [DOMHTMLAppletElement class]);
105     addElementClass(areaTag, [DOMHTMLAreaElement class]);
106     addElementClass(baseTag, [DOMHTMLBaseElement class]);
107     addElementClass(basefontTag, [DOMHTMLBaseFontElement class]);
108     addElementClass(bodyTag, [DOMHTMLBodyElement class]);
109     addElementClass(brTag, [DOMHTMLBRElement class]);
110     addElementClass(buttonTag, [DOMHTMLButtonElement class]);
111     addElementClass(canvasTag, [DOMHTMLImageElement class]);
112     addElementClass(captionTag, [DOMHTMLTableCaptionElement class]);
113     addElementClass(colTag, [DOMHTMLTableColElement class]);
114     addElementClass(colgroupTag, [DOMHTMLTableColElement class]);
115     addElementClass(dirTag, [DOMHTMLDirectoryElement class]);
116     addElementClass(divTag, [DOMHTMLDivElement class]);
117     addElementClass(dlTag, [DOMHTMLDListElement class]);
118     addElementClass(fieldsetTag, [DOMHTMLFieldSetElement class]);
119     addElementClass(fontTag, [DOMHTMLFontElement class]);
120     addElementClass(formTag, [DOMHTMLFormElement class]);
121     addElementClass(frameTag, [DOMHTMLFrameElement class]);
122     addElementClass(framesetTag, [DOMHTMLFrameSetElement class]);
123     addElementClass(h1Tag, [DOMHTMLHeadingElement class]);
124     addElementClass(h2Tag, [DOMHTMLHeadingElement class]);
125     addElementClass(h3Tag, [DOMHTMLHeadingElement class]);
126     addElementClass(h4Tag, [DOMHTMLHeadingElement class]);
127     addElementClass(h5Tag, [DOMHTMLHeadingElement class]);
128     addElementClass(h6Tag, [DOMHTMLHeadingElement class]);
129     addElementClass(headTag, [DOMHTMLHeadElement class]);
130     addElementClass(hrTag, [DOMHTMLHRElement class]);
131     addElementClass(htmlTag, [DOMHTMLHtmlElement class]);
132     addElementClass(iframeTag, [DOMHTMLIFrameElement class]);
133     addElementClass(imgTag, [DOMHTMLImageElement class]);
134     addElementClass(inputTag, [DOMHTMLInputElement class]);
135     addElementClass(isindexTag, [DOMHTMLIsIndexElement class]);
136     addElementClass(labelTag, [DOMHTMLLabelElement class]);
137     addElementClass(legendTag, [DOMHTMLLegendElement class]);
138     addElementClass(liTag, [DOMHTMLLIElement class]);
139     addElementClass(linkTag, [DOMHTMLLinkElement class]);
140     addElementClass(listingTag, [DOMHTMLPreElement class]);
141     addElementClass(mapTag, [DOMHTMLMapElement class]);
142     addElementClass(menuTag, [DOMHTMLMenuElement class]);
143     addElementClass(metaTag, [DOMHTMLMetaElement class]);
144     addElementClass(objectTag, [DOMHTMLObjectElement class]);
145     addElementClass(olTag, [DOMHTMLOListElement class]);
146     addElementClass(optgroupTag, [DOMHTMLOptGroupElement class]);
147     addElementClass(optionTag, [DOMHTMLOptionElement class]);
148     addElementClass(pTag, [DOMHTMLParagraphElement class]);
149     addElementClass(paramTag, [DOMHTMLParamElement class]);
150     addElementClass(preTag, [DOMHTMLPreElement class]);
151     addElementClass(qTag, [DOMHTMLQuoteElement class]);
152     addElementClass(scriptTag, [DOMHTMLScriptElement class]);
153     addElementClass(selectTag, [DOMHTMLSelectElement class]);
154     addElementClass(styleTag, [DOMHTMLStyleElement class]);
155     addElementClass(tableTag, [DOMHTMLTableElement class]);
156     addElementClass(tbodyTag, [DOMHTMLTableSectionElement class]);
157     addElementClass(tdTag, [DOMHTMLTableCellElement class]);
158     addElementClass(textareaTag, [DOMHTMLTextAreaElement class]);
159     addElementClass(tfootTag, [DOMHTMLTableSectionElement class]);
160     addElementClass(theadTag, [DOMHTMLTableSectionElement class]);
161     addElementClass(titleTag, [DOMHTMLTitleElement class]);
162     addElementClass(trTag, [DOMHTMLTableRowElement class]);
163     addElementClass(ulTag, [DOMHTMLUListElement class]);
164
165     // FIXME: Reflect marquee once the API has been determined.
166 }
167
168 static Class elementClass(const WebCore::AtomicString& tagName)
169 {
170     if (!elementClassMap)
171         createHTMLElementClassMap();
172     Class objcClass = elementClassMap->get(tagName.impl());
173     if (!objcClass)
174         objcClass = [DOMHTMLElement class];
175     return objcClass;
176 }
177
178 @implementation DOMNode (WebCoreInternal)
179
180 // FIXME: should this go in the main implementation?
181 - (NSString *)description
182 {
183     if (!_internal)
184         return [NSString stringWithFormat:@"<%@: null>", [[self class] description], self];
185     
186     NSString *value = [self nodeValue];
187     if (value)
188         return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>",
189             [[self class] description], [self nodeName], _internal, value];
190
191     return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal];
192 }
193
194 - (id)_initWithNode:(WebCore::Node *)impl
195 {
196     ASSERT(impl);
197
198     [super _init];
199     _internal = reinterpret_cast<DOMObjectInternal*>(impl);
200     impl->ref();
201     addDOMWrapper(self, impl);
202     return self;
203 }
204
205 + (DOMNode *)_nodeWith:(WebCore::Node *)impl
206 {
207     if (!impl)
208         return nil;
209     
210     id cachedInstance;
211     cachedInstance = getDOMWrapper(impl);
212     if (cachedInstance)
213         return [[cachedInstance retain] autorelease];
214     
215     Class wrapperClass = nil;
216     switch (impl->nodeType()) {
217         case WebCore::Node::ELEMENT_NODE:
218             if (impl->isHTMLElement())
219                 wrapperClass = elementClass(static_cast<WebCore::HTMLElement*>(impl)->localName());
220             else
221                 wrapperClass = [DOMElement class];
222             break;
223         case WebCore::Node::ATTRIBUTE_NODE:
224             wrapperClass = [DOMAttr class];
225             break;
226         case WebCore::Node::TEXT_NODE:
227             wrapperClass = [DOMText class];
228             break;
229         case WebCore::Node::CDATA_SECTION_NODE:
230             wrapperClass = [DOMCDATASection class];
231             break;
232         case WebCore::Node::ENTITY_REFERENCE_NODE:
233             wrapperClass = [DOMEntityReference class];
234             break;
235         case WebCore::Node::ENTITY_NODE:
236             wrapperClass = [DOMEntity class];
237             break;
238         case WebCore::Node::PROCESSING_INSTRUCTION_NODE:
239             wrapperClass = [DOMProcessingInstruction class];
240             break;
241         case WebCore::Node::COMMENT_NODE:
242             wrapperClass = [DOMComment class];
243             break;
244         case WebCore::Node::DOCUMENT_NODE:
245             if (static_cast<WebCore::Document*>(impl)->isHTMLDocument())
246                 wrapperClass = [DOMHTMLDocument class];
247             else
248                 wrapperClass = [DOMDocument class];
249             break;
250         case WebCore::Node::DOCUMENT_TYPE_NODE:
251             wrapperClass = [DOMDocumentType class];
252             break;
253         case WebCore::Node::DOCUMENT_FRAGMENT_NODE:
254             wrapperClass = [DOMDocumentFragment class];
255             break;
256         case WebCore::Node::NOTATION_NODE:
257             wrapperClass = [DOMNotation class];
258             break;
259         case WebCore::Node::XPATH_NAMESPACE_NODE:
260             // FIXME: Create an XPath objective C wrapper
261             // See http://bugzilla.opendarwin.org/show_bug.cgi?id=8755
262             return nil;
263     }
264     return [[[wrapperClass alloc] _initWithNode:impl] autorelease];
265 }
266
267 - (WebCore::Node *)_node
268 {
269     return reinterpret_cast<WebCore::Node*>(_internal);
270 }
271
272 - (const KJS::Bindings::RootObject *)_executionContext
273 {
274     if (WebCore::Node *n = [self _node]) {
275         if (WebCore::FrameMac *f = Mac(n->document()->frame()))
276             return f->executionContextForDOM();
277     }
278     return 0;
279 }
280
281 @end
282
283 @implementation DOMNode (DOMNodeExtensions)
284
285 // FIXME: this should be implemented in the implementation
286 - (NSRect)boundingBox
287 {
288     WebCore::RenderObject *renderer = [self _node]->renderer();
289     if (renderer)
290         return renderer->absoluteBoundingBoxRect();
291     return NSZeroRect;
292 }
293
294 // FIXME: this should be implemented in the implementation
295 - (NSArray *)lineBoxRects
296 {
297     WebCore::RenderObject *renderer = [self _node]->renderer();
298     if (renderer) {
299         Vector<WebCore::IntRect> rects;
300         renderer->lineBoxRects(rects);
301         size_t size = rects.size();
302         NSMutableArray *results = [NSMutableArray arrayWithCapacity:size];
303         for (size_t i = 0; i < size; ++i)
304             [results addObject:[NSValue valueWithRect:rects[i]]];
305         return results;
306     }
307     return nil;
308 }
309
310 @end
311
312 // FIXME: this should be auto-generated
313 @implementation DOMNode (DOMEventTarget)
314
315 - (void)addEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture
316 {
317     if (![self _node]->isEventTargetNode())
318         raiseDOMException(DOM_NOT_SUPPORTED_ERR);
319     
320     WebCore::EventListener *wrapper = ObjCEventListener::create(listener);
321     EventTargetNodeCast([self _node])->addEventListener(type, wrapper, useCapture);
322     wrapper->deref();
323 }
324
325 - (void)addEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture
326 {
327     // FIXME: this method can be removed once Mail changes to use the new method <rdar://problem/4746649>
328     [self addEventListener:type listener:listener useCapture:useCapture];
329 }
330
331 - (void)removeEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture
332 {
333     if (![self _node]->isEventTargetNode())
334         raiseDOMException(DOM_NOT_SUPPORTED_ERR);
335
336     if (WebCore::EventListener *wrapper = ObjCEventListener::find(listener))
337         EventTargetNodeCast([self _node])->removeEventListener(type, wrapper, useCapture);
338 }
339
340 - (void)removeEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture
341 {
342     // FIXME: this method can be removed once Mail changes to use the new method <rdar://problem/4746649>
343     [self removeEventListener:type listener:listener useCapture:useCapture];
344 }
345
346 - (BOOL)dispatchEvent:(DOMEvent *)event
347 {
348     if (![self _node]->isEventTargetNode())
349         raiseDOMException(DOM_NOT_SUPPORTED_ERR);
350
351     WebCore::ExceptionCode ec = 0;
352     BOOL result = EventTargetNodeCast([self _node])->dispatchEvent([event _event], ec);
353     raiseOnDOMError(ec);
354     return result;
355 }
356
357 @end
358
359 //------------------------------------------------------------------------------------------
360 // DOMElement
361
362 // FIXME: this should be auto-genenerate in DOMElement.mm
363 @implementation DOMElement (DOMElementAppKitExtensions)
364
365 // FIXME: this should be implemented in the implementation
366 - (NSImage*)image
367 {
368     WebCore::RenderObject* renderer = [self _element]->renderer();
369     if (renderer && renderer->isImage()) {
370         WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
371         if (img->cachedImage() && !img->cachedImage()->isErrorImage())
372             return img->cachedImage()->image()->getNSImage();
373     }
374     return nil;
375 }
376
377 @end
378
379 @implementation DOMElement (WebPrivate)
380
381 // FIXME: this should be implemented in the implementation
382 - (NSFont *)_font
383 {
384     WebCore::RenderObject* renderer = [self _element]->renderer();
385     if (renderer)
386         return renderer->style()->font().primaryFont()->getNSFont();
387     return nil;
388 }
389
390 // FIXME: this should be implemented in the implementation
391 - (NSData*)_imageTIFFRepresentation
392 {
393     WebCore::RenderObject* renderer = [self _element]->renderer();
394     if (renderer && renderer->isImage()) {
395         WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
396         if (img->cachedImage() && !img->cachedImage()->isErrorImage())
397             return (NSData*)(img->cachedImage()->image()->getTIFFRepresentation());
398     }
399     return nil;
400 }
401
402 // FIXME: this should be implemented in the implementation
403 - (NSURL *)_getURLAttribute:(NSString *)name
404 {
405     ASSERT(name);
406     WebCore::Element* element = [self _element];
407     ASSERT(element);
408     return WebCore::KURL(element->document()->completeURL(parseURL(element->getAttribute(name)).deprecatedString())).getNSURL();
409 }
410
411 // FIXME: this should be implemented in the implementation
412 - (void *)_NPObject
413 {
414     WebCore::Element* element = [self _element];
415     if (element->hasTagName(appletTag) || element->hasTagName(embedTag) || element->hasTagName(objectTag))
416         return static_cast<WebCore::HTMLPlugInElement*>(element)->getNPObject();
417     return 0;
418 }
419
420 // FIXME: this should be implemented in the implementation
421 - (BOOL)isFocused
422 {
423     WebCore::Element* impl = [self _element];
424     if (impl->document()->focusNode() == impl)
425         return YES;
426     return NO;
427 }
428
429 @end
430
431
432 //------------------------------------------------------------------------------------------
433 // DOMRange
434
435 @implementation DOMRange (WebPrivate)
436
437 - (NSString *)description
438 {
439     if (!_internal)
440         return @"<DOMRange: null>";
441     return [NSString stringWithFormat:@"<DOMRange: %@ %d %@ %d>",
442                [self startContainer], [self startOffset], [self endContainer], [self endOffset]];
443 }
444
445 // FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with
446 // calls to the public method - (NSString *)text.
447 - (NSString *)_text
448 {
449     return [self text];
450 }
451
452 @end
453
454
455 //------------------------------------------------------------------------------------------
456 // DOMNodeFilter
457
458 @implementation DOMNodeFilter
459
460 - (id)_initWithNodeFilter:(WebCore::NodeFilter *)impl
461 {
462     ASSERT(impl);
463
464     [super _init];
465     _internal = reinterpret_cast<DOMObjectInternal*>(impl);
466     impl->ref();
467     addDOMWrapper(self, impl);
468     return self;
469 }
470
471 + (DOMNodeFilter *)_nodeFilterWith:(WebCore::NodeFilter *)impl
472 {
473     if (!impl)
474         return nil;
475     
476     id cachedInstance;
477     cachedInstance = getDOMWrapper(impl);
478     if (cachedInstance)
479         return [[cachedInstance retain] autorelease];
480     
481     return [[[self alloc] _initWithNodeFilter:impl] autorelease];
482 }
483
484 - (WebCore::NodeFilter *)_nodeFilter
485 {
486     return reinterpret_cast<WebCore::NodeFilter*>(_internal);
487 }
488
489 - (void)dealloc
490 {
491     if (_internal)
492         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
493     [super dealloc];
494 }
495
496 - (void)finalize
497 {
498     if (_internal)
499         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
500     [super finalize];
501 }
502
503 - (short)acceptNode:(DOMNode *)node
504 {
505     return [self _nodeFilter]->acceptNode([node _node]);
506 }
507
508 @end
509
510
511 //------------------------------------------------------------------------------------------
512 // DOMNodeIterator
513
514 @implementation DOMNodeIterator(WebCoreInternal)
515
516 - (id)_initWithNodeIterator:(WebCore::NodeIterator *)impl filter:(id <DOMNodeFilter>)filter
517 {
518     ASSERT(impl);
519
520     [super _init];
521     _internal = reinterpret_cast<DOMObjectInternal*>(impl);
522     impl->ref();
523     addDOMWrapper(self, impl);
524     m_filter = [filter retain];
525     return self;
526 }
527
528 - (WebCore::NodeIterator *)_nodeIterator
529 {
530     return reinterpret_cast<WebCore::NodeIterator*>(_internal);
531 }
532
533 + (DOMNodeIterator *)_nodeIteratorWith:(WebCore::NodeIterator *)impl filter:(id <DOMNodeFilter>)filter
534 {
535     if (!impl)
536         return nil;
537     
538     id cachedInstance;
539     cachedInstance = getDOMWrapper(impl);
540     if (cachedInstance)
541         return [[cachedInstance retain] autorelease];
542     
543     return [[[self alloc] _initWithNodeIterator:impl filter:filter] autorelease];
544 }
545
546 @end
547
548
549 //------------------------------------------------------------------------------------------
550 // DOMTreeWalker
551
552 @implementation DOMTreeWalker (WebCoreInternal)
553
554 - (id)_initWithTreeWalker:(WebCore::TreeWalker *)impl filter:(id <DOMNodeFilter>)filter
555 {
556     ASSERT(impl);
557
558     [super _init];
559     _internal = reinterpret_cast<DOMObjectInternal*>(impl);
560     impl->ref();
561     addDOMWrapper(self, impl);
562     m_filter = [filter retain];
563     return self;
564 }
565
566 - (WebCore::TreeWalker *)_treeWalker
567 {
568     return reinterpret_cast<WebCore::TreeWalker *>(_internal);
569 }
570
571 + (DOMTreeWalker *)_treeWalkerWith:(WebCore::TreeWalker *)impl filter:(id <DOMNodeFilter>)filter
572 {
573     if (!impl)
574         return nil;
575     
576     id cachedInstance;
577     cachedInstance = getDOMWrapper(impl);
578     if (cachedInstance)
579         return [[cachedInstance retain] autorelease];
580     
581     return [[[self alloc] _initWithTreeWalker:impl filter:filter] autorelease];
582 }
583
584 @end
585
586
587 //------------------------------------------------------------------------------------------
588 // ObjCNodeFilterCondition
589
590 class ObjCNodeFilterCondition : public WebCore::NodeFilterCondition {
591 public:
592     ObjCNodeFilterCondition(id <DOMNodeFilter>);
593     virtual ~ObjCNodeFilterCondition();
594     virtual short acceptNode(WebCore::Node*) const;
595
596 private:
597     ObjCNodeFilterCondition(const ObjCNodeFilterCondition&);
598     ObjCNodeFilterCondition &operator=(const ObjCNodeFilterCondition&);
599
600     id <DOMNodeFilter> m_filter;
601 };
602
603 ObjCNodeFilterCondition::ObjCNodeFilterCondition(id <DOMNodeFilter> filter)
604     : m_filter(filter)
605 {
606     ASSERT(m_filter);
607     CFRetain(m_filter);
608 }
609
610 ObjCNodeFilterCondition::~ObjCNodeFilterCondition()
611 {
612     CFRelease(m_filter);
613 }
614
615 short ObjCNodeFilterCondition::acceptNode(WebCore::Node* node) const
616 {
617     if (!node)
618         return WebCore::NodeFilter::FILTER_REJECT;
619     return [m_filter acceptNode:[DOMNode _nodeWith:node]];
620 }
621
622
623 //------------------------------------------------------------------------------------------
624 // DOMDocument (DOMDocumentTraversal)
625
626 // FIXME: this should be auto-genenerate in DOMDocument.mm
627 @implementation DOMDocument (DOMDocumentTraversal)
628
629 - (DOMNodeIterator *)createNodeIterator:(DOMNode *)root whatToShow:(unsigned)whatToShow filter:(id <DOMNodeFilter>)filter expandEntityReferences:(BOOL)expandEntityReferences
630 {
631     RefPtr<WebCore::NodeFilter> cppFilter;
632     if (filter)
633         cppFilter = new WebCore::NodeFilter(new ObjCNodeFilterCondition(filter));
634     WebCore::ExceptionCode ec = 0;
635     RefPtr<WebCore::NodeIterator> impl = [self _document]->createNodeIterator([root _node], whatToShow, cppFilter, expandEntityReferences, ec);
636     raiseOnDOMError(ec);
637     return [DOMNodeIterator _nodeIteratorWith:impl.get() filter:filter];
638 }
639
640 - (DOMTreeWalker *)createTreeWalker:(DOMNode *)root whatToShow:(unsigned)whatToShow filter:(id <DOMNodeFilter>)filter expandEntityReferences:(BOOL)expandEntityReferences
641 {
642     RefPtr<WebCore::NodeFilter> cppFilter;
643     if (filter)
644         cppFilter = new WebCore::NodeFilter(new ObjCNodeFilterCondition(filter));
645     WebCore::ExceptionCode ec = 0;
646     RefPtr<WebCore::TreeWalker> impl = [self _document]->createTreeWalker([root _node], whatToShow, cppFilter, expandEntityReferences, ec);
647     raiseOnDOMError(ec);
648     return [DOMTreeWalker _treeWalkerWith:impl.get() filter:filter];
649 }
650
651 @end
652
653 @implementation DOMDocument (DOMDocumentTraversalDeprecated)
654
655 - (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
656 {
657     return [self createNodeIterator:root whatToShow:whatToShow filter:filter expandEntityReferences:expandEntityReferences];
658 }
659
660 - (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
661 {
662     return [self createTreeWalker:root whatToShow:whatToShow filter:filter expandEntityReferences:expandEntityReferences];
663 }
664
665 @end
666
667 //------------------------------------------------------------------------------------------
668 // ObjCEventListener
669
670 ObjCEventListener* ObjCEventListener::find(id <DOMEventListener> listener)
671 {
672     if (ListenerMap* map = listenerMap)
673         return map->get(listener);
674     return 0;
675 }
676
677 ObjCEventListener *ObjCEventListener::create(id <DOMEventListener> listener)
678 {
679     ObjCEventListener* wrapper = find(listener);
680     if (!wrapper)
681         wrapper = new ObjCEventListener(listener);
682     wrapper->ref();
683     return wrapper;
684 }
685
686 ObjCEventListener::ObjCEventListener(id <DOMEventListener> listener)
687     : m_listener([listener retain])
688 {
689     ListenerMap* map = listenerMap;
690     if (!map) {
691         map = new ListenerMap;
692         listenerMap = map;
693     }
694     map->set(listener, this);
695 }
696
697 ObjCEventListener::~ObjCEventListener()
698 {
699     listenerMap->remove(m_listener);
700     [m_listener release];
701 }
702
703 void ObjCEventListener::handleEvent(WebCore::Event* event, bool)
704 {
705     [m_listener handleEvent:[DOMEvent _eventWith:event]];
706 }