/*
 * Copyright (C) 2004-2019 Apple Inc. All rights reserved.
 * Copyright (C) 2006 James G. Speth (speth@end.com)
 * Copyright (C) 2006 Samuel Weinig (sam.weinig@gmail.com)
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL APPLE INC. OR
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 
 */

#import "DOM.h"

#import "ExceptionHandlers.h"
#import "DOMElementInternal.h"
#import "DOMHTMLCanvasElement.h"
#import "DOMHTMLTableCellElementInternal.h"
#import "DOMHTMLVideoElement.h"
#import "DOMInternal.h"
#import "DOMNodeInternal.h"
#import "DOMPrivate.h"
#import "DOMRangeInternal.h"
#import <JavaScriptCore/APICast.h>
#import <WebCore/CachedImage.h>
#import <WebCore/DragImage.h>
#import <WebCore/FocusController.h>
#import <WebCore/FontCascade.h>
#import <WebCore/Frame.h>
#import <WebCore/HTMLLinkElement.h>
#import <WebCore/HTMLNames.h>
#import <WebCore/HTMLParserIdioms.h>
#import <WebCore/HTMLTableCellElement.h>
#import <WebCore/Image.h>
#import <WebCore/JSNode.h>
#import <WebCore/KeyboardEvent.h>
#import <WebCore/MediaList.h>
#import <WebCore/MediaQueryEvaluator.h>
#import <WebCore/NodeFilter.h>
#import <WebCore/NodeRenderStyle.h>
#import <WebCore/Page.h>
#import <WebCore/Range.h>
#import <WebCore/RenderImage.h>
#import <WebCore/RenderView.h>
#import <WebCore/ScriptController.h>
#import <WebCore/SimpleRange.h>
#import <WebCore/TextIndicator.h>
#import <WebCore/Touch.h>
#import <WebCore/WebScriptObjectPrivate.h>
#import <wtf/HashMap.h>
#import <wtf/cocoa/VectorCocoa.h>

#if PLATFORM(IOS_FAMILY)
#import <WebCore/WAKAppKitStubs.h>
#import <WebCore/WAKWindow.h>
#import <WebCore/WebCoreThreadMessage.h>
#endif

using namespace JSC;
using namespace WebCore;

//------------------------------------------------------------------------------------------
// DOMNode

typedef HashMap<const QualifiedName::QualifiedNameImpl*, Class> ObjCClassMap;
static ObjCClassMap* elementClassMap;

static void addElementClass(const QualifiedName& tag, Class objCClass)
{
    elementClassMap->set(tag.impl(), objCClass);
}

