2011-01-07 Adam Barth <abarth@webkit.org>
[WebKit-https.git] / Source / WebCore / bindings / objc / DOM.mm
1 /*
2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 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 "DOMInternal.h" // import first to make the private/public trick work
30 #import "DOM.h"
31
32 #import "DOMElementInternal.h"
33 #import "DOMHTMLCanvasElement.h"
34 #import "DOMNodeInternal.h"
35 #import "DOMPrivate.h"
36 #import "DOMRangeInternal.h"
37 #import "Frame.h"
38 #import "HTMLElement.h"
39 #import "HTMLNames.h"
40 #import "HTMLParserIdioms.h"
41 #import "Image.h"
42 #import "NodeFilter.h"
43 #import "RenderImage.h"
44 #import "WebScriptObjectPrivate.h"
45 #import <wtf/HashMap.h>
46
47 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
48 #import "DOMSVG.h"
49 #import "SVGElementInstance.h"
50 #import "SVGNames.h"
51 #endif
52
53 using namespace JSC;
54 using namespace WebCore;
55
56 // FIXME: Would be nice to break this up into separate files to match how other WebKit
57 // code is organized.
58
59 //------------------------------------------------------------------------------------------
60 // DOMNode
61
62 namespace WebCore {
63
64 typedef HashMap<const QualifiedName::QualifiedNameImpl*, Class> ObjCClassMap;
65 static ObjCClassMap* elementClassMap;
66
67 static void addElementClass(const QualifiedName& tag, Class objCClass)
68 {
69     elementClassMap->set(tag.impl(), objCClass);
70 }
71
72 static void createElementClassMap()
73 {
74     // Create the table.
75     elementClassMap = new ObjCClassMap;
76
77     // FIXME: Reflect marquee once the API has been determined.
78
79     // Populate it with HTML and SVG element classes.
80     addElementClass(HTMLNames::aTag, [DOMHTMLAnchorElement class]);
81     addElementClass(HTMLNames::appletTag, [DOMHTMLAppletElement class]);
82     addElementClass(HTMLNames::areaTag, [DOMHTMLAreaElement class]);
83     addElementClass(HTMLNames::baseTag, [DOMHTMLBaseElement class]);
84     addElementClass(HTMLNames::basefontTag, [DOMHTMLBaseFontElement class]);
85     addElementClass(HTMLNames::bodyTag, [DOMHTMLBodyElement class]);
86     addElementClass(HTMLNames::brTag, [DOMHTMLBRElement class]);
87     addElementClass(HTMLNames::buttonTag, [DOMHTMLButtonElement class]);
88     addElementClass(HTMLNames::canvasTag, [DOMHTMLCanvasElement class]);
89     addElementClass(HTMLNames::captionTag, [DOMHTMLTableCaptionElement class]);
90     addElementClass(HTMLNames::colTag, [DOMHTMLTableColElement class]);
91     addElementClass(HTMLNames::colgroupTag, [DOMHTMLTableColElement class]);
92     addElementClass(HTMLNames::delTag, [DOMHTMLModElement class]);
93     addElementClass(HTMLNames::dirTag, [DOMHTMLDirectoryElement class]);
94     addElementClass(HTMLNames::divTag, [DOMHTMLDivElement class]);
95     addElementClass(HTMLNames::dlTag, [DOMHTMLDListElement class]);
96     addElementClass(HTMLNames::embedTag, [DOMHTMLEmbedElement class]);
97     addElementClass(HTMLNames::fieldsetTag, [DOMHTMLFieldSetElement class]);
98     addElementClass(HTMLNames::fontTag, [DOMHTMLFontElement class]);
99     addElementClass(HTMLNames::formTag, [DOMHTMLFormElement class]);
100     addElementClass(HTMLNames::frameTag, [DOMHTMLFrameElement class]);
101     addElementClass(HTMLNames::framesetTag, [DOMHTMLFrameSetElement class]);
102     addElementClass(HTMLNames::h1Tag, [DOMHTMLHeadingElement class]);
103     addElementClass(HTMLNames::h2Tag, [DOMHTMLHeadingElement class]);
104     addElementClass(HTMLNames::h3Tag, [DOMHTMLHeadingElement class]);
105     addElementClass(HTMLNames::h4Tag, [DOMHTMLHeadingElement class]);
106     addElementClass(HTMLNames::h5Tag, [DOMHTMLHeadingElement class]);
107     addElementClass(HTMLNames::h6Tag, [DOMHTMLHeadingElement class]);
108     addElementClass(HTMLNames::headTag, [DOMHTMLHeadElement class]);
109     addElementClass(HTMLNames::hrTag, [DOMHTMLHRElement class]);
110     addElementClass(HTMLNames::htmlTag, [DOMHTMLHtmlElement class]);
111     addElementClass(HTMLNames::iframeTag, [DOMHTMLIFrameElement class]);
112     addElementClass(HTMLNames::imgTag, [DOMHTMLImageElement class]);
113     addElementClass(HTMLNames::inputTag, [DOMHTMLInputElement class]);
114     addElementClass(HTMLNames::insTag, [DOMHTMLModElement class]);
115     addElementClass(HTMLNames::isindexTag, [DOMHTMLIsIndexElement class]);
116     addElementClass(HTMLNames::labelTag, [DOMHTMLLabelElement class]);
117     addElementClass(HTMLNames::legendTag, [DOMHTMLLegendElement class]);
118     addElementClass(HTMLNames::liTag, [DOMHTMLLIElement class]);
119     addElementClass(HTMLNames::linkTag, [DOMHTMLLinkElement class]);
120     addElementClass(HTMLNames::listingTag, [DOMHTMLPreElement class]);
121     addElementClass(HTMLNames::mapTag, [DOMHTMLMapElement class]);
122     addElementClass(HTMLNames::marqueeTag, [DOMHTMLMarqueeElement class]);
123     addElementClass(HTMLNames::menuTag, [DOMHTMLMenuElement class]);
124     addElementClass(HTMLNames::metaTag, [DOMHTMLMetaElement class]);
125     addElementClass(HTMLNames::objectTag, [DOMHTMLObjectElement class]);
126     addElementClass(HTMLNames::olTag, [DOMHTMLOListElement class]);
127     addElementClass(HTMLNames::optgroupTag, [DOMHTMLOptGroupElement class]);
128     addElementClass(HTMLNames::optionTag, [DOMHTMLOptionElement class]);
129     addElementClass(HTMLNames::pTag, [DOMHTMLParagraphElement class]);
130     addElementClass(HTMLNames::paramTag, [DOMHTMLParamElement class]);
131     addElementClass(HTMLNames::preTag, [DOMHTMLPreElement class]);
132     addElementClass(HTMLNames::qTag, [DOMHTMLQuoteElement class]);
133     addElementClass(HTMLNames::scriptTag, [DOMHTMLScriptElement class]);
134     addElementClass(HTMLNames::keygenTag, [DOMHTMLSelectElement class]);
135     addElementClass(HTMLNames::selectTag, [DOMHTMLSelectElement class]);
136     addElementClass(HTMLNames::styleTag, [DOMHTMLStyleElement class]);
137     addElementClass(HTMLNames::tableTag, [DOMHTMLTableElement class]);
138     addElementClass(HTMLNames::tbodyTag, [DOMHTMLTableSectionElement class]);
139     addElementClass(HTMLNames::tdTag, [DOMHTMLTableCellElement class]);
140     addElementClass(HTMLNames::textareaTag, [DOMHTMLTextAreaElement class]);
141     addElementClass(HTMLNames::tfootTag, [DOMHTMLTableSectionElement class]);
142     addElementClass(HTMLNames::thTag, [DOMHTMLTableCellElement class]);
143     addElementClass(HTMLNames::theadTag, [DOMHTMLTableSectionElement class]);
144     addElementClass(HTMLNames::titleTag, [DOMHTMLTitleElement class]);
145     addElementClass(HTMLNames::trTag, [DOMHTMLTableRowElement class]);
146     addElementClass(HTMLNames::ulTag, [DOMHTMLUListElement class]);
147     addElementClass(HTMLNames::xmpTag, [DOMHTMLPreElement class]);
148
149 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
150     addElementClass(SVGNames::aTag, [DOMSVGAElement class]);
151     addElementClass(SVGNames::altGlyphTag, [DOMSVGAltGlyphElement class]);
152 #if ENABLE(SVG_ANIMATION)
153     addElementClass(SVGNames::animateTag, [DOMSVGAnimateElement class]);
154     addElementClass(SVGNames::animateColorTag, [DOMSVGAnimateColorElement class]);
155     addElementClass(SVGNames::animateTransformTag, [DOMSVGAnimateTransformElement class]);
156     addElementClass(SVGNames::setTag, [DOMSVGSetElement class]);
157 #endif
158     addElementClass(SVGNames::circleTag, [DOMSVGCircleElement class]);
159     addElementClass(SVGNames::clipPathTag, [DOMSVGClipPathElement class]);
160     addElementClass(SVGNames::cursorTag, [DOMSVGCursorElement class]);
161     addElementClass(SVGNames::defsTag, [DOMSVGDefsElement class]);
162     addElementClass(SVGNames::descTag, [DOMSVGDescElement class]);
163     addElementClass(SVGNames::ellipseTag, [DOMSVGEllipseElement class]);
164 #if ENABLE(FILTERS)
165     addElementClass(SVGNames::feBlendTag, [DOMSVGFEBlendElement class]);
166     addElementClass(SVGNames::feColorMatrixTag, [DOMSVGFEColorMatrixElement class]);
167     addElementClass(SVGNames::feComponentTransferTag, [DOMSVGFEComponentTransferElement class]);
168     addElementClass(SVGNames::feCompositeTag, [DOMSVGFECompositeElement class]);
169     addElementClass(SVGNames::feConvolveMatrixTag, [DOMSVGFEConvolveMatrixElement class]);
170     addElementClass(SVGNames::feDiffuseLightingTag, [DOMSVGFEDiffuseLightingElement class]);
171     addElementClass(SVGNames::feDisplacementMapTag, [DOMSVGFEDisplacementMapElement class]);
172     addElementClass(SVGNames::feDistantLightTag, [DOMSVGFEDistantLightElement class]);
173     addElementClass(SVGNames::feFloodTag, [DOMSVGFEFloodElement class]);
174     addElementClass(SVGNames::feFuncATag, [DOMSVGFEFuncAElement class]);
175     addElementClass(SVGNames::feFuncBTag, [DOMSVGFEFuncBElement class]);
176     addElementClass(SVGNames::feFuncGTag, [DOMSVGFEFuncGElement class]);
177     addElementClass(SVGNames::feFuncRTag, [DOMSVGFEFuncRElement class]);
178     addElementClass(SVGNames::feGaussianBlurTag, [DOMSVGFEGaussianBlurElement class]);
179     addElementClass(SVGNames::feImageTag, [DOMSVGFEImageElement class]);
180     addElementClass(SVGNames::feMergeTag, [DOMSVGFEMergeElement class]);
181     addElementClass(SVGNames::feMergeNodeTag, [DOMSVGFEMergeNodeElement class]);
182     addElementClass(SVGNames::feMorphologyTag, [DOMSVGFEMorphologyElement class]);
183     addElementClass(SVGNames::feOffsetTag, [DOMSVGFEOffsetElement class]);
184     addElementClass(SVGNames::fePointLightTag, [DOMSVGFEPointLightElement class]);
185     addElementClass(SVGNames::feSpecularLightingTag, [DOMSVGFESpecularLightingElement class]);
186     addElementClass(SVGNames::feSpotLightTag, [DOMSVGFESpotLightElement class]);
187     addElementClass(SVGNames::feTileTag, [DOMSVGFETileElement class]);
188     addElementClass(SVGNames::feTurbulenceTag, [DOMSVGFETurbulenceElement class]);
189     addElementClass(SVGNames::filterTag, [DOMSVGFilterElement class]);
190 #endif
191 #if ENABLE(SVG_FONTS)
192     addElementClass(SVGNames::fontTag, [DOMSVGFontElement class]);
193     addElementClass(SVGNames::font_faceTag, [DOMSVGFontFaceElement class]);
194     addElementClass(SVGNames::font_face_formatTag, [DOMSVGFontFaceFormatElement class]);
195     addElementClass(SVGNames::font_face_nameTag, [DOMSVGFontFaceNameElement class]);
196     addElementClass(SVGNames::font_face_srcTag, [DOMSVGFontFaceSrcElement class]);
197     addElementClass(SVGNames::font_face_uriTag, [DOMSVGFontFaceUriElement class]);
198     addElementClass(SVGNames::glyphTag, [DOMSVGGlyphElement class]);
199 #endif
200     addElementClass(SVGNames::gTag, [DOMSVGGElement class]);
201     addElementClass(SVGNames::imageTag, [DOMSVGImageElement class]);
202     addElementClass(SVGNames::lineTag, [DOMSVGLineElement class]);
203     addElementClass(SVGNames::linearGradientTag, [DOMSVGLinearGradientElement class]);
204     addElementClass(SVGNames::markerTag, [DOMSVGMarkerElement class]);
205     addElementClass(SVGNames::maskTag, [DOMSVGMaskElement class]);
206     addElementClass(SVGNames::metadataTag, [DOMSVGMetadataElement class]);
207 #if ENABLE(SVG_FONTS)
208     addElementClass(SVGNames::missing_glyphTag, [DOMSVGMissingGlyphElement class]);
209 #endif
210     addElementClass(SVGNames::pathTag, [DOMSVGPathElement class]);
211     addElementClass(SVGNames::patternTag, [DOMSVGPatternElement class]);
212     addElementClass(SVGNames::polygonTag, [DOMSVGPolygonElement class]);
213     addElementClass(SVGNames::polylineTag, [DOMSVGPolylineElement class]);
214     addElementClass(SVGNames::radialGradientTag, [DOMSVGRadialGradientElement class]);
215     addElementClass(SVGNames::rectTag, [DOMSVGRectElement class]);
216     addElementClass(SVGNames::scriptTag, [DOMSVGScriptElement class]);
217     addElementClass(SVGNames::stopTag, [DOMSVGStopElement class]);
218     addElementClass(SVGNames::styleTag, [DOMSVGStyleElement class]);
219     addElementClass(SVGNames::svgTag, [DOMSVGSVGElement class]);
220     addElementClass(SVGNames::switchTag, [DOMSVGSwitchElement class]);
221     addElementClass(SVGNames::symbolTag, [DOMSVGSymbolElement class]);
222     addElementClass(SVGNames::textTag, [DOMSVGTextElement class]);
223     addElementClass(SVGNames::titleTag, [DOMSVGTitleElement class]);
224     addElementClass(SVGNames::trefTag, [DOMSVGTRefElement class]);
225     addElementClass(SVGNames::tspanTag, [DOMSVGTSpanElement class]);
226     addElementClass(SVGNames::textPathTag, [DOMSVGTextPathElement class]);
227     addElementClass(SVGNames::useTag, [DOMSVGUseElement class]);
228     addElementClass(SVGNames::viewTag, [DOMSVGViewElement class]);
229 #endif
230 }
231
232 static Class lookupElementClass(const QualifiedName& tag)
233 {
234     // Do a special lookup to ignore element prefixes
235     if (tag.hasPrefix())
236         return elementClassMap->get(QualifiedName(nullAtom, tag.localName(), tag.namespaceURI()).impl());
237     
238     return elementClassMap->get(tag.impl());
239 }
240
241 static Class elementClass(const QualifiedName& tag, Class defaultClass)
242 {
243     if (!elementClassMap)
244         createElementClassMap();
245     Class objcClass = lookupElementClass(tag);
246     if (!objcClass)
247         objcClass = defaultClass;
248     return objcClass;
249 }
250
251 static NSArray *kit(const Vector<IntRect>& rects)
252 {
253     size_t size = rects.size();
254     NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
255     for (size_t i = 0; i < size; ++i)
256         [array addObject:[NSValue valueWithRect:rects[i]]];
257     return array;
258 }
259
260 } // namespace WebCore
261
262 @implementation DOMNode (WebCoreInternal)
263
264 - (NSString *)description
265 {
266     if (!_internal)
267         return [NSString stringWithFormat:@"<%@: null>", [[self class] description], self];
268
269     NSString *value = [self nodeValue];
270     if (value)
271         return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>",
272             [[self class] description], [self nodeName], _internal, value];
273
274     return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal];
275 }
276
277 - (JSC::Bindings::RootObject*)_rootObject
278 {
279     WebCore::Frame* frame = core(self)->document()->frame();
280     if (!frame)
281         return 0;
282     return frame->script()->bindingRootObject();
283 }
284
285 @end
286
287 Class kitClass(WebCore::Node* impl)
288 {
289     switch (impl->nodeType()) {
290         case WebCore::Node::ELEMENT_NODE:
291             if (impl->isHTMLElement())
292                 return WebCore::elementClass(static_cast<WebCore::HTMLElement*>(impl)->tagQName(), [DOMHTMLElement class]);
293 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
294             if (impl->isSVGElement())
295                 return WebCore::elementClass(static_cast<WebCore::SVGElement*>(impl)->tagQName(), [DOMSVGElement class]);
296 #endif
297             return [DOMElement class];
298         case WebCore::Node::ATTRIBUTE_NODE:
299             return [DOMAttr class];
300         case WebCore::Node::TEXT_NODE:
301             return [DOMText class];
302         case WebCore::Node::CDATA_SECTION_NODE:
303             return [DOMCDATASection class];
304         case WebCore::Node::ENTITY_REFERENCE_NODE:
305             return [DOMEntityReference class];
306         case WebCore::Node::ENTITY_NODE:
307             return [DOMEntity class];
308         case WebCore::Node::PROCESSING_INSTRUCTION_NODE:
309             return [DOMProcessingInstruction class];
310         case WebCore::Node::COMMENT_NODE:
311             return [DOMComment class];
312         case WebCore::Node::DOCUMENT_NODE:
313             if (static_cast<WebCore::Document*>(impl)->isHTMLDocument())
314                 return [DOMHTMLDocument class];
315 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
316             if (static_cast<WebCore::Document*>(impl)->isSVGDocument())
317                 return [DOMSVGDocument class];
318 #endif
319             return [DOMDocument class];
320         case WebCore::Node::DOCUMENT_TYPE_NODE:
321             return [DOMDocumentType class];
322         case WebCore::Node::DOCUMENT_FRAGMENT_NODE:
323             return [DOMDocumentFragment class];
324         case WebCore::Node::NOTATION_NODE:
325             return [DOMNotation class];
326         case WebCore::Node::XPATH_NAMESPACE_NODE:
327             // FIXME: Create an XPath objective C wrapper
328             // See http://bugs.webkit.org/show_bug.cgi?id=8755
329             return nil;
330     }
331     ASSERT_NOT_REACHED();
332     return nil;
333 }
334
335 id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
336 {
337     if (!eventTarget)
338         return nil;
339
340     if (WebCore::Node* node = eventTarget->toNode())
341         return kit(node);
342
343 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
344     if (WebCore::SVGElementInstance* svgElementInstance = eventTarget->toSVGElementInstance())
345         return kit(svgElementInstance);
346 #endif
347
348     // We don't have an ObjC binding for XMLHttpRequest.
349
350     return nil;
351 }
352
353 @implementation DOMNode (DOMNodeExtensions)
354
355 - (NSRect)boundingBox
356 {
357     // FIXME: Could we move this function to WebCore::Node and autogenerate?
358     core(self)->document()->updateLayoutIgnorePendingStylesheets();
359     WebCore::RenderObject* renderer = core(self)->renderer();
360     if (!renderer)
361         return NSZeroRect;
362     return renderer->absoluteBoundingBoxRect();
363 }
364
365 - (NSArray *)lineBoxRects
366 {
367     return [self textRects];
368 }
369
370 @end
371
372 @implementation DOMNode (DOMNodeExtensionsPendingPublic)
373
374 - (NSImage *)renderedImage
375 {
376     // FIXME: Could we move this function to WebCore::Node and autogenerate?
377     WebCore::Node* node = core(self);
378     WebCore::Frame* frame = node->document()->frame();
379     if (!frame)
380         return nil;
381     return frame->nodeImage(node).get();
382 }
383
384 - (NSArray *)textRects
385 {
386     // FIXME: Could we move this function to WebCore::Node and autogenerate?
387     core(self)->document()->updateLayoutIgnorePendingStylesheets();
388     if (!core(self)->renderer())
389         return nil;
390     RefPtr<Range> range = Range::create(core(self)->document());
391     WebCore::ExceptionCode ec = 0;
392     range->selectNodeContents(core(self), ec);
393     Vector<WebCore::IntRect> rects;
394     range->textRects(rects);
395     return kit(rects);
396 }
397 @end
398
399 @implementation DOMRange (DOMRangeExtensions)
400
401 - (NSRect)boundingBox
402 {
403     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
404     core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets();
405     return core(self)->boundingBox();
406 }
407
408 - (NSArray *)textRects
409 {
410     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
411     Vector<WebCore::IntRect> rects;
412     core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets();
413     core(self)->textRects(rects);
414     return kit(rects);
415 }
416
417 - (NSArray *)lineBoxRects
418 {
419     // FIXME: Remove this once all clients stop using it and we drop Leopard support.
420     return [self textRects];
421 }
422
423 @end
424
425 //------------------------------------------------------------------------------------------
426 // DOMElement
427
428 @implementation DOMElement (DOMElementAppKitExtensions)
429
430 - (NSImage*)image
431 {
432     // FIXME: Could we move this function to WebCore::Node and autogenerate?
433     WebCore::RenderObject* renderer = core(self)->renderer();
434     if (!renderer || !renderer->isImage())
435         return nil;
436     WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage();
437     if (!cachedImage || cachedImage->errorOccurred())
438         return nil;
439     return cachedImage->image()->getNSImage();
440 }
441
442 @end
443
444 @implementation DOMElement (WebPrivate)
445
446 - (NSFont *)_font
447 {
448     // FIXME: Could we move this function to WebCore::Element and autogenerate?
449     WebCore::RenderObject* renderer = core(self)->renderer();
450     if (!renderer)
451         return nil;
452     return renderer->style()->font().primaryFont()->getNSFont();
453 }
454
455 - (NSData *)_imageTIFFRepresentation
456 {
457     // FIXME: Could we move this function to WebCore::Element and autogenerate?
458     WebCore::RenderObject* renderer = core(self)->renderer();
459     if (!renderer || !renderer->isImage())
460         return nil;
461     WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage();
462     if (!cachedImage || cachedImage->errorOccurred())
463         return nil;
464     return (NSData *)cachedImage->image()->getTIFFRepresentation();
465 }
466
467 - (NSURL *)_getURLAttribute:(NSString *)name
468 {
469     // FIXME: Could we move this function to WebCore::Element and autogenerate?
470     ASSERT(name);
471     WebCore::Element* element = core(self);
472     ASSERT(element);
473     return element->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(element->getAttribute(name)));
474 }
475
476 - (BOOL)isFocused
477 {
478     // FIXME: Could we move this function to WebCore::Element and autogenerate?
479     WebCore::Element* element = core(self);
480     return element->document()->focusedNode() == element;
481 }
482
483 @end
484
485 //------------------------------------------------------------------------------------------
486 // DOMRange
487
488 @implementation DOMRange (WebPrivate)
489
490 - (NSString *)description
491 {
492     if (!_internal)
493         return @"<DOMRange: null>";
494     return [NSString stringWithFormat:@"<DOMRange: %@ %d %@ %d>",
495                [self startContainer], [self startOffset], [self endContainer], [self endOffset]];
496 }
497
498 // FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
499 // calls to the public method - (NSString *)text.
500 - (NSString *)_text
501 {
502     return [self text];
503 }
504
505 @end
506
507 //------------------------------------------------------------------------------------------
508 // DOMRGBColor
509
510 @implementation DOMRGBColor (WebPrivate)
511
512 // FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
513 // calls to the public method - (NSColor *)color.
514 - (NSColor *)_color
515 {
516     return [self color];
517 }
518
519 @end
520
521
522 //------------------------------------------------------------------------------------------
523 // DOMNodeFilter
524
525 DOMNodeFilter *kit(WebCore::NodeFilter* impl)
526 {
527     if (!impl)
528         return nil;
529     
530     if (DOMNodeFilter *wrapper = getDOMWrapper(impl))
531         return [[wrapper retain] autorelease];
532     
533     DOMNodeFilter *wrapper = [[DOMNodeFilter alloc] _init];
534     wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(impl);
535     impl->ref();
536     addDOMWrapper(wrapper, impl);
537     return [wrapper autorelease];
538 }
539
540 WebCore::NodeFilter* core(DOMNodeFilter *wrapper)
541 {
542     return wrapper ? reinterpret_cast<WebCore::NodeFilter*>(wrapper->_internal) : 0;
543 }
544
545 @implementation DOMNodeFilter
546
547 - (void)dealloc
548 {
549     if (_internal)
550         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
551     [super dealloc];
552 }
553
554 - (void)finalize
555 {
556     if (_internal)
557         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
558     [super finalize];
559 }
560
561 - (short)acceptNode:(DOMNode *)node
562 {
563     return core(self)->acceptNode(core(node));
564 }
565
566 @end