Commit 54555a11 authored by jonlee@apple.com's avatar jonlee@apple.com

REGRESSION (WK2): (Shift-)option-tabbing skips over elements when...

REGRESSION (WK2): (Shift-)option-tabbing skips over elements when transitioning from chrome to webview
https://bugs.webkit.org/show_bug.cgi?id=68412
<rdar://problem/9988252>

Reviewed by Darin Adler.

Source/WebKit2:

In WK1 setInitialFocus() is called on FocusController with the key event that
caused the web view to become first responder. In WK2 no event is sent. So if
the key stroke that caused the change in first responder status contains the
option modifier key, FocusController did not know that it had to switch behavior.

Because there are multiple ways that the WKView can becomeFirstResponder, I changed
the signature to setInitialFocus to express whether the key event parameter is an
actual key event.

* UIProcess/API/C/win/WKView.cpp:
(WKViewSetInitialFocus):
* UIProcess/API/mac/WKView.mm:
(-[WKView becomeFirstResponder]): Take the NSApp currentEvent and pass it along if
the event is a keyboard event, otherwise pass an empty event.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setInitialFocus): Change in function signature to confirm that
the event that caused the initial focus was a keyboard event, and provide the keyboard
event itself.
* UIProcess/WebPageProxy.h:
* UIProcess/win/WebView.cpp:
(WebKit::WebView::setInitialFocus):
* UIProcess/win/WebView.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setInitialFocus): If we know that the cause of this was a keyboard
event, we pass that event to the FocusController. Otherwise we fall back to the original
behavior, which is to pass no event at all.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:

Tools:

In order to create a test for the bug, I had to update DRT and WKTR to create some
widget that allows first responder status to move away from the main web view.

Three methods were added to layoutTestController: addChromeInputField,
removeChromeInputField, and focusWebView. addChromeInputField adds a text field
that is a sibling to the web view, and sets up the key event loop between the two.
removeChromeInputField removes that field. focusWebView moves first responder
status to the web view.

The test makes the call via layoutTestController and passes a callback that it
assumes will be executed once the task is completed. In DRT the callback is called
synchronously. In WKTR this is handled with message passing between the two
processes.

* DumpRenderTree/LayoutTestController.cpp:
(addChromeInputFieldCallback):
(removeChromeInputFieldCallback):
(focusWebViewCallback):
(LayoutTestController::staticFunctions):
* DumpRenderTree/LayoutTestController.h:
* DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* DumpRenderTree/mac/DumpRenderTree.mm:
(resetWebViewToConsistentStateBeforeTesting): When resetting for the next test,
make sure to remove the chrome input field.
* DumpRenderTree/mac/LayoutTestControllerMac.mm:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* DumpRenderTree/win/LayoutTestControllerWin.cpp:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessage):
(WTR::InjectedBundle::postAddChromeInputField):
(WTR::InjectedBundle::postRemoveChromeInputField):
(WTR::InjectedBundle::postFocusWebView):
* WebKitTestRunner/InjectedBundle/InjectedBundle.h:
* WebKitTestRunner/InjectedBundle/LayoutTestController.cpp:
(WTR::callbackMap): Create a hash map that keeps track of the callbacks provided
through JS.
(WTR::cacheLayoutTestControllerCallback):
(WTR::callLayoutTestControllerCallback):
(WTR::LayoutTestController::addChromeInputField):
(WTR::LayoutTestController::removeChromeInputField):
(WTR::LayoutTestController::focusWebView):
(WTR::LayoutTestController::callAddChromeInputFieldCallback):
(WTR::LayoutTestController::callRemoveChromeInputFieldCallback):
(WTR::LayoutTestController::callFocusWebViewCallback):
* WebKitTestRunner/InjectedBundle/LayoutTestController.h:
* WebKitTestRunner/PlatformWebView.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetStateToConsistentValues):
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
* WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):
* WebKitTestRunner/win/PlatformWebViewWin.cpp:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):

* DumpRenderTree/mac/LayoutTestControllerMac.mm: These functions have nothing to do
with the patch-- just cleaning up style.
(LayoutTestController::addDisallowedURL):
(originsArrayToJS):
(LayoutTestController::queueLoad):
(LayoutTestController::setMockDeviceOrientation):
(LayoutTestController::setIconDatabaseEnabled):
(LayoutTestController::setEditingBehavior):