static void createElementClassMap()
{
    // Create the table.
    elementClassMap = new ObjCClassMap;

    addElementClass(HTMLNames::aTag, [DOMHTMLAnchorElement class]);
    addElementClass(HTMLNames::appletTag, [DOMHTMLAppletElement class]);
    addElementClass(HTMLNames::areaTag, [DOMHTMLAreaElement class]);
    addElementClass(HTMLNames::baseTag, [DOMHTMLBaseElement class]);
    addElementClass(HTMLNames::basefontTag, [DOMHTMLBaseFontElement class]);
    addElementClass(HTMLNames::bodyTag, [DOMHTMLBodyElement class]);
    addElementClass(HTMLNames::brTag, [DOMHTMLBRElement class]);
    addElementClass(HTMLNames::buttonTag, [DOMHTMLButtonElement class]);
    addElementClass(HTMLNames::canvasTag, [DOMHTMLCanvasElement class]);
    addElementClass(HTMLNames::captionTag, [DOMHTMLTableCaptionElement class]);
    addElementClass(HTMLNames::colTag, [DOMHTMLTableColElement class]);
    addElementClass(HTMLNames::colgroupTag, [DOMHTMLTableColElement class]);
    addElementClass(HTMLNames::delTag, [DOMHTMLModElement class]);
    addElementClass(HTMLNames::dirTag, [DOMHTMLDirectoryElement class]);
    addElementClass(HTMLNames::divTag, [DOMHTMLDivElement class]);
    addElementClass(HTMLNames::dlTag, [DOMHTMLDListElement class]);
    addElementClass(HTMLNames::embedTag, [DOMHTMLEmbedElement class]);
    addElementClass(HTMLNames::fieldsetTag, [DOMHTMLFieldSetElement class]);
    addElementClass(HTMLNames::fontTag, [DOMHTMLFontElement class]);
    addElementClass(HTMLNames::formTag, [DOMHTMLFormElement class]);
    addElementClass(HTMLNames::frameTag, [DOMHTMLFrameElement class]);
    addElementClass(HTMLNames::framesetTag, [DOMHTMLFrameSetElement class]);
    addElementClass(HTMLNames::h1Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::h2Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::h3Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::h4Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::h5Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::h6Tag, [DOMHTMLHeadingElement class]);
    addElementClass(HTMLNames::headTag, [DOMHTMLHeadElement class]);
    addElementClass(HTMLNames::hrTag, [DOMHTMLHRElement class]);
    addElementClass(HTMLNames::htmlTag, [DOMHTMLHtmlElement class]);
    addElementClass(HTMLNames::iframeTag, [DOMHTMLIFrameElement class]);
    addElementClass(HTMLNames::imgTag, [DOMHTMLImageElement class]);
    addElementClass(HTMLNames::inputTag, [DOMHTMLInputElement class]);
    addElementClass(HTMLNames::insTag, [DOMHTMLModElement class]);
    addElementClass(HTMLNames::labelTag, [DOMHTMLLabelElement class]);
    addElementClass(HTMLNames::legendTag, [DOMHTMLLegendElement class]);
    addElementClass(HTMLNames::liTag, [DOMHTMLLIElement class]);
    addElementClass(HTMLNames::linkTag, [DOMHTMLLinkElement class]);
    addElementClass(HTMLNames::listingTag, [DOMHTMLPreElement class]);
    addElementClass(HTMLNames::mapTag, [DOMHTMLMapElement class]);
    addElementClass(HTMLNames::marqueeTag, [DOMHTMLMarqueeElement class]);
    addElementClass(HTMLNames::menuTag, [DOMHTMLMenuElement class]);
    addElementClass(HTMLNames::metaTag, [DOMHTMLMetaElement class]);
    addElementClass(HTMLNames::objectTag, [DOMHTMLObjectElement class]);
    addElementClass(HTMLNames::olTag, [DOMHTMLOListElement class]);
    addElementClass(HTMLNames::optgroupTag, [DOMHTMLOptGroupElement class]);
    addElementClass(HTMLNames::optionTag, [DOMHTMLOptionElement class]);
    addElementClass(HTMLNames::pTag, [DOMHTMLParagraphElement class]);
    addElementClass(HTMLNames::paramTag, [DOMHTMLParamElement class]);
    addElementClass(HTMLNames::preTag, [DOMHTMLPreElement class]);
    addElementClass(HTMLNames::qTag, [DOMHTMLQuoteElement class]);
    addElementClass(HTMLNames::scriptTag, [DOMHTMLScriptElement class]);
    addElementClass(HTMLNames::selectTag, [DOMHTMLSelectElement class]);
    addElementClass(HTMLNames::styleTag, [DOMHTMLStyleElement class]);
    addElementClass(HTMLNames::tableTag, [DOMHTMLTableElement class]);
    addElementClass(HTMLNames::tbodyTag, [DOMHTMLTableSectionElement class]);
    addElementClass(HTMLNames::tdTag, [DOMHTMLTableCellElement class]);
    addElementClass(HTMLNames::textareaTag, [DOMHTMLTextAreaElement class]);
    addElementClass(HTMLNames::tfootTag, [DOMHTMLTableSectionElement class]);
    addElementClass(HTMLNames::thTag, [DOMHTMLTableCellElement class]);
    addElementClass(HTMLNames::theadTag, [DOMHTMLTableSectionElement class]);
    addElementClass(HTMLNames::titleTag, [DOMHTMLTitleElement class]);
    addElementClass(HTMLNames::trTag, [DOMHTMLTableRowElement class]);
    addElementClass(HTMLNames::ulTag, [DOMHTMLUListElement class]);
    addElementClass(HTMLNames::videoTag, [DOMHTMLVideoElement class]);
    addElementClass(HTMLNames::xmpTag, [DOMHTMLPreElement class]);
}

