/*
 * Copyright (C) 2005-2020 Apple Inc. All rights reserved.
 *
 * 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. 
 * 3.  Neither the name of Apple Inc. ("Apple") nor the names of
 *     its contributors may be used to endorse or promote products derived
 *     from this software without specific prior written permission. 
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "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 OR ITS 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 "WebFrameInternal.h"

#import "DOMCSSStyleDeclarationInternal.h"
#import "DOMDocumentFragmentInternal.h"
#import "DOMDocumentInternal.h"
#import "DOMElementInternal.h"
#import "DOMHTMLElementInternal.h"
#import "DOMNodeInternal.h"
#import "DOMPrivate.h"
#import "DOMRangeInternal.h"
#import "WebArchiveInternal.h"
#import "WebChromeClient.h"
#import "WebDataSourceInternal.h"
#import "WebDocumentLoaderMac.h"
#import "WebDynamicScrollBarsView.h"
#import "WebEditorClient.h"
#import "WebElementDictionary.h"
#import "WebFrameLoaderClient.h"
#import "WebFrameViewInternal.h"
#import "WebHTMLView.h"
#import "WebHTMLViewInternal.h"
#import "WebKitStatisticsPrivate.h"
#import "WebKitVersionChecks.h"
#import "WebNSObjectExtras.h"
#import "WebNSURLExtras.h"
#import "WebScriptDebugger.h"
#import "WebScriptWorldInternal.h"
#import "WebViewInternal.h"
#import <JavaScriptCore/APICast.h>
#import <JavaScriptCore/JSCJSValue.h>
#import <JavaScriptCore/JSContextInternal.h>
#import <JavaScriptCore/JSGlobalObjectInlines.h>
#import <JavaScriptCore/JSLock.h>
#import <JavaScriptCore/JSObject.h>
#import <WebCore/AXObjectCache.h>
#import <WebCore/AccessibilityObject.h>
#import <WebCore/CSSStyleDeclaration.h>
#import <WebCore/CachedResourceLoader.h>
#import <WebCore/Chrome.h>
#import <WebCore/ColorMac.h>
#import <WebCore/CompositionHighlight.h>
#import <WebCore/DatabaseManager.h>
#import <WebCore/DocumentFragment.h>
#import <WebCore/DocumentLoader.h>
#import <WebCore/DocumentMarkerController.h>
#import <WebCore/Editing.h>
#import <WebCore/Editor.h>
#import <WebCore/EventHandler.h>
#import <WebCore/EventNames.h>
#import <WebCore/Frame.h>
#import <WebCore/FrameLoadRequest.h>
#import <WebCore/FrameLoader.h>
#import <WebCore/FrameLoaderStateMachine.h>
#import <WebCore/FrameSelection.h>
#import <WebCore/FrameTree.h>
#import <WebCore/GraphicsContextCG.h>
#import <WebCore/HTMLFrameOwnerElement.h>
#import <WebCore/HTMLNames.h>
#import <WebCore/HistoryItem.h>
#import <WebCore/HitTestResult.h>
#import <WebCore/JSNode.h>
#import <WebCore/LegacyWebArchive.h>
#import <WebCore/MIMETypeRegistry.h>
#import <WebCore/Page.h>
#import <WebCore/PlatformEventFactoryMac.h>
#import <WebCore/PluginData.h>
#import <WebCore/PrintContext.h>
#import <WebCore/Range.h>
#import <WebCore/RenderLayer.h>
#import <WebCore/RenderLayerCompositor.h>
#import <WebCore/RenderLayerScrollableArea.h>
#import <WebCore/RenderView.h>
#import <WebCore/RenderWidget.h>
#import <WebCore/RenderedDocumentMarker.h>
#import <WebCore/RuntimeApplicationChecks.h>
#import <WebCore/ScriptController.h>
#import <WebCore/SecurityOrigin.h>
#import <WebCore/SmartReplace.h>
#import <WebCore/StyleProperties.h>
#import <WebCore/SubframeLoader.h>
#import <WebCore/TextIterator.h>
#import <WebCore/ThreadCheck.h>
#import <WebCore/VisibleUnits.h>
#import <WebCore/markup.h>
#import <pal/spi/cg/CoreGraphicsSPI.h>
#import <wtf/cocoa/VectorCocoa.h>

#if PLATFORM(IOS_FAMILY)
#import "WebMailDelegate.h"
#import "WebResource.h"
#import "WebUIKitDelegate.h"
#import <WebCore/Document.h>
#import <WebCore/FocusController.h>
#import <WebCore/Font.h>
#import <WebCore/FrameSelection.h>
#import <WebCore/HistoryController.h>
#import <WebCore/NodeTraversal.h>
#import <WebCore/RenderLayer.h>
#import <WebCore/TextResourceDecoder.h>
#import <WebCore/WAKScrollView.h>
#import <WebCore/WAKWindow.h>
#import <WebCore/WKGraphics.h>
#import <WebCore/WebCoreThreadRun.h>
#endif

#if USE(QUICK_LOOK)
#import <WebCore/QuickLook.h>
#import <WebCore/WebCoreURLResponseIOS.h>
#endif

using JSC::JSGlobalObject;
using JSC::JSLock;

/*
Here is the current behavior matrix for four types of navigations:

Standard Nav:

 Restore form state:   YES
 Restore scroll and focus state:  YES
 Cache policy: NSURLRequestUseProtocolCachePolicy
 Add to back/forward list: YES
 
Back/Forward:

 Restore form state:   YES
 Restore scroll and focus state:  YES
 Cache policy: NSURLRequestReturnCacheDataElseLoad
 Add to back/forward list: NO

Reload (meaning only the reload button):

 Restore form state:   NO
 Restore scroll and focus state:  YES
 Cache policy: NSURLRequestReloadIgnoringCacheData
 Add to back/forward list: NO

Repeat load of the same URL (by any other means of navigation other than the reload button, including hitting return in the location field):

 Restore form state:   NO
 Restore scroll and focus state:  NO, reset to initial conditions
 Cache policy: NSURLRequestReloadIgnoringCacheData
 Add to back/forward list: NO
*/

NSString *WebPageCacheEntryDateKey = @"WebPageCacheEntryDateKey";
NSString *WebPageCacheDataSourceKey = @"WebPageCacheDataSourceKey";
NSString *WebPageCacheDocumentViewKey = @"WebPageCacheDocumentViewKey";

NSString *WebFrameMainDocumentError = @"WebFrameMainDocumentErrorKey";
NSString *WebFrameHasPlugins = @"WebFrameHasPluginsKey";
NSString *WebFrameHasUnloadListener = @"WebFrameHasUnloadListenerKey";
NSString *WebFrameUsesDatabases = @"WebFrameUsesDatabasesKey";
NSString *WebFrameUsesGeolocation = @"WebFrameUsesGeolocationKey";
NSString *WebFrameUsesApplicationCache = @"WebFrameUsesApplicationCacheKey";
NSString *WebFrameCanSuspendActiveDOMObjects = @"WebFrameCanSuspendActiveDOMObjectsKey";

// FIXME: Remove when this key becomes publicly defined
NSString *NSAccessibilityEnhancedUserInterfaceAttribute = @"AXEnhancedUserInterface";

@implementation WebFramePrivate

- (void)setWebFrameView:(WebFrameView *)v
{ 
    webFrameView = v;
}

@end

WebCore::EditableLinkBehavior core(WebKitEditableLinkBehavior editableLinkBehavior)
{
    using namespace WebCore;
    switch (editableLinkBehavior) {
        case WebKitEditableLinkDefaultBehavior:
            return EditableLinkBehavior::Default;
        case WebKitEditableLinkAlwaysLive:
            return EditableLinkBehavior::AlwaysLive;
        case WebKitEditableLinkOnlyLiveWithShiftKey:
            return EditableLinkBehavior::OnlyLiveWithShiftKey;
        case WebKitEditableLinkLiveWhenNotFocused:
            return EditableLinkBehavior::LiveWhenNotFocused;
        case WebKitEditableLinkNeverLive:
            return EditableLinkBehavior::NeverLive;
    }
    ASSERT_NOT_REACHED();
    return EditableLinkBehavior::Default;
}

WebCore::TextDirectionSubmenuInclusionBehavior core(WebTextDirectionSubmenuInclusionBehavior behavior)
{
    using namespace WebCore;
    switch (behavior) {
        case WebTextDirectionSubmenuNeverIncluded:
            return TextDirectionSubmenuInclusionBehavior::NeverIncluded;
        case WebTextDirectionSubmenuAutomaticallyIncluded:
            return TextDirectionSubmenuInclusionBehavior::AutomaticallyIncluded;
        case WebTextDirectionSubmenuAlwaysIncluded:
            return TextDirectionSubmenuInclusionBehavior::AlwaysIncluded;
    }
    ASSERT_NOT_REACHED();
    return TextDirectionSubmenuInclusionBehavior::NeverIncluded;
}

#if PLATFORM(IOS_FAMILY)

Vector<Vector<String>> vectorForDictationPhrasesArray(NSArray *dictationPhrases)
{
    Vector<Vector<String>> result;

    for (id dictationPhrase in dictationPhrases) {
        if (![dictationPhrase isKindOfClass:[NSArray class]])
            continue;
        result.append(Vector<String>());
        for (id interpretation : (NSArray *)dictationPhrase) {
            if (![interpretation isKindOfClass:[NSString class]])
                continue;
            result.last().append((NSString *)interpretation);
        }
    }
    
    return result;
}

#endif

@implementation WebFrame (WebInternal)

WebCore::Frame* core(WebFrame *frame)
{
    return frame ? frame->_private->coreFrame : 0;
}

WebFrame *kit(WebCore::Frame* frame)
{
    if (!frame)
        return nil;

    WebCore::FrameLoaderClient& frameLoaderClient = frame->loader().client();
    if (frameLoaderClient.isEmptyFrameLoaderClient())
        return nil;

    return static_cast<WebFrameLoaderClient&>(frameLoaderClient).webFrame();
}

WebCore::Page* core(WebView *webView)
{
    return [webView page];
}

WebView *kit(WebCore::Page* page)
{
    if (!page)
        return nil;

    if (page->chrome().client().isEmptyChromeClient())
        return nil;

    return static_cast<WebChromeClient&>(page->chrome().client()).webView();
}

WebView *getWebView(WebFrame *webFrame)
{
    auto coreFrame = core(webFrame);
    if (!coreFrame)
        return nil;
    return kit(coreFrame->page());
}

