| /* |
| * Copyright (C) 2017 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. |
| */ |
| |
| #include "config.h" |
| |
| #import "PlatformUtilities.h" |
| #import "Test.h" |
| #import "TestWKWebView.h" |
| #import <WebKit/WKWebViewPrivate.h> |
| #import <WebKit/_WKFocusedElementInfo.h> |
| #import <WebKit/_WKFormInputSession.h> |
| #import <WebKit/_WKInputDelegate.h> |
| #import <wtf/BlockPtr.h> |
| #import <wtf/RetainPtr.h> |
| |
| static bool done; |
| static bool willSubmitFormValuesCalled; |
| |
| @interface InputDelegate : NSObject <_WKInputDelegate, WKURLSchemeHandler> |
| @property (nonatomic, copy) BOOL(^shouldStartInputSessionHandler)(id <_WKFocusedElementInfo>); |
| @end |
| |
| @implementation InputDelegate { |
| BlockPtr<BOOL(id <_WKFocusedElementInfo>)> _shouldStartInputSessionHandler; |
| } |
| |
| - (void)webView:(WKWebView *)webView startURLSchemeTask:(id <WKURLSchemeTask>)task |
| { |
| EXPECT_TRUE(willSubmitFormValuesCalled); |
| EXPECT_STREQ(task.request.URL.absoluteString.UTF8String, "test:///formtarget"); |
| EXPECT_NOT_NULL(task.request.HTTPBody); |
| EXPECT_EQ(task.request.HTTPBody.length, 62u); |
| EXPECT_STREQ(static_cast<const char*>(task.request.HTTPBody.bytes), "testname1=testvalue1&testname2=testvalue2&testname3=testvalue3"); |
| done = true; |
| } |
| |
| - (void)webView:(WKWebView *)webView stopURLSchemeTask:(id <WKURLSchemeTask>)task |
| { |
| } |
| |
| - (void)_webView:(WKWebView *)webView willSubmitFormValues:(NSDictionary *)values userObject:(NSObject <NSSecureCoding> *)userObject submissionHandler:(void (^)(void))submissionHandler |
| { |
| EXPECT_EQ(values.count, 2u); |
| EXPECT_STREQ([[values objectForKey:@"testname1"] UTF8String], "testvalue1"); |
| EXPECT_STREQ([[values objectForKey:@"testname2"] UTF8String], "testvalue2"); |
| willSubmitFormValuesCalled = true; |
| submissionHandler(); |
| } |
| |
| - (BOOL)_webView:(WKWebView *)webView focusShouldStartInputSession:(id <_WKFocusedElementInfo>)info |
| { |
| if (_shouldStartInputSessionHandler) |
| return _shouldStartInputSessionHandler(info); |
| return [info isUserInitiated]; |
| } |
| |
| - (BOOL(^)(id <_WKFocusedElementInfo>))shouldStartInputSessionHandler |
| { |
| return _shouldStartInputSessionHandler.get(); |
| } |
| |
| - (void)setShouldStartInputSessionHandler:(BOOL(^)(id <_WKFocusedElementInfo>))handler |
| { |
| _shouldStartInputSessionHandler = makeBlockPtr(handler); |
| } |
| |
| @end |
| |
| TEST(WebKit, FormSubmission) |
| { |
| auto delegate = adoptNS([[InputDelegate alloc] init]); |
| auto configuration = adoptNS([[WKWebViewConfiguration alloc] init]); |
| [configuration setURLSchemeHandler:delegate.get() forURLScheme:@"test"]; |
| auto webView = adoptNS([[WKWebView alloc] initWithFrame:NSMakeRect(0, 0, 800, 600) configuration:configuration.get()]); |
| [webView _setInputDelegate:delegate.get()]; |
| [webView loadHTMLString:@"<body onload='document.getElementById(\"formID\").submit()'><form id='formID' method='post' action='test:///formtarget'>" |
| "<input type='text' name='testname1' value='testvalue1'/>" |
| "<input type='password' name='testname2' value='testvalue2'/>" |
| "<input type='hidden' name='testname3' value='testvalue3'/>" |
| "</form></body>" baseURL:nil]; |
| TestWebKitAPI::Util::run(&done); |
| } |
| |
| #if PLATFORM(IOS_FAMILY) |
| |
| TEST(WebKit, FocusedElementInfo) |
| { |
| auto webView = adoptNS([[TestWKWebView alloc] initWithFrame:CGRectMake(0, 0, 320, 500)]); |
| auto delegate = adoptNS([[InputDelegate alloc] init]); |
| [webView _setInputDelegate:delegate.get()]; |
| |
| __block RetainPtr<id <_WKFocusedElementInfo>> currentElement; |
| [delegate setShouldStartInputSessionHandler:^BOOL(id<_WKFocusedElementInfo> element) { |
| currentElement = element; |
| return NO; |
| }]; |
| |
| [webView synchronouslyLoadHTMLString:@"<label for='foo'>bar</label><input id='foo'>"]; |
| [webView stringByEvaluatingJavaScript:@"foo.focus()"]; |
| [webView waitForNextPresentationUpdate]; |
| EXPECT_WK_STREQ("", [currentElement placeholder]); |
| EXPECT_WK_STREQ("bar", [currentElement label]); |
| |
| [webView synchronouslyLoadHTMLString:@"<input placeholder='bar'>"]; |
| [webView stringByEvaluatingJavaScript:@"document.querySelector('input').focus()"]; |
| [webView waitForNextPresentationUpdate]; |
| EXPECT_WK_STREQ("bar", [currentElement placeholder]); |
| EXPECT_WK_STREQ("", [currentElement label]); |
| |
| [webView synchronouslyLoadHTMLString:@"<label for='baz'>garply</label><select id='baz'></select>"]; |
| [webView stringByEvaluatingJavaScript:@"baz.focus()"]; |
| [webView waitForNextPresentationUpdate]; |
| EXPECT_WK_STREQ("", [currentElement placeholder]); |
| EXPECT_WK_STREQ("garply", [currentElement label]); |
| |
| [webView synchronouslyLoadHTMLString:@"<label for='foo' style='display: none'>bar</label><label for='foo'></label><input id='foo'><label for='foo'>garply</label>"]; |
| [webView stringByEvaluatingJavaScript:@"foo.focus()"]; |
| [webView waitForNextPresentationUpdate]; |
| EXPECT_WK_STREQ("", [currentElement placeholder]); |
| EXPECT_WK_STREQ("garply", [currentElement label]); |
| } |
| |
| #endif // PLATFORM(IOS_FAMILY) |
| |
| |