static Class lookupElementClass(const QualifiedName& tag)
{
    // Do a special lookup to ignore element prefixes
    if (tag.hasPrefix())
        return elementClassMap->get(QualifiedName(nullAtom(), tag.localName(), tag.namespaceURI()).impl());
    
    return elementClassMap->get(tag.impl());
}

static Class elementClass(const QualifiedName& tag, Class defaultClass)
{
    if (!elementClassMap)
        createElementClassMap();
    Class objcClass = lookupElementClass(tag);
    if (!objcClass)
        objcClass = defaultClass;
    return objcClass;
}

#if PLATFORM(IOS_FAMILY)

static WKQuad wkQuadFromFloatQuad(const FloatQuad& inQuad)
{
    return { inQuad.p1(), inQuad.p2(), inQuad.p3(), inQuad.p4() };
}

static NSArray *kit(const Vector<FloatQuad>& quads)
{
    return createNSArray(quads, [] (auto& quad) {
        return adoptNS([[WKQuadObject alloc] initWithQuad:wkQuadFromFloatQuad(quad)]);
    }).autorelease();
}

static inline WKQuad zeroQuad()
{
    return { CGPointZero, CGPointZero, CGPointZero, CGPointZero };
}

@implementation WKQuadObject {
    WKQuad _quad;
}

- (id)initWithQuad:(WKQuad)quad
{
    if ((self = [super init]))
        _quad = quad;
    return self;
}

- (WKQuad)quad
{
    return _quad;
}

- (CGRect)boundingBox
{
    float left = std::min({ _quad.p1.x, _quad.p2.x, _quad.p3.x, _quad.p4.x });
    float top = std::min({ _quad.p1.y, _quad.p2.y, _quad.p3.y, _quad.p4.y });
    
    float right = std::max({ _quad.p1.x, _quad.p2.x, _quad.p3.x, _quad.p4.x });
    float bottom = std::max({ _quad.p1.y, _quad.p2.y, _quad.p3.y, _quad.p4.y });

    return CGRectMake(left, top, right - left, bottom - top);
}

@end

#endif

@implementation DOMNode (WebCoreInternal)

IGNORE_WARNINGS_BEGIN("objc-protocol-method-implementation")

- (NSString *)description
{
    if (!_internal)
        return [NSString stringWithFormat:@"<%@: null>", [[self class] description]];

    NSString *value = [self nodeValue];
    if (value)
        return [NSString stringWithFormat:@"<%@ [%@]: %p '%@'>", [[self class] description], [self nodeName], _internal, value];

    return [NSString stringWithFormat:@"<%@ [%@]: %p>", [[self class] description], [self nodeName], _internal];
}

IGNORE_WARNINGS_END

- (Bindings::RootObject*)_rootObject
{
    auto* frame = core(self)->document().frame();
    if (!frame)
        return nullptr;
    return frame->script().bindingRootObject();
}

@end

Class kitClass(Node* impl)
{
    switch (impl->nodeType()) {
        case Node::ELEMENT_NODE:
            if (is<HTMLElement>(*impl))
                return elementClass(downcast<HTMLElement>(*impl).tagQName(), [DOMHTMLElement class]);
            return [DOMElement class];
        case Node::ATTRIBUTE_NODE:
            return [DOMAttr class];
        case Node::TEXT_NODE:
            return [DOMText class];
        case Node::CDATA_SECTION_NODE:
            return [DOMCDATASection class];
        case Node::PROCESSING_INSTRUCTION_NODE:
            return [DOMProcessingInstruction class];
        case Node::COMMENT_NODE:
            return [DOMComment class];
        case Node::DOCUMENT_NODE:
            if (static_cast<Document*>(impl)->isHTMLDocument())
                return [DOMHTMLDocument class];
            return [DOMDocument class];
        case Node::DOCUMENT_TYPE_NODE:
            return [DOMDocumentType class];
        case Node::DOCUMENT_FRAGMENT_NODE:
            return [DOMDocumentFragment class];
    }
    ASSERT_NOT_REACHED();
    return nil;
}