+ (Ref<WebCore::Frame>)_createFrameWithPage:(WebCore::Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView ownerElement:(WebCore::HTMLFrameOwnerElement*)ownerElement
{
    WebView *webView = kit(page);

    RetainPtr<WebFrame> frame = adoptNS([[self alloc] _initWithWebFrameView:frameView webView:webView]);
    auto coreFrame = WebCore::Frame::create(page, ownerElement, makeUniqueRef<WebFrameLoaderClient>(frame.get()));
    frame->_private->coreFrame = coreFrame.ptr();

    coreFrame.get().tree().setName(name);
    if (ownerElement) {
        ASSERT(ownerElement->document().frame());
        ownerElement->document().frame()->tree().appendChild(coreFrame.get());
    }

    coreFrame.get().init();

    [webView _setZoomMultiplier:[webView _realZoomMultiplier] isTextOnly:[webView _realZoomMultiplierIsTextOnly]];

    return coreFrame;
}

+ (void)_createMainFrameWithPage:(WebCore::Page*)page frameName:(const String&)name frameView:(WebFrameView *)frameView
{
    WebView *webView = kit(page);

    RetainPtr<WebFrame> frame = adoptNS([[self alloc] _initWithWebFrameView:frameView webView:webView]);
    frame->_private->coreFrame = &page->mainFrame();
    static_cast<WebFrameLoaderClient&>(page->mainFrame().loader().client()).setWebFrame(*frame.get());

    page->mainFrame().tree().setName(name);
    page->mainFrame().init();

    [webView _setZoomMultiplier:[webView _realZoomMultiplier] isTextOnly:[webView _realZoomMultiplierIsTextOnly]];
}

+ (Ref<WebCore::Frame>)_createSubframeWithOwnerElement:(WebCore::HTMLFrameOwnerElement*)ownerElement frameName:(const String&)name frameView:(WebFrameView *)frameView
{
    return [self _createFrameWithPage:ownerElement->document().frame()->page() frameName:name frameView:frameView ownerElement:ownerElement];
}

- (BOOL)_isIncludedInWebKitStatistics
{
    return _private && _private->includedInWebKitStatistics;
}

#if PLATFORM(IOS_FAMILY)
static NSURL *createUniqueWebDataURL();

+ (void)_createMainFrameWithSimpleHTMLDocumentWithPage:(WebCore::Page*)page frameView:(WebFrameView *)frameView style:(NSString *)style
{
    WebView *webView = kit(page);
    
    RetainPtr<WebFrame> frame = adoptNS([[self alloc] _initWithWebFrameView:frameView webView:webView]);
    frame->_private->coreFrame = &page->mainFrame();
    static_cast<WebFrameLoaderClient&>(page->mainFrame().loader().client()).setWebFrame(*frame.get());

    frame.get()->_private->coreFrame->initWithSimpleHTMLDocument(style, createUniqueWebDataURL());
}
#endif

- (void)_attachScriptDebugger
{
    auto& windowProxy = _private->coreFrame->windowProxy();

    // Calling ScriptController::globalObject() would create a window proxy, and dispatch corresponding callbacks, which may be premature
    // if the script debugger is attached before a document is created.  These calls use the debuggerWorld(), we will need to pass a world
    // to be able to debug isolated worlds.
    if (!windowProxy.existingJSWindowProxy(WebCore::debuggerWorld()))
        return;

    auto* globalObject = windowProxy.globalObject(WebCore::debuggerWorld());
    if (!globalObject)
        return;

    if (_private->scriptDebugger) {
        ASSERT(_private->scriptDebugger.get() == globalObject->debugger());
        return;
    }

    _private->scriptDebugger = makeUnique<WebScriptDebugger>(globalObject);
}

- (void)_detachScriptDebugger
{
    _private->scriptDebugger = nullptr;
}

- (id)_initWithWebFrameView:(WebFrameView *)fv webView:(WebView *)v
{
    self = [super init];
    if (!self)
        return nil;

    _private = [[WebFramePrivate alloc] init];

    // Set includedInWebKitStatistics before calling WebFrameView _setWebFrame, since
    // it calls WebFrame _isIncludedInWebKitStatistics.
    if ((_private->includedInWebKitStatistics = [[v class] shouldIncludeInWebKitStatistics]))
        ++WebFrameCount;

    if (fv) {
        [_private setWebFrameView:fv];
        [fv _setWebFrame:self];
    }

    _private->shouldCreateRenderers = YES;

    return self;
}

- (void)_clearCoreFrame
{
    _private->coreFrame = 0;
}

- (WebHTMLView *)_webHTMLDocumentView
{
    id documentView = [_private->webFrameView documentView];    
    return [documentView isKindOfClass:[WebHTMLView class]] ? (WebHTMLView *)documentView : nil;
}

- (void)_updateBackgroundAndUpdatesWhileOffscreen
{
    WebView *webView = getWebView(self);
    BOOL drawsBackground = [webView drawsBackground];
#if !PLATFORM(IOS_FAMILY)
    NSColor *backgroundColor = [webView backgroundColor];
#else
    CGColorRef backgroundColor = [webView backgroundColor];
#endif

    auto coreFrame = _private->coreFrame;
    for (auto frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        // Don't call setDrawsBackground:YES here because it may be NO because of a load
        // in progress; WebFrameLoaderClient keeps it set to NO during the load process.
        WebFrame *webFrame = kit(frame);
        if (!drawsBackground)
            [[[webFrame frameView] _scrollView] setDrawsBackground:NO];
#if !PLATFORM(IOS_FAMILY)
        [[[webFrame frameView] _scrollView] setBackgroundColor:backgroundColor];
#endif

        if (auto* view = frame->view()) {
            view->setTransparent(!drawsBackground);
#if !PLATFORM(IOS_FAMILY)
            ALLOW_DEPRECATED_DECLARATIONS_BEGIN
            WebCore::Color color = WebCore::colorFromNSColor([backgroundColor colorUsingColorSpaceName:NSDeviceRGBColorSpace]);
            ALLOW_DEPRECATED_DECLARATIONS_END
#else
            WebCore::Color color(WebCore::roundAndClampToSRGBALossy(backgroundColor));
#endif
            view->setBaseBackgroundColor(color);
            view->setShouldUpdateWhileOffscreen([webView shouldUpdateWhileOffscreen]);
        }
    }
}

- (void)_setInternalLoadDelegate:(id)internalLoadDelegate
{
    _private->internalLoadDelegate = internalLoadDelegate;
}

- (id)_internalLoadDelegate
{
    return _private->internalLoadDelegate;
}

- (void)_unmarkAllBadGrammar
{
    auto coreFrame = _private->coreFrame;
    for (auto frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        if (auto* document = frame->document())
            document->markers().removeMarkers(WebCore::DocumentMarker::Grammar);
    }
}

- (void)_unmarkAllMisspellings
{
#if !PLATFORM(IOS_FAMILY)
    auto coreFrame = _private->coreFrame;
    for (auto frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        if (auto* document = frame->document())
            document->markers().removeMarkers(WebCore::DocumentMarker::Spelling);
    }
#endif
}

- (BOOL)_hasSelection
{
    id documentView = [_private->webFrameView documentView];    

    // optimization for common case to avoid creating potentially large selection string
    if ([documentView isKindOfClass:[WebHTMLView class]])
        if (auto coreFrame = _private->coreFrame)
            return coreFrame->selection().isRange();

    if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
        return [[documentView selectedString] length] > 0;
    
    return NO;
}

- (void)_clearSelection
{
    id documentView = [_private->webFrameView documentView];    
    if ([documentView conformsToProtocol:@protocol(WebDocumentText)])
        [documentView deselectAll];
}

#if ASSERT_ENABLED
- (BOOL)_atMostOneFrameHasSelection
{
    // FIXME: 4186050 is one known case that makes this debug check fail.
    BOOL found = NO;
    auto coreFrame = _private->coreFrame;
    for (auto frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        if ([kit(frame) _hasSelection]) {
            if (found)
                return NO;
            found = YES;
        }
    }
    return YES;
}
#endif // ASSERT_ENABLED

- (WebFrame *)_findFrameWithSelection
{
    auto coreFrame = _private->coreFrame;
    for (auto frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        WebFrame *webFrame = kit(frame);
        if ([webFrame _hasSelection])
            return webFrame;
    }
    return nil;
}

- (void)_clearSelectionInOtherFrames
{
    // We rely on WebDocumentSelection protocol implementors to call this method when they become first 
    // responder. It would be nicer to just notice first responder changes here instead, but there's no 
    // notification sent when the first responder changes in general (Radar 2573089).
    WebFrame *frameWithSelection = [[getWebView(self) mainFrame] _findFrameWithSelection];
    if (frameWithSelection != self)
        [frameWithSelection _clearSelection];

    // While we're in the general area of selection and frames, check that there is only one now.
    ASSERT([[getWebView(self) mainFrame] _atMostOneFrameHasSelection]);
}

- (WebDataSource *)_dataSource
{
    return dataSource(_private->coreFrame->loader().documentLoader());
}

#if PLATFORM(IOS_FAMILY)

- (BOOL)_isCommitting
{
    return _private->isCommitting;
}

- (void)_setIsCommitting:(BOOL)value
{
    _private->isCommitting = value;
}

#endif

- (NSString *)_selectedString
{
    return _private->coreFrame->displayStringModifiedByEncoding(_private->coreFrame->editor().selectedText());
}

- (NSString *)_stringForRange:(DOMRange *)range
{
    if (!range)
        return @"";
    return plainText(makeSimpleRange(*core(range)), { }, true);
}

- (OptionSet<WebCore::PaintBehavior>)_paintBehaviorForDestinationContext:(CGContextRef)context
{
#if PLATFORM(MAC)
    // -currentContextDrawingToScreen returns YES for bitmap contexts.
    BOOL isPrinting = ![NSGraphicsContext currentContextDrawingToScreen];
    if (isPrinting)
        return OptionSet<WebCore::PaintBehavior>(WebCore::PaintBehavior::FlattenCompositingLayers) | WebCore::PaintBehavior::Snapshotting;
#endif

    if (CGContextGetType(context) != kCGContextTypeBitmap)
        return WebCore::PaintBehavior::Normal;

    // If we're drawing into a bitmap, we could be snapshotting or drawing into a layer-backed view.
    if (WebHTMLView *documentView = [self _webHTMLDocumentView]) {
#if PLATFORM(IOS_FAMILY)
        return [[documentView window] isInSnapshottingPaint] ? WebCore::PaintBehavior::Snapshotting : WebCore::PaintBehavior::Normal;
#endif
#if PLATFORM(MAC)
        // Even if we are layer-backed, we may be painting into an offscreen context.
        // We can be sure it's an offscreen context if we are not parented in a window, so exclude that case.
        // This does not cover all cases, such as a parented view being painted into an offscreen context.
        if ([documentView _web_isDrawingIntoLayer] && documentView.window)
            return WebCore::PaintBehavior::Normal;
#endif
    }

    return OptionSet<WebCore::PaintBehavior>(WebCore::PaintBehavior::FlattenCompositingLayers) | WebCore::PaintBehavior::Snapshotting;
}

- (void)_drawRect:(NSRect)rect contentsOnly:(BOOL)contentsOnly
{
#if !PLATFORM(IOS_FAMILY)
    ASSERT([[NSGraphicsContext currentContext] isFlipped]);

    CGContextRef ctx = [[NSGraphicsContext currentContext] CGContext];
#else
    CGContextRef ctx = WKGetCurrentGraphicsContext();
#endif
    WebCore::GraphicsContextCG context(ctx);

#if PLATFORM(IOS_FAMILY)
    WebCore::Frame *frame = core(self);
    if (WebCore::Page* page = frame->page())
        context.setIsAcceleratedContext(page->settings().acceleratedDrawingEnabled());
#elif PLATFORM(MAC)
    if (WebHTMLView *htmlDocumentView = [self _webHTMLDocumentView])
        context.setIsAcceleratedContext([htmlDocumentView _web_isDrawingIntoAcceleratedLayer]);
#endif

    auto* view = _private->coreFrame->view();
    
    OptionSet<WebCore::PaintBehavior> oldBehavior = view->paintBehavior();
    OptionSet<WebCore::PaintBehavior> paintBehavior = oldBehavior;
    
    if (auto* parentFrame = _private->coreFrame->tree().parent()) {
        // For subframes, we need to inherit the paint behavior from our parent
        if (auto* parentView = parentFrame ? parentFrame->view() : nullptr) {
            if (parentView->paintBehavior().contains(WebCore::PaintBehavior::FlattenCompositingLayers))
                paintBehavior.add(WebCore::PaintBehavior::FlattenCompositingLayers);
            
            if (parentView->paintBehavior().contains(WebCore::PaintBehavior::Snapshotting))
                paintBehavior.add(WebCore::PaintBehavior::Snapshotting);
            
            if (parentView->paintBehavior().contains(WebCore::PaintBehavior::TileFirstPaint))
                paintBehavior.add(WebCore::PaintBehavior::TileFirstPaint);
        }
    } else
        paintBehavior.add([self _paintBehaviorForDestinationContext:ctx]);
        
    view->setPaintBehavior(paintBehavior);

    if (contentsOnly)
        view->paintContents(context, WebCore::enclosingIntRect(rect));
    else
        view->paint(context, WebCore::enclosingIntRect(rect));

    view->setPaintBehavior(oldBehavior);
}

- (BOOL)_getVisibleRect:(NSRect*)rect
{
    ASSERT_ARG(rect, rect);
    if (auto* ownerRenderer = _private->coreFrame->ownerRenderer()) {
        if (ownerRenderer->needsLayout())
            return NO;
        *rect = ownerRenderer->pixelSnappedAbsoluteClippedOverflowRect();
        return YES;
    }

    return NO;
}

- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string
{
    return [self _stringByEvaluatingJavaScriptFromString:string forceUserGesture:true];
}

- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
{
    if (!string)
        return @"";

    RELEASE_ASSERT(isMainThread());

    ASSERT(_private->coreFrame->document());
    RetainPtr<WebFrame> protect(self); // Executing arbitrary JavaScript can destroy the frame.
    
#if PLATFORM(IOS_FAMILY)
    ASSERT(WebThreadIsLockedOrDisabled());
    JSC::JSGlobalObject* lexicalGlobalObject = _private->coreFrame->script().globalObject(WebCore::mainThreadNormalWorld());
    JSC::JSLockHolder jscLock(lexicalGlobalObject);
#endif

    JSC::JSValue result = _private->coreFrame->script().executeScriptIgnoringException(string, forceUserGesture);

    if (!_private->coreFrame) // In case the script removed our frame from the page.
        return @"";

    // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
    // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
    // JSEvaluateScript instead, since they have less surprising semantics.
    if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
        return @"";

#if !PLATFORM(IOS_FAMILY)
    JSC::JSGlobalObject* lexicalGlobalObject = _private->coreFrame->script().globalObject(WebCore::mainThreadNormalWorld());
    JSC::JSLockHolder lock(lexicalGlobalObject);
#endif
    return result.toWTFString(lexicalGlobalObject);
}

- (NSRect)_caretRectAtPosition:(const WebCore::Position&)pos affinity:(NSSelectionAffinity)affinity
{
    WebCore::VisiblePosition visiblePosition(pos, static_cast<WebCore::Affinity>(affinity));
    return visiblePosition.absoluteCaretBounds();
}

- (NSRect)_firstRectForDOMRange:(DOMRange *)range
{
    if (!range)
        return NSZeroRect;
    return _private->coreFrame->editor().firstRectForRange(makeSimpleRange(*core(range)));
}

- (void)_scrollDOMRangeToVisible:(DOMRange *)range
{
    bool insideFixed = false; // FIXME: get via firstRectForRange().
    NSRect rangeRect = [self _firstRectForDOMRange:range];
    auto* startNode = core([range startContainer]);
        
    if (startNode && startNode->renderer()) {
#if !PLATFORM(IOS_FAMILY)
        startNode->renderer()->scrollRectToVisible(WebCore::enclosingIntRect(rangeRect), insideFixed, { WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ShouldAllowCrossOriginScrolling::Yes });
#else
        auto* layer = startNode->renderer()->enclosingLayer();
        if (layer) {
            startNode->renderer()->scrollRectToVisible(WebCore::enclosingIntRect(rangeRect), insideFixed, { WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ShouldAllowCrossOriginScrolling::Yes });
            _private->coreFrame->selection().setCaretRectNeedsUpdate();
            _private->coreFrame->selection().updateAppearance();
        }
#endif
    }
}

#if PLATFORM(IOS_FAMILY)
- (void)_scrollDOMRangeToVisible:(DOMRange *)range withInset:(CGFloat)inset
{
    bool insideFixed = false; // FIXME: get via firstRectForRange().
    NSRect rangeRect = NSInsetRect([self _firstRectForDOMRange:range], inset, inset);
    auto* startNode = core([range startContainer]);

    if (startNode && startNode->renderer()) {
        auto* layer = startNode->renderer()->enclosingLayer();
        if (layer) {
            startNode->renderer()->scrollRectToVisible(WebCore::enclosingIntRect(rangeRect), insideFixed, { WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ScrollAlignment::alignToEdgeIfNeeded, WebCore::ShouldAllowCrossOriginScrolling::Yes});

            auto coreFrame = core(self);
            if (coreFrame) {
                auto& frameSelection = coreFrame->selection();
                frameSelection.setCaretRectNeedsUpdate();
                frameSelection.updateAppearance();
            }
        }
    }
}
#endif

- (BOOL)_needsLayout
{
    return _private->coreFrame->view() ? _private->coreFrame->view()->needsLayout() : false;
}

#if !PLATFORM(IOS_FAMILY)
- (DOMRange *)_rangeByAlteringCurrentSelection:(WebCore::FrameSelection::EAlteration)alteration direction:(WebCore::SelectionDirection)direction granularity:(WebCore::TextGranularity)granularity
{
    if (_private->coreFrame->selection().isNone())
        return nil;

    WebCore::FrameSelection selection;
    selection.setSelection(_private->coreFrame->selection().selection());
    selection.modify(alteration, direction, granularity);
    return kit(selection.selection().toNormalizedRange());
}
#endif

- (WebCore::TextGranularity)_selectionGranularity
{
    return _private->coreFrame->selection().granularity();
}

- (NSRange)_convertToNSRange:(const WebCore::SimpleRange&)range
{
    auto frame = _private->coreFrame;
    if (!frame)
        return NSMakeRange(NSNotFound, 0);

    auto* element = frame->selection().rootEditableElementOrDocumentElement();
    if (!element)
        return NSMakeRange(NSNotFound, 0);

    return characterRange(makeBoundaryPointBeforeNodeContents(*element), range);
}

- (std::optional<WebCore::SimpleRange>)_convertToDOMRange:(NSRange)nsrange
{
    return [self _convertToDOMRange:nsrange rangeIsRelativeTo:WebRangeIsRelativeTo::EditableRoot];
}

- (std::optional<WebCore::SimpleRange>)_convertToDOMRange:(NSRange)range rangeIsRelativeTo:(WebRangeIsRelativeTo)rangeIsRelativeTo
{
    if (range.location == NSNotFound)
        return std::nullopt;

    if (rangeIsRelativeTo == WebRangeIsRelativeTo::EditableRoot) {
        // Our critical assumption is that this code path is only called by input methods that
        // concentrate on a given area containing the selection
        // We have to do this because of text fields and textareas. The DOM for those is not
        // directly in the document DOM, so serialization is problematic. Our solution is
        // to use the root editable element of the selection start as the positional base.
        // That fits with AppKit's idea of an input context.
        auto* element = _private->coreFrame->selection().rootEditableElementOrDocumentElement();
        if (!element)
            return std::nullopt;
        return resolveCharacterRange(makeRangeSelectingNodeContents(*element), range);
    }

    ASSERT(rangeIsRelativeTo == WebRangeIsRelativeTo::Paragraph);

    auto paragraphStart = makeBoundaryPoint(startOfParagraph(_private->coreFrame->selection().selection().visibleStart()));
    if (!paragraphStart)
        return std::nullopt;

    auto scopeEnd = makeBoundaryPointAfterNodeContents(paragraphStart->container->treeScope().rootNode());
    return WebCore::resolveCharacterRange({ WTFMove(*paragraphStart), WTFMove(scopeEnd) }, range);
}

- (DOMRange *)_convertNSRangeToDOMRange:(NSRange)nsrange
{
    return kit([self _convertToDOMRange:nsrange]);
}

- (NSRange)_convertDOMRangeToNSRange:(DOMRange *)range
{
    if (!range)
        return NSMakeRange(NSNotFound, 0);
    return [self _convertToNSRange:makeSimpleRange(*core(range))];
}

- (DOMRange *)_markDOMRange
{
    return kit(_private->coreFrame->editor().mark().toNormalizedRange());
}

- (DOMDocumentFragment *)_documentFragmentWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString
{
    auto frame = _private->coreFrame;
    if (!frame)
        return nil;

    auto* document = frame->document();
    if (!document)
        return nil;

    return kit(createFragmentFromMarkup(*document, markupString, baseURLString, WebCore::DisallowScriptingContent).ptr());
}

- (DOMDocumentFragment *)_documentFragmentWithNodesAsParagraphs:(NSArray *)nodes
{
    auto frame = _private->coreFrame;
    if (!frame)
        return nil;

    auto* document = frame->document();
    if (!document)
        return nil;

    NSEnumerator *nodeEnum = [nodes objectEnumerator];
    Vector<WebCore::Node*> nodesVector;
    DOMNode *node;
    while ((node = [nodeEnum nextObject]))
        nodesVector.append(core(node));

    auto fragment = document->createDocumentFragment();

    for (auto* node : nodesVector) {
        auto element = createDefaultParagraphElement(*document);
        element->appendChild(*node);
        fragment->appendChild(element);
    }

    return kit(fragment.ptr());
}

- (void)_replaceSelectionWithNode:(DOMNode *)node selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
{
    DOMDocumentFragment *fragment = kit(_private->coreFrame->document()->createDocumentFragment().ptr());
    [fragment appendChild:node];
    [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle];
}

- (void)_insertParagraphSeparatorInQuotedContent
{
    if (_private->coreFrame->selection().isNone())
        return;

    _private->coreFrame->editor().insertParagraphSeparatorInQuotedContent();
}

- (WebCore::VisiblePosition)_visiblePositionForPoint:(NSPoint)point
{
    // FIXME: Someone with access to Apple's sources could remove this needless wrapper call.
    return _private->coreFrame->visiblePositionForPoint(WebCore::IntPoint(point));
}

- (DOMRange *)_characterRangeAtPoint:(NSPoint)point
{
    return kit(_private->coreFrame->rangeForPoint(WebCore::IntPoint(point)));
}

- (DOMCSSStyleDeclaration *)_typingStyle
{
    if (!_private->coreFrame)
        return nil;
    RefPtr<WebCore::MutableStyleProperties> typingStyle = _private->coreFrame->selection().copyTypingStyle();
    if (!typingStyle)
        return nil;
    return kit(&typingStyle->ensureCSSStyleDeclaration());
}

- (void)_setTypingStyle:(DOMCSSStyleDeclaration *)style withUndoAction:(WebCore::EditAction)undoAction
{
    if (!_private->coreFrame || !style)
        return;
    // FIXME: We shouldn't have to create a copy here.
    Ref<WebCore::MutableStyleProperties> properties(core(style)->copyProperties());
    _private->coreFrame->editor().computeAndSetTypingStyle(properties.get(), undoAction);
}

#if ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)
- (void)_dragSourceEndedAt:(NSPoint)windowLoc operation:(NSDragOperation)dragOperationMask
{
    if (!_private->coreFrame)
        return;
    auto* view = _private->coreFrame->view();
    if (!view)
        return;
    // FIXME: These are fake modifier keys here, but they should be real ones instead.
    WebCore::PlatformMouseEvent event(WebCore::IntPoint(windowLoc), WebCore::IntPoint(WebCore::globalPoint(windowLoc, [view->platformWidget() window])),
        WebCore::LeftButton, WebCore::PlatformEvent::MouseMoved, 0, false, false, false, false, WallTime::now(), WebCore::ForceAtClick, WebCore::NoTap);
    _private->coreFrame->eventHandler().dragSourceEndedAt(event, coreDragOperationMask(dragOperationMask));
}
#endif // ENABLE(DRAG_SUPPORT) && PLATFORM(MAC)

- (BOOL)_canProvideDocumentSource
{
    auto frame = _private->coreFrame;
    String mimeType = frame->document()->loader()->writer().mimeType();
    auto* pluginData = frame->page() ? &frame->page()->pluginData() : 0;

    if (WebCore::MIMETypeRegistry::isTextMIMEType(mimeType)
        || WebCore::Image::supportsType(mimeType)
        || (pluginData && pluginData->supportsWebVisibleMimeType(mimeType, WebCore::PluginData::AllPlugins) && frame->arePluginsEnabled())
        || (pluginData && pluginData->supportsWebVisibleMimeType(mimeType, WebCore::PluginData::OnlyApplicationPlugins)))
        return NO;

    return YES;
}

- (BOOL)_canSaveAsWebArchive
{
    // Currently, all documents that we can view source for
    // (HTML and XML documents) can also be saved as web archives
    return [self _canProvideDocumentSource];
}

- (void)_commitData:(NSData *)data
{
    // FIXME: This really should be a setting.
    auto* document = _private->coreFrame->document();
    document->setShouldCreateRenderers(_private->shouldCreateRenderers);

    _private->coreFrame->loader().documentLoader()->commitData((const uint8_t*)[data bytes], [data length]);
}

@end

@implementation WebFrame (WebPrivate)

// FIXME: This exists only as a convenience for Safari, consider moving there.
- (BOOL)_isDescendantOfFrame:(WebFrame *)ancestor
{
    auto coreFrame = _private->coreFrame;
    return coreFrame && coreFrame->tree().isDescendantOf(core(ancestor));
}

- (void)_setShouldCreateRenderers:(BOOL)shouldCreateRenderers
{
    _private->shouldCreateRenderers = shouldCreateRenderers;
}

#if !PLATFORM(IOS_FAMILY)
- (NSColor *)_bodyBackgroundColor
#else
- (CGColorRef)_bodyBackgroundColor
#endif
{
    auto* document = _private->coreFrame->document();
    if (!document)
        return nil;
    auto* body = document->bodyOrFrameset();
    if (!body)
        return nil;
    auto* bodyRenderer = body->renderer();
    if (!bodyRenderer)
        return nil;
    WebCore::Color color = bodyRenderer->style().visitedDependentColorWithColorFilter(WebCore::CSSPropertyBackgroundColor);
    if (!color.isValid())
        return nil;
#if !PLATFORM(IOS_FAMILY)
    return nsColor(color);
#else
    return cachedCGColor(color);
#endif
}

- (BOOL)_isFrameSet
{
    auto* document = _private->coreFrame->document();
    return document && document->isFrameSet();
}

- (BOOL)_firstLayoutDone
{
    return _private->coreFrame->loader().stateMachine().firstLayoutDone();
}

- (BOOL)_isVisuallyNonEmpty
{
    if (auto* view = _private->coreFrame->view())
        return view->isVisuallyNonEmpty();
    return NO;
}

static WebFrameLoadType toWebFrameLoadType(WebCore::FrameLoadType frameLoadType)
{
    using namespace WebCore;
    switch (frameLoadType) {
    case FrameLoadType::Standard:
        return WebFrameLoadTypeStandard;
    case FrameLoadType::Back:
        return WebFrameLoadTypeBack;
    case FrameLoadType::Forward:
        return WebFrameLoadTypeForward;
    case FrameLoadType::IndexedBackForward:
        return WebFrameLoadTypeIndexedBackForward;
    case FrameLoadType::Reload:
        return WebFrameLoadTypeReload;
    case FrameLoadType::Same:
        return WebFrameLoadTypeSame;
    case FrameLoadType::RedirectWithLockedBackForwardList:
        return WebFrameLoadTypeInternal;
    case FrameLoadType::Replace:
        return WebFrameLoadTypeReplace;
    case FrameLoadType::ReloadFromOrigin:
    case FrameLoadType::ReloadExpiredOnly:
        // NOTE: reloading via remote inspection may trigger ReloadExpiredOnly, but otherwise
        // it is not a supported load type as it was added after WebKit1 became WebKitLegacy.
        return WebFrameLoadTypeReloadFromOrigin;
    }
}

- (WebFrameLoadType)_loadType
{
    return toWebFrameLoadType(_private->coreFrame->loader().loadType());
}

#if PLATFORM(IOS_FAMILY)

- (BOOL)needsLayout
{
    // Needed for Mail <rdar://problem/6228038>
    return _private->coreFrame ? [self _needsLayout] : NO;
}

- (void)_setLoadsSynchronously:(BOOL)flag
{
    _private->coreFrame->loader().setLoadsSynchronously(flag);
}

- (BOOL)_loadsSynchronously
{
    return _private->coreFrame->loader().loadsSynchronously();
}

- (NSArray *)_rectsForRange:(DOMRange *)range
{
    return range ? range.textRects : @[];
}

- (DOMRange *)_selectionRangeForFirstPoint:(CGPoint)first secondPoint:(CGPoint)second
{
    auto firstPosition = [self _visiblePositionForPoint:first];
    auto secondPosition = [self _visiblePositionForPoint:second];
    return kit(WebCore::VisibleSelection(firstPosition, secondPosition).toNormalizedRange());
}

- (DOMRange *)_selectionRangeForPoint:(CGPoint)point
{
    return kit(WebCore::VisibleSelection([self _visiblePositionForPoint:point]).toNormalizedRange());
}

#endif // PLATFORM(IOS_FAMILY)

- (NSRange)_selectedNSRange
{
    auto range = _private->coreFrame->selection().selection().toNormalizedRange();
    if (!range)
        return NSMakeRange(NSNotFound, 0);
    return [self _convertToNSRange:*range];
}

- (void)_selectNSRange:(NSRange)range
{
    if (auto domRange = [self _convertToDOMRange:range])
        _private->coreFrame->selection().setSelection(WebCore::VisibleSelection(*domRange));
}

- (BOOL)_isDisplayingStandaloneImage
{
    auto* document = _private->coreFrame->document();
    return document && document->isImageDocument();
}

- (unsigned)_pendingFrameUnloadEventCount
{
    return _private->coreFrame->document()->domWindow()->pendingUnloadEventListeners();
}

#if ENABLE(NETSCAPE_PLUGIN_API)
- (void)_recursive_resumeNullEventsForAllNetscapePlugins
{
    auto coreFrame = core(self);
    for (auto* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
        if ([documentView isKindOfClass:[WebHTMLView class]])
            [(WebHTMLView *)documentView _resumeNullEventsForAllNetscapePlugins];
    }
}

- (void)_recursive_pauseNullEventsForAllNetscapePlugins
{
    auto coreFrame = core(self);
    for (auto* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        NSView <WebDocumentView> *documentView = [[kit(frame) frameView] documentView];
        if ([documentView isKindOfClass:[WebHTMLView class]])
            [(WebHTMLView *)documentView _pauseNullEventsForAllNetscapePlugins];
    }
}
#endif

#if PLATFORM(IOS_FAMILY)

- (void)setTimeoutsPaused:(BOOL)flag
{
    if ([self _webHTMLDocumentView]) {
        if (auto coreFrame = _private->coreFrame)
            coreFrame->setTimersPaused(flag);
    }
}

- (void)setPluginsPaused:(BOOL)flag
{
    WebView *webView = getWebView(self);
    if (!webView)
        return;

    if (flag)
        [webView _stopAllPlugIns];
    else
        [webView _startAllPlugIns];
}

- (void)prepareForPause
{
    if ([self _webHTMLDocumentView]) {
        if (auto coreFrame = _private->coreFrame)
            coreFrame->dispatchPageHideEventBeforePause();
    }
}

- (void)resumeFromPause
{
    if ([self _webHTMLDocumentView]) {
        if (auto coreFrame = _private->coreFrame)
            coreFrame->dispatchPageShowEventBeforeResume();
    }
}

- (void)selectNSRange:(NSRange)range
{
    [self _selectNSRange:range];
}

- (void)selectWithoutClosingTypingNSRange:(NSRange)range
{
    if (auto domRange = [self _convertToDOMRange:range]) {
        _private->coreFrame->selection().setSelection(*domRange, { });
        _private->coreFrame->editor().ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping();
    }
}

- (NSRange)selectedNSRange
{
    return [self _selectedNSRange];
}

- (void)forceLayoutAdjustingViewSize:(BOOL)adjust
{
    _private->coreFrame->view()->forceLayout(!adjust);
    if (adjust)
        _private->coreFrame->view()->adjustViewSize();
}

- (void)_handleKeyEvent:(WebEvent *)event
{
    core(self)->eventHandler().keyEvent(event);
}

- (void)_selectAll
{
    core(self)->selection().selectAll();
}

- (void)_setSelectionFromNone
{
    core(self)->selection().setSelectionFromNone();
}

- (void)_restoreViewState
{
    ASSERT(!WebThreadIsEnabled() || WebThreadIsLocked());
    _private->coreFrame->loader().client().restoreViewState();
}

- (void)_saveViewState
{
    ASSERT(!WebThreadIsEnabled() || WebThreadIsLocked());
    auto& frameLoader = _private->coreFrame->loader();
    auto* item = frameLoader.history().currentItem();
    if (item)
        frameLoader.client().saveViewStateToItem(*item);
}

- (void)deviceOrientationChanged
{
    WebThreadRun(^{
#if ENABLE(ORIENTATION_EVENTS)
        WebView *webView = getWebView(self);
        [webView _setDeviceOrientation:[[webView _UIKitDelegateForwarder] deviceOrientation]];
#endif
        if (auto* frame = core(self))
            frame->orientationChanged();
    });
}

- (void)setNeedsLayout
{
    WebCore::Frame *frame = core(self);
    if (frame->view())
        frame->view()->setNeedsLayoutAfterViewConfigurationChange();
}

- (CGSize)renderedSizeOfNode:(DOMNode *)node constrainedToWidth:(float)width
{
    WebCore::Node* n = core(node);
    auto* renderer = n ? n->renderer() : nullptr;
    float w = std::min((float)renderer->maxPreferredLogicalWidth(), width);
    return is<WebCore::RenderBox>(renderer) ? CGSizeMake(w, downcast<WebCore::RenderBox>(*renderer).height()) : CGSizeMake(0, 0);
}

- (DOMNode *)deepestNodeAtViewportLocation:(CGPoint)aViewportLocation
{
    WebCore::Frame *frame = core(self);
    return kit(frame->deepestNodeAtLocation(WebCore::FloatPoint(aViewportLocation)));
}

- (DOMNode *)scrollableNodeAtViewportLocation:(CGPoint)aViewportLocation
{
    WebCore::Frame *frame = core(self);
    WebCore::Node *node = frame->nodeRespondingToScrollWheelEvents(WebCore::FloatPoint(aViewportLocation));
    return kit(node);
}

- (DOMNode *)approximateNodeAtViewportLocation:(CGPoint *)aViewportLocation
{
    WebCore::Frame *frame = core(self);
    WebCore::FloatPoint viewportLocation(*aViewportLocation);
    WebCore::FloatPoint adjustedLocation;
    WebCore::Node *node = frame->approximateNodeAtViewportLocationLegacy(viewportLocation, adjustedLocation);
    *aViewportLocation = adjustedLocation;
    return kit(node);
}

- (CGRect)renderRectForPoint:(CGPoint)point isReplaced:(BOOL *)isReplaced fontSize:(float *)fontSize
{
    WebCore::Frame *frame = core(self);
    bool replaced = false;
    CGRect rect = frame->renderRectForPoint(point, &replaced, fontSize);
    *isReplaced = replaced;
    return rect;
}

- (void)_setProhibitsScrolling:(BOOL)flag
{
    WebCore::Frame *frame = core(self);
    frame->view()->setProhibitsScrolling(flag);
}

- (void)revealSelectionAtExtent:(BOOL)revealExtent
{
    WebCore::Frame *frame = core(self);
    WebCore::RevealExtentOption revealExtentOption = revealExtent ? WebCore::RevealExtent : WebCore::DoNotRevealExtent;
    frame->selection().revealSelection(WebCore::SelectionRevealMode::Reveal, WebCore::ScrollAlignment::alignToEdgeIfNeeded, revealExtentOption);
}

- (void)resetSelection
{
    WebCore::Frame *frame = core(self);
    frame->selection().setSelection(frame->selection().selection());
}

- (BOOL)hasEditableSelection
{
    return core(self)->selection().selection().isContentEditable();
}

- (int)preferredHeight
{
    return core(self)->preferredHeight();
}

- (int)innerLineHeight:(DOMNode *)node
{
    if (!node)
        return 0;

    auto& coreNode = *core(node);

    coreNode.document().updateLayout();

    auto* renderer = coreNode.renderer();
    if (!renderer)
        return 0;

    return renderer->innerLineHeight();
}

- (void)updateLayout
{
    WebCore::Frame *frame = core(self);
    frame->updateLayout();
}

- (void)setIsActive:(BOOL)flag
{
    WebCore::Frame *frame = core(self);
    frame->page()->focusController().setActive(flag);
}

- (void)setSelectionChangeCallbacksDisabled:(BOOL)flag
{
    WebCore::Frame *frame = core(self);
    frame->setSelectionChangeCallbacksDisabled(flag);
}

- (NSRect)caretRect
{
    return core(self)->caretRect();
}

- (NSRect)rectForScrollToVisible
{
    return core(self)->rectForScrollToVisible();
}

- (void)setCaretColor:(CGColorRef)color
{
    WebCore::Color qColor = color ? WebCore::Color(WebCore::roundAndClampToSRGBALossy(color)) : WebCore::Color::black;
    WebCore::Frame *frame = core(self);
    frame->selection().setCaretColor(qColor);
}

- (CGColorRef)caretColor
{
    auto* frame = core(self);
    if (!frame)
        return nil;
    auto* document = frame->document();
    if (!document)
        return nil;
    auto* focusedElement = document->focusedElement();
    if (!focusedElement)
        return nil;
    auto* renderer = focusedElement->renderer();
    if (!renderer)
        return nil;
    auto color = WebCore::CaretBase::computeCaretColor(renderer->style(), renderer->element());
    return color.isValid() ? cachedCGColor(color) : nil;
}

- (NSView *)documentView
{
    WebCore::Frame *frame = core(self);
    return [[kit(frame) frameView] documentView];
}

- (int)layoutCount
{
    WebCore::Frame *frame = core(self);
    if (!frame || !frame->view())
        return 0;
    return frame->view()->layoutContext().layoutCount();
}

- (BOOL)isTelephoneNumberParsingAllowed
{
    WebCore::Frame *frame = core(self);
    if (!frame || !frame->document())
        return false;
    return frame->document()->isTelephoneNumberParsingAllowed();
}

- (BOOL)isTelephoneNumberParsingEnabled
{
    WebCore::Frame *frame = core(self);
    if (!frame || !frame->document())
        return false;
    return frame->document()->isTelephoneNumberParsingEnabled();
}

- (DOMRange *)selectedDOMRange
{
    return kit(core(self)->selection().selection().toNormalizedRange());
}

- (void)setSelectedDOMRange:(DOMRange *)range affinity:(NSSelectionAffinity)affinity closeTyping:(BOOL)closeTyping
{
    [self setSelectedDOMRange:range affinity:affinity closeTyping:closeTyping userTriggered:NO];
}

- (void)setSelectedDOMRange:(DOMRange *)range affinity:(NSSelectionAffinity)affinity closeTyping:(BOOL)closeTyping userTriggered:(BOOL)userTriggered
{
    using namespace WebCore;

    auto& frame = *core(self);
    if (!frame.page())
        return;

    // Ensure the view becomes first responder. This does not happen automatically on iOS because
    // we don't forward all the click events to WebKit.
    if (NSView *documentView = frame.view()->documentView())
        frame.page()->chrome().focusNSView(documentView);

    auto coreCloseTyping = closeTyping ? FrameSelection::ShouldCloseTyping::Yes : FrameSelection::ShouldCloseTyping::No;
    auto coreUserTriggered = userTriggered ? UserTriggered : NotUserTriggered;
    frame.selection().setSelectedRange(makeSimpleRange(core(range)), core(affinity), coreCloseTyping, coreUserTriggered);
    if (!closeTyping)
        frame.editor().ensureLastEditCommandHasCurrentSelectionIfOpenForMoreTyping();
}

- (NSSelectionAffinity)selectionAffinity
{
    WebCore::Frame *frame = core(self);
    return (NSSelectionAffinity)(frame->selection().selection().affinity());
}

- (void)expandSelectionToElementContainingCaretSelection
{
    WebCore::Frame *frame = core(self);
    frame->selection().expandSelectionToElementContainingCaretSelection();
}

- (DOMRange *)elementRangeContainingCaretSelection
{
    return kit(core(self)->selection().elementRangeContainingCaretSelection());
}

- (void)expandSelectionToWordContainingCaretSelection
{
    core(self)->selection().expandSelectionToWordContainingCaretSelection();
}

- (void)expandSelectionToStartOfWordContainingCaretSelection
{
    core(self)->selection().expandSelectionToStartOfWordContainingCaretSelection();
}

- (unichar)characterInRelationToCaretSelection:(int)amount
{
    return core(self)->selection().characterInRelationToCaretSelection(amount);
}

- (unichar)characterBeforeCaretSelection
{
    auto frame = core(self);
    if (!frame)
        return 0;
    frame->document()->updateLayout();
    return frame->selection().selection().visibleStart().characterBefore();
}

- (unichar)characterAfterCaretSelection
{
    auto frame = core(self);
    if (!frame)
        return 0;
    frame->document()->updateLayout();
    return frame->selection().selection().visibleEnd().characterAfter();
}

- (DOMRange *)wordRangeContainingCaretSelection
{
    return kit(core(self)->selection().wordRangeContainingCaretSelection());
}

- (NSString *)wordInRange:(DOMRange *)range
{
    if (!range)
        return nil;
    return [self _stringForRange:range];
}

- (int)wordOffsetInRange:(DOMRange *)range
{
    if (!range)
        return -1;

    auto selection = core(self)->selection().selection();
    if (!selection.isCaret())
        return -1;

    // FIXME: This will only work in cases where the selection remains in the same node after it is expanded.
    return std::max<int>(0, selection.start().deprecatedEditingOffset() - core(range)->startOffset());
}

- (BOOL)spaceFollowsWordInRange:(DOMRange *)range
{
    return range && isSpaceOrNewline(WebCore::VisiblePosition(makeDeprecatedLegacyPosition(makeSimpleRange(core(range))->end)).characterAfter());
}

- (NSArray *)wordsInCurrentParagraph
{
    return core(self)->wordsInCurrentParagraph();
}

- (BOOL)selectionAtDocumentStart
{
    auto frame = core(self);
    if (!frame)
        return NO;
    frame->document()->updateLayout();
    return isStartOfDocument(frame->selection().selection().visibleStart());
}

- (BOOL)selectionAtSentenceStart
{
    WebCore::Frame *frame = core(self);
    
    if (frame->selection().selection().isNone())
        return NO;
        
    frame->document()->updateLayout();
    
    return frame->selection().selectionAtSentenceStart();
}

- (BOOL)selectionAtWordStart
{
    WebCore::Frame *frame = core(self);
    
    if (frame->selection().selection().isNone())
        return NO;
        
    frame->document()->updateLayout();
    
    return frame->selection().selectionAtWordStart();
}

- (DOMRange *)rangeByMovingCurrentSelection:(int)amount
{
    return kit(core(self)->selection().rangeByMovingCurrentSelection(amount));
}

- (DOMRange *)rangeByExtendingCurrentSelection:(int)amount
{
    return kit(core(self)->selection().rangeByExtendingCurrentSelection(amount));
}

- (void)selectNSRange:(NSRange)range onElement:(DOMElement *)element
{
    // FIXME: This method does not do a useful operation: treating NSRange offsets as child node offsets does not make logical sense. Also, it's highly unlikely anyone calls it. We should delete it.
    if (!element)
        return;
    auto frame = core(self);
    if (!frame)
        return;
    auto& coreElement = *core(element);
    unsigned startOffset = range.location;
    unsigned endOffset = NSMaxRange(range);
    frame->selection().setSelection(WebCore::VisibleSelection { WebCore::SimpleRange { { coreElement, startOffset }, { coreElement, endOffset } } }, { WebCore::FrameSelection::FireSelectEvent });
}

- (DOMRange *)markedTextDOMRange
{
    WebCore::Frame *frame = core(self);
    if (!frame)
        return nil;

    return kit(frame->editor().compositionRange());
}

- (void)setMarkedText:(NSString *)text selectedRange:(NSRange)newSelRange
{
    WebCore::Frame *frame = core(self);
    if (!frame)
        return;
    
    Vector<WebCore::CompositionUnderline> underlines;
    frame->page()->chrome().client().suppressFormNotifications();
    frame->editor().setComposition(text, underlines, { }, newSelRange.location, NSMaxRange(newSelRange));
    frame->page()->chrome().client().restoreFormNotifications();
}

- (void)setMarkedText:(NSString *)text forCandidates:(BOOL)forCandidates
{
    WebCore::Frame *frame = core(self);
    if (!frame)
        return;
        
    Vector<WebCore::CompositionUnderline> underlines;
    frame->editor().setComposition(text, underlines, { }, 0, [text length]);
}

- (void)confirmMarkedText:(NSString *)text
{
    WebCore::Frame *frame = core(self);
    if (!frame || !frame->editor().client())
        return;
    
    frame->page()->chrome().client().suppressFormNotifications();
    if (text)
        frame->editor().confirmComposition(text);
    else
        frame->editor().confirmMarkedText();
    frame->page()->chrome().client().restoreFormNotifications();
}

- (void)setText:(NSString *)text asChildOfElement:(DOMElement *)element
{
    if (!element)
        return;
        
    WebCore::Frame *frame = core(self);
    if (!frame || !frame->document())
        return;
        
    frame->editor().setTextAsChildOfElement(text, *core(element));
}

- (void)setDictationPhrases:(NSArray *)dictationPhrases metadata:(id)metadata asChildOfElement:(DOMElement *)element
{
    if (!element)
        return;
    
    auto* frame = core(self);
    if (!frame)
        return;
    
    frame->editor().setDictationPhrasesAsChildOfElement(vectorForDictationPhrasesArray(dictationPhrases), metadata, *core(element));
}

- (NSArray *)interpretationsForCurrentRoot
{
    return core(self)->interpretationsForCurrentRoot();
}

// Collects the ranges and metadata for all of the mars voltas in the root editable element.
- (void)getDictationResultRanges:(NSArray **)outRanges andMetadatas:(NSArray **)outMetadatas
{
    ASSERT(outRanges);
    if (!outRanges)
        return;

    // *outRanges should not already point to an array.
    ASSERT(!(*outRanges));
    *outRanges = nil;

    ASSERT(outMetadatas);
    if (!outMetadatas)
        return;

    // *metadata should not already point to an array.
    ASSERT(!(*outMetadatas));
    *outMetadatas = nil;

    NSMutableArray *ranges = [NSMutableArray array];
    NSMutableArray *metadatas = [NSMutableArray array];

    auto* frame = core(self);
    auto* document = frame->document();

    auto& selection = frame->selection().selection();
    auto root = selection.isNone() ? frame->document()->bodyOrFrameset() : selection.rootEditableElement();

    RetainPtr<DOMRange> previousDOMRange;
    id previousMetadata = nil;

    for (WebCore::Node* node = root; node; node = WebCore::NodeTraversal::next(*node)) {
        auto markers = document->markers().markersFor(*node);
        for (auto* marker : markers) {
            if (marker->type() != WebCore::DocumentMarker::DictationResult)
                continue;

            id metadata = std::get<RetainPtr<id>>(marker->data()).get();

            // All result markers should have metadata.
            ASSERT(metadata);
            if (!metadata)
                continue;

            DOMRange *domRange = kit(makeSimpleRange(*node, *marker));

            if (metadata != previousMetadata) {
                [metadatas addObject:metadata];
                [ranges addObject:domRange];
                previousMetadata = metadata;
                previousDOMRange = domRange;
            } else {
                // It is possible for a DocumentMarker to be split by editing. Adjacent markers with the
                // the same metadata are for the same result. So combine their ranges.
                ASSERT(previousDOMRange == [ranges lastObject]);
                [ranges removeLastObject];
                DOMNode *startContainer = [domRange startContainer];
                int startOffset = [domRange startOffset];
                [previousDOMRange setEnd:startContainer offset:startOffset];
                [ranges addObject:previousDOMRange.get()];
            }
        }
    }
    
    *outRanges = ranges;
    *outMetadatas = metadatas;
    
    return;
}

- (id)dictationResultMetadataForRange:(DOMRange *)range
{
    if (!range)
        return nil;

    auto markers = core(self)->document()->markers().markersInRange(makeSimpleRange(*core(range)), WebCore::DocumentMarker::DictationResult);

    // UIKit should only ever give us a DOMRange for a phrase with alternatives, which should not be part of more than one result.
    ASSERT(markers.size() <= 1);
    if (markers.size() == 0)
        return nil;

    return std::get<RetainPtr<id>>(markers[0]->data()).get();
}

- (void)recursiveSetUpdateAppearanceEnabled:(BOOL)enabled
{
    WebCore::Frame *frame = core(self);
    if (frame)
        frame->recursiveSetUpdateAppearanceEnabled(enabled);
}

// WebCoreFrameBridge methods used by iOS applications and frameworks
// FIXME: WebCoreFrameBridge is long gone. Can we remove these methods?

+ (NSString *)stringWithData:(NSData *)data textEncodingName:(NSString *)textEncodingName
{
    WebCore::TextEncoding encoding(textEncodingName);
    if (!encoding.isValid())
        encoding = WebCore::WindowsLatin1Encoding();
    return encoding.decode(reinterpret_cast<const char*>([data bytes]), [data length]);
}

- (NSRect)caretRectAtNode:(DOMNode *)node offset:(int)offset affinity:(NSSelectionAffinity)affinity
{
    return [self _caretRectAtPosition:makeDeprecatedLegacyPosition(core(node), offset) affinity:affinity];
}

- (DOMRange *)characterRangeAtPoint:(NSPoint)point
{
    return [self _characterRangeAtPoint:point];
}

- (NSRange)convertDOMRangeToNSRange:(DOMRange *)range
{
    return [self _convertDOMRangeToNSRange:range];
}

- (DOMRange *)convertNSRangeToDOMRange:(NSRange)nsrange
{
    return [self _convertNSRangeToDOMRange:nsrange];
}

- (NSRect)firstRectForDOMRange:(DOMRange *)range
{
    return [self _firstRectForDOMRange:range];
}

- (CTFontRef)fontForSelection:(BOOL *)hasMultipleFonts
{
    bool multipleFonts = false;
    CTFontRef font = nil;
    if (_private->coreFrame) {
        if (auto coreFont = _private->coreFrame->editor().fontForSelection(multipleFonts))
            font = coreFont->getCTFont();
    }
    
    if (hasMultipleFonts)
        *hasMultipleFonts = multipleFonts;
    return font;
}

- (void)sendScrollEvent
{
    ASSERT(WebThreadIsLockedOrDisabled());
    _private->coreFrame->eventHandler().scheduleScrollEvent();
}

- (void)_userScrolled
{
    ASSERT(WebThreadIsLockedOrDisabled());
    if (auto* view = _private->coreFrame->view())
        view->setWasScrolledByUser(true);
}

- (NSString *)stringByEvaluatingJavaScriptFromString:(NSString *)string forceUserGesture:(BOOL)forceUserGesture
{
    return [self _stringByEvaluatingJavaScriptFromString:string forceUserGesture:forceUserGesture];
}

- (NSString *)stringForRange:(DOMRange *)range
{
    return [self _stringForRange:range];
}

//
// FIXME: We needed to add this method for iOS due to the opensource version's inclusion of
// matchStyle:YES. It seems odd that we should need to explicitly match style, given that the
// fragment is being made out of plain text, which shouldn't be carrying any style of its own.
// When we paste that it will pick up its style from the surrounding content. What else would
// we expect? If we flipped that matchStyle bit to NO, we could probably just get rid
// of this method, and call the standard WebKit version.
//
// There's a second problem here, too, which is that ReplaceSelectionCommand sometimes adds
// redundant style.
// 
- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
{
    auto range = _private->coreFrame->selection().selection().toNormalizedRange();
    DOMDocumentFragment* fragment = range ? kit(createFragmentFromText(*range, text).ptr()) : nil;
    [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:matchStyle];
}

- (void)_replaceSelectionWithWebArchive:(WebArchive *)webArchive selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
{
    NSArray* subresources = [webArchive subresources];
    for (WebResource* subresource in subresources) {
        if (![[self dataSource] subresourceForURL:[subresource URL]])
            [[self dataSource] addSubresource:subresource];
    }

    DOMDocumentFragment* fragment = [[self dataSource] _documentFragmentWithArchive:webArchive];
    [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
}

#endif // PLATFORM(IOS_FAMILY)

#if ENABLE(TEXT_AUTOSIZING)
- (void)resetTextAutosizingBeforeLayout
{
    if (![self _webHTMLDocumentView])
        return;
    
    auto coreFrame = core(self);
    for (auto* frame = coreFrame; frame; frame = frame->tree().traverseNext(coreFrame)) {
        WebCore::Document* doc = frame->document();
        if (!doc || !doc->renderView())
            continue;
        doc->renderView()->resetTextAutosizing();
    }
}

- (void)_setVisibleSize:(CGSize)size
{
    [self _setTextAutosizingWidth:size.width];
}

- (void)_setTextAutosizingWidth:(CGFloat)width
{
    auto* frame = core(self);
    auto* page = frame->page();
    if (!page)
        return;

    page->setTextAutosizingWidth(width);
}
#else
- (void)resetTextAutosizingBeforeLayout
{
}

- (void)_setVisibleSize:(CGSize)size
{
}

- (void)_setTextAutosizingWidth:(CGFloat)width
{
}
#endif // ENABLE(TEXT_AUTOSIZING)

- (void)_replaceSelectionWithFragment:(DOMDocumentFragment *)fragment selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace matchStyle:(BOOL)matchStyle
{
    if (_private->coreFrame->selection().isNone() || !fragment)
        return;
    _private->coreFrame->editor().replaceSelectionWithFragment(*core(fragment), selectReplacement ? WebCore::Editor::SelectReplacement::Yes : WebCore::Editor::SelectReplacement::No, smartReplace ? WebCore::Editor::SmartReplace::Yes : WebCore::Editor::SmartReplace::No, matchStyle ? WebCore::Editor::MatchStyle::Yes : WebCore::Editor::MatchStyle::No);
}

#if PLATFORM(IOS_FAMILY)
- (void)removeUnchangeableStyles
{
    _private->coreFrame->editor().removeUnchangeableStyles();
}

- (BOOL)hasRichlyEditableSelection
{
    return _private->coreFrame->selection().selection().isContentRichlyEditable();
}
#endif

- (void)_replaceSelectionWithText:(NSString *)text selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
{
    auto range = _private->coreFrame->selection().selection().toNormalizedRange();
    DOMDocumentFragment* fragment = range ? kit(createFragmentFromText(*range, text).ptr()) : nil;
    [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:YES];
}

- (void)_replaceSelectionWithMarkupString:(NSString *)markupString baseURLString:(NSString *)baseURLString selectReplacement:(BOOL)selectReplacement smartReplace:(BOOL)smartReplace
{
    DOMDocumentFragment *fragment = [self _documentFragmentWithMarkupString:markupString baseURLString:baseURLString];
    [self _replaceSelectionWithFragment:fragment selectReplacement:selectReplacement smartReplace:smartReplace matchStyle:NO];
}

#if PLATFORM(MAC)

// Determines whether whitespace needs to be added around aString to preserve proper spacing and
// punctuation when it's inserted into the receiver's text over charRange. Returns by reference
// in beforeString and afterString any whitespace that should be added, unless either or both are
// nil. Both are returned as nil if aString is nil or if smart insertion and deletion are disabled.
- (void)_smartInsertForString:(NSString *)pasteString replacingRange:(DOMRange *)rangeToReplace beforeString:(NSString **)beforeString afterString:(NSString **)afterString
{
    // give back nil pointers in case of early returns
    if (beforeString)
        *beforeString = nil;
    if (afterString)
        *afterString = nil;
        
    auto range = makeSimpleRange(core(rangeToReplace));
    if (!range)
        return;

    auto start = WebCore::VisiblePosition { makeContainerOffsetPosition(range->start) };
    auto end = WebCore::VisiblePosition { makeContainerOffsetPosition(range->end) };

    bool addLeadingSpace = start.deepEquivalent().leadingWhitespacePosition(WebCore::VisiblePosition::defaultAffinity, true).isNull() && !isStartOfParagraph(start);
    if (addLeadingSpace) {
        if (UChar previousCharacter = start.previous().characterAfter())
            addLeadingSpace = !WebCore::isCharacterSmartReplaceExempt(previousCharacter, true);
    }
    
    bool addTrailingSpace = end.deepEquivalent().trailingWhitespacePosition(WebCore::VisiblePosition::defaultAffinity, true).isNull() && !isEndOfParagraph(end);
    if (addTrailingSpace) {
        if (UChar followingCharacter = end.characterAfter())
            addTrailingSpace = !WebCore::isCharacterSmartReplaceExempt(followingCharacter, false);
    }

    // inspect source
    bool hasWhitespaceAtStart = false;
    bool hasWhitespaceAtEnd = false;
    unsigned pasteLength = [pasteString length];
    if (pasteLength > 0) {
        NSCharacterSet *whiteSet = [NSCharacterSet whitespaceAndNewlineCharacterSet];
        
        if ([whiteSet characterIsMember:[pasteString characterAtIndex:0]]) {
            hasWhitespaceAtStart = YES;
        }
        if ([whiteSet characterIsMember:[pasteString characterAtIndex:(pasteLength - 1)]]) {
            hasWhitespaceAtEnd = YES;
        }
    }

    // issue the verdict
    if (beforeString && addLeadingSpace && !hasWhitespaceAtStart)
        *beforeString = @" ";
    if (afterString && addTrailingSpace && !hasWhitespaceAtEnd)
        *afterString = @" ";
}

#endif // PLATFORM(MAC)

- (NSMutableDictionary *)_cacheabilityDictionary
{
    NSMutableDictionary *result = [NSMutableDictionary dictionary];
    
    auto& frameLoader = _private->coreFrame->loader();
    auto* documentLoader = frameLoader.documentLoader();
    if (documentLoader && !documentLoader->mainDocumentError().isNull())
        [result setObject:(NSError *)documentLoader->mainDocumentError() forKey:WebFrameMainDocumentError];
        
    if (frameLoader.subframeLoader().containsPlugins())
        [result setObject:@YES forKey:WebFrameHasPlugins];
    
    if (WebCore::DOMWindow* domWindow = _private->coreFrame->document()->domWindow()) {
        if (domWindow->hasEventListeners(WebCore::eventNames().unloadEvent))
            [result setObject:@YES forKey:WebFrameHasUnloadListener];
        if (domWindow->optionalApplicationCache())
            [result setObject:@YES forKey:WebFrameUsesApplicationCache];
    }
    
    if (auto* document = _private->coreFrame->document()) {
        if (WebCore::DatabaseManager::singleton().hasOpenDatabases(*document))
            [result setObject:@YES forKey:WebFrameUsesDatabases];
    }
    
    return result;
}

- (BOOL)_allowsFollowingLink:(NSURL *)URL
{
    if (!_private->coreFrame)
        return YES;
    return _private->coreFrame->document()->securityOrigin().canDisplay(URL);
}

- (NSString *)_stringByEvaluatingJavaScriptFromString:(NSString *)string withGlobalObject:(JSObjectRef)globalObjectRef inScriptWorld:(WebScriptWorld *)world
{
    if (!string)
        return @"";

    if (!world)
        return @"";

    // Start off with some guess at a frame and a global object, we'll try to do better...!
    auto* anyWorldGlobalObject = _private->coreFrame->script().globalObject(WebCore::mainThreadNormalWorld());

    // The global object is probably a proxy object? - if so, we know how to use this!
    JSC::JSObject* globalObjectObj = toJS(globalObjectRef);
    JSC::VM& vm = globalObjectObj->vm();
    if (!strcmp(globalObjectObj->classInfo(vm)->className, "JSWindowProxy"))
        anyWorldGlobalObject = JSC::jsDynamicCast<WebCore::JSDOMWindow*>(vm, static_cast<WebCore::JSWindowProxy*>(globalObjectObj)->window());

    if (!anyWorldGlobalObject)
        return @"";

    // Get the frame frome the global object we've settled on.
    auto* frame = anyWorldGlobalObject->wrapped().frame();
    ASSERT(frame->document());
    RetainPtr<WebFrame> webFrame(kit(frame)); // Running arbitrary JavaScript can destroy the frame.

    JSC::JSValue result = frame->script().executeUserAgentScriptInWorldIgnoringException(*core(world), string, true);

    if (!webFrame->_private->coreFrame) // In case the script removed our frame from the page.
        return @"";

    // This bizarre set of rules matches behavior from WebKit for Safari 2.0.
    // If you don't like it, use -[WebScriptObject evaluateWebScript:] or 
    // JSEvaluateScript instead, since they have less surprising semantics.
    if (!result || (!result.isBoolean() && !result.isString() && !result.isNumber()))
        return @"";

    JSC::JSGlobalObject* lexicalGlobalObject = anyWorldGlobalObject;
    JSC::JSLockHolder lock(lexicalGlobalObject);
    return result.toWTFString(lexicalGlobalObject);
}

- (JSGlobalContextRef)_globalContextForScriptWorld:(WebScriptWorld *)world
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return 0;
    auto* coreWorld = core(world);
    if (!coreWorld)
        return 0;
    return toGlobalRef(coreFrame->script().globalObject(*coreWorld));
}

#if JSC_OBJC_API_ENABLED
- (JSContext *)_javaScriptContextForScriptWorld:(WebScriptWorld *)world
{
    JSGlobalContextRef globalContextRef = [self _globalContextForScriptWorld:world];
    if (!globalContextRef)
        return 0;
    return [JSContext contextWithJSGlobalContextRef:globalContextRef];
}
#endif

#if !PLATFORM(IOS_FAMILY)
- (void)setAllowsScrollersToOverlapContent:(BOOL)flag
{
    ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
    [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAllowsScrollersToOverlapContent:flag];
}

- (void)setAlwaysHideHorizontalScroller:(BOOL)flag
{
    ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
    [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideHorizontalScroller:flag];
}
- (void)setAlwaysHideVerticalScroller:(BOOL)flag
{
    ASSERT([[[self frameView] _scrollView] isKindOfClass:[WebDynamicScrollBarsView class]]);
    [(WebDynamicScrollBarsView *)[[self frameView] _scrollView] setAlwaysHideVerticalScroller:flag];
}
#endif

- (void)setAccessibleName:(NSString *)name
{
#if ENABLE(ACCESSIBILITY)
    if (!WebCore::AXObjectCache::accessibilityEnabled())
        return;
    
    if (!_private->coreFrame || !_private->coreFrame->document())
        return;
    
    auto* rootObject = _private->coreFrame->document()->axObjectCache()->rootObject();
    if (rootObject) {
        String strName(name);
        rootObject->setAccessibleName(strName);
    }
#endif
}

- (BOOL)enhancedAccessibilityEnabled
{
#if ENABLE(ACCESSIBILITY)
    return WebCore::AXObjectCache::accessibilityEnhancedUserInterfaceEnabled();
#else
    return NO;
#endif
}

- (void)setEnhancedAccessibility:(BOOL)enable
{
#if ENABLE(ACCESSIBILITY)
    WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility(enable);
#endif
}

- (NSString*)_layerTreeAsText
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return @"";

    return coreFrame->contentRenderer()->compositor().layerTreeAsText();
}

