~ubuntu-branches/ubuntu/maverick/webkit/maverick

« back to all changes in this revision

Viewing changes to WebCore/bindings/objc/DOM.mm

  • Committer: Bazaar Package Importer
  • Author(s): Mike Hommey
  • Date: 2007-08-19 15:54:12 UTC
  • Revision ID: james.westby@ubuntu.com-20070819155412-uxxg1h9plpghmtbi
Tags: upstream-0~svn25144
ImportĀ upstreamĀ versionĀ 0~svn25144

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
 * Copyright (C) 2004, 2005, 2006, 2007 Apple 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 "CSSHelper.h"
 
33
#import "CSSStyleSheet.h"
 
34
#import "Comment.h"
 
35
#import "DOMHTMLCanvasElement.h"
 
36
#import "DOMInternal.h"
 
37
#import "DOMPrivate.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 "EventTarget.h"
 
45
#import "ExceptionHandlers.h"
 
46
#import "FontData.h"
 
47
#import "FoundationExtras.h"
 
48
#import "Frame.h"
 
49
#import "FrameView.h"
 
50
#import "HTMLDocument.h"
 
51
#import "HTMLNames.h"
 
52
#import "HTMLPlugInElement.h"
 
53
#import "Image.h"
 
54
#import "IntRect.h"
 
55
#import "NodeFilter.h"
 
56
#import "NodeFilterCondition.h"
 
57
#import "NodeIterator.h"
 
58
#import "NodeList.h"
 
59
#import "ProcessingInstruction.h"
 
60
#import "QualifiedName.h"
 
61
#import "Range.h"
 
62
#import "RenderImage.h"
 
63
#import "RenderView.h"
 
64
#import "Text.h"
 
65
#import "TreeWalker.h"
 
66
#import "WebScriptObjectPrivate.h"
 
67
#import <objc/objc-class.h>
 
68
#import <wtf/HashMap.h>
 
69
 
 
70
#if ENABLE(SVG)
 
71
#import "SVGDocument.h"
 
72
#import "SVGElement.h"
 
73
#import "SVGNames.h"
 
74
#endif
 
75
 
 
76
namespace WebCore {
 
77
 
 
78
class ObjCEventListener : public EventListener {
 
79
public:
 
80
    static ObjCEventListener* find(id <DOMEventListener>);
 
81
    static ObjCEventListener* create(id <DOMEventListener>);
 
82
 
 
83
private:
 
84
    ObjCEventListener(id <DOMEventListener>);
 
85
    virtual ~ObjCEventListener();
 
86
 
 
87
    virtual void handleEvent(Event*, bool isWindowEvent);
 
88
 
 
89
    id <DOMEventListener> m_listener;
 
90
};
 
91
 
 
92
typedef HashMap<id, ObjCEventListener*> ListenerMap;
 
93
static ListenerMap* listenerMap;
 
94
 
 
95
} // namespace WebCore
 
96
 
 
97
 
 
98
//------------------------------------------------------------------------------------------
 
99
// DOMNode
 
