Home | History | Annotate | Download | only in objc
      1 /*
      2  * Copyright (C) 2004, 2005, 2006, 2007, 2008, 2009 Apple Inc. All rights reserved.
      3  * Copyright (C) 2006 James G. Speth (speth (at) end.com)
      4  * Copyright (C) 2006 Samuel Weinig (sam.weinig (at) 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::selectTag, [DOMHTMLSelectElement class]);
    135     addElementClass(HTMLNames::styleTag, [DOMHTMLStyleElement class]);
    136     addElementClass(HTMLNames::tableTag, [DOMHTMLTableElement class]);
    137     addElementClass(HTMLNames::tbodyTag, [DOMHTMLTableSectionElement class]);
    138     addElementClass(HTMLNames::tdTag, [DOMHTMLTableCellElement class]);
    139     addElementClass(HTMLNames::textareaTag, [DOMHTMLTextAreaElement class]);
    140     addElementClass(HTMLNames::tfootTag, [DOMHTMLTableSectionElement class]);
    141     addElementClass(HTMLNames::thTag, [DOMHTMLTableCellElement class]);
    142     addElementClass(HTMLNames::theadTag, [DOMHTMLTableSectionElement class]);
    143     addElementClass(HTMLNames::titleTag, [DOMHTMLTitleElement class]);
    144     addElementClass(HTMLNames::trTag, [DOMHTMLTableRowElement class]);
    145     addElementClass(HTMLNames::ulTag, [DOMHTMLUListElement class]);
    146     addElementClass(HTMLNames::xmpTag, [DOMHTMLPreElement class]);
    147 
    148 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
    149     addElementClass(SVGNames::aTag, [DOMSVGAElement class]);
    150     addElementClass(SVGNames::altGlyphTag, [DOMSVGAltGlyphElement class]);
    151 #if ENABLE(SVG_ANIMATION)
    152     addElementClass(SVGNames::animateTag, [DOMSVGAnimateElement class]);
    153     addElementClass(SVGNames::animateColorTag, [DOMSVGAnimateColorElement class]);
    154     addElementClass(SVGNames::animateTransformTag, [DOMSVGAnimateTransformElement class]);
    155     addElementClass(SVGNames::setTag, [DOMSVGSetElement class]);
    156 #endif
    157     addElementClass(SVGNames::circleTag, [DOMSVGCircleElement class]);
    158     addElementClass(SVGNames::clipPathTag, [DOMSVGClipPathElement class]);
    159     addElementClass(SVGNames::cursorTag, [DOMSVGCursorElement class]);
    160     addElementClass(SVGNames::defsTag, [DOMSVGDefsElement class]);
    161     addElementClass(SVGNames::descTag, [DOMSVGDescElement class]);
    162     addElementClass(SVGNames::ellipseTag, [DOMSVGEllipseElement class]);
    163 #if ENABLE(FILTERS)
    164     addElementClass(SVGNames::feBlendTag, [DOMSVGFEBlendElement class]);
    165     addElementClass(SVGNames::feColorMatrixTag, [DOMSVGFEColorMatrixElement class]);
    166     addElementClass(SVGNames::feComponentTransferTag, [DOMSVGFEComponentTransferElement class]);
    167     addElementClass(SVGNames::feCompositeTag, [DOMSVGFECompositeElement class]);
    168     addElementClass(SVGNames::feConvolveMatrixTag, [DOMSVGFEConvolveMatrixElement class]);
    169     addElementClass(SVGNames::feDiffuseLightingTag, [DOMSVGFEDiffuseLightingElement class]);
    170     addElementClass(SVGNames::feDisplacementMapTag, [DOMSVGFEDisplacementMapElement class]);
    171     addElementClass(SVGNames::feDistantLightTag, [DOMSVGFEDistantLightElement class]);
    172     addElementClass(SVGNames::feFloodTag, [DOMSVGFEFloodElement class]);
    173     addElementClass(SVGNames::feFuncATag, [DOMSVGFEFuncAElement class]);
    174     addElementClass(SVGNames::feFuncBTag, [DOMSVGFEFuncBElement class]);
    175     addElementClass(SVGNames::feFuncGTag, [DOMSVGFEFuncGElement class]);
    176     addElementClass(SVGNames::feFuncRTag, [DOMSVGFEFuncRElement class]);
    177     addElementClass(SVGNames::feGaussianBlurTag, [DOMSVGFEGaussianBlurElement class]);
    178     addElementClass(SVGNames::feImageTag, [DOMSVGFEImageElement class]);
    179     addElementClass(SVGNames::feMergeTag, [DOMSVGFEMergeElement class]);
    180     addElementClass(SVGNames::feMergeNodeTag, [DOMSVGFEMergeNodeElement class]);
    181     addElementClass(SVGNames::feMorphologyTag, [DOMSVGFEMorphologyElement class]);
    182     addElementClass(SVGNames::feOffsetTag, [DOMSVGFEOffsetElement class]);
    183     addElementClass(SVGNames::fePointLightTag, [DOMSVGFEPointLightElement class]);
    184     addElementClass(SVGNames::feSpecularLightingTag, [DOMSVGFESpecularLightingElement class]);
    185     addElementClass(SVGNames::feSpotLightTag, [DOMSVGFESpotLightElement class]);
    186     addElementClass(SVGNames::feTileTag, [DOMSVGFETileElement class]);
    187     addElementClass(SVGNames::feTurbulenceTag, [DOMSVGFETurbulenceElement class]);
    188     addElementClass(SVGNames::filterTag, [DOMSVGFilterElement class]);
    189 #endif
    190 #if ENABLE(SVG_FONTS)
    191     addElementClass(SVGNames::fontTag, [DOMSVGFontElement class]);
    192     addElementClass(SVGNames::font_faceTag, [DOMSVGFontFaceElement class]);
    193     addElementClass(SVGNames::font_face_formatTag, [DOMSVGFontFaceFormatElement class]);
    194     addElementClass(SVGNames::font_face_nameTag, [DOMSVGFontFaceNameElement class]);
    195     addElementClass(SVGNames::font_face_srcTag, [DOMSVGFontFaceSrcElement class]);
    196     addElementClass(SVGNames::font_face_uriTag, [DOMSVGFontFaceUriElement class]);
    197     addElementClass(SVGNames::glyphTag, [DOMSVGGlyphElement class]);
    198 #endif
    199     addElementClass(SVGNames::gTag, [DOMSVGGElement class]);
    200     addElementClass(SVGNames::imageTag, [DOMSVGImageElement class]);
    201     addElementClass(SVGNames::lineTag, [DOMSVGLineElement class]);
    202     addElementClass(SVGNames::linearGradientTag, [DOMSVGLinearGradientElement class]);
    203     addElementClass(SVGNames::markerTag, [DOMSVGMarkerElement class]);
    204     addElementClass(SVGNames::maskTag, [DOMSVGMaskElement class]);
    205     addElementClass(SVGNames::metadataTag, [DOMSVGMetadataElement class]);
    206 #if ENABLE(SVG_FONTS)
    207     addElementClass(SVGNames::missing_glyphTag, [DOMSVGMissingGlyphElement class]);
    208 #endif
    209     addElementClass(SVGNames::pathTag, [DOMSVGPathElement class]);
    210     addElementClass(SVGNames::patternTag, [DOMSVGPatternElement class]);
    211     addElementClass(SVGNames::polygonTag, [DOMSVGPolygonElement class]);
    212     addElementClass(SVGNames::polylineTag, [DOMSVGPolylineElement class]);
    213     addElementClass(SVGNames::radialGradientTag, [DOMSVGRadialGradientElement class]);
    214     addElementClass(SVGNames::rectTag, [DOMSVGRectElement class]);
    215     addElementClass(SVGNames::scriptTag, [DOMSVGScriptElement class]);
    216     addElementClass(SVGNames::stopTag, [DOMSVGStopElement class]);
    217     addElementClass(SVGNames::styleTag, [DOMSVGStyleElement class]);
    218     addElementClass(SVGNames::svgTag, [DOMSVGSVGElement class]);
    219     addElementClass(SVGNames::switchTag, [DOMSVGSwitchElement class]);
    220     addElementClass(SVGNames::symbolTag, [DOMSVGSymbolElement class]);
    221     addElementClass(SVGNames::textTag, [DOMSVGTextElement class]);
    222     addElementClass(SVGNames::titleTag, [DOMSVGTitleElement class]);
    223     addElementClass(SVGNames::trefTag, [DOMSVGTRefElement class]);
    224     addElementClass(SVGNames::tspanTag, [DOMSVGTSpanElement class]);
    225     addElementClass(SVGNames::textPathTag, [DOMSVGTextPathElement class]);
    226     addElementClass(SVGNames::useTag, [DOMSVGUseElement class]);
    227     addElementClass(SVGNames::viewTag, [DOMSVGViewElement class]);
    228 #endif
    229 }
    230 
    231 static Class lookupElementClass(const QualifiedName& tag)
    232 {
    233     // Do a special lookup to ignore element prefixes
    234     if (tag.hasPrefix())
    235         return elementClassMap->get(QualifiedName(nullAtom, tag.localName(), tag.namespaceURI()).impl());
    236 
    237     return elementClassMap->get(tag.impl());
    238 }
    239 
    240 static Class elementClass(const QualifiedName& tag, Class defaultClass)
    241 {
    242     if (!elementClassMap)
    243         createElementClassMap();
    244     Class objcClass = lookupElementClass(tag);
    245     if (!objcClass)
    246         objcClass = defaultClass;
    247     return objcClass;
    248 }
    249 
    250 static NSArray *kit(const Vector<IntRect>& rects)
    251 {
    252     size_t size = rects.size();
    253     NSMutableArray *array = [NSMutableArray arrayWithCapacity:size];
    254     for (size_t i = 0; i < size; ++i)
    255         [array addObject:[NSValue valueWithRect:rects[i]]];
    256     return array;
    257 }
    258 
    259 } // namespace WebCore
    260 
    261 @implementation DOMNode (WebCoreInternal)
    262 
    263 - (NSString *)description
    264 {
    265     if (!_internal)
    266         return [NSString stringWithFormat:@"<%@: null>", [[self class] description], self];
    267 
    268     NSString *value = [self nodeValue];
    269     if (value)
    270         return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>",
    271             [[self class] description], [self nodeName], _internal, value];
    272 
    273     return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal];
    274 }
    275 
    276 - (JSC::Bindings::RootObject*)_rootObject
    277 {
    278     WebCore::Frame* frame = core(self)->document()->frame();
    279     if (!frame)
    280         return 0;
    281     return frame->script()->bindingRootObject();
    282 }
    283 
    284 @end
    285 
    286 Class kitClass(WebCore::Node* impl)
    287 {
    288     switch (impl->nodeType()) {
    289         case WebCore::Node::ELEMENT_NODE:
    290             if (impl->isHTMLElement())
    291                 return WebCore::elementClass(static_cast<WebCore::HTMLElement*>(impl)->tagQName(), [DOMHTMLElement class]);
    292 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
    293             if (impl->isSVGElement())
    294                 return WebCore::elementClass(static_cast<WebCore::SVGElement*>(impl)->tagQName(), [DOMSVGElement class]);
    295 #endif
    296             return [DOMElement class];
    297         case WebCore::Node::ATTRIBUTE_NODE:
    298             return [DOMAttr class];
    299         case WebCore::Node::TEXT_NODE:
    300             return [DOMText class];
    301         case WebCore::Node::CDATA_SECTION_NODE:
    302             return [DOMCDATASection class];
    303         case WebCore::Node::ENTITY_REFERENCE_NODE:
    304             return [DOMEntityReference class];
    305         case WebCore::Node::ENTITY_NODE:
    306             return [DOMEntity class];
    307         case WebCore::Node::PROCESSING_INSTRUCTION_NODE:
    308             return [DOMProcessingInstruction class];
    309         case WebCore::Node::COMMENT_NODE:
    310             return [DOMComment class];
    311         case WebCore::Node::DOCUMENT_NODE:
    312             if (static_cast<WebCore::Document*>(impl)->isHTMLDocument())
    313                 return [DOMHTMLDocument class];
    314 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
    315             if (static_cast<WebCore::Document*>(impl)->isSVGDocument())
    316                 return [DOMSVGDocument class];
    317 #endif
    318             return [DOMDocument class];
    319         case WebCore::Node::DOCUMENT_TYPE_NODE:
    320             return [DOMDocumentType class];
    321         case WebCore::Node::DOCUMENT_FRAGMENT_NODE:
    322             return [DOMDocumentFragment class];
    323         case WebCore::Node::NOTATION_NODE:
    324             return [DOMNotation class];
    325         case WebCore::Node::XPATH_NAMESPACE_NODE:
    326             // FIXME: Create an XPath objective C wrapper
    327             // See http://bugs.webkit.org/show_bug.cgi?id=8755
    328             return nil;
    329     }
    330     ASSERT_NOT_REACHED();
    331     return nil;
    332 }
    333 
    334 id <DOMEventTarget> kit(WebCore::EventTarget* eventTarget)
    335 {
    336     if (!eventTarget)
    337         return nil;
    338 
    339     if (WebCore::Node* node = eventTarget->toNode())
    340         return kit(node);
    341 
    342 #if ENABLE(SVG_DOM_OBJC_BINDINGS)
    343     if (WebCore::SVGElementInstance* svgElementInstance = eventTarget->toSVGElementInstance())
    344         return kit(svgElementInstance);
    345 #endif
    346 
    347     // We don't have an ObjC binding for XMLHttpRequest.
    348 
    349     return nil;
    350 }
    351 
    352 @implementation DOMNode (DOMNodeExtensions)
    353 
    354 - (NSRect)boundingBox
    355 {
    356     // FIXME: Could we move this function to WebCore::Node and autogenerate?
    357     core(self)->document()->updateLayoutIgnorePendingStylesheets();
    358     WebCore::RenderObject* renderer = core(self)->renderer();
    359     if (!renderer)
    360         return NSZeroRect;
    361     return renderer->absoluteBoundingBoxRect();
    362 }
    363 
    364 - (NSArray *)lineBoxRects
    365 {
    366     return [self textRects];
    367 }
    368 
    369 @end
    370 
    371 @implementation DOMNode (DOMNodeExtensionsPendingPublic)
    372 
    373 - (NSImage *)renderedImage
    374 {
    375     // FIXME: Could we move this function to WebCore::Node and autogenerate?
    376     WebCore::Node* node = core(self);
    377     WebCore::Frame* frame = node->document()->frame();
    378     if (!frame)
    379         return nil;
    380     return frame->nodeImage(node).get();
    381 }
    382 
    383 - (NSArray *)textRects
    384 {
    385     // FIXME: Could we move this function to WebCore::Node and autogenerate?
    386     core(self)->document()->updateLayoutIgnorePendingStylesheets();
    387     if (!core(self)->renderer())
    388         return nil;
    389     RefPtr<Range> range = Range::create(core(self)->document());
    390     WebCore::ExceptionCode ec = 0;
    391     range->selectNodeContents(core(self), ec);
    392     Vector<WebCore::IntRect> rects;
    393     range->textRects(rects);
    394     return kit(rects);
    395 }
    396 @end
    397 
    398 @implementation DOMRange (DOMRangeExtensions)
    399 
    400 - (NSRect)boundingBox
    401 {
    402     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
    403     core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets();
    404     return core(self)->boundingBox();
    405 }
    406 
    407 - (NSArray *)textRects
    408 {
    409     // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
    410     Vector<WebCore::IntRect> rects;
    411     core(self)->ownerDocument()->updateLayoutIgnorePendingStylesheets();
    412     core(self)->textRects(rects);
    413     return kit(rects);
    414 }
    415 
    416 - (NSArray *)lineBoxRects
    417 {
    418     // FIXME: Remove this once all clients stop using it and we drop Leopard support.
    419     return [self textRects];
    420 }
    421 
    422 @end
    423 
    424 //------------------------------------------------------------------------------------------
    425 // DOMElement
    426 
    427 @implementation DOMElement (DOMElementAppKitExtensions)
    428 
    429 - (NSImage*)image
    430 {
    431     // FIXME: Could we move this function to WebCore::Node and autogenerate?
    432     WebCore::RenderObject* renderer = core(self)->renderer();
    433     if (!renderer || !renderer->isImage())
    434         return nil;
    435     WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage();
    436     if (!cachedImage || cachedImage->errorOccurred())
    437         return nil;
    438     return cachedImage->image()->getNSImage();
    439 }
    440 
    441 @end
    442 
    443 @implementation DOMElement (WebPrivate)
    444 
    445 - (NSFont *)_font
    446 {
    447     // FIXME: Could we move this function to WebCore::Element and autogenerate?
    448     WebCore::RenderObject* renderer = core(self)->renderer();
    449     if (!renderer)
    450         return nil;
    451     return renderer->style()->font().primaryFont()->getNSFont();
    452 }
    453 
    454 - (NSData *)_imageTIFFRepresentation
    455 {
    456     // FIXME: Could we move this function to WebCore::Element and autogenerate?
    457     WebCore::RenderObject* renderer = core(self)->renderer();
    458     if (!renderer || !renderer->isImage())
    459         return nil;
    460     WebCore::CachedImage* cachedImage = static_cast<WebCore::RenderImage*>(renderer)->cachedImage();
    461     if (!cachedImage || cachedImage->errorOccurred())
    462         return nil;
    463     return (NSData *)cachedImage->image()->getTIFFRepresentation();
    464 }
    465 
    466 - (NSURL *)_getURLAttribute:(NSString *)name
    467 {
    468     // FIXME: Could we move this function to WebCore::Element and autogenerate?
    469     ASSERT(name);
    470     WebCore::Element* element = core(self);
    471     ASSERT(element);
    472     return element->document()->completeURL(stripLeadingAndTrailingHTMLSpaces(element->getAttribute(name)));
    473 }
    474 
    475 - (BOOL)isFocused
    476 {
    477     // FIXME: Could we move this function to WebCore::Element and autogenerate?
    478     WebCore::Element* element = core(self);
    479     return element->document()->focusedNode() == element;
    480 }
    481 
    482 @end
    483 
    484 //------------------------------------------------------------------------------------------
    485 // DOMRange
    486 
    487 @implementation DOMRange (WebPrivate)
    488 
    489 - (NSString *)description
    490 {
    491     if (!_internal)
    492         return @"<DOMRange: null>";
    493     return [NSString stringWithFormat:@"<DOMRange: %@ %d %@ %d>",
    494                [self startContainer], [self startOffset], [self endContainer], [self endOffset]];
    495 }
    496 
    497 // FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
    498 // calls to the public method - (NSString *)text.
    499 - (NSString *)_text
    500 {
    501     return [self text];
    502 }
    503 
    504 @end
    505 
    506 //------------------------------------------------------------------------------------------
    507 // DOMRGBColor
    508 
    509 @implementation DOMRGBColor (WebPrivate)
    510 
    511 // FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
    512 // calls to the public method - (NSColor *)color.
    513 - (NSColor *)_color
    514 {
    515     return [self color];
    516 }
    517 
    518 @end
    519 
    520 
    521 //------------------------------------------------------------------------------------------
    522 // DOMNodeFilter
    523 
    524 DOMNodeFilter *kit(WebCore::NodeFilter* impl)
    525 {
    526     if (!impl)
    527         return nil;
    528 
    529     if (DOMNodeFilter *wrapper = getDOMWrapper(impl))
    530         return [[wrapper retain] autorelease];
    531 
    532     DOMNodeFilter *wrapper = [[DOMNodeFilter alloc] _init];
    533     wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(impl);
    534     impl->ref();
    535     addDOMWrapper(wrapper, impl);
    536     return [wrapper autorelease];
    537 }
    538 
    539 WebCore::NodeFilter* core(DOMNodeFilter *wrapper)
    540 {
    541     return wrapper ? reinterpret_cast<WebCore::NodeFilter*>(wrapper->_internal) : 0;
    542 }
    543 
    544 @implementation DOMNodeFilter
    545 
    546 - (void)dealloc
    547 {
    548     if (_internal)
    549         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
    550     [super dealloc];
    551 }
    552 
    553 - (void)finalize
    554 {
    555     if (_internal)
    556         reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
    557     [super finalize];
    558 }
    559 
    560 - (short)acceptNode:(DOMNode *)node
    561 {
    562     return core(self)->acceptNode(core(node));
    563 }
    564 
    565 @end
    566