- (id)accessibilityRoot
{
#if ENABLE(ACCESSIBILITY)
    if (!WebCore::AXObjectCache::accessibilityEnabled()) {
        WebCore::AXObjectCache::enableAccessibility();
#if !PLATFORM(IOS_FAMILY)
        ALLOW_DEPRECATED_DECLARATIONS_BEGIN
        WebCore::AXObjectCache::setEnhancedUserInterfaceAccessibility([[NSApp accessibilityAttributeValue:NSAccessibilityEnhancedUserInterfaceAttribute] boolValue]);
        ALLOW_DEPRECATED_DECLARATIONS_END
#endif
    }
    
    if (!_private->coreFrame)
        return nil;
    
    auto* document = _private->coreFrame->document();
    if (!document || !document->axObjectCache())
        return nil;
    
    auto* rootObject = document->axObjectCache()->rootObjectForFrame(_private->coreFrame);
    if (!rootObject)
        return nil;
    
    // The root object will be a WebCore scroll view object. In WK1, scroll views are handled
    // by the system and the root object should be the web area (instead of the scroll view).
    if (rootObject->isAttachment() && rootObject->firstChild())
        return rootObject->firstChild()->wrapper();
    
    return rootObject->wrapper();
#else
    return nil;
#endif
}

- (void)_clearOpener
{
    auto coreFrame = _private->coreFrame;
    if (coreFrame)
        coreFrame->loader().setOpener(0);
}