100
 
 
101
namespace WebCore {
 
102
 
 
103
typedef HashMap<const QualifiedName::QualifiedNameImpl*, Class> ObjCClassMap;
 
104
static ObjCClassMap* elementClassMap;
 
105
 
 
106
static void addElementClass(const QualifiedName& tag, Class objCClass)
 
107
{
 
108
    elementClassMap->set(tag.impl(), objCClass);
 
109
}
 
110
 
 
111
static void createElementClassMap()
 
112
{
 
113
    // Create the table.
 
114
    elementClassMap = new ObjCClassMap;
 
115
 
 
116
    // FIXME: Reflect marquee once the API has been determined.
 
117
 
 
118
    // Populate it with HTML and SVG element classes.
 
119
    addElementClass(HTMLNames::aTag, [DOMHTMLAnchorElement class]);
 
120
    addElementClass(HTMLNames::appletTag, [DOMHTMLAppletElement class]);
 
121
    addElementClass(HTMLNames::areaTag, [DOMHTMLAreaElement class]);
 
122
    addElementClass(HTMLNames::baseTag, [DOMHTMLBaseElement class]);
 
123
    addElementClass(HTMLNames::basefontTag, [DOMHTMLBaseFontElement class]);
 
124
    addElementClass(HTMLNames::bodyTag, [DOMHTMLBodyElement class]);
 
125
    addElementClass(HTMLNames::brTag, [DOMHTMLBRElement class]);
 
126
    addElementClass(HTMLNames::buttonTag, [DOMHTMLButtonElement class]);
 
127
    addElementClass(HTMLNames::canvasTag, [DOMHTMLCanvasElement class]);
 
128
    addElementClass(HTMLNames::captionTag, [DOMHTMLTableCaptionElement class]);
 
129
    addElementClass(HTMLNames::colTag, [DOMHTMLTableColElement class]);
 
130
    addElementClass(HTMLNames::colgroupTag, [DOMHTMLTableColElement class]);
 
131
    addElementClass(HTMLNames::delTag, [DOMHTMLModElement class]);
 
132
    addElementClass(HTMLNames::dirTag, [DOMHTMLDirectoryElement class]);
 
133
    addElementClass(HTMLNames::divTag, [DOMHTMLDivElement class]);
 
134
    addElementClass(HTMLNames::dlTag, [DOMHTMLDListElement class]);
 
135
    addElementClass(HTMLNames::embedTag, [DOMHTMLEmbedElement class]);
 
136
    addElementClass(HTMLNames::fieldsetTag, [DOMHTMLFieldSetElement class]);
 
137
    addElementClass(HTMLNames::fontTag, [DOMHTMLFontElement class]);
 
138
    addElementClass(HTMLNames::formTag, [DOMHTMLFormElement class]);
 
139
    addElementClass(HTMLNames::frameTag, [DOMHTMLFrameElement class]);
 
140
    addElementClass(HTMLNames::framesetTag, [DOMHTMLFrameSetElement class]);
 
141
    addElementClass(HTMLNames::h1Tag, [DOMHTMLHeadingElement class]);
 
142
    addElementClass(HTMLNames::h2Tag, [DOMHTMLHeadingElement class]);
 
143
    addElementClass(HTMLNames::h3Tag, [DOMHTMLHeadingElement class]);
 
144
    addElementClass(HTMLNames::h4Tag, [DOMHTMLHeadingElement class]);
 
145
    addElementClass(HTMLNames::h5Tag, [DOMHTMLHeadingElement class]);
 
146
    addElementClass(HTMLNames::h6Tag, [DOMHTMLHeadingElement class]);
 
147
    addElementClass(HTMLNames::headTag, [DOMHTMLHeadElement class]);
 
148
    addElementClass(HTMLNames::hrTag, [DOMHTMLHRElement class]);
 
149
    addElementClass(HTMLNames::htmlTag, [DOMHTMLHtmlElement class]);
 
150
    addElementClass(HTMLNames::iframeTag, [DOMHTMLIFrameElement class]);
 
151
    addElementClass(HTMLNames::imgTag, [DOMHTMLImageElement class]);
 
152
    addElementClass(HTMLNames::inputTag, [DOMHTMLInputElement class]);
 
153
    addElementClass(HTMLNames::insTag, [DOMHTMLModElement class]);
 
154
    addElementClass(HTMLNames::isindexTag, [DOMHTMLIsIndexElement class]);
 
155
    addElementClass(HTMLNames::labelTag, [DOMHTMLLabelElement class]);
 
156
    addElementClass(HTMLNames::legendTag, [DOMHTMLLegendElement class]);
 
157
    addElementClass(HTMLNames::liTag, [DOMHTMLLIElement class]);
 
158
    addElementClass(HTMLNames::linkTag, [DOMHTMLLinkElement class]);
 
159
    addElementClass(HTMLNames::listingTag, [DOMHTMLPreElement class]);
 
160
    addElementClass(HTMLNames::mapTag, [DOMHTMLMapElement class]);
 
161
    addElementClass(HTMLNames::marqueeTag, [DOMHTMLMarqueeElement class]);
 
162
    addElementClass(HTMLNames::menuTag, [DOMHTMLMenuElement class]);
 
163
    addElementClass(HTMLNames::metaTag, [DOMHTMLMetaElement class]);
 
164
    addElementClass(HTMLNames::objectTag, [DOMHTMLObjectElement class]);
 
165
    addElementClass(HTMLNames::olTag, [DOMHTMLOListElement class]);
 
166
    addElementClass(HTMLNames::optgroupTag, [DOMHTMLOptGroupElement class]);
 
167
    addElementClass(HTMLNames::optionTag, [DOMHTMLOptionElement class]);
 
168
    addElementClass(HTMLNames::pTag, [DOMHTMLParagraphElement class]);
 
169
    addElementClass(HTMLNames::paramTag, [DOMHTMLParamElement class]);
 
170
    addElementClass(HTMLNames::preTag, [DOMHTMLPreElement class]);
 
171
    addElementClass(HTMLNames::qTag, [DOMHTMLQuoteElement class]);
 
172
    addElementClass(HTMLNames::scriptTag, [DOMHTMLScriptElement class]);
 
173
    addElementClass(HTMLNames::keygenTag, [DOMHTMLSelectElement class]);
 
174
    addElementClass(HTMLNames::selectTag, [DOMHTMLSelectElement class]);
 
175
    addElementClass(HTMLNames::styleTag, [DOMHTMLStyleElement class]);
 
176
    addElementClass(HTMLNames::tableTag, [DOMHTMLTableElement class]);
 
177
    addElementClass(HTMLNames::tbodyTag, [DOMHTMLTableSectionElement class]);
 
178
    addElementClass(HTMLNames::tdTag, [DOMHTMLTableCellElement class]);
 
179
    addElementClass(HTMLNames::textareaTag, [DOMHTMLTextAreaElement class]);
 
180
    addElementClass(HTMLNames::tfootTag, [DOMHTMLTableSectionElement class]);
 
181
    addElementClass(HTMLNames::thTag, [DOMHTMLTableCellElement class]);
 
182
    addElementClass(HTMLNames::theadTag, [DOMHTMLTableSectionElement class]);
 
183
    addElementClass(HTMLNames::titleTag, [DOMHTMLTitleElement class]);
 
184
    addElementClass(HTMLNames::trTag, [DOMHTMLTableRowElement class]);
 
185
    addElementClass(HTMLNames::ulTag, [DOMHTMLUListElement class]);
 
186
    addElementClass(HTMLNames::xmpTag, [DOMHTMLPreElement class]);
 
187
 
 
188
#if ENABLE(SVG)
 
189
    addElementClass(SVGNames::aTag, [DOMSVGAElement class]);
 
190
#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
 
191
    addElementClass(SVGNames::animateTag, [DOMSVGAnimateElement class]);
 
192
    addElementClass(SVGNames::animateColorTag, [DOMSVGAnimateColorElement class]);
 
193
    addElementClass(SVGNames::animateTransformTag, [DOMSVGAnimateTransformElement class]);
 
194
#endif
 
195
    addElementClass(SVGNames::circleTag, [DOMSVGCircleElement class]);
 
196
    addElementClass(SVGNames::clipPathTag, [DOMSVGClipPathElement class]);
 
197
    addElementClass(SVGNames::cursorTag, [DOMSVGCursorElement class]);
 
198
    addElementClass(SVGNames::defsTag, [DOMSVGDefsElement class]);
 
199
    addElementClass(SVGNames::descTag, [DOMSVGDescElement class]);
 
200
    addElementClass(SVGNames::ellipseTag, [DOMSVGEllipseElement class]);
 
201
#if ENABLE(SVG_EXPERIMENTAL_FEATURES)
 
202
    addElementClass(SVGNames::feBlendTag, [DOMSVGFEBlendElement class]);
 
203
    addElementClass(SVGNames::feColorMatrixTag, [DOMSVGFEColorMatrixElement class]);
 
204
    addElementClass(SVGNames::feComponentTransferTag, [DOMSVGFEComponentTransferElement class]);
 
205
    addElementClass(SVGNames::feCompositeTag, [DOMSVGFECompositeElement class]);
 
206
    addElementClass(SVGNames::feDiffuseLightingTag, [DOMSVGFEDiffuseLightingElement class]);
 
207
    addElementClass(SVGNames::feDisplacementMapTag, [DOMSVGFEDisplacementMapElement class]);
 
208
    addElementClass(SVGNames::feDistantLightTag, [DOMSVGFEDistantLightElement class]);
 
209
    addElementClass(SVGNames::feFloodTag, [DOMSVGFEFloodElement class]);
 
210
    addElementClass(SVGNames::feFuncATag, [DOMSVGFEFuncAElement class]);
 
211
    addElementClass(SVGNames::feFuncBTag, [DOMSVGFEFuncBElement class]);
 
212
    addElementClass(SVGNames::feFuncGTag, [DOMSVGFEFuncGElement class]);
 
213
    addElementClass(SVGNames::feFuncRTag, [DOMSVGFEFuncRElement class]);
 
214
    addElementClass(SVGNames::feGaussianBlurTag, [DOMSVGFEGaussianBlurElement class]);
 
215
    addElementClass(SVGNames::feImageTag, [DOMSVGFEImageElement class]);
 
216
    addElementClass(SVGNames::feMergeTag, [DOMSVGFEMergeElement class]);
 
217
    addElementClass(SVGNames::feMergeNodeTag, [DOMSVGFEMergeNodeElement class]);
 
218
    addElementClass(SVGNames::feOffsetTag, [DOMSVGFEOffsetElement class]);
 
219
    addElementClass(SVGNames::fePointLightTag, [DOMSVGFEPointLightElement class]);
 
220
    addElementClass(SVGNames::feSpecularLightingTag, [DOMSVGFESpecularLightingElement class]);
 
221
    addElementClass(SVGNames::feSpotLightTag, [DOMSVGFESpotLightElement class]);
 
222
    addElementClass(SVGNames::feTileTag, [DOMSVGFETileElement class]);
 
223
    addElementClass(SVGNames::feTurbulenceTag, [DOMSVGFETurbulenceElement class]);
 
224
    addElementClass(SVGNames::filterTag, [DOMSVGFilterElement class]);
 
225
    addElementClass(SVGNames::foreignObjectTag, [DOMSVGForeignObjectElement class]);
 
226
#endif
 
227
    addElementClass(SVGNames::gTag, [DOMSVGGElement class]);
 
228
    addElementClass(SVGNames::imageTag, [DOMSVGImageElement class]);
 
229
    addElementClass(SVGNames::lineTag, [DOMSVGLineElement class]);
 
230
    addElementClass(SVGNames::linearGradientTag, [DOMSVGLinearGradientElement class]);
 
231
    addElementClass(SVGNames::markerTag, [DOMSVGMarkerElement class]);
 
232
    addElementClass(SVGNames::maskTag, [DOMSVGMaskElement class]);
 
233
    addElementClass(SVGNames::metadataTag, [DOMSVGMetadataElement class]);
 
234
    addElementClass(SVGNames::pathTag, [DOMSVGPathElement class]);
 
235
    addElementClass(SVGNames::patternTag, [DOMSVGPatternElement class]);
 
236
    addElementClass(SVGNames::polygonTag, [DOMSVGPolygonElement class]);
 
237
    addElementClass(SVGNames::polylineTag, [DOMSVGPolylineElement class]);
 
238
    addElementClass(SVGNames::radialGradientTag, [DOMSVGRadialGradientElement class]);
 
239
    addElementClass(SVGNames::rectTag, [DOMSVGRectElement class]);
 
240
    addElementClass(SVGNames::scriptTag, [DOMSVGScriptElement class]);
 
241
    addElementClass(SVGNames::setTag, [DOMSVGSetElement class]);
 
242
    addElementClass(SVGNames::stopTag, [DOMSVGStopElement class]);
 
243
    addElementClass(SVGNames::styleTag, [DOMSVGStyleElement class]);
 
244
    addElementClass(SVGNames::svgTag, [DOMSVGSVGElement class]);
 
245
    addElementClass(SVGNames::switchTag, [DOMSVGSwitchElement class]);
 
246
    addElementClass(SVGNames::symbolTag, [DOMSVGSymbolElement class]);
 
247
    addElementClass(SVGNames::textTag, [DOMSVGTextElement class]);
 
248
    addElementClass(SVGNames::titleTag, [DOMSVGTitleElement class]);
 
249
    addElementClass(SVGNames::trefTag, [DOMSVGTRefElement class]);
 
250
    addElementClass(SVGNames::tspanTag, [DOMSVGTSpanElement class]);
 
251
    addElementClass(SVGNames::useTag, [DOMSVGUseElement class]);
 
252
    addElementClass(SVGNames::viewTag, [DOMSVGViewElement class]);
 
253
#endif
 
254
}
 
255
 
 
256
static Class elementClass(const QualifiedName& tag, Class defaultClass)
 
257
{
 
258
    if (!elementClassMap)
 
259
        createElementClassMap();
 
260
    Class objcClass = elementClassMap->get(tag.impl());
 
261
    if (!objcClass)
 
262
        objcClass = defaultClass;
 
263
    return objcClass;
 
264
}
 
265
 
 
266
static NSArray *kit(const Vector<IntRect>& rects)
 
267
{
 
268
    size_t size = rects.size();
 
269
    NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
 
270
    for (size_t i = 0; i < size; ++i)
 
271
        [array addObject:[NSValue valueWithRect:rects[i]]];
 
272
    return array;
 
273
}
 
274
 
 
275
} // namespace WebCore
 