id <DOMEventTarget> kit(EventTarget* target)
{
    // We don't have Objective-C bindings for XMLHttpRequest, DOMWindow, and other non-Node targets.
    return is<Node>(target) ? kit(downcast<Node>(target)) : nil;
}

@implementation DOMNode (DOMNodeExtensions)

#if PLATFORM(IOS_FAMILY)
- (CGRect)boundingBox
#else
- (NSRect)boundingBox
#endif
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    auto* renderer = node.renderer();
    if (!renderer)
#if PLATFORM(IOS_FAMILY)
        return CGRectZero;
#else
        return NSZeroRect;
#endif
    return renderer->absoluteBoundingBoxRect();
}

- (NSArray *)lineBoxRects
{
    return [self textRects];
}

#if PLATFORM(IOS_FAMILY)

// quad in page coordinates, taking transforms into account. c.f. - (NSRect)boundingBox;
- (WKQuad)absoluteQuad
{
    return [self absoluteQuadAndInsideFixedPosition:0];
}

- (WKQuad)absoluteQuadAndInsideFixedPosition:(BOOL *)insideFixed
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    auto* renderer = node.renderer();
    if (!renderer) {
        if (insideFixed)
            *insideFixed = false;
        return zeroQuad();
    }

    Vector<FloatQuad> quads;
    bool wasFixed = false;
    renderer->absoluteQuads(quads, &wasFixed);
    if (insideFixed)
        *insideFixed = wasFixed;

    if (quads.size() == 0)
        return zeroQuad();
    if (quads.size() == 1)
        return wkQuadFromFloatQuad(quads[0]);
    return wkQuadFromFloatQuad(unitedBoundingBoxes(quads));
}

// this method is like - (CGRect)boundingBox, but it accounts for for transforms
- (CGRect)boundingBoxUsingTransforms
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    auto* renderer = node.renderer();
    if (!renderer)
        return CGRectZero;
    return renderer->absoluteBoundingBoxRect(true);
}

// returns array of WKQuadObject
- (NSArray *)lineBoxQuads
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    WebCore::RenderObject *renderer = node.renderer();
    if (!renderer)
        return nil;
    Vector<WebCore::FloatQuad> quads;
    renderer->absoluteQuads(quads);
    return kit(quads);
}

- (Element*)_linkElement
{
    for (auto* node = core(self); node; node = node->parentNode()) {
        if (node->isLink())
            return &downcast<Element>(*node);
    }
    return nullptr;
}

- (NSURL *)hrefURL
{
    auto* link = [self _linkElement];
    if (!link)
        return nil;
    return link->document().completeURL(stripLeadingAndTrailingHTMLSpaces(link->getAttribute(HTMLNames::hrefAttr)));
}

- (NSString *)hrefTarget
{
    auto* link = [self _linkElement];
    if (!link)
        return nil;
    return link->getAttribute(HTMLNames::targetAttr);
}

- (CGRect)hrefFrame
{
    auto* link = [self _linkElement];
    if (!link)
        return CGRectZero;
    auto* renderer = link->renderer();
    if (!renderer)
        return CGRectZero;
    return renderer->absoluteBoundingBoxRect();
}

- (NSString *)hrefLabel
{
    auto* link = [self _linkElement];
    if (!link)
        return nil;
    return link->textContent();
}

- (NSString *)hrefTitle
{
    auto* link = [self _linkElement];
    if (!is<HTMLElement>(link))
        return nil;
    return link->document().displayStringModifiedByEncoding(downcast<HTMLElement>(*link).title());
}

