/* * Copyright (C) 2015 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" #import "UIScriptController.h" #import "EventSerializerMac.h" #import "PlatformWebView.h" #import "SharedEventStreamsMac.h" #import "TestController.h" #import "PlatformWebView.h" #import "StringFunctions.h" #import "TestController.h" #import "TestRunnerWKWebView.h" #import "UIScriptContext.h" #import #import #import #import #import #import namespace WTR { NSString *nsString(JSStringRef string) { return (NSString *)adoptCF(JSStringCopyCFString(kCFAllocatorDefault, string)).autorelease(); } void UIScriptController::doAsyncTask(JSValueRef callback) { unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); dispatch_async(dispatch_get_main_queue(), ^{ if (!m_context) return; m_context->asyncTaskComplete(callbackID); }); } void UIScriptController::doAfterPresentationUpdate(JSValueRef callback) { return doAsyncTask(callback); } void UIScriptController::doAfterNextStablePresentationUpdate(JSValueRef callback) { doAsyncTask(callback); } void UIScriptController::doAfterVisibleContentRectUpdate(JSValueRef callback) { doAsyncTask(callback); } void UIScriptController::replaceTextAtRange(JSStringRef text, int location, int length) { #if WK_API_ENABLED if (location == -1) location = NSNotFound; auto* webView = TestController::singleton().mainWebView()->platformView(); [webView _insertText:nsString(text) replacementRange:NSMakeRange(location, length)]; #else UNUSED_PARAM(text); UNUSED_PARAM(location); UNUSED_PARAM(length); #endif } void UIScriptController::zoomToScale(double scale, JSValueRef callback) { #if WK_API_ENABLED unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); auto* webView = TestController::singleton().mainWebView()->platformView(); [webView _setPageScale:scale withOrigin:CGPointZero]; [webView _doAfterNextPresentationUpdate: ^ { if (!m_context) return; m_context->asyncTaskComplete(callbackID); }]; #else UNUSED_PARAM(scale); UNUSED_PARAM(callback); #endif } void UIScriptController::simulateAccessibilitySettingsChangeNotification(JSValueRef callback) { #if WK_API_ENABLED unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); auto* webView = TestController::singleton().mainWebView()->platformView(); NSNotificationCenter *center = [[NSWorkspace sharedWorkspace] notificationCenter]; [center postNotificationName:NSWorkspaceAccessibilityDisplayOptionsDidChangeNotification object:webView]; [webView _doAfterNextPresentationUpdate: ^{ if (!m_context) return; m_context->asyncTaskComplete(callbackID); }]; #else UNUSED_PARAM(callback); #endif } JSObjectRef UIScriptController::contentsOfUserInterfaceItem(JSStringRef interfaceItem) const { #if WK_API_ENABLED TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); NSDictionary *contentDictionary = [webView _contentsOfUserInterfaceItem:toWTFString(toWK(interfaceItem))]; return JSValueToObject(m_context->jsContext(), [JSValue valueWithObject:contentDictionary inContext:[JSContext contextWithJSGlobalContextRef:m_context->jsContext()]].JSValueRef, nullptr); #else UNUSED_PARAM(interfaceItem); return nullptr; #endif } void UIScriptController::overridePreference(JSStringRef preferenceRef, JSStringRef valueRef) { #if WK_API_ENABLED TestRunnerWKWebView *webView = TestController::singleton().mainWebView()->platformView(); WKPreferences *preferences = webView.configuration.preferences; String preference = toWTFString(toWK(preferenceRef)); String value = toWTFString(toWK(valueRef)); if (preference == "WebKitMinimumFontSize") preferences.minimumFontSize = value.toDouble(); #else UNUSED_PARAM(preferenceRef); UNUSED_PARAM(valueRef); #endif } void UIScriptController::simulateRotation(DeviceOrientation*, JSValueRef) { } void UIScriptController::simulateRotationLikeSafari(DeviceOrientation*, JSValueRef) { } void UIScriptController::findString(JSStringRef, unsigned long options, unsigned long maxCount) { } void UIScriptController::removeViewFromWindow(JSValueRef callback) { #if WK_API_ENABLED unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); auto* mainWebView = TestController::singleton().mainWebView(); mainWebView->removeFromWindow(); [mainWebView->platformView() _doAfterNextPresentationUpdate: ^ { if (!m_context) return; m_context->asyncTaskComplete(callbackID); }]; #else UNUSED_PARAM(callback); #endif } void UIScriptController::addViewToWindow(JSValueRef callback) { #if WK_API_ENABLED unsigned callbackID = m_context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); auto* mainWebView = TestController::singleton().mainWebView(); mainWebView->addToWindow(); [mainWebView->platformView() _doAfterNextPresentationUpdate: ^ { if (!m_context) return; m_context->asyncTaskComplete(callbackID); }]; #else UNUSED_PARAM(callback); #endif } static void playBackEvents(UIScriptContext *context, NSString *eventStream, JSValueRef callback) { NSError *error = nil; NSArray *eventDicts = [NSJSONSerialization JSONObjectWithData:[eventStream dataUsingEncoding:NSUTF8StringEncoding] options:0 error:&error]; if (error) { NSLog(@"ERROR: %@", error); return; } unsigned callbackID = context->prepareForAsyncTask(callback, CallbackTypeNonPersistent); NSWindow *window = [TestController::singleton().mainWebView()->platformView() window]; [EventStreamPlayer playStream:eventDicts window:window completionHandler:^ { context->asyncTaskComplete(callbackID); }]; } void UIScriptController::beginBackSwipe(JSValueRef callback) { playBackEvents(m_context, beginSwipeBackEventStream(), callback); } void UIScriptController::completeBackSwipe(JSValueRef callback) { playBackEvents(m_context, completeSwipeBackEventStream(), callback); } void UIScriptController::platformPlayBackEventStream(JSStringRef eventStream, JSValueRef callback) { RetainPtr stream = adoptCF(JSStringCopyCFString(kCFAllocatorDefault, eventStream)); playBackEvents(m_context, (NSString *)stream.get(), callback); } } // namespace WTR