276
 
 
277
@implementation DOMNode (WebCoreInternal)
 
278
 
 
279
// FIXME: should this go in the main implementation?
 
280
- (NSString *)description
 
281
{
 
282
    if (!_internal)
 
283
        return [NSString stringWithFormat:@"<%@: null>", [[self class] description], self];
 
284
 
 
285
    NSString *value = [self nodeValue];
 
286
    if (value)
 
287
        return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>",
 
288
            [[self class] description], [self nodeName], _internal, value];
 
289
 
 
290
    return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal];
 
291
}
 
292
 
 
293
- (id)_initWithNode:(WebCore::Node *)impl
 
294
{
 
295
    ASSERT(impl);
 
296
 
 
297
    [super _init];
 
298
    _internal = reinterpret_cast<DOMObjectInternal*>(impl);
 
299
    impl->ref();
 
300
    WebCore::addDOMWrapper(self, impl);
 
301
    return self;
 
302
}
 
303
 
 
304
+ (DOMNode *)_wrapNode:(WebCore::Node *)impl
 
305
{
 
306
    if (!impl)
 
307
        return nil;
 
308
 
 
309
    id cachedInstance;
 
310
    cachedInstance = WebCore::getDOMWrapper(impl);
 
311
    if (cachedInstance)
 
312
        return [[cachedInstance retain] autorelease];
 
313
 
 
314
    Class wrapperClass = nil;
 
315
    switch (impl->nodeType()) {
 
316
        case WebCore::Node::ELEMENT_NODE:
 
317
            if (impl->isHTMLElement())
 
318
                wrapperClass = WebCore::elementClass(static_cast<WebCore::HTMLElement*>(impl)->tagQName(), [DOMHTMLElement class]);
 
319
#if ENABLE(SVG)
 
320
            else if (impl->isSVGElement())
 
321
                wrapperClass = WebCore::elementClass(static_cast<WebCore::SVGElement*>(impl)->tagQName(), [DOMSVGElement class]);
 
322
#endif
 
323
            else
 
324
                wrapperClass = [DOMElement class];
 
325
            break;
 
326
        case WebCore::Node::ATTRIBUTE_NODE:
 
327
            wrapperClass = [DOMAttr class];
 
328
            break;
 
329
        case WebCore::Node::TEXT_NODE:
 
330
            wrapperClass = [DOMText class];
 
331
            break;
 
332
        case WebCore::Node::CDATA_SECTION_NODE:
 
333
            wrapperClass = [DOMCDATASection class];
 
334
            break;
 
335
        case WebCore::Node::ENTITY_REFERENCE_NODE:
 
336
            wrapperClass = [DOMEntityReference class];
 
337
            break;
 
338
        case WebCore::Node::ENTITY_NODE:
 
339
            wrapperClass = [DOMEntity class];
 
340
            break;
 
341
        case WebCore::Node::PROCESSING_INSTRUCTION_NODE:
 
342
            wrapperClass = [DOMProcessingInstruction class];
 
343
            break;
 
344
        case WebCore::Node::COMMENT_NODE:
 
345
            wrapperClass = [DOMComment class];
 
346
            break;
 
347
        case WebCore::Node::DOCUMENT_NODE:
 
348
            if (static_cast<WebCore::Document*>(impl)->isHTMLDocument())
 
349
                wrapperClass = [DOMHTMLDocument class];
 
350
#if ENABLE(SVG)
 
351
            else if (static_cast<WebCore::Document*>(impl)->isSVGDocument())
 
352
                wrapperClass = [DOMSVGDocument class];
 
353
#endif
 
354
            else
 
355
                wrapperClass = [DOMDocument class];
 
356
            break;
 
357
        case WebCore::Node::DOCUMENT_TYPE_NODE:
 
358
            wrapperClass = [DOMDocumentType class];
 
359
            break;
 
360
        case WebCore::Node::DOCUMENT_FRAGMENT_NODE:
 
361
            wrapperClass = [DOMDocumentFragment class];
 
362
            break;
 
363
        case WebCore::Node::NOTATION_NODE:
 
364
            wrapperClass = [DOMNotation class];
 
365
            break;
 
366
        case WebCore::Node::XPATH_NAMESPACE_NODE:
 
367
            // FIXME: Create an XPath objective C wrapper
 
368
            // See http://bugs.webkit.org/show_bug.cgi?id=8755
 
369
            return nil;
 
370
    }
 
371
    return [[[wrapperClass alloc] _initWithNode:impl] autorelease];
 
372
}
 