- (BOOL)hasRichlyEditableDragCaret
{
    if (auto* page = core(self)->page())
        return page->dragCaretController().isContentRichlyEditable();
    return NO;
}

// Used by pagination code called from AppKit when a standalone web page is printed.
- (NSArray *)_computePageRectsWithPrintScaleFactor:(float)printScaleFactor pageSize:(NSSize)pageSize
{
    if (printScaleFactor <= 0) {
        LOG_ERROR("printScaleFactor has bad value %.2f", printScaleFactor);
        return @[];
    }

    if (!_private->coreFrame)
        return @[];
    if (!_private->coreFrame->document())
        return @[];
    if (!_private->coreFrame->view())
        return @[];
    if (!_private->coreFrame->view()->documentView())
        return @[];

    auto* root = _private->coreFrame->document()->renderView();
    if (!root)
        return @[];

    const auto& documentRect = root->documentRect();
    float printWidth = root->style().isHorizontalWritingMode() ? static_cast<float>(documentRect.width()) / printScaleFactor : pageSize.width;
    float printHeight = root->style().isHorizontalWritingMode() ? pageSize.height : static_cast<float>(documentRect.height()) / printScaleFactor;

    WebCore::PrintContext printContext(_private->coreFrame);
    printContext.computePageRectsWithPageSize(WebCore::FloatSize(printWidth, printHeight), true);
    return createNSArray(printContext.pageRects()).autorelease();
}