- (CGRect)boundingFrame
{
    return [self boundingBox];
}

- (WKQuad)innerFrameQuad // takes transforms into account
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    auto* renderer = node.renderer();
    if (!renderer)
        return zeroQuad();

    auto& style = renderer->style();
    IntRect boundingBox = renderer->absoluteBoundingBoxRect(true /* use transforms*/);

    boundingBox.move(style.borderLeftWidth(), style.borderTopWidth());
    boundingBox.setWidth(boundingBox.width() - style.borderLeftWidth() - style.borderRightWidth());
    boundingBox.setHeight(boundingBox.height() - style.borderBottomWidth() - style.borderTopWidth());

    // FIXME: This function advertises returning a quad, but it actually returns a bounding box (so there is no rotation, for instance).
    return wkQuadFromFloatQuad(FloatQuad(boundingBox));
}

- (float)computedFontSize
{
    auto* style = core(self)->renderStyle();
    if (!style)
        return 0.0f;
    return style->fontDescription().computedSize();
}

- (DOMNode *)nextFocusNode
{
    Page* page = core(self)->document().page();
    if (!page)
        return nil;
    return kit(page->focusController().nextFocusableElement(*core(self)));
}

- (DOMNode *)previousFocusNode
{
    Page* page = core(self)->document().page();
    if (!page)
        return nil;
    return kit(page->focusController().previousFocusableElement(*core(self)));
}

#endif // PLATFORM(IOS_FAMILY)

@end

@implementation DOMNode (DOMNodeExtensionsPendingPublic)

#if PLATFORM(MAC)

- (NSImage *)renderedImage
{
    auto& node = *core(self);
    auto* frame = node.document().frame();
    if (!frame)
        return nil;
    return createDragImageForNode(*frame, node).autorelease();
}

#endif

- (NSArray *)textRects
{
    auto& node = *core(self);
    node.document().updateLayoutIgnorePendingStylesheets();
    if (!node.renderer())
        return nil;
    return createNSArray(RenderObject::absoluteTextRects(makeRangeSelectingNodeContents(node))).autorelease();
}

@end

@implementation DOMNode (WebPrivate)

+ (id)_nodeFromJSWrapper:(JSObjectRef)jsWrapper
{
    JSObject* object = toJS(jsWrapper);
    if (!object->inherits<JSNode>(object->vm()))
        return nil;
    return kit(&jsCast<JSNode*>(object)->wrapped());
}

- (void)getPreviewSnapshotImage:(CGImageRef*)cgImage andRects:(NSArray **)rects
{
    if (!cgImage || !rects)
        return;

    *cgImage = nullptr;
    *rects = nullptr;

    auto& node = *core(self);

    constexpr OptionSet<TextIndicatorOption> options {
        TextIndicatorOption::TightlyFitContent,
        TextIndicatorOption::RespectTextColor,
        TextIndicatorOption::PaintBackgrounds,
        TextIndicatorOption::UseBoundingRectAndPaintAllContentForComplexRanges,
        TextIndicatorOption::IncludeMarginIfRangeMatchesSelection
    };
    const float margin = 4 / node.document().page()->pageScaleFactor();
    auto textIndicator = TextIndicator::createWithRange(makeRangeSelectingNodeContents(node), options, TextIndicatorPresentationTransition::None, FloatSize(margin, margin));

    if (textIndicator) {
        if (Image* image = textIndicator->contentImage())
            *cgImage = image->nativeImage().autorelease();
    }

    if (!*cgImage) {
        if (auto* renderer = node.renderer()) {
            FloatRect boundingBox;
            if (renderer->isRenderImage())
                boundingBox = downcast<RenderImage>(*renderer).absoluteContentQuad().enclosingBoundingBox();
            else
                boundingBox = renderer->absoluteBoundingBoxRect();
            boundingBox.inflate(margin);
            *rects = @[makeNSArrayElement(node.document().frame()->view()->contentsToWindow(enclosingIntRect(boundingBox)))];
        }
        return;
    }

    FloatPoint origin = textIndicator->textBoundingRectInRootViewCoordinates().location();
    *rects = createNSArray(textIndicator->textRectsInBoundingRectCoordinates(), [&] (CGRect rect) {
        rect.origin.x += origin.x();
        rect.origin.y += origin.y();
        return makeNSArrayElement(node.document().frame()->view()->contentsToWindow(enclosingIntRect(rect)));
    }).autorelease();
}