373
 
 
374
+ (id <DOMEventTarget>)_wrapEventTarget:(WebCore::EventTarget *)eventTarget
 
375
{
 
376
    if (!eventTarget)
 
377
        return nil;
 
378
    
 
379
    // We don't have an ObjC binding for XMLHttpRequest
 
380
    return [DOMNode _wrapNode:eventTarget->toNode()];
 
381
}
 
382
 
 
383
- (WebCore::Node *)_node
 
384
{
 
385
    return reinterpret_cast<WebCore::Node*>(_internal);
 
386
}
 
387
 
 
388
- (KJS::Bindings::RootObject*)_rootObject
 
389
{
 
390
    if (WebCore::Node *n = [self _node]) {
 
391
        if (WebCore::Frame* frame = n->document()->frame())
 
392
            return frame->bindingRootObject();
 
393
    }
 
394
    return 0;
 
395
}
 
396
 
 
397
@end
 
398
 
 
399
@implementation DOMNode (DOMNodeExtensions)
 
400
 
 
401
// FIXME: This should be implemented in Node so we don't have to fetch the renderer.
 
402
// If it was, we could even autogenerate.
 
403
- (NSRect)boundingBox
 
404
{
 
405
    [self _node]->document()->updateLayoutIgnorePendingStylesheets();
 
406
    WebCore::RenderObject *renderer = [self _node]->renderer();
 
407
    if (renderer)
 
408
        return renderer->absoluteBoundingBoxRect();
 
409
    return NSZeroRect;
 
410
}
 
