blob: b6165cddba6d6b64712484b7e4d1734c2328f7f5 [file] [log] [blame]
/*
* 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)