/*
 * Copyright (C) 2019-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.
 *
 * THIS SOFTWARE IS PROVIDED BY APPLE INC. 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 INC. 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 "config.h"

#if PLATFORM(IOS_FAMILY)

#import "PlatformUtilities.h"
#import "TestCocoa.h"
#import "TestInputDelegate.h"
#import "TestNavigationDelegate.h"
#import "TestWKWebView.h"
#import "UserInterfaceSwizzler.h"
#import <WebKit/WKPreferencesRefPrivate.h>
#import <WebKit/WKWebViewConfigurationPrivate.h>
#import <WebKit/WKWebViewPrivateForTesting.h>
#import <WebKit/_WKTextInputContext.h>
#import <wtf/RetainPtr.h>

namespace TestWebKitAPI {

class TextInteractionForScope {
public:
    TextInteractionForScope(const RetainPtr<TestWKWebView>& webView, const RetainPtr<_WKTextInputContext>& textInputContext)
        : m_webView { webView }
        , m_textInputContext { textInputContext }
    {
        [m_webView _willBeginTextInteractionInTextInputContext:m_textInputContext.get()];
    }

    ~TextInteractionForScope()
    {
        [m_webView _didFinishTextInteractionInTextInputContext:m_textInputContext.get()];
        [m_webView waitForNextPresentationUpdate];
    }

private:
    RetainPtr<TestWKWebView> m_webView;
    RetainPtr<_WKTextInputContext> m_textInputContext;
};

} // namespace TestWebKitAPI

static bool didScroll;

@interface TextInteractionScrollDelegate : NSObject <UIScrollViewDelegate>
@end

// Ideally this would ensure that the focused element is actually in view.
// For the purposes of the tests in this file it is enough to know whether
// a scroll occurred.
@implementation TextInteractionScrollDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    didScroll = true;
}

@end

@implementation TestWKWebView (SynchronousTextInputContext)

- (NSArray<_WKTextInputContext *> *)synchronouslyRequestTextInputContextsInRect:(CGRect)rect
{
    __block bool finished = false;
    __block RetainPtr<NSArray<_WKTextInputContext *>> result;
    [self _requestTextInputContextsInRect:rect completionHandler:^(NSArray<_WKTextInputContext *> *contexts) {
        result = contexts;
        finished = true;
    }];
    TestWebKitAPI::Util::run(&finished);
    return result.autorelease();
}

- (UIResponder<UITextInput> *)synchronouslyFocusTextInputContext:(_WKTextInputContext *)context placeCaretAt:(CGPoint)point
{
    __block bool finished = false;
    __block UIResponder<UITextInput> *responder = nil;
    [self _focusTextInputContext:context placeCaretAt:point completionHandler:^(UIResponder<UITextInput> *textInputResponder) {
        responder = textInputResponder;
        finished = true;
    }];
    TestWebKitAPI::Util::run(&finished);
    return responder;
}

@end

namespace TestWebKitAPI {

static NSString *applyStyle(NSString *HTMLString)
{
    return [@"<style>body { margin: 0; } iframe { border: none; }</style><meta name='viewport' content='initial-scale=1'>" stringByAppendingString:HTMLString];
}

static NSString *applyIframe(NSString *HTMLString)
{
    return applyStyle([NSString stringWithFormat:@"<iframe src=\"data:text/html,%@\" style='position: absolute; top: 200px;'>", [applyStyle(HTMLString) stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]);
}

TEST(RequestTextInputContext, Simple)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    // Basic inputs.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<textarea style='width: 100px; height: 100px;'></textarea>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<div contenteditable style='width: 100px; height: 100px;'></div>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);

    // Read only inputs; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;' readonly>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<textarea style='width: 100px; height: 100px;' readonly>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs outside the requested rect; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(100, 100, 100, 100)];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs scrolled outside the requested rect; should not be included.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'><br><div style='width: 100px; height: 10000px;'></div>")];
    [webView stringByEvaluatingJavaScript:@"window.scrollTo(0, 5000)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(5000, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(0UL, contexts.count);

    // Inputs scrolled into the requested rect.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px; position: absolute; top: 5000px;'><br><div style='width: 100px; height: 10000px;'></div>")];
    [webView stringByEvaluatingJavaScript:@"window.scrollTo(0, 5000)"];
    [webView waitForNextPresentationUpdate];
    EXPECT_EQ(5000, [[webView objectByEvaluatingJavaScript:@"pageYOffset"] floatValue]);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);

    // Multiple inputs.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'><br/><input type='text' style='width: 50px; height: 50px;'><br/><input type='text' style='width: 50px; height: 50px;'>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(3UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 100, 50, 50), contexts[0].boundingRect);
    EXPECT_EQ(CGRectMake(0, 50, 50, 50), contexts[1].boundingRect);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[2].boundingRect);

    // Nested <input>-inside-contenteditable.

    [webView synchronouslyLoadHTMLString:applyStyle(@"<div contenteditable style='width: 100px; height: 100px;'><input type='text' style='width: 50px; height: 50px;'></div>")];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(2UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 50, 50), contexts[0].boundingRect);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[1].boundingRect);
}

// Consider moving this to TestWKWebView if it could be useful to other tests.
static void webViewLoadHTMLStringAndWaitForAllFramesToPaint(TestWKWebView *webView, NSString *htmlString)
{
    ASSERT(webView); // Make passing a nil web view a more obvious failure than a hang.
    bool didFireDOMLoadEvent = false;
    [webView performAfterLoading:[&] { didFireDOMLoadEvent = true; }];
    [webView loadHTMLString:htmlString baseURL:[NSBundle.mainBundle.bundleURL URLByAppendingPathComponent:@"TestWebKitAPI.resources"]];
    TestWebKitAPI::Util::run(&didFireDOMLoadEvent);
    [webView waitForNextPresentationUpdate];
}

TEST(RequestTextInputContext, Iframe)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<input type='text' style='width: 50px; height: 50px;'>"));
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 50, 50), contexts[0].boundingRect);

    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<textarea style='width: 100px; height: 100px;'></textarea>"));
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);

    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<div contenteditable style='width: 100px; height: 100px;'></div>"));
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 200, 100, 100), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, ViewIsEditable)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body></body>")];
    [webView _setEditable:YES];
    EXPECT_GE([webView synchronouslyRequestTextInputContextsInRect:[webView bounds]].count, 1UL);
}

static CGRect squareCenteredAtPoint(float x, float y, float length)
{
    return CGRectMake(x - length / 2, y - length / 2, length, length);
}

TEST(RequestTextInputContext, NonCompositedOverlap)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    [webView synchronouslyLoadTestPageNamed:@"editable-region-composited-and-non-composited-overlap"];

    // Search rect fully contained in non-composited <div>.
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(270, 150, 10, 10)];
    EXPECT_EQ(0UL, contexts.count);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(170, 150, 10, 10)];
    EXPECT_EQ(0UL, contexts.count);

    // Search rect overlaps both the non-composited <div> and the editable element.
    contexts = [webView synchronouslyRequestTextInputContextsInRect:squareCenteredAtPoint(270, 150, 200)];
    EXPECT_EQ(1UL, contexts.count);
}

TEST(RequestTextInputContext, CompositedOverlap)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    NSArray<_WKTextInputContext *> *contexts;

    [webView synchronouslyLoadTestPageNamed:@"editable-region-composited-and-non-composited-overlap"];

    // Search rect fully contained in composited <div>.
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(270, 400, 10, 10)];
    EXPECT_EQ(0UL, contexts.count);
    contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(170, 400, 10, 10)];
    EXPECT_EQ(0UL, contexts.count);

    // Search rect overlaps both the composited <div> and the editable element.
    contexts = [webView synchronouslyRequestTextInputContextsInRect:squareCenteredAtPoint(270, 400, 200)];
    EXPECT_EQ(1UL, contexts.count);
}

TEST(RequestTextInputContext, RectContainsEditableNonRootChild)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue'>Hello World</div></body>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 500, 500), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, RectContainsNestedEditableNonRootChild)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue'><div style='width: 100px; height: 100px; background-color: yellow' contenteditable='true'>Hello World</div></div></body>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 500, 500), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, RectContainsInnerEditableNonRootChild)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body contenteditable='true' style='width: 500px; height: 500px'><div style='width: 200px; height: 200px; background-color: blue' contenteditable='false'><div style='width: 100px; height: 100px; background-color: yellow' contenteditable='true'>Hello World</div></div><p>Body</p></body>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:CGRectMake(10, 10, 20, 20)];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 100, 100), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, ReadOnlyField)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' value='hello world' style='width: 100px; height: 50px;' readonly>")];
    EXPECT_EQ(0UL, [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]].count);
}

TEST(RequestTextInputContext, DisabledField)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' value='hello world' style='width: 100px; height: 50px;' disabled>")];
    EXPECT_EQ(0UL, [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]].count);
}

TEST(RequestTextInputContext, FocusedEditableEmptyLine)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView _setInputDelegate:inputDelegate.get()];

    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyStyle(@"<span id='span' contenteditable='true'></span>"));
    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"span.focus()"];
    EXPECT_WK_STREQ("SPAN", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 0, 0), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, FocusedEditableLineWithOnlyLineBreak)
{
    RetainPtr<WKWebViewConfiguration> configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    RetainPtr<TestWKWebView> webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView _setInputDelegate:inputDelegate.get()];

    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyStyle(@"<span id='span' contenteditable='true'><br></span>"));
    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"span.focus()"];
    EXPECT_WK_STREQ("SPAN", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    EXPECT_EQ(CGRectMake(0, 0, 0, 19), contexts[0].boundingRect);
}

TEST(RequestTextInputContext, FocusAfterNavigation)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    // 1. Load initial page and save off the text input context for the input element on it.
    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' value='hello world' style='width: 100px; height: 50px;'>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    // 2. Load a new page.
    [webView synchronouslyLoadHTMLString:@"<body></body>"];

    // 3. Focus the input element in the old page.
    EXPECT_NULL([webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
}

TEST(RequestTextInputContext, CaretShouldNotMoveInAlreadyFocusedField)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    constexpr char exampleText[] = "hello world";
    constexpr size_t exampleTextLength = sizeof(exampleText) - 1;
    [webView synchronouslyLoadHTMLString:applyStyle([NSString stringWithFormat:@"<input type='text' value='%s' style='width: 100px; height: 50px;'>", exampleText])];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    // Place the caret the end of the field; should succeed becausse field is not already focused.
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];
    CGRect boundingRect = [inputElement boundingRect];
    CGPoint endPosition = CGPointMake(boundingRect.origin.x + boundingRect.size.width, boundingRect.origin.y + boundingRect.size.height / 2);
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:endPosition]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);

    // Try to place the caret at the start of the field; should fail since field is already focused.
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:boundingRect.origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, CaretShouldNotMoveInAlreadyFocusedField2)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView _setInputDelegate:inputDelegate.get()];

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' id='input' value='hello world' style='width: 100px; height: 50px;'>")];

    // Use JavaScript to place the caret after the 'h' in the field.
    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"input.focus()"];
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    [webView stringByEvaluatingJavaScript:@"input.setSelectionRange(1, 1)"];
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);

    // Use -focusTextInputContext: to place the caret at the beginning of the field; no change because the field is already focused.
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, PlaceCaretInNonAssistedFocusedField)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [webView _setInputDelegate:inputDelegate.get()];

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' id='input' value='hello world' style='width: 100px; height: 50px;'>")];

    // Use JavaScript to place the caret after the 'h' in the field.
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyDisallow; }];
    [webView stringByEvaluatingJavaScript:@"input.focus()"];
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    [webView stringByEvaluatingJavaScript:@"input.setSelectionRange(1, 1)"];
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(1, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);

    // Use -focusTextInputContext: to place the caret at the beginning of the field; the caret should move.
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, FocusTextFieldThenProgrammaticallyReplaceWithTextAreaAndFocusTextArea)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' style='width: 50px; height: 50px;'>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);

    RetainPtr<_WKTextInputContext> originalInput = contexts[0];
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:originalInput.get() placeCaretAt:[originalInput boundingRect].origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    // Replace the <input> with a <textarea> with script; the <input> should no longer be focusable.
    [webView objectByEvaluatingJavaScript:@"document.body.innerHTML = '<textarea>'"];
    contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> textArea = contexts[0];
    EXPECT_NULL([webView synchronouslyFocusTextInputContext:originalInput.get() placeCaretAt:[originalInput boundingRect].origin]);
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:textArea.get() placeCaretAt:[textArea boundingRect].origin]);
    EXPECT_WK_STREQ("TEXTAREA", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
}

TEST(RequestTextInputContext, FocusFieldAndPlaceCaretAtStart)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    [webView synchronouslyLoadHTMLString:applyStyle(@"<input type='text' value='hello world' style='width: 100px; height: 50px;'>")];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, FocusFieldAndPlaceCaretAtEnd)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    constexpr char exampleText[] = "hello world";
    constexpr size_t exampleTextLength = sizeof(exampleText) - 1;
    [webView synchronouslyLoadHTMLString:applyStyle([NSString stringWithFormat:@"<input type='text' value='%s' style='width: 100px; height: 50px;'>", exampleText])];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    CGRect boundingRect = [inputElement boundingRect];
    CGPoint endPosition = CGPointMake(boundingRect.origin.x + boundingRect.size.width, boundingRect.origin.y + boundingRect.size.height / 2);
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:endPosition]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, FocusFieldWithPaddingAndPlaceCaretAtEnd)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    constexpr char exampleText[] = "hello world";
    constexpr size_t exampleTextLength = sizeof(exampleText) - 1;
    [webView synchronouslyLoadHTMLString:applyStyle([NSString stringWithFormat:@"<input type='text' value='%s' style='width: 100px; height: 50px; padding: 20px'>", exampleText])];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    CGRect boundingRect = [inputElement boundingRect];
    CGPoint endPosition = CGPointMake(boundingRect.origin.x + boundingRect.size.width, boundingRect.origin.y);
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:endPosition]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, FocusFieldAndPlaceCaretOutsideField)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    constexpr char exampleText[] = "hello world";
    constexpr size_t exampleTextLength = sizeof(exampleText) - 1;
    [webView synchronouslyLoadHTMLString:applyStyle([NSString stringWithFormat:@"<input type='text' value='%s' style='width: 100px; height: 50px;'>", exampleText])];
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    auto resetTest = [&] {
        [webView stringByEvaluatingJavaScript:@"document.activeElement.blur()"];
        EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    };

    // Point before the field
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:CGPointMake(-1000, -500)]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
    resetTest();

    // Point after the field
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:CGPointMake(1000, 500)]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(static_cast<int>(exampleTextLength), [[webView objectByEvaluatingJavaScript:@"document.activeElement.selectionEnd"] intValue]);
    resetTest();
}

TEST(RequestTextInputContext, FocusFieldInFrame)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAllowUniversalAccessFromFileURLs:YES];
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    auto testPage = applyStyle([NSString stringWithFormat:@"<input type='text' value='mainFrameField' style='width: 100px; height: 50px;'>%@", applyIframe(@"<input type='text' value='iframeField' style='width: 120px; height: 70px;'>")]);
    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), testPage);
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(2UL, contexts.count);
    RetainPtr<_WKTextInputContext> frameBField = contexts[0];

    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:frameBField.get() placeCaretAt:[frameBField boundingRect].origin]);
    EXPECT_WK_STREQ("IFRAME", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.tagName"]);
    EXPECT_WK_STREQ("iframeField", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.value"]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.selectionStart"] intValue]);
    EXPECT_EQ(0, [[webView objectByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.selectionEnd"] intValue]);
}

TEST(RequestTextInputContext, SwitchFocusBetweenFrames)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAllowUniversalAccessFromFileURLs:YES];
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);

    auto testPage = applyStyle([NSString stringWithFormat:@"<input type='text' value='mainFrameField' style='width: 100px; height: 50px;'>%@", applyIframe(@"<input type='text' value='iframeField' style='width: 100px; height: 50px;'>")]);
    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), testPage);
    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(2UL, contexts.count);
    // Note that returned contexts are in hit-test order.
    RetainPtr<_WKTextInputContext> frameAField = contexts[1];
    RetainPtr<_WKTextInputContext> frameBField = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.tagName"]);
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:frameAField.get() placeCaretAt:[frameAField boundingRect].origin]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_WK_STREQ("mainFrameField", [webView stringByEvaluatingJavaScript:@"document.activeElement.value"]);
    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.tagName"]);

    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:frameBField.get() placeCaretAt:[frameBField boundingRect].origin]);
    EXPECT_WK_STREQ("IFRAME", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.tagName"]);
    EXPECT_WK_STREQ("iframeField", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.value"]);
}

TEST(RequestTextInputContext, FocusingAssistedElementShouldNotScrollPage)
{
    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView _setInputDelegate:inputDelegate.get()];
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><div id='editable' style='position: fixed; width: 100%; height: 50px; background-color: blue' contenteditable='true'></div></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);

    // Focus the field using JavaScript and scroll the page.
    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"editable.focus()"];
    EXPECT_WK_STREQ("DIV", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    [webView stringByEvaluatingJavaScript:@"window.scrollTo(0, 2000)"];
    EXPECT_EQ(2000, [[webView objectByEvaluatingJavaScript:@"window.scrollY"] intValue]);

    // Focus the field using -focusTextInputContext; page should not scroll.
    RetainPtr<_WKTextInputContext> editableElement = contexts[0];
    EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:editableElement.get() placeCaretAt:[editableElement boundingRect].origin]);
    EXPECT_WK_STREQ("DIV", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_EQ(2000, [[webView objectByEvaluatingJavaScript:@"window.scrollY"] intValue]);
}

TEST(RequestTextInputContext, TextInteraction_FocusingReadOnlyElementShouldScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    [webView stringByEvaluatingJavaScript:@"input.readOnly = true"];

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Focus the field using -focusTextInputContext; scroll view should scroll to reveal the focused element.
    {
        TextInteractionForScope scope { webView, inputElement };
        EXPECT_NULL([webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_FALSE(didScroll);
    }

    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_TRUE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusElementInDetachedDocument)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    [configuration _setAllowUniversalAccessFromFileURLs:YES];
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    webViewLoadHTMLStringAndWaitForAllFramesToPaint(webView.get(), applyIframe(@"<input type='text' id='input' style='width: 100px; height: 50px;'>"));

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.querySelector('iframe').contentDocument.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Save a reference to the framed document (to prevent its destruction when its frame is removed)
    // and remove the frame.
    [webView stringByEvaluatingJavaScript:@"g_framedDocument = document.querySelector('iframe').contentDocument; document.querySelector('iframe').remove()"];
    {
        TextInteractionForScope scope { webView, inputElement };
        EXPECT_NULL([webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
    }

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"g_framedDocument.activeElement.tagName"]);
    EXPECT_FALSE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusingElementShouldScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Scroll view should scroll to reveal the focused element.
    {
        TextInteractionForScope scope { webView, inputElement };
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_FALSE(didScroll);
    }

    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_TRUE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusingElementMultipleTimesShouldScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Scroll view should scroll to reveal the focused element.
    {
        TextInteractionForScope scope { webView, inputElement };
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_FALSE(didScroll);
    }

    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_TRUE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusDefocusDisableFocusAgainShouldNotScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    {
        TextInteractionForScope scope { webView, inputElement };
        // 1. Focus
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

        // 2. Defocus
        [webView stringByEvaluatingJavaScript:@"input.blur()"];
        EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

        // 3. Disable
        [webView stringByEvaluatingJavaScript:@"input.disabled = true"];

        // 4. Focus again; focused element should be unchanged and scroll view should not scroll.
        EXPECT_NULL([webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    }

    EXPECT_FALSE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusDefocusFocusAgainShouldScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    {
        TextInteractionForScope scope { webView, inputElement };
        // 1. Focus
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

        // 2. Defocus
        [webView stringByEvaluatingJavaScript:@"input.blur()"];
        EXPECT_WK_STREQ("BODY", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

        // 3. Focus again; focused element should change and scroll view should scroll to reveal focused element.
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
        EXPECT_FALSE(didScroll);
    }

    EXPECT_TRUE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusingAssistedElementShouldNotScrollToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView _setInputDelegate:inputDelegate.get()];
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"input.focus()"];
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Focus the field using -focusTextInputContext; scroll view should not scroll to reveal focused element.
    {
        TextInteractionForScope scope { webView, inputElement };
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
    }

    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_FALSE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_FocusingNonAssistedFocusedElementScrollsToReveal)
{
    IPhoneUserInterfaceSwizzler userInterfaceSwizzler;

    auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]);
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [webView _setInputDelegate:inputDelegate.get()];
    [webView synchronouslyLoadHTMLString:applyStyle(@"<body style='height: 4096px'><input id='input'></body>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyDisallow; }];
    [webView stringByEvaluatingJavaScript:@"input.focus()"]; // Will not start input assistance
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    didScroll = false;
    auto scrollDelegate = adoptNS([[TextInteractionScrollDelegate alloc] init]);
    [webView scrollView].delegate = scrollDelegate.get();

    // Focus the field using -focusTextInputContext; scroll view should scroll to reveal the focused element.
    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    {
        TextInteractionForScope scope { webView, inputElement };
        // Will start input assistance
        EXPECT_EQ((UIResponder<UITextInput> *)[webView textInputContentView], [webView synchronouslyFocusTextInputContext:inputElement.get() placeCaretAt:[inputElement boundingRect].origin]);
        EXPECT_FALSE(didScroll);
    }

    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);
    EXPECT_TRUE(didScroll);
}

TEST(RequestTextInputContext, TextInteraction_HighlightSelectedText)
{
    auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600)]);
    auto inputDelegate = adoptNS([[TestInputDelegate alloc] init]);
    [webView _setInputDelegate:inputDelegate.get()];
    [webView synchronouslyLoadHTMLString:applyStyle(@"<input id='input' value='hello'>")];

    NSArray<_WKTextInputContext *> *contexts = [webView synchronouslyRequestTextInputContextsInRect:[webView bounds]];
    EXPECT_EQ(1UL, contexts.count);
    RetainPtr<_WKTextInputContext> inputElement = contexts[0];

    [inputDelegate setFocusStartsInputSessionPolicyHandler:[] (WKWebView *, id <_WKFocusedElementInfo>) { return _WKFocusStartsInputSessionPolicyAllow; }];
    [webView evaluateJavaScriptAndWaitForInputSessionToChange:@"input.focus()"];
    [webView stringByEvaluatingJavaScript:@"input.setSelectionRange(0, 5)"];
    EXPECT_WK_STREQ("INPUT", [webView stringByEvaluatingJavaScript:@"document.activeElement.tagName"]);

    {
        TextInteractionForScope scope { webView, inputElement };
        [webView waitForNextPresentationUpdate];
        EXPECT_EQ(1UL, [[webView selectionViewRectsInContentCoordinates] count]);
    }
}

} // namespace TestWebKitAPI

#endif // PLATFORM(IOS_FAMILY)