411
 
 
412
// FIXME: This should be implemented in Node so we don't have to fetch the renderer.
 
413
// If it was, we could even autogenerate.
 
414
- (NSArray *)lineBoxRects
 
415
{
 
416
    [self _node]->document()->updateLayoutIgnorePendingStylesheets();
 
417
    WebCore::RenderObject *renderer = [self _node]->renderer();
 
418
    if (renderer) {
 
419
        Vector<WebCore::IntRect> rects;
 
420
        renderer->addLineBoxRects(rects);
 
421
        return kit(rects);
 
422
    }
 
423
    return nil;
 
424
}
 
425
 
 
426
@end
 
427
 
 
428
@implementation DOMRange (DOMRangeExtensions)
 
429
 
 
430
- (NSRect)boundingBox
 
431
{
 
432
    [self _range]->ownerDocument()->updateLayoutIgnorePendingStylesheets();
 
433
    return [self _range]->boundingBox();
 
434
}
 
435
 
 
436
- (NSArray *)lineBoxRects
 
437
{
 
438
    Vector<WebCore::IntRect> rects;
 
439
    [self _range]->ownerDocument()->updateLayoutIgnorePendingStylesheets();
 
440
    [self _range]->addLineBoxRects(rects);
 
441
    return kit(rects);
 
442
}
 