LayoutTests:

The option-key navigation is only relevant to the Mac platform.

* platform/mac/fast/forms/focus-option-control-on-page-expected.txt: Added.
* platform/mac/fast/forms/focus-option-control-on-page.html: Added.
* platform/mac/fast/forms/script-tests/focus-option-control-on-page.js: Added.
(startTest):
(runKeyPresses):
(notifyDone):
(log):

git-svn-id: http://svn.webkit.org/repository/webkit/trunk@96645 268f45cc-cd09-0410-ab3c-d52691b4dbfc
parent 90f99c25
2011-10-04 Jon Lee <jonlee@apple.com>
REGRESSION (WK2): (Shift-)option-tabbing skips over elements when transitioning from chrome to webview
https://bugs.webkit.org/show_bug.cgi?id=68412
<rdar://problem/9988252>
Reviewed by Darin Adler.
The option-key navigation is only relevant to the Mac platform.
* platform/mac/fast/forms/focus-option-control-on-page-expected.txt: Added.
* platform/mac/fast/forms/focus-option-control-on-page.html: Added.
* platform/mac/fast/forms/script-tests/focus-option-control-on-page.js: Added.
(startTest):
(runKeyPresses):
(notifyDone):
(log):
2011-10-04 David Hyatt <hyatt@apple.com>
https://bugs.webkit.org/show_bug.cgi?id=69372
https://bugs.webkit.org/show_bug.cgi?id=68412 - This test checks to see if option(alt)-tabbing properly focuses form elements that are normally not focused. For testing, the assumption is that by default pressing tab will skip over buttons, and option-tab will include buttons.
On success, you will see a series of "PASS" messages, followed by "TEST COMPLETE".
Pressing tab 4 times:
PASS result is " /1:focused text field /2: /3:focused text field /4:"
Pressing shift-tab 4 times:
PASS result is " /1:focused text field /2: /3:focused text field /4:"
Pressing option-tab 4 times:
PASS result is " /1:focused first button /2:focused text field /3:focused second button /4:"
Pressing shift-option-tab 4 times:
PASS result is " /1:focused second button /2:focused text field /3:focused first button /4:"
<!DOCTYPE HTML>
<html>
<head>
<link rel="stylesheet" href="../../../../fast/js/resources/js-test-style.css">
<script src="../../../../fast/js/resources/js-test-pre.js"></script>
</head>
<body>
<p id="description"></p>
<input type="button" onfocus="log('focused first button')" value="1">
<input type="text" onfocus="log('focused text field')" value="2">
<input type="button" onfocus="log('focused second button')" value="3">
<div id="console"></div>
<script src="script-tests/focus-option-control-on-page.js"></script>
<script src="../../../../fast/js/resources/js-test-post.js"></script>
</body>
</html>
description('https://bugs.webkit.org/show_bug.cgi?id=68412 - This test checks to see if option(alt)-tabbing properly focuses form elements that are normally not focused. For testing, the assumption is that by default pressing tab will skip over buttons, and option-tab will include buttons.');
var iteration = 0;
var modifiers;
var result;
function startTest() {
debug("Pressing tab 4 times:");
modifiers = undefined;
layoutTestController.focusWebView(runKeyPresses);
}
function runKeyPresses() {
result = '';
for (var i = 0; i < 4; ++i) {
result += ' /' + (i + 1) + ':';
eventSender.keyDown("\t", modifiers);
}
iteration++;
switch (iteration) {
case 1:
shouldBe('result', '" /1:focused text field /2: /3:focused text field /4:"');
debug("Pressing shift-tab 4 times:");
modifiers = ["shiftKey"];
layoutTestController.focusWebView(runKeyPresses);
break;
case 2:
shouldBe('result', '" /1:focused text field /2: /3:focused text field /4:"');
debug("Pressing option-tab 4 times:");
modifiers = ["altKey"];
layoutTestController.focusWebView(runKeyPresses);
break;
case 3:
shouldBe('result', '" /1:focused first button /2:focused text field /3:focused second button /4:"');
debug("Pressing shift-option-tab 4 times:");
modifiers = ["shiftKey", "altKey"];
layoutTestController.focusWebView(runKeyPresses);
break;
case 4:
shouldBe('result', '" /1:focused second button /2:focused text field /3:focused first button /4:"');
layoutTestController.removeChromeInputField(notifyDone);
break;
}
}
function notifyDone() {
setTimeout(function() { layoutTestController.notifyDone(); }, 0);
}
function log(val) {
result += val;
}
/////////////////////////////////
if (window.layoutTestController && window.eventSender && layoutTestController.addChromeInputField) {
window.jsTestIsAsync = true;
layoutTestController.addChromeInputField(startTest);
} else
finishJSTest();
var successfullyParsed = true;
2011-10-04 Jon Lee <jonlee@apple.com>
REGRESSION (WK2): (Shift-)option-tabbing skips over elements when transitioning from chrome to webview
https://bugs.webkit.org/show_bug.cgi?id=68412
<rdar://problem/9988252>
Reviewed by Darin Adler.
In WK1 setInitialFocus() is called on FocusController with the key event that
caused the web view to become first responder. In WK2 no event is sent. So if
the key stroke that caused the change in first responder status contains the
option modifier key, FocusController did not know that it had to switch behavior.
Because there are multiple ways that the WKView can becomeFirstResponder, I changed
the signature to setInitialFocus to express whether the key event parameter is an
actual key event.
* UIProcess/API/C/win/WKView.cpp:
(WKViewSetInitialFocus):
* UIProcess/API/mac/WKView.mm:
(-[WKView becomeFirstResponder]): Take the NSApp currentEvent and pass it along if
the event is a keyboard event, otherwise pass an empty event.
* UIProcess/WebPageProxy.cpp:
(WebKit::WebPageProxy::setInitialFocus): Change in function signature to confirm that
the event that caused the initial focus was a keyboard event, and provide the keyboard
event itself.
* UIProcess/WebPageProxy.h:
* UIProcess/win/WebView.cpp:
(WebKit::WebView::setInitialFocus):
* UIProcess/win/WebView.h:
* WebProcess/WebPage/WebPage.cpp:
(WebKit::WebPage::setInitialFocus): If we know that the cause of this was a keyboard
event, we pass that event to the FocusController. Otherwise we fall back to the original
behavior, which is to pass no event at all.
* WebProcess/WebPage/WebPage.h:
* WebProcess/WebPage/WebPage.messages.in:
2011-10-04 Jeff Miller <jeffm@apple.com>
WKPreferences should allow control of application chrome mode
......
......@@ -69,7 +69,8 @@ void WKViewSetIsInWindow(WKViewRef viewRef, bool isInWindow)
void WKViewSetInitialFocus(WKViewRef viewRef, bool forward)
{
toImpl(viewRef)->setInitialFocus(forward);
bool isKeyboardEventValid = false;
toImpl(viewRef)->setInitialFocus(forward, isKeyboardEventValid, WebKeyboardEvent());
}
void WKViewSetScrollOffsetOnNextResize(WKViewRef viewRef, WKSize scrollOffset)
......
......@@ -311,10 +311,14 @@ struct WKViewInterpretKeyEventsParameters {
_data->_page->viewStateDidChange(WebPageProxy::ViewIsFocused);
_data->_inBecomeFirstResponder = false;
if (direction != NSDirectSelection)
_data->_page->setInitialFocus(direction == NSSelectingNext);
if (direction != NSDirectSelection) {
NSEvent *event = [NSApp currentEvent];
NSEvent *keyboardEvent = nil;
if ([event type] == NSKeyDown || [event type] == NSKeyUp)
keyboardEvent = event;
_data->_page->setInitialFocus(direction == NSSelectingNext, keyboardEvent != nil, NativeWebKeyboardEvent(keyboardEvent, self));
}
return YES;
}
......
......@@ -700,11 +700,11 @@ IntSize WebPageProxy::viewSize() const
return m_pageClient->viewSize();
}
void WebPageProxy::setInitialFocus(bool forward)
void WebPageProxy::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& keyboardEvent)
{
if (!isValid())
return;
process()->send(Messages::WebPage::SetInitialFocus(forward), m_pageID);
process()->send(Messages::WebPage::SetInitialFocus(forward, isKeyboardEventValid, keyboardEvent), m_pageID);
}
void WebPageProxy::setWindowResizerSize(const IntSize& windowResizerSize)
......
......@@ -262,7 +262,7 @@ public:
void viewWillStartLiveResize();
void viewWillEndLiveResize();
void setInitialFocus(bool);
void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
void setWindowResizerSize(const WebCore::IntSize&);
void clearSelection();
......
......@@ -1068,9 +1068,9 @@ void WebView::setOverrideCursor(HCURSOR overrideCursor)
updateNativeCursor();
}
void WebView::setInitialFocus(bool forward)
void WebView::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
{
m_page->setInitialFocus(forward);
m_page->setInitialFocus(forward, isKeyboardEventValid, event);
}
void WebView::setScrollOffsetOnNextResize(const IntSize& scrollOffset)
......
......@@ -79,7 +79,7 @@ public:
void setIsInWindow(bool);
void setIsVisible(bool);
void setOverrideCursor(HCURSOR);
void setInitialFocus(bool forward);
void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
void setScrollOffsetOnNextResize(const WebCore::IntSize&);
void setFindIndicatorCallback(WKViewFindIndicatorCallback, void*);
WKViewFindIndicatorCallback getFindIndicatorCallback(void**);
......
......@@ -1365,13 +1365,21 @@ void WebPage::setFocused(bool isFocused)
m_page->focusController()->setFocused(isFocused);
}
void WebPage::setInitialFocus(bool forward)
void WebPage::setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent& event)
{
if (!m_page || !m_page->focusController())
return;
Frame* frame = m_page->focusController()->focusedOrMainFrame();
frame->document()->setFocusedNode(0);
if (isKeyboardEventValid && event.type() == WebEvent::KeyDown) {
PlatformKeyboardEvent platformEvent(platform(event));
platformEvent.disambiguateKeyDownEvent(PlatformKeyboardEvent::RawKeyDown);
m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, KeyboardEvent::create(platformEvent, frame->document()->defaultView()).get());
return;
}
m_page->focusController()->setInitialFocus(forward ? FocusDirectionForward : FocusDirectionBackward, 0);
}
......
......@@ -480,7 +480,7 @@ private:
void tryRestoreScrollPosition();
void setActive(bool);
void setFocused(bool);
void setInitialFocus(bool);
void setInitialFocus(bool forward, bool isKeyboardEventValid, const WebKeyboardEvent&);
void setWindowResizerSize(const WebCore::IntSize&);
void setIsInWindow(bool);
void validateCommand(const String&, uint64_t);
......
......@@ -23,7 +23,7 @@
messages -> WebPage {
SetActive(bool active)
SetFocused(bool focused)
SetInitialFocus(bool forward)
SetInitialFocus(bool forward, bool isKeyboardEventValid, WebKit::WebKeyboardEvent event)
SetIsInWindow(bool isInWindow)
SetDrawsBackground(bool drawsBackground)
......
2011-10-04 Jon Lee <jonlee@apple.com>
REGRESSION (WK2): (Shift-)option-tabbing skips over elements when transitioning from chrome to webview
https://bugs.webkit.org/show_bug.cgi?id=68412
<rdar://problem/9988252>
Reviewed by Darin Adler.
In order to create a test for the bug, I had to update DRT and WKTR to create some
widget that allows first responder status to move away from the main web view.
Three methods were added to layoutTestController: addChromeInputField,
removeChromeInputField, and focusWebView. addChromeInputField adds a text field
that is a sibling to the web view, and sets up the key event loop between the two.
removeChromeInputField removes that field. focusWebView moves first responder
status to the web view.
The test makes the call via layoutTestController and passes a callback that it
assumes will be executed once the task is completed. In DRT the callback is called
synchronously. In WKTR this is handled with message passing between the two
processes.
* DumpRenderTree/LayoutTestController.cpp:
(addChromeInputFieldCallback):
(removeChromeInputFieldCallback):
(focusWebViewCallback):
(LayoutTestController::staticFunctions):
* DumpRenderTree/LayoutTestController.h:
* DumpRenderTree/gtk/LayoutTestControllerGtk.cpp:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* DumpRenderTree/mac/DumpRenderTree.mm:
(resetWebViewToConsistentStateBeforeTesting): When resetting for the next test,
make sure to remove the chrome input field.
* DumpRenderTree/mac/LayoutTestControllerMac.mm:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* DumpRenderTree/win/LayoutTestControllerWin.cpp:
(LayoutTestController::addChromeInputField):
(LayoutTestController::removeChromeInputField):
(LayoutTestController::focusWebView):
* WebKitTestRunner/InjectedBundle/Bindings/LayoutTestController.idl:
* WebKitTestRunner/InjectedBundle/InjectedBundle.cpp:
(WTR::InjectedBundle::didReceiveMessage):
(WTR::InjectedBundle::postAddChromeInputField):
(WTR::InjectedBundle::postRemoveChromeInputField):
(WTR::InjectedBundle::postFocusWebView):
* WebKitTestRunner/InjectedBundle/InjectedBundle.h:
* WebKitTestRunner/InjectedBundle/LayoutTestController.cpp:
(WTR::callbackMap): Create a hash map that keeps track of the callbacks provided
through JS.
(WTR::cacheLayoutTestControllerCallback):
(WTR::callLayoutTestControllerCallback):
(WTR::LayoutTestController::addChromeInputField):
(WTR::LayoutTestController::removeChromeInputField):
(WTR::LayoutTestController::focusWebView):
(WTR::LayoutTestController::callAddChromeInputFieldCallback):
(WTR::LayoutTestController::callRemoveChromeInputFieldCallback):
(WTR::LayoutTestController::callFocusWebViewCallback):
* WebKitTestRunner/InjectedBundle/LayoutTestController.h:
* WebKitTestRunner/PlatformWebView.h:
* WebKitTestRunner/TestController.cpp:
(WTR::TestController::resetStateToConsistentValues):
* WebKitTestRunner/TestInvocation.cpp:
(WTR::TestInvocation::didReceiveMessageFromInjectedBundle):
* WebKitTestRunner/gtk/PlatformWebViewGtk.cpp:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):
* WebKitTestRunner/mac/PlatformWebViewMac.mm:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):
* WebKitTestRunner/win/PlatformWebViewWin.cpp:
(WTR::PlatformWebView::addChromeInputField):
(WTR::PlatformWebView::removeChromeInputField):
(WTR::PlatformWebView::makeWebViewFirstResponder):
* DumpRenderTree/mac/LayoutTestControllerMac.mm: These functions have nothing to do
with the patch-- just cleaning up style.
(LayoutTestController::addDisallowedURL):
(originsArrayToJS):
(LayoutTestController::queueLoad):
(LayoutTestController::setMockDeviceOrientation):
(LayoutTestController::setIconDatabaseEnabled):
(LayoutTestController::setEditingBehavior):
2011-10-04 Simon Fraser <simon.fraser@apple.com>
Move font-fixup code in WebKitTestRunner to a better place
......@@ -2160,6 +2160,36 @@ static JSValueRef setShouldStayOnPageAfterHandlingBeforeUnloadCallback(JSContext
return JSValueMakeUndefined(context);
}
static JSValueRef addChromeInputFieldCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
controller->addChromeInputField();
// the first argument is a callback that is called once the input field has been added
if (argumentCount == 1)
JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
return JSValueMakeUndefined(context);
}
static JSValueRef removeChromeInputFieldCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
controller->removeChromeInputField();
// the first argument is a callback that is called once the input field has been added
if (argumentCount == 1)
JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
return JSValueMakeUndefined(context);
}
static JSValueRef focusWebViewCallback(JSContextRef context, JSObjectRef, JSObjectRef thisObject, size_t argumentCount, const JSValueRef arguments[], JSValueRef* exception)
{
LayoutTestController* controller = static_cast<LayoutTestController*>(JSObjectGetPrivate(thisObject));
controller->focusWebView();
// the first argument is a callback that is called once the input field has been added
if (argumentCount == 1)
JSObjectCallAsFunction(context, JSValueToObject(context, arguments[0], 0), thisObject, 0, 0, 0);
return JSValueMakeUndefined(context);
}
// Static Values
static JSValueRef getGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
......@@ -2436,6 +2466,9 @@ JSStaticFunction* LayoutTestController::staticFunctions()
{ "setTextDirection", setTextDirectionCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "allowRoundingHacks", allowRoundingHacksCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "setShouldStayOnPageAfterHandlingBeforeUnload", setShouldStayOnPageAfterHandlingBeforeUnloadCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "addChromeInputField", addChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "removeChromeInputField", removeChromeInputFieldCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "focusWebView", focusWebViewCallback, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0 }
};
......
......@@ -314,6 +314,10 @@ public:
bool shouldStayOnPageAfterHandlingBeforeUnload() const { return m_shouldStayOnPageAfterHandlingBeforeUnload; }
void setShouldStayOnPageAfterHandlingBeforeUnload(bool shouldStayOnPageAfterHandlingBeforeUnload) { m_shouldStayOnPageAfterHandlingBeforeUnload = shouldStayOnPageAfterHandlingBeforeUnload; }
void addChromeInputField();
void removeChromeInputField();
void focusWebView();
void setPOSIXLocale(JSStringRef locale);
void setWebViewEditable(bool);
......
......@@ -987,3 +987,15 @@ void LayoutTestController::setTextDirection(JSStringRef direction)
void LayoutTestController::allowRoundingHacks()
{
}
void LayoutTestController::addChromeInputField()
{
}
void LayoutTestController::removeChromeInputField()
{
}
void LayoutTestController::focusWebView()
{
}
......@@ -1163,8 +1163,11 @@ static void resetWebViewToConsistentStateBeforeTesting()
resetDefaultsToConsistentValues();
if (gLayoutTestController)
if (gLayoutTestController) {
WebCoreTestSupport::resetInternalsObject([mainFrame globalContext]);
// in the case that a test using the chrome input field failed, be sure to clean up for the next test
gLayoutTestController->removeChromeInputField();
}
[[mainFrame webView] setSmartInsertDeleteEnabled:YES];
[[[mainFrame webView] inspector] setJavaScriptProfilingEnabled:NO];
......
......@@ -119,7 +119,7 @@ void LayoutTestController::addDisallowedURL(JSStringRef url)
disallowedURLs = CFSetCreateMutable(kCFAllocatorDefault, 0, NULL);
// Canonicalize the URL
NSURLRequest* request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:(NSString *)urlCF.get()]];
request = [NSURLProtocol canonicalRequestForRequest:request];
CFSetAddValue(disallowedURLs, [request URL]);
......@@ -168,7 +168,7 @@ void LayoutTestController::clearApplicationCacheForOrigin(JSStringRef url)
[origin release];
}
JSValueRef originsArrayToJS(JSContextRef context, NSArray* origins)
JSValueRef originsArrayToJS(JSContextRef context, NSArray *origins)
{
NSUInteger count = [origins count];
......@@ -425,7 +425,7 @@ void LayoutTestController::queueLoad(JSStringRef url, JSStringRef target)
NSString *urlNS = (NSString *)urlCF.get();
NSURL *nsurl = [NSURL URLWithString:urlNS relativeToURL:[[[mainFrame dataSource] response] URL]];
NSString* nsurlString = [nsurl absoluteString];
NSString *nsurlString = [nsurl absoluteString];
JSRetainPtr<JSStringRef> absoluteURL(Adopt, JSStringCreateWithUTF8CString([nsurlString UTF8String]));
WorkQueue::shared()->queue(new LoadItem(absoluteURL.get(), target));
......@@ -508,8 +508,8 @@ void LayoutTestController::setMockDeviceOrientation(bool canProvideAlpha, double
{
// DumpRenderTree configured the WebView to use WebDeviceOrientationProviderMock.
id<WebDeviceOrientationProvider> provider = [[mainFrame webView] _deviceOrientationProvider];
WebDeviceOrientationProviderMock* mockProvider = static_cast<WebDeviceOrientationProviderMock*>(provider);
WebDeviceOrientation* orientation = [[WebDeviceOrientation alloc] initWithCanProvideAlpha:canProvideAlpha alpha:alpha canProvideBeta:canProvideBeta beta:beta canProvideGamma:canProvideGamma gamma:gamma];
WebDeviceOrientationProviderMock *mockProvider = static_cast<WebDeviceOrientationProviderMock*>(provider);
WebDeviceOrientation *orientation = [[WebDeviceOrientation alloc] initWithCanProvideAlpha:canProvideAlpha alpha:alpha canProvideBeta:canProvideBeta beta:beta canProvideGamma:canProvideGamma gamma:gamma];
[mockProvider setOrientation:orientation];
[orientation release];
}
......@@ -550,7 +550,7 @@ void LayoutTestController::startSpeechInput(JSContextRef inputElement)
void LayoutTestController::setIconDatabaseEnabled(bool iconDatabaseEnabled)
{
// FIXME: Workaround <rdar://problem/6480108>
static WebIconDatabase* sharedWebIconDatabase = NULL;
static WebIconDatabase *sharedWebIconDatabase = NULL;
if (!sharedWebIconDatabase) {
if (!iconDatabaseEnabled)
return;
......@@ -1151,7 +1151,7 @@ void LayoutTestController::authenticateSession(JSStringRef url, JSStringRef user
void LayoutTestController::setEditingBehavior(const char* editingBehavior)
{
NSString* editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior];
NSString *editingBehaviorNS = [[NSString alloc] initWithUTF8String:editingBehavior];
if ([editingBehaviorNS isEqualToString:@"mac"])
[[WebPreferences standardPreferences] setEditingBehavior:WebKitEditingMacBehavior];
else if ([editingBehaviorNS isEqualToString:@"win"])
......@@ -1202,3 +1202,28 @@ void LayoutTestController::setTextDirection(JSStringRef directionName)
ASSERT_NOT_REACHED();
#endif
}
void LayoutTestController::addChromeInputField()
{
NSTextField *textField = [[NSTextField alloc] initWithFrame:NSMakeRect(0, 0, 100, 20)];
textField.tag = 1;
[[[[mainFrame webView] window] contentView] addSubview:textField];
[textField release];
[textField setNextKeyView:[mainFrame webView]];
[[mainFrame webView] setNextKeyView:textField];
}
void LayoutTestController::removeChromeInputField()
{
NSView* textField = [[[[mainFrame webView] window] contentView] viewWithTag:1];
if (textField) {
[textField removeFromSuperview];
focusWebView();
}
}
void LayoutTestController::focusWebView()
{
[[[mainFrame webView] window] makeFirstResponder:[mainFrame webView]];
}
......@@ -1540,3 +1540,15 @@ void LayoutTestController::setTextDirection(JSStringRef direction)
void LayoutTestController::allowRoundingHacks()
{
}
void LayoutTestController::addChromeInputField()
{
}
void LayoutTestController::removeChromeInputField()
{
}
void LayoutTestController::focusWebView()
{
}
......@@ -121,6 +121,11 @@ module WTR {
void setWillSendRequestReturnsNull(in boolean flag);
void setShouldStayOnPageAfterHandlingBeforeUnload(in boolean flag);
// Focus testing.
void addChromeInputField(in object callback);
void removeChromeInputField(in object callback);
void focusWebView(in object callback);
};
}
......@@ -158,6 +158,18 @@ void InjectedBundle::didReceiveMessage(WKStringRef messageName, WKTypeRef messag
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "CallAddChromeInputFieldCallback")) {
m_layoutTestController->callAddChromeInputFieldCallback();
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "CallRemoveChromeInputFieldCallback")) {
m_layoutTestController->callRemoveChromeInputFieldCallback();
return;
}
if (WKStringIsEqualToUTF8CString(messageName, "CallFocusWebViewCallback")) {
m_layoutTestController->callFocusWebViewCallback();
return;
}
WKRetainPtr<WKStringRef> errorMessageName(AdoptWK, WKStringCreateWithUTF8CString("Error"));
WKRetainPtr<WKStringRef> errorMessageBody(AdoptWK, WKStringCreateWithUTF8CString("Unknown"));
......@@ -246,4 +258,22 @@ void InjectedBundle::postNewBeforeUnloadReturnValue(bool value)
WKBundlePostMessage(m_bundle, messageName.get(), messageBody.get());
}
void InjectedBundle::postAddChromeInputField()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("AddChromeInputField"));
WKBundlePostMessage(m_bundle, messageName.get(), 0);
}
void InjectedBundle::postRemoveChromeInputField()
{
WKRetainPtr<WKStringRef> messageName(AdoptWK, WKStringCreateWithUTF8CString("RemoveChromeInputField"));
WKBundlePostMessage(m_bundle, messageName.get(), 0);
}