@end

@implementation DOMRange (DOMRangeExtensions)

#if PLATFORM(IOS_FAMILY)
- (CGRect)boundingBox
#else
- (NSRect)boundingBox
#endif
{
    // FIXME: The call to updateLayoutIgnorePendingStylesheets should be moved into WebCore::Range.
    auto& range = *core(self);
    range.ownerDocument().updateLayoutIgnorePendingStylesheets();
    return range.absoluteBoundingBox();
}

#if PLATFORM(MAC)
- (NSImage *)renderedImageForcingBlackText:(BOOL)forceBlackText
#else
- (CGImageRef)renderedImageForcingBlackText:(BOOL)forceBlackText
#endif
{
    auto range = makeSimpleRange(*core(self));
    auto frame = makeRefPtr(range.start.container->document().frame());
    if (!frame)
        return nil;

    auto renderedImage = createDragImageForRange(*frame, range, forceBlackText);

#if PLATFORM(MAC)
    // iOS uses CGImageRef for drag images, which doesn't support separate logical/physical sizes.
    IntSize size([renderedImage size]);
    size.scale(1 / frame->page()->deviceScaleFactor());
    [renderedImage setSize:size];
#endif

    return renderedImage.autorelease();
}

- (NSArray *)textRects
{
    auto range = makeSimpleRange(*core(self));
    range.start.container->document().updateLayoutIgnorePendingStylesheets();
    return createNSArray(RenderObject::absoluteTextRects(range)).autorelease();
}

- (NSArray *)lineBoxRects
{
    // FIXME: Remove this once all clients stop using it and we drop Leopard support.
    return [self textRects];
}

@end

//------------------------------------------------------------------------------------------
// DOMElement

@implementation DOMElement (DOMElementAppKitExtensions)

#if PLATFORM(MAC)

- (NSImage *)image
{
    auto* renderer = core(self)->renderer();
    if (!is<RenderImage>(renderer))
        return nil;
    auto* cachedImage = downcast<RenderImage>(*renderer).cachedImage();
    if (!cachedImage || cachedImage->errorOccurred())
        return nil;
    return cachedImage->imageForRenderer(renderer)->nsImage();
}

#endif

@end

@implementation DOMElement (WebPrivate)

- (CTFontRef)_font
{
    auto* renderer = core(self)->renderer();
    if (!renderer)
        return nil;
    return renderer->style().fontCascade().primaryFont().getCTFont();
}

#if PLATFORM(MAC)

- (NSData *)_imageTIFFRepresentation
{
    // FIXME: Could we move this function to WebCore::Element and autogenerate?
    auto* renderer = core(self)->renderer();
    if (!is<RenderImage>(renderer))
        return nil;
    auto* cachedImage = downcast<RenderImage>(*renderer).cachedImage();
    if (!cachedImage || cachedImage->errorOccurred())
        return nil;
    return (__bridge NSData *)cachedImage->imageForRenderer(renderer)->tiffRepresentation();
}

#endif

- (NSURL *)_getURLAttribute:(NSString *)name
{
    auto& element = *core(self);
    return element.document().completeURL(stripLeadingAndTrailingHTMLSpaces(element.getAttribute(name)));
}

- (BOOL)isFocused
{
    auto& element = *core(self);
    return element.document().focusedElement() == &element;
}

@end

#if PLATFORM(IOS_FAMILY)

@implementation DOMHTMLLinkElement (WebPrivate)