443
 
 
444
@end
 
445
 
 
446
// FIXME: this should be auto-generated
 
447
@implementation DOMNode (DOMEventTarget)
 
448
 
 
449
- (void)addEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture
 
450
{
 
451
    if (![self _node]->isEventTargetNode())
 
452
        WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);
 
453
    
 
454
    WebCore::EventListener *wrapper = WebCore::ObjCEventListener::create(listener);
 
455
    WebCore::EventTargetNodeCast([self _node])->addEventListener(type, wrapper, useCapture);
 
456
    wrapper->deref();
 
457
}
 
458
 
 
459
- (void)addEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture
 
460
{
 
461
    // FIXME: this method can be removed once Mail changes to use the new method <rdar://problem/4746649>
 
462
    [self addEventListener:type listener:listener useCapture:useCapture];
 
463
}
 
464
 
 
465
- (void)removeEventListener:(NSString *)type listener:(id <DOMEventListener>)listener useCapture:(BOOL)useCapture
 
466
{
 
467
    if (![self _node]->isEventTargetNode())
 
468
        WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);
 
469
 
 
470
    if (WebCore::EventListener *wrapper = WebCore::ObjCEventListener::find(listener))
 
471
        WebCore::EventTargetNodeCast([self _node])->removeEventListener(type, wrapper, useCapture);
 
472
}
 
473
 
 
474
- (void)removeEventListener:(NSString *)type :(id <DOMEventListener>)listener :(BOOL)useCapture
 
475
{
 
476
    // FIXME: this method can be removed once Mail changes to use the new method <rdar://problem/4746649>
 
477
    [self removeEventListener:type listener:listener useCapture:useCapture];
 
478
}
 
479
 
 
480
- (BOOL)dispatchEvent:(DOMEvent *)event
 
481
{
 
482
    if (![self _node]->isEventTargetNode())
 
483
        WebCore::raiseDOMException(DOM_NOT_SUPPORTED_ERR);
 
484
 
 
485
    WebCore::ExceptionCode ec = 0;
 
486
    BOOL result = WebCore::EventTargetNodeCast([self _node])->dispatchEvent([event _event], ec);
 
487
    WebCore::raiseOnDOMError(ec);
 
488
    return result;
 
489
}
 
490
 
 
491
@end
 
492
 
 
493
//------------------------------------------------------------------------------------------
 
494
// DOMElement
 
495
 
 
496
// FIXME: this should be auto-generated in DOMElement.mm
 
497
@implementation DOMElement (DOMElementAppKitExtensions)
 
498
 
 
499
// FIXME: this should be implemented in the implementation
 
500
- (NSImage*)image
 
501
{
 
502
    WebCore::RenderObject* renderer = [self _element]->renderer();
 
503
    if (renderer && renderer->isImage()) {
 
504
        WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
 
505
        if (img->cachedImage() && !img->cachedImage()->errorOccurred())
 
506
            return img->cachedImage()->image()->getNSImage();
 
507
    }
 
508
    return nil;
 
509
}
 
510
 
 
511
@end
 
512
 
 
513
@implementation DOMElement (WebPrivate)
 
514
 
 
515
// FIXME: this should be implemented in the implementation
 
516
- (NSFont *)_font
 
517
{
 
518
    WebCore::RenderObject* renderer = [self _element]->renderer();
 
519
    if (renderer)
 
520
        return renderer->style()->font().primaryFont()->getNSFont();
 
521
    return nil;
 
522
}
 
523
 
 
524
// FIXME: this should be implemented in the implementation
 
525
- (NSData *)_imageTIFFRepresentation
 
526
{
 
527
    WebCore::RenderObject* renderer = [self _element]->renderer();
 
528
    if (renderer && renderer->isImage()) {
 
529
        WebCore::RenderImage* img = static_cast<WebCore::RenderImage*>(renderer);
 
530
        if (img->cachedImage() && !img->cachedImage()->errorOccurred())
 
531
            return (NSData*)(img->cachedImage()->image()->getTIFFRepresentation());
 
532
    }
 
533
    return nil;
 
534
}
 
535
 
 
536
- (NSRect)_windowClipRect
 
537
{
 
538
    WebCore::RenderObject* renderer = [self _element]->renderer();
 
539
    if (renderer && renderer->view()) {
 
540
        WebCore::FrameView* frameView = renderer->view()->frameView();
 
541
        if (!frameView)
 
542
            return WebCore::IntRect();
 
543
        return frameView->windowClipRectForLayer(renderer->enclosingLayer(), true);
 
544
    }
 
545
    return WebCore::IntRect();
 
546
}
 
547
 
 
548
// FIXME: this should be implemented in the implementation
 