#if PLATFORM(IOS_FAMILY)

- (DOMDocumentFragment *)_documentFragmentForText:(NSString *)text
{
    auto range = _private->coreFrame->selection().selection().toNormalizedRange();
    return range ? kit(createFragmentFromText(*range, text).ptr()) : nil;
}

- (DOMDocumentFragment *)_documentFragmentForWebArchive:(WebArchive *)webArchive
{
    return [[self dataSource] _documentFragmentWithArchive:webArchive];
}

- (DOMDocumentFragment *)_documentFragmentForImageData:(NSData *)data withRelativeURLPart:(NSString *)relativeURLPart andMIMEType:(NSString *)mimeType
{
    auto resource = adoptNS([[WebResource alloc] initWithData:data
        URL:URL::fakeURLWithRelativePart(String { relativeURLPart })
        MIMEType:mimeType textEncodingName:nil frameName:nil]);
    return [[self _dataSource] _documentFragmentWithImageResource:resource.get()];
}

- (BOOL)focusedNodeHasContent
{
    auto coreFrame = _private->coreFrame;
   
    WebCore::Element* root;
    const auto& selection = coreFrame->selection().selection();
    if (selection.isNone() || !selection.isContentEditable())
        root = coreFrame->document()->bodyOrFrameset();
    else {
        // Can't use the focusedNode here because we want the root of the shadow tree for form elements.
        root = selection.rootEditableElement();
    }
    // Early return to avoid the expense of creating VisiblePositions.
    // FIXME: We fail to compute a root for SVG, we have a null check here so that we don't crash.
    if (!root || !root->hasChildNodes())
        return NO;

    WebCore::VisiblePosition first(makeContainerOffsetPosition(root, 0));
    WebCore::VisiblePosition last(makeContainerOffsetPosition(root, root->countChildNodes()));
    return first != last;
}