- (BOOL)_mediaQueryMatchesForOrientation:(int)orientation
{
    Document& document = static_cast<HTMLLinkElement*>(core(self))->document();
    FrameView* frameView = document.frame() ? document.frame()->view() : 0;
    if (!frameView)
        return false;
    int layoutWidth = frameView->layoutWidth();
    int layoutHeight = frameView->layoutHeight();
    IntSize savedFixedLayoutSize = frameView->fixedLayoutSize();
    bool savedUseFixedLayout = frameView->useFixedLayout();
    if ((orientation == WebMediaQueryOrientationPortrait && layoutWidth > layoutHeight) ||
        (orientation == WebMediaQueryOrientationLandscape && layoutWidth < layoutHeight)) {
        // temporarily swap the orientation for the evaluation
        frameView->setFixedLayoutSize(IntSize(layoutHeight, layoutWidth));
        frameView->setUseFixedLayout(true);
    }
        
    bool result = [self _mediaQueryMatches];

    frameView->setFixedLayoutSize(savedFixedLayoutSize);
    frameView->setUseFixedLayout(savedUseFixedLayout);

    return result;
}

- (BOOL)_mediaQueryMatches
{
    HTMLLinkElement& link = *static_cast<HTMLLinkElement*>(core(self));

    auto& media = link.attributeWithoutSynchronization(HTMLNames::mediaAttr);
    if (media.isEmpty())
        return true;

    Document& document = link.document();
    auto mediaQuerySet = MediaQuerySet::create(media, MediaQueryParserContext(document));
    return MediaQueryEvaluator { "screen", document, document.renderView() ? &document.renderView()->style() : nullptr }.evaluate(mediaQuerySet.get());
}

@end

#endif

//------------------------------------------------------------------------------------------
// DOMRange

@implementation DOMRange (WebPrivate)

- (NSString *)description
{
    if (!_internal)
        return @"<DOMRange: null>";
    return [NSString stringWithFormat:@"<DOMRange: %@ %d %@ %d>",
               [self startContainer], [self startOffset], [self endContainer], [self endOffset]];
}

// FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
// calls to the public method - (NSString *)text.
- (NSString *)_text
{
    return [self text];
}

@end

//------------------------------------------------------------------------------------------
// DOMRGBColor

@implementation DOMRGBColor (WebPrivate)

#if PLATFORM(MAC)

// FIXME: This should be removed as soon as all internal Apple uses of it have been replaced with
// calls to the public method - (NSColor *)color.
- (NSColor *)_color
{
    return [self color];
}

#endif

@end

//------------------------------------------------------------------------------------------
// DOMHTMLTableCellElement

@implementation DOMHTMLTableCellElement (WebPrivate)

- (DOMHTMLTableCellElement *)_cellAbove
{
    return kit(core(self)->cellAbove());
}

@end

//------------------------------------------------------------------------------------------
// DOMNodeFilter

DOMNodeFilter *kit(WebCore::NodeFilter* impl)
{
    if (!impl)
        return nil;
    
    if (DOMNodeFilter *wrapper = getDOMWrapper(impl))
        return [[wrapper retain] autorelease];
    
    DOMNodeFilter *wrapper = [[DOMNodeFilter alloc] _init];
    wrapper->_internal = reinterpret_cast<DOMObjectInternal*>(impl);
    impl->ref();
    addDOMWrapper(wrapper, impl);
    return [wrapper autorelease];
}

WebCore::NodeFilter* core(DOMNodeFilter *wrapper)
{
    return wrapper ? reinterpret_cast<WebCore::NodeFilter*>(wrapper->_internal) : 0;
}

@implementation DOMNodeFilter

- (void)dealloc
{
    if (_internal)
        reinterpret_cast<WebCore::NodeFilter*>(_internal)->deref();
    [super dealloc];
}

- (short)acceptNode:(DOMNode *)node
{
    if (!node)
        raiseTypeErrorException();
    
    auto result = core(self)->acceptNode(*core(node));
    return result.type() == CallbackResultType::Success ? result.releaseReturnValue() : NodeFilter::FILTER_REJECT;
}

@end