549
- (NSURL *)_getURLAttribute:(NSString *)name
 
550
{
 
551
    ASSERT(name);
 
552
    WebCore::Element* element = [self _element];
 
553
    ASSERT(element);
 
554
    return WebCore::KURL(element->document()->completeURL(parseURL(element->getAttribute(name)).deprecatedString())).getNSURL();
 
555
}
 
556
 
 
557
// FIXME: this should be implemented in the implementation
 
558
- (void *)_NPObject
 
559
{
 
560
#if USE(NPOBJECT)
 
561
    WebCore::Element* element = [self _element];
 
562
    if (element->hasTagName(WebCore::HTMLNames::appletTag) || element->hasTagName(WebCore::HTMLNames::embedTag) || element->hasTagName(WebCore::HTMLNames::objectTag))
 
563
        return static_cast<WebCore::HTMLPlugInElement*>(element)->getNPObject();
 
564
#endif
 
565
    return 0;
 
566
}
 
567
 
 
568
// FIXME: this should be implemented in the implementation
 
569
- (BOOL)isFocused
 
570
{
 
571
    WebCore::Element* impl = [self _element];
 
572
    if (impl->document()->focusedNode() == impl)
 
573
        return YES;
 
574
    return NO;
 
575
}
 
576
 
 
577
@end
 
578
 
 
579
 
 
580
//------------------------------------------------------------------------------------------
 
581
// DOMRange
 
582
 
 
583
@implementation DOMRange (WebPrivate)
 
584
 
 
585
- (NSString *)description
 
586
{
 
587
    if (!_internal)
 
588
        return @"<DOMRange: null>";
 
589
    return [NSString stringWithFormat:@"<DOMRange: %@ %d %@ %d>",
 
590
               [self startContainer], [self startOffset], [self endContainer], [self endOffset]];
 
591
}
 
592
 
 
593
// FIXME: this should be removed as soon as all internal Apple uses of it have been replaced with
 
594
// calls to the public method - (NSString *)text.
 
595
- (NSString *)_text
 
596
{
 
597
    return [self text];
 
598
}
 
599
 
 
600
@end
 
601
 
 
602
 
 
603
//------------------------------------------------------------------------------------------
 
604
// DOMNodeFilter
 
605
 
 
606
// FIXME: This implementation should be in it's own file.
 
607
 
 
608
@implementation DOMNodeFilter
 
609
 
 
610
- (id)_initWithNodeFilter:(WebCore::NodeFilter *)impl
 
611
{
 
612
    ASSERT(impl);
 
613
 
 
614
    [super _init];
 
615
    _internal = reinterpret_cast<DOMObjectInternal*>(impl);
 
616
    impl->ref();
 
617
    WebCore::addDOMWrapper(self, impl);
 
618
    return self;
 
619
}
 
620
 
 
621
+ (DOMNodeFilter *)_wrapNodeFilter:(WebCore::NodeFilter *)impl
 
622
{
 
623
    if (!impl)
 
624
        return nil;
 
625
    
 
626
    id cachedInstance;
 
627
    cachedInstance = WebCore::getDOMWrapper(impl);
 
628
    if (cachedInstance)
 
629
        return [[cachedInstance retain] autorelease];
 
630
    
 
631
    return [[[self alloc] _initWithNodeFilter:impl] autorelease];
 
632
}
 
633
 
 
634
- (WebCore::NodeFilter *)_nodeFilter
 
635
{
 
636
    return reinterpret_cast<WebCore::NodeFilter*>(_internal);
 
637
}
 
638
 
 
639
- (void)dealloc
 
640
{
 
641
    if (_internal)
 
642
        reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
 
643
    [super dealloc];
 
644
}
 
645
 
 
646
- (void)finalize
 
647
{
 
648
    if (_internal)
 
649
        reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
 
650
    [super finalize];
 
651
}
 
652
 
 
653
- (short)acceptNode:(DOMNode *)node
 
654
{
 
655
    return [self _nodeFilter]->acceptNode([node _node]);
 
656
}
 
657
 
 
658
@end
 
659
 
 
660
 
 
661
//------------------------------------------------------------------------------------------
 
662
// ObjCNodeFilterCondition
 
663
 
 
664
class ObjCNodeFilterCondition : public WebCore::NodeFilterCondition {
 
665
public:
 
666
    ObjCNodeFilterCondition(id <DOMNodeFilter>);
 
667
    virtual ~ObjCNodeFilterCondition();
 
668
    virtual short acceptNode(WebCore::Node*) const;
 
669
 
 
670
private:
 
671
    ObjCNodeFilterCondition(const ObjCNodeFilterCondition&);
 
672
    ObjCNodeFilterCondition &operator=(const ObjCNodeFilterCondition&);
 
673
 
 
674
    id <DOMNodeFilter> m_filter;
 
675
};
 
676
 
 
677
ObjCNodeFilterCondition::ObjCNodeFilterCondition(id <DOMNodeFilter> filter)
 
678
    : m_filter(filter)
 