- (void)_dispatchDidReceiveTitle:(NSString *)title
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return;
    coreFrame->loader().client().dispatchDidReceiveTitle({ title, WebCore::TextDirection::LTR });
}

#endif // PLATFORM(IOS_FAMILY)

- (JSValueRef)jsWrapperForNode:(DOMNode *)node inScriptWorld:(WebScriptWorld *)world
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return 0;

    if (!world)
        return 0;

    WebCore::JSDOMWindow* globalObject = coreFrame->script().globalObject(*core(world));
    JSC::JSGlobalObject* lexicalGlobalObject = globalObject;

    JSC::JSLockHolder lock(lexicalGlobalObject);
    return toRef(lexicalGlobalObject, toJS(lexicalGlobalObject, globalObject, core(node)));
}

- (NSDictionary *)elementAtPoint:(NSPoint)point
{
    using namespace WebCore;

    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    constexpr OptionSet<HitTestRequest::Type> hitType { HitTestRequest::Type::ReadOnly, HitTestRequest::Type::Active, HitTestRequest::Type::IgnoreClipping, HitTestRequest::Type::DisallowUserAgentShadowContent, HitTestRequest::Type::AllowChildFrameContent };
    return adoptNS([[WebElementDictionary alloc] initWithHitTestResult:coreFrame->eventHandler().hitTestResultAtPoint(WebCore::IntPoint(point), hitType)]).autorelease();
}

