/*
 * 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 = *core(self);
    auto* frame = range.ownerDocument().frame();
    if (!frame)
        return nil;

    Ref<Frame> protectedFrame(*frame);

    // iOS uses CGImageRef for drag images, which doesn't support separate logical/physical sizes.
#if PLATFORM(MAC)
    RetainPtr<NSImage> renderedImage = createDragImageForRange(*frame, range, forceBlackText);

    IntSize size([renderedImage size]);
    size.scale(1 / frame->page()->deviceScaleFactor());
    [renderedImage setSize:size];

    return renderedImage.autorelease();
#else
    return createDragImageForRange(*frame, range, forceBlackText).autorelease();
#endif
}

- (NSArray *)textRects
{
    auto& range = *core(self);
    range.ownerDocument().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
