1/*
2 * Copyright (C) 2015 Apple Inc. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27
28#if WK_HAVE_C_SPI
29
30#include "PlatformUtilities.h"
31#include "PlatformWebView.h"
32#include "Test.h"
33#include <wtf/StdLibExtras.h>
34
35namespace TestWebKitAPI {
36
37struct WebKit2TextFieldBeginAndEditEditingTest : public ::testing::Test {
38 std::unique_ptr<PlatformWebView> webView;
39
40 WKRetainPtr<WKStringRef> messageName;
41
42 bool didFinishLoad { false };
43 bool didReceiveMessage { false };
44
45 static void didReceiveMessageFromInjectedBundle(WKContextRef, WKStringRef messageName, WKTypeRef, const void* clientInfo)
46 {
47 WebKit2TextFieldBeginAndEditEditingTest& client = *static_cast<WebKit2TextFieldBeginAndEditEditingTest*>(const_cast<void*>(clientInfo));
48 client.messageName = messageName;
49 client.didReceiveMessage = true;
50 }
51
52 static void didFinishNavigation(WKPageRef, WKNavigationRef, WKTypeRef, const void* clientInfo)
53 {
54 WebKit2TextFieldBeginAndEditEditingTest& client = *static_cast<WebKit2TextFieldBeginAndEditEditingTest*>(const_cast<void*>(clientInfo));
55 client.didFinishLoad = true;
56 }
57
58 static void setInjectedBundleClient(WKContextRef context, const void* clientInfo)
59 {
60 WKContextInjectedBundleClientV1 injectedBundleClient;
61 memset(&injectedBundleClient, 0, sizeof(injectedBundleClient));
62
63 injectedBundleClient.base.version = 1;
64 injectedBundleClient.base.clientInfo = clientInfo;
65 injectedBundleClient.didReceiveMessageFromInjectedBundle = didReceiveMessageFromInjectedBundle;
66
67 WKContextSetInjectedBundleClient(context, &injectedBundleClient.base);
68 }
69
70 static void setPageLoaderClient(WKPageRef page, const void* clientInfo)
71 {
72 WKPageNavigationClientV0 loaderClient;
73 memset(&loaderClient, 0, sizeof(loaderClient));
74
75 loaderClient.base.version = 0;
76 loaderClient.base.clientInfo = clientInfo;
77 loaderClient.didFinishNavigation = didFinishNavigation;
78
79 WKPageSetPageNavigationClient(page, &loaderClient.base);
80 }
81
82 static void nullJavaScriptCallback(WKSerializedScriptValueRef, WKErrorRef, void*)
83 {
84 }
85
86 void executeJavaScriptAndCheckDidReceiveMessage(const char* javaScriptCode, const char* expectedMessageName)
87 {
88 didReceiveMessage = false;
89 WKPageRunJavaScriptInMainFrame(webView->page(), Util::toWK(javaScriptCode).get(), 0, nullJavaScriptCallback);
90 Util::run(&didReceiveMessage);
91 EXPECT_WK_STREQ(expectedMessageName, messageName);
92 }
93
94 // From ::testing::Test
95 void SetUp() override
96 {
97 WKRetainPtr<WKContextRef> context = adoptWK(Util::createContextForInjectedBundleTest("TextFieldDidBeginAndEndEditingEventsTest"));
98 setInjectedBundleClient(context.get(), this);
99
100 webView = std::make_unique<PlatformWebView>(context.get());
101 setPageLoaderClient(webView->page(), this);
102
103 didFinishLoad = false;
104 didReceiveMessage = false;
105
106 WKPageLoadURL(webView->page(), adoptWK(Util::createURLForResource("input-focus-blur", "html")).get());
107 Util::run(&didFinishLoad);
108 }
109};
110
111TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginAndEndEditingEvents)
112{
113 executeJavaScriptAndCheckDidReceiveMessage("focusTextField('input')", "DidReceiveTextFieldDidBeginEditing");
114 executeJavaScriptAndCheckDidReceiveMessage("blurTextField('input')", "DidReceiveTextFieldDidEndEditing");
115}
116
117TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginAndEndEditingEventsInReadOnlyField)
118{
119 executeJavaScriptAndCheckDidReceiveMessage("focusTextField('readonly')", "DidReceiveTextFieldDidBeginEditing");
120 executeJavaScriptAndCheckDidReceiveMessage("blurTextField('readonly')", "DidReceiveTextFieldDidEndEditing");
121}
122
123TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidBeginShouldNotBeDispatchedForAlreadyFocusedField)
124{
125 executeJavaScriptAndCheckDidReceiveMessage("focusTextField('input'); focusTextField('input')", "DidReceiveTextFieldDidBeginEditing");
126 executeJavaScriptAndCheckDidReceiveMessage("blurTextField('input')", "DidReceiveTextFieldDidEndEditing");
127}
128
129TEST_F(WebKit2TextFieldBeginAndEditEditingTest, TextFieldDidEndShouldBeDispatchedForRemovedFocusField)
130{
131 executeJavaScriptAndCheckDidReceiveMessage("focusTextField('input')", "DidReceiveTextFieldDidBeginEditing");
132 executeJavaScriptAndCheckDidReceiveMessage("removeTextField('input')", "DidReceiveTextFieldDidEndEditing");
133}
134
135} // namespace TestWebKitAPI
136
137#endif
138