- (NSURL *)_unreachableURL
{
    return [[self _dataSource] unreachableURL];
}

@end

@implementation WebFrame

- (instancetype)init
{
    return nil;
}

// Should be deprecated.
- (instancetype)initWithName:(NSString *)name webFrameView:(WebFrameView *)view webView:(WebView *)webView
{
    return nil;
}

- (void)dealloc
{
    if (_private && _private->includedInWebKitStatistics)
        --WebFrameCount;

    [_private release];

    [super dealloc];
}

- (NSString *)name
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    return coreFrame->tree().uniqueName();
}

- (WebFrameView *)frameView
{
    return _private->webFrameView.get();
}

- (WebView *)webView
{
    return getWebView(self);
}

static bool needsMicrosoftMessengerDOMDocumentWorkaround()
{
#if PLATFORM(IOS_FAMILY)
    return false;
#else
    static bool needsWorkaround = WebCore::MacApplication::isMicrosoftMessenger() && [[[NSBundle mainBundle] objectForInfoDictionaryKey:(NSString *)kCFBundleVersionKey] compare:@"7.1" options:NSNumericSearch] == NSOrderedAscending;
    return needsWorkaround;
#endif
}

- (DOMDocument *)DOMDocument
{
    if (needsMicrosoftMessengerDOMDocumentWorkaround() && !pthread_main_np())
        return nil;

    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    
    // FIXME: <rdar://problem/5145841> When loading a custom view/representation 
    // into a web frame, the old document can still be around. This makes sure that
    // we'll return nil in those cases.
    if (![[self _dataSource] _isDocumentHTML]) 
        return nil; 

    auto* document = coreFrame->document();
    
    // According to the documentation, we should return nil if the frame doesn't have a document.
    // While full-frame images and plugins do have an underlying HTML document, we return nil here to be
    // backwards compatible.
    if (document && (document->isPluginDocument() || document->isImageDocument()))
        return nil;
    
    return kit(coreFrame->document());
}