679
{
 
680
    ASSERT(m_filter);
 
681
    HardRetain(m_filter);
 
682
}
 
683
 
 
684
ObjCNodeFilterCondition::~ObjCNodeFilterCondition()
 
685
{
 
686
    HardRelease(m_filter);
 
687
}
 
688
 
 
689
short ObjCNodeFilterCondition::acceptNode(WebCore::Node* node) const
 
690
{
 
691
    if (!node)
 
692
        return WebCore::NodeFilter::FILTER_REJECT;
 
693
    return [m_filter acceptNode:[DOMNode _wrapNode:node]];
 
694
}
 
695
 
 
696
 
 
697
//------------------------------------------------------------------------------------------
 
698
// DOMDocument (DOMDocumentTraversal)
 
699
 
 
700
// FIXME: this should be auto-generated in DOMDocument.mm
 
701
@implementation DOMDocument (DOMDocumentTraversal)
 
702
 
 
703
- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root whatToShow:(unsigned)whatToShow filter:(id <DOMNodeFilter>)filter expandEntityReferences:(BOOL)expandEntityReferences
 
704
{
 
705
    WebCore::NodeFilter* cppFilter = 0;
 
706
    if (filter)
 
707
        cppFilter = new WebCore::NodeFilter(new ObjCNodeFilterCondition(filter));
 
708
    WebCore::ExceptionCode ec = 0;
 
709
    RefPtr<WebCore::NodeIterator> impl = [self _document]->createNodeIterator([root _node], whatToShow, cppFilter, expandEntityReferences, ec);
 
710
    WebCore::raiseOnDOMError(ec);
 
711
    return [DOMNodeIterator _wrapNodeIterator:impl.get() filter:filter];
 
712
}
 
713
 
 
714
- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root whatToShow:(unsigned)whatToShow filter:(id <DOMNodeFilter>)filter expandEntityReferences:(BOOL)expandEntityReferences
 
715
{
 
716
    WebCore::NodeFilter* cppFilter = 0;
 
717
    if (filter)
 
718
        cppFilter = new WebCore::NodeFilter(new ObjCNodeFilterCondition(filter));
 
719
    WebCore::ExceptionCode ec = 0;
 
720
    RefPtr<WebCore::TreeWalker> impl = [self _document]->createTreeWalker([root _node], whatToShow, cppFilter, expandEntityReferences, ec);
 
721
    WebCore::raiseOnDOMError(ec);
 
722
    return [DOMTreeWalker _wrapTreeWalker:impl.get() filter:filter];
 
723
}
 
724
 
 
725
@end
 
726
 
 
727
@implementation DOMDocument (DOMDocumentTraversalDeprecated)
 
728
 
 
729
- (DOMNodeIterator *)createNodeIterator:(DOMNode *)root :(unsigned)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
 
730
{
 
731
    return [self createNodeIterator:root whatToShow:whatToShow filter:filter expandEntityReferences:expandEntityReferences];
 
732
}
 
733
 
 
734
- (DOMTreeWalker *)createTreeWalker:(DOMNode *)root :(unsigned)whatToShow :(id <DOMNodeFilter>)filter :(BOOL)expandEntityReferences
 
735
{
 
736
    return [self createTreeWalker:root whatToShow:whatToShow filter:filter expandEntityReferences:expandEntityReferences];
 
737
}
 
738
 
 
739
@end
 
740
 
 
741
 
 
742
//------------------------------------------------------------------------------------------
 
743
// ObjCEventListener
 
744
 
 
745
namespace WebCore {
 
746
 
 
747
ObjCEventListener* ObjCEventListener::find(id <DOMEventListener> listener)
 
748
{
 
749
    if (ListenerMap* map = listenerMap)
 
750
        return map->get(listener);
 
751
    return 0;
 
752
}
 
753
 
 
754
ObjCEventListener *ObjCEventListener::create(id <DOMEventListener> listener)
 
755
{
 
756
    ObjCEventListener* wrapper = find(listener);
 
757
    if (!wrapper)
 
758
        wrapper = new ObjCEventListener(listener);
 
759
    wrapper->ref();
 
760
    return wrapper;
 
761
}
 
762
 
 
763
ObjCEventListener::ObjCEventListener(id <DOMEventListener> listener)
 
764
    : m_listener([listener retain])
 
765
{
 
766
    ListenerMap* map = listenerMap;
 
767
    if (!map) {
 
768
        map = new ListenerMap;
 
769
        listenerMap = map;
 
770
    }
 
771
    map->set(listener, this);
 
772
}
 
773
 
 
774
ObjCEventListener::~ObjCEventListener()
 
775
{
 
776
    listenerMap->remove(m_listener);
 
777
    [m_listener release];
 
778
}
 
779
 
 
780
void ObjCEventListener::handleEvent(Event* event, bool)
 
781
{
 
782
    [m_listener handleEvent:[DOMEvent _wrapEvent:event]];
 
783
}
 
784
 
 
785
} // namespace WebCore