- (DOMHTMLElement *)frameElement
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    return kit(coreFrame->ownerElement());
}

- (WebDataSource *)provisionalDataSource
{
    auto coreFrame = _private->coreFrame;
    return coreFrame ? dataSource(coreFrame->loader().provisionalDocumentLoader()) : nil;
}

- (WebDataSource *)dataSource
{
    auto coreFrame = _private->coreFrame;
    return coreFrame && coreFrame->loader().frameHasLoaded() ? [self _dataSource] : nil;
}

- (void)loadRequest:(NSURLRequest *)request
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return;

    WebCore::ResourceRequest resourceRequest(request);
    
    // Some users of WebKit API incorrectly use "file path as URL" style requests which are invalid.
    // By re-writing those URLs here we technically break the -[WebDataSource initialRequest] API
    // but that is necessary to implement this quirk only at the API boundary.
    // Note that other users of WebKit API use nil requests or requests with nil URLs or empty URLs, so we
    // only implement this workaround when the request had a non-nil or non-empty URL.
    if (!resourceRequest.url().isValid() && !resourceRequest.url().isEmpty())
        resourceRequest.setURL([NSURL URLWithString:[@"file:" stringByAppendingString:[[request URL] absoluteString]]]);

    coreFrame->loader().load(WebCore::FrameLoadRequest(*coreFrame, resourceRequest));
}

static NSURL *createUniqueWebDataURL()
{
    auto UUIDRef = adoptCF(CFUUIDCreate(kCFAllocatorDefault));
    auto UUIDString = adoptCF(CFUUIDCreateString(kCFAllocatorDefault, UUIDRef.get()));
    return [NSURL URLWithString:[NSString stringWithFormat:@"applewebdata://%@", (__bridge NSString *)UUIDString.get()]];
}

- (void)_loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL
{
#if PLATFORM(MAC)
    if (!pthread_main_np())
        return [[self _webkit_invokeOnMainThread] _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:baseURL unreachableURL:unreachableURL];
#endif

    NSURL *responseURL = nil;
    if (baseURL)
        baseURL = [baseURL absoluteURL];
    else {
        baseURL = aboutBlankURL();
        responseURL = createUniqueWebDataURL();
    }
    
#if USE(QUICK_LOOK)
    if (WebCore::shouldUseQuickLookForMIMEType(MIMEType)) {
        NSURL *quickLookURL = responseURL ? responseURL : baseURL;
        if (auto request = WebCore::registerQLPreviewConverterIfNeeded(quickLookURL, MIMEType, data)) {
            _private->coreFrame->loader().load(WebCore::FrameLoadRequest(*_private->coreFrame, request.get()));
            return;
        }
    }
#endif

    WebCore::ResourceRequest request(baseURL);

    WebCore::ResourceResponse response(responseURL, MIMEType, [data length], encodingName);
    WebCore::SubstituteData substituteData(WebCore::SharedBuffer::create(data), [unreachableURL absoluteURL], response, WebCore::SubstituteData::SessionHistoryVisibility::Hidden);

    _private->coreFrame->loader().load(WebCore::FrameLoadRequest(*_private->coreFrame, request, substituteData));
}

- (void)loadData:(NSData *)data MIMEType:(NSString *)MIMEType textEncodingName:(NSString *)encodingName baseURL:(NSURL *)baseURL
{
    WebCoreThreadViolationCheckRoundTwo();
    
    if (!MIMEType)
        MIMEType = @"text/html";
    [self _loadData:data MIMEType:MIMEType textEncodingName:encodingName baseURL:[baseURL _webkit_URLFromURLOrSchemelessFileURL] unreachableURL:nil];
}

- (void)_loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL unreachableURL:(NSURL *)unreachableURL
{
    NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding];
    [self _loadData:data MIMEType:@"text/html" textEncodingName:@"UTF-8" baseURL:baseURL unreachableURL:unreachableURL];
}

- (void)loadHTMLString:(NSString *)string baseURL:(NSURL *)baseURL
{
    WebCoreThreadViolationCheckRoundTwo();

    [self _loadHTMLString:string baseURL:[baseURL _webkit_URLFromURLOrSchemelessFileURL] unreachableURL:nil];
}

- (void)loadAlternateHTMLString:(NSString *)string baseURL:(NSURL *)baseURL forUnreachableURL:(NSURL *)unreachableURL
{
    WebCoreThreadViolationCheckRoundTwo();

    [self _loadHTMLString:string baseURL:[baseURL _webkit_URLFromURLOrSchemelessFileURL] unreachableURL:[unreachableURL _webkit_URLFromURLOrSchemelessFileURL]];
}

- (void)loadArchive:(WebArchive *)archive
{
    if (auto* coreArchive = [archive _coreLegacyWebArchive])
        _private->coreFrame->loader().loadArchive(*coreArchive);
}

- (void)stopLoading
{
    if (!_private->coreFrame)
        return;
    _private->coreFrame->loader().stopForUserCancel();
}

- (void)reload
{
    _private->coreFrame->loader().reload({ });
}

- (void)reloadFromOrigin
{
    _private->coreFrame->loader().reload(WebCore::ReloadOption::FromOrigin);
}

- (WebFrame *)findFrameNamed:(NSString *)name
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    return kit(coreFrame->tree().find(name, *coreFrame));
}

- (WebFrame *)parentFrame
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return nil;
    return retainPtr(kit(coreFrame->tree().parent())).autorelease();
}

- (NSArray *)childFrames
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return @[];
    NSMutableArray *children = [NSMutableArray arrayWithCapacity:coreFrame->tree().childCount()];
    for (WebCore::Frame* child = coreFrame->tree().firstChild(); child; child = child->tree().nextSibling())
        [children addObject:kit(child)];
    return children;
}

- (WebScriptObject *)windowObject
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return 0;
    return coreFrame->script().windowScriptObject();
}

- (JSGlobalContextRef)globalContext
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return 0;
    return toGlobalRef(coreFrame->script().globalObject(WebCore::mainThreadNormalWorld()));
}

#if JSC_OBJC_API_ENABLED
- (JSContext *)javaScriptContext
{
    auto coreFrame = _private->coreFrame;
    if (!coreFrame)
        return 0;
    return coreFrame->script().javaScriptContext();
}
#endif

@end
